From: drh Date: Sat, 25 Sep 2004 13:12:14 +0000 (+0000) Subject: Code simplifications and size reductions. (CVS 1983) X-Git-Tag: version-3.6.10~4164 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=94a11211f548208e2725d2f5cc6fef29828356fe;p=thirdparty%2Fsqlite.git Code simplifications and size reductions. (CVS 1983) FossilOrigin-Name: cb631a135da92fd689ee40a8b7e2695a510eb765 --- diff --git a/manifest b/manifest index 5d32ecf91f..11e1814aef 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Size\soptimizations\sin\svdbeapi.c.\s(CVS\s1982) -D 2004-09-24T23:59:12 +C Code\ssimplifications\sand\ssize\sreductions.\s(CVS\s1983) +D 2004-09-25T13:12:15 F Makefile.in abdeb5bd9d017822691884935c320037c33f6ee6 F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -33,7 +33,7 @@ F src/btree.h 94dfec0a1722d33359b23e7e310f2b64ffedf029 F src/build.c c5ecf114af4ebc2963a03142b6bd6f2284ee35fc F src/date.c eb8d5fa1a6d5cfc09031c8852d10ff742a94b15b F src/delete.c d862b383a9abc0b79f4588783c2619fe52d74ea7 -F src/expr.c 16ccea21ffb60f32ce2a9dd56d6d2c2cfdb0f1c6 +F src/expr.c f255c5c56c0371cb2955cbc2733621051e4f79f8 F src/func.c 1fbc5256639586573fd0e70814d6dcd8bc10afc1 F src/hash.c a97721a55440b7bea31ffe471bb2f6b4123cddd5 F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84 @@ -53,14 +53,14 @@ F src/os_win.c 9e2887825b1a32f0ceb1b73b93ffe29a112cd86f F src/os_win.h babd4e912967c6b09088cfe38a45e8005a07ba44 F src/pager.c 705a61117f05d7dd031762408f9a279834e88c3a F src/pager.h 67739fe649f33be55dba522ca8a9cc4e42d14f71 -F src/parse.y 9389af67bd49b8e5c9d2968b3315a30565b4a200 +F src/parse.y 93edda0f1e9b25bee7cdfb5bf624ae85f8e9e5c9 F src/pragma.c 5fb6647fda4c95edb08447a505e6c98c041e5b31 F src/printf.c 40770e1f553612d13dfc86d236086e69baa62fe1 F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3 -F src/select.c 13a4e6d0ca2bce8be60e26a499060524fef2e28c +F src/select.c 97c5f11b2b456dc6113454e592dbf03dc46e2b9d F src/shell.c 0856973c2b94e22664bc43f398ba3fc22d5e080c F src/sqlite.h.in e29a526593b806f148017ed8bada760ada84cf2f -F src/sqliteInt.h a7d334b2aca08de0c1cace3eebfabc129279c26f +F src/sqliteInt.h 581437ae245e5b8294bfc20c9a06a16bb6b3d281 F src/table.c 8168c6e824009f8485bff79fc60ea8fea6829b10 F src/tclsqlite.c 0302e3f42f015d132d1291f3388c06e86c24a008 F src/test1.c 1305825c29575ee55a1c8b98a191669fd78b6287 @@ -80,7 +80,7 @@ F src/vdbeInt.h 6017100adff362b8dfa37a69e3f1431f084bfa5b F src/vdbeapi.c 81ab9e84c55f5762f552904e6e5d309269b02017 F src/vdbeaux.c dc3848209aee05b32636a9c1dd913a56ef8dac79 F src/vdbemem.c ef9ac7d32acfe4bce5c5b408b1294c8d9e0cdb56 -F src/where.c 5d573333c07f259c8d3b8423d82ba774b78b63a9 +F src/where.c 04d3ee039d8e66c520e3b6bd5103dc3b8c3eb76b F test/all.test 929bfa932b55e75c96fe2203f7650ba451c1862c F test/attach.test feb2ce54e78688df4c84553416d5aec3b2a0112e F test/attach2.test 32ca2c1a5a347a7404219a11f9f84739a63d2582 @@ -247,7 +247,7 @@ F www/tclsqlite.tcl 560ecd6a916b320e59f2917317398f3d59b7cc25 F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9 F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 -P 8154d545e8ae3d22490b49ce4f327605883accaa -R 508b9be36c846738b3d04606ced87a41 +P b2f3d4bb8e24212d3cef7615c24da13f29c1440c +R 7b7549a8227df9a562548ecaa05d3fba U drh -Z da75a2e59bfb74cfb329258a940d48f5 +Z e21d66c92b9e14b190cf7982b2d07af5 diff --git a/manifest.uuid b/manifest.uuid index 74eccdd4e0..b820204224 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b2f3d4bb8e24212d3cef7615c24da13f29c1440c \ No newline at end of file +cb631a135da92fd689ee40a8b7e2695a510eb765 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index c081555068..a07fdcd003 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,24 +12,11 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.164 2004/09/24 12:24:07 drh Exp $ +** $Id: expr.c,v 1.165 2004/09/25 13:12:15 drh Exp $ */ #include "sqliteInt.h" #include -char const *sqlite3AffinityString(char affinity){ - switch( affinity ){ - case SQLITE_AFF_INTEGER: return "i"; - case SQLITE_AFF_NUMERIC: return "n"; - case SQLITE_AFF_TEXT: return "t"; - case SQLITE_AFF_NONE: return "o"; - default: - assert(0); - } - return 0; -} - - /* ** Return the 'affinity' of the expression pExpr if any. ** @@ -184,7 +171,7 @@ static int codeCompare( ){ int p1 = binaryCompareP1(pLeft, pRight, jumpIfNull); CollSeq *p3 = binaryCompareCollSeq(pParse, pLeft, pRight); - return sqlite3VdbeOp3(pParse->pVdbe, opcode, p1, dest, (void *)p3, P3_COLLSEQ); + return sqlite3VdbeOp3(pParse->pVdbe, opcode, p1, dest, (void*)p3, P3_COLLSEQ); } /* @@ -970,11 +957,9 @@ int sqlite3ExprResolveIds( ** a column, use numeric affinity. */ int i; - char const *affStr; if( !affinity ){ affinity = SQLITE_AFF_NUMERIC; } - affStr = sqlite3AffinityString(affinity); keyInfo.aColl[0] = pExpr->pLeft->pColl; /* Loop through each expression in . */ @@ -993,7 +978,7 @@ int sqlite3ExprResolveIds( /* Evaluate the expression and insert it into the temp table */ sqlite3ExprCode(pParse, pE2); - sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, affStr, P3_STATIC); + sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1); sqlite3VdbeAddOp(v, OP_String8, 0, 0); sqlite3VdbeAddOp(v, OP_PutStrKey, pExpr->iTable, 0); } @@ -1374,13 +1359,13 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ } case TK_IN: { int addr; - char const *affStr; + char affinity; /* Figure out the affinity to use to create a key from the results ** of the expression. affinityStr stores a static string suitable for ** P3 of OP_MakeRecord. */ - affStr = sqlite3AffinityString(comparisonAffinity(pExpr)); + affinity = comparisonAffinity(pExpr); sqlite3VdbeAddOp(v, OP_Integer, 1, 0); @@ -1393,7 +1378,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ sqlite3VdbeAddOp(v, OP_Pop, 2, 0); sqlite3VdbeAddOp(v, OP_String8, 0, 0); sqlite3VdbeAddOp(v, OP_Goto, 0, addr+7); - sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, affStr, P3_STATIC); /* addr + 4 */ + sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1); /* addr + 4 */ sqlite3VdbeAddOp(v, OP_Found, pExpr->iTable, addr+7); sqlite3VdbeAddOp(v, OP_AddImm, -1, 0); /* addr + 6 */ diff --git a/src/parse.y b/src/parse.y index 37a864aac7..f437b4ef14 100644 --- a/src/parse.y +++ b/src/parse.y @@ -14,7 +14,7 @@ ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** -** @(#) $Id: parse.y,v 1.136 2004/09/07 16:19:54 drh Exp $ +** @(#) $Id: parse.y,v 1.137 2004/09/25 13:12:16 drh Exp $ */ %token_prefix TK_ %token_type {Token} @@ -140,7 +140,7 @@ id(A) ::= ID(X). {A = X;} %left OR. %left AND. %right NOT. -%left EQ NE ISNULL NOTNULL IS LIKE GLOB BETWEEN IN. +%left ISNULL NOTNULL IS LIKE GLOB BETWEEN IN NE EQ. %left GT GE LT LE. %left BITAND BITOR LSHIFT RSHIFT. %left PLUS MINUS. diff --git a/src/select.c b/src/select.c index 265a402284..9742386631 100644 --- a/src/select.c +++ b/src/select.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** -** $Id: select.c,v 1.209 2004/09/19 02:15:26 drh Exp $ +** $Id: select.c,v 1.210 2004/09/25 13:12:16 drh Exp $ */ #include "sqliteInt.h" @@ -483,8 +483,7 @@ static int selectInnerLoop( char const *affStr; char aff = (iParm>>16)&0xFF; aff = sqlite3CompareAffinity(pEList->a[0].pExpr, aff); - affStr = sqlite3AffinityString(aff); - sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, affStr, P3_STATIC); + sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &aff, 1); sqlite3VdbeAddOp(v, OP_String8, 0, 0); sqlite3VdbeAddOp(v, OP_PutStrKey, (iParm&0x0000FFFF), 0); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 91cc0f177f..0babae4ca8 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.322 2004/09/19 02:15:26 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.323 2004/09/25 13:12:16 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -1372,7 +1372,6 @@ char sqlite3AffinityType(const char *, int); void sqlite3IndexAffinityStr(Vdbe *, Index *); void sqlite3TableAffinityStr(Vdbe *, Table *); char sqlite3CompareAffinity(Expr *pExpr, char aff2); -char const *sqlite3AffinityString(char affinity); int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity); char sqlite3ExprAffinity(Expr *pExpr); int sqlite3atoi64(const char*, i64*); diff --git a/src/where.c b/src/where.c index ce62b2b078..4110431e42 100644 --- a/src/where.c +++ b/src/where.c @@ -12,7 +12,7 @@ ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. ** -** $Id: where.c,v 1.114 2004/09/19 02:15:26 drh Exp $ +** $Id: where.c,v 1.115 2004/09/25 13:12:16 drh Exp $ */ #include "sqliteInt.h" @@ -357,6 +357,52 @@ static void disableTerm(WhereLevel *pLevel, Expr **ppExpr){ } } +/* +** Generate code that builds a probe for an index. Details: +** +** * Check the top nColumn entries on the stack. If any +** of those entries are NULL, jump immediately to brk, +** which is the loop exit, since no index entry will match +** if any part of the key is NULL. +** +** * Construct a probe entry from the top nColumn entries in +** the stack with affinities appropriate for index pIdx. +*/ +static void buildIndexProbe(Vdbe *v, int nColumn, int brk, Index *pIdx){ + sqlite3VdbeAddOp(v, OP_NotNull, -nColumn, sqlite3VdbeCurrentAddr(v)+3); + sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0); + sqlite3VdbeAddOp(v, OP_Goto, 0, brk); + sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0); + sqlite3IndexAffinityStr(v, pIdx); +} + +/* +** Generate code for an equality term of the WHERE clause. An equality +** term can be either X=expr or X IN (...). pTerm is the X. +*/ +static void codeEqualityTerm( + Parse *pParse, /* The parsing context */ + ExprInfo *pTerm, /* The term of the WHERE clause to be coded */ + int brk, /* Jump here to abandon the loop */ + WhereLevel *pLevel /* When level of the FROM clause we are working on */ +){ + Expr *pX = pTerm->p; + if( pX->op!=TK_IN ){ + assert( pX->op==TK_EQ ); + sqlite3ExprCode(pParse, pX->pRight); + }else{ + int iTab = pX->iTable; + Vdbe *v = pParse->pVdbe; + sqlite3VdbeAddOp(v, OP_Rewind, iTab, brk); + sqlite3VdbeAddOp(v, OP_KeyAsData, iTab, 1); + pLevel->inP2 = sqlite3VdbeAddOp(v, OP_IdxColumn, iTab, 0); + pLevel->inOp = OP_Next; + pLevel->inP1 = iTab; + } + disableTerm(pLevel, &pTerm->p); +} + + /* ** Generate the beginning of the loop used for WHERE clause processing. ** The return value is a pointer to an (opaque) structure that contains @@ -539,6 +585,7 @@ WhereInfo *sqlite3WhereBegin( loopMask = 0; for(i=0; inSrc && ia[i]; int iCur = pTabList->a[i].iCursor; /* The cursor for this table */ int mask = getMask(&maskSet, iCur); /* Cursor mask for this table */ Table *pTab = pTabList->a[i].pTab; @@ -554,7 +601,7 @@ WhereInfo *sqlite3WhereBegin( ** ** (Added:) Treat ROWID IN expr like ROWID=expr. */ - pWInfo->a[i].iCur = -1; + pLevel->iCur = -1; iDirectEq[i] = -1; iDirectLt[i] = -1; iDirectGt[i] = -1; @@ -574,7 +621,7 @@ WhereInfo *sqlite3WhereBegin( } if( iDirectEq[i]>=0 ){ loopMask |= mask; - pWInfo->a[i].pIdx = 0; + pLevel->pIdx = 0; continue; } @@ -612,8 +659,8 @@ WhereInfo *sqlite3WhereBegin( if( pIdx->nColumn>32 ) continue; /* Ignore indices too many columns */ for(pTerm=aExpr, j=0; jp->pLeft); Expr *pX = pTerm->p; + CollSeq *pColl = sqlite3ExprCollSeq(pParse, pX->pLeft); if( !pColl && pX->pRight ){ pColl = sqlite3ExprCollSeq(pParse, pX->pRight); } @@ -679,12 +726,12 @@ WhereInfo *sqlite3WhereBegin( bestScore = score; } } - pWInfo->a[i].pIdx = pBestIdx; - pWInfo->a[i].score = bestScore; - pWInfo->a[i].bRev = 0; + pLevel->pIdx = pBestIdx; + pLevel->score = bestScore; + pLevel->bRev = 0; loopMask |= mask; if( pBestIdx ){ - pWInfo->a[i].iCur = pParse->nTab++; + pLevel->iCur = pParse->nTab++; } } @@ -766,31 +813,18 @@ WhereInfo *sqlite3WhereBegin( pIdx = pLevel->pIdx; pLevel->inOp = OP_Noop; - if( i=0 ){ + if( i=0 ){ /* Case 1: We can directly reference a single row using an ** equality comparison against the ROWID field. Or ** we reference multiple rows using a "rowid IN (...)" ** construct. */ - Expr *pX; - k = iDirectEq[i]; assert( kp!=0 ); - assert( pTerm->idxLeft==iCur || pTerm->idxRight==iCur ); - brk = pLevel->brk = sqlite3VdbeMakeLabel(v); - pX = pTerm->p; assert( pTerm->idxLeft==iCur ); - if( pX->op!=TK_IN ){ - sqlite3ExprCode(pParse, pTerm->p->pRight); - }else{ - sqlite3VdbeAddOp(v, OP_Rewind, pX->iTable, brk); - sqlite3VdbeAddOp(v, OP_KeyAsData, pX->iTable, 1); - pLevel->inP2 = sqlite3VdbeAddOp(v, OP_IdxColumn, pX->iTable, 0); - pLevel->inOp = OP_Next; - pLevel->inP1 = pX->iTable; - } - disableTerm(pLevel, &pTerm->p); + brk = pLevel->brk = sqlite3VdbeMakeLabel(v); + codeEqualityTerm(pParse, pTerm, brk, pLevel); cont = pLevel->cont = sqlite3VdbeMakeLabel(v); sqlite3VdbeAddOp(v, OP_MustBeInt, 1, brk); haveKey = 0; @@ -816,40 +850,16 @@ WhereInfo *sqlite3WhereBegin( && pX->pLeft->iColumn==pIdx->aiColumn[j] ){ char idxaff = pIdx->pTable->aCol[pX->pLeft->iColumn].affinity; - if( sqlite3IndexAffinityOk(pTerm->p, idxaff) ){ - if( pX->op==TK_EQ ){ - sqlite3ExprCode(pParse, pX->pRight); - disableTerm(pLevel, &pTerm->p); - break; - } - assert( pX->op==TK_IN && nColumn==1 ); - if( pX->op==TK_IN && nColumn==1 ){ - sqlite3VdbeAddOp(v, OP_Rewind, pX->iTable, brk); - sqlite3VdbeAddOp(v, OP_KeyAsData, pX->iTable, 1); - pLevel->inP2 = sqlite3VdbeAddOp(v, OP_IdxColumn, pX->iTable, 0); - pLevel->inOp = OP_Next; - pLevel->inP1 = pX->iTable; - disableTerm(pLevel, &pTerm->p); - break; - } + if( sqlite3IndexAffinityOk(pX, idxaff) ){ + codeEqualityTerm(pParse, pTerm, brk, pLevel); + break; } } } } pLevel->iMem = pParse->nMem++; cont = pLevel->cont = sqlite3VdbeMakeLabel(v); - - /* At this point, the top nColumn elements of the stack are the - ** values of columns in the index we are using. Check to see if - ** any of these values are NULL. If they are, they will not match any - ** index entries, so skip immediately to the next iteration of the loop */ - sqlite3VdbeAddOp(v, OP_NotNull, -nColumn, sqlite3VdbeCurrentAddr(v)+3); - sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0); - sqlite3VdbeAddOp(v, OP_Goto, 0, brk); - - /* Generate an index key from the top nColumn elements of the stack */ - sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0); - sqlite3IndexAffinityStr(v, pIdx); + buildIndexProbe(v, nColumn, brk, pIdx); sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 0); /* Generate code (1) to move to the first matching element of the table. @@ -890,30 +900,32 @@ WhereInfo *sqlite3WhereBegin( brk = pLevel->brk = sqlite3VdbeMakeLabel(v); cont = pLevel->cont = sqlite3VdbeMakeLabel(v); if( iDirectGt[i]>=0 ){ + Expr *pX; k = iDirectGt[i]; assert( kp!=0 ); + pX = pTerm->p; + assert( pX!=0 ); assert( pTerm->idxLeft==iCur ); - sqlite3ExprCode(pParse, pTerm->p->pRight); - sqlite3VdbeAddOp(v, OP_ForceInt, - pTerm->p->op==TK_LT || pTerm->p->op==TK_GT, brk); + sqlite3ExprCode(pParse, pX->pRight); + sqlite3VdbeAddOp(v, OP_ForceInt, pX->op==TK_LT || pX->op==TK_GT, brk); sqlite3VdbeAddOp(v, OP_MoveGe, iCur, brk); disableTerm(pLevel, &pTerm->p); }else{ sqlite3VdbeAddOp(v, OP_Rewind, iCur, brk); } if( iDirectLt[i]>=0 ){ + Expr *pX; k = iDirectLt[i]; assert( kp!=0 ); + pX = pTerm->p; + assert( pX!=0 ); assert( pTerm->idxLeft==iCur ); - sqlite3ExprCode(pParse, pTerm->p->pRight); - /* sqlite3VdbeAddOp(v, OP_MustBeInt, 0, sqlite3VdbeCurrentAddr(v)+1); */ + sqlite3ExprCode(pParse, pX->pRight); pLevel->iMem = pParse->nMem++; sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1); - if( pTerm->p->op==TK_LT || pTerm->p->op==TK_GT ){ + if( pX->op==TK_LT || pX->op==TK_GT ){ testOp = OP_Ge; }else{ testOp = OP_Gt; @@ -965,14 +977,16 @@ WhereInfo *sqlite3WhereBegin( /* Evaluate the equality constraints */ for(j=0; jaiColumn[j]; for(pTerm=aExpr, k=0; kp==0 ) continue; + Expr *pX = pTerm->p; + if( pX==0 ) continue; if( pTerm->idxLeft==iCur - && pTerm->p->op==TK_EQ + && pX->op==TK_EQ && (pTerm->prereqRight & loopMask)==pTerm->prereqRight - && pTerm->p->pLeft->iColumn==pIdx->aiColumn[j] + && pX->pLeft->iColumn==iIdxCol ){ - sqlite3ExprCode(pParse, pTerm->p->pRight); + sqlite3ExprCode(pParse, pX->pRight); disableTerm(pLevel, &pTerm->p); break; } @@ -1001,15 +1015,15 @@ WhereInfo *sqlite3WhereBegin( */ if( (score & 1)!=0 ){ for(pTerm=aExpr, k=0; kp; - if( pExpr==0 ) continue; + Expr *pX = pTerm->p; + if( pX==0 ) continue; if( pTerm->idxLeft==iCur - && (pExpr->op==TK_LT || pExpr->op==TK_LE) + && (pX->op==TK_LT || pX->op==TK_LE) && (pTerm->prereqRight & loopMask)==pTerm->prereqRight - && pExpr->pLeft->iColumn==pIdx->aiColumn[j] + && pX->pLeft->iColumn==pIdx->aiColumn[j] ){ - sqlite3ExprCode(pParse, pExpr->pRight); - leFlag = pExpr->op==TK_LE; + sqlite3ExprCode(pParse, pX->pRight); + leFlag = pX->op==TK_LE; disableTerm(pLevel, &pTerm->p); break; } @@ -1022,11 +1036,7 @@ WhereInfo *sqlite3WhereBegin( if( testOp!=OP_Noop ){ int nCol = nEqColumn + (score & 1); pLevel->iMem = pParse->nMem++; - sqlite3VdbeAddOp(v, OP_NotNull, -nCol, sqlite3VdbeCurrentAddr(v)+3); - sqlite3VdbeAddOp(v, OP_Pop, nCol, 0); - sqlite3VdbeAddOp(v, OP_Goto, 0, brk); - sqlite3VdbeAddOp(v, OP_MakeRecord, nCol, 0); - sqlite3IndexAffinityStr(v, pIdx); + buildIndexProbe(v, nCol, brk, pIdx); if( pLevel->bRev ){ int op = leFlag ? OP_MoveLe : OP_MoveLt; sqlite3VdbeAddOp(v, op, pLevel->iCur, brk); @@ -1048,15 +1058,15 @@ WhereInfo *sqlite3WhereBegin( */ if( (score & 2)!=0 ){ for(pTerm=aExpr, k=0; kp; - if( pExpr==0 ) continue; + Expr *pX = pTerm->p; + if( pX==0 ) continue; if( pTerm->idxLeft==iCur - && (pExpr->op==TK_GT || pExpr->op==TK_GE) + && (pX->op==TK_GT || pX->op==TK_GE) && (pTerm->prereqRight & loopMask)==pTerm->prereqRight - && pExpr->pLeft->iColumn==pIdx->aiColumn[j] + && pX->pLeft->iColumn==pIdx->aiColumn[j] ){ - sqlite3ExprCode(pParse, pExpr->pRight); - geFlag = pExpr->op==TK_GE; + sqlite3ExprCode(pParse, pX->pRight); + geFlag = pX->op==TK_GE; disableTerm(pLevel, &pTerm->p); break; } @@ -1066,11 +1076,7 @@ WhereInfo *sqlite3WhereBegin( } if( nEqColumn>0 || (score&2)!=0 ){ int nCol = nEqColumn + ((score&2)!=0); - sqlite3VdbeAddOp(v, OP_NotNull, -nCol, sqlite3VdbeCurrentAddr(v)+3); - sqlite3VdbeAddOp(v, OP_Pop, nCol, 0); - sqlite3VdbeAddOp(v, OP_Goto, 0, brk); - sqlite3VdbeAddOp(v, OP_MakeRecord, nCol, 0); - sqlite3IndexAffinityStr(v, pIdx); + buildIndexProbe(v, nCol, brk, pIdx); if( pLevel->bRev ){ pLevel->iMem = pParse->nMem++; sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);