aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordan <dan@noemail.net>2016-07-29 18:12:12 +0000
committerdan <dan@noemail.net>2016-07-29 18:12:12 +0000
commit145b4ea519b7826e7905628c479549994e405b0b (patch)
tree146ca79f037aed1d233d1a6c112b9135fa1a905e /src
parent7b35a77b1a389d87cb5df356266b400e07d55afb (diff)
downloadsqlite-145b4ea519b7826e7905628c479549994e405b0b.tar.gz
sqlite-145b4ea519b7826e7905628c479549994e405b0b.zip
Change the way "(a, b) = (SELECT *)" expressions are handled in where.c if there is an index on one of the columns only.
FossilOrigin-Name: 4dfebff2924f46284d5b9cda69175f79b29d6028
Diffstat (limited to 'src')
-rw-r--r--src/expr.c12
-rw-r--r--src/sqliteInt.h3
-rw-r--r--src/wherecode.c32
-rw-r--r--src/whereexpr.c4
4 files changed, 31 insertions, 20 deletions
diff --git a/src/expr.c b/src/expr.c
index 2921898d3..3dcb73ff1 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -3512,18 +3512,6 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
break;
}
- case TK_SELECT_COLUMN: {
- Expr *pLeft = pExpr->pLeft;
- assert( pLeft );
- assert( pLeft->op==TK_SELECT || pLeft->op==TK_REGISTER );
- if( pLeft->op==TK_SELECT ){
- pLeft->iTable = sqlite3CodeSubselect(pParse, pLeft, 0, 0);
- pLeft->op = TK_REGISTER;
- }
- inReg = pLeft->iTable + pExpr->iColumn;
- break;
- }
-
/*
** Form A:
** CASE x WHEN e1 THEN r1 WHEN e2 THEN r2 ... WHEN eN THEN rN ELSE y END
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index ea41e6575..9dfc0bcaa 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -3936,7 +3936,8 @@ void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
int sqlite3GetToken(const unsigned char *, int *);
void sqlite3NestedParse(Parse*, const char*, ...);
void sqlite3ExpirePreparedStatements(sqlite3*);
-int sqlite3CodeSubselect(Parse *, Expr *, int, int);
+int sqlite3CodeSubselect(Parse*, Expr *, int, int);
+int sqlite3ExprCheckIN(Parse*, Expr*);
void sqlite3SelectPrep(Parse*, Select*, NameContext*);
void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p);
int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
diff --git a/src/wherecode.c b/src/wherecode.c
index 892831d82..9db4a0146 100644
--- a/src/wherecode.c
+++ b/src/wherecode.c
@@ -359,7 +359,31 @@ static int codeEqualityTerm(
assert( pLevel->pWLoop->aLTerm[iEq]==pTerm );
assert( iTarget>0 );
if( pX->op==TK_EQ || pX->op==TK_IS ){
- iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget);
+ Expr *pRight = pX->pRight;
+ if( pRight->op==TK_SELECT_COLUMN ){
+ /* This case occurs for expressions like "(a, b) == (SELECT ...)". */
+ WhereLoop *pLoop = pLevel->pWLoop;
+ int i;
+ Expr *pSub = pRight->pLeft;
+ assert( pSub->op==TK_SELECT );
+ for(i=pLoop->nSkip; i<iEq; i++){
+ Expr *pExpr = pLoop->aLTerm[i]->pExpr->pRight;
+ if( pExpr && pExpr->op==TK_SELECT_COLUMN && pExpr->pLeft==pSub ) break;
+ }
+
+ if( i==iEq ){
+ iReg = sqlite3CodeSubselect(pParse, pSub, 0, 0);
+ for(/*no-op*/; i<pLoop->nLTerm; i++){
+ Expr *pExpr = pLoop->aLTerm[i]->pExpr->pRight;
+ if( pExpr && pExpr->op==TK_SELECT_COLUMN && pExpr->pLeft==pSub ){
+ sqlite3VdbeAddOp2(v, OP_Copy, iReg+pExpr->iColumn, iTarget-iEq+i);
+ }
+ }
+ }
+ iReg = iTarget;
+ }else{
+ iReg = sqlite3ExprCodeTarget(pParse, pRight, iTarget);
+ }
}else if( pX->op==TK_ISNULL ){
iReg = iTarget;
sqlite3VdbeAddOp2(v, OP_Null, 0, iReg);
@@ -1489,10 +1513,6 @@ Bitmask sqlite3WhereCodeOneLoopStart(
testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE );
}
- /* Disable the start and end range terms if possible */
- /* disableTerm(pLevel, pRangeStart); */
- /* disableTerm(pLevel, pRangeEnd); */
-
/* Seek the table cursor, if required */
if( omitTable ){
/* pIdx is a covering index. No need to access the main table. */
@@ -1594,7 +1614,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
u16 wctrlFlags; /* Flags for sub-WHERE clause */
Expr *pAndExpr = 0; /* An ".. AND (...)" expression */
Table *pTab = pTabItem->pTab;
-
+
pTerm = pLoop->aLTerm[0];
assert( pTerm!=0 );
assert( pTerm->eOperator & WO_OR );
diff --git a/src/whereexpr.c b/src/whereexpr.c
index 9c9be9903..4b96e2faa 100644
--- a/src/whereexpr.c
+++ b/src/whereexpr.c
@@ -962,7 +962,8 @@ static void exprAnalyze(
Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV;
- if( op==TK_IN && pTerm->iField>0 ){
+ if( pTerm->iField>0 ){
+ assert( op==TK_IN );
assert( pLeft->op==TK_VECTOR );
pLeft = pLeft->x.pList->a[pTerm->iField-1].pExpr;
}
@@ -979,6 +980,7 @@ static void exprAnalyze(
WhereTerm *pNew;
Expr *pDup;
u16 eExtraOp = 0; /* Extra bits for pNew->eOperator */
+ assert( pTerm->iField==0 );
if( pTerm->leftCursor>=0 ){
int idxNew;
pDup = sqlite3ExprDup(db, pExpr, 0);