diff options
author | dan <dan@noemail.net> | 2016-07-29 18:12:12 +0000 |
---|---|---|
committer | dan <dan@noemail.net> | 2016-07-29 18:12:12 +0000 |
commit | 145b4ea519b7826e7905628c479549994e405b0b (patch) | |
tree | 146ca79f037aed1d233d1a6c112b9135fa1a905e /src | |
parent | 7b35a77b1a389d87cb5df356266b400e07d55afb (diff) | |
download | sqlite-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.c | 12 | ||||
-rw-r--r-- | src/sqliteInt.h | 3 | ||||
-rw-r--r-- | src/wherecode.c | 32 | ||||
-rw-r--r-- | src/whereexpr.c | 4 |
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); |