Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Unified Diff: third_party/sqlite/amalgamation/sqlite3.05.c

Issue 2755803002: NCI: trybot test for sqlite 3.17 import. (Closed)
Patch Set: also clang on Linux i386 Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/sqlite/amalgamation/sqlite3.04.c ('k') | third_party/sqlite/amalgamation/sqlite3.06.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/sqlite/amalgamation/sqlite3.05.c
diff --git a/third_party/sqlite/amalgamation/sqlite3.05.c b/third_party/sqlite/amalgamation/sqlite3.05.c
new file mode 100644
index 0000000000000000000000000000000000000000..7c65d7e29a337032792cfde70d0b3ae12f90a55a
--- /dev/null
+++ b/third_party/sqlite/amalgamation/sqlite3.05.c
@@ -0,0 +1,21684 @@
+/************** Begin file callback.c ****************************************/
+/*
+** 2005 May 23
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+**
+** This file contains functions used to access the internal hash tables
+** of user defined functions and collation sequences.
+*/
+
+/* #include "sqliteInt.h" */
+
+/*
+** Invoke the 'collation needed' callback to request a collation sequence
+** in the encoding enc of name zName, length nName.
+*/
+static void callCollNeeded(sqlite3 *db, int enc, const char *zName){
+ assert( !db->xCollNeeded || !db->xCollNeeded16 );
+ if( db->xCollNeeded ){
+ char *zExternal = sqlite3DbStrDup(db, zName);
+ if( !zExternal ) return;
+ db->xCollNeeded(db->pCollNeededArg, db, enc, zExternal);
+ sqlite3DbFree(db, zExternal);
+ }
+#ifndef SQLITE_OMIT_UTF16
+ if( db->xCollNeeded16 ){
+ char const *zExternal;
+ sqlite3_value *pTmp = sqlite3ValueNew(db);
+ sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC);
+ zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE);
+ if( zExternal ){
+ db->xCollNeeded16(db->pCollNeededArg, db, (int)ENC(db), zExternal);
+ }
+ sqlite3ValueFree(pTmp);
+ }
+#endif
+}
+
+/*
+** This routine is called if the collation factory fails to deliver a
+** collation function in the best encoding but there may be other versions
+** of this collation function (for other text encodings) available. Use one
+** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if
+** possible.
+*/
+static int synthCollSeq(sqlite3 *db, CollSeq *pColl){
+ CollSeq *pColl2;
+ char *z = pColl->zName;
+ int i;
+ static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 };
+ for(i=0; i<3; i++){
+ pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, 0);
+ if( pColl2->xCmp!=0 ){
+ memcpy(pColl, pColl2, sizeof(CollSeq));
+ pColl->xDel = 0; /* Do not copy the destructor */
+ return SQLITE_OK;
+ }
+ }
+ return SQLITE_ERROR;
+}
+
+/*
+** This function is responsible for invoking the collation factory callback
+** or substituting a collation sequence of a different encoding when the
+** requested collation sequence is not available in the desired encoding.
+**
+** If it is not NULL, then pColl must point to the database native encoding
+** collation sequence with name zName, length nName.
+**
+** The return value is either the collation sequence to be used in database
+** db for collation type name zName, length nName, or NULL, if no collation
+** sequence can be found. If no collation is found, leave an error message.
+**
+** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq()
+*/
+SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(
+ Parse *pParse, /* Parsing context */
+ u8 enc, /* The desired encoding for the collating sequence */
+ CollSeq *pColl, /* Collating sequence with native encoding, or NULL */
+ const char *zName /* Collating sequence name */
+){
+ CollSeq *p;
+ sqlite3 *db = pParse->db;
+
+ p = pColl;
+ if( !p ){
+ p = sqlite3FindCollSeq(db, enc, zName, 0);
+ }
+ if( !p || !p->xCmp ){
+ /* No collation sequence of this type for this encoding is registered.
+ ** Call the collation factory to see if it can supply us with one.
+ */
+ callCollNeeded(db, enc, zName);
+ p = sqlite3FindCollSeq(db, enc, zName, 0);
+ }
+ if( p && !p->xCmp && synthCollSeq(db, p) ){
+ p = 0;
+ }
+ assert( !p || p->xCmp );
+ if( p==0 ){
+ sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
+ }
+ return p;
+}
+
+/*
+** This routine is called on a collation sequence before it is used to
+** check that it is defined. An undefined collation sequence exists when
+** a database is loaded that contains references to collation sequences
+** that have not been defined by sqlite3_create_collation() etc.
+**
+** If required, this routine calls the 'collation needed' callback to
+** request a definition of the collating sequence. If this doesn't work,
+** an equivalent collating sequence that uses a text encoding different
+** from the main database is substituted, if one is available.
+*/
+SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
+ if( pColl ){
+ const char *zName = pColl->zName;
+ sqlite3 *db = pParse->db;
+ CollSeq *p = sqlite3GetCollSeq(pParse, ENC(db), pColl, zName);
+ if( !p ){
+ return SQLITE_ERROR;
+ }
+ assert( p==pColl );
+ }
+ return SQLITE_OK;
+}
+
+
+
+/*
+** Locate and return an entry from the db.aCollSeq hash table. If the entry
+** specified by zName and nName is not found and parameter 'create' is
+** true, then create a new entry. Otherwise return NULL.
+**
+** Each pointer stored in the sqlite3.aCollSeq hash table contains an
+** array of three CollSeq structures. The first is the collation sequence
+** preferred for UTF-8, the second UTF-16le, and the third UTF-16be.
+**
+** Stored immediately after the three collation sequences is a copy of
+** the collation sequence name. A pointer to this string is stored in
+** each collation sequence structure.
+*/
+static CollSeq *findCollSeqEntry(
+ sqlite3 *db, /* Database connection */
+ const char *zName, /* Name of the collating sequence */
+ int create /* Create a new entry if true */
+){
+ CollSeq *pColl;
+ pColl = sqlite3HashFind(&db->aCollSeq, zName);
+
+ if( 0==pColl && create ){
+ int nName = sqlite3Strlen30(zName);
+ pColl = sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName + 1);
+ if( pColl ){
+ CollSeq *pDel = 0;
+ pColl[0].zName = (char*)&pColl[3];
+ pColl[0].enc = SQLITE_UTF8;
+ pColl[1].zName = (char*)&pColl[3];
+ pColl[1].enc = SQLITE_UTF16LE;
+ pColl[2].zName = (char*)&pColl[3];
+ pColl[2].enc = SQLITE_UTF16BE;
+ memcpy(pColl[0].zName, zName, nName);
+ pColl[0].zName[nName] = 0;
+ pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, pColl);
+
+ /* If a malloc() failure occurred in sqlite3HashInsert(), it will
+ ** return the pColl pointer to be deleted (because it wasn't added
+ ** to the hash table).
+ */
+ assert( pDel==0 || pDel==pColl );
+ if( pDel!=0 ){
+ sqlite3OomFault(db);
+ sqlite3DbFree(db, pDel);
+ pColl = 0;
+ }
+ }
+ }
+ return pColl;
+}
+
+/*
+** Parameter zName points to a UTF-8 encoded string nName bytes long.
+** Return the CollSeq* pointer for the collation sequence named zName
+** for the encoding 'enc' from the database 'db'.
+**
+** If the entry specified is not found and 'create' is true, then create a
+** new entry. Otherwise return NULL.
+**
+** A separate function sqlite3LocateCollSeq() is a wrapper around
+** this routine. sqlite3LocateCollSeq() invokes the collation factory
+** if necessary and generates an error message if the collating sequence
+** cannot be found.
+**
+** See also: sqlite3LocateCollSeq(), sqlite3GetCollSeq()
+*/
+SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(
+ sqlite3 *db,
+ u8 enc,
+ const char *zName,
+ int create
+){
+ CollSeq *pColl;
+ if( zName ){
+ pColl = findCollSeqEntry(db, zName, create);
+ }else{
+ pColl = db->pDfltColl;
+ }
+ assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
+ assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE );
+ if( pColl ) pColl += enc-1;
+ return pColl;
+}
+
+/* During the search for the best function definition, this procedure
+** is called to test how well the function passed as the first argument
+** matches the request for a function with nArg arguments in a system
+** that uses encoding enc. The value returned indicates how well the
+** request is matched. A higher value indicates a better match.
+**
+** If nArg is -1 that means to only return a match (non-zero) if p->nArg
+** is also -1. In other words, we are searching for a function that
+** takes a variable number of arguments.
+**
+** If nArg is -2 that means that we are searching for any function
+** regardless of the number of arguments it uses, so return a positive
+** match score for any
+**
+** The returned value is always between 0 and 6, as follows:
+**
+** 0: Not a match.
+** 1: UTF8/16 conversion required and function takes any number of arguments.
+** 2: UTF16 byte order change required and function takes any number of args.
+** 3: encoding matches and function takes any number of arguments
+** 4: UTF8/16 conversion required - argument count matches exactly
+** 5: UTF16 byte order conversion required - argument count matches exactly
+** 6: Perfect match: encoding and argument count match exactly.
+**
+** If nArg==(-2) then any function with a non-null xSFunc is
+** a perfect match and any function with xSFunc NULL is
+** a non-match.
+*/
+#define FUNC_PERFECT_MATCH 6 /* The score for a perfect match */
+static int matchQuality(
+ FuncDef *p, /* The function we are evaluating for match quality */
+ int nArg, /* Desired number of arguments. (-1)==any */
+ u8 enc /* Desired text encoding */
+){
+ int match;
+
+ /* nArg of -2 is a special case */
+ if( nArg==(-2) ) return (p->xSFunc==0) ? 0 : FUNC_PERFECT_MATCH;
+
+ /* Wrong number of arguments means "no match" */
+ if( p->nArg!=nArg && p->nArg>=0 ) return 0;
+
+ /* Give a better score to a function with a specific number of arguments
+ ** than to function that accepts any number of arguments. */
+ if( p->nArg==nArg ){
+ match = 4;
+ }else{
+ match = 1;
+ }
+
+ /* Bonus points if the text encoding matches */
+ if( enc==(p->funcFlags & SQLITE_FUNC_ENCMASK) ){
+ match += 2; /* Exact encoding match */
+ }else if( (enc & p->funcFlags & 2)!=0 ){
+ match += 1; /* Both are UTF16, but with different byte orders */
+ }
+
+ return match;
+}
+
+/*
+** Search a FuncDefHash for a function with the given name. Return
+** a pointer to the matching FuncDef if found, or 0 if there is no match.
+*/
+static FuncDef *functionSearch(
+ int h, /* Hash of the name */
+ const char *zFunc /* Name of function */
+){
+ FuncDef *p;
+ for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){
+ if( sqlite3StrICmp(p->zName, zFunc)==0 ){
+ return p;
+ }
+ }
+ return 0;
+}
+
+/*
+** Insert a new FuncDef into a FuncDefHash hash table.
+*/
+SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(
+ FuncDef *aDef, /* List of global functions to be inserted */
+ int nDef /* Length of the apDef[] list */
+){
+ int i;
+ for(i=0; i<nDef; i++){
+ FuncDef *pOther;
+ const char *zName = aDef[i].zName;
+ int nName = sqlite3Strlen30(zName);
+ int h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % SQLITE_FUNC_HASH_SZ;
+ pOther = functionSearch(h, zName);
+ if( pOther ){
+ assert( pOther!=&aDef[i] && pOther->pNext!=&aDef[i] );
+ aDef[i].pNext = pOther->pNext;
+ pOther->pNext = &aDef[i];
+ }else{
+ aDef[i].pNext = 0;
+ aDef[i].u.pHash = sqlite3BuiltinFunctions.a[h];
+ sqlite3BuiltinFunctions.a[h] = &aDef[i];
+ }
+ }
+}
+
+
+
+/*
+** Locate a user function given a name, a number of arguments and a flag
+** indicating whether the function prefers UTF-16 over UTF-8. Return a
+** pointer to the FuncDef structure that defines that function, or return
+** NULL if the function does not exist.
+**
+** If the createFlag argument is true, then a new (blank) FuncDef
+** structure is created and liked into the "db" structure if a
+** no matching function previously existed.
+**
+** If nArg is -2, then the first valid function found is returned. A
+** function is valid if xSFunc is non-zero. The nArg==(-2)
+** case is used to see if zName is a valid function name for some number
+** of arguments. If nArg is -2, then createFlag must be 0.
+**
+** If createFlag is false, then a function with the required name and
+** number of arguments may be returned even if the eTextRep flag does not
+** match that requested.
+*/
+SQLITE_PRIVATE FuncDef *sqlite3FindFunction(
+ sqlite3 *db, /* An open database */
+ const char *zName, /* Name of the function. zero-terminated */
+ int nArg, /* Number of arguments. -1 means any number */
+ u8 enc, /* Preferred text encoding */
+ u8 createFlag /* Create new entry if true and does not otherwise exist */
+){
+ FuncDef *p; /* Iterator variable */
+ FuncDef *pBest = 0; /* Best match found so far */
+ int bestScore = 0; /* Score of best match */
+ int h; /* Hash value */
+ int nName; /* Length of the name */
+
+ assert( nArg>=(-2) );
+ assert( nArg>=(-1) || createFlag==0 );
+ nName = sqlite3Strlen30(zName);
+
+ /* First search for a match amongst the application-defined functions.
+ */
+ p = (FuncDef*)sqlite3HashFind(&db->aFunc, zName);
+ while( p ){
+ int score = matchQuality(p, nArg, enc);
+ if( score>bestScore ){
+ pBest = p;
+ bestScore = score;
+ }
+ p = p->pNext;
+ }
+
+ /* If no match is found, search the built-in functions.
+ **
+ ** If the SQLITE_PreferBuiltin flag is set, then search the built-in
+ ** functions even if a prior app-defined function was found. And give
+ ** priority to built-in functions.
+ **
+ ** Except, if createFlag is true, that means that we are trying to
+ ** install a new function. Whatever FuncDef structure is returned it will
+ ** have fields overwritten with new information appropriate for the
+ ** new function. But the FuncDefs for built-in functions are read-only.
+ ** So we must not search for built-ins when creating a new function.
+ */
+ if( !createFlag && (pBest==0 || (db->flags & SQLITE_PreferBuiltin)!=0) ){
+ bestScore = 0;
+ h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % SQLITE_FUNC_HASH_SZ;
+ p = functionSearch(h, zName);
+ while( p ){
+ int score = matchQuality(p, nArg, enc);
+ if( score>bestScore ){
+ pBest = p;
+ bestScore = score;
+ }
+ p = p->pNext;
+ }
+ }
+
+ /* If the createFlag parameter is true and the search did not reveal an
+ ** exact match for the name, number of arguments and encoding, then add a
+ ** new entry to the hash table and return it.
+ */
+ if( createFlag && bestScore<FUNC_PERFECT_MATCH &&
+ (pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){
+ FuncDef *pOther;
+ pBest->zName = (const char*)&pBest[1];
+ pBest->nArg = (u16)nArg;
+ pBest->funcFlags = enc;
+ memcpy((char*)&pBest[1], zName, nName+1);
+ pOther = (FuncDef*)sqlite3HashInsert(&db->aFunc, pBest->zName, pBest);
+ if( pOther==pBest ){
+ sqlite3DbFree(db, pBest);
+ sqlite3OomFault(db);
+ return 0;
+ }else{
+ pBest->pNext = pOther;
+ }
+ }
+
+ if( pBest && (pBest->xSFunc || createFlag) ){
+ return pBest;
+ }
+ return 0;
+}
+
+/*
+** Free all resources held by the schema structure. The void* argument points
+** at a Schema struct. This function does not call sqlite3DbFree(db, ) on the
+** pointer itself, it just cleans up subsidiary resources (i.e. the contents
+** of the schema hash tables).
+**
+** The Schema.cache_size variable is not cleared.
+*/
+SQLITE_PRIVATE void sqlite3SchemaClear(void *p){
+ Hash temp1;
+ Hash temp2;
+ HashElem *pElem;
+ Schema *pSchema = (Schema *)p;
+
+ temp1 = pSchema->tblHash;
+ temp2 = pSchema->trigHash;
+ sqlite3HashInit(&pSchema->trigHash);
+ sqlite3HashClear(&pSchema->idxHash);
+ for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
+ sqlite3DeleteTrigger(0, (Trigger*)sqliteHashData(pElem));
+ }
+ sqlite3HashClear(&temp2);
+ sqlite3HashInit(&pSchema->tblHash);
+ for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
+ Table *pTab = sqliteHashData(pElem);
+ sqlite3DeleteTable(0, pTab);
+ }
+ sqlite3HashClear(&temp1);
+ sqlite3HashClear(&pSchema->fkeyHash);
+ pSchema->pSeqTab = 0;
+ if( pSchema->schemaFlags & DB_SchemaLoaded ){
+ pSchema->iGeneration++;
+ pSchema->schemaFlags &= ~DB_SchemaLoaded;
+ }
+}
+
+/*
+** Find and return the schema associated with a BTree. Create
+** a new one if necessary.
+*/
+SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){
+ Schema * p;
+ if( pBt ){
+ p = (Schema *)sqlite3BtreeSchema(pBt, sizeof(Schema), sqlite3SchemaClear);
+ }else{
+ p = (Schema *)sqlite3DbMallocZero(0, sizeof(Schema));
+ }
+ if( !p ){
+ sqlite3OomFault(db);
+ }else if ( 0==p->file_format ){
+ sqlite3HashInit(&p->tblHash);
+ sqlite3HashInit(&p->idxHash);
+ sqlite3HashInit(&p->trigHash);
+ sqlite3HashInit(&p->fkeyHash);
+ p->enc = SQLITE_UTF8;
+ }
+ return p;
+}
+
+/************** End of callback.c ********************************************/
+/************** Begin file delete.c ******************************************/
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains C code routines that are called by the parser
+** in order to generate code for DELETE FROM statements.
+*/
+/* #include "sqliteInt.h" */
+
+/*
+** While a SrcList can in general represent multiple tables and subqueries
+** (as in the FROM clause of a SELECT statement) in this case it contains
+** the name of a single table, as one might find in an INSERT, DELETE,
+** or UPDATE statement. Look up that table in the symbol table and
+** return a pointer. Set an error message and return NULL if the table
+** name is not found or if any other error occurs.
+**
+** The following fields are initialized appropriate in pSrc:
+**
+** pSrc->a[0].pTab Pointer to the Table object
+** pSrc->a[0].pIndex Pointer to the INDEXED BY index, if there is one
+**
+*/
+SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
+ struct SrcList_item *pItem = pSrc->a;
+ Table *pTab;
+ assert( pItem && pSrc->nSrc==1 );
+ pTab = sqlite3LocateTableItem(pParse, 0, pItem);
+ sqlite3DeleteTable(pParse->db, pItem->pTab);
+ pItem->pTab = pTab;
+ if( pTab ){
+ pTab->nTabRef++;
+ }
+ if( sqlite3IndexedByLookup(pParse, pItem) ){
+ pTab = 0;
+ }
+ return pTab;
+}
+
+/*
+** Check to make sure the given table is writable. If it is not
+** writable, generate an error message and return 1. If it is
+** writable return 0;
+*/
+SQLITE_PRIVATE int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){
+ /* A table is not writable under the following circumstances:
+ **
+ ** 1) It is a virtual table and no implementation of the xUpdate method
+ ** has been provided, or
+ ** 2) It is a system table (i.e. sqlite_master), this call is not
+ ** part of a nested parse and writable_schema pragma has not
+ ** been specified.
+ **
+ ** In either case leave an error message in pParse and return non-zero.
+ */
+ if( ( IsVirtual(pTab)
+ && sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 )
+ || ( (pTab->tabFlags & TF_Readonly)!=0
+ && (pParse->db->flags & SQLITE_WriteSchema)==0
+ && pParse->nested==0 )
+ ){
+ sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
+ return 1;
+ }
+
+#ifndef SQLITE_OMIT_VIEW
+ if( !viewOk && pTab->pSelect ){
+ sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
+ return 1;
+ }
+#endif
+ return 0;
+}
+
+
+#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
+/*
+** Evaluate a view and store its result in an ephemeral table. The
+** pWhere argument is an optional WHERE clause that restricts the
+** set of rows in the view that are to be added to the ephemeral table.
+*/
+SQLITE_PRIVATE void sqlite3MaterializeView(
+ Parse *pParse, /* Parsing context */
+ Table *pView, /* View definition */
+ Expr *pWhere, /* Optional WHERE clause to be added */
+ int iCur /* Cursor number for ephemeral table */
+){
+ SelectDest dest;
+ Select *pSel;
+ SrcList *pFrom;
+ sqlite3 *db = pParse->db;
+ int iDb = sqlite3SchemaToIndex(db, pView->pSchema);
+ pWhere = sqlite3ExprDup(db, pWhere, 0);
+ pFrom = sqlite3SrcListAppend(db, 0, 0, 0);
+ if( pFrom ){
+ assert( pFrom->nSrc==1 );
+ pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName);
+ pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName);
+ assert( pFrom->a[0].pOn==0 );
+ assert( pFrom->a[0].pUsing==0 );
+ }
+ pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0,
+ SF_IncludeHidden, 0, 0);
+ sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
+ sqlite3Select(pParse, pSel, &dest);
+ sqlite3SelectDelete(db, pSel);
+}
+#endif /* !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) */
+
+#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
+/*
+** Generate an expression tree to implement the WHERE, ORDER BY,
+** and LIMIT/OFFSET portion of DELETE and UPDATE statements.
+**
+** DELETE FROM table_wxyz WHERE a<5 ORDER BY a LIMIT 1;
+** \__________________________/
+** pLimitWhere (pInClause)
+*/
+SQLITE_PRIVATE Expr *sqlite3LimitWhere(
+ Parse *pParse, /* The parser context */
+ SrcList *pSrc, /* the FROM clause -- which tables to scan */
+ Expr *pWhere, /* The WHERE clause. May be null */
+ ExprList *pOrderBy, /* The ORDER BY clause. May be null */
+ Expr *pLimit, /* The LIMIT clause. May be null */
+ Expr *pOffset, /* The OFFSET clause. May be null */
+ char *zStmtType /* Either DELETE or UPDATE. For err msgs. */
+){
+ Expr *pWhereRowid = NULL; /* WHERE rowid .. */
+ Expr *pInClause = NULL; /* WHERE rowid IN ( select ) */
+ Expr *pSelectRowid = NULL; /* SELECT rowid ... */
+ ExprList *pEList = NULL; /* Expression list contaning only pSelectRowid */
+ SrcList *pSelectSrc = NULL; /* SELECT rowid FROM x ... (dup of pSrc) */
+ Select *pSelect = NULL; /* Complete SELECT tree */
+
+ /* Check that there isn't an ORDER BY without a LIMIT clause.
+ */
+ if( pOrderBy && (pLimit == 0) ) {
+ sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType);
+ goto limit_where_cleanup;
+ }
+
+ /* We only need to generate a select expression if there
+ ** is a limit/offset term to enforce.
+ */
+ if( pLimit == 0 ) {
+ /* if pLimit is null, pOffset will always be null as well. */
+ assert( pOffset == 0 );
+ return pWhere;
+ }
+
+ /* Generate a select expression tree to enforce the limit/offset
+ ** term for the DELETE or UPDATE statement. For example:
+ ** DELETE FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1
+ ** becomes:
+ ** DELETE FROM table_a WHERE rowid IN (
+ ** SELECT rowid FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1
+ ** );
+ */
+
+ pSelectRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0);
+ if( pSelectRowid == 0 ) goto limit_where_cleanup;
+ pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid);
+ if( pEList == 0 ) goto limit_where_cleanup;
+
+ /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree
+ ** and the SELECT subtree. */
+ pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0);
+ if( pSelectSrc == 0 ) {
+ sqlite3ExprListDelete(pParse->db, pEList);
+ goto limit_where_cleanup;
+ }
+
+ /* generate the SELECT expression tree. */
+ pSelect = sqlite3SelectNew(pParse,pEList,pSelectSrc,pWhere,0,0,
+ pOrderBy,0,pLimit,pOffset);
+ if( pSelect == 0 ) return 0;
+
+ /* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */
+ pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0);
+ pInClause = pWhereRowid ? sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0) : 0;
+ sqlite3PExprAddSelect(pParse, pInClause, pSelect);
+ return pInClause;
+
+limit_where_cleanup:
+ sqlite3ExprDelete(pParse->db, pWhere);
+ sqlite3ExprListDelete(pParse->db, pOrderBy);
+ sqlite3ExprDelete(pParse->db, pLimit);
+ sqlite3ExprDelete(pParse->db, pOffset);
+ return 0;
+}
+#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) */
+ /* && !defined(SQLITE_OMIT_SUBQUERY) */
+
+/*
+** Generate code for a DELETE FROM statement.
+**
+** DELETE FROM table_wxyz WHERE a<5 AND b NOT NULL;
+** \________/ \________________/
+** pTabList pWhere
+*/
+SQLITE_PRIVATE void sqlite3DeleteFrom(
+ Parse *pParse, /* The parser context */
+ SrcList *pTabList, /* The table from which we should delete things */
+ Expr *pWhere /* The WHERE clause. May be null */
+){
+ Vdbe *v; /* The virtual database engine */
+ Table *pTab; /* The table from which records will be deleted */
+ int i; /* Loop counter */
+ WhereInfo *pWInfo; /* Information about the WHERE clause */
+ Index *pIdx; /* For looping over indices of the table */
+ int iTabCur; /* Cursor number for the table */
+ int iDataCur = 0; /* VDBE cursor for the canonical data source */
+ int iIdxCur = 0; /* Cursor number of the first index */
+ int nIdx; /* Number of indices */
+ sqlite3 *db; /* Main database structure */
+ AuthContext sContext; /* Authorization context */
+ NameContext sNC; /* Name context to resolve expressions in */
+ int iDb; /* Database number */
+ int memCnt = -1; /* Memory cell used for change counting */
+ int rcauth; /* Value returned by authorization callback */
+ int eOnePass; /* ONEPASS_OFF or _SINGLE or _MULTI */
+ int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */
+ u8 *aToOpen = 0; /* Open cursor iTabCur+j if aToOpen[j] is true */
+ Index *pPk; /* The PRIMARY KEY index on the table */
+ int iPk = 0; /* First of nPk registers holding PRIMARY KEY value */
+ i16 nPk = 1; /* Number of columns in the PRIMARY KEY */
+ int iKey; /* Memory cell holding key of row to be deleted */
+ i16 nKey; /* Number of memory cells in the row key */
+ int iEphCur = 0; /* Ephemeral table holding all primary key values */
+ int iRowSet = 0; /* Register for rowset of rows to delete */
+ int addrBypass = 0; /* Address of jump over the delete logic */
+ int addrLoop = 0; /* Top of the delete loop */
+ int addrEphOpen = 0; /* Instruction to open the Ephemeral table */
+ int bComplex; /* True if there are triggers or FKs or
+ ** subqueries in the WHERE clause */
+
+#ifndef SQLITE_OMIT_TRIGGER
+ int isView; /* True if attempting to delete from a view */
+ Trigger *pTrigger; /* List of table triggers, if required */
+#endif
+
+ memset(&sContext, 0, sizeof(sContext));
+ db = pParse->db;
+ if( pParse->nErr || db->mallocFailed ){
+ goto delete_from_cleanup;
+ }
+ assert( pTabList->nSrc==1 );
+
+ /* Locate the table which we want to delete. This table has to be
+ ** put in an SrcList structure because some of the subroutines we
+ ** will be calling are designed to work with multiple tables and expect
+ ** an SrcList* parameter instead of just a Table* parameter.
+ */
+ pTab = sqlite3SrcListLookup(pParse, pTabList);
+ if( pTab==0 ) goto delete_from_cleanup;
+
+ /* Figure out if we have any triggers and if the table being
+ ** deleted from is a view
+ */
+#ifndef SQLITE_OMIT_TRIGGER
+ pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
+ isView = pTab->pSelect!=0;
+ bComplex = pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0);
+#else
+# define pTrigger 0
+# define isView 0
+#endif
+#ifdef SQLITE_OMIT_VIEW
+# undef isView
+# define isView 0
+#endif
+
+ /* If pTab is really a view, make sure it has been initialized.
+ */
+ if( sqlite3ViewGetColumnNames(pParse, pTab) ){
+ goto delete_from_cleanup;
+ }
+
+ if( sqlite3IsReadOnly(pParse, pTab, (pTrigger?1:0)) ){
+ goto delete_from_cleanup;
+ }
+ iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+ assert( iDb<db->nDb );
+ rcauth = sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0,
+ db->aDb[iDb].zDbSName);
+ assert( rcauth==SQLITE_OK || rcauth==SQLITE_DENY || rcauth==SQLITE_IGNORE );
+ if( rcauth==SQLITE_DENY ){
+ goto delete_from_cleanup;
+ }
+ assert(!isView || pTrigger);
+
+ /* Assign cursor numbers to the table and all its indices.
+ */
+ assert( pTabList->nSrc==1 );
+ iTabCur = pTabList->a[0].iCursor = pParse->nTab++;
+ for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){
+ pParse->nTab++;
+ }
+
+ /* Start the view context
+ */
+ if( isView ){
+ sqlite3AuthContextPush(pParse, &sContext, pTab->zName);
+ }
+
+ /* Begin generating code.
+ */
+ v = sqlite3GetVdbe(pParse);
+ if( v==0 ){
+ goto delete_from_cleanup;
+ }
+ if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
+ sqlite3BeginWriteOperation(pParse, 1, iDb);
+
+ /* If we are trying to delete from a view, realize that view into
+ ** an ephemeral table.
+ */
+#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
+ if( isView ){
+ sqlite3MaterializeView(pParse, pTab, pWhere, iTabCur);
+ iDataCur = iIdxCur = iTabCur;
+ }
+#endif
+
+ /* Resolve the column names in the WHERE clause.
+ */
+ memset(&sNC, 0, sizeof(sNC));
+ sNC.pParse = pParse;
+ sNC.pSrcList = pTabList;
+ if( sqlite3ResolveExprNames(&sNC, pWhere) ){
+ goto delete_from_cleanup;
+ }
+
+ /* Initialize the counter of the number of rows deleted, if
+ ** we are counting rows.
+ */
+ if( db->flags & SQLITE_CountRows ){
+ memCnt = ++pParse->nMem;
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt);
+ }
+
+#ifndef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
+ /* Special case: A DELETE without a WHERE clause deletes everything.
+ ** It is easier just to erase the whole table. Prior to version 3.6.5,
+ ** this optimization caused the row change count (the value returned by
+ ** API function sqlite3_count_changes) to be set incorrectly. */
+ if( rcauth==SQLITE_OK
+ && pWhere==0
+ && !bComplex
+ && !IsVirtual(pTab)
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ && db->xPreUpdateCallback==0
+#endif
+ ){
+ assert( !isView );
+ sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName);
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt,
+ pTab->zName, P4_STATIC);
+ }
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ assert( pIdx->pSchema==pTab->pSchema );
+ sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb);
+ }
+ }else
+#endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */
+ {
+ u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK|WHERE_SEEK_TABLE;
+ if( sNC.ncFlags & NC_VarSelect ) bComplex = 1;
+ wcf |= (bComplex ? 0 : WHERE_ONEPASS_MULTIROW);
+ if( HasRowid(pTab) ){
+ /* For a rowid table, initialize the RowSet to an empty set */
+ pPk = 0;
+ nPk = 1;
+ iRowSet = ++pParse->nMem;
+ sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet);
+ }else{
+ /* For a WITHOUT ROWID table, create an ephemeral table used to
+ ** hold all primary keys for rows to be deleted. */
+ pPk = sqlite3PrimaryKeyIndex(pTab);
+ assert( pPk!=0 );
+ nPk = pPk->nKeyCol;
+ iPk = pParse->nMem+1;
+ pParse->nMem += nPk;
+ iEphCur = pParse->nTab++;
+ addrEphOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEphCur, nPk);
+ sqlite3VdbeSetP4KeyInfo(pParse, pPk);
+ }
+
+ /* Construct a query to find the rowid or primary key for every row
+ ** to be deleted, based on the WHERE clause. Set variable eOnePass
+ ** to indicate the strategy used to implement this delete:
+ **
+ ** ONEPASS_OFF: Two-pass approach - use a FIFO for rowids/PK values.
+ ** ONEPASS_SINGLE: One-pass approach - at most one row deleted.
+ ** ONEPASS_MULTI: One-pass approach - any number of rows may be deleted.
+ */
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, wcf, iTabCur+1);
+ if( pWInfo==0 ) goto delete_from_cleanup;
+ eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
+ assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI );
+ assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF );
+
+ /* Keep track of the number of rows to be deleted */
+ if( db->flags & SQLITE_CountRows ){
+ sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1);
+ }
+
+ /* Extract the rowid or primary key for the current row */
+ if( pPk ){
+ for(i=0; i<nPk; i++){
+ assert( pPk->aiColumn[i]>=0 );
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur,
+ pPk->aiColumn[i], iPk+i);
+ }
+ iKey = iPk;
+ }else{
+ iKey = pParse->nMem + 1;
+ iKey = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iTabCur, iKey, 0);
+ if( iKey>pParse->nMem ) pParse->nMem = iKey;
+ }
+
+ if( eOnePass!=ONEPASS_OFF ){
+ /* For ONEPASS, no need to store the rowid/primary-key. There is only
+ ** one, so just keep it in its register(s) and fall through to the
+ ** delete code. */
+ nKey = nPk; /* OP_Found will use an unpacked key */
+ aToOpen = sqlite3DbMallocRawNN(db, nIdx+2);
+ if( aToOpen==0 ){
+ sqlite3WhereEnd(pWInfo);
+ goto delete_from_cleanup;
+ }
+ memset(aToOpen, 1, nIdx+1);
+ aToOpen[nIdx+1] = 0;
+ if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iTabCur] = 0;
+ if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iTabCur] = 0;
+ if( addrEphOpen ) sqlite3VdbeChangeToNoop(v, addrEphOpen);
+ }else{
+ if( pPk ){
+ /* Add the PK key for this row to the temporary table */
+ iKey = ++pParse->nMem;
+ nKey = 0; /* Zero tells OP_Found to use a composite key */
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey,
+ sqlite3IndexAffinityStr(pParse->db, pPk), nPk);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iEphCur, iKey, iPk, nPk);
+ }else{
+ /* Add the rowid of the row to be deleted to the RowSet */
+ nKey = 1; /* OP_Seek always uses a single rowid */
+ sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey);
+ }
+ }
+
+ /* If this DELETE cannot use the ONEPASS strategy, this is the
+ ** end of the WHERE loop */
+ if( eOnePass!=ONEPASS_OFF ){
+ addrBypass = sqlite3VdbeMakeLabel(v);
+ }else{
+ sqlite3WhereEnd(pWInfo);
+ }
+
+ /* Unless this is a view, open cursors for the table we are
+ ** deleting from and all its indices. If this is a view, then the
+ ** only effect this statement has is to fire the INSTEAD OF
+ ** triggers.
+ */
+ if( !isView ){
+ int iAddrOnce = 0;
+ if( eOnePass==ONEPASS_MULTI ){
+ iAddrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+ }
+ testcase( IsVirtual(pTab) );
+ sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, OPFLAG_FORDELETE,
+ iTabCur, aToOpen, &iDataCur, &iIdxCur);
+ assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur );
+ assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 );
+ if( eOnePass==ONEPASS_MULTI ) sqlite3VdbeJumpHere(v, iAddrOnce);
+ }
+
+ /* Set up a loop over the rowids/primary-keys that were found in the
+ ** where-clause loop above.
+ */
+ if( eOnePass!=ONEPASS_OFF ){
+ assert( nKey==nPk ); /* OP_Found will use an unpacked key */
+ if( !IsVirtual(pTab) && aToOpen[iDataCur-iTabCur] ){
+ assert( pPk!=0 || pTab->pSelect!=0 );
+ sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);
+ VdbeCoverage(v);
+ }
+ }else if( pPk ){
+ addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_RowData, iEphCur, iKey);
+ assert( nKey==0 ); /* OP_Found will use a composite key */
+ }else{
+ addrLoop = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, 0, iKey);
+ VdbeCoverage(v);
+ assert( nKey==1 );
+ }
+
+ /* Delete the row */
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ if( IsVirtual(pTab) ){
+ const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
+ sqlite3VtabMakeWritable(pParse, pTab);
+ sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB);
+ sqlite3VdbeChangeP5(v, OE_Abort);
+ assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE );
+ sqlite3MayAbort(pParse);
+ if( eOnePass==ONEPASS_SINGLE && sqlite3IsToplevel(pParse) ){
+ pParse->isMultiWrite = 0;
+ }
+ }else
+#endif
+ {
+ int count = (pParse->nested==0); /* True to count changes */
+ sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
+ iKey, nKey, count, OE_Default, eOnePass, aiCurOnePass[1]);
+ }
+
+ /* End of the loop over all rowids/primary-keys. */
+ if( eOnePass!=ONEPASS_OFF ){
+ sqlite3VdbeResolveLabel(v, addrBypass);
+ sqlite3WhereEnd(pWInfo);
+ }else if( pPk ){
+ sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); VdbeCoverage(v);
+ sqlite3VdbeJumpHere(v, addrLoop);
+ }else{
+ sqlite3VdbeGoto(v, addrLoop);
+ sqlite3VdbeJumpHere(v, addrLoop);
+ }
+ } /* End non-truncate path */
+
+ /* Update the sqlite_sequence table by storing the content of the
+ ** maximum rowid counter values recorded while inserting into
+ ** autoincrement tables.
+ */
+ if( pParse->nested==0 && pParse->pTriggerTab==0 ){
+ sqlite3AutoincrementEnd(pParse);
+ }
+
+ /* Return the number of rows that were deleted. If this routine is
+ ** generating code because of a call to sqlite3NestedParse(), do not
+ ** invoke the callback function.
+ */
+ if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){
+ sqlite3VdbeAddOp2(v, OP_ResultRow, memCnt, 1);
+ sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC);
+ }
+
+delete_from_cleanup:
+ sqlite3AuthContextPop(&sContext);
+ sqlite3SrcListDelete(db, pTabList);
+ sqlite3ExprDelete(db, pWhere);
+ sqlite3DbFree(db, aToOpen);
+ return;
+}
+/* Make sure "isView" and other macros defined above are undefined. Otherwise
+** they may interfere with compilation of other functions in this file
+** (or in another file, if this file becomes part of the amalgamation). */
+#ifdef isView
+ #undef isView
+#endif
+#ifdef pTrigger
+ #undef pTrigger
+#endif
+
+/*
+** This routine generates VDBE code that causes a single row of a
+** single table to be deleted. Both the original table entry and
+** all indices are removed.
+**
+** Preconditions:
+**
+** 1. iDataCur is an open cursor on the btree that is the canonical data
+** store for the table. (This will be either the table itself,
+** in the case of a rowid table, or the PRIMARY KEY index in the case
+** of a WITHOUT ROWID table.)
+**
+** 2. Read/write cursors for all indices of pTab must be open as
+** cursor number iIdxCur+i for the i-th index.
+**
+** 3. The primary key for the row to be deleted must be stored in a
+** sequence of nPk memory cells starting at iPk. If nPk==0 that means
+** that a search record formed from OP_MakeRecord is contained in the
+** single memory location iPk.
+**
+** eMode:
+** Parameter eMode may be passed either ONEPASS_OFF (0), ONEPASS_SINGLE, or
+** ONEPASS_MULTI. If eMode is not ONEPASS_OFF, then the cursor
+** iDataCur already points to the row to delete. If eMode is ONEPASS_OFF
+** then this function must seek iDataCur to the entry identified by iPk
+** and nPk before reading from it.
+**
+** If eMode is ONEPASS_MULTI, then this call is being made as part
+** of a ONEPASS delete that affects multiple rows. In this case, if
+** iIdxNoSeek is a valid cursor number (>=0) and is not the same as
+** iDataCur, then its position should be preserved following the delete
+** operation. Or, if iIdxNoSeek is not a valid cursor number, the
+** position of iDataCur should be preserved instead.
+**
+** iIdxNoSeek:
+** If iIdxNoSeek is a valid cursor number (>=0) not equal to iDataCur,
+** then it identifies an index cursor (from within array of cursors
+** starting at iIdxCur) that already points to the index entry to be deleted.
+** Except, this optimization is disabled if there are BEFORE triggers since
+** the trigger body might have moved the cursor.
+*/
+SQLITE_PRIVATE void sqlite3GenerateRowDelete(
+ Parse *pParse, /* Parsing context */
+ Table *pTab, /* Table containing the row to be deleted */
+ Trigger *pTrigger, /* List of triggers to (potentially) fire */
+ int iDataCur, /* Cursor from which column data is extracted */
+ int iIdxCur, /* First index cursor */
+ int iPk, /* First memory cell containing the PRIMARY KEY */
+ i16 nPk, /* Number of PRIMARY KEY memory cells */
+ u8 count, /* If non-zero, increment the row change counter */
+ u8 onconf, /* Default ON CONFLICT policy for triggers */
+ u8 eMode, /* ONEPASS_OFF, _SINGLE, or _MULTI. See above */
+ int iIdxNoSeek /* Cursor number of cursor that does not need seeking */
+){
+ Vdbe *v = pParse->pVdbe; /* Vdbe */
+ int iOld = 0; /* First register in OLD.* array */
+ int iLabel; /* Label resolved to end of generated code */
+ u8 opSeek; /* Seek opcode */
+
+ /* Vdbe is guaranteed to have been allocated by this stage. */
+ assert( v );
+ VdbeModuleComment((v, "BEGIN: GenRowDel(%d,%d,%d,%d)",
+ iDataCur, iIdxCur, iPk, (int)nPk));
+
+ /* Seek cursor iCur to the row to delete. If this row no longer exists
+ ** (this can happen if a trigger program has already deleted it), do
+ ** not attempt to delete it or fire any DELETE triggers. */
+ iLabel = sqlite3VdbeMakeLabel(v);
+ opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
+ if( eMode==ONEPASS_OFF ){
+ sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
+ VdbeCoverageIf(v, opSeek==OP_NotExists);
+ VdbeCoverageIf(v, opSeek==OP_NotFound);
+ }
+
+ /* If there are any triggers to fire, allocate a range of registers to
+ ** use for the old.* references in the triggers. */
+ if( sqlite3FkRequired(pParse, pTab, 0, 0) || pTrigger ){
+ u32 mask; /* Mask of OLD.* columns in use */
+ int iCol; /* Iterator used while populating OLD.* */
+ int addrStart; /* Start of BEFORE trigger programs */
+
+ /* TODO: Could use temporary registers here. Also could attempt to
+ ** avoid copying the contents of the rowid register. */
+ mask = sqlite3TriggerColmask(
+ pParse, pTrigger, 0, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onconf
+ );
+ mask |= sqlite3FkOldmask(pParse, pTab);
+ iOld = pParse->nMem+1;
+ pParse->nMem += (1 + pTab->nCol);
+
+ /* Populate the OLD.* pseudo-table register array. These values will be
+ ** used by any BEFORE and AFTER triggers that exist. */
+ sqlite3VdbeAddOp2(v, OP_Copy, iPk, iOld);
+ for(iCol=0; iCol<pTab->nCol; iCol++){
+ testcase( mask!=0xffffffff && iCol==31 );
+ testcase( mask!=0xffffffff && iCol==32 );
+ if( mask==0xffffffff || (iCol<=31 && (mask & MASKBIT32(iCol))!=0) ){
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, iCol, iOld+iCol+1);
+ }
+ }
+
+ /* Invoke BEFORE DELETE trigger programs. */
+ addrStart = sqlite3VdbeCurrentAddr(v);
+ sqlite3CodeRowTrigger(pParse, pTrigger,
+ TK_DELETE, 0, TRIGGER_BEFORE, pTab, iOld, onconf, iLabel
+ );
+
+ /* If any BEFORE triggers were coded, then seek the cursor to the
+ ** row to be deleted again. It may be that the BEFORE triggers moved
+ ** the cursor or already deleted the row that the cursor was
+ ** pointing to.
+ **
+ ** Also disable the iIdxNoSeek optimization since the BEFORE trigger
+ ** may have moved that cursor.
+ */
+ if( addrStart<sqlite3VdbeCurrentAddr(v) ){
+ sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
+ VdbeCoverageIf(v, opSeek==OP_NotExists);
+ VdbeCoverageIf(v, opSeek==OP_NotFound);
+ testcase( iIdxNoSeek>=0 );
+ iIdxNoSeek = -1;
+ }
+
+ /* Do FK processing. This call checks that any FK constraints that
+ ** refer to this table (i.e. constraints attached to other tables)
+ ** are not violated by deleting this row. */
+ sqlite3FkCheck(pParse, pTab, iOld, 0, 0, 0);
+ }
+
+ /* Delete the index and table entries. Skip this step if pTab is really
+ ** a view (in which case the only effect of the DELETE statement is to
+ ** fire the INSTEAD OF triggers).
+ **
+ ** If variable 'count' is non-zero, then this OP_Delete instruction should
+ ** invoke the update-hook. The pre-update-hook, on the other hand should
+ ** be invoked unless table pTab is a system table. The difference is that
+ ** the update-hook is not invoked for rows removed by REPLACE, but the
+ ** pre-update-hook is.
+ */
+ if( pTab->pSelect==0 ){
+ u8 p5 = 0;
+ sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek);
+ sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0));
+ if( pParse->nested==0 ){
+ sqlite3VdbeAppendP4(v, (char*)pTab, P4_TABLE);
+ }
+ if( eMode!=ONEPASS_OFF ){
+ sqlite3VdbeChangeP5(v, OPFLAG_AUXDELETE);
+ }
+ if( iIdxNoSeek>=0 && iIdxNoSeek!=iDataCur ){
+ sqlite3VdbeAddOp1(v, OP_Delete, iIdxNoSeek);
+ }
+ if( eMode==ONEPASS_MULTI ) p5 |= OPFLAG_SAVEPOSITION;
+ sqlite3VdbeChangeP5(v, p5);
+ }
+
+ /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to
+ ** handle rows (possibly in other tables) that refer via a foreign key
+ ** to the row just deleted. */
+ sqlite3FkActions(pParse, pTab, 0, iOld, 0, 0);
+
+ /* Invoke AFTER DELETE trigger programs. */
+ sqlite3CodeRowTrigger(pParse, pTrigger,
+ TK_DELETE, 0, TRIGGER_AFTER, pTab, iOld, onconf, iLabel
+ );
+
+ /* Jump here if the row had already been deleted before any BEFORE
+ ** trigger programs were invoked. Or if a trigger program throws a
+ ** RAISE(IGNORE) exception. */
+ sqlite3VdbeResolveLabel(v, iLabel);
+ VdbeModuleComment((v, "END: GenRowDel()"));
+}
+
+/*
+** This routine generates VDBE code that causes the deletion of all
+** index entries associated with a single row of a single table, pTab
+**
+** Preconditions:
+**
+** 1. A read/write cursor "iDataCur" must be open on the canonical storage
+** btree for the table pTab. (This will be either the table itself
+** for rowid tables or to the primary key index for WITHOUT ROWID
+** tables.)
+**
+** 2. Read/write cursors for all indices of pTab must be open as
+** cursor number iIdxCur+i for the i-th index. (The pTab->pIndex
+** index is the 0-th index.)
+**
+** 3. The "iDataCur" cursor must be already be positioned on the row
+** that is to be deleted.
+*/
+SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(
+ Parse *pParse, /* Parsing and code generating context */
+ Table *pTab, /* Table containing the row to be deleted */
+ int iDataCur, /* Cursor of table holding data. */
+ int iIdxCur, /* First index cursor */
+ int *aRegIdx, /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */
+ int iIdxNoSeek /* Do not delete from this cursor */
+){
+ int i; /* Index loop counter */
+ int r1 = -1; /* Register holding an index key */
+ int iPartIdxLabel; /* Jump destination for skipping partial index entries */
+ Index *pIdx; /* Current index */
+ Index *pPrior = 0; /* Prior index */
+ Vdbe *v; /* The prepared statement under construction */
+ Index *pPk; /* PRIMARY KEY index, or NULL for rowid tables */
+
+ v = pParse->pVdbe;
+ pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
+ for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
+ assert( iIdxCur+i!=iDataCur || pPk==pIdx );
+ if( aRegIdx!=0 && aRegIdx[i]==0 ) continue;
+ if( pIdx==pPk ) continue;
+ if( iIdxCur+i==iIdxNoSeek ) continue;
+ VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName));
+ r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1,
+ &iPartIdxLabel, pPrior, r1);
+ sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1,
+ pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn);
+ sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel);
+ pPrior = pIdx;
+ }
+}
+
+/*
+** Generate code that will assemble an index key and stores it in register
+** regOut. The key with be for index pIdx which is an index on pTab.
+** iCur is the index of a cursor open on the pTab table and pointing to
+** the entry that needs indexing. If pTab is a WITHOUT ROWID table, then
+** iCur must be the cursor of the PRIMARY KEY index.
+**
+** Return a register number which is the first in a block of
+** registers that holds the elements of the index key. The
+** block of registers has already been deallocated by the time
+** this routine returns.
+**
+** If *piPartIdxLabel is not NULL, fill it in with a label and jump
+** to that label if pIdx is a partial index that should be skipped.
+** The label should be resolved using sqlite3ResolvePartIdxLabel().
+** A partial index should be skipped if its WHERE clause evaluates
+** to false or null. If pIdx is not a partial index, *piPartIdxLabel
+** will be set to zero which is an empty label that is ignored by
+** sqlite3ResolvePartIdxLabel().
+**
+** The pPrior and regPrior parameters are used to implement a cache to
+** avoid unnecessary register loads. If pPrior is not NULL, then it is
+** a pointer to a different index for which an index key has just been
+** computed into register regPrior. If the current pIdx index is generating
+** its key into the same sequence of registers and if pPrior and pIdx share
+** a column in common, then the register corresponding to that column already
+** holds the correct value and the loading of that register is skipped.
+** This optimization is helpful when doing a DELETE or an INTEGRITY_CHECK
+** on a table with multiple indices, and especially with the ROWID or
+** PRIMARY KEY columns of the index.
+*/
+SQLITE_PRIVATE int sqlite3GenerateIndexKey(
+ Parse *pParse, /* Parsing context */
+ Index *pIdx, /* The index for which to generate a key */
+ int iDataCur, /* Cursor number from which to take column data */
+ int regOut, /* Put the new key into this register if not 0 */
+ int prefixOnly, /* Compute only a unique prefix of the key */
+ int *piPartIdxLabel, /* OUT: Jump to this label to skip partial index */
+ Index *pPrior, /* Previously generated index key */
+ int regPrior /* Register holding previous generated key */
+){
+ Vdbe *v = pParse->pVdbe;
+ int j;
+ int regBase;
+ int nCol;
+
+ if( piPartIdxLabel ){
+ if( pIdx->pPartIdxWhere ){
+ *piPartIdxLabel = sqlite3VdbeMakeLabel(v);
+ pParse->iSelfTab = iDataCur;
+ sqlite3ExprCachePush(pParse);
+ sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel,
+ SQLITE_JUMPIFNULL);
+ }else{
+ *piPartIdxLabel = 0;
+ }
+ }
+ nCol = (prefixOnly && pIdx->uniqNotNull) ? pIdx->nKeyCol : pIdx->nColumn;
+ regBase = sqlite3GetTempRange(pParse, nCol);
+ if( pPrior && (regBase!=regPrior || pPrior->pPartIdxWhere) ) pPrior = 0;
+ for(j=0; j<nCol; j++){
+ if( pPrior
+ && pPrior->aiColumn[j]==pIdx->aiColumn[j]
+ && pPrior->aiColumn[j]!=XN_EXPR
+ ){
+ /* This column was already computed by the previous index */
+ continue;
+ }
+ sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iDataCur, j, regBase+j);
+ /* If the column affinity is REAL but the number is an integer, then it
+ ** might be stored in the table as an integer (using a compact
+ ** representation) then converted to REAL by an OP_RealAffinity opcode.
+ ** But we are getting ready to store this value back into an index, where
+ ** it should be converted by to INTEGER again. So omit the OP_RealAffinity
+ ** opcode if it is present */
+ sqlite3VdbeDeletePriorOpcode(v, OP_RealAffinity);
+ }
+ if( regOut ){
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut);
+ if( pIdx->pTable->pSelect ){
+ const char *zAff = sqlite3IndexAffinityStr(pParse->db, pIdx);
+ sqlite3VdbeChangeP4(v, -1, zAff, P4_TRANSIENT);
+ }
+ }
+ sqlite3ReleaseTempRange(pParse, regBase, nCol);
+ return regBase;
+}
+
+/*
+** If a prior call to sqlite3GenerateIndexKey() generated a jump-over label
+** because it was a partial index, then this routine should be called to
+** resolve that label.
+*/
+SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){
+ if( iLabel ){
+ sqlite3VdbeResolveLabel(pParse->pVdbe, iLabel);
+ sqlite3ExprCachePop(pParse);
+ }
+}
+
+/************** End of delete.c **********************************************/
+/************** Begin file func.c ********************************************/
+/*
+** 2002 February 23
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains the C-language implementations for many of the SQL
+** functions of SQLite. (Some function, and in particular the date and
+** time functions, are implemented separately.)
+*/
+/* #include "sqliteInt.h" */
+/* #include <stdlib.h> */
+/* #include <assert.h> */
+/* #include "vdbeInt.h" */
+
+/*
+** Return the collating function associated with a function.
+*/
+static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){
+ VdbeOp *pOp;
+ assert( context->pVdbe!=0 );
+ pOp = &context->pVdbe->aOp[context->iOp-1];
+ assert( pOp->opcode==OP_CollSeq );
+ assert( pOp->p4type==P4_COLLSEQ );
+ return pOp->p4.pColl;
+}
+
+/*
+** Indicate that the accumulator load should be skipped on this
+** iteration of the aggregate loop.
+*/
+static void sqlite3SkipAccumulatorLoad(sqlite3_context *context){
+ context->skipFlag = 1;
+}
+
+/*
+** Implementation of the non-aggregate min() and max() functions
+*/
+static void minmaxFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ int i;
+ int mask; /* 0 for min() or 0xffffffff for max() */
+ int iBest;
+ CollSeq *pColl;
+
+ assert( argc>1 );
+ mask = sqlite3_user_data(context)==0 ? 0 : -1;
+ pColl = sqlite3GetFuncCollSeq(context);
+ assert( pColl );
+ assert( mask==-1 || mask==0 );
+ iBest = 0;
+ if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
+ for(i=1; i<argc; i++){
+ if( sqlite3_value_type(argv[i])==SQLITE_NULL ) return;
+ if( (sqlite3MemCompare(argv[iBest], argv[i], pColl)^mask)>=0 ){
+ testcase( mask==0 );
+ iBest = i;
+ }
+ }
+ sqlite3_result_value(context, argv[iBest]);
+}
+
+/*
+** Return the type of the argument.
+*/
+static void typeofFunc(
+ sqlite3_context *context,
+ int NotUsed,
+ sqlite3_value **argv
+){
+ const char *z = 0;
+ UNUSED_PARAMETER(NotUsed);
+ switch( sqlite3_value_type(argv[0]) ){
+ case SQLITE_INTEGER: z = "integer"; break;
+ case SQLITE_TEXT: z = "text"; break;
+ case SQLITE_FLOAT: z = "real"; break;
+ case SQLITE_BLOB: z = "blob"; break;
+ default: z = "null"; break;
+ }
+ sqlite3_result_text(context, z, -1, SQLITE_STATIC);
+}
+
+
+/*
+** Implementation of the length() function
+*/
+static void lengthFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ int len;
+
+ assert( argc==1 );
+ UNUSED_PARAMETER(argc);
+ switch( sqlite3_value_type(argv[0]) ){
+ case SQLITE_BLOB:
+ case SQLITE_INTEGER:
+ case SQLITE_FLOAT: {
+ sqlite3_result_int(context, sqlite3_value_bytes(argv[0]));
+ break;
+ }
+ case SQLITE_TEXT: {
+ const unsigned char *z = sqlite3_value_text(argv[0]);
+ if( z==0 ) return;
+ len = 0;
+ while( *z ){
+ len++;
+ SQLITE_SKIP_UTF8(z);
+ }
+ sqlite3_result_int(context, len);
+ break;
+ }
+ default: {
+ sqlite3_result_null(context);
+ break;
+ }
+ }
+}
+
+/*
+** Implementation of the abs() function.
+**
+** IMP: R-23979-26855 The abs(X) function returns the absolute value of
+** the numeric argument X.
+*/
+static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
+ assert( argc==1 );
+ UNUSED_PARAMETER(argc);
+ switch( sqlite3_value_type(argv[0]) ){
+ case SQLITE_INTEGER: {
+ i64 iVal = sqlite3_value_int64(argv[0]);
+ if( iVal<0 ){
+ if( iVal==SMALLEST_INT64 ){
+ /* IMP: R-31676-45509 If X is the integer -9223372036854775808
+ ** then abs(X) throws an integer overflow error since there is no
+ ** equivalent positive 64-bit two complement value. */
+ sqlite3_result_error(context, "integer overflow", -1);
+ return;
+ }
+ iVal = -iVal;
+ }
+ sqlite3_result_int64(context, iVal);
+ break;
+ }
+ case SQLITE_NULL: {
+ /* IMP: R-37434-19929 Abs(X) returns NULL if X is NULL. */
+ sqlite3_result_null(context);
+ break;
+ }
+ default: {
+ /* Because sqlite3_value_double() returns 0.0 if the argument is not
+ ** something that can be converted into a number, we have:
+ ** IMP: R-01992-00519 Abs(X) returns 0.0 if X is a string or blob
+ ** that cannot be converted to a numeric value.
+ */
+ double rVal = sqlite3_value_double(argv[0]);
+ if( rVal<0 ) rVal = -rVal;
+ sqlite3_result_double(context, rVal);
+ break;
+ }
+ }
+}
+
+/*
+** Implementation of the instr() function.
+**
+** instr(haystack,needle) finds the first occurrence of needle
+** in haystack and returns the number of previous characters plus 1,
+** or 0 if needle does not occur within haystack.
+**
+** If both haystack and needle are BLOBs, then the result is one more than
+** the number of bytes in haystack prior to the first occurrence of needle,
+** or 0 if needle never occurs in haystack.
+*/
+static void instrFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ const unsigned char *zHaystack;
+ const unsigned char *zNeedle;
+ int nHaystack;
+ int nNeedle;
+ int typeHaystack, typeNeedle;
+ int N = 1;
+ int isText;
+
+ UNUSED_PARAMETER(argc);
+ typeHaystack = sqlite3_value_type(argv[0]);
+ typeNeedle = sqlite3_value_type(argv[1]);
+ if( typeHaystack==SQLITE_NULL || typeNeedle==SQLITE_NULL ) return;
+ nHaystack = sqlite3_value_bytes(argv[0]);
+ nNeedle = sqlite3_value_bytes(argv[1]);
+ if( nNeedle>0 ){
+ if( typeHaystack==SQLITE_BLOB && typeNeedle==SQLITE_BLOB ){
+ zHaystack = sqlite3_value_blob(argv[0]);
+ zNeedle = sqlite3_value_blob(argv[1]);
+ assert( zNeedle!=0 );
+ assert( zHaystack!=0 || nHaystack==0 );
+ isText = 0;
+ }else{
+ zHaystack = sqlite3_value_text(argv[0]);
+ zNeedle = sqlite3_value_text(argv[1]);
+ isText = 1;
+ if( zHaystack==0 || zNeedle==0 ) return;
+ }
+ while( nNeedle<=nHaystack && memcmp(zHaystack, zNeedle, nNeedle)!=0 ){
+ N++;
+ do{
+ nHaystack--;
+ zHaystack++;
+ }while( isText && (zHaystack[0]&0xc0)==0x80 );
+ }
+ if( nNeedle>nHaystack ) N = 0;
+ }
+ sqlite3_result_int(context, N);
+}
+
+/*
+** Implementation of the printf() function.
+*/
+static void printfFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ PrintfArguments x;
+ StrAccum str;
+ const char *zFormat;
+ int n;
+ sqlite3 *db = sqlite3_context_db_handle(context);
+
+ if( argc>=1 && (zFormat = (const char*)sqlite3_value_text(argv[0]))!=0 ){
+ x.nArg = argc-1;
+ x.nUsed = 0;
+ x.apArg = argv+1;
+ sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
+ str.printfFlags = SQLITE_PRINTF_SQLFUNC;
+ sqlite3XPrintf(&str, zFormat, &x);
+ n = str.nChar;
+ sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n,
+ SQLITE_DYNAMIC);
+ }
+}
+
+/*
+** Implementation of the substr() function.
+**
+** substr(x,p1,p2) returns p2 characters of x[] beginning with p1.
+** p1 is 1-indexed. So substr(x,1,1) returns the first character
+** of x. If x is text, then we actually count UTF-8 characters.
+** If x is a blob, then we count bytes.
+**
+** If p1 is negative, then we begin abs(p1) from the end of x[].
+**
+** If p2 is negative, return the p2 characters preceding p1.
+*/
+static void substrFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ const unsigned char *z;
+ const unsigned char *z2;
+ int len;
+ int p0type;
+ i64 p1, p2;
+ int negP2 = 0;
+
+ assert( argc==3 || argc==2 );
+ if( sqlite3_value_type(argv[1])==SQLITE_NULL
+ || (argc==3 && sqlite3_value_type(argv[2])==SQLITE_NULL)
+ ){
+ return;
+ }
+ p0type = sqlite3_value_type(argv[0]);
+ p1 = sqlite3_value_int(argv[1]);
+ if( p0type==SQLITE_BLOB ){
+ len = sqlite3_value_bytes(argv[0]);
+ z = sqlite3_value_blob(argv[0]);
+ if( z==0 ) return;
+ assert( len==sqlite3_value_bytes(argv[0]) );
+ }else{
+ z = sqlite3_value_text(argv[0]);
+ if( z==0 ) return;
+ len = 0;
+ if( p1<0 ){
+ for(z2=z; *z2; len++){
+ SQLITE_SKIP_UTF8(z2);
+ }
+ }
+ }
+#ifdef SQLITE_SUBSTR_COMPATIBILITY
+ /* If SUBSTR_COMPATIBILITY is defined then substr(X,0,N) work the same as
+ ** as substr(X,1,N) - it returns the first N characters of X. This
+ ** is essentially a back-out of the bug-fix in check-in [5fc125d362df4b8]
+ ** from 2009-02-02 for compatibility of applications that exploited the
+ ** old buggy behavior. */
+ if( p1==0 ) p1 = 1; /* <rdar://problem/6778339> */
+#endif
+ if( argc==3 ){
+ p2 = sqlite3_value_int(argv[2]);
+ if( p2<0 ){
+ p2 = -p2;
+ negP2 = 1;
+ }
+ }else{
+ p2 = sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH];
+ }
+ if( p1<0 ){
+ p1 += len;
+ if( p1<0 ){
+ p2 += p1;
+ if( p2<0 ) p2 = 0;
+ p1 = 0;
+ }
+ }else if( p1>0 ){
+ p1--;
+ }else if( p2>0 ){
+ p2--;
+ }
+ if( negP2 ){
+ p1 -= p2;
+ if( p1<0 ){
+ p2 += p1;
+ p1 = 0;
+ }
+ }
+ assert( p1>=0 && p2>=0 );
+ if( p0type!=SQLITE_BLOB ){
+ while( *z && p1 ){
+ SQLITE_SKIP_UTF8(z);
+ p1--;
+ }
+ for(z2=z; *z2 && p2; p2--){
+ SQLITE_SKIP_UTF8(z2);
+ }
+ sqlite3_result_text64(context, (char*)z, z2-z, SQLITE_TRANSIENT,
+ SQLITE_UTF8);
+ }else{
+ if( p1+p2>len ){
+ p2 = len-p1;
+ if( p2<0 ) p2 = 0;
+ }
+ sqlite3_result_blob64(context, (char*)&z[p1], (u64)p2, SQLITE_TRANSIENT);
+ }
+}
+
+/*
+** Implementation of the round() function
+*/
+#ifndef SQLITE_OMIT_FLOATING_POINT
+static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
+ int n = 0;
+ double r;
+ char *zBuf;
+ assert( argc==1 || argc==2 );
+ if( argc==2 ){
+ if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return;
+ n = sqlite3_value_int(argv[1]);
+ if( n>30 ) n = 30;
+ if( n<0 ) n = 0;
+ }
+ if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
+ r = sqlite3_value_double(argv[0]);
+ /* If Y==0 and X will fit in a 64-bit int,
+ ** handle the rounding directly,
+ ** otherwise use printf.
+ */
+ if( n==0 && r>=0 && r<LARGEST_INT64-1 ){
+ r = (double)((sqlite_int64)(r+0.5));
+ }else if( n==0 && r<0 && (-r)<LARGEST_INT64-1 ){
+ r = -(double)((sqlite_int64)((-r)+0.5));
+ }else{
+ zBuf = sqlite3_mprintf("%.*f",n,r);
+ if( zBuf==0 ){
+ sqlite3_result_error_nomem(context);
+ return;
+ }
+ sqlite3AtoF(zBuf, &r, sqlite3Strlen30(zBuf), SQLITE_UTF8);
+ sqlite3_free(zBuf);
+ }
+ sqlite3_result_double(context, r);
+}
+#endif
+
+/*
+** Allocate nByte bytes of space using sqlite3Malloc(). If the
+** allocation fails, call sqlite3_result_error_nomem() to notify
+** the database handle that malloc() has failed and return NULL.
+** If nByte is larger than the maximum string or blob length, then
+** raise an SQLITE_TOOBIG exception and return NULL.
+*/
+static void *contextMalloc(sqlite3_context *context, i64 nByte){
+ char *z;
+ sqlite3 *db = sqlite3_context_db_handle(context);
+ assert( nByte>0 );
+ testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH] );
+ testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
+ if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ sqlite3_result_error_toobig(context);
+ z = 0;
+ }else{
+ z = sqlite3Malloc(nByte);
+ if( !z ){
+ sqlite3_result_error_nomem(context);
+ }
+ }
+ return z;
+}
+
+/*
+** Implementation of the upper() and lower() SQL functions.
+*/
+static void upperFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
+ char *z1;
+ const char *z2;
+ int i, n;
+ UNUSED_PARAMETER(argc);
+ z2 = (char*)sqlite3_value_text(argv[0]);
+ n = sqlite3_value_bytes(argv[0]);
+ /* Verify that the call to _bytes() does not invalidate the _text() pointer */
+ assert( z2==(char*)sqlite3_value_text(argv[0]) );
+ if( z2 ){
+ z1 = contextMalloc(context, ((i64)n)+1);
+ if( z1 ){
+ for(i=0; i<n; i++){
+ z1[i] = (char)sqlite3Toupper(z2[i]);
+ }
+ sqlite3_result_text(context, z1, n, sqlite3_free);
+ }
+ }
+}
+static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
+ char *z1;
+ const char *z2;
+ int i, n;
+ UNUSED_PARAMETER(argc);
+ z2 = (char*)sqlite3_value_text(argv[0]);
+ n = sqlite3_value_bytes(argv[0]);
+ /* Verify that the call to _bytes() does not invalidate the _text() pointer */
+ assert( z2==(char*)sqlite3_value_text(argv[0]) );
+ if( z2 ){
+ z1 = contextMalloc(context, ((i64)n)+1);
+ if( z1 ){
+ for(i=0; i<n; i++){
+ z1[i] = sqlite3Tolower(z2[i]);
+ }
+ sqlite3_result_text(context, z1, n, sqlite3_free);
+ }
+ }
+}
+
+/*
+** Some functions like COALESCE() and IFNULL() and UNLIKELY() are implemented
+** as VDBE code so that unused argument values do not have to be computed.
+** However, we still need some kind of function implementation for this
+** routines in the function table. The noopFunc macro provides this.
+** noopFunc will never be called so it doesn't matter what the implementation
+** is. We might as well use the "version()" function as a substitute.
+*/
+#define noopFunc versionFunc /* Substitute function - never called */
+
+/*
+** Implementation of random(). Return a random integer.
+*/
+static void randomFunc(
+ sqlite3_context *context,
+ int NotUsed,
+ sqlite3_value **NotUsed2
+){
+ sqlite_int64 r;
+ UNUSED_PARAMETER2(NotUsed, NotUsed2);
+ sqlite3_randomness(sizeof(r), &r);
+ if( r<0 ){
+ /* We need to prevent a random number of 0x8000000000000000
+ ** (or -9223372036854775808) since when you do abs() of that
+ ** number of you get the same value back again. To do this
+ ** in a way that is testable, mask the sign bit off of negative
+ ** values, resulting in a positive value. Then take the
+ ** 2s complement of that positive value. The end result can
+ ** therefore be no less than -9223372036854775807.
+ */
+ r = -(r & LARGEST_INT64);
+ }
+ sqlite3_result_int64(context, r);
+}
+
+/*
+** Implementation of randomblob(N). Return a random blob
+** that is N bytes long.
+*/
+static void randomBlob(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ int n;
+ unsigned char *p;
+ assert( argc==1 );
+ UNUSED_PARAMETER(argc);
+ n = sqlite3_value_int(argv[0]);
+ if( n<1 ){
+ n = 1;
+ }
+ p = contextMalloc(context, n);
+ if( p ){
+ sqlite3_randomness(n, p);
+ sqlite3_result_blob(context, (char*)p, n, sqlite3_free);
+ }
+}
+
+/*
+** Implementation of the last_insert_rowid() SQL function. The return
+** value is the same as the sqlite3_last_insert_rowid() API function.
+*/
+static void last_insert_rowid(
+ sqlite3_context *context,
+ int NotUsed,
+ sqlite3_value **NotUsed2
+){
+ sqlite3 *db = sqlite3_context_db_handle(context);
+ UNUSED_PARAMETER2(NotUsed, NotUsed2);
+ /* IMP: R-51513-12026 The last_insert_rowid() SQL function is a
+ ** wrapper around the sqlite3_last_insert_rowid() C/C++ interface
+ ** function. */
+ sqlite3_result_int64(context, sqlite3_last_insert_rowid(db));
+}
+
+/*
+** Implementation of the changes() SQL function.
+**
+** IMP: R-62073-11209 The changes() SQL function is a wrapper
+** around the sqlite3_changes() C/C++ function and hence follows the same
+** rules for counting changes.
+*/
+static void changes(
+ sqlite3_context *context,
+ int NotUsed,
+ sqlite3_value **NotUsed2
+){
+ sqlite3 *db = sqlite3_context_db_handle(context);
+ UNUSED_PARAMETER2(NotUsed, NotUsed2);
+ sqlite3_result_int(context, sqlite3_changes(db));
+}
+
+/*
+** Implementation of the total_changes() SQL function. The return value is
+** the same as the sqlite3_total_changes() API function.
+*/
+static void total_changes(
+ sqlite3_context *context,
+ int NotUsed,
+ sqlite3_value **NotUsed2
+){
+ sqlite3 *db = sqlite3_context_db_handle(context);
+ UNUSED_PARAMETER2(NotUsed, NotUsed2);
+ /* IMP: R-52756-41993 This function is a wrapper around the
+ ** sqlite3_total_changes() C/C++ interface. */
+ sqlite3_result_int(context, sqlite3_total_changes(db));
+}
+
+/*
+** A structure defining how to do GLOB-style comparisons.
+*/
+struct compareInfo {
+ u8 matchAll; /* "*" or "%" */
+ u8 matchOne; /* "?" or "_" */
+ u8 matchSet; /* "[" or 0 */
+ u8 noCase; /* true to ignore case differences */
+};
+
+/*
+** For LIKE and GLOB matching on EBCDIC machines, assume that every
+** character is exactly one byte in size. Also, provde the Utf8Read()
+** macro for fast reading of the next character in the common case where
+** the next character is ASCII.
+*/
+#if defined(SQLITE_EBCDIC)
+# define sqlite3Utf8Read(A) (*((*A)++))
+# define Utf8Read(A) (*(A++))
+#else
+# define Utf8Read(A) (A[0]<0x80?*(A++):sqlite3Utf8Read(&A))
+#endif
+
+static const struct compareInfo globInfo = { '*', '?', '[', 0 };
+/* The correct SQL-92 behavior is for the LIKE operator to ignore
+** case. Thus 'a' LIKE 'A' would be true. */
+static const struct compareInfo likeInfoNorm = { '%', '_', 0, 1 };
+/* If SQLITE_CASE_SENSITIVE_LIKE is defined, then the LIKE operator
+** is case sensitive causing 'a' LIKE 'A' to be false */
+static const struct compareInfo likeInfoAlt = { '%', '_', 0, 0 };
+
+/*
+** Possible error returns from patternMatch()
+*/
+#define SQLITE_MATCH 0
+#define SQLITE_NOMATCH 1
+#define SQLITE_NOWILDCARDMATCH 2
+
+/*
+** Compare two UTF-8 strings for equality where the first string is
+** a GLOB or LIKE expression. Return values:
+**
+** SQLITE_MATCH: Match
+** SQLITE_NOMATCH: No match
+** SQLITE_NOWILDCARDMATCH: No match in spite of having * or % wildcards.
+**
+** Globbing rules:
+**
+** '*' Matches any sequence of zero or more characters.
+**
+** '?' Matches exactly one character.
+**
+** [...] Matches one character from the enclosed list of
+** characters.
+**
+** [^...] Matches one character not in the enclosed list.
+**
+** With the [...] and [^...] matching, a ']' character can be included
+** in the list by making it the first character after '[' or '^'. A
+** range of characters can be specified using '-'. Example:
+** "[a-z]" matches any single lower-case letter. To match a '-', make
+** it the last character in the list.
+**
+** Like matching rules:
+**
+** '%' Matches any sequence of zero or more characters
+**
+*** '_' Matches any one character
+**
+** Ec Where E is the "esc" character and c is any other
+** character, including '%', '_', and esc, match exactly c.
+**
+** The comments within this routine usually assume glob matching.
+**
+** This routine is usually quick, but can be N**2 in the worst case.
+*/
+static int patternCompare(
+ const u8 *zPattern, /* The glob pattern */
+ const u8 *zString, /* The string to compare against the glob */
+ const struct compareInfo *pInfo, /* Information about how to do the compare */
+ u32 matchOther /* The escape char (LIKE) or '[' (GLOB) */
+){
+ u32 c, c2; /* Next pattern and input string chars */
+ u32 matchOne = pInfo->matchOne; /* "?" or "_" */
+ u32 matchAll = pInfo->matchAll; /* "*" or "%" */
+ u8 noCase = pInfo->noCase; /* True if uppercase==lowercase */
+ const u8 *zEscaped = 0; /* One past the last escaped input char */
+
+ while( (c = Utf8Read(zPattern))!=0 ){
+ if( c==matchAll ){ /* Match "*" */
+ /* Skip over multiple "*" characters in the pattern. If there
+ ** are also "?" characters, skip those as well, but consume a
+ ** single character of the input string for each "?" skipped */
+ while( (c=Utf8Read(zPattern)) == matchAll || c == matchOne ){
+ if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){
+ return SQLITE_NOWILDCARDMATCH;
+ }
+ }
+ if( c==0 ){
+ return SQLITE_MATCH; /* "*" at the end of the pattern matches */
+ }else if( c==matchOther ){
+ if( pInfo->matchSet==0 ){
+ c = sqlite3Utf8Read(&zPattern);
+ if( c==0 ) return SQLITE_NOWILDCARDMATCH;
+ }else{
+ /* "[...]" immediately follows the "*". We have to do a slow
+ ** recursive search in this case, but it is an unusual case. */
+ assert( matchOther<0x80 ); /* '[' is a single-byte character */
+ while( *zString ){
+ int bMatch = patternCompare(&zPattern[-1],zString,pInfo,matchOther);
+ if( bMatch!=SQLITE_NOMATCH ) return bMatch;
+ SQLITE_SKIP_UTF8(zString);
+ }
+ return SQLITE_NOWILDCARDMATCH;
+ }
+ }
+
+ /* At this point variable c contains the first character of the
+ ** pattern string past the "*". Search in the input string for the
+ ** first matching character and recursively continue the match from
+ ** that point.
+ **
+ ** For a case-insensitive search, set variable cx to be the same as
+ ** c but in the other case and search the input string for either
+ ** c or cx.
+ */
+ if( c<=0x80 ){
+ u32 cx;
+ int bMatch;
+ if( noCase ){
+ cx = sqlite3Toupper(c);
+ c = sqlite3Tolower(c);
+ }else{
+ cx = c;
+ }
+ while( (c2 = *(zString++))!=0 ){
+ if( c2!=c && c2!=cx ) continue;
+ bMatch = patternCompare(zPattern,zString,pInfo,matchOther);
+ if( bMatch!=SQLITE_NOMATCH ) return bMatch;
+ }
+ }else{
+ int bMatch;
+ while( (c2 = Utf8Read(zString))!=0 ){
+ if( c2!=c ) continue;
+ bMatch = patternCompare(zPattern,zString,pInfo,matchOther);
+ if( bMatch!=SQLITE_NOMATCH ) return bMatch;
+ }
+ }
+ return SQLITE_NOWILDCARDMATCH;
+ }
+ if( c==matchOther ){
+ if( pInfo->matchSet==0 ){
+ c = sqlite3Utf8Read(&zPattern);
+ if( c==0 ) return SQLITE_NOMATCH;
+ zEscaped = zPattern;
+ }else{
+ u32 prior_c = 0;
+ int seen = 0;
+ int invert = 0;
+ c = sqlite3Utf8Read(&zString);
+ if( c==0 ) return SQLITE_NOMATCH;
+ c2 = sqlite3Utf8Read(&zPattern);
+ if( c2=='^' ){
+ invert = 1;
+ c2 = sqlite3Utf8Read(&zPattern);
+ }
+ if( c2==']' ){
+ if( c==']' ) seen = 1;
+ c2 = sqlite3Utf8Read(&zPattern);
+ }
+ while( c2 && c2!=']' ){
+ if( c2=='-' && zPattern[0]!=']' && zPattern[0]!=0 && prior_c>0 ){
+ c2 = sqlite3Utf8Read(&zPattern);
+ if( c>=prior_c && c<=c2 ) seen = 1;
+ prior_c = 0;
+ }else{
+ if( c==c2 ){
+ seen = 1;
+ }
+ prior_c = c2;
+ }
+ c2 = sqlite3Utf8Read(&zPattern);
+ }
+ if( c2==0 || (seen ^ invert)==0 ){
+ return SQLITE_NOMATCH;
+ }
+ continue;
+ }
+ }
+ c2 = Utf8Read(zString);
+ if( c==c2 ) continue;
+ if( noCase && sqlite3Tolower(c)==sqlite3Tolower(c2) && c<0x80 && c2<0x80 ){
+ continue;
+ }
+ if( c==matchOne && zPattern!=zEscaped && c2!=0 ) continue;
+ return SQLITE_NOMATCH;
+ }
+ return *zString==0 ? SQLITE_MATCH : SQLITE_NOMATCH;
+}
+
+/*
+** The sqlite3_strglob() interface. Return 0 on a match (like strcmp()) and
+** non-zero if there is no match.
+*/
+SQLITE_API int sqlite3_strglob(const char *zGlobPattern, const char *zString){
+ return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, '[');
+}
+
+/*
+** The sqlite3_strlike() interface. Return 0 on a match and non-zero for
+** a miss - like strcmp().
+*/
+SQLITE_API int sqlite3_strlike(const char *zPattern, const char *zStr, unsigned int esc){
+ return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc);
+}
+
+/*
+** Count the number of times that the LIKE operator (or GLOB which is
+** just a variation of LIKE) gets called. This is used for testing
+** only.
+*/
+#ifdef SQLITE_TEST
+SQLITE_API int sqlite3_like_count = 0;
+#endif
+
+
+/*
+** Implementation of the like() SQL function. This function implements
+** the build-in LIKE operator. The first argument to the function is the
+** pattern and the second argument is the string. So, the SQL statements:
+**
+** A LIKE B
+**
+** is implemented as like(B,A).
+**
+** This same function (with a different compareInfo structure) computes
+** the GLOB operator.
+*/
+static void likeFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ const unsigned char *zA, *zB;
+ u32 escape;
+ int nPat;
+ sqlite3 *db = sqlite3_context_db_handle(context);
+ struct compareInfo *pInfo = sqlite3_user_data(context);
+
+#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
+ if( sqlite3_value_type(argv[0])==SQLITE_BLOB
+ || sqlite3_value_type(argv[1])==SQLITE_BLOB
+ ){
+#ifdef SQLITE_TEST
+ sqlite3_like_count++;
+#endif
+ sqlite3_result_int(context, 0);
+ return;
+ }
+#endif
+ zB = sqlite3_value_text(argv[0]);
+ zA = sqlite3_value_text(argv[1]);
+
+ /* Limit the length of the LIKE or GLOB pattern to avoid problems
+ ** of deep recursion and N*N behavior in patternCompare().
+ */
+ nPat = sqlite3_value_bytes(argv[0]);
+ testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] );
+ testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]+1 );
+ if( nPat > db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] ){
+ sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1);
+ return;
+ }
+ assert( zB==sqlite3_value_text(argv[0]) ); /* Encoding did not change */
+
+ if( argc==3 ){
+ /* The escape character string must consist of a single UTF-8 character.
+ ** Otherwise, return an error.
+ */
+ const unsigned char *zEsc = sqlite3_value_text(argv[2]);
+ if( zEsc==0 ) return;
+ if( sqlite3Utf8CharLen((char*)zEsc, -1)!=1 ){
+ sqlite3_result_error(context,
+ "ESCAPE expression must be a single character", -1);
+ return;
+ }
+ escape = sqlite3Utf8Read(&zEsc);
+ }else{
+ escape = pInfo->matchSet;
+ }
+ if( zA && zB ){
+#ifdef SQLITE_TEST
+ sqlite3_like_count++;
+#endif
+ sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape)==SQLITE_MATCH);
+ }
+}
+
+/*
+** Implementation of the NULLIF(x,y) function. The result is the first
+** argument if the arguments are different. The result is NULL if the
+** arguments are equal to each other.
+*/
+static void nullifFunc(
+ sqlite3_context *context,
+ int NotUsed,
+ sqlite3_value **argv
+){
+ CollSeq *pColl = sqlite3GetFuncCollSeq(context);
+ UNUSED_PARAMETER(NotUsed);
+ if( sqlite3MemCompare(argv[0], argv[1], pColl)!=0 ){
+ sqlite3_result_value(context, argv[0]);
+ }
+}
+
+/*
+** Implementation of the sqlite_version() function. The result is the version
+** of the SQLite library that is running.
+*/
+static void versionFunc(
+ sqlite3_context *context,
+ int NotUsed,
+ sqlite3_value **NotUsed2
+){
+ UNUSED_PARAMETER2(NotUsed, NotUsed2);
+ /* IMP: R-48699-48617 This function is an SQL wrapper around the
+ ** sqlite3_libversion() C-interface. */
+ sqlite3_result_text(context, sqlite3_libversion(), -1, SQLITE_STATIC);
+}
+
+/*
+** Implementation of the sqlite_source_id() function. The result is a string
+** that identifies the particular version of the source code used to build
+** SQLite.
+*/
+static void sourceidFunc(
+ sqlite3_context *context,
+ int NotUsed,
+ sqlite3_value **NotUsed2
+){
+ UNUSED_PARAMETER2(NotUsed, NotUsed2);
+ /* IMP: R-24470-31136 This function is an SQL wrapper around the
+ ** sqlite3_sourceid() C interface. */
+ sqlite3_result_text(context, sqlite3_sourceid(), -1, SQLITE_STATIC);
+}
+
+/*
+** Implementation of the sqlite_log() function. This is a wrapper around
+** sqlite3_log(). The return value is NULL. The function exists purely for
+** its side-effects.
+*/
+static void errlogFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ UNUSED_PARAMETER(argc);
+ UNUSED_PARAMETER(context);
+ sqlite3_log(sqlite3_value_int(argv[0]), "%s", sqlite3_value_text(argv[1]));
+}
+
+/*
+** Implementation of the sqlite_compileoption_used() function.
+** The result is an integer that identifies if the compiler option
+** was used to build SQLite.
+*/
+#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+static void compileoptionusedFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ const char *zOptName;
+ assert( argc==1 );
+ UNUSED_PARAMETER(argc);
+ /* IMP: R-39564-36305 The sqlite_compileoption_used() SQL
+ ** function is a wrapper around the sqlite3_compileoption_used() C/C++
+ ** function.
+ */
+ if( (zOptName = (const char*)sqlite3_value_text(argv[0]))!=0 ){
+ sqlite3_result_int(context, sqlite3_compileoption_used(zOptName));
+ }
+}
+#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
+
+/*
+** Implementation of the sqlite_compileoption_get() function.
+** The result is a string that identifies the compiler options
+** used to build SQLite.
+*/
+#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+static void compileoptiongetFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ int n;
+ assert( argc==1 );
+ UNUSED_PARAMETER(argc);
+ /* IMP: R-04922-24076 The sqlite_compileoption_get() SQL function
+ ** is a wrapper around the sqlite3_compileoption_get() C/C++ function.
+ */
+ n = sqlite3_value_int(argv[0]);
+ sqlite3_result_text(context, sqlite3_compileoption_get(n), -1, SQLITE_STATIC);
+}
+#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
+
+/* Array for converting from half-bytes (nybbles) into ASCII hex
+** digits. */
+static const char hexdigits[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+};
+
+/*
+** Implementation of the QUOTE() function. This function takes a single
+** argument. If the argument is numeric, the return value is the same as
+** the argument. If the argument is NULL, the return value is the string
+** "NULL". Otherwise, the argument is enclosed in single quotes with
+** single-quote escapes.
+*/
+static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
+ assert( argc==1 );
+ UNUSED_PARAMETER(argc);
+ switch( sqlite3_value_type(argv[0]) ){
+ case SQLITE_FLOAT: {
+ double r1, r2;
+ char zBuf[50];
+ r1 = sqlite3_value_double(argv[0]);
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.15g", r1);
+ sqlite3AtoF(zBuf, &r2, 20, SQLITE_UTF8);
+ if( r1!=r2 ){
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.20e", r1);
+ }
+ sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
+ break;
+ }
+ case SQLITE_INTEGER: {
+ sqlite3_result_value(context, argv[0]);
+ break;
+ }
+ case SQLITE_BLOB: {
+ char *zText = 0;
+ char const *zBlob = sqlite3_value_blob(argv[0]);
+ int nBlob = sqlite3_value_bytes(argv[0]);
+ assert( zBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */
+ zText = (char *)contextMalloc(context, (2*(i64)nBlob)+4);
+ if( zText ){
+ int i;
+ for(i=0; i<nBlob; i++){
+ zText[(i*2)+2] = hexdigits[(zBlob[i]>>4)&0x0F];
+ zText[(i*2)+3] = hexdigits[(zBlob[i])&0x0F];
+ }
+ zText[(nBlob*2)+2] = '\'';
+ zText[(nBlob*2)+3] = '\0';
+ zText[0] = 'X';
+ zText[1] = '\'';
+ sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT);
+ sqlite3_free(zText);
+ }
+ break;
+ }
+ case SQLITE_TEXT: {
+ int i,j;
+ u64 n;
+ const unsigned char *zArg = sqlite3_value_text(argv[0]);
+ char *z;
+
+ if( zArg==0 ) return;
+ for(i=0, n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; }
+ z = contextMalloc(context, ((i64)i)+((i64)n)+3);
+ if( z ){
+ z[0] = '\'';
+ for(i=0, j=1; zArg[i]; i++){
+ z[j++] = zArg[i];
+ if( zArg[i]=='\'' ){
+ z[j++] = '\'';
+ }
+ }
+ z[j++] = '\'';
+ z[j] = 0;
+ sqlite3_result_text(context, z, j, sqlite3_free);
+ }
+ break;
+ }
+ default: {
+ assert( sqlite3_value_type(argv[0])==SQLITE_NULL );
+ sqlite3_result_text(context, "NULL", 4, SQLITE_STATIC);
+ break;
+ }
+ }
+}
+
+/*
+** The unicode() function. Return the integer unicode code-point value
+** for the first character of the input string.
+*/
+static void unicodeFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ const unsigned char *z = sqlite3_value_text(argv[0]);
+ (void)argc;
+ if( z && z[0] ) sqlite3_result_int(context, sqlite3Utf8Read(&z));
+}
+
+/*
+** The char() function takes zero or more arguments, each of which is
+** an integer. It constructs a string where each character of the string
+** is the unicode character for the corresponding integer argument.
+*/
+static void charFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ unsigned char *z, *zOut;
+ int i;
+ zOut = z = sqlite3_malloc64( argc*4+1 );
+ if( z==0 ){
+ sqlite3_result_error_nomem(context);
+ return;
+ }
+ for(i=0; i<argc; i++){
+ sqlite3_int64 x;
+ unsigned c;
+ x = sqlite3_value_int64(argv[i]);
+ if( x<0 || x>0x10ffff ) x = 0xfffd;
+ c = (unsigned)(x & 0x1fffff);
+ if( c<0x00080 ){
+ *zOut++ = (u8)(c&0xFF);
+ }else if( c<0x00800 ){
+ *zOut++ = 0xC0 + (u8)((c>>6)&0x1F);
+ *zOut++ = 0x80 + (u8)(c & 0x3F);
+ }else if( c<0x10000 ){
+ *zOut++ = 0xE0 + (u8)((c>>12)&0x0F);
+ *zOut++ = 0x80 + (u8)((c>>6) & 0x3F);
+ *zOut++ = 0x80 + (u8)(c & 0x3F);
+ }else{
+ *zOut++ = 0xF0 + (u8)((c>>18) & 0x07);
+ *zOut++ = 0x80 + (u8)((c>>12) & 0x3F);
+ *zOut++ = 0x80 + (u8)((c>>6) & 0x3F);
+ *zOut++ = 0x80 + (u8)(c & 0x3F);
+ } \
+ }
+ sqlite3_result_text64(context, (char*)z, zOut-z, sqlite3_free, SQLITE_UTF8);
+}
+
+/*
+** The hex() function. Interpret the argument as a blob. Return
+** a hexadecimal rendering as text.
+*/
+static void hexFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ int i, n;
+ const unsigned char *pBlob;
+ char *zHex, *z;
+ assert( argc==1 );
+ UNUSED_PARAMETER(argc);
+ pBlob = sqlite3_value_blob(argv[0]);
+ n = sqlite3_value_bytes(argv[0]);
+ assert( pBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */
+ z = zHex = contextMalloc(context, ((i64)n)*2 + 1);
+ if( zHex ){
+ for(i=0; i<n; i++, pBlob++){
+ unsigned char c = *pBlob;
+ *(z++) = hexdigits[(c>>4)&0xf];
+ *(z++) = hexdigits[c&0xf];
+ }
+ *z = 0;
+ sqlite3_result_text(context, zHex, n*2, sqlite3_free);
+ }
+}
+
+/*
+** The zeroblob(N) function returns a zero-filled blob of size N bytes.
+*/
+static void zeroblobFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ i64 n;
+ int rc;
+ assert( argc==1 );
+ UNUSED_PARAMETER(argc);
+ n = sqlite3_value_int64(argv[0]);
+ if( n<0 ) n = 0;
+ rc = sqlite3_result_zeroblob64(context, n); /* IMP: R-00293-64994 */
+ if( rc ){
+ sqlite3_result_error_code(context, rc);
+ }
+}
+
+/*
+** The replace() function. Three arguments are all strings: call
+** them A, B, and C. The result is also a string which is derived
+** from A by replacing every occurrence of B with C. The match
+** must be exact. Collating sequences are not used.
+*/
+static void replaceFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ const unsigned char *zStr; /* The input string A */
+ const unsigned char *zPattern; /* The pattern string B */
+ const unsigned char *zRep; /* The replacement string C */
+ unsigned char *zOut; /* The output */
+ int nStr; /* Size of zStr */
+ int nPattern; /* Size of zPattern */
+ int nRep; /* Size of zRep */
+ i64 nOut; /* Maximum size of zOut */
+ int loopLimit; /* Last zStr[] that might match zPattern[] */
+ int i, j; /* Loop counters */
+
+ assert( argc==3 );
+ UNUSED_PARAMETER(argc);
+ zStr = sqlite3_value_text(argv[0]);
+ if( zStr==0 ) return;
+ nStr = sqlite3_value_bytes(argv[0]);
+ assert( zStr==sqlite3_value_text(argv[0]) ); /* No encoding change */
+ zPattern = sqlite3_value_text(argv[1]);
+ if( zPattern==0 ){
+ assert( sqlite3_value_type(argv[1])==SQLITE_NULL
+ || sqlite3_context_db_handle(context)->mallocFailed );
+ return;
+ }
+ if( zPattern[0]==0 ){
+ assert( sqlite3_value_type(argv[1])!=SQLITE_NULL );
+ sqlite3_result_value(context, argv[0]);
+ return;
+ }
+ nPattern = sqlite3_value_bytes(argv[1]);
+ assert( zPattern==sqlite3_value_text(argv[1]) ); /* No encoding change */
+ zRep = sqlite3_value_text(argv[2]);
+ if( zRep==0 ) return;
+ nRep = sqlite3_value_bytes(argv[2]);
+ assert( zRep==sqlite3_value_text(argv[2]) );
+ nOut = nStr + 1;
+ assert( nOut<SQLITE_MAX_LENGTH );
+ zOut = contextMalloc(context, (i64)nOut);
+ if( zOut==0 ){
+ return;
+ }
+ loopLimit = nStr - nPattern;
+ for(i=j=0; i<=loopLimit; i++){
+ if( zStr[i]!=zPattern[0] || memcmp(&zStr[i], zPattern, nPattern) ){
+ zOut[j++] = zStr[i];
+ }else{
+ u8 *zOld;
+ sqlite3 *db = sqlite3_context_db_handle(context);
+ nOut += nRep - nPattern;
+ testcase( nOut-1==db->aLimit[SQLITE_LIMIT_LENGTH] );
+ testcase( nOut-2==db->aLimit[SQLITE_LIMIT_LENGTH] );
+ if( nOut-1>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ sqlite3_result_error_toobig(context);
+ sqlite3_free(zOut);
+ return;
+ }
+ zOld = zOut;
+ zOut = sqlite3_realloc64(zOut, (int)nOut);
+ if( zOut==0 ){
+ sqlite3_result_error_nomem(context);
+ sqlite3_free(zOld);
+ return;
+ }
+ memcpy(&zOut[j], zRep, nRep);
+ j += nRep;
+ i += nPattern-1;
+ }
+ }
+ assert( j+nStr-i+1==nOut );
+ memcpy(&zOut[j], &zStr[i], nStr-i);
+ j += nStr - i;
+ assert( j<=nOut );
+ zOut[j] = 0;
+ sqlite3_result_text(context, (char*)zOut, j, sqlite3_free);
+}
+
+/*
+** Implementation of the TRIM(), LTRIM(), and RTRIM() functions.
+** The userdata is 0x1 for left trim, 0x2 for right trim, 0x3 for both.
+*/
+static void trimFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ const unsigned char *zIn; /* Input string */
+ const unsigned char *zCharSet; /* Set of characters to trim */
+ int nIn; /* Number of bytes in input */
+ int flags; /* 1: trimleft 2: trimright 3: trim */
+ int i; /* Loop counter */
+ unsigned char *aLen = 0; /* Length of each character in zCharSet */
+ unsigned char **azChar = 0; /* Individual characters in zCharSet */
+ int nChar; /* Number of characters in zCharSet */
+
+ if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
+ return;
+ }
+ zIn = sqlite3_value_text(argv[0]);
+ if( zIn==0 ) return;
+ nIn = sqlite3_value_bytes(argv[0]);
+ assert( zIn==sqlite3_value_text(argv[0]) );
+ if( argc==1 ){
+ static const unsigned char lenOne[] = { 1 };
+ static unsigned char * const azOne[] = { (u8*)" " };
+ nChar = 1;
+ aLen = (u8*)lenOne;
+ azChar = (unsigned char **)azOne;
+ zCharSet = 0;
+ }else if( (zCharSet = sqlite3_value_text(argv[1]))==0 ){
+ return;
+ }else{
+ const unsigned char *z;
+ for(z=zCharSet, nChar=0; *z; nChar++){
+ SQLITE_SKIP_UTF8(z);
+ }
+ if( nChar>0 ){
+ azChar = contextMalloc(context, ((i64)nChar)*(sizeof(char*)+1));
+ if( azChar==0 ){
+ return;
+ }
+ aLen = (unsigned char*)&azChar[nChar];
+ for(z=zCharSet, nChar=0; *z; nChar++){
+ azChar[nChar] = (unsigned char *)z;
+ SQLITE_SKIP_UTF8(z);
+ aLen[nChar] = (u8)(z - azChar[nChar]);
+ }
+ }
+ }
+ if( nChar>0 ){
+ flags = SQLITE_PTR_TO_INT(sqlite3_user_data(context));
+ if( flags & 1 ){
+ while( nIn>0 ){
+ int len = 0;
+ for(i=0; i<nChar; i++){
+ len = aLen[i];
+ if( len<=nIn && memcmp(zIn, azChar[i], len)==0 ) break;
+ }
+ if( i>=nChar ) break;
+ zIn += len;
+ nIn -= len;
+ }
+ }
+ if( flags & 2 ){
+ while( nIn>0 ){
+ int len = 0;
+ for(i=0; i<nChar; i++){
+ len = aLen[i];
+ if( len<=nIn && memcmp(&zIn[nIn-len],azChar[i],len)==0 ) break;
+ }
+ if( i>=nChar ) break;
+ nIn -= len;
+ }
+ }
+ if( zCharSet ){
+ sqlite3_free(azChar);
+ }
+ }
+ sqlite3_result_text(context, (char*)zIn, nIn, SQLITE_TRANSIENT);
+}
+
+
+#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
+/*
+** The "unknown" function is automatically substituted in place of
+** any unrecognized function name when doing an EXPLAIN or EXPLAIN QUERY PLAN
+** when the SQLITE_ENABLE_UNKNOWN_FUNCTION compile-time option is used.
+** When the "sqlite3" command-line shell is built using this functionality,
+** that allows an EXPLAIN or EXPLAIN QUERY PLAN for complex queries
+** involving application-defined functions to be examined in a generic
+** sqlite3 shell.
+*/
+static void unknownFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ /* no-op */
+}
+#endif /*SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION*/
+
+
+/* IMP: R-25361-16150 This function is omitted from SQLite by default. It
+** is only available if the SQLITE_SOUNDEX compile-time option is used
+** when SQLite is built.
+*/
+#ifdef SQLITE_SOUNDEX
+/*
+** Compute the soundex encoding of a word.
+**
+** IMP: R-59782-00072 The soundex(X) function returns a string that is the
+** soundex encoding of the string X.
+*/
+static void soundexFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ char zResult[8];
+ const u8 *zIn;
+ int i, j;
+ static const unsigned char iCode[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0,
+ 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,
+ 0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0,
+ 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,
+ };
+ assert( argc==1 );
+ zIn = (u8*)sqlite3_value_text(argv[0]);
+ if( zIn==0 ) zIn = (u8*)"";
+ for(i=0; zIn[i] && !sqlite3Isalpha(zIn[i]); i++){}
+ if( zIn[i] ){
+ u8 prevcode = iCode[zIn[i]&0x7f];
+ zResult[0] = sqlite3Toupper(zIn[i]);
+ for(j=1; j<4 && zIn[i]; i++){
+ int code = iCode[zIn[i]&0x7f];
+ if( code>0 ){
+ if( code!=prevcode ){
+ prevcode = code;
+ zResult[j++] = code + '0';
+ }
+ }else{
+ prevcode = 0;
+ }
+ }
+ while( j<4 ){
+ zResult[j++] = '0';
+ }
+ zResult[j] = 0;
+ sqlite3_result_text(context, zResult, 4, SQLITE_TRANSIENT);
+ }else{
+ /* IMP: R-64894-50321 The string "?000" is returned if the argument
+ ** is NULL or contains no ASCII alphabetic characters. */
+ sqlite3_result_text(context, "?000", 4, SQLITE_STATIC);
+ }
+}
+#endif /* SQLITE_SOUNDEX */
+
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
+/*
+** A function that loads a shared-library extension then returns NULL.
+*/
+static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){
+ const char *zFile = (const char *)sqlite3_value_text(argv[0]);
+ const char *zProc;
+ sqlite3 *db = sqlite3_context_db_handle(context);
+ char *zErrMsg = 0;
+
+ /* Disallow the load_extension() SQL function unless the SQLITE_LoadExtFunc
+ ** flag is set. See the sqlite3_enable_load_extension() API.
+ */
+ if( (db->flags & SQLITE_LoadExtFunc)==0 ){
+ sqlite3_result_error(context, "not authorized", -1);
+ return;
+ }
+
+ if( argc==2 ){
+ zProc = (const char *)sqlite3_value_text(argv[1]);
+ }else{
+ zProc = 0;
+ }
+ if( zFile && sqlite3_load_extension(db, zFile, zProc, &zErrMsg) ){
+ sqlite3_result_error(context, zErrMsg, -1);
+ sqlite3_free(zErrMsg);
+ }
+}
+#endif
+
+
+/*
+** An instance of the following structure holds the context of a
+** sum() or avg() aggregate computation.
+*/
+typedef struct SumCtx SumCtx;
+struct SumCtx {
+ double rSum; /* Floating point sum */
+ i64 iSum; /* Integer sum */
+ i64 cnt; /* Number of elements summed */
+ u8 overflow; /* True if integer overflow seen */
+ u8 approx; /* True if non-integer value was input to the sum */
+};
+
+/*
+** Routines used to compute the sum, average, and total.
+**
+** The SUM() function follows the (broken) SQL standard which means
+** that it returns NULL if it sums over no inputs. TOTAL returns
+** 0.0 in that case. In addition, TOTAL always returns a float where
+** SUM might return an integer if it never encounters a floating point
+** value. TOTAL never fails, but SUM might through an exception if
+** it overflows an integer.
+*/
+static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){
+ SumCtx *p;
+ int type;
+ assert( argc==1 );
+ UNUSED_PARAMETER(argc);
+ p = sqlite3_aggregate_context(context, sizeof(*p));
+ type = sqlite3_value_numeric_type(argv[0]);
+ if( p && type!=SQLITE_NULL ){
+ p->cnt++;
+ if( type==SQLITE_INTEGER ){
+ i64 v = sqlite3_value_int64(argv[0]);
+ p->rSum += v;
+ if( (p->approx|p->overflow)==0 && sqlite3AddInt64(&p->iSum, v) ){
+ p->overflow = 1;
+ }
+ }else{
+ p->rSum += sqlite3_value_double(argv[0]);
+ p->approx = 1;
+ }
+ }
+}
+static void sumFinalize(sqlite3_context *context){
+ SumCtx *p;
+ p = sqlite3_aggregate_context(context, 0);
+ if( p && p->cnt>0 ){
+ if( p->overflow ){
+ sqlite3_result_error(context,"integer overflow",-1);
+ }else if( p->approx ){
+ sqlite3_result_double(context, p->rSum);
+ }else{
+ sqlite3_result_int64(context, p->iSum);
+ }
+ }
+}
+static void avgFinalize(sqlite3_context *context){
+ SumCtx *p;
+ p = sqlite3_aggregate_context(context, 0);
+ if( p && p->cnt>0 ){
+ sqlite3_result_double(context, p->rSum/(double)p->cnt);
+ }
+}
+static void totalFinalize(sqlite3_context *context){
+ SumCtx *p;
+ p = sqlite3_aggregate_context(context, 0);
+ /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
+ sqlite3_result_double(context, p ? p->rSum : (double)0);
+}
+
+/*
+** The following structure keeps track of state information for the
+** count() aggregate function.
+*/
+typedef struct CountCtx CountCtx;
+struct CountCtx {
+ i64 n;
+};
+
+/*
+** Routines to implement the count() aggregate function.
+*/
+static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){
+ CountCtx *p;
+ p = sqlite3_aggregate_context(context, sizeof(*p));
+ if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && p ){
+ p->n++;
+ }
+
+#ifndef SQLITE_OMIT_DEPRECATED
+ /* The sqlite3_aggregate_count() function is deprecated. But just to make
+ ** sure it still operates correctly, verify that its count agrees with our
+ ** internal count when using count(*) and when the total count can be
+ ** expressed as a 32-bit integer. */
+ assert( argc==1 || p==0 || p->n>0x7fffffff
+ || p->n==sqlite3_aggregate_count(context) );
+#endif
+}
+static void countFinalize(sqlite3_context *context){
+ CountCtx *p;
+ p = sqlite3_aggregate_context(context, 0);
+ sqlite3_result_int64(context, p ? p->n : 0);
+}
+
+/*
+** Routines to implement min() and max() aggregate functions.
+*/
+static void minmaxStep(
+ sqlite3_context *context,
+ int NotUsed,
+ sqlite3_value **argv
+){
+ Mem *pArg = (Mem *)argv[0];
+ Mem *pBest;
+ UNUSED_PARAMETER(NotUsed);
+
+ pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest));
+ if( !pBest ) return;
+
+ if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
+ if( pBest->flags ) sqlite3SkipAccumulatorLoad(context);
+ }else if( pBest->flags ){
+ int max;
+ int cmp;
+ CollSeq *pColl = sqlite3GetFuncCollSeq(context);
+ /* This step function is used for both the min() and max() aggregates,
+ ** the only difference between the two being that the sense of the
+ ** comparison is inverted. For the max() aggregate, the
+ ** sqlite3_user_data() function returns (void *)-1. For min() it
+ ** returns (void *)db, where db is the sqlite3* database pointer.
+ ** Therefore the next statement sets variable 'max' to 1 for the max()
+ ** aggregate, or 0 for min().
+ */
+ max = sqlite3_user_data(context)!=0;
+ cmp = sqlite3MemCompare(pBest, pArg, pColl);
+ if( (max && cmp<0) || (!max && cmp>0) ){
+ sqlite3VdbeMemCopy(pBest, pArg);
+ }else{
+ sqlite3SkipAccumulatorLoad(context);
+ }
+ }else{
+ pBest->db = sqlite3_context_db_handle(context);
+ sqlite3VdbeMemCopy(pBest, pArg);
+ }
+}
+static void minMaxFinalize(sqlite3_context *context){
+ sqlite3_value *pRes;
+ pRes = (sqlite3_value *)sqlite3_aggregate_context(context, 0);
+ if( pRes ){
+ if( pRes->flags ){
+ sqlite3_result_value(context, pRes);
+ }
+ sqlite3VdbeMemRelease(pRes);
+ }
+}
+
+/*
+** group_concat(EXPR, ?SEPARATOR?)
+*/
+static void groupConcatStep(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ const char *zVal;
+ StrAccum *pAccum;
+ const char *zSep;
+ int nVal, nSep;
+ assert( argc==1 || argc==2 );
+ if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
+ pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum));
+
+ if( pAccum ){
+ sqlite3 *db = sqlite3_context_db_handle(context);
+ int firstTerm = pAccum->mxAlloc==0;
+ pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH];
+ if( !firstTerm ){
+ if( argc==2 ){
+ zSep = (char*)sqlite3_value_text(argv[1]);
+ nSep = sqlite3_value_bytes(argv[1]);
+ }else{
+ zSep = ",";
+ nSep = 1;
+ }
+ if( zSep ) sqlite3StrAccumAppend(pAccum, zSep, nSep);
+ }
+ zVal = (char*)sqlite3_value_text(argv[0]);
+ nVal = sqlite3_value_bytes(argv[0]);
+ if( zVal ) sqlite3StrAccumAppend(pAccum, zVal, nVal);
+ }
+}
+static void groupConcatFinalize(sqlite3_context *context){
+ StrAccum *pAccum;
+ pAccum = sqlite3_aggregate_context(context, 0);
+ if( pAccum ){
+ if( pAccum->accError==STRACCUM_TOOBIG ){
+ sqlite3_result_error_toobig(context);
+ }else if( pAccum->accError==STRACCUM_NOMEM ){
+ sqlite3_result_error_nomem(context);
+ }else{
+ sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1,
+ sqlite3_free);
+ }
+ }
+}
+
+/*
+** This routine does per-connection function registration. Most
+** of the built-in functions above are part of the global function set.
+** This routine only deals with those that are not global.
+*/
+SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3 *db){
+ int rc = sqlite3_overload_function(db, "MATCH", 2);
+ assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
+ if( rc==SQLITE_NOMEM ){
+ sqlite3OomFault(db);
+ }
+}
+
+/*
+** Set the LIKEOPT flag on the 2-argument function with the given name.
+*/
+static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){
+ FuncDef *pDef;
+ pDef = sqlite3FindFunction(db, zName, 2, SQLITE_UTF8, 0);
+ if( ALWAYS(pDef) ){
+ pDef->funcFlags |= flagVal;
+ }
+}
+
+/*
+** Register the built-in LIKE and GLOB functions. The caseSensitive
+** parameter determines whether or not the LIKE operator is case
+** sensitive. GLOB is always case sensitive.
+*/
+SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
+ struct compareInfo *pInfo;
+ if( caseSensitive ){
+ pInfo = (struct compareInfo*)&likeInfoAlt;
+ }else{
+ pInfo = (struct compareInfo*)&likeInfoNorm;
+ }
+ sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0);
+ sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0);
+ sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8,
+ (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0);
+ setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
+ setLikeOptFlag(db, "like",
+ caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE);
+}
+
+/*
+** pExpr points to an expression which implements a function. If
+** it is appropriate to apply the LIKE optimization to that function
+** then set aWc[0] through aWc[2] to the wildcard characters and
+** return TRUE. If the function is not a LIKE-style function then
+** return FALSE.
+**
+** *pIsNocase is set to true if uppercase and lowercase are equivalent for
+** the function (default for LIKE). If the function makes the distinction
+** between uppercase and lowercase (as does GLOB) then *pIsNocase is set to
+** false.
+*/
+SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
+ FuncDef *pDef;
+ if( pExpr->op!=TK_FUNCTION
+ || !pExpr->x.pList
+ || pExpr->x.pList->nExpr!=2
+ ){
+ return 0;
+ }
+ assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
+ pDef = sqlite3FindFunction(db, pExpr->u.zToken, 2, SQLITE_UTF8, 0);
+ if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_FUNC_LIKE)==0 ){
+ return 0;
+ }
+
+ /* The memcpy() statement assumes that the wildcard characters are
+ ** the first three statements in the compareInfo structure. The
+ ** asserts() that follow verify that assumption
+ */
+ memcpy(aWc, pDef->pUserData, 3);
+ assert( (char*)&likeInfoAlt == (char*)&likeInfoAlt.matchAll );
+ assert( &((char*)&likeInfoAlt)[1] == (char*)&likeInfoAlt.matchOne );
+ assert( &((char*)&likeInfoAlt)[2] == (char*)&likeInfoAlt.matchSet );
+ *pIsNocase = (pDef->funcFlags & SQLITE_FUNC_CASE)==0;
+ return 1;
+}
+
+/*
+** All of the FuncDef structures in the aBuiltinFunc[] array above
+** to the global function hash table. This occurs at start-time (as
+** a consequence of calling sqlite3_initialize()).
+**
+** After this routine runs
+*/
+SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){
+ /*
+ ** The following array holds FuncDef structures for all of the functions
+ ** defined in this file.
+ **
+ ** The array cannot be constant since changes are made to the
+ ** FuncDef.pHash elements at start-time. The elements of this array
+ ** are read-only after initialization is complete.
+ **
+ ** For peak efficiency, put the most frequently used function last.
+ */
+ static FuncDef aBuiltinFunc[] = {
+#ifdef SQLITE_SOUNDEX
+ FUNCTION(soundex, 1, 0, 0, soundexFunc ),
+#endif
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
+ VFUNCTION(load_extension, 1, 0, 0, loadExt ),
+ VFUNCTION(load_extension, 2, 0, 0, loadExt ),
+#endif
+#if SQLITE_USER_AUTHENTICATION
+ FUNCTION(sqlite_crypt, 2, 0, 0, sqlite3CryptFunc ),
+#endif
+#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+ DFUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ),
+ DFUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ),
+#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
+ FUNCTION2(unlikely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
+ FUNCTION2(likelihood, 2, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
+ FUNCTION2(likely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
+#ifdef SQLITE_DEBUG
+ FUNCTION2(affinity, 1, 0, 0, noopFunc, SQLITE_FUNC_AFFINITY),
+#endif
+ FUNCTION(ltrim, 1, 1, 0, trimFunc ),
+ FUNCTION(ltrim, 2, 1, 0, trimFunc ),
+ FUNCTION(rtrim, 1, 2, 0, trimFunc ),
+ FUNCTION(rtrim, 2, 2, 0, trimFunc ),
+ FUNCTION(trim, 1, 3, 0, trimFunc ),
+ FUNCTION(trim, 2, 3, 0, trimFunc ),
+ FUNCTION(min, -1, 0, 1, minmaxFunc ),
+ FUNCTION(min, 0, 0, 1, 0 ),
+ AGGREGATE2(min, 1, 0, 1, minmaxStep, minMaxFinalize,
+ SQLITE_FUNC_MINMAX ),
+ FUNCTION(max, -1, 1, 1, minmaxFunc ),
+ FUNCTION(max, 0, 1, 1, 0 ),
+ AGGREGATE2(max, 1, 1, 1, minmaxStep, minMaxFinalize,
+ SQLITE_FUNC_MINMAX ),
+ FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF),
+ FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH),
+ FUNCTION(instr, 2, 0, 0, instrFunc ),
+ FUNCTION(printf, -1, 0, 0, printfFunc ),
+ FUNCTION(unicode, 1, 0, 0, unicodeFunc ),
+ FUNCTION(char, -1, 0, 0, charFunc ),
+ FUNCTION(abs, 1, 0, 0, absFunc ),
+#ifndef SQLITE_OMIT_FLOATING_POINT
+ FUNCTION(round, 1, 0, 0, roundFunc ),
+ FUNCTION(round, 2, 0, 0, roundFunc ),
+#endif
+ FUNCTION(upper, 1, 0, 0, upperFunc ),
+ FUNCTION(lower, 1, 0, 0, lowerFunc ),
+ FUNCTION(hex, 1, 0, 0, hexFunc ),
+ FUNCTION2(ifnull, 2, 0, 0, noopFunc, SQLITE_FUNC_COALESCE),
+ VFUNCTION(random, 0, 0, 0, randomFunc ),
+ VFUNCTION(randomblob, 1, 0, 0, randomBlob ),
+ FUNCTION(nullif, 2, 0, 1, nullifFunc ),
+ DFUNCTION(sqlite_version, 0, 0, 0, versionFunc ),
+ DFUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ),
+ FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ),
+ FUNCTION(quote, 1, 0, 0, quoteFunc ),
+ VFUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid),
+ VFUNCTION(changes, 0, 0, 0, changes ),
+ VFUNCTION(total_changes, 0, 0, 0, total_changes ),
+ FUNCTION(replace, 3, 0, 0, replaceFunc ),
+ FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ),
+ FUNCTION(substr, 2, 0, 0, substrFunc ),
+ FUNCTION(substr, 3, 0, 0, substrFunc ),
+ AGGREGATE(sum, 1, 0, 0, sumStep, sumFinalize ),
+ AGGREGATE(total, 1, 0, 0, sumStep, totalFinalize ),
+ AGGREGATE(avg, 1, 0, 0, sumStep, avgFinalize ),
+ AGGREGATE2(count, 0, 0, 0, countStep, countFinalize,
+ SQLITE_FUNC_COUNT ),
+ AGGREGATE(count, 1, 0, 0, countStep, countFinalize ),
+ AGGREGATE(group_concat, 1, 0, 0, groupConcatStep, groupConcatFinalize),
+ AGGREGATE(group_concat, 2, 0, 0, groupConcatStep, groupConcatFinalize),
+
+ LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
+#ifdef SQLITE_CASE_SENSITIVE_LIKE
+ LIKEFUNC(like, 2, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
+ LIKEFUNC(like, 3, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
+#else
+ LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE),
+ LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE),
+#endif
+#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
+ FUNCTION(unknown, -1, 0, 0, unknownFunc ),
+#endif
+ FUNCTION(coalesce, 1, 0, 0, 0 ),
+ FUNCTION(coalesce, 0, 0, 0, 0 ),
+ FUNCTION2(coalesce, -1, 0, 0, noopFunc, SQLITE_FUNC_COALESCE),
+ };
+#ifndef SQLITE_OMIT_ALTERTABLE
+ sqlite3AlterFunctions();
+#endif
+#if defined(SQLITE_ENABLE_STAT3) || defined(SQLITE_ENABLE_STAT4)
+ sqlite3AnalyzeFunctions();
+#endif
+ sqlite3RegisterDateTimeFunctions();
+ sqlite3InsertBuiltinFuncs(aBuiltinFunc, ArraySize(aBuiltinFunc));
+
+#if 0 /* Enable to print out how the built-in functions are hashed */
+ {
+ int i;
+ FuncDef *p;
+ for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){
+ printf("FUNC-HASH %02d:", i);
+ for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash){
+ int n = sqlite3Strlen30(p->zName);
+ int h = p->zName[0] + n;
+ printf(" %s(%d)", p->zName, h);
+ }
+ printf("\n");
+ }
+ }
+#endif
+}
+
+/************** End of func.c ************************************************/
+/************** Begin file fkey.c ********************************************/
+/*
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains code used by the compiler to add foreign key
+** support to compiled SQL statements.
+*/
+/* #include "sqliteInt.h" */
+
+#ifndef SQLITE_OMIT_FOREIGN_KEY
+#ifndef SQLITE_OMIT_TRIGGER
+
+/*
+** Deferred and Immediate FKs
+** --------------------------
+**
+** Foreign keys in SQLite come in two flavours: deferred and immediate.
+** If an immediate foreign key constraint is violated,
+** SQLITE_CONSTRAINT_FOREIGNKEY is returned and the current
+** statement transaction rolled back. If a
+** deferred foreign key constraint is violated, no action is taken
+** immediately. However if the application attempts to commit the
+** transaction before fixing the constraint violation, the attempt fails.
+**
+** Deferred constraints are implemented using a simple counter associated
+** with the database handle. The counter is set to zero each time a
+** database transaction is opened. Each time a statement is executed
+** that causes a foreign key violation, the counter is incremented. Each
+** time a statement is executed that removes an existing violation from
+** the database, the counter is decremented. When the transaction is
+** committed, the commit fails if the current value of the counter is
+** greater than zero. This scheme has two big drawbacks:
+**
+** * When a commit fails due to a deferred foreign key constraint,
+** there is no way to tell which foreign constraint is not satisfied,
+** or which row it is not satisfied for.
+**
+** * If the database contains foreign key violations when the
+** transaction is opened, this may cause the mechanism to malfunction.
+**
+** Despite these problems, this approach is adopted as it seems simpler
+** than the alternatives.
+**
+** INSERT operations:
+**
+** I.1) For each FK for which the table is the child table, search
+** the parent table for a match. If none is found increment the
+** constraint counter.
+**
+** I.2) For each FK for which the table is the parent table,
+** search the child table for rows that correspond to the new
+** row in the parent table. Decrement the counter for each row
+** found (as the constraint is now satisfied).
+**
+** DELETE operations:
+**
+** D.1) For each FK for which the table is the child table,
+** search the parent table for a row that corresponds to the
+** deleted row in the child table. If such a row is not found,
+** decrement the counter.
+**
+** D.2) For each FK for which the table is the parent table, search
+** the child table for rows that correspond to the deleted row
+** in the parent table. For each found increment the counter.
+**
+** UPDATE operations:
+**
+** An UPDATE command requires that all 4 steps above are taken, but only
+** for FK constraints for which the affected columns are actually
+** modified (values must be compared at runtime).
+**
+** Note that I.1 and D.1 are very similar operations, as are I.2 and D.2.
+** This simplifies the implementation a bit.
+**
+** For the purposes of immediate FK constraints, the OR REPLACE conflict
+** resolution is considered to delete rows before the new row is inserted.
+** If a delete caused by OR REPLACE violates an FK constraint, an exception
+** is thrown, even if the FK constraint would be satisfied after the new
+** row is inserted.
+**
+** Immediate constraints are usually handled similarly. The only difference
+** is that the counter used is stored as part of each individual statement
+** object (struct Vdbe). If, after the statement has run, its immediate
+** constraint counter is greater than zero,
+** it returns SQLITE_CONSTRAINT_FOREIGNKEY
+** and the statement transaction is rolled back. An exception is an INSERT
+** statement that inserts a single row only (no triggers). In this case,
+** instead of using a counter, an exception is thrown immediately if the
+** INSERT violates a foreign key constraint. This is necessary as such
+** an INSERT does not open a statement transaction.
+**
+** TODO: How should dropping a table be handled? How should renaming a
+** table be handled?
+**
+**
+** Query API Notes
+** ---------------
+**
+** Before coding an UPDATE or DELETE row operation, the code-generator
+** for those two operations needs to know whether or not the operation
+** requires any FK processing and, if so, which columns of the original
+** row are required by the FK processing VDBE code (i.e. if FKs were
+** implemented using triggers, which of the old.* columns would be
+** accessed). No information is required by the code-generator before
+** coding an INSERT operation. The functions used by the UPDATE/DELETE
+** generation code to query for this information are:
+**
+** sqlite3FkRequired() - Test to see if FK processing is required.
+** sqlite3FkOldmask() - Query for the set of required old.* columns.
+**
+**
+** Externally accessible module functions
+** --------------------------------------
+**
+** sqlite3FkCheck() - Check for foreign key violations.
+** sqlite3FkActions() - Code triggers for ON UPDATE/ON DELETE actions.
+** sqlite3FkDelete() - Delete an FKey structure.
+*/
+
+/*
+** VDBE Calling Convention
+** -----------------------
+**
+** Example:
+**
+** For the following INSERT statement:
+**
+** CREATE TABLE t1(a, b INTEGER PRIMARY KEY, c);
+** INSERT INTO t1 VALUES(1, 2, 3.1);
+**
+** Register (x): 2 (type integer)
+** Register (x+1): 1 (type integer)
+** Register (x+2): NULL (type NULL)
+** Register (x+3): 3.1 (type real)
+*/
+
+/*
+** A foreign key constraint requires that the key columns in the parent
+** table are collectively subject to a UNIQUE or PRIMARY KEY constraint.
+** Given that pParent is the parent table for foreign key constraint pFKey,
+** search the schema for a unique index on the parent key columns.
+**
+** If successful, zero is returned. If the parent key is an INTEGER PRIMARY
+** KEY column, then output variable *ppIdx is set to NULL. Otherwise, *ppIdx
+** is set to point to the unique index.
+**
+** If the parent key consists of a single column (the foreign key constraint
+** is not a composite foreign key), output variable *paiCol is set to NULL.
+** Otherwise, it is set to point to an allocated array of size N, where
+** N is the number of columns in the parent key. The first element of the
+** array is the index of the child table column that is mapped by the FK
+** constraint to the parent table column stored in the left-most column
+** of index *ppIdx. The second element of the array is the index of the
+** child table column that corresponds to the second left-most column of
+** *ppIdx, and so on.
+**
+** If the required index cannot be found, either because:
+**
+** 1) The named parent key columns do not exist, or
+**
+** 2) The named parent key columns do exist, but are not subject to a
+** UNIQUE or PRIMARY KEY constraint, or
+**
+** 3) No parent key columns were provided explicitly as part of the
+** foreign key definition, and the parent table does not have a
+** PRIMARY KEY, or
+**
+** 4) No parent key columns were provided explicitly as part of the
+** foreign key definition, and the PRIMARY KEY of the parent table
+** consists of a different number of columns to the child key in
+** the child table.
+**
+** then non-zero is returned, and a "foreign key mismatch" error loaded
+** into pParse. If an OOM error occurs, non-zero is returned and the
+** pParse->db->mallocFailed flag is set.
+*/
+SQLITE_PRIVATE int sqlite3FkLocateIndex(
+ Parse *pParse, /* Parse context to store any error in */
+ Table *pParent, /* Parent table of FK constraint pFKey */
+ FKey *pFKey, /* Foreign key to find index for */
+ Index **ppIdx, /* OUT: Unique index on parent table */
+ int **paiCol /* OUT: Map of index columns in pFKey */
+){
+ Index *pIdx = 0; /* Value to return via *ppIdx */
+ int *aiCol = 0; /* Value to return via *paiCol */
+ int nCol = pFKey->nCol; /* Number of columns in parent key */
+ char *zKey = pFKey->aCol[0].zCol; /* Name of left-most parent key column */
+
+ /* The caller is responsible for zeroing output parameters. */
+ assert( ppIdx && *ppIdx==0 );
+ assert( !paiCol || *paiCol==0 );
+ assert( pParse );
+
+ /* If this is a non-composite (single column) foreign key, check if it
+ ** maps to the INTEGER PRIMARY KEY of table pParent. If so, leave *ppIdx
+ ** and *paiCol set to zero and return early.
+ **
+ ** Otherwise, for a composite foreign key (more than one column), allocate
+ ** space for the aiCol array (returned via output parameter *paiCol).
+ ** Non-composite foreign keys do not require the aiCol array.
+ */
+ if( nCol==1 ){
+ /* The FK maps to the IPK if any of the following are true:
+ **
+ ** 1) There is an INTEGER PRIMARY KEY column and the FK is implicitly
+ ** mapped to the primary key of table pParent, or
+ ** 2) The FK is explicitly mapped to a column declared as INTEGER
+ ** PRIMARY KEY.
+ */
+ if( pParent->iPKey>=0 ){
+ if( !zKey ) return 0;
+ if( !sqlite3StrICmp(pParent->aCol[pParent->iPKey].zName, zKey) ) return 0;
+ }
+ }else if( paiCol ){
+ assert( nCol>1 );
+ aiCol = (int *)sqlite3DbMallocRawNN(pParse->db, nCol*sizeof(int));
+ if( !aiCol ) return 1;
+ *paiCol = aiCol;
+ }
+
+ for(pIdx=pParent->pIndex; pIdx; pIdx=pIdx->pNext){
+ if( pIdx->nKeyCol==nCol && IsUniqueIndex(pIdx) && pIdx->pPartIdxWhere==0 ){
+ /* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number
+ ** of columns. If each indexed column corresponds to a foreign key
+ ** column of pFKey, then this index is a winner. */
+
+ if( zKey==0 ){
+ /* If zKey is NULL, then this foreign key is implicitly mapped to
+ ** the PRIMARY KEY of table pParent. The PRIMARY KEY index may be
+ ** identified by the test. */
+ if( IsPrimaryKeyIndex(pIdx) ){
+ if( aiCol ){
+ int i;
+ for(i=0; i<nCol; i++) aiCol[i] = pFKey->aCol[i].iFrom;
+ }
+ break;
+ }
+ }else{
+ /* If zKey is non-NULL, then this foreign key was declared to
+ ** map to an explicit list of columns in table pParent. Check if this
+ ** index matches those columns. Also, check that the index uses
+ ** the default collation sequences for each column. */
+ int i, j;
+ for(i=0; i<nCol; i++){
+ i16 iCol = pIdx->aiColumn[i]; /* Index of column in parent tbl */
+ const char *zDfltColl; /* Def. collation for column */
+ char *zIdxCol; /* Name of indexed column */
+
+ if( iCol<0 ) break; /* No foreign keys against expression indexes */
+
+ /* If the index uses a collation sequence that is different from
+ ** the default collation sequence for the column, this index is
+ ** unusable. Bail out early in this case. */
+ zDfltColl = pParent->aCol[iCol].zColl;
+ if( !zDfltColl ) zDfltColl = sqlite3StrBINARY;
+ if( sqlite3StrICmp(pIdx->azColl[i], zDfltColl) ) break;
+
+ zIdxCol = pParent->aCol[iCol].zName;
+ for(j=0; j<nCol; j++){
+ if( sqlite3StrICmp(pFKey->aCol[j].zCol, zIdxCol)==0 ){
+ if( aiCol ) aiCol[i] = pFKey->aCol[j].iFrom;
+ break;
+ }
+ }
+ if( j==nCol ) break;
+ }
+ if( i==nCol ) break; /* pIdx is usable */
+ }
+ }
+ }
+
+ if( !pIdx ){
+ if( !pParse->disableTriggers ){
+ sqlite3ErrorMsg(pParse,
+ "foreign key mismatch - \"%w\" referencing \"%w\"",
+ pFKey->pFrom->zName, pFKey->zTo);
+ }
+ sqlite3DbFree(pParse->db, aiCol);
+ return 1;
+ }
+
+ *ppIdx = pIdx;
+ return 0;
+}
+
+/*
+** This function is called when a row is inserted into or deleted from the
+** child table of foreign key constraint pFKey. If an SQL UPDATE is executed
+** on the child table of pFKey, this function is invoked twice for each row
+** affected - once to "delete" the old row, and then again to "insert" the
+** new row.
+**
+** Each time it is called, this function generates VDBE code to locate the
+** row in the parent table that corresponds to the row being inserted into
+** or deleted from the child table. If the parent row can be found, no
+** special action is taken. Otherwise, if the parent row can *not* be
+** found in the parent table:
+**
+** Operation | FK type | Action taken
+** --------------------------------------------------------------------------
+** INSERT immediate Increment the "immediate constraint counter".
+**
+** DELETE immediate Decrement the "immediate constraint counter".
+**
+** INSERT deferred Increment the "deferred constraint counter".
+**
+** DELETE deferred Decrement the "deferred constraint counter".
+**
+** These operations are identified in the comment at the top of this file
+** (fkey.c) as "I.1" and "D.1".
+*/
+static void fkLookupParent(
+ Parse *pParse, /* Parse context */
+ int iDb, /* Index of database housing pTab */
+ Table *pTab, /* Parent table of FK pFKey */
+ Index *pIdx, /* Unique index on parent key columns in pTab */
+ FKey *pFKey, /* Foreign key constraint */
+ int *aiCol, /* Map from parent key columns to child table columns */
+ int regData, /* Address of array containing child table row */
+ int nIncr, /* Increment constraint counter by this */
+ int isIgnore /* If true, pretend pTab contains all NULL values */
+){
+ int i; /* Iterator variable */
+ Vdbe *v = sqlite3GetVdbe(pParse); /* Vdbe to add code to */
+ int iCur = pParse->nTab - 1; /* Cursor number to use */
+ int iOk = sqlite3VdbeMakeLabel(v); /* jump here if parent key found */
+
+ /* If nIncr is less than zero, then check at runtime if there are any
+ ** outstanding constraints to resolve. If there are not, there is no need
+ ** to check if deleting this row resolves any outstanding violations.
+ **
+ ** Check if any of the key columns in the child table row are NULL. If
+ ** any are, then the constraint is considered satisfied. No need to
+ ** search for a matching row in the parent table. */
+ if( nIncr<0 ){
+ sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, iOk);
+ VdbeCoverage(v);
+ }
+ for(i=0; i<pFKey->nCol; i++){
+ int iReg = aiCol[i] + regData + 1;
+ sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iOk); VdbeCoverage(v);
+ }
+
+ if( isIgnore==0 ){
+ if( pIdx==0 ){
+ /* If pIdx is NULL, then the parent key is the INTEGER PRIMARY KEY
+ ** column of the parent table (table pTab). */
+ int iMustBeInt; /* Address of MustBeInt instruction */
+ int regTemp = sqlite3GetTempReg(pParse);
+
+ /* Invoke MustBeInt to coerce the child key value to an integer (i.e.
+ ** apply the affinity of the parent key). If this fails, then there
+ ** is no matching parent key. Before using MustBeInt, make a copy of
+ ** the value. Otherwise, the value inserted into the child key column
+ ** will have INTEGER affinity applied to it, which may not be correct. */
+ sqlite3VdbeAddOp2(v, OP_SCopy, aiCol[0]+1+regData, regTemp);
+ iMustBeInt = sqlite3VdbeAddOp2(v, OP_MustBeInt, regTemp, 0);
+ VdbeCoverage(v);
+
+ /* If the parent table is the same as the child table, and we are about
+ ** to increment the constraint-counter (i.e. this is an INSERT operation),
+ ** then check if the row being inserted matches itself. If so, do not
+ ** increment the constraint-counter. */
+ if( pTab==pFKey->pFrom && nIncr==1 ){
+ sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp); VdbeCoverage(v);
+ sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
+ }
+
+ sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
+ sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp); VdbeCoverage(v);
+ sqlite3VdbeGoto(v, iOk);
+ sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
+ sqlite3VdbeJumpHere(v, iMustBeInt);
+ sqlite3ReleaseTempReg(pParse, regTemp);
+ }else{
+ int nCol = pFKey->nCol;
+ int regTemp = sqlite3GetTempRange(pParse, nCol);
+ int regRec = sqlite3GetTempReg(pParse);
+
+ sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb);
+ sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
+ for(i=0; i<nCol; i++){
+ sqlite3VdbeAddOp2(v, OP_Copy, aiCol[i]+1+regData, regTemp+i);
+ }
+
+ /* If the parent table is the same as the child table, and we are about
+ ** to increment the constraint-counter (i.e. this is an INSERT operation),
+ ** then check if the row being inserted matches itself. If so, do not
+ ** increment the constraint-counter.
+ **
+ ** If any of the parent-key values are NULL, then the row cannot match
+ ** itself. So set JUMPIFNULL to make sure we do the OP_Found if any
+ ** of the parent-key values are NULL (at this point it is known that
+ ** none of the child key values are).
+ */
+ if( pTab==pFKey->pFrom && nIncr==1 ){
+ int iJump = sqlite3VdbeCurrentAddr(v) + nCol + 1;
+ for(i=0; i<nCol; i++){
+ int iChild = aiCol[i]+1+regData;
+ int iParent = pIdx->aiColumn[i]+1+regData;
+ assert( pIdx->aiColumn[i]>=0 );
+ assert( aiCol[i]!=pTab->iPKey );
+ if( pIdx->aiColumn[i]==pTab->iPKey ){
+ /* The parent key is a composite key that includes the IPK column */
+ iParent = regData;
+ }
+ sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent); VdbeCoverage(v);
+ sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
+ }
+ sqlite3VdbeGoto(v, iOk);
+ }
+
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, regTemp, nCol, regRec,
+ sqlite3IndexAffinityStr(pParse->db,pIdx), nCol);
+ sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0); VdbeCoverage(v);
+
+ sqlite3ReleaseTempReg(pParse, regRec);
+ sqlite3ReleaseTempRange(pParse, regTemp, nCol);
+ }
+ }
+
+ if( !pFKey->isDeferred && !(pParse->db->flags & SQLITE_DeferFKs)
+ && !pParse->pToplevel
+ && !pParse->isMultiWrite
+ ){
+ /* Special case: If this is an INSERT statement that will insert exactly
+ ** one row into the table, raise a constraint immediately instead of
+ ** incrementing a counter. This is necessary as the VM code is being
+ ** generated for will not open a statement transaction. */
+ assert( nIncr==1 );
+ sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
+ OE_Abort, 0, P4_STATIC, P5_ConstraintFK);
+ }else{
+ if( nIncr>0 && pFKey->isDeferred==0 ){
+ sqlite3MayAbort(pParse);
+ }
+ sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
+ }
+
+ sqlite3VdbeResolveLabel(v, iOk);
+ sqlite3VdbeAddOp1(v, OP_Close, iCur);
+}
+
+
+/*
+** Return an Expr object that refers to a memory register corresponding
+** to column iCol of table pTab.
+**
+** regBase is the first of an array of register that contains the data
+** for pTab. regBase itself holds the rowid. regBase+1 holds the first
+** column. regBase+2 holds the second column, and so forth.
+*/
+static Expr *exprTableRegister(
+ Parse *pParse, /* Parsing and code generating context */
+ Table *pTab, /* The table whose content is at r[regBase]... */
+ int regBase, /* Contents of table pTab */
+ i16 iCol /* Which column of pTab is desired */
+){
+ Expr *pExpr;
+ Column *pCol;
+ const char *zColl;
+ sqlite3 *db = pParse->db;
+
+ pExpr = sqlite3Expr(db, TK_REGISTER, 0);
+ if( pExpr ){
+ if( iCol>=0 && iCol!=pTab->iPKey ){
+ pCol = &pTab->aCol[iCol];
+ pExpr->iTable = regBase + iCol + 1;
+ pExpr->affinity = pCol->affinity;
+ zColl = pCol->zColl;
+ if( zColl==0 ) zColl = db->pDfltColl->zName;
+ pExpr = sqlite3ExprAddCollateString(pParse, pExpr, zColl);
+ }else{
+ pExpr->iTable = regBase;
+ pExpr->affinity = SQLITE_AFF_INTEGER;
+ }
+ }
+ return pExpr;
+}
+
+/*
+** Return an Expr object that refers to column iCol of table pTab which
+** has cursor iCur.
+*/
+static Expr *exprTableColumn(
+ sqlite3 *db, /* The database connection */
+ Table *pTab, /* The table whose column is desired */
+ int iCursor, /* The open cursor on the table */
+ i16 iCol /* The column that is wanted */
+){
+ Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0);
+ if( pExpr ){
+ pExpr->pTab = pTab;
+ pExpr->iTable = iCursor;
+ pExpr->iColumn = iCol;
+ }
+ return pExpr;
+}
+
+/*
+** This function is called to generate code executed when a row is deleted
+** from the parent table of foreign key constraint pFKey and, if pFKey is
+** deferred, when a row is inserted into the same table. When generating
+** code for an SQL UPDATE operation, this function may be called twice -
+** once to "delete" the old row and once to "insert" the new row.
+**
+** Parameter nIncr is passed -1 when inserting a row (as this may decrease
+** the number of FK violations in the db) or +1 when deleting one (as this
+** may increase the number of FK constraint problems).
+**
+** The code generated by this function scans through the rows in the child
+** table that correspond to the parent table row being deleted or inserted.
+** For each child row found, one of the following actions is taken:
+**
+** Operation | FK type | Action taken
+** --------------------------------------------------------------------------
+** DELETE immediate Increment the "immediate constraint counter".
+** Or, if the ON (UPDATE|DELETE) action is RESTRICT,
+** throw a "FOREIGN KEY constraint failed" exception.
+**
+** INSERT immediate Decrement the "immediate constraint counter".
+**
+** DELETE deferred Increment the "deferred constraint counter".
+** Or, if the ON (UPDATE|DELETE) action is RESTRICT,
+** throw a "FOREIGN KEY constraint failed" exception.
+**
+** INSERT deferred Decrement the "deferred constraint counter".
+**
+** These operations are identified in the comment at the top of this file
+** (fkey.c) as "I.2" and "D.2".
+*/
+static void fkScanChildren(
+ Parse *pParse, /* Parse context */
+ SrcList *pSrc, /* The child table to be scanned */
+ Table *pTab, /* The parent table */
+ Index *pIdx, /* Index on parent covering the foreign key */
+ FKey *pFKey, /* The foreign key linking pSrc to pTab */
+ int *aiCol, /* Map from pIdx cols to child table cols */
+ int regData, /* Parent row data starts here */
+ int nIncr /* Amount to increment deferred counter by */
+){
+ sqlite3 *db = pParse->db; /* Database handle */
+ int i; /* Iterator variable */
+ Expr *pWhere = 0; /* WHERE clause to scan with */
+ NameContext sNameContext; /* Context used to resolve WHERE clause */
+ WhereInfo *pWInfo; /* Context used by sqlite3WhereXXX() */
+ int iFkIfZero = 0; /* Address of OP_FkIfZero */
+ Vdbe *v = sqlite3GetVdbe(pParse);
+
+ assert( pIdx==0 || pIdx->pTable==pTab );
+ assert( pIdx==0 || pIdx->nKeyCol==pFKey->nCol );
+ assert( pIdx!=0 || pFKey->nCol==1 );
+ assert( pIdx!=0 || HasRowid(pTab) );
+
+ if( nIncr<0 ){
+ iFkIfZero = sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, 0);
+ VdbeCoverage(v);
+ }
+
+ /* Create an Expr object representing an SQL expression like:
+ **
+ ** <parent-key1> = <child-key1> AND <parent-key2> = <child-key2> ...
+ **
+ ** The collation sequence used for the comparison should be that of
+ ** the parent key columns. The affinity of the parent key column should
+ ** be applied to each child key value before the comparison takes place.
+ */
+ for(i=0; i<pFKey->nCol; i++){
+ Expr *pLeft; /* Value from parent table row */
+ Expr *pRight; /* Column ref to child table */
+ Expr *pEq; /* Expression (pLeft = pRight) */
+ i16 iCol; /* Index of column in child table */
+ const char *zCol; /* Name of column in child table */
+
+ iCol = pIdx ? pIdx->aiColumn[i] : -1;
+ pLeft = exprTableRegister(pParse, pTab, regData, iCol);
+ iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
+ assert( iCol>=0 );
+ zCol = pFKey->pFrom->aCol[iCol].zName;
+ pRight = sqlite3Expr(db, TK_ID, zCol);
+ pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight);
+ pWhere = sqlite3ExprAnd(db, pWhere, pEq);
+ }
+
+ /* If the child table is the same as the parent table, then add terms
+ ** to the WHERE clause that prevent this entry from being scanned.
+ ** The added WHERE clause terms are like this:
+ **
+ ** $current_rowid!=rowid
+ ** NOT( $current_a==a AND $current_b==b AND ... )
+ **
+ ** The first form is used for rowid tables. The second form is used
+ ** for WITHOUT ROWID tables. In the second form, the primary key is
+ ** (a,b,...)
+ */
+ if( pTab==pFKey->pFrom && nIncr>0 ){
+ Expr *pNe; /* Expression (pLeft != pRight) */
+ Expr *pLeft; /* Value from parent table row */
+ Expr *pRight; /* Column ref to child table */
+ if( HasRowid(pTab) ){
+ pLeft = exprTableRegister(pParse, pTab, regData, -1);
+ pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, -1);
+ pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight);
+ }else{
+ Expr *pEq, *pAll = 0;
+ Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+ assert( pIdx!=0 );
+ for(i=0; i<pPk->nKeyCol; i++){
+ i16 iCol = pIdx->aiColumn[i];
+ assert( iCol>=0 );
+ pLeft = exprTableRegister(pParse, pTab, regData, iCol);
+ pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, iCol);
+ pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight);
+ pAll = sqlite3ExprAnd(db, pAll, pEq);
+ }
+ pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0);
+ }
+ pWhere = sqlite3ExprAnd(db, pWhere, pNe);
+ }
+
+ /* Resolve the references in the WHERE clause. */
+ memset(&sNameContext, 0, sizeof(NameContext));
+ sNameContext.pSrcList = pSrc;
+ sNameContext.pParse = pParse;
+ sqlite3ResolveExprNames(&sNameContext, pWhere);
+
+ /* Create VDBE to loop through the entries in pSrc that match the WHERE
+ ** clause. For each row found, increment either the deferred or immediate
+ ** foreign key constraint counter. */
+ pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0);
+ sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
+ if( pWInfo ){
+ sqlite3WhereEnd(pWInfo);
+ }
+
+ /* Clean up the WHERE clause constructed above. */
+ sqlite3ExprDelete(db, pWhere);
+ if( iFkIfZero ){
+ sqlite3VdbeJumpHere(v, iFkIfZero);
+ }
+}
+
+/*
+** This function returns a linked list of FKey objects (connected by
+** FKey.pNextTo) holding all children of table pTab. For example,
+** given the following schema:
+**
+** CREATE TABLE t1(a PRIMARY KEY);
+** CREATE TABLE t2(b REFERENCES t1(a);
+**
+** Calling this function with table "t1" as an argument returns a pointer
+** to the FKey structure representing the foreign key constraint on table
+** "t2". Calling this function with "t2" as the argument would return a
+** NULL pointer (as there are no FK constraints for which t2 is the parent
+** table).
+*/
+SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *pTab){
+ return (FKey *)sqlite3HashFind(&pTab->pSchema->fkeyHash, pTab->zName);
+}
+
+/*
+** The second argument is a Trigger structure allocated by the
+** fkActionTrigger() routine. This function deletes the Trigger structure
+** and all of its sub-components.
+**
+** The Trigger structure or any of its sub-components may be allocated from
+** the lookaside buffer belonging to database handle dbMem.
+*/
+static void fkTriggerDelete(sqlite3 *dbMem, Trigger *p){
+ if( p ){
+ TriggerStep *pStep = p->step_list;
+ sqlite3ExprDelete(dbMem, pStep->pWhere);
+ sqlite3ExprListDelete(dbMem, pStep->pExprList);
+ sqlite3SelectDelete(dbMem, pStep->pSelect);
+ sqlite3ExprDelete(dbMem, p->pWhen);
+ sqlite3DbFree(dbMem, p);
+ }
+}
+
+/*
+** This function is called to generate code that runs when table pTab is
+** being dropped from the database. The SrcList passed as the second argument
+** to this function contains a single entry guaranteed to resolve to
+** table pTab.
+**
+** Normally, no code is required. However, if either
+**
+** (a) The table is the parent table of a FK constraint, or
+** (b) The table is the child table of a deferred FK constraint and it is
+** determined at runtime that there are outstanding deferred FK
+** constraint violations in the database,
+**
+** then the equivalent of "DELETE FROM <tbl>" is executed before dropping
+** the table from the database. Triggers are disabled while running this
+** DELETE, but foreign key actions are not.
+*/
+SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){
+ sqlite3 *db = pParse->db;
+ if( (db->flags&SQLITE_ForeignKeys) && !IsVirtual(pTab) && !pTab->pSelect ){
+ int iSkip = 0;
+ Vdbe *v = sqlite3GetVdbe(pParse);
+
+ assert( v ); /* VDBE has already been allocated */
+ if( sqlite3FkReferences(pTab)==0 ){
+ /* Search for a deferred foreign key constraint for which this table
+ ** is the child table. If one cannot be found, return without
+ ** generating any VDBE code. If one can be found, then jump over
+ ** the entire DELETE if there are no outstanding deferred constraints
+ ** when this statement is run. */
+ FKey *p;
+ for(p=pTab->pFKey; p; p=p->pNextFrom){
+ if( p->isDeferred || (db->flags & SQLITE_DeferFKs) ) break;
+ }
+ if( !p ) return;
+ iSkip = sqlite3VdbeMakeLabel(v);
+ sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip); VdbeCoverage(v);
+ }
+
+ pParse->disableTriggers = 1;
+ sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0);
+ pParse->disableTriggers = 0;
+
+ /* If the DELETE has generated immediate foreign key constraint
+ ** violations, halt the VDBE and return an error at this point, before
+ ** any modifications to the schema are made. This is because statement
+ ** transactions are not able to rollback schema changes.
+ **
+ ** If the SQLITE_DeferFKs flag is set, then this is not required, as
+ ** the statement transaction will not be rolled back even if FK
+ ** constraints are violated.
+ */
+ if( (db->flags & SQLITE_DeferFKs)==0 ){
+ sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2);
+ VdbeCoverage(v);
+ sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
+ OE_Abort, 0, P4_STATIC, P5_ConstraintFK);
+ }
+
+ if( iSkip ){
+ sqlite3VdbeResolveLabel(v, iSkip);
+ }
+ }
+}
+
+
+/*
+** The second argument points to an FKey object representing a foreign key
+** for which pTab is the child table. An UPDATE statement against pTab
+** is currently being processed. For each column of the table that is
+** actually updated, the corresponding element in the aChange[] array
+** is zero or greater (if a column is unmodified the corresponding element
+** is set to -1). If the rowid column is modified by the UPDATE statement
+** the bChngRowid argument is non-zero.
+**
+** This function returns true if any of the columns that are part of the
+** child key for FK constraint *p are modified.
+*/
+static int fkChildIsModified(
+ Table *pTab, /* Table being updated */
+ FKey *p, /* Foreign key for which pTab is the child */
+ int *aChange, /* Array indicating modified columns */
+ int bChngRowid /* True if rowid is modified by this update */
+){
+ int i;
+ for(i=0; i<p->nCol; i++){
+ int iChildKey = p->aCol[i].iFrom;
+ if( aChange[iChildKey]>=0 ) return 1;
+ if( iChildKey==pTab->iPKey && bChngRowid ) return 1;
+ }
+ return 0;
+}
+
+/*
+** The second argument points to an FKey object representing a foreign key
+** for which pTab is the parent table. An UPDATE statement against pTab
+** is currently being processed. For each column of the table that is
+** actually updated, the corresponding element in the aChange[] array
+** is zero or greater (if a column is unmodified the corresponding element
+** is set to -1). If the rowid column is modified by the UPDATE statement
+** the bChngRowid argument is non-zero.
+**
+** This function returns true if any of the columns that are part of the
+** parent key for FK constraint *p are modified.
+*/
+static int fkParentIsModified(
+ Table *pTab,
+ FKey *p,
+ int *aChange,
+ int bChngRowid
+){
+ int i;
+ for(i=0; i<p->nCol; i++){
+ char *zKey = p->aCol[i].zCol;
+ int iKey;
+ for(iKey=0; iKey<pTab->nCol; iKey++){
+ if( aChange[iKey]>=0 || (iKey==pTab->iPKey && bChngRowid) ){
+ Column *pCol = &pTab->aCol[iKey];
+ if( zKey ){
+ if( 0==sqlite3StrICmp(pCol->zName, zKey) ) return 1;
+ }else if( pCol->colFlags & COLFLAG_PRIMKEY ){
+ return 1;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+** Return true if the parser passed as the first argument is being
+** used to code a trigger that is really a "SET NULL" action belonging
+** to trigger pFKey.
+*/
+static int isSetNullAction(Parse *pParse, FKey *pFKey){
+ Parse *pTop = sqlite3ParseToplevel(pParse);
+ if( pTop->pTriggerPrg ){
+ Trigger *p = pTop->pTriggerPrg->pTrigger;
+ if( (p==pFKey->apTrigger[0] && pFKey->aAction[0]==OE_SetNull)
+ || (p==pFKey->apTrigger[1] && pFKey->aAction[1]==OE_SetNull)
+ ){
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/*
+** This function is called when inserting, deleting or updating a row of
+** table pTab to generate VDBE code to perform foreign key constraint
+** processing for the operation.
+**
+** For a DELETE operation, parameter regOld is passed the index of the
+** first register in an array of (pTab->nCol+1) registers containing the
+** rowid of the row being deleted, followed by each of the column values
+** of the row being deleted, from left to right. Parameter regNew is passed
+** zero in this case.
+**
+** For an INSERT operation, regOld is passed zero and regNew is passed the
+** first register of an array of (pTab->nCol+1) registers containing the new
+** row data.
+**
+** For an UPDATE operation, this function is called twice. Once before
+** the original record is deleted from the table using the calling convention
+** described for DELETE. Then again after the original record is deleted
+** but before the new record is inserted using the INSERT convention.
+*/
+SQLITE_PRIVATE void sqlite3FkCheck(
+ Parse *pParse, /* Parse context */
+ Table *pTab, /* Row is being deleted from this table */
+ int regOld, /* Previous row data is stored here */
+ int regNew, /* New row data is stored here */
+ int *aChange, /* Array indicating UPDATEd columns (or 0) */
+ int bChngRowid /* True if rowid is UPDATEd */
+){
+ sqlite3 *db = pParse->db; /* Database handle */
+ FKey *pFKey; /* Used to iterate through FKs */
+ int iDb; /* Index of database containing pTab */
+ const char *zDb; /* Name of database containing pTab */
+ int isIgnoreErrors = pParse->disableTriggers;
+
+ /* Exactly one of regOld and regNew should be non-zero. */
+ assert( (regOld==0)!=(regNew==0) );
+
+ /* If foreign-keys are disabled, this function is a no-op. */
+ if( (db->flags&SQLITE_ForeignKeys)==0 ) return;
+
+ iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+ zDb = db->aDb[iDb].zDbSName;
+
+ /* Loop through all the foreign key constraints for which pTab is the
+ ** child table (the table that the foreign key definition is part of). */
+ for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){
+ Table *pTo; /* Parent table of foreign key pFKey */
+ Index *pIdx = 0; /* Index on key columns in pTo */
+ int *aiFree = 0;
+ int *aiCol;
+ int iCol;
+ int i;
+ int bIgnore = 0;
+
+ if( aChange
+ && sqlite3_stricmp(pTab->zName, pFKey->zTo)!=0
+ && fkChildIsModified(pTab, pFKey, aChange, bChngRowid)==0
+ ){
+ continue;
+ }
+
+ /* Find the parent table of this foreign key. Also find a unique index
+ ** on the parent key columns in the parent table. If either of these
+ ** schema items cannot be located, set an error in pParse and return
+ ** early. */
+ if( pParse->disableTriggers ){
+ pTo = sqlite3FindTable(db, pFKey->zTo, zDb);
+ }else{
+ pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo, zDb);
+ }
+ if( !pTo || sqlite3FkLocateIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ){
+ assert( isIgnoreErrors==0 || (regOld!=0 && regNew==0) );
+ if( !isIgnoreErrors || db->mallocFailed ) return;
+ if( pTo==0 ){
+ /* If isIgnoreErrors is true, then a table is being dropped. In this
+ ** case SQLite runs a "DELETE FROM xxx" on the table being dropped
+ ** before actually dropping it in order to check FK constraints.
+ ** If the parent table of an FK constraint on the current table is
+ ** missing, behave as if it is empty. i.e. decrement the relevant
+ ** FK counter for each row of the current table with non-NULL keys.
+ */
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ int iJump = sqlite3VdbeCurrentAddr(v) + pFKey->nCol + 1;
+ for(i=0; i<pFKey->nCol; i++){
+ int iReg = pFKey->aCol[i].iFrom + regOld + 1;
+ sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iJump); VdbeCoverage(v);
+ }
+ sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, -1);
+ }
+ continue;
+ }
+ assert( pFKey->nCol==1 || (aiFree && pIdx) );
+
+ if( aiFree ){
+ aiCol = aiFree;
+ }else{
+ iCol = pFKey->aCol[0].iFrom;
+ aiCol = &iCol;
+ }
+ for(i=0; i<pFKey->nCol; i++){
+ if( aiCol[i]==pTab->iPKey ){
+ aiCol[i] = -1;
+ }
+ assert( pIdx==0 || pIdx->aiColumn[i]>=0 );
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ /* Request permission to read the parent key columns. If the
+ ** authorization callback returns SQLITE_IGNORE, behave as if any
+ ** values read from the parent table are NULL. */
+ if( db->xAuth ){
+ int rcauth;
+ char *zCol = pTo->aCol[pIdx ? pIdx->aiColumn[i] : pTo->iPKey].zName;
+ rcauth = sqlite3AuthReadCol(pParse, pTo->zName, zCol, iDb);
+ bIgnore = (rcauth==SQLITE_IGNORE);
+ }
+#endif
+ }
+
+ /* Take a shared-cache advisory read-lock on the parent table. Allocate
+ ** a cursor to use to search the unique index on the parent key columns
+ ** in the parent table. */
+ sqlite3TableLock(pParse, iDb, pTo->tnum, 0, pTo->zName);
+ pParse->nTab++;
+
+ if( regOld!=0 ){
+ /* A row is being removed from the child table. Search for the parent.
+ ** If the parent does not exist, removing the child row resolves an
+ ** outstanding foreign key constraint violation. */
+ fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regOld, -1, bIgnore);
+ }
+ if( regNew!=0 && !isSetNullAction(pParse, pFKey) ){
+ /* A row is being added to the child table. If a parent row cannot
+ ** be found, adding the child row has violated the FK constraint.
+ **
+ ** If this operation is being performed as part of a trigger program
+ ** that is actually a "SET NULL" action belonging to this very
+ ** foreign key, then omit this scan altogether. As all child key
+ ** values are guaranteed to be NULL, it is not possible for adding
+ ** this row to cause an FK violation. */
+ fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regNew, +1, bIgnore);
+ }
+
+ sqlite3DbFree(db, aiFree);
+ }
+
+ /* Loop through all the foreign key constraints that refer to this table.
+ ** (the "child" constraints) */
+ for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){
+ Index *pIdx = 0; /* Foreign key index for pFKey */
+ SrcList *pSrc;
+ int *aiCol = 0;
+
+ if( aChange && fkParentIsModified(pTab, pFKey, aChange, bChngRowid)==0 ){
+ continue;
+ }
+
+ if( !pFKey->isDeferred && !(db->flags & SQLITE_DeferFKs)
+ && !pParse->pToplevel && !pParse->isMultiWrite
+ ){
+ assert( regOld==0 && regNew!=0 );
+ /* Inserting a single row into a parent table cannot cause (or fix)
+ ** an immediate foreign key violation. So do nothing in this case. */
+ continue;
+ }
+
+ if( sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ){
+ if( !isIgnoreErrors || db->mallocFailed ) return;
+ continue;
+ }
+ assert( aiCol || pFKey->nCol==1 );
+
+ /* Create a SrcList structure containing the child table. We need the
+ ** child table as a SrcList for sqlite3WhereBegin() */
+ pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
+ if( pSrc ){
+ struct SrcList_item *pItem = pSrc->a;
+ pItem->pTab = pFKey->pFrom;
+ pItem->zName = pFKey->pFrom->zName;
+ pItem->pTab->nTabRef++;
+ pItem->iCursor = pParse->nTab++;
+
+ if( regNew!=0 ){
+ fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regNew, -1);
+ }
+ if( regOld!=0 ){
+ int eAction = pFKey->aAction[aChange!=0];
+ fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regOld, 1);
+ /* If this is a deferred FK constraint, or a CASCADE or SET NULL
+ ** action applies, then any foreign key violations caused by
+ ** removing the parent key will be rectified by the action trigger.
+ ** So do not set the "may-abort" flag in this case.
+ **
+ ** Note 1: If the FK is declared "ON UPDATE CASCADE", then the
+ ** may-abort flag will eventually be set on this statement anyway
+ ** (when this function is called as part of processing the UPDATE
+ ** within the action trigger).
+ **
+ ** Note 2: At first glance it may seem like SQLite could simply omit
+ ** all OP_FkCounter related scans when either CASCADE or SET NULL
+ ** applies. The trouble starts if the CASCADE or SET NULL action
+ ** trigger causes other triggers or action rules attached to the
+ ** child table to fire. In these cases the fk constraint counters
+ ** might be set incorrectly if any OP_FkCounter related scans are
+ ** omitted. */
+ if( !pFKey->isDeferred && eAction!=OE_Cascade && eAction!=OE_SetNull ){
+ sqlite3MayAbort(pParse);
+ }
+ }
+ pItem->zName = 0;
+ sqlite3SrcListDelete(db, pSrc);
+ }
+ sqlite3DbFree(db, aiCol);
+ }
+}
+
+#define COLUMN_MASK(x) (((x)>31) ? 0xffffffff : ((u32)1<<(x)))
+
+/*
+** This function is called before generating code to update or delete a
+** row contained in table pTab.
+*/
+SQLITE_PRIVATE u32 sqlite3FkOldmask(
+ Parse *pParse, /* Parse context */
+ Table *pTab /* Table being modified */
+){
+ u32 mask = 0;
+ if( pParse->db->flags&SQLITE_ForeignKeys ){
+ FKey *p;
+ int i;
+ for(p=pTab->pFKey; p; p=p->pNextFrom){
+ for(i=0; i<p->nCol; i++) mask |= COLUMN_MASK(p->aCol[i].iFrom);
+ }
+ for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
+ Index *pIdx = 0;
+ sqlite3FkLocateIndex(pParse, pTab, p, &pIdx, 0);
+ if( pIdx ){
+ for(i=0; i<pIdx->nKeyCol; i++){
+ assert( pIdx->aiColumn[i]>=0 );
+ mask |= COLUMN_MASK(pIdx->aiColumn[i]);
+ }
+ }
+ }
+ }
+ return mask;
+}
+
+
+/*
+** This function is called before generating code to update or delete a
+** row contained in table pTab. If the operation is a DELETE, then
+** parameter aChange is passed a NULL value. For an UPDATE, aChange points
+** to an array of size N, where N is the number of columns in table pTab.
+** If the i'th column is not modified by the UPDATE, then the corresponding
+** entry in the aChange[] array is set to -1. If the column is modified,
+** the value is 0 or greater. Parameter chngRowid is set to true if the
+** UPDATE statement modifies the rowid fields of the table.
+**
+** If any foreign key processing will be required, this function returns
+** true. If there is no foreign key related processing, this function
+** returns false.
+*/
+SQLITE_PRIVATE int sqlite3FkRequired(
+ Parse *pParse, /* Parse context */
+ Table *pTab, /* Table being modified */
+ int *aChange, /* Non-NULL for UPDATE operations */
+ int chngRowid /* True for UPDATE that affects rowid */
+){
+ if( pParse->db->flags&SQLITE_ForeignKeys ){
+ if( !aChange ){
+ /* A DELETE operation. Foreign key processing is required if the
+ ** table in question is either the child or parent table for any
+ ** foreign key constraint. */
+ return (sqlite3FkReferences(pTab) || pTab->pFKey);
+ }else{
+ /* This is an UPDATE. Foreign key processing is only required if the
+ ** operation modifies one or more child or parent key columns. */
+ FKey *p;
+
+ /* Check if any child key columns are being modified. */
+ for(p=pTab->pFKey; p; p=p->pNextFrom){
+ if( fkChildIsModified(pTab, p, aChange, chngRowid) ) return 1;
+ }
+
+ /* Check if any parent key columns are being modified. */
+ for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
+ if( fkParentIsModified(pTab, p, aChange, chngRowid) ) return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+** This function is called when an UPDATE or DELETE operation is being
+** compiled on table pTab, which is the parent table of foreign-key pFKey.
+** If the current operation is an UPDATE, then the pChanges parameter is
+** passed a pointer to the list of columns being modified. If it is a
+** DELETE, pChanges is passed a NULL pointer.
+**
+** It returns a pointer to a Trigger structure containing a trigger
+** equivalent to the ON UPDATE or ON DELETE action specified by pFKey.
+** If the action is "NO ACTION" or "RESTRICT", then a NULL pointer is
+** returned (these actions require no special handling by the triggers
+** sub-system, code for them is created by fkScanChildren()).
+**
+** For example, if pFKey is the foreign key and pTab is table "p" in
+** the following schema:
+**
+** CREATE TABLE p(pk PRIMARY KEY);
+** CREATE TABLE c(ck REFERENCES p ON DELETE CASCADE);
+**
+** then the returned trigger structure is equivalent to:
+**
+** CREATE TRIGGER ... DELETE ON p BEGIN
+** DELETE FROM c WHERE ck = old.pk;
+** END;
+**
+** The returned pointer is cached as part of the foreign key object. It
+** is eventually freed along with the rest of the foreign key object by
+** sqlite3FkDelete().
+*/
+static Trigger *fkActionTrigger(
+ Parse *pParse, /* Parse context */
+ Table *pTab, /* Table being updated or deleted from */
+ FKey *pFKey, /* Foreign key to get action for */
+ ExprList *pChanges /* Change-list for UPDATE, NULL for DELETE */
+){
+ sqlite3 *db = pParse->db; /* Database handle */
+ int action; /* One of OE_None, OE_Cascade etc. */
+ Trigger *pTrigger; /* Trigger definition to return */
+ int iAction = (pChanges!=0); /* 1 for UPDATE, 0 for DELETE */
+
+ action = pFKey->aAction[iAction];
+ if( action==OE_Restrict && (db->flags & SQLITE_DeferFKs) ){
+ return 0;
+ }
+ pTrigger = pFKey->apTrigger[iAction];
+
+ if( action!=OE_None && !pTrigger ){
+ char const *zFrom; /* Name of child table */
+ int nFrom; /* Length in bytes of zFrom */
+ Index *pIdx = 0; /* Parent key index for this FK */
+ int *aiCol = 0; /* child table cols -> parent key cols */
+ TriggerStep *pStep = 0; /* First (only) step of trigger program */
+ Expr *pWhere = 0; /* WHERE clause of trigger step */
+ ExprList *pList = 0; /* Changes list if ON UPDATE CASCADE */
+ Select *pSelect = 0; /* If RESTRICT, "SELECT RAISE(...)" */
+ int i; /* Iterator variable */
+ Expr *pWhen = 0; /* WHEN clause for the trigger */
+
+ if( sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ) return 0;
+ assert( aiCol || pFKey->nCol==1 );
+
+ for(i=0; i<pFKey->nCol; i++){
+ Token tOld = { "old", 3 }; /* Literal "old" token */
+ Token tNew = { "new", 3 }; /* Literal "new" token */
+ Token tFromCol; /* Name of column in child table */
+ Token tToCol; /* Name of column in parent table */
+ int iFromCol; /* Idx of column in child table */
+ Expr *pEq; /* tFromCol = OLD.tToCol */
+
+ iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
+ assert( iFromCol>=0 );
+ assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKey<pTab->nCol) );
+ assert( pIdx==0 || pIdx->aiColumn[i]>=0 );
+ sqlite3TokenInit(&tToCol,
+ pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName);
+ sqlite3TokenInit(&tFromCol, pFKey->pFrom->aCol[iFromCol].zName);
+
+ /* Create the expression "OLD.zToCol = zFromCol". It is important
+ ** that the "OLD.zToCol" term is on the LHS of the = operator, so
+ ** that the affinity and collation sequence associated with the
+ ** parent table are used for the comparison. */
+ pEq = sqlite3PExpr(pParse, TK_EQ,
+ sqlite3PExpr(pParse, TK_DOT,
+ sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
+ sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)),
+ sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0)
+ );
+ pWhere = sqlite3ExprAnd(db, pWhere, pEq);
+
+ /* For ON UPDATE, construct the next term of the WHEN clause.
+ ** The final WHEN clause will be like this:
+ **
+ ** WHEN NOT(old.col1 IS new.col1 AND ... AND old.colN IS new.colN)
+ */
+ if( pChanges ){
+ pEq = sqlite3PExpr(pParse, TK_IS,
+ sqlite3PExpr(pParse, TK_DOT,
+ sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
+ sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)),
+ sqlite3PExpr(pParse, TK_DOT,
+ sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
+ sqlite3ExprAlloc(db, TK_ID, &tToCol, 0))
+ );
+ pWhen = sqlite3ExprAnd(db, pWhen, pEq);
+ }
+
+ if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){
+ Expr *pNew;
+ if( action==OE_Cascade ){
+ pNew = sqlite3PExpr(pParse, TK_DOT,
+ sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
+ sqlite3ExprAlloc(db, TK_ID, &tToCol, 0));
+ }else if( action==OE_SetDflt ){
+ Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt;
+ if( pDflt ){
+ pNew = sqlite3ExprDup(db, pDflt, 0);
+ }else{
+ pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0);
+ }
+ }else{
+ pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0);
+ }
+ pList = sqlite3ExprListAppend(pParse, pList, pNew);
+ sqlite3ExprListSetName(pParse, pList, &tFromCol, 0);
+ }
+ }
+ sqlite3DbFree(db, aiCol);
+
+ zFrom = pFKey->pFrom->zName;
+ nFrom = sqlite3Strlen30(zFrom);
+
+ if( action==OE_Restrict ){
+ Token tFrom;
+ Expr *pRaise;
+
+ tFrom.z = zFrom;
+ tFrom.n = nFrom;
+ pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed");
+ if( pRaise ){
+ pRaise->affinity = OE_Abort;
+ }
+ pSelect = sqlite3SelectNew(pParse,
+ sqlite3ExprListAppend(pParse, 0, pRaise),
+ sqlite3SrcListAppend(db, 0, &tFrom, 0),
+ pWhere,
+ 0, 0, 0, 0, 0, 0
+ );
+ pWhere = 0;
+ }
+
+ /* Disable lookaside memory allocation */
+ db->lookaside.bDisable++;
+
+ pTrigger = (Trigger *)sqlite3DbMallocZero(db,
+ sizeof(Trigger) + /* struct Trigger */
+ sizeof(TriggerStep) + /* Single step in trigger program */
+ nFrom + 1 /* Space for pStep->zTarget */
+ );
+ if( pTrigger ){
+ pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1];
+ pStep->zTarget = (char *)&pStep[1];
+ memcpy((char *)pStep->zTarget, zFrom, nFrom);
+
+ pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
+ pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE);
+ pStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
+ if( pWhen ){
+ pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0);
+ pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE);
+ }
+ }
+
+ /* Re-enable the lookaside buffer, if it was disabled earlier. */
+ db->lookaside.bDisable--;
+
+ sqlite3ExprDelete(db, pWhere);
+ sqlite3ExprDelete(db, pWhen);
+ sqlite3ExprListDelete(db, pList);
+ sqlite3SelectDelete(db, pSelect);
+ if( db->mallocFailed==1 ){
+ fkTriggerDelete(db, pTrigger);
+ return 0;
+ }
+ assert( pStep!=0 );
+
+ switch( action ){
+ case OE_Restrict:
+ pStep->op = TK_SELECT;
+ break;
+ case OE_Cascade:
+ if( !pChanges ){
+ pStep->op = TK_DELETE;
+ break;
+ }
+ default:
+ pStep->op = TK_UPDATE;
+ }
+ pStep->pTrig = pTrigger;
+ pTrigger->pSchema = pTab->pSchema;
+ pTrigger->pTabSchema = pTab->pSchema;
+ pFKey->apTrigger[iAction] = pTrigger;
+ pTrigger->op = (pChanges ? TK_UPDATE : TK_DELETE);
+ }
+
+ return pTrigger;
+}
+
+/*
+** This function is called when deleting or updating a row to implement
+** any required CASCADE, SET NULL or SET DEFAULT actions.
+*/
+SQLITE_PRIVATE void sqlite3FkActions(
+ Parse *pParse, /* Parse context */
+ Table *pTab, /* Table being updated or deleted from */
+ ExprList *pChanges, /* Change-list for UPDATE, NULL for DELETE */
+ int regOld, /* Address of array containing old row */
+ int *aChange, /* Array indicating UPDATEd columns (or 0) */
+ int bChngRowid /* True if rowid is UPDATEd */
+){
+ /* If foreign-key support is enabled, iterate through all FKs that
+ ** refer to table pTab. If there is an action associated with the FK
+ ** for this operation (either update or delete), invoke the associated
+ ** trigger sub-program. */
+ if( pParse->db->flags&SQLITE_ForeignKeys ){
+ FKey *pFKey; /* Iterator variable */
+ for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){
+ if( aChange==0 || fkParentIsModified(pTab, pFKey, aChange, bChngRowid) ){
+ Trigger *pAct = fkActionTrigger(pParse, pTab, pFKey, pChanges);
+ if( pAct ){
+ sqlite3CodeRowTriggerDirect(pParse, pAct, pTab, regOld, OE_Abort, 0);
+ }
+ }
+ }
+ }
+}
+
+#endif /* ifndef SQLITE_OMIT_TRIGGER */
+
+/*
+** Free all memory associated with foreign key definitions attached to
+** table pTab. Remove the deleted foreign keys from the Schema.fkeyHash
+** hash table.
+*/
+SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *db, Table *pTab){
+ FKey *pFKey; /* Iterator variable */
+ FKey *pNext; /* Copy of pFKey->pNextFrom */
+
+ assert( db==0 || IsVirtual(pTab)
+ || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) );
+ for(pFKey=pTab->pFKey; pFKey; pFKey=pNext){
+
+ /* Remove the FK from the fkeyHash hash table. */
+ if( !db || db->pnBytesFreed==0 ){
+ if( pFKey->pPrevTo ){
+ pFKey->pPrevTo->pNextTo = pFKey->pNextTo;
+ }else{
+ void *p = (void *)pFKey->pNextTo;
+ const char *z = (p ? pFKey->pNextTo->zTo : pFKey->zTo);
+ sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, p);
+ }
+ if( pFKey->pNextTo ){
+ pFKey->pNextTo->pPrevTo = pFKey->pPrevTo;
+ }
+ }
+
+ /* EV: R-30323-21917 Each foreign key constraint in SQLite is
+ ** classified as either immediate or deferred.
+ */
+ assert( pFKey->isDeferred==0 || pFKey->isDeferred==1 );
+
+ /* Delete any triggers created to implement actions for this FK. */
+#ifndef SQLITE_OMIT_TRIGGER
+ fkTriggerDelete(db, pFKey->apTrigger[0]);
+ fkTriggerDelete(db, pFKey->apTrigger[1]);
+#endif
+
+ pNext = pFKey->pNextFrom;
+ sqlite3DbFree(db, pFKey);
+ }
+}
+#endif /* ifndef SQLITE_OMIT_FOREIGN_KEY */
+
+/************** End of fkey.c ************************************************/
+/************** Begin file insert.c ******************************************/
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains C code routines that are called by the parser
+** to handle INSERT statements in SQLite.
+*/
+/* #include "sqliteInt.h" */
+
+/*
+** Generate code that will
+**
+** (1) acquire a lock for table pTab then
+** (2) open pTab as cursor iCur.
+**
+** If pTab is a WITHOUT ROWID table, then it is the PRIMARY KEY index
+** for that table that is actually opened.
+*/
+SQLITE_PRIVATE void sqlite3OpenTable(
+ Parse *pParse, /* Generate code into this VDBE */
+ int iCur, /* The cursor number of the table */
+ int iDb, /* The database index in sqlite3.aDb[] */
+ Table *pTab, /* The table to be opened */
+ int opcode /* OP_OpenRead or OP_OpenWrite */
+){
+ Vdbe *v;
+ assert( !IsVirtual(pTab) );
+ v = sqlite3GetVdbe(pParse);
+ assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
+ sqlite3TableLock(pParse, iDb, pTab->tnum,
+ (opcode==OP_OpenWrite)?1:0, pTab->zName);
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb, pTab->nCol);
+ VdbeComment((v, "%s", pTab->zName));
+ }else{
+ Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+ assert( pPk!=0 );
+ assert( pPk->tnum==pTab->tnum );
+ sqlite3VdbeAddOp3(v, opcode, iCur, pPk->tnum, iDb);
+ sqlite3VdbeSetP4KeyInfo(pParse, pPk);
+ VdbeComment((v, "%s", pTab->zName));
+ }
+}
+
+/*
+** Return a pointer to the column affinity string associated with index
+** pIdx. A column affinity string has one character for each column in
+** the table, according to the affinity of the column:
+**
+** Character Column affinity
+** ------------------------------
+** 'A' BLOB
+** 'B' TEXT
+** 'C' NUMERIC
+** 'D' INTEGER
+** 'F' REAL
+**
+** An extra 'D' is appended to the end of the string to cover the
+** rowid that appears as the last column in every index.
+**
+** Memory for the buffer containing the column index affinity string
+** is managed along with the rest of the Index structure. It will be
+** released when sqlite3DeleteIndex() is called.
+*/
+SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){
+ if( !pIdx->zColAff ){
+ /* The first time a column affinity string for a particular index is
+ ** required, it is allocated and populated here. It is then stored as
+ ** a member of the Index structure for subsequent use.
+ **
+ ** The column affinity string will eventually be deleted by
+ ** sqliteDeleteIndex() when the Index structure itself is cleaned
+ ** up.
+ */
+ int n;
+ Table *pTab = pIdx->pTable;
+ pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1);
+ if( !pIdx->zColAff ){
+ sqlite3OomFault(db);
+ return 0;
+ }
+ for(n=0; n<pIdx->nColumn; n++){
+ i16 x = pIdx->aiColumn[n];
+ if( x>=0 ){
+ pIdx->zColAff[n] = pTab->aCol[x].affinity;
+ }else if( x==XN_ROWID ){
+ pIdx->zColAff[n] = SQLITE_AFF_INTEGER;
+ }else{
+ char aff;
+ assert( x==XN_EXPR );
+ assert( pIdx->aColExpr!=0 );
+ aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr);
+ if( aff==0 ) aff = SQLITE_AFF_BLOB;
+ pIdx->zColAff[n] = aff;
+ }
+ }
+ pIdx->zColAff[n] = 0;
+ }
+
+ return pIdx->zColAff;
+}
+
+/*
+** Compute the affinity string for table pTab, if it has not already been
+** computed. As an optimization, omit trailing SQLITE_AFF_BLOB affinities.
+**
+** If the affinity exists (if it is no entirely SQLITE_AFF_BLOB values) and
+** if iReg>0 then code an OP_Affinity opcode that will set the affinities
+** for register iReg and following. Or if affinities exists and iReg==0,
+** then just set the P4 operand of the previous opcode (which should be
+** an OP_MakeRecord) to the affinity string.
+**
+** A column affinity string has one character per column:
+**
+** Character Column affinity
+** ------------------------------
+** 'A' BLOB
+** 'B' TEXT
+** 'C' NUMERIC
+** 'D' INTEGER
+** 'E' REAL
+*/
+SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){
+ int i;
+ char *zColAff = pTab->zColAff;
+ if( zColAff==0 ){
+ sqlite3 *db = sqlite3VdbeDb(v);
+ zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1);
+ if( !zColAff ){
+ sqlite3OomFault(db);
+ return;
+ }
+
+ for(i=0; i<pTab->nCol; i++){
+ zColAff[i] = pTab->aCol[i].affinity;
+ }
+ do{
+ zColAff[i--] = 0;
+ }while( i>=0 && zColAff[i]==SQLITE_AFF_BLOB );
+ pTab->zColAff = zColAff;
+ }
+ i = sqlite3Strlen30(zColAff);
+ if( i ){
+ if( iReg ){
+ sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i);
+ }else{
+ sqlite3VdbeChangeP4(v, -1, zColAff, i);
+ }
+ }
+}
+
+/*
+** Return non-zero if the table pTab in database iDb or any of its indices
+** have been opened at any point in the VDBE program. This is used to see if
+** a statement of the form "INSERT INTO <iDb, pTab> SELECT ..." can
+** run without using a temporary table for the results of the SELECT.
+*/
+static int readsTable(Parse *p, int iDb, Table *pTab){
+ Vdbe *v = sqlite3GetVdbe(p);
+ int i;
+ int iEnd = sqlite3VdbeCurrentAddr(v);
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ VTable *pVTab = IsVirtual(pTab) ? sqlite3GetVTable(p->db, pTab) : 0;
+#endif
+
+ for(i=1; i<iEnd; i++){
+ VdbeOp *pOp = sqlite3VdbeGetOp(v, i);
+ assert( pOp!=0 );
+ if( pOp->opcode==OP_OpenRead && pOp->p3==iDb ){
+ Index *pIndex;
+ int tnum = pOp->p2;
+ if( tnum==pTab->tnum ){
+ return 1;
+ }
+ for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){
+ if( tnum==pIndex->tnum ){
+ return 1;
+ }
+ }
+ }
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ if( pOp->opcode==OP_VOpen && pOp->p4.pVtab==pVTab ){
+ assert( pOp->p4.pVtab!=0 );
+ assert( pOp->p4type==P4_VTAB );
+ return 1;
+ }
+#endif
+ }
+ return 0;
+}
+
+#ifndef SQLITE_OMIT_AUTOINCREMENT
+/*
+** Locate or create an AutoincInfo structure associated with table pTab
+** which is in database iDb. Return the register number for the register
+** that holds the maximum rowid. Return zero if pTab is not an AUTOINCREMENT
+** table. (Also return zero when doing a VACUUM since we do not want to
+** update the AUTOINCREMENT counters during a VACUUM.)
+**
+** There is at most one AutoincInfo structure per table even if the
+** same table is autoincremented multiple times due to inserts within
+** triggers. A new AutoincInfo structure is created if this is the
+** first use of table pTab. On 2nd and subsequent uses, the original
+** AutoincInfo structure is used.
+**
+** Three memory locations are allocated:
+**
+** (1) Register to hold the name of the pTab table.
+** (2) Register to hold the maximum ROWID of pTab.
+** (3) Register to hold the rowid in sqlite_sequence of pTab
+**
+** The 2nd register is the one that is returned. That is all the
+** insert routine needs to know about.
+*/
+static int autoIncBegin(
+ Parse *pParse, /* Parsing context */
+ int iDb, /* Index of the database holding pTab */
+ Table *pTab /* The table we are writing to */
+){
+ int memId = 0; /* Register holding maximum rowid */
+ if( (pTab->tabFlags & TF_Autoincrement)!=0
+ && (pParse->db->flags & SQLITE_Vacuum)==0
+ ){
+ Parse *pToplevel = sqlite3ParseToplevel(pParse);
+ AutoincInfo *pInfo;
+
+ pInfo = pToplevel->pAinc;
+ while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; }
+ if( pInfo==0 ){
+ pInfo = sqlite3DbMallocRawNN(pParse->db, sizeof(*pInfo));
+ if( pInfo==0 ) return 0;
+ pInfo->pNext = pToplevel->pAinc;
+ pToplevel->pAinc = pInfo;
+ pInfo->pTab = pTab;
+ pInfo->iDb = iDb;
+ pToplevel->nMem++; /* Register to hold name of table */
+ pInfo->regCtr = ++pToplevel->nMem; /* Max rowid register */
+ pToplevel->nMem++; /* Rowid in sqlite_sequence */
+ }
+ memId = pInfo->regCtr;
+ }
+ return memId;
+}
+
+/*
+** This routine generates code that will initialize all of the
+** register used by the autoincrement tracker.
+*/
+SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse){
+ AutoincInfo *p; /* Information about an AUTOINCREMENT */
+ sqlite3 *db = pParse->db; /* The database connection */
+ Db *pDb; /* Database only autoinc table */
+ int memId; /* Register holding max rowid */
+ Vdbe *v = pParse->pVdbe; /* VDBE under construction */
+
+ /* This routine is never called during trigger-generation. It is
+ ** only called from the top-level */
+ assert( pParse->pTriggerTab==0 );
+ assert( sqlite3IsToplevel(pParse) );
+
+ assert( v ); /* We failed long ago if this is not so */
+ for(p = pParse->pAinc; p; p = p->pNext){
+ static const int iLn = VDBE_OFFSET_LINENO(2);
+ static const VdbeOpList autoInc[] = {
+ /* 0 */ {OP_Null, 0, 0, 0},
+ /* 1 */ {OP_Rewind, 0, 9, 0},
+ /* 2 */ {OP_Column, 0, 0, 0},
+ /* 3 */ {OP_Ne, 0, 7, 0},
+ /* 4 */ {OP_Rowid, 0, 0, 0},
+ /* 5 */ {OP_Column, 0, 1, 0},
+ /* 6 */ {OP_Goto, 0, 9, 0},
+ /* 7 */ {OP_Next, 0, 2, 0},
+ /* 8 */ {OP_Integer, 0, 0, 0},
+ /* 9 */ {OP_Close, 0, 0, 0}
+ };
+ VdbeOp *aOp;
+ pDb = &db->aDb[p->iDb];
+ memId = p->regCtr;
+ assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) );
+ sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead);
+ sqlite3VdbeLoadString(v, memId-1, p->pTab->zName);
+ aOp = sqlite3VdbeAddOpList(v, ArraySize(autoInc), autoInc, iLn);
+ if( aOp==0 ) break;
+ aOp[0].p2 = memId;
+ aOp[0].p3 = memId+1;
+ aOp[2].p3 = memId;
+ aOp[3].p1 = memId-1;
+ aOp[3].p3 = memId;
+ aOp[3].p5 = SQLITE_JUMPIFNULL;
+ aOp[4].p2 = memId+1;
+ aOp[5].p3 = memId;
+ aOp[8].p2 = memId;
+ }
+}
+
+/*
+** Update the maximum rowid for an autoincrement calculation.
+**
+** This routine should be called when the regRowid register holds a
+** new rowid that is about to be inserted. If that new rowid is
+** larger than the maximum rowid in the memId memory cell, then the
+** memory cell is updated.
+*/
+static void autoIncStep(Parse *pParse, int memId, int regRowid){
+ if( memId>0 ){
+ sqlite3VdbeAddOp2(pParse->pVdbe, OP_MemMax, memId, regRowid);
+ }
+}
+
+/*
+** This routine generates the code needed to write autoincrement
+** maximum rowid values back into the sqlite_sequence register.
+** Every statement that might do an INSERT into an autoincrement
+** table (either directly or through triggers) needs to call this
+** routine just before the "exit" code.
+*/
+static SQLITE_NOINLINE void autoIncrementEnd(Parse *pParse){
+ AutoincInfo *p;
+ Vdbe *v = pParse->pVdbe;
+ sqlite3 *db = pParse->db;
+
+ assert( v );
+ for(p = pParse->pAinc; p; p = p->pNext){
+ static const int iLn = VDBE_OFFSET_LINENO(2);
+ static const VdbeOpList autoIncEnd[] = {
+ /* 0 */ {OP_NotNull, 0, 2, 0},
+ /* 1 */ {OP_NewRowid, 0, 0, 0},
+ /* 2 */ {OP_MakeRecord, 0, 2, 0},
+ /* 3 */ {OP_Insert, 0, 0, 0},
+ /* 4 */ {OP_Close, 0, 0, 0}
+ };
+ VdbeOp *aOp;
+ Db *pDb = &db->aDb[p->iDb];
+ int iRec;
+ int memId = p->regCtr;
+
+ iRec = sqlite3GetTempReg(pParse);
+ assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) );
+ sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
+ aOp = sqlite3VdbeAddOpList(v, ArraySize(autoIncEnd), autoIncEnd, iLn);
+ if( aOp==0 ) break;
+ aOp[0].p1 = memId+1;
+ aOp[1].p2 = memId+1;
+ aOp[2].p1 = memId-1;
+ aOp[2].p3 = iRec;
+ aOp[3].p2 = iRec;
+ aOp[3].p3 = memId+1;
+ aOp[3].p5 = OPFLAG_APPEND;
+ sqlite3ReleaseTempReg(pParse, iRec);
+ }
+}
+SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse){
+ if( pParse->pAinc ) autoIncrementEnd(pParse);
+}
+#else
+/*
+** If SQLITE_OMIT_AUTOINCREMENT is defined, then the three routines
+** above are all no-ops
+*/
+# define autoIncBegin(A,B,C) (0)
+# define autoIncStep(A,B,C)
+#endif /* SQLITE_OMIT_AUTOINCREMENT */
+
+
+/* Forward declaration */
+static int xferOptimization(
+ Parse *pParse, /* Parser context */
+ Table *pDest, /* The table we are inserting into */
+ Select *pSelect, /* A SELECT statement to use as the data source */
+ int onError, /* How to handle constraint errors */
+ int iDbDest /* The database of pDest */
+);
+
+/*
+** This routine is called to handle SQL of the following forms:
+**
+** insert into TABLE (IDLIST) values(EXPRLIST),(EXPRLIST),...
+** insert into TABLE (IDLIST) select
+** insert into TABLE (IDLIST) default values
+**
+** The IDLIST following the table name is always optional. If omitted,
+** then a list of all (non-hidden) columns for the table is substituted.
+** The IDLIST appears in the pColumn parameter. pColumn is NULL if IDLIST
+** is omitted.
+**
+** For the pSelect parameter holds the values to be inserted for the
+** first two forms shown above. A VALUES clause is really just short-hand
+** for a SELECT statement that omits the FROM clause and everything else
+** that follows. If the pSelect parameter is NULL, that means that the
+** DEFAULT VALUES form of the INSERT statement is intended.
+**
+** The code generated follows one of four templates. For a simple
+** insert with data coming from a single-row VALUES clause, the code executes
+** once straight down through. Pseudo-code follows (we call this
+** the "1st template"):
+**
+** open write cursor to <table> and its indices
+** put VALUES clause expressions into registers
+** write the resulting record into <table>
+** cleanup
+**
+** The three remaining templates assume the statement is of the form
+**
+** INSERT INTO <table> SELECT ...
+**
+** If the SELECT clause is of the restricted form "SELECT * FROM <table2>" -
+** in other words if the SELECT pulls all columns from a single table
+** and there is no WHERE or LIMIT or GROUP BY or ORDER BY clauses, and
+** if <table2> and <table1> are distinct tables but have identical
+** schemas, including all the same indices, then a special optimization
+** is invoked that copies raw records from <table2> over to <table1>.
+** See the xferOptimization() function for the implementation of this
+** template. This is the 2nd template.
+**
+** open a write cursor to <table>
+** open read cursor on <table2>
+** transfer all records in <table2> over to <table>
+** close cursors
+** foreach index on <table>
+** open a write cursor on the <table> index
+** open a read cursor on the corresponding <table2> index
+** transfer all records from the read to the write cursors
+** close cursors
+** end foreach
+**
+** The 3rd template is for when the second template does not apply
+** and the SELECT clause does not read from <table> at any time.
+** The generated code follows this template:
+**
+** X <- A
+** goto B
+** A: setup for the SELECT
+** loop over the rows in the SELECT
+** load values into registers R..R+n
+** yield X
+** end loop
+** cleanup after the SELECT
+** end-coroutine X
+** B: open write cursor to <table> and its indices
+** C: yield X, at EOF goto D
+** insert the select result into <table> from R..R+n
+** goto C
+** D: cleanup
+**
+** The 4th template is used if the insert statement takes its
+** values from a SELECT but the data is being inserted into a table
+** that is also read as part of the SELECT. In the third form,
+** we have to use an intermediate table to store the results of
+** the select. The template is like this:
+**
+** X <- A
+** goto B
+** A: setup for the SELECT
+** loop over the tables in the SELECT
+** load value into register R..R+n
+** yield X
+** end loop
+** cleanup after the SELECT
+** end co-routine R
+** B: open temp table
+** L: yield X, at EOF goto M
+** insert row from R..R+n into temp table
+** goto L
+** M: open write cursor to <table> and its indices
+** rewind temp table
+** C: loop over rows of intermediate table
+** transfer values form intermediate table into <table>
+** end loop
+** D: cleanup
+*/
+SQLITE_PRIVATE void sqlite3Insert(
+ Parse *pParse, /* Parser context */
+ SrcList *pTabList, /* Name of table into which we are inserting */
+ Select *pSelect, /* A SELECT statement to use as the data source */
+ IdList *pColumn, /* Column names corresponding to IDLIST. */
+ int onError /* How to handle constraint errors */
+){
+ sqlite3 *db; /* The main database structure */
+ Table *pTab; /* The table to insert into. aka TABLE */
+ char *zTab; /* Name of the table into which we are inserting */
+ int i, j; /* Loop counters */
+ Vdbe *v; /* Generate code into this virtual machine */
+ Index *pIdx; /* For looping over indices of the table */
+ int nColumn; /* Number of columns in the data */
+ int nHidden = 0; /* Number of hidden columns if TABLE is virtual */
+ int iDataCur = 0; /* VDBE cursor that is the main data repository */
+ int iIdxCur = 0; /* First index cursor */
+ int ipkColumn = -1; /* Column that is the INTEGER PRIMARY KEY */
+ int endOfLoop; /* Label for the end of the insertion loop */
+ int srcTab = 0; /* Data comes from this temporary cursor if >=0 */
+ int addrInsTop = 0; /* Jump to label "D" */
+ int addrCont = 0; /* Top of insert loop. Label "C" in templates 3 and 4 */
+ SelectDest dest; /* Destination for SELECT on rhs of INSERT */
+ int iDb; /* Index of database holding TABLE */
+ u8 useTempTable = 0; /* Store SELECT results in intermediate table */
+ u8 appendFlag = 0; /* True if the insert is likely to be an append */
+ u8 withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */
+ u8 bIdListInOrder; /* True if IDLIST is in table order */
+ ExprList *pList = 0; /* List of VALUES() to be inserted */
+
+ /* Register allocations */
+ int regFromSelect = 0;/* Base register for data coming from SELECT */
+ int regAutoinc = 0; /* Register holding the AUTOINCREMENT counter */
+ int regRowCount = 0; /* Memory cell used for the row counter */
+ int regIns; /* Block of regs holding rowid+data being inserted */
+ int regRowid; /* registers holding insert rowid */
+ int regData; /* register holding first column to insert */
+ int *aRegIdx = 0; /* One register allocated to each index */
+
+#ifndef SQLITE_OMIT_TRIGGER
+ int isView; /* True if attempting to insert into a view */
+ Trigger *pTrigger; /* List of triggers on pTab, if required */
+ int tmask; /* Mask of trigger times */
+#endif
+
+ db = pParse->db;
+ memset(&dest, 0, sizeof(dest));
+ if( pParse->nErr || db->mallocFailed ){
+ goto insert_cleanup;
+ }
+
+ /* If the Select object is really just a simple VALUES() list with a
+ ** single row (the common case) then keep that one row of values
+ ** and discard the other (unused) parts of the pSelect object
+ */
+ if( pSelect && (pSelect->selFlags & SF_Values)!=0 && pSelect->pPrior==0 ){
+ pList = pSelect->pEList;
+ pSelect->pEList = 0;
+ sqlite3SelectDelete(db, pSelect);
+ pSelect = 0;
+ }
+
+ /* Locate the table into which we will be inserting new information.
+ */
+ assert( pTabList->nSrc==1 );
+ zTab = pTabList->a[0].zName;
+ if( NEVER(zTab==0) ) goto insert_cleanup;
+ pTab = sqlite3SrcListLookup(pParse, pTabList);
+ if( pTab==0 ){
+ goto insert_cleanup;
+ }
+ iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+ assert( iDb<db->nDb );
+ if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0,
+ db->aDb[iDb].zDbSName) ){
+ goto insert_cleanup;
+ }
+ withoutRowid = !HasRowid(pTab);
+
+ /* Figure out if we have any triggers and if the table being
+ ** inserted into is a view
+ */
+#ifndef SQLITE_OMIT_TRIGGER
+ pTrigger = sqlite3TriggersExist(pParse, pTab, TK_INSERT, 0, &tmask);
+ isView = pTab->pSelect!=0;
+#else
+# define pTrigger 0
+# define tmask 0
+# define isView 0
+#endif
+#ifdef SQLITE_OMIT_VIEW
+# undef isView
+# define isView 0
+#endif
+ assert( (pTrigger && tmask) || (pTrigger==0 && tmask==0) );
+
+ /* If pTab is really a view, make sure it has been initialized.
+ ** ViewGetColumnNames() is a no-op if pTab is not a view.
+ */
+ if( sqlite3ViewGetColumnNames(pParse, pTab) ){
+ goto insert_cleanup;
+ }
+
+ /* Cannot insert into a read-only table.
+ */
+ if( sqlite3IsReadOnly(pParse, pTab, tmask) ){
+ goto insert_cleanup;
+ }
+
+ /* Allocate a VDBE
+ */
+ v = sqlite3GetVdbe(pParse);
+ if( v==0 ) goto insert_cleanup;
+ if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
+ sqlite3BeginWriteOperation(pParse, pSelect || pTrigger, iDb);
+
+#ifndef SQLITE_OMIT_XFER_OPT
+ /* If the statement is of the form
+ **
+ ** INSERT INTO <table1> SELECT * FROM <table2>;
+ **
+ ** Then special optimizations can be applied that make the transfer
+ ** very fast and which reduce fragmentation of indices.
+ **
+ ** This is the 2nd template.
+ */
+ if( pColumn==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){
+ assert( !pTrigger );
+ assert( pList==0 );
+ goto insert_end;
+ }
+#endif /* SQLITE_OMIT_XFER_OPT */
+
+ /* If this is an AUTOINCREMENT table, look up the sequence number in the
+ ** sqlite_sequence table and store it in memory cell regAutoinc.
+ */
+ regAutoinc = autoIncBegin(pParse, iDb, pTab);
+
+ /* Allocate registers for holding the rowid of the new row,
+ ** the content of the new row, and the assembled row record.
+ */
+ regRowid = regIns = pParse->nMem+1;
+ pParse->nMem += pTab->nCol + 1;
+ if( IsVirtual(pTab) ){
+ regRowid++;
+ pParse->nMem++;
+ }
+ regData = regRowid+1;
+
+ /* If the INSERT statement included an IDLIST term, then make sure
+ ** all elements of the IDLIST really are columns of the table and
+ ** remember the column indices.
+ **
+ ** If the table has an INTEGER PRIMARY KEY column and that column
+ ** is named in the IDLIST, then record in the ipkColumn variable
+ ** the index into IDLIST of the primary key column. ipkColumn is
+ ** the index of the primary key as it appears in IDLIST, not as
+ ** is appears in the original table. (The index of the INTEGER
+ ** PRIMARY KEY in the original table is pTab->iPKey.)
+ */
+ bIdListInOrder = (pTab->tabFlags & TF_OOOHidden)==0;
+ if( pColumn ){
+ for(i=0; i<pColumn->nId; i++){
+ pColumn->a[i].idx = -1;
+ }
+ for(i=0; i<pColumn->nId; i++){
+ for(j=0; j<pTab->nCol; j++){
+ if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){
+ pColumn->a[i].idx = j;
+ if( i!=j ) bIdListInOrder = 0;
+ if( j==pTab->iPKey ){
+ ipkColumn = i; assert( !withoutRowid );
+ }
+ break;
+ }
+ }
+ if( j>=pTab->nCol ){
+ if( sqlite3IsRowid(pColumn->a[i].zName) && !withoutRowid ){
+ ipkColumn = i;
+ bIdListInOrder = 0;
+ }else{
+ sqlite3ErrorMsg(pParse, "table %S has no column named %s",
+ pTabList, 0, pColumn->a[i].zName);
+ pParse->checkSchema = 1;
+ goto insert_cleanup;
+ }
+ }
+ }
+ }
+
+ /* Figure out how many columns of data are supplied. If the data
+ ** is coming from a SELECT statement, then generate a co-routine that
+ ** produces a single row of the SELECT on each invocation. The
+ ** co-routine is the common header to the 3rd and 4th templates.
+ */
+ if( pSelect ){
+ /* Data is coming from a SELECT or from a multi-row VALUES clause.
+ ** Generate a co-routine to run the SELECT. */
+ int regYield; /* Register holding co-routine entry-point */
+ int addrTop; /* Top of the co-routine */
+ int rc; /* Result code */
+
+ regYield = ++pParse->nMem;
+ addrTop = sqlite3VdbeCurrentAddr(v) + 1;
+ sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop);
+ sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
+ dest.iSdst = bIdListInOrder ? regData : 0;
+ dest.nSdst = pTab->nCol;
+ rc = sqlite3Select(pParse, pSelect, &dest);
+ regFromSelect = dest.iSdst;
+ if( rc || db->mallocFailed || pParse->nErr ) goto insert_cleanup;
+ sqlite3VdbeEndCoroutine(v, regYield);
+ sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */
+ assert( pSelect->pEList );
+ nColumn = pSelect->pEList->nExpr;
+
+ /* Set useTempTable to TRUE if the result of the SELECT statement
+ ** should be written into a temporary table (template 4). Set to
+ ** FALSE if each output row of the SELECT can be written directly into
+ ** the destination table (template 3).
+ **
+ ** A temp table must be used if the table being updated is also one
+ ** of the tables being read by the SELECT statement. Also use a
+ ** temp table in the case of row triggers.
+ */
+ if( pTrigger || readsTable(pParse, iDb, pTab) ){
+ useTempTable = 1;
+ }
+
+ if( useTempTable ){
+ /* Invoke the coroutine to extract information from the SELECT
+ ** and add it to a transient table srcTab. The code generated
+ ** here is from the 4th template:
+ **
+ ** B: open temp table
+ ** L: yield X, goto M at EOF
+ ** insert row from R..R+n into temp table
+ ** goto L
+ ** M: ...
+ */
+ int regRec; /* Register to hold packed record */
+ int regTempRowid; /* Register to hold temp table ROWID */
+ int addrL; /* Label "L" */
+
+ srcTab = pParse->nTab++;
+ regRec = sqlite3GetTempReg(pParse);
+ regTempRowid = sqlite3GetTempReg(pParse);
+ sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn);
+ addrL = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec);
+ sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid);
+ sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid);
+ sqlite3VdbeGoto(v, addrL);
+ sqlite3VdbeJumpHere(v, addrL);
+ sqlite3ReleaseTempReg(pParse, regRec);
+ sqlite3ReleaseTempReg(pParse, regTempRowid);
+ }
+ }else{
+ /* This is the case if the data for the INSERT is coming from a
+ ** single-row VALUES clause
+ */
+ NameContext sNC;
+ memset(&sNC, 0, sizeof(sNC));
+ sNC.pParse = pParse;
+ srcTab = -1;
+ assert( useTempTable==0 );
+ if( pList ){
+ nColumn = pList->nExpr;
+ if( sqlite3ResolveExprListNames(&sNC, pList) ){
+ goto insert_cleanup;
+ }
+ }else{
+ nColumn = 0;
+ }
+ }
+
+ /* If there is no IDLIST term but the table has an integer primary
+ ** key, the set the ipkColumn variable to the integer primary key
+ ** column index in the original table definition.
+ */
+ if( pColumn==0 && nColumn>0 ){
+ ipkColumn = pTab->iPKey;
+ }
+
+ /* Make sure the number of columns in the source data matches the number
+ ** of columns to be inserted into the table.
+ */
+ for(i=0; i<pTab->nCol; i++){
+ nHidden += (IsHiddenColumn(&pTab->aCol[i]) ? 1 : 0);
+ }
+ if( pColumn==0 && nColumn && nColumn!=(pTab->nCol-nHidden) ){
+ sqlite3ErrorMsg(pParse,
+ "table %S has %d columns but %d values were supplied",
+ pTabList, 0, pTab->nCol-nHidden, nColumn);
+ goto insert_cleanup;
+ }
+ if( pColumn!=0 && nColumn!=pColumn->nId ){
+ sqlite3ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId);
+ goto insert_cleanup;
+ }
+
+ /* Initialize the count of rows to be inserted
+ */
+ if( db->flags & SQLITE_CountRows ){
+ regRowCount = ++pParse->nMem;
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
+ }
+
+ /* If this is not a view, open the table and and all indices */
+ if( !isView ){
+ int nIdx;
+ nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0,
+ &iDataCur, &iIdxCur);
+ aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+1));
+ if( aRegIdx==0 ){
+ goto insert_cleanup;
+ }
+ for(i=0, pIdx=pTab->pIndex; i<nIdx; pIdx=pIdx->pNext, i++){
+ assert( pIdx );
+ aRegIdx[i] = ++pParse->nMem;
+ pParse->nMem += pIdx->nColumn;
+ }
+ }
+
+ /* This is the top of the main insertion loop */
+ if( useTempTable ){
+ /* This block codes the top of loop only. The complete loop is the
+ ** following pseudocode (template 4):
+ **
+ ** rewind temp table, if empty goto D
+ ** C: loop over rows of intermediate table
+ ** transfer values form intermediate table into <table>
+ ** end loop
+ ** D: ...
+ */
+ addrInsTop = sqlite3VdbeAddOp1(v, OP_Rewind, srcTab); VdbeCoverage(v);
+ addrCont = sqlite3VdbeCurrentAddr(v);
+ }else if( pSelect ){
+ /* This block codes the top of loop only. The complete loop is the
+ ** following pseudocode (template 3):
+ **
+ ** C: yield X, at EOF goto D
+ ** insert the select result into <table> from R..R+n
+ ** goto C
+ ** D: ...
+ */
+ addrInsTop = addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
+ VdbeCoverage(v);
+ }
+
+ /* Run the BEFORE and INSTEAD OF triggers, if there are any
+ */
+ endOfLoop = sqlite3VdbeMakeLabel(v);
+ if( tmask & TRIGGER_BEFORE ){
+ int regCols = sqlite3GetTempRange(pParse, pTab->nCol+1);
+
+ /* build the NEW.* reference row. Note that if there is an INTEGER
+ ** PRIMARY KEY into which a NULL is being inserted, that NULL will be
+ ** translated into a unique ID for the row. But on a BEFORE trigger,
+ ** we do not know what the unique ID will be (because the insert has
+ ** not happened yet) so we substitute a rowid of -1
+ */
+ if( ipkColumn<0 ){
+ sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
+ }else{
+ int addr1;
+ assert( !withoutRowid );
+ if( useTempTable ){
+ sqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regCols);
+ }else{
+ assert( pSelect==0 ); /* Otherwise useTempTable is true */
+ sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regCols);
+ }
+ addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols); VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
+ sqlite3VdbeJumpHere(v, addr1);
+ sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols); VdbeCoverage(v);
+ }
+
+ /* Cannot have triggers on a virtual table. If it were possible,
+ ** this block would have to account for hidden column.
+ */
+ assert( !IsVirtual(pTab) );
+
+ /* Create the new column data
+ */
+ for(i=j=0; i<pTab->nCol; i++){
+ if( pColumn ){
+ for(j=0; j<pColumn->nId; j++){
+ if( pColumn->a[j].idx==i ) break;
+ }
+ }
+ if( (!useTempTable && !pList) || (pColumn && j>=pColumn->nId)
+ || (pColumn==0 && IsOrdinaryHiddenColumn(&pTab->aCol[i])) ){
+ sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regCols+i+1);
+ }else if( useTempTable ){
+ sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, regCols+i+1);
+ }else{
+ assert( pSelect==0 ); /* Otherwise useTempTable is true */
+ sqlite3ExprCodeAndCache(pParse, pList->a[j].pExpr, regCols+i+1);
+ }
+ if( pColumn==0 && !IsOrdinaryHiddenColumn(&pTab->aCol[i]) ) j++;
+ }
+
+ /* If this is an INSERT on a view with an INSTEAD OF INSERT trigger,
+ ** do not attempt any conversions before assembling the record.
+ ** If this is a real table, attempt conversions as required by the
+ ** table column affinities.
+ */
+ if( !isView ){
+ sqlite3TableAffinity(v, pTab, regCols+1);
+ }
+
+ /* Fire BEFORE or INSTEAD OF triggers */
+ sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE,
+ pTab, regCols-pTab->nCol-1, onError, endOfLoop);
+
+ sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol+1);
+ }
+
+ /* Compute the content of the next row to insert into a range of
+ ** registers beginning at regIns.
+ */
+ if( !isView ){
+ if( IsVirtual(pTab) ){
+ /* The row that the VUpdate opcode will delete: none */
+ sqlite3VdbeAddOp2(v, OP_Null, 0, regIns);
+ }
+ if( ipkColumn>=0 ){
+ if( useTempTable ){
+ sqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regRowid);
+ }else if( pSelect ){
+ sqlite3VdbeAddOp2(v, OP_Copy, regFromSelect+ipkColumn, regRowid);
+ }else{
+ VdbeOp *pOp;
+ sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regRowid);
+ pOp = sqlite3VdbeGetOp(v, -1);
+ if( ALWAYS(pOp) && pOp->opcode==OP_Null && !IsVirtual(pTab) ){
+ appendFlag = 1;
+ pOp->opcode = OP_NewRowid;
+ pOp->p1 = iDataCur;
+ pOp->p2 = regRowid;
+ pOp->p3 = regAutoinc;
+ }
+ }
+ /* If the PRIMARY KEY expression is NULL, then use OP_NewRowid
+ ** to generate a unique primary key value.
+ */
+ if( !appendFlag ){
+ int addr1;
+ if( !IsVirtual(pTab) ){
+ addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid); VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc);
+ sqlite3VdbeJumpHere(v, addr1);
+ }else{
+ addr1 = sqlite3VdbeCurrentAddr(v);
+ sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, addr1+2); VdbeCoverage(v);
+ }
+ sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid); VdbeCoverage(v);
+ }
+ }else if( IsVirtual(pTab) || withoutRowid ){
+ sqlite3VdbeAddOp2(v, OP_Null, 0, regRowid);
+ }else{
+ sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc);
+ appendFlag = 1;
+ }
+ autoIncStep(pParse, regAutoinc, regRowid);
+
+ /* Compute data for all columns of the new entry, beginning
+ ** with the first column.
+ */
+ nHidden = 0;
+ for(i=0; i<pTab->nCol; i++){
+ int iRegStore = regRowid+1+i;
+ if( i==pTab->iPKey ){
+ /* The value of the INTEGER PRIMARY KEY column is always a NULL.
+ ** Whenever this column is read, the rowid will be substituted
+ ** in its place. Hence, fill this column with a NULL to avoid
+ ** taking up data space with information that will never be used.
+ ** As there may be shallow copies of this value, make it a soft-NULL */
+ sqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore);
+ continue;
+ }
+ if( pColumn==0 ){
+ if( IsHiddenColumn(&pTab->aCol[i]) ){
+ j = -1;
+ nHidden++;
+ }else{
+ j = i - nHidden;
+ }
+ }else{
+ for(j=0; j<pColumn->nId; j++){
+ if( pColumn->a[j].idx==i ) break;
+ }
+ }
+ if( j<0 || nColumn==0 || (pColumn && j>=pColumn->nId) ){
+ sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore);
+ }else if( useTempTable ){
+ sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, iRegStore);
+ }else if( pSelect ){
+ if( regFromSelect!=regData ){
+ sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+j, iRegStore);
+ }
+ }else{
+ sqlite3ExprCode(pParse, pList->a[j].pExpr, iRegStore);
+ }
+ }
+
+ /* Generate code to check constraints and generate index keys and
+ ** do the insertion.
+ */
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ if( IsVirtual(pTab) ){
+ const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
+ sqlite3VtabMakeWritable(pParse, pTab);
+ sqlite3VdbeAddOp4(v, OP_VUpdate, 1, pTab->nCol+2, regIns, pVTab, P4_VTAB);
+ sqlite3VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError);
+ sqlite3MayAbort(pParse);
+ }else
+#endif
+ {
+ int isReplace; /* Set to true if constraints may cause a replace */
+ int bUseSeek; /* True to use OPFLAG_SEEKRESULT */
+ sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
+ regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace, 0
+ );
+ sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0);
+
+ /* Set the OPFLAG_USESEEKRESULT flag if either (a) there are no REPLACE
+ ** constraints or (b) there are no triggers and this table is not a
+ ** parent table in a foreign key constraint. It is safe to set the
+ ** flag in the second case as if any REPLACE constraint is hit, an
+ ** OP_Delete or OP_IdxDelete instruction will be executed on each
+ ** cursor that is disturbed. And these instructions both clear the
+ ** VdbeCursor.seekResult variable, disabling the OPFLAG_USESEEKRESULT
+ ** functionality. */
+ bUseSeek = (isReplace==0 || (pTrigger==0 &&
+ ((db->flags & SQLITE_ForeignKeys)==0 || sqlite3FkReferences(pTab)==0)
+ ));
+ sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur,
+ regIns, aRegIdx, 0, appendFlag, bUseSeek
+ );
+ }
+ }
+
+ /* Update the count of rows that are inserted
+ */
+ if( (db->flags & SQLITE_CountRows)!=0 ){
+ sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1);
+ }
+
+ if( pTrigger ){
+ /* Code AFTER triggers */
+ sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_AFTER,
+ pTab, regData-2-pTab->nCol, onError, endOfLoop);
+ }
+
+ /* The bottom of the main insertion loop, if the data source
+ ** is a SELECT statement.
+ */
+ sqlite3VdbeResolveLabel(v, endOfLoop);
+ if( useTempTable ){
+ sqlite3VdbeAddOp2(v, OP_Next, srcTab, addrCont); VdbeCoverage(v);
+ sqlite3VdbeJumpHere(v, addrInsTop);
+ sqlite3VdbeAddOp1(v, OP_Close, srcTab);
+ }else if( pSelect ){
+ sqlite3VdbeGoto(v, addrCont);
+ sqlite3VdbeJumpHere(v, addrInsTop);
+ }
+
+insert_end:
+ /* Update the sqlite_sequence table by storing the content of the
+ ** maximum rowid counter values recorded while inserting into
+ ** autoincrement tables.
+ */
+ if( pParse->nested==0 && pParse->pTriggerTab==0 ){
+ sqlite3AutoincrementEnd(pParse);
+ }
+
+ /*
+ ** Return the number of rows inserted. If this routine is
+ ** generating code because of a call to sqlite3NestedParse(), do not
+ ** invoke the callback function.
+ */
+ if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){
+ sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1);
+ sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC);
+ }
+
+insert_cleanup:
+ sqlite3SrcListDelete(db, pTabList);
+ sqlite3ExprListDelete(db, pList);
+ sqlite3SelectDelete(db, pSelect);
+ sqlite3IdListDelete(db, pColumn);
+ sqlite3DbFree(db, aRegIdx);
+}
+
+/* Make sure "isView" and other macros defined above are undefined. Otherwise
+** they may interfere with compilation of other functions in this file
+** (or in another file, if this file becomes part of the amalgamation). */
+#ifdef isView
+ #undef isView
+#endif
+#ifdef pTrigger
+ #undef pTrigger
+#endif
+#ifdef tmask
+ #undef tmask
+#endif
+
+/*
+** Meanings of bits in of pWalker->eCode for checkConstraintUnchanged()
+*/
+#define CKCNSTRNT_COLUMN 0x01 /* CHECK constraint uses a changing column */
+#define CKCNSTRNT_ROWID 0x02 /* CHECK constraint references the ROWID */
+
+/* This is the Walker callback from checkConstraintUnchanged(). Set
+** bit 0x01 of pWalker->eCode if
+** pWalker->eCode to 0 if this expression node references any of the
+** columns that are being modifed by an UPDATE statement.
+*/
+static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){
+ if( pExpr->op==TK_COLUMN ){
+ assert( pExpr->iColumn>=0 || pExpr->iColumn==-1 );
+ if( pExpr->iColumn>=0 ){
+ if( pWalker->u.aiCol[pExpr->iColumn]>=0 ){
+ pWalker->eCode |= CKCNSTRNT_COLUMN;
+ }
+ }else{
+ pWalker->eCode |= CKCNSTRNT_ROWID;
+ }
+ }
+ return WRC_Continue;
+}
+
+/*
+** pExpr is a CHECK constraint on a row that is being UPDATE-ed. The
+** only columns that are modified by the UPDATE are those for which
+** aiChng[i]>=0, and also the ROWID is modified if chngRowid is true.
+**
+** Return true if CHECK constraint pExpr does not use any of the
+** changing columns (or the rowid if it is changing). In other words,
+** return true if this CHECK constraint can be skipped when validating
+** the new row in the UPDATE statement.
+*/
+static int checkConstraintUnchanged(Expr *pExpr, int *aiChng, int chngRowid){
+ Walker w;
+ memset(&w, 0, sizeof(w));
+ w.eCode = 0;
+ w.xExprCallback = checkConstraintExprNode;
+ w.u.aiCol = aiChng;
+ sqlite3WalkExpr(&w, pExpr);
+ if( !chngRowid ){
+ testcase( (w.eCode & CKCNSTRNT_ROWID)!=0 );
+ w.eCode &= ~CKCNSTRNT_ROWID;
+ }
+ testcase( w.eCode==0 );
+ testcase( w.eCode==CKCNSTRNT_COLUMN );
+ testcase( w.eCode==CKCNSTRNT_ROWID );
+ testcase( w.eCode==(CKCNSTRNT_ROWID|CKCNSTRNT_COLUMN) );
+ return !w.eCode;
+}
+
+/*
+** Generate code to do constraint checks prior to an INSERT or an UPDATE
+** on table pTab.
+**
+** The regNewData parameter is the first register in a range that contains
+** the data to be inserted or the data after the update. There will be
+** pTab->nCol+1 registers in this range. The first register (the one
+** that regNewData points to) will contain the new rowid, or NULL in the
+** case of a WITHOUT ROWID table. The second register in the range will
+** contain the content of the first table column. The third register will
+** contain the content of the second table column. And so forth.
+**
+** The regOldData parameter is similar to regNewData except that it contains
+** the data prior to an UPDATE rather than afterwards. regOldData is zero
+** for an INSERT. This routine can distinguish between UPDATE and INSERT by
+** checking regOldData for zero.
+**
+** For an UPDATE, the pkChng boolean is true if the true primary key (the
+** rowid for a normal table or the PRIMARY KEY for a WITHOUT ROWID table)
+** might be modified by the UPDATE. If pkChng is false, then the key of
+** the iDataCur content table is guaranteed to be unchanged by the UPDATE.
+**
+** For an INSERT, the pkChng boolean indicates whether or not the rowid
+** was explicitly specified as part of the INSERT statement. If pkChng
+** is zero, it means that the either rowid is computed automatically or
+** that the table is a WITHOUT ROWID table and has no rowid. On an INSERT,
+** pkChng will only be true if the INSERT statement provides an integer
+** value for either the rowid column or its INTEGER PRIMARY KEY alias.
+**
+** The code generated by this routine will store new index entries into
+** registers identified by aRegIdx[]. No index entry is created for
+** indices where aRegIdx[i]==0. The order of indices in aRegIdx[] is
+** the same as the order of indices on the linked list of indices
+** at pTab->pIndex.
+**
+** The caller must have already opened writeable cursors on the main
+** table and all applicable indices (that is to say, all indices for which
+** aRegIdx[] is not zero). iDataCur is the cursor for the main table when
+** inserting or updating a rowid table, or the cursor for the PRIMARY KEY
+** index when operating on a WITHOUT ROWID table. iIdxCur is the cursor
+** for the first index in the pTab->pIndex list. Cursors for other indices
+** are at iIdxCur+N for the N-th element of the pTab->pIndex list.
+**
+** 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
+** sqlite3_step() 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 sqlite3_step() to return immediately
+** with SQLITE_CONSTRAINT.
+**
+** any FAIL Sqlite3_step() returns immediately with a
+** return code of SQLITE_CONSTRAINT. The
+** transaction is not rolled back and any
+** changes to prior rows are retained.
+**
+** any IGNORE The attempt in insert or update the current
+** row is skipped, without throwing an error.
+** Processing continues with the next row.
+** (There is an immediate jump to 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.
+*/
+SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
+ Parse *pParse, /* The parser context */
+ Table *pTab, /* The table being inserted or updated */
+ int *aRegIdx, /* Use register aRegIdx[i] for index i. 0 for unused */
+ int iDataCur, /* Canonical data cursor (main table or PK index) */
+ int iIdxCur, /* First index cursor */
+ int regNewData, /* First register in a range holding values to insert */
+ int regOldData, /* Previous content. 0 for INSERTs */
+ u8 pkChng, /* Non-zero if the rowid or PRIMARY KEY changed */
+ u8 overrideError, /* Override onError to this if not OE_Default */
+ int ignoreDest, /* Jump to this label on an OE_Ignore resolution */
+ int *pbMayReplace, /* OUT: Set to true if constraint may cause a replace */
+ int *aiChng /* column i is unchanged if aiChng[i]<0 */
+){
+ Vdbe *v; /* VDBE under constrution */
+ Index *pIdx; /* Pointer to one of the indices */
+ Index *pPk = 0; /* The PRIMARY KEY index */
+ sqlite3 *db; /* Database connection */
+ int i; /* loop counter */
+ int ix; /* Index loop counter */
+ int nCol; /* Number of columns */
+ int onError; /* Conflict resolution strategy */
+ int addr1; /* Address of jump instruction */
+ int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */
+ int nPkField; /* Number of fields in PRIMARY KEY. 1 for ROWID tables */
+ int ipkTop = 0; /* Top of the rowid change constraint check */
+ int ipkBottom = 0; /* Bottom of the rowid change constraint check */
+ u8 isUpdate; /* True if this is an UPDATE operation */
+ u8 bAffinityDone = 0; /* True if the OP_Affinity operation has been run */
+
+ isUpdate = regOldData!=0;
+ db = pParse->db;
+ v = sqlite3GetVdbe(pParse);
+ assert( v!=0 );
+ assert( pTab->pSelect==0 ); /* This table is not a VIEW */
+ nCol = pTab->nCol;
+
+ /* pPk is the PRIMARY KEY index for WITHOUT ROWID tables and NULL for
+ ** normal rowid tables. nPkField is the number of key fields in the
+ ** pPk index or 1 for a rowid table. In other words, nPkField is the
+ ** number of fields in the true primary key of the table. */
+ if( HasRowid(pTab) ){
+ pPk = 0;
+ nPkField = 1;
+ }else{
+ pPk = sqlite3PrimaryKeyIndex(pTab);
+ nPkField = pPk->nKeyCol;
+ }
+
+ /* Record that this module has started */
+ VdbeModuleComment((v, "BEGIN: GenCnstCks(%d,%d,%d,%d,%d)",
+ iDataCur, iIdxCur, regNewData, regOldData, pkChng));
+
+ /* Test all NOT NULL constraints.
+ */
+ for(i=0; i<nCol; i++){
+ if( i==pTab->iPKey ){
+ continue; /* ROWID is never NULL */
+ }
+ if( aiChng && aiChng[i]<0 ){
+ /* Don't bother checking for NOT NULL on columns that do not change */
+ continue;
+ }
+ onError = pTab->aCol[i].notNull;
+ if( onError==OE_None ) continue; /* This column is allowed to be NULL */
+ if( overrideError!=OE_Default ){
+ onError = overrideError;
+ }else if( onError==OE_Default ){
+ onError = OE_Abort;
+ }
+ if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){
+ onError = OE_Abort;
+ }
+ assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
+ || onError==OE_Ignore || onError==OE_Replace );
+ switch( onError ){
+ case OE_Abort:
+ sqlite3MayAbort(pParse);
+ /* Fall through */
+ case OE_Rollback:
+ case OE_Fail: {
+ char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName,
+ pTab->aCol[i].zName);
+ sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError,
+ regNewData+1+i);
+ sqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC);
+ sqlite3VdbeChangeP5(v, P5_ConstraintNotNull);
+ VdbeCoverage(v);
+ break;
+ }
+ case OE_Ignore: {
+ sqlite3VdbeAddOp2(v, OP_IsNull, regNewData+1+i, ignoreDest);
+ VdbeCoverage(v);
+ break;
+ }
+ default: {
+ assert( onError==OE_Replace );
+ addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regNewData+1+i);
+ VdbeCoverage(v);
+ sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i);
+ sqlite3VdbeJumpHere(v, addr1);
+ break;
+ }
+ }
+ }
+
+ /* Test all CHECK constraints
+ */
+#ifndef SQLITE_OMIT_CHECK
+ if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
+ ExprList *pCheck = pTab->pCheck;
+ pParse->ckBase = regNewData+1;
+ onError = overrideError!=OE_Default ? overrideError : OE_Abort;
+ for(i=0; i<pCheck->nExpr; i++){
+ int allOk;
+ Expr *pExpr = pCheck->a[i].pExpr;
+ if( aiChng && checkConstraintUnchanged(pExpr, aiChng, pkChng) ) continue;
+ allOk = sqlite3VdbeMakeLabel(v);
+ sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL);
+ if( onError==OE_Ignore ){
+ sqlite3VdbeGoto(v, ignoreDest);
+ }else{
+ char *zName = pCheck->a[i].zName;
+ if( zName==0 ) zName = pTab->zName;
+ if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
+ sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_CHECK,
+ onError, zName, P4_TRANSIENT,
+ P5_ConstraintCheck);
+ }
+ sqlite3VdbeResolveLabel(v, allOk);
+ }
+ }
+#endif /* !defined(SQLITE_OMIT_CHECK) */
+
+ /* If rowid is changing, make sure the new rowid does not previously
+ ** exist in the table.
+ */
+ if( pkChng && pPk==0 ){
+ int addrRowidOk = sqlite3VdbeMakeLabel(v);
+
+ /* Figure out what action to take in case of a rowid collision */
+ onError = pTab->keyConf;
+ if( overrideError!=OE_Default ){
+ onError = overrideError;
+ }else if( onError==OE_Default ){
+ onError = OE_Abort;
+ }
+
+ if( isUpdate ){
+ /* pkChng!=0 does not mean that the rowid has changed, only that
+ ** it might have changed. Skip the conflict logic below if the rowid
+ ** is unchanged. */
+ sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRowidOk, regOldData);
+ sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
+ VdbeCoverage(v);
+ }
+
+ /* If the response to a rowid conflict is REPLACE but the response
+ ** to some other UNIQUE constraint is FAIL or IGNORE, then we need
+ ** to defer the running of the rowid conflict checking until after
+ ** the UNIQUE constraints have run.
+ */
+ if( onError==OE_Replace && overrideError!=OE_Replace ){
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ if( pIdx->onError==OE_Ignore || pIdx->onError==OE_Fail ){
+ ipkTop = sqlite3VdbeAddOp0(v, OP_Goto);
+ break;
+ }
+ }
+ }
+
+ /* Check to see if the new rowid already exists in the table. Skip
+ ** the following conflict logic if it does not. */
+ sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regNewData);
+ VdbeCoverage(v);
+
+ /* Generate code that deals with a rowid collision */
+ switch( onError ){
+ default: {
+ onError = OE_Abort;
+ /* Fall thru into the next case */
+ }
+ case OE_Rollback:
+ case OE_Abort:
+ case OE_Fail: {
+ sqlite3RowidConstraint(pParse, onError, pTab);
+ break;
+ }
+ case OE_Replace: {
+ /* If there are DELETE triggers on this table and the
+ ** recursive-triggers flag is set, call GenerateRowDelete() to
+ ** remove the conflicting row from the table. This will fire
+ ** the triggers and remove both the table and index b-tree entries.
+ **
+ ** Otherwise, if there are no triggers or the recursive-triggers
+ ** flag is not set, but the table has one or more indexes, call
+ ** GenerateRowIndexDelete(). This removes the index b-tree entries
+ ** only. The table b-tree entry will be replaced by the new entry
+ ** when it is inserted.
+ **
+ ** If either GenerateRowDelete() or GenerateRowIndexDelete() is called,
+ ** also invoke MultiWrite() to indicate that this VDBE may require
+ ** statement rollback (if the statement is aborted after the delete
+ ** takes place). Earlier versions called sqlite3MultiWrite() regardless,
+ ** but being more selective here allows statements like:
+ **
+ ** REPLACE INTO t(rowid) VALUES($newrowid)
+ **
+ ** to run without a statement journal if there are no indexes on the
+ ** table.
+ */
+ Trigger *pTrigger = 0;
+ if( db->flags&SQLITE_RecTriggers ){
+ pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
+ }
+ if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){
+ sqlite3MultiWrite(pParse);
+ sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
+ regNewData, 1, 0, OE_Replace, 1, -1);
+ }else{
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ if( HasRowid(pTab) ){
+ /* This OP_Delete opcode fires the pre-update-hook only. It does
+ ** not modify the b-tree. It is more efficient to let the coming
+ ** OP_Insert replace the existing entry than it is to delete the
+ ** existing entry and then insert a new one. */
+ sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, OPFLAG_ISNOOP);
+ sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
+ }
+#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
+ if( pTab->pIndex ){
+ sqlite3MultiWrite(pParse);
+ sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,-1);
+ }
+ }
+ seenReplace = 1;
+ break;
+ }
+ case OE_Ignore: {
+ /*assert( seenReplace==0 );*/
+ sqlite3VdbeGoto(v, ignoreDest);
+ break;
+ }
+ }
+ sqlite3VdbeResolveLabel(v, addrRowidOk);
+ if( ipkTop ){
+ ipkBottom = sqlite3VdbeAddOp0(v, OP_Goto);
+ sqlite3VdbeJumpHere(v, ipkTop);
+ }
+ }
+
+ /* Test all UNIQUE constraints by creating entries for each UNIQUE
+ ** index and making sure that duplicate entries do not already exist.
+ ** Compute the revised record entries for indices as we go.
+ **
+ ** This loop also handles the case of the PRIMARY KEY index for a
+ ** WITHOUT ROWID table.
+ */
+ for(ix=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, ix++){
+ int regIdx; /* Range of registers hold conent for pIdx */
+ int regR; /* Range of registers holding conflicting PK */
+ int iThisCur; /* Cursor for this UNIQUE index */
+ int addrUniqueOk; /* Jump here if the UNIQUE constraint is satisfied */
+
+ if( aRegIdx[ix]==0 ) continue; /* Skip indices that do not change */
+ if( bAffinityDone==0 ){
+ sqlite3TableAffinity(v, pTab, regNewData+1);
+ bAffinityDone = 1;
+ }
+ iThisCur = iIdxCur+ix;
+ addrUniqueOk = sqlite3VdbeMakeLabel(v);
+
+ /* Skip partial indices for which the WHERE clause is not true */
+ if( pIdx->pPartIdxWhere ){
+ sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[ix]);
+ pParse->ckBase = regNewData+1;
+ sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, addrUniqueOk,
+ SQLITE_JUMPIFNULL);
+ pParse->ckBase = 0;
+ }
+
+ /* Create a record for this index entry as it should appear after
+ ** the insert or update. Store that record in the aRegIdx[ix] register
+ */
+ regIdx = aRegIdx[ix]+1;
+ for(i=0; i<pIdx->nColumn; i++){
+ int iField = pIdx->aiColumn[i];
+ int x;
+ if( iField==XN_EXPR ){
+ pParse->ckBase = regNewData+1;
+ sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[i].pExpr, regIdx+i);
+ pParse->ckBase = 0;
+ VdbeComment((v, "%s column %d", pIdx->zName, i));
+ }else{
+ if( iField==XN_ROWID || iField==pTab->iPKey ){
+ x = regNewData;
+ }else{
+ x = iField + regNewData + 1;
+ }
+ sqlite3VdbeAddOp2(v, iField<0 ? OP_IntCopy : OP_SCopy, x, regIdx+i);
+ VdbeComment((v, "%s", iField<0 ? "rowid" : pTab->aCol[iField].zName));
+ }
+ }
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]);
+ VdbeComment((v, "for %s", pIdx->zName));
+
+ /* In an UPDATE operation, if this index is the PRIMARY KEY index
+ ** of a WITHOUT ROWID table and there has been no change the
+ ** primary key, then no collision is possible. The collision detection
+ ** logic below can all be skipped. */
+ if( isUpdate && pPk==pIdx && pkChng==0 ){
+ sqlite3VdbeResolveLabel(v, addrUniqueOk);
+ continue;
+ }
+
+ /* Find out what action to take in case there is a uniqueness conflict */
+ onError = pIdx->onError;
+ if( onError==OE_None ){
+ sqlite3VdbeResolveLabel(v, addrUniqueOk);
+ continue; /* pIdx is not a UNIQUE index */
+ }
+ if( overrideError!=OE_Default ){
+ onError = overrideError;
+ }else if( onError==OE_Default ){
+ onError = OE_Abort;
+ }
+
+ /* Collision detection may be omitted if all of the following are true:
+ ** (1) The conflict resolution algorithm is REPLACE
+ ** (2) The table is a WITHOUT ROWID table
+ ** (3) There are no secondary indexes on the table
+ ** (4) No delete triggers need to be fired if there is a conflict
+ ** (5) No FK constraint counters need to be updated if a conflict occurs.
+ */
+ if( (ix==0 && pIdx->pNext==0) /* Condition 3 */
+ && pPk==pIdx /* Condition 2 */
+ && onError==OE_Replace /* Condition 1 */
+ && ( 0==(db->flags&SQLITE_RecTriggers) || /* Condition 4 */
+ 0==sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0))
+ && ( 0==(db->flags&SQLITE_ForeignKeys) || /* Condition 5 */
+ (0==pTab->pFKey && 0==sqlite3FkReferences(pTab)))
+ ){
+ sqlite3VdbeResolveLabel(v, addrUniqueOk);
+ continue;
+ }
+
+ /* Check to see if the new index entry will be unique */
+ sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk,
+ regIdx, pIdx->nKeyCol); VdbeCoverage(v);
+
+ /* Generate code to handle collisions */
+ regR = (pIdx==pPk) ? regIdx : sqlite3GetTempRange(pParse, nPkField);
+ if( isUpdate || onError==OE_Replace ){
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp2(v, OP_IdxRowid, iThisCur, regR);
+ /* Conflict only if the rowid of the existing index entry
+ ** is different from old-rowid */
+ if( isUpdate ){
+ sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData);
+ sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
+ VdbeCoverage(v);
+ }
+ }else{
+ int x;
+ /* Extract the PRIMARY KEY from the end of the index entry and
+ ** store it in registers regR..regR+nPk-1 */
+ if( pIdx!=pPk ){
+ for(i=0; i<pPk->nKeyCol; i++){
+ assert( pPk->aiColumn[i]>=0 );
+ x = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]);
+ sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i);
+ VdbeComment((v, "%s.%s", pTab->zName,
+ pTab->aCol[pPk->aiColumn[i]].zName));
+ }
+ }
+ if( isUpdate ){
+ /* If currently processing the PRIMARY KEY of a WITHOUT ROWID
+ ** table, only conflict if the new PRIMARY KEY values are actually
+ ** different from the old.
+ **
+ ** For a UNIQUE index, only conflict if the PRIMARY KEY values
+ ** of the matched index row are different from the original PRIMARY
+ ** KEY values of this row before the update. */
+ int addrJump = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol;
+ int op = OP_Ne;
+ int regCmp = (IsPrimaryKeyIndex(pIdx) ? regIdx : regR);
+
+ for(i=0; i<pPk->nKeyCol; i++){
+ char *p4 = (char*)sqlite3LocateCollSeq(pParse, pPk->azColl[i]);
+ x = pPk->aiColumn[i];
+ assert( x>=0 );
+ if( i==(pPk->nKeyCol-1) ){
+ addrJump = addrUniqueOk;
+ op = OP_Eq;
+ }
+ sqlite3VdbeAddOp4(v, op,
+ regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ
+ );
+ sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
+ VdbeCoverageIf(v, op==OP_Eq);
+ VdbeCoverageIf(v, op==OP_Ne);
+ }
+ }
+ }
+ }
+
+ /* Generate code that executes if the new index entry is not unique */
+ assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
+ || onError==OE_Ignore || onError==OE_Replace );
+ switch( onError ){
+ case OE_Rollback:
+ case OE_Abort:
+ case OE_Fail: {
+ sqlite3UniqueConstraint(pParse, onError, pIdx);
+ break;
+ }
+ case OE_Ignore: {
+ sqlite3VdbeGoto(v, ignoreDest);
+ break;
+ }
+ default: {
+ Trigger *pTrigger = 0;
+ assert( onError==OE_Replace );
+ sqlite3MultiWrite(pParse);
+ if( db->flags&SQLITE_RecTriggers ){
+ pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
+ }
+ sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
+ regR, nPkField, 0, OE_Replace,
+ (pIdx==pPk ? ONEPASS_SINGLE : ONEPASS_OFF), iThisCur);
+ seenReplace = 1;
+ break;
+ }
+ }
+ sqlite3VdbeResolveLabel(v, addrUniqueOk);
+ if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField);
+ }
+ if( ipkTop ){
+ sqlite3VdbeGoto(v, ipkTop+1);
+ sqlite3VdbeJumpHere(v, ipkBottom);
+ }
+
+ *pbMayReplace = seenReplace;
+ VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace));
+}
+
+#ifdef SQLITE_ENABLE_NULL_TRIM
+/*
+** Change the P5 operand on the last opcode (which should be an OP_MakeRecord)
+** to be the number of columns in table pTab that must not be NULL-trimmed.
+**
+** Or if no columns of pTab may be NULL-trimmed, leave P5 at zero.
+*/
+SQLITE_PRIVATE void sqlite3SetMakeRecordP5(Vdbe *v, Table *pTab){
+ u16 i;
+
+ /* Records with omitted columns are only allowed for schema format
+ ** version 2 and later (SQLite version 3.1.4, 2005-02-20). */
+ if( pTab->pSchema->file_format<2 ) return;
+
+ for(i=pTab->nCol; i>1 && pTab->aCol[i-1].pDflt==0; i--){}
+ sqlite3VdbeChangeP5(v, i);
+}
+#endif
+
+/*
+** This routine generates code to finish the INSERT or UPDATE operation
+** that was started by a prior call to sqlite3GenerateConstraintChecks.
+** A consecutive range of registers starting at regNewData contains the
+** rowid and the content to be inserted.
+**
+** The arguments to this routine should be the same as the first six
+** arguments to sqlite3GenerateConstraintChecks.
+*/
+SQLITE_PRIVATE void sqlite3CompleteInsertion(
+ Parse *pParse, /* The parser context */
+ Table *pTab, /* the table into which we are inserting */
+ int iDataCur, /* Cursor of the canonical data source */
+ int iIdxCur, /* First index cursor */
+ int regNewData, /* Range of content */
+ int *aRegIdx, /* Register used by each index. 0 for unused indices */
+ int update_flags, /* True for UPDATE, False for INSERT */
+ int appendBias, /* True if this is likely to be an append */
+ int useSeekResult /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */
+){
+ Vdbe *v; /* Prepared statements under construction */
+ Index *pIdx; /* An index being inserted or updated */
+ u8 pik_flags; /* flag values passed to the btree insert */
+ int regData; /* Content registers (after the rowid) */
+ int regRec; /* Register holding assembled record for the table */
+ int i; /* Loop counter */
+ u8 bAffinityDone = 0; /* True if OP_Affinity has been run already */
+
+ assert( update_flags==0
+ || update_flags==OPFLAG_ISUPDATE
+ || update_flags==(OPFLAG_ISUPDATE|OPFLAG_SAVEPOSITION)
+ );
+
+ v = sqlite3GetVdbe(pParse);
+ assert( v!=0 );
+ assert( pTab->pSelect==0 ); /* This table is not a VIEW */
+ for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
+ if( aRegIdx[i]==0 ) continue;
+ bAffinityDone = 1;
+ if( pIdx->pPartIdxWhere ){
+ sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
+ VdbeCoverage(v);
+ }
+ pik_flags = (useSeekResult ? OPFLAG_USESEEKRESULT : 0);
+ if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){
+ assert( pParse->nested==0 );
+ pik_flags |= OPFLAG_NCHANGE;
+ pik_flags |= (update_flags & OPFLAG_SAVEPOSITION);
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ if( update_flags==0 ){
+ sqlite3VdbeAddOp4(v, OP_InsertInt,
+ iIdxCur+i, aRegIdx[i], 0, (char*)pTab, P4_TABLE
+ );
+ sqlite3VdbeChangeP5(v, OPFLAG_ISNOOP);
+ }
+#endif
+ }
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i],
+ aRegIdx[i]+1,
+ pIdx->uniqNotNull ? pIdx->nKeyCol: pIdx->nColumn);
+ sqlite3VdbeChangeP5(v, pik_flags);
+ }
+ if( !HasRowid(pTab) ) return;
+ regData = regNewData + 1;
+ regRec = sqlite3GetTempReg(pParse);
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec);
+ sqlite3SetMakeRecordP5(v, pTab);
+ if( !bAffinityDone ){
+ sqlite3TableAffinity(v, pTab, 0);
+ sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol);
+ }
+ if( pParse->nested ){
+ pik_flags = 0;
+ }else{
+ pik_flags = OPFLAG_NCHANGE;
+ pik_flags |= (update_flags?update_flags:OPFLAG_LASTROWID);
+ }
+ if( appendBias ){
+ pik_flags |= OPFLAG_APPEND;
+ }
+ if( useSeekResult ){
+ pik_flags |= OPFLAG_USESEEKRESULT;
+ }
+ sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, regRec, regNewData);
+ if( !pParse->nested ){
+ sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
+ }
+ sqlite3VdbeChangeP5(v, pik_flags);
+}
+
+/*
+** Allocate cursors for the pTab table and all its indices and generate
+** code to open and initialized those cursors.
+**
+** The cursor for the object that contains the complete data (normally
+** the table itself, but the PRIMARY KEY index in the case of a WITHOUT
+** ROWID table) is returned in *piDataCur. The first index cursor is
+** returned in *piIdxCur. The number of indices is returned.
+**
+** Use iBase as the first cursor (either the *piDataCur for rowid tables
+** or the first index for WITHOUT ROWID tables) if it is non-negative.
+** If iBase is negative, then allocate the next available cursor.
+**
+** For a rowid table, *piDataCur will be exactly one less than *piIdxCur.
+** For a WITHOUT ROWID table, *piDataCur will be somewhere in the range
+** of *piIdxCurs, depending on where the PRIMARY KEY index appears on the
+** pTab->pIndex list.
+**
+** If pTab is a virtual table, then this routine is a no-op and the
+** *piDataCur and *piIdxCur values are left uninitialized.
+*/
+SQLITE_PRIVATE int sqlite3OpenTableAndIndices(
+ Parse *pParse, /* Parsing context */
+ Table *pTab, /* Table to be opened */
+ int op, /* OP_OpenRead or OP_OpenWrite */
+ u8 p5, /* P5 value for OP_Open* opcodes (except on WITHOUT ROWID) */
+ int iBase, /* Use this for the table cursor, if there is one */
+ u8 *aToOpen, /* If not NULL: boolean for each table and index */
+ int *piDataCur, /* Write the database source cursor number here */
+ int *piIdxCur /* Write the first index cursor number here */
+){
+ int i;
+ int iDb;
+ int iDataCur;
+ Index *pIdx;
+ Vdbe *v;
+
+ assert( op==OP_OpenRead || op==OP_OpenWrite );
+ assert( op==OP_OpenWrite || p5==0 );
+ if( IsVirtual(pTab) ){
+ /* This routine is a no-op for virtual tables. Leave the output
+ ** variables *piDataCur and *piIdxCur uninitialized so that valgrind
+ ** can detect if they are used by mistake in the caller. */
+ return 0;
+ }
+ iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
+ v = sqlite3GetVdbe(pParse);
+ assert( v!=0 );
+ if( iBase<0 ) iBase = pParse->nTab;
+ iDataCur = iBase++;
+ if( piDataCur ) *piDataCur = iDataCur;
+ if( HasRowid(pTab) && (aToOpen==0 || aToOpen[0]) ){
+ sqlite3OpenTable(pParse, iDataCur, iDb, pTab, op);
+ }else{
+ sqlite3TableLock(pParse, iDb, pTab->tnum, op==OP_OpenWrite, pTab->zName);
+ }
+ if( piIdxCur ) *piIdxCur = iBase;
+ for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
+ int iIdxCur = iBase++;
+ assert( pIdx->pSchema==pTab->pSchema );
+ if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){
+ if( piDataCur ) *piDataCur = iIdxCur;
+ p5 = 0;
+ }
+ if( aToOpen==0 || aToOpen[i+1] ){
+ sqlite3VdbeAddOp3(v, op, iIdxCur, pIdx->tnum, iDb);
+ sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
+ sqlite3VdbeChangeP5(v, p5);
+ VdbeComment((v, "%s", pIdx->zName));
+ }
+ }
+ if( iBase>pParse->nTab ) pParse->nTab = iBase;
+ return i;
+}
+
+
+#ifdef SQLITE_TEST
+/*
+** The following global variable is incremented whenever the
+** transfer optimization is used. This is used for testing
+** purposes only - to make sure the transfer optimization really
+** is happening when it is supposed to.
+*/
+SQLITE_API int sqlite3_xferopt_count;
+#endif /* SQLITE_TEST */
+
+
+#ifndef SQLITE_OMIT_XFER_OPT
+/*
+** Check to see if index pSrc is compatible as a source of data
+** for index pDest in an insert transfer optimization. The rules
+** for a compatible index:
+**
+** * The index is over the same set of columns
+** * The same DESC and ASC markings occurs on all columns
+** * The same onError processing (OE_Abort, OE_Ignore, etc)
+** * The same collating sequence on each column
+** * The index has the exact same WHERE clause
+*/
+static int xferCompatibleIndex(Index *pDest, Index *pSrc){
+ int i;
+ assert( pDest && pSrc );
+ assert( pDest->pTable!=pSrc->pTable );
+ if( pDest->nKeyCol!=pSrc->nKeyCol ){
+ return 0; /* Different number of columns */
+ }
+ if( pDest->onError!=pSrc->onError ){
+ return 0; /* Different conflict resolution strategies */
+ }
+ for(i=0; i<pSrc->nKeyCol; i++){
+ if( pSrc->aiColumn[i]!=pDest->aiColumn[i] ){
+ return 0; /* Different columns indexed */
+ }
+ if( pSrc->aiColumn[i]==XN_EXPR ){
+ assert( pSrc->aColExpr!=0 && pDest->aColExpr!=0 );
+ if( sqlite3ExprCompare(pSrc->aColExpr->a[i].pExpr,
+ pDest->aColExpr->a[i].pExpr, -1)!=0 ){
+ return 0; /* Different expressions in the index */
+ }
+ }
+ if( pSrc->aSortOrder[i]!=pDest->aSortOrder[i] ){
+ return 0; /* Different sort orders */
+ }
+ if( sqlite3_stricmp(pSrc->azColl[i],pDest->azColl[i])!=0 ){
+ return 0; /* Different collating sequences */
+ }
+ }
+ if( sqlite3ExprCompare(pSrc->pPartIdxWhere, pDest->pPartIdxWhere, -1) ){
+ return 0; /* Different WHERE clauses */
+ }
+
+ /* If no test above fails then the indices must be compatible */
+ return 1;
+}
+
+/*
+** Attempt the transfer optimization on INSERTs of the form
+**
+** INSERT INTO tab1 SELECT * FROM tab2;
+**
+** The xfer optimization transfers raw records from tab2 over to tab1.
+** Columns are not decoded and reassembled, which greatly improves
+** performance. Raw index records are transferred in the same way.
+**
+** The xfer optimization is only attempted if tab1 and tab2 are compatible.
+** There are lots of rules for determining compatibility - see comments
+** embedded in the code for details.
+**
+** This routine returns TRUE if the optimization is guaranteed to be used.
+** Sometimes the xfer optimization will only work if the destination table
+** is empty - a factor that can only be determined at run-time. In that
+** case, this routine generates code for the xfer optimization but also
+** does a test to see if the destination table is empty and jumps over the
+** xfer optimization code if the test fails. In that case, this routine
+** returns FALSE so that the caller will know to go ahead and generate
+** an unoptimized transfer. This routine also returns FALSE if there
+** is no chance that the xfer optimization can be applied.
+**
+** This optimization is particularly useful at making VACUUM run faster.
+*/
+static int xferOptimization(
+ Parse *pParse, /* Parser context */
+ Table *pDest, /* The table we are inserting into */
+ Select *pSelect, /* A SELECT statement to use as the data source */
+ int onError, /* How to handle constraint errors */
+ int iDbDest /* The database of pDest */
+){
+ sqlite3 *db = pParse->db;
+ ExprList *pEList; /* The result set of the SELECT */
+ Table *pSrc; /* The table in the FROM clause of SELECT */
+ Index *pSrcIdx, *pDestIdx; /* Source and destination indices */
+ struct SrcList_item *pItem; /* An element of pSelect->pSrc */
+ int i; /* Loop counter */
+ int iDbSrc; /* The database of pSrc */
+ int iSrc, iDest; /* Cursors from source and destination */
+ int addr1, addr2; /* Loop addresses */
+ int emptyDestTest = 0; /* Address of test for empty pDest */
+ int emptySrcTest = 0; /* Address of test for empty pSrc */
+ Vdbe *v; /* The VDBE we are building */
+ int regAutoinc; /* Memory register used by AUTOINC */
+ int destHasUniqueIdx = 0; /* True if pDest has a UNIQUE index */
+ int regData, regRowid; /* Registers holding data and rowid */
+
+ if( pSelect==0 ){
+ return 0; /* Must be of the form INSERT INTO ... SELECT ... */
+ }
+ if( pParse->pWith || pSelect->pWith ){
+ /* Do not attempt to process this query if there are an WITH clauses
+ ** attached to it. Proceeding may generate a false "no such table: xxx"
+ ** error if pSelect reads from a CTE named "xxx". */
+ return 0;
+ }
+ if( sqlite3TriggerList(pParse, pDest) ){
+ return 0; /* tab1 must not have triggers */
+ }
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ if( pDest->tabFlags & TF_Virtual ){
+ return 0; /* tab1 must not be a virtual table */
+ }
+#endif
+ if( onError==OE_Default ){
+ if( pDest->iPKey>=0 ) onError = pDest->keyConf;
+ if( onError==OE_Default ) onError = OE_Abort;
+ }
+ assert(pSelect->pSrc); /* allocated even if there is no FROM clause */
+ if( pSelect->pSrc->nSrc!=1 ){
+ return 0; /* FROM clause must have exactly one term */
+ }
+ if( pSelect->pSrc->a[0].pSelect ){
+ return 0; /* FROM clause cannot contain a subquery */
+ }
+ if( pSelect->pWhere ){
+ return 0; /* SELECT may not have a WHERE clause */
+ }
+ if( pSelect->pOrderBy ){
+ return 0; /* SELECT may not have an ORDER BY clause */
+ }
+ /* Do not need to test for a HAVING clause. If HAVING is present but
+ ** there is no ORDER BY, we will get an error. */
+ if( pSelect->pGroupBy ){
+ return 0; /* SELECT may not have a GROUP BY clause */
+ }
+ if( pSelect->pLimit ){
+ return 0; /* SELECT may not have a LIMIT clause */
+ }
+ assert( pSelect->pOffset==0 ); /* Must be so if pLimit==0 */
+ if( pSelect->pPrior ){
+ return 0; /* SELECT may not be a compound query */
+ }
+ if( pSelect->selFlags & SF_Distinct ){
+ return 0; /* SELECT may not be DISTINCT */
+ }
+ pEList = pSelect->pEList;
+ assert( pEList!=0 );
+ if( pEList->nExpr!=1 ){
+ return 0; /* The result set must have exactly one column */
+ }
+ assert( pEList->a[0].pExpr );
+ if( pEList->a[0].pExpr->op!=TK_ASTERISK ){
+ return 0; /* The result set must be the special operator "*" */
+ }
+
+ /* At this point we have established that the statement is of the
+ ** correct syntactic form to participate in this optimization. Now
+ ** we have to check the semantics.
+ */
+ pItem = pSelect->pSrc->a;
+ pSrc = sqlite3LocateTableItem(pParse, 0, pItem);
+ if( pSrc==0 ){
+ return 0; /* FROM clause does not contain a real table */
+ }
+ if( pSrc==pDest ){
+ return 0; /* tab1 and tab2 may not be the same table */
+ }
+ if( HasRowid(pDest)!=HasRowid(pSrc) ){
+ return 0; /* source and destination must both be WITHOUT ROWID or not */
+ }
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ if( pSrc->tabFlags & TF_Virtual ){
+ return 0; /* tab2 must not be a virtual table */
+ }
+#endif
+ if( pSrc->pSelect ){
+ return 0; /* tab2 may not be a view */
+ }
+ if( pDest->nCol!=pSrc->nCol ){
+ return 0; /* Number of columns must be the same in tab1 and tab2 */
+ }
+ if( pDest->iPKey!=pSrc->iPKey ){
+ return 0; /* Both tables must have the same INTEGER PRIMARY KEY */
+ }
+ for(i=0; i<pDest->nCol; i++){
+ Column *pDestCol = &pDest->aCol[i];
+ Column *pSrcCol = &pSrc->aCol[i];
+#ifdef SQLITE_ENABLE_HIDDEN_COLUMNS
+ if( (db->flags & SQLITE_Vacuum)==0
+ && (pDestCol->colFlags | pSrcCol->colFlags) & COLFLAG_HIDDEN
+ ){
+ return 0; /* Neither table may have __hidden__ columns */
+ }
+#endif
+ if( pDestCol->affinity!=pSrcCol->affinity ){
+ return 0; /* Affinity must be the same on all columns */
+ }
+ if( sqlite3_stricmp(pDestCol->zColl, pSrcCol->zColl)!=0 ){
+ return 0; /* Collating sequence must be the same on all columns */
+ }
+ if( pDestCol->notNull && !pSrcCol->notNull ){
+ return 0; /* tab2 must be NOT NULL if tab1 is */
+ }
+ /* Default values for second and subsequent columns need to match. */
+ if( i>0 ){
+ assert( pDestCol->pDflt==0 || pDestCol->pDflt->op==TK_SPAN );
+ assert( pSrcCol->pDflt==0 || pSrcCol->pDflt->op==TK_SPAN );
+ if( (pDestCol->pDflt==0)!=(pSrcCol->pDflt==0)
+ || (pDestCol->pDflt && strcmp(pDestCol->pDflt->u.zToken,
+ pSrcCol->pDflt->u.zToken)!=0)
+ ){
+ return 0; /* Default values must be the same for all columns */
+ }
+ }
+ }
+ for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
+ if( IsUniqueIndex(pDestIdx) ){
+ destHasUniqueIdx = 1;
+ }
+ for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){
+ if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
+ }
+ if( pSrcIdx==0 ){
+ return 0; /* pDestIdx has no corresponding index in pSrc */
+ }
+ }
+#ifndef SQLITE_OMIT_CHECK
+ if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){
+ return 0; /* Tables have different CHECK constraints. Ticket #2252 */
+ }
+#endif
+#ifndef SQLITE_OMIT_FOREIGN_KEY
+ /* Disallow the transfer optimization if the destination table constains
+ ** any foreign key constraints. This is more restrictive than necessary.
+ ** But the main beneficiary of the transfer optimization is the VACUUM
+ ** command, and the VACUUM command disables foreign key constraints. So
+ ** the extra complication to make this rule less restrictive is probably
+ ** not worth the effort. Ticket [6284df89debdfa61db8073e062908af0c9b6118e]
+ */
+ if( (db->flags & SQLITE_ForeignKeys)!=0 && pDest->pFKey!=0 ){
+ return 0;
+ }
+#endif
+ if( (db->flags & SQLITE_CountRows)!=0 ){
+ return 0; /* xfer opt does not play well with PRAGMA count_changes */
+ }
+
+ /* If we get this far, it means that the xfer optimization is at
+ ** least a possibility, though it might only work if the destination
+ ** table (tab1) is initially empty.
+ */
+#ifdef SQLITE_TEST
+ sqlite3_xferopt_count++;
+#endif
+ iDbSrc = sqlite3SchemaToIndex(db, pSrc->pSchema);
+ v = sqlite3GetVdbe(pParse);
+ sqlite3CodeVerifySchema(pParse, iDbSrc);
+ iSrc = pParse->nTab++;
+ iDest = pParse->nTab++;
+ regAutoinc = autoIncBegin(pParse, iDbDest, pDest);
+ regData = sqlite3GetTempReg(pParse);
+ regRowid = sqlite3GetTempReg(pParse);
+ sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite);
+ assert( HasRowid(pDest) || destHasUniqueIdx );
+ if( (db->flags & SQLITE_Vacuum)==0 && (
+ (pDest->iPKey<0 && pDest->pIndex!=0) /* (1) */
+ || destHasUniqueIdx /* (2) */
+ || (onError!=OE_Abort && onError!=OE_Rollback) /* (3) */
+ )){
+ /* In some circumstances, we are able to run the xfer optimization
+ ** only if the destination table is initially empty. Unless the
+ ** SQLITE_Vacuum flag is set, this block generates code to make
+ ** that determination. If SQLITE_Vacuum is set, then the destination
+ ** table is always empty.
+ **
+ ** Conditions under which the destination must be empty:
+ **
+ ** (1) There is no INTEGER PRIMARY KEY but there are indices.
+ ** (If the destination is not initially empty, the rowid fields
+ ** of index entries might need to change.)
+ **
+ ** (2) The destination has a unique index. (The xfer optimization
+ ** is unable to test uniqueness.)
+ **
+ ** (3) onError is something other than OE_Abort and OE_Rollback.
+ */
+ addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0); VdbeCoverage(v);
+ emptyDestTest = sqlite3VdbeAddOp0(v, OP_Goto);
+ sqlite3VdbeJumpHere(v, addr1);
+ }
+ if( HasRowid(pSrc) ){
+ u8 insFlags;
+ sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead);
+ emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
+ if( pDest->iPKey>=0 ){
+ addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
+ addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid);
+ VdbeCoverage(v);
+ sqlite3RowidConstraint(pParse, onError, pDest);
+ sqlite3VdbeJumpHere(v, addr2);
+ autoIncStep(pParse, regAutoinc, regRowid);
+ }else if( pDest->pIndex==0 ){
+ addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid);
+ }else{
+ addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
+ assert( (pDest->tabFlags & TF_Autoincrement)==0 );
+ }
+ sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1);
+ if( db->flags & SQLITE_Vacuum ){
+ sqlite3VdbeAddOp3(v, OP_Last, iDest, 0, -1);
+ insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|
+ OPFLAG_APPEND|OPFLAG_USESEEKRESULT;
+ }else{
+ insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND;
+ }
+ sqlite3VdbeAddOp4(v, OP_Insert, iDest, regData, regRowid,
+ (char*)pDest, P4_TABLE);
+ sqlite3VdbeChangeP5(v, insFlags);
+ sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
+ sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
+ }else{
+ sqlite3TableLock(pParse, iDbDest, pDest->tnum, 1, pDest->zName);
+ sqlite3TableLock(pParse, iDbSrc, pSrc->tnum, 0, pSrc->zName);
+ }
+ for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
+ u8 idxInsFlags = 0;
+ for(pSrcIdx=pSrc->pIndex; ALWAYS(pSrcIdx); pSrcIdx=pSrcIdx->pNext){
+ if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
+ }
+ assert( pSrcIdx );
+ sqlite3VdbeAddOp3(v, OP_OpenRead, iSrc, pSrcIdx->tnum, iDbSrc);
+ sqlite3VdbeSetP4KeyInfo(pParse, pSrcIdx);
+ VdbeComment((v, "%s", pSrcIdx->zName));
+ sqlite3VdbeAddOp3(v, OP_OpenWrite, iDest, pDestIdx->tnum, iDbDest);
+ sqlite3VdbeSetP4KeyInfo(pParse, pDestIdx);
+ sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR);
+ VdbeComment((v, "%s", pDestIdx->zName));
+ addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1);
+ if( db->flags & SQLITE_Vacuum ){
+ /* This INSERT command is part of a VACUUM operation, which guarantees
+ ** that the destination table is empty. If all indexed columns use
+ ** collation sequence BINARY, then it can also be assumed that the
+ ** index will be populated by inserting keys in strictly sorted
+ ** order. In this case, instead of seeking within the b-tree as part
+ ** of every OP_IdxInsert opcode, an OP_Last is added before the
+ ** OP_IdxInsert to seek to the point within the b-tree where each key
+ ** should be inserted. This is faster.
+ **
+ ** If any of the indexed columns use a collation sequence other than
+ ** BINARY, this optimization is disabled. This is because the user
+ ** might change the definition of a collation sequence and then run
+ ** a VACUUM command. In that case keys may not be written in strictly
+ ** sorted order. */
+ for(i=0; i<pSrcIdx->nColumn; i++){
+ const char *zColl = pSrcIdx->azColl[i];
+ assert( sqlite3_stricmp(sqlite3StrBINARY, zColl)!=0
+ || sqlite3StrBINARY==zColl );
+ if( sqlite3_stricmp(sqlite3StrBINARY, zColl) ) break;
+ }
+ if( i==pSrcIdx->nColumn ){
+ idxInsFlags = OPFLAG_USESEEKRESULT;
+ sqlite3VdbeAddOp3(v, OP_Last, iDest, 0, -1);
+ }
+ }
+ if( !HasRowid(pSrc) && pDestIdx->idxType==2 ){
+ idxInsFlags |= OPFLAG_NCHANGE;
+ }
+ sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, regData);
+ sqlite3VdbeChangeP5(v, idxInsFlags|OPFLAG_APPEND);
+ sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v);
+ sqlite3VdbeJumpHere(v, addr1);
+ sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
+ sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
+ }
+ if( emptySrcTest ) sqlite3VdbeJumpHere(v, emptySrcTest);
+ sqlite3ReleaseTempReg(pParse, regRowid);
+ sqlite3ReleaseTempReg(pParse, regData);
+ if( emptyDestTest ){
+ sqlite3AutoincrementEnd(pParse);
+ sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, 0);
+ sqlite3VdbeJumpHere(v, emptyDestTest);
+ sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
+ return 0;
+ }else{
+ return 1;
+ }
+}
+#endif /* SQLITE_OMIT_XFER_OPT */
+
+/************** End of insert.c **********************************************/
+/************** Begin file legacy.c ******************************************/
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** Main file for the SQLite library. The routines in this file
+** implement the programmer interface to the library. Routines in
+** other files are for internal use by SQLite and should not be
+** accessed by users of the library.
+*/
+
+/* #include "sqliteInt.h" */
+
+/*
+** Execute SQL code. 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.
+**
+** If the SQL is a query, then for each row in the query result
+** the xCallback() function is called. pArg becomes the first
+** argument to xCallback(). If xCallback=NULL then no callback
+** is invoked, even for queries.
+*/
+SQLITE_API int sqlite3_exec(
+ sqlite3 *db, /* The database on which the SQL executes */
+ const char *zSql, /* The SQL to be executed */
+ sqlite3_callback xCallback, /* Invoke this callback routine */
+ void *pArg, /* First argument to xCallback() */
+ char **pzErrMsg /* Write error messages here */
+){
+ int rc = SQLITE_OK; /* Return code */
+ const char *zLeftover; /* Tail of unprocessed SQL */
+ sqlite3_stmt *pStmt = 0; /* The current SQL statement */
+ char **azCols = 0; /* Names of result columns */
+ int callbackIsInit; /* True if callback data is initialized */
+
+ if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
+ if( zSql==0 ) zSql = "";
+
+ sqlite3_mutex_enter(db->mutex);
+ sqlite3Error(db, SQLITE_OK);
+ while( rc==SQLITE_OK && zSql[0] ){
+ int nCol;
+ char **azVals = 0;
+
+ pStmt = 0;
+ rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
+ assert( rc==SQLITE_OK || pStmt==0 );
+ if( rc!=SQLITE_OK ){
+ continue;
+ }
+ if( !pStmt ){
+ /* this happens for a comment or white-space */
+ zSql = zLeftover;
+ continue;
+ }
+
+ callbackIsInit = 0;
+ nCol = sqlite3_column_count(pStmt);
+
+ while( 1 ){
+ int i;
+ rc = sqlite3_step(pStmt);
+
+ /* Invoke the callback function if required */
+ if( xCallback && (SQLITE_ROW==rc ||
+ (SQLITE_DONE==rc && !callbackIsInit
+ && db->flags&SQLITE_NullCallback)) ){
+ if( !callbackIsInit ){
+ azCols = sqlite3DbMallocZero(db, 2*nCol*sizeof(const char*) + 1);
+ if( azCols==0 ){
+ goto exec_out;
+ }
+ for(i=0; i<nCol; i++){
+ azCols[i] = (char *)sqlite3_column_name(pStmt, i);
+ /* sqlite3VdbeSetColName() installs column names as UTF8
+ ** strings so there is no way for sqlite3_column_name() to fail. */
+ assert( azCols[i]!=0 );
+ }
+ callbackIsInit = 1;
+ }
+ if( rc==SQLITE_ROW ){
+ azVals = &azCols[nCol];
+ for(i=0; i<nCol; i++){
+ azVals[i] = (char *)sqlite3_column_text(pStmt, i);
+ if( !azVals[i] && sqlite3_column_type(pStmt, i)!=SQLITE_NULL ){
+ sqlite3OomFault(db);
+ goto exec_out;
+ }
+ }
+ }
+ if( xCallback(pArg, nCol, azVals, azCols) ){
+ /* EVIDENCE-OF: R-38229-40159 If the callback function to
+ ** sqlite3_exec() returns non-zero, then sqlite3_exec() will
+ ** return SQLITE_ABORT. */
+ rc = SQLITE_ABORT;
+ sqlite3VdbeFinalize((Vdbe *)pStmt);
+ pStmt = 0;
+ sqlite3Error(db, SQLITE_ABORT);
+ goto exec_out;
+ }
+ }
+
+ if( rc!=SQLITE_ROW ){
+ rc = sqlite3VdbeFinalize((Vdbe *)pStmt);
+ pStmt = 0;
+ zSql = zLeftover;
+ while( sqlite3Isspace(zSql[0]) ) zSql++;
+ break;
+ }
+ }
+
+ sqlite3DbFree(db, azCols);
+ azCols = 0;
+ }
+
+exec_out:
+ if( pStmt ) sqlite3VdbeFinalize((Vdbe *)pStmt);
+ sqlite3DbFree(db, azCols);
+
+ rc = sqlite3ApiExit(db, rc);
+ if( rc!=SQLITE_OK && pzErrMsg ){
+ int nErrMsg = 1 + sqlite3Strlen30(sqlite3_errmsg(db));
+ *pzErrMsg = sqlite3Malloc(nErrMsg);
+ if( *pzErrMsg ){
+ memcpy(*pzErrMsg, sqlite3_errmsg(db), nErrMsg);
+ }else{
+ rc = SQLITE_NOMEM_BKPT;
+ sqlite3Error(db, SQLITE_NOMEM);
+ }
+ }else if( pzErrMsg ){
+ *pzErrMsg = 0;
+ }
+
+ assert( (rc&db->errMask)==rc );
+ sqlite3_mutex_leave(db->mutex);
+ return rc;
+}
+
+/************** End of legacy.c **********************************************/
+/************** Begin file loadext.c *****************************************/
+/*
+** 2006 June 7
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains code used to dynamically load extensions into
+** the SQLite library.
+*/
+
+#ifndef SQLITE_CORE
+ #define SQLITE_CORE 1 /* Disable the API redefinition in sqlite3ext.h */
+#endif
+/************** Include sqlite3ext.h in the middle of loadext.c **************/
+/************** Begin file sqlite3ext.h **************************************/
+/*
+** 2006 June 7
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This header file defines the SQLite interface for use by
+** shared libraries that want to be imported as extensions into
+** an SQLite instance. Shared libraries that intend to be loaded
+** as extensions by SQLite should #include this file instead of
+** sqlite3.h.
+*/
+#ifndef SQLITE3EXT_H
+#define SQLITE3EXT_H
+/* #include "sqlite3.h" */
+
+/*
+** The following structure holds pointers to all of the SQLite API
+** routines.
+**
+** WARNING: In order to maintain backwards compatibility, add new
+** interfaces to the end of this structure only. If you insert new
+** interfaces in the middle of this structure, then older different
+** versions of SQLite will not be able to load each other's shared
+** libraries!
+*/
+struct sqlite3_api_routines {
+ void * (*aggregate_context)(sqlite3_context*,int nBytes);
+ int (*aggregate_count)(sqlite3_context*);
+ int (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*));
+ int (*bind_double)(sqlite3_stmt*,int,double);
+ int (*bind_int)(sqlite3_stmt*,int,int);
+ int (*bind_int64)(sqlite3_stmt*,int,sqlite_int64);
+ int (*bind_null)(sqlite3_stmt*,int);
+ int (*bind_parameter_count)(sqlite3_stmt*);
+ int (*bind_parameter_index)(sqlite3_stmt*,const char*zName);
+ const char * (*bind_parameter_name)(sqlite3_stmt*,int);
+ int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*));
+ int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*));
+ int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*);
+ int (*busy_handler)(sqlite3*,int(*)(void*,int),void*);
+ int (*busy_timeout)(sqlite3*,int ms);
+ int (*changes)(sqlite3*);
+ int (*close)(sqlite3*);
+ int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*,
+ int eTextRep,const char*));
+ int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*,
+ int eTextRep,const void*));
+ const void * (*column_blob)(sqlite3_stmt*,int iCol);
+ int (*column_bytes)(sqlite3_stmt*,int iCol);
+ int (*column_bytes16)(sqlite3_stmt*,int iCol);
+ int (*column_count)(sqlite3_stmt*pStmt);
+ const char * (*column_database_name)(sqlite3_stmt*,int);
+ const void * (*column_database_name16)(sqlite3_stmt*,int);
+ const char * (*column_decltype)(sqlite3_stmt*,int i);
+ const void * (*column_decltype16)(sqlite3_stmt*,int);
+ double (*column_double)(sqlite3_stmt*,int iCol);
+ int (*column_int)(sqlite3_stmt*,int iCol);
+ sqlite_int64 (*column_int64)(sqlite3_stmt*,int iCol);
+ const char * (*column_name)(sqlite3_stmt*,int);
+ const void * (*column_name16)(sqlite3_stmt*,int);
+ const char * (*column_origin_name)(sqlite3_stmt*,int);
+ const void * (*column_origin_name16)(sqlite3_stmt*,int);
+ const char * (*column_table_name)(sqlite3_stmt*,int);
+ const void * (*column_table_name16)(sqlite3_stmt*,int);
+ const unsigned char * (*column_text)(sqlite3_stmt*,int iCol);
+ const void * (*column_text16)(sqlite3_stmt*,int iCol);
+ int (*column_type)(sqlite3_stmt*,int iCol);
+ sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol);
+ void * (*commit_hook)(sqlite3*,int(*)(void*),void*);
+ int (*complete)(const char*sql);
+ int (*complete16)(const void*sql);
+ int (*create_collation)(sqlite3*,const char*,int,void*,
+ int(*)(void*,int,const void*,int,const void*));
+ int (*create_collation16)(sqlite3*,const void*,int,void*,
+ int(*)(void*,int,const void*,int,const void*));
+ int (*create_function)(sqlite3*,const char*,int,int,void*,
+ void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
+ void (*xStep)(sqlite3_context*,int,sqlite3_value**),
+ void (*xFinal)(sqlite3_context*));
+ int (*create_function16)(sqlite3*,const void*,int,int,void*,
+ void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
+ void (*xStep)(sqlite3_context*,int,sqlite3_value**),
+ void (*xFinal)(sqlite3_context*));
+ int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*);
+ int (*data_count)(sqlite3_stmt*pStmt);
+ sqlite3 * (*db_handle)(sqlite3_stmt*);
+ int (*declare_vtab)(sqlite3*,const char*);
+ int (*enable_shared_cache)(int);
+ int (*errcode)(sqlite3*db);
+ const char * (*errmsg)(sqlite3*);
+ const void * (*errmsg16)(sqlite3*);
+ int (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**);
+ int (*expired)(sqlite3_stmt*);
+ int (*finalize)(sqlite3_stmt*pStmt);
+ void (*free)(void*);
+ void (*free_table)(char**result);
+ int (*get_autocommit)(sqlite3*);
+ void * (*get_auxdata)(sqlite3_context*,int);
+ int (*get_table)(sqlite3*,const char*,char***,int*,int*,char**);
+ int (*global_recover)(void);
+ void (*interruptx)(sqlite3*);
+ sqlite_int64 (*last_insert_rowid)(sqlite3*);
+ const char * (*libversion)(void);
+ int (*libversion_number)(void);
+ void *(*malloc)(int);
+ char * (*mprintf)(const char*,...);
+ int (*open)(const char*,sqlite3**);
+ int (*open16)(const void*,sqlite3**);
+ int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
+ int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
+ void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*);
+ void (*progress_handler)(sqlite3*,int,int(*)(void*),void*);
+ void *(*realloc)(void*,int);
+ int (*reset)(sqlite3_stmt*pStmt);
+ void (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*));
+ void (*result_double)(sqlite3_context*,double);
+ void (*result_error)(sqlite3_context*,const char*,int);
+ void (*result_error16)(sqlite3_context*,const void*,int);
+ void (*result_int)(sqlite3_context*,int);
+ void (*result_int64)(sqlite3_context*,sqlite_int64);
+ void (*result_null)(sqlite3_context*);
+ void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*));
+ void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*));
+ void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*));
+ void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*));
+ void (*result_value)(sqlite3_context*,sqlite3_value*);
+ void * (*rollback_hook)(sqlite3*,void(*)(void*),void*);
+ int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,
+ const char*,const char*),void*);
+ void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*));
+ char * (*snprintf)(int,char*,const char*,...);
+ int (*step)(sqlite3_stmt*);
+ int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,
+ char const**,char const**,int*,int*,int*);
+ void (*thread_cleanup)(void);
+ int (*total_changes)(sqlite3*);
+ void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*);
+ int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*);
+ void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*,
+ sqlite_int64),void*);
+ void * (*user_data)(sqlite3_context*);
+ const void * (*value_blob)(sqlite3_value*);
+ int (*value_bytes)(sqlite3_value*);
+ int (*value_bytes16)(sqlite3_value*);
+ double (*value_double)(sqlite3_value*);
+ int (*value_int)(sqlite3_value*);
+ sqlite_int64 (*value_int64)(sqlite3_value*);
+ int (*value_numeric_type)(sqlite3_value*);
+ const unsigned char * (*value_text)(sqlite3_value*);
+ const void * (*value_text16)(sqlite3_value*);
+ const void * (*value_text16be)(sqlite3_value*);
+ const void * (*value_text16le)(sqlite3_value*);
+ int (*value_type)(sqlite3_value*);
+ char *(*vmprintf)(const char*,va_list);
+ /* Added ??? */
+ int (*overload_function)(sqlite3*, const char *zFuncName, int nArg);
+ /* Added by 3.3.13 */
+ int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
+ int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
+ int (*clear_bindings)(sqlite3_stmt*);
+ /* Added by 3.4.1 */
+ int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*,
+ void (*xDestroy)(void *));
+ /* Added by 3.5.0 */
+ int (*bind_zeroblob)(sqlite3_stmt*,int,int);
+ int (*blob_bytes)(sqlite3_blob*);
+ int (*blob_close)(sqlite3_blob*);
+ int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64,
+ int,sqlite3_blob**);
+ int (*blob_read)(sqlite3_blob*,void*,int,int);
+ int (*blob_write)(sqlite3_blob*,const void*,int,int);
+ int (*create_collation_v2)(sqlite3*,const char*,int,void*,
+ int(*)(void*,int,const void*,int,const void*),
+ void(*)(void*));
+ int (*file_control)(sqlite3*,const char*,int,void*);
+ sqlite3_int64 (*memory_highwater)(int);
+ sqlite3_int64 (*memory_used)(void);
+ sqlite3_mutex *(*mutex_alloc)(int);
+ void (*mutex_enter)(sqlite3_mutex*);
+ void (*mutex_free)(sqlite3_mutex*);
+ void (*mutex_leave)(sqlite3_mutex*);
+ int (*mutex_try)(sqlite3_mutex*);
+ int (*open_v2)(const char*,sqlite3**,int,const char*);
+ int (*release_memory)(int);
+ void (*result_error_nomem)(sqlite3_context*);
+ void (*result_error_toobig)(sqlite3_context*);
+ int (*sleep)(int);
+ void (*soft_heap_limit)(int);
+ sqlite3_vfs *(*vfs_find)(const char*);
+ int (*vfs_register)(sqlite3_vfs*,int);
+ int (*vfs_unregister)(sqlite3_vfs*);
+ int (*xthreadsafe)(void);
+ void (*result_zeroblob)(sqlite3_context*,int);
+ void (*result_error_code)(sqlite3_context*,int);
+ int (*test_control)(int, ...);
+ void (*randomness)(int,void*);
+ sqlite3 *(*context_db_handle)(sqlite3_context*);
+ int (*extended_result_codes)(sqlite3*,int);
+ int (*limit)(sqlite3*,int,int);
+ sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*);
+ const char *(*sql)(sqlite3_stmt*);
+ int (*status)(int,int*,int*,int);
+ int (*backup_finish)(sqlite3_backup*);
+ sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*);
+ int (*backup_pagecount)(sqlite3_backup*);
+ int (*backup_remaining)(sqlite3_backup*);
+ int (*backup_step)(sqlite3_backup*,int);
+ const char *(*compileoption_get)(int);
+ int (*compileoption_used)(const char*);
+ int (*create_function_v2)(sqlite3*,const char*,int,int,void*,
+ void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
+ void (*xStep)(sqlite3_context*,int,sqlite3_value**),
+ void (*xFinal)(sqlite3_context*),
+ void(*xDestroy)(void*));
+ int (*db_config)(sqlite3*,int,...);
+ sqlite3_mutex *(*db_mutex)(sqlite3*);
+ int (*db_status)(sqlite3*,int,int*,int*,int);
+ int (*extended_errcode)(sqlite3*);
+ void (*log)(int,const char*,...);
+ sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64);
+ const char *(*sourceid)(void);
+ int (*stmt_status)(sqlite3_stmt*,int,int);
+ int (*strnicmp)(const char*,const char*,int);
+ int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*);
+ int (*wal_autocheckpoint)(sqlite3*,int);
+ int (*wal_checkpoint)(sqlite3*,const char*);
+ void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*);
+ int (*blob_reopen)(sqlite3_blob*,sqlite3_int64);
+ int (*vtab_config)(sqlite3*,int op,...);
+ int (*vtab_on_conflict)(sqlite3*);
+ /* Version 3.7.16 and later */
+ int (*close_v2)(sqlite3*);
+ const char *(*db_filename)(sqlite3*,const char*);
+ int (*db_readonly)(sqlite3*,const char*);
+ int (*db_release_memory)(sqlite3*);
+ const char *(*errstr)(int);
+ int (*stmt_busy)(sqlite3_stmt*);
+ int (*stmt_readonly)(sqlite3_stmt*);
+ int (*stricmp)(const char*,const char*);
+ int (*uri_boolean)(const char*,const char*,int);
+ sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64);
+ const char *(*uri_parameter)(const char*,const char*);
+ char *(*vsnprintf)(int,char*,const char*,va_list);
+ int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*);
+ /* Version 3.8.7 and later */
+ int (*auto_extension)(void(*)(void));
+ int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64,
+ void(*)(void*));
+ int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64,
+ void(*)(void*),unsigned char);
+ int (*cancel_auto_extension)(void(*)(void));
+ int (*load_extension)(sqlite3*,const char*,const char*,char**);
+ void *(*malloc64)(sqlite3_uint64);
+ sqlite3_uint64 (*msize)(void*);
+ void *(*realloc64)(void*,sqlite3_uint64);
+ void (*reset_auto_extension)(void);
+ void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64,
+ void(*)(void*));
+ void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64,
+ void(*)(void*), unsigned char);
+ int (*strglob)(const char*,const char*);
+ /* Version 3.8.11 and later */
+ sqlite3_value *(*value_dup)(const sqlite3_value*);
+ void (*value_free)(sqlite3_value*);
+ int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64);
+ int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64);
+ /* Version 3.9.0 and later */
+ unsigned int (*value_subtype)(sqlite3_value*);
+ void (*result_subtype)(sqlite3_context*,unsigned int);
+ /* Version 3.10.0 and later */
+ int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int);
+ int (*strlike)(const char*,const char*,unsigned int);
+ int (*db_cacheflush)(sqlite3*);
+ /* Version 3.12.0 and later */
+ int (*system_errno)(sqlite3*);
+ /* Version 3.14.0 and later */
+ int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*);
+ char *(*expanded_sql)(sqlite3_stmt*);
+};
+
+/*
+** This is the function signature used for all extension entry points. It
+** is also defined in the file "loadext.c".
+*/
+typedef int (*sqlite3_loadext_entry)(
+ sqlite3 *db, /* Handle to the database. */
+ char **pzErrMsg, /* Used to set error string on failure. */
+ const sqlite3_api_routines *pThunk /* Extension API function pointers. */
+);
+
+/*
+** The following macros redefine the API routines so that they are
+** redirected through the global sqlite3_api structure.
+**
+** This header file is also used by the loadext.c source file
+** (part of the main SQLite library - not an extension) so that
+** it can get access to the sqlite3_api_routines structure
+** definition. But the main library does not want to redefine
+** the API. So the redefinition macros are only valid if the
+** SQLITE_CORE macros is undefined.
+*/
+#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
+#define sqlite3_aggregate_context sqlite3_api->aggregate_context
+#ifndef SQLITE_OMIT_DEPRECATED
+#define sqlite3_aggregate_count sqlite3_api->aggregate_count
+#endif
+#define sqlite3_bind_blob sqlite3_api->bind_blob
+#define sqlite3_bind_double sqlite3_api->bind_double
+#define sqlite3_bind_int sqlite3_api->bind_int
+#define sqlite3_bind_int64 sqlite3_api->bind_int64
+#define sqlite3_bind_null sqlite3_api->bind_null
+#define sqlite3_bind_parameter_count sqlite3_api->bind_parameter_count
+#define sqlite3_bind_parameter_index sqlite3_api->bind_parameter_index
+#define sqlite3_bind_parameter_name sqlite3_api->bind_parameter_name
+#define sqlite3_bind_text sqlite3_api->bind_text
+#define sqlite3_bind_text16 sqlite3_api->bind_text16
+#define sqlite3_bind_value sqlite3_api->bind_value
+#define sqlite3_busy_handler sqlite3_api->busy_handler
+#define sqlite3_busy_timeout sqlite3_api->busy_timeout
+#define sqlite3_changes sqlite3_api->changes
+#define sqlite3_close sqlite3_api->close
+#define sqlite3_collation_needed sqlite3_api->collation_needed
+#define sqlite3_collation_needed16 sqlite3_api->collation_needed16
+#define sqlite3_column_blob sqlite3_api->column_blob
+#define sqlite3_column_bytes sqlite3_api->column_bytes
+#define sqlite3_column_bytes16 sqlite3_api->column_bytes16
+#define sqlite3_column_count sqlite3_api->column_count
+#define sqlite3_column_database_name sqlite3_api->column_database_name
+#define sqlite3_column_database_name16 sqlite3_api->column_database_name16
+#define sqlite3_column_decltype sqlite3_api->column_decltype
+#define sqlite3_column_decltype16 sqlite3_api->column_decltype16
+#define sqlite3_column_double sqlite3_api->column_double
+#define sqlite3_column_int sqlite3_api->column_int
+#define sqlite3_column_int64 sqlite3_api->column_int64
+#define sqlite3_column_name sqlite3_api->column_name
+#define sqlite3_column_name16 sqlite3_api->column_name16
+#define sqlite3_column_origin_name sqlite3_api->column_origin_name
+#define sqlite3_column_origin_name16 sqlite3_api->column_origin_name16
+#define sqlite3_column_table_name sqlite3_api->column_table_name
+#define sqlite3_column_table_name16 sqlite3_api->column_table_name16
+#define sqlite3_column_text sqlite3_api->column_text
+#define sqlite3_column_text16 sqlite3_api->column_text16
+#define sqlite3_column_type sqlite3_api->column_type
+#define sqlite3_column_value sqlite3_api->column_value
+#define sqlite3_commit_hook sqlite3_api->commit_hook
+#define sqlite3_complete sqlite3_api->complete
+#define sqlite3_complete16 sqlite3_api->complete16
+#define sqlite3_create_collation sqlite3_api->create_collation
+#define sqlite3_create_collation16 sqlite3_api->create_collation16
+#define sqlite3_create_function sqlite3_api->create_function
+#define sqlite3_create_function16 sqlite3_api->create_function16
+#define sqlite3_create_module sqlite3_api->create_module
+#define sqlite3_create_module_v2 sqlite3_api->create_module_v2
+#define sqlite3_data_count sqlite3_api->data_count
+#define sqlite3_db_handle sqlite3_api->db_handle
+#define sqlite3_declare_vtab sqlite3_api->declare_vtab
+#define sqlite3_enable_shared_cache sqlite3_api->enable_shared_cache
+#define sqlite3_errcode sqlite3_api->errcode
+#define sqlite3_errmsg sqlite3_api->errmsg
+#define sqlite3_errmsg16 sqlite3_api->errmsg16
+#define sqlite3_exec sqlite3_api->exec
+#ifndef SQLITE_OMIT_DEPRECATED
+#define sqlite3_expired sqlite3_api->expired
+#endif
+#define sqlite3_finalize sqlite3_api->finalize
+#define sqlite3_free sqlite3_api->free
+#define sqlite3_free_table sqlite3_api->free_table
+#define sqlite3_get_autocommit sqlite3_api->get_autocommit
+#define sqlite3_get_auxdata sqlite3_api->get_auxdata
+#define sqlite3_get_table sqlite3_api->get_table
+#ifndef SQLITE_OMIT_DEPRECATED
+#define sqlite3_global_recover sqlite3_api->global_recover
+#endif
+#define sqlite3_interrupt sqlite3_api->interruptx
+#define sqlite3_last_insert_rowid sqlite3_api->last_insert_rowid
+#define sqlite3_libversion sqlite3_api->libversion
+#define sqlite3_libversion_number sqlite3_api->libversion_number
+#define sqlite3_malloc sqlite3_api->malloc
+#define sqlite3_mprintf sqlite3_api->mprintf
+#define sqlite3_open sqlite3_api->open
+#define sqlite3_open16 sqlite3_api->open16
+#define sqlite3_prepare sqlite3_api->prepare
+#define sqlite3_prepare16 sqlite3_api->prepare16
+#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
+#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
+#define sqlite3_profile sqlite3_api->profile
+#define sqlite3_progress_handler sqlite3_api->progress_handler
+#define sqlite3_realloc sqlite3_api->realloc
+#define sqlite3_reset sqlite3_api->reset
+#define sqlite3_result_blob sqlite3_api->result_blob
+#define sqlite3_result_double sqlite3_api->result_double
+#define sqlite3_result_error sqlite3_api->result_error
+#define sqlite3_result_error16 sqlite3_api->result_error16
+#define sqlite3_result_int sqlite3_api->result_int
+#define sqlite3_result_int64 sqlite3_api->result_int64
+#define sqlite3_result_null sqlite3_api->result_null
+#define sqlite3_result_text sqlite3_api->result_text
+#define sqlite3_result_text16 sqlite3_api->result_text16
+#define sqlite3_result_text16be sqlite3_api->result_text16be
+#define sqlite3_result_text16le sqlite3_api->result_text16le
+#define sqlite3_result_value sqlite3_api->result_value
+#define sqlite3_rollback_hook sqlite3_api->rollback_hook
+#define sqlite3_set_authorizer sqlite3_api->set_authorizer
+#define sqlite3_set_auxdata sqlite3_api->set_auxdata
+#define sqlite3_snprintf sqlite3_api->snprintf
+#define sqlite3_step sqlite3_api->step
+#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata
+#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup
+#define sqlite3_total_changes sqlite3_api->total_changes
+#define sqlite3_trace sqlite3_api->trace
+#ifndef SQLITE_OMIT_DEPRECATED
+#define sqlite3_transfer_bindings sqlite3_api->transfer_bindings
+#endif
+#define sqlite3_update_hook sqlite3_api->update_hook
+#define sqlite3_user_data sqlite3_api->user_data
+#define sqlite3_value_blob sqlite3_api->value_blob
+#define sqlite3_value_bytes sqlite3_api->value_bytes
+#define sqlite3_value_bytes16 sqlite3_api->value_bytes16
+#define sqlite3_value_double sqlite3_api->value_double
+#define sqlite3_value_int sqlite3_api->value_int
+#define sqlite3_value_int64 sqlite3_api->value_int64
+#define sqlite3_value_numeric_type sqlite3_api->value_numeric_type
+#define sqlite3_value_text sqlite3_api->value_text
+#define sqlite3_value_text16 sqlite3_api->value_text16
+#define sqlite3_value_text16be sqlite3_api->value_text16be
+#define sqlite3_value_text16le sqlite3_api->value_text16le
+#define sqlite3_value_type sqlite3_api->value_type
+#define sqlite3_vmprintf sqlite3_api->vmprintf
+#define sqlite3_vsnprintf sqlite3_api->vsnprintf
+#define sqlite3_overload_function sqlite3_api->overload_function
+#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
+#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
+#define sqlite3_clear_bindings sqlite3_api->clear_bindings
+#define sqlite3_bind_zeroblob sqlite3_api->bind_zeroblob
+#define sqlite3_blob_bytes sqlite3_api->blob_bytes
+#define sqlite3_blob_close sqlite3_api->blob_close
+#define sqlite3_blob_open sqlite3_api->blob_open
+#define sqlite3_blob_read sqlite3_api->blob_read
+#define sqlite3_blob_write sqlite3_api->blob_write
+#define sqlite3_create_collation_v2 sqlite3_api->create_collation_v2
+#define sqlite3_file_control sqlite3_api->file_control
+#define sqlite3_memory_highwater sqlite3_api->memory_highwater
+#define sqlite3_memory_used sqlite3_api->memory_used
+#define sqlite3_mutex_alloc sqlite3_api->mutex_alloc
+#define sqlite3_mutex_enter sqlite3_api->mutex_enter
+#define sqlite3_mutex_free sqlite3_api->mutex_free
+#define sqlite3_mutex_leave sqlite3_api->mutex_leave
+#define sqlite3_mutex_try sqlite3_api->mutex_try
+#define sqlite3_open_v2 sqlite3_api->open_v2
+#define sqlite3_release_memory sqlite3_api->release_memory
+#define sqlite3_result_error_nomem sqlite3_api->result_error_nomem
+#define sqlite3_result_error_toobig sqlite3_api->result_error_toobig
+#define sqlite3_sleep sqlite3_api->sleep
+#define sqlite3_soft_heap_limit sqlite3_api->soft_heap_limit
+#define sqlite3_vfs_find sqlite3_api->vfs_find
+#define sqlite3_vfs_register sqlite3_api->vfs_register
+#define sqlite3_vfs_unregister sqlite3_api->vfs_unregister
+#define sqlite3_threadsafe sqlite3_api->xthreadsafe
+#define sqlite3_result_zeroblob sqlite3_api->result_zeroblob
+#define sqlite3_result_error_code sqlite3_api->result_error_code
+#define sqlite3_test_control sqlite3_api->test_control
+#define sqlite3_randomness sqlite3_api->randomness
+#define sqlite3_context_db_handle sqlite3_api->context_db_handle
+#define sqlite3_extended_result_codes sqlite3_api->extended_result_codes
+#define sqlite3_limit sqlite3_api->limit
+#define sqlite3_next_stmt sqlite3_api->next_stmt
+#define sqlite3_sql sqlite3_api->sql
+#define sqlite3_status sqlite3_api->status
+#define sqlite3_backup_finish sqlite3_api->backup_finish
+#define sqlite3_backup_init sqlite3_api->backup_init
+#define sqlite3_backup_pagecount sqlite3_api->backup_pagecount
+#define sqlite3_backup_remaining sqlite3_api->backup_remaining
+#define sqlite3_backup_step sqlite3_api->backup_step
+#define sqlite3_compileoption_get sqlite3_api->compileoption_get
+#define sqlite3_compileoption_used sqlite3_api->compileoption_used
+#define sqlite3_create_function_v2 sqlite3_api->create_function_v2
+#define sqlite3_db_config sqlite3_api->db_config
+#define sqlite3_db_mutex sqlite3_api->db_mutex
+#define sqlite3_db_status sqlite3_api->db_status
+#define sqlite3_extended_errcode sqlite3_api->extended_errcode
+#define sqlite3_log sqlite3_api->log
+#define sqlite3_soft_heap_limit64 sqlite3_api->soft_heap_limit64
+#define sqlite3_sourceid sqlite3_api->sourceid
+#define sqlite3_stmt_status sqlite3_api->stmt_status
+#define sqlite3_strnicmp sqlite3_api->strnicmp
+#define sqlite3_unlock_notify sqlite3_api->unlock_notify
+#define sqlite3_wal_autocheckpoint sqlite3_api->wal_autocheckpoint
+#define sqlite3_wal_checkpoint sqlite3_api->wal_checkpoint
+#define sqlite3_wal_hook sqlite3_api->wal_hook
+#define sqlite3_blob_reopen sqlite3_api->blob_reopen
+#define sqlite3_vtab_config sqlite3_api->vtab_config
+#define sqlite3_vtab_on_conflict sqlite3_api->vtab_on_conflict
+/* Version 3.7.16 and later */
+#define sqlite3_close_v2 sqlite3_api->close_v2
+#define sqlite3_db_filename sqlite3_api->db_filename
+#define sqlite3_db_readonly sqlite3_api->db_readonly
+#define sqlite3_db_release_memory sqlite3_api->db_release_memory
+#define sqlite3_errstr sqlite3_api->errstr
+#define sqlite3_stmt_busy sqlite3_api->stmt_busy
+#define sqlite3_stmt_readonly sqlite3_api->stmt_readonly
+#define sqlite3_stricmp sqlite3_api->stricmp
+#define sqlite3_uri_boolean sqlite3_api->uri_boolean
+#define sqlite3_uri_int64 sqlite3_api->uri_int64
+#define sqlite3_uri_parameter sqlite3_api->uri_parameter
+#define sqlite3_uri_vsnprintf sqlite3_api->vsnprintf
+#define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2
+/* Version 3.8.7 and later */
+#define sqlite3_auto_extension sqlite3_api->auto_extension
+#define sqlite3_bind_blob64 sqlite3_api->bind_blob64
+#define sqlite3_bind_text64 sqlite3_api->bind_text64
+#define sqlite3_cancel_auto_extension sqlite3_api->cancel_auto_extension
+#define sqlite3_load_extension sqlite3_api->load_extension
+#define sqlite3_malloc64 sqlite3_api->malloc64
+#define sqlite3_msize sqlite3_api->msize
+#define sqlite3_realloc64 sqlite3_api->realloc64
+#define sqlite3_reset_auto_extension sqlite3_api->reset_auto_extension
+#define sqlite3_result_blob64 sqlite3_api->result_blob64
+#define sqlite3_result_text64 sqlite3_api->result_text64
+#define sqlite3_strglob sqlite3_api->strglob
+/* Version 3.8.11 and later */
+#define sqlite3_value_dup sqlite3_api->value_dup
+#define sqlite3_value_free sqlite3_api->value_free
+#define sqlite3_result_zeroblob64 sqlite3_api->result_zeroblob64
+#define sqlite3_bind_zeroblob64 sqlite3_api->bind_zeroblob64
+/* Version 3.9.0 and later */
+#define sqlite3_value_subtype sqlite3_api->value_subtype
+#define sqlite3_result_subtype sqlite3_api->result_subtype
+/* Version 3.10.0 and later */
+#define sqlite3_status64 sqlite3_api->status64
+#define sqlite3_strlike sqlite3_api->strlike
+#define sqlite3_db_cacheflush sqlite3_api->db_cacheflush
+/* Version 3.12.0 and later */
+#define sqlite3_system_errno sqlite3_api->system_errno
+/* Version 3.14.0 and later */
+#define sqlite3_trace_v2 sqlite3_api->trace_v2
+#define sqlite3_expanded_sql sqlite3_api->expanded_sql
+#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
+
+#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
+ /* This case when the file really is being compiled as a loadable
+ ** extension */
+# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0;
+# define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v;
+# define SQLITE_EXTENSION_INIT3 \
+ extern const sqlite3_api_routines *sqlite3_api;
+#else
+ /* This case when the file is being statically linked into the
+ ** application */
+# define SQLITE_EXTENSION_INIT1 /*no-op*/
+# define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */
+# define SQLITE_EXTENSION_INIT3 /*no-op*/
+#endif
+
+#endif /* SQLITE3EXT_H */
+
+/************** End of sqlite3ext.h ******************************************/
+/************** Continuing where we left off in loadext.c ********************/
+/* #include "sqliteInt.h" */
+
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
+/*
+** Some API routines are omitted when various features are
+** excluded from a build of SQLite. Substitute a NULL pointer
+** for any missing APIs.
+*/
+#ifndef SQLITE_ENABLE_COLUMN_METADATA
+# define sqlite3_column_database_name 0
+# define sqlite3_column_database_name16 0
+# define sqlite3_column_table_name 0
+# define sqlite3_column_table_name16 0
+# define sqlite3_column_origin_name 0
+# define sqlite3_column_origin_name16 0
+#endif
+
+#ifdef SQLITE_OMIT_AUTHORIZATION
+# define sqlite3_set_authorizer 0
+#endif
+
+#ifdef SQLITE_OMIT_UTF16
+# define sqlite3_bind_text16 0
+# define sqlite3_collation_needed16 0
+# define sqlite3_column_decltype16 0
+# define sqlite3_column_name16 0
+# define sqlite3_column_text16 0
+# define sqlite3_complete16 0
+# define sqlite3_create_collation16 0
+# define sqlite3_create_function16 0
+# define sqlite3_errmsg16 0
+# define sqlite3_open16 0
+# define sqlite3_prepare16 0
+# define sqlite3_prepare16_v2 0
+# define sqlite3_result_error16 0
+# define sqlite3_result_text16 0
+# define sqlite3_result_text16be 0
+# define sqlite3_result_text16le 0
+# define sqlite3_value_text16 0
+# define sqlite3_value_text16be 0
+# define sqlite3_value_text16le 0
+# define sqlite3_column_database_name16 0
+# define sqlite3_column_table_name16 0
+# define sqlite3_column_origin_name16 0
+#endif
+
+#ifdef SQLITE_OMIT_COMPLETE
+# define sqlite3_complete 0
+# define sqlite3_complete16 0
+#endif
+
+#ifdef SQLITE_OMIT_DECLTYPE
+# define sqlite3_column_decltype16 0
+# define sqlite3_column_decltype 0
+#endif
+
+#ifdef SQLITE_OMIT_PROGRESS_CALLBACK
+# define sqlite3_progress_handler 0
+#endif
+
+#ifdef SQLITE_OMIT_VIRTUALTABLE
+# define sqlite3_create_module 0
+# define sqlite3_create_module_v2 0
+# define sqlite3_declare_vtab 0
+# define sqlite3_vtab_config 0
+# define sqlite3_vtab_on_conflict 0
+#endif
+
+#ifdef SQLITE_OMIT_SHARED_CACHE
+# define sqlite3_enable_shared_cache 0
+#endif
+
+#if defined(SQLITE_OMIT_TRACE) || defined(SQLITE_OMIT_DEPRECATED)
+# define sqlite3_profile 0
+# define sqlite3_trace 0
+#endif
+
+#ifdef SQLITE_OMIT_GET_TABLE
+# define sqlite3_free_table 0
+# define sqlite3_get_table 0
+#endif
+
+#ifdef SQLITE_OMIT_INCRBLOB
+#define sqlite3_bind_zeroblob 0
+#define sqlite3_blob_bytes 0
+#define sqlite3_blob_close 0
+#define sqlite3_blob_open 0
+#define sqlite3_blob_read 0
+#define sqlite3_blob_write 0
+#define sqlite3_blob_reopen 0
+#endif
+
+#if defined(SQLITE_OMIT_TRACE)
+# define sqlite3_trace_v2 0
+#endif
+
+/*
+** The following structure contains pointers to all SQLite API routines.
+** A pointer to this structure is passed into extensions when they are
+** loaded so that the extension can make calls back into the SQLite
+** library.
+**
+** When adding new APIs, add them to the bottom of this structure
+** in order to preserve backwards compatibility.
+**
+** Extensions that use newer APIs should first call the
+** sqlite3_libversion_number() to make sure that the API they
+** intend to use is supported by the library. Extensions should
+** also check to make sure that the pointer to the function is
+** not NULL before calling it.
+*/
+static const sqlite3_api_routines sqlite3Apis = {
+ sqlite3_aggregate_context,
+#ifndef SQLITE_OMIT_DEPRECATED
+ sqlite3_aggregate_count,
+#else
+ 0,
+#endif
+ sqlite3_bind_blob,
+ sqlite3_bind_double,
+ sqlite3_bind_int,
+ sqlite3_bind_int64,
+ sqlite3_bind_null,
+ sqlite3_bind_parameter_count,
+ sqlite3_bind_parameter_index,
+ sqlite3_bind_parameter_name,
+ sqlite3_bind_text,
+ sqlite3_bind_text16,
+ sqlite3_bind_value,
+ sqlite3_busy_handler,
+ sqlite3_busy_timeout,
+ sqlite3_changes,
+ sqlite3_close,
+ sqlite3_collation_needed,
+ sqlite3_collation_needed16,
+ sqlite3_column_blob,
+ sqlite3_column_bytes,
+ sqlite3_column_bytes16,
+ sqlite3_column_count,
+ sqlite3_column_database_name,
+ sqlite3_column_database_name16,
+ sqlite3_column_decltype,
+ sqlite3_column_decltype16,
+ sqlite3_column_double,
+ sqlite3_column_int,
+ sqlite3_column_int64,
+ sqlite3_column_name,
+ sqlite3_column_name16,
+ sqlite3_column_origin_name,
+ sqlite3_column_origin_name16,
+ sqlite3_column_table_name,
+ sqlite3_column_table_name16,
+ sqlite3_column_text,
+ sqlite3_column_text16,
+ sqlite3_column_type,
+ sqlite3_column_value,
+ sqlite3_commit_hook,
+ sqlite3_complete,
+ sqlite3_complete16,
+ sqlite3_create_collation,
+ sqlite3_create_collation16,
+ sqlite3_create_function,
+ sqlite3_create_function16,
+ sqlite3_create_module,
+ sqlite3_data_count,
+ sqlite3_db_handle,
+ sqlite3_declare_vtab,
+ sqlite3_enable_shared_cache,
+ sqlite3_errcode,
+ sqlite3_errmsg,
+ sqlite3_errmsg16,
+ sqlite3_exec,
+#ifndef SQLITE_OMIT_DEPRECATED
+ sqlite3_expired,
+#else
+ 0,
+#endif
+ sqlite3_finalize,
+ sqlite3_free,
+ sqlite3_free_table,
+ sqlite3_get_autocommit,
+ sqlite3_get_auxdata,
+ sqlite3_get_table,
+ 0, /* Was sqlite3_global_recover(), but that function is deprecated */
+ sqlite3_interrupt,
+ sqlite3_last_insert_rowid,
+ sqlite3_libversion,
+ sqlite3_libversion_number,
+ sqlite3_malloc,
+ sqlite3_mprintf,
+ sqlite3_open,
+ sqlite3_open16,
+ sqlite3_prepare,
+ sqlite3_prepare16,
+ sqlite3_profile,
+ sqlite3_progress_handler,
+ sqlite3_realloc,
+ sqlite3_reset,
+ sqlite3_result_blob,
+ sqlite3_result_double,
+ sqlite3_result_error,
+ sqlite3_result_error16,
+ sqlite3_result_int,
+ sqlite3_result_int64,
+ sqlite3_result_null,
+ sqlite3_result_text,
+ sqlite3_result_text16,
+ sqlite3_result_text16be,
+ sqlite3_result_text16le,
+ sqlite3_result_value,
+ sqlite3_rollback_hook,
+ sqlite3_set_authorizer,
+ sqlite3_set_auxdata,
+ sqlite3_snprintf,
+ sqlite3_step,
+ sqlite3_table_column_metadata,
+#ifndef SQLITE_OMIT_DEPRECATED
+ sqlite3_thread_cleanup,
+#else
+ 0,
+#endif
+ sqlite3_total_changes,
+ sqlite3_trace,
+#ifndef SQLITE_OMIT_DEPRECATED
+ sqlite3_transfer_bindings,
+#else
+ 0,
+#endif
+ sqlite3_update_hook,
+ sqlite3_user_data,
+ sqlite3_value_blob,
+ sqlite3_value_bytes,
+ sqlite3_value_bytes16,
+ sqlite3_value_double,
+ sqlite3_value_int,
+ sqlite3_value_int64,
+ sqlite3_value_numeric_type,
+ sqlite3_value_text,
+ sqlite3_value_text16,
+ sqlite3_value_text16be,
+ sqlite3_value_text16le,
+ sqlite3_value_type,
+ sqlite3_vmprintf,
+ /*
+ ** The original API set ends here. All extensions can call any
+ ** of the APIs above provided that the pointer is not NULL. But
+ ** before calling APIs that follow, extension should check the
+ ** sqlite3_libversion_number() to make sure they are dealing with
+ ** a library that is new enough to support that API.
+ *************************************************************************
+ */
+ sqlite3_overload_function,
+
+ /*
+ ** Added after 3.3.13
+ */
+ sqlite3_prepare_v2,
+ sqlite3_prepare16_v2,
+ sqlite3_clear_bindings,
+
+ /*
+ ** Added for 3.4.1
+ */
+ sqlite3_create_module_v2,
+
+ /*
+ ** Added for 3.5.0
+ */
+ sqlite3_bind_zeroblob,
+ sqlite3_blob_bytes,
+ sqlite3_blob_close,
+ sqlite3_blob_open,
+ sqlite3_blob_read,
+ sqlite3_blob_write,
+ sqlite3_create_collation_v2,
+ sqlite3_file_control,
+ sqlite3_memory_highwater,
+ sqlite3_memory_used,
+#ifdef SQLITE_MUTEX_OMIT
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+#else
+ sqlite3_mutex_alloc,
+ sqlite3_mutex_enter,
+ sqlite3_mutex_free,
+ sqlite3_mutex_leave,
+ sqlite3_mutex_try,
+#endif
+ sqlite3_open_v2,
+ sqlite3_release_memory,
+ sqlite3_result_error_nomem,
+ sqlite3_result_error_toobig,
+ sqlite3_sleep,
+ sqlite3_soft_heap_limit,
+ sqlite3_vfs_find,
+ sqlite3_vfs_register,
+ sqlite3_vfs_unregister,
+
+ /*
+ ** Added for 3.5.8
+ */
+ sqlite3_threadsafe,
+ sqlite3_result_zeroblob,
+ sqlite3_result_error_code,
+ sqlite3_test_control,
+ sqlite3_randomness,
+ sqlite3_context_db_handle,
+
+ /*
+ ** Added for 3.6.0
+ */
+ sqlite3_extended_result_codes,
+ sqlite3_limit,
+ sqlite3_next_stmt,
+ sqlite3_sql,
+ sqlite3_status,
+
+ /*
+ ** Added for 3.7.4
+ */
+ sqlite3_backup_finish,
+ sqlite3_backup_init,
+ sqlite3_backup_pagecount,
+ sqlite3_backup_remaining,
+ sqlite3_backup_step,
+#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+ sqlite3_compileoption_get,
+ sqlite3_compileoption_used,
+#else
+ 0,
+ 0,
+#endif
+ sqlite3_create_function_v2,
+ sqlite3_db_config,
+ sqlite3_db_mutex,
+ sqlite3_db_status,
+ sqlite3_extended_errcode,
+ sqlite3_log,
+ sqlite3_soft_heap_limit64,
+ sqlite3_sourceid,
+ sqlite3_stmt_status,
+ sqlite3_strnicmp,
+#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
+ sqlite3_unlock_notify,
+#else
+ 0,
+#endif
+#ifndef SQLITE_OMIT_WAL
+ sqlite3_wal_autocheckpoint,
+ sqlite3_wal_checkpoint,
+ sqlite3_wal_hook,
+#else
+ 0,
+ 0,
+ 0,
+#endif
+ sqlite3_blob_reopen,
+ sqlite3_vtab_config,
+ sqlite3_vtab_on_conflict,
+ sqlite3_close_v2,
+ sqlite3_db_filename,
+ sqlite3_db_readonly,
+ sqlite3_db_release_memory,
+ sqlite3_errstr,
+ sqlite3_stmt_busy,
+ sqlite3_stmt_readonly,
+ sqlite3_stricmp,
+ sqlite3_uri_boolean,
+ sqlite3_uri_int64,
+ sqlite3_uri_parameter,
+ sqlite3_vsnprintf,
+ sqlite3_wal_checkpoint_v2,
+ /* Version 3.8.7 and later */
+ sqlite3_auto_extension,
+ sqlite3_bind_blob64,
+ sqlite3_bind_text64,
+ sqlite3_cancel_auto_extension,
+ sqlite3_load_extension,
+ sqlite3_malloc64,
+ sqlite3_msize,
+ sqlite3_realloc64,
+ sqlite3_reset_auto_extension,
+ sqlite3_result_blob64,
+ sqlite3_result_text64,
+ sqlite3_strglob,
+ /* Version 3.8.11 and later */
+ (sqlite3_value*(*)(const sqlite3_value*))sqlite3_value_dup,
+ sqlite3_value_free,
+ sqlite3_result_zeroblob64,
+ sqlite3_bind_zeroblob64,
+ /* Version 3.9.0 and later */
+ sqlite3_value_subtype,
+ sqlite3_result_subtype,
+ /* Version 3.10.0 and later */
+ sqlite3_status64,
+ sqlite3_strlike,
+ sqlite3_db_cacheflush,
+ /* Version 3.12.0 and later */
+ sqlite3_system_errno,
+ /* Version 3.14.0 and later */
+ sqlite3_trace_v2,
+ sqlite3_expanded_sql
+};
+
+/*
+** Attempt to load an SQLite extension library contained in the file
+** zFile. The entry point is zProc. zProc may be 0 in which case a
+** default entry point name (sqlite3_extension_init) is used. Use
+** of the default name is recommended.
+**
+** Return SQLITE_OK on success and SQLITE_ERROR if something goes wrong.
+**
+** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with
+** error message text. The calling function should free this memory
+** by calling sqlite3DbFree(db, ).
+*/
+static int sqlite3LoadExtension(
+ sqlite3 *db, /* Load the extension into this database connection */
+ const char *zFile, /* Name of the shared library containing extension */
+ const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */
+ char **pzErrMsg /* Put error message here if not 0 */
+){
+ sqlite3_vfs *pVfs = db->pVfs;
+ void *handle;
+ sqlite3_loadext_entry xInit;
+ char *zErrmsg = 0;
+ const char *zEntry;
+ char *zAltEntry = 0;
+ void **aHandle;
+ u64 nMsg = 300 + sqlite3Strlen30(zFile);
+ int ii;
+ int rc;
+
+ /* Shared library endings to try if zFile cannot be loaded as written */
+ static const char *azEndings[] = {
+#if SQLITE_OS_WIN
+ "dll"
+#elif defined(__APPLE__)
+ "dylib"
+#else
+ "so"
+#endif
+ };
+
+
+ if( pzErrMsg ) *pzErrMsg = 0;
+
+ /* Ticket #1863. To avoid a creating security problems for older
+ ** applications that relink against newer versions of SQLite, the
+ ** ability to run load_extension is turned off by default. One
+ ** must call either sqlite3_enable_load_extension(db) or
+ ** sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, 0)
+ ** to turn on extension loading.
+ */
+ if( (db->flags & SQLITE_LoadExtension)==0 ){
+ if( pzErrMsg ){
+ *pzErrMsg = sqlite3_mprintf("not authorized");
+ }
+ return SQLITE_ERROR;
+ }
+
+ zEntry = zProc ? zProc : "sqlite3_extension_init";
+
+ handle = sqlite3OsDlOpen(pVfs, zFile);
+#if SQLITE_OS_UNIX || SQLITE_OS_WIN
+ for(ii=0; ii<ArraySize(azEndings) && handle==0; ii++){
+ char *zAltFile = sqlite3_mprintf("%s.%s", zFile, azEndings[ii]);
+ if( zAltFile==0 ) return SQLITE_NOMEM_BKPT;
+ handle = sqlite3OsDlOpen(pVfs, zAltFile);
+ sqlite3_free(zAltFile);
+ }
+#endif
+ if( handle==0 ){
+ if( pzErrMsg ){
+ *pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg);
+ if( zErrmsg ){
+ sqlite3_snprintf(nMsg, zErrmsg,
+ "unable to open shared library [%s]", zFile);
+ sqlite3OsDlError(pVfs, nMsg-1, zErrmsg);
+ }
+ }
+ return SQLITE_ERROR;
+ }
+ xInit = (sqlite3_loadext_entry)sqlite3OsDlSym(pVfs, handle, zEntry);
+
+ /* If no entry point was specified and the default legacy
+ ** entry point name "sqlite3_extension_init" was not found, then
+ ** construct an entry point name "sqlite3_X_init" where the X is
+ ** replaced by the lowercase value of every ASCII alphabetic
+ ** character in the filename after the last "/" upto the first ".",
+ ** and eliding the first three characters if they are "lib".
+ ** Examples:
+ **
+ ** /usr/local/lib/libExample5.4.3.so ==> sqlite3_example_init
+ ** C:/lib/mathfuncs.dll ==> sqlite3_mathfuncs_init
+ */
+ if( xInit==0 && zProc==0 ){
+ int iFile, iEntry, c;
+ int ncFile = sqlite3Strlen30(zFile);
+ zAltEntry = sqlite3_malloc64(ncFile+30);
+ if( zAltEntry==0 ){
+ sqlite3OsDlClose(pVfs, handle);
+ return SQLITE_NOMEM_BKPT;
+ }
+ memcpy(zAltEntry, "sqlite3_", 8);
+ for(iFile=ncFile-1; iFile>=0 && zFile[iFile]!='/'; iFile--){}
+ iFile++;
+ if( sqlite3_strnicmp(zFile+iFile, "lib", 3)==0 ) iFile += 3;
+ for(iEntry=8; (c = zFile[iFile])!=0 && c!='.'; iFile++){
+ if( sqlite3Isalpha(c) ){
+ zAltEntry[iEntry++] = (char)sqlite3UpperToLower[(unsigned)c];
+ }
+ }
+ memcpy(zAltEntry+iEntry, "_init", 6);
+ zEntry = zAltEntry;
+ xInit = (sqlite3_loadext_entry)sqlite3OsDlSym(pVfs, handle, zEntry);
+ }
+ if( xInit==0 ){
+ if( pzErrMsg ){
+ nMsg += sqlite3Strlen30(zEntry);
+ *pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg);
+ if( zErrmsg ){
+ sqlite3_snprintf(nMsg, zErrmsg,
+ "no entry point [%s] in shared library [%s]", zEntry, zFile);
+ sqlite3OsDlError(pVfs, nMsg-1, zErrmsg);
+ }
+ }
+ sqlite3OsDlClose(pVfs, handle);
+ sqlite3_free(zAltEntry);
+ return SQLITE_ERROR;
+ }
+ sqlite3_free(zAltEntry);
+ rc = xInit(db, &zErrmsg, &sqlite3Apis);
+ if( rc ){
+ if( rc==SQLITE_OK_LOAD_PERMANENTLY ) return SQLITE_OK;
+ if( pzErrMsg ){
+ *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg);
+ }
+ sqlite3_free(zErrmsg);
+ sqlite3OsDlClose(pVfs, handle);
+ return SQLITE_ERROR;
+ }
+
+ /* Append the new shared library handle to the db->aExtension array. */
+ aHandle = sqlite3DbMallocZero(db, sizeof(handle)*(db->nExtension+1));
+ if( aHandle==0 ){
+ return SQLITE_NOMEM_BKPT;
+ }
+ if( db->nExtension>0 ){
+ memcpy(aHandle, db->aExtension, sizeof(handle)*db->nExtension);
+ }
+ sqlite3DbFree(db, db->aExtension);
+ db->aExtension = aHandle;
+
+ db->aExtension[db->nExtension++] = handle;
+ return SQLITE_OK;
+}
+SQLITE_API int sqlite3_load_extension(
+ sqlite3 *db, /* Load the extension into this database connection */
+ const char *zFile, /* Name of the shared library containing extension */
+ const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */
+ char **pzErrMsg /* Put error message here if not 0 */
+){
+ int rc;
+ sqlite3_mutex_enter(db->mutex);
+ rc = sqlite3LoadExtension(db, zFile, zProc, pzErrMsg);
+ rc = sqlite3ApiExit(db, rc);
+ sqlite3_mutex_leave(db->mutex);
+ return rc;
+}
+
+/*
+** Call this routine when the database connection is closing in order
+** to clean up loaded extensions
+*/
+SQLITE_PRIVATE void sqlite3CloseExtensions(sqlite3 *db){
+ int i;
+ assert( sqlite3_mutex_held(db->mutex) );
+ for(i=0; i<db->nExtension; i++){
+ sqlite3OsDlClose(db->pVfs, db->aExtension[i]);
+ }
+ sqlite3DbFree(db, db->aExtension);
+}
+
+/*
+** Enable or disable extension loading. Extension loading is disabled by
+** default so as not to open security holes in older applications.
+*/
+SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff){
+ sqlite3_mutex_enter(db->mutex);
+ if( onoff ){
+ db->flags |= SQLITE_LoadExtension|SQLITE_LoadExtFunc;
+ }else{
+ db->flags &= ~(SQLITE_LoadExtension|SQLITE_LoadExtFunc);
+ }
+ sqlite3_mutex_leave(db->mutex);
+ return SQLITE_OK;
+}
+
+#endif /* !defined(SQLITE_OMIT_LOAD_EXTENSION) */
+
+/*
+** The following object holds the list of automatically loaded
+** extensions.
+**
+** This list is shared across threads. The SQLITE_MUTEX_STATIC_MASTER
+** mutex must be held while accessing this list.
+*/
+typedef struct sqlite3AutoExtList sqlite3AutoExtList;
+static SQLITE_WSD struct sqlite3AutoExtList {
+ u32 nExt; /* Number of entries in aExt[] */
+ void (**aExt)(void); /* Pointers to the extension init functions */
+} sqlite3Autoext = { 0, 0 };
+
+/* The "wsdAutoext" macro will resolve to the autoextension
+** state vector. If writable static data is unsupported on the target,
+** we have to locate the state vector at run-time. In the more common
+** case where writable static data is supported, wsdStat can refer directly
+** to the "sqlite3Autoext" state vector declared above.
+*/
+#ifdef SQLITE_OMIT_WSD
+# define wsdAutoextInit \
+ sqlite3AutoExtList *x = &GLOBAL(sqlite3AutoExtList,sqlite3Autoext)
+# define wsdAutoext x[0]
+#else
+# define wsdAutoextInit
+# define wsdAutoext sqlite3Autoext
+#endif
+
+
+/*
+** Register a statically linked extension that is automatically
+** loaded by every new database connection.
+*/
+SQLITE_API int sqlite3_auto_extension(
+ void (*xInit)(void)
+){
+ int rc = SQLITE_OK;
+#ifndef SQLITE_OMIT_AUTOINIT
+ rc = sqlite3_initialize();
+ if( rc ){
+ return rc;
+ }else
+#endif
+ {
+ u32 i;
+#if SQLITE_THREADSAFE
+ sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
+#endif
+ wsdAutoextInit;
+ sqlite3_mutex_enter(mutex);
+ for(i=0; i<wsdAutoext.nExt; i++){
+ if( wsdAutoext.aExt[i]==xInit ) break;
+ }
+ if( i==wsdAutoext.nExt ){
+ u64 nByte = (wsdAutoext.nExt+1)*sizeof(wsdAutoext.aExt[0]);
+ void (**aNew)(void);
+ aNew = sqlite3_realloc64(wsdAutoext.aExt, nByte);
+ if( aNew==0 ){
+ rc = SQLITE_NOMEM_BKPT;
+ }else{
+ wsdAutoext.aExt = aNew;
+ wsdAutoext.aExt[wsdAutoext.nExt] = xInit;
+ wsdAutoext.nExt++;
+ }
+ }
+ sqlite3_mutex_leave(mutex);
+ assert( (rc&0xff)==rc );
+ return rc;
+ }
+}
+
+/*
+** Cancel a prior call to sqlite3_auto_extension. Remove xInit from the
+** set of routines that is invoked for each new database connection, if it
+** is currently on the list. If xInit is not on the list, then this
+** routine is a no-op.
+**
+** Return 1 if xInit was found on the list and removed. Return 0 if xInit
+** was not on the list.
+*/
+SQLITE_API int sqlite3_cancel_auto_extension(
+ void (*xInit)(void)
+){
+#if SQLITE_THREADSAFE
+ sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
+#endif
+ int i;
+ int n = 0;
+ wsdAutoextInit;
+ sqlite3_mutex_enter(mutex);
+ for(i=(int)wsdAutoext.nExt-1; i>=0; i--){
+ if( wsdAutoext.aExt[i]==xInit ){
+ wsdAutoext.nExt--;
+ wsdAutoext.aExt[i] = wsdAutoext.aExt[wsdAutoext.nExt];
+ n++;
+ break;
+ }
+ }
+ sqlite3_mutex_leave(mutex);
+ return n;
+}
+
+/*
+** Reset the automatic extension loading mechanism.
+*/
+SQLITE_API void sqlite3_reset_auto_extension(void){
+#ifndef SQLITE_OMIT_AUTOINIT
+ if( sqlite3_initialize()==SQLITE_OK )
+#endif
+ {
+#if SQLITE_THREADSAFE
+ sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
+#endif
+ wsdAutoextInit;
+ sqlite3_mutex_enter(mutex);
+ sqlite3_free(wsdAutoext.aExt);
+ wsdAutoext.aExt = 0;
+ wsdAutoext.nExt = 0;
+ sqlite3_mutex_leave(mutex);
+ }
+}
+
+/*
+** Load all automatic extensions.
+**
+** If anything goes wrong, set an error in the database connection.
+*/
+SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
+ u32 i;
+ int go = 1;
+ int rc;
+ sqlite3_loadext_entry xInit;
+
+ wsdAutoextInit;
+ if( wsdAutoext.nExt==0 ){
+ /* Common case: early out without every having to acquire a mutex */
+ return;
+ }
+ for(i=0; go; i++){
+ char *zErrmsg;
+#if SQLITE_THREADSAFE
+ sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
+#endif
+#ifdef SQLITE_OMIT_LOAD_EXTENSION
+ const sqlite3_api_routines *pThunk = 0;
+#else
+ const sqlite3_api_routines *pThunk = &sqlite3Apis;
+#endif
+ sqlite3_mutex_enter(mutex);
+ if( i>=wsdAutoext.nExt ){
+ xInit = 0;
+ go = 0;
+ }else{
+ xInit = (sqlite3_loadext_entry)wsdAutoext.aExt[i];
+ }
+ sqlite3_mutex_leave(mutex);
+ zErrmsg = 0;
+ if( xInit && (rc = xInit(db, &zErrmsg, pThunk))!=0 ){
+ sqlite3ErrorWithMsg(db, rc,
+ "automatic extension loading failed: %s", zErrmsg);
+ go = 0;
+ }
+ sqlite3_free(zErrmsg);
+ }
+}
+
+/************** End of loadext.c *********************************************/
+/************** Begin file pragma.c ******************************************/
+/*
+** 2003 April 6
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains code used to implement the PRAGMA command.
+*/
+/* #include "sqliteInt.h" */
+
+#if !defined(SQLITE_ENABLE_LOCKING_STYLE)
+# if defined(__APPLE__)
+# define SQLITE_ENABLE_LOCKING_STYLE 1
+# else
+# define SQLITE_ENABLE_LOCKING_STYLE 0
+# endif
+#endif
+
+/***************************************************************************
+** The "pragma.h" include file is an automatically generated file that
+** that includes the PragType_XXXX macro definitions and the aPragmaName[]
+** object. This ensures that the aPragmaName[] table is arranged in
+** lexicographical order to facility a binary search of the pragma name.
+** Do not edit pragma.h directly. Edit and rerun the script in at
+** ../tool/mkpragmatab.tcl. */
+/************** Include pragma.h in the middle of pragma.c *******************/
+/************** Begin file pragma.h ******************************************/
+/* DO NOT EDIT!
+** This file is automatically generated by the script at
+** ../tool/mkpragmatab.tcl. To update the set of pragmas, edit
+** that script and rerun it.
+*/
+
+/* The various pragma types */
+#define PragTyp_HEADER_VALUE 0
+#define PragTyp_AUTO_VACUUM 1
+#define PragTyp_FLAG 2
+#define PragTyp_BUSY_TIMEOUT 3
+#define PragTyp_CACHE_SIZE 4
+#define PragTyp_CACHE_SPILL 5
+#define PragTyp_CASE_SENSITIVE_LIKE 6
+#define PragTyp_COLLATION_LIST 7
+#define PragTyp_COMPILE_OPTIONS 8
+#define PragTyp_DATA_STORE_DIRECTORY 9
+#define PragTyp_DATABASE_LIST 10
+#define PragTyp_DEFAULT_CACHE_SIZE 11
+#define PragTyp_ENCODING 12
+#define PragTyp_FOREIGN_KEY_CHECK 13
+#define PragTyp_FOREIGN_KEY_LIST 14
+#define PragTyp_INCREMENTAL_VACUUM 15
+#define PragTyp_INDEX_INFO 16
+#define PragTyp_INDEX_LIST 17
+#define PragTyp_INTEGRITY_CHECK 18
+#define PragTyp_JOURNAL_MODE 19
+#define PragTyp_JOURNAL_SIZE_LIMIT 20
+#define PragTyp_LOCK_PROXY_FILE 21
+#define PragTyp_LOCKING_MODE 22
+#define PragTyp_PAGE_COUNT 23
+#define PragTyp_MMAP_SIZE 24
+#define PragTyp_PAGE_SIZE 25
+#define PragTyp_SECURE_DELETE 26
+#define PragTyp_SHRINK_MEMORY 27
+#define PragTyp_SOFT_HEAP_LIMIT 28
+#define PragTyp_STATS 29
+#define PragTyp_SYNCHRONOUS 30
+#define PragTyp_TABLE_INFO 31
+#define PragTyp_TEMP_STORE 32
+#define PragTyp_TEMP_STORE_DIRECTORY 33
+#define PragTyp_THREADS 34
+#define PragTyp_WAL_AUTOCHECKPOINT 35
+#define PragTyp_WAL_CHECKPOINT 36
+#define PragTyp_ACTIVATE_EXTENSIONS 37
+#define PragTyp_HEXKEY 38
+#define PragTyp_KEY 39
+#define PragTyp_REKEY 40
+#define PragTyp_LOCK_STATUS 41
+#define PragTyp_PARSER_TRACE 42
+
+/* Property flags associated with various pragma. */
+#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
+#define PragFlg_NoColumns 0x02 /* OP_ResultRow called with zero columns */
+#define PragFlg_NoColumns1 0x04 /* zero columns if RHS argument is present */
+#define PragFlg_ReadOnly 0x08 /* Read-only HEADER_VALUE */
+#define PragFlg_Result0 0x10 /* Acts as query when no argument */
+#define PragFlg_Result1 0x20 /* Acts as query when has one argument */
+#define PragFlg_SchemaOpt 0x40 /* Schema restricts name search if present */
+#define PragFlg_SchemaReq 0x80 /* Schema required - "main" is default */
+
+/* Names of columns for pragmas that return multi-column result
+** or that return single-column results where the name of the
+** result column is different from the name of the pragma
+*/
+static const char *const pragCName[] = {
+ /* 0 */ "cache_size", /* Used by: default_cache_size */
+ /* 1 */ "cid", /* Used by: table_info */
+ /* 2 */ "name",
+ /* 3 */ "type",
+ /* 4 */ "notnull",
+ /* 5 */ "dflt_value",
+ /* 6 */ "pk",
+ /* 7 */ "table", /* Used by: stats */
+ /* 8 */ "index",
+ /* 9 */ "width",
+ /* 10 */ "height",
+ /* 11 */ "seqno", /* Used by: index_info */
+ /* 12 */ "cid",
+ /* 13 */ "name",
+ /* 14 */ "seqno", /* Used by: index_xinfo */
+ /* 15 */ "cid",
+ /* 16 */ "name",
+ /* 17 */ "desc",
+ /* 18 */ "coll",
+ /* 19 */ "key",
+ /* 20 */ "seq", /* Used by: index_list */
+ /* 21 */ "name",
+ /* 22 */ "unique",
+ /* 23 */ "origin",
+ /* 24 */ "partial",
+ /* 25 */ "seq", /* Used by: database_list */
+ /* 26 */ "name",
+ /* 27 */ "file",
+ /* 28 */ "seq", /* Used by: collation_list */
+ /* 29 */ "name",
+ /* 30 */ "id", /* Used by: foreign_key_list */
+ /* 31 */ "seq",
+ /* 32 */ "table",
+ /* 33 */ "from",
+ /* 34 */ "to",
+ /* 35 */ "on_update",
+ /* 36 */ "on_delete",
+ /* 37 */ "match",
+ /* 38 */ "table", /* Used by: foreign_key_check */
+ /* 39 */ "rowid",
+ /* 40 */ "parent",
+ /* 41 */ "fkid",
+ /* 42 */ "busy", /* Used by: wal_checkpoint */
+ /* 43 */ "log",
+ /* 44 */ "checkpointed",
+ /* 45 */ "timeout", /* Used by: busy_timeout */
+ /* 46 */ "database", /* Used by: lock_status */
+ /* 47 */ "status",
+};
+
+/* Definitions of all built-in pragmas */
+typedef struct PragmaName {
+ const char *const zName; /* Name of pragma */
+ u8 ePragTyp; /* PragTyp_XXX value */
+ u8 mPragFlg; /* Zero or more PragFlg_XXX values */
+ u8 iPragCName; /* Start of column names in pragCName[] */
+ u8 nPragCName; /* Num of col names. 0 means use pragma name */
+ u32 iArg; /* Extra argument */
+} PragmaName;
+static const PragmaName aPragmaName[] = {
+#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
+ {/* zName: */ "activate_extensions",
+ /* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
+ {/* zName: */ "application_id",
+ /* ePragTyp: */ PragTyp_HEADER_VALUE,
+ /* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ BTREE_APPLICATION_ID },
+#endif
+#if !defined(SQLITE_OMIT_AUTOVACUUM)
+ {/* zName: */ "auto_vacuum",
+ /* ePragTyp: */ PragTyp_AUTO_VACUUM,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+#if !defined(SQLITE_OMIT_AUTOMATIC_INDEX)
+ {/* zName: */ "automatic_index",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_AutoIndex },
+#endif
+#endif
+ {/* zName: */ "busy_timeout",
+ /* ePragTyp: */ PragTyp_BUSY_TIMEOUT,
+ /* ePragFlg: */ PragFlg_Result0,
+ /* ColNames: */ 45, 1,
+ /* iArg: */ 0 },
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+ {/* zName: */ "cache_size",
+ /* ePragTyp: */ PragTyp_CACHE_SIZE,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ {/* zName: */ "cache_spill",
+ /* ePragTyp: */ PragTyp_CACHE_SPILL,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#endif
+ {/* zName: */ "case_sensitive_like",
+ /* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE,
+ /* ePragFlg: */ PragFlg_NoColumns,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+ {/* zName: */ "cell_size_check",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_CellSizeCk },
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ {/* zName: */ "checkpoint_fullfsync",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_CkptFullFSync },
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
+ {/* zName: */ "collation_list",
+ /* ePragTyp: */ PragTyp_COLLATION_LIST,
+ /* ePragFlg: */ PragFlg_Result0,
+ /* ColNames: */ 28, 2,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
+ {/* zName: */ "compile_options",
+ /* ePragTyp: */ PragTyp_COMPILE_OPTIONS,
+ /* ePragFlg: */ PragFlg_Result0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ {/* zName: */ "count_changes",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_CountRows },
+#endif
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN
+ {/* zName: */ "data_store_directory",
+ /* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY,
+ /* ePragFlg: */ PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
+ {/* zName: */ "data_version",
+ /* ePragTyp: */ PragTyp_HEADER_VALUE,
+ /* ePragFlg: */ PragFlg_ReadOnly|PragFlg_Result0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ BTREE_DATA_VERSION },
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
+ {/* zName: */ "database_list",
+ /* ePragTyp: */ PragTyp_DATABASE_LIST,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
+ /* ColNames: */ 25, 3,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
+ {/* zName: */ "default_cache_size",
+ /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 1,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
+ {/* zName: */ "defer_foreign_keys",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_DeferFKs },
+#endif
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ {/* zName: */ "empty_result_callbacks",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_NullCallback },
+#endif
+#if !defined(SQLITE_OMIT_UTF16)
+ {/* zName: */ "encoding",
+ /* ePragTyp: */ PragTyp_ENCODING,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
+ {/* zName: */ "foreign_key_check",
+ /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK,
+ /* ePragFlg: */ PragFlg_NeedSchema,
+ /* ColNames: */ 38, 4,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FOREIGN_KEY)
+ {/* zName: */ "foreign_key_list",
+ /* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
+ /* ColNames: */ 30, 8,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
+ {/* zName: */ "foreign_keys",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_ForeignKeys },
+#endif
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
+ {/* zName: */ "freelist_count",
+ /* ePragTyp: */ PragTyp_HEADER_VALUE,
+ /* ePragFlg: */ PragFlg_ReadOnly|PragFlg_Result0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ BTREE_FREE_PAGE_COUNT },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ {/* zName: */ "full_column_names",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_FullColNames },
+ {/* zName: */ "fullfsync",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_FullFSync },
+#endif
+#if defined(SQLITE_HAS_CODEC)
+ {/* zName: */ "hexkey",
+ /* ePragTyp: */ PragTyp_HEXKEY,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+ {/* zName: */ "hexrekey",
+ /* ePragTyp: */ PragTyp_HEXKEY,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+#if !defined(SQLITE_OMIT_CHECK)
+ {/* zName: */ "ignore_check_constraints",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_IgnoreChecks },
+#endif
+#endif
+#if !defined(SQLITE_OMIT_AUTOVACUUM)
+ {/* zName: */ "incremental_vacuum",
+ /* ePragTyp: */ PragTyp_INCREMENTAL_VACUUM,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_NoColumns,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
+ {/* zName: */ "index_info",
+ /* ePragTyp: */ PragTyp_INDEX_INFO,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
+ /* ColNames: */ 11, 3,
+ /* iArg: */ 0 },
+ {/* zName: */ "index_list",
+ /* ePragTyp: */ PragTyp_INDEX_LIST,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
+ /* ColNames: */ 20, 5,
+ /* iArg: */ 0 },
+ {/* zName: */ "index_xinfo",
+ /* ePragTyp: */ PragTyp_INDEX_INFO,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
+ /* ColNames: */ 14, 6,
+ /* iArg: */ 1 },
+#endif
+#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
+ {/* zName: */ "integrity_check",
+ /* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
+ /* ePragFlg: */ PragFlg_NeedSchema,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+ {/* zName: */ "journal_mode",
+ /* ePragTyp: */ PragTyp_JOURNAL_MODE,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+ {/* zName: */ "journal_size_limit",
+ /* ePragTyp: */ PragTyp_JOURNAL_SIZE_LIMIT,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#endif
+#if defined(SQLITE_HAS_CODEC)
+ {/* zName: */ "key",
+ /* ePragTyp: */ PragTyp_KEY,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ {/* zName: */ "legacy_file_format",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_LegacyFileFmt },
+#endif
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE
+ {/* zName: */ "lock_proxy_file",
+ /* ePragTyp: */ PragTyp_LOCK_PROXY_FILE,
+ /* ePragFlg: */ PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#endif
+#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
+ {/* zName: */ "lock_status",
+ /* ePragTyp: */ PragTyp_LOCK_STATUS,
+ /* ePragFlg: */ PragFlg_Result0,
+ /* ColNames: */ 46, 2,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+ {/* zName: */ "locking_mode",
+ /* ePragTyp: */ PragTyp_LOCKING_MODE,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+ {/* zName: */ "max_page_count",
+ /* ePragTyp: */ PragTyp_PAGE_COUNT,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+ {/* zName: */ "mmap_size",
+ /* ePragTyp: */ PragTyp_MMAP_SIZE,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+ {/* zName: */ "page_count",
+ /* ePragTyp: */ PragTyp_PAGE_COUNT,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+ {/* zName: */ "page_size",
+ /* ePragTyp: */ PragTyp_PAGE_SIZE,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#endif
+#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_PARSER_TRACE)
+ {/* zName: */ "parser_trace",
+ /* ePragTyp: */ PragTyp_PARSER_TRACE,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ {/* zName: */ "query_only",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_QueryOnly },
+#endif
+#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
+ {/* zName: */ "quick_check",
+ /* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
+ /* ePragFlg: */ PragFlg_NeedSchema,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ {/* zName: */ "read_uncommitted",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_ReadUncommitted },
+ {/* zName: */ "recursive_triggers",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_RecTriggers },
+#endif
+#if defined(SQLITE_HAS_CODEC)
+ {/* zName: */ "rekey",
+ /* ePragTyp: */ PragTyp_REKEY,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ {/* zName: */ "reverse_unordered_selects",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_ReverseOrder },
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
+ {/* zName: */ "schema_version",
+ /* ePragTyp: */ PragTyp_HEADER_VALUE,
+ /* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ BTREE_SCHEMA_VERSION },
+#endif
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+ {/* zName: */ "secure_delete",
+ /* ePragTyp: */ PragTyp_SECURE_DELETE,
+ /* ePragFlg: */ PragFlg_Result0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ {/* zName: */ "short_column_names",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_ShortColNames },
+#endif
+ {/* zName: */ "shrink_memory",
+ /* ePragTyp: */ PragTyp_SHRINK_MEMORY,
+ /* ePragFlg: */ PragFlg_NoColumns,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+ {/* zName: */ "soft_heap_limit",
+ /* ePragTyp: */ PragTyp_SOFT_HEAP_LIMIT,
+ /* ePragFlg: */ PragFlg_Result0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+#if defined(SQLITE_DEBUG)
+ {/* zName: */ "sql_trace",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_SqlTrace },
+#endif
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
+ {/* zName: */ "stats",
+ /* ePragTyp: */ PragTyp_STATS,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
+ /* ColNames: */ 7, 4,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+ {/* zName: */ "synchronous",
+ /* ePragTyp: */ PragTyp_SYNCHRONOUS,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
+ {/* zName: */ "table_info",
+ /* ePragTyp: */ PragTyp_TABLE_INFO,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
+ /* ColNames: */ 1, 6,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+ {/* zName: */ "temp_store",
+ /* ePragTyp: */ PragTyp_TEMP_STORE,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+ {/* zName: */ "temp_store_directory",
+ /* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY,
+ /* ePragFlg: */ PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#endif
+ {/* zName: */ "threads",
+ /* ePragTyp: */ PragTyp_THREADS,
+ /* ePragFlg: */ PragFlg_Result0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
+ {/* zName: */ "user_version",
+ /* ePragTyp: */ PragTyp_HEADER_VALUE,
+ /* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ BTREE_USER_VERSION },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+#if defined(SQLITE_DEBUG)
+ {/* zName: */ "vdbe_addoptrace",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_VdbeAddopTrace },
+ {/* zName: */ "vdbe_debug",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace },
+ {/* zName: */ "vdbe_eqp",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_VdbeEQP },
+ {/* zName: */ "vdbe_listing",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_VdbeListing },
+ {/* zName: */ "vdbe_trace",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_VdbeTrace },
+#endif
+#endif
+#if !defined(SQLITE_OMIT_WAL)
+ {/* zName: */ "wal_autocheckpoint",
+ /* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+ {/* zName: */ "wal_checkpoint",
+ /* ePragTyp: */ PragTyp_WAL_CHECKPOINT,
+ /* ePragFlg: */ PragFlg_NeedSchema,
+ /* ColNames: */ 42, 3,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ {/* zName: */ "writable_schema",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
+#endif
+};
+/* Number of pragmas: 60 on by default, 73 total. */
+
+/************** End of pragma.h **********************************************/
+/************** Continuing where we left off in pragma.c *********************/
+
+/*
+** Interpret the given string as a safety level. Return 0 for OFF,
+** 1 for ON or NORMAL, 2 for FULL, and 3 for EXTRA. Return 1 for an empty or
+** unrecognized string argument. The FULL and EXTRA option is disallowed
+** if the omitFull parameter it 1.
+**
+** Note that the values returned are one less that the values that
+** should be passed into sqlite3BtreeSetSafetyLevel(). The is done
+** to support legacy SQL code. The safety level used to be boolean
+** and older scripts may have used numbers 0 for OFF and 1 for ON.
+*/
+static u8 getSafetyLevel(const char *z, int omitFull, u8 dflt){
+ /* 123456789 123456789 123 */
+ static const char zText[] = "onoffalseyestruextrafull";
+ static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 15, 20};
+ static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 5, 4};
+ static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 3, 2};
+ /* on no off false yes true extra full */
+ int i, n;
+ if( sqlite3Isdigit(*z) ){
+ return (u8)sqlite3Atoi(z);
+ }
+ n = sqlite3Strlen30(z);
+ for(i=0; i<ArraySize(iLength); i++){
+ if( iLength[i]==n && sqlite3StrNICmp(&zText[iOffset[i]],z,n)==0
+ && (!omitFull || iValue[i]<=1)
+ ){
+ return iValue[i];
+ }
+ }
+ return dflt;
+}
+
+/*
+** Interpret the given string as a boolean value.
+*/
+SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z, u8 dflt){
+ return getSafetyLevel(z,1,dflt)!=0;
+}
+
+/* The sqlite3GetBoolean() function is used by other modules but the
+** remainder of this file is specific to PRAGMA processing. So omit
+** the rest of the file if PRAGMAs are omitted from the build.
+*/
+#if !defined(SQLITE_OMIT_PRAGMA)
+
+/*
+** Interpret the given string as a locking mode value.
+*/
+static int getLockingMode(const char *z){
+ if( z ){
+ if( 0==sqlite3StrICmp(z, "exclusive") ) return PAGER_LOCKINGMODE_EXCLUSIVE;
+ if( 0==sqlite3StrICmp(z, "normal") ) return PAGER_LOCKINGMODE_NORMAL;
+ }
+ return PAGER_LOCKINGMODE_QUERY;
+}
+
+#ifndef SQLITE_OMIT_AUTOVACUUM
+/*
+** Interpret the given string as an auto-vacuum mode value.
+**
+** The following strings, "none", "full" and "incremental" are
+** acceptable, as are their numeric equivalents: 0, 1 and 2 respectively.
+*/
+static int getAutoVacuum(const char *z){
+ int i;
+ if( 0==sqlite3StrICmp(z, "none") ) return BTREE_AUTOVACUUM_NONE;
+ if( 0==sqlite3StrICmp(z, "full") ) return BTREE_AUTOVACUUM_FULL;
+ if( 0==sqlite3StrICmp(z, "incremental") ) return BTREE_AUTOVACUUM_INCR;
+ i = sqlite3Atoi(z);
+ return (u8)((i>=0&&i<=2)?i:0);
+}
+#endif /* ifndef SQLITE_OMIT_AUTOVACUUM */
+
+#ifndef SQLITE_OMIT_PAGER_PRAGMAS
+/*
+** Interpret the given string as a temp db location. Return 1 for file
+** backed temporary databases, 2 for the Red-Black tree in memory database
+** and 0 to use the compile-time default.
+*/
+static int getTempStore(const char *z){
+ if( z[0]>='0' && z[0]<='2' ){
+ return z[0] - '0';
+ }else if( sqlite3StrICmp(z, "file")==0 ){
+ return 1;
+ }else if( sqlite3StrICmp(z, "memory")==0 ){
+ return 2;
+ }else{
+ return 0;
+ }
+}
+#endif /* SQLITE_PAGER_PRAGMAS */
+
+#ifndef SQLITE_OMIT_PAGER_PRAGMAS
+/*
+** Invalidate temp storage, either when the temp storage is changed
+** from default, or when 'file' and the temp_store_directory has changed
+*/
+static int invalidateTempStorage(Parse *pParse){
+ sqlite3 *db = pParse->db;
+ if( db->aDb[1].pBt!=0 ){
+ if( !db->autoCommit || sqlite3BtreeIsInReadTrans(db->aDb[1].pBt) ){
+ sqlite3ErrorMsg(pParse, "temporary storage cannot be changed "
+ "from within a transaction");
+ return SQLITE_ERROR;
+ }
+ sqlite3BtreeClose(db->aDb[1].pBt);
+ db->aDb[1].pBt = 0;
+ sqlite3ResetAllSchemasOfConnection(db);
+ }
+ return SQLITE_OK;
+}
+#endif /* SQLITE_PAGER_PRAGMAS */
+
+#ifndef SQLITE_OMIT_PAGER_PRAGMAS
+/*
+** If the TEMP database is open, close it and mark the database schema
+** as needing reloading. This must be done when using the SQLITE_TEMP_STORE
+** or DEFAULT_TEMP_STORE pragmas.
+*/
+static int changeTempStorage(Parse *pParse, const char *zStorageType){
+ int ts = getTempStore(zStorageType);
+ sqlite3 *db = pParse->db;
+ if( db->temp_store==ts ) return SQLITE_OK;
+ if( invalidateTempStorage( pParse ) != SQLITE_OK ){
+ return SQLITE_ERROR;
+ }
+ db->temp_store = (u8)ts;
+ return SQLITE_OK;
+}
+#endif /* SQLITE_PAGER_PRAGMAS */
+
+/*
+** Set result column names for a pragma.
+*/
+static void setPragmaResultColumnNames(
+ Vdbe *v, /* The query under construction */
+ const PragmaName *pPragma /* The pragma */
+){
+ u8 n = pPragma->nPragCName;
+ sqlite3VdbeSetNumCols(v, n==0 ? 1 : n);
+ if( n==0 ){
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, pPragma->zName, SQLITE_STATIC);
+ }else{
+ int i, j;
+ for(i=0, j=pPragma->iPragCName; i<n; i++, j++){
+ sqlite3VdbeSetColName(v, i, COLNAME_NAME, pragCName[j], SQLITE_STATIC);
+ }
+ }
+}
+
+/*
+** Generate code to return a single integer value.
+*/
+static void returnSingleInt(Vdbe *v, i64 value){
+ sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, 1, 0, (const u8*)&value, P4_INT64);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
+}
+
+/*
+** Generate code to return a single text value.
+*/
+static void returnSingleText(
+ Vdbe *v, /* Prepared statement under construction */
+ const char *zValue /* Value to be returned */
+){
+ if( zValue ){
+ sqlite3VdbeLoadString(v, 1, (const char*)zValue);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
+ }
+}
+
+
+/*
+** Set the safety_level and pager flags for pager iDb. Or if iDb<0
+** set these values for all pagers.
+*/
+#ifndef SQLITE_OMIT_PAGER_PRAGMAS
+static void setAllPagerFlags(sqlite3 *db){
+ if( db->autoCommit ){
+ Db *pDb = db->aDb;
+ int n = db->nDb;
+ assert( SQLITE_FullFSync==PAGER_FULLFSYNC );
+ assert( SQLITE_CkptFullFSync==PAGER_CKPT_FULLFSYNC );
+ assert( SQLITE_CacheSpill==PAGER_CACHESPILL );
+ assert( (PAGER_FULLFSYNC | PAGER_CKPT_FULLFSYNC | PAGER_CACHESPILL)
+ == PAGER_FLAGS_MASK );
+ assert( (pDb->safety_level & PAGER_SYNCHRONOUS_MASK)==pDb->safety_level );
+ while( (n--) > 0 ){
+ if( pDb->pBt ){
+ sqlite3BtreeSetPagerFlags(pDb->pBt,
+ pDb->safety_level | (db->flags & PAGER_FLAGS_MASK) );
+ }
+ pDb++;
+ }
+ }
+}
+#else
+# define setAllPagerFlags(X) /* no-op */
+#endif
+
+
+/*
+** Return a human-readable name for a constraint resolution action.
+*/
+#ifndef SQLITE_OMIT_FOREIGN_KEY
+static const char *actionName(u8 action){
+ const char *zName;
+ switch( action ){
+ case OE_SetNull: zName = "SET NULL"; break;
+ case OE_SetDflt: zName = "SET DEFAULT"; break;
+ case OE_Cascade: zName = "CASCADE"; break;
+ case OE_Restrict: zName = "RESTRICT"; break;
+ default: zName = "NO ACTION";
+ assert( action==OE_None ); break;
+ }
+ return zName;
+}
+#endif
+
+
+/*
+** Parameter eMode must be one of the PAGER_JOURNALMODE_XXX constants
+** defined in pager.h. This function returns the associated lowercase
+** journal-mode name.
+*/
+SQLITE_PRIVATE const char *sqlite3JournalModename(int eMode){
+ static char * const azModeName[] = {
+ "delete", "persist", "off", "truncate", "memory"
+#ifndef SQLITE_OMIT_WAL
+ , "wal"
+#endif
+ };
+ assert( PAGER_JOURNALMODE_DELETE==0 );
+ assert( PAGER_JOURNALMODE_PERSIST==1 );
+ assert( PAGER_JOURNALMODE_OFF==2 );
+ assert( PAGER_JOURNALMODE_TRUNCATE==3 );
+ assert( PAGER_JOURNALMODE_MEMORY==4 );
+ assert( PAGER_JOURNALMODE_WAL==5 );
+ assert( eMode>=0 && eMode<=ArraySize(azModeName) );
+
+ if( eMode==ArraySize(azModeName) ) return 0;
+ return azModeName[eMode];
+}
+
+/*
+** Locate a pragma in the aPragmaName[] array.
+*/
+static const PragmaName *pragmaLocate(const char *zName){
+ int upr, lwr, mid = 0, rc;
+ lwr = 0;
+ upr = ArraySize(aPragmaName)-1;
+ while( lwr<=upr ){
+ mid = (lwr+upr)/2;
+ rc = sqlite3_stricmp(zName, aPragmaName[mid].zName);
+ if( rc==0 ) break;
+ if( rc<0 ){
+ upr = mid - 1;
+ }else{
+ lwr = mid + 1;
+ }
+ }
+ return lwr>upr ? 0 : &aPragmaName[mid];
+}
+
+/*
+** Process a pragma statement.
+**
+** Pragmas are of this form:
+**
+** PRAGMA [schema.]id [= value]
+**
+** The identifier might also be a string. The value is a string, and
+** identifier, or a number. If minusFlag is true, then the value is
+** a number that was preceded by a minus sign.
+**
+** If the left side is "database.id" then pId1 is the database name
+** and pId2 is the id. If the left side is just "id" then pId1 is the
+** id and pId2 is any empty string.
+*/
+SQLITE_PRIVATE void sqlite3Pragma(
+ Parse *pParse,
+ Token *pId1, /* First part of [schema.]id field */
+ Token *pId2, /* Second part of [schema.]id field, or NULL */
+ Token *pValue, /* Token for <value>, or NULL */
+ int minusFlag /* True if a '-' sign preceded <value> */
+){
+ char *zLeft = 0; /* Nul-terminated UTF-8 string <id> */
+ char *zRight = 0; /* Nul-terminated UTF-8 string <value>, or NULL */
+ const char *zDb = 0; /* The database name */
+ Token *pId; /* Pointer to <id> token */
+ char *aFcntl[4]; /* Argument to SQLITE_FCNTL_PRAGMA */
+ int iDb; /* Database index for <database> */
+ int rc; /* return value form SQLITE_FCNTL_PRAGMA */
+ sqlite3 *db = pParse->db; /* The database connection */
+ Db *pDb; /* The specific database being pragmaed */
+ Vdbe *v = sqlite3GetVdbe(pParse); /* Prepared statement */
+ const PragmaName *pPragma; /* The pragma */
+
+ if( v==0 ) return;
+ sqlite3VdbeRunOnlyOnce(v);
+ pParse->nMem = 2;
+
+ /* Interpret the [schema.] part of the pragma statement. iDb is the
+ ** index of the database this pragma is being applied to in db.aDb[]. */
+ iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId);
+ if( iDb<0 ) return;
+ pDb = &db->aDb[iDb];
+
+ /* If the temp database has been explicitly named as part of the
+ ** pragma, make sure it is open.
+ */
+ if( iDb==1 && sqlite3OpenTempDatabase(pParse) ){
+ return;
+ }
+
+ zLeft = sqlite3NameFromToken(db, pId);
+ if( !zLeft ) return;
+ if( minusFlag ){
+ zRight = sqlite3MPrintf(db, "-%T", pValue);
+ }else{
+ zRight = sqlite3NameFromToken(db, pValue);
+ }
+
+ assert( pId2 );
+ zDb = pId2->n>0 ? pDb->zDbSName : 0;
+ if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){
+ goto pragma_out;
+ }
+
+ /* Send an SQLITE_FCNTL_PRAGMA file-control to the underlying VFS
+ ** connection. If it returns SQLITE_OK, then assume that the VFS
+ ** handled the pragma and generate a no-op prepared statement.
+ **
+ ** IMPLEMENTATION-OF: R-12238-55120 Whenever a PRAGMA statement is parsed,
+ ** an SQLITE_FCNTL_PRAGMA file control is sent to the open sqlite3_file
+ ** object corresponding to the database file to which the pragma
+ ** statement refers.
+ **
+ ** IMPLEMENTATION-OF: R-29875-31678 The argument to the SQLITE_FCNTL_PRAGMA
+ ** file control is an array of pointers to strings (char**) in which the
+ ** second element of the array is the name of the pragma and the third
+ ** element is the argument to the pragma or NULL if the pragma has no
+ ** argument.
+ */
+ aFcntl[0] = 0;
+ aFcntl[1] = zLeft;
+ aFcntl[2] = zRight;
+ aFcntl[3] = 0;
+ db->busyHandler.nBusy = 0;
+ rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl);
+ if( rc==SQLITE_OK ){
+ sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, aFcntl[0], SQLITE_TRANSIENT);
+ returnSingleText(v, aFcntl[0]);
+ sqlite3_free(aFcntl[0]);
+ goto pragma_out;
+ }
+ if( rc!=SQLITE_NOTFOUND ){
+ if( aFcntl[0] ){
+ sqlite3ErrorMsg(pParse, "%s", aFcntl[0]);
+ sqlite3_free(aFcntl[0]);
+ }
+ pParse->nErr++;
+ pParse->rc = rc;
+ goto pragma_out;
+ }
+
+ /* Locate the pragma in the lookup table */
+ pPragma = pragmaLocate(zLeft);
+ if( pPragma==0 ) goto pragma_out;
+
+ /* Make sure the database schema is loaded if the pragma requires that */
+ if( (pPragma->mPragFlg & PragFlg_NeedSchema)!=0 ){
+ if( sqlite3ReadSchema(pParse) ) goto pragma_out;
+ }
+
+ /* Register the result column names for pragmas that return results */
+ if( (pPragma->mPragFlg & PragFlg_NoColumns)==0
+ && ((pPragma->mPragFlg & PragFlg_NoColumns1)==0 || zRight==0)
+ ){
+ setPragmaResultColumnNames(v, pPragma);
+ }
+
+ /* Jump to the appropriate pragma handler */
+ switch( pPragma->ePragTyp ){
+
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
+ /*
+ ** PRAGMA [schema.]default_cache_size
+ ** PRAGMA [schema.]default_cache_size=N
+ **
+ ** The first form reports the current persistent setting for the
+ ** page cache size. The value returned is the maximum number of
+ ** pages in the page cache. The second form sets both the current
+ ** page cache size value and the persistent page cache size value
+ ** stored in the database file.
+ **
+ ** Older versions of SQLite would set the default cache size to a
+ ** negative number to indicate synchronous=OFF. These days, synchronous
+ ** is always on by default regardless of the sign of the default cache
+ ** size. But continue to take the absolute value of the default cache
+ ** size of historical compatibility.
+ */
+ case PragTyp_DEFAULT_CACHE_SIZE: {
+ static const int iLn = VDBE_OFFSET_LINENO(2);
+ static const VdbeOpList getCacheSize[] = {
+ { OP_Transaction, 0, 0, 0}, /* 0 */
+ { OP_ReadCookie, 0, 1, BTREE_DEFAULT_CACHE_SIZE}, /* 1 */
+ { OP_IfPos, 1, 8, 0},
+ { OP_Integer, 0, 2, 0},
+ { OP_Subtract, 1, 2, 1},
+ { OP_IfPos, 1, 8, 0},
+ { OP_Integer, 0, 1, 0}, /* 6 */
+ { OP_Noop, 0, 0, 0},
+ { OP_ResultRow, 1, 1, 0},
+ };
+ VdbeOp *aOp;
+ sqlite3VdbeUsesBtree(v, iDb);
+ if( !zRight ){
+ pParse->nMem += 2;
+ sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(getCacheSize));
+ aOp = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize, iLn);
+ if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break;
+ aOp[0].p1 = iDb;
+ aOp[1].p1 = iDb;
+ aOp[6].p1 = SQLITE_DEFAULT_CACHE_SIZE;
+ }else{
+ int size = sqlite3AbsInt32(sqlite3Atoi(zRight));
+ sqlite3BeginWriteOperation(pParse, 0, iDb);
+ sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, size);
+ assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+ pDb->pSchema->cache_size = size;
+ sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
+ }
+ break;
+ }
+#endif /* !SQLITE_OMIT_PAGER_PRAGMAS && !SQLITE_OMIT_DEPRECATED */
+
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+ /*
+ ** PRAGMA [schema.]page_size
+ ** PRAGMA [schema.]page_size=N
+ **
+ ** The first form reports the current setting for the
+ ** database page size in bytes. The second form sets the
+ ** database page size value. The value can only be set if
+ ** the database has not yet been created.
+ */
+ case PragTyp_PAGE_SIZE: {
+ Btree *pBt = pDb->pBt;
+ assert( pBt!=0 );
+ if( !zRight ){
+ int size = ALWAYS(pBt) ? sqlite3BtreeGetPageSize(pBt) : 0;
+ returnSingleInt(v, size);
+ }else{
+ /* Malloc may fail when setting the page-size, as there is an internal
+ ** buffer that the pager module resizes using sqlite3_realloc().
+ */
+ db->nextPagesize = sqlite3Atoi(zRight);
+ if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,-1,0) ){
+ sqlite3OomFault(db);
+ }
+ }
+ break;
+ }
+
+ /*
+ ** PRAGMA [schema.]secure_delete
+ ** PRAGMA [schema.]secure_delete=ON/OFF
+ **
+ ** The first form reports the current setting for the
+ ** secure_delete flag. The second form changes the secure_delete
+ ** flag setting and reports thenew value.
+ */
+ case PragTyp_SECURE_DELETE: {
+ Btree *pBt = pDb->pBt;
+ int b = -1;
+ assert( pBt!=0 );
+ if( zRight ){
+ b = sqlite3GetBoolean(zRight, 0);
+ }
+ if( pId2->n==0 && b>=0 ){
+ int ii;
+ for(ii=0; ii<db->nDb; ii++){
+ sqlite3BtreeSecureDelete(db->aDb[ii].pBt, b);
+ }
+ }
+ b = sqlite3BtreeSecureDelete(pBt, b);
+ returnSingleInt(v, b);
+ break;
+ }
+
+ /*
+ ** PRAGMA [schema.]max_page_count
+ ** PRAGMA [schema.]max_page_count=N
+ **
+ ** The first form reports the current setting for the
+ ** maximum number of pages in the database file. The
+ ** second form attempts to change this setting. Both
+ ** forms return the current setting.
+ **
+ ** The absolute value of N is used. This is undocumented and might
+ ** change. The only purpose is to provide an easy way to test
+ ** the sqlite3AbsInt32() function.
+ **
+ ** PRAGMA [schema.]page_count
+ **
+ ** Return the number of pages in the specified database.
+ */
+ case PragTyp_PAGE_COUNT: {
+ int iReg;
+ sqlite3CodeVerifySchema(pParse, iDb);
+ iReg = ++pParse->nMem;
+ if( sqlite3Tolower(zLeft[0])=='p' ){
+ sqlite3VdbeAddOp2(v, OP_Pagecount, iDb, iReg);
+ }else{
+ sqlite3VdbeAddOp3(v, OP_MaxPgcnt, iDb, iReg,
+ sqlite3AbsInt32(sqlite3Atoi(zRight)));
+ }
+ sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1);
+ break;
+ }
+
+ /*
+ ** PRAGMA [schema.]locking_mode
+ ** PRAGMA [schema.]locking_mode = (normal|exclusive)
+ */
+ case PragTyp_LOCKING_MODE: {
+ const char *zRet = "normal";
+ int eMode = getLockingMode(zRight);
+
+ if( pId2->n==0 && eMode==PAGER_LOCKINGMODE_QUERY ){
+ /* Simple "PRAGMA locking_mode;" statement. This is a query for
+ ** the current default locking mode (which may be different to
+ ** the locking-mode of the main database).
+ */
+ eMode = db->dfltLockMode;
+ }else{
+ Pager *pPager;
+ if( pId2->n==0 ){
+ /* This indicates that no database name was specified as part
+ ** of the PRAGMA command. In this case the locking-mode must be
+ ** set on all attached databases, as well as the main db file.
+ **
+ ** Also, the sqlite3.dfltLockMode variable is set so that
+ ** any subsequently attached databases also use the specified
+ ** locking mode.
+ */
+ int ii;
+ assert(pDb==&db->aDb[0]);
+ for(ii=2; ii<db->nDb; ii++){
+ pPager = sqlite3BtreePager(db->aDb[ii].pBt);
+ sqlite3PagerLockingMode(pPager, eMode);
+ }
+ db->dfltLockMode = (u8)eMode;
+ }
+ pPager = sqlite3BtreePager(pDb->pBt);
+ eMode = sqlite3PagerLockingMode(pPager, eMode);
+ }
+
+ assert( eMode==PAGER_LOCKINGMODE_NORMAL
+ || eMode==PAGER_LOCKINGMODE_EXCLUSIVE );
+ if( eMode==PAGER_LOCKINGMODE_EXCLUSIVE ){
+ zRet = "exclusive";
+ }
+ returnSingleText(v, zRet);
+ break;
+ }
+
+ /*
+ ** PRAGMA [schema.]journal_mode
+ ** PRAGMA [schema.]journal_mode =
+ ** (delete|persist|off|truncate|memory|wal|off)
+ */
+ case PragTyp_JOURNAL_MODE: {
+ int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */
+ int ii; /* Loop counter */
+
+ if( zRight==0 ){
+ /* If there is no "=MODE" part of the pragma, do a query for the
+ ** current mode */
+ eMode = PAGER_JOURNALMODE_QUERY;
+ }else{
+ const char *zMode;
+ int n = sqlite3Strlen30(zRight);
+ for(eMode=0; (zMode = sqlite3JournalModename(eMode))!=0; eMode++){
+ if( sqlite3StrNICmp(zRight, zMode, n)==0 ) break;
+ }
+ if( !zMode ){
+ /* If the "=MODE" part does not match any known journal mode,
+ ** then do a query */
+ eMode = PAGER_JOURNALMODE_QUERY;
+ }
+ }
+ if( eMode==PAGER_JOURNALMODE_QUERY && pId2->n==0 ){
+ /* Convert "PRAGMA journal_mode" into "PRAGMA main.journal_mode" */
+ iDb = 0;
+ pId2->n = 1;
+ }
+ for(ii=db->nDb-1; ii>=0; ii--){
+ if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){
+ sqlite3VdbeUsesBtree(v, ii);
+ sqlite3VdbeAddOp3(v, OP_JournalMode, ii, 1, eMode);
+ }
+ }
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
+ break;
+ }
+
+ /*
+ ** PRAGMA [schema.]journal_size_limit
+ ** PRAGMA [schema.]journal_size_limit=N
+ **
+ ** Get or set the size limit on rollback journal files.
+ */
+ case PragTyp_JOURNAL_SIZE_LIMIT: {
+ Pager *pPager = sqlite3BtreePager(pDb->pBt);
+ i64 iLimit = -2;
+ if( zRight ){
+ sqlite3DecOrHexToI64(zRight, &iLimit);
+ if( iLimit<-1 ) iLimit = -1;
+ }
+ iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit);
+ returnSingleInt(v, iLimit);
+ break;
+ }
+
+#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
+
+ /*
+ ** PRAGMA [schema.]auto_vacuum
+ ** PRAGMA [schema.]auto_vacuum=N
+ **
+ ** Get or set the value of the database 'auto-vacuum' parameter.
+ ** The value is one of: 0 NONE 1 FULL 2 INCREMENTAL
+ */
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ case PragTyp_AUTO_VACUUM: {
+ Btree *pBt = pDb->pBt;
+ assert( pBt!=0 );
+ if( !zRight ){
+ returnSingleInt(v, sqlite3BtreeGetAutoVacuum(pBt));
+ }else{
+ int eAuto = getAutoVacuum(zRight);
+ assert( eAuto>=0 && eAuto<=2 );
+ db->nextAutovac = (u8)eAuto;
+ /* Call SetAutoVacuum() to set initialize the internal auto and
+ ** incr-vacuum flags. This is required in case this connection
+ ** creates the database file. It is important that it is created
+ ** as an auto-vacuum capable db.
+ */
+ rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto);
+ if( rc==SQLITE_OK && (eAuto==1 || eAuto==2) ){
+ /* When setting the auto_vacuum mode to either "full" or
+ ** "incremental", write the value of meta[6] in the database
+ ** file. Before writing to meta[6], check that meta[3] indicates
+ ** that this really is an auto-vacuum capable database.
+ */
+ static const int iLn = VDBE_OFFSET_LINENO(2);
+ static const VdbeOpList setMeta6[] = {
+ { OP_Transaction, 0, 1, 0}, /* 0 */
+ { OP_ReadCookie, 0, 1, BTREE_LARGEST_ROOT_PAGE},
+ { OP_If, 1, 0, 0}, /* 2 */
+ { OP_Halt, SQLITE_OK, OE_Abort, 0}, /* 3 */
+ { OP_SetCookie, 0, BTREE_INCR_VACUUM, 0}, /* 4 */
+ };
+ VdbeOp *aOp;
+ int iAddr = sqlite3VdbeCurrentAddr(v);
+ sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(setMeta6));
+ aOp = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6, iLn);
+ if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break;
+ aOp[0].p1 = iDb;
+ aOp[1].p1 = iDb;
+ aOp[2].p2 = iAddr+4;
+ aOp[4].p1 = iDb;
+ aOp[4].p3 = eAuto - 1;
+ sqlite3VdbeUsesBtree(v, iDb);
+ }
+ }
+ break;
+ }
+#endif
+
+ /*
+ ** PRAGMA [schema.]incremental_vacuum(N)
+ **
+ ** Do N steps of incremental vacuuming on a database.
+ */
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ case PragTyp_INCREMENTAL_VACUUM: {
+ int iLimit, addr;
+ if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){
+ iLimit = 0x7fffffff;
+ }
+ sqlite3BeginWriteOperation(pParse, 0, iDb);
+ sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1);
+ addr = sqlite3VdbeAddOp1(v, OP_IncrVacuum, iDb); VdbeCoverage(v);
+ sqlite3VdbeAddOp1(v, OP_ResultRow, 1);
+ sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
+ sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr); VdbeCoverage(v);
+ sqlite3VdbeJumpHere(v, addr);
+ break;
+ }
+#endif
+
+#ifndef SQLITE_OMIT_PAGER_PRAGMAS
+ /*
+ ** PRAGMA [schema.]cache_size
+ ** PRAGMA [schema.]cache_size=N
+ **
+ ** The first form reports the current local setting for the
+ ** page cache size. The second form sets the local
+ ** page cache size value. If N is positive then that is the
+ ** number of pages in the cache. If N is negative, then the
+ ** number of pages is adjusted so that the cache uses -N kibibytes
+ ** of memory.
+ */
+ case PragTyp_CACHE_SIZE: {
+ assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+ if( !zRight ){
+ returnSingleInt(v, pDb->pSchema->cache_size);
+ }else{
+ int size = sqlite3Atoi(zRight);
+ pDb->pSchema->cache_size = size;
+ sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
+ }
+ break;
+ }
+
+ /*
+ ** PRAGMA [schema.]cache_spill
+ ** PRAGMA cache_spill=BOOLEAN
+ ** PRAGMA [schema.]cache_spill=N
+ **
+ ** The first form reports the current local setting for the
+ ** page cache spill size. The second form turns cache spill on
+ ** or off. When turnning cache spill on, the size is set to the
+ ** current cache_size. The third form sets a spill size that
+ ** may be different form the cache size.
+ ** If N is positive then that is the
+ ** number of pages in the cache. If N is negative, then the
+ ** number of pages is adjusted so that the cache uses -N kibibytes
+ ** of memory.
+ **
+ ** If the number of cache_spill pages is less then the number of
+ ** cache_size pages, no spilling occurs until the page count exceeds
+ ** the number of cache_size pages.
+ **
+ ** The cache_spill=BOOLEAN setting applies to all attached schemas,
+ ** not just the schema specified.
+ */
+ case PragTyp_CACHE_SPILL: {
+ assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+ if( !zRight ){
+ returnSingleInt(v,
+ (db->flags & SQLITE_CacheSpill)==0 ? 0 :
+ sqlite3BtreeSetSpillSize(pDb->pBt,0));
+ }else{
+ int size = 1;
+ if( sqlite3GetInt32(zRight, &size) ){
+ sqlite3BtreeSetSpillSize(pDb->pBt, size);
+ }
+ if( sqlite3GetBoolean(zRight, size!=0) ){
+ db->flags |= SQLITE_CacheSpill;
+ }else{
+ db->flags &= ~SQLITE_CacheSpill;
+ }
+ setAllPagerFlags(db);
+ }
+ break;
+ }
+
+ /*
+ ** PRAGMA [schema.]mmap_size(N)
+ **
+ ** Used to set mapping size limit. The mapping size limit is
+ ** used to limit the aggregate size of all memory mapped regions of the
+ ** database file. If this parameter is set to zero, then memory mapping
+ ** is not used at all. If N is negative, then the default memory map
+ ** limit determined by sqlite3_config(SQLITE_CONFIG_MMAP_SIZE) is set.
+ ** The parameter N is measured in bytes.
+ **
+ ** This value is advisory. The underlying VFS is free to memory map
+ ** as little or as much as it wants. Except, if N is set to 0 then the
+ ** upper layers will never invoke the xFetch interfaces to the VFS.
+ */
+ case PragTyp_MMAP_SIZE: {
+ sqlite3_int64 sz;
+#if SQLITE_MAX_MMAP_SIZE>0
+ assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+ if( zRight ){
+ int ii;
+ sqlite3DecOrHexToI64(zRight, &sz);
+ if( sz<0 ) sz = sqlite3GlobalConfig.szMmap;
+ if( pId2->n==0 ) db->szMmap = sz;
+ for(ii=db->nDb-1; ii>=0; ii--){
+ if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){
+ sqlite3BtreeSetMmapLimit(db->aDb[ii].pBt, sz);
+ }
+ }
+ }
+ sz = -1;
+ rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_MMAP_SIZE, &sz);
+#else
+ sz = 0;
+ rc = SQLITE_OK;
+#endif
+ if( rc==SQLITE_OK ){
+ returnSingleInt(v, sz);
+ }else if( rc!=SQLITE_NOTFOUND ){
+ pParse->nErr++;
+ pParse->rc = rc;
+ }
+ break;
+ }
+
+ /*
+ ** PRAGMA temp_store
+ ** PRAGMA temp_store = "default"|"memory"|"file"
+ **
+ ** Return or set the local value of the temp_store flag. Changing
+ ** the local value does not make changes to the disk file and the default
+ ** value will be restored the next time the database is opened.
+ **
+ ** Note that it is possible for the library compile-time options to
+ ** override this setting
+ */
+ case PragTyp_TEMP_STORE: {
+ if( !zRight ){
+ returnSingleInt(v, db->temp_store);
+ }else{
+ changeTempStorage(pParse, zRight);
+ }
+ break;
+ }
+
+ /*
+ ** PRAGMA temp_store_directory
+ ** PRAGMA temp_store_directory = ""|"directory_name"
+ **
+ ** Return or set the local value of the temp_store_directory flag. Changing
+ ** the value sets a specific directory to be used for temporary files.
+ ** Setting to a null string reverts to the default temporary directory search.
+ ** If temporary directory is changed, then invalidateTempStorage.
+ **
+ */
+ case PragTyp_TEMP_STORE_DIRECTORY: {
+ if( !zRight ){
+ returnSingleText(v, sqlite3_temp_directory);
+ }else{
+#ifndef SQLITE_OMIT_WSD
+ if( zRight[0] ){
+ int res;
+ rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res);
+ if( rc!=SQLITE_OK || res==0 ){
+ sqlite3ErrorMsg(pParse, "not a writable directory");
+ goto pragma_out;
+ }
+ }
+ if( SQLITE_TEMP_STORE==0
+ || (SQLITE_TEMP_STORE==1 && db->temp_store<=1)
+ || (SQLITE_TEMP_STORE==2 && db->temp_store==1)
+ ){
+ invalidateTempStorage(pParse);
+ }
+ sqlite3_free(sqlite3_temp_directory);
+ if( zRight[0] ){
+ sqlite3_temp_directory = sqlite3_mprintf("%s", zRight);
+ }else{
+ sqlite3_temp_directory = 0;
+ }
+#endif /* SQLITE_OMIT_WSD */
+ }
+ break;
+ }
+
+#if SQLITE_OS_WIN
+ /*
+ ** PRAGMA data_store_directory
+ ** PRAGMA data_store_directory = ""|"directory_name"
+ **
+ ** Return or set the local value of the data_store_directory flag. Changing
+ ** the value sets a specific directory to be used for database files that
+ ** were specified with a relative pathname. Setting to a null string reverts
+ ** to the default database directory, which for database files specified with
+ ** a relative path will probably be based on the current directory for the
+ ** process. Database file specified with an absolute path are not impacted
+ ** by this setting, regardless of its value.
+ **
+ */
+ case PragTyp_DATA_STORE_DIRECTORY: {
+ if( !zRight ){
+ returnSingleText(v, sqlite3_data_directory);
+ }else{
+#ifndef SQLITE_OMIT_WSD
+ if( zRight[0] ){
+ int res;
+ rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res);
+ if( rc!=SQLITE_OK || res==0 ){
+ sqlite3ErrorMsg(pParse, "not a writable directory");
+ goto pragma_out;
+ }
+ }
+ sqlite3_free(sqlite3_data_directory);
+ if( zRight[0] ){
+ sqlite3_data_directory = sqlite3_mprintf("%s", zRight);
+ }else{
+ sqlite3_data_directory = 0;
+ }
+#endif /* SQLITE_OMIT_WSD */
+ }
+ break;
+ }
+#endif
+
+#if SQLITE_ENABLE_LOCKING_STYLE
+ /*
+ ** PRAGMA [schema.]lock_proxy_file
+ ** PRAGMA [schema.]lock_proxy_file = ":auto:"|"lock_file_path"
+ **
+ ** Return or set the value of the lock_proxy_file flag. Changing
+ ** the value sets a specific file to be used for database access locks.
+ **
+ */
+ case PragTyp_LOCK_PROXY_FILE: {
+ if( !zRight ){
+ Pager *pPager = sqlite3BtreePager(pDb->pBt);
+ char *proxy_file_path = NULL;
+ sqlite3_file *pFile = sqlite3PagerFile(pPager);
+ sqlite3OsFileControlHint(pFile, SQLITE_GET_LOCKPROXYFILE,
+ &proxy_file_path);
+ returnSingleText(v, proxy_file_path);
+ }else{
+ Pager *pPager = sqlite3BtreePager(pDb->pBt);
+ sqlite3_file *pFile = sqlite3PagerFile(pPager);
+ int res;
+ if( zRight[0] ){
+ res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE,
+ zRight);
+ } else {
+ res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE,
+ NULL);
+ }
+ if( res!=SQLITE_OK ){
+ sqlite3ErrorMsg(pParse, "failed to set lock proxy file");
+ goto pragma_out;
+ }
+ }
+ break;
+ }
+#endif /* SQLITE_ENABLE_LOCKING_STYLE */
+
+ /*
+ ** PRAGMA [schema.]synchronous
+ ** PRAGMA [schema.]synchronous=OFF|ON|NORMAL|FULL|EXTRA
+ **
+ ** Return or set the local value of the synchronous flag. Changing
+ ** the local value does not make changes to the disk file and the
+ ** default value will be restored the next time the database is
+ ** opened.
+ */
+ case PragTyp_SYNCHRONOUS: {
+ if( !zRight ){
+ returnSingleInt(v, pDb->safety_level-1);
+ }else{
+ if( !db->autoCommit ){
+ sqlite3ErrorMsg(pParse,
+ "Safety level may not be changed inside a transaction");
+ }else{
+ int iLevel = (getSafetyLevel(zRight,0,1)+1) & PAGER_SYNCHRONOUS_MASK;
+ if( iLevel==0 ) iLevel = 1;
+ pDb->safety_level = iLevel;
+ pDb->bSyncSet = 1;
+ setAllPagerFlags(db);
+ }
+ }
+ break;
+ }
+#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
+
+#ifndef SQLITE_OMIT_FLAG_PRAGMAS
+ case PragTyp_FLAG: {
+ if( zRight==0 ){
+ setPragmaResultColumnNames(v, pPragma);
+ returnSingleInt(v, (db->flags & pPragma->iArg)!=0 );
+ }else{
+ int mask = pPragma->iArg; /* Mask of bits to set or clear. */
+ if( db->autoCommit==0 ){
+ /* Foreign key support may not be enabled or disabled while not
+ ** in auto-commit mode. */
+ mask &= ~(SQLITE_ForeignKeys);
+ }
+#if SQLITE_USER_AUTHENTICATION
+ if( db->auth.authLevel==UAUTH_User ){
+ /* Do not allow non-admin users to modify the schema arbitrarily */
+ mask &= ~(SQLITE_WriteSchema);
+ }
+#endif
+
+ if( sqlite3GetBoolean(zRight, 0) ){
+ db->flags |= mask;
+ }else{
+ db->flags &= ~mask;
+ if( mask==SQLITE_DeferFKs ) db->nDeferredImmCons = 0;
+ }
+
+ /* Many of the flag-pragmas modify the code generated by the SQL
+ ** compiler (eg. count_changes). So add an opcode to expire all
+ ** compiled SQL statements after modifying a pragma value.
+ */
+ sqlite3VdbeAddOp0(v, OP_Expire);
+ setAllPagerFlags(db);
+ }
+ break;
+ }
+#endif /* SQLITE_OMIT_FLAG_PRAGMAS */
+
+#ifndef SQLITE_OMIT_SCHEMA_PRAGMAS
+ /*
+ ** PRAGMA table_info(<table>)
+ **
+ ** Return a single row for each column of the named table. The columns of
+ ** the returned data set are:
+ **
+ ** cid: Column id (numbered from left to right, starting at 0)
+ ** name: Column name
+ ** type: Column declaration type.
+ ** notnull: True if 'NOT NULL' is part of column declaration
+ ** dflt_value: The default value for the column, if any.
+ */
+ case PragTyp_TABLE_INFO: if( zRight ){
+ Table *pTab;
+ pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb);
+ if( pTab ){
+ int i, k;
+ int nHidden = 0;
+ Column *pCol;
+ Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+ pParse->nMem = 6;
+ sqlite3CodeVerifySchema(pParse, iDb);
+ sqlite3ViewGetColumnNames(pParse, pTab);
+ for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
+ if( IsHiddenColumn(pCol) ){
+ nHidden++;
+ continue;
+ }
+ if( (pCol->colFlags & COLFLAG_PRIMKEY)==0 ){
+ k = 0;
+ }else if( pPk==0 ){
+ k = 1;
+ }else{
+ for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
+ }
+ assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN );
+ sqlite3VdbeMultiLoad(v, 1, "issisi",
+ i-nHidden,
+ pCol->zName,
+ sqlite3ColumnType(pCol,""),
+ pCol->notNull ? 1 : 0,
+ pCol->pDflt ? pCol->pDflt->u.zToken : 0,
+ k);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6);
+ }
+ }
+ }
+ break;
+
+ case PragTyp_STATS: {
+ Index *pIdx;
+ HashElem *i;
+ pParse->nMem = 4;
+ sqlite3CodeVerifySchema(pParse, iDb);
+ for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){
+ Table *pTab = sqliteHashData(i);
+ sqlite3VdbeMultiLoad(v, 1, "ssii",
+ pTab->zName,
+ 0,
+ pTab->szTabRow,
+ pTab->nRowLogEst);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ sqlite3VdbeMultiLoad(v, 2, "sii",
+ pIdx->zName,
+ pIdx->szIdxRow,
+ pIdx->aiRowLogEst[0]);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
+ }
+ }
+ }
+ break;
+
+ case PragTyp_INDEX_INFO: if( zRight ){
+ Index *pIdx;
+ Table *pTab;
+ pIdx = sqlite3FindIndex(db, zRight, zDb);
+ if( pIdx ){
+ int i;
+ int mx;
+ if( pPragma->iArg ){
+ /* PRAGMA index_xinfo (newer version with more rows and columns) */
+ mx = pIdx->nColumn;
+ pParse->nMem = 6;
+ }else{
+ /* PRAGMA index_info (legacy version) */
+ mx = pIdx->nKeyCol;
+ pParse->nMem = 3;
+ }
+ pTab = pIdx->pTable;
+ sqlite3CodeVerifySchema(pParse, iDb);
+ assert( pParse->nMem<=pPragma->nPragCName );
+ for(i=0; i<mx; i++){
+ i16 cnum = pIdx->aiColumn[i];
+ sqlite3VdbeMultiLoad(v, 1, "iis", i, cnum,
+ cnum<0 ? 0 : pTab->aCol[cnum].zName);
+ if( pPragma->iArg ){
+ sqlite3VdbeMultiLoad(v, 4, "isi",
+ pIdx->aSortOrder[i],
+ pIdx->azColl[i],
+ i<pIdx->nKeyCol);
+ }
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, pParse->nMem);
+ }
+ }
+ }
+ break;
+
+ case PragTyp_INDEX_LIST: if( zRight ){
+ Index *pIdx;
+ Table *pTab;
+ int i;
+ pTab = sqlite3FindTable(db, zRight, zDb);
+ if( pTab ){
+ pParse->nMem = 5;
+ sqlite3CodeVerifySchema(pParse, iDb);
+ for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){
+ const char *azOrigin[] = { "c", "u", "pk" };
+ sqlite3VdbeMultiLoad(v, 1, "isisi",
+ i,
+ pIdx->zName,
+ IsUniqueIndex(pIdx),
+ azOrigin[pIdx->idxType],
+ pIdx->pPartIdxWhere!=0);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5);
+ }
+ }
+ }
+ break;
+
+ case PragTyp_DATABASE_LIST: {
+ int i;
+ pParse->nMem = 3;
+ for(i=0; i<db->nDb; i++){
+ if( db->aDb[i].pBt==0 ) continue;
+ assert( db->aDb[i].zDbSName!=0 );
+ sqlite3VdbeMultiLoad(v, 1, "iss",
+ i,
+ db->aDb[i].zDbSName,
+ sqlite3BtreeGetFilename(db->aDb[i].pBt));
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
+ }
+ }
+ break;
+
+ case PragTyp_COLLATION_LIST: {
+ int i = 0;
+ HashElem *p;
+ pParse->nMem = 2;
+ for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){
+ CollSeq *pColl = (CollSeq *)sqliteHashData(p);
+ sqlite3VdbeMultiLoad(v, 1, "is", i++, pColl->zName);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2);
+ }
+ }
+ break;
+#endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */
+
+#ifndef SQLITE_OMIT_FOREIGN_KEY
+ case PragTyp_FOREIGN_KEY_LIST: if( zRight ){
+ FKey *pFK;
+ Table *pTab;
+ pTab = sqlite3FindTable(db, zRight, zDb);
+ if( pTab ){
+ pFK = pTab->pFKey;
+ if( pFK ){
+ int i = 0;
+ pParse->nMem = 8;
+ sqlite3CodeVerifySchema(pParse, iDb);
+ while(pFK){
+ int j;
+ for(j=0; j<pFK->nCol; j++){
+ sqlite3VdbeMultiLoad(v, 1, "iissssss",
+ i,
+ j,
+ pFK->zTo,
+ pTab->aCol[pFK->aCol[j].iFrom].zName,
+ pFK->aCol[j].zCol,
+ actionName(pFK->aAction[1]), /* ON UPDATE */
+ actionName(pFK->aAction[0]), /* ON DELETE */
+ "NONE");
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 8);
+ }
+ ++i;
+ pFK = pFK->pNextFrom;
+ }
+ }
+ }
+ }
+ break;
+#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
+
+#ifndef SQLITE_OMIT_FOREIGN_KEY
+#ifndef SQLITE_OMIT_TRIGGER
+ case PragTyp_FOREIGN_KEY_CHECK: {
+ FKey *pFK; /* A foreign key constraint */
+ Table *pTab; /* Child table contain "REFERENCES" keyword */
+ Table *pParent; /* Parent table that child points to */
+ Index *pIdx; /* Index in the parent table */
+ int i; /* Loop counter: Foreign key number for pTab */
+ int j; /* Loop counter: Field of the foreign key */
+ HashElem *k; /* Loop counter: Next table in schema */
+ int x; /* result variable */
+ int regResult; /* 3 registers to hold a result row */
+ int regKey; /* Register to hold key for checking the FK */
+ int regRow; /* Registers to hold a row from pTab */
+ int addrTop; /* Top of a loop checking foreign keys */
+ int addrOk; /* Jump here if the key is OK */
+ int *aiCols; /* child to parent column mapping */
+
+ regResult = pParse->nMem+1;
+ pParse->nMem += 4;
+ regKey = ++pParse->nMem;
+ regRow = ++pParse->nMem;
+ sqlite3CodeVerifySchema(pParse, iDb);
+ k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash);
+ while( k ){
+ if( zRight ){
+ pTab = sqlite3LocateTable(pParse, 0, zRight, zDb);
+ k = 0;
+ }else{
+ pTab = (Table*)sqliteHashData(k);
+ k = sqliteHashNext(k);
+ }
+ if( pTab==0 || pTab->pFKey==0 ) continue;
+ sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
+ if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow;
+ sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead);
+ sqlite3VdbeLoadString(v, regResult, pTab->zName);
+ for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
+ pParent = sqlite3FindTable(db, pFK->zTo, zDb);
+ if( pParent==0 ) continue;
+ pIdx = 0;
+ sqlite3TableLock(pParse, iDb, pParent->tnum, 0, pParent->zName);
+ x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0);
+ if( x==0 ){
+ if( pIdx==0 ){
+ sqlite3OpenTable(pParse, i, iDb, pParent, OP_OpenRead);
+ }else{
+ sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iDb);
+ sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
+ }
+ }else{
+ k = 0;
+ break;
+ }
+ }
+ assert( pParse->nErr>0 || pFK==0 );
+ if( pFK ) break;
+ if( pParse->nTab<i ) pParse->nTab = i;
+ addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0); VdbeCoverage(v);
+ for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
+ pParent = sqlite3FindTable(db, pFK->zTo, zDb);
+ pIdx = 0;
+ aiCols = 0;
+ if( pParent ){
+ x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols);
+ assert( x==0 );
+ }
+ addrOk = sqlite3VdbeMakeLabel(v);
+ if( pParent && pIdx==0 ){
+ int iKey = pFK->aCol[0].iFrom;
+ assert( iKey>=0 && iKey<pTab->nCol );
+ if( iKey!=pTab->iPKey ){
+ sqlite3VdbeAddOp3(v, OP_Column, 0, iKey, regRow);
+ sqlite3ColumnDefault(v, pTab, iKey, regRow);
+ sqlite3VdbeAddOp2(v, OP_IsNull, regRow, addrOk); VdbeCoverage(v);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Rowid, 0, regRow);
+ }
+ sqlite3VdbeAddOp3(v, OP_SeekRowid, i, 0, regRow); VdbeCoverage(v);
+ sqlite3VdbeGoto(v, addrOk);
+ sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
+ }else{
+ for(j=0; j<pFK->nCol; j++){
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, 0,
+ aiCols ? aiCols[j] : pFK->aCol[j].iFrom, regRow+j);
+ sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v);
+ }
+ if( pParent ){
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey,
+ sqlite3IndexAffinityStr(db,pIdx), pFK->nCol);
+ sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0);
+ VdbeCoverage(v);
+ }
+ }
+ sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1);
+ sqlite3VdbeMultiLoad(v, regResult+2, "si", pFK->zTo, i-1);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 4);
+ sqlite3VdbeResolveLabel(v, addrOk);
+ sqlite3DbFree(db, aiCols);
+ }
+ sqlite3VdbeAddOp2(v, OP_Next, 0, addrTop+1); VdbeCoverage(v);
+ sqlite3VdbeJumpHere(v, addrTop);
+ }
+ }
+ break;
+#endif /* !defined(SQLITE_OMIT_TRIGGER) */
+#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
+
+#ifndef NDEBUG
+ case PragTyp_PARSER_TRACE: {
+ if( zRight ){
+ if( sqlite3GetBoolean(zRight, 0) ){
+ sqlite3ParserTrace(stdout, "parser: ");
+ }else{
+ sqlite3ParserTrace(0, 0);
+ }
+ }
+ }
+ break;
+#endif
+
+ /* Reinstall the LIKE and GLOB functions. The variant of LIKE
+ ** used will be case sensitive or not depending on the RHS.
+ */
+ case PragTyp_CASE_SENSITIVE_LIKE: {
+ if( zRight ){
+ sqlite3RegisterLikeFunctions(db, sqlite3GetBoolean(zRight, 0));
+ }
+ }
+ break;
+
+#ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX
+# define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100
+#endif
+
+#ifndef SQLITE_OMIT_INTEGRITY_CHECK
+ /* Pragma "quick_check" is reduced version of
+ ** integrity_check designed to detect most database corruption
+ ** without most of the overhead of a full integrity-check.
+ */
+ case PragTyp_INTEGRITY_CHECK: {
+ int i, j, addr, mxErr;
+
+ int isQuick = (sqlite3Tolower(zLeft[0])=='q');
+
+ /* If the PRAGMA command was of the form "PRAGMA <db>.integrity_check",
+ ** then iDb is set to the index of the database identified by <db>.
+ ** In this case, the integrity of database iDb only is verified by
+ ** the VDBE created below.
+ **
+ ** Otherwise, if the command was simply "PRAGMA integrity_check" (or
+ ** "PRAGMA quick_check"), then iDb is set to 0. In this case, set iDb
+ ** to -1 here, to indicate that the VDBE should verify the integrity
+ ** of all attached databases. */
+ assert( iDb>=0 );
+ assert( iDb==0 || pId2->z );
+ if( pId2->z==0 ) iDb = -1;
+
+ /* Initialize the VDBE program */
+ pParse->nMem = 6;
+
+ /* Set the maximum error count */
+ mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
+ if( zRight ){
+ sqlite3GetInt32(zRight, &mxErr);
+ if( mxErr<=0 ){
+ mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
+ }
+ }
+ sqlite3VdbeAddOp2(v, OP_Integer, mxErr, 1); /* reg[1] holds errors left */
+
+ /* Do an integrity check on each database file */
+ for(i=0; i<db->nDb; i++){
+ HashElem *x;
+ Hash *pTbls;
+ int *aRoot;
+ int cnt = 0;
+ int mxIdx = 0;
+ int nIdx;
+
+ if( OMIT_TEMPDB && i==1 ) continue;
+ if( iDb>=0 && i!=iDb ) continue;
+
+ sqlite3CodeVerifySchema(pParse, i);
+ addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
+ sqlite3VdbeJumpHere(v, addr);
+
+ /* Do an integrity check of the B-Tree
+ **
+ ** Begin by finding the root pages numbers
+ ** for all tables and indices in the database.
+ */
+ assert( sqlite3SchemaMutexHeld(db, i, 0) );
+ pTbls = &db->aDb[i].pSchema->tblHash;
+ for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
+ Table *pTab = sqliteHashData(x);
+ Index *pIdx;
+ if( HasRowid(pTab) ) cnt++;
+ for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ cnt++; }
+ if( nIdx>mxIdx ) mxIdx = nIdx;
+ }
+ aRoot = sqlite3DbMallocRawNN(db, sizeof(int)*(cnt+1));
+ if( aRoot==0 ) break;
+ for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
+ Table *pTab = sqliteHashData(x);
+ Index *pIdx;
+ if( HasRowid(pTab) ) aRoot[cnt++] = pTab->tnum;
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ aRoot[cnt++] = pIdx->tnum;
+ }
+ }
+ aRoot[cnt] = 0;
+
+ /* Make sure sufficient number of registers have been allocated */
+ pParse->nMem = MAX( pParse->nMem, 8+mxIdx );
+
+ /* Do the b-tree integrity checks */
+ sqlite3VdbeAddOp4(v, OP_IntegrityCk, 2, cnt, 1, (char*)aRoot,P4_INTARRAY);
+ sqlite3VdbeChangeP5(v, (u8)i);
+ addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v);
+ sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
+ sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zDbSName),
+ P4_DYNAMIC);
+ sqlite3VdbeAddOp3(v, OP_Move, 2, 4, 1);
+ sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1);
+ sqlite3VdbeJumpHere(v, addr);
+
+ /* Make sure all the indices are constructed correctly.
+ */
+ for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){
+ Table *pTab = sqliteHashData(x);
+ Index *pIdx, *pPk;
+ Index *pPrior = 0;
+ int loopTop;
+ int iDataCur, iIdxCur;
+ int r1 = -1;
+
+ if( pTab->pIndex==0 ) continue;
+ pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
+ addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
+ sqlite3VdbeJumpHere(v, addr);
+ sqlite3ExprCacheClear(pParse);
+ sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0,
+ 1, 0, &iDataCur, &iIdxCur);
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, 7);
+ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */
+ }
+ assert( pParse->nMem>=8+j );
+ assert( sqlite3NoTempsInRange(pParse,1,7+j) );
+ sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v);
+ loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1);
+ /* Verify that all NOT NULL columns really are NOT NULL */
+ for(j=0; j<pTab->nCol; j++){
+ char *zErr;
+ int jmp2, jmp3;
+ if( j==pTab->iPKey ) continue;
+ if( pTab->aCol[j].notNull==0 ) continue;
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3);
+ sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
+ jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
+ zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
+ pTab->aCol[j].zName);
+ sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
+ jmp3 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v);
+ sqlite3VdbeAddOp0(v, OP_Halt);
+ sqlite3VdbeJumpHere(v, jmp2);
+ sqlite3VdbeJumpHere(v, jmp3);
+ }
+ /* Validate index entries for the current row */
+ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+ int jmp2, jmp3, jmp4, jmp5;
+ int ckUniq = sqlite3VdbeMakeLabel(v);
+ if( pPk==pIdx ) continue;
+ r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3,
+ pPrior, r1);
+ pPrior = pIdx;
+ sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1); /* increment entry count */
+ /* Verify that an index entry exists for the current table row */
+ jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1,
+ pIdx->nColumn); VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
+ sqlite3VdbeLoadString(v, 3, "row ");
+ sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3);
+ sqlite3VdbeLoadString(v, 4, " missing from index ");
+ sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
+ jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName);
+ sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
+ jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v);
+ sqlite3VdbeAddOp0(v, OP_Halt);
+ sqlite3VdbeJumpHere(v, jmp2);
+ /* For UNIQUE indexes, verify that only one entry exists with the
+ ** current key. The entry is unique if (1) any column is NULL
+ ** or (2) the next entry has a different key */
+ if( IsUniqueIndex(pIdx) ){
+ int uniqOk = sqlite3VdbeMakeLabel(v);
+ int jmp6;
+ int kk;
+ for(kk=0; kk<pIdx->nKeyCol; kk++){
+ int iCol = pIdx->aiColumn[kk];
+ assert( iCol!=XN_ROWID && iCol<pTab->nCol );
+ if( iCol>=0 && pTab->aCol[iCol].notNull ) continue;
+ sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk);
+ VdbeCoverage(v);
+ }
+ jmp6 = sqlite3VdbeAddOp1(v, OP_Next, iIdxCur+j); VdbeCoverage(v);
+ sqlite3VdbeGoto(v, uniqOk);
+ sqlite3VdbeJumpHere(v, jmp6);
+ sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1,
+ pIdx->nKeyCol); VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
+ sqlite3VdbeLoadString(v, 3, "non-unique entry in index ");
+ sqlite3VdbeGoto(v, jmp5);
+ sqlite3VdbeResolveLabel(v, uniqOk);
+ }
+ sqlite3VdbeJumpHere(v, jmp4);
+ sqlite3ResolvePartIdxLabel(pParse, jmp3);
+ }
+ sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
+ sqlite3VdbeJumpHere(v, loopTop-1);
+#ifndef SQLITE_OMIT_BTREECOUNT
+ sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
+ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+ if( pPk==pIdx ) continue;
+ addr = sqlite3VdbeCurrentAddr(v);
+ sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2); VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
+ sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
+ sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3); VdbeCoverage(v);
+ sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
+ sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
+ sqlite3VdbeLoadString(v, 3, pIdx->zName);
+ sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1);
+ }
+#endif /* SQLITE_OMIT_BTREECOUNT */
+ }
+ }
+ {
+ static const int iLn = VDBE_OFFSET_LINENO(2);
+ static const VdbeOpList endCode[] = {
+ { OP_AddImm, 1, 0, 0}, /* 0 */
+ { OP_If, 1, 4, 0}, /* 1 */
+ { OP_String8, 0, 3, 0}, /* 2 */
+ { OP_ResultRow, 3, 1, 0}, /* 3 */
+ };
+ VdbeOp *aOp;
+
+ aOp = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn);
+ if( aOp ){
+ aOp[0].p2 = -mxErr;
+ aOp[2].p4type = P4_STATIC;
+ aOp[2].p4.z = "ok";
+ }
+ }
+ }
+ break;
+#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
+
+#ifndef SQLITE_OMIT_UTF16
+ /*
+ ** PRAGMA encoding
+ ** PRAGMA encoding = "utf-8"|"utf-16"|"utf-16le"|"utf-16be"
+ **
+ ** In its first form, this pragma returns the encoding of the main
+ ** database. If the database is not initialized, it is initialized now.
+ **
+ ** The second form of this pragma is a no-op if the main database file
+ ** has not already been initialized. In this case it sets the default
+ ** encoding that will be used for the main database file if a new file
+ ** is created. If an existing main database file is opened, then the
+ ** default text encoding for the existing database is used.
+ **
+ ** In all cases new databases created using the ATTACH command are
+ ** created to use the same default text encoding as the main database. If
+ ** the main database has not been initialized and/or created when ATTACH
+ ** is executed, this is done before the ATTACH operation.
+ **
+ ** In the second form this pragma sets the text encoding to be used in
+ ** new database files created using this database handle. It is only
+ ** useful if invoked immediately after the main database i
+ */
+ case PragTyp_ENCODING: {
+ static const struct EncName {
+ char *zName;
+ u8 enc;
+ } encnames[] = {
+ { "UTF8", SQLITE_UTF8 },
+ { "UTF-8", SQLITE_UTF8 }, /* Must be element [1] */
+ { "UTF-16le", SQLITE_UTF16LE }, /* Must be element [2] */
+ { "UTF-16be", SQLITE_UTF16BE }, /* Must be element [3] */
+ { "UTF16le", SQLITE_UTF16LE },
+ { "UTF16be", SQLITE_UTF16BE },
+ { "UTF-16", 0 }, /* SQLITE_UTF16NATIVE */
+ { "UTF16", 0 }, /* SQLITE_UTF16NATIVE */
+ { 0, 0 }
+ };
+ const struct EncName *pEnc;
+ if( !zRight ){ /* "PRAGMA encoding" */
+ if( sqlite3ReadSchema(pParse) ) goto pragma_out;
+ assert( encnames[SQLITE_UTF8].enc==SQLITE_UTF8 );
+ assert( encnames[SQLITE_UTF16LE].enc==SQLITE_UTF16LE );
+ assert( encnames[SQLITE_UTF16BE].enc==SQLITE_UTF16BE );
+ returnSingleText(v, encnames[ENC(pParse->db)].zName);
+ }else{ /* "PRAGMA encoding = XXX" */
+ /* Only change the value of sqlite.enc if the database handle is not
+ ** initialized. If the main database exists, the new sqlite.enc value
+ ** will be overwritten when the schema is next loaded. If it does not
+ ** already exists, it will be created to use the new encoding value.
+ */
+ if(
+ !(DbHasProperty(db, 0, DB_SchemaLoaded)) ||
+ DbHasProperty(db, 0, DB_Empty)
+ ){
+ for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
+ if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){
+ SCHEMA_ENC(db) = ENC(db) =
+ pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE;
+ break;
+ }
+ }
+ if( !pEnc->zName ){
+ sqlite3ErrorMsg(pParse, "unsupported encoding: %s", zRight);
+ }
+ }
+ }
+ }
+ break;
+#endif /* SQLITE_OMIT_UTF16 */
+
+#ifndef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
+ /*
+ ** PRAGMA [schema.]schema_version
+ ** PRAGMA [schema.]schema_version = <integer>
+ **
+ ** PRAGMA [schema.]user_version
+ ** PRAGMA [schema.]user_version = <integer>
+ **
+ ** PRAGMA [schema.]freelist_count
+ **
+ ** PRAGMA [schema.]data_version
+ **
+ ** PRAGMA [schema.]application_id
+ ** PRAGMA [schema.]application_id = <integer>
+ **
+ ** The pragma's schema_version and user_version are used to set or get
+ ** the value of the schema-version and user-version, respectively. Both
+ ** the schema-version and the user-version are 32-bit signed integers
+ ** stored in the database header.
+ **
+ ** The schema-cookie is usually only manipulated internally by SQLite. It
+ ** is incremented by SQLite whenever the database schema is modified (by
+ ** creating or dropping a table or index). The schema version is used by
+ ** SQLite each time a query is executed to ensure that the internal cache
+ ** of the schema used when compiling the SQL query matches the schema of
+ ** the database against which the compiled query is actually executed.
+ ** Subverting this mechanism by using "PRAGMA schema_version" to modify
+ ** the schema-version is potentially dangerous and may lead to program
+ ** crashes or database corruption. Use with caution!
+ **
+ ** The user-version is not used internally by SQLite. It may be used by
+ ** applications for any purpose.
+ */
+ case PragTyp_HEADER_VALUE: {
+ int iCookie = pPragma->iArg; /* Which cookie to read or write */
+ sqlite3VdbeUsesBtree(v, iDb);
+ if( zRight && (pPragma->mPragFlg & PragFlg_ReadOnly)==0 ){
+ /* Write the specified cookie value */
+ static const VdbeOpList setCookie[] = {
+ { OP_Transaction, 0, 1, 0}, /* 0 */
+ { OP_SetCookie, 0, 0, 0}, /* 1 */
+ };
+ VdbeOp *aOp;
+ sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(setCookie));
+ aOp = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie, 0);
+ if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break;
+ aOp[0].p1 = iDb;
+ aOp[1].p1 = iDb;
+ aOp[1].p2 = iCookie;
+ aOp[1].p3 = sqlite3Atoi(zRight);
+ }else{
+ /* Read the specified cookie value */
+ static const VdbeOpList readCookie[] = {
+ { OP_Transaction, 0, 0, 0}, /* 0 */
+ { OP_ReadCookie, 0, 1, 0}, /* 1 */
+ { OP_ResultRow, 1, 1, 0}
+ };
+ VdbeOp *aOp;
+ sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(readCookie));
+ aOp = sqlite3VdbeAddOpList(v, ArraySize(readCookie),readCookie,0);
+ if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break;
+ aOp[0].p1 = iDb;
+ aOp[1].p1 = iDb;
+ aOp[1].p3 = iCookie;
+ sqlite3VdbeReusable(v);
+ }
+ }
+ break;
+#endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */
+
+#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+ /*
+ ** PRAGMA compile_options
+ **
+ ** Return the names of all compile-time options used in this build,
+ ** one option per row.
+ */
+ case PragTyp_COMPILE_OPTIONS: {
+ int i = 0;
+ const char *zOpt;
+ pParse->nMem = 1;
+ while( (zOpt = sqlite3_compileoption_get(i++))!=0 ){
+ sqlite3VdbeLoadString(v, 1, zOpt);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
+ }
+ sqlite3VdbeReusable(v);
+ }
+ break;
+#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
+
+#ifndef SQLITE_OMIT_WAL
+ /*
+ ** PRAGMA [schema.]wal_checkpoint = passive|full|restart|truncate
+ **
+ ** Checkpoint the database.
+ */
+ case PragTyp_WAL_CHECKPOINT: {
+ int iBt = (pId2->z?iDb:SQLITE_MAX_ATTACHED);
+ int eMode = SQLITE_CHECKPOINT_PASSIVE;
+ if( zRight ){
+ if( sqlite3StrICmp(zRight, "full")==0 ){
+ eMode = SQLITE_CHECKPOINT_FULL;
+ }else if( sqlite3StrICmp(zRight, "restart")==0 ){
+ eMode = SQLITE_CHECKPOINT_RESTART;
+ }else if( sqlite3StrICmp(zRight, "truncate")==0 ){
+ eMode = SQLITE_CHECKPOINT_TRUNCATE;
+ }
+ }
+ pParse->nMem = 3;
+ sqlite3VdbeAddOp3(v, OP_Checkpoint, iBt, eMode, 1);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
+ }
+ break;
+
+ /*
+ ** PRAGMA wal_autocheckpoint
+ ** PRAGMA wal_autocheckpoint = N
+ **
+ ** Configure a database connection to automatically checkpoint a database
+ ** after accumulating N frames in the log. Or query for the current value
+ ** of N.
+ */
+ case PragTyp_WAL_AUTOCHECKPOINT: {
+ if( zRight ){
+ sqlite3_wal_autocheckpoint(db, sqlite3Atoi(zRight));
+ }
+ returnSingleInt(v,
+ db->xWalCallback==sqlite3WalDefaultHook ?
+ SQLITE_PTR_TO_INT(db->pWalArg) : 0);
+ }
+ break;
+#endif
+
+ /*
+ ** PRAGMA shrink_memory
+ **
+ ** IMPLEMENTATION-OF: R-23445-46109 This pragma causes the database
+ ** connection on which it is invoked to free up as much memory as it
+ ** can, by calling sqlite3_db_release_memory().
+ */
+ case PragTyp_SHRINK_MEMORY: {
+ sqlite3_db_release_memory(db);
+ break;
+ }
+
+ /*
+ ** PRAGMA busy_timeout
+ ** PRAGMA busy_timeout = N
+ **
+ ** Call sqlite3_busy_timeout(db, N). Return the current timeout value
+ ** if one is set. If no busy handler or a different busy handler is set
+ ** then 0 is returned. Setting the busy_timeout to 0 or negative
+ ** disables the timeout.
+ */
+ /*case PragTyp_BUSY_TIMEOUT*/ default: {
+ assert( pPragma->ePragTyp==PragTyp_BUSY_TIMEOUT );
+ if( zRight ){
+ sqlite3_busy_timeout(db, sqlite3Atoi(zRight));
+ }
+ returnSingleInt(v, db->busyTimeout);
+ break;
+ }
+
+ /*
+ ** PRAGMA soft_heap_limit
+ ** PRAGMA soft_heap_limit = N
+ **
+ ** IMPLEMENTATION-OF: R-26343-45930 This pragma invokes the
+ ** sqlite3_soft_heap_limit64() interface with the argument N, if N is
+ ** specified and is a non-negative integer.
+ ** IMPLEMENTATION-OF: R-64451-07163 The soft_heap_limit pragma always
+ ** returns the same integer that would be returned by the
+ ** sqlite3_soft_heap_limit64(-1) C-language function.
+ */
+ case PragTyp_SOFT_HEAP_LIMIT: {
+ sqlite3_int64 N;
+ if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){
+ sqlite3_soft_heap_limit64(N);
+ }
+ returnSingleInt(v, sqlite3_soft_heap_limit64(-1));
+ break;
+ }
+
+ /*
+ ** PRAGMA threads
+ ** PRAGMA threads = N
+ **
+ ** Configure the maximum number of worker threads. Return the new
+ ** maximum, which might be less than requested.
+ */
+ case PragTyp_THREADS: {
+ sqlite3_int64 N;
+ if( zRight
+ && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK
+ && N>=0
+ ){
+ sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, (int)(N&0x7fffffff));
+ }
+ returnSingleInt(v, sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1));
+ break;
+ }
+
+#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
+ /*
+ ** Report the current state of file logs for all databases
+ */
+ case PragTyp_LOCK_STATUS: {
+ static const char *const azLockName[] = {
+ "unlocked", "shared", "reserved", "pending", "exclusive"
+ };
+ int i;
+ pParse->nMem = 2;
+ for(i=0; i<db->nDb; i++){
+ Btree *pBt;
+ const char *zState = "unknown";
+ int j;
+ if( db->aDb[i].zDbSName==0 ) continue;
+ pBt = db->aDb[i].pBt;
+ if( pBt==0 || sqlite3BtreePager(pBt)==0 ){
+ zState = "closed";
+ }else if( sqlite3_file_control(db, i ? db->aDb[i].zDbSName : 0,
+ SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){
+ zState = azLockName[j];
+ }
+ sqlite3VdbeMultiLoad(v, 1, "ss", db->aDb[i].zDbSName, zState);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2);
+ }
+ break;
+ }
+#endif
+
+#ifdef SQLITE_HAS_CODEC
+ case PragTyp_KEY: {
+ if( zRight ) sqlite3_key_v2(db, zDb, zRight, sqlite3Strlen30(zRight));
+ break;
+ }
+ case PragTyp_REKEY: {
+ if( zRight ) sqlite3_rekey_v2(db, zDb, zRight, sqlite3Strlen30(zRight));
+ break;
+ }
+ case PragTyp_HEXKEY: {
+ if( zRight ){
+ u8 iByte;
+ int i;
+ char zKey[40];
+ for(i=0, iByte=0; i<sizeof(zKey)*2 && sqlite3Isxdigit(zRight[i]); i++){
+ iByte = (iByte<<4) + sqlite3HexToInt(zRight[i]);
+ if( (i&1)!=0 ) zKey[i/2] = iByte;
+ }
+ if( (zLeft[3] & 0xf)==0xb ){
+ sqlite3_key_v2(db, zDb, zKey, i/2);
+ }else{
+ sqlite3_rekey_v2(db, zDb, zKey, i/2);
+ }
+ }
+ break;
+ }
+#endif
+#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
+ case PragTyp_ACTIVATE_EXTENSIONS: if( zRight ){
+#ifdef SQLITE_HAS_CODEC
+ if( sqlite3StrNICmp(zRight, "see-", 4)==0 ){
+ sqlite3_activate_see(&zRight[4]);
+ }
+#endif
+#ifdef SQLITE_ENABLE_CEROD
+ if( sqlite3StrNICmp(zRight, "cerod-", 6)==0 ){
+ sqlite3_activate_cerod(&zRight[6]);
+ }
+#endif
+ }
+ break;
+#endif
+
+ } /* End of the PRAGMA switch */
+
+ /* The following block is a no-op unless SQLITE_DEBUG is defined. Its only
+ ** purpose is to execute assert() statements to verify that if the
+ ** PragFlg_NoColumns1 flag is set and the caller specified an argument
+ ** to the PRAGMA, the implementation has not added any OP_ResultRow
+ ** instructions to the VM. */
+ if( (pPragma->mPragFlg & PragFlg_NoColumns1) && zRight ){
+ sqlite3VdbeVerifyNoResultRow(v);
+ }
+
+pragma_out:
+ sqlite3DbFree(db, zLeft);
+ sqlite3DbFree(db, zRight);
+}
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+/*****************************************************************************
+** Implementation of an eponymous virtual table that runs a pragma.
+**
+*/
+typedef struct PragmaVtab PragmaVtab;
+typedef struct PragmaVtabCursor PragmaVtabCursor;
+struct PragmaVtab {
+ sqlite3_vtab base; /* Base class. Must be first */
+ sqlite3 *db; /* The database connection to which it belongs */
+ const PragmaName *pName; /* Name of the pragma */
+ u8 nHidden; /* Number of hidden columns */
+ u8 iHidden; /* Index of the first hidden column */
+};
+struct PragmaVtabCursor {
+ sqlite3_vtab_cursor base; /* Base class. Must be first */
+ sqlite3_stmt *pPragma; /* The pragma statement to run */
+ sqlite_int64 iRowid; /* Current rowid */
+ char *azArg[2]; /* Value of the argument and schema */
+};
+
+/*
+** Pragma virtual table module xConnect method.
+*/
+static int pragmaVtabConnect(
+ sqlite3 *db,
+ void *pAux,
+ int argc, const char *const*argv,
+ sqlite3_vtab **ppVtab,
+ char **pzErr
+){
+ const PragmaName *pPragma = (const PragmaName*)pAux;
+ PragmaVtab *pTab = 0;
+ int rc;
+ int i, j;
+ char cSep = '(';
+ StrAccum acc;
+ char zBuf[200];
+
+ UNUSED_PARAMETER(argc);
+ UNUSED_PARAMETER(argv);
+ sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
+ sqlite3StrAccumAppendAll(&acc, "CREATE TABLE x");
+ for(i=0, j=pPragma->iPragCName; i<pPragma->nPragCName; i++, j++){
+ sqlite3XPrintf(&acc, "%c\"%s\"", cSep, pragCName[j]);
+ cSep = ',';
+ }
+ if( i==0 ){
+ sqlite3XPrintf(&acc, "(\"%s\"", pPragma->zName);
+ cSep = ',';
+ i++;
+ }
+ j = 0;
+ if( pPragma->mPragFlg & PragFlg_Result1 ){
+ sqlite3StrAccumAppendAll(&acc, ",arg HIDDEN");
+ j++;
+ }
+ if( pPragma->mPragFlg & (PragFlg_SchemaOpt|PragFlg_SchemaReq) ){
+ sqlite3StrAccumAppendAll(&acc, ",schema HIDDEN");
+ j++;
+ }
+ sqlite3StrAccumAppend(&acc, ")", 1);
+ sqlite3StrAccumFinish(&acc);
+ assert( strlen(zBuf) < sizeof(zBuf)-1 );
+ rc = sqlite3_declare_vtab(db, zBuf);
+ if( rc==SQLITE_OK ){
+ pTab = (PragmaVtab*)sqlite3_malloc(sizeof(PragmaVtab));
+ if( pTab==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ memset(pTab, 0, sizeof(PragmaVtab));
+ pTab->pName = pPragma;
+ pTab->db = db;
+ pTab->iHidden = i;
+ pTab->nHidden = j;
+ }
+ }else{
+ *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
+ }
+
+ *ppVtab = (sqlite3_vtab*)pTab;
+ return rc;
+}
+
+/*
+** Pragma virtual table module xDisconnect method.
+*/
+static int pragmaVtabDisconnect(sqlite3_vtab *pVtab){
+ PragmaVtab *pTab = (PragmaVtab*)pVtab;
+ sqlite3_free(pTab);
+ return SQLITE_OK;
+}
+
+/* Figure out the best index to use to search a pragma virtual table.
+**
+** There are not really any index choices. But we want to encourage the
+** query planner to give == constraints on as many hidden parameters as
+** possible, and especially on the first hidden parameter. So return a
+** high cost if hidden parameters are unconstrained.
+*/
+static int pragmaVtabBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
+ PragmaVtab *pTab = (PragmaVtab*)tab;
+ const struct sqlite3_index_constraint *pConstraint;
+ int i, j;
+ int seen[2];
+
+ pIdxInfo->estimatedCost = (double)1;
+ if( pTab->nHidden==0 ){ return SQLITE_OK; }
+ pConstraint = pIdxInfo->aConstraint;
+ seen[0] = 0;
+ seen[1] = 0;
+ for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
+ if( pConstraint->usable==0 ) continue;
+ if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
+ if( pConstraint->iColumn < pTab->iHidden ) continue;
+ j = pConstraint->iColumn - pTab->iHidden;
+ assert( j < 2 );
+ seen[j] = i+1;
+ }
+ if( seen[0]==0 ){
+ pIdxInfo->estimatedCost = (double)2147483647;
+ pIdxInfo->estimatedRows = 2147483647;
+ return SQLITE_OK;
+ }
+ j = seen[0]-1;
+ pIdxInfo->aConstraintUsage[j].argvIndex = 1;
+ pIdxInfo->aConstraintUsage[j].omit = 1;
+ if( seen[1]==0 ) return SQLITE_OK;
+ pIdxInfo->estimatedCost = (double)20;
+ pIdxInfo->estimatedRows = 20;
+ j = seen[1]-1;
+ pIdxInfo->aConstraintUsage[j].argvIndex = 2;
+ pIdxInfo->aConstraintUsage[j].omit = 1;
+ return SQLITE_OK;
+}
+
+/* Create a new cursor for the pragma virtual table */
+static int pragmaVtabOpen(sqlite3_vtab *pVtab, sqlite3_vtab_cursor **ppCursor){
+ PragmaVtabCursor *pCsr;
+ pCsr = (PragmaVtabCursor*)sqlite3_malloc(sizeof(*pCsr));
+ if( pCsr==0 ) return SQLITE_NOMEM;
+ memset(pCsr, 0, sizeof(PragmaVtabCursor));
+ pCsr->base.pVtab = pVtab;
+ *ppCursor = &pCsr->base;
+ return SQLITE_OK;
+}
+
+/* Clear all content from pragma virtual table cursor. */
+static void pragmaVtabCursorClear(PragmaVtabCursor *pCsr){
+ int i;
+ sqlite3_finalize(pCsr->pPragma);
+ pCsr->pPragma = 0;
+ for(i=0; i<ArraySize(pCsr->azArg); i++){
+ sqlite3_free(pCsr->azArg[i]);
+ pCsr->azArg[i] = 0;
+ }
+}
+
+/* Close a pragma virtual table cursor */
+static int pragmaVtabClose(sqlite3_vtab_cursor *cur){
+ PragmaVtabCursor *pCsr = (PragmaVtabCursor*)cur;
+ pragmaVtabCursorClear(pCsr);
+ sqlite3_free(pCsr);
+ return SQLITE_OK;
+}
+
+/* Advance the pragma virtual table cursor to the next row */
+static int pragmaVtabNext(sqlite3_vtab_cursor *pVtabCursor){
+ PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
+ int rc = SQLITE_OK;
+
+ /* Increment the xRowid value */
+ pCsr->iRowid++;
+ assert( pCsr->pPragma );
+ if( SQLITE_ROW!=sqlite3_step(pCsr->pPragma) ){
+ rc = sqlite3_finalize(pCsr->pPragma);
+ pCsr->pPragma = 0;
+ pragmaVtabCursorClear(pCsr);
+ }
+ return rc;
+}
+
+/*
+** Pragma virtual table module xFilter method.
+*/
+static int pragmaVtabFilter(
+ sqlite3_vtab_cursor *pVtabCursor,
+ int idxNum, const char *idxStr,
+ int argc, sqlite3_value **argv
+){
+ PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
+ PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab);
+ int rc;
+ int i, j;
+ StrAccum acc;
+ char *zSql;
+
+ UNUSED_PARAMETER(idxNum);
+ UNUSED_PARAMETER(idxStr);
+ pragmaVtabCursorClear(pCsr);
+ j = (pTab->pName->mPragFlg & PragFlg_Result1)!=0 ? 0 : 1;
+ for(i=0; i<argc; i++, j++){
+ assert( j<ArraySize(pCsr->azArg) );
+ pCsr->azArg[j] = sqlite3_mprintf("%s", sqlite3_value_text(argv[i]));
+ if( pCsr->azArg[j]==0 ){
+ return SQLITE_NOMEM;
+ }
+ }
+ sqlite3StrAccumInit(&acc, 0, 0, 0, pTab->db->aLimit[SQLITE_LIMIT_SQL_LENGTH]);
+ sqlite3StrAccumAppendAll(&acc, "PRAGMA ");
+ if( pCsr->azArg[1] ){
+ sqlite3XPrintf(&acc, "%Q.", pCsr->azArg[1]);
+ }
+ sqlite3StrAccumAppendAll(&acc, pTab->pName->zName);
+ if( pCsr->azArg[0] ){
+ sqlite3XPrintf(&acc, "=%Q", pCsr->azArg[0]);
+ }
+ zSql = sqlite3StrAccumFinish(&acc);
+ if( zSql==0 ) return SQLITE_NOMEM;
+ rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pPragma, 0);
+ sqlite3_free(zSql);
+ if( rc!=SQLITE_OK ){
+ pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db));
+ return rc;
+ }
+ return pragmaVtabNext(pVtabCursor);
+}
+
+/*
+** Pragma virtual table module xEof method.
+*/
+static int pragmaVtabEof(sqlite3_vtab_cursor *pVtabCursor){
+ PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
+ return (pCsr->pPragma==0);
+}
+
+/* The xColumn method simply returns the corresponding column from
+** the PRAGMA.
+*/
+static int pragmaVtabColumn(
+ sqlite3_vtab_cursor *pVtabCursor,
+ sqlite3_context *ctx,
+ int i
+){
+ PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
+ PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab);
+ if( i<pTab->iHidden ){
+ sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pPragma, i));
+ }else{
+ sqlite3_result_text(ctx, pCsr->azArg[i-pTab->iHidden],-1,SQLITE_TRANSIENT);
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Pragma virtual table module xRowid method.
+*/
+static int pragmaVtabRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *p){
+ PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
+ *p = pCsr->iRowid;
+ return SQLITE_OK;
+}
+
+/* The pragma virtual table object */
+static const sqlite3_module pragmaVtabModule = {
+ 0, /* iVersion */
+ 0, /* xCreate - create a table */
+ pragmaVtabConnect, /* xConnect - connect to an existing table */
+ pragmaVtabBestIndex, /* xBestIndex - Determine search strategy */
+ pragmaVtabDisconnect, /* xDisconnect - Disconnect from a table */
+ 0, /* xDestroy - Drop a table */
+ pragmaVtabOpen, /* xOpen - open a cursor */
+ pragmaVtabClose, /* xClose - close a cursor */
+ pragmaVtabFilter, /* xFilter - configure scan constraints */
+ pragmaVtabNext, /* xNext - advance a cursor */
+ pragmaVtabEof, /* xEof */
+ pragmaVtabColumn, /* xColumn - read data */
+ pragmaVtabRowid, /* xRowid - read data */
+ 0, /* xUpdate - write data */
+ 0, /* xBegin - begin transaction */
+ 0, /* xSync - sync transaction */
+ 0, /* xCommit - commit transaction */
+ 0, /* xRollback - rollback transaction */
+ 0, /* xFindFunction - function overloading */
+ 0, /* xRename - rename the table */
+ 0, /* xSavepoint */
+ 0, /* xRelease */
+ 0 /* xRollbackTo */
+};
+
+/*
+** Check to see if zTabName is really the name of a pragma. If it is,
+** then register an eponymous virtual table for that pragma and return
+** a pointer to the Module object for the new virtual table.
+*/
+SQLITE_PRIVATE Module *sqlite3PragmaVtabRegister(sqlite3 *db, const char *zName){
+ const PragmaName *pName;
+ assert( sqlite3_strnicmp(zName, "pragma_", 7)==0 );
+ pName = pragmaLocate(zName+7);
+ if( pName==0 ) return 0;
+ if( (pName->mPragFlg & (PragFlg_Result0|PragFlg_Result1))==0 ) return 0;
+ assert( sqlite3HashFind(&db->aModule, zName)==0 );
+ return sqlite3VtabCreateModule(db, zName, &pragmaVtabModule, (void*)pName, 0);
+}
+
+#endif /* SQLITE_OMIT_VIRTUALTABLE */
+
+#endif /* SQLITE_OMIT_PRAGMA */
+
+/************** End of pragma.c **********************************************/
+/************** Begin file prepare.c *****************************************/
+/*
+** 2005 May 25
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains the implementation of the sqlite3_prepare()
+** interface, and routines that contribute to loading the database schema
+** from disk.
+*/
+/* #include "sqliteInt.h" */
+
+/*
+** Fill the InitData structure with an error message that indicates
+** that the database is corrupt.
+*/
+static void corruptSchema(
+ InitData *pData, /* Initialization context */
+ const char *zObj, /* Object being parsed at the point of error */
+ const char *zExtra /* Error information */
+){
+ sqlite3 *db = pData->db;
+ if( !db->mallocFailed && (db->flags & SQLITE_RecoveryMode)==0 ){
+ char *z;
+ if( zObj==0 ) zObj = "?";
+ z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj);
+ if( zExtra ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra);
+ sqlite3DbFree(db, *pData->pzErrMsg);
+ *pData->pzErrMsg = z;
+ }
+ pData->rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_CORRUPT_BKPT;
+}
+
+/*
+** This is the callback routine for the code that initializes the
+** database. See sqlite3Init() below for additional information.
+** This routine is also called from the OP_ParseSchema opcode of the VDBE.
+**
+** Each callback contains the following information:
+**
+** argv[0] = name of thing being created
+** argv[1] = root page number for table or index. 0 for trigger or view.
+** argv[2] = SQL text for the CREATE statement.
+**
+*/
+SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
+ InitData *pData = (InitData*)pInit;
+ sqlite3 *db = pData->db;
+ int iDb = pData->iDb;
+
+ assert( argc==3 );
+ UNUSED_PARAMETER2(NotUsed, argc);
+ assert( sqlite3_mutex_held(db->mutex) );
+ DbClearProperty(db, iDb, DB_Empty);
+ if( db->mallocFailed ){
+ corruptSchema(pData, argv[0], 0);
+ return 1;
+ }
+
+ assert( iDb>=0 && iDb<db->nDb );
+ if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */
+ if( argv[1]==0 ){
+ corruptSchema(pData, argv[0], 0);
+ }else if( sqlite3_strnicmp(argv[2],"create ",7)==0 ){
+ /* Call the parser to process a CREATE TABLE, INDEX or VIEW.
+ ** But because db->init.busy is set to 1, no VDBE code is generated
+ ** or executed. All the parser does is build the internal data
+ ** structures that describe the table, index, or view.
+ */
+ int rc;
+ u8 saved_iDb = db->init.iDb;
+ sqlite3_stmt *pStmt;
+ TESTONLY(int rcp); /* Return code from sqlite3_prepare() */
+
+ assert( db->init.busy );
+ db->init.iDb = iDb;
+ db->init.newTnum = sqlite3Atoi(argv[1]);
+ db->init.orphanTrigger = 0;
+ TESTONLY(rcp = ) sqlite3_prepare(db, argv[2], -1, &pStmt, 0);
+ rc = db->errCode;
+ assert( (rc&0xFF)==(rcp&0xFF) );
+ db->init.iDb = saved_iDb;
+ assert( saved_iDb==0 || (db->flags & SQLITE_Vacuum)!=0 );
+ if( SQLITE_OK!=rc ){
+ if( db->init.orphanTrigger ){
+ assert( iDb==1 );
+ }else{
+ pData->rc = rc;
+ if( rc==SQLITE_NOMEM ){
+ sqlite3OomFault(db);
+ }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){
+ corruptSchema(pData, argv[0], sqlite3_errmsg(db));
+ }
+ }
+ }
+ sqlite3_finalize(pStmt);
+ }else if( argv[0]==0 || (argv[2]!=0 && argv[2][0]!=0) ){
+ corruptSchema(pData, argv[0], 0);
+ }else{
+ /* If the SQL column is blank it means this is an index that
+ ** was created to be the PRIMARY KEY or to fulfill a UNIQUE
+ ** constraint for a CREATE TABLE. The index should have already
+ ** been created when we processed the CREATE TABLE. All we have
+ ** to do here is record the root page number for that index.
+ */
+ Index *pIndex;
+ pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zDbSName);
+ if( pIndex==0 ){
+ /* This can occur if there exists an index on a TEMP table which
+ ** has the same name as another index on a permanent index. Since
+ ** the permanent table is hidden by the TEMP table, we can also
+ ** safely ignore the index on the permanent table.
+ */
+ /* Do Nothing */;
+ }else if( sqlite3GetInt32(argv[1], &pIndex->tnum)==0 ){
+ corruptSchema(pData, argv[0], "invalid rootpage");
+ }
+ }
+ return 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 sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
+ int rc;
+ int i;
+#ifndef SQLITE_OMIT_DEPRECATED
+ int size;
+#endif
+ Db *pDb;
+ char const *azArg[4];
+ int meta[5];
+ InitData initData;
+ const char *zMasterName;
+ int openedTransaction = 0;
+
+ assert( iDb>=0 && iDb<db->nDb );
+ assert( db->aDb[iDb].pSchema );
+ assert( sqlite3_mutex_held(db->mutex) );
+ assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) );
+
+ /* Construct the in-memory representation schema tables (sqlite_master or
+ ** sqlite_temp_master) by invoking the parser directly. The appropriate
+ ** table name will be inserted automatically by the parser so we can just
+ ** use the abbreviation "x" here. The parser will also automatically tag
+ ** the schema table as read-only. */
+ azArg[0] = zMasterName = SCHEMA_TABLE(iDb);
+ azArg[1] = "1";
+ azArg[2] = "CREATE TABLE x(type text,name text,tbl_name text,"
+ "rootpage integer,sql text)";
+ azArg[3] = 0;
+ initData.db = db;
+ initData.iDb = iDb;
+ initData.rc = SQLITE_OK;
+ initData.pzErrMsg = pzErrMsg;
+ sqlite3InitCallback(&initData, 3, (char **)azArg, 0);
+ if( initData.rc ){
+ rc = initData.rc;
+ goto error_out;
+ }
+
+ /* Create a cursor to hold the database open
+ */
+ pDb = &db->aDb[iDb];
+ if( pDb->pBt==0 ){
+ if( !OMIT_TEMPDB && ALWAYS(iDb==1) ){
+ DbSetProperty(db, 1, DB_SchemaLoaded);
+ }
+ return SQLITE_OK;
+ }
+
+ /* If there is not already a read-only (or read-write) transaction opened
+ ** on the b-tree database, open one now. If a transaction is opened, it
+ ** will be closed before this function returns. */
+ sqlite3BtreeEnter(pDb->pBt);
+ if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){
+ rc = sqlite3BtreeBeginTrans(pDb->pBt, 0);
+ if( rc!=SQLITE_OK ){
+ sqlite3SetString(pzErrMsg, db, sqlite3ErrStr(rc));
+ goto initone_error_out;
+ }
+ openedTransaction = 1;
+ }
+
+ /* Get the database meta information.
+ **
+ ** Meta values are as follows:
+ ** meta[0] Schema cookie. Changes with each schema change.
+ ** meta[1] File format of schema layer.
+ ** meta[2] Size of the page cache.
+ ** meta[3] Largest rootpage (auto/incr_vacuum mode)
+ ** meta[4] Db text encoding. 1:UTF-8 2:UTF-16LE 3:UTF-16BE
+ ** meta[5] User version
+ ** meta[6] Incremental vacuum mode
+ ** meta[7] unused
+ ** meta[8] unused
+ ** meta[9] unused
+ **
+ ** Note: The #defined SQLITE_UTF* symbols in sqliteInt.h correspond to
+ ** the possible values of meta[4].
+ */
+ for(i=0; i<ArraySize(meta); i++){
+ sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]);
+ }
+ pDb->pSchema->schema_cookie = meta[BTREE_SCHEMA_VERSION-1];
+
+ /* If opening a non-empty database, check the text encoding. For the
+ ** main database, set sqlite3.enc to the encoding of the main database.
+ ** For an attached db, it is an error if the encoding is not the same
+ ** as sqlite3.enc.
+ */
+ if( meta[BTREE_TEXT_ENCODING-1] ){ /* text encoding */
+ if( iDb==0 ){
+#ifndef SQLITE_OMIT_UTF16
+ u8 encoding;
+ /* If opening the main database, set ENC(db). */
+ encoding = (u8)meta[BTREE_TEXT_ENCODING-1] & 3;
+ if( encoding==0 ) encoding = SQLITE_UTF8;
+ ENC(db) = encoding;
+#else
+ ENC(db) = SQLITE_UTF8;
+#endif
+ }else{
+ /* If opening an attached database, the encoding much match ENC(db) */
+ if( meta[BTREE_TEXT_ENCODING-1]!=ENC(db) ){
+ sqlite3SetString(pzErrMsg, db, "attached databases must use the same"
+ " text encoding as main database");
+ rc = SQLITE_ERROR;
+ goto initone_error_out;
+ }
+ }
+ }else{
+ DbSetProperty(db, iDb, DB_Empty);
+ }
+ pDb->pSchema->enc = ENC(db);
+
+ if( pDb->pSchema->cache_size==0 ){
+#ifndef SQLITE_OMIT_DEPRECATED
+ size = sqlite3AbsInt32(meta[BTREE_DEFAULT_CACHE_SIZE-1]);
+ if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; }
+ pDb->pSchema->cache_size = size;
+#else
+ pDb->pSchema->cache_size = SQLITE_DEFAULT_CACHE_SIZE;
+#endif
+ sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
+ }
+
+ /*
+ ** file_format==1 Version 3.0.0.
+ ** file_format==2 Version 3.1.3. // ALTER TABLE ADD COLUMN
+ ** file_format==3 Version 3.1.4. // ditto but with non-NULL defaults
+ ** file_format==4 Version 3.3.0. // DESC indices. Boolean constants
+ */
+ pDb->pSchema->file_format = (u8)meta[BTREE_FILE_FORMAT-1];
+ if( pDb->pSchema->file_format==0 ){
+ pDb->pSchema->file_format = 1;
+ }
+ if( pDb->pSchema->file_format>SQLITE_MAX_FILE_FORMAT ){
+ sqlite3SetString(pzErrMsg, db, "unsupported file format");
+ rc = SQLITE_ERROR;
+ goto initone_error_out;
+ }
+
+ /* Ticket #2804: When we open a database in the newer file format,
+ ** clear the legacy_file_format pragma flag so that a VACUUM will
+ ** not downgrade the database and thus invalidate any descending
+ ** indices that the user might have created.
+ */
+ if( iDb==0 && meta[BTREE_FILE_FORMAT-1]>=4 ){
+ db->flags &= ~SQLITE_LegacyFileFmt;
+ }
+
+ /* Read the schema information out of the schema tables
+ */
+ assert( db->init.busy );
+ {
+ char *zSql;
+ zSql = sqlite3MPrintf(db,
+ "SELECT name, rootpage, sql FROM \"%w\".%s ORDER BY rowid",
+ db->aDb[iDb].zDbSName, zMasterName);
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ {
+ sqlite3_xauth xAuth;
+ xAuth = db->xAuth;
+ db->xAuth = 0;
+#endif
+ rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ db->xAuth = xAuth;
+ }
+#endif
+ if( rc==SQLITE_OK ) rc = initData.rc;
+ sqlite3DbFree(db, zSql);
+#ifndef SQLITE_OMIT_ANALYZE
+ if( rc==SQLITE_OK ){
+ sqlite3AnalysisLoad(db, iDb);
+ }
+#endif
+ }
+ if( db->mallocFailed ){
+ rc = SQLITE_NOMEM_BKPT;
+ sqlite3ResetAllSchemasOfConnection(db);
+ }
+ if( rc==SQLITE_OK || (db->flags&SQLITE_RecoveryMode)){
+ /* Black magic: If the SQLITE_RecoveryMode flag is set, then consider
+ ** the schema loaded, even if errors occurred. In this situation the
+ ** current sqlite3_prepare() operation will fail, but the following one
+ ** will attempt to compile the supplied statement against whatever subset
+ ** of the schema was loaded before the error occurred. The primary
+ ** purpose of this is to allow access to the sqlite_master table
+ ** even when its contents have been corrupted.
+ */
+ DbSetProperty(db, iDb, DB_SchemaLoaded);
+ rc = SQLITE_OK;
+ }
+
+ /* Jump here for an error that occurs after successfully allocating
+ ** curMain and calling sqlite3BtreeEnter(). For an error that occurs
+ ** before that point, jump to error_out.
+ */
+initone_error_out:
+ if( openedTransaction ){
+ sqlite3BtreeCommit(pDb->pBt);
+ }
+ sqlite3BtreeLeave(pDb->pBt);
+
+error_out:
+ if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
+ sqlite3OomFault(db);
+ }
+ return 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 a database is initialized, the DB_SchemaLoaded bit is set
+** bit is set in the flags field of the Db structure. If the database
+** file was of zero-length, then the DB_Empty flag is also set.
+*/
+SQLITE_PRIVATE int sqlite3Init(sqlite3 *db, char **pzErrMsg){
+ int i, rc;
+ int commit_internal = !(db->flags&SQLITE_InternChanges);
+
+ assert( sqlite3_mutex_held(db->mutex) );
+ assert( sqlite3BtreeHoldsMutex(db->aDb[0].pBt) );
+ assert( db->init.busy==0 );
+ rc = SQLITE_OK;
+ db->init.busy = 1;
+ ENC(db) = SCHEMA_ENC(db);
+ for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
+ if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
+ rc = sqlite3InitOne(db, i, pzErrMsg);
+ if( rc ){
+ sqlite3ResetOneSchema(db, i);
+ }
+ }
+
+ /* Once all the other databases have been initialized, load the schema
+ ** for the TEMP database. This is loaded last, as the TEMP database
+ ** schema may contain references to objects in other databases.
+ */
+#ifndef SQLITE_OMIT_TEMPDB
+ assert( db->nDb>1 );
+ if( rc==SQLITE_OK && !DbHasProperty(db, 1, DB_SchemaLoaded) ){
+ rc = sqlite3InitOne(db, 1, pzErrMsg);
+ if( rc ){
+ sqlite3ResetOneSchema(db, 1);
+ }
+ }
+#endif
+
+ db->init.busy = 0;
+ if( rc==SQLITE_OK && commit_internal ){
+ sqlite3CommitInternalChanges(db);
+ }
+
+ return rc;
+}
+
+/*
+** This routine is a no-op if the database schema is already initialized.
+** Otherwise, the schema is loaded. An error code is returned.
+*/
+SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse){
+ int rc = SQLITE_OK;
+ sqlite3 *db = pParse->db;
+ assert( sqlite3_mutex_held(db->mutex) );
+ if( !db->init.busy ){
+ rc = sqlite3Init(db, &pParse->zErrMsg);
+ }
+ if( rc!=SQLITE_OK ){
+ pParse->rc = rc;
+ pParse->nErr++;
+ }
+ return rc;
+}
+
+
+/*
+** Check schema cookies in all databases. If any cookie is out
+** of date set pParse->rc to SQLITE_SCHEMA. If all schema cookies
+** make no changes to pParse->rc.
+*/
+static void schemaIsValid(Parse *pParse){
+ sqlite3 *db = pParse->db;
+ int iDb;
+ int rc;
+ int cookie;
+
+ assert( pParse->checkSchema );
+ assert( sqlite3_mutex_held(db->mutex) );
+ for(iDb=0; iDb<db->nDb; iDb++){
+ int openedTransaction = 0; /* True if a transaction is opened */
+ Btree *pBt = db->aDb[iDb].pBt; /* Btree database to read cookie from */
+ if( pBt==0 ) continue;
+
+ /* If there is not already a read-only (or read-write) transaction opened
+ ** on the b-tree database, open one now. If a transaction is opened, it
+ ** will be closed immediately after reading the meta-value. */
+ if( !sqlite3BtreeIsInReadTrans(pBt) ){
+ rc = sqlite3BtreeBeginTrans(pBt, 0);
+ if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
+ sqlite3OomFault(db);
+ }
+ if( rc!=SQLITE_OK ) return;
+ openedTransaction = 1;
+ }
+
+ /* Read the schema cookie from the database. If it does not match the
+ ** value stored as part of the in-memory schema representation,
+ ** set Parse.rc to SQLITE_SCHEMA. */
+ sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie);
+ assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+ if( cookie!=db->aDb[iDb].pSchema->schema_cookie ){
+ sqlite3ResetOneSchema(db, iDb);
+ pParse->rc = SQLITE_SCHEMA;
+ }
+
+ /* Close the transaction, if one was opened. */
+ if( openedTransaction ){
+ sqlite3BtreeCommit(pBt);
+ }
+ }
+}
+
+/*
+** Convert a schema pointer into the iDb index that indicates
+** which database file in db->aDb[] the schema refers to.
+**
+** If the same database is attached more than once, the first
+** attached database is returned.
+*/
+SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){
+ int i = -1000000;
+
+ /* If pSchema is NULL, then return -1000000. This happens when code in
+ ** expr.c is trying to resolve a reference to a transient table (i.e. one
+ ** created by a sub-select). In this case the return value of this
+ ** function should never be used.
+ **
+ ** We return -1000000 instead of the more usual -1 simply because using
+ ** -1000000 as the incorrect index into db->aDb[] is much
+ ** more likely to cause a segfault than -1 (of course there are assert()
+ ** statements too, but it never hurts to play the odds).
+ */
+ assert( sqlite3_mutex_held(db->mutex) );
+ if( pSchema ){
+ for(i=0; ALWAYS(i<db->nDb); i++){
+ if( db->aDb[i].pSchema==pSchema ){
+ break;
+ }
+ }
+ assert( i>=0 && i<db->nDb );
+ }
+ return i;
+}
+
+/*
+** Free all memory allocations in the pParse object
+*/
+SQLITE_PRIVATE void sqlite3ParserReset(Parse *pParse){
+ if( pParse ){
+ sqlite3 *db = pParse->db;
+ sqlite3DbFree(db, pParse->aLabel);
+ sqlite3ExprListDelete(db, pParse->pConstExpr);
+ if( db ){
+ assert( db->lookaside.bDisable >= pParse->disableLookaside );
+ db->lookaside.bDisable -= pParse->disableLookaside;
+ }
+ pParse->disableLookaside = 0;
+ }
+}
+
+/*
+** Compile the UTF-8 encoded SQL statement zSql into a statement handle.
+*/
+static int sqlite3Prepare(
+ sqlite3 *db, /* Database handle. */
+ const char *zSql, /* UTF-8 encoded SQL statement. */
+ int nBytes, /* Length of zSql in bytes. */
+ int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */
+ Vdbe *pReprepare, /* VM being reprepared */
+ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
+ const char **pzTail /* OUT: End of parsed string */
+){
+ char *zErrMsg = 0; /* Error message */
+ int rc = SQLITE_OK; /* Result code */
+ int i; /* Loop counter */
+ Parse sParse; /* Parsing context */
+
+ memset(&sParse, 0, PARSE_HDR_SZ);
+ memset(PARSE_TAIL(&sParse), 0, PARSE_TAIL_SZ);
+ sParse.pReprepare = pReprepare;
+ assert( ppStmt && *ppStmt==0 );
+ /* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */
+ assert( sqlite3_mutex_held(db->mutex) );
+
+ /* Check to verify that it is possible to get a read lock on all
+ ** database schemas. The inability to get a read lock indicates that
+ ** some other database connection is holding a write-lock, which in
+ ** turn means that the other connection has made uncommitted changes
+ ** to the schema.
+ **
+ ** Were we to proceed and prepare the statement against the uncommitted
+ ** schema changes and if those schema changes are subsequently rolled
+ ** back and different changes are made in their place, then when this
+ ** prepared statement goes to run the schema cookie would fail to detect
+ ** the schema change. Disaster would follow.
+ **
+ ** This thread is currently holding mutexes on all Btrees (because
+ ** of the sqlite3BtreeEnterAll() in sqlite3LockAndPrepare()) so it
+ ** is not possible for another thread to start a new schema change
+ ** while this routine is running. Hence, we do not need to hold
+ ** locks on the schema, we just need to make sure nobody else is
+ ** holding them.
+ **
+ ** Note that setting READ_UNCOMMITTED overrides most lock detection,
+ ** but it does *not* override schema lock detection, so this all still
+ ** works even if READ_UNCOMMITTED is set.
+ */
+ for(i=0; i<db->nDb; i++) {
+ Btree *pBt = db->aDb[i].pBt;
+ if( pBt ){
+ assert( sqlite3BtreeHoldsMutex(pBt) );
+ rc = sqlite3BtreeSchemaLocked(pBt);
+ if( rc ){
+ const char *zDb = db->aDb[i].zDbSName;
+ sqlite3ErrorWithMsg(db, rc, "database schema is locked: %s", zDb);
+ testcase( db->flags & SQLITE_ReadUncommitted );
+ goto end_prepare;
+ }
+ }
+ }
+
+ sqlite3VtabUnlockList(db);
+
+ sParse.db = db;
+ if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){
+ char *zSqlCopy;
+ int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
+ testcase( nBytes==mxLen );
+ testcase( nBytes==mxLen+1 );
+ if( nBytes>mxLen ){
+ sqlite3ErrorWithMsg(db, SQLITE_TOOBIG, "statement too long");
+ rc = sqlite3ApiExit(db, SQLITE_TOOBIG);
+ goto end_prepare;
+ }
+ zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes);
+ if( zSqlCopy ){
+ sqlite3RunParser(&sParse, zSqlCopy, &zErrMsg);
+ sParse.zTail = &zSql[sParse.zTail-zSqlCopy];
+ sqlite3DbFree(db, zSqlCopy);
+ }else{
+ sParse.zTail = &zSql[nBytes];
+ }
+ }else{
+ sqlite3RunParser(&sParse, zSql, &zErrMsg);
+ }
+ assert( 0==sParse.nQueryLoop );
+
+ if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
+ if( sParse.checkSchema ){
+ schemaIsValid(&sParse);
+ }
+ if( db->mallocFailed ){
+ sParse.rc = SQLITE_NOMEM_BKPT;
+ }
+ if( pzTail ){
+ *pzTail = sParse.zTail;
+ }
+ rc = sParse.rc;
+
+#ifndef SQLITE_OMIT_EXPLAIN
+ if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
+ static const char * const azColName[] = {
+ "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
+ "selectid", "order", "from", "detail"
+ };
+ int iFirst, mx;
+ if( sParse.explain==2 ){
+ sqlite3VdbeSetNumCols(sParse.pVdbe, 4);
+ iFirst = 8;
+ mx = 12;
+ }else{
+ sqlite3VdbeSetNumCols(sParse.pVdbe, 8);
+ iFirst = 0;
+ mx = 8;
+ }
+ for(i=iFirst; i<mx; i++){
+ sqlite3VdbeSetColName(sParse.pVdbe, i-iFirst, COLNAME_NAME,
+ azColName[i], SQLITE_STATIC);
+ }
+ }
+#endif
+
+ if( db->init.busy==0 ){
+ Vdbe *pVdbe = sParse.pVdbe;
+ sqlite3VdbeSetSql(pVdbe, zSql, (int)(sParse.zTail-zSql), saveSqlFlag);
+ }
+ if( sParse.pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){
+ sqlite3VdbeFinalize(sParse.pVdbe);
+ assert(!(*ppStmt));
+ }else{
+ *ppStmt = (sqlite3_stmt*)sParse.pVdbe;
+ }
+
+ if( zErrMsg ){
+ sqlite3ErrorWithMsg(db, rc, "%s", zErrMsg);
+ sqlite3DbFree(db, zErrMsg);
+ }else{
+ sqlite3Error(db, rc);
+ }
+
+ /* Delete any TriggerPrg structures allocated while parsing this statement. */
+ while( sParse.pTriggerPrg ){
+ TriggerPrg *pT = sParse.pTriggerPrg;
+ sParse.pTriggerPrg = pT->pNext;
+ sqlite3DbFree(db, pT);
+ }
+
+end_prepare:
+
+ sqlite3ParserReset(&sParse);
+ rc = sqlite3ApiExit(db, rc);
+ assert( (rc&db->errMask)==rc );
+ return rc;
+}
+static int sqlite3LockAndPrepare(
+ sqlite3 *db, /* Database handle. */
+ const char *zSql, /* UTF-8 encoded SQL statement. */
+ int nBytes, /* Length of zSql in bytes. */
+ int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */
+ Vdbe *pOld, /* VM being reprepared */
+ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
+ const char **pzTail /* OUT: End of parsed string */
+){
+ int rc;
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( ppStmt==0 ) return SQLITE_MISUSE_BKPT;
+#endif
+ *ppStmt = 0;
+ if( !sqlite3SafetyCheckOk(db)||zSql==0 ){
+ return SQLITE_MISUSE_BKPT;
+ }
+ sqlite3_mutex_enter(db->mutex);
+ sqlite3BtreeEnterAll(db);
+ rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail);
+ if( rc==SQLITE_SCHEMA ){
+ sqlite3_finalize(*ppStmt);
+ rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail);
+ }
+ sqlite3BtreeLeaveAll(db);
+ sqlite3_mutex_leave(db->mutex);
+ assert( rc==SQLITE_OK || *ppStmt==0 );
+ return rc;
+}
+
+/*
+** Rerun the compilation of a statement after a schema change.
+**
+** If the statement is successfully recompiled, return SQLITE_OK. Otherwise,
+** if the statement cannot be recompiled because another connection has
+** locked the sqlite3_master table, return SQLITE_LOCKED. If any other error
+** occurs, return SQLITE_SCHEMA.
+*/
+SQLITE_PRIVATE int sqlite3Reprepare(Vdbe *p){
+ int rc;
+ sqlite3_stmt *pNew;
+ const char *zSql;
+ sqlite3 *db;
+
+ assert( sqlite3_mutex_held(sqlite3VdbeDb(p)->mutex) );
+ zSql = sqlite3_sql((sqlite3_stmt *)p);
+ assert( zSql!=0 ); /* Reprepare only called for prepare_v2() statements */
+ db = sqlite3VdbeDb(p);
+ assert( sqlite3_mutex_held(db->mutex) );
+ rc = sqlite3LockAndPrepare(db, zSql, -1, 0, p, &pNew, 0);
+ if( rc ){
+ if( rc==SQLITE_NOMEM ){
+ sqlite3OomFault(db);
+ }
+ assert( pNew==0 );
+ return rc;
+ }else{
+ assert( pNew!=0 );
+ }
+ sqlite3VdbeSwap((Vdbe*)pNew, p);
+ sqlite3TransferBindings(pNew, (sqlite3_stmt*)p);
+ sqlite3VdbeResetStepResult((Vdbe*)pNew);
+ sqlite3VdbeFinalize((Vdbe*)pNew);
+ return SQLITE_OK;
+}
+
+
+/*
+** Two versions of the official API. Legacy and new use. In the legacy
+** version, the original SQL text is not saved in the prepared statement
+** and so if a schema change occurs, SQLITE_SCHEMA is returned by
+** sqlite3_step(). In the new version, the original SQL text is retained
+** and the statement is automatically recompiled if an schema change
+** occurs.
+*/
+SQLITE_API int sqlite3_prepare(
+ sqlite3 *db, /* Database handle. */
+ const char *zSql, /* UTF-8 encoded SQL statement. */
+ int nBytes, /* Length of zSql in bytes. */
+ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
+ const char **pzTail /* OUT: End of parsed string */
+){
+ int rc;
+ rc = sqlite3LockAndPrepare(db,zSql,nBytes,0,0,ppStmt,pzTail);
+ assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
+ return rc;
+}
+SQLITE_API int sqlite3_prepare_v2(
+ sqlite3 *db, /* Database handle. */
+ const char *zSql, /* UTF-8 encoded SQL statement. */
+ int nBytes, /* Length of zSql in bytes. */
+ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
+ const char **pzTail /* OUT: End of parsed string */
+){
+ int rc;
+ rc = sqlite3LockAndPrepare(db,zSql,nBytes,1,0,ppStmt,pzTail);
+ assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
+ return rc;
+}
+
+
+#ifndef SQLITE_OMIT_UTF16
+/*
+** Compile the UTF-16 encoded SQL statement zSql into a statement handle.
+*/
+static int sqlite3Prepare16(
+ sqlite3 *db, /* Database handle. */
+ const void *zSql, /* UTF-16 encoded SQL statement. */
+ int nBytes, /* Length of zSql in bytes. */
+ int saveSqlFlag, /* True to save SQL text into the sqlite3_stmt */
+ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
+ const void **pzTail /* OUT: End of parsed string */
+){
+ /* This function currently works by first transforming the UTF-16
+ ** encoded string to UTF-8, then invoking sqlite3_prepare(). The
+ ** tricky bit is figuring out the pointer to return in *pzTail.
+ */
+ char *zSql8;
+ const char *zTail8 = 0;
+ int rc = SQLITE_OK;
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( ppStmt==0 ) return SQLITE_MISUSE_BKPT;
+#endif
+ *ppStmt = 0;
+ if( !sqlite3SafetyCheckOk(db)||zSql==0 ){
+ return SQLITE_MISUSE_BKPT;
+ }
+ if( nBytes>=0 ){
+ int sz;
+ const char *z = (const char*)zSql;
+ for(sz=0; sz<nBytes && (z[sz]!=0 || z[sz+1]!=0); sz += 2){}
+ nBytes = sz;
+ }
+ sqlite3_mutex_enter(db->mutex);
+ zSql8 = sqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE);
+ if( zSql8 ){
+ rc = sqlite3LockAndPrepare(db, zSql8, -1, saveSqlFlag, 0, ppStmt, &zTail8);
+ }
+
+ if( zTail8 && pzTail ){
+ /* If sqlite3_prepare returns a tail pointer, we calculate the
+ ** equivalent pointer into the UTF-16 string by counting the unicode
+ ** characters between zSql8 and zTail8, and then returning a pointer
+ ** the same number of characters into the UTF-16 string.
+ */
+ int chars_parsed = sqlite3Utf8CharLen(zSql8, (int)(zTail8-zSql8));
+ *pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, chars_parsed);
+ }
+ sqlite3DbFree(db, zSql8);
+ rc = sqlite3ApiExit(db, rc);
+ sqlite3_mutex_leave(db->mutex);
+ return rc;
+}
+
+/*
+** Two versions of the official API. Legacy and new use. In the legacy
+** version, the original SQL text is not saved in the prepared statement
+** and so if a schema change occurs, SQLITE_SCHEMA is returned by
+** sqlite3_step(). In the new version, the original SQL text is retained
+** and the statement is automatically recompiled if an schema change
+** occurs.
+*/
+SQLITE_API int sqlite3_prepare16(
+ sqlite3 *db, /* Database handle. */
+ const void *zSql, /* UTF-16 encoded SQL statement. */
+ int nBytes, /* Length of zSql in bytes. */
+ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
+ const void **pzTail /* OUT: End of parsed string */
+){
+ int rc;
+ rc = sqlite3Prepare16(db,zSql,nBytes,0,ppStmt,pzTail);
+ assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
+ return rc;
+}
+SQLITE_API int sqlite3_prepare16_v2(
+ sqlite3 *db, /* Database handle. */
+ const void *zSql, /* UTF-16 encoded SQL statement. */
+ int nBytes, /* Length of zSql in bytes. */
+ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
+ const void **pzTail /* OUT: End of parsed string */
+){
+ int rc;
+ rc = sqlite3Prepare16(db,zSql,nBytes,1,ppStmt,pzTail);
+ assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
+ return rc;
+}
+
+#endif /* SQLITE_OMIT_UTF16 */
+
+/************** End of prepare.c *********************************************/
+/************** Begin file select.c ******************************************/
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains C code routines that are called by the parser
+** to handle SELECT statements in SQLite.
+*/
+/* #include "sqliteInt.h" */
+
+/*
+** Trace output macros
+*/
+#if SELECTTRACE_ENABLED
+/***/ int sqlite3SelectTrace = 0;
+# define SELECTTRACE(K,P,S,X) \
+ if(sqlite3SelectTrace&(K)) \
+ sqlite3DebugPrintf("%*s%s.%p: ",(P)->nSelectIndent*2-2,"",\
+ (S)->zSelName,(S)),\
+ sqlite3DebugPrintf X
+#else
+# define SELECTTRACE(K,P,S,X)
+#endif
+
+
+/*
+** An instance of the following object is used to record information about
+** how to process the DISTINCT keyword, to simplify passing that information
+** into the selectInnerLoop() routine.
+*/
+typedef struct DistinctCtx DistinctCtx;
+struct DistinctCtx {
+ u8 isTnct; /* True if the DISTINCT keyword is present */
+ u8 eTnctType; /* One of the WHERE_DISTINCT_* operators */
+ int tabTnct; /* Ephemeral table used for DISTINCT processing */
+ int addrTnct; /* Address of OP_OpenEphemeral opcode for tabTnct */
+};
+
+/*
+** An instance of the following object is used to record information about
+** the ORDER BY (or GROUP BY) clause of query is being coded.
+*/
+typedef struct SortCtx SortCtx;
+struct SortCtx {
+ ExprList *pOrderBy; /* The ORDER BY (or GROUP BY clause) */
+ int nOBSat; /* Number of ORDER BY terms satisfied by indices */
+ int iECursor; /* Cursor number for the sorter */
+ int regReturn; /* Register holding block-output return address */
+ int labelBkOut; /* Start label for the block-output subroutine */
+ int addrSortIndex; /* Address of the OP_SorterOpen or OP_OpenEphemeral */
+ int labelDone; /* Jump here when done, ex: LIMIT reached */
+ u8 sortFlags; /* Zero or more SORTFLAG_* bits */
+ u8 bOrderedInnerLoop; /* ORDER BY correctly sorts the inner loop */
+};
+#define SORTFLAG_UseSorter 0x01 /* Use SorterOpen instead of OpenEphemeral */
+
+/*
+** Delete all the content of a Select structure. Deallocate the structure
+** itself only if bFree is true.
+*/
+static void clearSelect(sqlite3 *db, Select *p, int bFree){
+ while( p ){
+ Select *pPrior = p->pPrior;
+ sqlite3ExprListDelete(db, p->pEList);
+ sqlite3SrcListDelete(db, p->pSrc);
+ sqlite3ExprDelete(db, p->pWhere);
+ sqlite3ExprListDelete(db, p->pGroupBy);
+ sqlite3ExprDelete(db, p->pHaving);
+ sqlite3ExprListDelete(db, p->pOrderBy);
+ sqlite3ExprDelete(db, p->pLimit);
+ sqlite3ExprDelete(db, p->pOffset);
+ if( p->pWith ) sqlite3WithDelete(db, p->pWith);
+ if( bFree ) sqlite3DbFree(db, p);
+ p = pPrior;
+ bFree = 1;
+ }
+}
+
+/*
+** Initialize a SelectDest structure.
+*/
+SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iParm){
+ pDest->eDest = (u8)eDest;
+ pDest->iSDParm = iParm;
+ pDest->zAffSdst = 0;
+ pDest->iSdst = 0;
+ pDest->nSdst = 0;
+}
+
+
+/*
+** Allocate a new Select structure and return a pointer to that
+** structure.
+*/
+SQLITE_PRIVATE Select *sqlite3SelectNew(
+ Parse *pParse, /* Parsing context */
+ ExprList *pEList, /* which columns to include in the result */
+ SrcList *pSrc, /* the FROM clause -- which tables to scan */
+ Expr *pWhere, /* the WHERE clause */
+ ExprList *pGroupBy, /* the GROUP BY clause */
+ Expr *pHaving, /* the HAVING clause */
+ ExprList *pOrderBy, /* the ORDER BY clause */
+ u32 selFlags, /* Flag parameters, such as SF_Distinct */
+ Expr *pLimit, /* LIMIT value. NULL means not used */
+ Expr *pOffset /* OFFSET value. NULL means no offset */
+){
+ Select *pNew;
+ Select standin;
+ sqlite3 *db = pParse->db;
+ pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) );
+ if( pNew==0 ){
+ assert( db->mallocFailed );
+ pNew = &standin;
+ }
+ if( pEList==0 ){
+ pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ASTERISK,0));
+ }
+ pNew->pEList = pEList;
+ pNew->op = TK_SELECT;
+ pNew->selFlags = selFlags;
+ pNew->iLimit = 0;
+ pNew->iOffset = 0;
+#if SELECTTRACE_ENABLED
+ pNew->zSelName[0] = 0;
+#endif
+ pNew->addrOpenEphm[0] = -1;
+ pNew->addrOpenEphm[1] = -1;
+ pNew->nSelectRow = 0;
+ if( pSrc==0 ) pSrc = sqlite3DbMallocZero(db, sizeof(*pSrc));
+ pNew->pSrc = pSrc;
+ pNew->pWhere = pWhere;
+ pNew->pGroupBy = pGroupBy;
+ pNew->pHaving = pHaving;
+ pNew->pOrderBy = pOrderBy;
+ pNew->pPrior = 0;
+ pNew->pNext = 0;
+ pNew->pLimit = pLimit;
+ pNew->pOffset = pOffset;
+ pNew->pWith = 0;
+ assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || db->mallocFailed!=0 );
+ if( db->mallocFailed ) {
+ clearSelect(db, pNew, pNew!=&standin);
+ pNew = 0;
+ }else{
+ assert( pNew->pSrc!=0 || pParse->nErr>0 );
+ }
+ assert( pNew!=&standin );
+ return pNew;
+}
+
+#if SELECTTRACE_ENABLED
+/*
+** Set the name of a Select object
+*/
+SQLITE_PRIVATE void sqlite3SelectSetName(Select *p, const char *zName){
+ if( p && zName ){
+ sqlite3_snprintf(sizeof(p->zSelName), p->zSelName, "%s", zName);
+ }
+}
+#endif
+
+
+/*
+** Delete the given Select structure and all of its substructures.
+*/
+SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){
+ if( p ) clearSelect(db, p, 1);
+}
+
+/*
+** Return a pointer to the right-most SELECT statement in a compound.
+*/
+static Select *findRightmost(Select *p){
+ while( p->pNext ) p = p->pNext;
+ return p;
+}
+
+/*
+** Given 1 to 3 identifiers preceding the JOIN keyword, determine the
+** type of join. Return an integer constant that expresses that type
+** in terms of the following bit values:
+**
+** JT_INNER
+** JT_CROSS
+** JT_OUTER
+** JT_NATURAL
+** JT_LEFT
+** JT_RIGHT
+**
+** A full outer join is the combination of JT_LEFT and JT_RIGHT.
+**
+** If an illegal or unsupported join type is seen, then still return
+** a join type, but put an error in the pParse structure.
+*/
+SQLITE_PRIVATE int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){
+ int jointype = 0;
+ Token *apAll[3];
+ Token *p;
+ /* 0123456789 123456789 123456789 123 */
+ static const char zKeyText[] = "naturaleftouterightfullinnercross";
+ static const struct {
+ u8 i; /* Beginning of keyword text in zKeyText[] */
+ u8 nChar; /* Length of the keyword in characters */
+ u8 code; /* Join type mask */
+ } aKeyword[] = {
+ /* natural */ { 0, 7, JT_NATURAL },
+ /* left */ { 6, 4, JT_LEFT|JT_OUTER },
+ /* outer */ { 10, 5, JT_OUTER },
+ /* right */ { 14, 5, JT_RIGHT|JT_OUTER },
+ /* full */ { 19, 4, JT_LEFT|JT_RIGHT|JT_OUTER },
+ /* inner */ { 23, 5, JT_INNER },
+ /* cross */ { 28, 5, JT_INNER|JT_CROSS },
+ };
+ int i, j;
+ apAll[0] = pA;
+ apAll[1] = pB;
+ apAll[2] = pC;
+ for(i=0; i<3 && apAll[i]; i++){
+ p = apAll[i];
+ for(j=0; j<ArraySize(aKeyword); j++){
+ if( p->n==aKeyword[j].nChar
+ && sqlite3StrNICmp((char*)p->z, &zKeyText[aKeyword[j].i], p->n)==0 ){
+ jointype |= aKeyword[j].code;
+ break;
+ }
+ }
+ testcase( j==0 || j==1 || j==2 || j==3 || j==4 || j==5 || j==6 );
+ if( j>=ArraySize(aKeyword) ){
+ jointype |= JT_ERROR;
+ break;
+ }
+ }
+ if(
+ (jointype & (JT_INNER|JT_OUTER))==(JT_INNER|JT_OUTER) ||
+ (jointype & JT_ERROR)!=0
+ ){
+ const char *zSp = " ";
+ assert( pB!=0 );
+ if( pC==0 ){ zSp++; }
+ sqlite3ErrorMsg(pParse, "unknown or unsupported join type: "
+ "%T %T%s%T", pA, pB, zSp, pC);
+ jointype = JT_INNER;
+ }else if( (jointype & JT_OUTER)!=0
+ && (jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ){
+ sqlite3ErrorMsg(pParse,
+ "RIGHT and FULL OUTER JOINs are not currently supported");
+ jointype = JT_INNER;
+ }
+ return jointype;
+}
+
+/*
+** Return the index of a column in a table. Return -1 if the column
+** is not contained in the table.
+*/
+static int columnIndex(Table *pTab, const char *zCol){
+ int i;
+ for(i=0; i<pTab->nCol; i++){
+ if( sqlite3StrICmp(pTab->aCol[i].zName, zCol)==0 ) return i;
+ }
+ return -1;
+}
+
+/*
+** Search the first N tables in pSrc, from left to right, looking for a
+** table that has a column named zCol.
+**
+** When found, set *piTab and *piCol to the table index and column index
+** of the matching column and return TRUE.
+**
+** If not found, return FALSE.
+*/
+static int tableAndColumnIndex(
+ SrcList *pSrc, /* Array of tables to search */
+ int N, /* Number of tables in pSrc->a[] to search */
+ const char *zCol, /* Name of the column we are looking for */
+ int *piTab, /* Write index of pSrc->a[] here */
+ int *piCol /* Write index of pSrc->a[*piTab].pTab->aCol[] here */
+){
+ int i; /* For looping over tables in pSrc */
+ int iCol; /* Index of column matching zCol */
+
+ assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */
+ for(i=0; i<N; i++){
+ iCol = columnIndex(pSrc->a[i].pTab, zCol);
+ if( iCol>=0 ){
+ if( piTab ){
+ *piTab = i;
+ *piCol = iCol;
+ }
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/*
+** This function is used to add terms implied by JOIN syntax to the
+** WHERE clause expression of a SELECT statement. The new term, which
+** is ANDed with the existing WHERE clause, is of the form:
+**
+** (tab1.col1 = tab2.col2)
+**
+** where tab1 is the iSrc'th table in SrcList pSrc and tab2 is the
+** (iSrc+1)'th. Column col1 is column iColLeft of tab1, and col2 is
+** column iColRight of tab2.
+*/
+static void addWhereTerm(
+ Parse *pParse, /* Parsing context */
+ SrcList *pSrc, /* List of tables in FROM clause */
+ int iLeft, /* Index of first table to join in pSrc */
+ int iColLeft, /* Index of column in first table */
+ int iRight, /* Index of second table in pSrc */
+ int iColRight, /* Index of column in second table */
+ int isOuterJoin, /* True if this is an OUTER join */
+ Expr **ppWhere /* IN/OUT: The WHERE clause to add to */
+){
+ sqlite3 *db = pParse->db;
+ Expr *pE1;
+ Expr *pE2;
+ Expr *pEq;
+
+ assert( iLeft<iRight );
+ assert( pSrc->nSrc>iRight );
+ assert( pSrc->a[iLeft].pTab );
+ assert( pSrc->a[iRight].pTab );
+
+ pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iColLeft);
+ pE2 = sqlite3CreateColumnExpr(db, pSrc, iRight, iColRight);
+
+ pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2);
+ if( pEq && isOuterJoin ){
+ ExprSetProperty(pEq, EP_FromJoin);
+ assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) );
+ ExprSetVVAProperty(pEq, EP_NoReduce);
+ pEq->iRightJoinTable = (i16)pE2->iTable;
+ }
+ *ppWhere = sqlite3ExprAnd(db, *ppWhere, pEq);
+}
+
+/*
+** Set the EP_FromJoin property on all terms of the given expression.
+** And set the Expr.iRightJoinTable to iTable for every term in the
+** expression.
+**
+** The EP_FromJoin property is used on terms of an expression to tell
+** the LEFT OUTER JOIN processing logic that this term is part of the
+** join restriction specified in the ON or USING clause and not a part
+** of the more general WHERE clause. These terms are moved over to the
+** WHERE clause during join processing but we need to remember that they
+** originated in the ON or USING clause.
+**
+** The Expr.iRightJoinTable tells the WHERE clause processing that the
+** expression depends on table iRightJoinTable even if that table is not
+** explicitly mentioned in the expression. That information is needed
+** for cases like this:
+**
+** SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.b AND t1.x=5
+**
+** The where clause needs to defer the handling of the t1.x=5
+** term until after the t2 loop of the join. In that way, a
+** NULL t2 row will be inserted whenever t1.x!=5. If we do not
+** defer the handling of t1.x=5, it will be processed immediately
+** after the t1 loop and rows with t1.x!=5 will never appear in
+** the output, which is incorrect.
+*/
+static void setJoinExpr(Expr *p, int iTable){
+ while( p ){
+ ExprSetProperty(p, EP_FromJoin);
+ assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
+ ExprSetVVAProperty(p, EP_NoReduce);
+ p->iRightJoinTable = (i16)iTable;
+ if( p->op==TK_FUNCTION && p->x.pList ){
+ int i;
+ for(i=0; i<p->x.pList->nExpr; i++){
+ setJoinExpr(p->x.pList->a[i].pExpr, iTable);
+ }
+ }
+ setJoinExpr(p->pLeft, iTable);
+ p = p->pRight;
+ }
+}
+
+/*
+** This routine processes the join information for a SELECT statement.
+** ON and USING clauses are converted into extra terms of the WHERE clause.
+** NATURAL joins also create extra WHERE clause terms.
+**
+** The terms of a FROM clause are contained in the Select.pSrc structure.
+** The left most table is the first entry in Select.pSrc. The right-most
+** table is the last entry. The join operator is held in the entry to
+** the left. Thus entry 0 contains the join operator for the join between
+** entries 0 and 1. Any ON or USING clauses associated with the join are
+** also attached to the left entry.
+**
+** This routine returns the number of errors encountered.
+*/
+static int sqliteProcessJoin(Parse *pParse, Select *p){
+ SrcList *pSrc; /* All tables in the FROM clause */
+ int i, j; /* Loop counters */
+ struct SrcList_item *pLeft; /* Left table being joined */
+ struct SrcList_item *pRight; /* Right table being joined */
+
+ pSrc = p->pSrc;
+ pLeft = &pSrc->a[0];
+ pRight = &pLeft[1];
+ for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){
+ Table *pLeftTab = pLeft->pTab;
+ Table *pRightTab = pRight->pTab;
+ int isOuter;
+
+ if( NEVER(pLeftTab==0 || pRightTab==0) ) continue;
+ isOuter = (pRight->fg.jointype & JT_OUTER)!=0;
+
+ /* When the NATURAL keyword is present, add WHERE clause terms for
+ ** every column that the two tables have in common.
+ */
+ if( pRight->fg.jointype & JT_NATURAL ){
+ if( pRight->pOn || pRight->pUsing ){
+ sqlite3ErrorMsg(pParse, "a NATURAL join may not have "
+ "an ON or USING clause", 0);
+ return 1;
+ }
+ for(j=0; j<pRightTab->nCol; j++){
+ char *zName; /* Name of column in the right table */
+ int iLeft; /* Matching left table */
+ int iLeftCol; /* Matching column in the left table */
+
+ zName = pRightTab->aCol[j].zName;
+ if( tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol) ){
+ addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, j,
+ isOuter, &p->pWhere);
+ }
+ }
+ }
+
+ /* Disallow both ON and USING clauses in the same join
+ */
+ if( pRight->pOn && pRight->pUsing ){
+ sqlite3ErrorMsg(pParse, "cannot have both ON and USING "
+ "clauses in the same join");
+ return 1;
+ }
+
+ /* Add the ON clause to the end of the WHERE clause, connected by
+ ** an AND operator.
+ */
+ if( pRight->pOn ){
+ if( isOuter ) setJoinExpr(pRight->pOn, pRight->iCursor);
+ p->pWhere = sqlite3ExprAnd(pParse->db, p->pWhere, pRight->pOn);
+ pRight->pOn = 0;
+ }
+
+ /* Create extra terms on the WHERE clause for each column named
+ ** in the USING clause. Example: If the two tables to be joined are
+ ** A and B and the USING clause names X, Y, and Z, then add this
+ ** to the WHERE clause: A.X=B.X AND A.Y=B.Y AND A.Z=B.Z
+ ** Report an error if any column mentioned in the USING clause is
+ ** not contained in both tables to be joined.
+ */
+ if( pRight->pUsing ){
+ IdList *pList = pRight->pUsing;
+ for(j=0; j<pList->nId; j++){
+ char *zName; /* Name of the term in the USING clause */
+ int iLeft; /* Table on the left with matching column name */
+ int iLeftCol; /* Column number of matching column on the left */
+ int iRightCol; /* Column number of matching column on the right */
+
+ zName = pList->a[j].zName;
+ iRightCol = columnIndex(pRightTab, zName);
+ if( iRightCol<0
+ || !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol)
+ ){
+ sqlite3ErrorMsg(pParse, "cannot join using column %s - column "
+ "not present in both tables", zName);
+ return 1;
+ }
+ addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, iRightCol,
+ isOuter, &p->pWhere);
+ }
+ }
+ }
+ return 0;
+}
+
+/* Forward reference */
+static KeyInfo *keyInfoFromExprList(
+ Parse *pParse, /* Parsing context */
+ ExprList *pList, /* Form the KeyInfo object from this ExprList */
+ int iStart, /* Begin with this column of pList */
+ int nExtra /* Add this many extra columns to the end */
+);
+
+/*
+** Generate code that will push the record in registers regData
+** through regData+nData-1 onto the sorter.
+*/
+static void pushOntoSorter(
+ Parse *pParse, /* Parser context */
+ SortCtx *pSort, /* Information about the ORDER BY clause */
+ Select *pSelect, /* The whole SELECT statement */
+ int regData, /* First register holding data to be sorted */
+ int regOrigData, /* First register holding data before packing */
+ int nData, /* Number of elements in the data array */
+ int nPrefixReg /* No. of reg prior to regData available for use */
+){
+ Vdbe *v = pParse->pVdbe; /* Stmt under construction */
+ int bSeq = ((pSort->sortFlags & SORTFLAG_UseSorter)==0);
+ int nExpr = pSort->pOrderBy->nExpr; /* No. of ORDER BY terms */
+ int nBase = nExpr + bSeq + nData; /* Fields in sorter record */
+ int regBase; /* Regs for sorter record */
+ int regRecord = ++pParse->nMem; /* Assembled sorter record */
+ int nOBSat = pSort->nOBSat; /* ORDER BY terms to skip */
+ int op; /* Opcode to add sorter record to sorter */
+ int iLimit; /* LIMIT counter */
+
+ assert( bSeq==0 || bSeq==1 );
+ assert( nData==1 || regData==regOrigData || regOrigData==0 );
+ if( nPrefixReg ){
+ assert( nPrefixReg==nExpr+bSeq );
+ regBase = regData - nExpr - bSeq;
+ }else{
+ regBase = pParse->nMem + 1;
+ pParse->nMem += nBase;
+ }
+ assert( pSelect->iOffset==0 || pSelect->iLimit!=0 );
+ iLimit = pSelect->iOffset ? pSelect->iOffset+1 : pSelect->iLimit;
+ pSort->labelDone = sqlite3VdbeMakeLabel(v);
+ sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, regOrigData,
+ SQLITE_ECEL_DUP | (regOrigData? SQLITE_ECEL_REF : 0));
+ if( bSeq ){
+ sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr);
+ }
+ if( nPrefixReg==0 && nData>0 ){
+ sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+bSeq, nData);
+ }
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regRecord);
+ if( nOBSat>0 ){
+ int regPrevKey; /* The first nOBSat columns of the previous row */
+ int addrFirst; /* Address of the OP_IfNot opcode */
+ int addrJmp; /* Address of the OP_Jump opcode */
+ VdbeOp *pOp; /* Opcode that opens the sorter */
+ int nKey; /* Number of sorting key columns, including OP_Sequence */
+ KeyInfo *pKI; /* Original KeyInfo on the sorter table */
+
+ regPrevKey = pParse->nMem+1;
+ pParse->nMem += pSort->nOBSat;
+ nKey = nExpr - pSort->nOBSat + bSeq;
+ if( bSeq ){
+ addrFirst = sqlite3VdbeAddOp1(v, OP_IfNot, regBase+nExpr);
+ }else{
+ addrFirst = sqlite3VdbeAddOp1(v, OP_SequenceTest, pSort->iECursor);
+ }
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, OP_Compare, regPrevKey, regBase, pSort->nOBSat);
+ pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex);
+ if( pParse->db->mallocFailed ) return;
+ pOp->p2 = nKey + nData;
+ pKI = pOp->p4.pKeyInfo;
+ memset(pKI->aSortOrder, 0, pKI->nField); /* Makes OP_Jump below testable */
+ sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO);
+ testcase( pKI->nXField>2 );
+ pOp->p4.pKeyInfo = keyInfoFromExprList(pParse, pSort->pOrderBy, nOBSat,
+ pKI->nXField-1);
+ addrJmp = sqlite3VdbeCurrentAddr(v);
+ sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v);
+ pSort->labelBkOut = sqlite3VdbeMakeLabel(v);
+ pSort->regReturn = ++pParse->nMem;
+ sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut);
+ sqlite3VdbeAddOp1(v, OP_ResetSorter, pSort->iECursor);
+ if( iLimit ){
+ sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, pSort->labelDone);
+ VdbeCoverage(v);
+ }
+ sqlite3VdbeJumpHere(v, addrFirst);
+ sqlite3ExprCodeMove(pParse, regBase, regPrevKey, pSort->nOBSat);
+ sqlite3VdbeJumpHere(v, addrJmp);
+ }
+ if( pSort->sortFlags & SORTFLAG_UseSorter ){
+ op = OP_SorterInsert;
+ }else{
+ op = OP_IdxInsert;
+ }
+ sqlite3VdbeAddOp4Int(v, op, pSort->iECursor, regRecord,
+ regBase+nOBSat, nBase-nOBSat);
+ if( iLimit ){
+ int addr;
+ int r1 = 0;
+ /* Fill the sorter until it contains LIMIT+OFFSET entries. (The iLimit
+ ** register is initialized with value of LIMIT+OFFSET.) After the sorter
+ ** fills up, delete the least entry in the sorter after each insert.
+ ** Thus we never hold more than the LIMIT+OFFSET rows in memory at once */
+ addr = sqlite3VdbeAddOp1(v, OP_IfNotZero, iLimit); VdbeCoverage(v);
+ sqlite3VdbeAddOp1(v, OP_Last, pSort->iECursor);
+ if( pSort->bOrderedInnerLoop ){
+ r1 = ++pParse->nMem;
+ sqlite3VdbeAddOp3(v, OP_Column, pSort->iECursor, nExpr, r1);
+ VdbeComment((v, "seq"));
+ }
+ sqlite3VdbeAddOp1(v, OP_Delete, pSort->iECursor);
+ if( pSort->bOrderedInnerLoop ){
+ /* If the inner loop is driven by an index such that values from
+ ** the same iteration of the inner loop are in sorted order, then
+ ** immediately jump to the next iteration of an inner loop if the
+ ** entry from the current iteration does not fit into the top
+ ** LIMIT+OFFSET entries of the sorter. */
+ int iBrk = sqlite3VdbeCurrentAddr(v) + 2;
+ sqlite3VdbeAddOp3(v, OP_Eq, regBase+nExpr, iBrk, r1);
+ sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
+ VdbeCoverage(v);
+ }
+ sqlite3VdbeJumpHere(v, addr);
+ }
+}
+
+/*
+** Add code to implement the OFFSET
+*/
+static void codeOffset(
+ Vdbe *v, /* Generate code into this VM */
+ int iOffset, /* Register holding the offset counter */
+ int iContinue /* Jump here to skip the current record */
+){
+ if( iOffset>0 ){
+ sqlite3VdbeAddOp3(v, OP_IfPos, iOffset, iContinue, 1); VdbeCoverage(v);
+ VdbeComment((v, "OFFSET"));
+ }
+}
+
+/*
+** Add code that will check to make sure the N registers starting at iMem
+** form a distinct entry. iTab is a sorting index that holds previously
+** seen combinations of the N values. A new entry is made in iTab
+** if the current N values are new.
+**
+** A jump to addrRepeat is made and the N+1 values are popped from the
+** stack if the top N elements are not distinct.
+*/
+static void codeDistinct(
+ Parse *pParse, /* Parsing and code generating context */
+ int iTab, /* A sorting index used to test for distinctness */
+ int addrRepeat, /* Jump to here if not distinct */
+ int N, /* Number of elements */
+ int iMem /* First element */
+){
+ Vdbe *v;
+ int r1;
+
+ v = pParse->pVdbe;
+ r1 = sqlite3GetTempReg(pParse);
+ sqlite3VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, iMem, N); VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, iMem, N, r1);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r1, iMem, N);
+ sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
+ sqlite3ReleaseTempReg(pParse, r1);
+}
+
+/*
+** This routine generates the code for the inside of the inner loop
+** of a SELECT.
+**
+** If srcTab is negative, then the pEList expressions
+** are evaluated in order to get the data for this row. If srcTab is
+** zero or more, then data is pulled from srcTab and pEList is used only
+** to get the number of columns and the collation sequence for each column.
+*/
+static void selectInnerLoop(
+ Parse *pParse, /* The parser context */
+ Select *p, /* The complete select statement being coded */
+ ExprList *pEList, /* List of values being extracted */
+ int srcTab, /* Pull data from this table */
+ SortCtx *pSort, /* If not NULL, info on how to process ORDER BY */
+ DistinctCtx *pDistinct, /* If not NULL, info on how to process DISTINCT */
+ SelectDest *pDest, /* How to dispose of the results */
+ int iContinue, /* Jump here to continue with next row */
+ int iBreak /* Jump here to break out of the inner loop */
+){
+ Vdbe *v = pParse->pVdbe;
+ int i;
+ int hasDistinct; /* True if the DISTINCT keyword is present */
+ int eDest = pDest->eDest; /* How to dispose of results */
+ int iParm = pDest->iSDParm; /* First argument to disposal method */
+ int nResultCol; /* Number of result columns */
+ int nPrefixReg = 0; /* Number of extra registers before regResult */
+
+ /* Usually, regResult is the first cell in an array of memory cells
+ ** containing the current result row. In this case regOrig is set to the
+ ** same value. However, if the results are being sent to the sorter, the
+ ** values for any expressions that are also part of the sort-key are omitted
+ ** from this array. In this case regOrig is set to zero. */
+ int regResult; /* Start of memory holding current results */
+ int regOrig; /* Start of memory holding full result (or 0) */
+
+ assert( v );
+ assert( pEList!=0 );
+ hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP;
+ if( pSort && pSort->pOrderBy==0 ) pSort = 0;
+ if( pSort==0 && !hasDistinct ){
+ assert( iContinue!=0 );
+ codeOffset(v, p->iOffset, iContinue);
+ }
+
+ /* Pull the requested columns.
+ */
+ nResultCol = pEList->nExpr;
+
+ if( pDest->iSdst==0 ){
+ if( pSort ){
+ nPrefixReg = pSort->pOrderBy->nExpr;
+ if( !(pSort->sortFlags & SORTFLAG_UseSorter) ) nPrefixReg++;
+ pParse->nMem += nPrefixReg;
+ }
+ pDest->iSdst = pParse->nMem+1;
+ pParse->nMem += nResultCol;
+ }else if( pDest->iSdst+nResultCol > pParse->nMem ){
+ /* This is an error condition that can result, for example, when a SELECT
+ ** on the right-hand side of an INSERT contains more result columns than
+ ** there are columns in the table on the left. The error will be caught
+ ** and reported later. But we need to make sure enough memory is allocated
+ ** to avoid other spurious errors in the meantime. */
+ pParse->nMem += nResultCol;
+ }
+ pDest->nSdst = nResultCol;
+ regOrig = regResult = pDest->iSdst;
+ if( srcTab>=0 ){
+ for(i=0; i<nResultCol; i++){
+ sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, regResult+i);
+ VdbeComment((v, "%s", pEList->a[i].zName));
+ }
+ }else if( eDest!=SRT_Exists ){
+ /* If the destination is an EXISTS(...) expression, the actual
+ ** values returned by the SELECT are not required.
+ */
+ u8 ecelFlags;
+ if( eDest==SRT_Mem || eDest==SRT_Output || eDest==SRT_Coroutine ){
+ ecelFlags = SQLITE_ECEL_DUP;
+ }else{
+ ecelFlags = 0;
+ }
+ if( pSort && hasDistinct==0 && eDest!=SRT_EphemTab && eDest!=SRT_Table ){
+ /* For each expression in pEList that is a copy of an expression in
+ ** the ORDER BY clause (pSort->pOrderBy), set the associated
+ ** iOrderByCol value to one more than the index of the ORDER BY
+ ** expression within the sort-key that pushOntoSorter() will generate.
+ ** This allows the pEList field to be omitted from the sorted record,
+ ** saving space and CPU cycles. */
+ ecelFlags |= (SQLITE_ECEL_OMITREF|SQLITE_ECEL_REF);
+ for(i=pSort->nOBSat; i<pSort->pOrderBy->nExpr; i++){
+ int j;
+ if( (j = pSort->pOrderBy->a[i].u.x.iOrderByCol)>0 ){
+ pEList->a[j-1].u.x.iOrderByCol = i+1-pSort->nOBSat;
+ }
+ }
+ regOrig = 0;
+ assert( eDest==SRT_Set || eDest==SRT_Mem
+ || eDest==SRT_Coroutine || eDest==SRT_Output );
+ }
+ nResultCol = sqlite3ExprCodeExprList(pParse,pEList,regResult,0,ecelFlags);
+ }
+
+ /* If the DISTINCT keyword was present on the SELECT statement
+ ** and this row has been seen before, then do not make this row
+ ** part of the result.
+ */
+ if( hasDistinct ){
+ switch( pDistinct->eTnctType ){
+ case WHERE_DISTINCT_ORDERED: {
+ VdbeOp *pOp; /* No longer required OpenEphemeral instr. */
+ int iJump; /* Jump destination */
+ int regPrev; /* Previous row content */
+
+ /* Allocate space for the previous row */
+ regPrev = pParse->nMem+1;
+ pParse->nMem += nResultCol;
+
+ /* Change the OP_OpenEphemeral coded earlier to an OP_Null
+ ** sets the MEM_Cleared bit on the first register of the
+ ** previous value. This will cause the OP_Ne below to always
+ ** fail on the first iteration of the loop even if the first
+ ** row is all NULLs.
+ */
+ sqlite3VdbeChangeToNoop(v, pDistinct->addrTnct);
+ pOp = sqlite3VdbeGetOp(v, pDistinct->addrTnct);
+ pOp->opcode = OP_Null;
+ pOp->p1 = 1;
+ pOp->p2 = regPrev;
+
+ iJump = sqlite3VdbeCurrentAddr(v) + nResultCol;
+ for(i=0; i<nResultCol; i++){
+ CollSeq *pColl = sqlite3ExprCollSeq(pParse, pEList->a[i].pExpr);
+ if( i<nResultCol-1 ){
+ sqlite3VdbeAddOp3(v, OP_Ne, regResult+i, iJump, regPrev+i);
+ VdbeCoverage(v);
+ }else{
+ sqlite3VdbeAddOp3(v, OP_Eq, regResult+i, iContinue, regPrev+i);
+ VdbeCoverage(v);
+ }
+ sqlite3VdbeChangeP4(v, -1, (const char *)pColl, P4_COLLSEQ);
+ sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
+ }
+ assert( sqlite3VdbeCurrentAddr(v)==iJump || pParse->db->mallocFailed );
+ sqlite3VdbeAddOp3(v, OP_Copy, regResult, regPrev, nResultCol-1);
+ break;
+ }
+
+ case WHERE_DISTINCT_UNIQUE: {
+ sqlite3VdbeChangeToNoop(v, pDistinct->addrTnct);
+ break;
+ }
+
+ default: {
+ assert( pDistinct->eTnctType==WHERE_DISTINCT_UNORDERED );
+ codeDistinct(pParse, pDistinct->tabTnct, iContinue, nResultCol,
+ regResult);
+ break;
+ }
+ }
+ if( pSort==0 ){
+ codeOffset(v, p->iOffset, iContinue);
+ }
+ }
+
+ switch( eDest ){
+ /* In this mode, write each query result to the key of the temporary
+ ** table iParm.
+ */
+#ifndef SQLITE_OMIT_COMPOUND_SELECT
+ case SRT_Union: {
+ int r1;
+ r1 = sqlite3GetTempReg(pParse);
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol);
+ sqlite3ReleaseTempReg(pParse, r1);
+ break;
+ }
+
+ /* Construct a record from the query result, but instead of
+ ** saving that record, use it as a key to delete elements from
+ ** the temporary table iParm.
+ */
+ case SRT_Except: {
+ sqlite3VdbeAddOp3(v, OP_IdxDelete, iParm, regResult, nResultCol);
+ break;
+ }
+#endif /* SQLITE_OMIT_COMPOUND_SELECT */
+
+ /* Store the result as data using a unique key.
+ */
+ case SRT_Fifo:
+ case SRT_DistFifo:
+ case SRT_Table:
+ case SRT_EphemTab: {
+ int r1 = sqlite3GetTempRange(pParse, nPrefixReg+1);
+ testcase( eDest==SRT_Table );
+ testcase( eDest==SRT_EphemTab );
+ testcase( eDest==SRT_Fifo );
+ testcase( eDest==SRT_DistFifo );
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1+nPrefixReg);
+#ifndef SQLITE_OMIT_CTE
+ if( eDest==SRT_DistFifo ){
+ /* If the destination is DistFifo, then cursor (iParm+1) is open
+ ** on an ephemeral index. If the current row is already present
+ ** in the index, do not write it to the output. If not, add the
+ ** current row to the index and proceed with writing it to the
+ ** output table as well. */
+ int addr = sqlite3VdbeCurrentAddr(v) + 4;
+ sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, addr, r1, 0);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm+1, r1,regResult,nResultCol);
+ assert( pSort==0 );
+ }
+#endif
+ if( pSort ){
+ pushOntoSorter(pParse, pSort, p, r1+nPrefixReg,regResult,1,nPrefixReg);
+ }else{
+ int r2 = sqlite3GetTempReg(pParse);
+ sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2);
+ sqlite3VdbeAddOp3(v, OP_Insert, iParm, r1, r2);
+ sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
+ sqlite3ReleaseTempReg(pParse, r2);
+ }
+ sqlite3ReleaseTempRange(pParse, r1, nPrefixReg+1);
+ break;
+ }
+
+#ifndef SQLITE_OMIT_SUBQUERY
+ /* If we are creating a set for an "expr IN (SELECT ...)" construct,
+ ** then there should be a single item on the stack. Write this
+ ** item into the set table with bogus data.
+ */
+ case SRT_Set: {
+ if( pSort ){
+ /* At first glance you would think we could optimize out the
+ ** ORDER BY in this case since the order of entries in the set
+ ** does not matter. But there might be a LIMIT clause, in which
+ ** case the order does matter */
+ pushOntoSorter(
+ pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg);
+ }else{
+ int r1 = sqlite3GetTempReg(pParse);
+ assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol );
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol,
+ r1, pDest->zAffSdst, nResultCol);
+ sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol);
+ sqlite3ReleaseTempReg(pParse, r1);
+ }
+ break;
+ }
+
+ /* If any row exist in the result set, record that fact and abort.
+ */
+ case SRT_Exists: {
+ sqlite3VdbeAddOp2(v, OP_Integer, 1, iParm);
+ /* The LIMIT clause will terminate the loop for us */
+ break;
+ }
+
+ /* If this is a scalar select that is part of an expression, then
+ ** store the results in the appropriate memory cell or array of
+ ** memory cells and break out of the scan loop.
+ */
+ case SRT_Mem: {
+ if( pSort ){
+ assert( nResultCol<=pDest->nSdst );
+ pushOntoSorter(
+ pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg);
+ }else{
+ assert( nResultCol==pDest->nSdst );
+ assert( regResult==iParm );
+ /* The LIMIT clause will jump out of the loop for us */
+ }
+ break;
+ }
+#endif /* #ifndef SQLITE_OMIT_SUBQUERY */
+
+ case SRT_Coroutine: /* Send data to a co-routine */
+ case SRT_Output: { /* Return the results */
+ testcase( eDest==SRT_Coroutine );
+ testcase( eDest==SRT_Output );
+ if( pSort ){
+ pushOntoSorter(pParse, pSort, p, regResult, regOrig, nResultCol,
+ nPrefixReg);
+ }else if( eDest==SRT_Coroutine ){
+ sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nResultCol);
+ sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol);
+ }
+ break;
+ }
+
+#ifndef SQLITE_OMIT_CTE
+ /* Write the results into a priority queue that is order according to
+ ** pDest->pOrderBy (in pSO). pDest->iSDParm (in iParm) is the cursor for an
+ ** index with pSO->nExpr+2 columns. Build a key using pSO for the first
+ ** pSO->nExpr columns, then make sure all keys are unique by adding a
+ ** final OP_Sequence column. The last column is the record as a blob.
+ */
+ case SRT_DistQueue:
+ case SRT_Queue: {
+ int nKey;
+ int r1, r2, r3;
+ int addrTest = 0;
+ ExprList *pSO;
+ pSO = pDest->pOrderBy;
+ assert( pSO );
+ nKey = pSO->nExpr;
+ r1 = sqlite3GetTempReg(pParse);
+ r2 = sqlite3GetTempRange(pParse, nKey+2);
+ r3 = r2+nKey+1;
+ if( eDest==SRT_DistQueue ){
+ /* If the destination is DistQueue, then cursor (iParm+1) is open
+ ** on a second ephemeral index that holds all values every previously
+ ** added to the queue. */
+ addrTest = sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, 0,
+ regResult, nResultCol);
+ VdbeCoverage(v);
+ }
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r3);
+ if( eDest==SRT_DistQueue ){
+ sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r3);
+ sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
+ }
+ for(i=0; i<nKey; i++){
+ sqlite3VdbeAddOp2(v, OP_SCopy,
+ regResult + pSO->a[i].u.x.iOrderByCol - 1,
+ r2+i);
+ }
+ sqlite3VdbeAddOp2(v, OP_Sequence, iParm, r2+nKey);
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, r2, nKey+2, r1);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, r2, nKey+2);
+ if( addrTest ) sqlite3VdbeJumpHere(v, addrTest);
+ sqlite3ReleaseTempReg(pParse, r1);
+ sqlite3ReleaseTempRange(pParse, r2, nKey+2);
+ break;
+ }
+#endif /* SQLITE_OMIT_CTE */
+
+
+
+#if !defined(SQLITE_OMIT_TRIGGER)
+ /* Discard the results. This is used for SELECT statements inside
+ ** the body of a TRIGGER. The purpose of such selects is to call
+ ** user-defined functions that have side effects. We do not care
+ ** about the actual results of the select.
+ */
+ default: {
+ assert( eDest==SRT_Discard );
+ break;
+ }
+#endif
+ }
+
+ /* Jump to the end of the loop if the LIMIT is reached. Except, if
+ ** there is a sorter, in which case the sorter has already limited
+ ** the output for us.
+ */
+ if( pSort==0 && p->iLimit ){
+ sqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak); VdbeCoverage(v);
+ }
+}
+
+/*
+** Allocate a KeyInfo object sufficient for an index of N key columns and
+** X extra columns.
+*/
+SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){
+ int nExtra = (N+X)*(sizeof(CollSeq*)+1);
+ KeyInfo *p = sqlite3DbMallocRawNN(db, sizeof(KeyInfo) + nExtra);
+ if( p ){
+ p->aSortOrder = (u8*)&p->aColl[N+X];
+ p->nField = (u16)N;
+ p->nXField = (u16)X;
+ p->enc = ENC(db);
+ p->db = db;
+ p->nRef = 1;
+ memset(&p[1], 0, nExtra);
+ }else{
+ sqlite3OomFault(db);
+ }
+ return p;
+}
+
+/*
+** Deallocate a KeyInfo object
+*/
+SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo *p){
+ if( p ){
+ assert( p->nRef>0 );
+ p->nRef--;
+ if( p->nRef==0 ) sqlite3DbFree(p->db, p);
+ }
+}
+
+/*
+** Make a new pointer to a KeyInfo object
+*/
+SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoRef(KeyInfo *p){
+ if( p ){
+ assert( p->nRef>0 );
+ p->nRef++;
+ }
+ return p;
+}
+
+#ifdef SQLITE_DEBUG
+/*
+** Return TRUE if a KeyInfo object can be change. The KeyInfo object
+** can only be changed if this is just a single reference to the object.
+**
+** This routine is used only inside of assert() statements.
+*/
+SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo *p){ return p->nRef==1; }
+#endif /* SQLITE_DEBUG */
+
+/*
+** Given an expression list, generate a KeyInfo structure that records
+** the collating sequence for each expression in that expression list.
+**
+** If the ExprList is an ORDER BY or GROUP BY clause then the resulting
+** KeyInfo structure is appropriate for initializing a virtual index to
+** implement that clause. If the ExprList is the result set of a SELECT
+** then the KeyInfo structure is appropriate for initializing a virtual
+** index to implement a DISTINCT test.
+**
+** Space to hold the KeyInfo structure is obtained from malloc. The calling
+** function is responsible for seeing that this structure is eventually
+** freed.
+*/
+static KeyInfo *keyInfoFromExprList(
+ Parse *pParse, /* Parsing context */
+ ExprList *pList, /* Form the KeyInfo object from this ExprList */
+ int iStart, /* Begin with this column of pList */
+ int nExtra /* Add this many extra columns to the end */
+){
+ int nExpr;
+ KeyInfo *pInfo;
+ struct ExprList_item *pItem;
+ sqlite3 *db = pParse->db;
+ int i;
+
+ nExpr = pList->nExpr;
+ pInfo = sqlite3KeyInfoAlloc(db, nExpr-iStart, nExtra+1);
+ if( pInfo ){
+ assert( sqlite3KeyInfoIsWriteable(pInfo) );
+ for(i=iStart, pItem=pList->a+iStart; i<nExpr; i++, pItem++){
+ CollSeq *pColl;
+ pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
+ if( !pColl ) pColl = db->pDfltColl;
+ pInfo->aColl[i-iStart] = pColl;
+ pInfo->aSortOrder[i-iStart] = pItem->sortOrder;
+ }
+ }
+ return pInfo;
+}
+
+/*
+** Name of the connection operator, used for error messages.
+*/
+static const char *selectOpName(int id){
+ char *z;
+ switch( id ){
+ case TK_ALL: z = "UNION ALL"; break;
+ case TK_INTERSECT: z = "INTERSECT"; break;
+ case TK_EXCEPT: z = "EXCEPT"; break;
+ default: z = "UNION"; break;
+ }
+ return z;
+}
+
+#ifndef SQLITE_OMIT_EXPLAIN
+/*
+** Unless an "EXPLAIN QUERY PLAN" command is being processed, this function
+** is a no-op. Otherwise, it adds a single row of output to the EQP result,
+** where the caption is of the form:
+**
+** "USE TEMP B-TREE FOR xxx"
+**
+** where xxx is one of "DISTINCT", "ORDER BY" or "GROUP BY". Exactly which
+** is determined by the zUsage argument.
+*/
+static void explainTempTable(Parse *pParse, const char *zUsage){
+ if( pParse->explain==2 ){
+ Vdbe *v = pParse->pVdbe;
+ char *zMsg = sqlite3MPrintf(pParse->db, "USE TEMP B-TREE FOR %s", zUsage);
+ sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC);
+ }
+}
+
+/*
+** Assign expression b to lvalue a. A second, no-op, version of this macro
+** is provided when SQLITE_OMIT_EXPLAIN is defined. This allows the code
+** in sqlite3Select() to assign values to structure member variables that
+** only exist if SQLITE_OMIT_EXPLAIN is not defined without polluting the
+** code with #ifndef directives.
+*/
+# define explainSetInteger(a, b) a = b
+
+#else
+/* No-op versions of the explainXXX() functions and macros. */
+# define explainTempTable(y,z)
+# define explainSetInteger(y,z)
+#endif
+
+#if !defined(SQLITE_OMIT_EXPLAIN) && !defined(SQLITE_OMIT_COMPOUND_SELECT)
+/*
+** Unless an "EXPLAIN QUERY PLAN" command is being processed, this function
+** is a no-op. Otherwise, it adds a single row of output to the EQP result,
+** where the caption is of one of the two forms:
+**
+** "COMPOSITE SUBQUERIES iSub1 and iSub2 (op)"
+** "COMPOSITE SUBQUERIES iSub1 and iSub2 USING TEMP B-TREE (op)"
+**
+** where iSub1 and iSub2 are the integers passed as the corresponding
+** function parameters, and op is the text representation of the parameter
+** of the same name. The parameter "op" must be one of TK_UNION, TK_EXCEPT,
+** TK_INTERSECT or TK_ALL. The first form is used if argument bUseTmp is
+** false, or the second form if it is true.
+*/
+static void explainComposite(
+ Parse *pParse, /* Parse context */
+ int op, /* One of TK_UNION, TK_EXCEPT etc. */
+ int iSub1, /* Subquery id 1 */
+ int iSub2, /* Subquery id 2 */
+ int bUseTmp /* True if a temp table was used */
+){
+ assert( op==TK_UNION || op==TK_EXCEPT || op==TK_INTERSECT || op==TK_ALL );
+ if( pParse->explain==2 ){
+ Vdbe *v = pParse->pVdbe;
+ char *zMsg = sqlite3MPrintf(
+ pParse->db, "COMPOUND SUBQUERIES %d AND %d %s(%s)", iSub1, iSub2,
+ bUseTmp?"USING TEMP B-TREE ":"", selectOpName(op)
+ );
+ sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC);
+ }
+}
+#else
+/* No-op versions of the explainXXX() functions and macros. */
+# define explainComposite(v,w,x,y,z)
+#endif
+
+/*
+** If the inner loop was generated using a non-null pOrderBy argument,
+** then the results were placed in a sorter. After the loop is terminated
+** we need to run the sorter and output the results. The following
+** routine generates the code needed to do that.
+*/
+static void generateSortTail(
+ Parse *pParse, /* Parsing context */
+ Select *p, /* The SELECT statement */
+ SortCtx *pSort, /* Information on the ORDER BY clause */
+ int nColumn, /* Number of columns of data */
+ SelectDest *pDest /* Write the sorted results here */
+){
+ Vdbe *v = pParse->pVdbe; /* The prepared statement */
+ int addrBreak = pSort->labelDone; /* Jump here to exit loop */
+ int addrContinue = sqlite3VdbeMakeLabel(v); /* Jump here for next cycle */
+ int addr;
+ int addrOnce = 0;
+ int iTab;
+ ExprList *pOrderBy = pSort->pOrderBy;
+ int eDest = pDest->eDest;
+ int iParm = pDest->iSDParm;
+ int regRow;
+ int regRowid;
+ int iCol;
+ int nKey;
+ int iSortTab; /* Sorter cursor to read from */
+ int nSortData; /* Trailing values to read from sorter */
+ int i;
+ int bSeq; /* True if sorter record includes seq. no. */
+ struct ExprList_item *aOutEx = p->pEList->a;
+
+ assert( addrBreak<0 );
+ if( pSort->labelBkOut ){
+ sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut);
+ sqlite3VdbeGoto(v, addrBreak);
+ sqlite3VdbeResolveLabel(v, pSort->labelBkOut);
+ }
+ iTab = pSort->iECursor;
+ if( eDest==SRT_Output || eDest==SRT_Coroutine || eDest==SRT_Mem ){
+ regRowid = 0;
+ regRow = pDest->iSdst;
+ nSortData = nColumn;
+ }else{
+ regRowid = sqlite3GetTempReg(pParse);
+ regRow = sqlite3GetTempRange(pParse, nColumn);
+ nSortData = nColumn;
+ }
+ nKey = pOrderBy->nExpr - pSort->nOBSat;
+ if( pSort->sortFlags & SORTFLAG_UseSorter ){
+ int regSortOut = ++pParse->nMem;
+ iSortTab = pParse->nTab++;
+ if( pSort->labelBkOut ){
+ addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+ }
+ sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData);
+ if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
+ addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
+ VdbeCoverage(v);
+ codeOffset(v, p->iOffset, addrContinue);
+ sqlite3VdbeAddOp3(v, OP_SorterData, iTab, regSortOut, iSortTab);
+ bSeq = 0;
+ }else{
+ addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v);
+ codeOffset(v, p->iOffset, addrContinue);
+ iSortTab = iTab;
+ bSeq = 1;
+ }
+ for(i=0, iCol=nKey+bSeq; i<nSortData; i++){
+ int iRead;
+ if( aOutEx[i].u.x.iOrderByCol ){
+ iRead = aOutEx[i].u.x.iOrderByCol-1;
+ }else{
+ iRead = iCol++;
+ }
+ sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iRead, regRow+i);
+ VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
+ }
+ switch( eDest ){
+ case SRT_Table:
+ case SRT_EphemTab: {
+ sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);
+ sqlite3VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid);
+ sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
+ break;
+ }
+#ifndef SQLITE_OMIT_SUBQUERY
+ case SRT_Set: {
+ assert( nColumn==sqlite3Strlen30(pDest->zAffSdst) );
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, nColumn, regRowid,
+ pDest->zAffSdst, nColumn);
+ sqlite3ExprCacheAffinityChange(pParse, regRow, nColumn);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, regRowid, regRow, nColumn);
+ break;
+ }
+ case SRT_Mem: {
+ /* The LIMIT clause will terminate the loop for us */
+ break;
+ }
+#endif
+ default: {
+ assert( eDest==SRT_Output || eDest==SRT_Coroutine );
+ testcase( eDest==SRT_Output );
+ testcase( eDest==SRT_Coroutine );
+ if( eDest==SRT_Output ){
+ sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iSdst, nColumn);
+ sqlite3ExprCacheAffinityChange(pParse, pDest->iSdst, nColumn);
+ }else{
+ sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
+ }
+ break;
+ }
+ }
+ if( regRowid ){
+ if( eDest==SRT_Set ){
+ sqlite3ReleaseTempRange(pParse, regRow, nColumn);
+ }else{
+ sqlite3ReleaseTempReg(pParse, regRow);
+ }
+ sqlite3ReleaseTempReg(pParse, regRowid);
+ }
+ /* The bottom of the loop
+ */
+ sqlite3VdbeResolveLabel(v, addrContinue);
+ if( pSort->sortFlags & SORTFLAG_UseSorter ){
+ sqlite3VdbeAddOp2(v, OP_SorterNext, iTab, addr); VdbeCoverage(v);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); VdbeCoverage(v);
+ }
+ if( pSort->regReturn ) sqlite3VdbeAddOp1(v, OP_Return, pSort->regReturn);
+ sqlite3VdbeResolveLabel(v, addrBreak);
+}
+
+/*
+** Return a pointer to a string containing the 'declaration type' of the
+** expression pExpr. The string may be treated as static by the caller.
+**
+** Also try to estimate the size of the returned value and return that
+** result in *pEstWidth.
+**
+** The declaration type is the exact datatype definition extracted from the
+** original CREATE TABLE statement if the expression is a column. The
+** declaration type for a ROWID field is INTEGER. Exactly when an expression
+** is considered a column can be complex in the presence of subqueries. The
+** result-set expression in all of the following SELECT statements is
+** considered a column by this function.
+**
+** SELECT col FROM tbl;
+** SELECT (SELECT col FROM tbl;
+** SELECT (SELECT col FROM tbl);
+** SELECT abc FROM (SELECT col AS abc FROM tbl);
+**
+** The declaration type for any expression other than a column is NULL.
+**
+** This routine has either 3 or 6 parameters depending on whether or not
+** the SQLITE_ENABLE_COLUMN_METADATA compile-time option is used.
+*/
+#ifdef SQLITE_ENABLE_COLUMN_METADATA
+# define columnType(A,B,C,D,E,F) columnTypeImpl(A,B,C,D,E,F)
+#else /* if !defined(SQLITE_ENABLE_COLUMN_METADATA) */
+# define columnType(A,B,C,D,E,F) columnTypeImpl(A,B,F)
+#endif
+static const char *columnTypeImpl(
+ NameContext *pNC,
+ Expr *pExpr,
+#ifdef SQLITE_ENABLE_COLUMN_METADATA
+ const char **pzOrigDb,
+ const char **pzOrigTab,
+ const char **pzOrigCol,
+#endif
+ u8 *pEstWidth
+){
+ char const *zType = 0;
+ int j;
+ u8 estWidth = 1;
+#ifdef SQLITE_ENABLE_COLUMN_METADATA
+ char const *zOrigDb = 0;
+ char const *zOrigTab = 0;
+ char const *zOrigCol = 0;
+#endif
+
+ assert( pExpr!=0 );
+ assert( pNC->pSrcList!=0 );
+ switch( pExpr->op ){
+ case TK_AGG_COLUMN:
+ case TK_COLUMN: {
+ /* The expression is a column. Locate the table the column is being
+ ** extracted from in NameContext.pSrcList. This table may be real
+ ** database table or a subquery.
+ */
+ Table *pTab = 0; /* Table structure column is extracted from */
+ Select *pS = 0; /* Select the column is extracted from */
+ int iCol = pExpr->iColumn; /* Index of column in pTab */
+ testcase( pExpr->op==TK_AGG_COLUMN );
+ testcase( pExpr->op==TK_COLUMN );
+ while( pNC && !pTab ){
+ SrcList *pTabList = pNC->pSrcList;
+ for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++);
+ if( j<pTabList->nSrc ){
+ pTab = pTabList->a[j].pTab;
+ pS = pTabList->a[j].pSelect;
+ }else{
+ pNC = pNC->pNext;
+ }
+ }
+
+ if( pTab==0 ){
+ /* At one time, code such as "SELECT new.x" within a trigger would
+ ** cause this condition to run. Since then, we have restructured how
+ ** trigger code is generated and so this condition is no longer
+ ** possible. However, it can still be true for statements like
+ ** the following:
+ **
+ ** CREATE TABLE t1(col INTEGER);
+ ** SELECT (SELECT t1.col) FROM FROM t1;
+ **
+ ** when columnType() is called on the expression "t1.col" in the
+ ** sub-select. In this case, set the column type to NULL, even
+ ** though it should really be "INTEGER".
+ **
+ ** This is not a problem, as the column type of "t1.col" is never
+ ** used. When columnType() is called on the expression
+ ** "(SELECT t1.col)", the correct type is returned (see the TK_SELECT
+ ** branch below. */
+ break;
+ }
+
+ assert( pTab && pExpr->pTab==pTab );
+ if( pS ){
+ /* The "table" is actually a sub-select or a view in the FROM clause
+ ** of the SELECT statement. Return the declaration type and origin
+ ** data for the result-set column of the sub-select.
+ */
+ if( iCol>=0 && ALWAYS(iCol<pS->pEList->nExpr) ){
+ /* If iCol is less than zero, then the expression requests the
+ ** rowid of the sub-select or view. This expression is legal (see
+ ** test case misc2.2.2) - it always evaluates to NULL.
+ **
+ ** The ALWAYS() is because iCol>=pS->pEList->nExpr will have been
+ ** caught already by name resolution.
+ */
+ NameContext sNC;
+ Expr *p = pS->pEList->a[iCol].pExpr;
+ sNC.pSrcList = pS->pSrc;
+ sNC.pNext = pNC;
+ sNC.pParse = pNC->pParse;
+ zType = columnType(&sNC, p,&zOrigDb,&zOrigTab,&zOrigCol, &estWidth);
+ }
+ }else if( pTab->pSchema ){
+ /* A real table */
+ assert( !pS );
+ if( iCol<0 ) iCol = pTab->iPKey;
+ assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
+#ifdef SQLITE_ENABLE_COLUMN_METADATA
+ if( iCol<0 ){
+ zType = "INTEGER";
+ zOrigCol = "rowid";
+ }else{
+ zOrigCol = pTab->aCol[iCol].zName;
+ zType = sqlite3ColumnType(&pTab->aCol[iCol],0);
+ estWidth = pTab->aCol[iCol].szEst;
+ }
+ zOrigTab = pTab->zName;
+ if( pNC->pParse ){
+ int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema);
+ zOrigDb = pNC->pParse->db->aDb[iDb].zDbSName;
+ }
+#else
+ if( iCol<0 ){
+ zType = "INTEGER";
+ }else{
+ zType = sqlite3ColumnType(&pTab->aCol[iCol],0);
+ estWidth = pTab->aCol[iCol].szEst;
+ }
+#endif
+ }
+ break;
+ }
+#ifndef SQLITE_OMIT_SUBQUERY
+ case TK_SELECT: {
+ /* The expression is a sub-select. Return the declaration type and
+ ** origin info for the single column in the result set of the SELECT
+ ** statement.
+ */
+ NameContext sNC;
+ Select *pS = pExpr->x.pSelect;
+ Expr *p = pS->pEList->a[0].pExpr;
+ assert( ExprHasProperty(pExpr, EP_xIsSelect) );
+ sNC.pSrcList = pS->pSrc;
+ sNC.pNext = pNC;
+ sNC.pParse = pNC->pParse;
+ zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol, &estWidth);
+ break;
+ }
+#endif
+ }
+
+#ifdef SQLITE_ENABLE_COLUMN_METADATA
+ if( pzOrigDb ){
+ assert( pzOrigTab && pzOrigCol );
+ *pzOrigDb = zOrigDb;
+ *pzOrigTab = zOrigTab;
+ *pzOrigCol = zOrigCol;
+ }
+#endif
+ if( pEstWidth ) *pEstWidth = estWidth;
+ return zType;
+}
+
+/*
+** Generate code that will tell the VDBE the declaration types of columns
+** in the result set.
+*/
+static void generateColumnTypes(
+ Parse *pParse, /* Parser context */
+ SrcList *pTabList, /* List of tables */
+ ExprList *pEList /* Expressions defining the result set */
+){
+#ifndef SQLITE_OMIT_DECLTYPE
+ Vdbe *v = pParse->pVdbe;
+ int i;
+ NameContext sNC;
+ sNC.pSrcList = pTabList;
+ sNC.pParse = pParse;
+ for(i=0; i<pEList->nExpr; i++){
+ Expr *p = pEList->a[i].pExpr;
+ const char *zType;
+#ifdef SQLITE_ENABLE_COLUMN_METADATA
+ const char *zOrigDb = 0;
+ const char *zOrigTab = 0;
+ const char *zOrigCol = 0;
+ zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol, 0);
+
+ /* The vdbe must make its own copy of the column-type and other
+ ** column specific strings, in case the schema is reset before this
+ ** virtual machine is deleted.
+ */
+ sqlite3VdbeSetColName(v, i, COLNAME_DATABASE, zOrigDb, SQLITE_TRANSIENT);
+ sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, SQLITE_TRANSIENT);
+ sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, SQLITE_TRANSIENT);
+#else
+ zType = columnType(&sNC, p, 0, 0, 0, 0);
+#endif
+ sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT);
+ }
+#endif /* !defined(SQLITE_OMIT_DECLTYPE) */
+}
+
+/*
+** Generate code that will tell the VDBE the names of columns
+** in the result set. This information is used to provide the
+** azCol[] values in the callback.
+*/
+static void generateColumnNames(
+ Parse *pParse, /* Parser context */
+ SrcList *pTabList, /* List of tables */
+ ExprList *pEList /* Expressions defining the result set */
+){
+ Vdbe *v = pParse->pVdbe;
+ int i, j;
+ sqlite3 *db = pParse->db;
+ int fullNames, shortNames;
+
+#ifndef SQLITE_OMIT_EXPLAIN
+ /* If this is an EXPLAIN, skip this step */
+ if( pParse->explain ){
+ return;
+ }
+#endif
+
+ if( pParse->colNamesSet || db->mallocFailed ) return;
+ assert( v!=0 );
+ assert( pTabList!=0 );
+ pParse->colNamesSet = 1;
+ fullNames = (db->flags & SQLITE_FullColNames)!=0;
+ shortNames = (db->flags & SQLITE_ShortColNames)!=0;
+ sqlite3VdbeSetNumCols(v, pEList->nExpr);
+ for(i=0; i<pEList->nExpr; i++){
+ Expr *p;
+ p = pEList->a[i].pExpr;
+ if( NEVER(p==0) ) continue;
+ if( pEList->a[i].zName ){
+ char *zName = pEList->a[i].zName;
+ sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT);
+ }else if( p->op==TK_COLUMN || p->op==TK_AGG_COLUMN ){
+ Table *pTab;
+ char *zCol;
+ int iCol = p->iColumn;
+ for(j=0; ALWAYS(j<pTabList->nSrc); j++){
+ if( pTabList->a[j].iCursor==p->iTable ) break;
+ }
+ assert( j<pTabList->nSrc );
+ pTab = pTabList->a[j].pTab;
+ if( iCol<0 ) iCol = pTab->iPKey;
+ assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
+ if( iCol<0 ){
+ zCol = "rowid";
+ }else{
+ zCol = pTab->aCol[iCol].zName;
+ }
+ if( !shortNames && !fullNames ){
+ sqlite3VdbeSetColName(v, i, COLNAME_NAME,
+ sqlite3DbStrDup(db, pEList->a[i].zSpan), SQLITE_DYNAMIC);
+ }else if( fullNames ){
+ char *zName = 0;
+ zName = sqlite3MPrintf(db, "%s.%s", pTab->zName, zCol);
+ sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_DYNAMIC);
+ }else{
+ sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, SQLITE_TRANSIENT);
+ }
+ }else{
+ const char *z = pEList->a[i].zSpan;
+ z = z==0 ? sqlite3MPrintf(db, "column%d", i+1) : sqlite3DbStrDup(db, z);
+ sqlite3VdbeSetColName(v, i, COLNAME_NAME, z, SQLITE_DYNAMIC);
+ }
+ }
+ generateColumnTypes(pParse, pTabList, pEList);
+}
+
+/*
+** Given an expression list (which is really the list of expressions
+** that form the result set of a SELECT statement) compute appropriate
+** column names for a table that would hold the expression list.
+**
+** All column names will be unique.
+**
+** Only the column names are computed. Column.zType, Column.zColl,
+** and other fields of Column are zeroed.
+**
+** Return SQLITE_OK on success. If a memory allocation error occurs,
+** store NULL in *paCol and 0 in *pnCol and return SQLITE_NOMEM.
+*/
+SQLITE_PRIVATE int sqlite3ColumnsFromExprList(
+ Parse *pParse, /* Parsing context */
+ ExprList *pEList, /* Expr list from which to derive column names */
+ i16 *pnCol, /* Write the number of columns here */
+ Column **paCol /* Write the new column list here */
+){
+ sqlite3 *db = pParse->db; /* Database connection */
+ int i, j; /* Loop counters */
+ u32 cnt; /* Index added to make the name unique */
+ Column *aCol, *pCol; /* For looping over result columns */
+ int nCol; /* Number of columns in the result set */
+ Expr *p; /* Expression for a single result column */
+ char *zName; /* Column name */
+ int nName; /* Size of name in zName[] */
+ Hash ht; /* Hash table of column names */
+
+ sqlite3HashInit(&ht);
+ if( pEList ){
+ nCol = pEList->nExpr;
+ aCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol);
+ testcase( aCol==0 );
+ }else{
+ nCol = 0;
+ aCol = 0;
+ }
+ assert( nCol==(i16)nCol );
+ *pnCol = nCol;
+ *paCol = aCol;
+
+ for(i=0, pCol=aCol; i<nCol && !db->mallocFailed; i++, pCol++){
+ /* Get an appropriate name for the column
+ */
+ p = sqlite3ExprSkipCollate(pEList->a[i].pExpr);
+ if( (zName = pEList->a[i].zName)!=0 ){
+ /* If the column contains an "AS <name>" phrase, use <name> as the name */
+ }else{
+ Expr *pColExpr = p; /* The expression that is the result column name */
+ Table *pTab; /* Table associated with this expression */
+ while( pColExpr->op==TK_DOT ){
+ pColExpr = pColExpr->pRight;
+ assert( pColExpr!=0 );
+ }
+ if( pColExpr->op==TK_COLUMN && ALWAYS(pColExpr->pTab!=0) ){
+ /* For columns use the column name name */
+ int iCol = pColExpr->iColumn;
+ pTab = pColExpr->pTab;
+ if( iCol<0 ) iCol = pTab->iPKey;
+ zName = iCol>=0 ? pTab->aCol[iCol].zName : "rowid";
+ }else if( pColExpr->op==TK_ID ){
+ assert( !ExprHasProperty(pColExpr, EP_IntValue) );
+ zName = pColExpr->u.zToken;
+ }else{
+ /* Use the original text of the column expression as its name */
+ zName = pEList->a[i].zSpan;
+ }
+ }
+ zName = sqlite3MPrintf(db, "%s", zName);
+
+ /* Make sure the column name is unique. If the name is not unique,
+ ** append an integer to the name so that it becomes unique.
+ */
+ cnt = 0;
+ while( zName && sqlite3HashFind(&ht, zName)!=0 ){
+ nName = sqlite3Strlen30(zName);
+ if( nName>0 ){
+ for(j=nName-1; j>0 && sqlite3Isdigit(zName[j]); j--){}
+ if( zName[j]==':' ) nName = j;
+ }
+ zName = sqlite3MPrintf(db, "%.*z:%u", nName, zName, ++cnt);
+ if( cnt>3 ) sqlite3_randomness(sizeof(cnt), &cnt);
+ }
+ pCol->zName = zName;
+ sqlite3ColumnPropertiesFromName(0, pCol);
+ if( zName && sqlite3HashInsert(&ht, zName, pCol)==pCol ){
+ sqlite3OomFault(db);
+ }
+ }
+ sqlite3HashClear(&ht);
+ if( db->mallocFailed ){
+ for(j=0; j<i; j++){
+ sqlite3DbFree(db, aCol[j].zName);
+ }
+ sqlite3DbFree(db, aCol);
+ *paCol = 0;
+ *pnCol = 0;
+ return SQLITE_NOMEM_BKPT;
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Add type and collation information to a column list based on
+** a SELECT statement.
+**
+** The column list presumably came from selectColumnNamesFromExprList().
+** The column list has only names, not types or collations. This
+** routine goes through and adds the types and collations.
+**
+** This routine requires that all identifiers in the SELECT
+** statement be resolved.
+*/
+SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation(
+ Parse *pParse, /* Parsing contexts */
+ Table *pTab, /* Add column type information to this table */
+ Select *pSelect /* SELECT used to determine types and collations */
+){
+ sqlite3 *db = pParse->db;
+ NameContext sNC;
+ Column *pCol;
+ CollSeq *pColl;
+ int i;
+ Expr *p;
+ struct ExprList_item *a;
+ u64 szAll = 0;
+
+ assert( pSelect!=0 );
+ assert( (pSelect->selFlags & SF_Resolved)!=0 );
+ assert( pTab->nCol==pSelect->pEList->nExpr || db->mallocFailed );
+ if( db->mallocFailed ) return;
+ memset(&sNC, 0, sizeof(sNC));
+ sNC.pSrcList = pSelect->pSrc;
+ a = pSelect->pEList->a;
+ for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
+ const char *zType;
+ int n, m;
+ p = a[i].pExpr;
+ zType = columnType(&sNC, p, 0, 0, 0, &pCol->szEst);
+ szAll += pCol->szEst;
+ pCol->affinity = sqlite3ExprAffinity(p);
+ if( zType && (m = sqlite3Strlen30(zType))>0 ){
+ n = sqlite3Strlen30(pCol->zName);
+ pCol->zName = sqlite3DbReallocOrFree(db, pCol->zName, n+m+2);
+ if( pCol->zName ){
+ memcpy(&pCol->zName[n+1], zType, m+1);
+ pCol->colFlags |= COLFLAG_HASTYPE;
+ }
+ }
+ if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_BLOB;
+ pColl = sqlite3ExprCollSeq(pParse, p);
+ if( pColl && pCol->zColl==0 ){
+ pCol->zColl = sqlite3DbStrDup(db, pColl->zName);
+ }
+ }
+ pTab->szTabRow = sqlite3LogEst(szAll*4);
+}
+
+/*
+** Given a SELECT statement, generate a Table structure that describes
+** the result set of that SELECT.
+*/
+SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
+ Table *pTab;
+ sqlite3 *db = pParse->db;
+ int savedFlags;
+
+ savedFlags = db->flags;
+ db->flags &= ~SQLITE_FullColNames;
+ db->flags |= SQLITE_ShortColNames;
+ sqlite3SelectPrep(pParse, pSelect, 0);
+ if( pParse->nErr ) return 0;
+ while( pSelect->pPrior ) pSelect = pSelect->pPrior;
+ db->flags = savedFlags;
+ pTab = sqlite3DbMallocZero(db, sizeof(Table) );
+ if( pTab==0 ){
+ return 0;
+ }
+ /* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside
+ ** is disabled */
+ assert( db->lookaside.bDisable );
+ pTab->nTabRef = 1;
+ pTab->zName = 0;
+ pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
+ sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
+ sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSelect);
+ pTab->iPKey = -1;
+ if( db->mallocFailed ){
+ sqlite3DeleteTable(db, pTab);
+ return 0;
+ }
+ return pTab;
+}
+
+/*
+** Get a VDBE for the given parser context. Create a new one if necessary.
+** If an error occurs, return NULL and leave a message in pParse.
+*/
+static SQLITE_NOINLINE Vdbe *allocVdbe(Parse *pParse){
+ Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(pParse);
+ if( v ) sqlite3VdbeAddOp2(v, OP_Init, 0, 1);
+ if( pParse->pToplevel==0
+ && OptimizationEnabled(pParse->db,SQLITE_FactorOutConst)
+ ){
+ pParse->okConstFactor = 1;
+ }
+ return v;
+}
+SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse *pParse){
+ Vdbe *v = pParse->pVdbe;
+ return v ? v : allocVdbe(pParse);
+}
+
+
+/*
+** Compute the iLimit and iOffset fields of the SELECT based on the
+** pLimit and pOffset expressions. pLimit and pOffset hold the expressions
+** that appear in the original SQL statement after the LIMIT and OFFSET
+** keywords. Or NULL if those keywords are omitted. iLimit and iOffset
+** are the integer memory register numbers for counters used to compute
+** the limit and offset. If there is no limit and/or offset, then
+** iLimit and iOffset are negative.
+**
+** This routine changes the values of iLimit and iOffset only if
+** a limit or offset is defined by pLimit and pOffset. iLimit and
+** iOffset should have been preset to appropriate default values (zero)
+** prior to calling this routine.
+**
+** The iOffset register (if it exists) is initialized to the value
+** of the OFFSET. The iLimit register is initialized to LIMIT. Register
+** iOffset+1 is initialized to LIMIT+OFFSET.
+**
+** Only if pLimit!=0 or pOffset!=0 do the limit registers get
+** redefined. The UNION ALL operator uses this property to force
+** the reuse of the same limit and offset registers across multiple
+** SELECT statements.
+*/
+static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
+ Vdbe *v = 0;
+ int iLimit = 0;
+ int iOffset;
+ int n;
+ if( p->iLimit ) return;
+
+ /*
+ ** "LIMIT -1" always shows all rows. There is some
+ ** controversy about what the correct behavior should be.
+ ** The current implementation interprets "LIMIT 0" to mean
+ ** no rows.
+ */
+ sqlite3ExprCacheClear(pParse);
+ assert( p->pOffset==0 || p->pLimit!=0 );
+ if( p->pLimit ){
+ p->iLimit = iLimit = ++pParse->nMem;
+ v = sqlite3GetVdbe(pParse);
+ assert( v!=0 );
+ if( sqlite3ExprIsInteger(p->pLimit, &n) ){
+ sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit);
+ VdbeComment((v, "LIMIT counter"));
+ if( n==0 ){
+ sqlite3VdbeGoto(v, iBreak);
+ }else if( n>=0 && p->nSelectRow>sqlite3LogEst((u64)n) ){
+ p->nSelectRow = sqlite3LogEst((u64)n);
+ p->selFlags |= SF_FixedLimit;
+ }
+ }else{
+ sqlite3ExprCode(pParse, p->pLimit, iLimit);
+ sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); VdbeCoverage(v);
+ VdbeComment((v, "LIMIT counter"));
+ sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, iBreak); VdbeCoverage(v);
+ }
+ if( p->pOffset ){
+ p->iOffset = iOffset = ++pParse->nMem;
+ pParse->nMem++; /* Allocate an extra register for limit+offset */
+ sqlite3ExprCode(pParse, p->pOffset, iOffset);
+ sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v);
+ VdbeComment((v, "OFFSET counter"));
+ sqlite3VdbeAddOp3(v, OP_OffsetLimit, iLimit, iOffset+1, iOffset);
+ VdbeComment((v, "LIMIT+OFFSET"));
+ }
+ }
+}
+
+#ifndef SQLITE_OMIT_COMPOUND_SELECT
+/*
+** Return the appropriate collating sequence for the iCol-th column of
+** the result set for the compound-select statement "p". Return NULL if
+** the column has no default collating sequence.
+**
+** The collating sequence for the compound select is taken from the
+** left-most term of the select that has a collating sequence.
+*/
+static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){
+ CollSeq *pRet;
+ if( p->pPrior ){
+ pRet = multiSelectCollSeq(pParse, p->pPrior, iCol);
+ }else{
+ pRet = 0;
+ }
+ assert( iCol>=0 );
+ /* iCol must be less than p->pEList->nExpr. Otherwise an error would
+ ** have been thrown during name resolution and we would not have gotten
+ ** this far */
+ if( pRet==0 && ALWAYS(iCol<p->pEList->nExpr) ){
+ pRet = sqlite3ExprCollSeq(pParse, p->pEList->a[iCol].pExpr);
+ }
+ return pRet;
+}
+
+/*
+** The select statement passed as the second parameter is a compound SELECT
+** with an ORDER BY clause. This function allocates and returns a KeyInfo
+** structure suitable for implementing the ORDER BY.
+**
+** Space to hold the KeyInfo structure is obtained from malloc. The calling
+** function is responsible for ensuring that this structure is eventually
+** freed.
+*/
+static KeyInfo *multiSelectOrderByKeyInfo(Parse *pParse, Select *p, int nExtra){
+ ExprList *pOrderBy = p->pOrderBy;
+ int nOrderBy = p->pOrderBy->nExpr;
+ sqlite3 *db = pParse->db;
+ KeyInfo *pRet = sqlite3KeyInfoAlloc(db, nOrderBy+nExtra, 1);
+ if( pRet ){
+ int i;
+ for(i=0; i<nOrderBy; i++){
+ struct ExprList_item *pItem = &pOrderBy->a[i];
+ Expr *pTerm = pItem->pExpr;
+ CollSeq *pColl;
+
+ if( pTerm->flags & EP_Collate ){
+ pColl = sqlite3ExprCollSeq(pParse, pTerm);
+ }else{
+ pColl = multiSelectCollSeq(pParse, p, pItem->u.x.iOrderByCol-1);
+ if( pColl==0 ) pColl = db->pDfltColl;
+ pOrderBy->a[i].pExpr =
+ sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName);
+ }
+ assert( sqlite3KeyInfoIsWriteable(pRet) );
+ pRet->aColl[i] = pColl;
+ pRet->aSortOrder[i] = pOrderBy->a[i].sortOrder;
+ }
+ }
+
+ return pRet;
+}
+
+#ifndef SQLITE_OMIT_CTE
+/*
+** This routine generates VDBE code to compute the content of a WITH RECURSIVE
+** query of the form:
+**
+** <recursive-table> AS (<setup-query> UNION [ALL] <recursive-query>)
+** \___________/ \_______________/
+** p->pPrior p
+**
+**
+** There is exactly one reference to the recursive-table in the FROM clause
+** of recursive-query, marked with the SrcList->a[].fg.isRecursive flag.
+**
+** The setup-query runs once to generate an initial set of rows that go
+** into a Queue table. Rows are extracted from the Queue table one by
+** one. Each row extracted from Queue is output to pDest. Then the single
+** extracted row (now in the iCurrent table) becomes the content of the
+** recursive-table for a recursive-query run. The output of the recursive-query
+** is added back into the Queue table. Then another row is extracted from Queue
+** and the iteration continues until the Queue table is empty.
+**
+** If the compound query operator is UNION then no duplicate rows are ever
+** inserted into the Queue table. The iDistinct table keeps a copy of all rows
+** that have ever been inserted into Queue and causes duplicates to be
+** discarded. If the operator is UNION ALL, then duplicates are allowed.
+**
+** If the query has an ORDER BY, then entries in the Queue table are kept in
+** ORDER BY order and the first entry is extracted for each cycle. Without
+** an ORDER BY, the Queue table is just a FIFO.
+**
+** If a LIMIT clause is provided, then the iteration stops after LIMIT rows
+** have been output to pDest. A LIMIT of zero means to output no rows and a
+** negative LIMIT means to output all rows. If there is also an OFFSET clause
+** with a positive value, then the first OFFSET outputs are discarded rather
+** than being sent to pDest. The LIMIT count does not begin until after OFFSET
+** rows have been skipped.
+*/
+static void generateWithRecursiveQuery(
+ Parse *pParse, /* Parsing context */
+ Select *p, /* The recursive SELECT to be coded */
+ SelectDest *pDest /* What to do with query results */
+){
+ SrcList *pSrc = p->pSrc; /* The FROM clause of the recursive query */
+ int nCol = p->pEList->nExpr; /* Number of columns in the recursive table */
+ Vdbe *v = pParse->pVdbe; /* The prepared statement under construction */
+ Select *pSetup = p->pPrior; /* The setup query */
+ int addrTop; /* Top of the loop */
+ int addrCont, addrBreak; /* CONTINUE and BREAK addresses */
+ int iCurrent = 0; /* The Current table */
+ int regCurrent; /* Register holding Current table */
+ int iQueue; /* The Queue table */
+ int iDistinct = 0; /* To ensure unique results if UNION */
+ int eDest = SRT_Fifo; /* How to write to Queue */
+ SelectDest destQueue; /* SelectDest targetting the Queue table */
+ int i; /* Loop counter */
+ int rc; /* Result code */
+ ExprList *pOrderBy; /* The ORDER BY clause */
+ Expr *pLimit, *pOffset; /* Saved LIMIT and OFFSET */
+ int regLimit, regOffset; /* Registers used by LIMIT and OFFSET */
+
+ /* Obtain authorization to do a recursive query */
+ if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return;
+
+ /* Process the LIMIT and OFFSET clauses, if they exist */
+ addrBreak = sqlite3VdbeMakeLabel(v);
+ p->nSelectRow = 320; /* 4 billion rows */
+ computeLimitRegisters(pParse, p, addrBreak);
+ pLimit = p->pLimit;
+ pOffset = p->pOffset;
+ regLimit = p->iLimit;
+ regOffset = p->iOffset;
+ p->pLimit = p->pOffset = 0;
+ p->iLimit = p->iOffset = 0;
+ pOrderBy = p->pOrderBy;
+
+ /* Locate the cursor number of the Current table */
+ for(i=0; ALWAYS(i<pSrc->nSrc); i++){
+ if( pSrc->a[i].fg.isRecursive ){
+ iCurrent = pSrc->a[i].iCursor;
+ break;
+ }
+ }
+
+ /* Allocate cursors numbers for Queue and Distinct. The cursor number for
+ ** the Distinct table must be exactly one greater than Queue in order
+ ** for the SRT_DistFifo and SRT_DistQueue destinations to work. */
+ iQueue = pParse->nTab++;
+ if( p->op==TK_UNION ){
+ eDest = pOrderBy ? SRT_DistQueue : SRT_DistFifo;
+ iDistinct = pParse->nTab++;
+ }else{
+ eDest = pOrderBy ? SRT_Queue : SRT_Fifo;
+ }
+ sqlite3SelectDestInit(&destQueue, eDest, iQueue);
+
+ /* Allocate cursors for Current, Queue, and Distinct. */
+ regCurrent = ++pParse->nMem;
+ sqlite3VdbeAddOp3(v, OP_OpenPseudo, iCurrent, regCurrent, nCol);
+ if( pOrderBy ){
+ KeyInfo *pKeyInfo = multiSelectOrderByKeyInfo(pParse, p, 1);
+ sqlite3VdbeAddOp4(v, OP_OpenEphemeral, iQueue, pOrderBy->nExpr+2, 0,
+ (char*)pKeyInfo, P4_KEYINFO);
+ destQueue.pOrderBy = pOrderBy;
+ }else{
+ sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iQueue, nCol);
+ }
+ VdbeComment((v, "Queue table"));
+ if( iDistinct ){
+ p->addrOpenEphm[0] = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iDistinct, 0);
+ p->selFlags |= SF_UsesEphemeral;
+ }
+
+ /* Detach the ORDER BY clause from the compound SELECT */
+ p->pOrderBy = 0;
+
+ /* Store the results of the setup-query in Queue. */
+ pSetup->pNext = 0;
+ rc = sqlite3Select(pParse, pSetup, &destQueue);
+ pSetup->pNext = p;
+ if( rc ) goto end_of_recursive_query;
+
+ /* Find the next row in the Queue and output that row */
+ addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iQueue, addrBreak); VdbeCoverage(v);
+
+ /* Transfer the next row in Queue over to Current */
+ sqlite3VdbeAddOp1(v, OP_NullRow, iCurrent); /* To reset column cache */
+ if( pOrderBy ){
+ sqlite3VdbeAddOp3(v, OP_Column, iQueue, pOrderBy->nExpr+1, regCurrent);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_RowData, iQueue, regCurrent);
+ }
+ sqlite3VdbeAddOp1(v, OP_Delete, iQueue);
+
+ /* Output the single row in Current */
+ addrCont = sqlite3VdbeMakeLabel(v);
+ codeOffset(v, regOffset, addrCont);
+ selectInnerLoop(pParse, p, p->pEList, iCurrent,
+ 0, 0, pDest, addrCont, addrBreak);
+ if( regLimit ){
+ sqlite3VdbeAddOp2(v, OP_DecrJumpZero, regLimit, addrBreak);
+ VdbeCoverage(v);
+ }
+ sqlite3VdbeResolveLabel(v, addrCont);
+
+ /* Execute the recursive SELECT taking the single row in Current as
+ ** the value for the recursive-table. Store the results in the Queue.
+ */
+ if( p->selFlags & SF_Aggregate ){
+ sqlite3ErrorMsg(pParse, "recursive aggregate queries not supported");
+ }else{
+ p->pPrior = 0;
+ sqlite3Select(pParse, p, &destQueue);
+ assert( p->pPrior==0 );
+ p->pPrior = pSetup;
+ }
+
+ /* Keep running the loop until the Queue is empty */
+ sqlite3VdbeGoto(v, addrTop);
+ sqlite3VdbeResolveLabel(v, addrBreak);
+
+end_of_recursive_query:
+ sqlite3ExprListDelete(pParse->db, p->pOrderBy);
+ p->pOrderBy = pOrderBy;
+ p->pLimit = pLimit;
+ p->pOffset = pOffset;
+ return;
+}
+#endif /* SQLITE_OMIT_CTE */
+
+/* Forward references */
+static int multiSelectOrderBy(
+ Parse *pParse, /* Parsing context */
+ Select *p, /* The right-most of SELECTs to be coded */
+ SelectDest *pDest /* What to do with query results */
+);
+
+/*
+** Handle the special case of a compound-select that originates from a
+** VALUES clause. By handling this as a special case, we avoid deep
+** recursion, and thus do not need to enforce the SQLITE_LIMIT_COMPOUND_SELECT
+** on a VALUES clause.
+**
+** Because the Select object originates from a VALUES clause:
+** (1) It has no LIMIT or OFFSET
+** (2) All terms are UNION ALL
+** (3) There is no ORDER BY clause
+*/
+static int multiSelectValues(
+ Parse *pParse, /* Parsing context */
+ Select *p, /* The right-most of SELECTs to be coded */
+ SelectDest *pDest /* What to do with query results */
+){
+ Select *pPrior;
+ int nRow = 1;
+ int rc = 0;
+ assert( p->selFlags & SF_MultiValue );
+ do{
+ assert( p->selFlags & SF_Values );
+ assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) );
+ assert( p->pLimit==0 );
+ assert( p->pOffset==0 );
+ assert( p->pNext==0 || p->pEList->nExpr==p->pNext->pEList->nExpr );
+ if( p->pPrior==0 ) break;
+ assert( p->pPrior->pNext==p );
+ p = p->pPrior;
+ nRow++;
+ }while(1);
+ while( p ){
+ pPrior = p->pPrior;
+ p->pPrior = 0;
+ rc = sqlite3Select(pParse, p, pDest);
+ p->pPrior = pPrior;
+ if( rc ) break;
+ p->nSelectRow = nRow;
+ p = p->pNext;
+ }
+ return rc;
+}
+
+/*
+** This routine is called to process a compound query form from
+** two or more separate queries using UNION, UNION ALL, EXCEPT, or
+** INTERSECT
+**
+** "p" points to the right-most of the two queries. the query on the
+** left is p->pPrior. The left query could also be a compound query
+** in which case this routine will be called recursively.
+**
+** The results of the total query are to be written into a destination
+** of type eDest with parameter iParm.
+**
+** Example 1: Consider a three-way compound SQL statement.
+**
+** SELECT a FROM t1 UNION SELECT b FROM t2 UNION SELECT c FROM t3
+**
+** This statement is parsed up as follows:
+**
+** SELECT c FROM t3
+** |
+** `-----> SELECT b FROM t2
+** |
+** `------> SELECT a FROM t1
+**
+** The arrows in the diagram above represent the Select.pPrior pointer.
+** So if this routine is called with p equal to the t3 query, then
+** pPrior will be the t2 query. p->op will be TK_UNION in this case.
+**
+** Notice that because of the way SQLite parses compound SELECTs, the
+** individual selects always group from left to right.
+*/
+static int multiSelect(
+ Parse *pParse, /* Parsing context */
+ Select *p, /* The right-most of SELECTs to be coded */
+ SelectDest *pDest /* What to do with query results */
+){
+ int rc = SQLITE_OK; /* Success code from a subroutine */
+ Select *pPrior; /* Another SELECT immediately to our left */
+ Vdbe *v; /* Generate code to this VDBE */
+ SelectDest dest; /* Alternative data destination */
+ Select *pDelete = 0; /* Chain of simple selects to delete */
+ sqlite3 *db; /* Database connection */
+#ifndef SQLITE_OMIT_EXPLAIN
+ int iSub1 = 0; /* EQP id of left-hand query */
+ int iSub2 = 0; /* EQP id of right-hand query */
+#endif
+
+ /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs. Only
+ ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT.
+ */
+ assert( p && p->pPrior ); /* Calling function guarantees this much */
+ assert( (p->selFlags & SF_Recursive)==0 || p->op==TK_ALL || p->op==TK_UNION );
+ db = pParse->db;
+ pPrior = p->pPrior;
+ dest = *pDest;
+ if( pPrior->pOrderBy ){
+ sqlite3ErrorMsg(pParse,"ORDER BY clause should come after %s not before",
+ selectOpName(p->op));
+ rc = 1;
+ goto multi_select_end;
+ }
+ if( pPrior->pLimit ){
+ sqlite3ErrorMsg(pParse,"LIMIT clause should come after %s not before",
+ selectOpName(p->op));
+ rc = 1;
+ goto multi_select_end;
+ }
+
+ v = sqlite3GetVdbe(pParse);
+ assert( v!=0 ); /* The VDBE already created by calling function */
+
+ /* Create the destination temporary table if necessary
+ */
+ if( dest.eDest==SRT_EphemTab ){
+ assert( p->pEList );
+ sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iSDParm, p->pEList->nExpr);
+ dest.eDest = SRT_Table;
+ }
+
+ /* Special handling for a compound-select that originates as a VALUES clause.
+ */
+ if( p->selFlags & SF_MultiValue ){
+ rc = multiSelectValues(pParse, p, &dest);
+ goto multi_select_end;
+ }
+
+ /* Make sure all SELECTs in the statement have the same number of elements
+ ** in their result sets.
+ */
+ assert( p->pEList && pPrior->pEList );
+ assert( p->pEList->nExpr==pPrior->pEList->nExpr );
+
+#ifndef SQLITE_OMIT_CTE
+ if( p->selFlags & SF_Recursive ){
+ generateWithRecursiveQuery(pParse, p, &dest);
+ }else
+#endif
+
+ /* Compound SELECTs that have an ORDER BY clause are handled separately.
+ */
+ if( p->pOrderBy ){
+ return multiSelectOrderBy(pParse, p, pDest);
+ }else
+
+ /* Generate code for the left and right SELECT statements.
+ */
+ switch( p->op ){
+ case TK_ALL: {
+ int addr = 0;
+ int nLimit;
+ assert( !pPrior->pLimit );
+ pPrior->iLimit = p->iLimit;
+ pPrior->iOffset = p->iOffset;
+ pPrior->pLimit = p->pLimit;
+ pPrior->pOffset = p->pOffset;
+ explainSetInteger(iSub1, pParse->iNextSelectId);
+ rc = sqlite3Select(pParse, pPrior, &dest);
+ p->pLimit = 0;
+ p->pOffset = 0;
+ if( rc ){
+ goto multi_select_end;
+ }
+ p->pPrior = 0;
+ p->iLimit = pPrior->iLimit;
+ p->iOffset = pPrior->iOffset;
+ if( p->iLimit ){
+ addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v);
+ VdbeComment((v, "Jump ahead if LIMIT reached"));
+ if( p->iOffset ){
+ sqlite3VdbeAddOp3(v, OP_OffsetLimit,
+ p->iLimit, p->iOffset+1, p->iOffset);
+ }
+ }
+ explainSetInteger(iSub2, pParse->iNextSelectId);
+ rc = sqlite3Select(pParse, p, &dest);
+ testcase( rc!=SQLITE_OK );
+ pDelete = p->pPrior;
+ p->pPrior = pPrior;
+ p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
+ if( pPrior->pLimit
+ && sqlite3ExprIsInteger(pPrior->pLimit, &nLimit)
+ && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit)
+ ){
+ p->nSelectRow = sqlite3LogEst((u64)nLimit);
+ }
+ if( addr ){
+ sqlite3VdbeJumpHere(v, addr);
+ }
+ break;
+ }
+ case TK_EXCEPT:
+ case TK_UNION: {
+ int unionTab; /* Cursor number of the temporary table holding result */
+ u8 op = 0; /* One of the SRT_ operations to apply to self */
+ int priorOp; /* The SRT_ operation to apply to prior selects */
+ Expr *pLimit, *pOffset; /* Saved values of p->nLimit and p->nOffset */
+ int addr;
+ SelectDest uniondest;
+
+ testcase( p->op==TK_EXCEPT );
+ testcase( p->op==TK_UNION );
+ priorOp = SRT_Union;
+ if( dest.eDest==priorOp ){
+ /* We can reuse a temporary table generated by a SELECT to our
+ ** right.
+ */
+ assert( p->pLimit==0 ); /* Not allowed on leftward elements */
+ assert( p->pOffset==0 ); /* Not allowed on leftward elements */
+ unionTab = dest.iSDParm;
+ }else{
+ /* We will need to create our own temporary table to hold the
+ ** intermediate results.
+ */
+ unionTab = pParse->nTab++;
+ assert( p->pOrderBy==0 );
+ addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0);
+ assert( p->addrOpenEphm[0] == -1 );
+ p->addrOpenEphm[0] = addr;
+ findRightmost(p)->selFlags |= SF_UsesEphemeral;
+ assert( p->pEList );
+ }
+
+ /* Code the SELECT statements to our left
+ */
+ assert( !pPrior->pOrderBy );
+ sqlite3SelectDestInit(&uniondest, priorOp, unionTab);
+ explainSetInteger(iSub1, pParse->iNextSelectId);
+ rc = sqlite3Select(pParse, pPrior, &uniondest);
+ if( rc ){
+ goto multi_select_end;
+ }
+
+ /* Code the current SELECT statement
+ */
+ if( p->op==TK_EXCEPT ){
+ op = SRT_Except;
+ }else{
+ assert( p->op==TK_UNION );
+ op = SRT_Union;
+ }
+ p->pPrior = 0;
+ pLimit = p->pLimit;
+ p->pLimit = 0;
+ pOffset = p->pOffset;
+ p->pOffset = 0;
+ uniondest.eDest = op;
+ explainSetInteger(iSub2, pParse->iNextSelectId);
+ rc = sqlite3Select(pParse, p, &uniondest);
+ testcase( rc!=SQLITE_OK );
+ /* Query flattening in sqlite3Select() might refill p->pOrderBy.
+ ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */
+ sqlite3ExprListDelete(db, p->pOrderBy);
+ pDelete = p->pPrior;
+ p->pPrior = pPrior;
+ p->pOrderBy = 0;
+ if( p->op==TK_UNION ){
+ p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
+ }
+ sqlite3ExprDelete(db, p->pLimit);
+ p->pLimit = pLimit;
+ p->pOffset = pOffset;
+ p->iLimit = 0;
+ p->iOffset = 0;
+
+ /* Convert the data in the temporary table into whatever form
+ ** it is that we currently need.
+ */
+ assert( unionTab==dest.iSDParm || dest.eDest!=priorOp );
+ if( dest.eDest!=priorOp ){
+ int iCont, iBreak, iStart;
+ assert( p->pEList );
+ if( dest.eDest==SRT_Output ){
+ Select *pFirst = p;
+ while( pFirst->pPrior ) pFirst = pFirst->pPrior;
+ generateColumnNames(pParse, pFirst->pSrc, pFirst->pEList);
+ }
+ iBreak = sqlite3VdbeMakeLabel(v);
+ iCont = sqlite3VdbeMakeLabel(v);
+ computeLimitRegisters(pParse, p, iBreak);
+ sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v);
+ iStart = sqlite3VdbeCurrentAddr(v);
+ selectInnerLoop(pParse, p, p->pEList, unionTab,
+ 0, 0, &dest, iCont, iBreak);
+ sqlite3VdbeResolveLabel(v, iCont);
+ sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v);
+ sqlite3VdbeResolveLabel(v, iBreak);
+ sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0);
+ }
+ break;
+ }
+ default: assert( p->op==TK_INTERSECT ); {
+ int tab1, tab2;
+ int iCont, iBreak, iStart;
+ Expr *pLimit, *pOffset;
+ int addr;
+ SelectDest intersectdest;
+ int r1;
+
+ /* INTERSECT is different from the others since it requires
+ ** two temporary tables. Hence it has its own case. Begin
+ ** by allocating the tables we will need.
+ */
+ tab1 = pParse->nTab++;
+ tab2 = pParse->nTab++;
+ assert( p->pOrderBy==0 );
+
+ addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0);
+ assert( p->addrOpenEphm[0] == -1 );
+ p->addrOpenEphm[0] = addr;
+ findRightmost(p)->selFlags |= SF_UsesEphemeral;
+ assert( p->pEList );
+
+ /* Code the SELECTs to our left into temporary table "tab1".
+ */
+ sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1);
+ explainSetInteger(iSub1, pParse->iNextSelectId);
+ rc = sqlite3Select(pParse, pPrior, &intersectdest);
+ if( rc ){
+ goto multi_select_end;
+ }
+
+ /* Code the current SELECT into temporary table "tab2"
+ */
+ addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0);
+ assert( p->addrOpenEphm[1] == -1 );
+ p->addrOpenEphm[1] = addr;
+ p->pPrior = 0;
+ pLimit = p->pLimit;
+ p->pLimit = 0;
+ pOffset = p->pOffset;
+ p->pOffset = 0;
+ intersectdest.iSDParm = tab2;
+ explainSetInteger(iSub2, pParse->iNextSelectId);
+ rc = sqlite3Select(pParse, p, &intersectdest);
+ testcase( rc!=SQLITE_OK );
+ pDelete = p->pPrior;
+ p->pPrior = pPrior;
+ if( p->nSelectRow>pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow;
+ sqlite3ExprDelete(db, p->pLimit);
+ p->pLimit = pLimit;
+ p->pOffset = pOffset;
+
+ /* Generate code to take the intersection of the two temporary
+ ** tables.
+ */
+ assert( p->pEList );
+ if( dest.eDest==SRT_Output ){
+ Select *pFirst = p;
+ while( pFirst->pPrior ) pFirst = pFirst->pPrior;
+ generateColumnNames(pParse, pFirst->pSrc, pFirst->pEList);
+ }
+ iBreak = sqlite3VdbeMakeLabel(v);
+ iCont = sqlite3VdbeMakeLabel(v);
+ computeLimitRegisters(pParse, p, iBreak);
+ sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v);
+ r1 = sqlite3GetTempReg(pParse);
+ iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1);
+ sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); VdbeCoverage(v);
+ sqlite3ReleaseTempReg(pParse, r1);
+ selectInnerLoop(pParse, p, p->pEList, tab1,
+ 0, 0, &dest, iCont, iBreak);
+ sqlite3VdbeResolveLabel(v, iCont);
+ sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v);
+ sqlite3VdbeResolveLabel(v, iBreak);
+ sqlite3VdbeAddOp2(v, OP_Close, tab2, 0);
+ sqlite3VdbeAddOp2(v, OP_Close, tab1, 0);
+ break;
+ }
+ }
+
+ explainComposite(pParse, p->op, iSub1, iSub2, p->op!=TK_ALL);
+
+ /* Compute collating sequences used by
+ ** temporary tables needed to implement the compound select.
+ ** Attach the KeyInfo structure to all temporary tables.
+ **
+ ** This section is run by the right-most SELECT statement only.
+ ** SELECT statements to the left always skip this part. The right-most
+ ** SELECT might also skip this part if it has no ORDER BY clause and
+ ** no temp tables are required.
+ */
+ if( p->selFlags & SF_UsesEphemeral ){
+ int i; /* Loop counter */
+ KeyInfo *pKeyInfo; /* Collating sequence for the result set */
+ Select *pLoop; /* For looping through SELECT statements */
+ CollSeq **apColl; /* For looping through pKeyInfo->aColl[] */
+ int nCol; /* Number of columns in result set */
+
+ assert( p->pNext==0 );
+ nCol = p->pEList->nExpr;
+ pKeyInfo = sqlite3KeyInfoAlloc(db, nCol, 1);
+ if( !pKeyInfo ){
+ rc = SQLITE_NOMEM_BKPT;
+ goto multi_select_end;
+ }
+ for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
+ *apColl = multiSelectCollSeq(pParse, p, i);
+ if( 0==*apColl ){
+ *apColl = db->pDfltColl;
+ }
+ }
+
+ for(pLoop=p; pLoop; pLoop=pLoop->pPrior){
+ for(i=0; i<2; i++){
+ int addr = pLoop->addrOpenEphm[i];
+ if( addr<0 ){
+ /* If [0] is unused then [1] is also unused. So we can
+ ** always safely abort as soon as the first unused slot is found */
+ assert( pLoop->addrOpenEphm[1]<0 );
+ break;
+ }
+ sqlite3VdbeChangeP2(v, addr, nCol);
+ sqlite3VdbeChangeP4(v, addr, (char*)sqlite3KeyInfoRef(pKeyInfo),
+ P4_KEYINFO);
+ pLoop->addrOpenEphm[i] = -1;
+ }
+ }
+ sqlite3KeyInfoUnref(pKeyInfo);
+ }
+
+multi_select_end:
+ pDest->iSdst = dest.iSdst;
+ pDest->nSdst = dest.nSdst;
+ sqlite3SelectDelete(db, pDelete);
+ return rc;
+}
+#endif /* SQLITE_OMIT_COMPOUND_SELECT */
+
+/*
+** Error message for when two or more terms of a compound select have different
+** size result sets.
+*/
+SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p){
+ if( p->selFlags & SF_Values ){
+ sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms");
+ }else{
+ sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
+ " do not have the same number of result columns", selectOpName(p->op));
+ }
+}
+
+/*
+** Code an output subroutine for a coroutine implementation of a
+** SELECT statment.
+**
+** The data to be output is contained in pIn->iSdst. There are
+** pIn->nSdst columns to be output. pDest is where the output should
+** be sent.
+**
+** regReturn is the number of the register holding the subroutine
+** return address.
+**
+** If regPrev>0 then it is the first register in a vector that
+** records the previous output. mem[regPrev] is a flag that is false
+** if there has been no previous output. If regPrev>0 then code is
+** generated to suppress duplicates. pKeyInfo is used for comparing
+** keys.
+**
+** If the LIMIT found in p->iLimit is reached, jump immediately to
+** iBreak.
+*/
+static int generateOutputSubroutine(
+ Parse *pParse, /* Parsing context */
+ Select *p, /* The SELECT statement */
+ SelectDest *pIn, /* Coroutine supplying data */
+ SelectDest *pDest, /* Where to send the data */
+ int regReturn, /* The return address register */
+ int regPrev, /* Previous result register. No uniqueness if 0 */
+ KeyInfo *pKeyInfo, /* For comparing with previous entry */
+ int iBreak /* Jump here if we hit the LIMIT */
+){
+ Vdbe *v = pParse->pVdbe;
+ int iContinue;
+ int addr;
+
+ addr = sqlite3VdbeCurrentAddr(v);
+ iContinue = sqlite3VdbeMakeLabel(v);
+
+ /* Suppress duplicates for UNION, EXCEPT, and INTERSECT
+ */
+ if( regPrev ){
+ int addr1, addr2;
+ addr1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); VdbeCoverage(v);
+ addr2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst,
+ (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
+ sqlite3VdbeAddOp3(v, OP_Jump, addr2+2, iContinue, addr2+2); VdbeCoverage(v);
+ sqlite3VdbeJumpHere(v, addr1);
+ sqlite3VdbeAddOp3(v, OP_Copy, pIn->iSdst, regPrev+1, pIn->nSdst-1);
+ sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev);
+ }
+ if( pParse->db->mallocFailed ) return 0;
+
+ /* Suppress the first OFFSET entries if there is an OFFSET clause
+ */
+ codeOffset(v, p->iOffset, iContinue);
+
+ assert( pDest->eDest!=SRT_Exists );
+ assert( pDest->eDest!=SRT_Table );
+ switch( pDest->eDest ){
+ /* Store the result as data using a unique key.
+ */
+ case SRT_EphemTab: {
+ int r1 = sqlite3GetTempReg(pParse);
+ int r2 = sqlite3GetTempReg(pParse);
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1);
+ sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iSDParm, r2);
+ sqlite3VdbeAddOp3(v, OP_Insert, pDest->iSDParm, r1, r2);
+ sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
+ sqlite3ReleaseTempReg(pParse, r2);
+ sqlite3ReleaseTempReg(pParse, r1);
+ break;
+ }
+
+#ifndef SQLITE_OMIT_SUBQUERY
+ /* If we are creating a set for an "expr IN (SELECT ...)".
+ */
+ case SRT_Set: {
+ int r1;
+ testcase( pIn->nSdst>1 );
+ r1 = sqlite3GetTempReg(pParse);
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst,
+ r1, pDest->zAffSdst, pIn->nSdst);
+ sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1,
+ pIn->iSdst, pIn->nSdst);
+ sqlite3ReleaseTempReg(pParse, r1);
+ break;
+ }
+
+ /* If this is a scalar select that is part of an expression, then
+ ** store the results in the appropriate memory cell and break out
+ ** of the scan loop.
+ */
+ case SRT_Mem: {
+ assert( pIn->nSdst==1 || pParse->nErr>0 ); testcase( pIn->nSdst!=1 );
+ sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, 1);
+ /* The LIMIT clause will jump out of the loop for us */
+ break;
+ }
+#endif /* #ifndef SQLITE_OMIT_SUBQUERY */
+
+ /* The results are stored in a sequence of registers
+ ** starting at pDest->iSdst. Then the co-routine yields.
+ */
+ case SRT_Coroutine: {
+ if( pDest->iSdst==0 ){
+ pDest->iSdst = sqlite3GetTempRange(pParse, pIn->nSdst);
+ pDest->nSdst = pIn->nSdst;
+ }
+ sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pIn->nSdst);
+ sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
+ break;
+ }
+
+ /* If none of the above, then the result destination must be
+ ** SRT_Output. This routine is never called with any other
+ ** destination other than the ones handled above or SRT_Output.
+ **
+ ** For SRT_Output, results are stored in a sequence of registers.
+ ** Then the OP_ResultRow opcode is used to cause sqlite3_step() to
+ ** return the next row of result.
+ */
+ default: {
+ assert( pDest->eDest==SRT_Output );
+ sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iSdst, pIn->nSdst);
+ sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst);
+ break;
+ }
+ }
+
+ /* Jump to the end of the loop if the LIMIT is reached.
+ */
+ if( p->iLimit ){
+ sqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak); VdbeCoverage(v);
+ }
+
+ /* Generate the subroutine return
+ */
+ sqlite3VdbeResolveLabel(v, iContinue);
+ sqlite3VdbeAddOp1(v, OP_Return, regReturn);
+
+ return addr;
+}
+
+/*
+** Alternative compound select code generator for cases when there
+** is an ORDER BY clause.
+**
+** We assume a query of the following form:
+**
+** <selectA> <operator> <selectB> ORDER BY <orderbylist>
+**
+** <operator> is one of UNION ALL, UNION, EXCEPT, or INTERSECT. The idea
+** is to code both <selectA> and <selectB> with the ORDER BY clause as
+** co-routines. Then run the co-routines in parallel and merge the results
+** into the output. In addition to the two coroutines (called selectA and
+** selectB) there are 7 subroutines:
+**
+** outA: Move the output of the selectA coroutine into the output
+** of the compound query.
+**
+** outB: Move the output of the selectB coroutine into the output
+** of the compound query. (Only generated for UNION and
+** UNION ALL. EXCEPT and INSERTSECT never output a row that
+** appears only in B.)
+**
+** AltB: Called when there is data from both coroutines and A<B.
+**
+** AeqB: Called when there is data from both coroutines and A==B.
+**
+** AgtB: Called when there is data from both coroutines and A>B.
+**
+** EofA: Called when data is exhausted from selectA.
+**
+** EofB: Called when data is exhausted from selectB.
+**
+** The implementation of the latter five subroutines depend on which
+** <operator> is used:
+**
+**
+** UNION ALL UNION EXCEPT INTERSECT
+** ------------- ----------------- -------------- -----------------
+** AltB: outA, nextA outA, nextA outA, nextA nextA
+**
+** AeqB: outA, nextA nextA nextA outA, nextA
+**
+** AgtB: outB, nextB outB, nextB nextB nextB
+**
+** EofA: outB, nextB outB, nextB halt halt
+**
+** EofB: outA, nextA outA, nextA outA, nextA halt
+**
+** In the AltB, AeqB, and AgtB subroutines, an EOF on A following nextA
+** causes an immediate jump to EofA and an EOF on B following nextB causes
+** an immediate jump to EofB. Within EofA and EofB, and EOF on entry or
+** following nextX causes a jump to the end of the select processing.
+**
+** Duplicate removal in the UNION, EXCEPT, and INTERSECT cases is handled
+** within the output subroutine. The regPrev register set holds the previously
+** output value. A comparison is made against this value and the output
+** is skipped if the next results would be the same as the previous.
+**
+** The implementation plan is to implement the two coroutines and seven
+** subroutines first, then put the control logic at the bottom. Like this:
+**
+** goto Init
+** coA: coroutine for left query (A)
+** coB: coroutine for right query (B)
+** outA: output one row of A
+** outB: output one row of B (UNION and UNION ALL only)
+** EofA: ...
+** EofB: ...
+** AltB: ...
+** AeqB: ...
+** AgtB: ...
+** Init: initialize coroutine registers
+** yield coA
+** if eof(A) goto EofA
+** yield coB
+** if eof(B) goto EofB
+** Cmpr: Compare A, B
+** Jump AltB, AeqB, AgtB
+** End: ...
+**
+** We call AltB, AeqB, AgtB, EofA, and EofB "subroutines" but they are not
+** actually called using Gosub and they do not Return. EofA and EofB loop
+** until all data is exhausted then jump to the "end" labe. AltB, AeqB,
+** and AgtB jump to either L2 or to one of EofA or EofB.
+*/
+#ifndef SQLITE_OMIT_COMPOUND_SELECT
+static int multiSelectOrderBy(
+ Parse *pParse, /* Parsing context */
+ Select *p, /* The right-most of SELECTs to be coded */
+ SelectDest *pDest /* What to do with query results */
+){
+ int i, j; /* Loop counters */
+ Select *pPrior; /* Another SELECT immediately to our left */
+ Vdbe *v; /* Generate code to this VDBE */
+ SelectDest destA; /* Destination for coroutine A */
+ SelectDest destB; /* Destination for coroutine B */
+ int regAddrA; /* Address register for select-A coroutine */
+ int regAddrB; /* Address register for select-B coroutine */
+ int addrSelectA; /* Address of the select-A coroutine */
+ int addrSelectB; /* Address of the select-B coroutine */
+ int regOutA; /* Address register for the output-A subroutine */
+ int regOutB; /* Address register for the output-B subroutine */
+ int addrOutA; /* Address of the output-A subroutine */
+ int addrOutB = 0; /* Address of the output-B subroutine */
+ int addrEofA; /* Address of the select-A-exhausted subroutine */
+ int addrEofA_noB; /* Alternate addrEofA if B is uninitialized */
+ int addrEofB; /* Address of the select-B-exhausted subroutine */
+ int addrAltB; /* Address of the A<B subroutine */
+ int addrAeqB; /* Address of the A==B subroutine */
+ int addrAgtB; /* Address of the A>B subroutine */
+ int regLimitA; /* Limit register for select-A */
+ int regLimitB; /* Limit register for select-A */
+ int regPrev; /* A range of registers to hold previous output */
+ int savedLimit; /* Saved value of p->iLimit */
+ int savedOffset; /* Saved value of p->iOffset */
+ int labelCmpr; /* Label for the start of the merge algorithm */
+ int labelEnd; /* Label for the end of the overall SELECT stmt */
+ int addr1; /* Jump instructions that get retargetted */
+ int op; /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */
+ KeyInfo *pKeyDup = 0; /* Comparison information for duplicate removal */
+ KeyInfo *pKeyMerge; /* Comparison information for merging rows */
+ sqlite3 *db; /* Database connection */
+ ExprList *pOrderBy; /* The ORDER BY clause */
+ int nOrderBy; /* Number of terms in the ORDER BY clause */
+ int *aPermute; /* Mapping from ORDER BY terms to result set columns */
+#ifndef SQLITE_OMIT_EXPLAIN
+ int iSub1; /* EQP id of left-hand query */
+ int iSub2; /* EQP id of right-hand query */
+#endif
+
+ assert( p->pOrderBy!=0 );
+ assert( pKeyDup==0 ); /* "Managed" code needs this. Ticket #3382. */
+ db = pParse->db;
+ v = pParse->pVdbe;
+ assert( v!=0 ); /* Already thrown the error if VDBE alloc failed */
+ labelEnd = sqlite3VdbeMakeLabel(v);
+ labelCmpr = sqlite3VdbeMakeLabel(v);
+
+
+ /* Patch up the ORDER BY clause
+ */
+ op = p->op;
+ pPrior = p->pPrior;
+ assert( pPrior->pOrderBy==0 );
+ pOrderBy = p->pOrderBy;
+ assert( pOrderBy );
+ nOrderBy = pOrderBy->nExpr;
+
+ /* For operators other than UNION ALL we have to make sure that
+ ** the ORDER BY clause covers every term of the result set. Add
+ ** terms to the ORDER BY clause as necessary.
+ */
+ if( op!=TK_ALL ){
+ for(i=1; db->mallocFailed==0 && i<=p->pEList->nExpr; i++){
+ struct ExprList_item *pItem;
+ for(j=0, pItem=pOrderBy->a; j<nOrderBy; j++, pItem++){
+ assert( pItem->u.x.iOrderByCol>0 );
+ if( pItem->u.x.iOrderByCol==i ) break;
+ }
+ if( j==nOrderBy ){
+ Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
+ if( pNew==0 ) return SQLITE_NOMEM_BKPT;
+ pNew->flags |= EP_IntValue;
+ pNew->u.iValue = i;
+ pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
+ if( pOrderBy ) pOrderBy->a[nOrderBy++].u.x.iOrderByCol = (u16)i;
+ }
+ }
+ }
+
+ /* Compute the comparison permutation and keyinfo that is used with
+ ** the permutation used to determine if the next
+ ** row of results comes from selectA or selectB. Also add explicit
+ ** collations to the ORDER BY clause terms so that when the subqueries
+ ** to the right and the left are evaluated, they use the correct
+ ** collation.
+ */
+ aPermute = sqlite3DbMallocRawNN(db, sizeof(int)*(nOrderBy + 1));
+ if( aPermute ){
+ struct ExprList_item *pItem;
+ aPermute[0] = nOrderBy;
+ for(i=1, pItem=pOrderBy->a; i<=nOrderBy; i++, pItem++){
+ assert( pItem->u.x.iOrderByCol>0 );
+ assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr );
+ aPermute[i] = pItem->u.x.iOrderByCol - 1;
+ }
+ pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1);
+ }else{
+ pKeyMerge = 0;
+ }
+
+ /* Reattach the ORDER BY clause to the query.
+ */
+ p->pOrderBy = pOrderBy;
+ pPrior->pOrderBy = sqlite3ExprListDup(pParse->db, pOrderBy, 0);
+
+ /* Allocate a range of temporary registers and the KeyInfo needed
+ ** for the logic that removes duplicate result rows when the
+ ** operator is UNION, EXCEPT, or INTERSECT (but not UNION ALL).
+ */
+ if( op==TK_ALL ){
+ regPrev = 0;
+ }else{
+ int nExpr = p->pEList->nExpr;
+ assert( nOrderBy>=nExpr || db->mallocFailed );
+ regPrev = pParse->nMem+1;
+ pParse->nMem += nExpr+1;
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev);
+ pKeyDup = sqlite3KeyInfoAlloc(db, nExpr, 1);
+ if( pKeyDup ){
+ assert( sqlite3KeyInfoIsWriteable(pKeyDup) );
+ for(i=0; i<nExpr; i++){
+ pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i);
+ pKeyDup->aSortOrder[i] = 0;
+ }
+ }
+ }
+
+ /* Separate the left and the right query from one another
+ */
+ p->pPrior = 0;
+ pPrior->pNext = 0;
+ sqlite3ResolveOrderGroupBy(pParse, p, p->pOrderBy, "ORDER");
+ if( pPrior->pPrior==0 ){
+ sqlite3ResolveOrderGroupBy(pParse, pPrior, pPrior->pOrderBy, "ORDER");
+ }
+
+ /* Compute the limit registers */
+ computeLimitRegisters(pParse, p, labelEnd);
+ if( p->iLimit && op==TK_ALL ){
+ regLimitA = ++pParse->nMem;
+ regLimitB = ++pParse->nMem;
+ sqlite3VdbeAddOp2(v, OP_Copy, p->iOffset ? p->iOffset+1 : p->iLimit,
+ regLimitA);
+ sqlite3VdbeAddOp2(v, OP_Copy, regLimitA, regLimitB);
+ }else{
+ regLimitA = regLimitB = 0;
+ }
+ sqlite3ExprDelete(db, p->pLimit);
+ p->pLimit = 0;
+ sqlite3ExprDelete(db, p->pOffset);
+ p->pOffset = 0;
+
+ regAddrA = ++pParse->nMem;
+ regAddrB = ++pParse->nMem;
+ regOutA = ++pParse->nMem;
+ regOutB = ++pParse->nMem;
+ sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA);
+ sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB);
+
+ /* Generate a coroutine to evaluate the SELECT statement to the
+ ** left of the compound operator - the "A" select.
+ */
+ addrSelectA = sqlite3VdbeCurrentAddr(v) + 1;
+ addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA);
+ VdbeComment((v, "left SELECT"));
+ pPrior->iLimit = regLimitA;
+ explainSetInteger(iSub1, pParse->iNextSelectId);
+ sqlite3Select(pParse, pPrior, &destA);
+ sqlite3VdbeEndCoroutine(v, regAddrA);
+ sqlite3VdbeJumpHere(v, addr1);
+
+ /* Generate a coroutine to evaluate the SELECT statement on
+ ** the right - the "B" select
+ */
+ addrSelectB = sqlite3VdbeCurrentAddr(v) + 1;
+ addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrB, 0, addrSelectB);
+ VdbeComment((v, "right SELECT"));
+ savedLimit = p->iLimit;
+ savedOffset = p->iOffset;
+ p->iLimit = regLimitB;
+ p->iOffset = 0;
+ explainSetInteger(iSub2, pParse->iNextSelectId);
+ sqlite3Select(pParse, p, &destB);
+ p->iLimit = savedLimit;
+ p->iOffset = savedOffset;
+ sqlite3VdbeEndCoroutine(v, regAddrB);
+
+ /* Generate a subroutine that outputs the current row of the A
+ ** select as the next output row of the compound select.
+ */
+ VdbeNoopComment((v, "Output routine for A"));
+ addrOutA = generateOutputSubroutine(pParse,
+ p, &destA, pDest, regOutA,
+ regPrev, pKeyDup, labelEnd);
+
+ /* Generate a subroutine that outputs the current row of the B
+ ** select as the next output row of the compound select.
+ */
+ if( op==TK_ALL || op==TK_UNION ){
+ VdbeNoopComment((v, "Output routine for B"));
+ addrOutB = generateOutputSubroutine(pParse,
+ p, &destB, pDest, regOutB,
+ regPrev, pKeyDup, labelEnd);
+ }
+ sqlite3KeyInfoUnref(pKeyDup);
+
+ /* Generate a subroutine to run when the results from select A
+ ** are exhausted and only data in select B remains.
+ */
+ if( op==TK_EXCEPT || op==TK_INTERSECT ){
+ addrEofA_noB = addrEofA = labelEnd;
+ }else{
+ VdbeNoopComment((v, "eof-A subroutine"));
+ addrEofA = sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
+ addrEofA_noB = sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, labelEnd);
+ VdbeCoverage(v);
+ sqlite3VdbeGoto(v, addrEofA);
+ p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
+ }
+
+ /* Generate a subroutine to run when the results from select B
+ ** are exhausted and only data in select A remains.
+ */
+ if( op==TK_INTERSECT ){
+ addrEofB = addrEofA;
+ if( p->nSelectRow > pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow;
+ }else{
+ VdbeNoopComment((v, "eof-B subroutine"));
+ addrEofB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
+ sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, labelEnd); VdbeCoverage(v);
+ sqlite3VdbeGoto(v, addrEofB);
+ }
+
+ /* Generate code to handle the case of A<B
+ */
+ VdbeNoopComment((v, "A-lt-B subroutine"));
+ addrAltB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
+ sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA); VdbeCoverage(v);
+ sqlite3VdbeGoto(v, labelCmpr);
+
+ /* Generate code to handle the case of A==B
+ */
+ if( op==TK_ALL ){
+ addrAeqB = addrAltB;
+ }else if( op==TK_INTERSECT ){
+ addrAeqB = addrAltB;
+ addrAltB++;
+ }else{
+ VdbeNoopComment((v, "A-eq-B subroutine"));
+ addrAeqB =
+ sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA); VdbeCoverage(v);
+ sqlite3VdbeGoto(v, labelCmpr);
+ }
+
+ /* Generate code to handle the case of A>B
+ */
+ VdbeNoopComment((v, "A-gt-B subroutine"));
+ addrAgtB = sqlite3VdbeCurrentAddr(v);
+ if( op==TK_ALL || op==TK_UNION ){
+ sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
+ }
+ sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v);
+ sqlite3VdbeGoto(v, labelCmpr);
+
+ /* This code runs once to initialize everything.
+ */
+ sqlite3VdbeJumpHere(v, addr1);
+ sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA_noB); VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v);
+
+ /* Implement the main merge loop
+ */
+ sqlite3VdbeResolveLabel(v, labelCmpr);
+ sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY);
+ sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy,
+ (char*)pKeyMerge, P4_KEYINFO);
+ sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE);
+ sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB); VdbeCoverage(v);
+
+ /* Jump to the this point in order to terminate the query.
+ */
+ sqlite3VdbeResolveLabel(v, labelEnd);
+
+ /* Set the number of output columns
+ */
+ if( pDest->eDest==SRT_Output ){
+ Select *pFirst = pPrior;
+ while( pFirst->pPrior ) pFirst = pFirst->pPrior;
+ generateColumnNames(pParse, pFirst->pSrc, pFirst->pEList);
+ }
+
+ /* Reassembly the compound query so that it will be freed correctly
+ ** by the calling function */
+ if( p->pPrior ){
+ sqlite3SelectDelete(db, p->pPrior);
+ }
+ p->pPrior = pPrior;
+ pPrior->pNext = p;
+
+ /*** TBD: Insert subroutine calls to close cursors on incomplete
+ **** subqueries ****/
+ explainComposite(pParse, p->op, iSub1, iSub2, 0);
+ return pParse->nErr!=0;
+}
+#endif
+
+#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
+/* Forward Declarations */
+static void substExprList(Parse*, ExprList*, int, ExprList*);
+static void substSelect(Parse*, Select *, int, ExprList*, int);
+
+/*
+** Scan through the expression pExpr. Replace every reference to
+** a column in table number iTable with a copy of the iColumn-th
+** entry in pEList. (But leave references to the ROWID column
+** unchanged.)
+**
+** This routine is part of the flattening procedure. A subquery
+** whose result set is defined by pEList appears as entry in the
+** FROM clause of a SELECT such that the VDBE cursor assigned to that
+** FORM clause entry is iTable. This routine make the necessary
+** changes to pExpr so that it refers directly to the source table
+** of the subquery rather the result set of the subquery.
+*/
+static Expr *substExpr(
+ Parse *pParse, /* Report errors here */
+ Expr *pExpr, /* Expr in which substitution occurs */
+ int iTable, /* Table to be substituted */
+ ExprList *pEList /* Substitute expressions */
+){
+ sqlite3 *db = pParse->db;
+ if( pExpr==0 ) return 0;
+ if( pExpr->op==TK_COLUMN && pExpr->iTable==iTable ){
+ if( pExpr->iColumn<0 ){
+ pExpr->op = TK_NULL;
+ }else{
+ Expr *pNew;
+ Expr *pCopy = pEList->a[pExpr->iColumn].pExpr;
+ assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
+ assert( pExpr->pLeft==0 && pExpr->pRight==0 );
+ if( sqlite3ExprIsVector(pCopy) ){
+ sqlite3VectorErrorMsg(pParse, pCopy);
+ }else{
+ pNew = sqlite3ExprDup(db, pCopy, 0);
+ if( pNew && (pExpr->flags & EP_FromJoin) ){
+ pNew->iRightJoinTable = pExpr->iRightJoinTable;
+ pNew->flags |= EP_FromJoin;
+ }
+ sqlite3ExprDelete(db, pExpr);
+ pExpr = pNew;
+ }
+ }
+ }else{
+ pExpr->pLeft = substExpr(pParse, pExpr->pLeft, iTable, pEList);
+ pExpr->pRight = substExpr(pParse, pExpr->pRight, iTable, pEList);
+ if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+ substSelect(pParse, pExpr->x.pSelect, iTable, pEList, 1);
+ }else{
+ substExprList(pParse, pExpr->x.pList, iTable, pEList);
+ }
+ }
+ return pExpr;
+}
+static void substExprList(
+ Parse *pParse, /* Report errors here */
+ ExprList *pList, /* List to scan and in which to make substitutes */
+ int iTable, /* Table to be substituted */
+ ExprList *pEList /* Substitute values */
+){
+ int i;
+ if( pList==0 ) return;
+ for(i=0; i<pList->nExpr; i++){
+ pList->a[i].pExpr = substExpr(pParse, pList->a[i].pExpr, iTable, pEList);
+ }
+}
+static void substSelect(
+ Parse *pParse, /* Report errors here */
+ Select *p, /* SELECT statement in which to make substitutions */
+ int iTable, /* Table to be replaced */
+ ExprList *pEList, /* Substitute values */
+ int doPrior /* Do substitutes on p->pPrior too */
+){
+ SrcList *pSrc;
+ struct SrcList_item *pItem;
+ int i;
+ if( !p ) return;
+ do{
+ substExprList(pParse, p->pEList, iTable, pEList);
+ substExprList(pParse, p->pGroupBy, iTable, pEList);
+ substExprList(pParse, p->pOrderBy, iTable, pEList);
+ p->pHaving = substExpr(pParse, p->pHaving, iTable, pEList);
+ p->pWhere = substExpr(pParse, p->pWhere, iTable, pEList);
+ pSrc = p->pSrc;
+ assert( pSrc!=0 );
+ for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
+ substSelect(pParse, pItem->pSelect, iTable, pEList, 1);
+ if( pItem->fg.isTabFunc ){
+ substExprList(pParse, pItem->u1.pFuncArg, iTable, pEList);
+ }
+ }
+ }while( doPrior && (p = p->pPrior)!=0 );
+}
+#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
+
+#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
+/*
+** This routine attempts to flatten subqueries as a performance optimization.
+** This routine returns 1 if it makes changes and 0 if no flattening occurs.
+**
+** To understand the concept of flattening, consider the following
+** query:
+**
+** SELECT a FROM (SELECT x+y AS a FROM t1 WHERE z<100) WHERE a>5
+**
+** The default way of implementing this query is to execute the
+** subquery first and store the results in a temporary table, then
+** run the outer query on that temporary table. This requires two
+** passes over the data. Furthermore, because the temporary table
+** has no indices, the WHERE clause on the outer query cannot be
+** optimized.
+**
+** This routine attempts to rewrite queries such as the above into
+** a single flat select, like this:
+**
+** SELECT x+y AS a FROM t1 WHERE z<100 AND a>5
+**
+** The code generated for this simplification gives the same result
+** but only has to scan the data once. And because indices might
+** exist on the table t1, a complete scan of the data might be
+** avoided.
+**
+** Flattening is only attempted if all of the following are true:
+**
+** (1) The subquery and the outer query do not both use aggregates.
+**
+** (2) The subquery is not an aggregate or (2a) the outer query is not a join
+** and (2b) the outer query does not use subqueries other than the one
+** FROM-clause subquery that is a candidate for flattening. (2b is
+** due to ticket [2f7170d73bf9abf80] from 2015-02-09.)
+**
+** (3) The subquery is not the right operand of a left outer join
+** (Originally ticket #306. Strengthened by ticket #3300)
+**
+** (4) The subquery is not DISTINCT.
+**
+** (**) At one point restrictions (4) and (5) defined a subset of DISTINCT
+** sub-queries that were excluded from this optimization. Restriction
+** (4) has since been expanded to exclude all DISTINCT subqueries.
+**
+** (6) The subquery does not use aggregates or the outer query is not
+** DISTINCT.
+**
+** (7) The subquery has a FROM clause. TODO: For subqueries without
+** A FROM clause, consider adding a FROM close with the special
+** table sqlite_once that consists of a single row containing a
+** single NULL.
+**
+** (8) The subquery does not use LIMIT or the outer query is not a join.
+**
+** (9) The subquery does not use LIMIT or the outer query does not use
+** aggregates.
+**
+** (**) Restriction (10) was removed from the code on 2005-02-05 but we
+** accidently carried the comment forward until 2014-09-15. Original
+** text: "The subquery does not use aggregates or the outer query
+** does not use LIMIT."
+**
+** (11) The subquery and the outer query do not both have ORDER BY clauses.
+**
+** (**) Not implemented. Subsumed into restriction (3). Was previously
+** a separate restriction deriving from ticket #350.
+**
+** (13) The subquery and outer query do not both use LIMIT.
+**
+** (14) The subquery does not use OFFSET.
+**
+** (15) The outer query is not part of a compound select or the
+** subquery does not have a LIMIT clause.
+** (See ticket #2339 and ticket [02a8e81d44]).
+**
+** (16) The outer query is not an aggregate or the subquery does
+** not contain ORDER BY. (Ticket #2942) This used to not matter
+** until we introduced the group_concat() function.
+**
+** (17) The sub-query is not a compound select, or it is a UNION ALL
+** compound clause made up entirely of non-aggregate queries, and
+** the parent query:
+**
+** * is not itself part of a compound select,
+** * is not an aggregate or DISTINCT query, and
+** * is not a join
+**
+** The parent and sub-query may contain WHERE clauses. Subject to
+** rules (11), (13) and (14), they may also contain ORDER BY,
+** LIMIT and OFFSET clauses. The subquery cannot use any compound
+** operator other than UNION ALL because all the other compound
+** operators have an implied DISTINCT which is disallowed by
+** restriction (4).
+**
+** Also, each component of the sub-query must return the same number
+** of result columns. This is actually a requirement for any compound
+** SELECT statement, but all the code here does is make sure that no
+** such (illegal) sub-query is flattened. The caller will detect the
+** syntax error and return a detailed message.
+**
+** (18) If the sub-query is a compound select, then all terms of the
+** ORDER by clause of the parent must be simple references to
+** columns of the sub-query.
+**
+** (19) The subquery does not use LIMIT or the outer query does not
+** have a WHERE clause.
+**
+** (20) If the sub-query is a compound select, then it must not use
+** an ORDER BY clause. Ticket #3773. We could relax this constraint
+** somewhat by saying that the terms of the ORDER BY clause must
+** appear as unmodified result columns in the outer query. But we
+** have other optimizations in mind to deal with that case.
+**
+** (21) The subquery does not use LIMIT or the outer query is not
+** DISTINCT. (See ticket [752e1646fc]).
+**
+** (22) The subquery is not a recursive CTE.
+**
+** (23) The parent is not a recursive CTE, or the sub-query is not a
+** compound query. This restriction is because transforming the
+** parent to a compound query confuses the code that handles
+** recursive queries in multiSelect().
+**
+** (24) The subquery is not an aggregate that uses the built-in min() or
+** or max() functions. (Without this restriction, a query like:
+** "SELECT x FROM (SELECT max(y), x FROM t1)" would not necessarily
+** return the value X for which Y was maximal.)
+**
+**
+** In this routine, the "p" parameter is a pointer to the outer query.
+** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query
+** uses aggregates and subqueryIsAgg is true if the subquery uses aggregates.
+**
+** If flattening is not attempted, this routine is a no-op and returns 0.
+** If flattening is attempted this routine returns 1.
+**
+** All of the expression analysis must occur on both the outer query and
+** the subquery before this routine runs.
+*/
+static int flattenSubquery(
+ Parse *pParse, /* Parsing context */
+ Select *p, /* The parent or outer SELECT statement */
+ int iFrom, /* Index in p->pSrc->a[] of the inner subquery */
+ int isAgg, /* True if outer SELECT uses aggregate functions */
+ int subqueryIsAgg /* True if the subquery uses aggregate functions */
+){
+ const char *zSavedAuthContext = pParse->zAuthContext;
+ Select *pParent; /* Current UNION ALL term of the other query */
+ Select *pSub; /* The inner query or "subquery" */
+ Select *pSub1; /* Pointer to the rightmost select in sub-query */
+ SrcList *pSrc; /* The FROM clause of the outer query */
+ SrcList *pSubSrc; /* The FROM clause of the subquery */
+ ExprList *pList; /* The result set of the outer query */
+ int iParent; /* VDBE cursor number of the pSub result set temp table */
+ int i; /* Loop counter */
+ Expr *pWhere; /* The WHERE clause */
+ struct SrcList_item *pSubitem; /* The subquery */
+ sqlite3 *db = pParse->db;
+
+ /* Check to see if flattening is permitted. Return 0 if not.
+ */
+ assert( p!=0 );
+ assert( p->pPrior==0 ); /* Unable to flatten compound queries */
+ if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0;
+ pSrc = p->pSrc;
+ assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
+ pSubitem = &pSrc->a[iFrom];
+ iParent = pSubitem->iCursor;
+ pSub = pSubitem->pSelect;
+ assert( pSub!=0 );
+ if( subqueryIsAgg ){
+ if( isAgg ) return 0; /* Restriction (1) */
+ if( pSrc->nSrc>1 ) return 0; /* Restriction (2a) */
+ if( (p->pWhere && ExprHasProperty(p->pWhere,EP_Subquery))
+ || (sqlite3ExprListFlags(p->pEList) & EP_Subquery)!=0
+ || (sqlite3ExprListFlags(p->pOrderBy) & EP_Subquery)!=0
+ ){
+ return 0; /* Restriction (2b) */
+ }
+ }
+
+ pSubSrc = pSub->pSrc;
+ assert( pSubSrc );
+ /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants,
+ ** not arbitrary expressions, we allowed some combining of LIMIT and OFFSET
+ ** because they could be computed at compile-time. But when LIMIT and OFFSET
+ ** became arbitrary expressions, we were forced to add restrictions (13)
+ ** and (14). */
+ if( pSub->pLimit && p->pLimit ) return 0; /* Restriction (13) */
+ if( pSub->pOffset ) return 0; /* Restriction (14) */
+ if( (p->selFlags & SF_Compound)!=0 && pSub->pLimit ){
+ return 0; /* Restriction (15) */
+ }
+ if( pSubSrc->nSrc==0 ) return 0; /* Restriction (7) */
+ if( pSub->selFlags & SF_Distinct ) return 0; /* Restriction (5) */
+ if( pSub->pLimit && (pSrc->nSrc>1 || isAgg) ){
+ return 0; /* Restrictions (8)(9) */
+ }
+ if( (p->selFlags & SF_Distinct)!=0 && subqueryIsAgg ){
+ return 0; /* Restriction (6) */
+ }
+ if( p->pOrderBy && pSub->pOrderBy ){
+ return 0; /* Restriction (11) */
+ }
+ if( isAgg && pSub->pOrderBy ) return 0; /* Restriction (16) */
+ if( pSub->pLimit && p->pWhere ) return 0; /* Restriction (19) */
+ if( pSub->pLimit && (p->selFlags & SF_Distinct)!=0 ){
+ return 0; /* Restriction (21) */
+ }
+ testcase( pSub->selFlags & SF_Recursive );
+ testcase( pSub->selFlags & SF_MinMaxAgg );
+ if( pSub->selFlags & (SF_Recursive|SF_MinMaxAgg) ){
+ return 0; /* Restrictions (22) and (24) */
+ }
+ if( (p->selFlags & SF_Recursive) && pSub->pPrior ){
+ return 0; /* Restriction (23) */
+ }
+
+ /* OBSOLETE COMMENT 1:
+ ** Restriction 3: If the subquery is a join, make sure the subquery is
+ ** not used as the right operand of an outer join. Examples of why this
+ ** is not allowed:
+ **
+ ** t1 LEFT OUTER JOIN (t2 JOIN t3)
+ **
+ ** If we flatten the above, we would get
+ **
+ ** (t1 LEFT OUTER JOIN t2) JOIN t3
+ **
+ ** which is not at all the same thing.
+ **
+ ** OBSOLETE COMMENT 2:
+ ** Restriction 12: If the subquery is the right operand of a left outer
+ ** join, make sure the subquery has no WHERE clause.
+ ** An examples of why this is not allowed:
+ **
+ ** t1 LEFT OUTER JOIN (SELECT * FROM t2 WHERE t2.x>0)
+ **
+ ** If we flatten the above, we would get
+ **
+ ** (t1 LEFT OUTER JOIN t2) WHERE t2.x>0
+ **
+ ** But the t2.x>0 test will always fail on a NULL row of t2, which
+ ** effectively converts the OUTER JOIN into an INNER JOIN.
+ **
+ ** THIS OVERRIDES OBSOLETE COMMENTS 1 AND 2 ABOVE:
+ ** Ticket #3300 shows that flattening the right term of a LEFT JOIN
+ ** is fraught with danger. Best to avoid the whole thing. If the
+ ** subquery is the right term of a LEFT JOIN, then do not flatten.
+ */
+ if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){
+ return 0;
+ }
+
+ /* Restriction 17: If the sub-query is a compound SELECT, then it must
+ ** use only the UNION ALL operator. And none of the simple select queries
+ ** that make up the compound SELECT are allowed to be aggregate or distinct
+ ** queries.
+ */
+ if( pSub->pPrior ){
+ if( pSub->pOrderBy ){
+ return 0; /* Restriction 20 */
+ }
+ if( isAgg || (p->selFlags & SF_Distinct)!=0 || pSrc->nSrc!=1 ){
+ return 0;
+ }
+ for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){
+ testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
+ testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
+ assert( pSub->pSrc!=0 );
+ assert( pSub->pEList->nExpr==pSub1->pEList->nExpr );
+ if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0
+ || (pSub1->pPrior && pSub1->op!=TK_ALL)
+ || pSub1->pSrc->nSrc<1
+ ){
+ return 0;
+ }
+ testcase( pSub1->pSrc->nSrc>1 );
+ }
+
+ /* Restriction 18. */
+ if( p->pOrderBy ){
+ int ii;
+ for(ii=0; ii<p->pOrderBy->nExpr; ii++){
+ if( p->pOrderBy->a[ii].u.x.iOrderByCol==0 ) return 0;
+ }
+ }
+ }
+
+ /***** If we reach this point, flattening is permitted. *****/
+ SELECTTRACE(1,pParse,p,("flatten %s.%p from term %d\n",
+ pSub->zSelName, pSub, iFrom));
+
+ /* Authorize the subquery */
+ pParse->zAuthContext = pSubitem->zName;
+ TESTONLY(i =) sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0);
+ testcase( i==SQLITE_DENY );
+ pParse->zAuthContext = zSavedAuthContext;
+
+ /* If the sub-query is a compound SELECT statement, then (by restrictions
+ ** 17 and 18 above) it must be a UNION ALL and the parent query must
+ ** be of the form:
+ **
+ ** SELECT <expr-list> FROM (<sub-query>) <where-clause>
+ **
+ ** followed by any ORDER BY, LIMIT and/or OFFSET clauses. This block
+ ** creates N-1 copies of the parent query without any ORDER BY, LIMIT or
+ ** OFFSET clauses and joins them to the left-hand-side of the original
+ ** using UNION ALL operators. In this case N is the number of simple
+ ** select statements in the compound sub-query.
+ **
+ ** Example:
+ **
+ ** SELECT a+1 FROM (
+ ** SELECT x FROM tab
+ ** UNION ALL
+ ** SELECT y FROM tab
+ ** UNION ALL
+ ** SELECT abs(z*2) FROM tab2
+ ** ) WHERE a!=5 ORDER BY 1
+ **
+ ** Transformed into:
+ **
+ ** SELECT x+1 FROM tab WHERE x+1!=5
+ ** UNION ALL
+ ** SELECT y+1 FROM tab WHERE y+1!=5
+ ** UNION ALL
+ ** SELECT abs(z*2)+1 FROM tab2 WHERE abs(z*2)+1!=5
+ ** ORDER BY 1
+ **
+ ** We call this the "compound-subquery flattening".
+ */
+ for(pSub=pSub->pPrior; pSub; pSub=pSub->pPrior){
+ Select *pNew;
+ ExprList *pOrderBy = p->pOrderBy;
+ Expr *pLimit = p->pLimit;
+ Expr *pOffset = p->pOffset;
+ Select *pPrior = p->pPrior;
+ p->pOrderBy = 0;
+ p->pSrc = 0;
+ p->pPrior = 0;
+ p->pLimit = 0;
+ p->pOffset = 0;
+ pNew = sqlite3SelectDup(db, p, 0);
+ sqlite3SelectSetName(pNew, pSub->zSelName);
+ p->pOffset = pOffset;
+ p->pLimit = pLimit;
+ p->pOrderBy = pOrderBy;
+ p->pSrc = pSrc;
+ p->op = TK_ALL;
+ if( pNew==0 ){
+ p->pPrior = pPrior;
+ }else{
+ pNew->pPrior = pPrior;
+ if( pPrior ) pPrior->pNext = pNew;
+ pNew->pNext = p;
+ p->pPrior = pNew;
+ SELECTTRACE(2,pParse,p,
+ ("compound-subquery flattener creates %s.%p as peer\n",
+ pNew->zSelName, pNew));
+ }
+ if( db->mallocFailed ) return 1;
+ }
+
+ /* Begin flattening the iFrom-th entry of the FROM clause
+ ** in the outer query.
+ */
+ pSub = pSub1 = pSubitem->pSelect;
+
+ /* Delete the transient table structure associated with the
+ ** subquery
+ */
+ sqlite3DbFree(db, pSubitem->zDatabase);
+ sqlite3DbFree(db, pSubitem->zName);
+ sqlite3DbFree(db, pSubitem->zAlias);
+ pSubitem->zDatabase = 0;
+ pSubitem->zName = 0;
+ pSubitem->zAlias = 0;
+ pSubitem->pSelect = 0;
+
+ /* Defer deleting the Table object associated with the
+ ** subquery until code generation is
+ ** complete, since there may still exist Expr.pTab entries that
+ ** refer to the subquery even after flattening. Ticket #3346.
+ **
+ ** pSubitem->pTab is always non-NULL by test restrictions and tests above.
+ */
+ if( ALWAYS(pSubitem->pTab!=0) ){
+ Table *pTabToDel = pSubitem->pTab;
+ if( pTabToDel->nTabRef==1 ){
+ Parse *pToplevel = sqlite3ParseToplevel(pParse);
+ pTabToDel->pNextZombie = pToplevel->pZombieTab;
+ pToplevel->pZombieTab = pTabToDel;
+ }else{
+ pTabToDel->nTabRef--;
+ }
+ pSubitem->pTab = 0;
+ }
+
+ /* The following loop runs once for each term in a compound-subquery
+ ** flattening (as described above). If we are doing a different kind
+ ** of flattening - a flattening other than a compound-subquery flattening -
+ ** then this loop only runs once.
+ **
+ ** This loop moves all of the FROM elements of the subquery into the
+ ** the FROM clause of the outer query. Before doing this, remember
+ ** the cursor number for the original outer query FROM element in
+ ** iParent. The iParent cursor will never be used. Subsequent code
+ ** will scan expressions looking for iParent references and replace
+ ** those references with expressions that resolve to the subquery FROM
+ ** elements we are now copying in.
+ */
+ for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){
+ int nSubSrc;
+ u8 jointype = 0;
+ pSubSrc = pSub->pSrc; /* FROM clause of subquery */
+ nSubSrc = pSubSrc->nSrc; /* Number of terms in subquery FROM clause */
+ pSrc = pParent->pSrc; /* FROM clause of the outer query */
+
+ if( pSrc ){
+ assert( pParent==p ); /* First time through the loop */
+ jointype = pSubitem->fg.jointype;
+ }else{
+ assert( pParent!=p ); /* 2nd and subsequent times through the loop */
+ pSrc = pParent->pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
+ if( pSrc==0 ){
+ assert( db->mallocFailed );
+ break;
+ }
+ }
+
+ /* The subquery uses a single slot of the FROM clause of the outer
+ ** query. If the subquery has more than one element in its FROM clause,
+ ** then expand the outer query to make space for it to hold all elements
+ ** of the subquery.
+ **
+ ** Example:
+ **
+ ** SELECT * FROM tabA, (SELECT * FROM sub1, sub2), tabB;
+ **
+ ** The outer query has 3 slots in its FROM clause. One slot of the
+ ** outer query (the middle slot) is used by the subquery. The next
+ ** block of code will expand the outer query FROM clause to 4 slots.
+ ** The middle slot is expanded to two slots in order to make space
+ ** for the two elements in the FROM clause of the subquery.
+ */
+ if( nSubSrc>1 ){
+ pParent->pSrc = pSrc = sqlite3SrcListEnlarge(db, pSrc, nSubSrc-1,iFrom+1);
+ if( db->mallocFailed ){
+ break;
+ }
+ }
+
+ /* Transfer the FROM clause terms from the subquery into the
+ ** outer query.
+ */
+ for(i=0; i<nSubSrc; i++){
+ sqlite3IdListDelete(db, pSrc->a[i+iFrom].pUsing);
+ assert( pSrc->a[i+iFrom].fg.isTabFunc==0 );
+ pSrc->a[i+iFrom] = pSubSrc->a[i];
+ memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
+ }
+ pSrc->a[iFrom].fg.jointype = jointype;
+
+ /* Now begin substituting subquery result set expressions for
+ ** references to the iParent in the outer query.
+ **
+ ** Example:
+ **
+ ** SELECT a+5, b*10 FROM (SELECT x*3 AS a, y+10 AS b FROM t1) WHERE a>b;
+ ** \ \_____________ subquery __________/ /
+ ** \_____________________ outer query ______________________________/
+ **
+ ** We look at every expression in the outer query and every place we see
+ ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10".
+ */
+ pList = pParent->pEList;
+ for(i=0; i<pList->nExpr; i++){
+ if( pList->a[i].zName==0 ){
+ char *zName = sqlite3DbStrDup(db, pList->a[i].zSpan);
+ sqlite3Dequote(zName);
+ pList->a[i].zName = zName;
+ }
+ }
+ if( pSub->pOrderBy ){
+ /* At this point, any non-zero iOrderByCol values indicate that the
+ ** ORDER BY column expression is identical to the iOrderByCol'th
+ ** expression returned by SELECT statement pSub. Since these values
+ ** do not necessarily correspond to columns in SELECT statement pParent,
+ ** zero them before transfering the ORDER BY clause.
+ **
+ ** Not doing this may cause an error if a subsequent call to this
+ ** function attempts to flatten a compound sub-query into pParent
+ ** (the only way this can happen is if the compound sub-query is
+ ** currently part of pSub->pSrc). See ticket [d11a6e908f]. */
+ ExprList *pOrderBy = pSub->pOrderBy;
+ for(i=0; i<pOrderBy->nExpr; i++){
+ pOrderBy->a[i].u.x.iOrderByCol = 0;
+ }
+ assert( pParent->pOrderBy==0 );
+ assert( pSub->pPrior==0 );
+ pParent->pOrderBy = pOrderBy;
+ pSub->pOrderBy = 0;
+ }
+ pWhere = sqlite3ExprDup(db, pSub->pWhere, 0);
+ if( subqueryIsAgg ){
+ assert( pParent->pHaving==0 );
+ pParent->pHaving = pParent->pWhere;
+ pParent->pWhere = pWhere;
+ pParent->pHaving = sqlite3ExprAnd(db,
+ sqlite3ExprDup(db, pSub->pHaving, 0), pParent->pHaving
+ );
+ assert( pParent->pGroupBy==0 );
+ pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy, 0);
+ }else{
+ pParent->pWhere = sqlite3ExprAnd(db, pWhere, pParent->pWhere);
+ }
+ substSelect(pParse, pParent, iParent, pSub->pEList, 0);
+
+ /* The flattened query is distinct if either the inner or the
+ ** outer query is distinct.
+ */
+ pParent->selFlags |= pSub->selFlags & SF_Distinct;
+
+ /*
+ ** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y;
+ **
+ ** One is tempted to try to add a and b to combine the limits. But this
+ ** does not work if either limit is negative.
+ */
+ if( pSub->pLimit ){
+ pParent->pLimit = pSub->pLimit;
+ pSub->pLimit = 0;
+ }
+ }
+
+ /* Finially, delete what is left of the subquery and return
+ ** success.
+ */
+ sqlite3SelectDelete(db, pSub1);
+
+#if SELECTTRACE_ENABLED
+ if( sqlite3SelectTrace & 0x100 ){
+ SELECTTRACE(0x100,pParse,p,("After flattening:\n"));
+ sqlite3TreeViewSelect(0, p, 0);
+ }
+#endif
+
+ return 1;
+}
+#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
+
+
+
+#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
+/*
+** Make copies of relevant WHERE clause terms of the outer query into
+** the WHERE clause of subquery. Example:
+**
+** SELECT * FROM (SELECT a AS x, c-d AS y FROM t1) WHERE x=5 AND y=10;
+**
+** Transformed into:
+**
+** SELECT * FROM (SELECT a AS x, c-d AS y FROM t1 WHERE a=5 AND c-d=10)
+** WHERE x=5 AND y=10;
+**
+** The hope is that the terms added to the inner query will make it more
+** efficient.
+**
+** Do not attempt this optimization if:
+**
+** (1) The inner query is an aggregate. (In that case, we'd really want
+** to copy the outer WHERE-clause terms onto the HAVING clause of the
+** inner query. But they probably won't help there so do not bother.)
+**
+** (2) The inner query is the recursive part of a common table expression.
+**
+** (3) The inner query has a LIMIT clause (since the changes to the WHERE
+** close would change the meaning of the LIMIT).
+**
+** (4) The inner query is the right operand of a LEFT JOIN. (The caller
+** enforces this restriction since this routine does not have enough
+** information to know.)
+**
+** (5) The WHERE clause expression originates in the ON or USING clause
+** of a LEFT JOIN.
+**
+** Return 0 if no changes are made and non-zero if one or more WHERE clause
+** terms are duplicated into the subquery.
+*/
+static int pushDownWhereTerms(
+ Parse *pParse, /* Parse context (for malloc() and error reporting) */
+ Select *pSubq, /* The subquery whose WHERE clause is to be augmented */
+ Expr *pWhere, /* The WHERE clause of the outer query */
+ int iCursor /* Cursor number of the subquery */
+){
+ Expr *pNew;
+ int nChng = 0;
+ Select *pX; /* For looping over compound SELECTs in pSubq */
+ if( pWhere==0 ) return 0;
+ for(pX=pSubq; pX; pX=pX->pPrior){
+ if( (pX->selFlags & (SF_Aggregate|SF_Recursive))!=0 ){
+ testcase( pX->selFlags & SF_Aggregate );
+ testcase( pX->selFlags & SF_Recursive );
+ testcase( pX!=pSubq );
+ return 0; /* restrictions (1) and (2) */
+ }
+ }
+ if( pSubq->pLimit!=0 ){
+ return 0; /* restriction (3) */
+ }
+ while( pWhere->op==TK_AND ){
+ nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, iCursor);
+ pWhere = pWhere->pLeft;
+ }
+ if( ExprHasProperty(pWhere,EP_FromJoin) ) return 0; /* restriction 5 */
+ if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){
+ nChng++;
+ while( pSubq ){
+ pNew = sqlite3ExprDup(pParse->db, pWhere, 0);
+ pNew = substExpr(pParse, pNew, iCursor, pSubq->pEList);
+ pSubq->pWhere = sqlite3ExprAnd(pParse->db, pSubq->pWhere, pNew);
+ pSubq = pSubq->pPrior;
+ }
+ }
+ return nChng;
+}
+#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
+
+/*
+** Based on the contents of the AggInfo structure indicated by the first
+** argument, this function checks if the following are true:
+**
+** * the query contains just a single aggregate function,
+** * the aggregate function is either min() or max(), and
+** * the argument to the aggregate function is a column value.
+**
+** If all of the above are true, then WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX
+** is returned as appropriate. Also, *ppMinMax is set to point to the
+** list of arguments passed to the aggregate before returning.
+**
+** Or, if the conditions above are not met, *ppMinMax is set to 0 and
+** WHERE_ORDERBY_NORMAL is returned.
+*/
+static u8 minMaxQuery(AggInfo *pAggInfo, ExprList **ppMinMax){
+ int eRet = WHERE_ORDERBY_NORMAL; /* Return value */
+
+ *ppMinMax = 0;
+ if( pAggInfo->nFunc==1 ){
+ Expr *pExpr = pAggInfo->aFunc[0].pExpr; /* Aggregate function */
+ ExprList *pEList = pExpr->x.pList; /* Arguments to agg function */
+
+ assert( pExpr->op==TK_AGG_FUNCTION );
+ if( pEList && pEList->nExpr==1 && pEList->a[0].pExpr->op==TK_AGG_COLUMN ){
+ const char *zFunc = pExpr->u.zToken;
+ if( sqlite3StrICmp(zFunc, "min")==0 ){
+ eRet = WHERE_ORDERBY_MIN;
+ *ppMinMax = pEList;
+ }else if( sqlite3StrICmp(zFunc, "max")==0 ){
+ eRet = WHERE_ORDERBY_MAX;
+ *ppMinMax = pEList;
+ }
+ }
+ }
+
+ assert( *ppMinMax==0 || (*ppMinMax)->nExpr==1 );
+ return eRet;
+}
+
+/*
+** The select statement passed as the first argument is an aggregate query.
+** The second argument is the associated aggregate-info object. This
+** function tests if the SELECT is of the form:
+**
+** SELECT count(*) FROM <tbl>
+**
+** where table is a database table, not a sub-select or view. If the query
+** does match this pattern, then a pointer to the Table object representing
+** <tbl> is returned. Otherwise, 0 is returned.
+*/
+static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){
+ Table *pTab;
+ Expr *pExpr;
+
+ assert( !p->pGroupBy );
+
+ if( p->pWhere || p->pEList->nExpr!=1
+ || p->pSrc->nSrc!=1 || p->pSrc->a[0].pSelect
+ ){
+ return 0;
+ }
+ pTab = p->pSrc->a[0].pTab;
+ pExpr = p->pEList->a[0].pExpr;
+ assert( pTab && !pTab->pSelect && pExpr );
+
+ if( IsVirtual(pTab) ) return 0;
+ if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
+ if( NEVER(pAggInfo->nFunc==0) ) return 0;
+ if( (pAggInfo->aFunc[0].pFunc->funcFlags&SQLITE_FUNC_COUNT)==0 ) return 0;
+ if( pExpr->flags&EP_Distinct ) return 0;
+
+ return pTab;
+}
+
+/*
+** If the source-list item passed as an argument was augmented with an
+** INDEXED BY clause, then try to locate the specified index. If there
+** was such a clause and the named index cannot be found, return
+** SQLITE_ERROR and leave an error in pParse. Otherwise, populate
+** pFrom->pIndex and return SQLITE_OK.
+*/
+SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, struct SrcList_item *pFrom){
+ if( pFrom->pTab && pFrom->fg.isIndexedBy ){
+ Table *pTab = pFrom->pTab;
+ char *zIndexedBy = pFrom->u1.zIndexedBy;
+ Index *pIdx;
+ for(pIdx=pTab->pIndex;
+ pIdx && sqlite3StrICmp(pIdx->zName, zIndexedBy);
+ pIdx=pIdx->pNext
+ );
+ if( !pIdx ){
+ sqlite3ErrorMsg(pParse, "no such index: %s", zIndexedBy, 0);
+ pParse->checkSchema = 1;
+ return SQLITE_ERROR;
+ }
+ pFrom->pIBIndex = pIdx;
+ }
+ return SQLITE_OK;
+}
+/*
+** Detect compound SELECT statements that use an ORDER BY clause with
+** an alternative collating sequence.
+**
+** SELECT ... FROM t1 EXCEPT SELECT ... FROM t2 ORDER BY .. COLLATE ...
+**
+** These are rewritten as a subquery:
+**
+** SELECT * FROM (SELECT ... FROM t1 EXCEPT SELECT ... FROM t2)
+** ORDER BY ... COLLATE ...
+**
+** This transformation is necessary because the multiSelectOrderBy() routine
+** above that generates the code for a compound SELECT with an ORDER BY clause
+** uses a merge algorithm that requires the same collating sequence on the
+** result columns as on the ORDER BY clause. See ticket
+** http://www.sqlite.org/src/info/6709574d2a
+**
+** This transformation is only needed for EXCEPT, INTERSECT, and UNION.
+** The UNION ALL operator works fine with multiSelectOrderBy() even when
+** there are COLLATE terms in the ORDER BY.
+*/
+static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){
+ int i;
+ Select *pNew;
+ Select *pX;
+ sqlite3 *db;
+ struct ExprList_item *a;
+ SrcList *pNewSrc;
+ Parse *pParse;
+ Token dummy;
+
+ if( p->pPrior==0 ) return WRC_Continue;
+ if( p->pOrderBy==0 ) return WRC_Continue;
+ for(pX=p; pX && (pX->op==TK_ALL || pX->op==TK_SELECT); pX=pX->pPrior){}
+ if( pX==0 ) return WRC_Continue;
+ a = p->pOrderBy->a;
+ for(i=p->pOrderBy->nExpr-1; i>=0; i--){
+ if( a[i].pExpr->flags & EP_Collate ) break;
+ }
+ if( i<0 ) return WRC_Continue;
+
+ /* If we reach this point, that means the transformation is required. */
+
+ pParse = pWalker->pParse;
+ db = pParse->db;
+ pNew = sqlite3DbMallocZero(db, sizeof(*pNew) );
+ if( pNew==0 ) return WRC_Abort;
+ memset(&dummy, 0, sizeof(dummy));
+ pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0,0);
+ if( pNewSrc==0 ) return WRC_Abort;
+ *pNew = *p;
+ p->pSrc = pNewSrc;
+ p->pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ASTERISK, 0));
+ p->op = TK_SELECT;
+ p->pWhere = 0;
+ pNew->pGroupBy = 0;
+ pNew->pHaving = 0;
+ pNew->pOrderBy = 0;
+ p->pPrior = 0;
+ p->pNext = 0;
+ p->pWith = 0;
+ p->selFlags &= ~SF_Compound;
+ assert( (p->selFlags & SF_Converted)==0 );
+ p->selFlags |= SF_Converted;
+ assert( pNew->pPrior!=0 );
+ pNew->pPrior->pNext = pNew;
+ pNew->pLimit = 0;
+ pNew->pOffset = 0;
+ return WRC_Continue;
+}
+
+/*
+** Check to see if the FROM clause term pFrom has table-valued function
+** arguments. If it does, leave an error message in pParse and return
+** non-zero, since pFrom is not allowed to be a table-valued function.
+*/
+static int cannotBeFunction(Parse *pParse, struct SrcList_item *pFrom){
+ if( pFrom->fg.isTabFunc ){
+ sqlite3ErrorMsg(pParse, "'%s' is not a function", pFrom->zName);
+ return 1;
+ }
+ return 0;
+}
+
+#ifndef SQLITE_OMIT_CTE
+/*
+** Argument pWith (which may be NULL) points to a linked list of nested
+** WITH contexts, from inner to outermost. If the table identified by
+** FROM clause element pItem is really a common-table-expression (CTE)
+** then return a pointer to the CTE definition for that table. Otherwise
+** return NULL.
+**
+** If a non-NULL value is returned, set *ppContext to point to the With
+** object that the returned CTE belongs to.
+*/
+static struct Cte *searchWith(
+ With *pWith, /* Current innermost WITH clause */
+ struct SrcList_item *pItem, /* FROM clause element to resolve */
+ With **ppContext /* OUT: WITH clause return value belongs to */
+){
+ const char *zName;
+ if( pItem->zDatabase==0 && (zName = pItem->zName)!=0 ){
+ With *p;
+ for(p=pWith; p; p=p->pOuter){
+ int i;
+ for(i=0; i<p->nCte; i++){
+ if( sqlite3StrICmp(zName, p->a[i].zName)==0 ){
+ *ppContext = p;
+ return &p->a[i];
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+/* The code generator maintains a stack of active WITH clauses
+** with the inner-most WITH clause being at the top of the stack.
+**
+** This routine pushes the WITH clause passed as the second argument
+** onto the top of the stack. If argument bFree is true, then this
+** WITH clause will never be popped from the stack. In this case it
+** should be freed along with the Parse object. In other cases, when
+** bFree==0, the With object will be freed along with the SELECT
+** statement with which it is associated.
+*/
+SQLITE_PRIVATE void sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){
+ assert( bFree==0 || (pParse->pWith==0 && pParse->pWithToFree==0) );
+ if( pWith ){
+ assert( pParse->pWith!=pWith );
+ pWith->pOuter = pParse->pWith;
+ pParse->pWith = pWith;
+ if( bFree ) pParse->pWithToFree = pWith;
+ }
+}
+
+/*
+** This function checks if argument pFrom refers to a CTE declared by
+** a WITH clause on the stack currently maintained by the parser. And,
+** if currently processing a CTE expression, if it is a recursive
+** reference to the current CTE.
+**
+** If pFrom falls into either of the two categories above, pFrom->pTab
+** and other fields are populated accordingly. The caller should check
+** (pFrom->pTab!=0) to determine whether or not a successful match
+** was found.
+**
+** Whether or not a match is found, SQLITE_OK is returned if no error
+** occurs. If an error does occur, an error message is stored in the
+** parser and some error code other than SQLITE_OK returned.
+*/
+static int withExpand(
+ Walker *pWalker,
+ struct SrcList_item *pFrom
+){
+ Parse *pParse = pWalker->pParse;
+ sqlite3 *db = pParse->db;
+ struct Cte *pCte; /* Matched CTE (or NULL if no match) */
+ With *pWith; /* WITH clause that pCte belongs to */
+
+ assert( pFrom->pTab==0 );
+
+ pCte = searchWith(pParse->pWith, pFrom, &pWith);
+ if( pCte ){
+ Table *pTab;
+ ExprList *pEList;
+ Select *pSel;
+ Select *pLeft; /* Left-most SELECT statement */
+ int bMayRecursive; /* True if compound joined by UNION [ALL] */
+ With *pSavedWith; /* Initial value of pParse->pWith */
+
+ /* If pCte->zCteErr is non-NULL at this point, then this is an illegal
+ ** recursive reference to CTE pCte. Leave an error in pParse and return
+ ** early. If pCte->zCteErr is NULL, then this is not a recursive reference.
+ ** In this case, proceed. */
+ if( pCte->zCteErr ){
+ sqlite3ErrorMsg(pParse, pCte->zCteErr, pCte->zName);
+ return SQLITE_ERROR;
+ }
+ if( cannotBeFunction(pParse, pFrom) ) return SQLITE_ERROR;
+
+ assert( pFrom->pTab==0 );
+ pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
+ if( pTab==0 ) return WRC_Abort;
+ pTab->nTabRef = 1;
+ pTab->zName = sqlite3DbStrDup(db, pCte->zName);
+ pTab->iPKey = -1;
+ pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
+ pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid;
+ pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0);
+ if( db->mallocFailed ) return SQLITE_NOMEM_BKPT;
+ assert( pFrom->pSelect );
+
+ /* Check if this is a recursive CTE. */
+ pSel = pFrom->pSelect;
+ bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION );
+ if( bMayRecursive ){
+ int i;
+ SrcList *pSrc = pFrom->pSelect->pSrc;
+ for(i=0; i<pSrc->nSrc; i++){
+ struct SrcList_item *pItem = &pSrc->a[i];
+ if( pItem->zDatabase==0
+ && pItem->zName!=0
+ && 0==sqlite3StrICmp(pItem->zName, pCte->zName)
+ ){
+ pItem->pTab = pTab;
+ pItem->fg.isRecursive = 1;
+ pTab->nTabRef++;
+ pSel->selFlags |= SF_Recursive;
+ }
+ }
+ }
+
+ /* Only one recursive reference is permitted. */
+ if( pTab->nTabRef>2 ){
+ sqlite3ErrorMsg(
+ pParse, "multiple references to recursive table: %s", pCte->zName
+ );
+ return SQLITE_ERROR;
+ }
+ assert( pTab->nTabRef==1 || ((pSel->selFlags&SF_Recursive) && pTab->nTabRef==2 ));
+
+ pCte->zCteErr = "circular reference: %s";
+ pSavedWith = pParse->pWith;
+ pParse->pWith = pWith;
+ if( bMayRecursive ){
+ Select *pPrior = pSel->pPrior;
+ assert( pPrior->pWith==0 );
+ pPrior->pWith = pSel->pWith;
+ sqlite3WalkSelect(pWalker, pPrior);
+ pPrior->pWith = 0;
+ }else{
+ sqlite3WalkSelect(pWalker, pSel);
+ }
+ pParse->pWith = pWith;
+
+ for(pLeft=pSel; pLeft->pPrior; pLeft=pLeft->pPrior);
+ pEList = pLeft->pEList;
+ if( pCte->pCols ){
+ if( pEList && pEList->nExpr!=pCte->pCols->nExpr ){
+ sqlite3ErrorMsg(pParse, "table %s has %d values for %d columns",
+ pCte->zName, pEList->nExpr, pCte->pCols->nExpr
+ );
+ pParse->pWith = pSavedWith;
+ return SQLITE_ERROR;
+ }
+ pEList = pCte->pCols;
+ }
+
+ sqlite3ColumnsFromExprList(pParse, pEList, &pTab->nCol, &pTab->aCol);
+ if( bMayRecursive ){
+ if( pSel->selFlags & SF_Recursive ){
+ pCte->zCteErr = "multiple recursive references: %s";
+ }else{
+ pCte->zCteErr = "recursive reference in a subquery: %s";
+ }
+ sqlite3WalkSelect(pWalker, pSel);
+ }
+ pCte->zCteErr = 0;
+ pParse->pWith = pSavedWith;
+ }
+
+ return SQLITE_OK;
+}
+#endif
+
+#ifndef SQLITE_OMIT_CTE
+/*
+** If the SELECT passed as the second argument has an associated WITH
+** clause, pop it from the stack stored as part of the Parse object.
+**
+** This function is used as the xSelectCallback2() callback by
+** sqlite3SelectExpand() when walking a SELECT tree to resolve table
+** names and other FROM clause elements.
+*/
+static void selectPopWith(Walker *pWalker, Select *p){
+ Parse *pParse = pWalker->pParse;
+ if( pParse->pWith && p->pPrior==0 ){
+ With *pWith = findRightmost(p)->pWith;
+ if( pWith!=0 ){
+ assert( pParse->pWith==pWith );
+ pParse->pWith = pWith->pOuter;
+ }
+ }
+}
+#else
+#define selectPopWith 0
+#endif
+
+/*
+** This routine is a Walker callback for "expanding" a SELECT statement.
+** "Expanding" means to do the following:
+**
+** (1) Make sure VDBE cursor numbers have been assigned to every
+** element of the FROM clause.
+**
+** (2) Fill in the pTabList->a[].pTab fields in the SrcList that
+** defines FROM clause. When views appear in the FROM clause,
+** fill pTabList->a[].pSelect with a copy of the SELECT statement
+** that implements the view. A copy is made of the view's SELECT
+** statement so that we can freely modify or delete that statement
+** without worrying about messing up the persistent representation
+** of the view.
+**
+** (3) Add terms to the WHERE clause to accommodate the NATURAL keyword
+** on joins and the ON and USING clause of joins.
+**
+** (4) Scan the list of columns in the result set (pEList) looking
+** for instances of the "*" operator or the TABLE.* operator.
+** If found, expand each "*" to be every column in every table
+** and TABLE.* to be every column in TABLE.
+**
+*/
+static int selectExpander(Walker *pWalker, Select *p){
+ Parse *pParse = pWalker->pParse;
+ int i, j, k;
+ SrcList *pTabList;
+ ExprList *pEList;
+ struct SrcList_item *pFrom;
+ sqlite3 *db = pParse->db;
+ Expr *pE, *pRight, *pExpr;
+ u16 selFlags = p->selFlags;
+
+ p->selFlags |= SF_Expanded;
+ if( db->mallocFailed ){
+ return WRC_Abort;
+ }
+ if( NEVER(p->pSrc==0) || (selFlags & SF_Expanded)!=0 ){
+ return WRC_Prune;
+ }
+ pTabList = p->pSrc;
+ pEList = p->pEList;
+ if( p->pWith ){
+ sqlite3WithPush(pParse, p->pWith, 0);
+ }
+
+ /* Make sure cursor numbers have been assigned to all entries in
+ ** the FROM clause of the SELECT statement.
+ */
+ sqlite3SrcListAssignCursors(pParse, pTabList);
+
+ /* Look up every table named in the FROM clause of the select. If
+ ** an entry of the FROM clause is a subquery instead of a table or view,
+ ** then create a transient table structure to describe the subquery.
+ */
+ for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
+ Table *pTab;
+ assert( pFrom->fg.isRecursive==0 || pFrom->pTab!=0 );
+ if( pFrom->fg.isRecursive ) continue;
+ assert( pFrom->pTab==0 );
+#ifndef SQLITE_OMIT_CTE
+ if( withExpand(pWalker, pFrom) ) return WRC_Abort;
+ if( pFrom->pTab ) {} else
+#endif
+ if( pFrom->zName==0 ){
+#ifndef SQLITE_OMIT_SUBQUERY
+ Select *pSel = pFrom->pSelect;
+ /* A sub-query in the FROM clause of a SELECT */
+ assert( pSel!=0 );
+ assert( pFrom->pTab==0 );
+ if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort;
+ pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
+ if( pTab==0 ) return WRC_Abort;
+ pTab->nTabRef = 1;
+ pTab->zName = sqlite3MPrintf(db, "sqlite_sq_%p", (void*)pTab);
+ while( pSel->pPrior ){ pSel = pSel->pPrior; }
+ sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol);
+ pTab->iPKey = -1;
+ pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
+ pTab->tabFlags |= TF_Ephemeral;
+#endif
+ }else{
+ /* An ordinary table or view name in the FROM clause */
+ assert( pFrom->pTab==0 );
+ pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom);
+ if( pTab==0 ) return WRC_Abort;
+ if( pTab->nTabRef>=0xffff ){
+ sqlite3ErrorMsg(pParse, "too many references to \"%s\": max 65535",
+ pTab->zName);
+ pFrom->pTab = 0;
+ return WRC_Abort;
+ }
+ pTab->nTabRef++;
+ if( !IsVirtual(pTab) && cannotBeFunction(pParse, pFrom) ){
+ return WRC_Abort;
+ }
+#if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
+ if( IsVirtual(pTab) || pTab->pSelect ){
+ i16 nCol;
+ if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
+ assert( pFrom->pSelect==0 );
+ pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
+ sqlite3SelectSetName(pFrom->pSelect, pTab->zName);
+ nCol = pTab->nCol;
+ pTab->nCol = -1;
+ sqlite3WalkSelect(pWalker, pFrom->pSelect);
+ pTab->nCol = nCol;
+ }
+#endif
+ }
+
+ /* Locate the index named by the INDEXED BY clause, if any. */
+ if( sqlite3IndexedByLookup(pParse, pFrom) ){
+ return WRC_Abort;
+ }
+ }
+
+ /* Process NATURAL keywords, and ON and USING clauses of joins.
+ */
+ if( db->mallocFailed || sqliteProcessJoin(pParse, p) ){
+ return WRC_Abort;
+ }
+
+ /* For every "*" that occurs in the column list, insert the names of
+ ** all columns in all tables. And for every TABLE.* insert the names
+ ** of all columns in TABLE. The parser inserted a special expression
+ ** with the TK_ASTERISK operator for each "*" that it found in the column
+ ** list. The following code just has to locate the TK_ASTERISK
+ ** expressions and expand each one to the list of all columns in
+ ** all tables.
+ **
+ ** The first loop just checks to see if there are any "*" operators
+ ** that need expanding.
+ */
+ for(k=0; k<pEList->nExpr; k++){
+ pE = pEList->a[k].pExpr;
+ if( pE->op==TK_ASTERISK ) break;
+ assert( pE->op!=TK_DOT || pE->pRight!=0 );
+ assert( pE->op!=TK_DOT || (pE->pLeft!=0 && pE->pLeft->op==TK_ID) );
+ if( pE->op==TK_DOT && pE->pRight->op==TK_ASTERISK ) break;
+ }
+ if( k<pEList->nExpr ){
+ /*
+ ** If we get here it means the result set contains one or more "*"
+ ** operators that need to be expanded. Loop through each expression
+ ** in the result set and expand them one by one.
+ */
+ struct ExprList_item *a = pEList->a;
+ ExprList *pNew = 0;
+ int flags = pParse->db->flags;
+ int longNames = (flags & SQLITE_FullColNames)!=0
+ && (flags & SQLITE_ShortColNames)==0;
+
+ for(k=0; k<pEList->nExpr; k++){
+ pE = a[k].pExpr;
+ pRight = pE->pRight;
+ assert( pE->op!=TK_DOT || pRight!=0 );
+ if( pE->op!=TK_ASTERISK
+ && (pE->op!=TK_DOT || pRight->op!=TK_ASTERISK)
+ ){
+ /* This particular expression does not need to be expanded.
+ */
+ pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr);
+ if( pNew ){
+ pNew->a[pNew->nExpr-1].zName = a[k].zName;
+ pNew->a[pNew->nExpr-1].zSpan = a[k].zSpan;
+ a[k].zName = 0;
+ a[k].zSpan = 0;
+ }
+ a[k].pExpr = 0;
+ }else{
+ /* This expression is a "*" or a "TABLE.*" and needs to be
+ ** expanded. */
+ int tableSeen = 0; /* Set to 1 when TABLE matches */
+ char *zTName = 0; /* text of name of TABLE */
+ if( pE->op==TK_DOT ){
+ assert( pE->pLeft!=0 );
+ assert( !ExprHasProperty(pE->pLeft, EP_IntValue) );
+ zTName = pE->pLeft->u.zToken;
+ }
+ for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
+ Table *pTab = pFrom->pTab;
+ Select *pSub = pFrom->pSelect;
+ char *zTabName = pFrom->zAlias;
+ const char *zSchemaName = 0;
+ int iDb;
+ if( zTabName==0 ){
+ zTabName = pTab->zName;
+ }
+ if( db->mallocFailed ) break;
+ if( pSub==0 || (pSub->selFlags & SF_NestedFrom)==0 ){
+ pSub = 0;
+ if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
+ continue;
+ }
+ iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+ zSchemaName = iDb>=0 ? db->aDb[iDb].zDbSName : "*";
+ }
+ for(j=0; j<pTab->nCol; j++){
+ char *zName = pTab->aCol[j].zName;
+ char *zColname; /* The computed column name */
+ char *zToFree; /* Malloced string that needs to be freed */
+ Token sColname; /* Computed column name as a token */
+
+ assert( zName );
+ if( zTName && pSub
+ && sqlite3MatchSpanName(pSub->pEList->a[j].zSpan, 0, zTName, 0)==0
+ ){
+ continue;
+ }
+
+ /* If a column is marked as 'hidden', omit it from the expanded
+ ** result-set list unless the SELECT has the SF_IncludeHidden
+ ** bit set.
+ */
+ if( (p->selFlags & SF_IncludeHidden)==0
+ && IsHiddenColumn(&pTab->aCol[j])
+ ){
+ continue;
+ }
+ tableSeen = 1;
+
+ if( i>0 && zTName==0 ){
+ if( (pFrom->fg.jointype & JT_NATURAL)!=0
+ && tableAndColumnIndex(pTabList, i, zName, 0, 0)
+ ){
+ /* In a NATURAL join, omit the join columns from the
+ ** table to the right of the join */
+ continue;
+ }
+ if( sqlite3IdListIndex(pFrom->pUsing, zName)>=0 ){
+ /* In a join with a USING clause, omit columns in the
+ ** using clause from the table on the right. */
+ continue;
+ }
+ }
+ pRight = sqlite3Expr(db, TK_ID, zName);
+ zColname = zName;
+ zToFree = 0;
+ if( longNames || pTabList->nSrc>1 ){
+ Expr *pLeft;
+ pLeft = sqlite3Expr(db, TK_ID, zTabName);
+ pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
+ if( zSchemaName ){
+ pLeft = sqlite3Expr(db, TK_ID, zSchemaName);
+ pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pExpr);
+ }
+ if( longNames ){
+ zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName);
+ zToFree = zColname;
+ }
+ }else{
+ pExpr = pRight;
+ }
+ pNew = sqlite3ExprListAppend(pParse, pNew, pExpr);
+ sqlite3TokenInit(&sColname, zColname);
+ sqlite3ExprListSetName(pParse, pNew, &sColname, 0);
+ if( pNew && (p->selFlags & SF_NestedFrom)!=0 ){
+ struct ExprList_item *pX = &pNew->a[pNew->nExpr-1];
+ if( pSub ){
+ pX->zSpan = sqlite3DbStrDup(db, pSub->pEList->a[j].zSpan);
+ testcase( pX->zSpan==0 );
+ }else{
+ pX->zSpan = sqlite3MPrintf(db, "%s.%s.%s",
+ zSchemaName, zTabName, zColname);
+ testcase( pX->zSpan==0 );
+ }
+ pX->bSpanIsTab = 1;
+ }
+ sqlite3DbFree(db, zToFree);
+ }
+ }
+ if( !tableSeen ){
+ if( zTName ){
+ sqlite3ErrorMsg(pParse, "no such table: %s", zTName);
+ }else{
+ sqlite3ErrorMsg(pParse, "no tables specified");
+ }
+ }
+ }
+ }
+ sqlite3ExprListDelete(db, pEList);
+ p->pEList = pNew;
+ }
+#if SQLITE_MAX_COLUMN
+ if( p->pEList && p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
+ sqlite3ErrorMsg(pParse, "too many columns in result set");
+ return WRC_Abort;
+ }
+#endif
+ return WRC_Continue;
+}
+
+/*
+** No-op routine for the parse-tree walker.
+**
+** When this routine is the Walker.xExprCallback then expression trees
+** are walked without any actions being taken at each node. Presumably,
+** when this routine is used for Walker.xExprCallback then
+** Walker.xSelectCallback is set to do something useful for every
+** subquery in the parser tree.
+*/
+SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
+ UNUSED_PARAMETER2(NotUsed, NotUsed2);
+ return WRC_Continue;
+}
+
+/*
+** This routine "expands" a SELECT statement and all of its subqueries.
+** For additional information on what it means to "expand" a SELECT
+** statement, see the comment on the selectExpand worker callback above.
+**
+** Expanding a SELECT statement is the first step in processing a
+** SELECT statement. The SELECT statement must be expanded before
+** name resolution is performed.
+**
+** If anything goes wrong, an error message is written into pParse.
+** The calling function can detect the problem by looking at pParse->nErr
+** and/or pParse->db->mallocFailed.
+*/
+static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
+ Walker w;
+ memset(&w, 0, sizeof(w));
+ w.xExprCallback = sqlite3ExprWalkNoop;
+ w.pParse = pParse;
+ if( pParse->hasCompound ){
+ w.xSelectCallback = convertCompoundSelectToSubquery;
+ sqlite3WalkSelect(&w, pSelect);
+ }
+ w.xSelectCallback = selectExpander;
+ w.xSelectCallback2 = selectPopWith;
+ sqlite3WalkSelect(&w, pSelect);
+}
+
+
+#ifndef SQLITE_OMIT_SUBQUERY
+/*
+** This is a Walker.xSelectCallback callback for the sqlite3SelectTypeInfo()
+** interface.
+**
+** For each FROM-clause subquery, add Column.zType and Column.zColl
+** information to the Table structure that represents the result set
+** of that subquery.
+**
+** The Table structure that represents the result set was constructed
+** by selectExpander() but the type and collation information was omitted
+** at that point because identifiers had not yet been resolved. This
+** routine is called after identifier resolution.
+*/
+static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
+ Parse *pParse;
+ int i;
+ SrcList *pTabList;
+ struct SrcList_item *pFrom;
+
+ assert( p->selFlags & SF_Resolved );
+ assert( (p->selFlags & SF_HasTypeInfo)==0 );
+ p->selFlags |= SF_HasTypeInfo;
+ pParse = pWalker->pParse;
+ pTabList = p->pSrc;
+ for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
+ Table *pTab = pFrom->pTab;
+ assert( pTab!=0 );
+ if( (pTab->tabFlags & TF_Ephemeral)!=0 ){
+ /* A sub-query in the FROM clause of a SELECT */
+ Select *pSel = pFrom->pSelect;
+ if( pSel ){
+ while( pSel->pPrior ) pSel = pSel->pPrior;
+ sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSel);
+ }
+ }
+ }
+}
+#endif
+
+
+/*
+** This routine adds datatype and collating sequence information to
+** the Table structures of all FROM-clause subqueries in a
+** SELECT statement.
+**
+** Use this routine after name resolution.
+*/
+static void sqlite3SelectAddTypeInfo(Parse *pParse, Select *pSelect){
+#ifndef SQLITE_OMIT_SUBQUERY
+ Walker w;
+ memset(&w, 0, sizeof(w));
+ w.xSelectCallback2 = selectAddSubqueryTypeInfo;
+ w.xExprCallback = sqlite3ExprWalkNoop;
+ w.pParse = pParse;
+ sqlite3WalkSelect(&w, pSelect);
+#endif
+}
+
+
+/*
+** This routine sets up a SELECT statement for processing. The
+** following is accomplished:
+**
+** * VDBE Cursor numbers are assigned to all FROM-clause terms.
+** * Ephemeral Table objects are created for all FROM-clause subqueries.
+** * ON and USING clauses are shifted into WHERE statements
+** * Wildcards "*" and "TABLE.*" in result sets are expanded.
+** * Identifiers in expression are matched to tables.
+**
+** This routine acts recursively on all subqueries within the SELECT.
+*/
+SQLITE_PRIVATE void sqlite3SelectPrep(
+ Parse *pParse, /* The parser context */
+ Select *p, /* The SELECT statement being coded. */
+ NameContext *pOuterNC /* Name context for container */
+){
+ sqlite3 *db;
+ if( NEVER(p==0) ) return;
+ db = pParse->db;
+ if( db->mallocFailed ) return;
+ if( p->selFlags & SF_HasTypeInfo ) return;
+ sqlite3SelectExpand(pParse, p);
+ if( pParse->nErr || db->mallocFailed ) return;
+ sqlite3ResolveSelectNames(pParse, p, pOuterNC);
+ if( pParse->nErr || db->mallocFailed ) return;
+ sqlite3SelectAddTypeInfo(pParse, p);
+}
+
+/*
+** Reset the aggregate accumulator.
+**
+** The aggregate accumulator is a set of memory cells that hold
+** intermediate results while calculating an aggregate. This
+** routine generates code that stores NULLs in all of those memory
+** cells.
+*/
+static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
+ Vdbe *v = pParse->pVdbe;
+ int i;
+ struct AggInfo_func *pFunc;
+ int nReg = pAggInfo->nFunc + pAggInfo->nColumn;
+ if( nReg==0 ) return;
+#ifdef SQLITE_DEBUG
+ /* Verify that all AggInfo registers are within the range specified by
+ ** AggInfo.mnReg..AggInfo.mxReg */
+ assert( nReg==pAggInfo->mxReg-pAggInfo->mnReg+1 );
+ for(i=0; i<pAggInfo->nColumn; i++){
+ assert( pAggInfo->aCol[i].iMem>=pAggInfo->mnReg
+ && pAggInfo->aCol[i].iMem<=pAggInfo->mxReg );
+ }
+ for(i=0; i<pAggInfo->nFunc; i++){
+ assert( pAggInfo->aFunc[i].iMem>=pAggInfo->mnReg
+ && pAggInfo->aFunc[i].iMem<=pAggInfo->mxReg );
+ }
+#endif
+ sqlite3VdbeAddOp3(v, OP_Null, 0, pAggInfo->mnReg, pAggInfo->mxReg);
+ for(pFunc=pAggInfo->aFunc, i=0; i<pAggInfo->nFunc; i++, pFunc++){
+ if( pFunc->iDistinct>=0 ){
+ Expr *pE = pFunc->pExpr;
+ assert( !ExprHasProperty(pE, EP_xIsSelect) );
+ if( pE->x.pList==0 || pE->x.pList->nExpr!=1 ){
+ sqlite3ErrorMsg(pParse, "DISTINCT aggregates must have exactly one "
+ "argument");
+ pFunc->iDistinct = -1;
+ }else{
+ KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList, 0, 0);
+ sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0,
+ (char*)pKeyInfo, P4_KEYINFO);
+ }
+ }
+ }
+}
+
+/*
+** Invoke the OP_AggFinalize opcode for every aggregate function
+** in the AggInfo structure.
+*/
+static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){
+ Vdbe *v = pParse->pVdbe;
+ int i;
+ struct AggInfo_func *pF;
+ for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
+ ExprList *pList = pF->pExpr->x.pList;
+ assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) );
+ sqlite3VdbeAddOp2(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0);
+ sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
+ }
+}
+
+/*
+** Update the accumulator memory cells for an aggregate based on
+** the current cursor position.
+*/
+static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
+ Vdbe *v = pParse->pVdbe;
+ int i;
+ int regHit = 0;
+ int addrHitTest = 0;
+ struct AggInfo_func *pF;
+ struct AggInfo_col *pC;
+
+ pAggInfo->directMode = 1;
+ for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
+ int nArg;
+ int addrNext = 0;
+ int regAgg;
+ ExprList *pList = pF->pExpr->x.pList;
+ assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) );
+ if( pList ){
+ nArg = pList->nExpr;
+ regAgg = sqlite3GetTempRange(pParse, nArg);
+ sqlite3ExprCodeExprList(pParse, pList, regAgg, 0, SQLITE_ECEL_DUP);
+ }else{
+ nArg = 0;
+ regAgg = 0;
+ }
+ if( pF->iDistinct>=0 ){
+ addrNext = sqlite3VdbeMakeLabel(v);
+ testcase( nArg==0 ); /* Error condition */
+ testcase( nArg>1 ); /* Also an error */
+ codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg);
+ }
+ if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
+ CollSeq *pColl = 0;
+ struct ExprList_item *pItem;
+ int j;
+ assert( pList!=0 ); /* pList!=0 if pF->pFunc has NEEDCOLL */
+ for(j=0, pItem=pList->a; !pColl && j<nArg; j++, pItem++){
+ pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
+ }
+ if( !pColl ){
+ pColl = pParse->db->pDfltColl;
+ }
+ if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem;
+ sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ);
+ }
+ sqlite3VdbeAddOp3(v, OP_AggStep0, 0, regAgg, pF->iMem);
+ sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
+ sqlite3VdbeChangeP5(v, (u8)nArg);
+ sqlite3ExprCacheAffinityChange(pParse, regAgg, nArg);
+ sqlite3ReleaseTempRange(pParse, regAgg, nArg);
+ if( addrNext ){
+ sqlite3VdbeResolveLabel(v, addrNext);
+ sqlite3ExprCacheClear(pParse);
+ }
+ }
+
+ /* Before populating the accumulator registers, clear the column cache.
+ ** Otherwise, if any of the required column values are already present
+ ** in registers, sqlite3ExprCode() may use OP_SCopy to copy the value
+ ** to pC->iMem. But by the time the value is used, the original register
+ ** may have been used, invalidating the underlying buffer holding the
+ ** text or blob value. See ticket [883034dcb5].
+ **
+ ** Another solution would be to change the OP_SCopy used to copy cached
+ ** values to an OP_Copy.
+ */
+ if( regHit ){
+ addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v);
+ }
+ sqlite3ExprCacheClear(pParse);
+ for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
+ sqlite3ExprCode(pParse, pC->pExpr, pC->iMem);
+ }
+ pAggInfo->directMode = 0;
+ sqlite3ExprCacheClear(pParse);
+ if( addrHitTest ){
+ sqlite3VdbeJumpHere(v, addrHitTest);
+ }
+}
+
+/*
+** Add a single OP_Explain instruction to the VDBE to explain a simple
+** count(*) query ("SELECT count(*) FROM pTab").
+*/
+#ifndef SQLITE_OMIT_EXPLAIN
+static void explainSimpleCount(
+ Parse *pParse, /* Parse context */
+ Table *pTab, /* Table being queried */
+ Index *pIdx /* Index used to optimize scan, or NULL */
+){
+ if( pParse->explain==2 ){
+ int bCover = (pIdx!=0 && (HasRowid(pTab) || !IsPrimaryKeyIndex(pIdx)));
+ char *zEqp = sqlite3MPrintf(pParse->db, "SCAN TABLE %s%s%s",
+ pTab->zName,
+ bCover ? " USING COVERING INDEX " : "",
+ bCover ? pIdx->zName : ""
+ );
+ sqlite3VdbeAddOp4(
+ pParse->pVdbe, OP_Explain, pParse->iSelectId, 0, 0, zEqp, P4_DYNAMIC
+ );
+ }
+}
+#else
+# define explainSimpleCount(a,b,c)
+#endif
+
+/*
+** Generate code for the SELECT statement given in the p argument.
+**
+** The results are returned according to the SelectDest structure.
+** See comments in sqliteInt.h for further information.
+**
+** This routine returns the number of errors. If any errors are
+** encountered, then an appropriate error message is left in
+** pParse->zErrMsg.
+**
+** This routine does NOT free the Select structure passed in. The
+** calling function needs to do that.
+*/
+SQLITE_PRIVATE int sqlite3Select(
+ Parse *pParse, /* The parser context */
+ Select *p, /* The SELECT statement being coded. */
+ SelectDest *pDest /* What to do with the query results */
+){
+ int i, j; /* Loop counters */
+ WhereInfo *pWInfo; /* Return from sqlite3WhereBegin() */
+ Vdbe *v; /* The virtual machine under construction */
+ int isAgg; /* True for select lists like "count(*)" */
+ ExprList *pEList = 0; /* List of columns to extract. */
+ SrcList *pTabList; /* List of tables to select from */
+ Expr *pWhere; /* The WHERE clause. May be NULL */
+ ExprList *pGroupBy; /* The GROUP BY clause. May be NULL */
+ Expr *pHaving; /* The HAVING clause. May be NULL */
+ int rc = 1; /* Value to return from this function */
+ DistinctCtx sDistinct; /* Info on how to code the DISTINCT keyword */
+ SortCtx sSort; /* Info on how to code the ORDER BY clause */
+ AggInfo sAggInfo; /* Information used by aggregate queries */
+ int iEnd; /* Address of the end of the query */
+ sqlite3 *db; /* The database connection */
+
+#ifndef SQLITE_OMIT_EXPLAIN
+ int iRestoreSelectId = pParse->iSelectId;
+ pParse->iSelectId = pParse->iNextSelectId++;
+#endif
+
+ db = pParse->db;
+ if( p==0 || db->mallocFailed || pParse->nErr ){
+ return 1;
+ }
+ if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
+ memset(&sAggInfo, 0, sizeof(sAggInfo));
+#if SELECTTRACE_ENABLED
+ pParse->nSelectIndent++;
+ SELECTTRACE(1,pParse,p, ("begin processing:\n"));
+ if( sqlite3SelectTrace & 0x100 ){
+ sqlite3TreeViewSelect(0, p, 0);
+ }
+#endif
+
+ assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo );
+ assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo );
+ assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue );
+ assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue );
+ if( IgnorableOrderby(pDest) ){
+ assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union ||
+ pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard ||
+ pDest->eDest==SRT_Queue || pDest->eDest==SRT_DistFifo ||
+ pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_Fifo);
+ /* If ORDER BY makes no difference in the output then neither does
+ ** DISTINCT so it can be removed too. */
+ sqlite3ExprListDelete(db, p->pOrderBy);
+ p->pOrderBy = 0;
+ p->selFlags &= ~SF_Distinct;
+ }
+ sqlite3SelectPrep(pParse, p, 0);
+ memset(&sSort, 0, sizeof(sSort));
+ sSort.pOrderBy = p->pOrderBy;
+ pTabList = p->pSrc;
+ if( pParse->nErr || db->mallocFailed ){
+ goto select_end;
+ }
+ assert( p->pEList!=0 );
+ isAgg = (p->selFlags & SF_Aggregate)!=0;
+#if SELECTTRACE_ENABLED
+ if( sqlite3SelectTrace & 0x100 ){
+ SELECTTRACE(0x100,pParse,p, ("after name resolution:\n"));
+ sqlite3TreeViewSelect(0, p, 0);
+ }
+#endif
+
+ /* Try to flatten subqueries in the FROM clause up into the main query
+ */
+#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
+ for(i=0; !p->pPrior && i<pTabList->nSrc; i++){
+ struct SrcList_item *pItem = &pTabList->a[i];
+ Select *pSub = pItem->pSelect;
+ int isAggSub;
+ Table *pTab = pItem->pTab;
+ if( pSub==0 ) continue;
+
+ /* Catch mismatch in the declared columns of a view and the number of
+ ** columns in the SELECT on the RHS */
+ if( pTab->nCol!=pSub->pEList->nExpr ){
+ sqlite3ErrorMsg(pParse, "expected %d columns for '%s' but got %d",
+ pTab->nCol, pTab->zName, pSub->pEList->nExpr);
+ goto select_end;
+ }
+
+ isAggSub = (pSub->selFlags & SF_Aggregate)!=0;
+ if( flattenSubquery(pParse, p, i, isAgg, isAggSub) ){
+ /* This subquery can be absorbed into its parent. */
+ if( isAggSub ){
+ isAgg = 1;
+ p->selFlags |= SF_Aggregate;
+ }
+ i = -1;
+ }
+ pTabList = p->pSrc;
+ if( db->mallocFailed ) goto select_end;
+ if( !IgnorableOrderby(pDest) ){
+ sSort.pOrderBy = p->pOrderBy;
+ }
+ }
+#endif
+
+ /* Get a pointer the VDBE under construction, allocating a new VDBE if one
+ ** does not already exist */
+ v = sqlite3GetVdbe(pParse);
+ if( v==0 ) goto select_end;
+
+#ifndef SQLITE_OMIT_COMPOUND_SELECT
+ /* Handle compound SELECT statements using the separate multiSelect()
+ ** procedure.
+ */
+ if( p->pPrior ){
+ rc = multiSelect(pParse, p, pDest);
+ explainSetInteger(pParse->iSelectId, iRestoreSelectId);
+#if SELECTTRACE_ENABLED
+ SELECTTRACE(1,pParse,p,("end compound-select processing\n"));
+ pParse->nSelectIndent--;
+#endif
+ return rc;
+ }
+#endif
+
+ /* Generate code for all sub-queries in the FROM clause
+ */
+#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
+ for(i=0; i<pTabList->nSrc; i++){
+ struct SrcList_item *pItem = &pTabList->a[i];
+ SelectDest dest;
+ Select *pSub = pItem->pSelect;
+ if( pSub==0 ) continue;
+
+ /* Sometimes the code for a subquery will be generated more than
+ ** once, if the subquery is part of the WHERE clause in a LEFT JOIN,
+ ** for example. In that case, do not regenerate the code to manifest
+ ** a view or the co-routine to implement a view. The first instance
+ ** is sufficient, though the subroutine to manifest the view does need
+ ** to be invoked again. */
+ if( pItem->addrFillSub ){
+ if( pItem->fg.viaCoroutine==0 ){
+ sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub);
+ }
+ continue;
+ }
+
+ /* Increment Parse.nHeight by the height of the largest expression
+ ** tree referred to by this, the parent select. The child select
+ ** may contain expression trees of at most
+ ** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit
+ ** more conservative than necessary, but much easier than enforcing
+ ** an exact limit.
+ */
+ pParse->nHeight += sqlite3SelectExprHeight(p);
+
+ /* Make copies of constant WHERE-clause terms in the outer query down
+ ** inside the subquery. This can help the subquery to run more efficiently.
+ */
+ if( (pItem->fg.jointype & JT_OUTER)==0
+ && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor)
+ ){
+#if SELECTTRACE_ENABLED
+ if( sqlite3SelectTrace & 0x100 ){
+ SELECTTRACE(0x100,pParse,p,("After WHERE-clause push-down:\n"));
+ sqlite3TreeViewSelect(0, p, 0);
+ }
+#endif
+ }
+
+ /* Generate code to implement the subquery
+ **
+ ** The subquery is implemented as a co-routine if all of these are true:
+ ** (1) The subquery is guaranteed to be the outer loop (so that it
+ ** does not need to be computed more than once)
+ ** (2) The ALL keyword after SELECT is omitted. (Applications are
+ ** allowed to say "SELECT ALL" instead of just "SELECT" to disable
+ ** the use of co-routines.)
+ ** (3) Co-routines are not disabled using sqlite3_test_control()
+ ** with SQLITE_TESTCTRL_OPTIMIZATIONS.
+ **
+ ** TODO: Are there other reasons beside (1) to use a co-routine
+ ** implementation?
+ */
+ if( i==0
+ && (pTabList->nSrc==1
+ || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0) /* (1) */
+ && (p->selFlags & SF_All)==0 /* (2) */
+ && OptimizationEnabled(db, SQLITE_SubqCoroutine) /* (3) */
+ ){
+ /* Implement a co-routine that will return a single row of the result
+ ** set on each invocation.
+ */
+ int addrTop = sqlite3VdbeCurrentAddr(v)+1;
+ pItem->regReturn = ++pParse->nMem;
+ sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop);
+ VdbeComment((v, "%s", pItem->pTab->zName));
+ pItem->addrFillSub = addrTop;
+ sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
+ explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
+ sqlite3Select(pParse, pSub, &dest);
+ pItem->pTab->nRowLogEst = pSub->nSelectRow;
+ pItem->fg.viaCoroutine = 1;
+ pItem->regResult = dest.iSdst;
+ sqlite3VdbeEndCoroutine(v, pItem->regReturn);
+ sqlite3VdbeJumpHere(v, addrTop-1);
+ sqlite3ClearTempRegCache(pParse);
+ }else{
+ /* Generate a subroutine that will fill an ephemeral table with
+ ** the content of this subquery. pItem->addrFillSub will point
+ ** to the address of the generated subroutine. pItem->regReturn
+ ** is a register allocated to hold the subroutine return address
+ */
+ int topAddr;
+ int onceAddr = 0;
+ int retAddr;
+ assert( pItem->addrFillSub==0 );
+ pItem->regReturn = ++pParse->nMem;
+ topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn);
+ pItem->addrFillSub = topAddr+1;
+ if( pItem->fg.isCorrelated==0 ){
+ /* If the subquery is not correlated and if we are not inside of
+ ** a trigger, then we only need to compute the value of the subquery
+ ** once. */
+ onceAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+ VdbeComment((v, "materialize \"%s\"", pItem->pTab->zName));
+ }else{
+ VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName));
+ }
+ sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
+ explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
+ sqlite3Select(pParse, pSub, &dest);
+ pItem->pTab->nRowLogEst = pSub->nSelectRow;
+ if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
+ retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn);
+ VdbeComment((v, "end %s", pItem->pTab->zName));
+ sqlite3VdbeChangeP1(v, topAddr, retAddr);
+ sqlite3ClearTempRegCache(pParse);
+ }
+ if( db->mallocFailed ) goto select_end;
+ pParse->nHeight -= sqlite3SelectExprHeight(p);
+ }
+#endif
+
+ /* Various elements of the SELECT copied into local variables for
+ ** convenience */
+ pEList = p->pEList;
+ pWhere = p->pWhere;
+ pGroupBy = p->pGroupBy;
+ pHaving = p->pHaving;
+ sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0;
+
+#if SELECTTRACE_ENABLED
+ if( sqlite3SelectTrace & 0x400 ){
+ SELECTTRACE(0x400,pParse,p,("After all FROM-clause analysis:\n"));
+ sqlite3TreeViewSelect(0, p, 0);
+ }
+#endif
+
+ /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and
+ ** if the select-list is the same as the ORDER BY list, then this query
+ ** can be rewritten as a GROUP BY. In other words, this:
+ **
+ ** SELECT DISTINCT xyz FROM ... ORDER BY xyz
+ **
+ ** is transformed to:
+ **
+ ** SELECT xyz FROM ... GROUP BY xyz ORDER BY xyz
+ **
+ ** The second form is preferred as a single index (or temp-table) may be
+ ** used for both the ORDER BY and DISTINCT processing. As originally
+ ** written the query must use a temp-table for at least one of the ORDER
+ ** BY and DISTINCT, and an index or separate temp-table for the other.
+ */
+ if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct
+ && sqlite3ExprListCompare(sSort.pOrderBy, pEList, -1)==0
+ ){
+ p->selFlags &= ~SF_Distinct;
+ pGroupBy = p->pGroupBy = sqlite3ExprListDup(db, pEList, 0);
+ /* Notice that even thought SF_Distinct has been cleared from p->selFlags,
+ ** the sDistinct.isTnct is still set. Hence, isTnct represents the
+ ** original setting of the SF_Distinct flag, not the current setting */
+ assert( sDistinct.isTnct );
+
+#if SELECTTRACE_ENABLED
+ if( sqlite3SelectTrace & 0x400 ){
+ SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n"));
+ sqlite3TreeViewSelect(0, p, 0);
+ }
+#endif
+ }
+
+ /* If there is an ORDER BY clause, then create an ephemeral index to
+ ** do the sorting. But this sorting ephemeral index might end up
+ ** being unused if the data can be extracted in pre-sorted order.
+ ** If that is the case, then the OP_OpenEphemeral instruction will be
+ ** changed to an OP_Noop once we figure out that the sorting index is
+ ** not needed. The sSort.addrSortIndex variable is used to facilitate
+ ** that change.
+ */
+ if( sSort.pOrderBy ){
+ KeyInfo *pKeyInfo;
+ pKeyInfo = keyInfoFromExprList(pParse, sSort.pOrderBy, 0, pEList->nExpr);
+ sSort.iECursor = pParse->nTab++;
+ sSort.addrSortIndex =
+ sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
+ sSort.iECursor, sSort.pOrderBy->nExpr+1+pEList->nExpr, 0,
+ (char*)pKeyInfo, P4_KEYINFO
+ );
+ }else{
+ sSort.addrSortIndex = -1;
+ }
+
+ /* If the output is destined for a temporary table, open that table.
+ */
+ if( pDest->eDest==SRT_EphemTab ){
+ sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr);
+ }
+
+ /* Set the limiter.
+ */
+ iEnd = sqlite3VdbeMakeLabel(v);
+ if( (p->selFlags & SF_FixedLimit)==0 ){
+ p->nSelectRow = 320; /* 4 billion rows */
+ }
+ computeLimitRegisters(pParse, p, iEnd);
+ if( p->iLimit==0 && sSort.addrSortIndex>=0 ){
+ sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen);
+ sSort.sortFlags |= SORTFLAG_UseSorter;
+ }
+
+ /* Open an ephemeral index to use for the distinct set.
+ */
+ if( p->selFlags & SF_Distinct ){
+ sDistinct.tabTnct = pParse->nTab++;
+ sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
+ sDistinct.tabTnct, 0, 0,
+ (char*)keyInfoFromExprList(pParse, p->pEList,0,0),
+ P4_KEYINFO);
+ sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
+ sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED;
+ }else{
+ sDistinct.eTnctType = WHERE_DISTINCT_NOOP;
+ }
+
+ if( !isAgg && pGroupBy==0 ){
+ /* No aggregate functions and no GROUP BY clause */
+ u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0);
+ assert( WHERE_USE_LIMIT==SF_FixedLimit );
+ wctrlFlags |= p->selFlags & SF_FixedLimit;
+
+ /* Begin the database scan. */
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy,
+ p->pEList, wctrlFlags, p->nSelectRow);
+ if( pWInfo==0 ) goto select_end;
+ if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){
+ p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo);
+ }
+ if( sDistinct.isTnct && sqlite3WhereIsDistinct(pWInfo) ){
+ sDistinct.eTnctType = sqlite3WhereIsDistinct(pWInfo);
+ }
+ if( sSort.pOrderBy ){
+ sSort.nOBSat = sqlite3WhereIsOrdered(pWInfo);
+ sSort.bOrderedInnerLoop = sqlite3WhereOrderedInnerLoop(pWInfo);
+ if( sSort.nOBSat==sSort.pOrderBy->nExpr ){
+ sSort.pOrderBy = 0;
+ }
+ }
+
+ /* If sorting index that was created by a prior OP_OpenEphemeral
+ ** instruction ended up not being needed, then change the OP_OpenEphemeral
+ ** into an OP_Noop.
+ */
+ if( sSort.addrSortIndex>=0 && sSort.pOrderBy==0 ){
+ sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex);
+ }
+
+ /* Use the standard inner loop. */
+ selectInnerLoop(pParse, p, pEList, -1, &sSort, &sDistinct, pDest,
+ sqlite3WhereContinueLabel(pWInfo),
+ sqlite3WhereBreakLabel(pWInfo));
+
+ /* End the database scan loop.
+ */
+ sqlite3WhereEnd(pWInfo);
+ }else{
+ /* This case when there exist aggregate functions or a GROUP BY clause
+ ** or both */
+ NameContext sNC; /* Name context for processing aggregate information */
+ int iAMem; /* First Mem address for storing current GROUP BY */
+ int iBMem; /* First Mem address for previous GROUP BY */
+ int iUseFlag; /* Mem address holding flag indicating that at least
+ ** one row of the input to the aggregator has been
+ ** processed */
+ int iAbortFlag; /* Mem address which causes query abort if positive */
+ int groupBySort; /* Rows come from source in GROUP BY order */
+ int addrEnd; /* End of processing for this SELECT */
+ int sortPTab = 0; /* Pseudotable used to decode sorting results */
+ int sortOut = 0; /* Output register from the sorter */
+ int orderByGrp = 0; /* True if the GROUP BY and ORDER BY are the same */
+
+ /* Remove any and all aliases between the result set and the
+ ** GROUP BY clause.
+ */
+ if( pGroupBy ){
+ int k; /* Loop counter */
+ struct ExprList_item *pItem; /* For looping over expression in a list */
+
+ for(k=p->pEList->nExpr, pItem=p->pEList->a; k>0; k--, pItem++){
+ pItem->u.x.iAlias = 0;
+ }
+ for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){
+ pItem->u.x.iAlias = 0;
+ }
+ assert( 66==sqlite3LogEst(100) );
+ if( p->nSelectRow>66 ) p->nSelectRow = 66;
+ }else{
+ assert( 0==sqlite3LogEst(1) );
+ p->nSelectRow = 0;
+ }
+
+ /* If there is both a GROUP BY and an ORDER BY clause and they are
+ ** identical, then it may be possible to disable the ORDER BY clause
+ ** on the grounds that the GROUP BY will cause elements to come out
+ ** in the correct order. It also may not - the GROUP BY might use a
+ ** database index that causes rows to be grouped together as required
+ ** but not actually sorted. Either way, record the fact that the
+ ** ORDER BY and GROUP BY clauses are the same by setting the orderByGrp
+ ** variable. */
+ if( sqlite3ExprListCompare(pGroupBy, sSort.pOrderBy, -1)==0 ){
+ orderByGrp = 1;
+ }
+
+ /* Create a label to jump to when we want to abort the query */
+ addrEnd = sqlite3VdbeMakeLabel(v);
+
+ /* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in
+ ** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the
+ ** SELECT statement.
+ */
+ memset(&sNC, 0, sizeof(sNC));
+ sNC.pParse = pParse;
+ sNC.pSrcList = pTabList;
+ sNC.pAggInfo = &sAggInfo;
+ sAggInfo.mnReg = pParse->nMem+1;
+ sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0;
+ sAggInfo.pGroupBy = pGroupBy;
+ sqlite3ExprAnalyzeAggList(&sNC, pEList);
+ sqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy);
+ if( pHaving ){
+ sqlite3ExprAnalyzeAggregates(&sNC, pHaving);
+ }
+ sAggInfo.nAccumulator = sAggInfo.nColumn;
+ for(i=0; i<sAggInfo.nFunc; i++){
+ assert( !ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_xIsSelect) );
+ sNC.ncFlags |= NC_InAggFunc;
+ sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->x.pList);
+ sNC.ncFlags &= ~NC_InAggFunc;
+ }
+ sAggInfo.mxReg = pParse->nMem;
+ if( db->mallocFailed ) goto select_end;
+
+ /* Processing for aggregates with GROUP BY is very different and
+ ** much more complex than aggregates without a GROUP BY.
+ */
+ if( pGroupBy ){
+ KeyInfo *pKeyInfo; /* Keying information for the group by clause */
+ int addr1; /* A-vs-B comparision jump */
+ int addrOutputRow; /* Start of subroutine that outputs a result row */
+ int regOutputRow; /* Return address register for output subroutine */
+ int addrSetAbort; /* Set the abort flag and return */
+ int addrTopOfLoop; /* Top of the input loop */
+ int addrSortingIdx; /* The OP_OpenEphemeral for the sorting index */
+ int addrReset; /* Subroutine for resetting the accumulator */
+ int regReset; /* Return address register for reset subroutine */
+
+ /* If there is a GROUP BY clause we might need a sorting index to
+ ** implement it. Allocate that sorting index now. If it turns out
+ ** that we do not need it after all, the OP_SorterOpen instruction
+ ** will be converted into a Noop.
+ */
+ sAggInfo.sortingIdx = pParse->nTab++;
+ pKeyInfo = keyInfoFromExprList(pParse, pGroupBy, 0, sAggInfo.nColumn);
+ addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen,
+ sAggInfo.sortingIdx, sAggInfo.nSortingColumn,
+ 0, (char*)pKeyInfo, P4_KEYINFO);
+
+ /* Initialize memory locations used by GROUP BY aggregate processing
+ */
+ iUseFlag = ++pParse->nMem;
+ iAbortFlag = ++pParse->nMem;
+ regOutputRow = ++pParse->nMem;
+ addrOutputRow = sqlite3VdbeMakeLabel(v);
+ regReset = ++pParse->nMem;
+ addrReset = sqlite3VdbeMakeLabel(v);
+ iAMem = pParse->nMem + 1;
+ pParse->nMem += pGroupBy->nExpr;
+ iBMem = pParse->nMem + 1;
+ pParse->nMem += pGroupBy->nExpr;
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, iAbortFlag);
+ VdbeComment((v, "clear abort flag"));
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag);
+ VdbeComment((v, "indicate accumulator empty"));
+ sqlite3VdbeAddOp3(v, OP_Null, 0, iAMem, iAMem+pGroupBy->nExpr-1);
+
+ /* Begin a loop that will extract all source rows in GROUP BY order.
+ ** This might involve two separate loops with an OP_Sort in between, or
+ ** it might be a single loop that uses an index to extract information
+ ** in the right order to begin with.
+ */
+ sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0,
+ WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0), 0
+ );
+ if( pWInfo==0 ) goto select_end;
+ if( sqlite3WhereIsOrdered(pWInfo)==pGroupBy->nExpr ){
+ /* The optimizer is able to deliver rows in group by order so
+ ** we do not have to sort. The OP_OpenEphemeral table will be
+ ** cancelled later because we still need to use the pKeyInfo
+ */
+ groupBySort = 0;
+ }else{
+ /* Rows are coming out in undetermined order. We have to push
+ ** each row into a sorting index, terminate the first loop,
+ ** then loop over the sorting index in order to get the output
+ ** in sorted order
+ */
+ int regBase;
+ int regRecord;
+ int nCol;
+ int nGroupBy;
+
+ explainTempTable(pParse,
+ (sDistinct.isTnct && (p->selFlags&SF_Distinct)==0) ?
+ "DISTINCT" : "GROUP BY");
+
+ groupBySort = 1;
+ nGroupBy = pGroupBy->nExpr;
+ nCol = nGroupBy;
+ j = nGroupBy;
+ for(i=0; i<sAggInfo.nColumn; i++){
+ if( sAggInfo.aCol[i].iSorterColumn>=j ){
+ nCol++;
+ j++;
+ }
+ }
+ regBase = sqlite3GetTempRange(pParse, nCol);
+ sqlite3ExprCacheClear(pParse);
+ sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0);
+ j = nGroupBy;
+ for(i=0; i<sAggInfo.nColumn; i++){
+ struct AggInfo_col *pCol = &sAggInfo.aCol[i];
+ if( pCol->iSorterColumn>=j ){
+ int r1 = j + regBase;
+ sqlite3ExprCodeGetColumnToReg(pParse,
+ pCol->pTab, pCol->iColumn, pCol->iTable, r1);
+ j++;
+ }
+ }
+ regRecord = sqlite3GetTempReg(pParse);
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord);
+ sqlite3VdbeAddOp2(v, OP_SorterInsert, sAggInfo.sortingIdx, regRecord);
+ sqlite3ReleaseTempReg(pParse, regRecord);
+ sqlite3ReleaseTempRange(pParse, regBase, nCol);
+ sqlite3WhereEnd(pWInfo);
+ sAggInfo.sortingIdxPTab = sortPTab = pParse->nTab++;
+ sortOut = sqlite3GetTempReg(pParse);
+ sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol);
+ sqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd);
+ VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v);
+ sAggInfo.useSortingIdx = 1;
+ sqlite3ExprCacheClear(pParse);
+
+ }
+
+ /* If the index or temporary table used by the GROUP BY sort
+ ** will naturally deliver rows in the order required by the ORDER BY
+ ** clause, cancel the ephemeral table open coded earlier.
+ **
+ ** This is an optimization - the correct answer should result regardless.
+ ** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER to
+ ** disable this optimization for testing purposes. */
+ if( orderByGrp && OptimizationEnabled(db, SQLITE_GroupByOrder)
+ && (groupBySort || sqlite3WhereIsSorted(pWInfo))
+ ){
+ sSort.pOrderBy = 0;
+ sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex);
+ }
+
+ /* Evaluate the current GROUP BY terms and store in b0, b1, b2...
+ ** (b0 is memory location iBMem+0, b1 is iBMem+1, and so forth)
+ ** Then compare the current GROUP BY terms against the GROUP BY terms
+ ** from the previous row currently stored in a0, a1, a2...
+ */
+ addrTopOfLoop = sqlite3VdbeCurrentAddr(v);
+ sqlite3ExprCacheClear(pParse);
+ if( groupBySort ){
+ sqlite3VdbeAddOp3(v, OP_SorterData, sAggInfo.sortingIdx,
+ sortOut, sortPTab);
+ }
+ for(j=0; j<pGroupBy->nExpr; j++){
+ if( groupBySort ){
+ sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j);
+ }else{
+ sAggInfo.directMode = 1;
+ sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
+ }
+ }
+ sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr,
+ (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
+ addr1 = sqlite3VdbeCurrentAddr(v);
+ sqlite3VdbeAddOp3(v, OP_Jump, addr1+1, 0, addr1+1); VdbeCoverage(v);
+
+ /* Generate code that runs whenever the GROUP BY changes.
+ ** Changes in the GROUP BY are detected by the previous code
+ ** block. If there were no changes, this block is skipped.
+ **
+ ** This code copies current group by terms in b0,b1,b2,...
+ ** over to a0,a1,a2. It then calls the output subroutine
+ ** and resets the aggregate accumulator registers in preparation
+ ** for the next GROUP BY batch.
+ */
+ sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr);
+ sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow);
+ VdbeComment((v, "output one row"));
+ sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); VdbeCoverage(v);
+ VdbeComment((v, "check abort flag"));
+ sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
+ VdbeComment((v, "reset accumulator"));
+
+ /* Update the aggregate accumulators based on the content of
+ ** the current row
+ */
+ sqlite3VdbeJumpHere(v, addr1);
+ updateAccumulator(pParse, &sAggInfo);
+ sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag);
+ VdbeComment((v, "indicate data in accumulator"));
+
+ /* End of the loop
+ */
+ if( groupBySort ){
+ sqlite3VdbeAddOp2(v, OP_SorterNext, sAggInfo.sortingIdx, addrTopOfLoop);
+ VdbeCoverage(v);
+ }else{
+ sqlite3WhereEnd(pWInfo);
+ sqlite3VdbeChangeToNoop(v, addrSortingIdx);
+ }
+
+ /* Output the final row of result
+ */
+ sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow);
+ VdbeComment((v, "output final row"));
+
+ /* Jump over the subroutines
+ */
+ sqlite3VdbeGoto(v, addrEnd);
+
+ /* Generate a subroutine that outputs a single row of the result
+ ** set. This subroutine first looks at the iUseFlag. If iUseFlag
+ ** is less than or equal to zero, the subroutine is a no-op. If
+ ** the processing calls for the query to abort, this subroutine
+ ** increments the iAbortFlag memory location before returning in
+ ** order to signal the caller to abort.
+ */
+ addrSetAbort = sqlite3VdbeCurrentAddr(v);
+ sqlite3VdbeAddOp2(v, OP_Integer, 1, iAbortFlag);
+ VdbeComment((v, "set abort flag"));
+ sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
+ sqlite3VdbeResolveLabel(v, addrOutputRow);
+ addrOutputRow = sqlite3VdbeCurrentAddr(v);
+ sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2);
+ VdbeCoverage(v);
+ VdbeComment((v, "Groupby result generator entry point"));
+ sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
+ finalizeAggFunctions(pParse, &sAggInfo);
+ sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
+ selectInnerLoop(pParse, p, p->pEList, -1, &sSort,
+ &sDistinct, pDest,
+ addrOutputRow+1, addrSetAbort);
+ sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
+ VdbeComment((v, "end groupby result generator"));
+
+ /* Generate a subroutine that will reset the group-by accumulator
+ */
+ sqlite3VdbeResolveLabel(v, addrReset);
+ resetAccumulator(pParse, &sAggInfo);
+ sqlite3VdbeAddOp1(v, OP_Return, regReset);
+
+ } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */
+ else {
+ ExprList *pDel = 0;
+#ifndef SQLITE_OMIT_BTREECOUNT
+ Table *pTab;
+ if( (pTab = isSimpleCount(p, &sAggInfo))!=0 ){
+ /* If isSimpleCount() returns a pointer to a Table structure, then
+ ** the SQL statement is of the form:
+ **
+ ** SELECT count(*) FROM <tbl>
+ **
+ ** where the Table structure returned represents table <tbl>.
+ **
+ ** This statement is so common that it is optimized specially. The
+ ** OP_Count instruction is executed either on the intkey table that
+ ** contains the data for table <tbl> or on one of its indexes. It
+ ** is better to execute the op on an index, as indexes are almost
+ ** always spread across less pages than their corresponding tables.
+ */
+ const int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
+ const int iCsr = pParse->nTab++; /* Cursor to scan b-tree */
+ Index *pIdx; /* Iterator variable */
+ KeyInfo *pKeyInfo = 0; /* Keyinfo for scanned index */
+ Index *pBest = 0; /* Best index found so far */
+ int iRoot = pTab->tnum; /* Root page of scanned b-tree */
+
+ sqlite3CodeVerifySchema(pParse, iDb);
+ sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
+
+ /* Search for the index that has the lowest scan cost.
+ **
+ ** (2011-04-15) Do not do a full scan of an unordered index.
+ **
+ ** (2013-10-03) Do not count the entries in a partial index.
+ **
+ ** In practice the KeyInfo structure will not be used. It is only
+ ** passed to keep OP_OpenRead happy.
+ */
+ if( !HasRowid(pTab) ) pBest = sqlite3PrimaryKeyIndex(pTab);
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ if( pIdx->bUnordered==0
+ && pIdx->szIdxRow<pTab->szTabRow
+ && pIdx->pPartIdxWhere==0
+ && (!pBest || pIdx->szIdxRow<pBest->szIdxRow)
+ ){
+ pBest = pIdx;
+ }
+ }
+ if( pBest ){
+ iRoot = pBest->tnum;
+ pKeyInfo = sqlite3KeyInfoOfIndex(pParse, pBest);
+ }
+
+ /* Open a read-only cursor, execute the OP_Count, close the cursor. */
+ sqlite3VdbeAddOp4Int(v, OP_OpenRead, iCsr, iRoot, iDb, 1);
+ if( pKeyInfo ){
+ sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO);
+ }
+ sqlite3VdbeAddOp2(v, OP_Count, iCsr, sAggInfo.aFunc[0].iMem);
+ sqlite3VdbeAddOp1(v, OP_Close, iCsr);
+ explainSimpleCount(pParse, pTab, pBest);
+ }else
+#endif /* SQLITE_OMIT_BTREECOUNT */
+ {
+ /* Check if the query is of one of the following forms:
+ **
+ ** SELECT min(x) FROM ...
+ ** SELECT max(x) FROM ...
+ **
+ ** If it is, then ask the code in where.c to attempt to sort results
+ ** as if there was an "ORDER ON x" or "ORDER ON x DESC" clause.
+ ** If where.c is able to produce results sorted in this order, then
+ ** add vdbe code to break out of the processing loop after the
+ ** first iteration (since the first iteration of the loop is
+ ** guaranteed to operate on the row with the minimum or maximum
+ ** value of x, the only row required).
+ **
+ ** A special flag must be passed to sqlite3WhereBegin() to slightly
+ ** modify behavior as follows:
+ **
+ ** + If the query is a "SELECT min(x)", then the loop coded by
+ ** where.c should not iterate over any values with a NULL value
+ ** for x.
+ **
+ ** + The optimizer code in where.c (the thing that decides which
+ ** index or indices to use) should place a different priority on
+ ** satisfying the 'ORDER BY' clause than it does in other cases.
+ ** Refer to code and comments in where.c for details.
+ */
+ ExprList *pMinMax = 0;
+ u8 flag = WHERE_ORDERBY_NORMAL;
+
+ assert( p->pGroupBy==0 );
+ assert( flag==0 );
+ if( p->pHaving==0 ){
+ flag = minMaxQuery(&sAggInfo, &pMinMax);
+ }
+ assert( flag==0 || (pMinMax!=0 && pMinMax->nExpr==1) );
+
+ if( flag ){
+ pMinMax = sqlite3ExprListDup(db, pMinMax, 0);
+ pDel = pMinMax;
+ assert( db->mallocFailed || pMinMax!=0 );
+ if( !db->mallocFailed ){
+ pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0;
+ pMinMax->a[0].pExpr->op = TK_COLUMN;
+ }
+ }
+
+ /* This case runs if the aggregate has no GROUP BY clause. The
+ ** processing is much simpler since there is only a single row
+ ** of output.
+ */
+ resetAccumulator(pParse, &sAggInfo);
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMax, 0,flag,0);
+ if( pWInfo==0 ){
+ sqlite3ExprListDelete(db, pDel);
+ goto select_end;
+ }
+ updateAccumulator(pParse, &sAggInfo);
+ assert( pMinMax==0 || pMinMax->nExpr==1 );
+ if( sqlite3WhereIsOrdered(pWInfo)>0 ){
+ sqlite3VdbeGoto(v, sqlite3WhereBreakLabel(pWInfo));
+ VdbeComment((v, "%s() by index",
+ (flag==WHERE_ORDERBY_MIN?"min":"max")));
+ }
+ sqlite3WhereEnd(pWInfo);
+ finalizeAggFunctions(pParse, &sAggInfo);
+ }
+
+ sSort.pOrderBy = 0;
+ sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL);
+ selectInnerLoop(pParse, p, p->pEList, -1, 0, 0,
+ pDest, addrEnd, addrEnd);
+ sqlite3ExprListDelete(db, pDel);
+ }
+ sqlite3VdbeResolveLabel(v, addrEnd);
+
+ } /* endif aggregate query */
+
+ if( sDistinct.eTnctType==WHERE_DISTINCT_UNORDERED ){
+ explainTempTable(pParse, "DISTINCT");
+ }
+
+ /* If there is an ORDER BY clause, then we need to sort the results
+ ** and send them to the callback one by one.
+ */
+ if( sSort.pOrderBy ){
+ explainTempTable(pParse,
+ sSort.nOBSat>0 ? "RIGHT PART OF ORDER BY":"ORDER BY");
+ generateSortTail(pParse, p, &sSort, pEList->nExpr, pDest);
+ }
+
+ /* Jump here to skip this query
+ */
+ sqlite3VdbeResolveLabel(v, iEnd);
+
+ /* The SELECT has been coded. If there is an error in the Parse structure,
+ ** set the return code to 1. Otherwise 0. */
+ rc = (pParse->nErr>0);
+
+ /* Control jumps to here if an error is encountered above, or upon
+ ** successful coding of the SELECT.
+ */
+select_end:
+ explainSetInteger(pParse->iSelectId, iRestoreSelectId);
+
+ /* Identify column names if results of the SELECT are to be output.
+ */
+ if( rc==SQLITE_OK && pDest->eDest==SRT_Output ){
+ generateColumnNames(pParse, pTabList, pEList);
+ }
+
+ sqlite3DbFree(db, sAggInfo.aCol);
+ sqlite3DbFree(db, sAggInfo.aFunc);
+#if SELECTTRACE_ENABLED
+ SELECTTRACE(1,pParse,p,("end processing\n"));
+ pParse->nSelectIndent--;
+#endif
+ return rc;
+}
+
+/************** End of select.c **********************************************/
+/************** Begin file table.c *******************************************/
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains the sqlite3_get_table() and sqlite3_free_table()
+** interface routines. These are just wrappers around the main
+** interface routine of sqlite3_exec().
+**
+** These routines are in a separate files so that they will not be linked
+** if they are not used.
+*/
+/* #include "sqliteInt.h" */
+
+#ifndef SQLITE_OMIT_GET_TABLE
+
+/*
+** This structure is used to pass data from sqlite3_get_table() through
+** to the callback function is uses to build the result.
+*/
+typedef struct TabResult {
+ char **azResult; /* Accumulated output */
+ char *zErrMsg; /* Error message text, if an error occurs */
+ u32 nAlloc; /* Slots allocated for azResult[] */
+ u32 nRow; /* Number of rows in the result */
+ u32 nColumn; /* Number of columns in the result */
+ u32 nData; /* Slots used in azResult[]. (nRow+1)*nColumn */
+ int rc; /* Return code from sqlite3_exec() */
+} TabResult;
+
+/*
+** This routine is called once for each row in the result table. Its job
+** is to fill in the TabResult structure appropriately, allocating new
+** memory as necessary.
+*/
+static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
+ TabResult *p = (TabResult*)pArg; /* Result accumulator */
+ int need; /* Slots needed in p->azResult[] */
+ int i; /* Loop counter */
+ char *z; /* A single column of result */
+
+ /* Make sure there is enough space in p->azResult to hold everything
+ ** we need to remember from this invocation of the callback.
+ */
+ if( p->nRow==0 && argv!=0 ){
+ need = nCol*2;
+ }else{
+ need = nCol;
+ }
+ if( p->nData + need > p->nAlloc ){
+ char **azNew;
+ p->nAlloc = p->nAlloc*2 + need;
+ azNew = sqlite3_realloc64( p->azResult, sizeof(char*)*p->nAlloc );
+ if( azNew==0 ) goto malloc_failed;
+ p->azResult = azNew;
+ }
+
+ /* If this is the first row, then generate an extra row containing
+ ** the names of all columns.
+ */
+ if( p->nRow==0 ){
+ p->nColumn = nCol;
+ for(i=0; i<nCol; i++){
+ z = sqlite3_mprintf("%s", colv[i]);
+ if( z==0 ) goto malloc_failed;
+ p->azResult[p->nData++] = z;
+ }
+ }else if( (int)p->nColumn!=nCol ){
+ sqlite3_free(p->zErrMsg);
+ p->zErrMsg = sqlite3_mprintf(
+ "sqlite3_get_table() called with two or more incompatible queries"
+ );
+ p->rc = SQLITE_ERROR;
+ return 1;
+ }
+
+ /* Copy over the row data
+ */
+ if( argv!=0 ){
+ for(i=0; i<nCol; i++){
+ if( argv[i]==0 ){
+ z = 0;
+ }else{
+ int n = sqlite3Strlen30(argv[i])+1;
+ z = sqlite3_malloc64( n );
+ if( z==0 ) goto malloc_failed;
+ memcpy(z, argv[i], n);
+ }
+ p->azResult[p->nData++] = z;
+ }
+ p->nRow++;
+ }
+ return 0;
+
+malloc_failed:
+ p->rc = SQLITE_NOMEM_BKPT;
+ return 1;
+}
+
+/*
+** Query the database. But instead of invoking a callback for each row,
+** malloc() for space to hold the result and return the entire results
+** at the conclusion of the call.
+**
+** The result that is written to ***pazResult is held in memory obtained
+** from malloc(). But the caller cannot free this memory directly.
+** Instead, the entire table should be passed to sqlite3_free_table() when
+** the calling procedure is finished using it.
+*/
+SQLITE_API int sqlite3_get_table(
+ sqlite3 *db, /* The database on which the SQL executes */
+ const char *zSql, /* The SQL to be executed */
+ char ***pazResult, /* Write the result table here */
+ int *pnRow, /* Write the number of rows in the result here */
+ int *pnColumn, /* Write the number of columns of result here */
+ char **pzErrMsg /* Write error messages here */
+){
+ int rc;
+ TabResult res;
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) || pazResult==0 ) return SQLITE_MISUSE_BKPT;
+#endif
+ *pazResult = 0;
+ if( pnColumn ) *pnColumn = 0;
+ if( pnRow ) *pnRow = 0;
+ if( pzErrMsg ) *pzErrMsg = 0;
+ res.zErrMsg = 0;
+ res.nRow = 0;
+ res.nColumn = 0;
+ res.nData = 1;
+ res.nAlloc = 20;
+ res.rc = SQLITE_OK;
+ res.azResult = sqlite3_malloc64(sizeof(char*)*res.nAlloc );
+ if( res.azResult==0 ){
+ db->errCode = SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
+ }
+ res.azResult[0] = 0;
+ rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg);
+ assert( sizeof(res.azResult[0])>= sizeof(res.nData) );
+ res.azResult[0] = SQLITE_INT_TO_PTR(res.nData);
+ if( (rc&0xff)==SQLITE_ABORT ){
+ sqlite3_free_table(&res.azResult[1]);
+ if( res.zErrMsg ){
+ if( pzErrMsg ){
+ sqlite3_free(*pzErrMsg);
+ *pzErrMsg = sqlite3_mprintf("%s",res.zErrMsg);
+ }
+ sqlite3_free(res.zErrMsg);
+ }
+ db->errCode = res.rc; /* Assume 32-bit assignment is atomic */
+ return res.rc;
+ }
+ sqlite3_free(res.zErrMsg);
+ if( rc!=SQLITE_OK ){
+ sqlite3_free_table(&res.azResult[1]);
+ return rc;
+ }
+ if( res.nAlloc>res.nData ){
+ char **azNew;
+ azNew = sqlite3_realloc64( res.azResult, sizeof(char*)*res.nData );
+ if( azNew==0 ){
+ sqlite3_free_table(&res.azResult[1]);
+ db->errCode = SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
+ }
+ res.azResult = azNew;
+ }
+ *pazResult = &res.azResult[1];
+ if( pnColumn ) *pnColumn = res.nColumn;
+ if( pnRow ) *pnRow = res.nRow;
+ return rc;
+}
+
+/*
+** This routine frees the space the sqlite3_get_table() malloced.
+*/
+SQLITE_API void sqlite3_free_table(
+ char **azResult /* Result returned from sqlite3_get_table() */
+){
+ if( azResult ){
+ int i, n;
+ azResult--;
+ assert( azResult!=0 );
+ n = SQLITE_PTR_TO_INT(azResult[0]);
+ for(i=1; i<n; i++){ if( azResult[i] ) sqlite3_free(azResult[i]); }
+ sqlite3_free(azResult);
+ }
+}
+
+#endif /* SQLITE_OMIT_GET_TABLE */
+
+/************** End of table.c ***********************************************/
+/************** Begin file trigger.c *****************************************/
+/*
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains the implementation for TRIGGERs
+*/
+/* #include "sqliteInt.h" */
+
+#ifndef SQLITE_OMIT_TRIGGER
+/*
+** Delete a linked list of TriggerStep structures.
+*/
+SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3 *db, TriggerStep *pTriggerStep){
+ while( pTriggerStep ){
+ TriggerStep * pTmp = pTriggerStep;
+ pTriggerStep = pTriggerStep->pNext;
+
+ sqlite3ExprDelete(db, pTmp->pWhere);
+ sqlite3ExprListDelete(db, pTmp->pExprList);
+ sqlite3SelectDelete(db, pTmp->pSelect);
+ sqlite3IdListDelete(db, pTmp->pIdList);
+
+ sqlite3DbFree(db, pTmp);
+ }
+}
+
+/*
+** Given table pTab, return a list of all the triggers attached to
+** the table. The list is connected by Trigger.pNext pointers.
+**
+** All of the triggers on pTab that are in the same database as pTab
+** are already attached to pTab->pTrigger. But there might be additional
+** triggers on pTab in the TEMP schema. This routine prepends all
+** TEMP triggers on pTab to the beginning of the pTab->pTrigger list
+** and returns the combined list.
+**
+** To state it another way: This routine returns a list of all triggers
+** that fire off of pTab. The list will include any TEMP triggers on
+** pTab as well as the triggers lised in pTab->pTrigger.
+*/
+SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){
+ Schema * const pTmpSchema = pParse->db->aDb[1].pSchema;
+ Trigger *pList = 0; /* List of triggers to return */
+
+ if( pParse->disableTriggers ){
+ return 0;
+ }
+
+ if( pTmpSchema!=pTab->pSchema ){
+ HashElem *p;
+ assert( sqlite3SchemaMutexHeld(pParse->db, 0, pTmpSchema) );
+ for(p=sqliteHashFirst(&pTmpSchema->trigHash); p; p=sqliteHashNext(p)){
+ Trigger *pTrig = (Trigger *)sqliteHashData(p);
+ if( pTrig->pTabSchema==pTab->pSchema
+ && 0==sqlite3StrICmp(pTrig->table, pTab->zName)
+ ){
+ pTrig->pNext = (pList ? pList : pTab->pTrigger);
+ pList = pTrig;
+ }
+ }
+ }
+
+ return (pList ? pList : pTab->pTrigger);
+}
+
+/*
+** This is called by the parser when it sees a CREATE TRIGGER statement
+** up to the point of the BEGIN before the trigger actions. A Trigger
+** structure is generated based on the information available and stored
+** in pParse->pNewTrigger. After the trigger actions have been parsed, the
+** sqlite3FinishTrigger() function is called to complete the trigger
+** construction process.
+*/
+SQLITE_PRIVATE void sqlite3BeginTrigger(
+ Parse *pParse, /* The parse context of the CREATE TRIGGER statement */
+ Token *pName1, /* The name of the trigger */
+ Token *pName2, /* The name of the trigger */
+ int tr_tm, /* One of TK_BEFORE, TK_AFTER, TK_INSTEAD */
+ int op, /* One of TK_INSERT, TK_UPDATE, TK_DELETE */
+ IdList *pColumns, /* column list if this is an UPDATE OF trigger */
+ SrcList *pTableName,/* The name of the table/view the trigger applies to */
+ Expr *pWhen, /* WHEN clause */
+ int isTemp, /* True if the TEMPORARY keyword is present */
+ int noErr /* Suppress errors if the trigger already exists */
+){
+ Trigger *pTrigger = 0; /* The new trigger */
+ Table *pTab; /* Table that the trigger fires off of */
+ char *zName = 0; /* Name of the trigger */
+ sqlite3 *db = pParse->db; /* The database connection */
+ int iDb; /* The database to store the trigger in */
+ Token *pName; /* The unqualified db name */
+ DbFixer sFix; /* State vector for the DB fixer */
+
+ assert( pName1!=0 ); /* pName1->z might be NULL, but not pName1 itself */
+ assert( pName2!=0 );
+ assert( op==TK_INSERT || op==TK_UPDATE || op==TK_DELETE );
+ assert( op>0 && op<0xff );
+ if( isTemp ){
+ /* If TEMP was specified, then the trigger name may not be qualified. */
+ if( pName2->n>0 ){
+ sqlite3ErrorMsg(pParse, "temporary trigger may not have qualified name");
+ goto trigger_cleanup;
+ }
+ iDb = 1;
+ pName = pName1;
+ }else{
+ /* Figure out the db that the trigger will be created in */
+ iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
+ if( iDb<0 ){
+ goto trigger_cleanup;
+ }
+ }
+ if( !pTableName || db->mallocFailed ){
+ goto trigger_cleanup;
+ }
+
+ /* A long-standing parser bug is that this syntax was allowed:
+ **
+ ** CREATE TRIGGER attached.demo AFTER INSERT ON attached.tab ....
+ ** ^^^^^^^^
+ **
+ ** To maintain backwards compatibility, ignore the database
+ ** name on pTableName if we are reparsing out of SQLITE_MASTER.
+ */
+ if( db->init.busy && iDb!=1 ){
+ sqlite3DbFree(db, pTableName->a[0].zDatabase);
+ pTableName->a[0].zDatabase = 0;
+ }
+
+ /* If the trigger name was unqualified, and the table is a temp table,
+ ** then set iDb to 1 to create the trigger in the temporary database.
+ ** If sqlite3SrcListLookup() returns 0, indicating the table does not
+ ** exist, the error is caught by the block below.
+ */
+ pTab = sqlite3SrcListLookup(pParse, pTableName);
+ if( db->init.busy==0 && pName2->n==0 && pTab
+ && pTab->pSchema==db->aDb[1].pSchema ){
+ iDb = 1;
+ }
+
+ /* Ensure the table name matches database name and that the table exists */
+ if( db->mallocFailed ) goto trigger_cleanup;
+ assert( pTableName->nSrc==1 );
+ sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName);
+ if( sqlite3FixSrcList(&sFix, pTableName) ){
+ goto trigger_cleanup;
+ }
+ pTab = sqlite3SrcListLookup(pParse, pTableName);
+ if( !pTab ){
+ /* The table does not exist. */
+ if( db->init.iDb==1 ){
+ /* Ticket #3810.
+ ** Normally, whenever a table is dropped, all associated triggers are
+ ** dropped too. But if a TEMP trigger is created on a non-TEMP table
+ ** and the table is dropped by a different database connection, the
+ ** trigger is not visible to the database connection that does the
+ ** drop so the trigger cannot be dropped. This results in an
+ ** "orphaned trigger" - a trigger whose associated table is missing.
+ */
+ db->init.orphanTrigger = 1;
+ }
+ goto trigger_cleanup;
+ }
+ if( IsVirtual(pTab) ){
+ sqlite3ErrorMsg(pParse, "cannot create triggers on virtual tables");
+ goto trigger_cleanup;
+ }
+
+ /* Check that the trigger name is not reserved and that no trigger of the
+ ** specified name exists */
+ zName = sqlite3NameFromToken(db, pName);
+ if( !zName || SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
+ goto trigger_cleanup;
+ }
+ assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+ if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){
+ if( !noErr ){
+ sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
+ }else{
+ assert( !db->init.busy );
+ sqlite3CodeVerifySchema(pParse, iDb);
+ }
+ goto trigger_cleanup;
+ }
+
+ /* Do not create a trigger on a system table */
+ if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
+ sqlite3ErrorMsg(pParse, "cannot create trigger on system table");
+ goto trigger_cleanup;
+ }
+
+ /* INSTEAD of triggers are only for views and views only support INSTEAD
+ ** of triggers.
+ */
+ if( pTab->pSelect && tr_tm!=TK_INSTEAD ){
+ sqlite3ErrorMsg(pParse, "cannot create %s trigger on view: %S",
+ (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName, 0);
+ goto trigger_cleanup;
+ }
+ if( !pTab->pSelect && tr_tm==TK_INSTEAD ){
+ sqlite3ErrorMsg(pParse, "cannot create INSTEAD OF"
+ " trigger on table: %S", pTableName, 0);
+ goto trigger_cleanup;
+ }
+
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ {
+ int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+ int code = SQLITE_CREATE_TRIGGER;
+ const char *zDb = db->aDb[iTabDb].zDbSName;
+ const char *zDbTrig = isTemp ? db->aDb[1].zDbSName : zDb;
+ if( iTabDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER;
+ if( sqlite3AuthCheck(pParse, code, zName, pTab->zName, zDbTrig) ){
+ goto trigger_cleanup;
+ }
+ if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iTabDb),0,zDb)){
+ goto trigger_cleanup;
+ }
+ }
+#endif
+
+ /* INSTEAD OF triggers can only appear on views and BEFORE triggers
+ ** cannot appear on views. So we might as well translate every
+ ** INSTEAD OF trigger into a BEFORE trigger. It simplifies code
+ ** elsewhere.
+ */
+ if (tr_tm == TK_INSTEAD){
+ tr_tm = TK_BEFORE;
+ }
+
+ /* Build the Trigger object */
+ pTrigger = (Trigger*)sqlite3DbMallocZero(db, sizeof(Trigger));
+ if( pTrigger==0 ) goto trigger_cleanup;
+ pTrigger->zName = zName;
+ zName = 0;
+ pTrigger->table = sqlite3DbStrDup(db, pTableName->a[0].zName);
+ pTrigger->pSchema = db->aDb[iDb].pSchema;
+ pTrigger->pTabSchema = pTab->pSchema;
+ pTrigger->op = (u8)op;
+ pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER;
+ pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE);
+ pTrigger->pColumns = sqlite3IdListDup(db, pColumns);
+ assert( pParse->pNewTrigger==0 );
+ pParse->pNewTrigger = pTrigger;
+
+trigger_cleanup:
+ sqlite3DbFree(db, zName);
+ sqlite3SrcListDelete(db, pTableName);
+ sqlite3IdListDelete(db, pColumns);
+ sqlite3ExprDelete(db, pWhen);
+ if( !pParse->pNewTrigger ){
+ sqlite3DeleteTrigger(db, pTrigger);
+ }else{
+ assert( pParse->pNewTrigger==pTrigger );
+ }
+}
+
+/*
+** This routine is called after all of the trigger actions have been parsed
+** in order to complete the process of building the trigger.
+*/
+SQLITE_PRIVATE void sqlite3FinishTrigger(
+ Parse *pParse, /* Parser context */
+ TriggerStep *pStepList, /* The triggered program */
+ Token *pAll /* Token that describes the complete CREATE TRIGGER */
+){
+ Trigger *pTrig = pParse->pNewTrigger; /* Trigger being finished */
+ char *zName; /* Name of trigger */
+ sqlite3 *db = pParse->db; /* The database */
+ DbFixer sFix; /* Fixer object */
+ int iDb; /* Database containing the trigger */
+ Token nameToken; /* Trigger name for error reporting */
+
+ pParse->pNewTrigger = 0;
+ if( NEVER(pParse->nErr) || !pTrig ) goto triggerfinish_cleanup;
+ zName = pTrig->zName;
+ iDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
+ pTrig->step_list = pStepList;
+ while( pStepList ){
+ pStepList->pTrig = pTrig;
+ pStepList = pStepList->pNext;
+ }
+ sqlite3TokenInit(&nameToken, pTrig->zName);
+ sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken);
+ if( sqlite3FixTriggerStep(&sFix, pTrig->step_list)
+ || sqlite3FixExpr(&sFix, pTrig->pWhen)
+ ){
+ goto triggerfinish_cleanup;
+ }
+
+ /* if we are not initializing,
+ ** build the sqlite_master entry
+ */
+ if( !db->init.busy ){
+ Vdbe *v;
+ char *z;
+
+ /* Make an entry in the sqlite_master table */
+ v = sqlite3GetVdbe(pParse);
+ if( v==0 ) goto triggerfinish_cleanup;
+ sqlite3BeginWriteOperation(pParse, 0, iDb);
+ z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n);
+ sqlite3NestedParse(pParse,
+ "INSERT INTO %Q.%s VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')",
+ db->aDb[iDb].zDbSName, MASTER_NAME, zName,
+ pTrig->table, z);
+ sqlite3DbFree(db, z);
+ sqlite3ChangeCookie(pParse, iDb);
+ sqlite3VdbeAddParseSchemaOp(v, iDb,
+ sqlite3MPrintf(db, "type='trigger' AND name='%q'", zName));
+ }
+
+ if( db->init.busy ){
+ Trigger *pLink = pTrig;
+ Hash *pHash = &db->aDb[iDb].pSchema->trigHash;
+ assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+ pTrig = sqlite3HashInsert(pHash, zName, pTrig);
+ if( pTrig ){
+ sqlite3OomFault(db);
+ }else if( pLink->pSchema==pLink->pTabSchema ){
+ Table *pTab;
+ pTab = sqlite3HashFind(&pLink->pTabSchema->tblHash, pLink->table);
+ assert( pTab!=0 );
+ pLink->pNext = pTab->pTrigger;
+ pTab->pTrigger = pLink;
+ }
+ }
+
+triggerfinish_cleanup:
+ sqlite3DeleteTrigger(db, pTrig);
+ assert( !pParse->pNewTrigger );
+ sqlite3DeleteTriggerStep(db, pStepList);
+}
+
+/*
+** Turn a SELECT statement (that the pSelect parameter points to) into
+** a trigger step. Return a pointer to a TriggerStep structure.
+**
+** The parser calls this routine when it finds a SELECT statement in
+** body of a TRIGGER.
+*/
+SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3 *db, Select *pSelect){
+ TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep));
+ if( pTriggerStep==0 ) {
+ sqlite3SelectDelete(db, pSelect);
+ return 0;
+ }
+ pTriggerStep->op = TK_SELECT;
+ pTriggerStep->pSelect = pSelect;
+ pTriggerStep->orconf = OE_Default;
+ return pTriggerStep;
+}
+
+/*
+** Allocate space to hold a new trigger step. The allocated space
+** holds both the TriggerStep object and the TriggerStep.target.z string.
+**
+** If an OOM error occurs, NULL is returned and db->mallocFailed is set.
+*/
+static TriggerStep *triggerStepAllocate(
+ sqlite3 *db, /* Database connection */
+ u8 op, /* Trigger opcode */
+ Token *pName /* The target name */
+){
+ TriggerStep *pTriggerStep;
+
+ pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1);
+ if( pTriggerStep ){
+ char *z = (char*)&pTriggerStep[1];
+ memcpy(z, pName->z, pName->n);
+ sqlite3Dequote(z);
+ pTriggerStep->zTarget = z;
+ pTriggerStep->op = op;
+ }
+ return pTriggerStep;
+}
+
+/*
+** Build a trigger step out of an INSERT statement. Return a pointer
+** to the new trigger step.
+**
+** The parser calls this routine when it sees an INSERT inside the
+** body of a trigger.
+*/
+SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(
+ sqlite3 *db, /* The database connection */
+ Token *pTableName, /* Name of the table into which we insert */
+ IdList *pColumn, /* List of columns in pTableName to insert into */
+ Select *pSelect, /* A SELECT statement that supplies values */
+ u8 orconf /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
+){
+ TriggerStep *pTriggerStep;
+
+ assert(pSelect != 0 || db->mallocFailed);
+
+ pTriggerStep = triggerStepAllocate(db, TK_INSERT, pTableName);
+ if( pTriggerStep ){
+ pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
+ pTriggerStep->pIdList = pColumn;
+ pTriggerStep->orconf = orconf;
+ }else{
+ sqlite3IdListDelete(db, pColumn);
+ }
+ sqlite3SelectDelete(db, pSelect);
+
+ return pTriggerStep;
+}
+
+/*
+** Construct a trigger step that implements an UPDATE statement and return
+** a pointer to that trigger step. The parser calls this routine when it
+** sees an UPDATE statement inside the body of a CREATE TRIGGER.
+*/
+SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(
+ sqlite3 *db, /* The database connection */
+ Token *pTableName, /* Name of the table to be updated */
+ ExprList *pEList, /* The SET clause: list of column and new values */
+ Expr *pWhere, /* The WHERE clause */
+ u8 orconf /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
+){
+ TriggerStep *pTriggerStep;
+
+ pTriggerStep = triggerStepAllocate(db, TK_UPDATE, pTableName);
+ if( pTriggerStep ){
+ pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE);
+ pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
+ pTriggerStep->orconf = orconf;
+ }
+ sqlite3ExprListDelete(db, pEList);
+ sqlite3ExprDelete(db, pWhere);
+ return pTriggerStep;
+}
+
+/*
+** Construct a trigger step that implements a DELETE statement and return
+** a pointer to that trigger step. The parser calls this routine when it
+** sees a DELETE statement inside the body of a CREATE TRIGGER.
+*/
+SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(
+ sqlite3 *db, /* Database connection */
+ Token *pTableName, /* The table from which rows are deleted */
+ Expr *pWhere /* The WHERE clause */
+){
+ TriggerStep *pTriggerStep;
+
+ pTriggerStep = triggerStepAllocate(db, TK_DELETE, pTableName);
+ if( pTriggerStep ){
+ pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
+ pTriggerStep->orconf = OE_Default;
+ }
+ sqlite3ExprDelete(db, pWhere);
+ return pTriggerStep;
+}
+
+/*
+** Recursively delete a Trigger structure
+*/
+SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){
+ if( pTrigger==0 ) return;
+ sqlite3DeleteTriggerStep(db, pTrigger->step_list);
+ sqlite3DbFree(db, pTrigger->zName);
+ sqlite3DbFree(db, pTrigger->table);
+ sqlite3ExprDelete(db, pTrigger->pWhen);
+ sqlite3IdListDelete(db, pTrigger->pColumns);
+ sqlite3DbFree(db, pTrigger);
+}
+
+/*
+** This function is called to drop a trigger from the database schema.
+**
+** This may be called directly from the parser and therefore identifies
+** the trigger by name. The sqlite3DropTriggerPtr() routine does the
+** same job as this routine except it takes a pointer to the trigger
+** instead of the trigger name.
+**/
+SQLITE_PRIVATE void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){
+ Trigger *pTrigger = 0;
+ int i;
+ const char *zDb;
+ const char *zName;
+ sqlite3 *db = pParse->db;
+
+ if( db->mallocFailed ) goto drop_trigger_cleanup;
+ if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
+ goto drop_trigger_cleanup;
+ }
+
+ assert( pName->nSrc==1 );
+ zDb = pName->a[0].zDatabase;
+ zName = pName->a[0].zName;
+ assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) );
+ for(i=OMIT_TEMPDB; i<db->nDb; i++){
+ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
+ if( zDb && sqlite3StrICmp(db->aDb[j].zDbSName, zDb) ) continue;
+ assert( sqlite3SchemaMutexHeld(db, j, 0) );
+ pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName);
+ if( pTrigger ) break;
+ }
+ if( !pTrigger ){
+ if( !noErr ){
+ sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0);
+ }else{
+ sqlite3CodeVerifyNamedSchema(pParse, zDb);
+ }
+ pParse->checkSchema = 1;
+ goto drop_trigger_cleanup;
+ }
+ sqlite3DropTriggerPtr(pParse, pTrigger);
+
+drop_trigger_cleanup:
+ sqlite3SrcListDelete(db, pName);
+}
+
+/*
+** Return a pointer to the Table structure for the table that a trigger
+** is set on.
+*/
+static Table *tableOfTrigger(Trigger *pTrigger){
+ return sqlite3HashFind(&pTrigger->pTabSchema->tblHash, pTrigger->table);
+}
+
+
+/*
+** Drop a trigger given a pointer to that trigger.
+*/
+SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){
+ Table *pTable;
+ Vdbe *v;
+ sqlite3 *db = pParse->db;
+ int iDb;
+
+ iDb = sqlite3SchemaToIndex(pParse->db, pTrigger->pSchema);
+ assert( iDb>=0 && iDb<db->nDb );
+ pTable = tableOfTrigger(pTrigger);
+ assert( pTable );
+ assert( pTable->pSchema==pTrigger->pSchema || iDb==1 );
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ {
+ int code = SQLITE_DROP_TRIGGER;
+ const char *zDb = db->aDb[iDb].zDbSName;
+ const char *zTab = SCHEMA_TABLE(iDb);
+ if( iDb==1 ) code = SQLITE_DROP_TEMP_TRIGGER;
+ if( sqlite3AuthCheck(pParse, code, pTrigger->zName, pTable->zName, zDb) ||
+ sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
+ return;
+ }
+ }
+#endif
+
+ /* Generate code to destroy the database record of the trigger.
+ */
+ assert( pTable!=0 );
+ if( (v = sqlite3GetVdbe(pParse))!=0 ){
+ sqlite3NestedParse(pParse,
+ "DELETE FROM %Q.%s WHERE name=%Q AND type='trigger'",
+ db->aDb[iDb].zDbSName, MASTER_NAME, pTrigger->zName
+ );
+ sqlite3ChangeCookie(pParse, iDb);
+ sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0);
+ }
+}
+
+/*
+** Remove a trigger from the hash tables of the sqlite* pointer.
+*/
+SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){
+ Trigger *pTrigger;
+ Hash *pHash;
+
+ assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+ pHash = &(db->aDb[iDb].pSchema->trigHash);
+ pTrigger = sqlite3HashInsert(pHash, zName, 0);
+ if( ALWAYS(pTrigger) ){
+ if( pTrigger->pSchema==pTrigger->pTabSchema ){
+ Table *pTab = tableOfTrigger(pTrigger);
+ Trigger **pp;
+ for(pp=&pTab->pTrigger; *pp!=pTrigger; pp=&((*pp)->pNext));
+ *pp = (*pp)->pNext;
+ }
+ sqlite3DeleteTrigger(db, pTrigger);
+ db->flags |= SQLITE_InternChanges;
+ }
+}
+
+/*
+** pEList is the SET clause of an UPDATE statement. Each entry
+** in pEList is of the format <id>=<expr>. If any of the entries
+** in pEList have an <id> which matches an identifier in pIdList,
+** then return TRUE. If pIdList==NULL, then it is considered a
+** wildcard that matches anything. Likewise if pEList==NULL then
+** it matches anything so always return true. Return false only
+** if there is no match.
+*/
+static int checkColumnOverlap(IdList *pIdList, ExprList *pEList){
+ int e;
+ if( pIdList==0 || NEVER(pEList==0) ) return 1;
+ for(e=0; e<pEList->nExpr; e++){
+ if( sqlite3IdListIndex(pIdList, pEList->a[e].zName)>=0 ) return 1;
+ }
+ return 0;
+}
+
+/*
+** Return a list of all triggers on table pTab if there exists at least
+** one trigger that must be fired when an operation of type 'op' is
+** performed on the table, and, if that operation is an UPDATE, if at
+** least one of the columns in pChanges is being modified.
+*/
+SQLITE_PRIVATE Trigger *sqlite3TriggersExist(
+ Parse *pParse, /* Parse context */
+ Table *pTab, /* The table the contains the triggers */
+ int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */
+ ExprList *pChanges, /* Columns that change in an UPDATE statement */
+ int *pMask /* OUT: Mask of TRIGGER_BEFORE|TRIGGER_AFTER */
+){
+ int mask = 0;
+ Trigger *pList = 0;
+ Trigger *p;
+
+ if( (pParse->db->flags & SQLITE_EnableTrigger)!=0 ){
+ pList = sqlite3TriggerList(pParse, pTab);
+ }
+ assert( pList==0 || IsVirtual(pTab)==0 );
+ for(p=pList; p; p=p->pNext){
+ if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){
+ mask |= p->tr_tm;
+ }
+ }
+ if( pMask ){
+ *pMask = mask;
+ }
+ return (mask ? pList : 0);
+}
+
+/*
+** Convert the pStep->zTarget string into a SrcList and return a pointer
+** to that SrcList.
+**
+** This routine adds a specific database name, if needed, to the target when
+** forming the SrcList. This prevents a trigger in one database from
+** referring to a target in another database. An exception is when the
+** trigger is in TEMP in which case it can refer to any other database it
+** wants.
+*/
+static SrcList *targetSrcList(
+ Parse *pParse, /* The parsing context */
+ TriggerStep *pStep /* The trigger containing the target token */
+){
+ sqlite3 *db = pParse->db;
+ int iDb; /* Index of the database to use */
+ SrcList *pSrc; /* SrcList to be returned */
+
+ pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
+ if( pSrc ){
+ assert( pSrc->nSrc>0 );
+ pSrc->a[pSrc->nSrc-1].zName = sqlite3DbStrDup(db, pStep->zTarget);
+ iDb = sqlite3SchemaToIndex(db, pStep->pTrig->pSchema);
+ if( iDb==0 || iDb>=2 ){
+ const char *zDb;
+ assert( iDb<db->nDb );
+ zDb = db->aDb[iDb].zDbSName;
+ pSrc->a[pSrc->nSrc-1].zDatabase = sqlite3DbStrDup(db, zDb);
+ }
+ }
+ return pSrc;
+}
+
+/*
+** Generate VDBE code for the statements inside the body of a single
+** trigger.
+*/
+static int codeTriggerProgram(
+ Parse *pParse, /* The parser context */
+ TriggerStep *pStepList, /* List of statements inside the trigger body */
+ int orconf /* Conflict algorithm. (OE_Abort, etc) */
+){
+ TriggerStep *pStep;
+ Vdbe *v = pParse->pVdbe;
+ sqlite3 *db = pParse->db;
+
+ assert( pParse->pTriggerTab && pParse->pToplevel );
+ assert( pStepList );
+ assert( v!=0 );
+ for(pStep=pStepList; pStep; pStep=pStep->pNext){
+ /* Figure out the ON CONFLICT policy that will be used for this step
+ ** of the trigger program. If the statement that caused this trigger
+ ** to fire had an explicit ON CONFLICT, then use it. Otherwise, use
+ ** the ON CONFLICT policy that was specified as part of the trigger
+ ** step statement. Example:
+ **
+ ** CREATE TRIGGER AFTER INSERT ON t1 BEGIN;
+ ** INSERT OR REPLACE INTO t2 VALUES(new.a, new.b);
+ ** END;
+ **
+ ** INSERT INTO t1 ... ; -- insert into t2 uses REPLACE policy
+ ** INSERT OR IGNORE INTO t1 ... ; -- insert into t2 uses IGNORE policy
+ */
+ pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf;
+ assert( pParse->okConstFactor==0 );
+
+ switch( pStep->op ){
+ case TK_UPDATE: {
+ sqlite3Update(pParse,
+ targetSrcList(pParse, pStep),
+ sqlite3ExprListDup(db, pStep->pExprList, 0),
+ sqlite3ExprDup(db, pStep->pWhere, 0),
+ pParse->eOrconf
+ );
+ break;
+ }
+ case TK_INSERT: {
+ sqlite3Insert(pParse,
+ targetSrcList(pParse, pStep),
+ sqlite3SelectDup(db, pStep->pSelect, 0),
+ sqlite3IdListDup(db, pStep->pIdList),
+ pParse->eOrconf
+ );
+ break;
+ }
+ case TK_DELETE: {
+ sqlite3DeleteFrom(pParse,
+ targetSrcList(pParse, pStep),
+ sqlite3ExprDup(db, pStep->pWhere, 0)
+ );
+ break;
+ }
+ default: assert( pStep->op==TK_SELECT ); {
+ SelectDest sDest;
+ Select *pSelect = sqlite3SelectDup(db, pStep->pSelect, 0);
+ sqlite3SelectDestInit(&sDest, SRT_Discard, 0);
+ sqlite3Select(pParse, pSelect, &sDest);
+ sqlite3SelectDelete(db, pSelect);
+ break;
+ }
+ }
+ if( pStep->op!=TK_SELECT ){
+ sqlite3VdbeAddOp0(v, OP_ResetCount);
+ }
+ }
+
+ return 0;
+}
+
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
+/*
+** This function is used to add VdbeComment() annotations to a VDBE
+** program. It is not used in production code, only for debugging.
+*/
+static const char *onErrorText(int onError){
+ switch( onError ){
+ case OE_Abort: return "abort";
+ case OE_Rollback: return "rollback";
+ case OE_Fail: return "fail";
+ case OE_Replace: return "replace";
+ case OE_Ignore: return "ignore";
+ case OE_Default: return "default";
+ }
+ return "n/a";
+}
+#endif
+
+/*
+** Parse context structure pFrom has just been used to create a sub-vdbe
+** (trigger program). If an error has occurred, transfer error information
+** from pFrom to pTo.
+*/
+static void transferParseError(Parse *pTo, Parse *pFrom){
+ assert( pFrom->zErrMsg==0 || pFrom->nErr );
+ assert( pTo->zErrMsg==0 || pTo->nErr );
+ if( pTo->nErr==0 ){
+ pTo->zErrMsg = pFrom->zErrMsg;
+ pTo->nErr = pFrom->nErr;
+ pTo->rc = pFrom->rc;
+ }else{
+ sqlite3DbFree(pFrom->db, pFrom->zErrMsg);
+ }
+}
+
+/*
+** Create and populate a new TriggerPrg object with a sub-program
+** implementing trigger pTrigger with ON CONFLICT policy orconf.
+*/
+static TriggerPrg *codeRowTrigger(
+ Parse *pParse, /* Current parse context */
+ Trigger *pTrigger, /* Trigger to code */
+ Table *pTab, /* The table pTrigger is attached to */
+ int orconf /* ON CONFLICT policy to code trigger program with */
+){
+ Parse *pTop = sqlite3ParseToplevel(pParse);
+ sqlite3 *db = pParse->db; /* Database handle */
+ TriggerPrg *pPrg; /* Value to return */
+ Expr *pWhen = 0; /* Duplicate of trigger WHEN expression */
+ Vdbe *v; /* Temporary VM */
+ NameContext sNC; /* Name context for sub-vdbe */
+ SubProgram *pProgram = 0; /* Sub-vdbe for trigger program */
+ Parse *pSubParse; /* Parse context for sub-vdbe */
+ int iEndTrigger = 0; /* Label to jump to if WHEN is false */
+
+ assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) );
+ assert( pTop->pVdbe );
+
+ /* Allocate the TriggerPrg and SubProgram objects. To ensure that they
+ ** are freed if an error occurs, link them into the Parse.pTriggerPrg
+ ** list of the top-level Parse object sooner rather than later. */
+ pPrg = sqlite3DbMallocZero(db, sizeof(TriggerPrg));
+ if( !pPrg ) return 0;
+ pPrg->pNext = pTop->pTriggerPrg;
+ pTop->pTriggerPrg = pPrg;
+ pPrg->pProgram = pProgram = sqlite3DbMallocZero(db, sizeof(SubProgram));
+ if( !pProgram ) return 0;
+ sqlite3VdbeLinkSubProgram(pTop->pVdbe, pProgram);
+ pPrg->pTrigger = pTrigger;
+ pPrg->orconf = orconf;
+ pPrg->aColmask[0] = 0xffffffff;
+ pPrg->aColmask[1] = 0xffffffff;
+
+ /* Allocate and populate a new Parse context to use for coding the
+ ** trigger sub-program. */
+ pSubParse = sqlite3StackAllocZero(db, sizeof(Parse));
+ if( !pSubParse ) return 0;
+ memset(&sNC, 0, sizeof(sNC));
+ sNC.pParse = pSubParse;
+ pSubParse->db = db;
+ pSubParse->pTriggerTab = pTab;
+ pSubParse->pToplevel = pTop;
+ pSubParse->zAuthContext = pTrigger->zName;
+ pSubParse->eTriggerOp = pTrigger->op;
+ pSubParse->nQueryLoop = pParse->nQueryLoop;
+
+ v = sqlite3GetVdbe(pSubParse);
+ if( v ){
+ VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)",
+ pTrigger->zName, onErrorText(orconf),
+ (pTrigger->tr_tm==TRIGGER_BEFORE ? "BEFORE" : "AFTER"),
+ (pTrigger->op==TK_UPDATE ? "UPDATE" : ""),
+ (pTrigger->op==TK_INSERT ? "INSERT" : ""),
+ (pTrigger->op==TK_DELETE ? "DELETE" : ""),
+ pTab->zName
+ ));
+#ifndef SQLITE_OMIT_TRACE
+ sqlite3VdbeChangeP4(v, -1,
+ sqlite3MPrintf(db, "-- TRIGGER %s", pTrigger->zName), P4_DYNAMIC
+ );
+#endif
+
+ /* If one was specified, code the WHEN clause. If it evaluates to false
+ ** (or NULL) the sub-vdbe is immediately halted by jumping to the
+ ** OP_Halt inserted at the end of the program. */
+ if( pTrigger->pWhen ){
+ pWhen = sqlite3ExprDup(db, pTrigger->pWhen, 0);
+ if( SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen)
+ && db->mallocFailed==0
+ ){
+ iEndTrigger = sqlite3VdbeMakeLabel(v);
+ sqlite3ExprIfFalse(pSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL);
+ }
+ sqlite3ExprDelete(db, pWhen);
+ }
+
+ /* Code the trigger program into the sub-vdbe. */
+ codeTriggerProgram(pSubParse, pTrigger->step_list, orconf);
+
+ /* Insert an OP_Halt at the end of the sub-program. */
+ if( iEndTrigger ){
+ sqlite3VdbeResolveLabel(v, iEndTrigger);
+ }
+ sqlite3VdbeAddOp0(v, OP_Halt);
+ VdbeComment((v, "End: %s.%s", pTrigger->zName, onErrorText(orconf)));
+
+ transferParseError(pParse, pSubParse);
+ if( db->mallocFailed==0 ){
+ pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg);
+ }
+ pProgram->nMem = pSubParse->nMem;
+ pProgram->nCsr = pSubParse->nTab;
+ pProgram->token = (void *)pTrigger;
+ pPrg->aColmask[0] = pSubParse->oldmask;
+ pPrg->aColmask[1] = pSubParse->newmask;
+ sqlite3VdbeDelete(v);
+ }
+
+ assert( !pSubParse->pAinc && !pSubParse->pZombieTab );
+ assert( !pSubParse->pTriggerPrg && !pSubParse->nMaxArg );
+ sqlite3ParserReset(pSubParse);
+ sqlite3StackFree(db, pSubParse);
+
+ return pPrg;
+}
+
+/*
+** Return a pointer to a TriggerPrg object containing the sub-program for
+** trigger pTrigger with default ON CONFLICT algorithm orconf. If no such
+** TriggerPrg object exists, a new object is allocated and populated before
+** being returned.
+*/
+static TriggerPrg *getRowTrigger(
+ Parse *pParse, /* Current parse context */
+ Trigger *pTrigger, /* Trigger to code */
+ Table *pTab, /* The table trigger pTrigger is attached to */
+ int orconf /* ON CONFLICT algorithm. */
+){
+ Parse *pRoot = sqlite3ParseToplevel(pParse);
+ TriggerPrg *pPrg;
+
+ assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) );
+
+ /* It may be that this trigger has already been coded (or is in the
+ ** process of being coded). If this is the case, then an entry with
+ ** a matching TriggerPrg.pTrigger field will be present somewhere
+ ** in the Parse.pTriggerPrg list. Search for such an entry. */
+ for(pPrg=pRoot->pTriggerPrg;
+ pPrg && (pPrg->pTrigger!=pTrigger || pPrg->orconf!=orconf);
+ pPrg=pPrg->pNext
+ );
+
+ /* If an existing TriggerPrg could not be located, create a new one. */
+ if( !pPrg ){
+ pPrg = codeRowTrigger(pParse, pTrigger, pTab, orconf);
+ }
+
+ return pPrg;
+}
+
+/*
+** Generate code for the trigger program associated with trigger p on
+** table pTab. The reg, orconf and ignoreJump parameters passed to this
+** function are the same as those described in the header function for
+** sqlite3CodeRowTrigger()
+*/
+SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect(
+ Parse *pParse, /* Parse context */
+ Trigger *p, /* Trigger to code */
+ Table *pTab, /* The table to code triggers from */
+ int reg, /* Reg array containing OLD.* and NEW.* values */
+ int orconf, /* ON CONFLICT policy */
+ int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */
+){
+ Vdbe *v = sqlite3GetVdbe(pParse); /* Main VM */
+ TriggerPrg *pPrg;
+ pPrg = getRowTrigger(pParse, p, pTab, orconf);
+ assert( pPrg || pParse->nErr || pParse->db->mallocFailed );
+
+ /* Code the OP_Program opcode in the parent VDBE. P4 of the OP_Program
+ ** is a pointer to the sub-vdbe containing the trigger program. */
+ if( pPrg ){
+ int bRecursive = (p->zName && 0==(pParse->db->flags&SQLITE_RecTriggers));
+
+ sqlite3VdbeAddOp4(v, OP_Program, reg, ignoreJump, ++pParse->nMem,
+ (const char *)pPrg->pProgram, P4_SUBPROGRAM);
+ VdbeComment(
+ (v, "Call: %s.%s", (p->zName?p->zName:"fkey"), onErrorText(orconf)));
+
+ /* Set the P5 operand of the OP_Program instruction to non-zero if
+ ** recursive invocation of this trigger program is disallowed. Recursive
+ ** invocation is disallowed if (a) the sub-program is really a trigger,
+ ** not a foreign key action, and (b) the flag to enable recursive triggers
+ ** is clear. */
+ sqlite3VdbeChangeP5(v, (u8)bRecursive);
+ }
+}
+
+/*
+** This is called to code the required FOR EACH ROW triggers for an operation
+** on table pTab. The operation to code triggers for (INSERT, UPDATE or DELETE)
+** is given by the op parameter. The tr_tm parameter determines whether the
+** BEFORE or AFTER triggers are coded. If the operation is an UPDATE, then
+** parameter pChanges is passed the list of columns being modified.
+**
+** If there are no triggers that fire at the specified time for the specified
+** operation on pTab, this function is a no-op.
+**
+** The reg argument is the address of the first in an array of registers
+** that contain the values substituted for the new.* and old.* references
+** in the trigger program. If N is the number of columns in table pTab
+** (a copy of pTab->nCol), then registers are populated as follows:
+**
+** Register Contains
+** ------------------------------------------------------
+** reg+0 OLD.rowid
+** reg+1 OLD.* value of left-most column of pTab
+** ... ...
+** reg+N OLD.* value of right-most column of pTab
+** reg+N+1 NEW.rowid
+** reg+N+2 OLD.* value of left-most column of pTab
+** ... ...
+** reg+N+N+1 NEW.* value of right-most column of pTab
+**
+** For ON DELETE triggers, the registers containing the NEW.* values will
+** never be accessed by the trigger program, so they are not allocated or
+** populated by the caller (there is no data to populate them with anyway).
+** Similarly, for ON INSERT triggers the values stored in the OLD.* registers
+** are never accessed, and so are not allocated by the caller. So, for an
+** ON INSERT trigger, the value passed to this function as parameter reg
+** is not a readable register, although registers (reg+N) through
+** (reg+N+N+1) are.
+**
+** Parameter orconf is the default conflict resolution algorithm for the
+** trigger program to use (REPLACE, IGNORE etc.). Parameter ignoreJump
+** is the instruction that control should jump to if a trigger program
+** raises an IGNORE exception.
+*/
+SQLITE_PRIVATE void sqlite3CodeRowTrigger(
+ Parse *pParse, /* Parse context */
+ Trigger *pTrigger, /* List of triggers on table pTab */
+ int op, /* One of TK_UPDATE, TK_INSERT, TK_DELETE */
+ ExprList *pChanges, /* Changes list for any UPDATE OF triggers */
+ int tr_tm, /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
+ Table *pTab, /* The table to code triggers from */
+ int reg, /* The first in an array of registers (see above) */
+ int orconf, /* ON CONFLICT policy */
+ int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */
+){
+ Trigger *p; /* Used to iterate through pTrigger list */
+
+ assert( op==TK_UPDATE || op==TK_INSERT || op==TK_DELETE );
+ assert( tr_tm==TRIGGER_BEFORE || tr_tm==TRIGGER_AFTER );
+ assert( (op==TK_UPDATE)==(pChanges!=0) );
+
+ for(p=pTrigger; p; p=p->pNext){
+
+ /* Sanity checking: The schema for the trigger and for the table are
+ ** always defined. The trigger must be in the same schema as the table
+ ** or else it must be a TEMP trigger. */
+ assert( p->pSchema!=0 );
+ assert( p->pTabSchema!=0 );
+ assert( p->pSchema==p->pTabSchema
+ || p->pSchema==pParse->db->aDb[1].pSchema );
+
+ /* Determine whether we should code this trigger */
+ if( p->op==op
+ && p->tr_tm==tr_tm
+ && checkColumnOverlap(p->pColumns, pChanges)
+ ){
+ sqlite3CodeRowTriggerDirect(pParse, p, pTab, reg, orconf, ignoreJump);
+ }
+ }
+}
+
+/*
+** Triggers may access values stored in the old.* or new.* pseudo-table.
+** This function returns a 32-bit bitmask indicating which columns of the
+** old.* or new.* tables actually are used by triggers. This information
+** may be used by the caller, for example, to avoid having to load the entire
+** old.* record into memory when executing an UPDATE or DELETE command.
+**
+** Bit 0 of the returned mask is set if the left-most column of the
+** table may be accessed using an [old|new].<col> reference. Bit 1 is set if
+** the second leftmost column value is required, and so on. If there
+** are more than 32 columns in the table, and at least one of the columns
+** with an index greater than 32 may be accessed, 0xffffffff is returned.
+**
+** It is not possible to determine if the old.rowid or new.rowid column is
+** accessed by triggers. The caller must always assume that it is.
+**
+** Parameter isNew must be either 1 or 0. If it is 0, then the mask returned
+** applies to the old.* table. If 1, the new.* table.
+**
+** Parameter tr_tm must be a mask with one or both of the TRIGGER_BEFORE
+** and TRIGGER_AFTER bits set. Values accessed by BEFORE triggers are only
+** included in the returned mask if the TRIGGER_BEFORE bit is set in the
+** tr_tm parameter. Similarly, values accessed by AFTER triggers are only
+** included in the returned mask if the TRIGGER_AFTER bit is set in tr_tm.
+*/
+SQLITE_PRIVATE u32 sqlite3TriggerColmask(
+ Parse *pParse, /* Parse context */
+ Trigger *pTrigger, /* List of triggers on table pTab */
+ ExprList *pChanges, /* Changes list for any UPDATE OF triggers */
+ int isNew, /* 1 for new.* ref mask, 0 for old.* ref mask */
+ int tr_tm, /* Mask of TRIGGER_BEFORE|TRIGGER_AFTER */
+ Table *pTab, /* The table to code triggers from */
+ int orconf /* Default ON CONFLICT policy for trigger steps */
+){
+ const int op = pChanges ? TK_UPDATE : TK_DELETE;
+ u32 mask = 0;
+ Trigger *p;
+
+ assert( isNew==1 || isNew==0 );
+ for(p=pTrigger; p; p=p->pNext){
+ if( p->op==op && (tr_tm&p->tr_tm)
+ && checkColumnOverlap(p->pColumns,pChanges)
+ ){
+ TriggerPrg *pPrg;
+ pPrg = getRowTrigger(pParse, p, pTab, orconf);
+ if( pPrg ){
+ mask |= pPrg->aColmask[isNew];
+ }
+ }
+ }
+
+ return mask;
+}
+
+#endif /* !defined(SQLITE_OMIT_TRIGGER) */
+
+/************** End of trigger.c *********************************************/
+/************** Begin file update.c ******************************************/
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains C code routines that are called by the parser
+** to handle UPDATE statements.
+*/
+/* #include "sqliteInt.h" */
+
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+/* Forward declaration */
+static void updateVirtualTable(
+ Parse *pParse, /* The parsing context */
+ SrcList *pSrc, /* The virtual table to be modified */
+ Table *pTab, /* The virtual table */
+ ExprList *pChanges, /* The columns to change in the UPDATE statement */
+ Expr *pRowidExpr, /* Expression used to recompute the rowid */
+ int *aXRef, /* Mapping from columns of pTab to entries in pChanges */
+ Expr *pWhere, /* WHERE clause of the UPDATE statement */
+ int onError /* ON CONFLICT strategy */
+);
+#endif /* SQLITE_OMIT_VIRTUALTABLE */
+
+/*
+** The most recently coded instruction was an OP_Column to retrieve the
+** i-th column of table pTab. This routine sets the P4 parameter of the
+** OP_Column to the default value, if any.
+**
+** The default value of a column is specified by a DEFAULT clause in the
+** column definition. This was either supplied by the user when the table
+** was created, or added later to the table definition by an ALTER TABLE
+** command. If the latter, then the row-records in the table btree on disk
+** may not contain a value for the column and the default value, taken
+** from the P4 parameter of the OP_Column instruction, is returned instead.
+** If the former, then all row-records are guaranteed to include a value
+** for the column and the P4 value is not required.
+**
+** Column definitions created by an ALTER TABLE command may only have
+** literal default values specified: a number, null or a string. (If a more
+** complicated default expression value was provided, it is evaluated
+** when the ALTER TABLE is executed and one of the literal values written
+** into the sqlite_master table.)
+**
+** Therefore, the P4 parameter is only required if the default value for
+** the column is a literal number, string or null. The sqlite3ValueFromExpr()
+** function is capable of transforming these types of expressions into
+** sqlite3_value objects.
+**
+** If parameter iReg is not negative, code an OP_RealAffinity instruction
+** on register iReg. This is used when an equivalent integer value is
+** stored in place of an 8-byte floating point value in order to save
+** space.
+*/
+SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
+ assert( pTab!=0 );
+ if( !pTab->pSelect ){
+ sqlite3_value *pValue = 0;
+ u8 enc = ENC(sqlite3VdbeDb(v));
+ Column *pCol = &pTab->aCol[i];
+ VdbeComment((v, "%s.%s", pTab->zName, pCol->zName));
+ assert( i<pTab->nCol );
+ sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc,
+ pCol->affinity, &pValue);
+ if( pValue ){
+ sqlite3VdbeAppendP4(v, pValue, P4_MEM);
+ }
+ }
+#ifndef SQLITE_OMIT_FLOATING_POINT
+ if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
+ sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
+ }
+#endif
+}
+
+/*
+** Process an UPDATE statement.
+**
+** UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
+** \_______/ \________/ \______/ \________________/
+* onError pTabList pChanges pWhere
+*/
+SQLITE_PRIVATE void sqlite3Update(
+ Parse *pParse, /* The parser context */
+ SrcList *pTabList, /* The table in which we should change things */
+ ExprList *pChanges, /* Things to be changed */
+ Expr *pWhere, /* The WHERE clause. May be null */
+ int onError /* How to handle constraint errors */
+){
+ int i, j; /* Loop counters */
+ Table *pTab; /* The table to be updated */
+ int addrTop = 0; /* VDBE instruction address of the start of the loop */
+ WhereInfo *pWInfo; /* Information about the WHERE clause */
+ Vdbe *v; /* The virtual database engine */
+ Index *pIdx; /* For looping over indices */
+ Index *pPk; /* The PRIMARY KEY index for WITHOUT ROWID tables */
+ int nIdx; /* Number of indices that need updating */
+ int iBaseCur; /* Base cursor number */
+ int iDataCur; /* Cursor for the canonical data btree */
+ int iIdxCur; /* Cursor for the first index */
+ sqlite3 *db; /* The database structure */
+ int *aRegIdx = 0; /* First register in array assigned to each index */
+ int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the
+ ** an expression for the i-th column of the table.
+ ** aXRef[i]==-1 if the i-th column is not changed. */
+ u8 *aToOpen; /* 1 for tables and indices to be opened */
+ u8 chngPk; /* PRIMARY KEY changed in a WITHOUT ROWID table */
+ u8 chngRowid; /* Rowid changed in a normal table */
+ u8 chngKey; /* Either chngPk or chngRowid */
+ Expr *pRowidExpr = 0; /* Expression defining the new record number */
+ AuthContext sContext; /* The authorization context */
+ NameContext sNC; /* The name-context to resolve expressions in */
+ int iDb; /* Database containing the table being updated */
+ int eOnePass; /* ONEPASS_XXX value from where.c */
+ int hasFK; /* True if foreign key processing is required */
+ int labelBreak; /* Jump here to break out of UPDATE loop */
+ int labelContinue; /* Jump here to continue next step of UPDATE loop */
+ int flags; /* Flags for sqlite3WhereBegin() */
+
+#ifndef SQLITE_OMIT_TRIGGER
+ int isView; /* True when updating a view (INSTEAD OF trigger) */
+ Trigger *pTrigger; /* List of triggers on pTab, if required */
+ int tmask; /* Mask of TRIGGER_BEFORE|TRIGGER_AFTER */
+#endif
+ int newmask; /* Mask of NEW.* columns accessed by BEFORE triggers */
+ int iEph = 0; /* Ephemeral table holding all primary key values */
+ int nKey = 0; /* Number of elements in regKey for WITHOUT ROWID */
+ int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */
+ int addrOpen = 0; /* Address of OP_OpenEphemeral */
+ int iPk = 0; /* First of nPk cells holding PRIMARY KEY value */
+ i16 nPk = 0; /* Number of components of the PRIMARY KEY */
+ int bReplace = 0; /* True if REPLACE conflict resolution might happen */
+
+ /* Register Allocations */
+ int regRowCount = 0; /* A count of rows changed */
+ int regOldRowid = 0; /* The old rowid */
+ int regNewRowid = 0; /* The new rowid */
+ int regNew = 0; /* Content of the NEW.* table in triggers */
+ int regOld = 0; /* Content of OLD.* table in triggers */
+ int regRowSet = 0; /* Rowset of rows to be updated */
+ int regKey = 0; /* composite PRIMARY KEY value */
+
+ memset(&sContext, 0, sizeof(sContext));
+ db = pParse->db;
+ if( pParse->nErr || db->mallocFailed ){
+ goto update_cleanup;
+ }
+ assert( pTabList->nSrc==1 );
+
+ /* Locate the table which we want to update.
+ */
+ pTab = sqlite3SrcListLookup(pParse, pTabList);
+ if( pTab==0 ) goto update_cleanup;
+ iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
+
+ /* Figure out if we have any triggers and if the table being
+ ** updated is a view.
+ */
+#ifndef SQLITE_OMIT_TRIGGER
+ pTrigger = sqlite3TriggersExist(pParse, pTab, TK_UPDATE, pChanges, &tmask);
+ isView = pTab->pSelect!=0;
+ assert( pTrigger || tmask==0 );
+#else
+# define pTrigger 0
+# define isView 0
+# define tmask 0
+#endif
+#ifdef SQLITE_OMIT_VIEW
+# undef isView
+# define isView 0
+#endif
+
+ if( sqlite3ViewGetColumnNames(pParse, pTab) ){
+ goto update_cleanup;
+ }
+ if( sqlite3IsReadOnly(pParse, pTab, tmask) ){
+ goto update_cleanup;
+ }
+
+ /* Allocate a cursors for the main database table and for all indices.
+ ** The index cursors might not be used, but if they are used they
+ ** need to occur right after the database cursor. So go ahead and
+ ** allocate enough space, just in case.
+ */
+ pTabList->a[0].iCursor = iBaseCur = iDataCur = pParse->nTab++;
+ iIdxCur = iDataCur+1;
+ pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
+ for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){
+ if( IsPrimaryKeyIndex(pIdx) && pPk!=0 ){
+ iDataCur = pParse->nTab;
+ pTabList->a[0].iCursor = iDataCur;
+ }
+ pParse->nTab++;
+ }
+
+ /* Allocate space for aXRef[], aRegIdx[], and aToOpen[].
+ ** Initialize aXRef[] and aToOpen[] to their default values.
+ */
+ aXRef = sqlite3DbMallocRawNN(db, sizeof(int) * (pTab->nCol+nIdx) + nIdx+2 );
+ if( aXRef==0 ) goto update_cleanup;
+ aRegIdx = aXRef+pTab->nCol;
+ aToOpen = (u8*)(aRegIdx+nIdx);
+ memset(aToOpen, 1, nIdx+1);
+ aToOpen[nIdx+1] = 0;
+ for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;
+
+ /* Initialize the name-context */
+ memset(&sNC, 0, sizeof(sNC));
+ sNC.pParse = pParse;
+ sNC.pSrcList = pTabList;
+
+ /* Resolve the column names in all the expressions of the
+ ** of the UPDATE statement. Also find the column index
+ ** for each column to be updated in the pChanges array. For each
+ ** column to be updated, make sure we have authorization to change
+ ** that column.
+ */
+ chngRowid = chngPk = 0;
+ for(i=0; i<pChanges->nExpr; i++){
+ if( sqlite3ResolveExprNames(&sNC, pChanges->a[i].pExpr) ){
+ goto update_cleanup;
+ }
+ for(j=0; j<pTab->nCol; j++){
+ if( sqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){
+ if( j==pTab->iPKey ){
+ chngRowid = 1;
+ pRowidExpr = pChanges->a[i].pExpr;
+ }else if( pPk && (pTab->aCol[j].colFlags & COLFLAG_PRIMKEY)!=0 ){
+ chngPk = 1;
+ }
+ aXRef[j] = i;
+ break;
+ }
+ }
+ if( j>=pTab->nCol ){
+ if( pPk==0 && sqlite3IsRowid(pChanges->a[i].zName) ){
+ j = -1;
+ chngRowid = 1;
+ pRowidExpr = pChanges->a[i].pExpr;
+ }else{
+ sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName);
+ pParse->checkSchema = 1;
+ goto update_cleanup;
+ }
+ }
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ {
+ int rc;
+ rc = sqlite3AuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
+ j<0 ? "ROWID" : pTab->aCol[j].zName,
+ db->aDb[iDb].zDbSName);
+ if( rc==SQLITE_DENY ){
+ goto update_cleanup;
+ }else if( rc==SQLITE_IGNORE ){
+ aXRef[j] = -1;
+ }
+ }
+#endif
+ }
+ assert( (chngRowid & chngPk)==0 );
+ assert( chngRowid==0 || chngRowid==1 );
+ assert( chngPk==0 || chngPk==1 );
+ chngKey = chngRowid + chngPk;
+
+ /* The SET expressions are not actually used inside the WHERE loop.
+ ** So reset the colUsed mask. Unless this is a virtual table. In that
+ ** case, set all bits of the colUsed mask (to ensure that the virtual
+ ** table implementation makes all columns available).
+ */
+ pTabList->a[0].colUsed = IsVirtual(pTab) ? ALLBITS : 0;
+
+ hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngKey);
+
+ /* There is one entry in the aRegIdx[] array for each index on the table
+ ** being updated. Fill in aRegIdx[] with a register number that will hold
+ ** the key for accessing each index.
+ **
+ ** FIXME: Be smarter about omitting indexes that use expressions.
+ */
+ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+ int reg;
+ if( chngKey || hasFK || pIdx->pPartIdxWhere || pIdx==pPk ){
+ reg = ++pParse->nMem;
+ pParse->nMem += pIdx->nColumn;
+ }else{
+ reg = 0;
+ for(i=0; i<pIdx->nKeyCol; i++){
+ i16 iIdxCol = pIdx->aiColumn[i];
+ if( iIdxCol<0 || aXRef[iIdxCol]>=0 ){
+ reg = ++pParse->nMem;
+ pParse->nMem += pIdx->nColumn;
+ if( (onError==OE_Replace)
+ || (onError==OE_Default && pIdx->onError==OE_Replace)
+ ){
+ bReplace = 1;
+ }
+ break;
+ }
+ }
+ }
+ if( reg==0 ) aToOpen[j+1] = 0;
+ aRegIdx[j] = reg;
+ }
+ if( bReplace ){
+ /* If REPLACE conflict resolution might be invoked, open cursors on all
+ ** indexes in case they are needed to delete records. */
+ memset(aToOpen, 1, nIdx+1);
+ }
+
+ /* Begin generating code. */
+ v = sqlite3GetVdbe(pParse);
+ if( v==0 ) goto update_cleanup;
+ if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
+ sqlite3BeginWriteOperation(pParse, 1, iDb);
+
+ /* Allocate required registers. */
+ if( !IsVirtual(pTab) ){
+ regRowSet = ++pParse->nMem;
+ regOldRowid = regNewRowid = ++pParse->nMem;
+ if( chngPk || pTrigger || hasFK ){
+ regOld = pParse->nMem + 1;
+ pParse->nMem += pTab->nCol;
+ }
+ if( chngKey || pTrigger || hasFK ){
+ regNewRowid = ++pParse->nMem;
+ }
+ regNew = pParse->nMem + 1;
+ pParse->nMem += pTab->nCol;
+ }
+
+ /* Start the view context. */
+ if( isView ){
+ sqlite3AuthContextPush(pParse, &sContext, pTab->zName);
+ }
+
+ /* If we are trying to update a view, realize that view into
+ ** an ephemeral table.
+ */
+#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
+ if( isView ){
+ sqlite3MaterializeView(pParse, pTab, pWhere, iDataCur);
+ }
+#endif
+
+ /* Resolve the column names in all the expressions in the
+ ** WHERE clause.
+ */
+ if( sqlite3ResolveExprNames(&sNC, pWhere) ){
+ goto update_cleanup;
+ }
+
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ /* Virtual tables must be handled separately */
+ if( IsVirtual(pTab) ){
+ updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef,
+ pWhere, onError);
+ goto update_cleanup;
+ }
+#endif
+
+ /* Initialize the count of updated rows */
+ if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab ){
+ regRowCount = ++pParse->nMem;
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
+ }
+
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid);
+ }else{
+ assert( pPk!=0 );
+ nPk = pPk->nKeyCol;
+ iPk = pParse->nMem+1;
+ pParse->nMem += nPk;
+ regKey = ++pParse->nMem;
+ iEph = pParse->nTab++;
+
+ sqlite3VdbeAddOp2(v, OP_Null, 0, iPk);
+ addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk);
+ sqlite3VdbeSetP4KeyInfo(pParse, pPk);
+ }
+
+ /* Begin the database scan.
+ **
+ ** Do not consider a single-pass strategy for a multi-row update if
+ ** there are any triggers or foreign keys to process, or rows may
+ ** be deleted as a result of REPLACE conflict handling. Any of these
+ ** things might disturb a cursor being used to scan through the table
+ ** or index, causing a single-pass approach to malfunction. */
+ flags = WHERE_ONEPASS_DESIRED|WHERE_SEEK_UNIQ_TABLE;
+ if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){
+ flags |= WHERE_ONEPASS_MULTIROW;
+ }
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, flags, iIdxCur);
+ if( pWInfo==0 ) goto update_cleanup;
+
+ /* A one-pass strategy that might update more than one row may not
+ ** be used if any column of the index used for the scan is being
+ ** updated. Otherwise, if there is an index on "b", statements like
+ ** the following could create an infinite loop:
+ **
+ ** UPDATE t1 SET b=b+1 WHERE b>?
+ **
+ ** Fall back to ONEPASS_OFF if where.c has selected a ONEPASS_MULTI
+ ** strategy that uses an index for which one or more columns are being
+ ** updated. */
+ eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
+ if( eOnePass==ONEPASS_MULTI ){
+ int iCur = aiCurOnePass[1];
+ if( iCur>=0 && iCur!=iDataCur && aToOpen[iCur-iBaseCur] ){
+ eOnePass = ONEPASS_OFF;
+ }
+ assert( iCur!=iDataCur || !HasRowid(pTab) );
+ }
+
+ if( HasRowid(pTab) ){
+ /* Read the rowid of the current row of the WHERE scan. In ONEPASS_OFF
+ ** mode, write the rowid into the FIFO. In either of the one-pass modes,
+ ** leave it in register regOldRowid. */
+ sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid);
+ if( eOnePass==ONEPASS_OFF ){
+ sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid);
+ }
+ }else{
+ /* Read the PK of the current row into an array of registers. In
+ ** ONEPASS_OFF mode, serialize the array into a record and store it in
+ ** the ephemeral table. Or, in ONEPASS_SINGLE or MULTI mode, change
+ ** the OP_OpenEphemeral instruction to a Noop (the ephemeral table
+ ** is not required) and leave the PK fields in the array of registers. */
+ for(i=0; i<nPk; i++){
+ assert( pPk->aiColumn[i]>=0 );
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur,pPk->aiColumn[i],iPk+i);
+ }
+ if( eOnePass ){
+ sqlite3VdbeChangeToNoop(v, addrOpen);
+ nKey = nPk;
+ regKey = iPk;
+ }else{
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, regKey,
+ sqlite3IndexAffinityStr(db, pPk), nPk);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iEph, regKey, iPk, nPk);
+ }
+ }
+
+ if( eOnePass!=ONEPASS_MULTI ){
+ sqlite3WhereEnd(pWInfo);
+ }
+
+ labelBreak = sqlite3VdbeMakeLabel(v);
+ if( !isView ){
+ int addrOnce = 0;
+
+ /* Open every index that needs updating. */
+ if( eOnePass!=ONEPASS_OFF ){
+ if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iBaseCur] = 0;
+ if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iBaseCur] = 0;
+ }
+
+ if( eOnePass==ONEPASS_MULTI && (nIdx-(aiCurOnePass[1]>=0))>0 ){
+ addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+ }
+ sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur, aToOpen,
+ 0, 0);
+ if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
+ }
+
+ /* Top of the update loop */
+ if( eOnePass!=ONEPASS_OFF ){
+ if( !isView && aiCurOnePass[0]!=iDataCur && aiCurOnePass[1]!=iDataCur ){
+ assert( pPk );
+ sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey);
+ VdbeCoverageNeverTaken(v);
+ }
+ if( eOnePass==ONEPASS_SINGLE ){
+ labelContinue = labelBreak;
+ }else{
+ labelContinue = sqlite3VdbeMakeLabel(v);
+ }
+ sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
+ VdbeCoverageIf(v, pPk==0);
+ VdbeCoverageIf(v, pPk!=0);
+ }else if( pPk ){
+ labelContinue = sqlite3VdbeMakeLabel(v);
+ sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v);
+ addrTop = sqlite3VdbeAddOp2(v, OP_RowData, iEph, regKey);
+ sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0);
+ VdbeCoverage(v);
+ }else{
+ labelContinue = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet, labelBreak,
+ regOldRowid);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid);
+ VdbeCoverage(v);
+ }
+
+ /* If the record number will change, set register regNewRowid to
+ ** contain the new value. If the record number is not being modified,
+ ** then regNewRowid is the same register as regOldRowid, which is
+ ** already populated. */
+ assert( chngKey || pTrigger || hasFK || regOldRowid==regNewRowid );
+ if( chngRowid ){
+ sqlite3ExprCode(pParse, pRowidExpr, regNewRowid);
+ sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid); VdbeCoverage(v);
+ }
+
+ /* Compute the old pre-UPDATE content of the row being changed, if that
+ ** information is needed */
+ if( chngPk || hasFK || pTrigger ){
+ u32 oldmask = (hasFK ? sqlite3FkOldmask(pParse, pTab) : 0);
+ oldmask |= sqlite3TriggerColmask(pParse,
+ pTrigger, pChanges, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onError
+ );
+ for(i=0; i<pTab->nCol; i++){
+ if( oldmask==0xffffffff
+ || (i<32 && (oldmask & MASKBIT32(i))!=0)
+ || (pTab->aCol[i].colFlags & COLFLAG_PRIMKEY)!=0
+ ){
+ testcase( oldmask!=0xffffffff && i==31 );
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regOld+i);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Null, 0, regOld+i);
+ }
+ }
+ if( chngRowid==0 && pPk==0 ){
+ sqlite3VdbeAddOp2(v, OP_Copy, regOldRowid, regNewRowid);
+ }
+ }
+
+ /* Populate the array of registers beginning at regNew with the new
+ ** row data. This array is used to check constants, create the new
+ ** table and index records, and as the values for any new.* references
+ ** made by triggers.
+ **
+ ** If there are one or more BEFORE triggers, then do not populate the
+ ** registers associated with columns that are (a) not modified by
+ ** this UPDATE statement and (b) not accessed by new.* references. The
+ ** values for registers not modified by the UPDATE must be reloaded from
+ ** the database after the BEFORE triggers are fired anyway (as the trigger
+ ** may have modified them). So not loading those that are not going to
+ ** be used eliminates some redundant opcodes.
+ */
+ newmask = sqlite3TriggerColmask(
+ pParse, pTrigger, pChanges, 1, TRIGGER_BEFORE, pTab, onError
+ );
+ for(i=0; i<pTab->nCol; i++){
+ if( i==pTab->iPKey ){
+ sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
+ }else{
+ j = aXRef[i];
+ if( j>=0 ){
+ sqlite3ExprCode(pParse, pChanges->a[j].pExpr, regNew+i);
+ }else if( 0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask & MASKBIT32(i)) ){
+ /* This branch loads the value of a column that will not be changed
+ ** into a register. This is done if there are no BEFORE triggers, or
+ ** if there are one or more BEFORE triggers that use this value via
+ ** a new.* reference in a trigger program.
+ */
+ testcase( i==31 );
+ testcase( i==32 );
+ sqlite3ExprCodeGetColumnToReg(pParse, pTab, i, iDataCur, regNew+i);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
+ }
+ }
+ }
+
+ /* Fire any BEFORE UPDATE triggers. This happens before constraints are
+ ** verified. One could argue that this is wrong.
+ */
+ if( tmask&TRIGGER_BEFORE ){
+ sqlite3TableAffinity(v, pTab, regNew);
+ sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges,
+ TRIGGER_BEFORE, pTab, regOldRowid, onError, labelContinue);
+
+ /* The row-trigger may have deleted the row being updated. In this
+ ** case, jump to the next row. No updates or AFTER triggers are
+ ** required. This behavior - what happens when the row being updated
+ ** is deleted or renamed by a BEFORE trigger - is left undefined in the
+ ** documentation.
+ */
+ if( pPk ){
+ sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue,regKey,nKey);
+ VdbeCoverage(v);
+ }else{
+ sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid);
+ VdbeCoverage(v);
+ }
+
+ /* If it did not delete it, the row-trigger may still have modified
+ ** some of the columns of the row being updated. Load the values for
+ ** all columns not modified by the update statement into their
+ ** registers in case this has happened.
+ */
+ for(i=0; i<pTab->nCol; i++){
+ if( aXRef[i]<0 && i!=pTab->iPKey ){
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i);
+ }
+ }
+ }
+
+ if( !isView ){
+ int addr1 = 0; /* Address of jump instruction */
+
+ /* Do constraint checks. */
+ assert( regOldRowid>0 );
+ sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
+ regNewRowid, regOldRowid, chngKey, onError, labelContinue, &bReplace,
+ aXRef);
+
+ /* Do FK constraint checks. */
+ if( hasFK ){
+ sqlite3FkCheck(pParse, pTab, regOldRowid, 0, aXRef, chngKey);
+ }
+
+ /* Delete the index entries associated with the current record. */
+ if( bReplace || chngKey ){
+ if( pPk ){
+ addr1 = sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, 0, regKey, nKey);
+ }else{
+ addr1 = sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, 0, regOldRowid);
+ }
+ VdbeCoverageNeverTaken(v);
+ }
+ sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx, -1);
+
+ /* If changing the rowid value, or if there are foreign key constraints
+ ** to process, delete the old record. Otherwise, add a noop OP_Delete
+ ** to invoke the pre-update hook.
+ **
+ ** That (regNew==regnewRowid+1) is true is also important for the
+ ** pre-update hook. If the caller invokes preupdate_new(), the returned
+ ** value is copied from memory cell (regNewRowid+1+iCol), where iCol
+ ** is the column index supplied by the user.
+ */
+ assert( regNew==regNewRowid+1 );
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ sqlite3VdbeAddOp3(v, OP_Delete, iDataCur,
+ OPFLAG_ISUPDATE | ((hasFK || chngKey) ? 0 : OPFLAG_ISNOOP),
+ regNewRowid
+ );
+ if( eOnePass==ONEPASS_MULTI ){
+ assert( hasFK==0 && chngKey==0 );
+ sqlite3VdbeChangeP5(v, OPFLAG_SAVEPOSITION);
+ }
+ if( !pParse->nested ){
+ sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
+ }
+#else
+ if( hasFK || chngKey ){
+ sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0);
+ }
+#endif
+ if( bReplace || chngKey ){
+ sqlite3VdbeJumpHere(v, addr1);
+ }
+
+ if( hasFK ){
+ sqlite3FkCheck(pParse, pTab, 0, regNewRowid, aXRef, chngKey);
+ }
+
+ /* Insert the new index entries and the new record. */
+ sqlite3CompleteInsertion(
+ pParse, pTab, iDataCur, iIdxCur, regNewRowid, aRegIdx,
+ OPFLAG_ISUPDATE | (eOnePass==ONEPASS_MULTI ? OPFLAG_SAVEPOSITION : 0),
+ 0, 0
+ );
+
+ /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to
+ ** handle rows (possibly in other tables) that refer via a foreign key
+ ** to the row just updated. */
+ if( hasFK ){
+ sqlite3FkActions(pParse, pTab, pChanges, regOldRowid, aXRef, chngKey);
+ }
+ }
+
+ /* Increment the row counter
+ */
+ if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab){
+ sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1);
+ }
+
+ sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges,
+ TRIGGER_AFTER, pTab, regOldRowid, onError, labelContinue);
+
+ /* Repeat the above with the next record to be updated, until
+ ** all record selected by the WHERE clause have been updated.
+ */
+ if( eOnePass==ONEPASS_SINGLE ){
+ /* Nothing to do at end-of-loop for a single-pass */
+ }else if( eOnePass==ONEPASS_MULTI ){
+ sqlite3VdbeResolveLabel(v, labelContinue);
+ sqlite3WhereEnd(pWInfo);
+ }else if( pPk ){
+ sqlite3VdbeResolveLabel(v, labelContinue);
+ sqlite3VdbeAddOp2(v, OP_Next, iEph, addrTop); VdbeCoverage(v);
+ }else{
+ sqlite3VdbeGoto(v, labelContinue);
+ }
+ sqlite3VdbeResolveLabel(v, labelBreak);
+
+ /* Update the sqlite_sequence table by storing the content of the
+ ** maximum rowid counter values recorded while inserting into
+ ** autoincrement tables.
+ */
+ if( pParse->nested==0 && pParse->pTriggerTab==0 ){
+ sqlite3AutoincrementEnd(pParse);
+ }
+
+ /*
+ ** Return the number of rows that were changed. If this routine is
+ ** generating code because of a call to sqlite3NestedParse(), do not
+ ** invoke the callback function.
+ */
+ if( (db->flags&SQLITE_CountRows) && !pParse->pTriggerTab && !pParse->nested ){
+ sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1);
+ sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC);
+ }
+
+update_cleanup:
+ sqlite3AuthContextPop(&sContext);
+ sqlite3DbFree(db, aXRef); /* Also frees aRegIdx[] and aToOpen[] */
+ sqlite3SrcListDelete(db, pTabList);
+ sqlite3ExprListDelete(db, pChanges);
+ sqlite3ExprDelete(db, pWhere);
+ return;
+}
+/* Make sure "isView" and other macros defined above are undefined. Otherwise
+** they may interfere with compilation of other functions in this file
+** (or in another file, if this file becomes part of the amalgamation). */
+#ifdef isView
+ #undef isView
+#endif
+#ifdef pTrigger
+ #undef pTrigger
+#endif
+
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+/*
+** Generate code for an UPDATE of a virtual table.
+**
+** There are two possible strategies - the default and the special
+** "onepass" strategy. Onepass is only used if the virtual table
+** implementation indicates that pWhere may match at most one row.
+**
+** The default strategy is to create an ephemeral table that contains
+** for each row to be changed:
+**
+** (A) The original rowid of that row.
+** (B) The revised rowid for the row.
+** (C) The content of every column in the row.
+**
+** Then loop through the contents of this ephemeral table executing a
+** VUpdate for each row. When finished, drop the ephemeral table.
+**
+** The "onepass" strategy does not use an ephemeral table. Instead, it
+** stores the same values (A, B and C above) in a register array and
+** makes a single invocation of VUpdate.
+*/
+static void updateVirtualTable(
+ Parse *pParse, /* The parsing context */
+ SrcList *pSrc, /* The virtual table to be modified */
+ Table *pTab, /* The virtual table */
+ ExprList *pChanges, /* The columns to change in the UPDATE statement */
+ Expr *pRowid, /* Expression used to recompute the rowid */
+ int *aXRef, /* Mapping from columns of pTab to entries in pChanges */
+ Expr *pWhere, /* WHERE clause of the UPDATE statement */
+ int onError /* ON CONFLICT strategy */
+){
+ Vdbe *v = pParse->pVdbe; /* Virtual machine under construction */
+ int ephemTab; /* Table holding the result of the SELECT */
+ int i; /* Loop counter */
+ sqlite3 *db = pParse->db; /* Database connection */
+ const char *pVTab = (const char*)sqlite3GetVTable(db, pTab);
+ WhereInfo *pWInfo;
+ int nArg = 2 + pTab->nCol; /* Number of arguments to VUpdate */
+ int regArg; /* First register in VUpdate arg array */
+ int regRec; /* Register in which to assemble record */
+ int regRowid; /* Register for ephem table rowid */
+ int iCsr = pSrc->a[0].iCursor; /* Cursor used for virtual table scan */
+ int aDummy[2]; /* Unused arg for sqlite3WhereOkOnePass() */
+ int bOnePass; /* True to use onepass strategy */
+ int addr; /* Address of OP_OpenEphemeral */
+
+ /* Allocate nArg registers to martial the arguments to VUpdate. Then
+ ** create and open the ephemeral table in which the records created from
+ ** these arguments will be temporarily stored. */
+ assert( v );
+ ephemTab = pParse->nTab++;
+ addr= sqlite3VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, nArg);
+ regArg = pParse->nMem + 1;
+ pParse->nMem += nArg;
+ regRec = ++pParse->nMem;
+ regRowid = ++pParse->nMem;
+
+ /* Start scanning the virtual table */
+ pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0,0,WHERE_ONEPASS_DESIRED,0);
+ if( pWInfo==0 ) return;
+
+ /* Populate the argument registers. */
+ sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg);
+ if( pRowid ){
+ sqlite3ExprCode(pParse, pRowid, regArg+1);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg+1);
+ }
+ for(i=0; i<pTab->nCol; i++){
+ if( aXRef[i]>=0 ){
+ sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i);
+ }else{
+ sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i);
+ }
+ }
+
+ bOnePass = sqlite3WhereOkOnePass(pWInfo, aDummy);
+
+ if( bOnePass ){
+ /* If using the onepass strategy, no-op out the OP_OpenEphemeral coded
+ ** above. Also, if this is a top-level parse (not a trigger), clear the
+ ** multi-write flag so that the VM does not open a statement journal */
+ sqlite3VdbeChangeToNoop(v, addr);
+ if( sqlite3IsToplevel(pParse) ){
+ pParse->isMultiWrite = 0;
+ }
+ }else{
+ /* Create a record from the argument register contents and insert it into
+ ** the ephemeral table. */
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regArg, nArg, regRec);
+ sqlite3VdbeAddOp2(v, OP_NewRowid, ephemTab, regRowid);
+ sqlite3VdbeAddOp3(v, OP_Insert, ephemTab, regRec, regRowid);
+ }
+
+
+ if( bOnePass==0 ){
+ /* End the virtual table scan */
+ sqlite3WhereEnd(pWInfo);
+
+ /* Begin scannning through the ephemeral table. */
+ addr = sqlite3VdbeAddOp1(v, OP_Rewind, ephemTab); VdbeCoverage(v);
+
+ /* Extract arguments from the current row of the ephemeral table and
+ ** invoke the VUpdate method. */
+ for(i=0; i<nArg; i++){
+ sqlite3VdbeAddOp3(v, OP_Column, ephemTab, i, regArg+i);
+ }
+ }
+ sqlite3VtabMakeWritable(pParse, pTab);
+ sqlite3VdbeAddOp4(v, OP_VUpdate, 0, nArg, regArg, pVTab, P4_VTAB);
+ sqlite3VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError);
+ sqlite3MayAbort(pParse);
+
+ /* End of the ephemeral table scan. Or, if using the onepass strategy,
+ ** jump to here if the scan visited zero rows. */
+ if( bOnePass==0 ){
+ sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1); VdbeCoverage(v);
+ sqlite3VdbeJumpHere(v, addr);
+ sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0);
+ }else{
+ sqlite3WhereEnd(pWInfo);
+ }
+}
+#endif /* SQLITE_OMIT_VIRTUALTABLE */
+
+/************** End of update.c **********************************************/
+/************** Begin file vacuum.c ******************************************/
+/*
+** 2003 April 6
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains code used to implement the VACUUM command.
+**
+** Most of the code in this file may be omitted by defining the
+** SQLITE_OMIT_VACUUM macro.
+*/
+/* #include "sqliteInt.h" */
+/* #include "vdbeInt.h" */
+
+#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
+
+/*
+** Execute zSql on database db.
+**
+** If zSql returns rows, then each row will have exactly one
+** column. (This will only happen if zSql begins with "SELECT".)
+** Take each row of result and call execSql() again recursively.
+**
+** The execSqlF() routine does the same thing, except it accepts
+** a format string as its third argument
+*/
+static int execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
+ sqlite3_stmt *pStmt;
+ int rc;
+
+ /* printf("SQL: [%s]\n", zSql); fflush(stdout); */
+ rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
+ if( rc!=SQLITE_OK ) return rc;
+ while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){
+ const char *zSubSql = (const char*)sqlite3_column_text(pStmt,0);
+ assert( sqlite3_strnicmp(zSql,"SELECT",6)==0 );
+ if( zSubSql ){
+ assert( zSubSql[0]!='S' );
+ rc = execSql(db, pzErrMsg, zSubSql);
+ if( rc!=SQLITE_OK ) break;
+ }
+ }
+ assert( rc!=SQLITE_ROW );
+ if( rc==SQLITE_DONE ) rc = SQLITE_OK;
+ if( rc ){
+ sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
+ }
+ (void)sqlite3_finalize(pStmt);
+ return rc;
+}
+static int execSqlF(sqlite3 *db, char **pzErrMsg, const char *zSql, ...){
+ char *z;
+ va_list ap;
+ int rc;
+ va_start(ap, zSql);
+ z = sqlite3VMPrintf(db, zSql, ap);
+ va_end(ap);
+ if( z==0 ) return SQLITE_NOMEM;
+ rc = execSql(db, pzErrMsg, z);
+ sqlite3DbFree(db, z);
+ return rc;
+}
+
+/*
+** The VACUUM command is used to clean up the database,
+** collapse free space, etc. It is modelled after the VACUUM command
+** in PostgreSQL. The VACUUM command works as follows:
+**
+** (1) Create a new transient database file
+** (2) Copy all content from the database being vacuumed into
+** the new transient database file
+** (3) Copy content from the transient database back into the
+** original database.
+**
+** The transient database requires temporary disk space approximately
+** equal to the size of the original database. The copy operation of
+** step (3) requires additional temporary disk space approximately equal
+** to the size of the original database for the rollback journal.
+** Hence, temporary disk space that is approximately 2x the size of the
+** original database is required. Every page of the database is written
+** approximately 3 times: Once for step (2) and twice for step (3).
+** Two writes per page are required in step (3) because the original
+** database content must be written into the rollback journal prior to
+** overwriting the database with the vacuumed content.
+**
+** Only 1x temporary space and only 1x writes would be required if
+** the copy of step (3) were replaced by deleting the original database
+** and renaming the transient database as the original. But that will
+** not work if other processes are attached to the original database.
+** And a power loss in between deleting the original and renaming the
+** transient would cause the database file to appear to be deleted
+** following reboot.
+*/
+SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm){
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ int iDb = pNm ? sqlite3TwoPartName(pParse, pNm, pNm, &pNm) : 0;
+ if( v && (iDb>=2 || iDb==0) ){
+ sqlite3VdbeAddOp1(v, OP_Vacuum, iDb);
+ sqlite3VdbeUsesBtree(v, iDb);
+ }
+ return;
+}
+
+/*
+** This routine implements the OP_Vacuum opcode of the VDBE.
+*/
+SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
+ int rc = SQLITE_OK; /* Return code from service routines */
+ Btree *pMain; /* The database being vacuumed */
+ Btree *pTemp; /* The temporary database we vacuum into */
+ int saved_flags; /* Saved value of the db->flags */
+ int saved_nChange; /* Saved value of db->nChange */
+ int saved_nTotalChange; /* Saved value of db->nTotalChange */
+ u8 saved_mTrace; /* Saved trace settings */
+ Db *pDb = 0; /* Database to detach at end of vacuum */
+ int isMemDb; /* True if vacuuming a :memory: database */
+ int nRes; /* Bytes of reserved space at the end of each page */
+ int nDb; /* Number of attached databases */
+ const char *zDbMain; /* Schema name of database to vacuum */
+
+ if( !db->autoCommit ){
+ sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
+ return SQLITE_ERROR;
+ }
+ if( db->nVdbeActive>1 ){
+ sqlite3SetString(pzErrMsg, db,"cannot VACUUM - SQL statements in progress");
+ return SQLITE_ERROR;
+ }
+
+ /* Save the current value of the database flags so that it can be
+ ** restored before returning. Then set the writable-schema flag, and
+ ** disable CHECK and foreign key constraints. */
+ saved_flags = db->flags;
+ saved_nChange = db->nChange;
+ saved_nTotalChange = db->nTotalChange;
+ saved_mTrace = db->mTrace;
+ db->flags |= (SQLITE_WriteSchema | SQLITE_IgnoreChecks
+ | SQLITE_PreferBuiltin | SQLITE_Vacuum);
+ db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder | SQLITE_CountRows);
+ db->mTrace = 0;
+
+ zDbMain = db->aDb[iDb].zDbSName;
+ pMain = db->aDb[iDb].pBt;
+ isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));
+
+ /* Attach the temporary database as 'vacuum_db'. The synchronous pragma
+ ** can be set to 'off' for this file, as it is not recovered if a crash
+ ** occurs anyway. The integrity of the database is maintained by a
+ ** (possibly synchronous) transaction opened on the main database before
+ ** sqlite3BtreeCopyFile() is called.
+ **
+ ** An optimisation would be to use a non-journaled pager.
+ ** (Later:) I tried setting "PRAGMA vacuum_db.journal_mode=OFF" but
+ ** that actually made the VACUUM run slower. Very little journalling
+ ** actually occurs when doing a vacuum since the vacuum_db is initially
+ ** empty. Only the journal header is written. Apparently it takes more
+ ** time to parse and run the PRAGMA to turn journalling off than it does
+ ** to write the journal header file.
+ */
+ nDb = db->nDb;
+ rc = execSql(db, pzErrMsg, "ATTACH''AS vacuum_db");
+ if( rc!=SQLITE_OK ) goto end_of_vacuum;
+ assert( (db->nDb-1)==nDb );
+ pDb = &db->aDb[nDb];
+ assert( strcmp(pDb->zDbSName,"vacuum_db")==0 );
+ pTemp = pDb->pBt;
+
+ /* The call to execSql() to attach the temp database has left the file
+ ** locked (as there was more than one active statement when the transaction
+ ** to read the schema was concluded. Unlock it here so that this doesn't
+ ** cause problems for the call to BtreeSetPageSize() below. */
+ sqlite3BtreeCommit(pTemp);
+
+ nRes = sqlite3BtreeGetOptimalReserve(pMain);
+
+ /* A VACUUM cannot change the pagesize of an encrypted database. */
+#ifdef SQLITE_HAS_CODEC
+ if( db->nextPagesize ){
+ extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
+ int nKey;
+ char *zKey;
+ sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
+ if( nKey ) db->nextPagesize = 0;
+ }
+#endif
+
+ sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size);
+ sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0));
+ sqlite3BtreeSetPagerFlags(pTemp, PAGER_SYNCHRONOUS_OFF|PAGER_CACHESPILL);
+
+ /* Begin a transaction and take an exclusive lock on the main database
+ ** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below,
+ ** to ensure that we do not try to change the page-size on a WAL database.
+ */
+ rc = execSql(db, pzErrMsg, "BEGIN");
+ if( rc!=SQLITE_OK ) goto end_of_vacuum;
+ rc = sqlite3BtreeBeginTrans(pMain, 2);
+ if( rc!=SQLITE_OK ) goto end_of_vacuum;
+
+ /* Do not attempt to change the page size for a WAL database */
+ if( sqlite3PagerGetJournalMode(sqlite3BtreePager(pMain))
+ ==PAGER_JOURNALMODE_WAL ){
+ db->nextPagesize = 0;
+ }
+
+ if( sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain), nRes, 0)
+ || (!isMemDb && sqlite3BtreeSetPageSize(pTemp, db->nextPagesize, nRes, 0))
+ || NEVER(db->mallocFailed)
+ ){
+ rc = SQLITE_NOMEM_BKPT;
+ goto end_of_vacuum;
+ }
+
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ sqlite3BtreeSetAutoVacuum(pTemp, db->nextAutovac>=0 ? db->nextAutovac :
+ sqlite3BtreeGetAutoVacuum(pMain));
+#endif
+
+ /* Query the schema of the main database. Create a mirror schema
+ ** in the temporary database.
+ */
+ db->init.iDb = nDb; /* force new CREATE statements into vacuum_db */
+ rc = execSqlF(db, pzErrMsg,
+ "SELECT sql FROM \"%w\".sqlite_master"
+ " WHERE type='table'AND name<>'sqlite_sequence'"
+ " AND coalesce(rootpage,1)>0",
+ zDbMain
+ );
+ if( rc!=SQLITE_OK ) goto end_of_vacuum;
+ rc = execSqlF(db, pzErrMsg,
+ "SELECT sql FROM \"%w\".sqlite_master"
+ " WHERE type='index' AND length(sql)>10",
+ zDbMain
+ );
+ if( rc!=SQLITE_OK ) goto end_of_vacuum;
+ db->init.iDb = 0;
+
+ /* Loop through the tables in the main database. For each, do
+ ** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy
+ ** the contents to the temporary database.
+ */
+ rc = execSqlF(db, pzErrMsg,
+ "SELECT'INSERT INTO vacuum_db.'||quote(name)"
+ "||' SELECT*FROM\"%w\".'||quote(name)"
+ "FROM vacuum_db.sqlite_master "
+ "WHERE type='table'AND coalesce(rootpage,1)>0",
+ zDbMain
+ );
+ assert( (db->flags & SQLITE_Vacuum)!=0 );
+ db->flags &= ~SQLITE_Vacuum;
+ if( rc!=SQLITE_OK ) goto end_of_vacuum;
+
+ /* Copy the triggers, views, and virtual tables from the main database
+ ** over to the temporary database. None of these objects has any
+ ** associated storage, so all we have to do is copy their entries
+ ** from the SQLITE_MASTER table.
+ */
+ rc = execSqlF(db, pzErrMsg,
+ "INSERT INTO vacuum_db.sqlite_master"
+ " SELECT*FROM \"%w\".sqlite_master"
+ " WHERE type IN('view','trigger')"
+ " OR(type='table'AND rootpage=0)",
+ zDbMain
+ );
+ if( rc ) goto end_of_vacuum;
+
+ /* At this point, there is a write transaction open on both the
+ ** vacuum database and the main database. Assuming no error occurs,
+ ** both transactions are closed by this block - the main database
+ ** transaction by sqlite3BtreeCopyFile() and the other by an explicit
+ ** call to sqlite3BtreeCommit().
+ */
+ {
+ u32 meta;
+ int i;
+
+ /* This array determines which meta meta values are preserved in the
+ ** vacuum. Even entries are the meta value number and odd entries
+ ** are an increment to apply to the meta value after the vacuum.
+ ** The increment is used to increase the schema cookie so that other
+ ** connections to the same database will know to reread the schema.
+ */
+ static const unsigned char aCopy[] = {
+ BTREE_SCHEMA_VERSION, 1, /* Add one to the old schema cookie */
+ BTREE_DEFAULT_CACHE_SIZE, 0, /* Preserve the default page cache size */
+ BTREE_TEXT_ENCODING, 0, /* Preserve the text encoding */
+ BTREE_USER_VERSION, 0, /* Preserve the user version */
+ BTREE_APPLICATION_ID, 0, /* Preserve the application id */
+ };
+
+ assert( 1==sqlite3BtreeIsInTrans(pTemp) );
+ assert( 1==sqlite3BtreeIsInTrans(pMain) );
+
+ /* Copy Btree meta values */
+ for(i=0; i<ArraySize(aCopy); i+=2){
+ /* GetMeta() and UpdateMeta() cannot fail in this context because
+ ** we already have page 1 loaded into cache and marked dirty. */
+ sqlite3BtreeGetMeta(pMain, aCopy[i], &meta);
+ rc = sqlite3BtreeUpdateMeta(pTemp, aCopy[i], meta+aCopy[i+1]);
+ if( NEVER(rc!=SQLITE_OK) ) goto end_of_vacuum;
+ }
+
+ rc = sqlite3BtreeCopyFile(pMain, pTemp);
+ if( rc!=SQLITE_OK ) goto end_of_vacuum;
+ rc = sqlite3BtreeCommit(pTemp);
+ if( rc!=SQLITE_OK ) goto end_of_vacuum;
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ sqlite3BtreeSetAutoVacuum(pMain, sqlite3BtreeGetAutoVacuum(pTemp));
+#endif
+ }
+
+ assert( rc==SQLITE_OK );
+ rc = sqlite3BtreeSetPageSize(pMain, sqlite3BtreeGetPageSize(pTemp), nRes,1);
+
+end_of_vacuum:
+ /* Restore the original value of db->flags */
+ db->init.iDb = 0;
+ db->flags = saved_flags;
+ db->nChange = saved_nChange;
+ db->nTotalChange = saved_nTotalChange;
+ db->mTrace = saved_mTrace;
+ sqlite3BtreeSetPageSize(pMain, -1, -1, 1);
+
+ /* Currently there is an SQL level transaction open on the vacuum
+ ** database. No locks are held on any other files (since the main file
+ ** was committed at the btree level). So it safe to end the transaction
+ ** by manually setting the autoCommit flag to true and detaching the
+ ** vacuum database. The vacuum_db journal file is deleted when the pager
+ ** is closed by the DETACH.
+ */
+ db->autoCommit = 1;
+
+ if( pDb ){
+ sqlite3BtreeClose(pDb->pBt);
+ pDb->pBt = 0;
+ pDb->pSchema = 0;
+ }
+
+ /* This both clears the schemas and reduces the size of the db->aDb[]
+ ** array. */
+ sqlite3ResetAllSchemasOfConnection(db);
+
+ return rc;
+}
+
+#endif /* SQLITE_OMIT_VACUUM && SQLITE_OMIT_ATTACH */
+
+/************** End of vacuum.c **********************************************/
+/************** Begin file vtab.c ********************************************/
+/*
+** 2006 June 10
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains code used to help implement virtual tables.
+*/
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+/* #include "sqliteInt.h" */
+
+/*
+** Before a virtual table xCreate() or xConnect() method is invoked, the
+** sqlite3.pVtabCtx member variable is set to point to an instance of
+** this struct allocated on the stack. It is used by the implementation of
+** the sqlite3_declare_vtab() and sqlite3_vtab_config() APIs, both of which
+** are invoked only from within xCreate and xConnect methods.
+*/
+struct VtabCtx {
+ VTable *pVTable; /* The virtual table being constructed */
+ Table *pTab; /* The Table object to which the virtual table belongs */
+ VtabCtx *pPrior; /* Parent context (if any) */
+ int bDeclared; /* True after sqlite3_declare_vtab() is called */
+};
+
+/*
+** Construct and install a Module object for a virtual table. When this
+** routine is called, it is guaranteed that all appropriate locks are held
+** and the module is not already part of the connection.
+*/
+SQLITE_PRIVATE Module *sqlite3VtabCreateModule(
+ sqlite3 *db, /* Database in which module is registered */
+ const char *zName, /* Name assigned to this module */
+ const sqlite3_module *pModule, /* The definition of the module */
+ void *pAux, /* Context pointer for xCreate/xConnect */
+ void (*xDestroy)(void *) /* Module destructor function */
+){
+ Module *pMod;
+ int nName = sqlite3Strlen30(zName);
+ pMod = (Module *)sqlite3DbMallocRawNN(db, sizeof(Module) + nName + 1);
+ if( pMod ){
+ Module *pDel;
+ char *zCopy = (char *)(&pMod[1]);
+ memcpy(zCopy, zName, nName+1);
+ pMod->zName = zCopy;
+ pMod->pModule = pModule;
+ pMod->pAux = pAux;
+ pMod->xDestroy = xDestroy;
+ pMod->pEpoTab = 0;
+ pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod);
+ assert( pDel==0 || pDel==pMod );
+ if( pDel ){
+ sqlite3OomFault(db);
+ sqlite3DbFree(db, pDel);
+ pMod = 0;
+ }
+ }
+ return pMod;
+}
+
+/*
+** The actual function that does the work of creating a new module.
+** This function implements the sqlite3_create_module() and
+** sqlite3_create_module_v2() interfaces.
+*/
+static int createModule(
+ sqlite3 *db, /* Database in which module is registered */
+ const char *zName, /* Name assigned to this module */
+ const sqlite3_module *pModule, /* The definition of the module */
+ void *pAux, /* Context pointer for xCreate/xConnect */
+ void (*xDestroy)(void *) /* Module destructor function */
+){
+ int rc = SQLITE_OK;
+
+ sqlite3_mutex_enter(db->mutex);
+ if( sqlite3HashFind(&db->aModule, zName) ){
+ rc = SQLITE_MISUSE_BKPT;
+ }else{
+ (void)sqlite3VtabCreateModule(db, zName, pModule, pAux, xDestroy);
+ }
+ rc = sqlite3ApiExit(db, rc);
+ if( rc!=SQLITE_OK && xDestroy ) xDestroy(pAux);
+ sqlite3_mutex_leave(db->mutex);
+ return rc;
+}
+
+
+/*
+** External API function used to create a new virtual-table module.
+*/
+SQLITE_API int sqlite3_create_module(
+ sqlite3 *db, /* Database in which module is registered */
+ const char *zName, /* Name assigned to this module */
+ const sqlite3_module *pModule, /* The definition of the module */
+ void *pAux /* Context pointer for xCreate/xConnect */
+){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT;
+#endif
+ return createModule(db, zName, pModule, pAux, 0);
+}
+
+/*
+** External API function used to create a new virtual-table module.
+*/
+SQLITE_API int sqlite3_create_module_v2(
+ sqlite3 *db, /* Database in which module is registered */
+ const char *zName, /* Name assigned to this module */
+ const sqlite3_module *pModule, /* The definition of the module */
+ void *pAux, /* Context pointer for xCreate/xConnect */
+ void (*xDestroy)(void *) /* Module destructor function */
+){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT;
+#endif
+ return createModule(db, zName, pModule, pAux, xDestroy);
+}
+
+/*
+** Lock the virtual table so that it cannot be disconnected.
+** Locks nest. Every lock should have a corresponding unlock.
+** If an unlock is omitted, resources leaks will occur.
+**
+** If a disconnect is attempted while a virtual table is locked,
+** the disconnect is deferred until all locks have been removed.
+*/
+SQLITE_PRIVATE void sqlite3VtabLock(VTable *pVTab){
+ pVTab->nRef++;
+}
+
+
+/*
+** pTab is a pointer to a Table structure representing a virtual-table.
+** Return a pointer to the VTable object used by connection db to access
+** this virtual-table, if one has been created, or NULL otherwise.
+*/
+SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3 *db, Table *pTab){
+ VTable *pVtab;
+ assert( IsVirtual(pTab) );
+ for(pVtab=pTab->pVTable; pVtab && pVtab->db!=db; pVtab=pVtab->pNext);
+ return pVtab;
+}
+
+/*
+** Decrement the ref-count on a virtual table object. When the ref-count
+** reaches zero, call the xDisconnect() method to delete the object.
+*/
+SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *pVTab){
+ sqlite3 *db = pVTab->db;
+
+ assert( db );
+ assert( pVTab->nRef>0 );
+ assert( db->magic==SQLITE_MAGIC_OPEN || db->magic==SQLITE_MAGIC_ZOMBIE );
+
+ pVTab->nRef--;
+ if( pVTab->nRef==0 ){
+ sqlite3_vtab *p = pVTab->pVtab;
+ if( p ){
+ p->pModule->xDisconnect(p);
+ }
+ sqlite3DbFree(db, pVTab);
+ }
+}
+
+/*
+** Table p is a virtual table. This function moves all elements in the
+** p->pVTable list to the sqlite3.pDisconnect lists of their associated
+** database connections to be disconnected at the next opportunity.
+** Except, if argument db is not NULL, then the entry associated with
+** connection db is left in the p->pVTable list.
+*/
+static VTable *vtabDisconnectAll(sqlite3 *db, Table *p){
+ VTable *pRet = 0;
+ VTable *pVTable = p->pVTable;
+ p->pVTable = 0;
+
+ /* Assert that the mutex (if any) associated with the BtShared database
+ ** that contains table p is held by the caller. See header comments
+ ** above function sqlite3VtabUnlockList() for an explanation of why
+ ** this makes it safe to access the sqlite3.pDisconnect list of any
+ ** database connection that may have an entry in the p->pVTable list.
+ */
+ assert( db==0 || sqlite3SchemaMutexHeld(db, 0, p->pSchema) );
+
+ while( pVTable ){
+ sqlite3 *db2 = pVTable->db;
+ VTable *pNext = pVTable->pNext;
+ assert( db2 );
+ if( db2==db ){
+ pRet = pVTable;
+ p->pVTable = pRet;
+ pRet->pNext = 0;
+ }else{
+ pVTable->pNext = db2->pDisconnect;
+ db2->pDisconnect = pVTable;
+ }
+ pVTable = pNext;
+ }
+
+ assert( !db || pRet );
+ return pRet;
+}
+
+/*
+** Table *p is a virtual table. This function removes the VTable object
+** for table *p associated with database connection db from the linked
+** list in p->pVTab. It also decrements the VTable ref count. This is
+** used when closing database connection db to free all of its VTable
+** objects without disturbing the rest of the Schema object (which may
+** be being used by other shared-cache connections).
+*/
+SQLITE_PRIVATE void sqlite3VtabDisconnect(sqlite3 *db, Table *p){
+ VTable **ppVTab;
+
+ assert( IsVirtual(p) );
+ assert( sqlite3BtreeHoldsAllMutexes(db) );
+ assert( sqlite3_mutex_held(db->mutex) );
+
+ for(ppVTab=&p->pVTable; *ppVTab; ppVTab=&(*ppVTab)->pNext){
+ if( (*ppVTab)->db==db ){
+ VTable *pVTab = *ppVTab;
+ *ppVTab = pVTab->pNext;
+ sqlite3VtabUnlock(pVTab);
+ break;
+ }
+ }
+}
+
+
+/*
+** Disconnect all the virtual table objects in the sqlite3.pDisconnect list.
+**
+** This function may only be called when the mutexes associated with all
+** shared b-tree databases opened using connection db are held by the
+** caller. This is done to protect the sqlite3.pDisconnect list. The
+** sqlite3.pDisconnect list is accessed only as follows:
+**
+** 1) By this function. In this case, all BtShared mutexes and the mutex
+** associated with the database handle itself must be held.
+**
+** 2) By function vtabDisconnectAll(), when it adds a VTable entry to
+** the sqlite3.pDisconnect list. In this case either the BtShared mutex
+** associated with the database the virtual table is stored in is held
+** or, if the virtual table is stored in a non-sharable database, then
+** the database handle mutex is held.
+**
+** As a result, a sqlite3.pDisconnect cannot be accessed simultaneously
+** by multiple threads. It is thread-safe.
+*/
+SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3 *db){
+ VTable *p = db->pDisconnect;
+ db->pDisconnect = 0;
+
+ assert( sqlite3BtreeHoldsAllMutexes(db) );
+ assert( sqlite3_mutex_held(db->mutex) );
+
+ if( p ){
+ sqlite3ExpirePreparedStatements(db);
+ do {
+ VTable *pNext = p->pNext;
+ sqlite3VtabUnlock(p);
+ p = pNext;
+ }while( p );
+ }
+}
+
+/*
+** Clear any and all virtual-table information from the Table record.
+** This routine is called, for example, just before deleting the Table
+** record.
+**
+** Since it is a virtual-table, the Table structure contains a pointer
+** to the head of a linked list of VTable structures. Each VTable
+** structure is associated with a single sqlite3* user of the schema.
+** The reference count of the VTable structure associated with database
+** connection db is decremented immediately (which may lead to the
+** structure being xDisconnected and free). Any other VTable structures
+** in the list are moved to the sqlite3.pDisconnect list of the associated
+** database connection.
+*/
+SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table *p){
+ if( !db || db->pnBytesFreed==0 ) vtabDisconnectAll(0, p);
+ if( p->azModuleArg ){
+ int i;
+ for(i=0; i<p->nModuleArg; i++){
+ if( i!=1 ) sqlite3DbFree(db, p->azModuleArg[i]);
+ }
+ sqlite3DbFree(db, p->azModuleArg);
+ }
+}
+
+/*
+** Add a new module argument to pTable->azModuleArg[].
+** The string is not copied - the pointer is stored. The
+** string will be freed automatically when the table is
+** deleted.
+*/
+static void addModuleArgument(sqlite3 *db, Table *pTable, char *zArg){
+ int nBytes = sizeof(char *)*(2+pTable->nModuleArg);
+ char **azModuleArg;
+ azModuleArg = sqlite3DbRealloc(db, pTable->azModuleArg, nBytes);
+ if( azModuleArg==0 ){
+ sqlite3DbFree(db, zArg);
+ }else{
+ int i = pTable->nModuleArg++;
+ azModuleArg[i] = zArg;
+ azModuleArg[i+1] = 0;
+ pTable->azModuleArg = azModuleArg;
+ }
+}
+
+/*
+** The parser calls this routine when it first sees a CREATE VIRTUAL TABLE
+** statement. The module name has been parsed, but the optional list
+** of parameters that follow the module name are still pending.
+*/
+SQLITE_PRIVATE void sqlite3VtabBeginParse(
+ Parse *pParse, /* Parsing context */
+ Token *pName1, /* Name of new table, or database name */
+ Token *pName2, /* Name of new table or NULL */
+ Token *pModuleName, /* Name of the module for the virtual table */
+ int ifNotExists /* No error if the table already exists */
+){
+ int iDb; /* The database the table is being created in */
+ Table *pTable; /* The new virtual table */
+ sqlite3 *db; /* Database connection */
+
+ sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, ifNotExists);
+ pTable = pParse->pNewTable;
+ if( pTable==0 ) return;
+ assert( 0==pTable->pIndex );
+
+ db = pParse->db;
+ iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
+ assert( iDb>=0 );
+
+ pTable->tabFlags |= TF_Virtual;
+ pTable->nModuleArg = 0;
+ addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
+ addModuleArgument(db, pTable, 0);
+ addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));
+ assert( (pParse->sNameToken.z==pName2->z && pName2->z!=0)
+ || (pParse->sNameToken.z==pName1->z && pName2->z==0)
+ );
+ pParse->sNameToken.n = (int)(
+ &pModuleName->z[pModuleName->n] - pParse->sNameToken.z
+ );
+
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ /* Creating a virtual table invokes the authorization callback twice.
+ ** The first invocation, to obtain permission to INSERT a row into the
+ ** sqlite_master table, has already been made by sqlite3StartTable().
+ ** The second call, to obtain permission to create the table, is made now.
+ */
+ if( pTable->azModuleArg ){
+ sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName,
+ pTable->azModuleArg[0], pParse->db->aDb[iDb].zDbSName);
+ }
+#endif
+}
+
+/*
+** This routine takes the module argument that has been accumulating
+** in pParse->zArg[] and appends it to the list of arguments on the
+** virtual table currently under construction in pParse->pTable.
+*/
+static void addArgumentToVtab(Parse *pParse){
+ if( pParse->sArg.z && pParse->pNewTable ){
+ const char *z = (const char*)pParse->sArg.z;
+ int n = pParse->sArg.n;
+ sqlite3 *db = pParse->db;
+ addModuleArgument(db, pParse->pNewTable, sqlite3DbStrNDup(db, z, n));
+ }
+}
+
+/*
+** The parser calls this routine after the CREATE VIRTUAL TABLE statement
+** has been completely parsed.
+*/
+SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
+ Table *pTab = pParse->pNewTable; /* The table being constructed */
+ sqlite3 *db = pParse->db; /* The database connection */
+
+ if( pTab==0 ) return;
+ addArgumentToVtab(pParse);
+ pParse->sArg.z = 0;
+ if( pTab->nModuleArg<1 ) return;
+
+ /* If the CREATE VIRTUAL TABLE statement is being entered for the
+ ** first time (in other words if the virtual table is actually being
+ ** created now instead of just being read out of sqlite_master) then
+ ** do additional initialization work and store the statement text
+ ** in the sqlite_master table.
+ */
+ if( !db->init.busy ){
+ char *zStmt;
+ char *zWhere;
+ int iDb;
+ int iReg;
+ Vdbe *v;
+
+ /* Compute the complete text of the CREATE VIRTUAL TABLE statement */
+ if( pEnd ){
+ pParse->sNameToken.n = (int)(pEnd->z - pParse->sNameToken.z) + pEnd->n;
+ }
+ zStmt = sqlite3MPrintf(db, "CREATE VIRTUAL TABLE %T", &pParse->sNameToken);
+
+ /* A slot for the record has already been allocated in the
+ ** SQLITE_MASTER table. We just need to update that slot with all
+ ** the information we've collected.
+ **
+ ** The VM register number pParse->regRowid holds the rowid of an
+ ** entry in the sqlite_master table tht was created for this vtab
+ ** by sqlite3StartTable().
+ */
+ iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+ sqlite3NestedParse(pParse,
+ "UPDATE %Q.%s "
+ "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q "
+ "WHERE rowid=#%d",
+ db->aDb[iDb].zDbSName, MASTER_NAME,
+ pTab->zName,
+ pTab->zName,
+ zStmt,
+ pParse->regRowid
+ );
+ sqlite3DbFree(db, zStmt);
+ v = sqlite3GetVdbe(pParse);
+ sqlite3ChangeCookie(pParse, iDb);
+
+ sqlite3VdbeAddOp0(v, OP_Expire);
+ zWhere = sqlite3MPrintf(db, "name='%q' AND type='table'", pTab->zName);
+ sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere);
+
+ iReg = ++pParse->nMem;
+ sqlite3VdbeLoadString(v, iReg, pTab->zName);
+ sqlite3VdbeAddOp2(v, OP_VCreate, iDb, iReg);
+ }
+
+ /* If we are rereading the sqlite_master table create the in-memory
+ ** record of the table. The xConnect() method is not called until
+ ** the first time the virtual table is used in an SQL statement. This
+ ** allows a schema that contains virtual tables to be loaded before
+ ** the required virtual table implementations are registered. */
+ else {
+ Table *pOld;
+ Schema *pSchema = pTab->pSchema;
+ const char *zName = pTab->zName;
+ assert( sqlite3SchemaMutexHeld(db, 0, pSchema) );
+ pOld = sqlite3HashInsert(&pSchema->tblHash, zName, pTab);
+ if( pOld ){
+ sqlite3OomFault(db);
+ assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */
+ return;
+ }
+ pParse->pNewTable = 0;
+ }
+}
+
+/*
+** The parser calls this routine when it sees the first token
+** of an argument to the module name in a CREATE VIRTUAL TABLE statement.
+*/
+SQLITE_PRIVATE void sqlite3VtabArgInit(Parse *pParse){
+ addArgumentToVtab(pParse);
+ pParse->sArg.z = 0;
+ pParse->sArg.n = 0;
+}
+
+/*
+** The parser calls this routine for each token after the first token
+** in an argument to the module name in a CREATE VIRTUAL TABLE statement.
+*/
+SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse *pParse, Token *p){
+ Token *pArg = &pParse->sArg;
+ if( pArg->z==0 ){
+ pArg->z = p->z;
+ pArg->n = p->n;
+ }else{
+ assert(pArg->z <= p->z);
+ pArg->n = (int)(&p->z[p->n] - pArg->z);
+ }
+}
+
+/*
+** Invoke a virtual table constructor (either xCreate or xConnect). The
+** pointer to the function to invoke is passed as the fourth parameter
+** to this procedure.
+*/
+static int vtabCallConstructor(
+ sqlite3 *db,
+ Table *pTab,
+ Module *pMod,
+ int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**),
+ char **pzErr
+){
+ VtabCtx sCtx;
+ VTable *pVTable;
+ int rc;
+ const char *const*azArg = (const char *const*)pTab->azModuleArg;
+ int nArg = pTab->nModuleArg;
+ char *zErr = 0;
+ char *zModuleName;
+ int iDb;
+ VtabCtx *pCtx;
+
+ /* Check that the virtual-table is not already being initialized */
+ for(pCtx=db->pVtabCtx; pCtx; pCtx=pCtx->pPrior){
+ if( pCtx->pTab==pTab ){
+ *pzErr = sqlite3MPrintf(db,
+ "vtable constructor called recursively: %s", pTab->zName
+ );
+ return SQLITE_LOCKED;
+ }
+ }
+
+ zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
+ if( !zModuleName ){
+ return SQLITE_NOMEM_BKPT;
+ }
+
+ pVTable = sqlite3DbMallocZero(db, sizeof(VTable));
+ if( !pVTable ){
+ sqlite3DbFree(db, zModuleName);
+ return SQLITE_NOMEM_BKPT;
+ }
+ pVTable->db = db;
+ pVTable->pMod = pMod;
+
+ iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+ pTab->azModuleArg[1] = db->aDb[iDb].zDbSName;
+
+ /* Invoke the virtual table constructor */
+ assert( &db->pVtabCtx );
+ assert( xConstruct );
+ sCtx.pTab = pTab;
+ sCtx.pVTable = pVTable;
+ sCtx.pPrior = db->pVtabCtx;
+ sCtx.bDeclared = 0;
+ db->pVtabCtx = &sCtx;
+ rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
+ db->pVtabCtx = sCtx.pPrior;
+ if( rc==SQLITE_NOMEM ) sqlite3OomFault(db);
+ assert( sCtx.pTab==pTab );
+
+ if( SQLITE_OK!=rc ){
+ if( zErr==0 ){
+ *pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName);
+ }else {
+ *pzErr = sqlite3MPrintf(db, "%s", zErr);
+ sqlite3_free(zErr);
+ }
+ sqlite3DbFree(db, pVTable);
+ }else if( ALWAYS(pVTable->pVtab) ){
+ /* Justification of ALWAYS(): A correct vtab constructor must allocate
+ ** the sqlite3_vtab object if successful. */
+ memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0]));
+ pVTable->pVtab->pModule = pMod->pModule;
+ pVTable->nRef = 1;
+ if( sCtx.bDeclared==0 ){
+ const char *zFormat = "vtable constructor did not declare schema: %s";
+ *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName);
+ sqlite3VtabUnlock(pVTable);
+ rc = SQLITE_ERROR;
+ }else{
+ int iCol;
+ u8 oooHidden = 0;
+ /* If everything went according to plan, link the new VTable structure
+ ** into the linked list headed by pTab->pVTable. Then loop through the
+ ** columns of the table to see if any of them contain the token "hidden".
+ ** If so, set the Column COLFLAG_HIDDEN flag and remove the token from
+ ** the type string. */
+ pVTable->pNext = pTab->pVTable;
+ pTab->pVTable = pVTable;
+
+ for(iCol=0; iCol<pTab->nCol; iCol++){
+ char *zType = sqlite3ColumnType(&pTab->aCol[iCol], "");
+ int nType;
+ int i = 0;
+ nType = sqlite3Strlen30(zType);
+ for(i=0; i<nType; i++){
+ if( 0==sqlite3StrNICmp("hidden", &zType[i], 6)
+ && (i==0 || zType[i-1]==' ')
+ && (zType[i+6]=='\0' || zType[i+6]==' ')
+ ){
+ break;
+ }
+ }
+ if( i<nType ){
+ int j;
+ int nDel = 6 + (zType[i+6] ? 1 : 0);
+ for(j=i; (j+nDel)<=nType; j++){
+ zType[j] = zType[j+nDel];
+ }
+ if( zType[i]=='\0' && i>0 ){
+ assert(zType[i-1]==' ');
+ zType[i-1] = '\0';
+ }
+ pTab->aCol[iCol].colFlags |= COLFLAG_HIDDEN;
+ oooHidden = TF_OOOHidden;
+ }else{
+ pTab->tabFlags |= oooHidden;
+ }
+ }
+ }
+ }
+
+ sqlite3DbFree(db, zModuleName);
+ return rc;
+}
+
+/*
+** This function is invoked by the parser to call the xConnect() method
+** of the virtual table pTab. If an error occurs, an error code is returned
+** and an error left in pParse.
+**
+** This call is a no-op if table pTab is not a virtual table.
+*/
+SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
+ sqlite3 *db = pParse->db;
+ const char *zMod;
+ Module *pMod;
+ int rc;
+
+ assert( pTab );
+ if( (pTab->tabFlags & TF_Virtual)==0 || sqlite3GetVTable(db, pTab) ){
+ return SQLITE_OK;
+ }
+
+ /* Locate the required virtual table module */
+ zMod = pTab->azModuleArg[0];
+ pMod = (Module*)sqlite3HashFind(&db->aModule, zMod);
+
+ if( !pMod ){
+ const char *zModule = pTab->azModuleArg[0];
+ sqlite3ErrorMsg(pParse, "no such module: %s", zModule);
+ rc = SQLITE_ERROR;
+ }else{
+ char *zErr = 0;
+ rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xConnect, &zErr);
+ if( rc!=SQLITE_OK ){
+ sqlite3ErrorMsg(pParse, "%s", zErr);
+ }
+ sqlite3DbFree(db, zErr);
+ }
+
+ return rc;
+}
+/*
+** Grow the db->aVTrans[] array so that there is room for at least one
+** more v-table. Return SQLITE_NOMEM if a malloc fails, or SQLITE_OK otherwise.
+*/
+static int growVTrans(sqlite3 *db){
+ const int ARRAY_INCR = 5;
+
+ /* Grow the sqlite3.aVTrans array if required */
+ if( (db->nVTrans%ARRAY_INCR)==0 ){
+ VTable **aVTrans;
+ int nBytes = sizeof(sqlite3_vtab *) * (db->nVTrans + ARRAY_INCR);
+ aVTrans = sqlite3DbRealloc(db, (void *)db->aVTrans, nBytes);
+ if( !aVTrans ){
+ return SQLITE_NOMEM_BKPT;
+ }
+ memset(&aVTrans[db->nVTrans], 0, sizeof(sqlite3_vtab *)*ARRAY_INCR);
+ db->aVTrans = aVTrans;
+ }
+
+ return SQLITE_OK;
+}
+
+/*
+** Add the virtual table pVTab to the array sqlite3.aVTrans[]. Space should
+** have already been reserved using growVTrans().
+*/
+static void addToVTrans(sqlite3 *db, VTable *pVTab){
+ /* Add pVtab to the end of sqlite3.aVTrans */
+ db->aVTrans[db->nVTrans++] = pVTab;
+ sqlite3VtabLock(pVTab);
+}
+
+/*
+** This function is invoked by the vdbe to call the xCreate method
+** of the virtual table named zTab in database iDb.
+**
+** If an error occurs, *pzErr is set to point to an English language
+** description of the error and an SQLITE_XXX error code is returned.
+** In this case the caller must call sqlite3DbFree(db, ) on *pzErr.
+*/
+SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){
+ int rc = SQLITE_OK;
+ Table *pTab;
+ Module *pMod;
+ const char *zMod;
+
+ pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName);
+ assert( pTab && (pTab->tabFlags & TF_Virtual)!=0 && !pTab->pVTable );
+
+ /* Locate the required virtual table module */
+ zMod = pTab->azModuleArg[0];
+ pMod = (Module*)sqlite3HashFind(&db->aModule, zMod);
+
+ /* If the module has been registered and includes a Create method,
+ ** invoke it now. If the module has not been registered, return an
+ ** error. Otherwise, do nothing.
+ */
+ if( pMod==0 || pMod->pModule->xCreate==0 || pMod->pModule->xDestroy==0 ){
+ *pzErr = sqlite3MPrintf(db, "no such module: %s", zMod);
+ rc = SQLITE_ERROR;
+ }else{
+ rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xCreate, pzErr);
+ }
+
+ /* Justification of ALWAYS(): The xConstructor method is required to
+ ** create a valid sqlite3_vtab if it returns SQLITE_OK. */
+ if( rc==SQLITE_OK && ALWAYS(sqlite3GetVTable(db, pTab)) ){
+ rc = growVTrans(db);
+ if( rc==SQLITE_OK ){
+ addToVTrans(db, sqlite3GetVTable(db, pTab));
+ }
+ }
+
+ return rc;
+}
+
+/*
+** This function is used to set the schema of a virtual table. It is only
+** valid to call this function from within the xCreate() or xConnect() of a
+** virtual table module.
+*/
+SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
+ VtabCtx *pCtx;
+ Parse *pParse;
+ int rc = SQLITE_OK;
+ Table *pTab;
+ char *zErr = 0;
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) || zCreateTable==0 ){
+ return SQLITE_MISUSE_BKPT;
+ }
+#endif
+ sqlite3_mutex_enter(db->mutex);
+ pCtx = db->pVtabCtx;
+ if( !pCtx || pCtx->bDeclared ){
+ sqlite3Error(db, SQLITE_MISUSE);
+ sqlite3_mutex_leave(db->mutex);
+ return SQLITE_MISUSE_BKPT;
+ }
+ pTab = pCtx->pTab;
+ assert( (pTab->tabFlags & TF_Virtual)!=0 );
+
+ pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
+ if( pParse==0 ){
+ rc = SQLITE_NOMEM_BKPT;
+ }else{
+ pParse->declareVtab = 1;
+ pParse->db = db;
+ pParse->nQueryLoop = 1;
+
+ if( SQLITE_OK==sqlite3RunParser(pParse, zCreateTable, &zErr)
+ && pParse->pNewTable
+ && !db->mallocFailed
+ && !pParse->pNewTable->pSelect
+ && (pParse->pNewTable->tabFlags & TF_Virtual)==0
+ ){
+ if( !pTab->aCol ){
+ Table *pNew = pParse->pNewTable;
+ Index *pIdx;
+ pTab->aCol = pNew->aCol;
+ pTab->nCol = pNew->nCol;
+ pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid);
+ pNew->nCol = 0;
+ pNew->aCol = 0;
+ assert( pTab->pIndex==0 );
+ if( !HasRowid(pNew) && pCtx->pVTable->pMod->pModule->xUpdate!=0 ){
+ rc = SQLITE_ERROR;
+ }
+ pIdx = pNew->pIndex;
+ if( pIdx ){
+ assert( pIdx->pNext==0 );
+ pTab->pIndex = pIdx;
+ pNew->pIndex = 0;
+ pIdx->pTable = pTab;
+ }
+ }
+ pCtx->bDeclared = 1;
+ }else{
+ sqlite3ErrorWithMsg(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr);
+ sqlite3DbFree(db, zErr);
+ rc = SQLITE_ERROR;
+ }
+ pParse->declareVtab = 0;
+
+ if( pParse->pVdbe ){
+ sqlite3VdbeFinalize(pParse->pVdbe);
+ }
+ sqlite3DeleteTable(db, pParse->pNewTable);
+ sqlite3ParserReset(pParse);
+ sqlite3StackFree(db, pParse);
+ }
+
+ assert( (rc&0xff)==rc );
+ rc = sqlite3ApiExit(db, rc);
+ sqlite3_mutex_leave(db->mutex);
+ return rc;
+}
+
+/*
+** This function is invoked by the vdbe to call the xDestroy method
+** of the virtual table named zTab in database iDb. This occurs
+** when a DROP TABLE is mentioned.
+**
+** This call is a no-op if zTab is not a virtual table.
+*/
+SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
+ int rc = SQLITE_OK;
+ Table *pTab;
+
+ pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName);
+ if( pTab!=0 && ALWAYS(pTab->pVTable!=0) ){
+ VTable *p;
+ int (*xDestroy)(sqlite3_vtab *);
+ for(p=pTab->pVTable; p; p=p->pNext){
+ assert( p->pVtab );
+ if( p->pVtab->nRef>0 ){
+ return SQLITE_LOCKED;
+ }
+ }
+ p = vtabDisconnectAll(db, pTab);
+ xDestroy = p->pMod->pModule->xDestroy;
+ assert( xDestroy!=0 ); /* Checked before the virtual table is created */
+ rc = xDestroy(p->pVtab);
+ /* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */
+ if( rc==SQLITE_OK ){
+ assert( pTab->pVTable==p && p->pNext==0 );
+ p->pVtab = 0;
+ pTab->pVTable = 0;
+ sqlite3VtabUnlock(p);
+ }
+ }
+
+ return rc;
+}
+
+/*
+** This function invokes either the xRollback or xCommit method
+** of each of the virtual tables in the sqlite3.aVTrans array. The method
+** called is identified by the second argument, "offset", which is
+** the offset of the method to call in the sqlite3_module structure.
+**
+** The array is cleared after invoking the callbacks.
+*/
+static void callFinaliser(sqlite3 *db, int offset){
+ int i;
+ if( db->aVTrans ){
+ VTable **aVTrans = db->aVTrans;
+ db->aVTrans = 0;
+ for(i=0; i<db->nVTrans; i++){
+ VTable *pVTab = aVTrans[i];
+ sqlite3_vtab *p = pVTab->pVtab;
+ if( p ){
+ int (*x)(sqlite3_vtab *);
+ x = *(int (**)(sqlite3_vtab *))((char *)p->pModule + offset);
+ if( x ) x(p);
+ }
+ pVTab->iSavepoint = 0;
+ sqlite3VtabUnlock(pVTab);
+ }
+ sqlite3DbFree(db, aVTrans);
+ db->nVTrans = 0;
+ }
+}
+
+/*
+** Invoke the xSync method of all virtual tables in the sqlite3.aVTrans
+** array. Return the error code for the first error that occurs, or
+** SQLITE_OK if all xSync operations are successful.
+**
+** If an error message is available, leave it in p->zErrMsg.
+*/
+SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, Vdbe *p){
+ int i;
+ int rc = SQLITE_OK;
+ VTable **aVTrans = db->aVTrans;
+
+ db->aVTrans = 0;
+ for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){
+ int (*x)(sqlite3_vtab *);
+ sqlite3_vtab *pVtab = aVTrans[i]->pVtab;
+ if( pVtab && (x = pVtab->pModule->xSync)!=0 ){
+ rc = x(pVtab);
+ sqlite3VtabImportErrmsg(p, pVtab);
+ }
+ }
+ db->aVTrans = aVTrans;
+ return rc;
+}
+
+/*
+** Invoke the xRollback method of all virtual tables in the
+** sqlite3.aVTrans array. Then clear the array itself.
+*/
+SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db){
+ callFinaliser(db, offsetof(sqlite3_module,xRollback));
+ return SQLITE_OK;
+}
+
+/*
+** Invoke the xCommit method of all virtual tables in the
+** sqlite3.aVTrans array. Then clear the array itself.
+*/
+SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db){
+ callFinaliser(db, offsetof(sqlite3_module,xCommit));
+ return SQLITE_OK;
+}
+
+/*
+** If the virtual table pVtab supports the transaction interface
+** (xBegin/xRollback/xCommit and optionally xSync) and a transaction is
+** not currently open, invoke the xBegin method now.
+**
+** If the xBegin call is successful, place the sqlite3_vtab pointer
+** in the sqlite3.aVTrans array.
+*/
+SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *db, VTable *pVTab){
+ int rc = SQLITE_OK;
+ const sqlite3_module *pModule;
+
+ /* Special case: If db->aVTrans is NULL and db->nVTrans is greater
+ ** than zero, then this function is being called from within a
+ ** virtual module xSync() callback. It is illegal to write to
+ ** virtual module tables in this case, so return SQLITE_LOCKED.
+ */
+ if( sqlite3VtabInSync(db) ){
+ return SQLITE_LOCKED;
+ }
+ if( !pVTab ){
+ return SQLITE_OK;
+ }
+ pModule = pVTab->pVtab->pModule;
+
+ if( pModule->xBegin ){
+ int i;
+
+ /* If pVtab is already in the aVTrans array, return early */
+ for(i=0; i<db->nVTrans; i++){
+ if( db->aVTrans[i]==pVTab ){
+ return SQLITE_OK;
+ }
+ }
+
+ /* Invoke the xBegin method. If successful, add the vtab to the
+ ** sqlite3.aVTrans[] array. */
+ rc = growVTrans(db);
+ if( rc==SQLITE_OK ){
+ rc = pModule->xBegin(pVTab->pVtab);
+ if( rc==SQLITE_OK ){
+ int iSvpt = db->nStatement + db->nSavepoint;
+ addToVTrans(db, pVTab);
+ if( iSvpt && pModule->xSavepoint ){
+ pVTab->iSavepoint = iSvpt;
+ rc = pModule->xSavepoint(pVTab->pVtab, iSvpt-1);
+ }
+ }
+ }
+ }
+ return rc;
+}
+
+/*
+** Invoke either the xSavepoint, xRollbackTo or xRelease method of all
+** virtual tables that currently have an open transaction. Pass iSavepoint
+** as the second argument to the virtual table method invoked.
+**
+** If op is SAVEPOINT_BEGIN, the xSavepoint method is invoked. If it is
+** SAVEPOINT_ROLLBACK, the xRollbackTo method. Otherwise, if op is
+** SAVEPOINT_RELEASE, then the xRelease method of each virtual table with
+** an open transaction is invoked.
+**
+** If any virtual table method returns an error code other than SQLITE_OK,
+** processing is abandoned and the error returned to the caller of this
+** function immediately. If all calls to virtual table methods are successful,
+** SQLITE_OK is returned.
+*/
+SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){
+ int rc = SQLITE_OK;
+
+ assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN );
+ assert( iSavepoint>=-1 );
+ if( db->aVTrans ){
+ int i;
+ for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){
+ VTable *pVTab = db->aVTrans[i];
+ const sqlite3_module *pMod = pVTab->pMod->pModule;
+ if( pVTab->pVtab && pMod->iVersion>=2 ){
+ int (*xMethod)(sqlite3_vtab *, int);
+ switch( op ){
+ case SAVEPOINT_BEGIN:
+ xMethod = pMod->xSavepoint;
+ pVTab->iSavepoint = iSavepoint+1;
+ break;
+ case SAVEPOINT_ROLLBACK:
+ xMethod = pMod->xRollbackTo;
+ break;
+ default:
+ xMethod = pMod->xRelease;
+ break;
+ }
+ if( xMethod && pVTab->iSavepoint>iSavepoint ){
+ rc = xMethod(pVTab->pVtab, iSavepoint);
+ }
+ }
+ }
+ }
+ return rc;
+}
+
+/*
+** The first parameter (pDef) is a function implementation. The
+** second parameter (pExpr) is the first argument to this function.
+** If pExpr is a column in a virtual table, then let the virtual
+** table implementation have an opportunity to overload the function.
+**
+** This routine is used to allow virtual table implementations to
+** overload MATCH, LIKE, GLOB, and REGEXP operators.
+**
+** Return either the pDef argument (indicating no change) or a
+** new FuncDef structure that is marked as ephemeral using the
+** SQLITE_FUNC_EPHEM flag.
+*/
+SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(
+ sqlite3 *db, /* Database connection for reporting malloc problems */
+ FuncDef *pDef, /* Function to possibly overload */
+ int nArg, /* Number of arguments to the function */
+ Expr *pExpr /* First argument to the function */
+){
+ Table *pTab;
+ sqlite3_vtab *pVtab;
+ sqlite3_module *pMod;
+ void (*xSFunc)(sqlite3_context*,int,sqlite3_value**) = 0;
+ void *pArg = 0;
+ FuncDef *pNew;
+ int rc = 0;
+ char *zLowerName;
+ unsigned char *z;
+
+
+ /* Check to see the left operand is a column in a virtual table */
+ if( NEVER(pExpr==0) ) return pDef;
+ if( pExpr->op!=TK_COLUMN ) return pDef;
+ pTab = pExpr->pTab;
+ if( NEVER(pTab==0) ) return pDef;
+ if( (pTab->tabFlags & TF_Virtual)==0 ) return pDef;
+ pVtab = sqlite3GetVTable(db, pTab)->pVtab;
+ assert( pVtab!=0 );
+ assert( pVtab->pModule!=0 );
+ pMod = (sqlite3_module *)pVtab->pModule;
+ if( pMod->xFindFunction==0 ) return pDef;
+
+ /* Call the xFindFunction method on the virtual table implementation
+ ** to see if the implementation wants to overload this function
+ */
+ zLowerName = sqlite3DbStrDup(db, pDef->zName);
+ if( zLowerName ){
+ for(z=(unsigned char*)zLowerName; *z; z++){
+ *z = sqlite3UpperToLower[*z];
+ }
+ rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xSFunc, &pArg);
+ sqlite3DbFree(db, zLowerName);
+ }
+ if( rc==0 ){
+ return pDef;
+ }
+
+ /* Create a new ephemeral function definition for the overloaded
+ ** function */
+ pNew = sqlite3DbMallocZero(db, sizeof(*pNew)
+ + sqlite3Strlen30(pDef->zName) + 1);
+ if( pNew==0 ){
+ return pDef;
+ }
+ *pNew = *pDef;
+ pNew->zName = (const char*)&pNew[1];
+ memcpy((char*)&pNew[1], pDef->zName, sqlite3Strlen30(pDef->zName)+1);
+ pNew->xSFunc = xSFunc;
+ pNew->pUserData = pArg;
+ pNew->funcFlags |= SQLITE_FUNC_EPHEM;
+ return pNew;
+}
+
+/*
+** Make sure virtual table pTab is contained in the pParse->apVirtualLock[]
+** array so that an OP_VBegin will get generated for it. Add pTab to the
+** array if it is missing. If pTab is already in the array, this routine
+** is a no-op.
+*/
+SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){
+ Parse *pToplevel = sqlite3ParseToplevel(pParse);
+ int i, n;
+ Table **apVtabLock;
+
+ assert( IsVirtual(pTab) );
+ for(i=0; i<pToplevel->nVtabLock; i++){
+ if( pTab==pToplevel->apVtabLock[i] ) return;
+ }
+ n = (pToplevel->nVtabLock+1)*sizeof(pToplevel->apVtabLock[0]);
+ apVtabLock = sqlite3_realloc64(pToplevel->apVtabLock, n);
+ if( apVtabLock ){
+ pToplevel->apVtabLock = apVtabLock;
+ pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab;
+ }else{
+ sqlite3OomFault(pToplevel->db);
+ }
+}
+
+/*
+** Check to see if virtual table module pMod can be have an eponymous
+** virtual table instance. If it can, create one if one does not already
+** exist. Return non-zero if the eponymous virtual table instance exists
+** when this routine returns, and return zero if it does not exist.
+**
+** An eponymous virtual table instance is one that is named after its
+** module, and more importantly, does not require a CREATE VIRTUAL TABLE
+** statement in order to come into existance. Eponymous virtual table
+** instances always exist. They cannot be DROP-ed.
+**
+** Any virtual table module for which xConnect and xCreate are the same
+** method can have an eponymous virtual table instance.
+*/
+SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){
+ const sqlite3_module *pModule = pMod->pModule;
+ Table *pTab;
+ char *zErr = 0;
+ int rc;
+ sqlite3 *db = pParse->db;
+ if( pMod->pEpoTab ) return 1;
+ if( pModule->xCreate!=0 && pModule->xCreate!=pModule->xConnect ) return 0;
+ pTab = sqlite3DbMallocZero(db, sizeof(Table));
+ if( pTab==0 ) return 0;
+ pTab->zName = sqlite3DbStrDup(db, pMod->zName);
+ if( pTab->zName==0 ){
+ sqlite3DbFree(db, pTab);
+ return 0;
+ }
+ pMod->pEpoTab = pTab;
+ pTab->nTabRef = 1;
+ pTab->pSchema = db->aDb[0].pSchema;
+ pTab->tabFlags |= TF_Virtual;
+ pTab->nModuleArg = 0;
+ pTab->iPKey = -1;
+ addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName));
+ addModuleArgument(db, pTab, 0);
+ addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName));
+ rc = vtabCallConstructor(db, pTab, pMod, pModule->xConnect, &zErr);
+ if( rc ){
+ sqlite3ErrorMsg(pParse, "%s", zErr);
+ sqlite3DbFree(db, zErr);
+ sqlite3VtabEponymousTableClear(db, pMod);
+ return 0;
+ }
+ return 1;
+}
+
+/*
+** Erase the eponymous virtual table instance associated with
+** virtual table module pMod, if it exists.
+*/
+SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3 *db, Module *pMod){
+ Table *pTab = pMod->pEpoTab;
+ if( pTab!=0 ){
+ /* Mark the table as Ephemeral prior to deleting it, so that the
+ ** sqlite3DeleteTable() routine will know that it is not stored in
+ ** the schema. */
+ pTab->tabFlags |= TF_Ephemeral;
+ sqlite3DeleteTable(db, pTab);
+ pMod->pEpoTab = 0;
+ }
+}
+
+/*
+** Return the ON CONFLICT resolution mode in effect for the virtual
+** table update operation currently in progress.
+**
+** The results of this routine are undefined unless it is called from
+** within an xUpdate method.
+*/
+SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *db){
+ static const unsigned char aMap[] = {
+ SQLITE_ROLLBACK, SQLITE_ABORT, SQLITE_FAIL, SQLITE_IGNORE, SQLITE_REPLACE
+ };
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
+#endif
+ assert( OE_Rollback==1 && OE_Abort==2 && OE_Fail==3 );
+ assert( OE_Ignore==4 && OE_Replace==5 );
+ assert( db->vtabOnConflict>=1 && db->vtabOnConflict<=5 );
+ return (int)aMap[db->vtabOnConflict-1];
+}
+
+/*
+** Call from within the xCreate() or xConnect() methods to provide
+** the SQLite core with additional information about the behavior
+** of the virtual table being implemented.
+*/
+SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){
+ va_list ap;
+ int rc = SQLITE_OK;
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
+#endif
+ sqlite3_mutex_enter(db->mutex);
+ va_start(ap, op);
+ switch( op ){
+ case SQLITE_VTAB_CONSTRAINT_SUPPORT: {
+ VtabCtx *p = db->pVtabCtx;
+ if( !p ){
+ rc = SQLITE_MISUSE_BKPT;
+ }else{
+ assert( p->pTab==0 || (p->pTab->tabFlags & TF_Virtual)!=0 );
+ p->pVTable->bConstraint = (u8)va_arg(ap, int);
+ }
+ break;
+ }
+ default:
+ rc = SQLITE_MISUSE_BKPT;
+ break;
+ }
+ va_end(ap);
+
+ if( rc!=SQLITE_OK ) sqlite3Error(db, rc);
+ sqlite3_mutex_leave(db->mutex);
+ return rc;
+}
+
+#endif /* SQLITE_OMIT_VIRTUALTABLE */
+
+/************** End of vtab.c ************************************************/
+
+/* Chain include. */
+#include "sqlite3.06.c"
« no previous file with comments | « third_party/sqlite/amalgamation/sqlite3.04.c ('k') | third_party/sqlite/amalgamation/sqlite3.06.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698