summaryrefslogtreecommitdiff
path: root/ext/sqlite/libsqlite/src/where.c
diff options
context:
space:
mode:
authorWez Furlong <wez@php.net>2003-06-04 22:40:00 +0000
committerWez Furlong <wez@php.net>2003-06-04 22:40:00 +0000
commit80e7f7001d39add9010ba78be636245410b79c24 (patch)
tree23ae7f9f01ea9bb1add35b1ff85efa2421d05142 /ext/sqlite/libsqlite/src/where.c
parent82a1818fdec3afe8e3a5cc8aa7171f4472ea1e4a (diff)
downloadphp-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.c200
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);
}