summaryrefslogtreecommitdiff
path: root/chromium/third_party/sqlite/src/src/whereexpr.c
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-09-18 14:34:04 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2017-10-04 11:15:27 +0000
commite6430e577f105ad8813c92e75c54660c4985026e (patch)
tree88115e5d1fb471fea807111924dcccbeadbf9e4f /chromium/third_party/sqlite/src/src/whereexpr.c
parent53d399fe6415a96ea6986ec0d402a9c07da72453 (diff)
downloadqtwebengine-chromium-e6430e577f105ad8813c92e75c54660c4985026e.tar.gz
BASELINE: Update Chromium to 61.0.3163.99
Change-Id: I8452f34574d88ca2b27af9bd56fc9ff3f16b1367 Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/third_party/sqlite/src/src/whereexpr.c')
-rw-r--r--chromium/third_party/sqlite/src/src/whereexpr.c160
1 files changed, 91 insertions, 69 deletions
diff --git a/chromium/third_party/sqlite/src/src/whereexpr.c b/chromium/third_party/sqlite/src/src/whereexpr.c
index 826d329b7f1..3d53959110f 100644
--- a/chromium/third_party/sqlite/src/src/whereexpr.c
+++ b/chromium/third_party/sqlite/src/src/whereexpr.c
@@ -114,7 +114,7 @@ static int allowedOp(int op){
** collating sequence, then COLLATE operators are adjusted to ensure
** that the collating sequence does not change. For example:
** "Y collate NOCASE op X" becomes "X op Y" because any collation sequence on
-** the left hand side of a comparison overrides any collation sequence
+** the left hand side of a comparison overrides any collation sequence
** attached to the right. For the same reason the EP_Collate flag
** is not commuted.
*/
@@ -213,19 +213,10 @@ static int isLikeOrGlob(
#endif
pList = pExpr->x.pList;
pLeft = pList->a[1].pExpr;
- if( pLeft->op!=TK_COLUMN
- || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
- || IsVirtual(pLeft->pTab) /* Value might be numeric */
- ){
- /* IMP: R-02065-49465 The left-hand side of the LIKE or GLOB operator must
- ** be the name of an indexed column with TEXT affinity. */
- return 0;
- }
- assert( pLeft->iColumn!=(-1) ); /* Because IPK never has AFF_TEXT */
pRight = sqlite3ExprSkipCollate(pList->a[0].pExpr);
op = pRight->op;
- if( op==TK_VARIABLE ){
+ if( op==TK_VARIABLE && (db->flags & SQLITE_EnableQPSG)==0 ){
Vdbe *pReprepare = pParse->pReprepare;
int iCol = pRight->iColumn;
pVal = sqlite3VdbeGetBoundValue(pReprepare, iCol, SQLITE_AFF_BLOB);
@@ -238,6 +229,23 @@ static int isLikeOrGlob(
z = pRight->u.zToken;
}
if( z ){
+
+ /* If the RHS begins with a digit or a minus sign, then the LHS must
+ ** be an ordinary column (not a virtual table column) with TEXT affinity.
+ ** Otherwise the LHS might be numeric and "lhs >= rhs" would be false
+ ** even though "lhs LIKE rhs" is true. But if the RHS does not start
+ ** with a digit or '-', then "lhs LIKE rhs" will always be false if
+ ** the LHS is numeric and so the optimization still works.
+ */
+ if( sqlite3Isdigit(z[0]) || z[0]=='-' ){
+ if( pLeft->op!=TK_COLUMN
+ || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
+ || IsVirtual(pLeft->pTab) /* Value might be numeric */
+ ){
+ sqlite3ValueFree(pVal);
+ return 0;
+ }
+ }
cnt = 0;
while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
cnt++;
@@ -257,7 +265,7 @@ static int isLikeOrGlob(
** function, then no OP_Variable will be added to the program.
** This causes problems for the sqlite3_bind_parameter_name()
** API. To work around them, add a dummy OP_Variable here.
- */
+ */
int r1 = sqlite3GetTempReg(pParse);
sqlite3ExprCodeTarget(pParse, pRight, r1);
sqlite3VdbeChangeP3(v, sqlite3VdbeCurrentAddr(v)-1, 0);
@@ -282,7 +290,7 @@ static int isLikeOrGlob(
**
** column OP expr
**
-** where OP is one of MATCH, GLOB, LIKE or REGEXP and "column" is a
+** where OP is one of MATCH, GLOB, LIKE or REGEXP and "column" is a
** column of a virtual table.
**
** If it is then return TRUE. If not, return FALSE.
@@ -378,7 +386,7 @@ static WhereTerm *whereNthSubterm(WhereTerm *pTerm, int N){
**
** The following is NOT generated:
**
-** x<y OR x>y --> x!=y
+** x<y OR x>y --> x!=y
*/
static void whereCombineDisjuncts(
SrcList *pSrc, /* the FROM clause */
@@ -398,8 +406,8 @@ static void whereCombineDisjuncts(
&& (eOp & (WO_EQ|WO_GT|WO_GE))!=eOp ) return;
assert( pOne->pExpr->pLeft!=0 && pOne->pExpr->pRight!=0 );
assert( pTwo->pExpr->pLeft!=0 && pTwo->pExpr->pRight!=0 );
- if( sqlite3ExprCompare(pOne->pExpr->pLeft, pTwo->pExpr->pLeft, -1) ) return;
- if( sqlite3ExprCompare(pOne->pExpr->pRight, pTwo->pExpr->pRight, -1) )return;
+ if( sqlite3ExprCompare(0,pOne->pExpr->pLeft, pTwo->pExpr->pLeft, -1) ) return;
+ if( sqlite3ExprCompare(0,pOne->pExpr->pRight, pTwo->pExpr->pRight,-1) )return;
/* If we reach this point, it means the two subterms can be combined */
if( (eOp & (eOp-1))!=0 ){
if( eOp & (WO_LT|WO_LE) ){
@@ -475,10 +483,10 @@ static void whereCombineDisjuncts(
** WhereTerm.u.pOrInfo->indexable |= the cursor number for table T
**
** A subterm is "indexable" if it is of the form
-** "T.C <op> <expr>" where C is any column of table T and
+** "T.C <op> <expr>" where C is any column of table T and
** <op> is one of "=", "<", "<=", ">", ">=", "IS NULL", or "IN".
** A subterm is also indexable if it is an AND of two or more
-** subsubterms at least one of which is indexable. Indexable AND
+** subsubterms at least one of which is indexable. Indexable AND
** subterms have their eOperator set to WO_AND and they have
** u.pAndInfo set to a dynamically allocated WhereAndTerm object.
**
@@ -569,8 +577,8 @@ static void exprAnalyzeOrTerm(
if( !db->mallocFailed ){
for(j=0, pAndTerm=pAndWC->a; j<pAndWC->nTerm; j++, pAndTerm++){
assert( pAndTerm->pExpr );
- if( allowedOp(pAndTerm->pExpr->op)
- || pAndTerm->eOperator==WO_MATCH
+ if( allowedOp(pAndTerm->pExpr->op)
+ || pAndTerm->eOperator==WO_MATCH
){
b |= sqlite3WhereGetMask(&pWInfo->sMaskSet, pAndTerm->leftCursor);
}
@@ -666,7 +674,7 @@ static void exprAnalyzeOrTerm(
pOrTerm->leftCursor))==0 ){
/* This term must be of the form t1.a==t2.b where t2 is in the
** chngToIN set but t1 is not. This term will be either preceded
- ** or follwed by an inverted copy (t2.b==t1.a). Skip this term
+ ** or follwed by an inverted copy (t2.b==t1.a). Skip this term
** and use its inversion. */
testcase( pOrTerm->wtFlags & TERM_COPIED );
testcase( pOrTerm->wtFlags & TERM_VIRTUAL );
@@ -714,7 +722,7 @@ static void exprAnalyzeOrTerm(
}
/* At this point, okToChngToIN is true if original pTerm satisfies
- ** case 1. In that case, construct a new virtual term that is
+ ** case 1. In that case, construct a new virtual term that is
** pTerm converted into an IN operator.
*/
if( okToChngToIN ){
@@ -822,8 +830,8 @@ static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){
** Expression pExpr is one operand of a comparison operator that might
** be useful for indexing. This routine checks to see if pExpr appears
** in any index. Return TRUE (1) if pExpr is an indexed term and return
-** FALSE (0) if not. If TRUE is returned, also set *piCur to the cursor
-** number of the table that is indexed and *piColumn to the column number
+** FALSE (0) if not. If TRUE is returned, also set aiCurCol[0] to the cursor
+** number of the table that is indexed and aiCurCol[1] to the column number
** of the column that is indexed, or XN_EXPR (-2) if an expression is being
** indexed.
**
@@ -831,20 +839,39 @@ static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){
** true even if that particular column is not indexed, because the column
** might be added to an automatic index later.
*/
-static int exprMightBeIndexed(
+static SQLITE_NOINLINE int exprMightBeIndexed2(
SrcList *pFrom, /* The FROM clause */
- int op, /* The specific comparison operator */
Bitmask mPrereq, /* Bitmask of FROM clause terms referenced by pExpr */
- Expr *pExpr, /* An operand of a comparison operator */
- int *piCur, /* Write the referenced table cursor number here */
- int *piColumn /* Write the referenced table column number here */
+ int *aiCurCol, /* Write the referenced table cursor and column here */
+ Expr *pExpr /* An operand of a comparison operator */
){
Index *pIdx;
int i;
int iCur;
-
- /* If this expression is a vector to the left or right of a
- ** inequality constraint (>, <, >= or <=), perform the processing
+ for(i=0; mPrereq>1; i++, mPrereq>>=1){}
+ iCur = pFrom->a[i].iCursor;
+ for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ if( pIdx->aColExpr==0 ) continue;
+ for(i=0; i<pIdx->nKeyCol; i++){
+ if( pIdx->aiColumn[i]!=XN_EXPR ) continue;
+ if( sqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
+ aiCurCol[0] = iCur;
+ aiCurCol[1] = XN_EXPR;
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+static int exprMightBeIndexed(
+ SrcList *pFrom, /* The FROM clause */
+ Bitmask mPrereq, /* Bitmask of FROM clause terms referenced by pExpr */
+ int *aiCurCol, /* Write the referenced table cursor & column here */
+ Expr *pExpr, /* An operand of a comparison operator */
+ int op /* The specific comparison operator */
+){
+ /* If this expression is a vector to the left or right of a
+ ** inequality constraint (>, <, >= or <=), perform the processing
** on the first element of the vector. */
assert( TK_GT+1==TK_LE && TK_GT+2==TK_LT && TK_GT+3==TK_GE );
assert( TK_IS<TK_GE && TK_ISNULL<TK_GE && TK_IN<TK_GE );
@@ -854,26 +881,13 @@ static int exprMightBeIndexed(
}
if( pExpr->op==TK_COLUMN ){
- *piCur = pExpr->iTable;
- *piColumn = pExpr->iColumn;
+ aiCurCol[0] = pExpr->iTable;
+ aiCurCol[1] = pExpr->iColumn;
return 1;
}
if( mPrereq==0 ) return 0; /* No table references */
if( (mPrereq&(mPrereq-1))!=0 ) return 0; /* Refs more than one table */
- for(i=0; mPrereq>1; i++, mPrereq>>=1){}
- iCur = pFrom->a[i].iCursor;
- for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- if( pIdx->aColExpr==0 ) continue;
- for(i=0; i<pIdx->nKeyCol; i++){
- if( pIdx->aiColumn[i]!=XN_EXPR ) continue;
- if( sqlite3ExprCompare(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
- *piCur = iCur;
- *piColumn = XN_EXPR;
- return 1;
- }
- }
- }
- return 0;
+ return exprMightBeIndexed2(pFrom,mPrereq,aiCurCol,pExpr);
}
/*
@@ -937,7 +951,9 @@ static void exprAnalyze(
}else{
pTerm->prereqRight = sqlite3WhereExprUsage(pMaskSet, pExpr->pRight);
}
+ pMaskSet->bVarSelect = 0;
prereqAll = sqlite3WhereExprUsage(pMaskSet, pExpr);
+ if( pMaskSet->bVarSelect ) pTerm->wtFlags |= TERM_VARSELECT;
if( ExprHasProperty(pExpr, EP_FromJoin) ){
Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->iRightJoinTable);
prereqAll |= x;
@@ -953,7 +969,7 @@ static void exprAnalyze(
pTerm->iParent = -1;
pTerm->eOperator = 0;
if( allowedOp(op) ){
- int iCur, iColumn;
+ int aiCurCol[2];
Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft);
Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV;
@@ -964,14 +980,14 @@ static void exprAnalyze(
pLeft = pLeft->x.pList->a[pTerm->iField-1].pExpr;
}
- if( exprMightBeIndexed(pSrc, op, prereqLeft, pLeft, &iCur, &iColumn) ){
- pTerm->leftCursor = iCur;
- pTerm->u.leftColumn = iColumn;
+ if( exprMightBeIndexed(pSrc, prereqLeft, aiCurCol, pLeft, op) ){
+ pTerm->leftCursor = aiCurCol[0];
+ pTerm->u.leftColumn = aiCurCol[1];
pTerm->eOperator = operatorMask(op) & opMask;
}
if( op==TK_IS ) pTerm->wtFlags |= TERM_IS;
- if( pRight
- && exprMightBeIndexed(pSrc, op, pTerm->prereqRight, pRight, &iCur,&iColumn)
+ if( pRight
+ && exprMightBeIndexed(pSrc, pTerm->prereqRight, aiCurCol, pRight, op)
){
WhereTerm *pNew;
Expr *pDup;
@@ -1001,8 +1017,8 @@ static void exprAnalyze(
pNew = pTerm;
}
exprCommute(pParse, pDup);
- pNew->leftCursor = iCur;
- pNew->u.leftColumn = iColumn;
+ pNew->leftCursor = aiCurCol[0];
+ pNew->u.leftColumn = aiCurCol[1];
testcase( (prereqLeft | extraRight) != prereqLeft );
pNew->prereqRight = prereqLeft | extraRight;
pNew->prereqAll = prereqAll;
@@ -1035,7 +1051,7 @@ static void exprAnalyze(
for(i=0; i<2; i++){
Expr *pNewExpr;
int idxNew;
- pNewExpr = sqlite3PExpr(pParse, ops[i],
+ pNewExpr = sqlite3PExpr(pParse, ops[i],
sqlite3ExprDup(db, pExpr->pLeft, 0),
sqlite3ExprDup(db, pList->a[i].pExpr, 0));
transferJoinMarkings(pNewExpr, pExpr);
@@ -1073,7 +1089,7 @@ static void exprAnalyze(
** bound is made all lowercase so that the bounds also work when comparing
** BLOBs.
*/
- if( pWC->op==TK_AND
+ if( pWC->op==TK_AND
&& isLikeOrGlob(pParse, pExpr, &pStr1, &isComplete, &noCase)
){
Expr *pLeft; /* LHS of LIKE/GLOB operator */
@@ -1109,7 +1125,7 @@ static void exprAnalyze(
if( noCase ){
/* The point is to increment the last character before the first
** wildcard. But if we increment '@', that will push it into the
- ** alphabetic range where case conversions will mess up the
+ ** alphabetic range where case conversions will mess up the
** inequality. To avoid this, make sure to also run the full
** LIKE on all candidate expressions by clearing the isComplete flag
*/
@@ -1162,8 +1178,11 @@ static void exprAnalyze(
prereqColumn = sqlite3WhereExprUsage(pMaskSet, pLeft);
if( (prereqExpr & prereqColumn)==0 ){
Expr *pNewExpr;
- pNewExpr = sqlite3PExpr(pParse, TK_MATCH,
+ pNewExpr = sqlite3PExpr(pParse, TK_MATCH,
0, sqlite3ExprDup(db, pRight, 0));
+ if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){
+ ExprSetProperty(pNewExpr, EP_FromJoin);
+ }
idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew==0 );
pNewTerm = &pWC->a[idxNew];
@@ -1187,11 +1206,11 @@ static void exprAnalyze(
**
** This is only required if at least one side of the comparison operation
** is not a sub-select. */
- if( pWC->op==TK_AND
+ if( pWC->op==TK_AND
&& (pExpr->op==TK_EQ || pExpr->op==TK_IS)
&& (nLeft = sqlite3ExprVectorSize(pExpr->pLeft))>1
&& sqlite3ExprVectorSize(pExpr->pRight)==nLeft
- && ( (pExpr->pLeft->flags & EP_xIsSelect)==0
+ && ( (pExpr->pLeft->flags & EP_xIsSelect)==0
|| (pExpr->pRight->flags & EP_xIsSelect)==0)
){
int i;
@@ -1213,7 +1232,7 @@ static void exprAnalyze(
/* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create
** a virtual term for each vector component. The expression object
- ** used by each such virtual term is pExpr (the full vector IN(...)
+ ** used by each such virtual term is pExpr (the full vector IN(...)
** expression). The WhereTerm.iField variable identifies the index within
** the vector on the LHS that the virtual term represents.
**
@@ -1361,13 +1380,16 @@ Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){
Bitmask mask;
if( p==0 ) return 0;
if( p->op==TK_COLUMN ){
- mask = sqlite3WhereGetMask(pMaskSet, p->iTable);
- return mask;
+ return sqlite3WhereGetMask(pMaskSet, p->iTable);
}
+ mask = (p->op==TK_IF_NULL_ROW) ? sqlite3WhereGetMask(pMaskSet, p->iTable) : 0;
assert( !ExprHasProperty(p, EP_TokenOnly) );
- mask = p->pRight ? sqlite3WhereExprUsage(pMaskSet, p->pRight) : 0;
if( p->pLeft ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft);
- if( ExprHasProperty(p, EP_xIsSelect) ){
+ if( p->pRight ){
+ mask |= sqlite3WhereExprUsage(pMaskSet, p->pRight);
+ assert( p->x.pList==0 );
+ }else if( ExprHasProperty(p, EP_xIsSelect) ){
+ if( ExprHasProperty(p, EP_VarSelect) ) pMaskSet->bVarSelect = 1;
mask |= exprSelectUsage(pMaskSet, p->x.pSelect);
}else if( p->x.pList ){
mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList);
@@ -1387,7 +1409,7 @@ Bitmask sqlite3WhereExprListUsage(WhereMaskSet *pMaskSet, ExprList *pList){
/*
-** Call exprAnalyze on all terms in a WHERE clause.
+** Call exprAnalyze on all terms in a WHERE clause.
**
** Note that exprAnalyze() might add new virtual terms onto the
** end of the WHERE clause. We do not want to analyze these new
@@ -1406,7 +1428,7 @@ void sqlite3WhereExprAnalyze(
/*
** For table-valued-functions, transform the function arguments into
-** new WHERE clause terms.
+** new WHERE clause terms.
**
** Each function argument translates into an equality constraint against
** a HIDDEN column in the table.