diff options
author | Wez Furlong <wez@php.net> | 2003-06-04 22:40:00 +0000 |
---|---|---|
committer | Wez Furlong <wez@php.net> | 2003-06-04 22:40:00 +0000 |
commit | 80e7f7001d39add9010ba78be636245410b79c24 (patch) | |
tree | 23ae7f9f01ea9bb1add35b1ff85efa2421d05142 /ext/sqlite/libsqlite/src/where.c | |
parent | 82a1818fdec3afe8e3a5cc8aa7171f4472ea1e4a (diff) | |
download | php-git-80e7f7001d39add9010ba78be636245410b79c24.tar.gz |
Update bundled library to version 2.8.2.
Make OnUpdateInt compatible with ZE2.
Fix the makefile fragment for non-gnu makes
Diffstat (limited to 'ext/sqlite/libsqlite/src/where.c')
-rw-r--r-- | ext/sqlite/libsqlite/src/where.c | 200 |
1 files changed, 118 insertions, 82 deletions
diff --git a/ext/sqlite/libsqlite/src/where.c b/ext/sqlite/libsqlite/src/where.c index 682b33c79f..7f95dc78c3 100644 --- a/ext/sqlite/libsqlite/src/where.c +++ b/ext/sqlite/libsqlite/src/where.c @@ -10,8 +10,7 @@ ** ************************************************************************* ** This module contains C code that generates VDBE code used to process -** the WHERE clause of SQL statements. Also found here are subroutines -** to generate VDBE code to evaluate expressions. +** the WHERE clause of SQL statements. ** ** $Id$ */ @@ -38,6 +37,21 @@ struct ExprInfo { }; /* +** An instance of the following structure keeps track of a mapping +** between VDBE cursor numbers and bitmasks. The VDBE cursor numbers +** are small integers contained in SrcList_item.iCursor and Expr.iTable +** fields. For any given WHERE clause, we want to track which cursors +** are being used, so we assign a single bit in a 32-bit word to track +** that cursor. Then a 32-bit integer is able to show the set of all +** cursors being used. +*/ +typedef struct ExprMaskSet ExprMaskSet; +struct ExprMaskSet { + int n; /* Number of assigned cursor values */ + int ix[32]; /* Cursor assigned to each bit */ +}; + +/* ** Determine the number of elements in an array. */ #define ARRAYSIZE(X) (sizeof(X)/sizeof(X[0])) @@ -69,36 +83,60 @@ static int exprSplit(int nSlot, ExprInfo *aSlot, Expr *pExpr){ } /* +** Initialize an expression mask set +*/ +#define initMaskSet(P) memset(P, 0, sizeof(*P)) + +/* +** Return the bitmask for the given cursor. Assign a new bitmask +** if this is the first time the cursor has been seen. +*/ +static int getMask(ExprMaskSet *pMaskSet, int iCursor){ + int i; + for(i=0; i<pMaskSet->n; i++){ + if( pMaskSet->ix[i]==iCursor ) return 1<<i; + } + if( i==pMaskSet->n && i<ARRAYSIZE(pMaskSet->ix) ){ + pMaskSet->n++; + pMaskSet->ix[i] = iCursor; + return 1<<i; + } + return 0; +} + +/* +** Destroy an expression mask set +*/ +#define freeMaskSet(P) /* NO-OP */ + +/* ** This routine walks (recursively) an expression tree and generates ** a bitmask indicating which tables are used in that expression -** tree. Bit 0 of the mask is set if table base+0 is used. Bit 1 -** is set if table base+1 is used. And so forth. +** tree. ** ** In order for this routine to work, the calling function must have ** previously invoked sqliteExprResolveIds() on the expression. See ** the header comment on that routine for additional information. -** -** "base" is the cursor number (the value of the iTable field) that -** corresponds to the first entry in the list of tables that appear -** in the FROM clause of a SELECT. For UPDATE and DELETE statements -** there is just a single table with "base" as the cursor number. +** The sqliteExprResolveIds() routines looks for column names and +** sets their opcodes to TK_COLUMN and their Expr.iTable fields to +** the VDBE cursor number of the table. */ -static int exprTableUsage(int base, Expr *p){ +static int exprTableUsage(ExprMaskSet *pMaskSet, Expr *p){ unsigned int mask = 0; if( p==0 ) return 0; if( p->op==TK_COLUMN ){ - return 1<< (p->iTable - base); + return getMask(pMaskSet, p->iTable); } if( p->pRight ){ - mask = exprTableUsage(base, p->pRight); + mask = exprTableUsage(pMaskSet, p->pRight); } if( p->pLeft ){ - mask |= exprTableUsage(base, p->pLeft); + mask |= exprTableUsage(pMaskSet, p->pLeft); } if( p->pList ){ int i; for(i=0; i<p->pList->nExpr; i++){ - mask |= exprTableUsage(base, p->pList->a[i].pExpr); + mask |= exprTableUsage(pMaskSet, p->pList->a[i].pExpr); } } return mask; @@ -128,25 +166,22 @@ static int allowedOp(int op){ ** "p" field filled in. The job of this routine is to analyze the ** subexpression and populate all the other fields of the ExprInfo ** structure. -** -** "base" is the cursor number (the value of the iTable field) that -** corresponds to the first entry in the table list. */ -static void exprAnalyze(int base, ExprInfo *pInfo){ +static void exprAnalyze(ExprMaskSet *pMaskSet, ExprInfo *pInfo){ Expr *pExpr = pInfo->p; - pInfo->prereqLeft = exprTableUsage(base, pExpr->pLeft); - pInfo->prereqRight = exprTableUsage(base, pExpr->pRight); - pInfo->prereqAll = exprTableUsage(base, pExpr); + pInfo->prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft); + pInfo->prereqRight = exprTableUsage(pMaskSet, pExpr->pRight); + pInfo->prereqAll = exprTableUsage(pMaskSet, pExpr); pInfo->indexable = 0; pInfo->idxLeft = -1; pInfo->idxRight = -1; if( allowedOp(pExpr->op) && (pInfo->prereqRight & pInfo->prereqLeft)==0 ){ if( pExpr->pRight && pExpr->pRight->op==TK_COLUMN ){ - pInfo->idxRight = pExpr->pRight->iTable - base; + pInfo->idxRight = pExpr->pRight->iTable; pInfo->indexable = 1; } if( pExpr->pLeft->op==TK_COLUMN ){ - pInfo->idxLeft = pExpr->pLeft->iTable - base; + pInfo->idxLeft = pExpr->pLeft->iTable; pInfo->indexable = 1; } } @@ -263,9 +298,9 @@ static Index *findSortingIndex( ** end / ** ** There are Btree cursors associated with each table. t1 uses cursor -** "base". t2 uses cursor "base+1". And so forth. This routine generates -** the code to open those cursors. sqliteWhereEnd() generates the code -** to close them. +** number pTabList->a[0].iCursor. t2 uses the cursor pTabList->a[1].iCursor. +** And so forth. This routine generates code to open those VDBE cursors +** and sqliteWhereEnd() generates the code to close them. ** ** If the WHERE clause is empty, the foreach loops must each scan their ** entire tables. Thus a three-way join is an O(N^3) operation. But if @@ -315,7 +350,6 @@ static Index *findSortingIndex( */ WhereInfo *sqliteWhereBegin( Parse *pParse, /* The parser context */ - int base, /* VDBE cursor index for left-most table in pTabList */ SrcList *pTabList, /* A list of all tables to be scanned */ Expr *pWhere, /* The WHERE clause */ int pushKey, /* If TRUE, leave the table key on the stack */ @@ -328,6 +362,7 @@ WhereInfo *sqliteWhereBegin( int nExpr; /* Number of subexpressions in the WHERE clause */ int loopMask; /* One bit set for each outer loop */ int haveKey; /* True if KEY is on the stack */ + ExprMaskSet maskSet; /* The expression mask set */ int iDirectEq[32]; /* Term of the form ROWID==X for the N-th table */ int iDirectLt[32]; /* Term of the form ROWID<X or ROWID<=X */ int iDirectGt[32]; /* Term of the form ROWID>X or ROWID>=X */ @@ -343,6 +378,7 @@ WhereInfo *sqliteWhereBegin( ** array fills up, the last entry might point to an expression which ** contains additional unfactored AND operators. */ + initMaskSet(&maskSet); memset(aExpr, 0, sizeof(aExpr)); nExpr = exprSplit(ARRAYSIZE(aExpr), aExpr, pWhere); if( nExpr==ARRAYSIZE(aExpr) ){ @@ -364,14 +400,13 @@ WhereInfo *sqliteWhereBegin( } pWInfo->pParse = pParse; pWInfo->pTabList = pTabList; - pWInfo->base = base; pWInfo->peakNTab = pWInfo->savedNTab = pParse->nTab; pWInfo->iBreak = sqliteVdbeMakeLabel(v); /* Special case: a WHERE clause that is constant. Evaluate the ** expression and either jump over all of the code or fall thru. */ - if( pWhere && sqliteExprIsConstant(pWhere) ){ + if( pWhere && (pTabList->nSrc==0 || sqliteExprIsConstant(pWhere)) ){ sqliteExprIfFalse(pParse, pWhere, pWInfo->iBreak, 1); pWhere = 0; } @@ -379,7 +414,7 @@ WhereInfo *sqliteWhereBegin( /* Analyze all of the subexpressions. */ for(i=0; i<nExpr; i++){ - exprAnalyze(base, &aExpr[i]); + exprAnalyze(&maskSet, &aExpr[i]); /* If we are executing a trigger body, remove all references to ** new.* and old.* tables from the prerequisite masks. @@ -387,13 +422,13 @@ WhereInfo *sqliteWhereBegin( if( pParse->trigStack ){ int x; if( (x = pParse->trigStack->newIdx) >= 0 ){ - int mask = ~(1 << (x - base)); + int mask = ~getMask(&maskSet, x); aExpr[i].prereqRight &= mask; aExpr[i].prereqLeft &= mask; aExpr[i].prereqAll &= mask; } if( (x = pParse->trigStack->oldIdx) >= 0 ){ - int mask = ~(1 << (x - base)); + int mask = ~getMask(&maskSet, x); aExpr[i].prereqRight &= mask; aExpr[i].prereqLeft &= mask; aExpr[i].prereqAll &= mask; @@ -420,8 +455,9 @@ WhereInfo *sqliteWhereBegin( loopMask = 0; for(i=0; i<pTabList->nSrc && i<ARRAYSIZE(iDirectEq); i++){ int j; - int idx = i; - Table *pTab = pTabList->a[idx].pTab; + 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; Index *pIdx; Index *pBestIdx = 0; int bestScore = 0; @@ -439,7 +475,7 @@ WhereInfo *sqliteWhereBegin( iDirectLt[i] = -1; iDirectGt[i] = -1; for(j=0; j<nExpr; j++){ - if( aExpr[j].idxLeft==idx && aExpr[j].p->pLeft->iColumn<0 + if( aExpr[j].idxLeft==iCur && aExpr[j].p->pLeft->iColumn<0 && (aExpr[j].prereqRight & loopMask)==aExpr[j].prereqRight ){ switch( aExpr[j].p->op ){ case TK_IN: @@ -450,7 +486,7 @@ WhereInfo *sqliteWhereBegin( case TK_GT: iDirectGt[i] = j; break; } } - if( aExpr[j].idxRight==idx && aExpr[j].p->pRight->iColumn<0 + if( aExpr[j].idxRight==iCur && aExpr[j].p->pRight->iColumn<0 && (aExpr[j].prereqLeft & loopMask)==aExpr[j].prereqLeft ){ switch( aExpr[j].p->op ){ case TK_EQ: iDirectEq[i] = j; break; @@ -462,7 +498,7 @@ WhereInfo *sqliteWhereBegin( } } if( iDirectEq[i]>=0 ){ - loopMask |= 1<<idx; + loopMask |= mask; pWInfo->a[i].pIdx = 0; continue; } @@ -501,7 +537,7 @@ WhereInfo *sqliteWhereBegin( if( pIdx->nColumn>32 ) continue; /* Ignore indices too many columns */ for(j=0; j<nExpr; j++){ - if( aExpr[j].idxLeft==idx + if( aExpr[j].idxLeft==iCur && (aExpr[j].prereqRight & loopMask)==aExpr[j].prereqRight ){ int iColumn = aExpr[j].p->pLeft->iColumn; int k; @@ -536,7 +572,7 @@ WhereInfo *sqliteWhereBegin( } } } - if( aExpr[j].idxRight==idx + if( aExpr[j].idxRight==iCur && (aExpr[j].prereqLeft & loopMask)==aExpr[j].prereqLeft ){ int iColumn = aExpr[j].p->pRight->iColumn; int k; @@ -589,7 +625,7 @@ WhereInfo *sqliteWhereBegin( pWInfo->a[i].pIdx = pBestIdx; pWInfo->a[i].score = bestScore; pWInfo->a[i].bRev = 0; - loopMask |= 1<<idx; + loopMask |= mask; if( pBestIdx ){ pWInfo->a[i].iCur = pParse->nTab++; pWInfo->peakNTab = pParse->nTab; @@ -620,7 +656,8 @@ WhereInfo *sqliteWhereBegin( pSortIdx = 0; }else{ int nEqCol = (pWInfo->a[0].score+4)/8; - pSortIdx = findSortingIndex(pTab, base, *ppOrderBy, pIdx, nEqCol, &bRev); + pSortIdx = findSortingIndex(pTab, pTabList->a[0].iCursor, + *ppOrderBy, pIdx, nEqCol, &bRev); } if( pSortIdx && (pIdx==0 || pIdx==pSortIdx) ){ if( pIdx==0 ){ @@ -636,21 +673,18 @@ WhereInfo *sqliteWhereBegin( /* Open all tables in the pTabList and all indices used by those tables. */ for(i=0; i<pTabList->nSrc; i++){ - int openOp; Table *pTab; pTab = pTabList->a[i].pTab; if( pTab->isTransient || pTab->pSelect ) continue; - openOp = pTab->isTemp ? OP_OpenAux : OP_Open; - sqliteVdbeAddOp(v, openOp, base+i, pTab->tnum); + sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0); + sqliteVdbeAddOp(v, OP_OpenRead, pTabList->a[i].iCursor, pTab->tnum); sqliteVdbeChangeP3(v, -1, pTab->zName, P3_STATIC); - if( i==0 && !pParse->schemaVerified && - (pParse->db->flags & SQLITE_InTrans)==0 ){ - sqliteVdbeAddOp(v, OP_VerifyCookie, pParse->db->schema_cookie, 0); - pParse->schemaVerified = 1; - } + sqliteCodeVerifySchema(pParse, pTab->iDb); if( pWInfo->a[i].pIdx!=0 ){ - sqliteVdbeAddOp(v, openOp, pWInfo->a[i].iCur, pWInfo->a[i].pIdx->tnum); + sqliteVdbeAddOp(v, OP_Integer, pWInfo->a[i].pIdx->iDb, 0); + sqliteVdbeAddOp(v, OP_OpenRead, + pWInfo->a[i].iCur, pWInfo->a[i].pIdx->tnum); sqliteVdbeChangeP3(v, -1, pWInfo->a[i].pIdx->zName, P3_STATIC); } } @@ -660,7 +694,7 @@ WhereInfo *sqliteWhereBegin( loopMask = 0; for(i=0; i<pTabList->nSrc; i++){ int j, k; - int idx = i; + int iCur = pTabList->a[i].iCursor; Index *pIdx; WhereLevel *pLevel = &pWInfo->a[i]; @@ -686,9 +720,9 @@ WhereInfo *sqliteWhereBegin( k = iDirectEq[i]; assert( k<nExpr ); assert( aExpr[k].p!=0 ); - assert( aExpr[k].idxLeft==idx || aExpr[k].idxRight==idx ); + assert( aExpr[k].idxLeft==iCur || aExpr[k].idxRight==iCur ); brk = pLevel->brk = sqliteVdbeMakeLabel(v); - if( aExpr[k].idxLeft==idx ){ + if( aExpr[k].idxLeft==iCur ){ Expr *pX = aExpr[k].p; if( pX->op!=TK_IN ){ sqliteExprCode(pParse, aExpr[k].p->pRight); @@ -712,7 +746,7 @@ WhereInfo *sqliteWhereBegin( cont = pLevel->cont = sqliteVdbeMakeLabel(v); sqliteVdbeAddOp(v, OP_MustBeInt, 1, brk); haveKey = 0; - sqliteVdbeAddOp(v, OP_NotExists, base+idx, brk); + sqliteVdbeAddOp(v, OP_NotExists, iCur, brk); pLevel->op = OP_Noop; }else if( pIdx!=0 && pLevel->score>0 && pLevel->score%4==0 ){ /* Case 2: There is an index and all terms of the WHERE clause that @@ -726,7 +760,7 @@ WhereInfo *sqliteWhereBegin( for(k=0; k<nExpr; k++){ Expr *pX = aExpr[k].p; if( pX==0 ) continue; - if( aExpr[k].idxLeft==idx + if( aExpr[k].idxLeft==iCur && (aExpr[k].prereqRight & loopMask)==aExpr[k].prereqRight && pX->pLeft->iColumn==pIdx->aiColumn[j] ){ @@ -753,7 +787,7 @@ WhereInfo *sqliteWhereBegin( break; } } - if( aExpr[k].idxRight==idx + if( aExpr[k].idxRight==iCur && aExpr[k].p->op==TK_EQ && (aExpr[k].prereqLeft & loopMask)==aExpr[k].prereqLeft && aExpr[k].p->pRight->iColumn==pIdx->aiColumn[j] @@ -796,7 +830,7 @@ WhereInfo *sqliteWhereBegin( if( i==pTabList->nSrc-1 && pushKey ){ haveKey = 1; }else{ - sqliteVdbeAddOp(v, OP_MoveTo, base+idx, 0); + sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0); haveKey = 0; } pLevel->p1 = pLevel->iCur; @@ -813,8 +847,8 @@ WhereInfo *sqliteWhereBegin( k = iDirectGt[i]; assert( k<nExpr ); assert( aExpr[k].p!=0 ); - assert( aExpr[k].idxLeft==idx || aExpr[k].idxRight==idx ); - if( aExpr[k].idxLeft==idx ){ + assert( aExpr[k].idxLeft==iCur || aExpr[k].idxRight==iCur ); + if( aExpr[k].idxLeft==iCur ){ sqliteExprCode(pParse, aExpr[k].p->pRight); }else{ sqliteExprCode(pParse, aExpr[k].p->pLeft); @@ -823,17 +857,17 @@ WhereInfo *sqliteWhereBegin( if( aExpr[k].p->op==TK_LT || aExpr[k].p->op==TK_GT ){ sqliteVdbeAddOp(v, OP_AddImm, 1, 0); } - sqliteVdbeAddOp(v, OP_MoveTo, base+idx, brk); + sqliteVdbeAddOp(v, OP_MoveTo, iCur, brk); aExpr[k].p = 0; }else{ - sqliteVdbeAddOp(v, OP_Rewind, base+idx, brk); + sqliteVdbeAddOp(v, OP_Rewind, iCur, brk); } if( iDirectLt[i]>=0 ){ k = iDirectLt[i]; assert( k<nExpr ); assert( aExpr[k].p!=0 ); - assert( aExpr[k].idxLeft==idx || aExpr[k].idxRight==idx ); - if( aExpr[k].idxLeft==idx ){ + assert( aExpr[k].idxLeft==iCur || aExpr[k].idxRight==iCur ); + if( aExpr[k].idxLeft==iCur ){ sqliteExprCode(pParse, aExpr[k].p->pRight); }else{ sqliteExprCode(pParse, aExpr[k].p->pLeft); @@ -850,10 +884,10 @@ WhereInfo *sqliteWhereBegin( } start = sqliteVdbeCurrentAddr(v); pLevel->op = OP_Next; - pLevel->p1 = base+idx; + pLevel->p1 = iCur; pLevel->p2 = start; if( testOp!=OP_Noop ){ - sqliteVdbeAddOp(v, OP_Recno, base+idx, 0); + sqliteVdbeAddOp(v, OP_Recno, iCur, 0); sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0); sqliteVdbeAddOp(v, testOp, 0, brk); } @@ -866,10 +900,10 @@ WhereInfo *sqliteWhereBegin( brk = pLevel->brk = sqliteVdbeMakeLabel(v); cont = pLevel->cont = sqliteVdbeMakeLabel(v); - sqliteVdbeAddOp(v, OP_Rewind, base+idx, brk); + sqliteVdbeAddOp(v, OP_Rewind, iCur, brk); start = sqliteVdbeCurrentAddr(v); pLevel->op = OP_Next; - pLevel->p1 = base+idx; + pLevel->p1 = iCur; pLevel->p2 = start; haveKey = 0; }else{ @@ -895,7 +929,7 @@ WhereInfo *sqliteWhereBegin( for(j=0; j<nEqColumn; j++){ for(k=0; k<nExpr; k++){ if( aExpr[k].p==0 ) continue; - if( aExpr[k].idxLeft==idx + if( aExpr[k].idxLeft==iCur && aExpr[k].p->op==TK_EQ && (aExpr[k].prereqRight & loopMask)==aExpr[k].prereqRight && aExpr[k].p->pLeft->iColumn==pIdx->aiColumn[j] @@ -904,7 +938,7 @@ WhereInfo *sqliteWhereBegin( aExpr[k].p = 0; break; } - if( aExpr[k].idxRight==idx + if( aExpr[k].idxRight==iCur && aExpr[k].p->op==TK_EQ && (aExpr[k].prereqLeft & loopMask)==aExpr[k].prereqLeft && aExpr[k].p->pRight->iColumn==pIdx->aiColumn[j] @@ -940,7 +974,7 @@ WhereInfo *sqliteWhereBegin( for(k=0; k<nExpr; k++){ Expr *pExpr = aExpr[k].p; if( pExpr==0 ) continue; - if( aExpr[k].idxLeft==idx + if( aExpr[k].idxLeft==iCur && (pExpr->op==TK_LT || pExpr->op==TK_LE) && (aExpr[k].prereqRight & loopMask)==aExpr[k].prereqRight && pExpr->pLeft->iColumn==pIdx->aiColumn[j] @@ -950,7 +984,7 @@ WhereInfo *sqliteWhereBegin( aExpr[k].p = 0; break; } - if( aExpr[k].idxRight==idx + if( aExpr[k].idxRight==iCur && (pExpr->op==TK_GT || pExpr->op==TK_GE) && (aExpr[k].prereqLeft & loopMask)==aExpr[k].prereqLeft && pExpr->pRight->iColumn==pIdx->aiColumn[j] @@ -995,7 +1029,7 @@ WhereInfo *sqliteWhereBegin( for(k=0; k<nExpr; k++){ Expr *pExpr = aExpr[k].p; if( pExpr==0 ) continue; - if( aExpr[k].idxLeft==idx + if( aExpr[k].idxLeft==iCur && (pExpr->op==TK_GT || pExpr->op==TK_GE) && (aExpr[k].prereqRight & loopMask)==aExpr[k].prereqRight && pExpr->pLeft->iColumn==pIdx->aiColumn[j] @@ -1005,7 +1039,7 @@ WhereInfo *sqliteWhereBegin( aExpr[k].p = 0; break; } - if( aExpr[k].idxRight==idx + if( aExpr[k].idxRight==iCur && (pExpr->op==TK_LT || pExpr->op==TK_LE) && (aExpr[k].prereqLeft & loopMask)==aExpr[k].prereqLeft && pExpr->pRight->iColumn==pIdx->aiColumn[j] @@ -1051,7 +1085,7 @@ WhereInfo *sqliteWhereBegin( if( i==pTabList->nSrc-1 && pushKey ){ haveKey = 1; }else{ - sqliteVdbeAddOp(v, OP_MoveTo, base+idx, 0); + sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0); haveKey = 0; } @@ -1061,7 +1095,7 @@ WhereInfo *sqliteWhereBegin( pLevel->p1 = pLevel->iCur; pLevel->p2 = start; } - loopMask |= 1<<idx; + loopMask |= getMask(&maskSet, iCur); /* Insert code to test every subexpression that can be completely ** computed using the current set of tables. @@ -1074,7 +1108,7 @@ WhereInfo *sqliteWhereBegin( } if( haveKey ){ haveKey = 0; - sqliteVdbeAddOp(v, OP_MoveTo, base+idx, 0); + sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0); } sqliteExprIfFalse(pParse, aExpr[j].p, cont, 1); aExpr[j].p = 0; @@ -1097,7 +1131,7 @@ WhereInfo *sqliteWhereBegin( ** no outer joins with DELETE and UPDATE. */ haveKey = 0; - sqliteVdbeAddOp(v, OP_MoveTo, base+idx, 0); + sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0); } sqliteExprIfFalse(pParse, aExpr[j].p, cont, 1); aExpr[j].p = 0; @@ -1106,8 +1140,9 @@ WhereInfo *sqliteWhereBegin( } pWInfo->iContinue = cont; if( pushKey && !haveKey ){ - sqliteVdbeAddOp(v, OP_Recno, base, 0); + sqliteVdbeAddOp(v, OP_Recno, pTabList->a[0].iCursor, 0); } + freeMaskSet(&maskSet); return pWInfo; } @@ -1118,7 +1153,6 @@ WhereInfo *sqliteWhereBegin( void sqliteWhereEnd(WhereInfo *pWInfo){ Vdbe *v = pWInfo->pParse->pVdbe; int i; - int base = pWInfo->base; WhereLevel *pLevel; SrcList *pTabList = pWInfo->pTabList; @@ -1136,7 +1170,7 @@ void sqliteWhereEnd(WhereInfo *pWInfo){ int addr; addr = sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iLeftJoin, 0); sqliteVdbeAddOp(v, OP_NotNull, 1, addr+4 + (pLevel->iCur>=0)); - sqliteVdbeAddOp(v, OP_NullRow, base+i, 0); + sqliteVdbeAddOp(v, OP_NullRow, pTabList->a[i].iCursor, 0); if( pLevel->iCur>=0 ){ sqliteVdbeAddOp(v, OP_NullRow, pLevel->iCur, 0); } @@ -1145,9 +1179,11 @@ void sqliteWhereEnd(WhereInfo *pWInfo){ } sqliteVdbeResolveLabel(v, pWInfo->iBreak); for(i=0; i<pTabList->nSrc; i++){ - if( pTabList->a[i].pTab->isTransient ) continue; + Table *pTab = pTabList->a[i].pTab; + assert( pTab!=0 ); + if( pTab->isTransient || pTab->pSelect ) continue; pLevel = &pWInfo->a[i]; - sqliteVdbeAddOp(v, OP_Close, base+i, 0); + sqliteVdbeAddOp(v, OP_Close, pTabList->a[i].iCursor, 0); if( pLevel->pIdx!=0 ){ sqliteVdbeAddOp(v, OP_Close, pLevel->iCur, 0); } |