aboutsummaryrefslogtreecommitdiff
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
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
-rw-r--r--manifest20
-rw-r--r--manifest.uuid2
-rw-r--r--src/expr.c12
-rw-r--r--src/sqliteInt.h3
-rw-r--r--src/wherecode.c32
-rw-r--r--src/whereexpr.c4
-rw-r--r--test/rowvalue3.test3
7 files changed, 45 insertions, 31 deletions
diff --git a/manifest b/manifest
index a1321d1be..4ed47839f 100644
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sfurther\sissues\swith\smulti-column\sIN(...)\soperators.\sAlso\ssome\serror\shandling\scases\ssurrounding\srow\svalues.
-D 2016-07-28T19:47:15.803
+C Change\sthe\sway\s"(a,\sb)\s=\s(SELECT\s*)"\sexpressions\sare\shandled\sin\swhere.c\sif\sthere\sis\san\sindex\son\sone\sof\sthe\scolumns\sonly.
+D 2016-07-29T18:12:12.900
F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a
@@ -337,7 +337,7 @@ F src/ctime.c 61949e83c4c36e37195a8398ebc752780b534d95
F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39
F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0
F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f
-F src/expr.c 473ce0ac25868b750f3bf9f59bbe7e8f06a0bdd5
+F src/expr.c d21255d0b778cf819d74092463df7630bbcd9fe7
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413
F src/func.c 61a4114cf7004f10c542cfabbab9f2bcb9033045
@@ -388,7 +388,7 @@ F src/shell.c 9351fc6de11e1d908648c0a92d85627138e3dee5
F src/sqlite.h.in c6e68a4a47610631822a4f8f83a44c9f75339331
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 46f300b6e300e0fa916d7d58c44b53415b8471a9
-F src/sqliteInt.h 65cf752e1a62cedb2430ecc0547a09833ea13616
+F src/sqliteInt.h 65473a83bccce3556425f764900cb1b716b6cfa1
F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247
F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab
F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9
@@ -465,8 +465,8 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2
F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354
F src/where.c df58d6ad7878a08aa96c652ccbc6d0949f8fa472
F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613
-F src/wherecode.c 3aff7683566af3428f865904aafa7efb1fbd8701
-F src/whereexpr.c bc85d04c6751ca40cab99a10de308e44893c76b9
+F src/wherecode.c e259a0b9b0eed28a9b4f5085fa1dfef4c3145361
+F src/whereexpr.c a58e878dad5cad54c100792eb8bafb9840d699f5
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@@ -1020,7 +1020,7 @@ F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81
F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d
F test/rowvalue.test 979738b3d49f1d93e3fee56a71d4446217917abc
F test/rowvalue2.test 8d5dfe75b8f4d1868a2f91f0356f20d36cba64ff
-F test/rowvalue3.test 587c1056016fa6b7a40a9bf6cb85d5443fa47d96
+F test/rowvalue3.test 5127afb4414bf62546161497c04840c46e371770
F test/rowvalue4.test 4480898d62d6813e3e38d9d38c02b9a0be5f94be
F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798
F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09
@@ -1512,7 +1512,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 9685880f7baeb670739fdcf2d9df08e22abaa699
-R 66ab918b4b1a726fe3dea7b50bb8fdb0
+P cc3f6542bec99b00d2698889bcea2aa0b587efa0
+R 02d8106109a69b80c3fcb6354dcce9eb
U dan
-Z 5baa8fdab10ded1fdce6b30d35067148
+Z 1ebe0c81a88c1eb2162a3b6fe26c472e
diff --git a/manifest.uuid b/manifest.uuid
index c951167b8..0edf69435 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-cc3f6542bec99b00d2698889bcea2aa0b587efa0 \ No newline at end of file
+4dfebff2924f46284d5b9cda69175f79b29d6028 \ No newline at end of file
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);
diff --git a/test/rowvalue3.test b/test/rowvalue3.test
index 32c86251d..2da141ec7 100644
--- a/test/rowvalue3.test
+++ b/test/rowvalue3.test
@@ -46,6 +46,7 @@ foreach {tn sql res} {
9 "SELECT (1, 2) IN (SELECT rowid, b FROM t1)" 1
10 "SELECT 1 WHERE (1, 2) IN (SELECT rowid, b FROM t1)" 1
11 "SELECT 1 WHERE (1, NULL) IN (SELECT rowid, b FROM t1)" {}
+ 12 "SELECT 1 FROM t1 WHERE (a, b) = (SELECT +a, +b FROM t1)" {1}
} {
do_execsql_test 1.$tn $sql $res
}
@@ -208,6 +209,8 @@ foreach {tn idx} {
}
}
+#-------------------------------------------------------------------------
+
finish_test