mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-18 10:21:03 +03:00
Merge changes from trunk.
FossilOrigin-Name: c80e9e8e8cc1e7676d7c782ee0827726875db79e
This commit is contained in:
46
src/where.c
46
src/where.c
@@ -171,37 +171,37 @@ static void createMask(WhereMaskSet *pMaskSet, int iCursor){
|
||||
*/
|
||||
static WhereTerm *whereScanNext(WhereScan *pScan){
|
||||
int iCur; /* The cursor on the LHS of the term */
|
||||
int iColumn; /* The column on the LHS of the term. -1 for IPK */
|
||||
i16 iColumn; /* The column on the LHS of the term. -1 for IPK */
|
||||
Expr *pX; /* An expression being tested */
|
||||
WhereClause *pWC; /* Shorthand for pScan->pWC */
|
||||
WhereTerm *pTerm; /* The term being tested */
|
||||
int k = pScan->k; /* Where to start scanning */
|
||||
|
||||
while( pScan->iEquiv<=pScan->nEquiv ){
|
||||
iCur = pScan->aEquiv[pScan->iEquiv-2];
|
||||
iColumn = pScan->aEquiv[pScan->iEquiv-1];
|
||||
iCur = pScan->aiCur[pScan->iEquiv-1];
|
||||
iColumn = pScan->aiColumn[pScan->iEquiv-1];
|
||||
while( (pWC = pScan->pWC)!=0 ){
|
||||
for(pTerm=pWC->a+k; k<pWC->nTerm; k++, pTerm++){
|
||||
if( pTerm->leftCursor==iCur
|
||||
&& pTerm->u.leftColumn==iColumn
|
||||
&& (pScan->iEquiv<=2 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin))
|
||||
&& (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin))
|
||||
){
|
||||
if( (pTerm->eOperator & WO_EQUIV)!=0
|
||||
&& pScan->nEquiv<ArraySize(pScan->aEquiv)
|
||||
&& pScan->nEquiv<ArraySize(pScan->aiCur)
|
||||
){
|
||||
int j;
|
||||
pX = sqlite3ExprSkipCollate(pTerm->pExpr->pRight);
|
||||
assert( pX->op==TK_COLUMN );
|
||||
for(j=0; j<pScan->nEquiv; j+=2){
|
||||
if( pScan->aEquiv[j]==pX->iTable
|
||||
&& pScan->aEquiv[j+1]==pX->iColumn ){
|
||||
for(j=0; j<pScan->nEquiv; j++){
|
||||
if( pScan->aiCur[j]==pX->iTable
|
||||
&& pScan->aiColumn[j]==pX->iColumn ){
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( j==pScan->nEquiv ){
|
||||
pScan->aEquiv[j] = pX->iTable;
|
||||
pScan->aEquiv[j+1] = pX->iColumn;
|
||||
pScan->nEquiv += 2;
|
||||
pScan->aiCur[j] = pX->iTable;
|
||||
pScan->aiColumn[j] = pX->iColumn;
|
||||
pScan->nEquiv++;
|
||||
}
|
||||
}
|
||||
if( (pTerm->eOperator & pScan->opMask)!=0 ){
|
||||
@@ -223,8 +223,8 @@ static WhereTerm *whereScanNext(WhereScan *pScan){
|
||||
}
|
||||
if( (pTerm->eOperator & (WO_EQ|WO_IS))!=0
|
||||
&& (pX = pTerm->pExpr->pRight)->op==TK_COLUMN
|
||||
&& pX->iTable==pScan->aEquiv[0]
|
||||
&& pX->iColumn==pScan->aEquiv[1]
|
||||
&& pX->iTable==pScan->aiCur[0]
|
||||
&& pX->iColumn==pScan->aiColumn[0]
|
||||
){
|
||||
testcase( pTerm->eOperator & WO_IS );
|
||||
continue;
|
||||
@@ -239,7 +239,7 @@ static WhereTerm *whereScanNext(WhereScan *pScan){
|
||||
}
|
||||
pScan->pWC = pScan->pOrigWC;
|
||||
k = 0;
|
||||
pScan->iEquiv += 2;
|
||||
pScan->iEquiv++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -286,10 +286,10 @@ static WhereTerm *whereScanInit(
|
||||
}
|
||||
pScan->opMask = opMask;
|
||||
pScan->k = 0;
|
||||
pScan->aEquiv[0] = iCur;
|
||||
pScan->aEquiv[1] = iColumn;
|
||||
pScan->nEquiv = 2;
|
||||
pScan->iEquiv = 2;
|
||||
pScan->aiCur[0] = iCur;
|
||||
pScan->aiColumn[0] = iColumn;
|
||||
pScan->nEquiv = 1;
|
||||
pScan->iEquiv = 1;
|
||||
return whereScanNext(pScan);
|
||||
}
|
||||
|
||||
@@ -305,12 +305,10 @@ static WhereTerm *whereScanInit(
|
||||
** The term returned might by Y=<expr> if there is another constraint in
|
||||
** the WHERE clause that specifies that X=Y. Any such constraints will be
|
||||
** identified by the WO_EQUIV bit in the pTerm->eOperator field. The
|
||||
** aEquiv[] array holds X and all its equivalents, with each SQL variable
|
||||
** taking up two slots in aEquiv[]. The first slot is for the cursor number
|
||||
** and the second is for the column number. There are 22 slots in aEquiv[]
|
||||
** so that means we can look for X plus up to 10 other equivalent values.
|
||||
** Hence a search for X will return <expr> if X=A1 and A1=A2 and A2=A3
|
||||
** and ... and A9=A10 and A10=<expr>.
|
||||
** aiCur[]/iaColumn[] arrays hold X and all its equivalents. There are 11
|
||||
** slots in aiCur[]/aiColumn[] so that means we can look for X plus up to 10
|
||||
** other equivalent values. Hence a search for X will return <expr> if X=A1
|
||||
** and A1=A2 and A2=A3 and ... and A9=A10 and A10=<expr>.
|
||||
**
|
||||
** If there are multiple terms in the WHERE clause of the form "X <op> <expr>"
|
||||
** then try for the one with no dependencies on <expr> - in other words where
|
||||
|
||||
Reference in New Issue
Block a user