| | @@ -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-10 15:04:52 af7abebeb1f70466833bc766d294d721eaef746f" |
| 662 | 662 | |
| 663 | 663 | /* |
| 664 | 664 | ** CAPI3REF: Run-Time Library Version Numbers |
| 665 | 665 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 666 | 666 | ** |
| | @@ -8272,10 +8272,35 @@ |
| 8272 | 8272 | typedef u64 tRowcnt; /* 64-bit only if requested at compile-time */ |
| 8273 | 8273 | #else |
| 8274 | 8274 | typedef u32 tRowcnt; /* 32-bit is the default */ |
| 8275 | 8275 | #endif |
| 8276 | 8276 | |
| 8277 | +/* |
| 8278 | +** Estimated quantities used for query planning are stored as 16-bit |
| 8279 | +** logarithms. For quantity X, the value stored is 10*log2(X). This |
| 8280 | +** gives a possible range of values of approximately 1.0e986 to 1e-986. |
| 8281 | +** But the allowed values are "grainy". Not every value is representable. |
| 8282 | +** For example, quantities 16 and 17 are both represented by a LogEst |
| 8283 | +** of 40. However, since LogEst quantatites are suppose to be estimates, |
| 8284 | +** not exact values, this imprecision is not a problem. |
| 8285 | +** |
| 8286 | +** "LogEst" is short for "Logarithimic Estimate". |
| 8287 | +** |
| 8288 | +** Examples: |
| 8289 | +** 1 -> 0 20 -> 43 10000 -> 132 |
| 8290 | +** 2 -> 10 25 -> 46 25000 -> 146 |
| 8291 | +** 3 -> 16 100 -> 66 1000000 -> 199 |
| 8292 | +** 4 -> 20 1000 -> 99 1048576 -> 200 |
| 8293 | +** 10 -> 33 1024 -> 100 4294967296 -> 320 |
| 8294 | +** |
| 8295 | +** The LogEst can be negative to indicate fractional values. |
| 8296 | +** Examples: |
| 8297 | +** |
| 8298 | +** 0.5 -> -10 0.1 -> -33 0.0625 -> -40 |
| 8299 | +*/ |
| 8300 | +typedef INT16_TYPE LogEst; |
| 8301 | + |
| 8277 | 8302 | /* |
| 8278 | 8303 | ** Macros to determine whether the machine is big or little endian, |
| 8279 | 8304 | ** evaluated at runtime. |
| 8280 | 8305 | */ |
| 8281 | 8306 | #ifdef SQLITE_AMALGAMATION |
| | @@ -10419,11 +10444,12 @@ |
| 10419 | 10444 | char *zDflt; /* Original text of the default value */ |
| 10420 | 10445 | char *zType; /* Data type for this column */ |
| 10421 | 10446 | char *zColl; /* Collating sequence. If NULL, use the default */ |
| 10422 | 10447 | u8 notNull; /* An OE_ code for handling a NOT NULL constraint */ |
| 10423 | 10448 | char affinity; /* One of the SQLITE_AFF_... values */ |
| 10424 | | - u16 colFlags; /* Boolean properties. See COLFLAG_ defines below */ |
| 10449 | + u8 szEst; /* Estimated size of this column. INT==1 */ |
| 10450 | + u8 colFlags; /* Boolean properties. See COLFLAG_ defines below */ |
| 10425 | 10451 | }; |
| 10426 | 10452 | |
| 10427 | 10453 | /* Allowed values for Column.colFlags: |
| 10428 | 10454 | */ |
| 10429 | 10455 | #define COLFLAG_PRIMKEY 0x0001 /* Column is part of the primary key */ |
| | @@ -10583,10 +10609,11 @@ |
| 10583 | 10609 | tRowcnt nRowEst; /* Estimated rows in table - from sqlite_stat1 table */ |
| 10584 | 10610 | int tnum; /* Root BTree node for this table (see note above) */ |
| 10585 | 10611 | i16 iPKey; /* If not negative, use aCol[iPKey] as the primary key */ |
| 10586 | 10612 | i16 nCol; /* Number of columns in this table */ |
| 10587 | 10613 | u16 nRef; /* Number of pointers to this Table */ |
| 10614 | + LogEst szTabRow; /* Estimated size of each table row in bytes */ |
| 10588 | 10615 | u8 tabFlags; /* Mask of TF_* values */ |
| 10589 | 10616 | u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */ |
| 10590 | 10617 | #ifndef SQLITE_OMIT_ALTERTABLE |
| 10591 | 10618 | int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */ |
| 10592 | 10619 | #endif |
| | @@ -10694,11 +10721,11 @@ |
| 10694 | 10721 | #define OE_Restrict 6 /* OE_Abort for IMMEDIATE, OE_Rollback for DEFERRED */ |
| 10695 | 10722 | #define OE_SetNull 7 /* Set the foreign key value to NULL */ |
| 10696 | 10723 | #define OE_SetDflt 8 /* Set the foreign key value to its default */ |
| 10697 | 10724 | #define OE_Cascade 9 /* Cascade the changes */ |
| 10698 | 10725 | |
| 10699 | | -#define OE_Default 99 /* Do whatever the default action is */ |
| 10726 | +#define OE_Default 10 /* Do whatever the default action is */ |
| 10700 | 10727 | |
| 10701 | 10728 | |
| 10702 | 10729 | /* |
| 10703 | 10730 | ** An instance of the following structure is passed as the first |
| 10704 | 10731 | ** argument to sqlite3VdbeKeyCompare and is used to control the |
| | @@ -10781,10 +10808,11 @@ |
| 10781 | 10808 | Schema *pSchema; /* Schema containing this index */ |
| 10782 | 10809 | u8 *aSortOrder; /* for each column: True==DESC, False==ASC */ |
| 10783 | 10810 | char **azColl; /* Array of collation sequence names for index */ |
| 10784 | 10811 | Expr *pPartIdxWhere; /* WHERE clause for partial indices */ |
| 10785 | 10812 | int tnum; /* DB Page containing root of this index */ |
| 10813 | + LogEst szIdxRow; /* Estimated average row size in bytes */ |
| 10786 | 10814 | u16 nColumn; /* Number of columns in table used by this index */ |
| 10787 | 10815 | u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ |
| 10788 | 10816 | unsigned autoIndex:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */ |
| 10789 | 10817 | unsigned bUnordered:1; /* Use this index for == or IN queries only */ |
| 10790 | 10818 | unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */ |
| | @@ -11636,10 +11664,11 @@ |
| 11636 | 11664 | */ |
| 11637 | 11665 | typedef struct DbFixer DbFixer; |
| 11638 | 11666 | struct DbFixer { |
| 11639 | 11667 | Parse *pParse; /* The parsing context. Error messages written here */ |
| 11640 | 11668 | Schema *pSchema; /* Fix items to this schema */ |
| 11669 | + int bVarOnly; /* Check for variable references only */ |
| 11641 | 11670 | const char *zDb; /* Make sure all objects are contained in this database */ |
| 11642 | 11671 | const char *zType; /* Type of the container - used for error messages */ |
| 11643 | 11672 | const Token *pName; /* Name of the container - used for error messages */ |
| 11644 | 11673 | }; |
| 11645 | 11674 | |
| | @@ -12174,11 +12203,11 @@ |
| 12174 | 12203 | # define sqlite3AuthContextPush(a,b,c) |
| 12175 | 12204 | # define sqlite3AuthContextPop(a) ((void)(a)) |
| 12176 | 12205 | #endif |
| 12177 | 12206 | SQLITE_PRIVATE void sqlite3Attach(Parse*, Expr*, Expr*, Expr*); |
| 12178 | 12207 | SQLITE_PRIVATE void sqlite3Detach(Parse*, Expr*); |
| 12179 | | -SQLITE_PRIVATE int sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*); |
| 12208 | +SQLITE_PRIVATE void sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*); |
| 12180 | 12209 | SQLITE_PRIVATE int sqlite3FixSrcList(DbFixer*, SrcList*); |
| 12181 | 12210 | SQLITE_PRIVATE int sqlite3FixSelect(DbFixer*, Select*); |
| 12182 | 12211 | SQLITE_PRIVATE int sqlite3FixExpr(DbFixer*, Expr*); |
| 12183 | 12212 | SQLITE_PRIVATE int sqlite3FixExprList(DbFixer*, ExprList*); |
| 12184 | 12213 | SQLITE_PRIVATE int sqlite3FixTriggerStep(DbFixer*, TriggerStep*); |
| | @@ -12186,10 +12215,16 @@ |
| 12186 | 12215 | SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*); |
| 12187 | 12216 | SQLITE_PRIVATE int sqlite3Atoi(const char*); |
| 12188 | 12217 | SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nChar); |
| 12189 | 12218 | SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte); |
| 12190 | 12219 | SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**); |
| 12220 | +SQLITE_PRIVATE LogEst sqlite3LogEst(u64); |
| 12221 | +SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst,LogEst); |
| 12222 | +#ifndef SQLITE_OMIT_VIRTUALTABLE |
| 12223 | +SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double); |
| 12224 | +#endif |
| 12225 | +SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst); |
| 12191 | 12226 | |
| 12192 | 12227 | /* |
| 12193 | 12228 | ** Routines to read and write variable-length integers. These used to |
| 12194 | 12229 | ** be defined locally, but now we use the varint routines in the util.c |
| 12195 | 12230 | ** file. Code should use the MACRO forms below, as the Varint32 versions |
| | @@ -12302,11 +12337,11 @@ |
| 12302 | 12337 | SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*); |
| 12303 | 12338 | SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int); |
| 12304 | 12339 | SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *); |
| 12305 | 12340 | SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *); |
| 12306 | 12341 | SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*); |
| 12307 | | -SQLITE_PRIVATE char sqlite3AffinityType(const char*); |
| 12342 | +SQLITE_PRIVATE char sqlite3AffinityType(const char*, u8*); |
| 12308 | 12343 | SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*); |
| 12309 | 12344 | SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*); |
| 12310 | 12345 | SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*); |
| 12311 | 12346 | SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *, const char *); |
| 12312 | 12347 | SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3*,int iDB); |
| | @@ -22387,10 +22422,87 @@ |
| 22387 | 22422 | for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){} |
| 22388 | 22423 | if( z[i]=='.' && ALWAYS(sz>i+4) ) memmove(&z[i+1], &z[sz-3], 4); |
| 22389 | 22424 | } |
| 22390 | 22425 | } |
| 22391 | 22426 | #endif |
| 22427 | + |
| 22428 | +/* |
| 22429 | +** Find (an approximate) sum of two LogEst values. This computation is |
| 22430 | +** not a simple "+" operator because LogEst is stored as a logarithmic |
| 22431 | +** value. |
| 22432 | +** |
| 22433 | +*/ |
| 22434 | +SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst a, LogEst b){ |
| 22435 | + static const unsigned char x[] = { |
| 22436 | + 10, 10, /* 0,1 */ |
| 22437 | + 9, 9, /* 2,3 */ |
| 22438 | + 8, 8, /* 4,5 */ |
| 22439 | + 7, 7, 7, /* 6,7,8 */ |
| 22440 | + 6, 6, 6, /* 9,10,11 */ |
| 22441 | + 5, 5, 5, /* 12-14 */ |
| 22442 | + 4, 4, 4, 4, /* 15-18 */ |
| 22443 | + 3, 3, 3, 3, 3, 3, /* 19-24 */ |
| 22444 | + 2, 2, 2, 2, 2, 2, 2, /* 25-31 */ |
| 22445 | + }; |
| 22446 | + if( a>=b ){ |
| 22447 | + if( a>b+49 ) return a; |
| 22448 | + if( a>b+31 ) return a+1; |
| 22449 | + return a+x[a-b]; |
| 22450 | + }else{ |
| 22451 | + if( b>a+49 ) return b; |
| 22452 | + if( b>a+31 ) return b+1; |
| 22453 | + return b+x[b-a]; |
| 22454 | + } |
| 22455 | +} |
| 22456 | + |
| 22457 | +/* |
| 22458 | +** Convert an integer into a LogEst. In other words, compute a |
| 22459 | +** good approximatation for 10*log2(x). |
| 22460 | +*/ |
| 22461 | +SQLITE_PRIVATE LogEst sqlite3LogEst(u64 x){ |
| 22462 | + static LogEst a[] = { 0, 2, 3, 5, 6, 7, 8, 9 }; |
| 22463 | + LogEst y = 40; |
| 22464 | + if( x<8 ){ |
| 22465 | + if( x<2 ) return 0; |
| 22466 | + while( x<8 ){ y -= 10; x <<= 1; } |
| 22467 | + }else{ |
| 22468 | + while( x>255 ){ y += 40; x >>= 4; } |
| 22469 | + while( x>15 ){ y += 10; x >>= 1; } |
| 22470 | + } |
| 22471 | + return a[x&7] + y - 10; |
| 22472 | +} |
| 22473 | + |
| 22474 | +#ifndef SQLITE_OMIT_VIRTUALTABLE |
| 22475 | +/* |
| 22476 | +** Convert a double into a LogEst |
| 22477 | +** In other words, compute an approximation for 10*log2(x). |
| 22478 | +*/ |
| 22479 | +SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double x){ |
| 22480 | + u64 a; |
| 22481 | + LogEst e; |
| 22482 | + assert( sizeof(x)==8 && sizeof(a)==8 ); |
| 22483 | + if( x<=1 ) return 0; |
| 22484 | + if( x<=2000000000 ) return sqlite3LogEst((u64)x); |
| 22485 | + memcpy(&a, &x, 8); |
| 22486 | + e = (a>>52) - 1022; |
| 22487 | + return e*10; |
| 22488 | +} |
| 22489 | +#endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 22490 | + |
| 22491 | +/* |
| 22492 | +** Convert a LogEst into an integer. |
| 22493 | +*/ |
| 22494 | +SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst x){ |
| 22495 | + u64 n; |
| 22496 | + if( x<10 ) return 1; |
| 22497 | + n = x%10; |
| 22498 | + x /= 10; |
| 22499 | + if( n>=5 ) n -= 2; |
| 22500 | + else if( n>=1 ) n -= 1; |
| 22501 | + if( x>=3 ) return (n+8)<<(x-3); |
| 22502 | + return (n+8)>>(3-x); |
| 22503 | +} |
| 22392 | 22504 | |
| 22393 | 22505 | /************** End of util.c ************************************************/ |
| 22394 | 22506 | /************** Begin file hash.c ********************************************/ |
| 22395 | 22507 | /* |
| 22396 | 22508 | ** 2001 September 22 |
| | @@ -48986,17 +49098,17 @@ |
| 48986 | 49098 | ** page contain a special header (the "file header") that describes the file. |
| 48987 | 49099 | ** The format of the file header is as follows: |
| 48988 | 49100 | ** |
| 48989 | 49101 | ** OFFSET SIZE DESCRIPTION |
| 48990 | 49102 | ** 0 16 Header string: "SQLite format 3\000" |
| 48991 | | -** 16 2 Page size in bytes. |
| 49103 | +** 16 2 Page size in bytes. (1 means 65536) |
| 48992 | 49104 | ** 18 1 File format write version |
| 48993 | 49105 | ** 19 1 File format read version |
| 48994 | 49106 | ** 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 |
| 49107 | +** 21 1 Max embedded payload fraction (must be 64) |
| 49108 | +** 22 1 Min embedded payload fraction (must be 32) |
| 49109 | +** 23 1 Min leaf payload fraction (must be 32) |
| 48998 | 49110 | ** 24 4 File change counter |
| 48999 | 49111 | ** 28 4 Reserved for future use |
| 49000 | 49112 | ** 32 4 First freelist page |
| 49001 | 49113 | ** 36 4 Number of freelist pages in the file |
| 49002 | 49114 | ** 40 60 15 4-byte meta values passed to higher layers |
| | @@ -49006,13 +49118,14 @@ |
| 49006 | 49118 | ** 48 4 Size of page cache |
| 49007 | 49119 | ** 52 4 Largest root-page (auto/incr_vacuum) |
| 49008 | 49120 | ** 56 4 1=UTF-8 2=UTF16le 3=UTF16be |
| 49009 | 49121 | ** 60 4 User version |
| 49010 | 49122 | ** 64 4 Incremental vacuum mode |
| 49011 | | -** 68 4 unused |
| 49012 | | -** 72 4 unused |
| 49013 | | -** 76 4 unused |
| 49123 | +** 68 4 Application-ID |
| 49124 | +** 72 20 unused |
| 49125 | +** 92 4 The version-valid-for number |
| 49126 | +** 96 4 SQLITE_VERSION_NUMBER |
| 49014 | 49127 | ** |
| 49015 | 49128 | ** All of the integer values are big-endian (most significant byte first). |
| 49016 | 49129 | ** |
| 49017 | 49130 | ** The file change counter is incremented when the database is changed |
| 49018 | 49131 | ** This counter allows other processes to know when the file has changed |
| | @@ -52378,11 +52491,10 @@ |
| 52378 | 52491 | pBt->max1bytePayload = (u8)pBt->maxLocal; |
| 52379 | 52492 | } |
| 52380 | 52493 | assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) ); |
| 52381 | 52494 | pBt->pPage1 = pPage1; |
| 52382 | 52495 | pBt->nPage = nPage; |
| 52383 | | -assert( pPage1->leaf==0 || pPage1->leaf==1 ); |
| 52384 | 52496 | return SQLITE_OK; |
| 52385 | 52497 | |
| 52386 | 52498 | page1_init_failed: |
| 52387 | 52499 | releasePage(pPage1); |
| 52388 | 52500 | pBt->pPage1 = 0; |
| | @@ -52538,11 +52650,11 @@ |
| 52538 | 52650 | ** is requested, this is a no-op. |
| 52539 | 52651 | */ |
| 52540 | 52652 | if( p->inTrans==TRANS_WRITE || (p->inTrans==TRANS_READ && !wrflag) ){ |
| 52541 | 52653 | goto trans_begun; |
| 52542 | 52654 | } |
| 52543 | | - assert( IfNotOmitAV(pBt->bDoTruncate)==0 ); |
| 52655 | + assert( pBt->inTransaction==TRANS_WRITE || IfNotOmitAV(pBt->bDoTruncate)==0 ); |
| 52544 | 52656 | |
| 52545 | 52657 | /* Write transactions are not possible on a read-only database */ |
| 52546 | 52658 | if( (pBt->btsFlags & BTS_READ_ONLY)!=0 && wrflag ){ |
| 52547 | 52659 | rc = SQLITE_READONLY; |
| 52548 | 52660 | goto trans_begun; |
| | @@ -62977,10 +63089,11 @@ |
| 62977 | 63089 | } |
| 62978 | 63090 | fclose(out); |
| 62979 | 63091 | } |
| 62980 | 63092 | } |
| 62981 | 63093 | #endif |
| 63094 | + p->iCurrentTime = 0; |
| 62982 | 63095 | p->magic = VDBE_MAGIC_INIT; |
| 62983 | 63096 | return p->rc & db->errMask; |
| 62984 | 63097 | } |
| 62985 | 63098 | |
| 62986 | 63099 | /* |
| | @@ -76082,11 +76195,11 @@ |
| 76082 | 76195 | return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr); |
| 76083 | 76196 | } |
| 76084 | 76197 | #ifndef SQLITE_OMIT_CAST |
| 76085 | 76198 | if( op==TK_CAST ){ |
| 76086 | 76199 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); |
| 76087 | | - return sqlite3AffinityType(pExpr->u.zToken); |
| 76200 | + return sqlite3AffinityType(pExpr->u.zToken, 0); |
| 76088 | 76201 | } |
| 76089 | 76202 | #endif |
| 76090 | 76203 | if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER) |
| 76091 | 76204 | && pExpr->pTab!=0 |
| 76092 | 76205 | ){ |
| | @@ -78502,11 +78615,11 @@ |
| 78502 | 78615 | case TK_CAST: { |
| 78503 | 78616 | /* Expressions of the form: CAST(pLeft AS token) */ |
| 78504 | 78617 | int aff, to_op; |
| 78505 | 78618 | inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); |
| 78506 | 78619 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); |
| 78507 | | - aff = sqlite3AffinityType(pExpr->u.zToken); |
| 78620 | + aff = sqlite3AffinityType(pExpr->u.zToken, 0); |
| 78508 | 78621 | to_op = aff - SQLITE_AFF_TEXT + OP_ToText; |
| 78509 | 78622 | assert( to_op==OP_ToText || aff!=SQLITE_AFF_TEXT ); |
| 78510 | 78623 | assert( to_op==OP_ToBlob || aff!=SQLITE_AFF_NONE ); |
| 78511 | 78624 | assert( to_op==OP_ToNumeric || aff!=SQLITE_AFF_NUMERIC ); |
| 78512 | 78625 | assert( to_op==OP_ToInt || aff!=SQLITE_AFF_INTEGER ); |
| | @@ -79169,11 +79282,11 @@ |
| 79169 | 79282 | } |
| 79170 | 79283 | #ifndef SQLITE_OMIT_CAST |
| 79171 | 79284 | case TK_CAST: { |
| 79172 | 79285 | /* Expressions of the form: CAST(pLeft AS token) */ |
| 79173 | 79286 | const char *zAff = "unk"; |
| 79174 | | - switch( sqlite3AffinityType(pExpr->u.zToken) ){ |
| 79287 | + switch( sqlite3AffinityType(pExpr->u.zToken, 0) ){ |
| 79175 | 79288 | case SQLITE_AFF_TEXT: zAff = "TEXT"; break; |
| 79176 | 79289 | case SQLITE_AFF_NONE: zAff = "NONE"; break; |
| 79177 | 79290 | case SQLITE_AFF_NUMERIC: zAff = "NUMERIC"; break; |
| 79178 | 79291 | case SQLITE_AFF_INTEGER: zAff = "INTEGER"; break; |
| 79179 | 79292 | case SQLITE_AFF_REAL: zAff = "REAL"; break; |
| | @@ -81884,16 +81997,16 @@ |
| 81884 | 81997 | if( zRet==0 ){ |
| 81885 | 81998 | sqlite3_result_error_nomem(context); |
| 81886 | 81999 | return; |
| 81887 | 82000 | } |
| 81888 | 82001 | |
| 81889 | | - sqlite3_snprintf(24, zRet, "%lld", p->nRow); |
| 82002 | + sqlite3_snprintf(24, zRet, "%llu", (u64)p->nRow); |
| 81890 | 82003 | z = zRet + sqlite3Strlen30(zRet); |
| 81891 | 82004 | for(i=0; i<(p->nCol-1); i++){ |
| 81892 | | - i64 nDistinct = p->current.anDLt[i] + 1; |
| 81893 | | - i64 iVal = (p->nRow + nDistinct - 1) / nDistinct; |
| 81894 | | - sqlite3_snprintf(24, z, " %lld", iVal); |
| 82005 | + u64 nDistinct = p->current.anDLt[i] + 1; |
| 82006 | + u64 iVal = (p->nRow + nDistinct - 1) / nDistinct; |
| 82007 | + sqlite3_snprintf(24, z, " %llu", iVal); |
| 81895 | 82008 | z += sqlite3Strlen30(z); |
| 81896 | 82009 | assert( p->current.anEq[i] ); |
| 81897 | 82010 | } |
| 81898 | 82011 | assert( z[0]=='\0' && z>zRet ); |
| 81899 | 82012 | |
| | @@ -81930,11 +82043,11 @@ |
| 81930 | 82043 | sqlite3_result_error_nomem(context); |
| 81931 | 82044 | }else{ |
| 81932 | 82045 | int i; |
| 81933 | 82046 | char *z = zRet; |
| 81934 | 82047 | for(i=0; i<p->nCol; i++){ |
| 81935 | | - sqlite3_snprintf(24, z, "%lld ", aCnt[i]); |
| 82048 | + sqlite3_snprintf(24, z, "%llu ", (u64)aCnt[i]); |
| 81936 | 82049 | z += sqlite3Strlen30(z); |
| 81937 | 82050 | } |
| 81938 | 82051 | assert( z[0]=='\0' && z>zRet ); |
| 81939 | 82052 | z[-1] = '\0'; |
| 81940 | 82053 | sqlite3_result_text(context, zRet, -1, sqlite3_free); |
| | @@ -82391,22 +82504,20 @@ |
| 82391 | 82504 | ** The first argument points to a nul-terminated string containing a |
| 82392 | 82505 | ** list of space separated integers. Read the first nOut of these into |
| 82393 | 82506 | ** the array aOut[]. |
| 82394 | 82507 | */ |
| 82395 | 82508 | static void decodeIntArray( |
| 82396 | | - char *zIntArray, |
| 82397 | | - int nOut, |
| 82398 | | - tRowcnt *aOut, |
| 82399 | | - int *pbUnordered |
| 82509 | + char *zIntArray, /* String containing int array to decode */ |
| 82510 | + int nOut, /* Number of slots in aOut[] */ |
| 82511 | + tRowcnt *aOut, /* Store integers here */ |
| 82512 | + Index *pIndex /* Handle extra flags for this index, if not NULL */ |
| 82400 | 82513 | ){ |
| 82401 | 82514 | char *z = zIntArray; |
| 82402 | 82515 | int c; |
| 82403 | 82516 | int i; |
| 82404 | 82517 | tRowcnt v; |
| 82405 | 82518 | |
| 82406 | | - assert( pbUnordered==0 || *pbUnordered==0 ); |
| 82407 | | - |
| 82408 | 82519 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 82409 | 82520 | if( z==0 ) z = ""; |
| 82410 | 82521 | #else |
| 82411 | 82522 | if( NEVER(z==0) ) z = ""; |
| 82412 | 82523 | #endif |
| | @@ -82417,12 +82528,23 @@ |
| 82417 | 82528 | z++; |
| 82418 | 82529 | } |
| 82419 | 82530 | aOut[i] = v; |
| 82420 | 82531 | if( *z==' ' ) z++; |
| 82421 | 82532 | } |
| 82422 | | - if( pbUnordered && strcmp(z, "unordered")==0 ){ |
| 82423 | | - *pbUnordered = 1; |
| 82533 | +#ifndef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 82534 | + assert( pIndex!=0 ); |
| 82535 | +#else |
| 82536 | + if( pIndex ) |
| 82537 | +#endif |
| 82538 | + { |
| 82539 | + if( strcmp(z, "unordered")==0 ){ |
| 82540 | + pIndex->bUnordered = 1; |
| 82541 | + }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){ |
| 82542 | + int v32 = 0; |
| 82543 | + sqlite3GetInt32(z+3, &v32); |
| 82544 | + pIndex->szIdxRow = sqlite3LogEst(v32); |
| 82545 | + } |
| 82424 | 82546 | } |
| 82425 | 82547 | } |
| 82426 | 82548 | |
| 82427 | 82549 | /* |
| 82428 | 82550 | ** This callback is invoked once for each index when reading the |
| | @@ -82457,16 +82579,17 @@ |
| 82457 | 82579 | pIndex = 0; |
| 82458 | 82580 | } |
| 82459 | 82581 | z = argv[2]; |
| 82460 | 82582 | |
| 82461 | 82583 | if( pIndex ){ |
| 82462 | | - int bUnordered = 0; |
| 82463 | | - decodeIntArray((char*)z, pIndex->nColumn+1, pIndex->aiRowEst,&bUnordered); |
| 82584 | + decodeIntArray((char*)z, pIndex->nColumn+1, pIndex->aiRowEst, pIndex); |
| 82464 | 82585 | if( pIndex->pPartIdxWhere==0 ) pTable->nRowEst = pIndex->aiRowEst[0]; |
| 82465 | | - pIndex->bUnordered = bUnordered; |
| 82466 | 82586 | }else{ |
| 82467 | | - decodeIntArray((char*)z, 1, &pTable->nRowEst, 0); |
| 82587 | + Index fakeIdx; |
| 82588 | + fakeIdx.szIdxRow = pTable->szTabRow; |
| 82589 | + decodeIntArray((char*)z, 1, &pTable->nRowEst, &fakeIdx); |
| 82590 | + pTable->szTabRow = fakeIdx.szIdxRow; |
| 82468 | 82591 | } |
| 82469 | 82592 | |
| 82470 | 82593 | return 0; |
| 82471 | 82594 | } |
| 82472 | 82595 | |
| | @@ -83185,32 +83308,28 @@ |
| 83185 | 83308 | #endif /* SQLITE_OMIT_ATTACH */ |
| 83186 | 83309 | |
| 83187 | 83310 | /* |
| 83188 | 83311 | ** Initialize a DbFixer structure. This routine must be called prior |
| 83189 | 83312 | ** 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 | 83313 | */ |
| 83194 | | -SQLITE_PRIVATE int sqlite3FixInit( |
| 83314 | +SQLITE_PRIVATE void sqlite3FixInit( |
| 83195 | 83315 | DbFixer *pFix, /* The fixer to be initialized */ |
| 83196 | 83316 | Parse *pParse, /* Error messages will be written here */ |
| 83197 | 83317 | int iDb, /* This is the database that must be used */ |
| 83198 | 83318 | const char *zType, /* "view", "trigger", or "index" */ |
| 83199 | 83319 | const Token *pName /* Name of the view, trigger, or index */ |
| 83200 | 83320 | ){ |
| 83201 | 83321 | sqlite3 *db; |
| 83202 | 83322 | |
| 83203 | | - if( NEVER(iDb<0) || iDb==1 ) return 0; |
| 83204 | 83323 | db = pParse->db; |
| 83205 | 83324 | assert( db->nDb>iDb ); |
| 83206 | 83325 | pFix->pParse = pParse; |
| 83207 | 83326 | pFix->zDb = db->aDb[iDb].zName; |
| 83208 | 83327 | pFix->pSchema = db->aDb[iDb].pSchema; |
| 83209 | 83328 | pFix->zType = zType; |
| 83210 | 83329 | pFix->pName = pName; |
| 83211 | | - return 1; |
| 83330 | + pFix->bVarOnly = (iDb==1); |
| 83212 | 83331 | } |
| 83213 | 83332 | |
| 83214 | 83333 | /* |
| 83215 | 83334 | ** The following set of routines walk through the parse tree and assign |
| 83216 | 83335 | ** a specific database to all table references where the database name |
| | @@ -83234,19 +83353,21 @@ |
| 83234 | 83353 | struct SrcList_item *pItem; |
| 83235 | 83354 | |
| 83236 | 83355 | if( NEVER(pList==0) ) return 0; |
| 83237 | 83356 | zDb = pFix->zDb; |
| 83238 | 83357 | 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; |
| 83358 | + if( pFix->bVarOnly==0 ){ |
| 83359 | + if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){ |
| 83360 | + sqlite3ErrorMsg(pFix->pParse, |
| 83361 | + "%s %T cannot reference objects in database %s", |
| 83362 | + pFix->zType, pFix->pName, pItem->zDatabase); |
| 83363 | + return 1; |
| 83364 | + } |
| 83365 | + sqlite3DbFree(pFix->pParse->db, pItem->zDatabase); |
| 83366 | + pItem->zDatabase = 0; |
| 83367 | + pItem->pSchema = pFix->pSchema; |
| 83368 | + } |
| 83248 | 83369 | #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) |
| 83249 | 83370 | if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1; |
| 83250 | 83371 | if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1; |
| 83251 | 83372 | #endif |
| 83252 | 83373 | } |
| | @@ -83264,13 +83385,25 @@ |
| 83264 | 83385 | if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){ |
| 83265 | 83386 | return 1; |
| 83266 | 83387 | } |
| 83267 | 83388 | if( sqlite3FixExpr(pFix, pSelect->pWhere) ){ |
| 83268 | 83389 | return 1; |
| 83390 | + } |
| 83391 | + if( sqlite3FixExprList(pFix, pSelect->pGroupBy) ){ |
| 83392 | + return 1; |
| 83269 | 83393 | } |
| 83270 | 83394 | if( sqlite3FixExpr(pFix, pSelect->pHaving) ){ |
| 83271 | 83395 | return 1; |
| 83396 | + } |
| 83397 | + if( sqlite3FixExprList(pFix, pSelect->pOrderBy) ){ |
| 83398 | + return 1; |
| 83399 | + } |
| 83400 | + if( sqlite3FixExpr(pFix, pSelect->pLimit) ){ |
| 83401 | + return 1; |
| 83402 | + } |
| 83403 | + if( sqlite3FixExpr(pFix, pSelect->pOffset) ){ |
| 83404 | + return 1; |
| 83272 | 83405 | } |
| 83273 | 83406 | pSelect = pSelect->pPrior; |
| 83274 | 83407 | } |
| 83275 | 83408 | return 0; |
| 83276 | 83409 | } |
| | @@ -83277,10 +83410,18 @@ |
| 83277 | 83410 | SQLITE_PRIVATE int sqlite3FixExpr( |
| 83278 | 83411 | DbFixer *pFix, /* Context of the fixation */ |
| 83279 | 83412 | Expr *pExpr /* The expression to be fixed to one database */ |
| 83280 | 83413 | ){ |
| 83281 | 83414 | while( pExpr ){ |
| 83415 | + if( pExpr->op==TK_VARIABLE ){ |
| 83416 | + if( pFix->pParse->db->init.busy ){ |
| 83417 | + pExpr->op = TK_NULL; |
| 83418 | + }else{ |
| 83419 | + sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType); |
| 83420 | + return 1; |
| 83421 | + } |
| 83422 | + } |
| 83282 | 83423 | if( ExprHasProperty(pExpr, EP_TokenOnly) ) break; |
| 83283 | 83424 | if( ExprHasProperty(pExpr, EP_xIsSelect) ){ |
| 83284 | 83425 | if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1; |
| 83285 | 83426 | }else{ |
| 83286 | 83427 | if( sqlite3FixExprList(pFix, pExpr->x.pList) ) return 1; |
| | @@ -84460,11 +84601,11 @@ |
| 84460 | 84601 | } |
| 84461 | 84602 | pTable->zName = zName; |
| 84462 | 84603 | pTable->iPKey = -1; |
| 84463 | 84604 | pTable->pSchema = db->aDb[iDb].pSchema; |
| 84464 | 84605 | pTable->nRef = 1; |
| 84465 | | - pTable->nRowEst = 1000000; |
| 84606 | + pTable->nRowEst = 1048576; |
| 84466 | 84607 | assert( pParse->pNewTable==0 ); |
| 84467 | 84608 | pParse->pNewTable = pTable; |
| 84468 | 84609 | |
| 84469 | 84610 | /* If this is the magic sqlite_sequence table used by autoincrement, |
| 84470 | 84611 | ** then record a pointer to this table in the main database structure |
| | @@ -84607,10 +84748,11 @@ |
| 84607 | 84748 | /* If there is no type specified, columns have the default affinity |
| 84608 | 84749 | ** 'NONE'. If there is a type specified, then sqlite3AddColumnType() will |
| 84609 | 84750 | ** be called next to set pCol->affinity correctly. |
| 84610 | 84751 | */ |
| 84611 | 84752 | pCol->affinity = SQLITE_AFF_NONE; |
| 84753 | + pCol->szEst = 1; |
| 84612 | 84754 | p->nCol++; |
| 84613 | 84755 | } |
| 84614 | 84756 | |
| 84615 | 84757 | /* |
| 84616 | 84758 | ** This routine is called by the parser while in the middle of |
| | @@ -84648,26 +84790,30 @@ |
| 84648 | 84790 | ** 'DOUB' | SQLITE_AFF_REAL |
| 84649 | 84791 | ** |
| 84650 | 84792 | ** If none of the substrings in the above table are found, |
| 84651 | 84793 | ** SQLITE_AFF_NUMERIC is returned. |
| 84652 | 84794 | */ |
| 84653 | | -SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn){ |
| 84795 | +SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn, u8 *pszEst){ |
| 84654 | 84796 | u32 h = 0; |
| 84655 | 84797 | char aff = SQLITE_AFF_NUMERIC; |
| 84798 | + const char *zChar = 0; |
| 84656 | 84799 | |
| 84657 | | - if( zIn ) while( zIn[0] ){ |
| 84800 | + if( zIn==0 ) return aff; |
| 84801 | + while( zIn[0] ){ |
| 84658 | 84802 | h = (h<<8) + sqlite3UpperToLower[(*zIn)&0xff]; |
| 84659 | 84803 | zIn++; |
| 84660 | 84804 | if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){ /* CHAR */ |
| 84661 | | - aff = SQLITE_AFF_TEXT; |
| 84805 | + aff = SQLITE_AFF_TEXT; |
| 84806 | + zChar = zIn; |
| 84662 | 84807 | }else if( h==(('c'<<24)+('l'<<16)+('o'<<8)+'b') ){ /* CLOB */ |
| 84663 | 84808 | aff = SQLITE_AFF_TEXT; |
| 84664 | 84809 | }else if( h==(('t'<<24)+('e'<<16)+('x'<<8)+'t') ){ /* TEXT */ |
| 84665 | 84810 | aff = SQLITE_AFF_TEXT; |
| 84666 | 84811 | }else if( h==(('b'<<24)+('l'<<16)+('o'<<8)+'b') /* BLOB */ |
| 84667 | 84812 | && (aff==SQLITE_AFF_NUMERIC || aff==SQLITE_AFF_REAL) ){ |
| 84668 | 84813 | aff = SQLITE_AFF_NONE; |
| 84814 | + if( zIn[0]=='(' ) zChar = zIn; |
| 84669 | 84815 | #ifndef SQLITE_OMIT_FLOATING_POINT |
| 84670 | 84816 | }else if( h==(('r'<<24)+('e'<<16)+('a'<<8)+'l') /* REAL */ |
| 84671 | 84817 | && aff==SQLITE_AFF_NUMERIC ){ |
| 84672 | 84818 | aff = SQLITE_AFF_REAL; |
| 84673 | 84819 | }else if( h==(('f'<<24)+('l'<<16)+('o'<<8)+'a') /* FLOA */ |
| | @@ -84681,10 +84827,32 @@ |
| 84681 | 84827 | aff = SQLITE_AFF_INTEGER; |
| 84682 | 84828 | break; |
| 84683 | 84829 | } |
| 84684 | 84830 | } |
| 84685 | 84831 | |
| 84832 | + /* If pszEst is not NULL, store an estimate of the field size. The |
| 84833 | + ** estimate is scaled so that the size of an integer is 1. */ |
| 84834 | + if( pszEst ){ |
| 84835 | + *pszEst = 1; /* default size is approx 4 bytes */ |
| 84836 | + if( aff<=SQLITE_AFF_NONE ){ |
| 84837 | + if( zChar ){ |
| 84838 | + while( zChar[0] ){ |
| 84839 | + if( sqlite3Isdigit(zChar[0]) ){ |
| 84840 | + int v; |
| 84841 | + sqlite3GetInt32(zChar, &v); |
| 84842 | + v = v/4 + 1; |
| 84843 | + if( v>255 ) v = 255; |
| 84844 | + *pszEst = v; /* BLOB(k), VARCHAR(k), CHAR(k) -> r=(k/4+1) */ |
| 84845 | + break; |
| 84846 | + } |
| 84847 | + zChar++; |
| 84848 | + } |
| 84849 | + }else{ |
| 84850 | + *pszEst = 5; /* BLOB, TEXT, CLOB -> r=5 (approx 20 bytes)*/ |
| 84851 | + } |
| 84852 | + } |
| 84853 | + } |
| 84686 | 84854 | return aff; |
| 84687 | 84855 | } |
| 84688 | 84856 | |
| 84689 | 84857 | /* |
| 84690 | 84858 | ** This routine is called by the parser while in the middle of |
| | @@ -84702,11 +84870,11 @@ |
| 84702 | 84870 | p = pParse->pNewTable; |
| 84703 | 84871 | if( p==0 || NEVER(p->nCol<1) ) return; |
| 84704 | 84872 | pCol = &p->aCol[p->nCol-1]; |
| 84705 | 84873 | assert( pCol->zType==0 ); |
| 84706 | 84874 | pCol->zType = sqlite3NameFromToken(pParse->db, pType); |
| 84707 | | - pCol->affinity = sqlite3AffinityType(pCol->zType); |
| 84875 | + pCol->affinity = sqlite3AffinityType(pCol->zType, &pCol->szEst); |
| 84708 | 84876 | } |
| 84709 | 84877 | |
| 84710 | 84878 | /* |
| 84711 | 84879 | ** The expression is the default value for the most recently added column |
| 84712 | 84880 | ** of the table currently under construction. |
| | @@ -85050,18 +85218,46 @@ |
| 85050 | 85218 | testcase( pCol->affinity==SQLITE_AFF_REAL ); |
| 85051 | 85219 | |
| 85052 | 85220 | zType = azType[pCol->affinity - SQLITE_AFF_TEXT]; |
| 85053 | 85221 | len = sqlite3Strlen30(zType); |
| 85054 | 85222 | assert( pCol->affinity==SQLITE_AFF_NONE |
| 85055 | | - || pCol->affinity==sqlite3AffinityType(zType) ); |
| 85223 | + || pCol->affinity==sqlite3AffinityType(zType, 0) ); |
| 85056 | 85224 | memcpy(&zStmt[k], zType, len); |
| 85057 | 85225 | k += len; |
| 85058 | 85226 | assert( k<=n ); |
| 85059 | 85227 | } |
| 85060 | 85228 | sqlite3_snprintf(n-k, &zStmt[k], "%s", zEnd); |
| 85061 | 85229 | return zStmt; |
| 85062 | 85230 | } |
| 85231 | + |
| 85232 | +/* |
| 85233 | +** Estimate the total row width for a table. |
| 85234 | +*/ |
| 85235 | +static void estimateTableWidth(Table *pTab){ |
| 85236 | + unsigned wTable = 0; |
| 85237 | + const Column *pTabCol; |
| 85238 | + int i; |
| 85239 | + for(i=pTab->nCol, pTabCol=pTab->aCol; i>0; i--, pTabCol++){ |
| 85240 | + wTable += pTabCol->szEst; |
| 85241 | + } |
| 85242 | + if( pTab->iPKey<0 ) wTable++; |
| 85243 | + pTab->szTabRow = sqlite3LogEst(wTable*4); |
| 85244 | +} |
| 85245 | + |
| 85246 | +/* |
| 85247 | +** Estimate the average size of a row for an index. |
| 85248 | +*/ |
| 85249 | +static void estimateIndexWidth(Index *pIdx){ |
| 85250 | + unsigned wIndex = 1; |
| 85251 | + int i; |
| 85252 | + const Column *aCol = pIdx->pTable->aCol; |
| 85253 | + for(i=0; i<pIdx->nColumn; i++){ |
| 85254 | + assert( pIdx->aiColumn[i]>=0 && pIdx->aiColumn[i]<pIdx->pTable->nCol ); |
| 85255 | + wIndex += aCol[pIdx->aiColumn[i]].szEst; |
| 85256 | + } |
| 85257 | + pIdx->szIdxRow = sqlite3LogEst(wIndex*4); |
| 85258 | +} |
| 85063 | 85259 | |
| 85064 | 85260 | /* |
| 85065 | 85261 | ** This routine is called to report the final ")" that terminates |
| 85066 | 85262 | ** a CREATE TABLE statement. |
| 85067 | 85263 | ** |
| | @@ -85085,13 +85281,14 @@ |
| 85085 | 85281 | Parse *pParse, /* Parse context */ |
| 85086 | 85282 | Token *pCons, /* The ',' token after the last column defn. */ |
| 85087 | 85283 | Token *pEnd, /* The final ')' token in the CREATE TABLE */ |
| 85088 | 85284 | Select *pSelect /* Select from a "CREATE ... AS SELECT" */ |
| 85089 | 85285 | ){ |
| 85090 | | - Table *p; |
| 85091 | | - sqlite3 *db = pParse->db; |
| 85092 | | - int iDb; |
| 85286 | + Table *p; /* The new table */ |
| 85287 | + sqlite3 *db = pParse->db; /* The database connection */ |
| 85288 | + int iDb; /* Database in which the table lives */ |
| 85289 | + Index *pIdx; /* An implied index of the table */ |
| 85093 | 85290 | |
| 85094 | 85291 | if( (pEnd==0 && pSelect==0) || db->mallocFailed ){ |
| 85095 | 85292 | return; |
| 85096 | 85293 | } |
| 85097 | 85294 | p = pParse->pNewTable; |
| | @@ -85106,10 +85303,16 @@ |
| 85106 | 85303 | */ |
| 85107 | 85304 | if( p->pCheck ){ |
| 85108 | 85305 | sqlite3ResolveSelfReference(pParse, p, NC_IsCheck, 0, p->pCheck); |
| 85109 | 85306 | } |
| 85110 | 85307 | #endif /* !defined(SQLITE_OMIT_CHECK) */ |
| 85308 | + |
| 85309 | + /* Estimate the average row size for the table and for all implied indices */ |
| 85310 | + estimateTableWidth(p); |
| 85311 | + for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 85312 | + estimateIndexWidth(pIdx); |
| 85313 | + } |
| 85111 | 85314 | |
| 85112 | 85315 | /* If the db->init.busy is 1 it means we are reading the SQL off the |
| 85113 | 85316 | ** "sqlite_master" or "sqlite_temp_master" table on the disk. |
| 85114 | 85317 | ** So do not write to the disk again. Extract the root page number |
| 85115 | 85318 | ** for the table from the db->init.newTnum field. (The page number |
| | @@ -85303,13 +85506,12 @@ |
| 85303 | 85506 | sqlite3SelectDelete(db, pSelect); |
| 85304 | 85507 | return; |
| 85305 | 85508 | } |
| 85306 | 85509 | sqlite3TwoPartName(pParse, pName1, pName2, &pName); |
| 85307 | 85510 | iDb = sqlite3SchemaToIndex(db, p->pSchema); |
| 85308 | | - if( sqlite3FixInit(&sFix, pParse, iDb, "view", pName) |
| 85309 | | - && sqlite3FixSelect(&sFix, pSelect) |
| 85310 | | - ){ |
| 85511 | + sqlite3FixInit(&sFix, pParse, iDb, "view", pName); |
| 85512 | + if( sqlite3FixSelect(&sFix, pSelect) ){ |
| 85311 | 85513 | sqlite3SelectDelete(db, pSelect); |
| 85312 | 85514 | return; |
| 85313 | 85515 | } |
| 85314 | 85516 | |
| 85315 | 85517 | /* Make a copy of the entire SELECT statement that defines the view. |
| | @@ -86066,13 +86268,14 @@ |
| 86066 | 86268 | sqlite3 *db = pParse->db; |
| 86067 | 86269 | Db *pDb; /* The specific table containing the indexed database */ |
| 86068 | 86270 | int iDb; /* Index of the database that is being written */ |
| 86069 | 86271 | Token *pName = 0; /* Unqualified name of the index to create */ |
| 86070 | 86272 | struct ExprList_item *pListItem; /* For looping over pList */ |
| 86071 | | - int nCol; |
| 86072 | | - int nExtra = 0; |
| 86073 | | - char *zExtra; |
| 86273 | + const Column *pTabCol; /* A column in the table */ |
| 86274 | + int nCol; /* Number of columns */ |
| 86275 | + int nExtra = 0; /* Space allocated for zExtra[] */ |
| 86276 | + char *zExtra; /* Extra space after the Index object */ |
| 86074 | 86277 | |
| 86075 | 86278 | assert( pParse->nErr==0 ); /* Never called with prior errors */ |
| 86076 | 86279 | if( db->mallocFailed || IN_DECLARE_VTAB ){ |
| 86077 | 86280 | goto exit_create_index; |
| 86078 | 86281 | } |
| | @@ -86105,13 +86308,12 @@ |
| 86105 | 86308 | iDb = 1; |
| 86106 | 86309 | } |
| 86107 | 86310 | } |
| 86108 | 86311 | #endif |
| 86109 | 86312 | |
| 86110 | | - if( sqlite3FixInit(&sFix, pParse, iDb, "index", pName) && |
| 86111 | | - sqlite3FixSrcList(&sFix, pTblName) |
| 86112 | | - ){ |
| 86313 | + sqlite3FixInit(&sFix, pParse, iDb, "index", pName); |
| 86314 | + if( sqlite3FixSrcList(&sFix, pTblName) ){ |
| 86113 | 86315 | /* Because the parser constructs pTblName from a single identifier, |
| 86114 | 86316 | ** sqlite3FixSrcList can never fail. */ |
| 86115 | 86317 | assert(0); |
| 86116 | 86318 | } |
| 86117 | 86319 | pTab = sqlite3LocateTableItem(pParse, 0, &pTblName->a[0]); |
| | @@ -86296,11 +86498,10 @@ |
| 86296 | 86498 | ** same column more than once cannot be an error because that would |
| 86297 | 86499 | ** break backwards compatibility - it needs to be a warning. |
| 86298 | 86500 | */ |
| 86299 | 86501 | for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){ |
| 86300 | 86502 | const char *zColName = pListItem->zName; |
| 86301 | | - Column *pTabCol; |
| 86302 | 86503 | int requestedSortOrder; |
| 86303 | 86504 | char *zColl; /* Collation sequence name */ |
| 86304 | 86505 | |
| 86305 | 86506 | for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){ |
| 86306 | 86507 | if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break; |
| | @@ -86333,10 +86534,11 @@ |
| 86333 | 86534 | requestedSortOrder = pListItem->sortOrder & sortOrderMask; |
| 86334 | 86535 | pIndex->aSortOrder[i] = (u8)requestedSortOrder; |
| 86335 | 86536 | if( pTab->aCol[j].notNull==0 ) pIndex->uniqNotNull = 0; |
| 86336 | 86537 | } |
| 86337 | 86538 | sqlite3DefaultRowEst(pIndex); |
| 86539 | + if( pParse->pNewTable==0 ) estimateIndexWidth(pIndex); |
| 86338 | 86540 | |
| 86339 | 86541 | if( pTab==pParse->pNewTable ){ |
| 86340 | 86542 | /* This routine has been called to create an automatic index as a |
| 86341 | 86543 | ** result of a PRIMARY KEY or UNIQUE clause on a column definition, or |
| 86342 | 86544 | ** a PRIMARY KEY or UNIQUE clause following the column definitions. |
| | @@ -88238,10 +88440,11 @@ |
| 88238 | 88440 | ** API function sqlite3_count_changes) to be set incorrectly. */ |
| 88239 | 88441 | if( rcauth==SQLITE_OK && pWhere==0 && !pTrigger && !IsVirtual(pTab) |
| 88240 | 88442 | && 0==sqlite3FkRequired(pParse, pTab, 0, 0) |
| 88241 | 88443 | ){ |
| 88242 | 88444 | assert( !isView ); |
| 88445 | + sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName); |
| 88243 | 88446 | sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt, |
| 88244 | 88447 | pTab->zName, P4_STATIC); |
| 88245 | 88448 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 88246 | 88449 | assert( pIdx->pSchema==pTab->pSchema ); |
| 88247 | 88450 | sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb); |
| | @@ -93487,10 +93690,11 @@ |
| 93487 | 93690 | (char*)pKey, P4_KEYINFO_HANDOFF); |
| 93488 | 93691 | VdbeComment((v, "%s", pSrcIdx->zName)); |
| 93489 | 93692 | pKey = sqlite3IndexKeyinfo(pParse, pDestIdx); |
| 93490 | 93693 | sqlite3VdbeAddOp4(v, OP_OpenWrite, iDest, pDestIdx->tnum, iDbDest, |
| 93491 | 93694 | (char*)pKey, P4_KEYINFO_HANDOFF); |
| 93695 | + sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR); |
| 93492 | 93696 | VdbeComment((v, "%s", pDestIdx->zName)); |
| 93493 | 93697 | addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); |
| 93494 | 93698 | sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, regData); |
| 93495 | 93699 | sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1); |
| 93496 | 93700 | sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); |
| | @@ -94974,181 +95178,363 @@ |
| 94974 | 95178 | #define PragTyp_HEXKEY 35 |
| 94975 | 95179 | #define PragTyp_KEY 36 |
| 94976 | 95180 | #define PragTyp_REKEY 37 |
| 94977 | 95181 | #define PragTyp_LOCK_STATUS 38 |
| 94978 | 95182 | #define PragTyp_PARSER_TRACE 39 |
| 95183 | +#define PragFlag_NeedSchema 0x01 |
| 94979 | 95184 | static const struct sPragmaNames { |
| 94980 | 95185 | const char *const zName; /* Name of pragma */ |
| 94981 | 95186 | u8 ePragTyp; /* PragTyp_XXX value */ |
| 95187 | + u8 mPragFlag; /* Zero or more PragFlag_XXX values */ |
| 94982 | 95188 | u32 iArg; /* Extra argument */ |
| 94983 | 95189 | } aPragmaNames[] = { |
| 94984 | 95190 | #if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD) |
| 94985 | | - { "activate_extensions", PragTyp_ACTIVATE_EXTENSIONS, 0 }, |
| 95191 | + { /* zName: */ "activate_extensions", |
| 95192 | + /* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS, |
| 95193 | + /* ePragFlag: */ 0, |
| 95194 | + /* iArg: */ 0 }, |
| 94986 | 95195 | #endif |
| 94987 | 95196 | #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) |
| 94988 | | - { "application_id", PragTyp_HEADER_VALUE, 0 }, |
| 95197 | + { /* zName: */ "application_id", |
| 95198 | + /* ePragTyp: */ PragTyp_HEADER_VALUE, |
| 95199 | + /* ePragFlag: */ 0, |
| 95200 | + /* iArg: */ 0 }, |
| 94989 | 95201 | #endif |
| 94990 | 95202 | #if !defined(SQLITE_OMIT_AUTOVACUUM) |
| 94991 | | - { "auto_vacuum", PragTyp_AUTO_VACUUM, 0 }, |
| 95203 | + { /* zName: */ "auto_vacuum", |
| 95204 | + /* ePragTyp: */ PragTyp_AUTO_VACUUM, |
| 95205 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95206 | + /* iArg: */ 0 }, |
| 94992 | 95207 | #endif |
| 94993 | 95208 | #if !defined(SQLITE_OMIT_AUTOMATIC_INDEX) |
| 94994 | | - { "automatic_index", PragTyp_FLAG, |
| 94995 | | - SQLITE_AutoIndex }, |
| 95209 | + { /* zName: */ "automatic_index", |
| 95210 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95211 | + /* ePragFlag: */ 0, |
| 95212 | + /* iArg: */ SQLITE_AutoIndex }, |
| 94996 | 95213 | #endif |
| 94997 | | - { "busy_timeout", PragTyp_BUSY_TIMEOUT, 0 }, |
| 95214 | + { /* zName: */ "busy_timeout", |
| 95215 | + /* ePragTyp: */ PragTyp_BUSY_TIMEOUT, |
| 95216 | + /* ePragFlag: */ 0, |
| 95217 | + /* iArg: */ 0 }, |
| 94998 | 95218 | #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 94999 | | - { "cache_size", PragTyp_CACHE_SIZE, 0 }, |
| 95219 | + { /* zName: */ "cache_size", |
| 95220 | + /* ePragTyp: */ PragTyp_CACHE_SIZE, |
| 95221 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95222 | + /* iArg: */ 0 }, |
| 95000 | 95223 | #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 }, |
| 95224 | + { /* zName: */ "cache_spill", |
| 95225 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95226 | + /* ePragFlag: */ 0, |
| 95227 | + /* iArg: */ SQLITE_CacheSpill }, |
| 95228 | + { /* zName: */ "case_sensitive_like", |
| 95229 | + /* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE, |
| 95230 | + /* ePragFlag: */ 0, |
| 95231 | + /* iArg: */ 0 }, |
| 95232 | + { /* zName: */ "checkpoint_fullfsync", |
| 95233 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95234 | + /* ePragFlag: */ 0, |
| 95235 | + /* iArg: */ SQLITE_CkptFullFSync }, |
| 95006 | 95236 | #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) |
| 95007 | | - { "collation_list", PragTyp_COLLATION_LIST, 0 }, |
| 95237 | + { /* zName: */ "collation_list", |
| 95238 | + /* ePragTyp: */ PragTyp_COLLATION_LIST, |
| 95239 | + /* ePragFlag: */ 0, |
| 95240 | + /* iArg: */ 0 }, |
| 95008 | 95241 | #endif |
| 95009 | 95242 | #if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS) |
| 95010 | | - { "compile_options", PragTyp_COMPILE_OPTIONS, 0 }, |
| 95243 | + { /* zName: */ "compile_options", |
| 95244 | + /* ePragTyp: */ PragTyp_COMPILE_OPTIONS, |
| 95245 | + /* ePragFlag: */ 0, |
| 95246 | + /* iArg: */ 0 }, |
| 95011 | 95247 | #endif |
| 95012 | | - { "count_changes", PragTyp_FLAG, |
| 95013 | | - SQLITE_CountRows }, |
| 95248 | + { /* zName: */ "count_changes", |
| 95249 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95250 | + /* ePragFlag: */ 0, |
| 95251 | + /* iArg: */ SQLITE_CountRows }, |
| 95014 | 95252 | #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN |
| 95015 | | - { "data_store_directory", PragTyp_DATA_STORE_DIRECTORY, 0 }, |
| 95253 | + { /* zName: */ "data_store_directory", |
| 95254 | + /* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY, |
| 95255 | + /* ePragFlag: */ 0, |
| 95256 | + /* iArg: */ 0 }, |
| 95016 | 95257 | #endif |
| 95017 | 95258 | #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) |
| 95018 | | - { "database_list", PragTyp_DATABASE_LIST, 0 }, |
| 95259 | + { /* zName: */ "database_list", |
| 95260 | + /* ePragTyp: */ PragTyp_DATABASE_LIST, |
| 95261 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95262 | + /* iArg: */ 0 }, |
| 95019 | 95263 | #endif |
| 95020 | 95264 | #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) |
| 95021 | | - { "default_cache_size", PragTyp_DEFAULT_CACHE_SIZE, 0 }, |
| 95265 | + { /* zName: */ "default_cache_size", |
| 95266 | + /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE, |
| 95267 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95268 | + /* iArg: */ 0 }, |
| 95022 | 95269 | #endif |
| 95023 | 95270 | #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) |
| 95024 | | - { "defer_foreign_keys", PragTyp_FLAG, |
| 95025 | | - SQLITE_DeferFKs }, |
| 95271 | + { /* zName: */ "defer_foreign_keys", |
| 95272 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95273 | + /* ePragFlag: */ 0, |
| 95274 | + /* iArg: */ SQLITE_DeferFKs }, |
| 95026 | 95275 | #endif |
| 95027 | | - { "empty_result_callbacks", PragTyp_FLAG, |
| 95028 | | - SQLITE_NullCallback }, |
| 95276 | + { /* zName: */ "empty_result_callbacks", |
| 95277 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95278 | + /* ePragFlag: */ 0, |
| 95279 | + /* iArg: */ SQLITE_NullCallback }, |
| 95029 | 95280 | #if !defined(SQLITE_OMIT_UTF16) |
| 95030 | | - { "encoding", PragTyp_ENCODING, 0 }, |
| 95281 | + { /* zName: */ "encoding", |
| 95282 | + /* ePragTyp: */ PragTyp_ENCODING, |
| 95283 | + /* ePragFlag: */ 0, |
| 95284 | + /* iArg: */ 0 }, |
| 95031 | 95285 | #endif |
| 95032 | 95286 | #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) |
| 95033 | | - { "foreign_key_check", PragTyp_FOREIGN_KEY_CHECK, 0 }, |
| 95287 | + { /* zName: */ "foreign_key_check", |
| 95288 | + /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK, |
| 95289 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95290 | + /* iArg: */ 0 }, |
| 95034 | 95291 | #endif |
| 95035 | 95292 | #if !defined(SQLITE_OMIT_FOREIGN_KEY) |
| 95036 | | - { "foreign_key_list", PragTyp_FOREIGN_KEY_LIST, 0 }, |
| 95293 | + { /* zName: */ "foreign_key_list", |
| 95294 | + /* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST, |
| 95295 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95296 | + /* iArg: */ 0 }, |
| 95037 | 95297 | #endif |
| 95038 | 95298 | #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) |
| 95039 | | - { "foreign_keys", PragTyp_FLAG, |
| 95040 | | - SQLITE_ForeignKeys }, |
| 95299 | + { /* zName: */ "foreign_keys", |
| 95300 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95301 | + /* ePragFlag: */ 0, |
| 95302 | + /* iArg: */ SQLITE_ForeignKeys }, |
| 95041 | 95303 | #endif |
| 95042 | 95304 | #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) |
| 95043 | | - { "freelist_count", PragTyp_HEADER_VALUE, 0 }, |
| 95305 | + { /* zName: */ "freelist_count", |
| 95306 | + /* ePragTyp: */ PragTyp_HEADER_VALUE, |
| 95307 | + /* ePragFlag: */ 0, |
| 95308 | + /* iArg: */ 0 }, |
| 95044 | 95309 | #endif |
| 95045 | | - { "full_column_names", PragTyp_FLAG, |
| 95046 | | - SQLITE_FullColNames }, |
| 95047 | | - { "fullfsync", PragTyp_FLAG, |
| 95048 | | - SQLITE_FullFSync }, |
| 95310 | + { /* zName: */ "full_column_names", |
| 95311 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95312 | + /* ePragFlag: */ 0, |
| 95313 | + /* iArg: */ SQLITE_FullColNames }, |
| 95314 | + { /* zName: */ "fullfsync", |
| 95315 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95316 | + /* ePragFlag: */ 0, |
| 95317 | + /* iArg: */ SQLITE_FullFSync }, |
| 95049 | 95318 | #if defined(SQLITE_HAS_CODEC) |
| 95050 | | - { "hexkey", PragTyp_HEXKEY, 0 }, |
| 95319 | + { /* zName: */ "hexkey", |
| 95320 | + /* ePragTyp: */ PragTyp_HEXKEY, |
| 95321 | + /* ePragFlag: */ 0, |
| 95322 | + /* iArg: */ 0 }, |
| 95323 | + { /* zName: */ "hexrekey", |
| 95324 | + /* ePragTyp: */ PragTyp_HEXKEY, |
| 95325 | + /* ePragFlag: */ 0, |
| 95326 | + /* iArg: */ 0 }, |
| 95051 | 95327 | #endif |
| 95052 | 95328 | #if !defined(SQLITE_OMIT_CHECK) |
| 95053 | | - { "ignore_check_constraints", PragTyp_FLAG, |
| 95054 | | - SQLITE_IgnoreChecks }, |
| 95329 | + { /* zName: */ "ignore_check_constraints", |
| 95330 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95331 | + /* ePragFlag: */ 0, |
| 95332 | + /* iArg: */ SQLITE_IgnoreChecks }, |
| 95055 | 95333 | #endif |
| 95056 | 95334 | #if !defined(SQLITE_OMIT_AUTOVACUUM) |
| 95057 | | - { "incremental_vacuum", PragTyp_INCREMENTAL_VACUUM, 0 }, |
| 95335 | + { /* zName: */ "incremental_vacuum", |
| 95336 | + /* ePragTyp: */ PragTyp_INCREMENTAL_VACUUM, |
| 95337 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95338 | + /* iArg: */ 0 }, |
| 95058 | 95339 | #endif |
| 95059 | 95340 | #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) |
| 95060 | | - { "index_info", PragTyp_INDEX_INFO, 0 }, |
| 95061 | | - { "index_list", PragTyp_INDEX_LIST, 0 }, |
| 95341 | + { /* zName: */ "index_info", |
| 95342 | + /* ePragTyp: */ PragTyp_INDEX_INFO, |
| 95343 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95344 | + /* iArg: */ 0 }, |
| 95345 | + { /* zName: */ "index_list", |
| 95346 | + /* ePragTyp: */ PragTyp_INDEX_LIST, |
| 95347 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95348 | + /* iArg: */ 0 }, |
| 95062 | 95349 | #endif |
| 95063 | 95350 | #if !defined(SQLITE_OMIT_INTEGRITY_CHECK) |
| 95064 | | - { "integrity_check", PragTyp_INTEGRITY_CHECK, 0 }, |
| 95351 | + { /* zName: */ "integrity_check", |
| 95352 | + /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, |
| 95353 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95354 | + /* iArg: */ 0 }, |
| 95065 | 95355 | #endif |
| 95066 | 95356 | #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 95067 | | - { "journal_mode", PragTyp_JOURNAL_MODE, 0 }, |
| 95068 | | - { "journal_size_limit", PragTyp_JOURNAL_SIZE_LIMIT, 0 }, |
| 95357 | + { /* zName: */ "journal_mode", |
| 95358 | + /* ePragTyp: */ PragTyp_JOURNAL_MODE, |
| 95359 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95360 | + /* iArg: */ 0 }, |
| 95361 | + { /* zName: */ "journal_size_limit", |
| 95362 | + /* ePragTyp: */ PragTyp_JOURNAL_SIZE_LIMIT, |
| 95363 | + /* ePragFlag: */ 0, |
| 95364 | + /* iArg: */ 0 }, |
| 95069 | 95365 | #endif |
| 95070 | 95366 | #if defined(SQLITE_HAS_CODEC) |
| 95071 | | - { "key", PragTyp_KEY, 0 }, |
| 95367 | + { /* zName: */ "key", |
| 95368 | + /* ePragTyp: */ PragTyp_KEY, |
| 95369 | + /* ePragFlag: */ 0, |
| 95370 | + /* iArg: */ 0 }, |
| 95072 | 95371 | #endif |
| 95073 | | - { "legacy_file_format", PragTyp_FLAG, |
| 95074 | | - SQLITE_LegacyFileFmt }, |
| 95372 | + { /* zName: */ "legacy_file_format", |
| 95373 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95374 | + /* ePragFlag: */ 0, |
| 95375 | + /* iArg: */ SQLITE_LegacyFileFmt }, |
| 95075 | 95376 | #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE |
| 95076 | | - { "lock_proxy_file", PragTyp_LOCK_PROXY_FILE, 0 }, |
| 95377 | + { /* zName: */ "lock_proxy_file", |
| 95378 | + /* ePragTyp: */ PragTyp_LOCK_PROXY_FILE, |
| 95379 | + /* ePragFlag: */ 0, |
| 95380 | + /* iArg: */ 0 }, |
| 95077 | 95381 | #endif |
| 95078 | 95382 | #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 }, |
| 95383 | + { /* zName: */ "lock_status", |
| 95384 | + /* ePragTyp: */ PragTyp_LOCK_STATUS, |
| 95385 | + /* ePragFlag: */ 0, |
| 95386 | + /* iArg: */ 0 }, |
| 95387 | +#endif |
| 95388 | +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 95389 | + { /* zName: */ "locking_mode", |
| 95390 | + /* ePragTyp: */ PragTyp_LOCKING_MODE, |
| 95391 | + /* ePragFlag: */ 0, |
| 95392 | + /* iArg: */ 0 }, |
| 95393 | + { /* zName: */ "max_page_count", |
| 95394 | + /* ePragTyp: */ PragTyp_PAGE_COUNT, |
| 95395 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95396 | + /* iArg: */ 0 }, |
| 95397 | + { /* zName: */ "mmap_size", |
| 95398 | + /* ePragTyp: */ PragTyp_MMAP_SIZE, |
| 95399 | + /* ePragFlag: */ 0, |
| 95400 | + /* iArg: */ 0 }, |
| 95401 | + { /* zName: */ "page_count", |
| 95402 | + /* ePragTyp: */ PragTyp_PAGE_COUNT, |
| 95403 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95404 | + /* iArg: */ 0 }, |
| 95405 | + { /* zName: */ "page_size", |
| 95406 | + /* ePragTyp: */ PragTyp_PAGE_SIZE, |
| 95407 | + /* ePragFlag: */ 0, |
| 95408 | + /* iArg: */ 0 }, |
| 95409 | +#endif |
| 95410 | +#if defined(SQLITE_DEBUG) |
| 95411 | + { /* zName: */ "parser_trace", |
| 95412 | + /* ePragTyp: */ PragTyp_PARSER_TRACE, |
| 95413 | + /* ePragFlag: */ 0, |
| 95414 | + /* iArg: */ 0 }, |
| 95415 | +#endif |
| 95416 | + { /* zName: */ "query_only", |
| 95417 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95418 | + /* ePragFlag: */ 0, |
| 95419 | + /* iArg: */ SQLITE_QueryOnly }, |
| 95420 | +#if !defined(SQLITE_OMIT_INTEGRITY_CHECK) |
| 95421 | + { /* zName: */ "quick_check", |
| 95422 | + /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, |
| 95423 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95424 | + /* iArg: */ 0 }, |
| 95425 | +#endif |
| 95426 | + { /* zName: */ "read_uncommitted", |
| 95427 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95428 | + /* ePragFlag: */ 0, |
| 95429 | + /* iArg: */ SQLITE_ReadUncommitted }, |
| 95430 | + { /* zName: */ "recursive_triggers", |
| 95431 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95432 | + /* ePragFlag: */ 0, |
| 95433 | + /* iArg: */ SQLITE_RecTriggers }, |
| 95434 | +#if defined(SQLITE_HAS_CODEC) |
| 95435 | + { /* zName: */ "rekey", |
| 95436 | + /* ePragTyp: */ PragTyp_REKEY, |
| 95437 | + /* ePragFlag: */ 0, |
| 95438 | + /* iArg: */ 0 }, |
| 95439 | +#endif |
| 95440 | + { /* zName: */ "reverse_unordered_selects", |
| 95441 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95442 | + /* ePragFlag: */ 0, |
| 95443 | + /* iArg: */ SQLITE_ReverseOrder }, |
| 95444 | +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) |
| 95445 | + { /* zName: */ "schema_version", |
| 95446 | + /* ePragTyp: */ PragTyp_HEADER_VALUE, |
| 95447 | + /* ePragFlag: */ 0, |
| 95448 | + /* iArg: */ 0 }, |
| 95449 | +#endif |
| 95450 | +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 95451 | + { /* zName: */ "secure_delete", |
| 95452 | + /* ePragTyp: */ PragTyp_SECURE_DELETE, |
| 95453 | + /* ePragFlag: */ 0, |
| 95454 | + /* iArg: */ 0 }, |
| 95455 | +#endif |
| 95456 | + { /* zName: */ "short_column_names", |
| 95457 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95458 | + /* ePragFlag: */ 0, |
| 95459 | + /* iArg: */ SQLITE_ShortColNames }, |
| 95460 | + { /* zName: */ "shrink_memory", |
| 95461 | + /* ePragTyp: */ PragTyp_SHRINK_MEMORY, |
| 95462 | + /* ePragFlag: */ 0, |
| 95463 | + /* iArg: */ 0 }, |
| 95464 | + { /* zName: */ "soft_heap_limit", |
| 95465 | + /* ePragTyp: */ PragTyp_SOFT_HEAP_LIMIT, |
| 95466 | + /* ePragFlag: */ 0, |
| 95467 | + /* iArg: */ 0 }, |
| 95468 | +#if defined(SQLITE_DEBUG) |
| 95469 | + { /* zName: */ "sql_trace", |
| 95470 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95471 | + /* ePragFlag: */ 0, |
| 95472 | + /* iArg: */ SQLITE_SqlTrace }, |
| 95473 | +#endif |
| 95474 | +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 95475 | + { /* zName: */ "synchronous", |
| 95476 | + /* ePragTyp: */ PragTyp_SYNCHRONOUS, |
| 95477 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95478 | + /* iArg: */ 0 }, |
| 95121 | 95479 | #endif |
| 95122 | 95480 | #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) |
| 95123 | | - { "table_info", PragTyp_TABLE_INFO, 0 }, |
| 95481 | + { /* zName: */ "table_info", |
| 95482 | + /* ePragTyp: */ PragTyp_TABLE_INFO, |
| 95483 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95484 | + /* iArg: */ 0 }, |
| 95124 | 95485 | #endif |
| 95125 | 95486 | #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 95126 | | - { "temp_store", PragTyp_TEMP_STORE, 0 }, |
| 95127 | | - { "temp_store_directory", PragTyp_TEMP_STORE_DIRECTORY, 0 }, |
| 95487 | + { /* zName: */ "temp_store", |
| 95488 | + /* ePragTyp: */ PragTyp_TEMP_STORE, |
| 95489 | + /* ePragFlag: */ 0, |
| 95490 | + /* iArg: */ 0 }, |
| 95491 | + { /* zName: */ "temp_store_directory", |
| 95492 | + /* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY, |
| 95493 | + /* ePragFlag: */ 0, |
| 95494 | + /* iArg: */ 0 }, |
| 95128 | 95495 | #endif |
| 95129 | 95496 | #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) |
| 95130 | | - { "user_version", PragTyp_HEADER_VALUE, 0 }, |
| 95497 | + { /* zName: */ "user_version", |
| 95498 | + /* ePragTyp: */ PragTyp_HEADER_VALUE, |
| 95499 | + /* ePragFlag: */ 0, |
| 95500 | + /* iArg: */ 0 }, |
| 95131 | 95501 | #endif |
| 95132 | 95502 | #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 }, |
| 95503 | + { /* zName: */ "vdbe_addoptrace", |
| 95504 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95505 | + /* ePragFlag: */ 0, |
| 95506 | + /* iArg: */ SQLITE_VdbeAddopTrace }, |
| 95507 | + { /* zName: */ "vdbe_debug", |
| 95508 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95509 | + /* ePragFlag: */ 0, |
| 95510 | + /* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace }, |
| 95511 | + { /* zName: */ "vdbe_listing", |
| 95512 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95513 | + /* ePragFlag: */ 0, |
| 95514 | + /* iArg: */ SQLITE_VdbeListing }, |
| 95515 | + { /* zName: */ "vdbe_trace", |
| 95516 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95517 | + /* ePragFlag: */ 0, |
| 95518 | + /* iArg: */ SQLITE_VdbeTrace }, |
| 95141 | 95519 | #endif |
| 95142 | 95520 | #if !defined(SQLITE_OMIT_WAL) |
| 95143 | | - { "wal_autocheckpoint", PragTyp_WAL_AUTOCHECKPOINT, 0 }, |
| 95144 | | - { "wal_checkpoint", PragTyp_WAL_CHECKPOINT, 0 }, |
| 95521 | + { /* zName: */ "wal_autocheckpoint", |
| 95522 | + /* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT, |
| 95523 | + /* ePragFlag: */ 0, |
| 95524 | + /* iArg: */ 0 }, |
| 95525 | + { /* zName: */ "wal_checkpoint", |
| 95526 | + /* ePragTyp: */ PragTyp_WAL_CHECKPOINT, |
| 95527 | + /* ePragFlag: */ PragFlag_NeedSchema, |
| 95528 | + /* iArg: */ 0 }, |
| 95145 | 95529 | #endif |
| 95146 | | - { "writable_schema", PragTyp_FLAG, |
| 95147 | | - SQLITE_WriteSchema|SQLITE_RecoveryMode }, |
| 95530 | + { /* zName: */ "writable_schema", |
| 95531 | + /* ePragTyp: */ PragTyp_FLAG, |
| 95532 | + /* ePragFlag: */ 0, |
| 95533 | + /* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode }, |
| 95148 | 95534 | }; |
| 95149 | | -/* Number of pragmas: 55 on by default, 66 total. */ |
| 95535 | +/* Number of pragmas: 55 on by default, 67 total. */ |
| 95150 | 95536 | /* End of the automatically generated pragma table. |
| 95151 | 95537 | ***************************************************************************/ |
| 95152 | 95538 | |
| 95153 | 95539 | /* |
| 95154 | 95540 | ** Interpret the given string as a safety level. Return 0 for OFF, |
| | @@ -95476,10 +95862,15 @@ |
| 95476 | 95862 | }else{ |
| 95477 | 95863 | lwr = mid + 1; |
| 95478 | 95864 | } |
| 95479 | 95865 | } |
| 95480 | 95866 | if( lwr>upr ) goto pragma_out; |
| 95867 | + |
| 95868 | + /* Make sure the database schema is loaded if the pragma requires that */ |
| 95869 | + if( (aPragmaNames[mid].mPragFlag & PragFlag_NeedSchema)!=0 ){ |
| 95870 | + if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 95871 | + } |
| 95481 | 95872 | |
| 95482 | 95873 | /* Jump to the appropriate pragma handler */ |
| 95483 | 95874 | switch( aPragmaNames[mid].ePragTyp ){ |
| 95484 | 95875 | |
| 95485 | 95876 | #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) |
| | @@ -95510,11 +95901,10 @@ |
| 95510 | 95901 | { OP_Integer, 0, 1, 0}, /* 6 */ |
| 95511 | 95902 | { OP_Noop, 0, 0, 0}, |
| 95512 | 95903 | { OP_ResultRow, 1, 1, 0}, |
| 95513 | 95904 | }; |
| 95514 | 95905 | int addr; |
| 95515 | | - if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 95516 | 95906 | sqlite3VdbeUsesBtree(v, iDb); |
| 95517 | 95907 | if( !zRight ){ |
| 95518 | 95908 | sqlite3VdbeSetNumCols(v, 1); |
| 95519 | 95909 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", SQLITE_STATIC); |
| 95520 | 95910 | pParse->nMem += 2; |
| | @@ -95606,11 +95996,10 @@ |
| 95606 | 95996 | ** |
| 95607 | 95997 | ** Return the number of pages in the specified database. |
| 95608 | 95998 | */ |
| 95609 | 95999 | case PragTyp_PAGE_COUNT: { |
| 95610 | 96000 | int iReg; |
| 95611 | | - if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 95612 | 96001 | sqlite3CodeVerifySchema(pParse, iDb); |
| 95613 | 96002 | iReg = ++pParse->nMem; |
| 95614 | 96003 | if( sqlite3Tolower(zLeft[0])=='p' ){ |
| 95615 | 96004 | sqlite3VdbeAddOp2(v, OP_Pagecount, iDb, iReg); |
| 95616 | 96005 | }else{ |
| | @@ -95679,18 +96068,10 @@ |
| 95679 | 96068 | */ |
| 95680 | 96069 | case PragTyp_JOURNAL_MODE: { |
| 95681 | 96070 | int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */ |
| 95682 | 96071 | int ii; /* Loop counter */ |
| 95683 | 96072 | |
| 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 | 96073 | sqlite3VdbeSetNumCols(v, 1); |
| 95693 | 96074 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "journal_mode", SQLITE_STATIC); |
| 95694 | 96075 | |
| 95695 | 96076 | if( zRight==0 ){ |
| 95696 | 96077 | /* If there is no "=MODE" part of the pragma, do a query for the |
| | @@ -95752,55 +96133,44 @@ |
| 95752 | 96133 | */ |
| 95753 | 96134 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| 95754 | 96135 | case PragTyp_AUTO_VACUUM: { |
| 95755 | 96136 | Btree *pBt = pDb->pBt; |
| 95756 | 96137 | assert( pBt!=0 ); |
| 95757 | | - if( sqlite3ReadSchema(pParse) ){ |
| 95758 | | - goto pragma_out; |
| 95759 | | - } |
| 95760 | 96138 | 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); |
| 96139 | + returnSingleInt(pParse, "auto_vacuum", sqlite3BtreeGetAutoVacuum(pBt)); |
| 95768 | 96140 | }else{ |
| 95769 | 96141 | int eAuto = getAutoVacuum(zRight); |
| 95770 | 96142 | assert( eAuto>=0 && eAuto<=2 ); |
| 95771 | 96143 | 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 | | - } |
| 96144 | + /* Call SetAutoVacuum() to set initialize the internal auto and |
| 96145 | + ** incr-vacuum flags. This is required in case this connection |
| 96146 | + ** creates the database file. It is important that it is created |
| 96147 | + ** as an auto-vacuum capable db. |
| 96148 | + */ |
| 96149 | + rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto); |
| 96150 | + if( rc==SQLITE_OK && (eAuto==1 || eAuto==2) ){ |
| 96151 | + /* When setting the auto_vacuum mode to either "full" or |
| 96152 | + ** "incremental", write the value of meta[6] in the database |
| 96153 | + ** file. Before writing to meta[6], check that meta[3] indicates |
| 96154 | + ** that this really is an auto-vacuum capable database. |
| 96155 | + */ |
| 96156 | + static const VdbeOpList setMeta6[] = { |
| 96157 | + { OP_Transaction, 0, 1, 0}, /* 0 */ |
| 96158 | + { OP_ReadCookie, 0, 1, BTREE_LARGEST_ROOT_PAGE}, |
| 96159 | + { OP_If, 1, 0, 0}, /* 2 */ |
| 96160 | + { OP_Halt, SQLITE_OK, OE_Abort, 0}, /* 3 */ |
| 96161 | + { OP_Integer, 0, 1, 0}, /* 4 */ |
| 96162 | + { OP_SetCookie, 0, BTREE_INCR_VACUUM, 1}, /* 5 */ |
| 96163 | + }; |
| 96164 | + int iAddr; |
| 96165 | + iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6); |
| 96166 | + sqlite3VdbeChangeP1(v, iAddr, iDb); |
| 96167 | + sqlite3VdbeChangeP1(v, iAddr+1, iDb); |
| 96168 | + sqlite3VdbeChangeP2(v, iAddr+2, iAddr+4); |
| 96169 | + sqlite3VdbeChangeP1(v, iAddr+4, eAuto-1); |
| 96170 | + sqlite3VdbeChangeP1(v, iAddr+5, iDb); |
| 96171 | + sqlite3VdbeUsesBtree(v, iDb); |
| 95802 | 96172 | } |
| 95803 | 96173 | } |
| 95804 | 96174 | break; |
| 95805 | 96175 | } |
| 95806 | 96176 | #endif |
| | @@ -95811,13 +96181,10 @@ |
| 95811 | 96181 | ** Do N steps of incremental vacuuming on a database. |
| 95812 | 96182 | */ |
| 95813 | 96183 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| 95814 | 96184 | case PragTyp_INCREMENTAL_VACUUM: { |
| 95815 | 96185 | int iLimit, addr; |
| 95816 | | - if( sqlite3ReadSchema(pParse) ){ |
| 95817 | | - goto pragma_out; |
| 95818 | | - } |
| 95819 | 96186 | if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){ |
| 95820 | 96187 | iLimit = 0x7fffffff; |
| 95821 | 96188 | } |
| 95822 | 96189 | sqlite3BeginWriteOperation(pParse, 0, iDb); |
| 95823 | 96190 | sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1); |
| | @@ -95841,11 +96208,10 @@ |
| 95841 | 96208 | ** number of pages in the cache. If N is negative, then the |
| 95842 | 96209 | ** number of pages is adjusted so that the cache uses -N kibibytes |
| 95843 | 96210 | ** of memory. |
| 95844 | 96211 | */ |
| 95845 | 96212 | case PragTyp_CACHE_SIZE: { |
| 95846 | | - if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 95847 | 96213 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 95848 | 96214 | if( !zRight ){ |
| 95849 | 96215 | returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size); |
| 95850 | 96216 | }else{ |
| 95851 | 96217 | int size = sqlite3Atoi(zRight); |
| | @@ -96062,11 +96428,10 @@ |
| 96062 | 96428 | ** the local value does not make changes to the disk file and the |
| 96063 | 96429 | ** default value will be restored the next time the database is |
| 96064 | 96430 | ** opened. |
| 96065 | 96431 | */ |
| 96066 | 96432 | case PragTyp_SYNCHRONOUS: { |
| 96067 | | - if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 96068 | 96433 | if( !zRight ){ |
| 96069 | 96434 | returnSingleInt(pParse, "synchronous", pDb->safety_level-1); |
| 96070 | 96435 | }else{ |
| 96071 | 96436 | if( !db->autoCommit ){ |
| 96072 | 96437 | sqlite3ErrorMsg(pParse, |
| | @@ -96124,11 +96489,10 @@ |
| 96124 | 96489 | ** notnull: True if 'NOT NULL' is part of column declaration |
| 96125 | 96490 | ** dflt_value: The default value for the column, if any. |
| 96126 | 96491 | */ |
| 96127 | 96492 | case PragTyp_TABLE_INFO: if( zRight ){ |
| 96128 | 96493 | Table *pTab; |
| 96129 | | - if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 96130 | 96494 | pTab = sqlite3FindTable(db, zRight, zDb); |
| 96131 | 96495 | if( pTab ){ |
| 96132 | 96496 | int i, k; |
| 96133 | 96497 | int nHidden = 0; |
| 96134 | 96498 | Column *pCol; |
| | @@ -96174,11 +96538,10 @@ |
| 96174 | 96538 | break; |
| 96175 | 96539 | |
| 96176 | 96540 | case PragTyp_INDEX_INFO: if( zRight ){ |
| 96177 | 96541 | Index *pIdx; |
| 96178 | 96542 | Table *pTab; |
| 96179 | | - if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 96180 | 96543 | pIdx = sqlite3FindIndex(db, zRight, zDb); |
| 96181 | 96544 | if( pIdx ){ |
| 96182 | 96545 | int i; |
| 96183 | 96546 | pTab = pIdx->pTable; |
| 96184 | 96547 | sqlite3VdbeSetNumCols(v, 3); |
| | @@ -96200,39 +96563,41 @@ |
| 96200 | 96563 | break; |
| 96201 | 96564 | |
| 96202 | 96565 | case PragTyp_INDEX_LIST: if( zRight ){ |
| 96203 | 96566 | Index *pIdx; |
| 96204 | 96567 | Table *pTab; |
| 96205 | | - if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 96568 | + int i; |
| 96206 | 96569 | pTab = sqlite3FindTable(db, zRight, zDb); |
| 96207 | 96570 | if( pTab ){ |
| 96208 | 96571 | v = sqlite3GetVdbe(pParse); |
| 96209 | | - pIdx = pTab->pIndex; |
| 96210 | | - if( pIdx ){ |
| 96211 | | - int i = 0; |
| 96212 | | - sqlite3VdbeSetNumCols(v, 3); |
| 96213 | | - pParse->nMem = 3; |
| 96214 | | - sqlite3CodeVerifySchema(pParse, iDb); |
| 96215 | | - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC); |
| 96216 | | - sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC); |
| 96217 | | - sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC); |
| 96218 | | - while(pIdx){ |
| 96219 | | - sqlite3VdbeAddOp2(v, OP_Integer, i, 1); |
| 96220 | | - sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0); |
| 96221 | | - sqlite3VdbeAddOp2(v, OP_Integer, pIdx->onError!=OE_None, 3); |
| 96222 | | - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); |
| 96223 | | - ++i; |
| 96224 | | - pIdx = pIdx->pNext; |
| 96225 | | - } |
| 96572 | + sqlite3VdbeSetNumCols(v, 4); |
| 96573 | + pParse->nMem = 4; |
| 96574 | + sqlite3CodeVerifySchema(pParse, iDb); |
| 96575 | + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC); |
| 96576 | + sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC); |
| 96577 | + sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC); |
| 96578 | + sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "avgrowsize", SQLITE_STATIC); |
| 96579 | + sqlite3VdbeAddOp2(v, OP_Integer, 0, 1); |
| 96580 | + sqlite3VdbeAddOp2(v, OP_Null, 0, 2); |
| 96581 | + sqlite3VdbeAddOp2(v, OP_Integer, 1, 3); |
| 96582 | + sqlite3VdbeAddOp2(v, OP_Integer, |
| 96583 | + (int)sqlite3LogEstToInt(pTab->szTabRow), 4); |
| 96584 | + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4); |
| 96585 | + for(pIdx=pTab->pIndex, i=1; pIdx; pIdx=pIdx->pNext, i++){ |
| 96586 | + sqlite3VdbeAddOp2(v, OP_Integer, i, 1); |
| 96587 | + sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0); |
| 96588 | + sqlite3VdbeAddOp2(v, OP_Integer, pIdx->onError!=OE_None, 3); |
| 96589 | + sqlite3VdbeAddOp2(v, OP_Integer, |
| 96590 | + (int)sqlite3LogEstToInt(pIdx->szIdxRow), 4); |
| 96591 | + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4); |
| 96226 | 96592 | } |
| 96227 | 96593 | } |
| 96228 | 96594 | } |
| 96229 | 96595 | break; |
| 96230 | 96596 | |
| 96231 | 96597 | case PragTyp_DATABASE_LIST: { |
| 96232 | 96598 | int i; |
| 96233 | | - if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 96234 | 96599 | sqlite3VdbeSetNumCols(v, 3); |
| 96235 | 96600 | pParse->nMem = 3; |
| 96236 | 96601 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC); |
| 96237 | 96602 | sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC); |
| 96238 | 96603 | sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "file", SQLITE_STATIC); |
| | @@ -96267,11 +96632,10 @@ |
| 96267 | 96632 | |
| 96268 | 96633 | #ifndef SQLITE_OMIT_FOREIGN_KEY |
| 96269 | 96634 | case PragTyp_FOREIGN_KEY_LIST: if( zRight ){ |
| 96270 | 96635 | FKey *pFK; |
| 96271 | 96636 | Table *pTab; |
| 96272 | | - if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 96273 | 96637 | pTab = sqlite3FindTable(db, zRight, zDb); |
| 96274 | 96638 | if( pTab ){ |
| 96275 | 96639 | v = sqlite3GetVdbe(pParse); |
| 96276 | 96640 | pFK = pTab->pFKey; |
| 96277 | 96641 | if( pFK ){ |
| | @@ -96329,11 +96693,10 @@ |
| 96329 | 96693 | int regRow; /* Registers to hold a row from pTab */ |
| 96330 | 96694 | int addrTop; /* Top of a loop checking foreign keys */ |
| 96331 | 96695 | int addrOk; /* Jump here if the key is OK */ |
| 96332 | 96696 | int *aiCols; /* child to parent column mapping */ |
| 96333 | 96697 | |
| 96334 | | - if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 96335 | 96698 | regResult = pParse->nMem+1; |
| 96336 | 96699 | pParse->nMem += 4; |
| 96337 | 96700 | regKey = ++pParse->nMem; |
| 96338 | 96701 | regRow = ++pParse->nMem; |
| 96339 | 96702 | v = sqlite3GetVdbe(pParse); |
| | @@ -96490,11 +96853,10 @@ |
| 96490 | 96853 | assert( iDb>=0 ); |
| 96491 | 96854 | assert( iDb==0 || pId2->z ); |
| 96492 | 96855 | if( pId2->z==0 ) iDb = -1; |
| 96493 | 96856 | |
| 96494 | 96857 | /* Initialize the VDBE program */ |
| 96495 | | - if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 96496 | 96858 | pParse->nMem = 6; |
| 96497 | 96859 | sqlite3VdbeSetNumCols(v, 1); |
| 96498 | 96860 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "integrity_check", SQLITE_STATIC); |
| 96499 | 96861 | |
| 96500 | 96862 | /* Set the maximum error count */ |
| | @@ -96814,11 +97176,10 @@ |
| 96814 | 97176 | eMode = SQLITE_CHECKPOINT_FULL; |
| 96815 | 97177 | }else if( sqlite3StrICmp(zRight, "restart")==0 ){ |
| 96816 | 97178 | eMode = SQLITE_CHECKPOINT_RESTART; |
| 96817 | 97179 | } |
| 96818 | 97180 | } |
| 96819 | | - if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 96820 | 97181 | sqlite3VdbeSetNumCols(v, 3); |
| 96821 | 97182 | pParse->nMem = 3; |
| 96822 | 97183 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "busy", SQLITE_STATIC); |
| 96823 | 97184 | sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "log", SQLITE_STATIC); |
| 96824 | 97185 | sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "checkpointed", SQLITE_STATIC); |
| | @@ -96934,16 +97295,16 @@ |
| 96934 | 97295 | if( zRight ) sqlite3_rekey_v2(db, zDb, zRight, sqlite3Strlen30(zRight)); |
| 96935 | 97296 | break; |
| 96936 | 97297 | } |
| 96937 | 97298 | case PragTyp_HEXKEY: { |
| 96938 | 97299 | if( zRight ){ |
| 96939 | | - int i, h1, h2; |
| 97300 | + u8 iByte; |
| 97301 | + int i; |
| 96940 | 97302 | 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); |
| 97303 | + for(i=0, iByte=0; i<sizeof(zKey)*2 && sqlite3Isxdigit(zRight[i]); i++){ |
| 97304 | + iByte = (iByte<<4) + sqlite3HexToInt(zRight[i]); |
| 97305 | + if( (i&1)!=0 ) zKey[i/2] = iByte; |
| 96945 | 97306 | } |
| 96946 | 97307 | if( (zLeft[3] & 0xf)==0xb ){ |
| 96947 | 97308 | sqlite3_key_v2(db, zDb, zKey, i/2); |
| 96948 | 97309 | }else{ |
| 96949 | 97310 | sqlite3_rekey_v2(db, zDb, zKey, i/2); |
| | @@ -98913,10 +99274,13 @@ |
| 98913 | 99274 | } |
| 98914 | 99275 | |
| 98915 | 99276 | /* |
| 98916 | 99277 | ** Return a pointer to a string containing the 'declaration type' of the |
| 98917 | 99278 | ** expression pExpr. The string may be treated as static by the caller. |
| 99279 | +** |
| 99280 | +** Also try to estimate the size of the returned value and return that |
| 99281 | +** result in *pEstWidth. |
| 98918 | 99282 | ** |
| 98919 | 99283 | ** The declaration type is the exact datatype definition extracted from the |
| 98920 | 99284 | ** original CREATE TABLE statement if the expression is a column. The |
| 98921 | 99285 | ** declaration type for a ROWID field is INTEGER. Exactly when an expression |
| 98922 | 99286 | ** is considered a column can be complex in the presence of subqueries. The |
| | @@ -98927,25 +99291,40 @@ |
| 98927 | 99291 | ** SELECT (SELECT col FROM tbl; |
| 98928 | 99292 | ** SELECT (SELECT col FROM tbl); |
| 98929 | 99293 | ** SELECT abc FROM (SELECT col AS abc FROM tbl); |
| 98930 | 99294 | ** |
| 98931 | 99295 | ** The declaration type for any expression other than a column is NULL. |
| 99296 | +** |
| 99297 | +** This routine has either 3 or 6 parameters depending on whether or not |
| 99298 | +** the SQLITE_ENABLE_COLUMN_METADATA compile-time option is used. |
| 98932 | 99299 | */ |
| 98933 | | -static const char *columnType( |
| 99300 | +#ifdef SQLITE_ENABLE_COLUMN_METADATA |
| 99301 | +# define columnType(A,B,C,D,E,F) columnTypeImpl(A,B,C,D,E,F) |
| 99302 | +static const char *columnTypeImpl( |
| 99303 | + NameContext *pNC, |
| 99304 | + Expr *pExpr, |
| 99305 | + const char **pzOrigDb, |
| 99306 | + const char **pzOrigTab, |
| 99307 | + const char **pzOrigCol, |
| 99308 | + u8 *pEstWidth |
| 99309 | +){ |
| 99310 | + char const *zOrigDb = 0; |
| 99311 | + char const *zOrigTab = 0; |
| 99312 | + char const *zOrigCol = 0; |
| 99313 | +#else /* if !defined(SQLITE_ENABLE_COLUMN_METADATA) */ |
| 99314 | +# define columnType(A,B,C,D,E,F) columnTypeImpl(A,B,F) |
| 99315 | +static const char *columnTypeImpl( |
| 98934 | 99316 | NameContext *pNC, |
| 98935 | 99317 | Expr *pExpr, |
| 98936 | | - const char **pzOriginDb, |
| 98937 | | - const char **pzOriginTab, |
| 98938 | | - const char **pzOriginCol |
| 99318 | + u8 *pEstWidth |
| 98939 | 99319 | ){ |
| 99320 | +#endif /* !defined(SQLITE_ENABLE_COLUMN_METADATA) */ |
| 98940 | 99321 | char const *zType = 0; |
| 98941 | | - char const *zOriginDb = 0; |
| 98942 | | - char const *zOriginTab = 0; |
| 98943 | | - char const *zOriginCol = 0; |
| 98944 | 99322 | int j; |
| 99323 | + u8 estWidth = 1; |
| 99324 | + |
| 98945 | 99325 | if( NEVER(pExpr==0) || pNC->pSrcList==0 ) return 0; |
| 98946 | | - |
| 98947 | 99326 | switch( pExpr->op ){ |
| 98948 | 99327 | case TK_AGG_COLUMN: |
| 98949 | 99328 | case TK_COLUMN: { |
| 98950 | 99329 | /* The expression is a column. Locate the table the column is being |
| 98951 | 99330 | ** extracted from in NameContext.pSrcList. This table may be real |
| | @@ -99002,29 +99381,39 @@ |
| 99002 | 99381 | NameContext sNC; |
| 99003 | 99382 | Expr *p = pS->pEList->a[iCol].pExpr; |
| 99004 | 99383 | sNC.pSrcList = pS->pSrc; |
| 99005 | 99384 | sNC.pNext = pNC; |
| 99006 | 99385 | sNC.pParse = pNC->pParse; |
| 99007 | | - zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol); |
| 99386 | + zType = columnType(&sNC, p,&zOrigDb,&zOrigTab,&zOrigCol, &estWidth); |
| 99008 | 99387 | } |
| 99009 | 99388 | }else if( ALWAYS(pTab->pSchema) ){ |
| 99010 | 99389 | /* A real table */ |
| 99011 | 99390 | assert( !pS ); |
| 99012 | 99391 | if( iCol<0 ) iCol = pTab->iPKey; |
| 99013 | 99392 | assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) ); |
| 99393 | +#ifdef SQLITE_ENABLE_COLUMN_METADATA |
| 99014 | 99394 | if( iCol<0 ){ |
| 99015 | 99395 | zType = "INTEGER"; |
| 99016 | | - zOriginCol = "rowid"; |
| 99396 | + zOrigCol = "rowid"; |
| 99017 | 99397 | }else{ |
| 99018 | 99398 | zType = pTab->aCol[iCol].zType; |
| 99019 | | - zOriginCol = pTab->aCol[iCol].zName; |
| 99399 | + zOrigCol = pTab->aCol[iCol].zName; |
| 99400 | + estWidth = pTab->aCol[iCol].szEst; |
| 99020 | 99401 | } |
| 99021 | | - zOriginTab = pTab->zName; |
| 99402 | + zOrigTab = pTab->zName; |
| 99022 | 99403 | if( pNC->pParse ){ |
| 99023 | 99404 | int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema); |
| 99024 | | - zOriginDb = pNC->pParse->db->aDb[iDb].zName; |
| 99405 | + zOrigDb = pNC->pParse->db->aDb[iDb].zName; |
| 99025 | 99406 | } |
| 99407 | +#else |
| 99408 | + if( iCol<0 ){ |
| 99409 | + zType = "INTEGER"; |
| 99410 | + }else{ |
| 99411 | + zType = pTab->aCol[iCol].zType; |
| 99412 | + estWidth = pTab->aCol[iCol].szEst; |
| 99413 | + } |
| 99414 | +#endif |
| 99026 | 99415 | } |
| 99027 | 99416 | break; |
| 99028 | 99417 | } |
| 99029 | 99418 | #ifndef SQLITE_OMIT_SUBQUERY |
| 99030 | 99419 | case TK_SELECT: { |
| | @@ -99037,22 +99426,25 @@ |
| 99037 | 99426 | Expr *p = pS->pEList->a[0].pExpr; |
| 99038 | 99427 | assert( ExprHasProperty(pExpr, EP_xIsSelect) ); |
| 99039 | 99428 | sNC.pSrcList = pS->pSrc; |
| 99040 | 99429 | sNC.pNext = pNC; |
| 99041 | 99430 | sNC.pParse = pNC->pParse; |
| 99042 | | - zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol); |
| 99431 | + zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol, &estWidth); |
| 99043 | 99432 | break; |
| 99044 | 99433 | } |
| 99045 | 99434 | #endif |
| 99046 | 99435 | } |
| 99047 | | - |
| 99048 | | - if( pzOriginDb ){ |
| 99049 | | - assert( pzOriginTab && pzOriginCol ); |
| 99050 | | - *pzOriginDb = zOriginDb; |
| 99051 | | - *pzOriginTab = zOriginTab; |
| 99052 | | - *pzOriginCol = zOriginCol; |
| 99436 | + |
| 99437 | +#ifdef SQLITE_ENABLE_COLUMN_METADATA |
| 99438 | + if( pzOrigDb ){ |
| 99439 | + assert( pzOrigTab && pzOrigCol ); |
| 99440 | + *pzOrigDb = zOrigDb; |
| 99441 | + *pzOrigTab = zOrigTab; |
| 99442 | + *pzOrigCol = zOrigCol; |
| 99053 | 99443 | } |
| 99444 | +#endif |
| 99445 | + if( pEstWidth ) *pEstWidth = estWidth; |
| 99054 | 99446 | return zType; |
| 99055 | 99447 | } |
| 99056 | 99448 | |
| 99057 | 99449 | /* |
| 99058 | 99450 | ** Generate code that will tell the VDBE the declaration types of columns |
| | @@ -99074,25 +99466,25 @@ |
| 99074 | 99466 | const char *zType; |
| 99075 | 99467 | #ifdef SQLITE_ENABLE_COLUMN_METADATA |
| 99076 | 99468 | const char *zOrigDb = 0; |
| 99077 | 99469 | const char *zOrigTab = 0; |
| 99078 | 99470 | const char *zOrigCol = 0; |
| 99079 | | - zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol); |
| 99471 | + zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol, 0); |
| 99080 | 99472 | |
| 99081 | 99473 | /* The vdbe must make its own copy of the column-type and other |
| 99082 | 99474 | ** column specific strings, in case the schema is reset before this |
| 99083 | 99475 | ** virtual machine is deleted. |
| 99084 | 99476 | */ |
| 99085 | 99477 | sqlite3VdbeSetColName(v, i, COLNAME_DATABASE, zOrigDb, SQLITE_TRANSIENT); |
| 99086 | 99478 | sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, SQLITE_TRANSIENT); |
| 99087 | 99479 | sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, SQLITE_TRANSIENT); |
| 99088 | 99480 | #else |
| 99089 | | - zType = columnType(&sNC, p, 0, 0, 0); |
| 99481 | + zType = columnType(&sNC, p, 0, 0, 0, 0); |
| 99090 | 99482 | #endif |
| 99091 | 99483 | sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT); |
| 99092 | 99484 | } |
| 99093 | | -#endif /* SQLITE_OMIT_DECLTYPE */ |
| 99485 | +#endif /* !defined(SQLITE_OMIT_DECLTYPE) */ |
| 99094 | 99486 | } |
| 99095 | 99487 | |
| 99096 | 99488 | /* |
| 99097 | 99489 | ** Generate code that will tell the VDBE the names of columns |
| 99098 | 99490 | ** in the result set. This information is used to provide the |
| | @@ -99277,39 +99669,41 @@ |
| 99277 | 99669 | ** This routine requires that all identifiers in the SELECT |
| 99278 | 99670 | ** statement be resolved. |
| 99279 | 99671 | */ |
| 99280 | 99672 | static void selectAddColumnTypeAndCollation( |
| 99281 | 99673 | Parse *pParse, /* Parsing contexts */ |
| 99282 | | - int nCol, /* Number of columns */ |
| 99283 | | - Column *aCol, /* List of columns */ |
| 99674 | + Table *pTab, /* Add column type information to this table */ |
| 99284 | 99675 | Select *pSelect /* SELECT used to determine types and collations */ |
| 99285 | 99676 | ){ |
| 99286 | 99677 | sqlite3 *db = pParse->db; |
| 99287 | 99678 | NameContext sNC; |
| 99288 | 99679 | Column *pCol; |
| 99289 | 99680 | CollSeq *pColl; |
| 99290 | 99681 | int i; |
| 99291 | 99682 | Expr *p; |
| 99292 | 99683 | struct ExprList_item *a; |
| 99684 | + u64 szAll = 0; |
| 99293 | 99685 | |
| 99294 | 99686 | assert( pSelect!=0 ); |
| 99295 | 99687 | assert( (pSelect->selFlags & SF_Resolved)!=0 ); |
| 99296 | | - assert( nCol==pSelect->pEList->nExpr || db->mallocFailed ); |
| 99688 | + assert( pTab->nCol==pSelect->pEList->nExpr || db->mallocFailed ); |
| 99297 | 99689 | if( db->mallocFailed ) return; |
| 99298 | 99690 | memset(&sNC, 0, sizeof(sNC)); |
| 99299 | 99691 | sNC.pSrcList = pSelect->pSrc; |
| 99300 | 99692 | a = pSelect->pEList->a; |
| 99301 | | - for(i=0, pCol=aCol; i<nCol; i++, pCol++){ |
| 99693 | + for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){ |
| 99302 | 99694 | p = a[i].pExpr; |
| 99303 | | - pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p, 0, 0, 0)); |
| 99695 | + pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p,0,0,0, &pCol->szEst)); |
| 99696 | + szAll += pCol->szEst; |
| 99304 | 99697 | pCol->affinity = sqlite3ExprAffinity(p); |
| 99305 | 99698 | if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_NONE; |
| 99306 | 99699 | pColl = sqlite3ExprCollSeq(pParse, p); |
| 99307 | 99700 | if( pColl ){ |
| 99308 | 99701 | pCol->zColl = sqlite3DbStrDup(db, pColl->zName); |
| 99309 | 99702 | } |
| 99310 | 99703 | } |
| 99704 | + pTab->szTabRow = sqlite3LogEst(szAll*4); |
| 99311 | 99705 | } |
| 99312 | 99706 | |
| 99313 | 99707 | /* |
| 99314 | 99708 | ** Given a SELECT statement, generate a Table structure that describes |
| 99315 | 99709 | ** the result set of that SELECT. |
| | @@ -99333,13 +99727,13 @@ |
| 99333 | 99727 | /* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside |
| 99334 | 99728 | ** is disabled */ |
| 99335 | 99729 | assert( db->lookaside.bEnabled==0 ); |
| 99336 | 99730 | pTab->nRef = 1; |
| 99337 | 99731 | pTab->zName = 0; |
| 99338 | | - pTab->nRowEst = 1000000; |
| 99732 | + pTab->nRowEst = 1048576; |
| 99339 | 99733 | selectColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol); |
| 99340 | | - selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSelect); |
| 99734 | + selectAddColumnTypeAndCollation(pParse, pTab, pSelect); |
| 99341 | 99735 | pTab->iPKey = -1; |
| 99342 | 99736 | if( db->mallocFailed ){ |
| 99343 | 99737 | sqlite3DeleteTable(db, pTab); |
| 99344 | 99738 | return 0; |
| 99345 | 99739 | } |
| | @@ -101247,15 +101641,15 @@ |
| 101247 | 101641 | assert( pFrom->pTab==0 ); |
| 101248 | 101642 | sqlite3WalkSelect(pWalker, pSel); |
| 101249 | 101643 | pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); |
| 101250 | 101644 | if( pTab==0 ) return WRC_Abort; |
| 101251 | 101645 | pTab->nRef = 1; |
| 101252 | | - pTab->zName = sqlite3MPrintf(db, "sqlite_subquery_%p_", (void*)pTab); |
| 101646 | + pTab->zName = sqlite3MPrintf(db, "sqlite_sq_%p", (void*)pTab); |
| 101253 | 101647 | while( pSel->pPrior ){ pSel = pSel->pPrior; } |
| 101254 | 101648 | selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol); |
| 101255 | 101649 | pTab->iPKey = -1; |
| 101256 | | - pTab->nRowEst = 1000000; |
| 101650 | + pTab->nRowEst = 1048576; |
| 101257 | 101651 | pTab->tabFlags |= TF_Ephemeral; |
| 101258 | 101652 | #endif |
| 101259 | 101653 | }else{ |
| 101260 | 101654 | /* An ordinary table or view name in the FROM clause */ |
| 101261 | 101655 | assert( pFrom->pTab==0 ); |
| | @@ -101535,11 +101929,11 @@ |
| 101535 | 101929 | if( ALWAYS(pTab!=0) && (pTab->tabFlags & TF_Ephemeral)!=0 ){ |
| 101536 | 101930 | /* A sub-query in the FROM clause of a SELECT */ |
| 101537 | 101931 | Select *pSel = pFrom->pSelect; |
| 101538 | 101932 | assert( pSel ); |
| 101539 | 101933 | while( pSel->pPrior ) pSel = pSel->pPrior; |
| 101540 | | - selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSel); |
| 101934 | + selectAddColumnTypeAndCollation(pParse, pTab, pSel); |
| 101541 | 101935 | } |
| 101542 | 101936 | } |
| 101543 | 101937 | } |
| 101544 | 101938 | return WRC_Continue; |
| 101545 | 101939 | } |
| | @@ -102450,29 +102844,29 @@ |
| 102450 | 102844 | int iRoot = pTab->tnum; /* Root page of scanned b-tree */ |
| 102451 | 102845 | |
| 102452 | 102846 | sqlite3CodeVerifySchema(pParse, iDb); |
| 102453 | 102847 | sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); |
| 102454 | 102848 | |
| 102455 | | - /* Search for the index that has the least amount of columns. If |
| 102456 | | - ** there is such an index, and it has less columns than the table |
| 102457 | | - ** does, then we can assume that it consumes less space on disk and |
| 102458 | | - ** will therefore be cheaper to scan to determine the query result. |
| 102459 | | - ** In this case set iRoot to the root page number of the index b-tree |
| 102460 | | - ** and pKeyInfo to the KeyInfo structure required to navigate the |
| 102461 | | - ** index. |
| 102849 | + /* Search for the index that has the lowest scan cost. |
| 102462 | 102850 | ** |
| 102463 | 102851 | ** (2011-04-15) Do not do a full scan of an unordered index. |
| 102852 | + ** |
| 102853 | + ** (2013-10-03) Do not count the entires in a partial index. |
| 102464 | 102854 | ** |
| 102465 | 102855 | ** In practice the KeyInfo structure will not be used. It is only |
| 102466 | 102856 | ** passed to keep OP_OpenRead happy. |
| 102467 | 102857 | */ |
| 102468 | 102858 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 102469 | | - if( pIdx->bUnordered==0 && (!pBest || pIdx->nColumn<pBest->nColumn) ){ |
| 102859 | + if( pIdx->bUnordered==0 |
| 102860 | + && pIdx->szIdxRow<pTab->szTabRow |
| 102861 | + && pIdx->pPartIdxWhere==0 |
| 102862 | + && (!pBest || pIdx->szIdxRow<pBest->szIdxRow) |
| 102863 | + ){ |
| 102470 | 102864 | pBest = pIdx; |
| 102471 | 102865 | } |
| 102472 | 102866 | } |
| 102473 | | - if( pBest && pBest->nColumn<pTab->nCol ){ |
| 102867 | + if( pBest ){ |
| 102474 | 102868 | iRoot = pBest->tnum; |
| 102475 | 102869 | pKeyInfo = sqlite3IndexKeyinfo(pParse, pBest); |
| 102476 | 102870 | } |
| 102477 | 102871 | |
| 102478 | 102872 | /* Open a read-only cursor, execute the OP_Count, close the cursor. */ |
| | @@ -103046,12 +103440,12 @@ |
| 103046 | 103440 | } |
| 103047 | 103441 | |
| 103048 | 103442 | /* Ensure the table name matches database name and that the table exists */ |
| 103049 | 103443 | if( db->mallocFailed ) goto trigger_cleanup; |
| 103050 | 103444 | assert( pTableName->nSrc==1 ); |
| 103051 | | - if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName) && |
| 103052 | | - sqlite3FixSrcList(&sFix, pTableName) ){ |
| 103445 | + sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName); |
| 103446 | + if( sqlite3FixSrcList(&sFix, pTableName) ){ |
| 103053 | 103447 | goto trigger_cleanup; |
| 103054 | 103448 | } |
| 103055 | 103449 | pTab = sqlite3SrcListLookup(pParse, pTableName); |
| 103056 | 103450 | if( !pTab ){ |
| 103057 | 103451 | /* The table does not exist. */ |
| | @@ -103189,12 +103583,14 @@ |
| 103189 | 103583 | pStepList->pTrig = pTrig; |
| 103190 | 103584 | pStepList = pStepList->pNext; |
| 103191 | 103585 | } |
| 103192 | 103586 | nameToken.z = pTrig->zName; |
| 103193 | 103587 | nameToken.n = sqlite3Strlen30(nameToken.z); |
| 103194 | | - if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken) |
| 103195 | | - && sqlite3FixTriggerStep(&sFix, pTrig->step_list) ){ |
| 103588 | + sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken); |
| 103589 | + if( sqlite3FixTriggerStep(&sFix, pTrig->step_list) |
| 103590 | + || sqlite3FixExpr(&sFix, pTrig->pWhen) |
| 103591 | + ){ |
| 103196 | 103592 | goto triggerfinish_cleanup; |
| 103197 | 103593 | } |
| 103198 | 103594 | |
| 103199 | 103595 | /* if we are not initializing, |
| 103200 | 103596 | ** build the sqlite_master entry |
| | @@ -104781,18 +105177,38 @@ |
| 104781 | 105177 | |
| 104782 | 105178 | return vacuumFinalize(db, pStmt, pzErrMsg); |
| 104783 | 105179 | } |
| 104784 | 105180 | |
| 104785 | 105181 | /* |
| 104786 | | -** The non-standard VACUUM command is used to clean up the database, |
| 105182 | +** The VACUUM command is used to clean up the database, |
| 104787 | 105183 | ** collapse free space, etc. It is modelled after the VACUUM command |
| 104788 | | -** in PostgreSQL. |
| 105184 | +** in PostgreSQL. The VACUUM command works as follows: |
| 104789 | 105185 | ** |
| 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. |
| 105186 | +** (1) Create a new transient database file |
| 105187 | +** (2) Copy all content from the database being vacuumed into |
| 105188 | +** the new transient database file |
| 105189 | +** (3) Copy content from the transient database back into the |
| 105190 | +** original database. |
| 105191 | +** |
| 105192 | +** The transient database requires temporary disk space approximately |
| 105193 | +** equal to the size of the original database. The copy operation of |
| 105194 | +** step (3) requires additional temporary disk space approximately equal |
| 105195 | +** to the size of the original database for the rollback journal. |
| 105196 | +** Hence, temporary disk space that is approximately 2x the size of the |
| 105197 | +** orginal database is required. Every page of the database is written |
| 105198 | +** approximately 3 times: Once for step (2) and twice for step (3). |
| 105199 | +** Two writes per page are required in step (3) because the original |
| 105200 | +** database content must be written into the rollback journal prior to |
| 105201 | +** overwriting the database with the vacuumed content. |
| 105202 | +** |
| 105203 | +** Only 1x temporary space and only 1x writes would be required if |
| 105204 | +** the copy of step (3) were replace by deleting the original database |
| 105205 | +** and renaming the transient database as the original. But that will |
| 105206 | +** not work if other processes are attached to the original database. |
| 105207 | +** And a power loss in between deleting the original and renaming the |
| 105208 | +** transient would cause the database file to appear to be deleted |
| 105209 | +** following reboot. |
| 104794 | 105210 | */ |
| 104795 | 105211 | SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse){ |
| 104796 | 105212 | Vdbe *v = sqlite3GetVdbe(pParse); |
| 104797 | 105213 | if( v ){ |
| 104798 | 105214 | sqlite3VdbeAddOp2(v, OP_Vacuum, 0, 0); |
| | @@ -106206,30 +106622,10 @@ |
| 106206 | 106622 | typedef struct WhereLoopBuilder WhereLoopBuilder; |
| 106207 | 106623 | typedef struct WhereScan WhereScan; |
| 106208 | 106624 | typedef struct WhereOrCost WhereOrCost; |
| 106209 | 106625 | typedef struct WhereOrSet WhereOrSet; |
| 106210 | 106626 | |
| 106211 | | -/* |
| 106212 | | -** Cost X is tracked as 10*log2(X) stored in a 16-bit integer. The |
| 106213 | | -** maximum cost for ordinary tables is 64*(2**63) which becomes 6900. |
| 106214 | | -** (Virtual tables can return a larger cost, but let's assume they do not.) |
| 106215 | | -** So all costs can be stored in a 16-bit integer without risk |
| 106216 | | -** of overflow. |
| 106217 | | -** |
| 106218 | | -** Costs are estimates, so no effort is made to compute 10*log2(X) exactly. |
| 106219 | | -** Instead, a close estimate is used. Any value of X=1 is stored as 0. |
| 106220 | | -** X=2 is 10. X=3 is 16. X=1000 is 99. etc. Negative values are allowed. |
| 106221 | | -** A WhereCost of -10 means 0.5. WhereCost of -20 means 0.25. And so forth. |
| 106222 | | -** |
| 106223 | | -** The tool/wherecosttest.c source file implements a command-line program |
| 106224 | | -** that will convert WhereCosts to integers, convert integers to WhereCosts |
| 106225 | | -** and do addition and multiplication on WhereCost values. The wherecosttest |
| 106226 | | -** command-line program is a useful utility to have around when working with |
| 106227 | | -** this module. |
| 106228 | | -*/ |
| 106229 | | -typedef short int WhereCost; |
| 106230 | | - |
| 106231 | 106627 | /* |
| 106232 | 106628 | ** This object contains information needed to implement a single nested |
| 106233 | 106629 | ** loop in WHERE clause. |
| 106234 | 106630 | ** |
| 106235 | 106631 | ** Contrast this object with WhereLoop. This object describes the |
| | @@ -106290,13 +106686,13 @@ |
| 106290 | 106686 | #ifdef SQLITE_DEBUG |
| 106291 | 106687 | char cId; /* Symbolic ID of this loop for debugging use */ |
| 106292 | 106688 | #endif |
| 106293 | 106689 | u8 iTab; /* Position in FROM clause of table for this loop */ |
| 106294 | 106690 | u8 iSortIdx; /* Sorting index number. 0==None */ |
| 106295 | | - WhereCost rSetup; /* One-time setup cost (ex: create transient index) */ |
| 106296 | | - WhereCost rRun; /* Cost of running each loop */ |
| 106297 | | - WhereCost nOut; /* Estimated number of output rows */ |
| 106691 | + LogEst rSetup; /* One-time setup cost (ex: create transient index) */ |
| 106692 | + LogEst rRun; /* Cost of running each loop */ |
| 106693 | + LogEst nOut; /* Estimated number of output rows */ |
| 106298 | 106694 | union { |
| 106299 | 106695 | struct { /* Information for internal btree tables */ |
| 106300 | 106696 | int nEq; /* Number of equality constraints */ |
| 106301 | 106697 | Index *pIndex; /* Index used, or NULL */ |
| 106302 | 106698 | } btree; |
| | @@ -106322,12 +106718,12 @@ |
| 106322 | 106718 | ** subquery on one operand of an OR operator in the WHERE clause. |
| 106323 | 106719 | ** See WhereOrSet for additional information |
| 106324 | 106720 | */ |
| 106325 | 106721 | struct WhereOrCost { |
| 106326 | 106722 | Bitmask prereq; /* Prerequisites */ |
| 106327 | | - WhereCost rRun; /* Cost of running this subquery */ |
| 106328 | | - WhereCost nOut; /* Number of outputs for this subquery */ |
| 106723 | + LogEst rRun; /* Cost of running this subquery */ |
| 106724 | + LogEst nOut; /* Number of outputs for this subquery */ |
| 106329 | 106725 | }; |
| 106330 | 106726 | |
| 106331 | 106727 | /* The WhereOrSet object holds a set of possible WhereOrCosts that |
| 106332 | 106728 | ** correspond to the subquery(s) of OR-clause processing. Only the |
| 106333 | 106729 | ** best N_OR_COST elements are retained. |
| | @@ -106361,12 +106757,12 @@ |
| 106361 | 106757 | ** at the end is the choosen query plan. |
| 106362 | 106758 | */ |
| 106363 | 106759 | struct WherePath { |
| 106364 | 106760 | Bitmask maskLoop; /* Bitmask of all WhereLoop objects in this path */ |
| 106365 | 106761 | Bitmask revLoop; /* aLoop[]s that should be reversed for ORDER BY */ |
| 106366 | | - WhereCost nRow; /* Estimated number of rows generated by this path */ |
| 106367 | | - WhereCost rCost; /* Total cost of this path */ |
| 106762 | + LogEst nRow; /* Estimated number of rows generated by this path */ |
| 106763 | + LogEst rCost; /* Total cost of this path */ |
| 106368 | 106764 | u8 isOrdered; /* True if this path satisfies ORDER BY */ |
| 106369 | 106765 | u8 isOrderedValid; /* True if the isOrdered field is valid */ |
| 106370 | 106766 | WhereLoop **aLoop; /* Array of WhereLoop objects implementing this path */ |
| 106371 | 106767 | }; |
| 106372 | 106768 | |
| | @@ -106428,11 +106824,11 @@ |
| 106428 | 106824 | union { |
| 106429 | 106825 | int leftColumn; /* Column number of X in "X <op> <expr>" */ |
| 106430 | 106826 | WhereOrInfo *pOrInfo; /* Extra information if (eOperator & WO_OR)!=0 */ |
| 106431 | 106827 | WhereAndInfo *pAndInfo; /* Extra information if (eOperator& WO_AND)!=0 */ |
| 106432 | 106828 | } u; |
| 106433 | | - WhereCost truthProb; /* Probability of truth for this expression */ |
| 106829 | + LogEst truthProb; /* Probability of truth for this expression */ |
| 106434 | 106830 | u16 eOperator; /* A WO_xx value describing <op> */ |
| 106435 | 106831 | u8 wtFlags; /* TERM_xxx bit flags. See below */ |
| 106436 | 106832 | u8 nChild; /* Number of children that must disable us */ |
| 106437 | 106833 | WhereClause *pWC; /* The clause this term is part of */ |
| 106438 | 106834 | Bitmask prereqRight; /* Bitmask of tables used by pExpr->pRight */ |
| | @@ -106576,11 +106972,11 @@ |
| 106576 | 106972 | SrcList *pTabList; /* List of tables in the join */ |
| 106577 | 106973 | ExprList *pOrderBy; /* The ORDER BY clause or NULL */ |
| 106578 | 106974 | ExprList *pResultSet; /* Result set. DISTINCT operates on these */ |
| 106579 | 106975 | WhereLoop *pLoops; /* List of all WhereLoop objects */ |
| 106580 | 106976 | Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ |
| 106581 | | - WhereCost nRowOut; /* Estimated number of output rows */ |
| 106977 | + LogEst nRowOut; /* Estimated number of output rows */ |
| 106582 | 106978 | u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */ |
| 106583 | 106979 | u8 bOBSat; /* ORDER BY satisfied by indices */ |
| 106584 | 106980 | u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE/DELETE */ |
| 106585 | 106981 | u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */ |
| 106586 | 106982 | u8 eDistinct; /* One of the WHERE_DISTINCT_* values below */ |
| | @@ -106636,30 +107032,15 @@ |
| 106636 | 107032 | #define WHERE_IN_ABLE 0x00000800 /* Able to support an IN operator */ |
| 106637 | 107033 | #define WHERE_ONEROW 0x00001000 /* Selects no more than one row */ |
| 106638 | 107034 | #define WHERE_MULTI_OR 0x00002000 /* OR using multiple indices */ |
| 106639 | 107035 | #define WHERE_AUTO_INDEX 0x00004000 /* Uses an ephemeral index */ |
| 106640 | 107036 | |
| 106641 | | - |
| 106642 | | -/* Convert a WhereCost value (10 times log2(X)) into its integer value X. |
| 106643 | | -** A rough approximation is used. The value returned is not exact. |
| 106644 | | -*/ |
| 106645 | | -static u64 whereCostToInt(WhereCost x){ |
| 106646 | | - u64 n; |
| 106647 | | - if( x<10 ) return 1; |
| 106648 | | - n = x%10; |
| 106649 | | - x /= 10; |
| 106650 | | - if( n>=5 ) n -= 2; |
| 106651 | | - else if( n>=1 ) n -= 1; |
| 106652 | | - if( x>=3 ) return (n+8)<<(x-3); |
| 106653 | | - return (n+8)>>(3-x); |
| 106654 | | -} |
| 106655 | | - |
| 106656 | 107037 | /* |
| 106657 | 107038 | ** Return the estimated number of output rows from a WHERE clause |
| 106658 | 107039 | */ |
| 106659 | 107040 | SQLITE_PRIVATE u64 sqlite3WhereOutputRowCount(WhereInfo *pWInfo){ |
| 106660 | | - return whereCostToInt(pWInfo->nRowOut); |
| 107041 | + return sqlite3LogEstToInt(pWInfo->nRowOut); |
| 106661 | 107042 | } |
| 106662 | 107043 | |
| 106663 | 107044 | /* |
| 106664 | 107045 | ** Return one of the WHERE_DISTINCT_xxxxx values to indicate how this |
| 106665 | 107046 | ** WHERE clause returns outputs for DISTINCT processing. |
| | @@ -106717,12 +107098,12 @@ |
| 106717 | 107098 | ** so that pSet keeps the N_OR_COST best entries seen so far. |
| 106718 | 107099 | */ |
| 106719 | 107100 | static int whereOrInsert( |
| 106720 | 107101 | WhereOrSet *pSet, /* The WhereOrSet to be updated */ |
| 106721 | 107102 | Bitmask prereq, /* Prerequisites of the new entry */ |
| 106722 | | - WhereCost rRun, /* Run-cost of the new entry */ |
| 106723 | | - WhereCost nOut /* Number of outputs for the new entry */ |
| 107103 | + LogEst rRun, /* Run-cost of the new entry */ |
| 107104 | + LogEst nOut /* Number of outputs for the new entry */ |
| 106724 | 107105 | ){ |
| 106725 | 107106 | u16 i; |
| 106726 | 107107 | WhereOrCost *p; |
| 106727 | 107108 | for(i=pSet->n, p=pSet->a; i>0; i--, p++){ |
| 106728 | 107109 | if( rRun<=p->rRun && (prereq & p->prereq)==prereq ){ |
| | @@ -106803,13 +107184,10 @@ |
| 106803 | 107184 | if( pWC->a!=pWC->aStatic ){ |
| 106804 | 107185 | sqlite3DbFree(db, pWC->a); |
| 106805 | 107186 | } |
| 106806 | 107187 | } |
| 106807 | 107188 | |
| 106808 | | -/* Forward declaration */ |
| 106809 | | -static WhereCost whereCost(tRowcnt x); |
| 106810 | | - |
| 106811 | 107189 | /* |
| 106812 | 107190 | ** Add a single new WhereTerm entry to the WhereClause object pWC. |
| 106813 | 107191 | ** The new WhereTerm object is constructed from Expr p and with wtFlags. |
| 106814 | 107192 | ** The index in pWC->a[] of the new WhereTerm is returned on success. |
| 106815 | 107193 | ** 0 is returned if the new WhereTerm could not be added due to a memory |
| | @@ -106848,11 +107226,11 @@ |
| 106848 | 107226 | } |
| 106849 | 107227 | pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]); |
| 106850 | 107228 | } |
| 106851 | 107229 | pTerm = &pWC->a[idx = pWC->nTerm++]; |
| 106852 | 107230 | if( p && ExprHasProperty(p, EP_Unlikely) ){ |
| 106853 | | - pTerm->truthProb = whereCost(p->iTable) - 99; |
| 107231 | + pTerm->truthProb = sqlite3LogEst(p->iTable) - 99; |
| 106854 | 107232 | }else{ |
| 106855 | 107233 | pTerm->truthProb = -1; |
| 106856 | 107234 | } |
| 106857 | 107235 | pTerm->pExpr = sqlite3ExprSkipCollate(p); |
| 106858 | 107236 | pTerm->wtFlags = wtFlags; |
| | @@ -108112,79 +108490,16 @@ |
| 108112 | 108490 | } |
| 108113 | 108491 | |
| 108114 | 108492 | return 0; |
| 108115 | 108493 | } |
| 108116 | 108494 | |
| 108117 | | -/* |
| 108118 | | -** Find (an approximate) sum of two WhereCosts. This computation is |
| 108119 | | -** not a simple "+" operator because WhereCost is stored as a logarithmic |
| 108120 | | -** value. |
| 108121 | | -** |
| 108122 | | -*/ |
| 108123 | | -static WhereCost whereCostAdd(WhereCost a, WhereCost b){ |
| 108124 | | - static const unsigned char x[] = { |
| 108125 | | - 10, 10, /* 0,1 */ |
| 108126 | | - 9, 9, /* 2,3 */ |
| 108127 | | - 8, 8, /* 4,5 */ |
| 108128 | | - 7, 7, 7, /* 6,7,8 */ |
| 108129 | | - 6, 6, 6, /* 9,10,11 */ |
| 108130 | | - 5, 5, 5, /* 12-14 */ |
| 108131 | | - 4, 4, 4, 4, /* 15-18 */ |
| 108132 | | - 3, 3, 3, 3, 3, 3, /* 19-24 */ |
| 108133 | | - 2, 2, 2, 2, 2, 2, 2, /* 25-31 */ |
| 108134 | | - }; |
| 108135 | | - if( a>=b ){ |
| 108136 | | - if( a>b+49 ) return a; |
| 108137 | | - if( a>b+31 ) return a+1; |
| 108138 | | - return a+x[a-b]; |
| 108139 | | - }else{ |
| 108140 | | - if( b>a+49 ) return b; |
| 108141 | | - if( b>a+31 ) return b+1; |
| 108142 | | - return b+x[b-a]; |
| 108143 | | - } |
| 108144 | | -} |
| 108145 | | - |
| 108146 | | -/* |
| 108147 | | -** Convert an integer into a WhereCost. In other words, compute a |
| 108148 | | -** good approximatation for 10*log2(x). |
| 108149 | | -*/ |
| 108150 | | -static WhereCost whereCost(tRowcnt x){ |
| 108151 | | - static WhereCost a[] = { 0, 2, 3, 5, 6, 7, 8, 9 }; |
| 108152 | | - WhereCost y = 40; |
| 108153 | | - if( x<8 ){ |
| 108154 | | - if( x<2 ) return 0; |
| 108155 | | - while( x<8 ){ y -= 10; x <<= 1; } |
| 108156 | | - }else{ |
| 108157 | | - while( x>255 ){ y += 40; x >>= 4; } |
| 108158 | | - while( x>15 ){ y += 10; x >>= 1; } |
| 108159 | | - } |
| 108160 | | - return a[x&7] + y - 10; |
| 108161 | | -} |
| 108162 | | - |
| 108163 | | -#ifndef SQLITE_OMIT_VIRTUALTABLE |
| 108164 | | -/* |
| 108165 | | -** Convert a double (as received from xBestIndex of a virtual table) |
| 108166 | | -** into a WhereCost. In other words, compute an approximation for |
| 108167 | | -** 10*log2(x). |
| 108168 | | -*/ |
| 108169 | | -static WhereCost whereCostFromDouble(double x){ |
| 108170 | | - u64 a; |
| 108171 | | - WhereCost e; |
| 108172 | | - assert( sizeof(x)==8 && sizeof(a)==8 ); |
| 108173 | | - if( x<=1 ) return 0; |
| 108174 | | - if( x<=2000000000 ) return whereCost((tRowcnt)x); |
| 108175 | | - memcpy(&a, &x, 8); |
| 108176 | | - e = (a>>52) - 1022; |
| 108177 | | - return e*10; |
| 108178 | | -} |
| 108179 | | -#endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 108180 | 108495 | |
| 108181 | 108496 | /* |
| 108182 | 108497 | ** Estimate the logarithm of the input value to base 2. |
| 108183 | 108498 | */ |
| 108184 | | -static WhereCost estLog(WhereCost N){ |
| 108185 | | - WhereCost x = whereCost(N); |
| 108499 | +static LogEst estLog(LogEst N){ |
| 108500 | + LogEst x = sqlite3LogEst(N); |
| 108186 | 108501 | return x>33 ? x - 33 : 0; |
| 108187 | 108502 | } |
| 108188 | 108503 | |
| 108189 | 108504 | /* |
| 108190 | 108505 | ** Two routines for printing the content of an sqlite3_index_info |
| | @@ -108693,11 +109008,11 @@ |
| 108693 | 109008 | ** |
| 108694 | 109009 | ** ... FROM t1 WHERE a > ? AND a < ? ... |
| 108695 | 109010 | ** |
| 108696 | 109011 | ** then nEq is set to 0. |
| 108697 | 109012 | ** |
| 108698 | | -** When this function is called, *pnOut is set to the whereCost() of the |
| 109013 | +** When this function is called, *pnOut is set to the sqlite3LogEst() of the |
| 108699 | 109014 | ** number of rows that the index scan is expected to visit without |
| 108700 | 109015 | ** considering the range constraints. If nEq is 0, this is the number of |
| 108701 | 109016 | ** rows in the index. Assuming no error occurs, *pnOut is adjusted (reduced) |
| 108702 | 109017 | ** to account for the range contraints pLower and pUpper. |
| 108703 | 109018 | ** |
| | @@ -108709,19 +109024,19 @@ |
| 108709 | 109024 | static int whereRangeScanEst( |
| 108710 | 109025 | Parse *pParse, /* Parsing & code generating context */ |
| 108711 | 109026 | WhereLoopBuilder *pBuilder, |
| 108712 | 109027 | WhereTerm *pLower, /* Lower bound on the range. ex: "x>123" Might be NULL */ |
| 108713 | 109028 | WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */ |
| 108714 | | - WhereCost *pnOut /* IN/OUT: Number of rows visited */ |
| 109029 | + WhereLoop *pLoop /* Modify the .nOut and maybe .rRun fields */ |
| 108715 | 109030 | ){ |
| 108716 | 109031 | int rc = SQLITE_OK; |
| 108717 | | - int nOut = (int)*pnOut; |
| 108718 | | - WhereCost nNew; |
| 109032 | + int nOut = pLoop->nOut; |
| 109033 | + int nEq = pLoop->u.btree.nEq; |
| 109034 | + LogEst nNew; |
| 108719 | 109035 | |
| 108720 | 109036 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 108721 | | - Index *p = pBuilder->pNew->u.btree.pIndex; |
| 108722 | | - int nEq = pBuilder->pNew->u.btree.nEq; |
| 109037 | + Index *p = pLoop->u.btree.pIndex; |
| 108723 | 109038 | |
| 108724 | 109039 | if( p->nSample>0 |
| 108725 | 109040 | && nEq==pBuilder->nRecValid |
| 108726 | 109041 | && nEq<p->nSampleCol |
| 108727 | 109042 | && OptimizationEnabled(pParse->db, SQLITE_Stat3) |
| | @@ -108798,18 +109113,18 @@ |
| 108798 | 109113 | } |
| 108799 | 109114 | |
| 108800 | 109115 | pBuilder->pRec = pRec; |
| 108801 | 109116 | if( rc==SQLITE_OK ){ |
| 108802 | 109117 | if( iUpper>iLower ){ |
| 108803 | | - nNew = whereCost(iUpper - iLower); |
| 109118 | + nNew = sqlite3LogEst(iUpper - iLower); |
| 108804 | 109119 | }else{ |
| 108805 | | - nNew = 10; assert( 10==whereCost(2) ); |
| 109120 | + nNew = 10; assert( 10==sqlite3LogEst(2) ); |
| 108806 | 109121 | } |
| 108807 | 109122 | if( nNew<nOut ){ |
| 108808 | 109123 | nOut = nNew; |
| 108809 | 109124 | } |
| 108810 | | - *pnOut = (WhereCost)nOut; |
| 109125 | + pLoop->nOut = (LogEst)nOut; |
| 108811 | 109126 | WHERETRACE(0x100, ("range scan regions: %u..%u est=%d\n", |
| 108812 | 109127 | (u32)iLower, (u32)iUpper, nOut)); |
| 108813 | 109128 | return SQLITE_OK; |
| 108814 | 109129 | } |
| 108815 | 109130 | } |
| | @@ -108820,20 +109135,20 @@ |
| 108820 | 109135 | assert( pLower || pUpper ); |
| 108821 | 109136 | /* TUNING: Each inequality constraint reduces the search space 4-fold. |
| 108822 | 109137 | ** A BETWEEN operator, therefore, reduces the search space 16-fold */ |
| 108823 | 109138 | nNew = nOut; |
| 108824 | 109139 | if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ){ |
| 108825 | | - nNew -= 20; assert( 20==whereCost(4) ); |
| 109140 | + nNew -= 20; assert( 20==sqlite3LogEst(4) ); |
| 108826 | 109141 | nOut--; |
| 108827 | 109142 | } |
| 108828 | 109143 | if( pUpper ){ |
| 108829 | | - nNew -= 20; assert( 20==whereCost(4) ); |
| 109144 | + nNew -= 20; assert( 20==sqlite3LogEst(4) ); |
| 108830 | 109145 | nOut--; |
| 108831 | 109146 | } |
| 108832 | 109147 | if( nNew<10 ) nNew = 10; |
| 108833 | 109148 | if( nNew<nOut ) nOut = nNew; |
| 108834 | | - *pnOut = (WhereCost)nOut; |
| 109149 | + pLoop->nOut = (LogEst)nOut; |
| 108835 | 109150 | return rc; |
| 108836 | 109151 | } |
| 108837 | 109152 | |
| 108838 | 109153 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 108839 | 109154 | /* |
| | @@ -110473,11 +110788,11 @@ |
| 110473 | 110788 | */ |
| 110474 | 110789 | static int whereLoopAddBtreeIndex( |
| 110475 | 110790 | WhereLoopBuilder *pBuilder, /* The WhereLoop factory */ |
| 110476 | 110791 | struct SrcList_item *pSrc, /* FROM clause term being analyzed */ |
| 110477 | 110792 | Index *pProbe, /* An index on pSrc */ |
| 110478 | | - WhereCost nInMul /* log(Number of iterations due to IN) */ |
| 110793 | + LogEst nInMul /* log(Number of iterations due to IN) */ |
| 110479 | 110794 | ){ |
| 110480 | 110795 | WhereInfo *pWInfo = pBuilder->pWInfo; /* WHERE analyse context */ |
| 110481 | 110796 | Parse *pParse = pWInfo->pParse; /* Parsing context */ |
| 110482 | 110797 | sqlite3 *db = pParse->db; /* Database connection malloc context */ |
| 110483 | 110798 | WhereLoop *pNew; /* Template WhereLoop under construction */ |
| | @@ -110486,15 +110801,15 @@ |
| 110486 | 110801 | WhereScan scan; /* Iterator for WHERE terms */ |
| 110487 | 110802 | Bitmask saved_prereq; /* Original value of pNew->prereq */ |
| 110488 | 110803 | u16 saved_nLTerm; /* Original value of pNew->nLTerm */ |
| 110489 | 110804 | int saved_nEq; /* Original value of pNew->u.btree.nEq */ |
| 110490 | 110805 | u32 saved_wsFlags; /* Original value of pNew->wsFlags */ |
| 110491 | | - WhereCost saved_nOut; /* Original value of pNew->nOut */ |
| 110806 | + LogEst saved_nOut; /* Original value of pNew->nOut */ |
| 110492 | 110807 | int iCol; /* Index of the column in the table */ |
| 110493 | 110808 | int rc = SQLITE_OK; /* Return code */ |
| 110494 | | - WhereCost nRowEst; /* Estimated index selectivity */ |
| 110495 | | - WhereCost rLogSize; /* Logarithm of table size */ |
| 110809 | + LogEst nRowEst; /* Estimated index selectivity */ |
| 110810 | + LogEst rLogSize; /* Logarithm of table size */ |
| 110496 | 110811 | WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */ |
| 110497 | 110812 | |
| 110498 | 110813 | pNew = pBuilder->pNew; |
| 110499 | 110814 | if( db->mallocFailed ) return SQLITE_NOMEM; |
| 110500 | 110815 | |
| | @@ -110510,11 +110825,11 @@ |
| 110510 | 110825 | if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE); |
| 110511 | 110826 | |
| 110512 | 110827 | assert( pNew->u.btree.nEq<=pProbe->nColumn ); |
| 110513 | 110828 | if( pNew->u.btree.nEq < pProbe->nColumn ){ |
| 110514 | 110829 | iCol = pProbe->aiColumn[pNew->u.btree.nEq]; |
| 110515 | | - nRowEst = whereCost(pProbe->aiRowEst[pNew->u.btree.nEq+1]); |
| 110830 | + nRowEst = sqlite3LogEst(pProbe->aiRowEst[pNew->u.btree.nEq+1]); |
| 110516 | 110831 | if( nRowEst==0 && pProbe->onError==OE_None ) nRowEst = 1; |
| 110517 | 110832 | }else{ |
| 110518 | 110833 | iCol = -1; |
| 110519 | 110834 | nRowEst = 0; |
| 110520 | 110835 | } |
| | @@ -110524,11 +110839,11 @@ |
| 110524 | 110839 | saved_nLTerm = pNew->nLTerm; |
| 110525 | 110840 | saved_wsFlags = pNew->wsFlags; |
| 110526 | 110841 | saved_prereq = pNew->prereq; |
| 110527 | 110842 | saved_nOut = pNew->nOut; |
| 110528 | 110843 | pNew->rSetup = 0; |
| 110529 | | - rLogSize = estLog(whereCost(pProbe->aiRowEst[0])); |
| 110844 | + rLogSize = estLog(sqlite3LogEst(pProbe->aiRowEst[0])); |
| 110530 | 110845 | for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){ |
| 110531 | 110846 | int nIn = 0; |
| 110532 | 110847 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 110533 | 110848 | int nRecValid = pBuilder->nRecValid; |
| 110534 | 110849 | #endif |
| | @@ -110551,14 +110866,14 @@ |
| 110551 | 110866 | if( pTerm->eOperator & WO_IN ){ |
| 110552 | 110867 | Expr *pExpr = pTerm->pExpr; |
| 110553 | 110868 | pNew->wsFlags |= WHERE_COLUMN_IN; |
| 110554 | 110869 | if( ExprHasProperty(pExpr, EP_xIsSelect) ){ |
| 110555 | 110870 | /* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */ |
| 110556 | | - nIn = 46; assert( 46==whereCost(25) ); |
| 110871 | + nIn = 46; assert( 46==sqlite3LogEst(25) ); |
| 110557 | 110872 | }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){ |
| 110558 | 110873 | /* "x IN (value, value, ...)" */ |
| 110559 | | - nIn = whereCost(pExpr->x.pList->nExpr); |
| 110874 | + nIn = sqlite3LogEst(pExpr->x.pList->nExpr); |
| 110560 | 110875 | } |
| 110561 | 110876 | pNew->rRun += nIn; |
| 110562 | 110877 | pNew->u.btree.nEq++; |
| 110563 | 110878 | pNew->nOut = nRowEst + nInMul + nIn; |
| 110564 | 110879 | }else if( pTerm->eOperator & (WO_EQ) ){ |
| | @@ -110576,11 +110891,11 @@ |
| 110576 | 110891 | pNew->nOut = nRowEst + nInMul; |
| 110577 | 110892 | }else if( pTerm->eOperator & (WO_ISNULL) ){ |
| 110578 | 110893 | pNew->wsFlags |= WHERE_COLUMN_NULL; |
| 110579 | 110894 | pNew->u.btree.nEq++; |
| 110580 | 110895 | /* TUNING: IS NULL selects 2 rows */ |
| 110581 | | - nIn = 10; assert( 10==whereCost(2) ); |
| 110896 | + nIn = 10; assert( 10==sqlite3LogEst(2) ); |
| 110582 | 110897 | pNew->nOut = nRowEst + nInMul + nIn; |
| 110583 | 110898 | }else if( pTerm->eOperator & (WO_GT|WO_GE) ){ |
| 110584 | 110899 | testcase( pTerm->eOperator & WO_GT ); |
| 110585 | 110900 | testcase( pTerm->eOperator & WO_GE ); |
| 110586 | 110901 | pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT; |
| | @@ -110596,11 +110911,11 @@ |
| 110596 | 110911 | pNew->aLTerm[pNew->nLTerm-2] : 0; |
| 110597 | 110912 | } |
| 110598 | 110913 | if( pNew->wsFlags & WHERE_COLUMN_RANGE ){ |
| 110599 | 110914 | /* Adjust nOut and rRun for STAT3 range values */ |
| 110600 | 110915 | assert( pNew->nOut==saved_nOut ); |
| 110601 | | - whereRangeScanEst(pParse, pBuilder, pBtm, pTop, &pNew->nOut); |
| 110916 | + whereRangeScanEst(pParse, pBuilder, pBtm, pTop, pNew); |
| 110602 | 110917 | } |
| 110603 | 110918 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 110604 | 110919 | if( nInMul==0 |
| 110605 | 110920 | && pProbe->nSample |
| 110606 | 110921 | && pNew->u.btree.nEq<=pProbe->nSampleCol |
| | @@ -110616,22 +110931,22 @@ |
| 110616 | 110931 | && !ExprHasProperty(pExpr, EP_xIsSelect) ){ |
| 110617 | 110932 | rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut); |
| 110618 | 110933 | } |
| 110619 | 110934 | assert( nOut==0 || rc==SQLITE_OK ); |
| 110620 | 110935 | if( nOut ){ |
| 110621 | | - nOut = whereCost(nOut); |
| 110936 | + nOut = sqlite3LogEst(nOut); |
| 110622 | 110937 | pNew->nOut = MIN(nOut, saved_nOut); |
| 110623 | 110938 | } |
| 110624 | 110939 | } |
| 110625 | 110940 | #endif |
| 110626 | 110941 | if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){ |
| 110627 | 110942 | /* Each row involves a step of the index, then a binary search of |
| 110628 | 110943 | ** the main table */ |
| 110629 | | - pNew->rRun = whereCostAdd(pNew->rRun, rLogSize>27 ? rLogSize-17 : 10); |
| 110944 | + pNew->rRun = sqlite3LogEstAdd(pNew->rRun,rLogSize>27 ? rLogSize-17 : 10); |
| 110630 | 110945 | } |
| 110631 | 110946 | /* Step cost for each output row */ |
| 110632 | | - pNew->rRun = whereCostAdd(pNew->rRun, pNew->nOut); |
| 110947 | + pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut); |
| 110633 | 110948 | whereLoopOutputAdjust(pBuilder->pWC, pNew, pSrc->iCursor); |
| 110634 | 110949 | rc = whereLoopInsert(pBuilder, pNew); |
| 110635 | 110950 | if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 |
| 110636 | 110951 | && pNew->u.btree.nEq<(pProbe->nColumn + (pProbe->zName!=0)) |
| 110637 | 110952 | ){ |
| | @@ -110727,18 +111042,20 @@ |
| 110727 | 111042 | struct SrcList_item *pSrc; /* The FROM clause btree term to add */ |
| 110728 | 111043 | WhereLoop *pNew; /* Template WhereLoop object */ |
| 110729 | 111044 | int rc = SQLITE_OK; /* Return code */ |
| 110730 | 111045 | int iSortIdx = 1; /* Index number */ |
| 110731 | 111046 | int b; /* A boolean value */ |
| 110732 | | - WhereCost rSize; /* number of rows in the table */ |
| 110733 | | - WhereCost rLogSize; /* Logarithm of the number of rows in the table */ |
| 111047 | + LogEst rSize; /* number of rows in the table */ |
| 111048 | + LogEst rLogSize; /* Logarithm of the number of rows in the table */ |
| 110734 | 111049 | WhereClause *pWC; /* The parsed WHERE clause */ |
| 111050 | + Table *pTab; /* Table being queried */ |
| 110735 | 111051 | |
| 110736 | 111052 | pNew = pBuilder->pNew; |
| 110737 | 111053 | pWInfo = pBuilder->pWInfo; |
| 110738 | 111054 | pTabList = pWInfo->pTabList; |
| 110739 | 111055 | pSrc = pTabList->a + pNew->iTab; |
| 111056 | + pTab = pSrc->pTab; |
| 110740 | 111057 | pWC = pBuilder->pWC; |
| 110741 | 111058 | assert( !IsVirtual(pSrc->pTab) ); |
| 110742 | 111059 | |
| 110743 | 111060 | if( pSrc->pIndex ){ |
| 110744 | 111061 | /* An INDEXED BY clause specifies a particular index to use */ |
| | @@ -110752,22 +111069,22 @@ |
| 110752 | 111069 | memset(&sPk, 0, sizeof(Index)); |
| 110753 | 111070 | sPk.nColumn = 1; |
| 110754 | 111071 | sPk.aiColumn = &aiColumnPk; |
| 110755 | 111072 | sPk.aiRowEst = aiRowEstPk; |
| 110756 | 111073 | sPk.onError = OE_Replace; |
| 110757 | | - sPk.pTable = pSrc->pTab; |
| 110758 | | - aiRowEstPk[0] = pSrc->pTab->nRowEst; |
| 111074 | + sPk.pTable = pTab; |
| 111075 | + aiRowEstPk[0] = pTab->nRowEst; |
| 110759 | 111076 | aiRowEstPk[1] = 1; |
| 110760 | 111077 | pFirst = pSrc->pTab->pIndex; |
| 110761 | 111078 | if( pSrc->notIndexed==0 ){ |
| 110762 | 111079 | /* The real indices of the table are only considered if the |
| 110763 | 111080 | ** NOT INDEXED qualifier is omitted from the FROM clause */ |
| 110764 | 111081 | sPk.pNext = pFirst; |
| 110765 | 111082 | } |
| 110766 | 111083 | pProbe = &sPk; |
| 110767 | 111084 | } |
| 110768 | | - rSize = whereCost(pSrc->pTab->nRowEst); |
| 111085 | + rSize = sqlite3LogEst(pTab->nRowEst); |
| 110769 | 111086 | rLogSize = estLog(rSize); |
| 110770 | 111087 | |
| 110771 | 111088 | #ifndef SQLITE_OMIT_AUTOMATIC_INDEX |
| 110772 | 111089 | /* Automatic indexes */ |
| 110773 | 111090 | if( !pBuilder->pOrSet |
| | @@ -110788,17 +111105,17 @@ |
| 110788 | 111105 | pNew->nLTerm = 1; |
| 110789 | 111106 | pNew->aLTerm[0] = pTerm; |
| 110790 | 111107 | /* TUNING: One-time cost for computing the automatic index is |
| 110791 | 111108 | ** approximately 7*N*log2(N) where N is the number of rows in |
| 110792 | 111109 | ** the table being indexed. */ |
| 110793 | | - pNew->rSetup = rLogSize + rSize + 28; assert( 28==whereCost(7) ); |
| 111110 | + pNew->rSetup = rLogSize + rSize + 28; assert( 28==sqlite3LogEst(7) ); |
| 110794 | 111111 | /* TUNING: Each index lookup yields 20 rows in the table. This |
| 110795 | 111112 | ** is more than the usual guess of 10 rows, since we have no way |
| 110796 | 111113 | ** of knowning how selective the index will ultimately be. It would |
| 110797 | 111114 | ** not be unreasonable to make this value much larger. */ |
| 110798 | | - pNew->nOut = 43; assert( 43==whereCost(20) ); |
| 110799 | | - pNew->rRun = whereCostAdd(rLogSize,pNew->nOut); |
| 111115 | + pNew->nOut = 43; assert( 43==sqlite3LogEst(20) ); |
| 111116 | + pNew->rRun = sqlite3LogEstAdd(rLogSize,pNew->nOut); |
| 110800 | 111117 | pNew->wsFlags = WHERE_AUTO_INDEX; |
| 110801 | 111118 | pNew->prereq = mExtra | pTerm->prereqRight; |
| 110802 | 111119 | rc = whereLoopInsert(pBuilder, pNew); |
| 110803 | 111120 | } |
| 110804 | 111121 | } |
| | @@ -110828,14 +111145,12 @@ |
| 110828 | 111145 | |
| 110829 | 111146 | /* Full table scan */ |
| 110830 | 111147 | pNew->iSortIdx = b ? iSortIdx : 0; |
| 110831 | 111148 | /* TUNING: Cost of full table scan is 3*(N + log2(N)). |
| 110832 | 111149 | ** + The extra 3 factor is to encourage the use of indexed lookups |
| 110833 | | - ** over full scans. A smaller constant 2 is used for covering |
| 110834 | | - ** index scans so that a covering index scan will be favored over |
| 110835 | | - ** a table scan. */ |
| 110836 | | - pNew->rRun = whereCostAdd(rSize,rLogSize) + 16; |
| 111150 | + ** over full scans. FIXME */ |
| 111151 | + pNew->rRun = sqlite3LogEstAdd(rSize,rLogSize) + 16; |
| 110837 | 111152 | whereLoopOutputAdjust(pWC, pNew, pSrc->iCursor); |
| 110838 | 111153 | rc = whereLoopInsert(pBuilder, pNew); |
| 110839 | 111154 | pNew->nOut = rSize; |
| 110840 | 111155 | if( rc ) break; |
| 110841 | 111156 | }else{ |
| | @@ -110844,26 +111159,25 @@ |
| 110844 | 111159 | |
| 110845 | 111160 | /* Full scan via index */ |
| 110846 | 111161 | if( b |
| 110847 | 111162 | || ( m==0 |
| 110848 | 111163 | && pProbe->bUnordered==0 |
| 111164 | + && pProbe->szIdxRow<pTab->szTabRow |
| 110849 | 111165 | && (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 |
| 110850 | 111166 | && sqlite3GlobalConfig.bUseCis |
| 110851 | 111167 | && OptimizationEnabled(pWInfo->pParse->db, SQLITE_CoverIdxScan) |
| 110852 | 111168 | ) |
| 110853 | 111169 | ){ |
| 110854 | 111170 | pNew->iSortIdx = b ? iSortIdx : 0; |
| 110855 | 111171 | if( m==0 ){ |
| 110856 | | - /* TUNING: Cost of a covering index scan is 2*(N + log2(N)). |
| 110857 | | - ** + The extra 2 factor is to encourage the use of indexed lookups |
| 110858 | | - ** over index scans. A table scan uses a factor of 3 so that |
| 110859 | | - ** index scans are favored over table scans. |
| 110860 | | - ** + If this covering index might also help satisfy the ORDER BY |
| 110861 | | - ** clause, then the cost is fudged down slightly so that this |
| 110862 | | - ** index is favored above other indices that have no hope of |
| 110863 | | - ** helping with the ORDER BY. */ |
| 110864 | | - pNew->rRun = 10 + whereCostAdd(rSize,rLogSize) - b; |
| 111172 | + /* TUNING: Cost of a covering index scan is K*(N + log2(N)). |
| 111173 | + ** + The extra factor K of between 1.1 and 3.0 that depends |
| 111174 | + ** on the relative sizes of the table and the index. K |
| 111175 | + ** is smaller for smaller indices, thus favoring them. |
| 111176 | + */ |
| 111177 | + pNew->rRun = sqlite3LogEstAdd(rSize,rLogSize) + 1 + |
| 111178 | + (15*pProbe->szIdxRow)/pTab->szTabRow; |
| 110865 | 111179 | }else{ |
| 110866 | 111180 | assert( b!=0 ); |
| 110867 | 111181 | /* TUNING: Cost of scanning a non-covering index is (N+1)*log2(N) |
| 110868 | 111182 | ** which we will simplify to just N*log2(N) */ |
| 110869 | 111183 | pNew->rRun = rSize + rLogSize; |
| | @@ -111037,13 +111351,13 @@ |
| 111037 | 111351 | pIdxInfo->needToFreeIdxStr = 0; |
| 111038 | 111352 | pNew->u.vtab.idxStr = pIdxInfo->idxStr; |
| 111039 | 111353 | pNew->u.vtab.isOrdered = (u8)((pIdxInfo->nOrderBy!=0) |
| 111040 | 111354 | && pIdxInfo->orderByConsumed); |
| 111041 | 111355 | pNew->rSetup = 0; |
| 111042 | | - pNew->rRun = whereCostFromDouble(pIdxInfo->estimatedCost); |
| 111356 | + pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost); |
| 111043 | 111357 | /* TUNING: Every virtual table query returns 25 rows */ |
| 111044 | | - pNew->nOut = 46; assert( 46==whereCost(25) ); |
| 111358 | + pNew->nOut = 46; assert( 46==sqlite3LogEst(25) ); |
| 111045 | 111359 | whereLoopInsert(pBuilder, pNew); |
| 111046 | 111360 | if( pNew->u.vtab.needFree ){ |
| 111047 | 111361 | sqlite3_free(pNew->u.vtab.idxStr); |
| 111048 | 111362 | pNew->u.vtab.needFree = 0; |
| 111049 | 111363 | } |
| | @@ -111076,10 +111390,12 @@ |
| 111076 | 111390 | pWC = pBuilder->pWC; |
| 111077 | 111391 | if( pWInfo->wctrlFlags & WHERE_AND_ONLY ) return SQLITE_OK; |
| 111078 | 111392 | pWCEnd = pWC->a + pWC->nTerm; |
| 111079 | 111393 | pNew = pBuilder->pNew; |
| 111080 | 111394 | memset(&sSum, 0, sizeof(sSum)); |
| 111395 | + pItem = pWInfo->pTabList->a + pNew->iTab; |
| 111396 | + iCur = pItem->iCursor; |
| 111081 | 111397 | |
| 111082 | 111398 | for(pTerm=pWC->a; pTerm<pWCEnd && rc==SQLITE_OK; pTerm++){ |
| 111083 | 111399 | if( (pTerm->eOperator & WO_OR)!=0 |
| 111084 | 111400 | && (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0 |
| 111085 | 111401 | ){ |
| | @@ -111087,12 +111403,10 @@ |
| 111087 | 111403 | WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm]; |
| 111088 | 111404 | WhereTerm *pOrTerm; |
| 111089 | 111405 | int once = 1; |
| 111090 | 111406 | int i, j; |
| 111091 | 111407 | |
| 111092 | | - pItem = pWInfo->pTabList->a + pNew->iTab; |
| 111093 | | - iCur = pItem->iCursor; |
| 111094 | 111408 | sSubBuild = *pBuilder; |
| 111095 | 111409 | sSubBuild.pOrderBy = 0; |
| 111096 | 111410 | sSubBuild.pOrSet = &sCur; |
| 111097 | 111411 | |
| 111098 | 111412 | for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){ |
| | @@ -111129,12 +111443,12 @@ |
| 111129 | 111443 | whereOrMove(&sPrev, &sSum); |
| 111130 | 111444 | sSum.n = 0; |
| 111131 | 111445 | for(i=0; i<sPrev.n; i++){ |
| 111132 | 111446 | for(j=0; j<sCur.n; j++){ |
| 111133 | 111447 | whereOrInsert(&sSum, sPrev.a[i].prereq | sCur.a[j].prereq, |
| 111134 | | - whereCostAdd(sPrev.a[i].rRun, sCur.a[j].rRun), |
| 111135 | | - whereCostAdd(sPrev.a[i].nOut, sCur.a[j].nOut)); |
| 111448 | + sqlite3LogEstAdd(sPrev.a[i].rRun, sCur.a[j].rRun), |
| 111449 | + sqlite3LogEstAdd(sPrev.a[i].nOut, sCur.a[j].nOut)); |
| 111136 | 111450 | } |
| 111137 | 111451 | } |
| 111138 | 111452 | } |
| 111139 | 111453 | } |
| 111140 | 111454 | pNew->nLTerm = 1; |
| | @@ -111468,23 +111782,23 @@ |
| 111468 | 111782 | ** costs if nRowEst==0. |
| 111469 | 111783 | ** |
| 111470 | 111784 | ** Return SQLITE_OK on success or SQLITE_NOMEM of a memory allocation |
| 111471 | 111785 | ** error occurs. |
| 111472 | 111786 | */ |
| 111473 | | -static int wherePathSolver(WhereInfo *pWInfo, WhereCost nRowEst){ |
| 111787 | +static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ |
| 111474 | 111788 | int mxChoice; /* Maximum number of simultaneous paths tracked */ |
| 111475 | 111789 | int nLoop; /* Number of terms in the join */ |
| 111476 | 111790 | Parse *pParse; /* Parsing context */ |
| 111477 | 111791 | sqlite3 *db; /* The database connection */ |
| 111478 | 111792 | int iLoop; /* Loop counter over the terms of the join */ |
| 111479 | 111793 | int ii, jj; /* Loop counters */ |
| 111480 | 111794 | int mxI = 0; /* Index of next entry to replace */ |
| 111481 | | - WhereCost rCost; /* Cost of a path */ |
| 111482 | | - WhereCost nOut; /* Number of outputs */ |
| 111483 | | - WhereCost mxCost = 0; /* Maximum cost of a set of paths */ |
| 111484 | | - WhereCost mxOut = 0; /* Maximum nOut value on the set of paths */ |
| 111485 | | - WhereCost rSortCost; /* Cost to do a sort */ |
| 111795 | + LogEst rCost; /* Cost of a path */ |
| 111796 | + LogEst nOut; /* Number of outputs */ |
| 111797 | + LogEst mxCost = 0; /* Maximum cost of a set of paths */ |
| 111798 | + LogEst mxOut = 0; /* Maximum nOut value on the set of paths */ |
| 111799 | + LogEst rSortCost; /* Cost to do a sort */ |
| 111486 | 111800 | int nTo, nFrom; /* Number of valid entries in aTo[] and aFrom[] */ |
| 111487 | 111801 | WherePath *aFrom; /* All nFrom paths at the previous level */ |
| 111488 | 111802 | WherePath *aTo; /* The nTo best paths at the current level */ |
| 111489 | 111803 | WherePath *pFrom; /* An element of aFrom[] that we are working on */ |
| 111490 | 111804 | WherePath *pTo; /* An element of aTo[] that we are working on */ |
| | @@ -111517,21 +111831,23 @@ |
| 111517 | 111831 | /* Seed the search with a single WherePath containing zero WhereLoops. |
| 111518 | 111832 | ** |
| 111519 | 111833 | ** TUNING: Do not let the number of iterations go above 25. If the cost |
| 111520 | 111834 | ** of computing an automatic index is not paid back within the first 25 |
| 111521 | 111835 | ** rows, then do not use the automatic index. */ |
| 111522 | | - aFrom[0].nRow = MIN(pParse->nQueryLoop, 46); assert( 46==whereCost(25) ); |
| 111836 | + aFrom[0].nRow = MIN(pParse->nQueryLoop, 46); assert( 46==sqlite3LogEst(25) ); |
| 111523 | 111837 | nFrom = 1; |
| 111524 | 111838 | |
| 111525 | 111839 | /* Precompute the cost of sorting the final result set, if the caller |
| 111526 | 111840 | ** to sqlite3WhereBegin() was concerned about sorting */ |
| 111527 | 111841 | rSortCost = 0; |
| 111528 | 111842 | if( pWInfo->pOrderBy==0 || nRowEst==0 ){ |
| 111529 | 111843 | aFrom[0].isOrderedValid = 1; |
| 111530 | 111844 | }else{ |
| 111531 | | - /* TUNING: Estimated cost of sorting is N*log2(N) where N is the |
| 111532 | | - ** number of output rows. */ |
| 111845 | + /* TUNING: Estimated cost of sorting is 48*N*log2(N) where N is the |
| 111846 | + ** number of output rows. The 48 is the expected size of a row to sort. |
| 111847 | + ** FIXME: compute a better estimate of the 48 multiplier based on the |
| 111848 | + ** result set expressions. */ |
| 111533 | 111849 | rSortCost = nRowEst + estLog(nRowEst); |
| 111534 | 111850 | WHERETRACE(0x002,("---- sort cost=%-3d\n", rSortCost)); |
| 111535 | 111851 | } |
| 111536 | 111852 | |
| 111537 | 111853 | /* Compute successively longer WherePaths using the previous generation |
| | @@ -111547,12 +111863,12 @@ |
| 111547 | 111863 | u8 isOrdered = pFrom->isOrdered; |
| 111548 | 111864 | if( (pWLoop->prereq & ~pFrom->maskLoop)!=0 ) continue; |
| 111549 | 111865 | if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue; |
| 111550 | 111866 | /* At this point, pWLoop is a candidate to be the next loop. |
| 111551 | 111867 | ** Compute its cost */ |
| 111552 | | - rCost = whereCostAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow); |
| 111553 | | - rCost = whereCostAdd(rCost, pFrom->rCost); |
| 111868 | + rCost = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow); |
| 111869 | + rCost = sqlite3LogEstAdd(rCost, pFrom->rCost); |
| 111554 | 111870 | nOut = pFrom->nRow + pWLoop->nOut; |
| 111555 | 111871 | maskNew = pFrom->maskLoop | pWLoop->maskSelf; |
| 111556 | 111872 | if( !isOrderedValid ){ |
| 111557 | 111873 | switch( wherePathSatisfiesOrderBy(pWInfo, |
| 111558 | 111874 | pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags, |
| | @@ -111562,11 +111878,11 @@ |
| 111562 | 111878 | isOrderedValid = 1; |
| 111563 | 111879 | break; |
| 111564 | 111880 | case 0: /* No. pFrom+pWLoop will require a separate sort */ |
| 111565 | 111881 | isOrdered = 0; |
| 111566 | 111882 | isOrderedValid = 1; |
| 111567 | | - rCost = whereCostAdd(rCost, rSortCost); |
| 111883 | + rCost = sqlite3LogEstAdd(rCost, rSortCost); |
| 111568 | 111884 | break; |
| 111569 | 111885 | default: /* Cannot tell yet. Try again on the next iteration */ |
| 111570 | 111886 | break; |
| 111571 | 111887 | } |
| 111572 | 111888 | }else{ |
| | @@ -111769,11 +112085,11 @@ |
| 111769 | 112085 | pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW; |
| 111770 | 112086 | pLoop->aLTerm[0] = pTerm; |
| 111771 | 112087 | pLoop->nLTerm = 1; |
| 111772 | 112088 | pLoop->u.btree.nEq = 1; |
| 111773 | 112089 | /* TUNING: Cost of a rowid lookup is 10 */ |
| 111774 | | - pLoop->rRun = 33; /* 33==whereCost(10) */ |
| 112090 | + pLoop->rRun = 33; /* 33==sqlite3LogEst(10) */ |
| 111775 | 112091 | }else{ |
| 111776 | 112092 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 111777 | 112093 | assert( pLoop->aLTermSpace==pLoop->aLTerm ); |
| 111778 | 112094 | assert( ArraySize(pLoop->aLTermSpace)==4 ); |
| 111779 | 112095 | if( pIdx->onError==OE_None |
| | @@ -111792,16 +112108,16 @@ |
| 111792 | 112108 | } |
| 111793 | 112109 | pLoop->nLTerm = j; |
| 111794 | 112110 | pLoop->u.btree.nEq = j; |
| 111795 | 112111 | pLoop->u.btree.pIndex = pIdx; |
| 111796 | 112112 | /* TUNING: Cost of a unique index lookup is 15 */ |
| 111797 | | - pLoop->rRun = 39; /* 39==whereCost(15) */ |
| 112113 | + pLoop->rRun = 39; /* 39==sqlite3LogEst(15) */ |
| 111798 | 112114 | break; |
| 111799 | 112115 | } |
| 111800 | 112116 | } |
| 111801 | 112117 | if( pLoop->wsFlags ){ |
| 111802 | | - pLoop->nOut = (WhereCost)1; |
| 112118 | + pLoop->nOut = (LogEst)1; |
| 111803 | 112119 | pWInfo->a[0].pWLoop = pLoop; |
| 111804 | 112120 | pLoop->maskSelf = getMask(&pWInfo->sMaskSet, iCur); |
| 111805 | 112121 | pWInfo->a[0].iTabCur = iCur; |
| 111806 | 112122 | pWInfo->nRowOut = 1; |
| 111807 | 112123 | if( pWInfo->pOrderBy ) pWInfo->bOBSat = 1; |
| | @@ -112165,11 +112481,11 @@ |
| 112165 | 112481 | WHERETRACE(0xffff,("*** Optimizer Finished ***\n")); |
| 112166 | 112482 | pWInfo->pParse->nQueryLoop += pWInfo->nRowOut; |
| 112167 | 112483 | |
| 112168 | 112484 | /* If the caller is an UPDATE or DELETE statement that is requesting |
| 112169 | 112485 | ** to use a one-pass algorithm, determine if this is appropriate. |
| 112170 | | - ** The one-pass algorithm only works if the WHERE clause constraints |
| 112486 | + ** The one-pass algorithm only works if the WHERE clause constrains |
| 112171 | 112487 | ** the statement to update a single row. |
| 112172 | 112488 | */ |
| 112173 | 112489 | assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 ); |
| 112174 | 112490 | if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 |
| 112175 | 112491 | && (pWInfo->a[0].pWLoop->wsFlags & WHERE_ONEROW)!=0 ){ |
| | @@ -121583,10 +121899,16 @@ |
| 121583 | 121899 | ** verifying the operation of the SQLite core. |
| 121584 | 121900 | */ |
| 121585 | 121901 | int inTransaction; /* True after xBegin but before xCommit/xRollback */ |
| 121586 | 121902 | int mxSavepoint; /* Largest valid xSavepoint integer */ |
| 121587 | 121903 | #endif |
| 121904 | + |
| 121905 | +#ifdef SQLITE_TEST |
| 121906 | + /* True to disable the incremental doclist optimization. This is controled |
| 121907 | + ** by special insert command 'test-no-incr-doclist'. */ |
| 121908 | + int bNoIncrDoclist; |
| 121909 | +#endif |
| 121588 | 121910 | }; |
| 121589 | 121911 | |
| 121590 | 121912 | /* |
| 121591 | 121913 | ** When the core wants to read from the virtual table, it creates a |
| 121592 | 121914 | ** virtual table cursor (an instance of the following structure) using |
| | @@ -121608,11 +121930,12 @@ |
| 121608 | 121930 | int nDoclist; /* Size of buffer at aDoclist */ |
| 121609 | 121931 | u8 bDesc; /* True to sort in descending order */ |
| 121610 | 121932 | int eEvalmode; /* An FTS3_EVAL_XX constant */ |
| 121611 | 121933 | int nRowAvg; /* Average size of database rows, in pages */ |
| 121612 | 121934 | sqlite3_int64 nDoc; /* Documents in table */ |
| 121613 | | - |
| 121935 | + i64 iMinDocid; /* Minimum docid to return */ |
| 121936 | + i64 iMaxDocid; /* Maximum docid to return */ |
| 121614 | 121937 | int isMatchinfoNeeded; /* True when aMatchinfo[] needs filling in */ |
| 121615 | 121938 | u32 *aMatchinfo; /* Information about most recent match */ |
| 121616 | 121939 | int nMatchinfo; /* Number of elements in aMatchinfo[] */ |
| 121617 | 121940 | char *zMatchinfo; /* Matchinfo specification */ |
| 121618 | 121941 | }; |
| | @@ -121638,10 +121961,19 @@ |
| 121638 | 121961 | */ |
| 121639 | 121962 | #define FTS3_FULLSCAN_SEARCH 0 /* Linear scan of %_content table */ |
| 121640 | 121963 | #define FTS3_DOCID_SEARCH 1 /* Lookup by rowid on %_content table */ |
| 121641 | 121964 | #define FTS3_FULLTEXT_SEARCH 2 /* Full-text index search */ |
| 121642 | 121965 | |
| 121966 | +/* |
| 121967 | +** The lower 16-bits of the sqlite3_index_info.idxNum value set by |
| 121968 | +** the xBestIndex() method contains the Fts3Cursor.eSearch value described |
| 121969 | +** above. The upper 16-bits contain a combination of the following |
| 121970 | +** bits, used to describe extra constraints on full-text searches. |
| 121971 | +*/ |
| 121972 | +#define FTS3_HAVE_LANGID 0x00010000 /* languageid=? */ |
| 121973 | +#define FTS3_HAVE_DOCID_GE 0x00020000 /* docid>=? */ |
| 121974 | +#define FTS3_HAVE_DOCID_LE 0x00040000 /* docid<=? */ |
| 121643 | 121975 | |
| 121644 | 121976 | struct Fts3Doclist { |
| 121645 | 121977 | char *aAll; /* Array containing doclist (or NULL) */ |
| 121646 | 121978 | int nAll; /* Size of a[] in bytes */ |
| 121647 | 121979 | char *pNextDocid; /* Pointer to next docid */ |
| | @@ -123058,27 +123390,31 @@ |
| 123058 | 123390 | */ |
| 123059 | 123391 | static int fts3BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ |
| 123060 | 123392 | Fts3Table *p = (Fts3Table *)pVTab; |
| 123061 | 123393 | int i; /* Iterator variable */ |
| 123062 | 123394 | int iCons = -1; /* Index of constraint to use */ |
| 123395 | + |
| 123063 | 123396 | int iLangidCons = -1; /* Index of langid=x constraint, if present */ |
| 123397 | + int iDocidGe = -1; /* Index of docid>=x constraint, if present */ |
| 123398 | + int iDocidLe = -1; /* Index of docid<=x constraint, if present */ |
| 123399 | + int iIdx; |
| 123064 | 123400 | |
| 123065 | 123401 | /* By default use a full table scan. This is an expensive option, |
| 123066 | 123402 | ** so search through the constraints to see if a more efficient |
| 123067 | 123403 | ** strategy is possible. |
| 123068 | 123404 | */ |
| 123069 | 123405 | pInfo->idxNum = FTS3_FULLSCAN_SEARCH; |
| 123070 | 123406 | pInfo->estimatedCost = 5000000; |
| 123071 | 123407 | for(i=0; i<pInfo->nConstraint; i++){ |
| 123408 | + int bDocid; /* True if this constraint is on docid */ |
| 123072 | 123409 | struct sqlite3_index_constraint *pCons = &pInfo->aConstraint[i]; |
| 123073 | 123410 | if( pCons->usable==0 ) continue; |
| 123411 | + |
| 123412 | + bDocid = (pCons->iColumn<0 || pCons->iColumn==p->nColumn+1); |
| 123074 | 123413 | |
| 123075 | 123414 | /* 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 | | - ){ |
| 123415 | + if( iCons<0 && pCons->op==SQLITE_INDEX_CONSTRAINT_EQ && bDocid ){ |
| 123080 | 123416 | pInfo->idxNum = FTS3_DOCID_SEARCH; |
| 123081 | 123417 | pInfo->estimatedCost = 1.0; |
| 123082 | 123418 | iCons = i; |
| 123083 | 123419 | } |
| 123084 | 123420 | |
| | @@ -123103,18 +123439,42 @@ |
| 123103 | 123439 | if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ |
| 123104 | 123440 | && pCons->iColumn==p->nColumn + 2 |
| 123105 | 123441 | ){ |
| 123106 | 123442 | iLangidCons = i; |
| 123107 | 123443 | } |
| 123444 | + |
| 123445 | + if( bDocid ){ |
| 123446 | + switch( pCons->op ){ |
| 123447 | + case SQLITE_INDEX_CONSTRAINT_GE: |
| 123448 | + case SQLITE_INDEX_CONSTRAINT_GT: |
| 123449 | + iDocidGe = i; |
| 123450 | + break; |
| 123451 | + |
| 123452 | + case SQLITE_INDEX_CONSTRAINT_LE: |
| 123453 | + case SQLITE_INDEX_CONSTRAINT_LT: |
| 123454 | + iDocidLe = i; |
| 123455 | + break; |
| 123456 | + } |
| 123457 | + } |
| 123108 | 123458 | } |
| 123109 | 123459 | |
| 123460 | + iIdx = 1; |
| 123110 | 123461 | if( iCons>=0 ){ |
| 123111 | | - pInfo->aConstraintUsage[iCons].argvIndex = 1; |
| 123462 | + pInfo->aConstraintUsage[iCons].argvIndex = iIdx++; |
| 123112 | 123463 | pInfo->aConstraintUsage[iCons].omit = 1; |
| 123113 | 123464 | } |
| 123114 | 123465 | if( iLangidCons>=0 ){ |
| 123115 | | - pInfo->aConstraintUsage[iLangidCons].argvIndex = 2; |
| 123466 | + pInfo->idxNum |= FTS3_HAVE_LANGID; |
| 123467 | + pInfo->aConstraintUsage[iLangidCons].argvIndex = iIdx++; |
| 123468 | + } |
| 123469 | + if( iDocidGe>=0 ){ |
| 123470 | + pInfo->idxNum |= FTS3_HAVE_DOCID_GE; |
| 123471 | + pInfo->aConstraintUsage[iDocidGe].argvIndex = iIdx++; |
| 123472 | + } |
| 123473 | + if( iDocidLe>=0 ){ |
| 123474 | + pInfo->idxNum |= FTS3_HAVE_DOCID_LE; |
| 123475 | + pInfo->aConstraintUsage[iDocidLe].argvIndex = iIdx++; |
| 123116 | 123476 | } |
| 123117 | 123477 | |
| 123118 | 123478 | /* Regardless of the strategy selected, FTS can deliver rows in rowid (or |
| 123119 | 123479 | ** docid) order. Both ascending and descending are possible. |
| 123120 | 123480 | */ |
| | @@ -124556,10 +124916,37 @@ |
| 124556 | 124916 | rc = fts3EvalNext((Fts3Cursor *)pCursor); |
| 124557 | 124917 | } |
| 124558 | 124918 | assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 ); |
| 124559 | 124919 | return rc; |
| 124560 | 124920 | } |
| 124921 | + |
| 124922 | +/* |
| 124923 | +** The following are copied from sqliteInt.h. |
| 124924 | +** |
| 124925 | +** Constants for the largest and smallest possible 64-bit signed integers. |
| 124926 | +** These macros are designed to work correctly on both 32-bit and 64-bit |
| 124927 | +** compilers. |
| 124928 | +*/ |
| 124929 | +#ifndef SQLITE_AMALGAMATION |
| 124930 | +# define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32)) |
| 124931 | +# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64) |
| 124932 | +#endif |
| 124933 | + |
| 124934 | +/* |
| 124935 | +** If the numeric type of argument pVal is "integer", then return it |
| 124936 | +** converted to a 64-bit signed integer. Otherwise, return a copy of |
| 124937 | +** the second parameter, iDefault. |
| 124938 | +*/ |
| 124939 | +static sqlite3_int64 fts3DocidRange(sqlite3_value *pVal, i64 iDefault){ |
| 124940 | + if( pVal ){ |
| 124941 | + int eType = sqlite3_value_numeric_type(pVal); |
| 124942 | + if( eType==SQLITE_INTEGER ){ |
| 124943 | + return sqlite3_value_int64(pVal); |
| 124944 | + } |
| 124945 | + } |
| 124946 | + return iDefault; |
| 124947 | +} |
| 124561 | 124948 | |
| 124562 | 124949 | /* |
| 124563 | 124950 | ** This is the xFilter interface for the virtual table. See |
| 124564 | 124951 | ** the virtual table xFilter method documentation for additional |
| 124565 | 124952 | ** information. |
| | @@ -124582,44 +124969,62 @@ |
| 124582 | 124969 | int nVal, /* Number of elements in apVal */ |
| 124583 | 124970 | sqlite3_value **apVal /* Arguments for the indexing scheme */ |
| 124584 | 124971 | ){ |
| 124585 | 124972 | int rc; |
| 124586 | 124973 | char *zSql; /* SQL statement used to access %_content */ |
| 124974 | + int eSearch; |
| 124587 | 124975 | Fts3Table *p = (Fts3Table *)pCursor->pVtab; |
| 124588 | 124976 | Fts3Cursor *pCsr = (Fts3Cursor *)pCursor; |
| 124977 | + |
| 124978 | + sqlite3_value *pCons = 0; /* The MATCH or rowid constraint, if any */ |
| 124979 | + sqlite3_value *pLangid = 0; /* The "langid = ?" constraint, if any */ |
| 124980 | + sqlite3_value *pDocidGe = 0; /* The "docid >= ?" constraint, if any */ |
| 124981 | + sqlite3_value *pDocidLe = 0; /* The "docid <= ?" constraint, if any */ |
| 124982 | + int iIdx; |
| 124589 | 124983 | |
| 124590 | 124984 | UNUSED_PARAMETER(idxStr); |
| 124591 | 124985 | UNUSED_PARAMETER(nVal); |
| 124592 | 124986 | |
| 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) ); |
| 124987 | + eSearch = (idxNum & 0x0000FFFF); |
| 124988 | + assert( eSearch>=0 && eSearch<=(FTS3_FULLTEXT_SEARCH+p->nColumn) ); |
| 124596 | 124989 | assert( p->pSegments==0 ); |
| 124990 | + |
| 124991 | + /* Collect arguments into local variables */ |
| 124992 | + iIdx = 0; |
| 124993 | + if( eSearch!=FTS3_FULLSCAN_SEARCH ) pCons = apVal[iIdx++]; |
| 124994 | + if( idxNum & FTS3_HAVE_LANGID ) pLangid = apVal[iIdx++]; |
| 124995 | + if( idxNum & FTS3_HAVE_DOCID_GE ) pDocidGe = apVal[iIdx++]; |
| 124996 | + if( idxNum & FTS3_HAVE_DOCID_LE ) pDocidLe = apVal[iIdx++]; |
| 124997 | + assert( iIdx==nVal ); |
| 124597 | 124998 | |
| 124598 | 124999 | /* In case the cursor has been used before, clear it now. */ |
| 124599 | 125000 | sqlite3_finalize(pCsr->pStmt); |
| 124600 | 125001 | sqlite3_free(pCsr->aDoclist); |
| 124601 | 125002 | sqlite3Fts3ExprFree(pCsr->pExpr); |
| 124602 | 125003 | memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor)); |
| 124603 | 125004 | |
| 125005 | + /* Set the lower and upper bounds on docids to return */ |
| 125006 | + pCsr->iMinDocid = fts3DocidRange(pDocidGe, SMALLEST_INT64); |
| 125007 | + pCsr->iMaxDocid = fts3DocidRange(pDocidLe, LARGEST_INT64); |
| 125008 | + |
| 124604 | 125009 | if( idxStr ){ |
| 124605 | 125010 | pCsr->bDesc = (idxStr[0]=='D'); |
| 124606 | 125011 | }else{ |
| 124607 | 125012 | pCsr->bDesc = p->bDescIdx; |
| 124608 | 125013 | } |
| 124609 | | - pCsr->eSearch = (i16)idxNum; |
| 125014 | + pCsr->eSearch = (i16)eSearch; |
| 124610 | 125015 | |
| 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]); |
| 125016 | + if( eSearch!=FTS3_DOCID_SEARCH && eSearch!=FTS3_FULLSCAN_SEARCH ){ |
| 125017 | + int iCol = eSearch-FTS3_FULLTEXT_SEARCH; |
| 125018 | + const char *zQuery = (const char *)sqlite3_value_text(pCons); |
| 124614 | 125019 | |
| 124615 | | - if( zQuery==0 && sqlite3_value_type(apVal[0])!=SQLITE_NULL ){ |
| 125020 | + if( zQuery==0 && sqlite3_value_type(pCons)!=SQLITE_NULL ){ |
| 124616 | 125021 | return SQLITE_NOMEM; |
| 124617 | 125022 | } |
| 124618 | 125023 | |
| 124619 | 125024 | pCsr->iLangid = 0; |
| 124620 | | - if( nVal==2 ) pCsr->iLangid = sqlite3_value_int(apVal[1]); |
| 125025 | + if( pLangid ) pCsr->iLangid = sqlite3_value_int(pLangid); |
| 124621 | 125026 | |
| 124622 | 125027 | assert( p->base.zErrMsg==0 ); |
| 124623 | 125028 | rc = sqlite3Fts3ExprParse(p->pTokenizer, pCsr->iLangid, |
| 124624 | 125029 | p->azColumn, p->bFts4, p->nColumn, iCol, zQuery, -1, &pCsr->pExpr, |
| 124625 | 125030 | &p->base.zErrMsg |
| | @@ -124638,11 +125043,11 @@ |
| 124638 | 125043 | /* Compile a SELECT statement for this cursor. For a full-table-scan, the |
| 124639 | 125044 | ** statement loops through all rows of the %_content table. For a |
| 124640 | 125045 | ** full-text query or docid lookup, the statement retrieves a single |
| 124641 | 125046 | ** row by docid. |
| 124642 | 125047 | */ |
| 124643 | | - if( idxNum==FTS3_FULLSCAN_SEARCH ){ |
| 125048 | + if( eSearch==FTS3_FULLSCAN_SEARCH ){ |
| 124644 | 125049 | zSql = sqlite3_mprintf( |
| 124645 | 125050 | "SELECT %s ORDER BY rowid %s", |
| 124646 | 125051 | p->zReadExprlist, (pCsr->bDesc ? "DESC" : "ASC") |
| 124647 | 125052 | ); |
| 124648 | 125053 | if( zSql ){ |
| | @@ -124649,14 +125054,14 @@ |
| 124649 | 125054 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0); |
| 124650 | 125055 | sqlite3_free(zSql); |
| 124651 | 125056 | }else{ |
| 124652 | 125057 | rc = SQLITE_NOMEM; |
| 124653 | 125058 | } |
| 124654 | | - }else if( idxNum==FTS3_DOCID_SEARCH ){ |
| 125059 | + }else if( eSearch==FTS3_DOCID_SEARCH ){ |
| 124655 | 125060 | rc = fts3CursorSeekStmt(pCsr, &pCsr->pStmt); |
| 124656 | 125061 | if( rc==SQLITE_OK ){ |
| 124657 | | - rc = sqlite3_bind_value(pCsr->pStmt, 1, apVal[0]); |
| 125062 | + rc = sqlite3_bind_value(pCsr->pStmt, 1, pCons); |
| 124658 | 125063 | } |
| 124659 | 125064 | } |
| 124660 | 125065 | if( rc!=SQLITE_OK ) return rc; |
| 124661 | 125066 | |
| 124662 | 125067 | return fts3NextMethod(pCursor); |
| | @@ -125543,10 +125948,16 @@ |
| 125543 | 125948 | } |
| 125544 | 125949 | |
| 125545 | 125950 | return SQLITE_OK; |
| 125546 | 125951 | } |
| 125547 | 125952 | |
| 125953 | +/* |
| 125954 | +** Maximum number of tokens a phrase may have to be considered for the |
| 125955 | +** incremental doclists strategy. |
| 125956 | +*/ |
| 125957 | +#define MAX_INCR_PHRASE_TOKENS 4 |
| 125958 | + |
| 125548 | 125959 | /* |
| 125549 | 125960 | ** This function is called for each Fts3Phrase in a full-text query |
| 125550 | 125961 | ** expression to initialize the mechanism for returning rows. Once this |
| 125551 | 125962 | ** function has been called successfully on an Fts3Phrase, it may be |
| 125552 | 125963 | ** used with fts3EvalPhraseNext() to iterate through the matching docids. |
| | @@ -125556,27 +125967,47 @@ |
| 125556 | 125967 | ** memory within this call. |
| 125557 | 125968 | ** |
| 125558 | 125969 | ** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code. |
| 125559 | 125970 | */ |
| 125560 | 125971 | static int fts3EvalPhraseStart(Fts3Cursor *pCsr, int bOptOk, Fts3Phrase *p){ |
| 125561 | | - int rc; /* Error code */ |
| 125562 | | - Fts3PhraseToken *pFirst = &p->aToken[0]; |
| 125563 | 125972 | 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 | | - ){ |
| 125973 | + int rc = SQLITE_OK; /* Error code */ |
| 125974 | + int i; |
| 125975 | + |
| 125976 | + /* Determine if doclists may be loaded from disk incrementally. This is |
| 125977 | + ** possible if the bOptOk argument is true, the FTS doclists will be |
| 125978 | + ** scanned in forward order, and the phrase consists of |
| 125979 | + ** MAX_INCR_PHRASE_TOKENS or fewer tokens, none of which are are "^first" |
| 125980 | + ** tokens or prefix tokens that cannot use a prefix-index. */ |
| 125981 | + int bHaveIncr = 0; |
| 125982 | + int bIncrOk = (bOptOk |
| 125983 | + && pCsr->bDesc==pTab->bDescIdx |
| 125984 | + && p->nToken<=MAX_INCR_PHRASE_TOKENS && p->nToken>0 |
| 125985 | + && p->nToken<=MAX_INCR_PHRASE_TOKENS && p->nToken>0 |
| 125986 | +#ifdef SQLITE_TEST |
| 125987 | + && pTab->bNoIncrDoclist==0 |
| 125988 | +#endif |
| 125989 | + ); |
| 125990 | + for(i=0; bIncrOk==1 && i<p->nToken; i++){ |
| 125991 | + Fts3PhraseToken *pToken = &p->aToken[i]; |
| 125992 | + if( pToken->bFirst || (pToken->pSegcsr!=0 && !pToken->pSegcsr->bLookup) ){ |
| 125993 | + bIncrOk = 0; |
| 125994 | + } |
| 125995 | + if( pToken->pSegcsr ) bHaveIncr = 1; |
| 125996 | + } |
| 125997 | + |
| 125998 | + if( bIncrOk && bHaveIncr ){ |
| 125572 | 125999 | /* Use the incremental approach. */ |
| 125573 | 126000 | int iCol = (p->iColumn >= pTab->nColumn ? -1 : p->iColumn); |
| 125574 | | - rc = sqlite3Fts3MsrIncrStart( |
| 125575 | | - pTab, pFirst->pSegcsr, iCol, pFirst->z, pFirst->n); |
| 126001 | + for(i=0; rc==SQLITE_OK && i<p->nToken; i++){ |
| 126002 | + Fts3PhraseToken *pToken = &p->aToken[i]; |
| 126003 | + Fts3MultiSegReader *pSegcsr = pToken->pSegcsr; |
| 126004 | + if( pSegcsr ){ |
| 126005 | + rc = sqlite3Fts3MsrIncrStart(pTab, pSegcsr, iCol, pToken->z, pToken->n); |
| 126006 | + } |
| 126007 | + } |
| 125576 | 126008 | p->bIncr = 1; |
| 125577 | | - |
| 125578 | 126009 | }else{ |
| 125579 | 126010 | /* Load the full doclist for the phrase into memory. */ |
| 125580 | 126011 | rc = fts3EvalPhraseLoad(pCsr, p); |
| 125581 | 126012 | p->bIncr = 0; |
| 125582 | 126013 | } |
| | @@ -125680,10 +126111,220 @@ |
| 125680 | 126111 | } |
| 125681 | 126112 | } |
| 125682 | 126113 | |
| 125683 | 126114 | *ppIter = p; |
| 125684 | 126115 | } |
| 126116 | + |
| 126117 | +/* |
| 126118 | +** Advance the iterator pDL to the next entry in pDL->aAll/nAll. Set *pbEof |
| 126119 | +** to true if EOF is reached. |
| 126120 | +*/ |
| 126121 | +static void fts3EvalDlPhraseNext( |
| 126122 | + Fts3Table *pTab, |
| 126123 | + Fts3Doclist *pDL, |
| 126124 | + u8 *pbEof |
| 126125 | +){ |
| 126126 | + char *pIter; /* Used to iterate through aAll */ |
| 126127 | + char *pEnd = &pDL->aAll[pDL->nAll]; /* 1 byte past end of aAll */ |
| 126128 | + |
| 126129 | + if( pDL->pNextDocid ){ |
| 126130 | + pIter = pDL->pNextDocid; |
| 126131 | + }else{ |
| 126132 | + pIter = pDL->aAll; |
| 126133 | + } |
| 126134 | + |
| 126135 | + if( pIter>=pEnd ){ |
| 126136 | + /* We have already reached the end of this doclist. EOF. */ |
| 126137 | + *pbEof = 1; |
| 126138 | + }else{ |
| 126139 | + sqlite3_int64 iDelta; |
| 126140 | + pIter += sqlite3Fts3GetVarint(pIter, &iDelta); |
| 126141 | + if( pTab->bDescIdx==0 || pDL->pNextDocid==0 ){ |
| 126142 | + pDL->iDocid += iDelta; |
| 126143 | + }else{ |
| 126144 | + pDL->iDocid -= iDelta; |
| 126145 | + } |
| 126146 | + pDL->pList = pIter; |
| 126147 | + fts3PoslistCopy(0, &pIter); |
| 126148 | + pDL->nList = (int)(pIter - pDL->pList); |
| 126149 | + |
| 126150 | + /* pIter now points just past the 0x00 that terminates the position- |
| 126151 | + ** list for document pDL->iDocid. However, if this position-list was |
| 126152 | + ** edited in place by fts3EvalNearTrim(), then pIter may not actually |
| 126153 | + ** point to the start of the next docid value. The following line deals |
| 126154 | + ** with this case by advancing pIter past the zero-padding added by |
| 126155 | + ** fts3EvalNearTrim(). */ |
| 126156 | + while( pIter<pEnd && *pIter==0 ) pIter++; |
| 126157 | + |
| 126158 | + pDL->pNextDocid = pIter; |
| 126159 | + assert( pIter>=&pDL->aAll[pDL->nAll] || *pIter ); |
| 126160 | + *pbEof = 0; |
| 126161 | + } |
| 126162 | +} |
| 126163 | + |
| 126164 | +/* |
| 126165 | +** Helper type used by fts3EvalIncrPhraseNext() and incrPhraseTokenNext(). |
| 126166 | +*/ |
| 126167 | +typedef struct TokenDoclist TokenDoclist; |
| 126168 | +struct TokenDoclist { |
| 126169 | + int bIgnore; |
| 126170 | + sqlite3_int64 iDocid; |
| 126171 | + char *pList; |
| 126172 | + int nList; |
| 126173 | +}; |
| 126174 | + |
| 126175 | +/* |
| 126176 | +** Token pToken is an incrementally loaded token that is part of a |
| 126177 | +** multi-token phrase. Advance it to the next matching document in the |
| 126178 | +** database and populate output variable *p with the details of the new |
| 126179 | +** entry. Or, if the iterator has reached EOF, set *pbEof to true. |
| 126180 | +** |
| 126181 | +** If an error occurs, return an SQLite error code. Otherwise, return |
| 126182 | +** SQLITE_OK. |
| 126183 | +*/ |
| 126184 | +static int incrPhraseTokenNext( |
| 126185 | + Fts3Table *pTab, /* Virtual table handle */ |
| 126186 | + Fts3Phrase *pPhrase, /* Phrase to advance token of */ |
| 126187 | + int iToken, /* Specific token to advance */ |
| 126188 | + TokenDoclist *p, /* OUT: Docid and doclist for new entry */ |
| 126189 | + u8 *pbEof /* OUT: True if iterator is at EOF */ |
| 126190 | +){ |
| 126191 | + int rc = SQLITE_OK; |
| 126192 | + |
| 126193 | + if( pPhrase->iDoclistToken==iToken ){ |
| 126194 | + assert( p->bIgnore==0 ); |
| 126195 | + assert( pPhrase->aToken[iToken].pSegcsr==0 ); |
| 126196 | + fts3EvalDlPhraseNext(pTab, &pPhrase->doclist, pbEof); |
| 126197 | + p->pList = pPhrase->doclist.pList; |
| 126198 | + p->nList = pPhrase->doclist.nList; |
| 126199 | + p->iDocid = pPhrase->doclist.iDocid; |
| 126200 | + }else{ |
| 126201 | + Fts3PhraseToken *pToken = &pPhrase->aToken[iToken]; |
| 126202 | + assert( pToken->pDeferred==0 ); |
| 126203 | + assert( pToken->pSegcsr || pPhrase->iDoclistToken>=0 ); |
| 126204 | + if( pToken->pSegcsr ){ |
| 126205 | + assert( p->bIgnore==0 ); |
| 126206 | + rc = sqlite3Fts3MsrIncrNext( |
| 126207 | + pTab, pToken->pSegcsr, &p->iDocid, &p->pList, &p->nList |
| 126208 | + ); |
| 126209 | + if( p->pList==0 ) *pbEof = 1; |
| 126210 | + }else{ |
| 126211 | + p->bIgnore = 1; |
| 126212 | + } |
| 126213 | + } |
| 126214 | + |
| 126215 | + return rc; |
| 126216 | +} |
| 126217 | + |
| 126218 | + |
| 126219 | +/* |
| 126220 | +** The phrase iterator passed as the second argument: |
| 126221 | +** |
| 126222 | +** * features at least one token that uses an incremental doclist, and |
| 126223 | +** |
| 126224 | +** * does not contain any deferred tokens. |
| 126225 | +** |
| 126226 | +** Advance it to the next matching documnent in the database and populate |
| 126227 | +** the Fts3Doclist.pList and nList fields. |
| 126228 | +** |
| 126229 | +** If there is no "next" entry and no error occurs, then *pbEof is set to |
| 126230 | +** 1 before returning. Otherwise, if no error occurs and the iterator is |
| 126231 | +** successfully advanced, *pbEof is set to 0. |
| 126232 | +** |
| 126233 | +** If an error occurs, return an SQLite error code. Otherwise, return |
| 126234 | +** SQLITE_OK. |
| 126235 | +*/ |
| 126236 | +static int fts3EvalIncrPhraseNext( |
| 126237 | + Fts3Cursor *pCsr, /* FTS Cursor handle */ |
| 126238 | + Fts3Phrase *p, /* Phrase object to advance to next docid */ |
| 126239 | + u8 *pbEof /* OUT: Set to 1 if EOF */ |
| 126240 | +){ |
| 126241 | + int rc = SQLITE_OK; |
| 126242 | + Fts3Doclist *pDL = &p->doclist; |
| 126243 | + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; |
| 126244 | + u8 bEof = 0; |
| 126245 | + |
| 126246 | + /* This is only called if it is guaranteed that the phrase has at least |
| 126247 | + ** one incremental token. In which case the bIncr flag is set. */ |
| 126248 | + assert( p->bIncr==1 ); |
| 126249 | + |
| 126250 | + if( p->nToken==1 && p->bIncr ){ |
| 126251 | + rc = sqlite3Fts3MsrIncrNext(pTab, p->aToken[0].pSegcsr, |
| 126252 | + &pDL->iDocid, &pDL->pList, &pDL->nList |
| 126253 | + ); |
| 126254 | + if( pDL->pList==0 ) bEof = 1; |
| 126255 | + }else{ |
| 126256 | + int bDescDoclist = pCsr->bDesc; |
| 126257 | + struct TokenDoclist a[MAX_INCR_PHRASE_TOKENS]; |
| 126258 | + |
| 126259 | + memset(a, 0, sizeof(a)); |
| 126260 | + assert( p->nToken<=MAX_INCR_PHRASE_TOKENS ); |
| 126261 | + assert( p->iDoclistToken<MAX_INCR_PHRASE_TOKENS ); |
| 126262 | + |
| 126263 | + while( bEof==0 ){ |
| 126264 | + int bMaxSet = 0; |
| 126265 | + sqlite3_int64 iMax; /* Largest docid for all iterators */ |
| 126266 | + int i; /* Used to iterate through tokens */ |
| 126267 | + |
| 126268 | + /* Advance the iterator for each token in the phrase once. */ |
| 126269 | + for(i=0; rc==SQLITE_OK && i<p->nToken; i++){ |
| 126270 | + rc = incrPhraseTokenNext(pTab, p, i, &a[i], &bEof); |
| 126271 | + if( a[i].bIgnore==0 && (bMaxSet==0 || DOCID_CMP(iMax, a[i].iDocid)<0) ){ |
| 126272 | + iMax = a[i].iDocid; |
| 126273 | + bMaxSet = 1; |
| 126274 | + } |
| 126275 | + } |
| 126276 | + assert( rc!=SQLITE_OK || a[p->nToken-1].bIgnore==0 ); |
| 126277 | + assert( rc!=SQLITE_OK || bMaxSet ); |
| 126278 | + |
| 126279 | + /* Keep advancing iterators until they all point to the same document */ |
| 126280 | + for(i=0; i<p->nToken; i++){ |
| 126281 | + while( rc==SQLITE_OK && bEof==0 |
| 126282 | + && a[i].bIgnore==0 && DOCID_CMP(a[i].iDocid, iMax)<0 |
| 126283 | + ){ |
| 126284 | + rc = incrPhraseTokenNext(pTab, p, i, &a[i], &bEof); |
| 126285 | + if( DOCID_CMP(a[i].iDocid, iMax)>0 ){ |
| 126286 | + iMax = a[i].iDocid; |
| 126287 | + i = 0; |
| 126288 | + } |
| 126289 | + } |
| 126290 | + } |
| 126291 | + |
| 126292 | + /* Check if the current entries really are a phrase match */ |
| 126293 | + if( bEof==0 ){ |
| 126294 | + int nList = 0; |
| 126295 | + int nByte = a[p->nToken-1].nList; |
| 126296 | + char *aDoclist = sqlite3_malloc(nByte+1); |
| 126297 | + if( !aDoclist ) return SQLITE_NOMEM; |
| 126298 | + memcpy(aDoclist, a[p->nToken-1].pList, nByte+1); |
| 126299 | + |
| 126300 | + for(i=0; i<(p->nToken-1); i++){ |
| 126301 | + if( a[i].bIgnore==0 ){ |
| 126302 | + char *pL = a[i].pList; |
| 126303 | + char *pR = aDoclist; |
| 126304 | + char *pOut = aDoclist; |
| 126305 | + int nDist = p->nToken-1-i; |
| 126306 | + int res = fts3PoslistPhraseMerge(&pOut, nDist, 0, 1, &pL, &pR); |
| 126307 | + if( res==0 ) break; |
| 126308 | + nList = (pOut - aDoclist); |
| 126309 | + } |
| 126310 | + } |
| 126311 | + if( i==(p->nToken-1) ){ |
| 126312 | + pDL->iDocid = iMax; |
| 126313 | + pDL->pList = aDoclist; |
| 126314 | + pDL->nList = nList; |
| 126315 | + pDL->bFreeList = 1; |
| 126316 | + break; |
| 126317 | + } |
| 126318 | + sqlite3_free(aDoclist); |
| 126319 | + } |
| 126320 | + } |
| 126321 | + } |
| 126322 | + |
| 126323 | + *pbEof = bEof; |
| 126324 | + return rc; |
| 126325 | +} |
| 125685 | 126326 | |
| 125686 | 126327 | /* |
| 125687 | 126328 | ** Attempt to move the phrase iterator to point to the next matching docid. |
| 125688 | 126329 | ** If an error occurs, return an SQLite error code. Otherwise, return |
| 125689 | 126330 | ** SQLITE_OK. |
| | @@ -125700,59 +126341,18 @@ |
| 125700 | 126341 | int rc = SQLITE_OK; |
| 125701 | 126342 | Fts3Doclist *pDL = &p->doclist; |
| 125702 | 126343 | Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; |
| 125703 | 126344 | |
| 125704 | 126345 | 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 | | - } |
| 126346 | + rc = fts3EvalIncrPhraseNext(pCsr, p, pbEof); |
| 125713 | 126347 | }else if( pCsr->bDesc!=pTab->bDescIdx && pDL->nAll ){ |
| 125714 | 126348 | sqlite3Fts3DoclistPrev(pTab->bDescIdx, pDL->aAll, pDL->nAll, |
| 125715 | 126349 | &pDL->pNextDocid, &pDL->iDocid, &pDL->nList, pbEof |
| 125716 | 126350 | ); |
| 125717 | 126351 | pDL->pList = pDL->pNextDocid; |
| 125718 | 126352 | }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 | | - } |
| 126353 | + fts3EvalDlPhraseNext(pTab, pDL, pbEof); |
| 125754 | 126354 | } |
| 125755 | 126355 | |
| 125756 | 126356 | return rc; |
| 125757 | 126357 | } |
| 125758 | 126358 | |
| | @@ -125773,11 +126373,10 @@ |
| 125773 | 126373 | ** code before returning. |
| 125774 | 126374 | */ |
| 125775 | 126375 | static void fts3EvalStartReaders( |
| 125776 | 126376 | Fts3Cursor *pCsr, /* FTS Cursor handle */ |
| 125777 | 126377 | Fts3Expr *pExpr, /* Expression to initialize phrases in */ |
| 125778 | | - int bOptOk, /* True to enable incremental loading */ |
| 125779 | 126378 | int *pRc /* IN/OUT: Error code */ |
| 125780 | 126379 | ){ |
| 125781 | 126380 | if( pExpr && SQLITE_OK==*pRc ){ |
| 125782 | 126381 | if( pExpr->eType==FTSQUERY_PHRASE ){ |
| 125783 | 126382 | int i; |
| | @@ -125784,14 +126383,14 @@ |
| 125784 | 126383 | int nToken = pExpr->pPhrase->nToken; |
| 125785 | 126384 | for(i=0; i<nToken; i++){ |
| 125786 | 126385 | if( pExpr->pPhrase->aToken[i].pDeferred==0 ) break; |
| 125787 | 126386 | } |
| 125788 | 126387 | pExpr->bDeferred = (i==nToken); |
| 125789 | | - *pRc = fts3EvalPhraseStart(pCsr, bOptOk, pExpr->pPhrase); |
| 126388 | + *pRc = fts3EvalPhraseStart(pCsr, 1, pExpr->pPhrase); |
| 125790 | 126389 | }else{ |
| 125791 | | - fts3EvalStartReaders(pCsr, pExpr->pLeft, bOptOk, pRc); |
| 125792 | | - fts3EvalStartReaders(pCsr, pExpr->pRight, bOptOk, pRc); |
| 126390 | + fts3EvalStartReaders(pCsr, pExpr->pLeft, pRc); |
| 126391 | + fts3EvalStartReaders(pCsr, pExpr->pRight, pRc); |
| 125793 | 126392 | pExpr->bDeferred = (pExpr->pLeft->bDeferred && pExpr->pRight->bDeferred); |
| 125794 | 126393 | } |
| 125795 | 126394 | } |
| 125796 | 126395 | } |
| 125797 | 126396 | |
| | @@ -126029,11 +126628,11 @@ |
| 126029 | 126628 | /* Set nLoad4 to the value of (4^nOther) for the next iteration of the |
| 126030 | 126629 | ** for-loop. Except, limit the value to 2^24 to prevent it from |
| 126031 | 126630 | ** overflowing the 32-bit integer it is stored in. */ |
| 126032 | 126631 | if( ii<12 ) nLoad4 = nLoad4*4; |
| 126033 | 126632 | |
| 126034 | | - if( ii==0 || pTC->pPhrase->nToken>1 ){ |
| 126633 | + if( ii==0 || (pTC->pPhrase->nToken>1 && ii!=nToken-1) ){ |
| 126035 | 126634 | /* Either this is the cheapest token in the entire query, or it is |
| 126036 | 126635 | ** part of a multi-token phrase. Either way, the entire doclist will |
| 126037 | 126636 | ** (eventually) be loaded into memory. It may as well be now. */ |
| 126038 | 126637 | Fts3PhraseToken *pToken = pTC->pToken; |
| 126039 | 126638 | int nList = 0; |
| | @@ -126109,11 +126708,11 @@ |
| 126109 | 126708 | sqlite3_free(aTC); |
| 126110 | 126709 | } |
| 126111 | 126710 | } |
| 126112 | 126711 | #endif |
| 126113 | 126712 | |
| 126114 | | - fts3EvalStartReaders(pCsr, pCsr->pExpr, 1, &rc); |
| 126713 | + fts3EvalStartReaders(pCsr, pCsr->pExpr, &rc); |
| 126115 | 126714 | return rc; |
| 126116 | 126715 | } |
| 126117 | 126716 | |
| 126118 | 126717 | /* |
| 126119 | 126718 | ** Invalidate the current position list for phrase pPhrase. |
| | @@ -126592,10 +127191,20 @@ |
| 126592 | 127191 | pCsr->isRequireSeek = 1; |
| 126593 | 127192 | pCsr->isMatchinfoNeeded = 1; |
| 126594 | 127193 | pCsr->iPrevId = pExpr->iDocid; |
| 126595 | 127194 | }while( pCsr->isEof==0 && fts3EvalTestDeferredAndNear(pCsr, &rc) ); |
| 126596 | 127195 | } |
| 127196 | + |
| 127197 | + /* Check if the cursor is past the end of the docid range specified |
| 127198 | + ** by Fts3Cursor.iMinDocid/iMaxDocid. If so, set the EOF flag. */ |
| 127199 | + if( rc==SQLITE_OK && ( |
| 127200 | + (pCsr->bDesc==0 && pCsr->iPrevId>pCsr->iMaxDocid) |
| 127201 | + || (pCsr->bDesc!=0 && pCsr->iPrevId<pCsr->iMinDocid) |
| 127202 | + )){ |
| 127203 | + pCsr->isEof = 1; |
| 127204 | + } |
| 127205 | + |
| 126597 | 127206 | return rc; |
| 126598 | 127207 | } |
| 126599 | 127208 | |
| 126600 | 127209 | /* |
| 126601 | 127210 | ** Restart interation for expression pExpr so that the next call to |
| | @@ -126615,16 +127224,20 @@ |
| 126615 | 127224 | Fts3Phrase *pPhrase = pExpr->pPhrase; |
| 126616 | 127225 | |
| 126617 | 127226 | if( pPhrase ){ |
| 126618 | 127227 | fts3EvalInvalidatePoslist(pPhrase); |
| 126619 | 127228 | if( pPhrase->bIncr ){ |
| 126620 | | - assert( pPhrase->nToken==1 ); |
| 126621 | | - assert( pPhrase->aToken[0].pSegcsr ); |
| 126622 | | - sqlite3Fts3MsrIncrRestart(pPhrase->aToken[0].pSegcsr); |
| 127229 | + int i; |
| 127230 | + for(i=0; i<pPhrase->nToken; i++){ |
| 127231 | + Fts3PhraseToken *pToken = &pPhrase->aToken[i]; |
| 127232 | + assert( pToken->pDeferred==0 ); |
| 127233 | + if( pToken->pSegcsr ){ |
| 127234 | + sqlite3Fts3MsrIncrRestart(pToken->pSegcsr); |
| 127235 | + } |
| 127236 | + } |
| 126623 | 127237 | *pRc = fts3EvalPhraseStart(pCsr, 0, pPhrase); |
| 126624 | 127238 | } |
| 126625 | | - |
| 126626 | 127239 | pPhrase->doclist.pNextDocid = 0; |
| 126627 | 127240 | pPhrase->doclist.iDocid = 0; |
| 126628 | 127241 | } |
| 126629 | 127242 | |
| 126630 | 127243 | pExpr->iDocid = 0; |
| | @@ -126869,19 +127482,27 @@ |
| 126869 | 127482 | |
| 126870 | 127483 | iDocid = pExpr->iDocid; |
| 126871 | 127484 | pIter = pPhrase->doclist.pList; |
| 126872 | 127485 | if( iDocid!=pCsr->iPrevId || pExpr->bEof ){ |
| 126873 | 127486 | int bDescDoclist = pTab->bDescIdx; /* For DOCID_CMP macro */ |
| 127487 | + int iMul; /* +1 if csr dir matches index dir, else -1 */ |
| 126874 | 127488 | int bOr = 0; |
| 126875 | 127489 | u8 bEof = 0; |
| 126876 | | - Fts3Expr *p; |
| 127490 | + u8 bTreeEof = 0; |
| 127491 | + Fts3Expr *p; /* Used to iterate from pExpr to root */ |
| 127492 | + Fts3Expr *pNear; /* Most senior NEAR ancestor (or pExpr) */ |
| 126877 | 127493 | |
| 126878 | 127494 | /* Check if this phrase descends from an OR expression node. If not, |
| 126879 | 127495 | ** return NULL. Otherwise, the entry that corresponds to docid |
| 126880 | | - ** pCsr->iPrevId may lie earlier in the doclist buffer. */ |
| 127496 | + ** pCsr->iPrevId may lie earlier in the doclist buffer. Or, if the |
| 127497 | + ** tree that the node is part of has been marked as EOF, but the node |
| 127498 | + ** itself is not EOF, then it may point to an earlier entry. */ |
| 127499 | + pNear = pExpr; |
| 126881 | 127500 | for(p=pExpr->pParent; p; p=p->pParent){ |
| 126882 | 127501 | if( p->eType==FTSQUERY_OR ) bOr = 1; |
| 127502 | + if( p->eType==FTSQUERY_NEAR ) pNear = p; |
| 127503 | + if( p->bEof ) bTreeEof = 1; |
| 126883 | 127504 | } |
| 126884 | 127505 | if( bOr==0 ) return SQLITE_OK; |
| 126885 | 127506 | |
| 126886 | 127507 | /* This is the descendent of an OR node. In this case we cannot use |
| 126887 | 127508 | ** an incremental phrase. Load the entire doclist for the phrase |
| | @@ -126896,33 +127517,63 @@ |
| 126896 | 127517 | } |
| 126897 | 127518 | pIter = pPhrase->doclist.pList; |
| 126898 | 127519 | assert( rc!=SQLITE_OK || pPhrase->bIncr==0 ); |
| 126899 | 127520 | if( rc!=SQLITE_OK ) return rc; |
| 126900 | 127521 | } |
| 127522 | + |
| 127523 | + iMul = ((pCsr->bDesc==bDescDoclist) ? 1 : -1); |
| 127524 | + while( bTreeEof==1 |
| 127525 | + && pNear->bEof==0 |
| 127526 | + && (DOCID_CMP(pNear->iDocid, pCsr->iPrevId) * iMul)<0 |
| 127527 | + ){ |
| 127528 | + int rc = SQLITE_OK; |
| 127529 | + fts3EvalNextRow(pCsr, pExpr, &rc); |
| 127530 | + if( rc!=SQLITE_OK ) return rc; |
| 127531 | + iDocid = pExpr->iDocid; |
| 127532 | + pIter = pPhrase->doclist.pList; |
| 127533 | + } |
| 126901 | 127534 | |
| 126902 | | - if( pExpr->bEof ){ |
| 126903 | | - pIter = 0; |
| 126904 | | - iDocid = 0; |
| 126905 | | - } |
| 126906 | 127535 | bEof = (pPhrase->doclist.nAll==0); |
| 126907 | 127536 | assert( bDescDoclist==0 || bDescDoclist==1 ); |
| 126908 | 127537 | assert( pCsr->bDesc==0 || pCsr->bDesc==1 ); |
| 126909 | 127538 | |
| 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 | | - ); |
| 127539 | + if( bEof==0 ){ |
| 127540 | + if( pCsr->bDesc==bDescDoclist ){ |
| 127541 | + int dummy; |
| 127542 | + if( pNear->bEof ){ |
| 127543 | + /* This expression is already at EOF. So position it to point to the |
| 127544 | + ** last entry in the doclist at pPhrase->doclist.aAll[]. Variable |
| 127545 | + ** iDocid is already set for this entry, so all that is required is |
| 127546 | + ** to set pIter to point to the first byte of the last position-list |
| 127547 | + ** in the doclist. |
| 127548 | + ** |
| 127549 | + ** It would also be correct to set pIter and iDocid to zero. In |
| 127550 | + ** this case, the first call to sqltie3Fts4DoclistPrev() below |
| 127551 | + ** would also move the iterator to point to the last entry in the |
| 127552 | + ** doclist. However, this is expensive, as to do so it has to |
| 127553 | + ** iterate through the entire doclist from start to finish (since |
| 127554 | + ** it does not know the docid for the last entry). */ |
| 127555 | + pIter = &pPhrase->doclist.aAll[pPhrase->doclist.nAll-1]; |
| 127556 | + fts3ReversePoslist(pPhrase->doclist.aAll, &pIter); |
| 127557 | + } |
| 127558 | + while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){ |
| 127559 | + sqlite3Fts3DoclistPrev( |
| 127560 | + bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll, |
| 127561 | + &pIter, &iDocid, &dummy, &bEof |
| 127562 | + ); |
| 127563 | + } |
| 127564 | + }else{ |
| 127565 | + if( pNear->bEof ){ |
| 127566 | + pIter = 0; |
| 127567 | + iDocid = 0; |
| 127568 | + } |
| 127569 | + while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){ |
| 127570 | + sqlite3Fts3DoclistNext( |
| 127571 | + bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll, |
| 127572 | + &pIter, &iDocid, &bEof |
| 127573 | + ); |
| 127574 | + } |
| 126924 | 127575 | } |
| 126925 | 127576 | } |
| 126926 | 127577 | |
| 126927 | 127578 | if( bEof || iDocid!=pCsr->iPrevId ) pIter = 0; |
| 126928 | 127579 | } |
| | @@ -135756,11 +136407,11 @@ |
| 135756 | 136407 | assert( p->bFts4==0 ); |
| 135757 | 136408 | sqlite3Fts3CreateStatTable(&rc, p); |
| 135758 | 136409 | if( rc ) return rc; |
| 135759 | 136410 | } |
| 135760 | 136411 | rc = fts3SqlStmt(p, SQL_REPLACE_STAT, &pStmt, 0); |
| 135761 | | - if( rc ) return rc;; |
| 136412 | + if( rc ) return rc; |
| 135762 | 136413 | sqlite3_bind_int(pStmt, 1, FTS_STAT_AUTOINCRMERGE); |
| 135763 | 136414 | sqlite3_bind_int(pStmt, 2, p->bAutoincrmerge); |
| 135764 | 136415 | sqlite3_step(pStmt); |
| 135765 | 136416 | rc = sqlite3_reset(pStmt); |
| 135766 | 136417 | return rc; |
| | @@ -136025,10 +136676,13 @@ |
| 136025 | 136676 | }else if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){ |
| 136026 | 136677 | p->nNodeSize = atoi(&zVal[9]); |
| 136027 | 136678 | rc = SQLITE_OK; |
| 136028 | 136679 | }else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 9) ){ |
| 136029 | 136680 | p->nMaxPendingData = atoi(&zVal[11]); |
| 136681 | + rc = SQLITE_OK; |
| 136682 | + }else if( nVal>21 && 0==sqlite3_strnicmp(zVal, "test-no-incr-doclist=", 21) ){ |
| 136683 | + p->bNoIncrDoclist = atoi(&zVal[21]); |
| 136030 | 136684 | rc = SQLITE_OK; |
| 136031 | 136685 | #endif |
| 136032 | 136686 | }else{ |
| 136033 | 136687 | rc = SQLITE_ERROR; |
| 136034 | 136688 | } |
| 136035 | 136689 | |