| | @@ -656,11 +656,11 @@ |
| 656 | 656 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 657 | 657 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 658 | 658 | */ |
| 659 | 659 | #define SQLITE_VERSION "3.8.1" |
| 660 | 660 | #define SQLITE_VERSION_NUMBER 3008001 |
| 661 | | -#define SQLITE_SOURCE_ID "2013-09-16 12:57:19 daf6ba413cb3cb6065774ba07495eab4a28b49b0" |
| 661 | +#define SQLITE_SOURCE_ID "2013-10-07 21:49:16 36d64dc36f18c166b2c93c43579fa3bbb5cd545f" |
| 662 | 662 | |
| 663 | 663 | /* |
| 664 | 664 | ** CAPI3REF: Run-Time Library Version Numbers |
| 665 | 665 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 666 | 666 | ** |
| | @@ -11636,10 +11636,11 @@ |
| 11636 | 11636 | */ |
| 11637 | 11637 | typedef struct DbFixer DbFixer; |
| 11638 | 11638 | struct DbFixer { |
| 11639 | 11639 | Parse *pParse; /* The parsing context. Error messages written here */ |
| 11640 | 11640 | Schema *pSchema; /* Fix items to this schema */ |
| 11641 | + int bVarOnly; /* Check for variable references only */ |
| 11641 | 11642 | const char *zDb; /* Make sure all objects are contained in this database */ |
| 11642 | 11643 | const char *zType; /* Type of the container - used for error messages */ |
| 11643 | 11644 | const Token *pName; /* Name of the container - used for error messages */ |
| 11644 | 11645 | }; |
| 11645 | 11646 | |
| | @@ -12174,11 +12175,11 @@ |
| 12174 | 12175 | # define sqlite3AuthContextPush(a,b,c) |
| 12175 | 12176 | # define sqlite3AuthContextPop(a) ((void)(a)) |
| 12176 | 12177 | #endif |
| 12177 | 12178 | SQLITE_PRIVATE void sqlite3Attach(Parse*, Expr*, Expr*, Expr*); |
| 12178 | 12179 | SQLITE_PRIVATE void sqlite3Detach(Parse*, Expr*); |
| 12179 | | -SQLITE_PRIVATE int sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*); |
| 12180 | +SQLITE_PRIVATE void sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*); |
| 12180 | 12181 | SQLITE_PRIVATE int sqlite3FixSrcList(DbFixer*, SrcList*); |
| 12181 | 12182 | SQLITE_PRIVATE int sqlite3FixSelect(DbFixer*, Select*); |
| 12182 | 12183 | SQLITE_PRIVATE int sqlite3FixExpr(DbFixer*, Expr*); |
| 12183 | 12184 | SQLITE_PRIVATE int sqlite3FixExprList(DbFixer*, ExprList*); |
| 12184 | 12185 | SQLITE_PRIVATE int sqlite3FixTriggerStep(DbFixer*, TriggerStep*); |
| | @@ -48986,17 +48987,17 @@ |
| 48986 | 48987 | ** page contain a special header (the "file header") that describes the file. |
| 48987 | 48988 | ** The format of the file header is as follows: |
| 48988 | 48989 | ** |
| 48989 | 48990 | ** OFFSET SIZE DESCRIPTION |
| 48990 | 48991 | ** 0 16 Header string: "SQLite format 3\000" |
| 48991 | | -** 16 2 Page size in bytes. |
| 48992 | +** 16 2 Page size in bytes. (1 means 65536) |
| 48992 | 48993 | ** 18 1 File format write version |
| 48993 | 48994 | ** 19 1 File format read version |
| 48994 | 48995 | ** 20 1 Bytes of unused space at the end of each page |
| 48995 | | -** 21 1 Max embedded payload fraction |
| 48996 | | -** 22 1 Min embedded payload fraction |
| 48997 | | -** 23 1 Min leaf payload fraction |
| 48996 | +** 21 1 Max embedded payload fraction (must be 64) |
| 48997 | +** 22 1 Min embedded payload fraction (must be 32) |
| 48998 | +** 23 1 Min leaf payload fraction (must be 32) |
| 48998 | 48999 | ** 24 4 File change counter |
| 48999 | 49000 | ** 28 4 Reserved for future use |
| 49000 | 49001 | ** 32 4 First freelist page |
| 49001 | 49002 | ** 36 4 Number of freelist pages in the file |
| 49002 | 49003 | ** 40 60 15 4-byte meta values passed to higher layers |
| | @@ -49006,13 +49007,14 @@ |
| 49006 | 49007 | ** 48 4 Size of page cache |
| 49007 | 49008 | ** 52 4 Largest root-page (auto/incr_vacuum) |
| 49008 | 49009 | ** 56 4 1=UTF-8 2=UTF16le 3=UTF16be |
| 49009 | 49010 | ** 60 4 User version |
| 49010 | 49011 | ** 64 4 Incremental vacuum mode |
| 49011 | | -** 68 4 unused |
| 49012 | | -** 72 4 unused |
| 49013 | | -** 76 4 unused |
| 49012 | +** 68 4 Application-ID |
| 49013 | +** 72 20 unused |
| 49014 | +** 92 4 The version-valid-for number |
| 49015 | +** 96 4 SQLITE_VERSION_NUMBER |
| 49014 | 49016 | ** |
| 49015 | 49017 | ** All of the integer values are big-endian (most significant byte first). |
| 49016 | 49018 | ** |
| 49017 | 49019 | ** The file change counter is incremented when the database is changed |
| 49018 | 49020 | ** This counter allows other processes to know when the file has changed |
| | @@ -52378,11 +52380,10 @@ |
| 52378 | 52380 | pBt->max1bytePayload = (u8)pBt->maxLocal; |
| 52379 | 52381 | } |
| 52380 | 52382 | assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) ); |
| 52381 | 52383 | pBt->pPage1 = pPage1; |
| 52382 | 52384 | pBt->nPage = nPage; |
| 52383 | | -assert( pPage1->leaf==0 || pPage1->leaf==1 ); |
| 52384 | 52385 | return SQLITE_OK; |
| 52385 | 52386 | |
| 52386 | 52387 | page1_init_failed: |
| 52387 | 52388 | releasePage(pPage1); |
| 52388 | 52389 | pBt->pPage1 = 0; |
| | @@ -52538,11 +52539,11 @@ |
| 52538 | 52539 | ** is requested, this is a no-op. |
| 52539 | 52540 | */ |
| 52540 | 52541 | if( p->inTrans==TRANS_WRITE || (p->inTrans==TRANS_READ && !wrflag) ){ |
| 52541 | 52542 | goto trans_begun; |
| 52542 | 52543 | } |
| 52543 | | - assert( IfNotOmitAV(pBt->bDoTruncate)==0 ); |
| 52544 | + assert( pBt->inTransaction==TRANS_WRITE || IfNotOmitAV(pBt->bDoTruncate)==0 ); |
| 52544 | 52545 | |
| 52545 | 52546 | /* Write transactions are not possible on a read-only database */ |
| 52546 | 52547 | if( (pBt->btsFlags & BTS_READ_ONLY)!=0 && wrflag ){ |
| 52547 | 52548 | rc = SQLITE_READONLY; |
| 52548 | 52549 | goto trans_begun; |
| | @@ -62977,10 +62978,11 @@ |
| 62977 | 62978 | } |
| 62978 | 62979 | fclose(out); |
| 62979 | 62980 | } |
| 62980 | 62981 | } |
| 62981 | 62982 | #endif |
| 62983 | + p->iCurrentTime = 0; |
| 62982 | 62984 | p->magic = VDBE_MAGIC_INIT; |
| 62983 | 62985 | return p->rc & db->errMask; |
| 62984 | 62986 | } |
| 62985 | 62987 | |
| 62986 | 62988 | /* |
| | @@ -83185,32 +83187,28 @@ |
| 83185 | 83187 | #endif /* SQLITE_OMIT_ATTACH */ |
| 83186 | 83188 | |
| 83187 | 83189 | /* |
| 83188 | 83190 | ** Initialize a DbFixer structure. This routine must be called prior |
| 83189 | 83191 | ** to passing the structure to one of the sqliteFixAAAA() routines below. |
| 83190 | | -** |
| 83191 | | -** The return value indicates whether or not fixation is required. TRUE |
| 83192 | | -** means we do need to fix the database references, FALSE means we do not. |
| 83193 | 83192 | */ |
| 83194 | | -SQLITE_PRIVATE int sqlite3FixInit( |
| 83193 | +SQLITE_PRIVATE void sqlite3FixInit( |
| 83195 | 83194 | DbFixer *pFix, /* The fixer to be initialized */ |
| 83196 | 83195 | Parse *pParse, /* Error messages will be written here */ |
| 83197 | 83196 | int iDb, /* This is the database that must be used */ |
| 83198 | 83197 | const char *zType, /* "view", "trigger", or "index" */ |
| 83199 | 83198 | const Token *pName /* Name of the view, trigger, or index */ |
| 83200 | 83199 | ){ |
| 83201 | 83200 | sqlite3 *db; |
| 83202 | 83201 | |
| 83203 | | - if( NEVER(iDb<0) || iDb==1 ) return 0; |
| 83204 | 83202 | db = pParse->db; |
| 83205 | 83203 | assert( db->nDb>iDb ); |
| 83206 | 83204 | pFix->pParse = pParse; |
| 83207 | 83205 | pFix->zDb = db->aDb[iDb].zName; |
| 83208 | 83206 | pFix->pSchema = db->aDb[iDb].pSchema; |
| 83209 | 83207 | pFix->zType = zType; |
| 83210 | 83208 | pFix->pName = pName; |
| 83211 | | - return 1; |
| 83209 | + pFix->bVarOnly = (iDb==1); |
| 83212 | 83210 | } |
| 83213 | 83211 | |
| 83214 | 83212 | /* |
| 83215 | 83213 | ** The following set of routines walk through the parse tree and assign |
| 83216 | 83214 | ** a specific database to all table references where the database name |
| | @@ -83234,19 +83232,21 @@ |
| 83234 | 83232 | struct SrcList_item *pItem; |
| 83235 | 83233 | |
| 83236 | 83234 | if( NEVER(pList==0) ) return 0; |
| 83237 | 83235 | zDb = pFix->zDb; |
| 83238 | 83236 | for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){ |
| 83239 | | - if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){ |
| 83240 | | - sqlite3ErrorMsg(pFix->pParse, |
| 83241 | | - "%s %T cannot reference objects in database %s", |
| 83242 | | - pFix->zType, pFix->pName, pItem->zDatabase); |
| 83243 | | - return 1; |
| 83244 | | - } |
| 83245 | | - sqlite3DbFree(pFix->pParse->db, pItem->zDatabase); |
| 83246 | | - pItem->zDatabase = 0; |
| 83247 | | - pItem->pSchema = pFix->pSchema; |
| 83237 | + if( pFix->bVarOnly==0 ){ |
| 83238 | + if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){ |
| 83239 | + sqlite3ErrorMsg(pFix->pParse, |
| 83240 | + "%s %T cannot reference objects in database %s", |
| 83241 | + pFix->zType, pFix->pName, pItem->zDatabase); |
| 83242 | + return 1; |
| 83243 | + } |
| 83244 | + sqlite3DbFree(pFix->pParse->db, pItem->zDatabase); |
| 83245 | + pItem->zDatabase = 0; |
| 83246 | + pItem->pSchema = pFix->pSchema; |
| 83247 | + } |
| 83248 | 83248 | #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) |
| 83249 | 83249 | if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1; |
| 83250 | 83250 | if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1; |
| 83251 | 83251 | #endif |
| 83252 | 83252 | } |
| | @@ -83264,13 +83264,25 @@ |
| 83264 | 83264 | if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){ |
| 83265 | 83265 | return 1; |
| 83266 | 83266 | } |
| 83267 | 83267 | if( sqlite3FixExpr(pFix, pSelect->pWhere) ){ |
| 83268 | 83268 | return 1; |
| 83269 | + } |
| 83270 | + if( sqlite3FixExprList(pFix, pSelect->pGroupBy) ){ |
| 83271 | + return 1; |
| 83269 | 83272 | } |
| 83270 | 83273 | if( sqlite3FixExpr(pFix, pSelect->pHaving) ){ |
| 83271 | 83274 | return 1; |
| 83275 | + } |
| 83276 | + if( sqlite3FixExprList(pFix, pSelect->pOrderBy) ){ |
| 83277 | + return 1; |
| 83278 | + } |
| 83279 | + if( sqlite3FixExpr(pFix, pSelect->pLimit) ){ |
| 83280 | + return 1; |
| 83281 | + } |
| 83282 | + if( sqlite3FixExpr(pFix, pSelect->pOffset) ){ |
| 83283 | + return 1; |
| 83272 | 83284 | } |
| 83273 | 83285 | pSelect = pSelect->pPrior; |
| 83274 | 83286 | } |
| 83275 | 83287 | return 0; |
| 83276 | 83288 | } |
| | @@ -83277,10 +83289,18 @@ |
| 83277 | 83289 | SQLITE_PRIVATE int sqlite3FixExpr( |
| 83278 | 83290 | DbFixer *pFix, /* Context of the fixation */ |
| 83279 | 83291 | Expr *pExpr /* The expression to be fixed to one database */ |
| 83280 | 83292 | ){ |
| 83281 | 83293 | while( pExpr ){ |
| 83294 | + if( pExpr->op==TK_VARIABLE ){ |
| 83295 | + if( pFix->pParse->db->init.busy ){ |
| 83296 | + pExpr->op = TK_NULL; |
| 83297 | + }else{ |
| 83298 | + sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType); |
| 83299 | + return 1; |
| 83300 | + } |
| 83301 | + } |
| 83282 | 83302 | if( ExprHasProperty(pExpr, EP_TokenOnly) ) break; |
| 83283 | 83303 | if( ExprHasProperty(pExpr, EP_xIsSelect) ){ |
| 83284 | 83304 | if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1; |
| 83285 | 83305 | }else{ |
| 83286 | 83306 | if( sqlite3FixExprList(pFix, pExpr->x.pList) ) return 1; |
| | @@ -85303,13 +85323,12 @@ |
| 85303 | 85323 | sqlite3SelectDelete(db, pSelect); |
| 85304 | 85324 | return; |
| 85305 | 85325 | } |
| 85306 | 85326 | sqlite3TwoPartName(pParse, pName1, pName2, &pName); |
| 85307 | 85327 | iDb = sqlite3SchemaToIndex(db, p->pSchema); |
| 85308 | | - if( sqlite3FixInit(&sFix, pParse, iDb, "view", pName) |
| 85309 | | - && sqlite3FixSelect(&sFix, pSelect) |
| 85310 | | - ){ |
| 85328 | + sqlite3FixInit(&sFix, pParse, iDb, "view", pName); |
| 85329 | + if( sqlite3FixSelect(&sFix, pSelect) ){ |
| 85311 | 85330 | sqlite3SelectDelete(db, pSelect); |
| 85312 | 85331 | return; |
| 85313 | 85332 | } |
| 85314 | 85333 | |
| 85315 | 85334 | /* Make a copy of the entire SELECT statement that defines the view. |
| | @@ -86105,13 +86124,12 @@ |
| 86105 | 86124 | iDb = 1; |
| 86106 | 86125 | } |
| 86107 | 86126 | } |
| 86108 | 86127 | #endif |
| 86109 | 86128 | |
| 86110 | | - if( sqlite3FixInit(&sFix, pParse, iDb, "index", pName) && |
| 86111 | | - sqlite3FixSrcList(&sFix, pTblName) |
| 86112 | | - ){ |
| 86129 | + sqlite3FixInit(&sFix, pParse, iDb, "index", pName); |
| 86130 | + if( sqlite3FixSrcList(&sFix, pTblName) ){ |
| 86113 | 86131 | /* Because the parser constructs pTblName from a single identifier, |
| 86114 | 86132 | ** sqlite3FixSrcList can never fail. */ |
| 86115 | 86133 | assert(0); |
| 86116 | 86134 | } |
| 86117 | 86135 | pTab = sqlite3LocateTableItem(pParse, 0, &pTblName->a[0]); |
| | @@ -88238,10 +88256,11 @@ |
| 88238 | 88256 | ** API function sqlite3_count_changes) to be set incorrectly. */ |
| 88239 | 88257 | if( rcauth==SQLITE_OK && pWhere==0 && !pTrigger && !IsVirtual(pTab) |
| 88240 | 88258 | && 0==sqlite3FkRequired(pParse, pTab, 0, 0) |
| 88241 | 88259 | ){ |
| 88242 | 88260 | assert( !isView ); |
| 88261 | + sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName); |
| 88243 | 88262 | sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt, |
| 88244 | 88263 | pTab->zName, P4_STATIC); |
| 88245 | 88264 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 88246 | 88265 | assert( pIdx->pSchema==pTab->pSchema ); |
| 88247 | 88266 | sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb); |
| | @@ -93487,10 +93506,11 @@ |
| 93487 | 93506 | (char*)pKey, P4_KEYINFO_HANDOFF); |
| 93488 | 93507 | VdbeComment((v, "%s", pSrcIdx->zName)); |
| 93489 | 93508 | pKey = sqlite3IndexKeyinfo(pParse, pDestIdx); |
| 93490 | 93509 | sqlite3VdbeAddOp4(v, OP_OpenWrite, iDest, pDestIdx->tnum, iDbDest, |
| 93491 | 93510 | (char*)pKey, P4_KEYINFO_HANDOFF); |
| 93511 | + sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR); |
| 93492 | 93512 | VdbeComment((v, "%s", pDestIdx->zName)); |
| 93493 | 93513 | addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); |
| 93494 | 93514 | sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, regData); |
| 93495 | 93515 | sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1); |
| 93496 | 93516 | sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); |
| | @@ -94974,181 +94994,363 @@ |
| 94974 | 94994 | #define PragTyp_HEXKEY 35 |
| 94975 | 94995 | #define PragTyp_KEY 36 |
| 94976 | 94996 | #define PragTyp_REKEY 37 |
| 94977 | 94997 | #define PragTyp_LOCK_STATUS 38 |
| 94978 | 94998 | #define PragTyp_PARSER_TRACE 39 |
| 94999 | +#define PragFlag_NeedSchema 0x01 |
| 94979 | 95000 | static const struct sPragmaNames { |
| 94980 | 95001 | const char *const zName; /* Name of pragma */ |
| 94981 | 95002 | u8 ePragTyp; /* PragTyp_XXX value */ |
| 95003 | + u8 mPragFlag; /* Zero or more PragFlag_XXX values */ |
| 94982 | 95004 | u32 iArg; /* Extra argument */ |
| 94983 | 95005 | } aPragmaNames[] = { |
| 94984 | 95006 | #if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD) |
| 94985 | | - { "activate_extensions", PragTyp_ACTIVATE_EXTENSIONS, 0 }, |
| 95007 | + { /* zName: */ "activate_extensions", |
| 95008 | + /* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS, |
| 95009 | + /* ePragFlag: */ 0, |
| 95010 | + /* iArg: */ 0 }, |
| 94986 | 95011 | #endif |
| 94987 | 95012 | #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) |
| 94988 | | - { "application_id", PragTyp_HEADER_VALUE, 0 }, |
| 95013 | + { /* zName: */ "application_id", |
| 95014 | + /* ePragTyp: */ PragTyp_HEADER_VALUE, |
| 95015 | + /* ePragFlag: */ 0, |
| 95016 | + /* iArg: */ 0 }, |
| 94989 | 95017 | #endif |
| 94990 | 95018 | #if !defined(SQLITE_OMIT_AUTOVACUUM) |
| 94991 | | - { "auto_vacuum", PragTyp_AUTO_VACUUM, 0 }, |
| 95019 | + { /* zName: */ "auto_vacuum", |
| 95020 | + /* ePragTyp: */ PragTyp_AUTO_VACUUM, |
| 95021 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95022 | + /* iArg: */ 0 }, |
| 94992 | 95023 | #endif |
| 94993 | 95024 | #if !defined(SQLITE_OMIT_AUTOMATIC_INDEX) |
| 94994 | | - { "automatic_index", PragTyp_FLAG, |
| 94995 | | - SQLITE_AutoIndex }, |
| 95025 | + { /* zName: */ "automatic_index", |
| 95026 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95027 | + /* ePragFlag: */ 0, |
| 95028 | + /* iArg: */ SQLITE_AutoIndex }, |
| 94996 | 95029 | #endif |
| 94997 | | - { "busy_timeout", PragTyp_BUSY_TIMEOUT, 0 }, |
| 95030 | + { /* zName: */ "busy_timeout", |
| 95031 | + /* ePragTyp: */ PragTyp_BUSY_TIMEOUT, |
| 95032 | + /* ePragFlag: */ 0, |
| 95033 | + /* iArg: */ 0 }, |
| 94998 | 95034 | #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 94999 | | - { "cache_size", PragTyp_CACHE_SIZE, 0 }, |
| 95035 | + { /* zName: */ "cache_size", |
| 95036 | + /* ePragTyp: */ PragTyp_CACHE_SIZE, |
| 95037 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95038 | + /* iArg: */ 0 }, |
| 95000 | 95039 | #endif |
| 95001 | | - { "cache_spill", PragTyp_FLAG, |
| 95002 | | - SQLITE_CacheSpill }, |
| 95003 | | - { "case_sensitive_like", PragTyp_CASE_SENSITIVE_LIKE, 0 }, |
| 95004 | | - { "checkpoint_fullfsync", PragTyp_FLAG, |
| 95005 | | - SQLITE_CkptFullFSync }, |
| 95040 | + { /* zName: */ "cache_spill", |
| 95041 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95042 | + /* ePragFlag: */ 0, |
| 95043 | + /* iArg: */ SQLITE_CacheSpill }, |
| 95044 | + { /* zName: */ "case_sensitive_like", |
| 95045 | + /* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE, |
| 95046 | + /* ePragFlag: */ 0, |
| 95047 | + /* iArg: */ 0 }, |
| 95048 | + { /* zName: */ "checkpoint_fullfsync", |
| 95049 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95050 | + /* ePragFlag: */ 0, |
| 95051 | + /* iArg: */ SQLITE_CkptFullFSync }, |
| 95006 | 95052 | #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) |
| 95007 | | - { "collation_list", PragTyp_COLLATION_LIST, 0 }, |
| 95053 | + { /* zName: */ "collation_list", |
| 95054 | + /* ePragTyp: */ PragTyp_COLLATION_LIST, |
| 95055 | + /* ePragFlag: */ 0, |
| 95056 | + /* iArg: */ 0 }, |
| 95008 | 95057 | #endif |
| 95009 | 95058 | #if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS) |
| 95010 | | - { "compile_options", PragTyp_COMPILE_OPTIONS, 0 }, |
| 95059 | + { /* zName: */ "compile_options", |
| 95060 | + /* ePragTyp: */ PragTyp_COMPILE_OPTIONS, |
| 95061 | + /* ePragFlag: */ 0, |
| 95062 | + /* iArg: */ 0 }, |
| 95011 | 95063 | #endif |
| 95012 | | - { "count_changes", PragTyp_FLAG, |
| 95013 | | - SQLITE_CountRows }, |
| 95064 | + { /* zName: */ "count_changes", |
| 95065 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95066 | + /* ePragFlag: */ 0, |
| 95067 | + /* iArg: */ SQLITE_CountRows }, |
| 95014 | 95068 | #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN |
| 95015 | | - { "data_store_directory", PragTyp_DATA_STORE_DIRECTORY, 0 }, |
| 95069 | + { /* zName: */ "data_store_directory", |
| 95070 | + /* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY, |
| 95071 | + /* ePragFlag: */ 0, |
| 95072 | + /* iArg: */ 0 }, |
| 95016 | 95073 | #endif |
| 95017 | 95074 | #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) |
| 95018 | | - { "database_list", PragTyp_DATABASE_LIST, 0 }, |
| 95075 | + { /* zName: */ "database_list", |
| 95076 | + /* ePragTyp: */ PragTyp_DATABASE_LIST, |
| 95077 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95078 | + /* iArg: */ 0 }, |
| 95019 | 95079 | #endif |
| 95020 | 95080 | #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) |
| 95021 | | - { "default_cache_size", PragTyp_DEFAULT_CACHE_SIZE, 0 }, |
| 95081 | + { /* zName: */ "default_cache_size", |
| 95082 | + /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE, |
| 95083 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95084 | + /* iArg: */ 0 }, |
| 95022 | 95085 | #endif |
| 95023 | 95086 | #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) |
| 95024 | | - { "defer_foreign_keys", PragTyp_FLAG, |
| 95025 | | - SQLITE_DeferFKs }, |
| 95087 | + { /* zName: */ "defer_foreign_keys", |
| 95088 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95089 | + /* ePragFlag: */ 0, |
| 95090 | + /* iArg: */ SQLITE_DeferFKs }, |
| 95026 | 95091 | #endif |
| 95027 | | - { "empty_result_callbacks", PragTyp_FLAG, |
| 95028 | | - SQLITE_NullCallback }, |
| 95092 | + { /* zName: */ "empty_result_callbacks", |
| 95093 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95094 | + /* ePragFlag: */ 0, |
| 95095 | + /* iArg: */ SQLITE_NullCallback }, |
| 95029 | 95096 | #if !defined(SQLITE_OMIT_UTF16) |
| 95030 | | - { "encoding", PragTyp_ENCODING, 0 }, |
| 95097 | + { /* zName: */ "encoding", |
| 95098 | + /* ePragTyp: */ PragTyp_ENCODING, |
| 95099 | + /* ePragFlag: */ 0, |
| 95100 | + /* iArg: */ 0 }, |
| 95031 | 95101 | #endif |
| 95032 | 95102 | #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) |
| 95033 | | - { "foreign_key_check", PragTyp_FOREIGN_KEY_CHECK, 0 }, |
| 95103 | + { /* zName: */ "foreign_key_check", |
| 95104 | + /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK, |
| 95105 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95106 | + /* iArg: */ 0 }, |
| 95034 | 95107 | #endif |
| 95035 | 95108 | #if !defined(SQLITE_OMIT_FOREIGN_KEY) |
| 95036 | | - { "foreign_key_list", PragTyp_FOREIGN_KEY_LIST, 0 }, |
| 95109 | + { /* zName: */ "foreign_key_list", |
| 95110 | + /* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST, |
| 95111 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95112 | + /* iArg: */ 0 }, |
| 95037 | 95113 | #endif |
| 95038 | 95114 | #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) |
| 95039 | | - { "foreign_keys", PragTyp_FLAG, |
| 95040 | | - SQLITE_ForeignKeys }, |
| 95115 | + { /* zName: */ "foreign_keys", |
| 95116 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95117 | + /* ePragFlag: */ 0, |
| 95118 | + /* iArg: */ SQLITE_ForeignKeys }, |
| 95041 | 95119 | #endif |
| 95042 | 95120 | #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) |
| 95043 | | - { "freelist_count", PragTyp_HEADER_VALUE, 0 }, |
| 95121 | + { /* zName: */ "freelist_count", |
| 95122 | + /* ePragTyp: */ PragTyp_HEADER_VALUE, |
| 95123 | + /* ePragFlag: */ 0, |
| 95124 | + /* iArg: */ 0 }, |
| 95044 | 95125 | #endif |
| 95045 | | - { "full_column_names", PragTyp_FLAG, |
| 95046 | | - SQLITE_FullColNames }, |
| 95047 | | - { "fullfsync", PragTyp_FLAG, |
| 95048 | | - SQLITE_FullFSync }, |
| 95126 | + { /* zName: */ "full_column_names", |
| 95127 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95128 | + /* ePragFlag: */ 0, |
| 95129 | + /* iArg: */ SQLITE_FullColNames }, |
| 95130 | + { /* zName: */ "fullfsync", |
| 95131 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95132 | + /* ePragFlag: */ 0, |
| 95133 | + /* iArg: */ SQLITE_FullFSync }, |
| 95049 | 95134 | #if defined(SQLITE_HAS_CODEC) |
| 95050 | | - { "hexkey", PragTyp_HEXKEY, 0 }, |
| 95135 | + { /* zName: */ "hexkey", |
| 95136 | + /* ePragTyp: */ PragTyp_HEXKEY, |
| 95137 | + /* ePragFlag: */ 0, |
| 95138 | + /* iArg: */ 0 }, |
| 95139 | + { /* zName: */ "hexrekey", |
| 95140 | + /* ePragTyp: */ PragTyp_HEXKEY, |
| 95141 | + /* ePragFlag: */ 0, |
| 95142 | + /* iArg: */ 0 }, |
| 95051 | 95143 | #endif |
| 95052 | 95144 | #if !defined(SQLITE_OMIT_CHECK) |
| 95053 | | - { "ignore_check_constraints", PragTyp_FLAG, |
| 95054 | | - SQLITE_IgnoreChecks }, |
| 95145 | + { /* zName: */ "ignore_check_constraints", |
| 95146 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95147 | + /* ePragFlag: */ 0, |
| 95148 | + /* iArg: */ SQLITE_IgnoreChecks }, |
| 95055 | 95149 | #endif |
| 95056 | 95150 | #if !defined(SQLITE_OMIT_AUTOVACUUM) |
| 95057 | | - { "incremental_vacuum", PragTyp_INCREMENTAL_VACUUM, 0 }, |
| 95151 | + { /* zName: */ "incremental_vacuum", |
| 95152 | + /* ePragTyp: */ PragTyp_INCREMENTAL_VACUUM, |
| 95153 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95154 | + /* iArg: */ 0 }, |
| 95058 | 95155 | #endif |
| 95059 | 95156 | #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) |
| 95060 | | - { "index_info", PragTyp_INDEX_INFO, 0 }, |
| 95061 | | - { "index_list", PragTyp_INDEX_LIST, 0 }, |
| 95157 | + { /* zName: */ "index_info", |
| 95158 | + /* ePragTyp: */ PragTyp_INDEX_INFO, |
| 95159 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95160 | + /* iArg: */ 0 }, |
| 95161 | + { /* zName: */ "index_list", |
| 95162 | + /* ePragTyp: */ PragTyp_INDEX_LIST, |
| 95163 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95164 | + /* iArg: */ 0 }, |
| 95062 | 95165 | #endif |
| 95063 | 95166 | #if !defined(SQLITE_OMIT_INTEGRITY_CHECK) |
| 95064 | | - { "integrity_check", PragTyp_INTEGRITY_CHECK, 0 }, |
| 95167 | + { /* zName: */ "integrity_check", |
| 95168 | + /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, |
| 95169 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95170 | + /* iArg: */ 0 }, |
| 95065 | 95171 | #endif |
| 95066 | 95172 | #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 95067 | | - { "journal_mode", PragTyp_JOURNAL_MODE, 0 }, |
| 95068 | | - { "journal_size_limit", PragTyp_JOURNAL_SIZE_LIMIT, 0 }, |
| 95173 | + { /* zName: */ "journal_mode", |
| 95174 | + /* ePragTyp: */ PragTyp_JOURNAL_MODE, |
| 95175 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95176 | + /* iArg: */ 0 }, |
| 95177 | + { /* zName: */ "journal_size_limit", |
| 95178 | + /* ePragTyp: */ PragTyp_JOURNAL_SIZE_LIMIT, |
| 95179 | + /* ePragFlag: */ 0, |
| 95180 | + /* iArg: */ 0 }, |
| 95069 | 95181 | #endif |
| 95070 | 95182 | #if defined(SQLITE_HAS_CODEC) |
| 95071 | | - { "key", PragTyp_KEY, 0 }, |
| 95183 | + { /* zName: */ "key", |
| 95184 | + /* ePragTyp: */ PragTyp_KEY, |
| 95185 | + /* ePragFlag: */ 0, |
| 95186 | + /* iArg: */ 0 }, |
| 95072 | 95187 | #endif |
| 95073 | | - { "legacy_file_format", PragTyp_FLAG, |
| 95074 | | - SQLITE_LegacyFileFmt }, |
| 95188 | + { /* zName: */ "legacy_file_format", |
| 95189 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95190 | + /* ePragFlag: */ 0, |
| 95191 | + /* iArg: */ SQLITE_LegacyFileFmt }, |
| 95075 | 95192 | #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE |
| 95076 | | - { "lock_proxy_file", PragTyp_LOCK_PROXY_FILE, 0 }, |
| 95193 | + { /* zName: */ "lock_proxy_file", |
| 95194 | + /* ePragTyp: */ PragTyp_LOCK_PROXY_FILE, |
| 95195 | + /* ePragFlag: */ 0, |
| 95196 | + /* iArg: */ 0 }, |
| 95077 | 95197 | #endif |
| 95078 | 95198 | #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) |
| 95079 | | - { "lock_status", PragTyp_LOCK_STATUS, 0 }, |
| 95080 | | -#endif |
| 95081 | | -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 95082 | | - { "locking_mode", PragTyp_LOCKING_MODE, 0 }, |
| 95083 | | - { "max_page_count", PragTyp_PAGE_COUNT, 0 }, |
| 95084 | | - { "mmap_size", PragTyp_MMAP_SIZE, 0 }, |
| 95085 | | - { "page_count", PragTyp_PAGE_COUNT, 0 }, |
| 95086 | | - { "page_size", PragTyp_PAGE_SIZE, 0 }, |
| 95087 | | -#endif |
| 95088 | | -#if defined(SQLITE_DEBUG) |
| 95089 | | - { "parser_trace", PragTyp_PARSER_TRACE, 0 }, |
| 95090 | | -#endif |
| 95091 | | - { "query_only", PragTyp_FLAG, |
| 95092 | | - SQLITE_QueryOnly }, |
| 95093 | | -#if !defined(SQLITE_OMIT_INTEGRITY_CHECK) |
| 95094 | | - { "quick_check", PragTyp_INTEGRITY_CHECK, 0 }, |
| 95095 | | -#endif |
| 95096 | | - { "read_uncommitted", PragTyp_FLAG, |
| 95097 | | - SQLITE_ReadUncommitted }, |
| 95098 | | - { "recursive_triggers", PragTyp_FLAG, |
| 95099 | | - SQLITE_RecTriggers }, |
| 95100 | | -#if defined(SQLITE_HAS_CODEC) |
| 95101 | | - { "rekey", PragTyp_REKEY, 0 }, |
| 95102 | | -#endif |
| 95103 | | - { "reverse_unordered_selects", PragTyp_FLAG, |
| 95104 | | - SQLITE_ReverseOrder }, |
| 95105 | | -#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) |
| 95106 | | - { "schema_version", PragTyp_HEADER_VALUE, 0 }, |
| 95107 | | -#endif |
| 95108 | | -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 95109 | | - { "secure_delete", PragTyp_SECURE_DELETE, 0 }, |
| 95110 | | -#endif |
| 95111 | | - { "short_column_names", PragTyp_FLAG, |
| 95112 | | - SQLITE_ShortColNames }, |
| 95113 | | - { "shrink_memory", PragTyp_SHRINK_MEMORY, 0 }, |
| 95114 | | - { "soft_heap_limit", PragTyp_SOFT_HEAP_LIMIT, 0 }, |
| 95115 | | -#if defined(SQLITE_DEBUG) |
| 95116 | | - { "sql_trace", PragTyp_FLAG, |
| 95117 | | - SQLITE_SqlTrace }, |
| 95118 | | -#endif |
| 95119 | | -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 95120 | | - { "synchronous", PragTyp_SYNCHRONOUS, 0 }, |
| 95199 | + { /* zName: */ "lock_status", |
| 95200 | + /* ePragTyp: */ PragTyp_LOCK_STATUS, |
| 95201 | + /* ePragFlag: */ 0, |
| 95202 | + /* iArg: */ 0 }, |
| 95203 | +#endif |
| 95204 | +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 95205 | + { /* zName: */ "locking_mode", |
| 95206 | + /* ePragTyp: */ PragTyp_LOCKING_MODE, |
| 95207 | + /* ePragFlag: */ 0, |
| 95208 | + /* iArg: */ 0 }, |
| 95209 | + { /* zName: */ "max_page_count", |
| 95210 | + /* ePragTyp: */ PragTyp_PAGE_COUNT, |
| 95211 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95212 | + /* iArg: */ 0 }, |
| 95213 | + { /* zName: */ "mmap_size", |
| 95214 | + /* ePragTyp: */ PragTyp_MMAP_SIZE, |
| 95215 | + /* ePragFlag: */ 0, |
| 95216 | + /* iArg: */ 0 }, |
| 95217 | + { /* zName: */ "page_count", |
| 95218 | + /* ePragTyp: */ PragTyp_PAGE_COUNT, |
| 95219 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95220 | + /* iArg: */ 0 }, |
| 95221 | + { /* zName: */ "page_size", |
| 95222 | + /* ePragTyp: */ PragTyp_PAGE_SIZE, |
| 95223 | + /* ePragFlag: */ 0, |
| 95224 | + /* iArg: */ 0 }, |
| 95225 | +#endif |
| 95226 | +#if defined(SQLITE_DEBUG) |
| 95227 | + { /* zName: */ "parser_trace", |
| 95228 | + /* ePragTyp: */ PragTyp_PARSER_TRACE, |
| 95229 | + /* ePragFlag: */ 0, |
| 95230 | + /* iArg: */ 0 }, |
| 95231 | +#endif |
| 95232 | + { /* zName: */ "query_only", |
| 95233 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95234 | + /* ePragFlag: */ 0, |
| 95235 | + /* iArg: */ SQLITE_QueryOnly }, |
| 95236 | +#if !defined(SQLITE_OMIT_INTEGRITY_CHECK) |
| 95237 | + { /* zName: */ "quick_check", |
| 95238 | + /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, |
| 95239 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95240 | + /* iArg: */ 0 }, |
| 95241 | +#endif |
| 95242 | + { /* zName: */ "read_uncommitted", |
| 95243 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95244 | + /* ePragFlag: */ 0, |
| 95245 | + /* iArg: */ SQLITE_ReadUncommitted }, |
| 95246 | + { /* zName: */ "recursive_triggers", |
| 95247 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95248 | + /* ePragFlag: */ 0, |
| 95249 | + /* iArg: */ SQLITE_RecTriggers }, |
| 95250 | +#if defined(SQLITE_HAS_CODEC) |
| 95251 | + { /* zName: */ "rekey", |
| 95252 | + /* ePragTyp: */ PragTyp_REKEY, |
| 95253 | + /* ePragFlag: */ 0, |
| 95254 | + /* iArg: */ 0 }, |
| 95255 | +#endif |
| 95256 | + { /* zName: */ "reverse_unordered_selects", |
| 95257 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95258 | + /* ePragFlag: */ 0, |
| 95259 | + /* iArg: */ SQLITE_ReverseOrder }, |
| 95260 | +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) |
| 95261 | + { /* zName: */ "schema_version", |
| 95262 | + /* ePragTyp: */ PragTyp_HEADER_VALUE, |
| 95263 | + /* ePragFlag: */ 0, |
| 95264 | + /* iArg: */ 0 }, |
| 95265 | +#endif |
| 95266 | +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 95267 | + { /* zName: */ "secure_delete", |
| 95268 | + /* ePragTyp: */ PragTyp_SECURE_DELETE, |
| 95269 | + /* ePragFlag: */ 0, |
| 95270 | + /* iArg: */ 0 }, |
| 95271 | +#endif |
| 95272 | + { /* zName: */ "short_column_names", |
| 95273 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95274 | + /* ePragFlag: */ 0, |
| 95275 | + /* iArg: */ SQLITE_ShortColNames }, |
| 95276 | + { /* zName: */ "shrink_memory", |
| 95277 | + /* ePragTyp: */ PragTyp_SHRINK_MEMORY, |
| 95278 | + /* ePragFlag: */ 0, |
| 95279 | + /* iArg: */ 0 }, |
| 95280 | + { /* zName: */ "soft_heap_limit", |
| 95281 | + /* ePragTyp: */ PragTyp_SOFT_HEAP_LIMIT, |
| 95282 | + /* ePragFlag: */ 0, |
| 95283 | + /* iArg: */ 0 }, |
| 95284 | +#if defined(SQLITE_DEBUG) |
| 95285 | + { /* zName: */ "sql_trace", |
| 95286 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95287 | + /* ePragFlag: */ 0, |
| 95288 | + /* iArg: */ SQLITE_SqlTrace }, |
| 95289 | +#endif |
| 95290 | +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 95291 | + { /* zName: */ "synchronous", |
| 95292 | + /* ePragTyp: */ PragTyp_SYNCHRONOUS, |
| 95293 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95294 | + /* iArg: */ 0 }, |
| 95121 | 95295 | #endif |
| 95122 | 95296 | #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) |
| 95123 | | - { "table_info", PragTyp_TABLE_INFO, 0 }, |
| 95297 | + { /* zName: */ "table_info", |
| 95298 | + /* ePragTyp: */ PragTyp_TABLE_INFO, |
| 95299 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95300 | + /* iArg: */ 0 }, |
| 95124 | 95301 | #endif |
| 95125 | 95302 | #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 95126 | | - { "temp_store", PragTyp_TEMP_STORE, 0 }, |
| 95127 | | - { "temp_store_directory", PragTyp_TEMP_STORE_DIRECTORY, 0 }, |
| 95303 | + { /* zName: */ "temp_store", |
| 95304 | + /* ePragTyp: */ PragTyp_TEMP_STORE, |
| 95305 | + /* ePragFlag: */ 0, |
| 95306 | + /* iArg: */ 0 }, |
| 95307 | + { /* zName: */ "temp_store_directory", |
| 95308 | + /* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY, |
| 95309 | + /* ePragFlag: */ 0, |
| 95310 | + /* iArg: */ 0 }, |
| 95128 | 95311 | #endif |
| 95129 | 95312 | #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) |
| 95130 | | - { "user_version", PragTyp_HEADER_VALUE, 0 }, |
| 95313 | + { /* zName: */ "user_version", |
| 95314 | + /* ePragTyp: */ PragTyp_HEADER_VALUE, |
| 95315 | + /* ePragFlag: */ 0, |
| 95316 | + /* iArg: */ 0 }, |
| 95131 | 95317 | #endif |
| 95132 | 95318 | #if defined(SQLITE_DEBUG) |
| 95133 | | - { "vdbe_addoptrace", PragTyp_FLAG, |
| 95134 | | - SQLITE_VdbeAddopTrace }, |
| 95135 | | - { "vdbe_debug", PragTyp_FLAG, |
| 95136 | | - SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace }, |
| 95137 | | - { "vdbe_listing", PragTyp_FLAG, |
| 95138 | | - SQLITE_VdbeListing }, |
| 95139 | | - { "vdbe_trace", PragTyp_FLAG, |
| 95140 | | - SQLITE_VdbeTrace }, |
| 95319 | + { /* zName: */ "vdbe_addoptrace", |
| 95320 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95321 | + /* ePragFlag: */ 0, |
| 95322 | + /* iArg: */ SQLITE_VdbeAddopTrace }, |
| 95323 | + { /* zName: */ "vdbe_debug", |
| 95324 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95325 | + /* ePragFlag: */ 0, |
| 95326 | + /* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace }, |
| 95327 | + { /* zName: */ "vdbe_listing", |
| 95328 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95329 | + /* ePragFlag: */ 0, |
| 95330 | + /* iArg: */ SQLITE_VdbeListing }, |
| 95331 | + { /* zName: */ "vdbe_trace", |
| 95332 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95333 | + /* ePragFlag: */ 0, |
| 95334 | + /* iArg: */ SQLITE_VdbeTrace }, |
| 95141 | 95335 | #endif |
| 95142 | 95336 | #if !defined(SQLITE_OMIT_WAL) |
| 95143 | | - { "wal_autocheckpoint", PragTyp_WAL_AUTOCHECKPOINT, 0 }, |
| 95144 | | - { "wal_checkpoint", PragTyp_WAL_CHECKPOINT, 0 }, |
| 95337 | + { /* zName: */ "wal_autocheckpoint", |
| 95338 | + /* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT, |
| 95339 | + /* ePragFlag: */ 0, |
| 95340 | + /* iArg: */ 0 }, |
| 95341 | + { /* zName: */ "wal_checkpoint", |
| 95342 | + /* ePragTyp: */ PragTyp_WAL_CHECKPOINT, |
| 95343 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95344 | + /* iArg: */ 0 }, |
| 95145 | 95345 | #endif |
| 95146 | | - { "writable_schema", PragTyp_FLAG, |
| 95147 | | - SQLITE_WriteSchema|SQLITE_RecoveryMode }, |
| 95346 | + { /* zName: */ "writable_schema", |
| 95347 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95348 | + /* ePragFlag: */ 0, |
| 95349 | + /* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode }, |
| 95148 | 95350 | }; |
| 95149 | | -/* Number of pragmas: 55 on by default, 66 total. */ |
| 95351 | +/* Number of pragmas: 55 on by default, 67 total. */ |
| 95150 | 95352 | /* End of the automatically generated pragma table. |
| 95151 | 95353 | ***************************************************************************/ |
| 95152 | 95354 | |
| 95153 | 95355 | /* |
| 95154 | 95356 | ** Interpret the given string as a safety level. Return 0 for OFF, |
| | @@ -95476,10 +95678,15 @@ |
| 95476 | 95678 | }else{ |
| 95477 | 95679 | lwr = mid + 1; |
| 95478 | 95680 | } |
| 95479 | 95681 | } |
| 95480 | 95682 | if( lwr>upr ) goto pragma_out; |
| 95683 | + |
| 95684 | + /* Make sure the database schema is loaded if the pragma requires that */ |
| 95685 | + if( (aPragmaNames[mid].mPragFlag & PragFlag_NeedSchema)!=0 ){ |
| 95686 | + if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 95687 | + } |
| 95481 | 95688 | |
| 95482 | 95689 | /* Jump to the appropriate pragma handler */ |
| 95483 | 95690 | switch( aPragmaNames[mid].ePragTyp ){ |
| 95484 | 95691 | |
| 95485 | 95692 | #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) |
| | @@ -95510,11 +95717,10 @@ |
| 95510 | 95717 | { OP_Integer, 0, 1, 0}, /* 6 */ |
| 95511 | 95718 | { OP_Noop, 0, 0, 0}, |
| 95512 | 95719 | { OP_ResultRow, 1, 1, 0}, |
| 95513 | 95720 | }; |
| 95514 | 95721 | int addr; |
| 95515 | | - if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 95516 | 95722 | sqlite3VdbeUsesBtree(v, iDb); |
| 95517 | 95723 | if( !zRight ){ |
| 95518 | 95724 | sqlite3VdbeSetNumCols(v, 1); |
| 95519 | 95725 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", SQLITE_STATIC); |
| 95520 | 95726 | pParse->nMem += 2; |
| | @@ -95606,11 +95812,10 @@ |
| 95606 | 95812 | ** |
| 95607 | 95813 | ** Return the number of pages in the specified database. |
| 95608 | 95814 | */ |
| 95609 | 95815 | case PragTyp_PAGE_COUNT: { |
| 95610 | 95816 | int iReg; |
| 95611 | | - if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 95612 | 95817 | sqlite3CodeVerifySchema(pParse, iDb); |
| 95613 | 95818 | iReg = ++pParse->nMem; |
| 95614 | 95819 | if( sqlite3Tolower(zLeft[0])=='p' ){ |
| 95615 | 95820 | sqlite3VdbeAddOp2(v, OP_Pagecount, iDb, iReg); |
| 95616 | 95821 | }else{ |
| | @@ -95679,18 +95884,10 @@ |
| 95679 | 95884 | */ |
| 95680 | 95885 | case PragTyp_JOURNAL_MODE: { |
| 95681 | 95886 | int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */ |
| 95682 | 95887 | int ii; /* Loop counter */ |
| 95683 | 95888 | |
| 95684 | | - /* Force the schema to be loaded on all databases. This causes all |
| 95685 | | - ** database files to be opened and the journal_modes set. This is |
| 95686 | | - ** necessary because subsequent processing must know if the databases |
| 95687 | | - ** are in WAL mode. */ |
| 95688 | | - if( sqlite3ReadSchema(pParse) ){ |
| 95689 | | - goto pragma_out; |
| 95690 | | - } |
| 95691 | | - |
| 95692 | 95889 | sqlite3VdbeSetNumCols(v, 1); |
| 95693 | 95890 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "journal_mode", SQLITE_STATIC); |
| 95694 | 95891 | |
| 95695 | 95892 | if( zRight==0 ){ |
| 95696 | 95893 | /* If there is no "=MODE" part of the pragma, do a query for the |
| | @@ -95752,55 +95949,44 @@ |
| 95752 | 95949 | */ |
| 95753 | 95950 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| 95754 | 95951 | case PragTyp_AUTO_VACUUM: { |
| 95755 | 95952 | Btree *pBt = pDb->pBt; |
| 95756 | 95953 | assert( pBt!=0 ); |
| 95757 | | - if( sqlite3ReadSchema(pParse) ){ |
| 95758 | | - goto pragma_out; |
| 95759 | | - } |
| 95760 | 95954 | if( !zRight ){ |
| 95761 | | - int auto_vacuum; |
| 95762 | | - if( ALWAYS(pBt) ){ |
| 95763 | | - auto_vacuum = sqlite3BtreeGetAutoVacuum(pBt); |
| 95764 | | - }else{ |
| 95765 | | - auto_vacuum = SQLITE_DEFAULT_AUTOVACUUM; |
| 95766 | | - } |
| 95767 | | - returnSingleInt(pParse, "auto_vacuum", auto_vacuum); |
| 95955 | + returnSingleInt(pParse, "auto_vacuum", sqlite3BtreeGetAutoVacuum(pBt)); |
| 95768 | 95956 | }else{ |
| 95769 | 95957 | int eAuto = getAutoVacuum(zRight); |
| 95770 | 95958 | assert( eAuto>=0 && eAuto<=2 ); |
| 95771 | 95959 | db->nextAutovac = (u8)eAuto; |
| 95772 | | - if( ALWAYS(eAuto>=0) ){ |
| 95773 | | - /* Call SetAutoVacuum() to set initialize the internal auto and |
| 95774 | | - ** incr-vacuum flags. This is required in case this connection |
| 95775 | | - ** creates the database file. It is important that it is created |
| 95776 | | - ** as an auto-vacuum capable db. |
| 95777 | | - */ |
| 95778 | | - rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto); |
| 95779 | | - if( rc==SQLITE_OK && (eAuto==1 || eAuto==2) ){ |
| 95780 | | - /* When setting the auto_vacuum mode to either "full" or |
| 95781 | | - ** "incremental", write the value of meta[6] in the database |
| 95782 | | - ** file. Before writing to meta[6], check that meta[3] indicates |
| 95783 | | - ** that this really is an auto-vacuum capable database. |
| 95784 | | - */ |
| 95785 | | - static const VdbeOpList setMeta6[] = { |
| 95786 | | - { OP_Transaction, 0, 1, 0}, /* 0 */ |
| 95787 | | - { OP_ReadCookie, 0, 1, BTREE_LARGEST_ROOT_PAGE}, |
| 95788 | | - { OP_If, 1, 0, 0}, /* 2 */ |
| 95789 | | - { OP_Halt, SQLITE_OK, OE_Abort, 0}, /* 3 */ |
| 95790 | | - { OP_Integer, 0, 1, 0}, /* 4 */ |
| 95791 | | - { OP_SetCookie, 0, BTREE_INCR_VACUUM, 1}, /* 5 */ |
| 95792 | | - }; |
| 95793 | | - int iAddr; |
| 95794 | | - iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6); |
| 95795 | | - sqlite3VdbeChangeP1(v, iAddr, iDb); |
| 95796 | | - sqlite3VdbeChangeP1(v, iAddr+1, iDb); |
| 95797 | | - sqlite3VdbeChangeP2(v, iAddr+2, iAddr+4); |
| 95798 | | - sqlite3VdbeChangeP1(v, iAddr+4, eAuto-1); |
| 95799 | | - sqlite3VdbeChangeP1(v, iAddr+5, iDb); |
| 95800 | | - sqlite3VdbeUsesBtree(v, iDb); |
| 95801 | | - } |
| 95960 | + /* Call SetAutoVacuum() to set initialize the internal auto and |
| 95961 | + ** incr-vacuum flags. This is required in case this connection |
| 95962 | + ** creates the database file. It is important that it is created |
| 95963 | + ** as an auto-vacuum capable db. |
| 95964 | + */ |
| 95965 | + rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto); |
| 95966 | + if( rc==SQLITE_OK && (eAuto==1 || eAuto==2) ){ |
| 95967 | + /* When setting the auto_vacuum mode to either "full" or |
| 95968 | + ** "incremental", write the value of meta[6] in the database |
| 95969 | + ** file. Before writing to meta[6], check that meta[3] indicates |
| 95970 | + ** that this really is an auto-vacuum capable database. |
| 95971 | + */ |
| 95972 | + static const VdbeOpList setMeta6[] = { |
| 95973 | + { OP_Transaction, 0, 1, 0}, /* 0 */ |
| 95974 | + { OP_ReadCookie, 0, 1, BTREE_LARGEST_ROOT_PAGE}, |
| 95975 | + { OP_If, 1, 0, 0}, /* 2 */ |
| 95976 | + { OP_Halt, SQLITE_OK, OE_Abort, 0}, /* 3 */ |
| 95977 | + { OP_Integer, 0, 1, 0}, /* 4 */ |
| 95978 | + { OP_SetCookie, 0, BTREE_INCR_VACUUM, 1}, /* 5 */ |
| 95979 | + }; |
| 95980 | + int iAddr; |
| 95981 | + iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6); |
| 95982 | + sqlite3VdbeChangeP1(v, iAddr, iDb); |
| 95983 | + sqlite3VdbeChangeP1(v, iAddr+1, iDb); |
| 95984 | + sqlite3VdbeChangeP2(v, iAddr+2, iAddr+4); |
| 95985 | + sqlite3VdbeChangeP1(v, iAddr+4, eAuto-1); |
| 95986 | + sqlite3VdbeChangeP1(v, iAddr+5, iDb); |
| 95987 | + sqlite3VdbeUsesBtree(v, iDb); |
| 95802 | 95988 | } |
| 95803 | 95989 | } |
| 95804 | 95990 | break; |
| 95805 | 95991 | } |
| 95806 | 95992 | #endif |
| | @@ -95811,13 +95997,10 @@ |
| 95811 | 95997 | ** Do N steps of incremental vacuuming on a database. |
| 95812 | 95998 | */ |
| 95813 | 95999 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| 95814 | 96000 | case PragTyp_INCREMENTAL_VACUUM: { |
| 95815 | 96001 | int iLimit, addr; |
| 95816 | | - if( sqlite3ReadSchema(pParse) ){ |
| 95817 | | - goto pragma_out; |
| 95818 | | - } |
| 95819 | 96002 | if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){ |
| 95820 | 96003 | iLimit = 0x7fffffff; |
| 95821 | 96004 | } |
| 95822 | 96005 | sqlite3BeginWriteOperation(pParse, 0, iDb); |
| 95823 | 96006 | sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1); |
| | @@ -95841,11 +96024,10 @@ |
| 95841 | 96024 | ** number of pages in the cache. If N is negative, then the |
| 95842 | 96025 | ** number of pages is adjusted so that the cache uses -N kibibytes |
| 95843 | 96026 | ** of memory. |
| 95844 | 96027 | */ |
| 95845 | 96028 | case PragTyp_CACHE_SIZE: { |
| 95846 | | - if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 95847 | 96029 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 95848 | 96030 | if( !zRight ){ |
| 95849 | 96031 | returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size); |
| 95850 | 96032 | }else{ |
| 95851 | 96033 | int size = sqlite3Atoi(zRight); |
| | @@ -96062,11 +96244,10 @@ |
| 96062 | 96244 | ** the local value does not make changes to the disk file and the |
| 96063 | 96245 | ** default value will be restored the next time the database is |
| 96064 | 96246 | ** opened. |
| 96065 | 96247 | */ |
| 96066 | 96248 | case PragTyp_SYNCHRONOUS: { |
| 96067 | | - if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 96068 | 96249 | if( !zRight ){ |
| 96069 | 96250 | returnSingleInt(pParse, "synchronous", pDb->safety_level-1); |
| 96070 | 96251 | }else{ |
| 96071 | 96252 | if( !db->autoCommit ){ |
| 96072 | 96253 | sqlite3ErrorMsg(pParse, |
| | @@ -96124,11 +96305,10 @@ |
| 96124 | 96305 | ** notnull: True if 'NOT NULL' is part of column declaration |
| 96125 | 96306 | ** dflt_value: The default value for the column, if any. |
| 96126 | 96307 | */ |
| 96127 | 96308 | case PragTyp_TABLE_INFO: if( zRight ){ |
| 96128 | 96309 | Table *pTab; |
| 96129 | | - if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 96130 | 96310 | pTab = sqlite3FindTable(db, zRight, zDb); |
| 96131 | 96311 | if( pTab ){ |
| 96132 | 96312 | int i, k; |
| 96133 | 96313 | int nHidden = 0; |
| 96134 | 96314 | Column *pCol; |
| | @@ -96174,11 +96354,10 @@ |
| 96174 | 96354 | break; |
| 96175 | 96355 | |
| 96176 | 96356 | case PragTyp_INDEX_INFO: if( zRight ){ |
| 96177 | 96357 | Index *pIdx; |
| 96178 | 96358 | Table *pTab; |
| 96179 | | - if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 96180 | 96359 | pIdx = sqlite3FindIndex(db, zRight, zDb); |
| 96181 | 96360 | if( pIdx ){ |
| 96182 | 96361 | int i; |
| 96183 | 96362 | pTab = pIdx->pTable; |
| 96184 | 96363 | sqlite3VdbeSetNumCols(v, 3); |
| | @@ -96200,11 +96379,10 @@ |
| 96200 | 96379 | break; |
| 96201 | 96380 | |
| 96202 | 96381 | case PragTyp_INDEX_LIST: if( zRight ){ |
| 96203 | 96382 | Index *pIdx; |
| 96204 | 96383 | Table *pTab; |
| 96205 | | - if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 96206 | 96384 | pTab = sqlite3FindTable(db, zRight, zDb); |
| 96207 | 96385 | if( pTab ){ |
| 96208 | 96386 | v = sqlite3GetVdbe(pParse); |
| 96209 | 96387 | pIdx = pTab->pIndex; |
| 96210 | 96388 | if( pIdx ){ |
| | @@ -96228,11 +96406,10 @@ |
| 96228 | 96406 | } |
| 96229 | 96407 | break; |
| 96230 | 96408 | |
| 96231 | 96409 | case PragTyp_DATABASE_LIST: { |
| 96232 | 96410 | int i; |
| 96233 | | - if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 96234 | 96411 | sqlite3VdbeSetNumCols(v, 3); |
| 96235 | 96412 | pParse->nMem = 3; |
| 96236 | 96413 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC); |
| 96237 | 96414 | sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC); |
| 96238 | 96415 | sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "file", SQLITE_STATIC); |
| | @@ -96267,11 +96444,10 @@ |
| 96267 | 96444 | |
| 96268 | 96445 | #ifndef SQLITE_OMIT_FOREIGN_KEY |
| 96269 | 96446 | case PragTyp_FOREIGN_KEY_LIST: if( zRight ){ |
| 96270 | 96447 | FKey *pFK; |
| 96271 | 96448 | Table *pTab; |
| 96272 | | - if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 96273 | 96449 | pTab = sqlite3FindTable(db, zRight, zDb); |
| 96274 | 96450 | if( pTab ){ |
| 96275 | 96451 | v = sqlite3GetVdbe(pParse); |
| 96276 | 96452 | pFK = pTab->pFKey; |
| 96277 | 96453 | if( pFK ){ |
| | @@ -96329,11 +96505,10 @@ |
| 96329 | 96505 | int regRow; /* Registers to hold a row from pTab */ |
| 96330 | 96506 | int addrTop; /* Top of a loop checking foreign keys */ |
| 96331 | 96507 | int addrOk; /* Jump here if the key is OK */ |
| 96332 | 96508 | int *aiCols; /* child to parent column mapping */ |
| 96333 | 96509 | |
| 96334 | | - if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 96335 | 96510 | regResult = pParse->nMem+1; |
| 96336 | 96511 | pParse->nMem += 4; |
| 96337 | 96512 | regKey = ++pParse->nMem; |
| 96338 | 96513 | regRow = ++pParse->nMem; |
| 96339 | 96514 | v = sqlite3GetVdbe(pParse); |
| | @@ -96490,11 +96665,10 @@ |
| 96490 | 96665 | assert( iDb>=0 ); |
| 96491 | 96666 | assert( iDb==0 || pId2->z ); |
| 96492 | 96667 | if( pId2->z==0 ) iDb = -1; |
| 96493 | 96668 | |
| 96494 | 96669 | /* Initialize the VDBE program */ |
| 96495 | | - if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 96496 | 96670 | pParse->nMem = 6; |
| 96497 | 96671 | sqlite3VdbeSetNumCols(v, 1); |
| 96498 | 96672 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "integrity_check", SQLITE_STATIC); |
| 96499 | 96673 | |
| 96500 | 96674 | /* Set the maximum error count */ |
| | @@ -96814,11 +96988,10 @@ |
| 96814 | 96988 | eMode = SQLITE_CHECKPOINT_FULL; |
| 96815 | 96989 | }else if( sqlite3StrICmp(zRight, "restart")==0 ){ |
| 96816 | 96990 | eMode = SQLITE_CHECKPOINT_RESTART; |
| 96817 | 96991 | } |
| 96818 | 96992 | } |
| 96819 | | - if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 96820 | 96993 | sqlite3VdbeSetNumCols(v, 3); |
| 96821 | 96994 | pParse->nMem = 3; |
| 96822 | 96995 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "busy", SQLITE_STATIC); |
| 96823 | 96996 | sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "log", SQLITE_STATIC); |
| 96824 | 96997 | sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "checkpointed", SQLITE_STATIC); |
| | @@ -96934,16 +97107,16 @@ |
| 96934 | 97107 | if( zRight ) sqlite3_rekey_v2(db, zDb, zRight, sqlite3Strlen30(zRight)); |
| 96935 | 97108 | break; |
| 96936 | 97109 | } |
| 96937 | 97110 | case PragTyp_HEXKEY: { |
| 96938 | 97111 | if( zRight ){ |
| 96939 | | - int i, h1, h2; |
| 97112 | + u8 iByte; |
| 97113 | + int i; |
| 96940 | 97114 | char zKey[40]; |
| 96941 | | - for(i=0; (h1 = zRight[i])!=0 && (h2 = zRight[i+1])!=0; i+=2){ |
| 96942 | | - h1 += 9*(1&(h1>>6)); |
| 96943 | | - h2 += 9*(1&(h2>>6)); |
| 96944 | | - zKey[i/2] = (h2 & 0x0f) | ((h1 & 0xf)<<4); |
| 97115 | + for(i=0, iByte=0; i<sizeof(zKey)*2 && sqlite3Isxdigit(zRight[i]); i++){ |
| 97116 | + iByte = (iByte<<4) + sqlite3HexToInt(zRight[i]); |
| 97117 | + if( (i&1)!=0 ) zKey[i/2] = iByte; |
| 96945 | 97118 | } |
| 96946 | 97119 | if( (zLeft[3] & 0xf)==0xb ){ |
| 96947 | 97120 | sqlite3_key_v2(db, zDb, zKey, i/2); |
| 96948 | 97121 | }else{ |
| 96949 | 97122 | sqlite3_rekey_v2(db, zDb, zKey, i/2); |
| | @@ -102459,16 +102632,21 @@ |
| 102459 | 102632 | ** In this case set iRoot to the root page number of the index b-tree |
| 102460 | 102633 | ** and pKeyInfo to the KeyInfo structure required to navigate the |
| 102461 | 102634 | ** index. |
| 102462 | 102635 | ** |
| 102463 | 102636 | ** (2011-04-15) Do not do a full scan of an unordered index. |
| 102637 | + ** |
| 102638 | + ** (2013-10-03) Do not count the entires in a partial index. |
| 102464 | 102639 | ** |
| 102465 | 102640 | ** In practice the KeyInfo structure will not be used. It is only |
| 102466 | 102641 | ** passed to keep OP_OpenRead happy. |
| 102467 | 102642 | */ |
| 102468 | 102643 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 102469 | | - if( pIdx->bUnordered==0 && (!pBest || pIdx->nColumn<pBest->nColumn) ){ |
| 102644 | + if( pIdx->bUnordered==0 |
| 102645 | + && pIdx->pPartIdxWhere==0 |
| 102646 | + && (!pBest || pIdx->nColumn<pBest->nColumn) |
| 102647 | + ){ |
| 102470 | 102648 | pBest = pIdx; |
| 102471 | 102649 | } |
| 102472 | 102650 | } |
| 102473 | 102651 | if( pBest && pBest->nColumn<pTab->nCol ){ |
| 102474 | 102652 | iRoot = pBest->tnum; |
| | @@ -103046,12 +103224,12 @@ |
| 103046 | 103224 | } |
| 103047 | 103225 | |
| 103048 | 103226 | /* Ensure the table name matches database name and that the table exists */ |
| 103049 | 103227 | if( db->mallocFailed ) goto trigger_cleanup; |
| 103050 | 103228 | assert( pTableName->nSrc==1 ); |
| 103051 | | - if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName) && |
| 103052 | | - sqlite3FixSrcList(&sFix, pTableName) ){ |
| 103229 | + sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName); |
| 103230 | + if( sqlite3FixSrcList(&sFix, pTableName) ){ |
| 103053 | 103231 | goto trigger_cleanup; |
| 103054 | 103232 | } |
| 103055 | 103233 | pTab = sqlite3SrcListLookup(pParse, pTableName); |
| 103056 | 103234 | if( !pTab ){ |
| 103057 | 103235 | /* The table does not exist. */ |
| | @@ -103189,12 +103367,14 @@ |
| 103189 | 103367 | pStepList->pTrig = pTrig; |
| 103190 | 103368 | pStepList = pStepList->pNext; |
| 103191 | 103369 | } |
| 103192 | 103370 | nameToken.z = pTrig->zName; |
| 103193 | 103371 | nameToken.n = sqlite3Strlen30(nameToken.z); |
| 103194 | | - if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken) |
| 103195 | | - && sqlite3FixTriggerStep(&sFix, pTrig->step_list) ){ |
| 103372 | + sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken); |
| 103373 | + if( sqlite3FixTriggerStep(&sFix, pTrig->step_list) |
| 103374 | + || sqlite3FixExpr(&sFix, pTrig->pWhen) |
| 103375 | + ){ |
| 103196 | 103376 | goto triggerfinish_cleanup; |
| 103197 | 103377 | } |
| 103198 | 103378 | |
| 103199 | 103379 | /* if we are not initializing, |
| 103200 | 103380 | ** build the sqlite_master entry |
| | @@ -104781,18 +104961,38 @@ |
| 104781 | 104961 | |
| 104782 | 104962 | return vacuumFinalize(db, pStmt, pzErrMsg); |
| 104783 | 104963 | } |
| 104784 | 104964 | |
| 104785 | 104965 | /* |
| 104786 | | -** The non-standard VACUUM command is used to clean up the database, |
| 104966 | +** The VACUUM command is used to clean up the database, |
| 104787 | 104967 | ** collapse free space, etc. It is modelled after the VACUUM command |
| 104788 | | -** in PostgreSQL. |
| 104968 | +** in PostgreSQL. The VACUUM command works as follows: |
| 104789 | 104969 | ** |
| 104790 | | -** In version 1.0.x of SQLite, the VACUUM command would call |
| 104791 | | -** gdbm_reorganize() on all the database tables. But beginning |
| 104792 | | -** with 2.0.0, SQLite no longer uses GDBM so this command has |
| 104793 | | -** become a no-op. |
| 104970 | +** (1) Create a new transient database file |
| 104971 | +** (2) Copy all content from the database being vacuumed into |
| 104972 | +** the new transient database file |
| 104973 | +** (3) Copy content from the transient database back into the |
| 104974 | +** original database. |
| 104975 | +** |
| 104976 | +** The transient database requires temporary disk space approximately |
| 104977 | +** equal to the size of the original database. The copy operation of |
| 104978 | +** step (3) requires additional temporary disk space approximately equal |
| 104979 | +** to the size of the original database for the rollback journal. |
| 104980 | +** Hence, temporary disk space that is approximately 2x the size of the |
| 104981 | +** orginal database is required. Every page of the database is written |
| 104982 | +** approximately 3 times: Once for step (2) and twice for step (3). |
| 104983 | +** Two writes per page are required in step (3) because the original |
| 104984 | +** database content must be written into the rollback journal prior to |
| 104985 | +** overwriting the database with the vacuumed content. |
| 104986 | +** |
| 104987 | +** Only 1x temporary space and only 1x writes would be required if |
| 104988 | +** the copy of step (3) were replace by deleting the original database |
| 104989 | +** and renaming the transient database as the original. But that will |
| 104990 | +** not work if other processes are attached to the original database. |
| 104991 | +** And a power loss in between deleting the original and renaming the |
| 104992 | +** transient would cause the database file to appear to be deleted |
| 104993 | +** following reboot. |
| 104794 | 104994 | */ |
| 104795 | 104995 | SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse){ |
| 104796 | 104996 | Vdbe *v = sqlite3GetVdbe(pParse); |
| 104797 | 104997 | if( v ){ |
| 104798 | 104998 | sqlite3VdbeAddOp2(v, OP_Vacuum, 0, 0); |
| | @@ -112165,11 +112365,11 @@ |
| 112165 | 112365 | WHERETRACE(0xffff,("*** Optimizer Finished ***\n")); |
| 112166 | 112366 | pWInfo->pParse->nQueryLoop += pWInfo->nRowOut; |
| 112167 | 112367 | |
| 112168 | 112368 | /* If the caller is an UPDATE or DELETE statement that is requesting |
| 112169 | 112369 | ** to use a one-pass algorithm, determine if this is appropriate. |
| 112170 | | - ** The one-pass algorithm only works if the WHERE clause constraints |
| 112370 | + ** The one-pass algorithm only works if the WHERE clause constrains |
| 112171 | 112371 | ** the statement to update a single row. |
| 112172 | 112372 | */ |
| 112173 | 112373 | assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 ); |
| 112174 | 112374 | if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 |
| 112175 | 112375 | && (pWInfo->a[0].pWLoop->wsFlags & WHERE_ONEROW)!=0 ){ |
| | @@ -121583,10 +121783,16 @@ |
| 121583 | 121783 | ** verifying the operation of the SQLite core. |
| 121584 | 121784 | */ |
| 121585 | 121785 | int inTransaction; /* True after xBegin but before xCommit/xRollback */ |
| 121586 | 121786 | int mxSavepoint; /* Largest valid xSavepoint integer */ |
| 121587 | 121787 | #endif |
| 121788 | + |
| 121789 | +#ifdef SQLITE_TEST |
| 121790 | + /* True to disable the incremental doclist optimization. This is controled |
| 121791 | + ** by special insert command 'test-no-incr-doclist'. */ |
| 121792 | + int bNoIncrDoclist; |
| 121793 | +#endif |
| 121588 | 121794 | }; |
| 121589 | 121795 | |
| 121590 | 121796 | /* |
| 121591 | 121797 | ** When the core wants to read from the virtual table, it creates a |
| 121592 | 121798 | ** virtual table cursor (an instance of the following structure) using |
| | @@ -121608,11 +121814,12 @@ |
| 121608 | 121814 | int nDoclist; /* Size of buffer at aDoclist */ |
| 121609 | 121815 | u8 bDesc; /* True to sort in descending order */ |
| 121610 | 121816 | int eEvalmode; /* An FTS3_EVAL_XX constant */ |
| 121611 | 121817 | int nRowAvg; /* Average size of database rows, in pages */ |
| 121612 | 121818 | sqlite3_int64 nDoc; /* Documents in table */ |
| 121613 | | - |
| 121819 | + i64 iMinDocid; /* Minimum docid to return */ |
| 121820 | + i64 iMaxDocid; /* Maximum docid to return */ |
| 121614 | 121821 | int isMatchinfoNeeded; /* True when aMatchinfo[] needs filling in */ |
| 121615 | 121822 | u32 *aMatchinfo; /* Information about most recent match */ |
| 121616 | 121823 | int nMatchinfo; /* Number of elements in aMatchinfo[] */ |
| 121617 | 121824 | char *zMatchinfo; /* Matchinfo specification */ |
| 121618 | 121825 | }; |
| | @@ -121638,10 +121845,19 @@ |
| 121638 | 121845 | */ |
| 121639 | 121846 | #define FTS3_FULLSCAN_SEARCH 0 /* Linear scan of %_content table */ |
| 121640 | 121847 | #define FTS3_DOCID_SEARCH 1 /* Lookup by rowid on %_content table */ |
| 121641 | 121848 | #define FTS3_FULLTEXT_SEARCH 2 /* Full-text index search */ |
| 121642 | 121849 | |
| 121850 | +/* |
| 121851 | +** The lower 16-bits of the sqlite3_index_info.idxNum value set by |
| 121852 | +** the xBestIndex() method contains the Fts3Cursor.eSearch value described |
| 121853 | +** above. The upper 16-bits contain a combination of the following |
| 121854 | +** bits, used to describe extra constraints on full-text searches. |
| 121855 | +*/ |
| 121856 | +#define FTS3_HAVE_LANGID 0x00010000 /* languageid=? */ |
| 121857 | +#define FTS3_HAVE_DOCID_GE 0x00020000 /* docid>=? */ |
| 121858 | +#define FTS3_HAVE_DOCID_LE 0x00040000 /* docid<=? */ |
| 121643 | 121859 | |
| 121644 | 121860 | struct Fts3Doclist { |
| 121645 | 121861 | char *aAll; /* Array containing doclist (or NULL) */ |
| 121646 | 121862 | int nAll; /* Size of a[] in bytes */ |
| 121647 | 121863 | char *pNextDocid; /* Pointer to next docid */ |
| | @@ -123058,27 +123274,31 @@ |
| 123058 | 123274 | */ |
| 123059 | 123275 | static int fts3BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ |
| 123060 | 123276 | Fts3Table *p = (Fts3Table *)pVTab; |
| 123061 | 123277 | int i; /* Iterator variable */ |
| 123062 | 123278 | int iCons = -1; /* Index of constraint to use */ |
| 123279 | + |
| 123063 | 123280 | int iLangidCons = -1; /* Index of langid=x constraint, if present */ |
| 123281 | + int iDocidGe = -1; /* Index of docid>=x constraint, if present */ |
| 123282 | + int iDocidLe = -1; /* Index of docid<=x constraint, if present */ |
| 123283 | + int iIdx; |
| 123064 | 123284 | |
| 123065 | 123285 | /* By default use a full table scan. This is an expensive option, |
| 123066 | 123286 | ** so search through the constraints to see if a more efficient |
| 123067 | 123287 | ** strategy is possible. |
| 123068 | 123288 | */ |
| 123069 | 123289 | pInfo->idxNum = FTS3_FULLSCAN_SEARCH; |
| 123070 | 123290 | pInfo->estimatedCost = 5000000; |
| 123071 | 123291 | for(i=0; i<pInfo->nConstraint; i++){ |
| 123292 | + int bDocid; /* True if this constraint is on docid */ |
| 123072 | 123293 | struct sqlite3_index_constraint *pCons = &pInfo->aConstraint[i]; |
| 123073 | 123294 | if( pCons->usable==0 ) continue; |
| 123295 | + |
| 123296 | + bDocid = (pCons->iColumn<0 || pCons->iColumn==p->nColumn+1); |
| 123074 | 123297 | |
| 123075 | 123298 | /* A direct lookup on the rowid or docid column. Assign a cost of 1.0. */ |
| 123076 | | - if( iCons<0 |
| 123077 | | - && pCons->op==SQLITE_INDEX_CONSTRAINT_EQ |
| 123078 | | - && (pCons->iColumn<0 || pCons->iColumn==p->nColumn+1 ) |
| 123079 | | - ){ |
| 123299 | + if( iCons<0 && pCons->op==SQLITE_INDEX_CONSTRAINT_EQ && bDocid ){ |
| 123080 | 123300 | pInfo->idxNum = FTS3_DOCID_SEARCH; |
| 123081 | 123301 | pInfo->estimatedCost = 1.0; |
| 123082 | 123302 | iCons = i; |
| 123083 | 123303 | } |
| 123084 | 123304 | |
| | @@ -123103,18 +123323,42 @@ |
| 123103 | 123323 | if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ |
| 123104 | 123324 | && pCons->iColumn==p->nColumn + 2 |
| 123105 | 123325 | ){ |
| 123106 | 123326 | iLangidCons = i; |
| 123107 | 123327 | } |
| 123328 | + |
| 123329 | + if( bDocid ){ |
| 123330 | + switch( pCons->op ){ |
| 123331 | + case SQLITE_INDEX_CONSTRAINT_GE: |
| 123332 | + case SQLITE_INDEX_CONSTRAINT_GT: |
| 123333 | + iDocidGe = i; |
| 123334 | + break; |
| 123335 | + |
| 123336 | + case SQLITE_INDEX_CONSTRAINT_LE: |
| 123337 | + case SQLITE_INDEX_CONSTRAINT_LT: |
| 123338 | + iDocidLe = i; |
| 123339 | + break; |
| 123340 | + } |
| 123341 | + } |
| 123108 | 123342 | } |
| 123109 | 123343 | |
| 123344 | + iIdx = 1; |
| 123110 | 123345 | if( iCons>=0 ){ |
| 123111 | | - pInfo->aConstraintUsage[iCons].argvIndex = 1; |
| 123346 | + pInfo->aConstraintUsage[iCons].argvIndex = iIdx++; |
| 123112 | 123347 | pInfo->aConstraintUsage[iCons].omit = 1; |
| 123113 | 123348 | } |
| 123114 | 123349 | if( iLangidCons>=0 ){ |
| 123115 | | - pInfo->aConstraintUsage[iLangidCons].argvIndex = 2; |
| 123350 | + pInfo->idxNum |= FTS3_HAVE_LANGID; |
| 123351 | + pInfo->aConstraintUsage[iLangidCons].argvIndex = iIdx++; |
| 123352 | + } |
| 123353 | + if( iDocidGe>=0 ){ |
| 123354 | + pInfo->idxNum |= FTS3_HAVE_DOCID_GE; |
| 123355 | + pInfo->aConstraintUsage[iDocidGe].argvIndex = iIdx++; |
| 123356 | + } |
| 123357 | + if( iDocidLe>=0 ){ |
| 123358 | + pInfo->idxNum |= FTS3_HAVE_DOCID_LE; |
| 123359 | + pInfo->aConstraintUsage[iDocidLe].argvIndex = iIdx++; |
| 123116 | 123360 | } |
| 123117 | 123361 | |
| 123118 | 123362 | /* Regardless of the strategy selected, FTS can deliver rows in rowid (or |
| 123119 | 123363 | ** docid) order. Both ascending and descending are possible. |
| 123120 | 123364 | */ |
| | @@ -124556,10 +124800,37 @@ |
| 124556 | 124800 | rc = fts3EvalNext((Fts3Cursor *)pCursor); |
| 124557 | 124801 | } |
| 124558 | 124802 | assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 ); |
| 124559 | 124803 | return rc; |
| 124560 | 124804 | } |
| 124805 | + |
| 124806 | +/* |
| 124807 | +** The following are copied from sqliteInt.h. |
| 124808 | +** |
| 124809 | +** Constants for the largest and smallest possible 64-bit signed integers. |
| 124810 | +** These macros are designed to work correctly on both 32-bit and 64-bit |
| 124811 | +** compilers. |
| 124812 | +*/ |
| 124813 | +#ifndef SQLITE_AMALGAMATION |
| 124814 | +# define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32)) |
| 124815 | +# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64) |
| 124816 | +#endif |
| 124817 | + |
| 124818 | +/* |
| 124819 | +** If the numeric type of argument pVal is "integer", then return it |
| 124820 | +** converted to a 64-bit signed integer. Otherwise, return a copy of |
| 124821 | +** the second parameter, iDefault. |
| 124822 | +*/ |
| 124823 | +static sqlite3_int64 fts3DocidRange(sqlite3_value *pVal, i64 iDefault){ |
| 124824 | + if( pVal ){ |
| 124825 | + int eType = sqlite3_value_numeric_type(pVal); |
| 124826 | + if( eType==SQLITE_INTEGER ){ |
| 124827 | + return sqlite3_value_int64(pVal); |
| 124828 | + } |
| 124829 | + } |
| 124830 | + return iDefault; |
| 124831 | +} |
| 124561 | 124832 | |
| 124562 | 124833 | /* |
| 124563 | 124834 | ** This is the xFilter interface for the virtual table. See |
| 124564 | 124835 | ** the virtual table xFilter method documentation for additional |
| 124565 | 124836 | ** information. |
| | @@ -124582,44 +124853,62 @@ |
| 124582 | 124853 | int nVal, /* Number of elements in apVal */ |
| 124583 | 124854 | sqlite3_value **apVal /* Arguments for the indexing scheme */ |
| 124584 | 124855 | ){ |
| 124585 | 124856 | int rc; |
| 124586 | 124857 | char *zSql; /* SQL statement used to access %_content */ |
| 124858 | + int eSearch; |
| 124587 | 124859 | Fts3Table *p = (Fts3Table *)pCursor->pVtab; |
| 124588 | 124860 | Fts3Cursor *pCsr = (Fts3Cursor *)pCursor; |
| 124861 | + |
| 124862 | + sqlite3_value *pCons = 0; /* The MATCH or rowid constraint, if any */ |
| 124863 | + sqlite3_value *pLangid = 0; /* The "langid = ?" constraint, if any */ |
| 124864 | + sqlite3_value *pDocidGe = 0; /* The "docid >= ?" constraint, if any */ |
| 124865 | + sqlite3_value *pDocidLe = 0; /* The "docid <= ?" constraint, if any */ |
| 124866 | + int iIdx; |
| 124589 | 124867 | |
| 124590 | 124868 | UNUSED_PARAMETER(idxStr); |
| 124591 | 124869 | UNUSED_PARAMETER(nVal); |
| 124592 | 124870 | |
| 124593 | | - assert( idxNum>=0 && idxNum<=(FTS3_FULLTEXT_SEARCH+p->nColumn) ); |
| 124594 | | - assert( nVal==0 || nVal==1 || nVal==2 ); |
| 124595 | | - assert( (nVal==0)==(idxNum==FTS3_FULLSCAN_SEARCH) ); |
| 124871 | + eSearch = (idxNum & 0x0000FFFF); |
| 124872 | + assert( eSearch>=0 && eSearch<=(FTS3_FULLTEXT_SEARCH+p->nColumn) ); |
| 124596 | 124873 | assert( p->pSegments==0 ); |
| 124874 | + |
| 124875 | + /* Collect arguments into local variables */ |
| 124876 | + iIdx = 0; |
| 124877 | + if( eSearch!=FTS3_FULLSCAN_SEARCH ) pCons = apVal[iIdx++]; |
| 124878 | + if( idxNum & FTS3_HAVE_LANGID ) pLangid = apVal[iIdx++]; |
| 124879 | + if( idxNum & FTS3_HAVE_DOCID_GE ) pDocidGe = apVal[iIdx++]; |
| 124880 | + if( idxNum & FTS3_HAVE_DOCID_LE ) pDocidLe = apVal[iIdx++]; |
| 124881 | + assert( iIdx==nVal ); |
| 124597 | 124882 | |
| 124598 | 124883 | /* In case the cursor has been used before, clear it now. */ |
| 124599 | 124884 | sqlite3_finalize(pCsr->pStmt); |
| 124600 | 124885 | sqlite3_free(pCsr->aDoclist); |
| 124601 | 124886 | sqlite3Fts3ExprFree(pCsr->pExpr); |
| 124602 | 124887 | memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor)); |
| 124603 | 124888 | |
| 124889 | + /* Set the lower and upper bounds on docids to return */ |
| 124890 | + pCsr->iMinDocid = fts3DocidRange(pDocidGe, SMALLEST_INT64); |
| 124891 | + pCsr->iMaxDocid = fts3DocidRange(pDocidLe, LARGEST_INT64); |
| 124892 | + |
| 124604 | 124893 | if( idxStr ){ |
| 124605 | 124894 | pCsr->bDesc = (idxStr[0]=='D'); |
| 124606 | 124895 | }else{ |
| 124607 | 124896 | pCsr->bDesc = p->bDescIdx; |
| 124608 | 124897 | } |
| 124609 | | - pCsr->eSearch = (i16)idxNum; |
| 124898 | + pCsr->eSearch = (i16)eSearch; |
| 124610 | 124899 | |
| 124611 | | - if( idxNum!=FTS3_DOCID_SEARCH && idxNum!=FTS3_FULLSCAN_SEARCH ){ |
| 124612 | | - int iCol = idxNum-FTS3_FULLTEXT_SEARCH; |
| 124613 | | - const char *zQuery = (const char *)sqlite3_value_text(apVal[0]); |
| 124900 | + if( eSearch!=FTS3_DOCID_SEARCH && eSearch!=FTS3_FULLSCAN_SEARCH ){ |
| 124901 | + int iCol = eSearch-FTS3_FULLTEXT_SEARCH; |
| 124902 | + const char *zQuery = (const char *)sqlite3_value_text(pCons); |
| 124614 | 124903 | |
| 124615 | | - if( zQuery==0 && sqlite3_value_type(apVal[0])!=SQLITE_NULL ){ |
| 124904 | + if( zQuery==0 && sqlite3_value_type(pCons)!=SQLITE_NULL ){ |
| 124616 | 124905 | return SQLITE_NOMEM; |
| 124617 | 124906 | } |
| 124618 | 124907 | |
| 124619 | 124908 | pCsr->iLangid = 0; |
| 124620 | | - if( nVal==2 ) pCsr->iLangid = sqlite3_value_int(apVal[1]); |
| 124909 | + if( pLangid ) pCsr->iLangid = sqlite3_value_int(pLangid); |
| 124621 | 124910 | |
| 124622 | 124911 | assert( p->base.zErrMsg==0 ); |
| 124623 | 124912 | rc = sqlite3Fts3ExprParse(p->pTokenizer, pCsr->iLangid, |
| 124624 | 124913 | p->azColumn, p->bFts4, p->nColumn, iCol, zQuery, -1, &pCsr->pExpr, |
| 124625 | 124914 | &p->base.zErrMsg |
| | @@ -124638,11 +124927,11 @@ |
| 124638 | 124927 | /* Compile a SELECT statement for this cursor. For a full-table-scan, the |
| 124639 | 124928 | ** statement loops through all rows of the %_content table. For a |
| 124640 | 124929 | ** full-text query or docid lookup, the statement retrieves a single |
| 124641 | 124930 | ** row by docid. |
| 124642 | 124931 | */ |
| 124643 | | - if( idxNum==FTS3_FULLSCAN_SEARCH ){ |
| 124932 | + if( eSearch==FTS3_FULLSCAN_SEARCH ){ |
| 124644 | 124933 | zSql = sqlite3_mprintf( |
| 124645 | 124934 | "SELECT %s ORDER BY rowid %s", |
| 124646 | 124935 | p->zReadExprlist, (pCsr->bDesc ? "DESC" : "ASC") |
| 124647 | 124936 | ); |
| 124648 | 124937 | if( zSql ){ |
| | @@ -124649,14 +124938,14 @@ |
| 124649 | 124938 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0); |
| 124650 | 124939 | sqlite3_free(zSql); |
| 124651 | 124940 | }else{ |
| 124652 | 124941 | rc = SQLITE_NOMEM; |
| 124653 | 124942 | } |
| 124654 | | - }else if( idxNum==FTS3_DOCID_SEARCH ){ |
| 124943 | + }else if( eSearch==FTS3_DOCID_SEARCH ){ |
| 124655 | 124944 | rc = fts3CursorSeekStmt(pCsr, &pCsr->pStmt); |
| 124656 | 124945 | if( rc==SQLITE_OK ){ |
| 124657 | | - rc = sqlite3_bind_value(pCsr->pStmt, 1, apVal[0]); |
| 124946 | + rc = sqlite3_bind_value(pCsr->pStmt, 1, pCons); |
| 124658 | 124947 | } |
| 124659 | 124948 | } |
| 124660 | 124949 | if( rc!=SQLITE_OK ) return rc; |
| 124661 | 124950 | |
| 124662 | 124951 | return fts3NextMethod(pCursor); |
| | @@ -125543,10 +125832,16 @@ |
| 125543 | 125832 | } |
| 125544 | 125833 | |
| 125545 | 125834 | return SQLITE_OK; |
| 125546 | 125835 | } |
| 125547 | 125836 | |
| 125837 | +/* |
| 125838 | +** Maximum number of tokens a phrase may have to be considered for the |
| 125839 | +** incremental doclists strategy. |
| 125840 | +*/ |
| 125841 | +#define MAX_INCR_PHRASE_TOKENS 4 |
| 125842 | + |
| 125548 | 125843 | /* |
| 125549 | 125844 | ** This function is called for each Fts3Phrase in a full-text query |
| 125550 | 125845 | ** expression to initialize the mechanism for returning rows. Once this |
| 125551 | 125846 | ** function has been called successfully on an Fts3Phrase, it may be |
| 125552 | 125847 | ** used with fts3EvalPhraseNext() to iterate through the matching docids. |
| | @@ -125556,27 +125851,47 @@ |
| 125556 | 125851 | ** memory within this call. |
| 125557 | 125852 | ** |
| 125558 | 125853 | ** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code. |
| 125559 | 125854 | */ |
| 125560 | 125855 | static int fts3EvalPhraseStart(Fts3Cursor *pCsr, int bOptOk, Fts3Phrase *p){ |
| 125561 | | - int rc; /* Error code */ |
| 125562 | | - Fts3PhraseToken *pFirst = &p->aToken[0]; |
| 125563 | 125856 | Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; |
| 125564 | | - |
| 125565 | | - if( pCsr->bDesc==pTab->bDescIdx |
| 125566 | | - && bOptOk==1 |
| 125567 | | - && p->nToken==1 |
| 125568 | | - && pFirst->pSegcsr |
| 125569 | | - && pFirst->pSegcsr->bLookup |
| 125570 | | - && pFirst->bFirst==0 |
| 125571 | | - ){ |
| 125857 | + int rc = SQLITE_OK; /* Error code */ |
| 125858 | + int i; |
| 125859 | + |
| 125860 | + /* Determine if doclists may be loaded from disk incrementally. This is |
| 125861 | + ** possible if the bOptOk argument is true, the FTS doclists will be |
| 125862 | + ** scanned in forward order, and the phrase consists of |
| 125863 | + ** MAX_INCR_PHRASE_TOKENS or fewer tokens, none of which are are "^first" |
| 125864 | + ** tokens or prefix tokens that cannot use a prefix-index. */ |
| 125865 | + int bHaveIncr = 0; |
| 125866 | + int bIncrOk = (bOptOk |
| 125867 | + && pCsr->bDesc==pTab->bDescIdx |
| 125868 | + && p->nToken<=MAX_INCR_PHRASE_TOKENS && p->nToken>0 |
| 125869 | + && p->nToken<=MAX_INCR_PHRASE_TOKENS && p->nToken>0 |
| 125870 | +#ifdef SQLITE_TEST |
| 125871 | + && pTab->bNoIncrDoclist==0 |
| 125872 | +#endif |
| 125873 | + ); |
| 125874 | + for(i=0; bIncrOk==1 && i<p->nToken; i++){ |
| 125875 | + Fts3PhraseToken *pToken = &p->aToken[i]; |
| 125876 | + if( pToken->bFirst || (pToken->pSegcsr!=0 && !pToken->pSegcsr->bLookup) ){ |
| 125877 | + bIncrOk = 0; |
| 125878 | + } |
| 125879 | + if( pToken->pSegcsr ) bHaveIncr = 1; |
| 125880 | + } |
| 125881 | + |
| 125882 | + if( bIncrOk && bHaveIncr ){ |
| 125572 | 125883 | /* Use the incremental approach. */ |
| 125573 | 125884 | int iCol = (p->iColumn >= pTab->nColumn ? -1 : p->iColumn); |
| 125574 | | - rc = sqlite3Fts3MsrIncrStart( |
| 125575 | | - pTab, pFirst->pSegcsr, iCol, pFirst->z, pFirst->n); |
| 125885 | + for(i=0; rc==SQLITE_OK && i<p->nToken; i++){ |
| 125886 | + Fts3PhraseToken *pToken = &p->aToken[i]; |
| 125887 | + Fts3MultiSegReader *pSegcsr = pToken->pSegcsr; |
| 125888 | + if( pSegcsr ){ |
| 125889 | + rc = sqlite3Fts3MsrIncrStart(pTab, pSegcsr, iCol, pToken->z, pToken->n); |
| 125890 | + } |
| 125891 | + } |
| 125576 | 125892 | p->bIncr = 1; |
| 125577 | | - |
| 125578 | 125893 | }else{ |
| 125579 | 125894 | /* Load the full doclist for the phrase into memory. */ |
| 125580 | 125895 | rc = fts3EvalPhraseLoad(pCsr, p); |
| 125581 | 125896 | p->bIncr = 0; |
| 125582 | 125897 | } |
| | @@ -125680,10 +125995,220 @@ |
| 125680 | 125995 | } |
| 125681 | 125996 | } |
| 125682 | 125997 | |
| 125683 | 125998 | *ppIter = p; |
| 125684 | 125999 | } |
| 126000 | + |
| 126001 | +/* |
| 126002 | +** Advance the iterator pDL to the next entry in pDL->aAll/nAll. Set *pbEof |
| 126003 | +** to true if EOF is reached. |
| 126004 | +*/ |
| 126005 | +static void fts3EvalDlPhraseNext( |
| 126006 | + Fts3Table *pTab, |
| 126007 | + Fts3Doclist *pDL, |
| 126008 | + u8 *pbEof |
| 126009 | +){ |
| 126010 | + char *pIter; /* Used to iterate through aAll */ |
| 126011 | + char *pEnd = &pDL->aAll[pDL->nAll]; /* 1 byte past end of aAll */ |
| 126012 | + |
| 126013 | + if( pDL->pNextDocid ){ |
| 126014 | + pIter = pDL->pNextDocid; |
| 126015 | + }else{ |
| 126016 | + pIter = pDL->aAll; |
| 126017 | + } |
| 126018 | + |
| 126019 | + if( pIter>=pEnd ){ |
| 126020 | + /* We have already reached the end of this doclist. EOF. */ |
| 126021 | + *pbEof = 1; |
| 126022 | + }else{ |
| 126023 | + sqlite3_int64 iDelta; |
| 126024 | + pIter += sqlite3Fts3GetVarint(pIter, &iDelta); |
| 126025 | + if( pTab->bDescIdx==0 || pDL->pNextDocid==0 ){ |
| 126026 | + pDL->iDocid += iDelta; |
| 126027 | + }else{ |
| 126028 | + pDL->iDocid -= iDelta; |
| 126029 | + } |
| 126030 | + pDL->pList = pIter; |
| 126031 | + fts3PoslistCopy(0, &pIter); |
| 126032 | + pDL->nList = (int)(pIter - pDL->pList); |
| 126033 | + |
| 126034 | + /* pIter now points just past the 0x00 that terminates the position- |
| 126035 | + ** list for document pDL->iDocid. However, if this position-list was |
| 126036 | + ** edited in place by fts3EvalNearTrim(), then pIter may not actually |
| 126037 | + ** point to the start of the next docid value. The following line deals |
| 126038 | + ** with this case by advancing pIter past the zero-padding added by |
| 126039 | + ** fts3EvalNearTrim(). */ |
| 126040 | + while( pIter<pEnd && *pIter==0 ) pIter++; |
| 126041 | + |
| 126042 | + pDL->pNextDocid = pIter; |
| 126043 | + assert( pIter>=&pDL->aAll[pDL->nAll] || *pIter ); |
| 126044 | + *pbEof = 0; |
| 126045 | + } |
| 126046 | +} |
| 126047 | + |
| 126048 | +/* |
| 126049 | +** Helper type used by fts3EvalIncrPhraseNext() and incrPhraseTokenNext(). |
| 126050 | +*/ |
| 126051 | +typedef struct TokenDoclist TokenDoclist; |
| 126052 | +struct TokenDoclist { |
| 126053 | + int bIgnore; |
| 126054 | + sqlite3_int64 iDocid; |
| 126055 | + char *pList; |
| 126056 | + int nList; |
| 126057 | +}; |
| 126058 | + |
| 126059 | +/* |
| 126060 | +** Token pToken is an incrementally loaded token that is part of a |
| 126061 | +** multi-token phrase. Advance it to the next matching document in the |
| 126062 | +** database and populate output variable *p with the details of the new |
| 126063 | +** entry. Or, if the iterator has reached EOF, set *pbEof to true. |
| 126064 | +** |
| 126065 | +** If an error occurs, return an SQLite error code. Otherwise, return |
| 126066 | +** SQLITE_OK. |
| 126067 | +*/ |
| 126068 | +static int incrPhraseTokenNext( |
| 126069 | + Fts3Table *pTab, /* Virtual table handle */ |
| 126070 | + Fts3Phrase *pPhrase, /* Phrase to advance token of */ |
| 126071 | + int iToken, /* Specific token to advance */ |
| 126072 | + TokenDoclist *p, /* OUT: Docid and doclist for new entry */ |
| 126073 | + u8 *pbEof /* OUT: True if iterator is at EOF */ |
| 126074 | +){ |
| 126075 | + int rc = SQLITE_OK; |
| 126076 | + |
| 126077 | + if( pPhrase->iDoclistToken==iToken ){ |
| 126078 | + assert( p->bIgnore==0 ); |
| 126079 | + assert( pPhrase->aToken[iToken].pSegcsr==0 ); |
| 126080 | + fts3EvalDlPhraseNext(pTab, &pPhrase->doclist, pbEof); |
| 126081 | + p->pList = pPhrase->doclist.pList; |
| 126082 | + p->nList = pPhrase->doclist.nList; |
| 126083 | + p->iDocid = pPhrase->doclist.iDocid; |
| 126084 | + }else{ |
| 126085 | + Fts3PhraseToken *pToken = &pPhrase->aToken[iToken]; |
| 126086 | + assert( pToken->pDeferred==0 ); |
| 126087 | + assert( pToken->pSegcsr || pPhrase->iDoclistToken>=0 ); |
| 126088 | + if( pToken->pSegcsr ){ |
| 126089 | + assert( p->bIgnore==0 ); |
| 126090 | + rc = sqlite3Fts3MsrIncrNext( |
| 126091 | + pTab, pToken->pSegcsr, &p->iDocid, &p->pList, &p->nList |
| 126092 | + ); |
| 126093 | + if( p->pList==0 ) *pbEof = 1; |
| 126094 | + }else{ |
| 126095 | + p->bIgnore = 1; |
| 126096 | + } |
| 126097 | + } |
| 126098 | + |
| 126099 | + return rc; |
| 126100 | +} |
| 126101 | + |
| 126102 | + |
| 126103 | +/* |
| 126104 | +** The phrase iterator passed as the second argument: |
| 126105 | +** |
| 126106 | +** * features at least one token that uses an incremental doclist, and |
| 126107 | +** |
| 126108 | +** * does not contain any deferred tokens. |
| 126109 | +** |
| 126110 | +** Advance it to the next matching documnent in the database and populate |
| 126111 | +** the Fts3Doclist.pList and nList fields. |
| 126112 | +** |
| 126113 | +** If there is no "next" entry and no error occurs, then *pbEof is set to |
| 126114 | +** 1 before returning. Otherwise, if no error occurs and the iterator is |
| 126115 | +** successfully advanced, *pbEof is set to 0. |
| 126116 | +** |
| 126117 | +** If an error occurs, return an SQLite error code. Otherwise, return |
| 126118 | +** SQLITE_OK. |
| 126119 | +*/ |
| 126120 | +static int fts3EvalIncrPhraseNext( |
| 126121 | + Fts3Cursor *pCsr, /* FTS Cursor handle */ |
| 126122 | + Fts3Phrase *p, /* Phrase object to advance to next docid */ |
| 126123 | + u8 *pbEof /* OUT: Set to 1 if EOF */ |
| 126124 | +){ |
| 126125 | + int rc = SQLITE_OK; |
| 126126 | + Fts3Doclist *pDL = &p->doclist; |
| 126127 | + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; |
| 126128 | + u8 bEof = 0; |
| 126129 | + |
| 126130 | + /* This is only called if it is guaranteed that the phrase has at least |
| 126131 | + ** one incremental token. In which case the bIncr flag is set. */ |
| 126132 | + assert( p->bIncr==1 ); |
| 126133 | + |
| 126134 | + if( p->nToken==1 && p->bIncr ){ |
| 126135 | + rc = sqlite3Fts3MsrIncrNext(pTab, p->aToken[0].pSegcsr, |
| 126136 | + &pDL->iDocid, &pDL->pList, &pDL->nList |
| 126137 | + ); |
| 126138 | + if( pDL->pList==0 ) bEof = 1; |
| 126139 | + }else{ |
| 126140 | + int bDescDoclist = pCsr->bDesc; |
| 126141 | + struct TokenDoclist a[MAX_INCR_PHRASE_TOKENS]; |
| 126142 | + |
| 126143 | + memset(a, 0, sizeof(a)); |
| 126144 | + assert( p->nToken<=MAX_INCR_PHRASE_TOKENS ); |
| 126145 | + assert( p->iDoclistToken<MAX_INCR_PHRASE_TOKENS ); |
| 126146 | + |
| 126147 | + while( bEof==0 ){ |
| 126148 | + int bMaxSet = 0; |
| 126149 | + sqlite3_int64 iMax; /* Largest docid for all iterators */ |
| 126150 | + int i; /* Used to iterate through tokens */ |
| 126151 | + |
| 126152 | + /* Advance the iterator for each token in the phrase once. */ |
| 126153 | + for(i=0; rc==SQLITE_OK && i<p->nToken; i++){ |
| 126154 | + rc = incrPhraseTokenNext(pTab, p, i, &a[i], &bEof); |
| 126155 | + if( a[i].bIgnore==0 && (bMaxSet==0 || DOCID_CMP(iMax, a[i].iDocid)<0) ){ |
| 126156 | + iMax = a[i].iDocid; |
| 126157 | + bMaxSet = 1; |
| 126158 | + } |
| 126159 | + } |
| 126160 | + assert( rc!=SQLITE_OK || a[p->nToken-1].bIgnore==0 ); |
| 126161 | + assert( rc!=SQLITE_OK || bMaxSet ); |
| 126162 | + |
| 126163 | + /* Keep advancing iterators until they all point to the same document */ |
| 126164 | + for(i=0; i<p->nToken; i++){ |
| 126165 | + while( rc==SQLITE_OK && bEof==0 |
| 126166 | + && a[i].bIgnore==0 && DOCID_CMP(a[i].iDocid, iMax)<0 |
| 126167 | + ){ |
| 126168 | + rc = incrPhraseTokenNext(pTab, p, i, &a[i], &bEof); |
| 126169 | + if( DOCID_CMP(a[i].iDocid, iMax)>0 ){ |
| 126170 | + iMax = a[i].iDocid; |
| 126171 | + i = 0; |
| 126172 | + } |
| 126173 | + } |
| 126174 | + } |
| 126175 | + |
| 126176 | + /* Check if the current entries really are a phrase match */ |
| 126177 | + if( bEof==0 ){ |
| 126178 | + int nList = 0; |
| 126179 | + int nByte = a[p->nToken-1].nList; |
| 126180 | + char *aDoclist = sqlite3_malloc(nByte+1); |
| 126181 | + if( !aDoclist ) return SQLITE_NOMEM; |
| 126182 | + memcpy(aDoclist, a[p->nToken-1].pList, nByte+1); |
| 126183 | + |
| 126184 | + for(i=0; i<(p->nToken-1); i++){ |
| 126185 | + if( a[i].bIgnore==0 ){ |
| 126186 | + char *pL = a[i].pList; |
| 126187 | + char *pR = aDoclist; |
| 126188 | + char *pOut = aDoclist; |
| 126189 | + int nDist = p->nToken-1-i; |
| 126190 | + int res = fts3PoslistPhraseMerge(&pOut, nDist, 0, 1, &pL, &pR); |
| 126191 | + if( res==0 ) break; |
| 126192 | + nList = (pOut - aDoclist); |
| 126193 | + } |
| 126194 | + } |
| 126195 | + if( i==(p->nToken-1) ){ |
| 126196 | + pDL->iDocid = iMax; |
| 126197 | + pDL->pList = aDoclist; |
| 126198 | + pDL->nList = nList; |
| 126199 | + pDL->bFreeList = 1; |
| 126200 | + break; |
| 126201 | + } |
| 126202 | + sqlite3_free(aDoclist); |
| 126203 | + } |
| 126204 | + } |
| 126205 | + } |
| 126206 | + |
| 126207 | + *pbEof = bEof; |
| 126208 | + return rc; |
| 126209 | +} |
| 125685 | 126210 | |
| 125686 | 126211 | /* |
| 125687 | 126212 | ** Attempt to move the phrase iterator to point to the next matching docid. |
| 125688 | 126213 | ** If an error occurs, return an SQLite error code. Otherwise, return |
| 125689 | 126214 | ** SQLITE_OK. |
| | @@ -125700,59 +126225,18 @@ |
| 125700 | 126225 | int rc = SQLITE_OK; |
| 125701 | 126226 | Fts3Doclist *pDL = &p->doclist; |
| 125702 | 126227 | Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; |
| 125703 | 126228 | |
| 125704 | 126229 | if( p->bIncr ){ |
| 125705 | | - assert( p->nToken==1 ); |
| 125706 | | - assert( pDL->pNextDocid==0 ); |
| 125707 | | - rc = sqlite3Fts3MsrIncrNext(pTab, p->aToken[0].pSegcsr, |
| 125708 | | - &pDL->iDocid, &pDL->pList, &pDL->nList |
| 125709 | | - ); |
| 125710 | | - if( rc==SQLITE_OK && !pDL->pList ){ |
| 125711 | | - *pbEof = 1; |
| 125712 | | - } |
| 126230 | + rc = fts3EvalIncrPhraseNext(pCsr, p, pbEof); |
| 125713 | 126231 | }else if( pCsr->bDesc!=pTab->bDescIdx && pDL->nAll ){ |
| 125714 | 126232 | sqlite3Fts3DoclistPrev(pTab->bDescIdx, pDL->aAll, pDL->nAll, |
| 125715 | 126233 | &pDL->pNextDocid, &pDL->iDocid, &pDL->nList, pbEof |
| 125716 | 126234 | ); |
| 125717 | 126235 | pDL->pList = pDL->pNextDocid; |
| 125718 | 126236 | }else{ |
| 125719 | | - char *pIter; /* Used to iterate through aAll */ |
| 125720 | | - char *pEnd = &pDL->aAll[pDL->nAll]; /* 1 byte past end of aAll */ |
| 125721 | | - if( pDL->pNextDocid ){ |
| 125722 | | - pIter = pDL->pNextDocid; |
| 125723 | | - }else{ |
| 125724 | | - pIter = pDL->aAll; |
| 125725 | | - } |
| 125726 | | - |
| 125727 | | - if( pIter>=pEnd ){ |
| 125728 | | - /* We have already reached the end of this doclist. EOF. */ |
| 125729 | | - *pbEof = 1; |
| 125730 | | - }else{ |
| 125731 | | - sqlite3_int64 iDelta; |
| 125732 | | - pIter += sqlite3Fts3GetVarint(pIter, &iDelta); |
| 125733 | | - if( pTab->bDescIdx==0 || pDL->pNextDocid==0 ){ |
| 125734 | | - pDL->iDocid += iDelta; |
| 125735 | | - }else{ |
| 125736 | | - pDL->iDocid -= iDelta; |
| 125737 | | - } |
| 125738 | | - pDL->pList = pIter; |
| 125739 | | - fts3PoslistCopy(0, &pIter); |
| 125740 | | - pDL->nList = (int)(pIter - pDL->pList); |
| 125741 | | - |
| 125742 | | - /* pIter now points just past the 0x00 that terminates the position- |
| 125743 | | - ** list for document pDL->iDocid. However, if this position-list was |
| 125744 | | - ** edited in place by fts3EvalNearTrim(), then pIter may not actually |
| 125745 | | - ** point to the start of the next docid value. The following line deals |
| 125746 | | - ** with this case by advancing pIter past the zero-padding added by |
| 125747 | | - ** fts3EvalNearTrim(). */ |
| 125748 | | - while( pIter<pEnd && *pIter==0 ) pIter++; |
| 125749 | | - |
| 125750 | | - pDL->pNextDocid = pIter; |
| 125751 | | - assert( pIter>=&pDL->aAll[pDL->nAll] || *pIter ); |
| 125752 | | - *pbEof = 0; |
| 125753 | | - } |
| 126237 | + fts3EvalDlPhraseNext(pTab, pDL, pbEof); |
| 125754 | 126238 | } |
| 125755 | 126239 | |
| 125756 | 126240 | return rc; |
| 125757 | 126241 | } |
| 125758 | 126242 | |
| | @@ -125773,11 +126257,10 @@ |
| 125773 | 126257 | ** code before returning. |
| 125774 | 126258 | */ |
| 125775 | 126259 | static void fts3EvalStartReaders( |
| 125776 | 126260 | Fts3Cursor *pCsr, /* FTS Cursor handle */ |
| 125777 | 126261 | Fts3Expr *pExpr, /* Expression to initialize phrases in */ |
| 125778 | | - int bOptOk, /* True to enable incremental loading */ |
| 125779 | 126262 | int *pRc /* IN/OUT: Error code */ |
| 125780 | 126263 | ){ |
| 125781 | 126264 | if( pExpr && SQLITE_OK==*pRc ){ |
| 125782 | 126265 | if( pExpr->eType==FTSQUERY_PHRASE ){ |
| 125783 | 126266 | int i; |
| | @@ -125784,14 +126267,14 @@ |
| 125784 | 126267 | int nToken = pExpr->pPhrase->nToken; |
| 125785 | 126268 | for(i=0; i<nToken; i++){ |
| 125786 | 126269 | if( pExpr->pPhrase->aToken[i].pDeferred==0 ) break; |
| 125787 | 126270 | } |
| 125788 | 126271 | pExpr->bDeferred = (i==nToken); |
| 125789 | | - *pRc = fts3EvalPhraseStart(pCsr, bOptOk, pExpr->pPhrase); |
| 126272 | + *pRc = fts3EvalPhraseStart(pCsr, 1, pExpr->pPhrase); |
| 125790 | 126273 | }else{ |
| 125791 | | - fts3EvalStartReaders(pCsr, pExpr->pLeft, bOptOk, pRc); |
| 125792 | | - fts3EvalStartReaders(pCsr, pExpr->pRight, bOptOk, pRc); |
| 126274 | + fts3EvalStartReaders(pCsr, pExpr->pLeft, pRc); |
| 126275 | + fts3EvalStartReaders(pCsr, pExpr->pRight, pRc); |
| 125793 | 126276 | pExpr->bDeferred = (pExpr->pLeft->bDeferred && pExpr->pRight->bDeferred); |
| 125794 | 126277 | } |
| 125795 | 126278 | } |
| 125796 | 126279 | } |
| 125797 | 126280 | |
| | @@ -126029,11 +126512,11 @@ |
| 126029 | 126512 | /* Set nLoad4 to the value of (4^nOther) for the next iteration of the |
| 126030 | 126513 | ** for-loop. Except, limit the value to 2^24 to prevent it from |
| 126031 | 126514 | ** overflowing the 32-bit integer it is stored in. */ |
| 126032 | 126515 | if( ii<12 ) nLoad4 = nLoad4*4; |
| 126033 | 126516 | |
| 126034 | | - if( ii==0 || pTC->pPhrase->nToken>1 ){ |
| 126517 | + if( ii==0 || (pTC->pPhrase->nToken>1 && ii!=nToken-1) ){ |
| 126035 | 126518 | /* Either this is the cheapest token in the entire query, or it is |
| 126036 | 126519 | ** part of a multi-token phrase. Either way, the entire doclist will |
| 126037 | 126520 | ** (eventually) be loaded into memory. It may as well be now. */ |
| 126038 | 126521 | Fts3PhraseToken *pToken = pTC->pToken; |
| 126039 | 126522 | int nList = 0; |
| | @@ -126109,11 +126592,11 @@ |
| 126109 | 126592 | sqlite3_free(aTC); |
| 126110 | 126593 | } |
| 126111 | 126594 | } |
| 126112 | 126595 | #endif |
| 126113 | 126596 | |
| 126114 | | - fts3EvalStartReaders(pCsr, pCsr->pExpr, 1, &rc); |
| 126597 | + fts3EvalStartReaders(pCsr, pCsr->pExpr, &rc); |
| 126115 | 126598 | return rc; |
| 126116 | 126599 | } |
| 126117 | 126600 | |
| 126118 | 126601 | /* |
| 126119 | 126602 | ** Invalidate the current position list for phrase pPhrase. |
| | @@ -126592,10 +127075,20 @@ |
| 126592 | 127075 | pCsr->isRequireSeek = 1; |
| 126593 | 127076 | pCsr->isMatchinfoNeeded = 1; |
| 126594 | 127077 | pCsr->iPrevId = pExpr->iDocid; |
| 126595 | 127078 | }while( pCsr->isEof==0 && fts3EvalTestDeferredAndNear(pCsr, &rc) ); |
| 126596 | 127079 | } |
| 127080 | + |
| 127081 | + /* Check if the cursor is past the end of the docid range specified |
| 127082 | + ** by Fts3Cursor.iMinDocid/iMaxDocid. If so, set the EOF flag. */ |
| 127083 | + if( rc==SQLITE_OK && ( |
| 127084 | + (pCsr->bDesc==0 && pCsr->iPrevId>pCsr->iMaxDocid) |
| 127085 | + || (pCsr->bDesc!=0 && pCsr->iPrevId<pCsr->iMinDocid) |
| 127086 | + )){ |
| 127087 | + pCsr->isEof = 1; |
| 127088 | + } |
| 127089 | + |
| 126597 | 127090 | return rc; |
| 126598 | 127091 | } |
| 126599 | 127092 | |
| 126600 | 127093 | /* |
| 126601 | 127094 | ** Restart interation for expression pExpr so that the next call to |
| | @@ -126615,16 +127108,20 @@ |
| 126615 | 127108 | Fts3Phrase *pPhrase = pExpr->pPhrase; |
| 126616 | 127109 | |
| 126617 | 127110 | if( pPhrase ){ |
| 126618 | 127111 | fts3EvalInvalidatePoslist(pPhrase); |
| 126619 | 127112 | if( pPhrase->bIncr ){ |
| 126620 | | - assert( pPhrase->nToken==1 ); |
| 126621 | | - assert( pPhrase->aToken[0].pSegcsr ); |
| 126622 | | - sqlite3Fts3MsrIncrRestart(pPhrase->aToken[0].pSegcsr); |
| 127113 | + int i; |
| 127114 | + for(i=0; i<pPhrase->nToken; i++){ |
| 127115 | + Fts3PhraseToken *pToken = &pPhrase->aToken[i]; |
| 127116 | + assert( pToken->pDeferred==0 ); |
| 127117 | + if( pToken->pSegcsr ){ |
| 127118 | + sqlite3Fts3MsrIncrRestart(pToken->pSegcsr); |
| 127119 | + } |
| 127120 | + } |
| 126623 | 127121 | *pRc = fts3EvalPhraseStart(pCsr, 0, pPhrase); |
| 126624 | 127122 | } |
| 126625 | | - |
| 126626 | 127123 | pPhrase->doclist.pNextDocid = 0; |
| 126627 | 127124 | pPhrase->doclist.iDocid = 0; |
| 126628 | 127125 | } |
| 126629 | 127126 | |
| 126630 | 127127 | pExpr->iDocid = 0; |
| | @@ -126869,19 +127366,27 @@ |
| 126869 | 127366 | |
| 126870 | 127367 | iDocid = pExpr->iDocid; |
| 126871 | 127368 | pIter = pPhrase->doclist.pList; |
| 126872 | 127369 | if( iDocid!=pCsr->iPrevId || pExpr->bEof ){ |
| 126873 | 127370 | int bDescDoclist = pTab->bDescIdx; /* For DOCID_CMP macro */ |
| 127371 | + int iMul; /* +1 if csr dir matches index dir, else -1 */ |
| 126874 | 127372 | int bOr = 0; |
| 126875 | 127373 | u8 bEof = 0; |
| 126876 | | - Fts3Expr *p; |
| 127374 | + u8 bTreeEof = 0; |
| 127375 | + Fts3Expr *p; /* Used to iterate from pExpr to root */ |
| 127376 | + Fts3Expr *pNear; /* Most senior NEAR ancestor (or pExpr) */ |
| 126877 | 127377 | |
| 126878 | 127378 | /* Check if this phrase descends from an OR expression node. If not, |
| 126879 | 127379 | ** return NULL. Otherwise, the entry that corresponds to docid |
| 126880 | | - ** pCsr->iPrevId may lie earlier in the doclist buffer. */ |
| 127380 | + ** pCsr->iPrevId may lie earlier in the doclist buffer. Or, if the |
| 127381 | + ** tree that the node is part of has been marked as EOF, but the node |
| 127382 | + ** itself is not EOF, then it may point to an earlier entry. */ |
| 127383 | + pNear = pExpr; |
| 126881 | 127384 | for(p=pExpr->pParent; p; p=p->pParent){ |
| 126882 | 127385 | if( p->eType==FTSQUERY_OR ) bOr = 1; |
| 127386 | + if( p->eType==FTSQUERY_NEAR ) pNear = p; |
| 127387 | + if( p->bEof ) bTreeEof = 1; |
| 126883 | 127388 | } |
| 126884 | 127389 | if( bOr==0 ) return SQLITE_OK; |
| 126885 | 127390 | |
| 126886 | 127391 | /* This is the descendent of an OR node. In this case we cannot use |
| 126887 | 127392 | ** an incremental phrase. Load the entire doclist for the phrase |
| | @@ -126896,33 +127401,63 @@ |
| 126896 | 127401 | } |
| 126897 | 127402 | pIter = pPhrase->doclist.pList; |
| 126898 | 127403 | assert( rc!=SQLITE_OK || pPhrase->bIncr==0 ); |
| 126899 | 127404 | if( rc!=SQLITE_OK ) return rc; |
| 126900 | 127405 | } |
| 127406 | + |
| 127407 | + iMul = ((pCsr->bDesc==bDescDoclist) ? 1 : -1); |
| 127408 | + while( bTreeEof==1 |
| 127409 | + && pNear->bEof==0 |
| 127410 | + && (DOCID_CMP(pNear->iDocid, pCsr->iPrevId) * iMul)<0 |
| 127411 | + ){ |
| 127412 | + int rc = SQLITE_OK; |
| 127413 | + fts3EvalNextRow(pCsr, pExpr, &rc); |
| 127414 | + if( rc!=SQLITE_OK ) return rc; |
| 127415 | + iDocid = pExpr->iDocid; |
| 127416 | + pIter = pPhrase->doclist.pList; |
| 127417 | + } |
| 126901 | 127418 | |
| 126902 | | - if( pExpr->bEof ){ |
| 126903 | | - pIter = 0; |
| 126904 | | - iDocid = 0; |
| 126905 | | - } |
| 126906 | 127419 | bEof = (pPhrase->doclist.nAll==0); |
| 126907 | 127420 | assert( bDescDoclist==0 || bDescDoclist==1 ); |
| 126908 | 127421 | assert( pCsr->bDesc==0 || pCsr->bDesc==1 ); |
| 126909 | 127422 | |
| 126910 | | - if( pCsr->bDesc==bDescDoclist ){ |
| 126911 | | - int dummy; |
| 126912 | | - while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){ |
| 126913 | | - sqlite3Fts3DoclistPrev( |
| 126914 | | - bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll, |
| 126915 | | - &pIter, &iDocid, &dummy, &bEof |
| 126916 | | - ); |
| 126917 | | - } |
| 126918 | | - }else{ |
| 126919 | | - while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){ |
| 126920 | | - sqlite3Fts3DoclistNext( |
| 126921 | | - bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll, |
| 126922 | | - &pIter, &iDocid, &bEof |
| 126923 | | - ); |
| 127423 | + if( bEof==0 ){ |
| 127424 | + if( pCsr->bDesc==bDescDoclist ){ |
| 127425 | + int dummy; |
| 127426 | + if( pNear->bEof ){ |
| 127427 | + /* This expression is already at EOF. So position it to point to the |
| 127428 | + ** last entry in the doclist at pPhrase->doclist.aAll[]. Variable |
| 127429 | + ** iDocid is already set for this entry, so all that is required is |
| 127430 | + ** to set pIter to point to the first byte of the last position-list |
| 127431 | + ** in the doclist. |
| 127432 | + ** |
| 127433 | + ** It would also be correct to set pIter and iDocid to zero. In |
| 127434 | + ** this case, the first call to sqltie3Fts4DoclistPrev() below |
| 127435 | + ** would also move the iterator to point to the last entry in the |
| 127436 | + ** doclist. However, this is expensive, as to do so it has to |
| 127437 | + ** iterate through the entire doclist from start to finish (since |
| 127438 | + ** it does not know the docid for the last entry). */ |
| 127439 | + pIter = &pPhrase->doclist.aAll[pPhrase->doclist.nAll-1]; |
| 127440 | + fts3ReversePoslist(pPhrase->doclist.aAll, &pIter); |
| 127441 | + } |
| 127442 | + while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){ |
| 127443 | + sqlite3Fts3DoclistPrev( |
| 127444 | + bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll, |
| 127445 | + &pIter, &iDocid, &dummy, &bEof |
| 127446 | + ); |
| 127447 | + } |
| 127448 | + }else{ |
| 127449 | + if( pNear->bEof ){ |
| 127450 | + pIter = 0; |
| 127451 | + iDocid = 0; |
| 127452 | + } |
| 127453 | + while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){ |
| 127454 | + sqlite3Fts3DoclistNext( |
| 127455 | + bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll, |
| 127456 | + &pIter, &iDocid, &bEof |
| 127457 | + ); |
| 127458 | + } |
| 126924 | 127459 | } |
| 126925 | 127460 | } |
| 126926 | 127461 | |
| 126927 | 127462 | if( bEof || iDocid!=pCsr->iPrevId ) pIter = 0; |
| 126928 | 127463 | } |
| | @@ -135756,11 +136291,11 @@ |
| 135756 | 136291 | assert( p->bFts4==0 ); |
| 135757 | 136292 | sqlite3Fts3CreateStatTable(&rc, p); |
| 135758 | 136293 | if( rc ) return rc; |
| 135759 | 136294 | } |
| 135760 | 136295 | rc = fts3SqlStmt(p, SQL_REPLACE_STAT, &pStmt, 0); |
| 135761 | | - if( rc ) return rc;; |
| 136296 | + if( rc ) return rc; |
| 135762 | 136297 | sqlite3_bind_int(pStmt, 1, FTS_STAT_AUTOINCRMERGE); |
| 135763 | 136298 | sqlite3_bind_int(pStmt, 2, p->bAutoincrmerge); |
| 135764 | 136299 | sqlite3_step(pStmt); |
| 135765 | 136300 | rc = sqlite3_reset(pStmt); |
| 135766 | 136301 | return rc; |
| | @@ -136025,10 +136560,13 @@ |
| 136025 | 136560 | }else if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){ |
| 136026 | 136561 | p->nNodeSize = atoi(&zVal[9]); |
| 136027 | 136562 | rc = SQLITE_OK; |
| 136028 | 136563 | }else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 9) ){ |
| 136029 | 136564 | p->nMaxPendingData = atoi(&zVal[11]); |
| 136565 | + rc = SQLITE_OK; |
| 136566 | + }else if( nVal>21 && 0==sqlite3_strnicmp(zVal, "test-no-incr-doclist=", 21) ){ |
| 136567 | + p->bNoIncrDoclist = atoi(&zVal[21]); |
| 136030 | 136568 | rc = SQLITE_OK; |
| 136031 | 136569 | #endif |
| 136032 | 136570 | }else{ |
| 136033 | 136571 | rc = SQLITE_ERROR; |
| 136034 | 136572 | } |
| 136035 | 136573 | |