| | @@ -135,11 +135,11 @@ |
| 135 | 135 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 136 | 136 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 137 | 137 | */ |
| 138 | 138 | #define SQLITE_VERSION "3.8.2" |
| 139 | 139 | #define SQLITE_VERSION_NUMBER 3008002 |
| 140 | | -#define SQLITE_SOURCE_ID "2013-11-12 15:33:40 0f924c6ef6cf2ac5a61aafa8dd8e3309b3970499" |
| 140 | +#define SQLITE_SOURCE_ID "2013-11-14 19:34:10 10d59226382adcb8016fc2d927e5a0c0b36f3980" |
| 141 | 141 | |
| 142 | 142 | /* |
| 143 | 143 | ** CAPI3REF: Run-Time Library Version Numbers |
| 144 | 144 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 145 | 145 | ** |
| | @@ -9237,11 +9237,10 @@ |
| 9237 | 9237 | SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe*); |
| 9238 | 9238 | SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int); |
| 9239 | 9239 | SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe*); |
| 9240 | 9240 | #ifdef SQLITE_DEBUG |
| 9241 | 9241 | SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *, int); |
| 9242 | | -SQLITE_PRIVATE void sqlite3VdbeTrace(Vdbe*,FILE*); |
| 9243 | 9242 | #endif |
| 9244 | 9243 | SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe*); |
| 9245 | 9244 | SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe*); |
| 9246 | 9245 | SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe*); |
| 9247 | 9246 | SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe*,int); |
| | @@ -10304,10 +10303,11 @@ |
| 10304 | 10303 | #define SQLITE_PreferBuiltin 0x00200000 /* Preference to built-in funcs */ |
| 10305 | 10304 | #define SQLITE_LoadExtension 0x00400000 /* Enable load_extension */ |
| 10306 | 10305 | #define SQLITE_EnableTrigger 0x00800000 /* True to enable triggers */ |
| 10307 | 10306 | #define SQLITE_DeferFKs 0x01000000 /* Defer all FK constraints */ |
| 10308 | 10307 | #define SQLITE_QueryOnly 0x02000000 /* Disable database changes */ |
| 10308 | +#define SQLITE_VdbeEQP 0x04000000 /* Debug EXPLAIN QUERY PLAN */ |
| 10309 | 10309 | |
| 10310 | 10310 | |
| 10311 | 10311 | /* |
| 10312 | 10312 | ** Bits of the sqlite3.dbOptFlags field that are used by the |
| 10313 | 10313 | ** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to |
| | @@ -13700,13 +13700,10 @@ |
| 13700 | 13700 | i64 nFkConstraint; /* Number of imm. FK constraints this VM */ |
| 13701 | 13701 | i64 nStmtDefCons; /* Number of def. constraints when stmt started */ |
| 13702 | 13702 | i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */ |
| 13703 | 13703 | char *zSql; /* Text of the SQL statement that generated this */ |
| 13704 | 13704 | void *pFree; /* Free this when deleting the vdbe */ |
| 13705 | | -#ifdef SQLITE_DEBUG |
| 13706 | | - FILE *trace; /* Write an execution trace here, if not NULL */ |
| 13707 | | -#endif |
| 13708 | 13705 | #ifdef SQLITE_ENABLE_TREE_EXPLAIN |
| 13709 | 13706 | Explain *pExplain; /* The explainer */ |
| 13710 | 13707 | char *zExplain; /* Explanation of data structures */ |
| 13711 | 13708 | #endif |
| 13712 | 13709 | VdbeFrame *pFrame; /* Parent frame */ |
| | @@ -61013,19 +61010,10 @@ |
| 61013 | 61010 | pA->zSql = pB->zSql; |
| 61014 | 61011 | pB->zSql = zTmp; |
| 61015 | 61012 | pB->isPrepareV2 = pA->isPrepareV2; |
| 61016 | 61013 | } |
| 61017 | 61014 | |
| 61018 | | -#ifdef SQLITE_DEBUG |
| 61019 | | -/* |
| 61020 | | -** Turn tracing on or off |
| 61021 | | -*/ |
| 61022 | | -SQLITE_PRIVATE void sqlite3VdbeTrace(Vdbe *p, FILE *trace){ |
| 61023 | | - p->trace = trace; |
| 61024 | | -} |
| 61025 | | -#endif |
| 61026 | | - |
| 61027 | 61015 | /* |
| 61028 | 61016 | ** Resize the Vdbe.aOp array so that it is at least one op larger than |
| 61029 | 61017 | ** it was. |
| 61030 | 61018 | ** |
| 61031 | 61019 | ** If an out-of-memory error occurs while resizing the array, return |
| | @@ -61917,11 +61905,11 @@ |
| 61917 | 61905 | assert( i<nTemp ); |
| 61918 | 61906 | break; |
| 61919 | 61907 | } |
| 61920 | 61908 | case P4_COLLSEQ: { |
| 61921 | 61909 | CollSeq *pColl = pOp->p4.pColl; |
| 61922 | | - sqlite3_snprintf(nTemp, zTemp, "collseq(%.20s)", pColl->zName); |
| 61910 | + sqlite3_snprintf(nTemp, zTemp, "(%.20s)", pColl->zName); |
| 61923 | 61911 | break; |
| 61924 | 61912 | } |
| 61925 | 61913 | case P4_FUNCDEF: { |
| 61926 | 61914 | FuncDef *pDef = pOp->p4.pFunc; |
| 61927 | 61915 | sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg); |
| | @@ -62350,19 +62338,21 @@ |
| 62350 | 62338 | #ifdef SQLITE_DEBUG |
| 62351 | 62339 | /* |
| 62352 | 62340 | ** Print the SQL that was used to generate a VDBE program. |
| 62353 | 62341 | */ |
| 62354 | 62342 | SQLITE_PRIVATE void sqlite3VdbePrintSql(Vdbe *p){ |
| 62355 | | - int nOp = p->nOp; |
| 62356 | | - VdbeOp *pOp; |
| 62357 | | - if( nOp<1 ) return; |
| 62358 | | - pOp = &p->aOp[0]; |
| 62359 | | - if( pOp->opcode==OP_Trace && pOp->p4.z!=0 ){ |
| 62360 | | - const char *z = pOp->p4.z; |
| 62361 | | - while( sqlite3Isspace(*z) ) z++; |
| 62362 | | - printf("SQL: [%s]\n", z); |
| 62363 | | - } |
| 62343 | + const char *z = 0; |
| 62344 | + if( p->zSql ){ |
| 62345 | + z = p->zSql; |
| 62346 | + }else if( p->nOp>=1 ){ |
| 62347 | + const VdbeOp *pOp = &p->aOp[0]; |
| 62348 | + if( pOp->opcode==OP_Trace && pOp->p4.z!=0 ){ |
| 62349 | + z = pOp->p4.z; |
| 62350 | + while( sqlite3Isspace(*z) ) z++; |
| 62351 | + } |
| 62352 | + } |
| 62353 | + if( z ) printf("SQL: [%s]\n", z); |
| 62364 | 62354 | } |
| 62365 | 62355 | #endif |
| 62366 | 62356 | |
| 62367 | 62357 | #if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE) |
| 62368 | 62358 | /* |
| | @@ -66366,41 +66356,40 @@ |
| 66366 | 66356 | |
| 66367 | 66357 | #ifdef SQLITE_DEBUG |
| 66368 | 66358 | /* |
| 66369 | 66359 | ** Print the value of a register for tracing purposes: |
| 66370 | 66360 | */ |
| 66371 | | -static void memTracePrint(FILE *out, Mem *p){ |
| 66361 | +static void memTracePrint(Mem *p){ |
| 66372 | 66362 | if( p->flags & MEM_Invalid ){ |
| 66373 | | - fprintf(out, " undefined"); |
| 66363 | + printf(" undefined"); |
| 66374 | 66364 | }else if( p->flags & MEM_Null ){ |
| 66375 | | - fprintf(out, " NULL"); |
| 66365 | + printf(" NULL"); |
| 66376 | 66366 | }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){ |
| 66377 | | - fprintf(out, " si:%lld", p->u.i); |
| 66367 | + printf(" si:%lld", p->u.i); |
| 66378 | 66368 | }else if( p->flags & MEM_Int ){ |
| 66379 | | - fprintf(out, " i:%lld", p->u.i); |
| 66369 | + printf(" i:%lld", p->u.i); |
| 66380 | 66370 | #ifndef SQLITE_OMIT_FLOATING_POINT |
| 66381 | 66371 | }else if( p->flags & MEM_Real ){ |
| 66382 | | - fprintf(out, " r:%g", p->r); |
| 66372 | + printf(" r:%g", p->r); |
| 66383 | 66373 | #endif |
| 66384 | 66374 | }else if( p->flags & MEM_RowSet ){ |
| 66385 | | - fprintf(out, " (rowset)"); |
| 66375 | + printf(" (rowset)"); |
| 66386 | 66376 | }else{ |
| 66387 | 66377 | char zBuf[200]; |
| 66388 | 66378 | sqlite3VdbeMemPrettyPrint(p, zBuf); |
| 66389 | | - fprintf(out, " "); |
| 66390 | | - fprintf(out, "%s", zBuf); |
| 66379 | + printf(" %s", zBuf); |
| 66391 | 66380 | } |
| 66392 | 66381 | } |
| 66393 | | -static void registerTrace(FILE *out, int iReg, Mem *p){ |
| 66394 | | - fprintf(out, "REG[%d] = ", iReg); |
| 66395 | | - memTracePrint(out, p); |
| 66396 | | - fprintf(out, "\n"); |
| 66382 | +static void registerTrace(int iReg, Mem *p){ |
| 66383 | + printf("REG[%d] = ", iReg); |
| 66384 | + memTracePrint(p); |
| 66385 | + printf("\n"); |
| 66397 | 66386 | } |
| 66398 | 66387 | #endif |
| 66399 | 66388 | |
| 66400 | 66389 | #ifdef SQLITE_DEBUG |
| 66401 | | -# define REGISTER_TRACE(R,M) if(p->trace)registerTrace(p->trace,R,M) |
| 66390 | +# define REGISTER_TRACE(R,M) if(db->flags&SQLITE_VdbeTrace)registerTrace(R,M) |
| 66402 | 66391 | #else |
| 66403 | 66392 | # define REGISTER_TRACE(R,M) |
| 66404 | 66393 | #endif |
| 66405 | 66394 | |
| 66406 | 66395 | |
| | @@ -67051,17 +67040,32 @@ |
| 67051 | 67040 | } |
| 67052 | 67041 | } |
| 67053 | 67042 | #endif |
| 67054 | 67043 | #ifdef SQLITE_DEBUG |
| 67055 | 67044 | sqlite3BeginBenignMalloc(); |
| 67056 | | - if( p->pc==0 && (p->db->flags & SQLITE_VdbeListing)!=0 ){ |
| 67045 | + if( p->pc==0 |
| 67046 | + && (p->db->flags & (SQLITE_VdbeListing|SQLITE_VdbeEQP|SQLITE_VdbeTrace))!=0 |
| 67047 | + ){ |
| 67057 | 67048 | int i; |
| 67058 | | - printf("VDBE Program Listing:\n"); |
| 67049 | + int once = 1; |
| 67059 | 67050 | sqlite3VdbePrintSql(p); |
| 67060 | | - for(i=0; i<p->nOp; i++){ |
| 67061 | | - sqlite3VdbePrintOp(stdout, i, &aOp[i]); |
| 67051 | + if( p->db->flags & SQLITE_VdbeListing ){ |
| 67052 | + printf("VDBE Program Listing:\n"); |
| 67053 | + for(i=0; i<p->nOp; i++){ |
| 67054 | + sqlite3VdbePrintOp(stdout, i, &aOp[i]); |
| 67055 | + } |
| 67062 | 67056 | } |
| 67057 | + if( p->db->flags & SQLITE_VdbeEQP ){ |
| 67058 | + for(i=0; i<p->nOp; i++){ |
| 67059 | + if( aOp[i].opcode==OP_Explain ){ |
| 67060 | + if( once ) printf("VDBE Query Plan:\n"); |
| 67061 | + printf("%s\n", aOp[i].p4.z); |
| 67062 | + once = 0; |
| 67063 | + } |
| 67064 | + } |
| 67065 | + } |
| 67066 | + if( p->db->flags & SQLITE_VdbeTrace ) printf("VDBE Trace:\n"); |
| 67063 | 67067 | } |
| 67064 | 67068 | sqlite3EndBenignMalloc(); |
| 67065 | 67069 | #endif |
| 67066 | 67070 | for(pc=p->pc; rc==SQLITE_OK; pc++){ |
| 67067 | 67071 | assert( pc>=0 && pc<p->nOp ); |
| | @@ -67074,16 +67078,12 @@ |
| 67074 | 67078 | pOp = &aOp[pc]; |
| 67075 | 67079 | |
| 67076 | 67080 | /* Only allow tracing if SQLITE_DEBUG is defined. |
| 67077 | 67081 | */ |
| 67078 | 67082 | #ifdef SQLITE_DEBUG |
| 67079 | | - if( p->trace ){ |
| 67080 | | - if( pc==0 ){ |
| 67081 | | - printf("VDBE Execution Trace:\n"); |
| 67082 | | - sqlite3VdbePrintSql(p); |
| 67083 | | - } |
| 67084 | | - sqlite3VdbePrintOp(p->trace, pc, pOp); |
| 67083 | + if( db->flags & SQLITE_VdbeTrace ){ |
| 67084 | + sqlite3VdbePrintOp(stdout, pc, pOp); |
| 67085 | 67085 | } |
| 67086 | 67086 | #endif |
| 67087 | 67087 | |
| 67088 | 67088 | |
| 67089 | 67089 | /* Check to see if we need to simulate an interrupt. This only happens |
| | @@ -67210,19 +67210,16 @@ |
| 67210 | 67210 | ** sqlite3VdbeExec() or since last time the progress callback was called). |
| 67211 | 67211 | ** If the progress callback returns non-zero, exit the virtual machine with |
| 67212 | 67212 | ** a return code SQLITE_ABORT. |
| 67213 | 67213 | */ |
| 67214 | 67214 | if( db->xProgress!=0 && nVmStep>=nProgressLimit ){ |
| 67215 | | - int prc; |
| 67216 | | - prc = db->xProgress(db->pProgressArg); |
| 67217 | | - if( prc!=0 ){ |
| 67215 | + assert( db->nProgressOps!=0 ); |
| 67216 | + nProgressLimit = nVmStep + db->nProgressOps - (nVmStep%db->nProgressOps); |
| 67217 | + if( db->xProgress(db->pProgressArg) ){ |
| 67218 | 67218 | rc = SQLITE_INTERRUPT; |
| 67219 | 67219 | goto vdbe_error_halt; |
| 67220 | 67220 | } |
| 67221 | | - if( db->xProgress!=0 ){ |
| 67222 | | - nProgressLimit = nVmStep + db->nProgressOps - (nVmStep%db->nProgressOps); |
| 67223 | | - } |
| 67224 | 67221 | } |
| 67225 | 67222 | #endif |
| 67226 | 67223 | |
| 67227 | 67224 | break; |
| 67228 | 67225 | } |
| | @@ -67654,10 +67651,22 @@ |
| 67654 | 67651 | int i; |
| 67655 | 67652 | #endif /* local variables moved into u.ag */ |
| 67656 | 67653 | assert( p->nResColumn==pOp->p2 ); |
| 67657 | 67654 | assert( pOp->p1>0 ); |
| 67658 | 67655 | assert( pOp->p1+pOp->p2<=(p->nMem-p->nCursor)+1 ); |
| 67656 | + |
| 67657 | +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK |
| 67658 | + /* Run the progress counter just before returning. |
| 67659 | + */ |
| 67660 | + if( db->xProgress!=0 |
| 67661 | + && nVmStep>=nProgressLimit |
| 67662 | + && db->xProgress(db->pProgressArg)!=0 |
| 67663 | + ){ |
| 67664 | + rc = SQLITE_INTERRUPT; |
| 67665 | + goto vdbe_error_halt; |
| 67666 | + } |
| 67667 | +#endif |
| 67659 | 67668 | |
| 67660 | 67669 | /* If this statement has violated immediate foreign key constraints, do |
| 67661 | 67670 | ** not return the number of rows modified. And do not RELEASE the statement |
| 67662 | 67671 | ** transaction. It needs to be rolled back. */ |
| 67663 | 67672 | if( SQLITE_OK!=(rc = sqlite3VdbeCheckFk(p, 0)) ){ |
| | @@ -72862,17 +72871,17 @@ |
| 72862 | 72871 | */ |
| 72863 | 72872 | #ifndef NDEBUG |
| 72864 | 72873 | assert( pc>=-1 && pc<p->nOp ); |
| 72865 | 72874 | |
| 72866 | 72875 | #ifdef SQLITE_DEBUG |
| 72867 | | - if( p->trace ){ |
| 72868 | | - if( rc!=0 ) fprintf(p->trace,"rc=%d\n",rc); |
| 72876 | + if( db->flags & SQLITE_VdbeTrace ){ |
| 72877 | + if( rc!=0 ) printf("rc=%d\n",rc); |
| 72869 | 72878 | if( pOp->opflags & (OPFLG_OUT2_PRERELEASE|OPFLG_OUT2) ){ |
| 72870 | | - registerTrace(p->trace, pOp->p2, &aMem[pOp->p2]); |
| 72879 | + registerTrace(pOp->p2, &aMem[pOp->p2]); |
| 72871 | 72880 | } |
| 72872 | 72881 | if( pOp->opflags & OPFLG_OUT3 ){ |
| 72873 | | - registerTrace(p->trace, pOp->p3, &aMem[pOp->p3]); |
| 72882 | + registerTrace(pOp->p3, &aMem[pOp->p3]); |
| 72874 | 72883 | } |
| 72875 | 72884 | } |
| 72876 | 72885 | #endif /* SQLITE_DEBUG */ |
| 72877 | 72886 | #endif /* NDEBUG */ |
| 72878 | 72887 | } /* The end of the for(;;) loop the loops through opcodes */ |
| | @@ -83106,14 +83115,16 @@ |
| 83106 | 83115 | } |
| 83107 | 83116 | pTable = sqlite3FindTable(pInfo->db, argv[0], pInfo->zDatabase); |
| 83108 | 83117 | if( pTable==0 ){ |
| 83109 | 83118 | return 0; |
| 83110 | 83119 | } |
| 83111 | | - if( argv[1] ){ |
| 83112 | | - pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); |
| 83113 | | - }else{ |
| 83120 | + if( argv[1]==0 ){ |
| 83114 | 83121 | pIndex = 0; |
| 83122 | + }else if( sqlite3_stricmp(argv[0],argv[1])==0 ){ |
| 83123 | + pIndex = sqlite3PrimaryKeyIndex(pTable); |
| 83124 | + }else{ |
| 83125 | + pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); |
| 83115 | 83126 | } |
| 83116 | 83127 | z = argv[2]; |
| 83117 | 83128 | |
| 83118 | 83129 | if( pIndex ){ |
| 83119 | 83130 | decodeIntArray((char*)z, pIndex->nKeyCol+1, pIndex->aiRowEst, pIndex); |
| | @@ -84467,14 +84478,10 @@ |
| 84467 | 84478 | |
| 84468 | 84479 | |
| 84469 | 84480 | /* Get the VDBE program ready for execution |
| 84470 | 84481 | */ |
| 84471 | 84482 | if( v && ALWAYS(pParse->nErr==0) && !db->mallocFailed ){ |
| 84472 | | -#ifdef SQLITE_DEBUG |
| 84473 | | - FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0; |
| 84474 | | - sqlite3VdbeTrace(v, trace); |
| 84475 | | -#endif |
| 84476 | 84483 | assert( pParse->iCacheLevel==0 ); /* Disables and re-enables match */ |
| 84477 | 84484 | /* A minimum of one cursor is required if autoincrement is used |
| 84478 | 84485 | * See ticket [a696379c1f08866] */ |
| 84479 | 84486 | if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1; |
| 84480 | 84487 | sqlite3VdbeMakeReady(v, pParse); |
| | @@ -96680,10 +96687,14 @@ |
| 96680 | 96687 | /* iArg: */ SQLITE_VdbeAddopTrace }, |
| 96681 | 96688 | { /* zName: */ "vdbe_debug", |
| 96682 | 96689 | /* ePragTyp: */ PragTyp_FLAG, |
| 96683 | 96690 | /* ePragFlag: */ 0, |
| 96684 | 96691 | /* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace }, |
| 96692 | + { /* zName: */ "vdbe_eqp", |
| 96693 | + /* ePragTyp: */ PragTyp_FLAG, |
| 96694 | + /* ePragFlag: */ 0, |
| 96695 | + /* iArg: */ SQLITE_VdbeEQP }, |
| 96685 | 96696 | { /* zName: */ "vdbe_listing", |
| 96686 | 96697 | /* ePragTyp: */ PragTyp_FLAG, |
| 96687 | 96698 | /* ePragFlag: */ 0, |
| 96688 | 96699 | /* iArg: */ SQLITE_VdbeListing }, |
| 96689 | 96700 | { /* zName: */ "vdbe_trace", |
| | @@ -96707,11 +96718,11 @@ |
| 96707 | 96718 | /* ePragTyp: */ PragTyp_FLAG, |
| 96708 | 96719 | /* ePragFlag: */ 0, |
| 96709 | 96720 | /* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode }, |
| 96710 | 96721 | #endif |
| 96711 | 96722 | }; |
| 96712 | | -/* Number of pragmas: 56 on by default, 68 total. */ |
| 96723 | +/* Number of pragmas: 56 on by default, 69 total. */ |
| 96713 | 96724 | /* End of the automatically generated pragma table. |
| 96714 | 96725 | ***************************************************************************/ |
| 96715 | 96726 | |
| 96716 | 96727 | /* |
| 96717 | 96728 | ** Interpret the given string as a safety level. Return 0 for OFF, |
| | @@ -107929,11 +107940,28 @@ |
| 107929 | 107940 | ** generating the code that loops through a table looking for applicable |
| 107930 | 107941 | ** rows. Indices are selected and used to speed the search when doing |
| 107931 | 107942 | ** so is applicable. Because this module is responsible for selecting |
| 107932 | 107943 | ** indices, you might also think of this module as the "query optimizer". |
| 107933 | 107944 | */ |
| 107934 | | - |
| 107945 | +/************** Include whereInt.h in the middle of where.c ******************/ |
| 107946 | +/************** Begin file whereInt.h ****************************************/ |
| 107947 | +/* |
| 107948 | +** 2013-11-12 |
| 107949 | +** |
| 107950 | +** The author disclaims copyright to this source code. In place of |
| 107951 | +** a legal notice, here is a blessing: |
| 107952 | +** |
| 107953 | +** May you do good and not evil. |
| 107954 | +** May you find forgiveness for yourself and forgive others. |
| 107955 | +** May you share freely, never taking more than you give. |
| 107956 | +** |
| 107957 | +************************************************************************* |
| 107958 | +** |
| 107959 | +** This file contains structure and macro definitions for the query |
| 107960 | +** planner logic in "where.c". These definitions are broken out into |
| 107961 | +** a separate source file for easier editing. |
| 107962 | +*/ |
| 107935 | 107963 | |
| 107936 | 107964 | /* |
| 107937 | 107965 | ** Trace output macros |
| 107938 | 107966 | */ |
| 107939 | 107967 | #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) |
| | @@ -107981,10 +108009,11 @@ |
| 107981 | 108009 | int iLeftJoin; /* Memory cell used to implement LEFT OUTER JOIN */ |
| 107982 | 108010 | int iTabCur; /* The VDBE cursor used to access the table */ |
| 107983 | 108011 | int iIdxCur; /* The VDBE cursor used to access pIdx */ |
| 107984 | 108012 | int addrBrk; /* Jump here to break out of the loop */ |
| 107985 | 108013 | int addrNxt; /* Jump here to start the next IN combination */ |
| 108014 | + int addrSkip; /* Jump here for next iteration of skip-scan */ |
| 107986 | 108015 | int addrCont; /* Jump here to continue with the next loop cycle */ |
| 107987 | 108016 | int addrFirst; /* First instruction of interior of the loop */ |
| 107988 | 108017 | int addrBody; /* Beginning of the body of this loop */ |
| 107989 | 108018 | u8 iFrom; /* Which entry in the FROM clause */ |
| 107990 | 108019 | u8 op, p5; /* Opcode and P5 of the opcode that ends the loop */ |
| | @@ -108030,11 +108059,11 @@ |
| 108030 | 108059 | LogEst rRun; /* Cost of running each loop */ |
| 108031 | 108060 | LogEst nOut; /* Estimated number of output rows */ |
| 108032 | 108061 | union { |
| 108033 | 108062 | struct { /* Information for internal btree tables */ |
| 108034 | 108063 | u16 nEq; /* Number of equality constraints */ |
| 108035 | | - u16 nSkip; /* Number of initial index columns skipped */ |
| 108064 | + u16 nSkip; /* Number of initial index columns to skip */ |
| 108036 | 108065 | Index *pIndex; /* Index used, or NULL */ |
| 108037 | 108066 | } btree; |
| 108038 | 108067 | struct { /* Information for virtual tables */ |
| 108039 | 108068 | int idxNum; /* Index number */ |
| 108040 | 108069 | u8 needFree; /* True if sqlite3_free(idxStr) is needed */ |
| | @@ -108371,10 +108400,14 @@ |
| 108371 | 108400 | #define WHERE_VIRTUALTABLE 0x00000400 /* WhereLoop.u.vtab is valid */ |
| 108372 | 108401 | #define WHERE_IN_ABLE 0x00000800 /* Able to support an IN operator */ |
| 108373 | 108402 | #define WHERE_ONEROW 0x00001000 /* Selects no more than one row */ |
| 108374 | 108403 | #define WHERE_MULTI_OR 0x00002000 /* OR using multiple indices */ |
| 108375 | 108404 | #define WHERE_AUTO_INDEX 0x00004000 /* Uses an ephemeral index */ |
| 108405 | +#define WHERE_SKIPSCAN 0x00008000 /* Uses the skip-scan algorithm */ |
| 108406 | + |
| 108407 | +/************** End of whereInt.h ********************************************/ |
| 108408 | +/************** Continuing where we left off in where.c **********************/ |
| 108376 | 108409 | |
| 108377 | 108410 | /* |
| 108378 | 108411 | ** Return the estimated number of output rows from a WHERE clause |
| 108379 | 108412 | */ |
| 108380 | 108413 | SQLITE_PRIVATE u64 sqlite3WhereOutputRowCount(WhereInfo *pWInfo){ |
| | @@ -110775,11 +110808,11 @@ |
| 110775 | 110808 | return iReg; |
| 110776 | 110809 | } |
| 110777 | 110810 | |
| 110778 | 110811 | /* |
| 110779 | 110812 | ** Generate code that will evaluate all == and IN constraints for an |
| 110780 | | -** index. |
| 110813 | +** index scan. |
| 110781 | 110814 | ** |
| 110782 | 110815 | ** For example, consider table t1(a,b,c,d,e,f) with index i1(a,b,c). |
| 110783 | 110816 | ** Suppose the WHERE clause is this: a==5 AND b IN (1,2,3) AND c>5 AND c<10 |
| 110784 | 110817 | ** The index has as many as three equality constraints, but in this |
| 110785 | 110818 | ** example, the third "c" value is an inequality. So only two |
| | @@ -110790,13 +110823,19 @@ |
| 110790 | 110823 | ** In the example above nEq==2. But this subroutine works for any value |
| 110791 | 110824 | ** of nEq including 0. If nEq==0, this routine is nearly a no-op. |
| 110792 | 110825 | ** The only thing it does is allocate the pLevel->iMem memory cell and |
| 110793 | 110826 | ** compute the affinity string. |
| 110794 | 110827 | ** |
| 110795 | | -** This routine always allocates at least one memory cell and returns |
| 110796 | | -** the index of that memory cell. The code that |
| 110797 | | -** calls this routine will use that memory cell to store the termination |
| 110828 | +** The nExtraReg parameter is 0 or 1. It is 0 if all WHERE clause constraints |
| 110829 | +** are == or IN and are covered by the nEq. nExtraReg is 1 if there is |
| 110830 | +** an inequality constraint (such as the "c>=5 AND c<10" in the example) that |
| 110831 | +** occurs after the nEq quality constraints. |
| 110832 | +** |
| 110833 | +** This routine allocates a range of nEq+nExtraReg memory cells and returns |
| 110834 | +** the index of the first memory cell in that range. The code that |
| 110835 | +** calls this routine will use that memory range to store keys for |
| 110836 | +** start and termination conditions of the loop. |
| 110798 | 110837 | ** key value of the loop. If one or more IN operators appear, then |
| 110799 | 110838 | ** this routine allocates an additional nEq memory cells for internal |
| 110800 | 110839 | ** use. |
| 110801 | 110840 | ** |
| 110802 | 110841 | ** Before returning, *pzAff is set to point to a buffer containing a |
| | @@ -110819,11 +110858,12 @@ |
| 110819 | 110858 | WhereLevel *pLevel, /* Which nested loop of the FROM we are coding */ |
| 110820 | 110859 | int bRev, /* Reverse the order of IN operators */ |
| 110821 | 110860 | int nExtraReg, /* Number of extra registers to allocate */ |
| 110822 | 110861 | char **pzAff /* OUT: Set to point to affinity string */ |
| 110823 | 110862 | ){ |
| 110824 | | - int nEq; /* The number of == or IN constraints to code */ |
| 110863 | + u16 nEq; /* The number of == or IN constraints to code */ |
| 110864 | + u16 nSkip; /* Number of left-most columns to skip */ |
| 110825 | 110865 | Vdbe *v = pParse->pVdbe; /* The vm under construction */ |
| 110826 | 110866 | Index *pIdx; /* The index being used for this loop */ |
| 110827 | 110867 | WhereTerm *pTerm; /* A single constraint term */ |
| 110828 | 110868 | WhereLoop *pLoop; /* The WhereLoop object */ |
| 110829 | 110869 | int j; /* Loop counter */ |
| | @@ -110833,10 +110873,11 @@ |
| 110833 | 110873 | |
| 110834 | 110874 | /* This module is only called on query plans that use an index. */ |
| 110835 | 110875 | pLoop = pLevel->pWLoop; |
| 110836 | 110876 | assert( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ); |
| 110837 | 110877 | nEq = pLoop->u.btree.nEq; |
| 110878 | + nSkip = pLoop->u.btree.nSkip; |
| 110838 | 110879 | pIdx = pLoop->u.btree.pIndex; |
| 110839 | 110880 | assert( pIdx!=0 ); |
| 110840 | 110881 | |
| 110841 | 110882 | /* Figure out how many memory cells we will need then allocate them. |
| 110842 | 110883 | */ |
| | @@ -110846,19 +110887,34 @@ |
| 110846 | 110887 | |
| 110847 | 110888 | zAff = sqlite3DbStrDup(pParse->db, sqlite3IndexAffinityStr(v, pIdx)); |
| 110848 | 110889 | if( !zAff ){ |
| 110849 | 110890 | pParse->db->mallocFailed = 1; |
| 110850 | 110891 | } |
| 110892 | + |
| 110893 | + if( nSkip ){ |
| 110894 | + int iIdxCur = pLevel->iIdxCur; |
| 110895 | + sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur); |
| 110896 | + VdbeComment((v, "begin skip-scan on %s", pIdx->zName)); |
| 110897 | + j = sqlite3VdbeAddOp0(v, OP_Goto); |
| 110898 | + pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLt:OP_SeekGt), |
| 110899 | + iIdxCur, 0, regBase, nSkip); |
| 110900 | + sqlite3VdbeJumpHere(v, j); |
| 110901 | + for(j=0; j<nSkip; j++){ |
| 110902 | + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, j, regBase+j); |
| 110903 | + assert( pIdx->aiColumn[j]>=0 ); |
| 110904 | + VdbeComment((v, "%s", pIdx->pTable->aCol[pIdx->aiColumn[j]].zName)); |
| 110905 | + } |
| 110906 | + } |
| 110851 | 110907 | |
| 110852 | 110908 | /* Evaluate the equality constraints |
| 110853 | 110909 | */ |
| 110854 | 110910 | assert( zAff==0 || (int)strlen(zAff)>=nEq ); |
| 110855 | | - for(j=0; j<nEq; j++){ |
| 110911 | + for(j=nSkip; j<nEq; j++){ |
| 110856 | 110912 | int r1; |
| 110857 | 110913 | pTerm = pLoop->aLTerm[j]; |
| 110858 | 110914 | assert( pTerm!=0 ); |
| 110859 | | - /* The following true for indices with redundant columns. |
| 110915 | + /* The following testcase is true for indices with redundant columns. |
| 110860 | 110916 | ** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */ |
| 110861 | 110917 | testcase( (pTerm->wtFlags & TERM_CODED)!=0 ); |
| 110862 | 110918 | testcase( pTerm->wtFlags & TERM_VIRTUAL ); |
| 110863 | 110919 | r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, regBase+j); |
| 110864 | 110920 | if( r1!=regBase+j ){ |
| | @@ -110928,11 +110984,12 @@ |
| 110928 | 110984 | ** It is the responsibility of the caller to free the buffer when it is |
| 110929 | 110985 | ** no longer required. |
| 110930 | 110986 | */ |
| 110931 | 110987 | static char *explainIndexRange(sqlite3 *db, WhereLoop *pLoop, Table *pTab){ |
| 110932 | 110988 | Index *pIndex = pLoop->u.btree.pIndex; |
| 110933 | | - int nEq = pLoop->u.btree.nEq; |
| 110989 | + u16 nEq = pLoop->u.btree.nEq; |
| 110990 | + u16 nSkip = pLoop->u.btree.nSkip; |
| 110934 | 110991 | int i, j; |
| 110935 | 110992 | Column *aCol = pTab->aCol; |
| 110936 | 110993 | i16 *aiColumn = pIndex->aiColumn; |
| 110937 | 110994 | StrAccum txt; |
| 110938 | 110995 | |
| | @@ -110942,11 +110999,18 @@ |
| 110942 | 110999 | sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH); |
| 110943 | 111000 | txt.db = db; |
| 110944 | 111001 | sqlite3StrAccumAppend(&txt, " (", 2); |
| 110945 | 111002 | for(i=0; i<nEq; i++){ |
| 110946 | 111003 | char *z = (i==pIndex->nKeyCol ) ? "rowid" : aCol[aiColumn[i]].zName; |
| 110947 | | - explainAppendTerm(&txt, i, z, "="); |
| 111004 | + if( i>=nSkip ){ |
| 111005 | + explainAppendTerm(&txt, i, z, "="); |
| 111006 | + }else{ |
| 111007 | + if( i ) sqlite3StrAccumAppend(&txt, " AND ", 5); |
| 111008 | + sqlite3StrAccumAppend(&txt, "ANY(", 4); |
| 111009 | + sqlite3StrAccumAppend(&txt, z, -1); |
| 111010 | + sqlite3StrAccumAppend(&txt, ")", 1); |
| 111011 | + } |
| 110948 | 111012 | } |
| 110949 | 111013 | |
| 110950 | 111014 | j = i; |
| 110951 | 111015 | if( pLoop->wsFlags&WHERE_BTM_LIMIT ){ |
| 110952 | 111016 | char *z = (j==pIndex->nKeyCol ) ? "rowid" : aCol[aiColumn[j]].zName; |
| | @@ -110972,11 +111036,14 @@ |
| 110972 | 111036 | WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ |
| 110973 | 111037 | int iLevel, /* Value for "level" column of output */ |
| 110974 | 111038 | int iFrom, /* Value for "from" column of output */ |
| 110975 | 111039 | u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ |
| 110976 | 111040 | ){ |
| 110977 | | - if( pParse->explain==2 ){ |
| 111041 | +#ifndef SQLITE_DEBUG |
| 111042 | + if( pParse->explain==2 ) |
| 111043 | +#endif |
| 111044 | + { |
| 110978 | 111045 | struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom]; |
| 110979 | 111046 | Vdbe *v = pParse->pVdbe; /* VM being constructed */ |
| 110980 | 111047 | sqlite3 *db = pParse->db; /* Database handle */ |
| 110981 | 111048 | char *zMsg; /* Text to add to EQP output */ |
| 110982 | 111049 | int iId = pParse->iSelectId; /* Select id (left-most output column) */ |
| | @@ -111078,11 +111145,11 @@ |
| 111078 | 111145 | iCur = pTabItem->iCursor; |
| 111079 | 111146 | pLevel->notReady = notReady & ~getMask(&pWInfo->sMaskSet, iCur); |
| 111080 | 111147 | bRev = (pWInfo->revMask>>iLevel)&1; |
| 111081 | 111148 | omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0 |
| 111082 | 111149 | && (pWInfo->wctrlFlags & WHERE_FORCE_TABLE)==0; |
| 111083 | | - VdbeNoopComment((v, "Begin WHERE-Loop %d: %s", iLevel,pTabItem->pTab->zName)); |
| 111150 | + VdbeNoopComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName)); |
| 111084 | 111151 | |
| 111085 | 111152 | /* Create labels for the "break" and "continue" instructions |
| 111086 | 111153 | ** for the current loop. Jump to addrBrk to break out of a loop. |
| 111087 | 111154 | ** Jump to cont to go immediately to the next iteration of the |
| 111088 | 111155 | ** loop. |
| | @@ -111305,12 +111372,12 @@ |
| 111305 | 111372 | static const u8 aEndOp[] = { |
| 111306 | 111373 | OP_Noop, /* 0: (!end_constraints) */ |
| 111307 | 111374 | OP_IdxGE, /* 1: (end_constraints && !bRev) */ |
| 111308 | 111375 | OP_IdxLT /* 2: (end_constraints && bRev) */ |
| 111309 | 111376 | }; |
| 111310 | | - int nEq = pLoop->u.btree.nEq; /* Number of == or IN terms */ |
| 111311 | | - int isMinQuery = 0; /* If this is an optimized SELECT min(x).. */ |
| 111377 | + u16 nEq = pLoop->u.btree.nEq; /* Number of == or IN terms */ |
| 111378 | + int isMinQuery = 0; /* If this is an optimized SELECT min(x).. */ |
| 111312 | 111379 | int regBase; /* Base register holding constraint values */ |
| 111313 | 111380 | int r1; /* Temp register */ |
| 111314 | 111381 | WhereTerm *pRangeStart = 0; /* Inequality constraint at range start */ |
| 111315 | 111382 | WhereTerm *pRangeEnd = 0; /* Inequality constraint at range end */ |
| 111316 | 111383 | int startEq; /* True if range start uses ==, >= or <= */ |
| | @@ -111324,10 +111391,11 @@ |
| 111324 | 111391 | char *zStartAff; /* Affinity for start of range constraint */ |
| 111325 | 111392 | char *zEndAff; /* Affinity for end of range constraint */ |
| 111326 | 111393 | |
| 111327 | 111394 | pIdx = pLoop->u.btree.pIndex; |
| 111328 | 111395 | iIdxCur = pLevel->iIdxCur; |
| 111396 | + assert( nEq>=pLoop->u.btree.nSkip ); |
| 111329 | 111397 | |
| 111330 | 111398 | /* If this loop satisfies a sort order (pOrderBy) request that |
| 111331 | 111399 | ** was passed to this function to implement a "SELECT min(x) ..." |
| 111332 | 111400 | ** query, then the caller will only allow the loop to run for |
| 111333 | 111401 | ** a single iteration. This means that the first row returned |
| | @@ -111337,12 +111405,11 @@ |
| 111337 | 111405 | */ |
| 111338 | 111406 | if( (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)!=0 |
| 111339 | 111407 | && (pWInfo->bOBSat!=0) |
| 111340 | 111408 | && (pIdx->nKeyCol>nEq) |
| 111341 | 111409 | ){ |
| 111342 | | - /* assert( pOrderBy->nExpr==1 ); */ |
| 111343 | | - /* assert( pOrderBy->a[0].pExpr->iColumn==pIdx->aiColumn[nEq] ); */ |
| 111410 | + assert( pLoop->u.btree.nSkip==0 ); |
| 111344 | 111411 | isMinQuery = 1; |
| 111345 | 111412 | nExtraReg = 1; |
| 111346 | 111413 | } |
| 111347 | 111414 | |
| 111348 | 111415 | /* Find any inequality constraint terms for the start and end |
| | @@ -111469,12 +111536,16 @@ |
| 111469 | 111536 | ** If it is, jump to the next iteration of the loop. |
| 111470 | 111537 | */ |
| 111471 | 111538 | r1 = sqlite3GetTempReg(pParse); |
| 111472 | 111539 | testcase( pLoop->wsFlags & WHERE_BTM_LIMIT ); |
| 111473 | 111540 | testcase( pLoop->wsFlags & WHERE_TOP_LIMIT ); |
| 111474 | | - if( (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 ){ |
| 111541 | + if( (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 |
| 111542 | + && (j = pIdx->aiColumn[nEq])>=0 |
| 111543 | + && pIdx->pTable->aCol[j].notNull==0 |
| 111544 | + ){ |
| 111475 | 111545 | sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, nEq, r1); |
| 111546 | + VdbeComment((v, "%s", pIdx->pTable->aCol[j].zName)); |
| 111476 | 111547 | sqlite3VdbeAddOp2(v, OP_IsNull, r1, addrCont); |
| 111477 | 111548 | } |
| 111478 | 111549 | sqlite3ReleaseTempReg(pParse, r1); |
| 111479 | 111550 | |
| 111480 | 111551 | /* Seek the table cursor, if required */ |
| | @@ -111858,16 +111929,11 @@ |
| 111858 | 111929 | if( strncmp(zName, "sqlite_autoindex_", 17)==0 ){ |
| 111859 | 111930 | int i = sqlite3Strlen30(zName) - 1; |
| 111860 | 111931 | while( zName[i]!='_' ) i--; |
| 111861 | 111932 | zName += i; |
| 111862 | 111933 | } |
| 111863 | | - if( p->u.btree.nSkip ){ |
| 111864 | | - sqlite3DebugPrintf(".%-15s %d+%d", zName, |
| 111865 | | - p->u.btree.nSkip, p->u.btree.nEq); |
| 111866 | | - }else{ |
| 111867 | | - sqlite3DebugPrintf(".%-16s %2d", zName, p->u.btree.nEq); |
| 111868 | | - } |
| 111934 | + sqlite3DebugPrintf(".%-16s %2d", zName, p->u.btree.nEq); |
| 111869 | 111935 | }else{ |
| 111870 | 111936 | sqlite3DebugPrintf("%20s",""); |
| 111871 | 111937 | } |
| 111872 | 111938 | }else{ |
| 111873 | 111939 | char *z; |
| | @@ -111890,10 +111956,11 @@ |
| 111890 | 111956 | int i; |
| 111891 | 111957 | Vdbe *v = pWInfo->pParse->pVdbe; |
| 111892 | 111958 | sqlite3ExplainBegin(v); |
| 111893 | 111959 | for(i=0; i<p->nLTerm; i++){ |
| 111894 | 111960 | WhereTerm *pTerm = p->aLTerm[i]; |
| 111961 | + if( pTerm==0 ) continue; |
| 111895 | 111962 | sqlite3ExplainPrintf(v, " (%d) #%-2d ", i+1, (int)(pTerm-pWC->a)); |
| 111896 | 111963 | sqlite3ExplainPush(v); |
| 111897 | 111964 | whereExplainTerm(v, pTerm); |
| 111898 | 111965 | sqlite3ExplainPop(v); |
| 111899 | 111966 | sqlite3ExplainNL(v); |
| | @@ -112173,10 +112240,11 @@ |
| 112173 | 112240 | if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) break; |
| 112174 | 112241 | if( (pTerm->prereqAll & pLoop->maskSelf)==0 ) continue; |
| 112175 | 112242 | if( (pTerm->prereqAll & notAllowed)!=0 ) continue; |
| 112176 | 112243 | for(j=pLoop->nLTerm-1; j>=0; j--){ |
| 112177 | 112244 | pX = pLoop->aLTerm[j]; |
| 112245 | + if( pX==0 ) continue; |
| 112178 | 112246 | if( pX==pTerm ) break; |
| 112179 | 112247 | if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break; |
| 112180 | 112248 | } |
| 112181 | 112249 | if( j<0 ) pLoop->nOut += pTerm->truthProb; |
| 112182 | 112250 | } |
| | @@ -112202,11 +112270,12 @@ |
| 112202 | 112270 | WhereTerm *pTerm; /* A WhereTerm under consideration */ |
| 112203 | 112271 | int opMask; /* Valid operators for constraints */ |
| 112204 | 112272 | WhereScan scan; /* Iterator for WHERE terms */ |
| 112205 | 112273 | Bitmask saved_prereq; /* Original value of pNew->prereq */ |
| 112206 | 112274 | u16 saved_nLTerm; /* Original value of pNew->nLTerm */ |
| 112207 | | - int saved_nEq; /* Original value of pNew->u.btree.nEq */ |
| 112275 | + u16 saved_nEq; /* Original value of pNew->u.btree.nEq */ |
| 112276 | + u16 saved_nSkip; /* Original value of pNew->u.btree.nSkip */ |
| 112208 | 112277 | u32 saved_wsFlags; /* Original value of pNew->wsFlags */ |
| 112209 | 112278 | LogEst saved_nOut; /* Original value of pNew->nOut */ |
| 112210 | 112279 | int iCol; /* Index of the column in the table */ |
| 112211 | 112280 | int rc = SQLITE_OK; /* Return code */ |
| 112212 | 112281 | LogEst nRowEst; /* Estimated index selectivity */ |
| | @@ -112237,16 +112306,30 @@ |
| 112237 | 112306 | nRowEst = 0; |
| 112238 | 112307 | } |
| 112239 | 112308 | pTerm = whereScanInit(&scan, pBuilder->pWC, pSrc->iCursor, iCol, |
| 112240 | 112309 | opMask, pProbe); |
| 112241 | 112310 | saved_nEq = pNew->u.btree.nEq; |
| 112311 | + saved_nSkip = pNew->u.btree.nSkip; |
| 112242 | 112312 | saved_nLTerm = pNew->nLTerm; |
| 112243 | 112313 | saved_wsFlags = pNew->wsFlags; |
| 112244 | 112314 | saved_prereq = pNew->prereq; |
| 112245 | 112315 | saved_nOut = pNew->nOut; |
| 112246 | 112316 | pNew->rSetup = 0; |
| 112247 | 112317 | rLogSize = estLog(sqlite3LogEst(pProbe->aiRowEst[0])); |
| 112318 | + if( pTerm==0 |
| 112319 | + && saved_nEq==saved_nSkip |
| 112320 | + && saved_nEq+1<pProbe->nKeyCol |
| 112321 | + && pProbe->aiRowEst[saved_nEq+1]>50 |
| 112322 | + ){ |
| 112323 | + LogEst nIter; |
| 112324 | + pNew->u.btree.nEq++; |
| 112325 | + pNew->u.btree.nSkip++; |
| 112326 | + pNew->aLTerm[pNew->nLTerm++] = 0; |
| 112327 | + pNew->wsFlags |= WHERE_SKIPSCAN; |
| 112328 | + nIter = sqlite3LogEst(pProbe->aiRowEst[0]/pProbe->aiRowEst[saved_nEq+1]); |
| 112329 | + whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter); |
| 112330 | + } |
| 112248 | 112331 | for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){ |
| 112249 | 112332 | int nIn = 0; |
| 112250 | 112333 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 112251 | 112334 | int nRecValid = pBuilder->nRecValid; |
| 112252 | 112335 | #endif |
| | @@ -112278,12 +112361,14 @@ |
| 112278 | 112361 | } |
| 112279 | 112362 | pNew->rRun += nIn; |
| 112280 | 112363 | pNew->u.btree.nEq++; |
| 112281 | 112364 | pNew->nOut = nRowEst + nInMul + nIn; |
| 112282 | 112365 | }else if( pTerm->eOperator & (WO_EQ) ){ |
| 112283 | | - assert( (pNew->wsFlags & (WHERE_COLUMN_NULL|WHERE_COLUMN_IN))!=0 |
| 112284 | | - || nInMul==0 ); |
| 112366 | + assert( |
| 112367 | + (pNew->wsFlags & (WHERE_COLUMN_NULL|WHERE_COLUMN_IN|WHERE_SKIPSCAN))!=0 |
| 112368 | + || nInMul==0 |
| 112369 | + ); |
| 112285 | 112370 | pNew->wsFlags |= WHERE_COLUMN_EQ; |
| 112286 | 112371 | if( iCol<0 |
| 112287 | 112372 | || (pProbe->onError!=OE_None && nInMul==0 |
| 112288 | 112373 | && pNew->u.btree.nEq==pProbe->nKeyCol-1) |
| 112289 | 112374 | ){ |
| | @@ -112360,10 +112445,11 @@ |
| 112360 | 112445 | pBuilder->nRecValid = nRecValid; |
| 112361 | 112446 | #endif |
| 112362 | 112447 | } |
| 112363 | 112448 | pNew->prereq = saved_prereq; |
| 112364 | 112449 | pNew->u.btree.nEq = saved_nEq; |
| 112450 | + pNew->u.btree.nSkip = saved_nSkip; |
| 112365 | 112451 | pNew->wsFlags = saved_wsFlags; |
| 112366 | 112452 | pNew->nOut = saved_nOut; |
| 112367 | 112453 | pNew->nLTerm = saved_nLTerm; |
| 112368 | 112454 | return rc; |
| 112369 | 112455 | } |
| | @@ -112506,10 +112592,11 @@ |
| 112506 | 112592 | WhereTerm *pWCEnd = pWC->a + pWC->nTerm; |
| 112507 | 112593 | for(pTerm=pWC->a; rc==SQLITE_OK && pTerm<pWCEnd; pTerm++){ |
| 112508 | 112594 | if( pTerm->prereqRight & pNew->maskSelf ) continue; |
| 112509 | 112595 | if( termCanDriveIndex(pTerm, pSrc, 0) ){ |
| 112510 | 112596 | pNew->u.btree.nEq = 1; |
| 112597 | + pNew->u.btree.nSkip = 0; |
| 112511 | 112598 | pNew->u.btree.pIndex = 0; |
| 112512 | 112599 | pNew->nLTerm = 1; |
| 112513 | 112600 | pNew->aLTerm[0] = pTerm; |
| 112514 | 112601 | /* TUNING: One-time cost for computing the automatic index is |
| 112515 | 112602 | ** approximately 7*N*log2(N) where N is the number of rows in |
| | @@ -112535,10 +112622,11 @@ |
| 112535 | 112622 | if( pProbe->pPartIdxWhere!=0 |
| 112536 | 112623 | && !whereUsablePartialIndex(pNew->iTab, pWC, pProbe->pPartIdxWhere) ){ |
| 112537 | 112624 | continue; /* Partial index inappropriate for this query */ |
| 112538 | 112625 | } |
| 112539 | 112626 | pNew->u.btree.nEq = 0; |
| 112627 | + pNew->u.btree.nSkip = 0; |
| 112540 | 112628 | pNew->nLTerm = 0; |
| 112541 | 112629 | pNew->iSortIdx = 0; |
| 112542 | 112630 | pNew->rSetup = 0; |
| 112543 | 112631 | pNew->prereq = mExtra; |
| 112544 | 112632 | pNew->nOut = rSize; |
| | @@ -112620,11 +112708,12 @@ |
| 112620 | 112708 | /* |
| 112621 | 112709 | ** Add all WhereLoop objects for a table of the join identified by |
| 112622 | 112710 | ** pBuilder->pNew->iTab. That table is guaranteed to be a virtual table. |
| 112623 | 112711 | */ |
| 112624 | 112712 | static int whereLoopAddVirtual( |
| 112625 | | - WhereLoopBuilder *pBuilder /* WHERE clause information */ |
| 112713 | + WhereLoopBuilder *pBuilder, /* WHERE clause information */ |
| 112714 | + Bitmask mExtra |
| 112626 | 112715 | ){ |
| 112627 | 112716 | WhereInfo *pWInfo; /* WHERE analysis context */ |
| 112628 | 112717 | Parse *pParse; /* The parsing context */ |
| 112629 | 112718 | WhereClause *pWC; /* The WHERE clause */ |
| 112630 | 112719 | struct SrcList_item *pSrc; /* The FROM clause term to search */ |
| | @@ -112710,11 +112799,11 @@ |
| 112710 | 112799 | pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2; |
| 112711 | 112800 | pIdxInfo->estimatedRows = 25; |
| 112712 | 112801 | rc = vtabBestIndex(pParse, pTab, pIdxInfo); |
| 112713 | 112802 | if( rc ) goto whereLoopAddVtab_exit; |
| 112714 | 112803 | pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; |
| 112715 | | - pNew->prereq = 0; |
| 112804 | + pNew->prereq = mExtra; |
| 112716 | 112805 | mxTerm = -1; |
| 112717 | 112806 | assert( pNew->nLSlot>=nConstraint ); |
| 112718 | 112807 | for(i=0; i<nConstraint; i++) pNew->aLTerm[i] = 0; |
| 112719 | 112808 | pNew->u.vtab.omitMask = 0; |
| 112720 | 112809 | for(i=0; i<nConstraint; i++, pIdxCons++){ |
| | @@ -112837,12 +112926,11 @@ |
| 112837 | 112926 | continue; |
| 112838 | 112927 | } |
| 112839 | 112928 | sCur.n = 0; |
| 112840 | 112929 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 112841 | 112930 | if( IsVirtual(pItem->pTab) ){ |
| 112842 | | - rc = whereLoopAddVirtual(&sSubBuild); |
| 112843 | | - for(i=0; i<sCur.n; i++) sCur.a[i].prereq |= mExtra; |
| 112931 | + rc = whereLoopAddVirtual(&sSubBuild, mExtra); |
| 112844 | 112932 | }else |
| 112845 | 112933 | #endif |
| 112846 | 112934 | { |
| 112847 | 112935 | rc = whereLoopAddBtree(&sSubBuild, mExtra); |
| 112848 | 112936 | } |
| | @@ -112908,11 +112996,11 @@ |
| 112908 | 112996 | if( ((pItem->jointype|priorJoinType) & (JT_LEFT|JT_CROSS))!=0 ){ |
| 112909 | 112997 | mExtra = mPrior; |
| 112910 | 112998 | } |
| 112911 | 112999 | priorJoinType = pItem->jointype; |
| 112912 | 113000 | if( IsVirtual(pItem->pTab) ){ |
| 112913 | | - rc = whereLoopAddVirtual(pBuilder); |
| 113001 | + rc = whereLoopAddVirtual(pBuilder, mExtra); |
| 112914 | 113002 | }else{ |
| 112915 | 113003 | rc = whereLoopAddBtree(pBuilder, mExtra); |
| 112916 | 113004 | } |
| 112917 | 113005 | if( rc==SQLITE_OK ){ |
| 112918 | 113006 | rc = whereLoopAddOr(pBuilder, mExtra); |
| | @@ -113069,10 +113157,11 @@ |
| 113069 | 113157 | for(j=0; j<nColumn; j++){ |
| 113070 | 113158 | u8 bOnce; /* True to run the ORDER BY search loop */ |
| 113071 | 113159 | |
| 113072 | 113160 | /* Skip over == and IS NULL terms */ |
| 113073 | 113161 | if( j<pLoop->u.btree.nEq |
| 113162 | + && pLoop->u.btree.nSkip==0 |
| 113074 | 113163 | && ((i = pLoop->aLTerm[j]->eOperator) & (WO_EQ|WO_ISNULL))!=0 |
| 113075 | 113164 | ){ |
| 113076 | 113165 | if( i & WO_ISNULL ){ |
| 113077 | 113166 | testcase( isOrderDistinct ); |
| 113078 | 113167 | isOrderDistinct = 0; |
| | @@ -113494,10 +113583,11 @@ |
| 113494 | 113583 | if( pItem->zIndex ) return 0; |
| 113495 | 113584 | iCur = pItem->iCursor; |
| 113496 | 113585 | pWC = &pWInfo->sWC; |
| 113497 | 113586 | pLoop = pBuilder->pNew; |
| 113498 | 113587 | pLoop->wsFlags = 0; |
| 113588 | + pLoop->u.btree.nSkip = 0; |
| 113499 | 113589 | pTerm = findTerm(pWC, iCur, -1, 0, WO_EQ, 0); |
| 113500 | 113590 | if( pTerm ){ |
| 113501 | 113591 | pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW; |
| 113502 | 113592 | pLoop->aLTerm[0] = pTerm; |
| 113503 | 113593 | pLoop->nLTerm = 1; |
| | @@ -114037,10 +114127,11 @@ |
| 114037 | 114127 | notReady = codeOneLoopStart(pWInfo, ii, notReady); |
| 114038 | 114128 | pWInfo->iContinue = pLevel->addrCont; |
| 114039 | 114129 | } |
| 114040 | 114130 | |
| 114041 | 114131 | /* Done. */ |
| 114132 | + VdbeNoopComment((v, "Begin WHERE-core")); |
| 114042 | 114133 | return pWInfo; |
| 114043 | 114134 | |
| 114044 | 114135 | /* Jump here if malloc fails */ |
| 114045 | 114136 | whereBeginError: |
| 114046 | 114137 | if( pWInfo ){ |
| | @@ -114063,12 +114154,14 @@ |
| 114063 | 114154 | SrcList *pTabList = pWInfo->pTabList; |
| 114064 | 114155 | sqlite3 *db = pParse->db; |
| 114065 | 114156 | |
| 114066 | 114157 | /* Generate loop termination code. |
| 114067 | 114158 | */ |
| 114159 | + VdbeNoopComment((v, "End WHERE-core")); |
| 114068 | 114160 | sqlite3ExprCacheClear(pParse); |
| 114069 | 114161 | for(i=pWInfo->nLevel-1; i>=0; i--){ |
| 114162 | + int addr; |
| 114070 | 114163 | pLevel = &pWInfo->a[i]; |
| 114071 | 114164 | pLoop = pLevel->pWLoop; |
| 114072 | 114165 | sqlite3VdbeResolveLabel(v, pLevel->addrCont); |
| 114073 | 114166 | if( pLevel->op!=OP_Noop ){ |
| 114074 | 114167 | sqlite3VdbeAddOp2(v, pLevel->op, pLevel->p1, pLevel->p2); |
| | @@ -114084,12 +114177,17 @@ |
| 114084 | 114177 | sqlite3VdbeJumpHere(v, pIn->addrInTop-1); |
| 114085 | 114178 | } |
| 114086 | 114179 | sqlite3DbFree(db, pLevel->u.in.aInLoop); |
| 114087 | 114180 | } |
| 114088 | 114181 | sqlite3VdbeResolveLabel(v, pLevel->addrBrk); |
| 114182 | + if( pLevel->addrSkip ){ |
| 114183 | + sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrSkip); |
| 114184 | + VdbeComment((v, "next skip-scan on %s", pLoop->u.btree.pIndex->zName)); |
| 114185 | + sqlite3VdbeJumpHere(v, pLevel->addrSkip); |
| 114186 | + sqlite3VdbeJumpHere(v, pLevel->addrSkip-2); |
| 114187 | + } |
| 114089 | 114188 | if( pLevel->iLeftJoin ){ |
| 114090 | | - int addr; |
| 114091 | 114189 | addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); |
| 114092 | 114190 | assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 |
| 114093 | 114191 | || (pLoop->wsFlags & WHERE_INDEXED)!=0 ); |
| 114094 | 114192 | if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 ){ |
| 114095 | 114193 | sqlite3VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor); |
| | @@ -114102,11 +114200,11 @@ |
| 114102 | 114200 | }else{ |
| 114103 | 114201 | sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrFirst); |
| 114104 | 114202 | } |
| 114105 | 114203 | sqlite3VdbeJumpHere(v, addr); |
| 114106 | 114204 | } |
| 114107 | | - VdbeNoopComment((v, "End WHERE-Loop %d: %s", i, |
| 114205 | + VdbeNoopComment((v, "End WHERE-loop%d: %s", i, |
| 114108 | 114206 | pWInfo->pTabList->a[pLevel->iFrom].pTab->zName)); |
| 114109 | 114207 | } |
| 114110 | 114208 | |
| 114111 | 114209 | /* The "break" point is here, just past the end of the outer loop. |
| 114112 | 114210 | ** Set it. |
| | @@ -123687,10 +123785,14 @@ |
| 123687 | 123785 | char *aDoclist; /* Pointer to doclist buffer */ |
| 123688 | 123786 | int nDoclist; /* Size of aDoclist[] in bytes */ |
| 123689 | 123787 | }; |
| 123690 | 123788 | |
| 123691 | 123789 | SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table*,int,int); |
| 123790 | + |
| 123791 | +#define fts3GetVarint32(p, piVal) ( \ |
| 123792 | + (*(u8*)(p)&0x80) ? sqlite3Fts3GetVarint32(p, piVal) : (*piVal=*(u8*)(p), 1) \ |
| 123793 | +) |
| 123692 | 123794 | |
| 123693 | 123795 | /* fts3.c */ |
| 123694 | 123796 | SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *, sqlite3_int64); |
| 123695 | 123797 | SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *, sqlite_int64 *); |
| 123696 | 123798 | SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *, int *); |
| | @@ -123795,36 +123897,60 @@ |
| 123795 | 123897 | q[-1] &= 0x7f; /* turn off high bit in final byte */ |
| 123796 | 123898 | assert( q - (unsigned char *)p <= FTS3_VARINT_MAX ); |
| 123797 | 123899 | return (int) (q - (unsigned char *)p); |
| 123798 | 123900 | } |
| 123799 | 123901 | |
| 123902 | +#define GETVARINT_STEP(v, ptr, shift, mask1, mask2, var, ret) \ |
| 123903 | + v = (v & mask1) | ( (*ptr++) << shift ); \ |
| 123904 | + if( (v & mask2)==0 ){ var = v; return ret; } |
| 123905 | + |
| 123800 | 123906 | /* |
| 123801 | 123907 | ** Read a 64-bit variable-length integer from memory starting at p[0]. |
| 123802 | 123908 | ** Return the number of bytes read, or 0 on error. |
| 123803 | 123909 | ** The value is stored in *v. |
| 123804 | 123910 | */ |
| 123805 | 123911 | SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *p, sqlite_int64 *v){ |
| 123806 | | - const unsigned char *q = (const unsigned char *) p; |
| 123807 | | - sqlite_uint64 x = 0, y = 1; |
| 123808 | | - while( (*q&0x80)==0x80 && q-(unsigned char *)p<FTS3_VARINT_MAX ){ |
| 123809 | | - x += y * (*q++ & 0x7f); |
| 123810 | | - y <<= 7; |
| 123811 | | - } |
| 123812 | | - x += y * (*q++); |
| 123813 | | - *v = (sqlite_int64) x; |
| 123814 | | - return (int) (q - (unsigned char *)p); |
| 123912 | + const char *pStart = p; |
| 123913 | + u32 a; |
| 123914 | + u64 b; |
| 123915 | + int shift; |
| 123916 | + |
| 123917 | + GETVARINT_STEP(a, p, 0, 0x00, 0x80, *v, 1); |
| 123918 | + GETVARINT_STEP(a, p, 7, 0x7F, 0x4000, *v, 2); |
| 123919 | + GETVARINT_STEP(a, p, 14, 0x3FFF, 0x200000, *v, 3); |
| 123920 | + GETVARINT_STEP(a, p, 21, 0x1FFFFF, 0x10000000, *v, 4); |
| 123921 | + b = (a & 0x0FFFFFFF ); |
| 123922 | + |
| 123923 | + for(shift=28; shift<=63; shift+=7){ |
| 123924 | + u64 c = *p++; |
| 123925 | + b += (c&0x7F) << shift; |
| 123926 | + if( (c & 0x80)==0 ) break; |
| 123927 | + } |
| 123928 | + *v = b; |
| 123929 | + return p - pStart; |
| 123815 | 123930 | } |
| 123816 | 123931 | |
| 123817 | 123932 | /* |
| 123818 | 123933 | ** Similar to sqlite3Fts3GetVarint(), except that the output is truncated to a |
| 123819 | 123934 | ** 32-bit integer before it is returned. |
| 123820 | 123935 | */ |
| 123821 | 123936 | SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *p, int *pi){ |
| 123822 | | - sqlite_int64 i; |
| 123823 | | - int ret = sqlite3Fts3GetVarint(p, &i); |
| 123824 | | - *pi = (int) i; |
| 123825 | | - return ret; |
| 123937 | + u32 a; |
| 123938 | + |
| 123939 | +#ifndef fts3GetVarint32 |
| 123940 | + GETVARINT_STEP(a, p, 0, 0x00, 0x80, *pi, 1); |
| 123941 | +#else |
| 123942 | + a = (*p++); |
| 123943 | + assert( a & 0x80 ); |
| 123944 | +#endif |
| 123945 | + |
| 123946 | + GETVARINT_STEP(a, p, 7, 0x7F, 0x4000, *pi, 2); |
| 123947 | + GETVARINT_STEP(a, p, 14, 0x3FFF, 0x200000, *pi, 3); |
| 123948 | + GETVARINT_STEP(a, p, 21, 0x1FFFFF, 0x10000000, *pi, 4); |
| 123949 | + a = (a & 0x0FFFFFFF ); |
| 123950 | + *pi = (int)(a | ((u32)(*p & 0x0F) << 28)); |
| 123951 | + return 5; |
| 123826 | 123952 | } |
| 123827 | 123953 | |
| 123828 | 123954 | /* |
| 123829 | 123955 | ** Return the number of bytes required to encode v as a varint |
| 123830 | 123956 | */ |
| | @@ -125180,14 +125306,14 @@ |
| 125180 | 125306 | int nBuffer; /* Total term size */ |
| 125181 | 125307 | |
| 125182 | 125308 | /* Load the next term on the node into zBuffer. Use realloc() to expand |
| 125183 | 125309 | ** the size of zBuffer if required. */ |
| 125184 | 125310 | if( !isFirstTerm ){ |
| 125185 | | - zCsr += sqlite3Fts3GetVarint32(zCsr, &nPrefix); |
| 125311 | + zCsr += fts3GetVarint32(zCsr, &nPrefix); |
| 125186 | 125312 | } |
| 125187 | 125313 | isFirstTerm = 0; |
| 125188 | | - zCsr += sqlite3Fts3GetVarint32(zCsr, &nSuffix); |
| 125314 | + zCsr += fts3GetVarint32(zCsr, &nSuffix); |
| 125189 | 125315 | |
| 125190 | 125316 | if( nPrefix<0 || nSuffix<0 || &zCsr[nSuffix]>zEnd ){ |
| 125191 | 125317 | rc = FTS_CORRUPT_VTAB; |
| 125192 | 125318 | goto finish_scan; |
| 125193 | 125319 | } |
| | @@ -125271,11 +125397,11 @@ |
| 125271 | 125397 | int rc; /* Return code */ |
| 125272 | 125398 | int iHeight; /* Height of this node in tree */ |
| 125273 | 125399 | |
| 125274 | 125400 | assert( piLeaf || piLeaf2 ); |
| 125275 | 125401 | |
| 125276 | | - sqlite3Fts3GetVarint32(zNode, &iHeight); |
| 125402 | + fts3GetVarint32(zNode, &iHeight); |
| 125277 | 125403 | rc = fts3ScanInteriorNode(zTerm, nTerm, zNode, nNode, piLeaf, piLeaf2); |
| 125278 | 125404 | assert( !piLeaf2 || !piLeaf || rc!=SQLITE_OK || (*piLeaf<=*piLeaf2) ); |
| 125279 | 125405 | |
| 125280 | 125406 | if( rc==SQLITE_OK && iHeight>1 ){ |
| 125281 | 125407 | char *zBlob = 0; /* Blob read from %_segments table */ |
| | @@ -125473,15 +125599,15 @@ |
| 125473 | 125599 | |
| 125474 | 125600 | while( *p1 || *p2 ){ |
| 125475 | 125601 | int iCol1; /* The current column index in pp1 */ |
| 125476 | 125602 | int iCol2; /* The current column index in pp2 */ |
| 125477 | 125603 | |
| 125478 | | - if( *p1==POS_COLUMN ) sqlite3Fts3GetVarint32(&p1[1], &iCol1); |
| 125604 | + if( *p1==POS_COLUMN ) fts3GetVarint32(&p1[1], &iCol1); |
| 125479 | 125605 | else if( *p1==POS_END ) iCol1 = POSITION_LIST_END; |
| 125480 | 125606 | else iCol1 = 0; |
| 125481 | 125607 | |
| 125482 | | - if( *p2==POS_COLUMN ) sqlite3Fts3GetVarint32(&p2[1], &iCol2); |
| 125608 | + if( *p2==POS_COLUMN ) fts3GetVarint32(&p2[1], &iCol2); |
| 125483 | 125609 | else if( *p2==POS_END ) iCol2 = POSITION_LIST_END; |
| 125484 | 125610 | else iCol2 = 0; |
| 125485 | 125611 | |
| 125486 | 125612 | if( iCol1==iCol2 ){ |
| 125487 | 125613 | sqlite3_int64 i1 = 0; /* Last position from pp1 */ |
| | @@ -125570,15 +125696,15 @@ |
| 125570 | 125696 | assert( isSaveLeft==0 || isExact==0 ); |
| 125571 | 125697 | |
| 125572 | 125698 | assert( p!=0 && *p1!=0 && *p2!=0 ); |
| 125573 | 125699 | if( *p1==POS_COLUMN ){ |
| 125574 | 125700 | p1++; |
| 125575 | | - p1 += sqlite3Fts3GetVarint32(p1, &iCol1); |
| 125701 | + p1 += fts3GetVarint32(p1, &iCol1); |
| 125576 | 125702 | } |
| 125577 | 125703 | if( *p2==POS_COLUMN ){ |
| 125578 | 125704 | p2++; |
| 125579 | | - p2 += sqlite3Fts3GetVarint32(p2, &iCol2); |
| 125705 | + p2 += fts3GetVarint32(p2, &iCol2); |
| 125580 | 125706 | } |
| 125581 | 125707 | |
| 125582 | 125708 | while( 1 ){ |
| 125583 | 125709 | if( iCol1==iCol2 ){ |
| 125584 | 125710 | char *pSave = p; |
| | @@ -125624,13 +125750,13 @@ |
| 125624 | 125750 | fts3ColumnlistCopy(0, &p2); |
| 125625 | 125751 | assert( (*p1&0xFE)==0 && (*p2&0xFE)==0 ); |
| 125626 | 125752 | if( 0==*p1 || 0==*p2 ) break; |
| 125627 | 125753 | |
| 125628 | 125754 | p1++; |
| 125629 | | - p1 += sqlite3Fts3GetVarint32(p1, &iCol1); |
| 125755 | + p1 += fts3GetVarint32(p1, &iCol1); |
| 125630 | 125756 | p2++; |
| 125631 | | - p2 += sqlite3Fts3GetVarint32(p2, &iCol2); |
| 125757 | + p2 += fts3GetVarint32(p2, &iCol2); |
| 125632 | 125758 | } |
| 125633 | 125759 | |
| 125634 | 125760 | /* Advance pointer p1 or p2 (whichever corresponds to the smaller of |
| 125635 | 125761 | ** iCol1 and iCol2) so that it points to either the 0x00 that marks the |
| 125636 | 125762 | ** end of the position list, or the 0x01 that precedes the next |
| | @@ -125638,16 +125764,16 @@ |
| 125638 | 125764 | */ |
| 125639 | 125765 | else if( iCol1<iCol2 ){ |
| 125640 | 125766 | fts3ColumnlistCopy(0, &p1); |
| 125641 | 125767 | if( 0==*p1 ) break; |
| 125642 | 125768 | p1++; |
| 125643 | | - p1 += sqlite3Fts3GetVarint32(p1, &iCol1); |
| 125769 | + p1 += fts3GetVarint32(p1, &iCol1); |
| 125644 | 125770 | }else{ |
| 125645 | 125771 | fts3ColumnlistCopy(0, &p2); |
| 125646 | 125772 | if( 0==*p2 ) break; |
| 125647 | 125773 | p2++; |
| 125648 | | - p2 += sqlite3Fts3GetVarint32(p2, &iCol2); |
| 125774 | + p2 += fts3GetVarint32(p2, &iCol2); |
| 125649 | 125775 | } |
| 125650 | 125776 | } |
| 125651 | 125777 | |
| 125652 | 125778 | fts3PoslistCopy(0, &p2); |
| 125653 | 125779 | fts3PoslistCopy(0, &p1); |
| | @@ -128810,11 +128936,11 @@ |
| 128810 | 128936 | */ |
| 128811 | 128937 | pExpr->aMI[iCol*3 + 1] += iCnt; |
| 128812 | 128938 | pExpr->aMI[iCol*3 + 2] += (iCnt>0); |
| 128813 | 128939 | if( *p==0x00 ) break; |
| 128814 | 128940 | p++; |
| 128815 | | - p += sqlite3Fts3GetVarint32(p, &iCol); |
| 128941 | + p += fts3GetVarint32(p, &iCol); |
| 128816 | 128942 | } |
| 128817 | 128943 | } |
| 128818 | 128944 | |
| 128819 | 128945 | fts3EvalUpdateCounts(pExpr->pLeft); |
| 128820 | 128946 | fts3EvalUpdateCounts(pExpr->pRight); |
| | @@ -129111,19 +129237,19 @@ |
| 129111 | 129237 | } |
| 129112 | 129238 | if( pIter==0 ) return SQLITE_OK; |
| 129113 | 129239 | |
| 129114 | 129240 | if( *pIter==0x01 ){ |
| 129115 | 129241 | pIter++; |
| 129116 | | - pIter += sqlite3Fts3GetVarint32(pIter, &iThis); |
| 129242 | + pIter += fts3GetVarint32(pIter, &iThis); |
| 129117 | 129243 | }else{ |
| 129118 | 129244 | iThis = 0; |
| 129119 | 129245 | } |
| 129120 | 129246 | while( iThis<iCol ){ |
| 129121 | 129247 | fts3ColumnlistCopy(0, &pIter); |
| 129122 | 129248 | if( *pIter==0x00 ) return 0; |
| 129123 | 129249 | pIter++; |
| 129124 | | - pIter += sqlite3Fts3GetVarint32(pIter, &iThis); |
| 129250 | + pIter += fts3GetVarint32(pIter, &iThis); |
| 129125 | 129251 | } |
| 129126 | 129252 | |
| 129127 | 129253 | *ppOut = ((iCol==iThis)?pIter:0); |
| 129128 | 129254 | return SQLITE_OK; |
| 129129 | 129255 | } |
| | @@ -134568,12 +134694,12 @@ |
| 134568 | 134694 | rc = fts3SegReaderRequire(pReader, pNext, FTS3_VARINT_MAX*2); |
| 134569 | 134695 | if( rc!=SQLITE_OK ) return rc; |
| 134570 | 134696 | |
| 134571 | 134697 | /* Because of the FTS3_NODE_PADDING bytes of padding, the following is |
| 134572 | 134698 | ** safe (no risk of overread) even if the node data is corrupted. */ |
| 134573 | | - pNext += sqlite3Fts3GetVarint32(pNext, &nPrefix); |
| 134574 | | - pNext += sqlite3Fts3GetVarint32(pNext, &nSuffix); |
| 134699 | + pNext += fts3GetVarint32(pNext, &nPrefix); |
| 134700 | + pNext += fts3GetVarint32(pNext, &nSuffix); |
| 134575 | 134701 | if( nPrefix<0 || nSuffix<=0 |
| 134576 | 134702 | || &pNext[nSuffix]>&pReader->aNode[pReader->nNode] |
| 134577 | 134703 | ){ |
| 134578 | 134704 | return FTS_CORRUPT_VTAB; |
| 134579 | 134705 | } |
| | @@ -134592,11 +134718,11 @@ |
| 134592 | 134718 | if( rc!=SQLITE_OK ) return rc; |
| 134593 | 134719 | |
| 134594 | 134720 | memcpy(&pReader->zTerm[nPrefix], pNext, nSuffix); |
| 134595 | 134721 | pReader->nTerm = nPrefix+nSuffix; |
| 134596 | 134722 | pNext += nSuffix; |
| 134597 | | - pNext += sqlite3Fts3GetVarint32(pNext, &pReader->nDoclist); |
| 134723 | + pNext += fts3GetVarint32(pNext, &pReader->nDoclist); |
| 134598 | 134724 | pReader->aDoclist = pNext; |
| 134599 | 134725 | pReader->pOffsetList = 0; |
| 134600 | 134726 | |
| 134601 | 134727 | /* Check that the doclist does not appear to extend past the end of the |
| 134602 | 134728 | ** b-tree node. And that the final byte of the doclist is 0x00. If either |
| | @@ -135753,11 +135879,11 @@ |
| 135753 | 135879 | pList = p; |
| 135754 | 135880 | if( nList==0 ){ |
| 135755 | 135881 | break; |
| 135756 | 135882 | } |
| 135757 | 135883 | p = &pList[1]; |
| 135758 | | - p += sqlite3Fts3GetVarint32(p, &iCurrent); |
| 135884 | + p += fts3GetVarint32(p, &iCurrent); |
| 135759 | 135885 | } |
| 135760 | 135886 | |
| 135761 | 135887 | if( bZero && &pList[nList]!=pEnd ){ |
| 135762 | 135888 | memset(&pList[nList], 0, pEnd - &pList[nList]); |
| 135763 | 135889 | } |
| | @@ -136718,21 +136844,21 @@ |
| 136718 | 136844 | if( p->iOff>=p->nNode ){ |
| 136719 | 136845 | /* EOF */ |
| 136720 | 136846 | p->aNode = 0; |
| 136721 | 136847 | }else{ |
| 136722 | 136848 | if( bFirst==0 ){ |
| 136723 | | - p->iOff += sqlite3Fts3GetVarint32(&p->aNode[p->iOff], &nPrefix); |
| 136849 | + p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nPrefix); |
| 136724 | 136850 | } |
| 136725 | | - p->iOff += sqlite3Fts3GetVarint32(&p->aNode[p->iOff], &nSuffix); |
| 136851 | + p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix); |
| 136726 | 136852 | |
| 136727 | 136853 | blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc); |
| 136728 | 136854 | if( rc==SQLITE_OK ){ |
| 136729 | 136855 | memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix); |
| 136730 | 136856 | p->term.n = nPrefix+nSuffix; |
| 136731 | 136857 | p->iOff += nSuffix; |
| 136732 | 136858 | if( p->iChild==0 ){ |
| 136733 | | - p->iOff += sqlite3Fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist); |
| 136859 | + p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist); |
| 136734 | 136860 | p->aDoclist = &p->aNode[p->iOff]; |
| 136735 | 136861 | p->iOff += p->nDoclist; |
| 136736 | 136862 | } |
| 136737 | 136863 | } |
| 136738 | 136864 | } |
| | @@ -137780,11 +137906,11 @@ |
| 137780 | 137906 | while( i>0 && (pHint->a[i-1] & 0x80) ) i--; |
| 137781 | 137907 | while( i>0 && (pHint->a[i-1] & 0x80) ) i--; |
| 137782 | 137908 | |
| 137783 | 137909 | pHint->n = i; |
| 137784 | 137910 | i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel); |
| 137785 | | - i += sqlite3Fts3GetVarint32(&pHint->a[i], pnInput); |
| 137911 | + i += fts3GetVarint32(&pHint->a[i], pnInput); |
| 137786 | 137912 | if( i!=nHint ) return SQLITE_CORRUPT_VTAB; |
| 137787 | 137913 | |
| 137788 | 137914 | return SQLITE_OK; |
| 137789 | 137915 | } |
| 137790 | 137916 | |
| | @@ -138773,11 +138899,11 @@ |
| 138773 | 138899 | ** After it returns, *piPos contains the value of the next element of the |
| 138774 | 138900 | ** list and *pp is advanced to the following varint. |
| 138775 | 138901 | */ |
| 138776 | 138902 | static void fts3GetDeltaPosition(char **pp, int *piPos){ |
| 138777 | 138903 | int iVal; |
| 138778 | | - *pp += sqlite3Fts3GetVarint32(*pp, &iVal); |
| 138904 | + *pp += fts3GetVarint32(*pp, &iVal); |
| 138779 | 138905 | *piPos += (iVal-2); |
| 138780 | 138906 | } |
| 138781 | 138907 | |
| 138782 | 138908 | /* |
| 138783 | 138909 | ** Helper function for fts3ExprIterate() (see below). |
| 138784 | 138910 | |