/* ** The pExpr should be a TK_COLUMN expression. The table referred to ** is in pTabList or else it is the NEW or OLD table of a trigger. ** Check to see if it is OK to read this particular column. ** ** If the auth function returns SQLITE_IGNORE, change the TK_COLUMN ** instruction into a TK_NULL. If the auth function returns SQLITE_DENY, ** then generate an error. */ void sqliteAuthRead( Parse *pParse, /* The parser context */ Expr *pExpr, /* The expression to check authorization on */ SrcList *pTabList /* All table that pExpr might refer to */ ){ sqlite *db = pParse->db; int rc; Table *pTab; /* The table being read */ const char *zCol; /* Name of the column of the table */ int iSrc; /* Index in pTabList->a[] of table being read */ const char *zDBase; /* Name of database being accessed */ if( db->xAuth==0 ) return; assert( pExpr->op==TK_COLUMN ); for(iSrc=0; iSrc<pTabList->nSrc; iSrc++){ if( pExpr->iTable==pTabList->a[iSrc].iCursor ) break; } if( iSrc>=0 && iSrc<pTabList->nSrc ){ pTab = pTabList->a[iSrc].pTab; }else{ /* This must be an attempt to read the NEW or OLD pseudo-tables ** of a trigger. */ TriggerStack *pStack; /* The stack of current triggers */ pStack = pParse->trigStack; assert( pStack!=0 ); assert( pExpr->iTable==pStack->newIdx || pExpr->iTable==pStack->oldIdx ); pTab = pStack->pTab; } if( pTab==0 ) return; if( pExpr->iColumn>=0 ){ assert( pExpr->iColumn<pTab->nCol ); zCol = pTab->aCol[pExpr->iColumn].zName; }else if( pTab->iPKey>=0 ){ assert( pTab->iPKey<pTab->nCol ); zCol = pTab->aCol[pTab->iPKey].zName; }else{ zCol = "ROWID"; } assert( pExpr->iDb<db->nDb ); zDBase = db->aDb[pExpr->iDb].zName; rc = db->xAuth(db->pAuthArg, SQLITE_READ, pTab->zName, zCol, zDBase, pParse->zAuthContext); if( rc==SQLITE_IGNORE ){ pExpr->op = TK_NULL; }else if( rc==SQLITE_DENY ){ if( db->nDb>2 || pExpr->iDb!=0 ){ sqliteSetString(&pParse->zErrMsg,"access to ", zDBase, ".", pTab->zName, ".", zCol, " is prohibited", 0); }else{ sqliteSetString(&pParse->zErrMsg,"access to ", pTab->zName, ".", zCol, " is prohibited", 0); } pParse->nErr++; pParse->rc = SQLITE_AUTH; }else if( rc!=SQLITE_OK ){ sqliteAuthBadReturnCode(pParse, rc); } }
/* ** Initialize all database files - the main database file, the file ** used to store temporary tables, and any additional database files ** created using ATTACH statements. Return a success code. If an ** error occurs, write an error message into *pzErrMsg. ** ** After the database is initialized, the SQLITE_Initialized ** bit is set in the flags field of the sqlite structure. An ** attempt is made to initialize the database as soon as it ** is opened. If that fails (perhaps because another process ** has the sqlite_master table locked) than another attempt ** is made the first time the database is accessed. */ int sqliteInit(sqlite *db, char **pzErrMsg){ int i, rc; if( db->init.busy ) return SQLITE_OK; assert( (db->flags & SQLITE_Initialized)==0 ); rc = SQLITE_OK; db->init.busy = 1; for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ if( DbHasProperty(db, i, DB_SchemaLoaded) ) continue; assert( i!=1 ); /* Should have been initialized together with 0 */ rc = sqliteInitOne(db, i, pzErrMsg); if( rc ){ sqliteResetInternalSchema(db, i); } } db->init.busy = 0; if( rc==SQLITE_OK ){ db->flags |= SQLITE_Initialized; sqliteCommitInternalChanges(db); } /* If the database is in formats 1 or 2, then upgrade it to ** version 3. This will reconstruct all indices. If the ** upgrade fails for any reason (ex: out of disk space, database ** is read only, interrupt received, etc.) then fail the init. */ if( rc==SQLITE_OK && db->file_format<3 ){ char *zErr = 0; InitData initData; int meta[SQLITE_N_BTREE_META]; db->magic = SQLITE_MAGIC_OPEN; initData.db = db; initData.pzErrMsg = &zErr; db->file_format = 3; rc = sqlite_exec(db, "BEGIN; SELECT name FROM sqlite_master WHERE type='table';", upgrade_3_callback, &initData, &zErr); if( rc==SQLITE_OK ){ sqliteBtreeGetMeta(db->aDb[0].pBt, meta); meta[2] = 4; sqliteBtreeUpdateMeta(db->aDb[0].pBt, meta); sqlite_exec(db, "COMMIT", 0, 0, 0); } if( rc!=SQLITE_OK ){ sqliteSetString(pzErrMsg, "unable to upgrade database to the version 2.6 format", zErr ? ": " : 0, zErr, (char*)0); } sqlite_freemem(zErr); } if( rc!=SQLITE_OK ){ db->flags &= ~SQLITE_Initialized; } return rc; }
/* ** Write an error message into pParse->zErrMsg that explains that the ** user-supplied authorization function returned an illegal value. */ static void sqliteAuthBadReturnCode(Parse *pParse, int rc){ char zBuf[20]; sprintf(zBuf, "(%d)", rc); sqliteSetString(&pParse->zErrMsg, "illegal return value ", zBuf, " from the authorization function - should be SQLITE_OK, " "SQLITE_IGNORE, or SQLITE_DENY", 0); pParse->nErr++; pParse->rc = SQLITE_MISUSE; }
/* * A string-manipulation helper function for check_redblack_tree(). If (orig == * NULL) a copy of val is returned. If (orig != NULL) then a copy of the * * concatenation of orig and val is returned. The original orig is deleted * (using sqliteFree()). */ static char *append_val(char * orig, char const * val){ char *z; if( !orig ){ z = sqliteStrDup( val ); } else{ z = 0; sqliteSetString(&z, orig, val, (char*)0); sqliteFree( orig ); } return z; }
/* ** Give a listing of the program in the virtual machine. ** ** The interface is the same as sqliteVdbeExec(). But instead of ** running the code, it invokes the callback once for each instruction. ** This feature is used to implement "EXPLAIN". */ int sqliteVdbeList( Vdbe *p /* The VDBE */ ){ sqlite *db = p->db; int i; int rc = SQLITE_OK; static char *azColumnNames[] = { "addr", "opcode", "p1", "p2", "p3", "int", "text", "int", "int", "text", 0 }; assert( p->popStack==0 ); assert( p->explain ); p->azColName = azColumnNames; p->azResColumn = p->zArgv; for(i=0; i<5; i++) p->zArgv[i] = p->aStack[i].zShort; i = p->pc; if( i>=p->nOp ){ p->rc = SQLITE_OK; rc = SQLITE_DONE; }else if( db->flags & SQLITE_Interrupt ){ db->flags &= ~SQLITE_Interrupt; if( db->magic!=SQLITE_MAGIC_BUSY ){ p->rc = SQLITE_MISUSE; }else{ p->rc = SQLITE_INTERRUPT; } rc = SQLITE_ERROR; sqliteSetString(&p->zErrMsg, sqlite_error_string(p->rc), (char*)0); }else{ sprintf(p->zArgv[0],"%d",i); sprintf(p->zArgv[2],"%d", p->aOp[i].p1); sprintf(p->zArgv[3],"%d", p->aOp[i].p2); if( p->aOp[i].p3type==P3_POINTER ){ sprintf(p->aStack[4].zShort, "ptr(%#x)", (int)p->aOp[i].p3); p->zArgv[4] = p->aStack[4].zShort; }else{ p->zArgv[4] = p->aOp[i].p3; } p->zArgv[1] = sqliteOpcodeNames[p->aOp[i].opcode]; p->pc = i+1; p->azResColumn = p->zArgv; p->nResColumn = 5; p->rc = SQLITE_OK; rc = SQLITE_ROW; } return rc; }
/* ** Clean up and delete a VDBE after execution. Return an integer which is ** the result code. Write any error message text into *pzErrMsg. */ int sqliteVdbeFinalize(Vdbe *p, char **pzErrMsg){ int rc; sqlite *db; if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){ sqliteSetString(pzErrMsg, sqlite_error_string(SQLITE_MISUSE), (char*)0); return SQLITE_MISUSE; } db = p->db; rc = sqliteVdbeReset(p, pzErrMsg); sqliteVdbeDelete(p); if( db->want_to_close && db->pVdbe==0 ){ sqlite_close(db); } if( rc==SQLITE_SCHEMA ){ sqliteResetInternalSchema(db, 0); } return rc; }
/* ** Do an authorization check using the code and arguments given. Return ** either SQLITE_OK (zero) or SQLITE_IGNORE or SQLITE_DENY. If SQLITE_DENY ** is returned, then the error count and error message in pParse are ** modified appropriately. */ int sqliteAuthCheck( Parse *pParse, int code, const char *zArg1, const char *zArg2, const char *zArg3 ){ sqlite *db = pParse->db; int rc; if( db->xAuth==0 ){ return SQLITE_OK; } rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext); if( rc==SQLITE_DENY ){ sqliteSetString(&pParse->zErrMsg, "not authorized", 0); pParse->rc = SQLITE_AUTH; pParse->nErr++; }else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){ rc = SQLITE_DENY; sqliteAuthBadReturnCode(pParse, rc); } return rc; }
/* ** Run the parser on the given SQL string. The parser structure is ** passed in. An SQLITE_ status code is returned. If an error occurs ** and pzErrMsg!=NULL then an error message might be written into ** memory obtained from malloc() and *pzErrMsg made to point to that ** error message. Or maybe not. */ int sqliteRunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ int nErr = 0; int i; void *pEngine; int tokenType; int lastTokenParsed = -1; sqlite *db = pParse->db; extern void *sqliteParserAlloc(void*(*)(int)); extern void sqliteParserFree(void*, void(*)(void*)); extern int sqliteParser(void*, int, Token, Parse*); db->flags &= ~SQLITE_Interrupt; pParse->rc = SQLITE_OK; i = 0; pEngine = sqliteParserAlloc((void*(*)(int))malloc); if( pEngine==0 ){ sqliteSetString(pzErrMsg, "out of memory", (char*)0); return 1; } pParse->sLastToken.dyn = 0; pParse->zTail = zSql; while( sqlite_malloc_failed==0 && zSql[i]!=0 ){ assert( i>=0 ); pParse->sLastToken.z = &zSql[i]; assert( pParse->sLastToken.dyn==0 ); pParse->sLastToken.n = sqliteGetToken((unsigned char*)&zSql[i], &tokenType); i += pParse->sLastToken.n; switch( tokenType ){ case TK_SPACE: case TK_COMMENT: { if( (db->flags & SQLITE_Interrupt)!=0 ){ pParse->rc = SQLITE_INTERRUPT; sqliteSetString(pzErrMsg, "interrupt", (char*)0); goto abort_parse; } break; } case TK_ILLEGAL: { sqliteSetNString(pzErrMsg, "unrecognized token: \"", -1, pParse->sLastToken.z, pParse->sLastToken.n, "\"", 1, 0); nErr++; goto abort_parse; } case TK_SEMI: { pParse->zTail = &zSql[i]; /* Fall thru into the default case */ } default: { sqliteParser(pEngine, tokenType, pParse->sLastToken, pParse); lastTokenParsed = tokenType; if( pParse->rc!=SQLITE_OK ){ goto abort_parse; } break; } } } abort_parse: if( zSql[i]==0 && nErr==0 && pParse->rc==SQLITE_OK ){ if( lastTokenParsed!=TK_SEMI ){ sqliteParser(pEngine, TK_SEMI, pParse->sLastToken, pParse); pParse->zTail = &zSql[i]; } sqliteParser(pEngine, 0, pParse->sLastToken, pParse); } sqliteParserFree(pEngine, free); if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){ sqliteSetString(&pParse->zErrMsg, sqlite_error_string(pParse->rc), (char*)0); } if( pParse->zErrMsg ){ if( pzErrMsg && *pzErrMsg==0 ){ *pzErrMsg = pParse->zErrMsg; }else{ sqliteFree(pParse->zErrMsg); } pParse->zErrMsg = 0; if( !nErr ) nErr++; } if( pParse->pVdbe && pParse->nErr>0 ){ sqliteVdbeDelete(pParse->pVdbe); pParse->pVdbe = 0; } if( pParse->pNewTable ){ sqliteDeleteTable(pParse->db, pParse->pNewTable); pParse->pNewTable = 0; } if( pParse->pNewTrigger ){ sqliteDeleteTrigger(pParse->pNewTrigger); pParse->pNewTrigger = 0; } if( nErr>0 && (pParse->rc==SQLITE_OK || pParse->rc==SQLITE_DONE) ){ pParse->rc = SQLITE_ERROR; } return nErr; }
/* ** Compile a single statement of SQL into a virtual machine. Return one ** of the SQLITE_ success/failure codes. Also write an error message into ** memory obtained from malloc() and make *pzErrMsg point to that message. */ int sqlite_compile( sqlite *db, /* The database on which the SQL executes */ const char *zSql, /* The SQL to be executed */ const char **pzTail, /* OUT: Next statement after the first */ sqlite_vm **ppVm, /* OUT: The virtual machine */ char **pzErrMsg /* OUT: Write error messages here */ ){ Parse sParse; if( pzErrMsg ) *pzErrMsg = 0; if( sqliteSafetyOn(db) ) goto exec_misuse; if( !db->init.busy ){ if( (db->flags & SQLITE_Initialized)==0 ){ int rc, cnt = 1; while( (rc = sqliteInit(db, pzErrMsg))==SQLITE_BUSY && db->xBusyCallback && db->xBusyCallback(db->pBusyArg, "", cnt++)!=0 ){} if( rc!=SQLITE_OK ){ sqliteStrRealloc(pzErrMsg); sqliteSafetyOff(db); return rc; } if( pzErrMsg ){ sqliteFree(*pzErrMsg); *pzErrMsg = 0; } } if( db->file_format<3 ){ sqliteSafetyOff(db); sqliteSetString(pzErrMsg, "obsolete database file format", (char*)0); return SQLITE_ERROR; } } assert( (db->flags & SQLITE_Initialized)!=0 || db->init.busy ); if( db->pVdbe==0 ){ db->nChange = 0; } memset(&sParse, 0, sizeof(sParse)); sParse.db = db; sqliteRunParser(&sParse, zSql, pzErrMsg); if( db->xTrace && !db->init.busy ){ /* Trace only the statment that was compiled. ** Make a copy of that part of the SQL string since zSQL is const ** and we must pass a zero terminated string to the trace function ** The copy is unnecessary if the tail pointer is pointing at the ** beginnig or end of the SQL string. */ if( sParse.zTail && sParse.zTail!=zSql && *sParse.zTail ){ char *tmpSql = sqliteStrNDup(zSql, sParse.zTail - zSql); if( tmpSql ){ db->xTrace(db->pTraceArg, tmpSql); free(tmpSql); }else{ /* If a memory error occurred during the copy, ** trace entire SQL string and fall through to the ** sqlite_malloc_failed test to report the error. */ db->xTrace(db->pTraceArg, zSql); } }else{ db->xTrace(db->pTraceArg, zSql); } } if( sqlite_malloc_failed ){ sqliteSetString(pzErrMsg, "out of memory", (char*)0); sParse.rc = SQLITE_NOMEM; sqliteRollbackAll(db); sqliteResetInternalSchema(db, 0); db->flags &= ~SQLITE_InTrans; } if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK; if( sParse.rc!=SQLITE_OK && pzErrMsg && *pzErrMsg==0 ){ sqliteSetString(pzErrMsg, sqlite_error_string(sParse.rc), (char*)0); } sqliteStrRealloc(pzErrMsg); if( sParse.rc==SQLITE_SCHEMA ){ sqliteResetInternalSchema(db, 0); } assert( ppVm ); *ppVm = (sqlite_vm*)sParse.pVdbe; if( pzTail ) *pzTail = sParse.zTail; if( sqliteSafetyOff(db) ) goto exec_misuse; return sParse.rc; exec_misuse: if( pzErrMsg ){ *pzErrMsg = 0; sqliteSetString(pzErrMsg, sqlite_error_string(SQLITE_MISUSE), (char*)0); sqliteStrRealloc(pzErrMsg); } return SQLITE_MISUSE; }
/* ** Open a new SQLite database. Construct an "sqlite" structure to define ** the state of this database and return a pointer to that structure. ** ** An attempt is made to initialize the in-memory data structures that ** hold the database schema. But if this fails (because the schema file ** is locked) then that step is deferred until the first call to ** sqlite_exec(). */ sqlite *sqlite_open(const char *zFilename, int mode, char **pzErrMsg){ sqlite *db; int rc, i; /* Allocate the sqlite data structure */ db = sqliteMalloc( sizeof(sqlite) ); if( pzErrMsg ) *pzErrMsg = 0; if( db==0 ) goto no_mem_on_open; db->onError = OE_Default; db->priorNewRowid = 0; db->magic = SQLITE_MAGIC_BUSY; db->nDb = 2; db->aDb = db->aDbStatic; /* db->flags |= SQLITE_ShortColNames; */ sqliteHashInit(&db->aFunc, SQLITE_HASH_STRING, 1); for(i=0; i<db->nDb; i++){ sqliteHashInit(&db->aDb[i].tblHash, SQLITE_HASH_STRING, 0); sqliteHashInit(&db->aDb[i].idxHash, SQLITE_HASH_STRING, 0); sqliteHashInit(&db->aDb[i].trigHash, SQLITE_HASH_STRING, 0); sqliteHashInit(&db->aDb[i].aFKey, SQLITE_HASH_STRING, 1); } /* Open the backend database driver */ if( zFilename[0]==':' && strcmp(zFilename,":memory:")==0 ){ db->temp_store = 2; } rc = sqliteBtreeFactory(db, zFilename, 0, MAX_PAGES, &db->aDb[0].pBt); if( rc!=SQLITE_OK ){ switch( rc ){ default: { sqliteSetString(pzErrMsg, "unable to open database: ", zFilename, (char*)0); } } sqliteFree(db); sqliteStrRealloc(pzErrMsg); return 0; } db->aDb[0].zName = "main"; db->aDb[1].zName = "temp"; /* Attempt to read the schema */ sqliteRegisterBuiltinFunctions(db); rc = sqliteInit(db, pzErrMsg); db->magic = SQLITE_MAGIC_OPEN; if( sqlite_malloc_failed ){ sqlite_close(db); goto no_mem_on_open; }else if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){ sqlite_close(db); sqliteStrRealloc(pzErrMsg); return 0; }else if( pzErrMsg ){ sqliteFree(*pzErrMsg); *pzErrMsg = 0; } /* Return a pointer to the newly opened database structure */ return db; no_mem_on_open: sqliteSetString(pzErrMsg, "out of memory", (char*)0); sqliteStrRealloc(pzErrMsg); return 0; }
/* ** Fill the InitData structure with an error message that indicates ** that the database is corrupt. */ static void corruptSchema(InitData *pData, const char *zExtra){ sqliteSetString(pData->pzErrMsg, "malformed database schema", zExtra!=0 && zExtra[0]!=0 ? " - " : (char*)0, zExtra, (char*)0); }
/* ** Attempt to read the database schema and initialize internal ** data structures for a single database file. The index of the ** database file is given by iDb. iDb==0 is used for the main ** database. iDb==1 should never be used. iDb>=2 is used for ** auxiliary databases. Return one of the SQLITE_ error codes to ** indicate success or failure. */ static int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){ int rc; BtCursor *curMain; int size; Table *pTab; char const *azArg[6]; char zDbNum[30]; int meta[SQLITE_N_BTREE_META]; InitData initData; char const *zMasterSchema; char const *zMasterName; char *zSql = 0; /* ** The master database table has a structure like this */ static char master_schema[] = "CREATE TABLE sqlite_master(\n" " type text,\n" " name text,\n" " tbl_name text,\n" " rootpage integer,\n" " sql text\n" ")" ; static char temp_master_schema[] = "CREATE TEMP TABLE sqlite_temp_master(\n" " type text,\n" " name text,\n" " tbl_name text,\n" " rootpage integer,\n" " sql text\n" ")" ; assert( iDb>=0 && iDb<db->nDb ); /* zMasterSchema and zInitScript are set to point at the master schema ** and initialisation script appropriate for the database being ** initialised. zMasterName is the name of the master table. */ if( iDb==1 ){ zMasterSchema = temp_master_schema; zMasterName = TEMP_MASTER_NAME; }else{ zMasterSchema = master_schema; zMasterName = MASTER_NAME; } /* Construct the schema table. */ sqliteSafetyOff(db); azArg[0] = "table"; azArg[1] = zMasterName; azArg[2] = "2"; azArg[3] = zMasterSchema; sprintf(zDbNum, "%d", iDb); azArg[4] = zDbNum; azArg[5] = 0; initData.db = db; initData.pzErrMsg = pzErrMsg; sqliteInitCallback(&initData, 5, (char **)azArg, 0); pTab = sqliteFindTable(db, zMasterName, db->aDb[iDb].zName); if( pTab ){ pTab->readOnly = 1; }else{ return SQLITE_NOMEM; } sqliteSafetyOn(db); /* Create a cursor to hold the database open */ if( db->aDb[iDb].pBt==0 ) return SQLITE_OK; rc = sqliteBtreeCursor(db->aDb[iDb].pBt, 2, 0, &curMain); if( rc ){ sqliteSetString(pzErrMsg, sqlite_error_string(rc), (char*)0); return rc; } /* Get the database meta information */ rc = sqliteBtreeGetMeta(db->aDb[iDb].pBt, meta); if( rc ){ sqliteSetString(pzErrMsg, sqlite_error_string(rc), (char*)0); sqliteBtreeCloseCursor(curMain); return rc; } db->aDb[iDb].schema_cookie = meta[1]; if( iDb==0 ){ db->next_cookie = meta[1]; db->file_format = meta[2]; size = meta[3]; if( size==0 ){ size = MAX_PAGES; } db->cache_size = size; db->safety_level = meta[4]; if( meta[6]>0 && meta[6]<=2 && db->temp_store==0 ){ db->temp_store = meta[6]; } if( db->safety_level==0 ) db->safety_level = 2; /* ** file_format==1 Version 2.1.0. ** file_format==2 Version 2.2.0. Add support for INTEGER PRIMARY KEY. ** file_format==3 Version 2.6.0. Fix empty-string index bug. ** file_format==4 Version 2.7.0. Add support for separate numeric and ** text datatypes. */ if( db->file_format==0 ){ /* This happens if the database was initially empty */ db->file_format = 4; }else if( db->file_format>4 ){ sqliteBtreeCloseCursor(curMain); sqliteSetString(pzErrMsg, "unsupported file format", (char*)0); return SQLITE_ERROR; } }else if( iDb!=1 && (db->file_format!=meta[2] || db->file_format<4) ){ assert( db->file_format>=4 ); if( meta[2]==0 ){ sqliteSetString(pzErrMsg, "cannot attach empty database: ", db->aDb[iDb].zName, (char*)0); }else{ sqliteSetString(pzErrMsg, "incompatible file format in auxiliary " "database: ", db->aDb[iDb].zName, (char*)0); } sqliteBtreeClose(db->aDb[iDb].pBt); db->aDb[iDb].pBt = 0; return SQLITE_FORMAT; } sqliteBtreeSetCacheSize(db->aDb[iDb].pBt, db->cache_size); sqliteBtreeSetSafetyLevel(db->aDb[iDb].pBt, meta[4]==0 ? 2 : meta[4]); /* Read the schema information out of the schema tables */ assert( db->init.busy ); sqliteSafetyOff(db); /* The following SQL will read the schema from the master tables. ** The first version works with SQLite file formats 2 or greater. ** The second version is for format 1 files. ** ** Beginning with file format 2, the rowid for new table entries ** (including entries in sqlite_master) is an increasing integer. ** So for file format 2 and later, we can play back sqlite_master ** and all the CREATE statements will appear in the right order. ** But with file format 1, table entries were random and so we ** have to make sure the CREATE TABLEs occur before their corresponding ** CREATE INDEXs. (We don't have to deal with CREATE VIEW or ** CREATE TRIGGER in file format 1 because those constructs did ** not exist then.) */ if( db->file_format>=2 ){ sqliteSetString(&zSql, "SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"", db->aDb[iDb].zName, "\".", zMasterName, (char*)0); }else{ sqliteSetString(&zSql, "SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"", db->aDb[iDb].zName, "\".", zMasterName, " WHERE type IN ('table', 'index')" " ORDER BY CASE type WHEN 'table' THEN 0 ELSE 1 END", (char*)0); } rc = sqlite_exec(db, zSql, sqliteInitCallback, &initData, 0); sqliteFree(zSql); sqliteSafetyOn(db); sqliteBtreeCloseCursor(curMain); if( sqlite_malloc_failed ){ sqliteSetString(pzErrMsg, "out of memory", (char*)0); rc = SQLITE_NOMEM; sqliteResetInternalSchema(db, 0); } if( rc==SQLITE_OK ){ DbSetProperty(db, iDb, DB_SchemaLoaded); }else{ sqliteResetInternalSchema(db, iDb); } return rc; }
/* ** Clean up a VDBE after execution but do not delete the VDBE just yet. ** Write any error messages into *pzErrMsg. Return the result code. ** ** After this routine is run, the VDBE should be ready to be executed ** again. */ int sqliteVdbeReset(Vdbe *p, char **pzErrMsg){ sqlite *db = p->db; int i; if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){ sqliteSetString(pzErrMsg, sqlite_error_string(SQLITE_MISUSE), (char*)0); return SQLITE_MISUSE; } if( p->zErrMsg ){ if( pzErrMsg && *pzErrMsg==0 ){ *pzErrMsg = p->zErrMsg; }else{ sqliteFree(p->zErrMsg); } p->zErrMsg = 0; }else if( p->rc ){ sqliteSetString(pzErrMsg, sqlite_error_string(p->rc), (char*)0); } Cleanup(p); if( p->rc!=SQLITE_OK ){ switch( p->errorAction ){ case OE_Abort: { if( !p->undoTransOnError ){ for(i=0; i<db->nDb; i++){ if( db->aDb[i].pBt ){ sqliteBtreeRollbackCkpt(db->aDb[i].pBt); } } break; } /* Fall through to ROLLBACK */ } case OE_Rollback: { sqliteRollbackAll(db); db->flags &= ~SQLITE_InTrans; db->onError = OE_Default; break; } default: { if( p->undoTransOnError ){ sqliteRollbackAll(db); db->flags &= ~SQLITE_InTrans; db->onError = OE_Default; } break; } } sqliteRollbackInternalChanges(db); } for(i=0; i<db->nDb; i++){ if( db->aDb[i].pBt && db->aDb[i].inTrans==2 ){ sqliteBtreeCommitCkpt(db->aDb[i].pBt); db->aDb[i].inTrans = 1; } } assert( p->pTos<&p->aStack[p->pc] || sqlite_malloc_failed==1 ); #ifdef VDBE_PROFILE { FILE *out = fopen("vdbe_profile.out", "a"); if( out ){ int i; fprintf(out, "---- "); for(i=0; i<p->nOp; i++){ fprintf(out, "%02x", p->aOp[i].opcode); } fprintf(out, "\n"); for(i=0; i<p->nOp; i++){ fprintf(out, "%6d %10lld %8lld ", p->aOp[i].cnt, p->aOp[i].cycles, p->aOp[i].cnt>0 ? p->aOp[i].cycles/p->aOp[i].cnt : 0 ); sqliteVdbePrintOp(out, i, &p->aOp[i]); } fclose(out); } } #endif p->magic = VDBE_MAGIC_INIT; return p->rc; }
/* ** Generate code to do a constraint check prior to an INSERT or an UPDATE. ** ** When this routine is called, the stack contains (from bottom to top) ** the following values: ** ** 1. The recno of the row to be updated before the update. This ** value is omitted unless we are doing an UPDATE that involves a ** change to the record number. ** ** 2. The recno of the row after the update. ** ** 3. The data in the first column of the entry after the update. ** ** i. Data from middle columns... ** ** N. The data in the last column of the entry after the update. ** ** The old recno shown as entry (1) above is omitted unless both isUpdate ** and recnoChng are 1. isUpdate is true for UPDATEs and false for ** INSERTs and recnoChng is true if the record number is being changed. ** ** The code generated by this routine pushes additional entries onto ** the stack which are the keys for new index entries for the new record. ** The order of index keys is the same as the order of the indices on ** the pTable->pIndex list. A key is only created for index i if ** aIdxUsed!=0 and aIdxUsed[i]!=0. ** ** This routine also generates code to check constraints. NOT NULL, ** CHECK, and UNIQUE constraints are all checked. If a constraint fails, ** then the appropriate action is performed. There are five possible ** actions: ROLLBACK, ABORT, FAIL, REPLACE, and IGNORE. ** ** Constraint type Action What Happens ** --------------- ---------- ---------------------------------------- ** any ROLLBACK The current transaction is rolled back and ** sqlite_exec() returns immediately with a ** return code of SQLITE_CONSTRAINT. ** ** any ABORT Back out changes from the current command ** only (do not do a complete rollback) then ** cause sqlite_exec() to return immediately ** with SQLITE_CONSTRAINT. ** ** any FAIL Sqlite_exec() returns immediately with a ** return code of SQLITE_CONSTRAINT. The ** transaction is not rolled back and any ** prior changes are retained. ** ** any IGNORE The record number and data is popped from ** the stack and there is an immediate jump ** to label ignoreDest. ** ** NOT NULL REPLACE The NULL value is replace by the default ** value for that column. If the default value ** is NULL, the action is the same as ABORT. ** ** UNIQUE REPLACE The other row that conflicts with the row ** being inserted is removed. ** ** CHECK REPLACE Illegal. The results in an exception. ** ** Which action to take is determined by the overrideError parameter. ** Or if overrideError==OE_Default, then the pParse->onError parameter ** is used. Or if pParse->onError==OE_Default then the onError value ** for the constraint is used. ** ** The calling routine must open a read/write cursor for pTab with ** cursor number "base". All indices of pTab must also have open ** read/write cursors with cursor number base+i for the i-th cursor. ** Except, if there is no possibility of a REPLACE action then ** cursors do not need to be open for indices where aIdxUsed[i]==0. ** ** If the isUpdate flag is true, it means that the "base" cursor is ** initially pointing to an entry that is being updated. The isUpdate ** flag causes extra code to be generated so that the "base" cursor ** is still pointing at the same entry after the routine returns. ** Without the isUpdate flag, the "base" cursor might be moved. */ void sqliteGenerateConstraintChecks( Parse *pParse, /* The parser context */ Table *pTab, /* the table into which we are inserting */ int base, /* Index of a read/write cursor pointing at pTab */ char *aIdxUsed, /* Which indices are used. NULL means all are used */ int recnoChng, /* True if the record number will change */ int isUpdate, /* True for UPDATE, False for INSERT */ int overrideError, /* Override onError to this if not OE_Default */ int ignoreDest /* Jump to this label on an OE_Ignore resolution */ ){ int i; Vdbe *v; int nCol; int onError; int addr; int extra; int iCur; Index *pIdx; int seenReplace = 0; int jumpInst1, jumpInst2; int contAddr; int hasTwoRecnos = (isUpdate && recnoChng); v = sqliteGetVdbe(pParse); assert( v!=0 ); assert( pTab->pSelect==0 ); /* This table is not a VIEW */ nCol = pTab->nCol; /* Test all NOT NULL constraints. */ for(i=0; i<nCol; i++){ if( i==pTab->iPKey ){ continue; } onError = pTab->aCol[i].notNull; if( onError==OE_None ) continue; if( overrideError!=OE_Default ){ onError = overrideError; }else if( pParse->db->onError!=OE_Default ){ onError = pParse->db->onError; }else if( onError==OE_Default ){ onError = OE_Abort; } if( onError==OE_Replace && pTab->aCol[i].zDflt==0 ){ onError = OE_Abort; } sqliteVdbeAddOp(v, OP_Dup, nCol-1-i, 1); addr = sqliteVdbeAddOp(v, OP_NotNull, 1, 0); switch( onError ){ case OE_Rollback: case OE_Abort: case OE_Fail: { char *zMsg = 0; sqliteVdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, onError); sqliteSetString(&zMsg, pTab->zName, ".", pTab->aCol[i].zName, " may not be NULL", (char*)0); sqliteVdbeChangeP3(v, -1, zMsg, P3_DYNAMIC); break; } case OE_Ignore: { sqliteVdbeAddOp(v, OP_Pop, nCol+1+hasTwoRecnos, 0); sqliteVdbeAddOp(v, OP_Goto, 0, ignoreDest); break; } case OE_Replace: { sqliteVdbeOp3(v, OP_String, 0, 0, pTab->aCol[i].zDflt, P3_STATIC); sqliteVdbeAddOp(v, OP_Push, nCol-i, 0); break; } default: assert(0); } sqliteVdbeChangeP2(v, addr, sqliteVdbeCurrentAddr(v)); } /* Test all CHECK constraints */ /**** TBD ****/ /* If we have an INTEGER PRIMARY KEY, make sure the primary key ** of the new record does not previously exist. Except, if this ** is an UPDATE and the primary key is not changing, that is OK. */ if( recnoChng ){ onError = pTab->keyConf; if( overrideError!=OE_Default ){ onError = overrideError; }else if( pParse->db->onError!=OE_Default ){ onError = pParse->db->onError; }else if( onError==OE_Default ){ onError = OE_Abort; } if( isUpdate ){ sqliteVdbeAddOp(v, OP_Dup, nCol+1, 1); sqliteVdbeAddOp(v, OP_Dup, nCol+1, 1); jumpInst1 = sqliteVdbeAddOp(v, OP_Eq, 0, 0); } sqliteVdbeAddOp(v, OP_Dup, nCol, 1); jumpInst2 = sqliteVdbeAddOp(v, OP_NotExists, base, 0); switch( onError ){ default: { onError = OE_Abort; /* Fall thru into the next case */ } case OE_Rollback: case OE_Abort: case OE_Fail: { sqliteVdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError, "PRIMARY KEY must be unique", P3_STATIC); break; } case OE_Replace: { sqliteGenerateRowIndexDelete(pParse->db, v, pTab, base, 0); if( isUpdate ){ sqliteVdbeAddOp(v, OP_Dup, nCol+hasTwoRecnos, 1); sqliteVdbeAddOp(v, OP_MoveTo, base, 0); } seenReplace = 1; break; } case OE_Ignore: { assert( seenReplace==0 ); sqliteVdbeAddOp(v, OP_Pop, nCol+1+hasTwoRecnos, 0); sqliteVdbeAddOp(v, OP_Goto, 0, ignoreDest); break; } } contAddr = sqliteVdbeCurrentAddr(v); sqliteVdbeChangeP2(v, jumpInst2, contAddr); if( isUpdate ){ sqliteVdbeChangeP2(v, jumpInst1, contAddr); sqliteVdbeAddOp(v, OP_Dup, nCol+1, 1); sqliteVdbeAddOp(v, OP_MoveTo, base, 0); } } /* Test all UNIQUE constraints by creating entries for each UNIQUE ** index and making sure that duplicate entries do not already exist. ** Add the new records to the indices as we go. */ extra = -1; for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){ if( aIdxUsed && aIdxUsed[iCur]==0 ) continue; /* Skip unused indices */ extra++; /* Create a key for accessing the index entry */ sqliteVdbeAddOp(v, OP_Dup, nCol+extra, 1); for(i=0; i<pIdx->nColumn; i++){ int idx = pIdx->aiColumn[i]; if( idx==pTab->iPKey ){ sqliteVdbeAddOp(v, OP_Dup, i+extra+nCol+1, 1); }else{ sqliteVdbeAddOp(v, OP_Dup, i+extra+nCol-idx, 1); } } jumpInst1 = sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0); if( pParse->db->file_format>=4 ) sqliteAddIdxKeyType(v, pIdx); /* Find out what action to take in case there is an indexing conflict */ onError = pIdx->onError; if( onError==OE_None ) continue; /* pIdx is not a UNIQUE index */ if( overrideError!=OE_Default ){ onError = overrideError; }else if( pParse->db->onError!=OE_Default ){ onError = pParse->db->onError; }else if( onError==OE_Default ){ onError = OE_Abort; } if( seenReplace ){ if( onError==OE_Ignore ) onError = OE_Replace; else if( onError==OE_Fail ) onError = OE_Abort; } /* Check to see if the new index entry will be unique */ sqliteVdbeAddOp(v, OP_Dup, extra+nCol+1+hasTwoRecnos, 1); jumpInst2 = sqliteVdbeAddOp(v, OP_IsUnique, base+iCur+1, 0); /* Generate code that executes if the new index entry is not unique */ switch( onError ){ case OE_Rollback: case OE_Abort: case OE_Fail: { int j, n1, n2; char zErrMsg[200]; strcpy(zErrMsg, pIdx->nColumn>1 ? "columns " : "column "); n1 = strlen(zErrMsg); for(j=0; j<pIdx->nColumn && n1<sizeof(zErrMsg)-30; j++){ char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName; n2 = strlen(zCol); if( j>0 ){ strcpy(&zErrMsg[n1], ", "); n1 += 2; } if( n1+n2>sizeof(zErrMsg)-30 ){ strcpy(&zErrMsg[n1], "..."); n1 += 3; break; }else{ strcpy(&zErrMsg[n1], zCol); n1 += n2; } } strcpy(&zErrMsg[n1], pIdx->nColumn>1 ? " are not unique" : " is not unique"); sqliteVdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError, zErrMsg, 0); break; } case OE_Ignore: { assert( seenReplace==0 ); sqliteVdbeAddOp(v, OP_Pop, nCol+extra+3+hasTwoRecnos, 0); sqliteVdbeAddOp(v, OP_Goto, 0, ignoreDest); break; } case OE_Replace: { sqliteGenerateRowDelete(pParse->db, v, pTab, base, 0); if( isUpdate ){ sqliteVdbeAddOp(v, OP_Dup, nCol+extra+1+hasTwoRecnos, 1); sqliteVdbeAddOp(v, OP_MoveTo, base, 0); } seenReplace = 1; break; } default: assert(0); } contAddr = sqliteVdbeCurrentAddr(v); #if NULL_DISTINCT_FOR_UNIQUE sqliteVdbeChangeP2(v, jumpInst1, contAddr); #endif sqliteVdbeChangeP2(v, jumpInst2, contAddr); } }
/* ** Generate the beginning of the loop used for WHERE clause processing. ** The return value is a pointer to an (opaque) structure that contains ** information needed to terminate the loop. Later, the calling routine ** should invoke sqliteWhereEnd() with the return value of this function ** in order to complete the WHERE clause processing. ** ** If an error occurs, this routine returns NULL. ** ** The basic idea is to do a nested loop, one loop for each table in ** the FROM clause of a select. (INSERT and UPDATE statements are the ** same as a SELECT with only a single table in the FROM clause.) For ** example, if the SQL is this: ** ** SELECT * FROM t1, t2, t3 WHERE ...; ** ** Then the code generated is conceptually like the following: ** ** foreach row1 in t1 do \ Code generated ** foreach row2 in t2 do |-- by sqliteWhereBegin() ** foreach row3 in t3 do / ** ... ** end \ Code generated ** end |-- by sqliteWhereEnd() ** end / ** ** There are Btree cursors associated with each table. t1 uses cursor ** number pTabList->a[0].iCursor. t2 uses the cursor pTabList->a[1].iCursor. ** And so forth. This routine generates code to open those VDBE cursors ** and sqliteWhereEnd() generates the code to close them. ** ** If the WHERE clause is empty, the foreach loops must each scan their ** entire tables. Thus a three-way join is an O(N^3) operation. But if ** the tables have indices and there are terms in the WHERE clause that ** refer to those indices, a complete table scan can be avoided and the ** code will run much faster. Most of the work of this routine is checking ** to see if there are indices that can be used to speed up the loop. ** ** Terms of the WHERE clause are also used to limit which rows actually ** make it to the "..." in the middle of the loop. After each "foreach", ** terms of the WHERE clause that use only terms in that loop and outer ** loops are evaluated and if false a jump is made around all subsequent ** inner loops (or around the "..." if the test occurs within the inner- ** most loop) ** ** OUTER JOINS ** ** An outer join of tables t1 and t2 is conceptally coded as follows: ** ** foreach row1 in t1 do ** flag = 0 ** foreach row2 in t2 do ** start: ** ... ** flag = 1 ** end ** if flag==0 then ** move the row2 cursor to a null row ** goto start ** fi ** end ** ** ORDER BY CLAUSE PROCESSING ** ** *ppOrderBy is a pointer to the ORDER BY clause of a SELECT statement, ** if there is one. If there is no ORDER BY clause or if this routine ** is called from an UPDATE or DELETE statement, then ppOrderBy is NULL. ** ** If an index can be used so that the natural output order of the table ** scan is correct for the ORDER BY clause, then that index is used and ** *ppOrderBy is set to NULL. This is an optimization that prevents an ** unnecessary sort of the result set if an index appropriate for the ** ORDER BY clause already exists. ** ** If the where clause loops cannot be arranged to provide the correct ** output order, then the *ppOrderBy is unchanged. */ WhereInfo *sqliteWhereBegin( Parse *pParse, /* The parser context */ SrcList *pTabList, /* A list of all tables to be scanned */ Expr *pWhere, /* The WHERE clause */ int pushKey, /* If TRUE, leave the table key on the stack */ ExprList **ppOrderBy /* An ORDER BY clause, or NULL */ ) { int i; /* Loop counter */ WhereInfo *pWInfo; /* Will become the return value of this function */ Vdbe *v = pParse->pVdbe; /* The virtual database engine */ int brk, cont = 0; /* Addresses used during code generation */ int nExpr; /* Number of subexpressions in the WHERE clause */ int loopMask; /* One bit set for each outer loop */ int haveKey; /* True if KEY is on the stack */ ExprMaskSet maskSet; /* The expression mask set */ int iDirectEq[32]; /* Term of the form ROWID==X for the N-th table */ int iDirectLt[32]; /* Term of the form ROWID<X or ROWID<=X */ int iDirectGt[32]; /* Term of the form ROWID>X or ROWID>=X */ ExprInfo aExpr[101]; /* The WHERE clause is divided into these expressions */ /* pushKey is only allowed if there is a single table (as in an INSERT or ** UPDATE statement) */ assert( pushKey==0 || pTabList->nSrc==1 ); /* Split the WHERE clause into separate subexpressions where each ** subexpression is separated by an AND operator. If the aExpr[] ** array fills up, the last entry might point to an expression which ** contains additional unfactored AND operators. */ initMaskSet(&maskSet); memset(aExpr, 0, sizeof(aExpr)); nExpr = exprSplit(ARRAYSIZE(aExpr), aExpr, pWhere); if( nExpr==ARRAYSIZE(aExpr) ) { char zBuf[50]; sprintf(zBuf, "%d", (int)ARRAYSIZE(aExpr)-1); sqliteSetString(&pParse->zErrMsg, "WHERE clause too complex - no more " "than ", zBuf, " terms allowed", (char*)0); pParse->nErr++; return 0; } /* Allocate and initialize the WhereInfo structure that will become the ** return value. */ pWInfo = sqliteMalloc( sizeof(WhereInfo) + pTabList->nSrc*sizeof(WhereLevel)); if( sqlite_malloc_failed ) { sqliteFree(pWInfo); return 0; } pWInfo->pParse = pParse; pWInfo->pTabList = pTabList; pWInfo->peakNTab = pWInfo->savedNTab = pParse->nTab; pWInfo->iBreak = sqliteVdbeMakeLabel(v); /* Special case: a WHERE clause that is constant. Evaluate the ** expression and either jump over all of the code or fall thru. */ if( pWhere && (pTabList->nSrc==0 || sqliteExprIsConstant(pWhere)) ) { sqliteExprIfFalse(pParse, pWhere, pWInfo->iBreak, 1); pWhere = 0; } /* Analyze all of the subexpressions. */ for(i=0; i<nExpr; i++) { exprAnalyze(&maskSet, &aExpr[i]); /* If we are executing a trigger body, remove all references to ** new.* and old.* tables from the prerequisite masks. */ if( pParse->trigStack ) { int x; if( (x = pParse->trigStack->newIdx) >= 0 ) { int mask = ~getMask(&maskSet, x); aExpr[i].prereqRight &= mask; aExpr[i].prereqLeft &= mask; aExpr[i].prereqAll &= mask; } if( (x = pParse->trigStack->oldIdx) >= 0 ) { int mask = ~getMask(&maskSet, x); aExpr[i].prereqRight &= mask; aExpr[i].prereqLeft &= mask; aExpr[i].prereqAll &= mask; } } } /* Figure out what index to use (if any) for each nested loop. ** Make pWInfo->a[i].pIdx point to the index to use for the i-th nested ** loop where i==0 is the outer loop and i==pTabList->nSrc-1 is the inner ** loop. ** ** If terms exist that use the ROWID of any table, then set the ** iDirectEq[], iDirectLt[], or iDirectGt[] elements for that table ** to the index of the term containing the ROWID. We always prefer ** to use a ROWID which can directly access a table rather than an ** index which requires reading an index first to get the rowid then ** doing a second read of the actual database table. ** ** Actually, if there are more than 32 tables in the join, only the ** first 32 tables are candidates for indices. This is (again) due ** to the limit of 32 bits in an integer bitmask. */ loopMask = 0; for(i=0; i<pTabList->nSrc && i<ARRAYSIZE(iDirectEq); i++) { int j; int iCur = pTabList->a[i].iCursor; /* The cursor for this table */ int mask = getMask(&maskSet, iCur); /* Cursor mask for this table */ Table *pTab = pTabList->a[i].pTab; Index *pIdx; Index *pBestIdx = 0; int bestScore = 0; /* Check to see if there is an expression that uses only the ** ROWID field of this table. For terms of the form ROWID==expr ** set iDirectEq[i] to the index of the term. For terms of the ** form ROWID<expr or ROWID<=expr set iDirectLt[i] to the term index. ** For terms like ROWID>expr or ROWID>=expr set iDirectGt[i]. ** ** (Added:) Treat ROWID IN expr like ROWID=expr. */ pWInfo->a[i].iCur = -1; iDirectEq[i] = -1; iDirectLt[i] = -1; iDirectGt[i] = -1; for(j=0; j<nExpr; j++) { if( aExpr[j].idxLeft==iCur && aExpr[j].p->pLeft->iColumn<0 && (aExpr[j].prereqRight & loopMask)==aExpr[j].prereqRight ) { switch( aExpr[j].p->op ) { case TK_IN: case TK_EQ: iDirectEq[i] = j; break; case TK_LE: case TK_LT: iDirectLt[i] = j; break; case TK_GE: case TK_GT: iDirectGt[i] = j; break; } } if( aExpr[j].idxRight==iCur && aExpr[j].p->pRight->iColumn<0 && (aExpr[j].prereqLeft & loopMask)==aExpr[j].prereqLeft ) { switch( aExpr[j].p->op ) { case TK_EQ: iDirectEq[i] = j; break; case TK_LE: case TK_LT: iDirectGt[i] = j; break; case TK_GE: case TK_GT: iDirectLt[i] = j; break; } } } if( iDirectEq[i]>=0 ) { loopMask |= mask; pWInfo->a[i].pIdx = 0; continue; } /* Do a search for usable indices. Leave pBestIdx pointing to ** the "best" index. pBestIdx is left set to NULL if no indices ** are usable. ** ** The best index is determined as follows. For each of the ** left-most terms that is fixed by an equality operator, add ** 8 to the score. The right-most term of the index may be ** constrained by an inequality. Add 1 if for an "x<..." constraint ** and add 2 for an "x>..." constraint. Chose the index that ** gives the best score. ** ** This scoring system is designed so that the score can later be ** used to determine how the index is used. If the score&7 is 0 ** then all constraints are equalities. If score&1 is not 0 then ** there is an inequality used as a termination key. (ex: "x<...") ** If score&2 is not 0 then there is an inequality used as the ** start key. (ex: "x>..."). A score or 4 is the special case ** of an IN operator constraint. (ex: "x IN ..."). ** ** The IN operator (as in "<expr> IN (...)") is treated the same as ** an equality comparison except that it can only be used on the ** left-most column of an index and other terms of the WHERE clause ** cannot be used in conjunction with the IN operator to help satisfy ** other columns of the index. */ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext) { int eqMask = 0; /* Index columns covered by an x=... term */ int ltMask = 0; /* Index columns covered by an x<... term */ int gtMask = 0; /* Index columns covered by an x>... term */ int inMask = 0; /* Index columns covered by an x IN .. term */ int nEq, m, score; if( pIdx->nColumn>32 ) continue; /* Ignore indices too many columns */ for(j=0; j<nExpr; j++) { if( aExpr[j].idxLeft==iCur && (aExpr[j].prereqRight & loopMask)==aExpr[j].prereqRight ) { int iColumn = aExpr[j].p->pLeft->iColumn; int k; for(k=0; k<pIdx->nColumn; k++) { if( pIdx->aiColumn[k]==iColumn ) { switch( aExpr[j].p->op ) { case TK_IN: { if( k==0 ) inMask |= 1; break; } case TK_EQ: { eqMask |= 1<<k; break; } case TK_LE: case TK_LT: { ltMask |= 1<<k; break; } case TK_GE: case TK_GT: { gtMask |= 1<<k; break; } default: { /* CANT_HAPPEN */ assert( 0 ); break; } } break; } } } if( aExpr[j].idxRight==iCur && (aExpr[j].prereqLeft & loopMask)==aExpr[j].prereqLeft ) { int iColumn = aExpr[j].p->pRight->iColumn; int k; for(k=0; k<pIdx->nColumn; k++) { if( pIdx->aiColumn[k]==iColumn ) { switch( aExpr[j].p->op ) { case TK_EQ: { eqMask |= 1<<k; break; } case TK_LE: case TK_LT: { gtMask |= 1<<k; break; } case TK_GE: case TK_GT: { ltMask |= 1<<k; break; } default: { /* CANT_HAPPEN */ assert( 0 ); break; } } break; } } } } /* The following loop ends with nEq set to the number of columns ** on the left of the index with == constraints. */ for(nEq=0; nEq<pIdx->nColumn; nEq++) { m = (1<<(nEq+1))-1; if( (m & eqMask)!=m ) break; } score = nEq*8; /* Base score is 8 times number of == constraints */ m = 1<<nEq; if( m & ltMask ) score++; /* Increase score for a < constraint */ if( m & gtMask ) score+=2; /* Increase score for a > constraint */ if( score==0 && inMask ) score = 4; /* Default score for IN constraint */ if( score>bestScore ) { pBestIdx = pIdx; bestScore = score; } } pWInfo->a[i].pIdx = pBestIdx; pWInfo->a[i].score = bestScore; pWInfo->a[i].bRev = 0; loopMask |= mask; if( pBestIdx ) { pWInfo->a[i].iCur = pParse->nTab++; pWInfo->peakNTab = pParse->nTab; } } /* Check to see if the ORDER BY clause is or can be satisfied by the ** use of an index on the first table. */ if( ppOrderBy && *ppOrderBy && pTabList->nSrc>0 ) { Index *pSortIdx; Index *pIdx; Table *pTab; int bRev = 0; pTab = pTabList->a[0].pTab; pIdx = pWInfo->a[0].pIdx; if( pIdx && pWInfo->a[0].score==4 ) { /* If there is already an IN index on the left-most table, ** it will not give the correct sort order. ** So, pretend that no suitable index is found. */ pSortIdx = 0; } else if( iDirectEq[0]>=0 || iDirectLt[0]>=0 || iDirectGt[0]>=0 ) { /* If the left-most column is accessed using its ROWID, then do ** not try to sort by index. */ pSortIdx = 0; } else { int nEqCol = (pWInfo->a[0].score+4)/8; pSortIdx = findSortingIndex(pTab, pTabList->a[0].iCursor, *ppOrderBy, pIdx, nEqCol, &bRev); } if( pSortIdx && (pIdx==0 || pIdx==pSortIdx) ) { if( pIdx==0 ) { pWInfo->a[0].pIdx = pSortIdx; pWInfo->a[0].iCur = pParse->nTab++; pWInfo->peakNTab = pParse->nTab; } pWInfo->a[0].bRev = bRev; *ppOrderBy = 0; } } /* Open all tables in the pTabList and all indices used by those tables. */ for(i=0; i<pTabList->nSrc; i++) { Table *pTab; pTab = pTabList->a[i].pTab; if( pTab->isTransient || pTab->pSelect ) continue; sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0); sqliteVdbeAddOp(v, OP_OpenRead, pTabList->a[i].iCursor, pTab->tnum); sqliteVdbeChangeP3(v, -1, pTab->zName, P3_STATIC); sqliteCodeVerifySchema(pParse, pTab->iDb); if( pWInfo->a[i].pIdx!=0 ) { sqliteVdbeAddOp(v, OP_Integer, pWInfo->a[i].pIdx->iDb, 0); sqliteVdbeAddOp(v, OP_OpenRead, pWInfo->a[i].iCur, pWInfo->a[i].pIdx->tnum); sqliteVdbeChangeP3(v, -1, pWInfo->a[i].pIdx->zName, P3_STATIC); } } /* Generate the code to do the search */ loopMask = 0; for(i=0; i<pTabList->nSrc; i++) { int j, k; int iCur = pTabList->a[i].iCursor; Index *pIdx; WhereLevel *pLevel = &pWInfo->a[i]; /* If this is the right table of a LEFT OUTER JOIN, allocate and ** initialize a memory cell that records if this table matches any ** row of the left table of the join. */ if( i>0 && (pTabList->a[i-1].jointype & JT_LEFT)!=0 ) { if( !pParse->nMem ) pParse->nMem++; pLevel->iLeftJoin = pParse->nMem++; sqliteVdbeAddOp(v, OP_String, 0, 0); sqliteVdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1); } pIdx = pLevel->pIdx; pLevel->inOp = OP_Noop; if( i<ARRAYSIZE(iDirectEq) && iDirectEq[i]>=0 ) { /* Case 1: We can directly reference a single row using an ** equality comparison against the ROWID field. Or ** we reference multiple rows using a "rowid IN (...)" ** construct. */ k = iDirectEq[i]; assert( k<nExpr ); assert( aExpr[k].p!=0 ); assert( aExpr[k].idxLeft==iCur || aExpr[k].idxRight==iCur ); brk = pLevel->brk = sqliteVdbeMakeLabel(v); if( aExpr[k].idxLeft==iCur ) { Expr *pX = aExpr[k].p; if( pX->op!=TK_IN ) { sqliteExprCode(pParse, aExpr[k].p->pRight); } else if( pX->pList ) { sqliteVdbeAddOp(v, OP_SetFirst, pX->iTable, brk); pLevel->inOp = OP_SetNext; pLevel->inP1 = pX->iTable; pLevel->inP2 = sqliteVdbeCurrentAddr(v); } else { assert( pX->pSelect ); sqliteVdbeAddOp(v, OP_Rewind, pX->iTable, brk); sqliteVdbeAddOp(v, OP_KeyAsData, pX->iTable, 1); pLevel->inP2 = sqliteVdbeAddOp(v, OP_FullKey, pX->iTable, 0); pLevel->inOp = OP_Next; pLevel->inP1 = pX->iTable; } } else { sqliteExprCode(pParse, aExpr[k].p->pLeft); } aExpr[k].p = 0; cont = pLevel->cont = sqliteVdbeMakeLabel(v); sqliteVdbeAddOp(v, OP_MustBeInt, 1, brk); haveKey = 0; sqliteVdbeAddOp(v, OP_NotExists, iCur, brk); pLevel->op = OP_Noop; } else if( pIdx!=0 && pLevel->score>0 && pLevel->score%4==0 ) { /* Case 2: There is an index and all terms of the WHERE clause that ** refer to the index use the "==" or "IN" operators. */ int start; int testOp; int nColumn = (pLevel->score+4)/8; brk = pLevel->brk = sqliteVdbeMakeLabel(v); for(j=0; j<nColumn; j++) { for(k=0; k<nExpr; k++) { Expr *pX = aExpr[k].p; if( pX==0 ) continue; if( aExpr[k].idxLeft==iCur && (aExpr[k].prereqRight & loopMask)==aExpr[k].prereqRight && pX->pLeft->iColumn==pIdx->aiColumn[j] ) { if( pX->op==TK_EQ ) { sqliteExprCode(pParse, pX->pRight); aExpr[k].p = 0; break; } if( pX->op==TK_IN && nColumn==1 ) { if( pX->pList ) { sqliteVdbeAddOp(v, OP_SetFirst, pX->iTable, brk); pLevel->inOp = OP_SetNext; pLevel->inP1 = pX->iTable; pLevel->inP2 = sqliteVdbeCurrentAddr(v); } else { assert( pX->pSelect ); sqliteVdbeAddOp(v, OP_Rewind, pX->iTable, brk); sqliteVdbeAddOp(v, OP_KeyAsData, pX->iTable, 1); pLevel->inP2 = sqliteVdbeAddOp(v, OP_FullKey, pX->iTable, 0); pLevel->inOp = OP_Next; pLevel->inP1 = pX->iTable; } aExpr[k].p = 0; break; } } if( aExpr[k].idxRight==iCur && aExpr[k].p->op==TK_EQ && (aExpr[k].prereqLeft & loopMask)==aExpr[k].prereqLeft && aExpr[k].p->pRight->iColumn==pIdx->aiColumn[j] ) { sqliteExprCode(pParse, aExpr[k].p->pLeft); aExpr[k].p = 0; break; } } } pLevel->iMem = pParse->nMem++; cont = pLevel->cont = sqliteVdbeMakeLabel(v); sqliteVdbeAddOp(v, OP_NotNull, -nColumn, sqliteVdbeCurrentAddr(v)+3); sqliteVdbeAddOp(v, OP_Pop, nColumn, 0); sqliteVdbeAddOp(v, OP_Goto, 0, brk); sqliteVdbeAddOp(v, OP_MakeKey, nColumn, 0); sqliteAddIdxKeyType(v, pIdx); if( nColumn==pIdx->nColumn || pLevel->bRev ) { sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 0); testOp = OP_IdxGT; } else { sqliteVdbeAddOp(v, OP_Dup, 0, 0); sqliteVdbeAddOp(v, OP_IncrKey, 0, 0); sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 1); testOp = OP_IdxGE; } if( pLevel->bRev ) { /* Scan in reverse order */ sqliteVdbeAddOp(v, OP_IncrKey, 0, 0); sqliteVdbeAddOp(v, OP_MoveLt, pLevel->iCur, brk); start = sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0); sqliteVdbeAddOp(v, OP_IdxLT, pLevel->iCur, brk); pLevel->op = OP_Prev; } else { /* Scan in the forward order */ sqliteVdbeAddOp(v, OP_MoveTo, pLevel->iCur, brk); start = sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0); sqliteVdbeAddOp(v, testOp, pLevel->iCur, brk); pLevel->op = OP_Next; } sqliteVdbeAddOp(v, OP_RowKey, pLevel->iCur, 0); sqliteVdbeAddOp(v, OP_IdxIsNull, nColumn, cont); sqliteVdbeAddOp(v, OP_IdxRecno, pLevel->iCur, 0); if( i==pTabList->nSrc-1 && pushKey ) { haveKey = 1; } else { sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0); haveKey = 0; } pLevel->p1 = pLevel->iCur; pLevel->p2 = start; } else if( i<ARRAYSIZE(iDirectLt) && (iDirectLt[i]>=0 || iDirectGt[i]>=0) ) { /* Case 3: We have an inequality comparison against the ROWID field. */ int testOp = OP_Noop; int start; brk = pLevel->brk = sqliteVdbeMakeLabel(v); cont = pLevel->cont = sqliteVdbeMakeLabel(v); if( iDirectGt[i]>=0 ) { k = iDirectGt[i]; assert( k<nExpr ); assert( aExpr[k].p!=0 ); assert( aExpr[k].idxLeft==iCur || aExpr[k].idxRight==iCur ); if( aExpr[k].idxLeft==iCur ) { sqliteExprCode(pParse, aExpr[k].p->pRight); } else { sqliteExprCode(pParse, aExpr[k].p->pLeft); } sqliteVdbeAddOp(v, OP_ForceInt, aExpr[k].p->op==TK_LT || aExpr[k].p->op==TK_GT, brk); sqliteVdbeAddOp(v, OP_MoveTo, iCur, brk); aExpr[k].p = 0; } else { sqliteVdbeAddOp(v, OP_Rewind, iCur, brk); } if( iDirectLt[i]>=0 ) { k = iDirectLt[i]; assert( k<nExpr ); assert( aExpr[k].p!=0 ); assert( aExpr[k].idxLeft==iCur || aExpr[k].idxRight==iCur ); if( aExpr[k].idxLeft==iCur ) { sqliteExprCode(pParse, aExpr[k].p->pRight); } else { sqliteExprCode(pParse, aExpr[k].p->pLeft); } /* sqliteVdbeAddOp(v, OP_MustBeInt, 0, sqliteVdbeCurrentAddr(v)+1); */ pLevel->iMem = pParse->nMem++; sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 1); if( aExpr[k].p->op==TK_LT || aExpr[k].p->op==TK_GT ) { testOp = OP_Ge; } else { testOp = OP_Gt; } aExpr[k].p = 0; } start = sqliteVdbeCurrentAddr(v); pLevel->op = OP_Next; pLevel->p1 = iCur; pLevel->p2 = start; if( testOp!=OP_Noop ) { sqliteVdbeAddOp(v, OP_Recno, iCur, 0); sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0); sqliteVdbeAddOp(v, testOp, 0, brk); } haveKey = 0; } else if( pIdx==0 ) { /* Case 4: There is no usable index. We must do a complete ** scan of the entire database table. */ int start; brk = pLevel->brk = sqliteVdbeMakeLabel(v); cont = pLevel->cont = sqliteVdbeMakeLabel(v); sqliteVdbeAddOp(v, OP_Rewind, iCur, brk); start = sqliteVdbeCurrentAddr(v); pLevel->op = OP_Next; pLevel->p1 = iCur; pLevel->p2 = start; haveKey = 0; } else { /* Case 5: The WHERE clause term that refers to the right-most ** column of the index is an inequality. For example, if ** the index is on (x,y,z) and the WHERE clause is of the ** form "x=5 AND y<10" then this case is used. Only the ** right-most column can be an inequality - the rest must ** use the "==" operator. ** ** This case is also used when there are no WHERE clause ** constraints but an index is selected anyway, in order ** to force the output order to conform to an ORDER BY. */ int score = pLevel->score; int nEqColumn = score/8; int start; int leFlag, geFlag; int testOp; /* Evaluate the equality constraints */ for(j=0; j<nEqColumn; j++) { for(k=0; k<nExpr; k++) { if( aExpr[k].p==0 ) continue; if( aExpr[k].idxLeft==iCur && aExpr[k].p->op==TK_EQ && (aExpr[k].prereqRight & loopMask)==aExpr[k].prereqRight && aExpr[k].p->pLeft->iColumn==pIdx->aiColumn[j] ) { sqliteExprCode(pParse, aExpr[k].p->pRight); aExpr[k].p = 0; break; } if( aExpr[k].idxRight==iCur && aExpr[k].p->op==TK_EQ && (aExpr[k].prereqLeft & loopMask)==aExpr[k].prereqLeft && aExpr[k].p->pRight->iColumn==pIdx->aiColumn[j] ) { sqliteExprCode(pParse, aExpr[k].p->pLeft); aExpr[k].p = 0; break; } } } /* Duplicate the equality term values because they will all be ** used twice: once to make the termination key and once to make the ** start key. */ for(j=0; j<nEqColumn; j++) { sqliteVdbeAddOp(v, OP_Dup, nEqColumn-1, 0); } /* Labels for the beginning and end of the loop */ cont = pLevel->cont = sqliteVdbeMakeLabel(v); brk = pLevel->brk = sqliteVdbeMakeLabel(v); /* Generate the termination key. This is the key value that ** will end the search. There is no termination key if there ** are no equality terms and no "X<..." term. ** ** 2002-Dec-04: On a reverse-order scan, the so-called "termination" ** key computed here really ends up being the start key. */ if( (score & 1)!=0 ) { for(k=0; k<nExpr; k++) { Expr *pExpr = aExpr[k].p; if( pExpr==0 ) continue; if( aExpr[k].idxLeft==iCur && (pExpr->op==TK_LT || pExpr->op==TK_LE) && (aExpr[k].prereqRight & loopMask)==aExpr[k].prereqRight && pExpr->pLeft->iColumn==pIdx->aiColumn[j] ) { sqliteExprCode(pParse, pExpr->pRight); leFlag = pExpr->op==TK_LE; aExpr[k].p = 0; break; } if( aExpr[k].idxRight==iCur && (pExpr->op==TK_GT || pExpr->op==TK_GE) && (aExpr[k].prereqLeft & loopMask)==aExpr[k].prereqLeft && pExpr->pRight->iColumn==pIdx->aiColumn[j] ) { sqliteExprCode(pParse, pExpr->pLeft); leFlag = pExpr->op==TK_GE; aExpr[k].p = 0; break; } } testOp = OP_IdxGE; } else { testOp = nEqColumn>0 ? OP_IdxGE : OP_Noop; leFlag = 1; } if( testOp!=OP_Noop ) { int nCol = nEqColumn + (score & 1); pLevel->iMem = pParse->nMem++; sqliteVdbeAddOp(v, OP_NotNull, -nCol, sqliteVdbeCurrentAddr(v)+3); sqliteVdbeAddOp(v, OP_Pop, nCol, 0); sqliteVdbeAddOp(v, OP_Goto, 0, brk); sqliteVdbeAddOp(v, OP_MakeKey, nCol, 0); sqliteAddIdxKeyType(v, pIdx); if( leFlag ) { sqliteVdbeAddOp(v, OP_IncrKey, 0, 0); } if( pLevel->bRev ) { sqliteVdbeAddOp(v, OP_MoveLt, pLevel->iCur, brk); } else { sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 1); } } else if( pLevel->bRev ) { sqliteVdbeAddOp(v, OP_Last, pLevel->iCur, brk); } /* Generate the start key. This is the key that defines the lower ** bound on the search. There is no start key if there are no ** equality terms and if there is no "X>..." term. In ** that case, generate a "Rewind" instruction in place of the ** start key search. ** ** 2002-Dec-04: In the case of a reverse-order search, the so-called ** "start" key really ends up being used as the termination key. */ if( (score & 2)!=0 ) { for(k=0; k<nExpr; k++) { Expr *pExpr = aExpr[k].p; if( pExpr==0 ) continue; if( aExpr[k].idxLeft==iCur && (pExpr->op==TK_GT || pExpr->op==TK_GE) && (aExpr[k].prereqRight & loopMask)==aExpr[k].prereqRight && pExpr->pLeft->iColumn==pIdx->aiColumn[j] ) { sqliteExprCode(pParse, pExpr->pRight); geFlag = pExpr->op==TK_GE; aExpr[k].p = 0; break; } if( aExpr[k].idxRight==iCur && (pExpr->op==TK_LT || pExpr->op==TK_LE) && (aExpr[k].prereqLeft & loopMask)==aExpr[k].prereqLeft && pExpr->pRight->iColumn==pIdx->aiColumn[j] ) { sqliteExprCode(pParse, pExpr->pLeft); geFlag = pExpr->op==TK_LE; aExpr[k].p = 0; break; } } } else { geFlag = 1; } if( nEqColumn>0 || (score&2)!=0 ) { int nCol = nEqColumn + ((score&2)!=0); sqliteVdbeAddOp(v, OP_NotNull, -nCol, sqliteVdbeCurrentAddr(v)+3); sqliteVdbeAddOp(v, OP_Pop, nCol, 0); sqliteVdbeAddOp(v, OP_Goto, 0, brk); sqliteVdbeAddOp(v, OP_MakeKey, nCol, 0); sqliteAddIdxKeyType(v, pIdx); if( !geFlag ) { sqliteVdbeAddOp(v, OP_IncrKey, 0, 0); } if( pLevel->bRev ) { pLevel->iMem = pParse->nMem++; sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 1); testOp = OP_IdxLT; } else { sqliteVdbeAddOp(v, OP_MoveTo, pLevel->iCur, brk); } } else if( pLevel->bRev ) { testOp = OP_Noop; } else { sqliteVdbeAddOp(v, OP_Rewind, pLevel->iCur, brk); } /* Generate the the top of the loop. If there is a termination ** key we have to test for that key and abort at the top of the ** loop. */ start = sqliteVdbeCurrentAddr(v); if( testOp!=OP_Noop ) { sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0); sqliteVdbeAddOp(v, testOp, pLevel->iCur, brk); } sqliteVdbeAddOp(v, OP_RowKey, pLevel->iCur, 0); sqliteVdbeAddOp(v, OP_IdxIsNull, nEqColumn + (score & 1), cont); sqliteVdbeAddOp(v, OP_IdxRecno, pLevel->iCur, 0); if( i==pTabList->nSrc-1 && pushKey ) { haveKey = 1; } else { sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0); haveKey = 0; } /* Record the instruction used to terminate the loop. */ pLevel->op = pLevel->bRev ? OP_Prev : OP_Next; pLevel->p1 = pLevel->iCur; pLevel->p2 = start; } loopMask |= getMask(&maskSet, iCur); /* Insert code to test every subexpression that can be completely ** computed using the current set of tables. */ for(j=0; j<nExpr; j++) { if( aExpr[j].p==0 ) continue; if( (aExpr[j].prereqAll & loopMask)!=aExpr[j].prereqAll ) continue; if( pLevel->iLeftJoin && !ExprHasProperty(aExpr[j].p,EP_FromJoin) ) { continue; } if( haveKey ) { haveKey = 0; sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0); } sqliteExprIfFalse(pParse, aExpr[j].p, cont, 1); aExpr[j].p = 0; } brk = cont; /* For a LEFT OUTER JOIN, generate code that will record the fact that ** at least one row of the right table has matched the left table. */ if( pLevel->iLeftJoin ) { pLevel->top = sqliteVdbeCurrentAddr(v); sqliteVdbeAddOp(v, OP_Integer, 1, 0); sqliteVdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1); for(j=0; j<nExpr; j++) { if( aExpr[j].p==0 ) continue; if( (aExpr[j].prereqAll & loopMask)!=aExpr[j].prereqAll ) continue; if( haveKey ) { /* Cannot happen. "haveKey" can only be true if pushKey is true ** an pushKey can only be true for DELETE and UPDATE and there are ** no outer joins with DELETE and UPDATE. */ haveKey = 0; sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0); } sqliteExprIfFalse(pParse, aExpr[j].p, cont, 1); aExpr[j].p = 0; } } } pWInfo->iContinue = cont; if( pushKey && !haveKey ) { sqliteVdbeAddOp(v, OP_Recno, pTabList->a[0].iCursor, 0); } freeMaskSet(&maskSet); return pWInfo; }
/* ** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up ** that name in the set of source tables in pSrcList and make the pExpr ** expression node refer back to that source column. The following changes ** are made to pExpr: ** ** pExpr->iDb Set the index in db->aDb[] of the database holding ** the table. ** pExpr->iTable Set to the cursor number for the table obtained ** from pSrcList. ** pExpr->iColumn Set to the column number within the table. ** pExpr->dataType Set to the appropriate data type for the column. ** pExpr->op Set to TK_COLUMN. ** pExpr->pLeft Any expression this points to is deleted ** pExpr->pRight Any expression this points to is deleted. ** ** The pDbToken is the name of the database (the "X"). This value may be ** NULL meaning that name is of the form Y.Z or Z. Any available database ** can be used. The pTableToken is the name of the table (the "Y"). This ** value can be NULL if pDbToken is also NULL. If pTableToken is NULL it ** means that the form of the name is Z and that columns from any table ** can be used. ** ** If the name cannot be resolved unambiguously, leave an error message ** in pParse and return non-zero. Return zero on success. */ static int lookupName( Parse *pParse, /* The parsing context */ Token *pDbToken, /* Name of the database containing table, or NULL */ Token *pTableToken, /* Name of table containing column, or NULL */ Token *pColumnToken, /* Name of the column. */ SrcList *pSrcList, /* List of tables used to resolve column names */ ExprList *pEList, /* List of expressions used to resolve "AS" */ Expr *pExpr /* Make this EXPR node point to the selected column */ ){ char *zDb = 0; /* Name of the database. The "X" in X.Y.Z */ char *zTab = 0; /* Name of the table. The "Y" in X.Y.Z or Y.Z */ char *zCol = 0; /* Name of the column. The "Z" */ int i, j; /* Loop counters */ int cnt = 0; /* Number of matching column names */ int cntTab = 0; /* Number of matching table names */ sqlite *db = pParse->db; /* The database */ assert( pColumnToken && pColumnToken->z ); /* The Z in X.Y.Z cannot be NULL */ if( pDbToken && pDbToken->z ){ zDb = sqliteStrNDup(pDbToken->z, pDbToken->n); sqliteDequote(zDb); }else{ zDb = 0; } if( pTableToken && pTableToken->z ){ zTab = sqliteStrNDup(pTableToken->z, pTableToken->n); sqliteDequote(zTab); }else{ assert( zDb==0 ); zTab = 0; } zCol = sqliteStrNDup(pColumnToken->z, pColumnToken->n); sqliteDequote(zCol); if( sqlite_malloc_failed ){ return 1; /* Leak memory (zDb and zTab) if malloc fails */ } assert( zTab==0 || pEList==0 ); pExpr->iTable = -1; for(i=0; i<pSrcList->nSrc; i++){ struct SrcList_item *pItem = &pSrcList->a[i]; Table *pTab = pItem->pTab; Column *pCol; if( pTab==0 ) continue; assert( pTab->nCol>0 ); if( zTab ){ if( pItem->zAlias ){ char *zTabName = pItem->zAlias; if( sqliteStrICmp(zTabName, zTab)!=0 ) continue; }else{ char *zTabName = pTab->zName; if( zTabName==0 || sqliteStrICmp(zTabName, zTab)!=0 ) continue; if( zDb!=0 && sqliteStrICmp(db->aDb[pTab->iDb].zName, zDb)!=0 ){ continue; } } } if( 0==(cntTab++) ){ pExpr->iTable = pItem->iCursor; pExpr->iDb = pTab->iDb; } for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){ if( sqliteStrICmp(pCol->zName, zCol)==0 ){ cnt++; pExpr->iTable = pItem->iCursor; pExpr->iDb = pTab->iDb; /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ pExpr->iColumn = j==pTab->iPKey ? -1 : j; pExpr->dataType = pCol->sortOrder & SQLITE_SO_TYPEMASK; break; } } } /* If we have not already resolved the name, then maybe ** it is a new.* or old.* trigger argument reference */ if( zDb==0 && zTab!=0 && cnt==0 && pParse->trigStack!=0 ){ TriggerStack *pTriggerStack = pParse->trigStack; Table *pTab = 0; if( pTriggerStack->newIdx != -1 && sqliteStrICmp("new", zTab) == 0 ){ pExpr->iTable = pTriggerStack->newIdx; assert( pTriggerStack->pTab ); pTab = pTriggerStack->pTab; }else if( pTriggerStack->oldIdx != -1 && sqliteStrICmp("old", zTab) == 0 ){ pExpr->iTable = pTriggerStack->oldIdx; assert( pTriggerStack->pTab ); pTab = pTriggerStack->pTab; } if( pTab ){ int j; Column *pCol = pTab->aCol; pExpr->iDb = pTab->iDb; cntTab++; for(j=0; j < pTab->nCol; j++, pCol++) { if( sqliteStrICmp(pCol->zName, zCol)==0 ){ cnt++; pExpr->iColumn = j==pTab->iPKey ? -1 : j; pExpr->dataType = pCol->sortOrder & SQLITE_SO_TYPEMASK; break; } } } } /* ** Perhaps the name is a reference to the ROWID */ if( cnt==0 && cntTab==1 && sqliteIsRowid(zCol) ){ cnt = 1; pExpr->iColumn = -1; pExpr->dataType = SQLITE_SO_NUM; } /* ** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z ** might refer to an result-set alias. This happens, for example, when ** we are resolving names in the WHERE clause of the following command: ** ** SELECT a+b AS x FROM table WHERE x<10; ** ** In cases like this, replace pExpr with a copy of the expression that ** forms the result set entry ("a+b" in the example) and return immediately. ** Note that the expression in the result set should have already been ** resolved by the time the WHERE clause is resolved. */ if( cnt==0 && pEList!=0 ){ for(j=0; j<pEList->nExpr; j++){ char *zAs = pEList->a[j].zName; if( zAs!=0 && sqliteStrICmp(zAs, zCol)==0 ){ assert( pExpr->pLeft==0 && pExpr->pRight==0 ); pExpr->op = TK_AS; pExpr->iColumn = j; pExpr->pLeft = sqliteExprDup(pEList->a[j].pExpr); sqliteFree(zCol); assert( zTab==0 && zDb==0 ); return 0; } } } /* ** If X and Y are NULL (in other words if only the column name Z is ** supplied) and the value of Z is enclosed in double-quotes, then ** Z is a string literal if it doesn't match any column names. In that ** case, we need to return right away and not make any changes to ** pExpr. */ if( cnt==0 && zTab==0 && pColumnToken->z[0]=='"' ){ sqliteFree(zCol); return 0; } /* ** cnt==0 means there was not match. cnt>1 means there were two or ** more matches. Either way, we have an error. */ if( cnt!=1 ){ char *z = 0; char *zErr; zErr = cnt==0 ? "no such column: %s" : "ambiguous column name: %s"; if( zDb ){ sqliteSetString(&z, zDb, ".", zTab, ".", zCol, 0); }else if( zTab ){ sqliteSetString(&z, zTab, ".", zCol, 0); }else{ z = sqliteStrDup(zCol); } sqliteErrorMsg(pParse, zErr, z); sqliteFree(z); } /* Clean up and return */ sqliteFree(zDb); sqliteFree(zTab); sqliteFree(zCol); sqliteExprDelete(pExpr->pLeft); pExpr->pLeft = 0; sqliteExprDelete(pExpr->pRight); pExpr->pRight = 0; pExpr->op = TK_COLUMN; sqliteAuthRead(pParse, pExpr, pSrcList); return cnt!=1; }