sync up our in tree sqlite with the 3.3.13 official release. Commit to follow to finish this process on the windows build.

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@4351 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Michael Jerris
2007-02-22 22:09:42 +00:00
parent 64133ab31a
commit 5791353cec
118 changed files with 15152 additions and 1229 deletions

View File

@@ -16,7 +16,7 @@
** so is applicable. Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
**
** $Id: where.c,v 1.228 2006/06/27 13:20:22 drh Exp $
** $Id: where.c,v 1.237 2007/02/06 13:26:33 drh Exp $
*/
#include "sqliteInt.h"
@@ -43,6 +43,7 @@ int sqlite3_where_trace = 0;
/* Forward reference
*/
typedef struct WhereClause WhereClause;
typedef struct ExprMaskSet ExprMaskSet;
/*
** The query generator uses an array of instances of this structure to
@@ -106,6 +107,7 @@ struct WhereTerm {
*/
struct WhereClause {
Parse *pParse; /* The parser context */
ExprMaskSet *pMaskSet; /* Mapping of table indices to bitmasks */
int nTerm; /* Number of terms */
int nSlot; /* Number of entries in a[] */
WhereTerm *a; /* Each a[] describes a term of the WHERE cluase */
@@ -138,7 +140,6 @@ struct WhereClause {
** numbers all get mapped into bit numbers that begin with 0 and contain
** no gaps.
*/
typedef struct ExprMaskSet ExprMaskSet;
struct ExprMaskSet {
int n; /* Number of assigned cursor values */
int ix[sizeof(Bitmask)*8]; /* Cursor assigned to each bit */
@@ -157,28 +158,42 @@ struct ExprMaskSet {
#define WO_GT (WO_EQ<<(TK_GT-TK_EQ))
#define WO_GE (WO_EQ<<(TK_GE-TK_EQ))
#define WO_MATCH 64
#define WO_ISNULL 128
/*
** Value for flags returned by bestIndex()
** Value for flags returned by bestIndex().
**
** The least significant byte is reserved as a mask for WO_ values above.
** The WhereLevel.flags field is usually set to WO_IN|WO_EQ|WO_ISNULL.
** But if the table is the right table of a left join, WhereLevel.flags
** is set to WO_IN|WO_EQ. The WhereLevel.flags field can then be used as
** the "op" parameter to findTerm when we are resolving equality constraints.
** ISNULL constraints will then not be used on the right table of a left
** join. Tickets #2177 and #2189.
*/
#define WHERE_ROWID_EQ 0x0001 /* rowid=EXPR or rowid IN (...) */
#define WHERE_ROWID_RANGE 0x0002 /* rowid<EXPR and/or rowid>EXPR */
#define WHERE_COLUMN_EQ 0x0010 /* x=EXPR or x IN (...) */
#define WHERE_COLUMN_RANGE 0x0020 /* x<EXPR and/or x>EXPR */
#define WHERE_COLUMN_IN 0x0040 /* x IN (...) */
#define WHERE_TOP_LIMIT 0x0100 /* x<EXPR or x<=EXPR constraint */
#define WHERE_BTM_LIMIT 0x0200 /* x>EXPR or x>=EXPR constraint */
#define WHERE_IDX_ONLY 0x0800 /* Use index only - omit table */
#define WHERE_ORDERBY 0x1000 /* Output will appear in correct order */
#define WHERE_REVERSE 0x2000 /* Scan in reverse order */
#define WHERE_UNIQUE 0x4000 /* Selects no more than one row */
#define WHERE_VIRTUALTABLE 0x8000 /* Use virtual-table processing */
#define WHERE_ROWID_EQ 0x000100 /* rowid=EXPR or rowid IN (...) */
#define WHERE_ROWID_RANGE 0x000200 /* rowid<EXPR and/or rowid>EXPR */
#define WHERE_COLUMN_EQ 0x001000 /* x=EXPR or x IN (...) */
#define WHERE_COLUMN_RANGE 0x002000 /* x<EXPR and/or x>EXPR */
#define WHERE_COLUMN_IN 0x004000 /* x IN (...) */
#define WHERE_TOP_LIMIT 0x010000 /* x<EXPR or x<=EXPR constraint */
#define WHERE_BTM_LIMIT 0x020000 /* x>EXPR or x>=EXPR constraint */
#define WHERE_IDX_ONLY 0x080000 /* Use index only - omit table */
#define WHERE_ORDERBY 0x100000 /* Output will appear in correct order */
#define WHERE_REVERSE 0x200000 /* Scan in reverse order */
#define WHERE_UNIQUE 0x400000 /* Selects no more than one row */
#define WHERE_VIRTUALTABLE 0x800000 /* Use virtual-table processing */
/*
** Initialize a preallocated WhereClause structure.
*/
static void whereClauseInit(WhereClause *pWC, Parse *pParse){
static void whereClauseInit(
WhereClause *pWC, /* The WhereClause to be initialized */
Parse *pParse, /* The parsing context */
ExprMaskSet *pMaskSet /* Mapping from table indices to bitmasks */
){
pWC->pParse = pParse;
pWC->pMaskSet = pMaskSet;
pWC->nTerm = 0;
pWC->nSlot = ARRAYSIZE(pWC->aStatic);
pWC->a = pWC->aStatic;
@@ -354,7 +369,7 @@ static int allowedOp(int op){
assert( TK_LT>TK_EQ && TK_LT<TK_GE );
assert( TK_LE>TK_EQ && TK_LE<TK_GE );
assert( TK_GE==TK_EQ+4 );
return op==TK_IN || (op>=TK_EQ && op<=TK_GE);
return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL;
}
/*
@@ -388,9 +403,12 @@ static int operatorMask(int op){
assert( allowedOp(op) );
if( op==TK_IN ){
c = WO_IN;
}else if( op==TK_ISNULL ){
c = WO_ISNULL;
}else{
c = WO_EQ<<(op-TK_EQ);
}
assert( op!=TK_ISNULL || c==WO_ISNULL );
assert( op!=TK_IN || c==WO_IN );
assert( op!=TK_EQ || c==WO_EQ );
assert( op!=TK_LT || c==WO_LT );
@@ -422,7 +440,7 @@ static WhereTerm *findTerm(
&& pTerm->leftColumn==iColumn
&& (pTerm->eOperator & op)!=0
){
if( iCur>=0 && pIdx ){
if( iCur>=0 && pIdx && pTerm->eOperator!=WO_ISNULL ){
Expr *pX = pTerm->pExpr;
CollSeq *pColl;
char idxaff;
@@ -451,7 +469,7 @@ static WhereTerm *findTerm(
}
/* Forward reference */
static void exprAnalyze(SrcList*, ExprMaskSet*, WhereClause*, int);
static void exprAnalyze(SrcList*, WhereClause*, int);
/*
** Call exprAnalyze on all terms in a WHERE clause.
@@ -460,12 +478,11 @@ static void exprAnalyze(SrcList*, ExprMaskSet*, WhereClause*, int);
*/
static void exprAnalyzeAll(
SrcList *pTabList, /* the FROM clause */
ExprMaskSet *pMaskSet, /* table masks */
WhereClause *pWC /* the WHERE clause to be analyzed */
){
int i;
for(i=pWC->nTerm-1; i>=0; i--){
exprAnalyze(pTabList, pMaskSet, pWC, i);
exprAnalyze(pTabList, pWC, i);
}
}
@@ -580,23 +597,27 @@ static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
*/
static void exprAnalyze(
SrcList *pSrc, /* the FROM clause */
ExprMaskSet *pMaskSet, /* table masks */
WhereClause *pWC, /* the WHERE clause */
int idxTerm /* Index of the term to be analyzed */
){
WhereTerm *pTerm = &pWC->a[idxTerm];
ExprMaskSet *pMaskSet = pWC->pMaskSet;
Expr *pExpr = pTerm->pExpr;
Bitmask prereqLeft;
Bitmask prereqAll;
int nPattern;
int isComplete;
int op;
if( sqlite3MallocFailed() ) return;
prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
if( pExpr->op==TK_IN ){
op = pExpr->op;
if( op==TK_IN ){
assert( pExpr->pRight==0 );
pTerm->prereqRight = exprListTableUsage(pMaskSet, pExpr->pList)
| exprSelectTableUsage(pMaskSet, pExpr->pSelect);
}else if( op==TK_ISNULL ){
pTerm->prereqRight = 0;
}else{
pTerm->prereqRight = exprTableUsage(pMaskSet, pExpr->pRight);
}
@@ -608,13 +629,13 @@ static void exprAnalyze(
pTerm->leftCursor = -1;
pTerm->iParent = -1;
pTerm->eOperator = 0;
if( allowedOp(pExpr->op) && (pTerm->prereqRight & prereqLeft)==0 ){
if( allowedOp(op) && (pTerm->prereqRight & prereqLeft)==0 ){
Expr *pLeft = pExpr->pLeft;
Expr *pRight = pExpr->pRight;
if( pLeft->op==TK_COLUMN ){
pTerm->leftCursor = pLeft->iTable;
pTerm->leftColumn = pLeft->iColumn;
pTerm->eOperator = operatorMask(pExpr->op);
pTerm->eOperator = operatorMask(op);
}
if( pRight && pRight->op==TK_COLUMN ){
WhereTerm *pNew;
@@ -622,6 +643,10 @@ static void exprAnalyze(
if( pTerm->leftCursor>=0 ){
int idxNew;
pDup = sqlite3ExprDup(pExpr);
if( sqlite3MallocFailed() ){
sqliteFree(pDup);
return;
}
idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
if( idxNew==0 ) return;
pNew = &pWC->a[idxNew];
@@ -659,7 +684,7 @@ static void exprAnalyze(
pNewExpr = sqlite3Expr(ops[i], sqlite3ExprDup(pExpr->pLeft),
sqlite3ExprDup(pList->a[i].pExpr), 0);
idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
exprAnalyze(pSrc, pMaskSet, pWC, idxNew);
exprAnalyze(pSrc, pWC, idxNew);
pTerm = &pWC->a[idxTerm];
pWC->a[idxNew].iParent = idxTerm;
}
@@ -688,9 +713,9 @@ static void exprAnalyze(
WhereTerm *pOrTerm;
assert( (pTerm->flags & TERM_DYNAMIC)==0 );
whereClauseInit(&sOr, pWC->pParse);
whereClauseInit(&sOr, pWC->pParse, pMaskSet);
whereSplit(&sOr, pExpr, TK_OR);
exprAnalyzeAll(pSrc, pMaskSet, &sOr);
exprAnalyzeAll(pSrc, &sOr);
assert( sOr.nTerm>0 );
j = 0;
do{
@@ -715,23 +740,22 @@ static void exprAnalyze(
if( ok ){
ExprList *pList = 0;
Expr *pNew, *pDup;
Expr *pLeft = 0;
for(i=sOr.nTerm-1, pOrTerm=sOr.a; i>=0 && ok; i--, pOrTerm++){
if( (pOrTerm->flags & TERM_OR_OK)==0 ) continue;
pDup = sqlite3ExprDup(pOrTerm->pExpr->pRight);
pList = sqlite3ExprListAppend(pList, pDup, 0);
pLeft = pOrTerm->pExpr->pLeft;
}
pDup = sqlite3Expr(TK_COLUMN, 0, 0, 0);
if( pDup ){
pDup->iTable = iCursor;
pDup->iColumn = iColumn;
}
assert( pLeft!=0 );
pDup = sqlite3ExprDup(pLeft);
pNew = sqlite3Expr(TK_IN, pDup, 0, 0);
if( pNew ){
int idxNew;
transferJoinMarkings(pNew, pExpr);
pNew->pList = pList;
idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
exprAnalyze(pSrc, pMaskSet, pWC, idxNew);
exprAnalyze(pSrc, pWC, idxNew);
pTerm = &pWC->a[idxTerm];
pWC->a[idxNew].iParent = idxTerm;
pTerm->nChild = 1;
@@ -768,10 +792,10 @@ or_not_possible:
}
pNewExpr1 = sqlite3Expr(TK_GE, sqlite3ExprDup(pLeft), pStr1, 0);
idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
exprAnalyze(pSrc, pMaskSet, pWC, idxNew1);
exprAnalyze(pSrc, pWC, idxNew1);
pNewExpr2 = sqlite3Expr(TK_LT, sqlite3ExprDup(pLeft), pStr2, 0);
idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
exprAnalyze(pSrc, pMaskSet, pWC, idxNew2);
exprAnalyze(pSrc, pWC, idxNew2);
pTerm = &pWC->a[idxTerm];
if( isComplete ){
pWC->a[idxNew1].iParent = idxTerm;
@@ -817,6 +841,25 @@ or_not_possible:
#endif /* SQLITE_OMIT_VIRTUALTABLE */
}
/*
** Return TRUE if any of the expressions in pList->a[iFirst...] contain
** a reference to any table other than the iBase table.
*/
static int referencesOtherTables(
ExprList *pList, /* Search expressions in ths list */
ExprMaskSet *pMaskSet, /* Mapping from tables to bitmaps */
int iFirst, /* Be searching with the iFirst-th expression */
int iBase /* Ignore references to this table */
){
Bitmask allowed = ~getMask(pMaskSet, iBase);
while( iFirst<pList->nExpr ){
if( (exprTableUsage(pMaskSet, pList->a[iFirst++].pExpr)&allowed)!=0 ){
return 1;
}
}
return 0;
}
/*
** This routine decides if pIdx can be used to satisfy the ORDER BY
@@ -839,6 +882,7 @@ or_not_possible:
*/
static int isSortingIndex(
Parse *pParse, /* Parsing context */
ExprMaskSet *pMaskSet, /* Mapping from table indices to bitmaps */
Index *pIdx, /* The index we are testing */
int base, /* Cursor number for the table to be sorted */
ExprList *pOrderBy, /* The ORDER BY clause */
@@ -857,22 +901,43 @@ static int isSortingIndex(
/* Match terms of the ORDER BY clause against columns of
** the index.
**
** Note that indices have pIdx->nColumn regular columns plus
** one additional column containing the rowid. The rowid column
** of the index is also allowed to match against the ORDER BY
** clause.
*/
for(i=j=0, pTerm=pOrderBy->a; j<nTerm && i<pIdx->nColumn; i++){
for(i=j=0, pTerm=pOrderBy->a; j<nTerm && i<=pIdx->nColumn; i++){
Expr *pExpr; /* The expression of the ORDER BY pTerm */
CollSeq *pColl; /* The collating sequence of pExpr */
int termSortOrder; /* Sort order for this term */
int iColumn; /* The i-th column of the index. -1 for rowid */
int iSortOrder; /* 1 for DESC, 0 for ASC on the i-th index term */
const char *zColl; /* Name of the collating sequence for i-th index term */
pExpr = pTerm->pExpr;
if( pExpr->op!=TK_COLUMN || pExpr->iTable!=base ){
/* Can not use an index sort on anything that is not a column in the
** left-most table of the FROM clause */
return 0;
break;
}
pColl = sqlite3ExprCollSeq(pParse, pExpr);
if( !pColl ) pColl = db->pDfltColl;
if( pExpr->iColumn!=pIdx->aiColumn[i] ||
sqlite3StrICmp(pColl->zName, pIdx->azColl[i]) ){
if( !pColl ){
pColl = db->pDfltColl;
}
if( i<pIdx->nColumn ){
iColumn = pIdx->aiColumn[i];
if( iColumn==pIdx->pTable->iPKey ){
iColumn = -1;
}
iSortOrder = pIdx->aSortOrder[i];
zColl = pIdx->azColl[i];
}else{
iColumn = -1;
iSortOrder = 0;
zColl = pColl->zName;
}
if( pExpr->iColumn!=iColumn || sqlite3StrICmp(pColl->zName, zColl) ){
/* Term j of the ORDER BY clause does not match column i of the index */
if( i<nEqCol ){
/* If an index column that is constrained by == fails to match an
@@ -888,8 +953,8 @@ static int isSortingIndex(
}
assert( pIdx->aSortOrder!=0 );
assert( pTerm->sortOrder==0 || pTerm->sortOrder==1 );
assert( pIdx->aSortOrder[i]==0 || pIdx->aSortOrder[i]==1 );
termSortOrder = pIdx->aSortOrder[i] ^ pTerm->sortOrder;
assert( iSortOrder==0 || iSortOrder==1 );
termSortOrder = iSortOrder ^ pTerm->sortOrder;
if( i>nEqCol ){
if( termSortOrder!=sortOrder ){
/* Indices can only be used if all ORDER BY terms past the
@@ -901,13 +966,29 @@ static int isSortingIndex(
}
j++;
pTerm++;
if( iColumn<0 && !referencesOtherTables(pOrderBy, pMaskSet, j, base) ){
/* If the indexed column is the primary key and everything matches
** so far and none of the ORDER BY terms to the right reference other
** tables in the join, then we are assured that the index can be used
** to sort because the primary key is unique and so none of the other
** columns will make any difference
*/
j = nTerm;
}
}
/* The index can be used for sorting if all terms of the ORDER BY clause
** are covered.
*/
*pbRev = sortOrder!=0;
if( j>=nTerm ){
*pbRev = sortOrder!=0;
/* All terms of the ORDER BY clause are covered by this index so
** this index can be used for sorting. */
return 1;
}
if( pIdx->onError!=OE_None && i==pIdx->nColumn
&& !referencesOtherTables(pOrderBy, pMaskSet, j, base) ){
/* All terms of this index match some prefix of the ORDER BY clause
** and the index is UNIQUE and no terms on the tail of the ORDER BY
** clause reference other tables in a join. If this is all true then
** the order by clause is superfluous. */
return 1;
}
return 0;
@@ -921,6 +1002,7 @@ static int isSortingIndex(
static int sortableByRowid(
int base, /* Cursor number for table to be sorted */
ExprList *pOrderBy, /* The ORDER BY clause */
ExprMaskSet *pMaskSet, /* Mapping from tables to bitmaps */
int *pbRev /* Set to 1 if ORDER BY is DESC */
){
Expr *p;
@@ -928,8 +1010,8 @@ static int sortableByRowid(
assert( pOrderBy!=0 );
assert( pOrderBy->nExpr>0 );
p = pOrderBy->a[0].pExpr;
if( pOrderBy->nExpr==1 && p->op==TK_COLUMN && p->iTable==base
&& p->iColumn==-1 ){
if( p->op==TK_COLUMN && p->iTable==base && p->iColumn==-1
&& !referencesOtherTables(pOrderBy, pMaskSet, 1, base) ){
*pbRev = pOrderBy->a[0].sortOrder;
return 1;
}
@@ -1232,6 +1314,7 @@ static double bestIndex(
int rev; /* True to scan in reverse order */
int flags; /* Flags associated with pProbe */
int nEq; /* Number of == or IN constraints */
int eqTermMask; /* Mask of valid equality operators */
double cost; /* Cost of using pProbe */
TRACE(("bestIndex: tbl=%s notReady=%x\n", pSrc->pTab->zName, notReady));
@@ -1246,7 +1329,7 @@ static double bestIndex(
*/
if( pProbe==0 &&
findTerm(pWC, iCur, -1, 0, WO_EQ|WO_IN|WO_LT|WO_LE|WO_GT|WO_GE,0)==0 &&
(pOrderBy==0 || !sortableByRowid(iCur, pOrderBy, &rev)) ){
(pOrderBy==0 || !sortableByRowid(iCur, pOrderBy, pWC->pMaskSet, &rev)) ){
*pFlags = 0;
*ppIndex = 0;
*pnEq = 0;
@@ -1308,7 +1391,7 @@ static double bestIndex(
/* If the table scan does not satisfy the ORDER BY clause, increase
** the cost by NlogN to cover the expense of sorting. */
if( pOrderBy ){
if( sortableByRowid(iCur, pOrderBy, &rev) ){
if( sortableByRowid(iCur, pOrderBy, pWC->pMaskSet, &rev) ){
flags |= WHERE_ORDERBY|WHERE_ROWID_RANGE;
if( rev ){
flags |= WHERE_REVERSE;
@@ -1323,6 +1406,17 @@ static double bestIndex(
bestFlags = flags;
}
/* If the pSrc table is the right table of a LEFT JOIN then we may not
** use an index to satisfy IS NULL constraints on that table. This is
** because columns might end up being NULL if the table does not match -
** a circumstance which the index cannot help us discover. Ticket #2177.
*/
if( (pSrc->jointype & JT_LEFT)!=0 ){
eqTermMask = WO_EQ|WO_IN;
}else{
eqTermMask = WO_EQ|WO_IN|WO_ISNULL;
}
/* Look at each index.
*/
for(; pProbe; pProbe=pProbe->pNext){
@@ -1337,7 +1431,7 @@ static double bestIndex(
flags = 0;
for(i=0; i<pProbe->nColumn; i++){
int j = pProbe->aiColumn[i];
pTerm = findTerm(pWC, iCur, j, notReady, WO_EQ|WO_IN, pProbe);
pTerm = findTerm(pWC, iCur, j, notReady, eqTermMask, pProbe);
if( pTerm==0 ) break;
flags |= WHERE_COLUMN_EQ;
if( pTerm->eOperator & WO_IN ){
@@ -1381,7 +1475,7 @@ static double bestIndex(
*/
if( pOrderBy ){
if( (flags & WHERE_COLUMN_IN)==0 &&
isSortingIndex(pParse,pProbe,iCur,pOrderBy,nEq,&rev) ){
isSortingIndex(pParse,pWC->pMaskSet,pProbe,iCur,pOrderBy,nEq,&rev) ){
if( flags==0 ){
flags = WHERE_COLUMN_RANGE;
}
@@ -1431,7 +1525,7 @@ static double bestIndex(
*ppIndex = bestIdx;
TRACE(("best index is %s, cost=%.9g, flags=%x, nEq=%d\n",
bestIdx ? bestIdx->zName : "(none)", lowestCost, bestFlags, bestNEq));
*pFlags = bestFlags;
*pFlags = bestFlags | eqTermMask;
*pnEq = bestNEq;
return lowestCost;
}
@@ -1476,30 +1570,18 @@ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
}
/*
** 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. Pop (nColumn+nExtra)
** elements from the stack.
**
** * Construct a probe entry from the top nColumn entries in
** the stack with affinities appropriate for index pIdx.
** Only nColumn elements are popped from the stack in this case
** (by OP_MakeRecord).
** Generate code that builds a probe for an index.
**
** There should be nColumn values on the stack. The index
** to be probed is pIdx. Pop the values from the stack and
** replace them all with a single record that is the index
** problem.
*/
static void buildIndexProbe(
Vdbe *v,
int nColumn,
int nExtra,
int brk,
Index *pIdx
Vdbe *v, /* Generate code into this VM */
int nColumn, /* The number of columns to check for NULL */
Index *pIdx /* Index that we will be searching */
){
sqlite3VdbeAddOp(v, OP_NotNull, -nColumn, sqlite3VdbeCurrentAddr(v)+3);
sqlite3VdbeAddOp(v, OP_Pop, nColumn+nExtra, 0);
sqlite3VdbeAddOp(v, OP_Goto, 0, brk);
sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
sqlite3IndexAffinityStr(v, pIdx);
}
@@ -1523,15 +1605,17 @@ static void codeEqualityTerm(
WhereLevel *pLevel /* When level of the FROM clause we are working on */
){
Expr *pX = pTerm->pExpr;
if( pX->op!=TK_IN ){
assert( pX->op==TK_EQ );
Vdbe *v = pParse->pVdbe;
if( pX->op==TK_EQ ){
sqlite3ExprCode(pParse, pX->pRight);
}else if( pX->op==TK_ISNULL ){
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
#ifndef SQLITE_OMIT_SUBQUERY
}else{
int iTab;
int *aIn;
Vdbe *v = pParse->pVdbe;
assert( pX->op==TK_IN );
sqlite3CodeSubselect(pParse, pX);
iTab = pX->iTable;
sqlite3VdbeAddOp(v, OP_Rewind, iTab, 0);
@@ -1603,17 +1687,20 @@ static void codeAllEqualityTerms(
/* Evaluate the equality constraints
*/
for(j=0; j<pIdx->nColumn; j++){
assert( pIdx->nColumn>=nEq );
for(j=0; j<nEq; j++){
int k = pIdx->aiColumn[j];
pTerm = findTerm(pWC, iCur, k, notReady, WO_EQ|WO_IN, pIdx);
pTerm = findTerm(pWC, iCur, k, notReady, pLevel->flags, pIdx);
if( pTerm==0 ) break;
assert( (pTerm->flags & TERM_CODED)==0 );
codeEqualityTerm(pParse, pTerm, brk, pLevel);
if( (pTerm->eOperator & WO_ISNULL)==0 ){
sqlite3VdbeAddOp(v, OP_IsNull, termsInMem ? -1 : -(j+1), brk);
}
if( termsInMem ){
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem+j+1, 1);
}
}
assert( j==nEq );
/* Make sure all the constraint values are on the top of the stack
*/
@@ -1776,7 +1863,7 @@ WhereInfo *sqlite3WhereBegin(
** subexpression is separated by an AND operator.
*/
initMaskSet(&maskSet);
whereClauseInit(&wc, pParse);
whereClauseInit(&wc, pParse, &maskSet);
whereSplit(&wc, pWhere, TK_AND);
/* Allocate and initialize the WhereInfo structure that will become the
@@ -1807,7 +1894,7 @@ WhereInfo *sqlite3WhereBegin(
for(i=0; i<pTabList->nSrc; i++){
createMask(&maskSet, pTabList->a[i].iCursor);
}
exprAnalyzeAll(pTabList, &maskSet, &wc);
exprAnalyzeAll(pTabList, &wc);
if( sqlite3MallocFailed() ){
goto whereBeginNoMem;
}
@@ -1850,8 +1937,7 @@ WhereInfo *sqlite3WhereBegin(
for(j=iFrom, pTabItem=&pTabList->a[j]; j<pTabList->nSrc; j++, pTabItem++){
int doNotReorder; /* True if this table should not be reordered */
doNotReorder = (pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0
|| (j>0 && (pTabItem[-1].jointype & (JT_LEFT|JT_CROSS))!=0);
doNotReorder = (pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0;
if( once && doNotReorder ) break;
m = getMask(&maskSet, pTabItem->iCursor);
if( (m & notReady)==0 ){
@@ -1986,7 +2072,9 @@ WhereInfo *sqlite3WhereBegin(
sqlite3VdbeOp3(v, OP_OpenRead, iIdxCur, pIx->tnum,
(char*)pKey, P3_KEYINFO_HANDOFF);
}
if( (pLevel->flags & WHERE_IDX_ONLY)!=0 ){
if( (pLevel->flags & (WHERE_IDX_ONLY|WHERE_COLUMN_RANGE))!=0 ){
/* Only call OP_SetNumColumns on the index if we might later use
** OP_Column on the index. */
sqlite3VdbeAddOp(v, OP_SetNumColumns, iIdxCur, pIx->nColumn+1);
}
sqlite3CodeVerifySchema(pParse, iDb);
@@ -2025,7 +2113,7 @@ WhereInfo *sqlite3WhereBegin(
** initialize a memory cell that records if this table matches any
** row of the left table of the join.
*/
if( pLevel->iFrom>0 && (pTabItem[-1].jointype & JT_LEFT)!=0 ){
if( pLevel->iFrom>0 && (pTabItem[0].jointype & JT_LEFT)!=0 ){
if( !pParse->nMem ) pParse->nMem++;
pLevel->iLeftJoin = pParse->nMem++;
sqlite3VdbeAddOp(v, OP_MemInt, 0, pLevel->iLeftJoin);
@@ -2159,7 +2247,6 @@ WhereInfo *sqlite3WhereBegin(
int btmEq=0; /* True if btm limit uses ==. False if strictly > */
int topOp, btmOp; /* Operators for the top and bottom search bounds */
int testOp;
int nNotNull; /* Number of rows of index that must be non-NULL */
int topLimit = (pLevel->flags & WHERE_TOP_LIMIT)!=0;
int btmLimit = (pLevel->flags & WHERE_BTM_LIMIT)!=0;
@@ -2181,7 +2268,6 @@ WhereInfo *sqlite3WhereBegin(
** operator and the top bound is a < or <= operator. For a descending
** index the operators are reversed.
*/
nNotNull = nEq + topLimit;
if( pIdx->aSortOrder[nEq]==SQLITE_SO_ASC ){
topOp = WO_LT|WO_LE;
btmOp = WO_GT|WO_GE;
@@ -2206,6 +2292,7 @@ WhereInfo *sqlite3WhereBegin(
pX = pTerm->pExpr;
assert( (pTerm->flags & TERM_CODED)==0 );
sqlite3ExprCode(pParse, pX->pRight);
sqlite3VdbeAddOp(v, OP_IsNull, -(nEq+1), brk);
topEq = pTerm->eOperator & (WO_LE|WO_GE);
disableTerm(pLevel, pTerm);
testOp = OP_IdxGE;
@@ -2216,7 +2303,7 @@ WhereInfo *sqlite3WhereBegin(
if( testOp!=OP_Noop ){
int nCol = nEq + topLimit;
pLevel->iMem = pParse->nMem++;
buildIndexProbe(v, nCol, nEq, brk, pIdx);
buildIndexProbe(v, nCol, pIdx);
if( bRev ){
int op = topEq ? OP_MoveLe : OP_MoveLt;
sqlite3VdbeAddOp(v, op, iIdxCur, brk);
@@ -2244,6 +2331,7 @@ WhereInfo *sqlite3WhereBegin(
pX = pTerm->pExpr;
assert( (pTerm->flags & TERM_CODED)==0 );
sqlite3ExprCode(pParse, pX->pRight);
sqlite3VdbeAddOp(v, OP_IsNull, -(nEq+1), brk);
btmEq = pTerm->eOperator & (WO_LE|WO_GE);
disableTerm(pLevel, pTerm);
}else{
@@ -2251,7 +2339,7 @@ WhereInfo *sqlite3WhereBegin(
}
if( nEq>0 || btmLimit ){
int nCol = nEq + btmLimit;
buildIndexProbe(v, nCol, 0, brk, pIdx);
buildIndexProbe(v, nCol, pIdx);
if( bRev ){
pLevel->iMem = pParse->nMem++;
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
@@ -2278,8 +2366,10 @@ WhereInfo *sqlite3WhereBegin(
sqlite3VdbeChangeP3(v, -1, "+", P3_STATIC);
}
}
sqlite3VdbeAddOp(v, OP_RowKey, iIdxCur, 0);
sqlite3VdbeAddOp(v, OP_IdxIsNull, nNotNull, cont);
if( topLimit | btmLimit ){
sqlite3VdbeAddOp(v, OP_Column, iIdxCur, nEq);
sqlite3VdbeAddOp(v, OP_IsNull, 1, cont);
}
if( !omitTable ){
sqlite3VdbeAddOp(v, OP_IdxRowid, iIdxCur, 0);
sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
@@ -2305,7 +2395,7 @@ WhereInfo *sqlite3WhereBegin(
/* Generate a single key that will be used to both start and terminate
** the search
*/
buildIndexProbe(v, nEq, 0, brk, pIdx);
buildIndexProbe(v, nEq, pIdx);
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 0);
/* Generate code (1) to move to the first matching element of the table.
@@ -2326,8 +2416,6 @@ WhereInfo *sqlite3WhereBegin(
sqlite3VdbeOp3(v, OP_IdxGE, iIdxCur, brk, "+", P3_STATIC);
pLevel->op = OP_Next;
}
sqlite3VdbeAddOp(v, OP_RowKey, iIdxCur, 0);
sqlite3VdbeAddOp(v, OP_IdxIsNull, nEq, cont);
if( !omitTable ){
sqlite3VdbeAddOp(v, OP_IdxRowid, iIdxCur, 0);
sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);