From 0fe456bb29e7a50a10b0c3da87ce6f963dc8b177 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 12 Mar 2013 18:34:50 +0000 Subject: [PATCH 1/7] A proposed fix for the DESC ORDER BY bug of ticket [4dd95f6943fbd18]. Seems to work, but lots more testing is needed prior to moving to trunk. FossilOrigin-Name: 614a038ad2fe111687d2bc1c0aa716d7eb8fdd7c --- manifest | 19 +++++++++++-------- manifest.uuid | 2 +- src/sqliteInt.h | 1 + src/where.c | 19 ++++++++++++++----- 4 files changed, 27 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index a6db29d38b..315e25336e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Define\s_BSD_SOURCE\swhen\sbuilding\son\sOpenBSD.\sThis\sis\srequired\sfor\sfchmod(). -D 2013-03-11T13:37:52.519 +C A\sproposed\sfix\sfor\sthe\sDESC\sORDER\sBY\sbug\sof\sticket\s[4dd95f6943fbd18].\nSeems\sto\swork,\sbut\slots\smore\stesting\sis\sneeded\sprior\sto\smoving\sto\strunk. +D 2013-03-12T18:34:50.356 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 9a804abbd3cae82d196e4d33aba13239e32522a5 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -179,7 +179,7 @@ F src/shell.c 7c41bfcd9e5bf9d96b9215f79b03a5b2b44a3bca F src/sqlite.h.in 31045976254225e6bf046a96e87b40fa4c1d55e4 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 7183ab832e23db0f934494f16928da127a571d75 -F src/sqliteInt.h 59477c6ddb25e7ed8d8b67f4c58ded254371182e +F src/sqliteInt.h e390bfafb5d65418555ce2464d5a4ad6e57e8c71 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c bedc37ec1a6bb9399944024d63f4c769971955a9 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -252,7 +252,7 @@ F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83 F src/wal.c f5c7b5027d0ed0e9bc9afeb4a3a8dfea762ec7d2 F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b -F src/where.c 8b7690cae8700b385d8a53a39387cf8054d8cc47 +F src/where.c 3db35b6231f3da4147294f59e7a1d339c987af32 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 @@ -1037,7 +1037,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 1da15adba8f6eec69c24ec6385d6f1a7905a388f -R 23658f0952d1a2fe0f61c5471a6869f3 -U dan -Z 6b791dcdadf138e4fa4768d3023bd490 +P f9027cb47bdec8dcebf1f038921b28d9e9928c18 +R 095810c67d8046e935e9a69945867a0f +T *branch * desc-orderby-fix-1 +T *sym-desc-orderby-fix-1 * +T -sym-trunk * +U drh +Z 8fce222dd4f4c4a0834625ece5c0e872 diff --git a/manifest.uuid b/manifest.uuid index 7c0fe040be..3380b73d72 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f9027cb47bdec8dcebf1f038921b28d9e9928c18 \ No newline at end of file +614a038ad2fe111687d2bc1c0aa716d7eb8fdd7c \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index e5b4ccac4b..2f15f150f6 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1931,6 +1931,7 @@ struct WherePlan { u32 wsFlags; /* WHERE_* flags that describe the strategy */ u16 nEq; /* Number of == constraints */ u16 nOBSat; /* Number of ORDER BY terms satisfied */ + u16 iOBSat; /* First ORDER BY term satisfied */ double nRow; /* Estimated number of rows (for EQP) */ union { Index *pIdx; /* Index when WHERE_INDEXED is true */ diff --git a/src/where.c b/src/where.c index aa81dabd47..d281ed3000 100644 --- a/src/where.c +++ b/src/where.c @@ -1834,6 +1834,7 @@ static void bestOrClauseIndex(WhereBestIdx *p){ p->cost.used = used; p->cost.plan.nRow = nRow; p->cost.plan.nOBSat = p->i ? p->aLevel[p->i-1].plan.nOBSat : 0; + p->cost.plan.iOBSat = p->cost.plan.nOBSat; p->cost.plan.wsFlags = flags; p->cost.plan.u.pTerm = pTerm; } @@ -3775,7 +3776,8 @@ static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){ static int codeEqualityTerm( Parse *pParse, /* The parsing context */ WhereTerm *pTerm, /* The term of the WHERE clause to be coded */ - WhereLevel *pLevel, /* When level of the FROM clause we are working on */ + WhereLevel *pLevel, /* The level of the FROM clause we are working on */ + int iEq, /* Index of the equality term within this level */ int iTarget /* Attempt to leave results in this register */ ){ Expr *pX = pTerm->pExpr; @@ -3793,8 +3795,15 @@ static int codeEqualityTerm( int eType; int iTab; struct InLoop *pIn; - u8 bRev = (pLevel->plan.wsFlags & WHERE_REVERSE)!=0; + u8 bRev; + if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){ + Index *pIdx = pLevel->plan.u.pIdx; + bRev = pIdx->aSortOrder[iEq+pLevel->plan.iOBSat]; + }else{ + bRev = 0; + } + if( pLevel->plan.wsFlags & WHERE_REVERSE ) bRev = 1 - bRev; assert( pX->op==TK_IN ); iReg = iTarget; eType = sqlite3FindInIndex(pParse, pX, 0); @@ -3912,7 +3921,7 @@ static int codeAllEqualityTerms( ** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */ testcase( (pTerm->wtFlags & TERM_CODED)!=0 ); testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */ - r1 = codeEqualityTerm(pParse, pTerm, pLevel, regBase+j); + r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, regBase+j); if( r1!=regBase+j ){ if( nReg==1 ){ sqlite3ReleaseTempReg(pParse, regBase); @@ -4189,7 +4198,7 @@ static Bitmask codeOneLoopStart( int iTarget = iReg+j+1; pTerm = &pWC->a[aConstraint[k].iTermOffset]; if( pTerm->eOperator & WO_IN ){ - codeEqualityTerm(pParse, pTerm, pLevel, iTarget); + codeEqualityTerm(pParse, pTerm, pLevel, k, iTarget); addrNotFound = pLevel->addrNxt; }else{ sqlite3ExprCode(pParse, pTerm->pExpr->pRight, iTarget); @@ -4230,7 +4239,7 @@ static Bitmask codeOneLoopStart( assert( pTerm->pExpr!=0 ); assert( omitTable==0 ); testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */ - iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, iReleaseReg); + iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, iReleaseReg); addrNxt = pLevel->addrNxt; sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt); sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, iRowidReg); From 7a3e147ee210c432d70647e6187567e4d77b8e04 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 12 Mar 2013 18:40:20 +0000 Subject: [PATCH 2/7] Revised fix for the DESC ORDER BY and IN constraint bug, ticket [4dd95f6943fbd18]. The previous check-in was incorrect. FossilOrigin-Name: 8b2eb7a43b4580f04c14ea8600cf080e0e7f384d --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/sqliteInt.h | 1 - src/where.c | 4 +--- 4 files changed, 9 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 315e25336e..22288ce63c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C A\sproposed\sfix\sfor\sthe\sDESC\sORDER\sBY\sbug\sof\sticket\s[4dd95f6943fbd18].\nSeems\sto\swork,\sbut\slots\smore\stesting\sis\sneeded\sprior\sto\smoving\sto\strunk. -D 2013-03-12T18:34:50.356 +C Revised\sfix\sfor\sthe\sDESC\sORDER\sBY\sand\sIN\sconstraint\sbug,\nticket\s[4dd95f6943fbd18].\s\sThe\sprevious\scheck-in\swas\sincorrect. +D 2013-03-12T18:40:20.150 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 9a804abbd3cae82d196e4d33aba13239e32522a5 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -179,7 +179,7 @@ F src/shell.c 7c41bfcd9e5bf9d96b9215f79b03a5b2b44a3bca F src/sqlite.h.in 31045976254225e6bf046a96e87b40fa4c1d55e4 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 7183ab832e23db0f934494f16928da127a571d75 -F src/sqliteInt.h e390bfafb5d65418555ce2464d5a4ad6e57e8c71 +F src/sqliteInt.h 59477c6ddb25e7ed8d8b67f4c58ded254371182e F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c bedc37ec1a6bb9399944024d63f4c769971955a9 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -252,7 +252,7 @@ F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83 F src/wal.c f5c7b5027d0ed0e9bc9afeb4a3a8dfea762ec7d2 F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b -F src/where.c 3db35b6231f3da4147294f59e7a1d339c987af32 +F src/where.c 6c2940f1fabea37d06a80770d2ad71971cf712b5 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 @@ -1037,10 +1037,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P f9027cb47bdec8dcebf1f038921b28d9e9928c18 -R 095810c67d8046e935e9a69945867a0f -T *branch * desc-orderby-fix-1 -T *sym-desc-orderby-fix-1 * -T -sym-trunk * +P 614a038ad2fe111687d2bc1c0aa716d7eb8fdd7c +R 2313f5d24d87760ccf57697a6a9ba832 U drh -Z 8fce222dd4f4c4a0834625ece5c0e872 +Z 3b6f4b92866e810112286b959abeaefd diff --git a/manifest.uuid b/manifest.uuid index 3380b73d72..6788caa20e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -614a038ad2fe111687d2bc1c0aa716d7eb8fdd7c \ No newline at end of file +8b2eb7a43b4580f04c14ea8600cf080e0e7f384d \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 2f15f150f6..e5b4ccac4b 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1931,7 +1931,6 @@ struct WherePlan { u32 wsFlags; /* WHERE_* flags that describe the strategy */ u16 nEq; /* Number of == constraints */ u16 nOBSat; /* Number of ORDER BY terms satisfied */ - u16 iOBSat; /* First ORDER BY term satisfied */ double nRow; /* Estimated number of rows (for EQP) */ union { Index *pIdx; /* Index when WHERE_INDEXED is true */ diff --git a/src/where.c b/src/where.c index d281ed3000..e1cc7a1837 100644 --- a/src/where.c +++ b/src/where.c @@ -1834,7 +1834,6 @@ static void bestOrClauseIndex(WhereBestIdx *p){ p->cost.used = used; p->cost.plan.nRow = nRow; p->cost.plan.nOBSat = p->i ? p->aLevel[p->i-1].plan.nOBSat : 0; - p->cost.plan.iOBSat = p->cost.plan.nOBSat; p->cost.plan.wsFlags = flags; p->cost.plan.u.pTerm = pTerm; } @@ -3798,8 +3797,7 @@ static int codeEqualityTerm( u8 bRev; if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){ - Index *pIdx = pLevel->plan.u.pIdx; - bRev = pIdx->aSortOrder[iEq+pLevel->plan.iOBSat]; + bRev = pLevel->plan.u.pIdx->aSortOrder[iEq]; }else{ bRev = 0; } From d7e8689078edf40dea9c71b06c7c9ec27cdf081d Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 12 Mar 2013 18:44:49 +0000 Subject: [PATCH 3/7] Add test cases for [4dd95f6943]. FossilOrigin-Name: 723c144c76fc171e5d19072d6d42a08013921ec6 --- manifest | 13 +++--- manifest.uuid | 2 +- test/tkt-4dd95f6943.test | 90 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 7 deletions(-) create mode 100644 test/tkt-4dd95f6943.test diff --git a/manifest b/manifest index 22288ce63c..923a152b6d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Revised\sfix\sfor\sthe\sDESC\sORDER\sBY\sand\sIN\sconstraint\sbug,\nticket\s[4dd95f6943fbd18].\s\sThe\sprevious\scheck-in\swas\sincorrect. -D 2013-03-12T18:40:20.150 +C Add\stest\scases\sfor\s[4dd95f6943]. +D 2013-03-12T18:44:49.167 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 9a804abbd3cae82d196e4d33aba13239e32522a5 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -778,6 +778,7 @@ F test/tkt-3998683a16.test 6d1d04d551ed1704eb3396ca87bb9ccc8c5c1eb7 F test/tkt-3a77c9714e.test 32bb28afa8c63fc76e972e996193139b63551ed9 F test/tkt-3fe897352e.test 10de1a67bd5c66b238a4c96abe55531b37bb4f00 F test/tkt-4a03edc4c8.test 2865e4edbc075b954daa82f8da7cc973033ec76e +F test/tkt-4dd95f6943.test 906062d9d09a9373f4db23d07afc91efab792149 F test/tkt-54844eea3f.test a12b851128f46a695e4e378cca67409b9b8f5894 F test/tkt-5d863f876e.test c9f36ca503fa154a3655f92a69d2c30da1747bfa F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84 @@ -1037,7 +1038,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 614a038ad2fe111687d2bc1c0aa716d7eb8fdd7c -R 2313f5d24d87760ccf57697a6a9ba832 -U drh -Z 3b6f4b92866e810112286b959abeaefd +P 8b2eb7a43b4580f04c14ea8600cf080e0e7f384d +R 9034788cece44d65e62540f59178537b +U dan +Z 993779e9755bd8c64570dcd5012e8aeb diff --git a/manifest.uuid b/manifest.uuid index 6788caa20e..a1e9dda464 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8b2eb7a43b4580f04c14ea8600cf080e0e7f384d \ No newline at end of file +723c144c76fc171e5d19072d6d42a08013921ec6 \ No newline at end of file diff --git a/test/tkt-4dd95f6943.test b/test/tkt-4dd95f6943.test new file mode 100644 index 0000000000..8fd6bc8074 --- /dev/null +++ b/test/tkt-4dd95f6943.test @@ -0,0 +1,90 @@ +# 2013 March 13 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set ::testprefix tkt-4dd95f6943 + +do_execsql_test 1.0 { + CREATE TABLE t1(x); + INSERT INTO t1 VALUES (3), (4), (2), (1), (5), (6); +} + +foreach {tn1 idx} { + 1 { CREATE INDEX i1 ON t1(x ASC) } + 2 { CREATE INDEX i1 ON t1(x DESC) } +} { + do_execsql_test 1.$tn1.1 { DROP INDEX IF EXISTS i1; } + do_execsql_test 1.$tn1.2 $idx + + do_execsql_test 1.$tn1.3 { + SELECT x FROM t1 WHERE x IN(2, 4, 5) ORDER BY x ASC; + } {2 4 5} + + do_execsql_test 1.$tn1.4 { + SELECT x FROM t1 WHERE x IN(2, 4, 5) ORDER BY x DESC; + } {5 4 2} +} + + +do_execsql_test 2.0 { + CREATE TABLE t2(x, y); + INSERT INTO t2 VALUES (5, 3), (5, 4), (5, 2), (5, 1), (5, 5), (5, 6); + INSERT INTO t2 VALUES (1, 3), (1, 4), (1, 2), (1, 1), (1, 5), (1, 6); + INSERT INTO t2 VALUES (3, 3), (3, 4), (3, 2), (3, 1), (3, 5), (3, 6); + INSERT INTO t2 VALUES (2, 3), (2, 4), (2, 2), (2, 1), (2, 5), (2, 6); + INSERT INTO t2 VALUES (4, 3), (4, 4), (4, 2), (4, 1), (4, 5), (4, 6); + INSERT INTO t2 VALUES (6, 3), (6, 4), (6, 2), (6, 1), (6, 5), (6, 6); + + CREATE TABLE t3(a, b); + INSERT INTO t3 VALUES (2, 2), (4, 4), (5, 5); + CREATE INDEX t3i1 ON t3(a ASC); + CREATE INDEX t3i2 ON t3(b DESC); +} + +foreach {tn1 idx} { + 1 { CREATE INDEX i1 ON t2(x ASC, y ASC) } + 2 { CREATE INDEX i1 ON t2(x ASC, y DESC) } + 3 { CREATE INDEX i1 ON t2(x DESC, y ASC) } + 4 { CREATE INDEX i1 ON t2(x DESC, y DESC) } + + 5 { CREATE INDEX i1 ON t2(y ASC, x ASC) } + 6 { CREATE INDEX i1 ON t2(y ASC, x DESC) } + 7 { CREATE INDEX i1 ON t2(y DESC, x ASC) } + 8 { CREATE INDEX i1 ON t2(y DESC, x DESC) } +} { + do_execsql_test 2.$tn1.1 { DROP INDEX IF EXISTS i1; } + do_execsql_test 2.$tn1.2 $idx + + foreach {tn2 inexpr} { + 1 "(2, 4, 5)" + 2 "(SELECT a FROM t3)" + 3 "(SELECT b FROM t3)" + } { + do_execsql_test 2.$tn1.3 " + SELECT x, y FROM t2 WHERE x = 1 AND y IN $inexpr ORDER BY x ASC, y ASC; + " {1 2 1 4 1 5} + do_execsql_test 2.$tn1.4 " + SELECT x, y FROM t2 WHERE x = 2 AND y IN $inexpr ORDER BY x ASC, y DESC; + " {2 5 2 4 2 2} + do_execsql_test 2.$tn1.5 " + SELECT x, y FROM t2 WHERE x = 3 AND y IN $inexpr ORDER BY x DESC, y ASC; + " {3 2 3 4 3 5} + do_execsql_test 2.$tn1.6 " + SELECT x, y FROM t2 WHERE x = 4 AND y IN $inexpr ORDER BY x DESC, y DESC; + " {4 5 4 4 4 2} + } +} + +finish_test + From d383216383fdea13fbeb972859bce9622897f88d Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 12 Mar 2013 18:49:25 +0000 Subject: [PATCH 4/7] Revise the patch to make it easier to understand. FossilOrigin-Name: 3ce7eb0265b5be4e23264ae41332b947011ff1ad --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 11 +++++------ 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 923a152b6d..20c07b237f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\scases\sfor\s[4dd95f6943]. -D 2013-03-12T18:44:49.167 +C Revise\sthe\spatch\sto\smake\sit\seasier\sto\sunderstand. +D 2013-03-12T18:49:25.514 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 9a804abbd3cae82d196e4d33aba13239e32522a5 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -252,7 +252,7 @@ F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83 F src/wal.c f5c7b5027d0ed0e9bc9afeb4a3a8dfea762ec7d2 F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b -F src/where.c 6c2940f1fabea37d06a80770d2ad71971cf712b5 +F src/where.c 494da8b32d3d616cf82de5fde00bd9e05a827927 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 @@ -1038,7 +1038,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 8b2eb7a43b4580f04c14ea8600cf080e0e7f384d -R 9034788cece44d65e62540f59178537b -U dan -Z 993779e9755bd8c64570dcd5012e8aeb +P 723c144c76fc171e5d19072d6d42a08013921ec6 +R 8845ff38c1d7ead5133653a3959bc6c8 +U drh +Z d1fe748b8afa7deacbc6c45434b31b72 diff --git a/manifest.uuid b/manifest.uuid index a1e9dda464..1574cb12d2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -723c144c76fc171e5d19072d6d42a08013921ec6 \ No newline at end of file +3ce7eb0265b5be4e23264ae41332b947011ff1ad \ No newline at end of file diff --git a/src/where.c b/src/where.c index e1cc7a1837..a424779a41 100644 --- a/src/where.c +++ b/src/where.c @@ -3794,14 +3794,13 @@ static int codeEqualityTerm( int eType; int iTab; struct InLoop *pIn; - u8 bRev; + u8 bRev = (pLevel->plan.wsFlags & WHERE_REVERSE)!=0; - if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){ - bRev = pLevel->plan.u.pIdx->aSortOrder[iEq]; - }else{ - bRev = 0; + if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 + && pLevel->plan.u.pIdx->aSortOrder[iEq] + ){ + bRev = 1 - bRev; } - if( pLevel->plan.wsFlags & WHERE_REVERSE ) bRev = 1 - bRev; assert( pX->op==TK_IN ); iReg = iTarget; eType = sqlite3FindInIndex(pParse, pX, 0); From 1ccce44937732f9aa7717fe25702a4c30ddf6315 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 12 Mar 2013 20:38:51 +0000 Subject: [PATCH 5/7] Fix the ORDER BY optimization with IN constraints when the RHS of the IN constraint is a descending index. FossilOrigin-Name: 62316ebaca933f7e5df2018e8360a2b74234f30a --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 12 +++++++----- src/sqliteInt.h | 3 ++- src/where.c | 3 ++- 5 files changed, 20 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 20c07b237f..6f61f7129c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Revise\sthe\spatch\sto\smake\sit\seasier\sto\sunderstand. -D 2013-03-12T18:49:25.514 +C Fix\sthe\sORDER\sBY\soptimization\swith\sIN\sconstraints\swhen\sthe\sRHS\sof\sthe\nIN\sconstraint\sis\sa\sdescending\sindex. +D 2013-03-12T20:38:51.980 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 9a804abbd3cae82d196e4d33aba13239e32522a5 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -130,7 +130,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 72a70dcfda75d3a1f81041ce4573e7afddcd8e4e F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/delete.c aeabdabeeeaa0584127f291baa9617153d334778 -F src/expr.c a23b4aac2a455b2e76b55bef5dcfbe62b665375c +F src/expr.c d488bb60e54c9305d9fca1fa6fcc7bfbd23b13a2 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e16942bd5c8a868ac53287886464a5ed0e72b179 F src/func.c 48987c025d69399f59a1c2a553cea5da41bf105d @@ -179,7 +179,7 @@ F src/shell.c 7c41bfcd9e5bf9d96b9215f79b03a5b2b44a3bca F src/sqlite.h.in 31045976254225e6bf046a96e87b40fa4c1d55e4 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 7183ab832e23db0f934494f16928da127a571d75 -F src/sqliteInt.h 59477c6ddb25e7ed8d8b67f4c58ded254371182e +F src/sqliteInt.h 0f8f05ee4db4ba9120b38f7a3992b325698f6e8a F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c bedc37ec1a6bb9399944024d63f4c769971955a9 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -252,7 +252,7 @@ F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83 F src/wal.c f5c7b5027d0ed0e9bc9afeb4a3a8dfea762ec7d2 F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b -F src/where.c 494da8b32d3d616cf82de5fde00bd9e05a827927 +F src/where.c 6fdacd2cd56995aaef80209f2697d97a92d6a96f F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 @@ -1038,7 +1038,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 723c144c76fc171e5d19072d6d42a08013921ec6 -R 8845ff38c1d7ead5133653a3959bc6c8 +P 3ce7eb0265b5be4e23264ae41332b947011ff1ad +R 18267d07fe1bd58129b86fe1181a82df U drh -Z d1fe748b8afa7deacbc6c45434b31b72 +Z f2422d1eba1fcbdba1a4cf32638de827 diff --git a/manifest.uuid b/manifest.uuid index 1574cb12d2..8bb08b37c7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3ce7eb0265b5be4e23264ae41332b947011ff1ad \ No newline at end of file +62316ebaca933f7e5df2018e8360a2b74234f30a \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 4f38ab0a46..ed5451b1c5 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1456,10 +1456,11 @@ int sqlite3CodeOnce(Parse *pParse){ ** ** The returned value of this function indicates the b-tree type, as follows: ** -** IN_INDEX_ROWID - The cursor was opened on a database table. -** IN_INDEX_INDEX - The cursor was opened on a database index. -** IN_INDEX_EPH - The cursor was opened on a specially created and -** populated epheremal table. +** IN_INDEX_ROWID - The cursor was opened on a database table. +** IN_INDEX_INDEX_ASC - The cursor was opened on an ascending index. +** IN_INDEX_INDEX_DESC - The cursor was opened on a descending index. +** IN_INDEX_EPH - The cursor was opened on a specially created and +** populated epheremal table. ** ** An existing b-tree might be used if the RHS expression pX is a simple ** subquery such as: @@ -1582,7 +1583,8 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ sqlite3VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, iDb, pKey,P4_KEYINFO_HANDOFF); VdbeComment((v, "%s", pIdx->zName)); - eType = IN_INDEX_INDEX; + assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 ); + eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0]; sqlite3VdbeJumpHere(v, iAddr); if( prNotFound && !pTab->aCol[iCol].notNull ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index e5b4ccac4b..129c4c5ea5 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3263,7 +3263,8 @@ const char *sqlite3JournalModename(int); #define IN_INDEX_ROWID 1 #define IN_INDEX_EPH 2 -#define IN_INDEX_INDEX 3 +#define IN_INDEX_INDEX_ASC 3 +#define IN_INDEX_INDEX_DESC 4 int sqlite3FindInIndex(Parse *, Expr *, int*); #ifdef SQLITE_ENABLE_ATOMIC_WRITE diff --git a/src/where.c b/src/where.c index a424779a41..d570b239c2 100644 --- a/src/where.c +++ b/src/where.c @@ -3799,11 +3799,12 @@ static int codeEqualityTerm( if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 && pLevel->plan.u.pIdx->aSortOrder[iEq] ){ - bRev = 1 - bRev; + bRev = !bRev; } assert( pX->op==TK_IN ); iReg = iTarget; eType = sqlite3FindInIndex(pParse, pX, 0); + if( eType==IN_INDEX_INDEX_DESC ) bRev = !bRev; iTab = pX->iTable; sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0); assert( pLevel->plan.wsFlags & WHERE_IN_ABLE ); From 3c60421864c8c8ecd394407ad28b1ab42a921b82 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 12 Mar 2013 22:13:33 +0000 Subject: [PATCH 6/7] Fix a test case that had an ambiguous result. FossilOrigin-Name: 38c6bddf8cf15fb358858da6da457046f40b61ce --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/descidx3.test | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 6f61f7129c..8f607ca689 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sORDER\sBY\soptimization\swith\sIN\sconstraints\swhen\sthe\sRHS\sof\sthe\nIN\sconstraint\sis\sa\sdescending\sindex. -D 2013-03-12T20:38:51.980 +C Fix\sa\stest\scase\sthat\shad\san\sambiguous\sresult. +D 2013-03-12T22:13:33.818 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 9a804abbd3cae82d196e4d33aba13239e32522a5 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -376,7 +376,7 @@ F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab F test/descidx1.test 533dcbda614b0463b0ea029527fd27e5a9ab2d66 F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d -F test/descidx3.test fe720e8b37d59f4cef808b0bf4e1b391c2e56b6f +F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2 F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e F test/distinct.test 84da1414b2e6887fffd5ed571311b344c5b082ce F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376 @@ -1038,7 +1038,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 3ce7eb0265b5be4e23264ae41332b947011ff1ad -R 18267d07fe1bd58129b86fe1181a82df +P 62316ebaca933f7e5df2018e8360a2b74234f30a +R 79ce1fde79ba1a1f337a01fab19de6ab U drh -Z f2422d1eba1fcbdba1a4cf32638de827 +Z ee8768f6007874088c82d4e86c289fa1 diff --git a/manifest.uuid b/manifest.uuid index 8bb08b37c7..c3b3020b8c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -62316ebaca933f7e5df2018e8360a2b74234f30a \ No newline at end of file +38c6bddf8cf15fb358858da6da457046f40b61ce \ No newline at end of file diff --git a/test/descidx3.test b/test/descidx3.test index 3cc87afa5f..c375acc705 100644 --- a/test/descidx3.test +++ b/test/descidx3.test @@ -132,11 +132,11 @@ ifcapable subquery { # the IN(...) operator is not available. Hence these tests cannot be # run. do_test descidx3-4.1 { - execsql { + lsort [execsql { UPDATE t1 SET a=2 WHERE i<6; SELECT i FROM t1 WHERE a IN (1,2) AND b>0 AND b<'zzz'; - } - } {8 6 2 4 3} + }] + } {2 3 4 6 8} do_test descidx3-4.2 { execsql { UPDATE t1 SET a=1; From 725e1ae52e75f126a3c1113ab3c37bce8eedf76b Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 12 Mar 2013 23:58:42 +0000 Subject: [PATCH 7/7] Add a single new test case to the ORDER BY with IN logic verify that if the RHS of the IN is a descending index that it still works. Add testcase() macros to the ORDER BY with IN logic to help verify that corner cases are tested. FossilOrigin-Name: 7e7356f1552cd53ea363d1ded3b2c221c9d0be01 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 9 ++++++++- test/tkt-4dd95f6943.test | 13 ++++++++++++- 4 files changed, 28 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 8f607ca689..18f233c95a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stest\scase\sthat\shad\san\sambiguous\sresult. -D 2013-03-12T22:13:33.818 +C Add\sa\ssingle\snew\stest\scase\sto\sthe\sORDER\sBY\swith\sIN\slogic\sverify\sthat\sif\sthe\nRHS\sof\sthe\sIN\sis\sa\sdescending\sindex\sthat\sit\sstill\sworks.\s\sAdd\stestcase()\nmacros\sto\sthe\sORDER\sBY\swith\sIN\slogic\sto\shelp\sverify\sthat\scorner\scases\sare\ntested. +D 2013-03-12T23:58:42.037 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 9a804abbd3cae82d196e4d33aba13239e32522a5 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -252,7 +252,7 @@ F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83 F src/wal.c f5c7b5027d0ed0e9bc9afeb4a3a8dfea762ec7d2 F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b -F src/where.c 6fdacd2cd56995aaef80209f2697d97a92d6a96f +F src/where.c bdbbfa7ef4ea04c8d9b09585b45d4717a72f980a F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 @@ -778,7 +778,7 @@ F test/tkt-3998683a16.test 6d1d04d551ed1704eb3396ca87bb9ccc8c5c1eb7 F test/tkt-3a77c9714e.test 32bb28afa8c63fc76e972e996193139b63551ed9 F test/tkt-3fe897352e.test 10de1a67bd5c66b238a4c96abe55531b37bb4f00 F test/tkt-4a03edc4c8.test 2865e4edbc075b954daa82f8da7cc973033ec76e -F test/tkt-4dd95f6943.test 906062d9d09a9373f4db23d07afc91efab792149 +F test/tkt-4dd95f6943.test b7fad82ce61a2650fa4861f903ee002c253730c3 F test/tkt-54844eea3f.test a12b851128f46a695e4e378cca67409b9b8f5894 F test/tkt-5d863f876e.test c9f36ca503fa154a3655f92a69d2c30da1747bfa F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84 @@ -1038,7 +1038,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 62316ebaca933f7e5df2018e8360a2b74234f30a -R 79ce1fde79ba1a1f337a01fab19de6ab +P 38c6bddf8cf15fb358858da6da457046f40b61ce +R 2dfce1e78b3d8600ba8f21b6bcbf51de U drh -Z ee8768f6007874088c82d4e86c289fa1 +Z 8bb717049072de8821087ba5a31c44c6 diff --git a/manifest.uuid b/manifest.uuid index c3b3020b8c..1339ff1366 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -38c6bddf8cf15fb358858da6da457046f40b61ce \ No newline at end of file +7e7356f1552cd53ea363d1ded3b2c221c9d0be01 \ No newline at end of file diff --git a/src/where.c b/src/where.c index d570b239c2..25f3d4c54d 100644 --- a/src/where.c +++ b/src/where.c @@ -3799,12 +3799,19 @@ static int codeEqualityTerm( if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 && pLevel->plan.u.pIdx->aSortOrder[iEq] ){ + testcase( iEq==0 ); + testcase( iEq==pLevel->plan.u.pIdx->nColumn-1 ); + testcase( iEq>0 && iEq+1plan.u.pIdx->nColumn ); + testcase( bRev ); bRev = !bRev; } assert( pX->op==TK_IN ); iReg = iTarget; eType = sqlite3FindInIndex(pParse, pX, 0); - if( eType==IN_INDEX_INDEX_DESC ) bRev = !bRev; + if( eType==IN_INDEX_INDEX_DESC ){ + testcase( bRev ); + bRev = !bRev; + } iTab = pX->iTable; sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0); assert( pLevel->plan.wsFlags & WHERE_IN_ABLE ); diff --git a/test/tkt-4dd95f6943.test b/test/tkt-4dd95f6943.test index 8fd6bc8074..6590118370 100644 --- a/test/tkt-4dd95f6943.test +++ b/test/tkt-4dd95f6943.test @@ -86,5 +86,16 @@ foreach {tn1 idx} { } } -finish_test +do_execsql_test 3.0 { + CREATE TABLE t7(x); + INSERT INTO t7 VALUES (1), (2), (3); + CREATE INDEX i7 ON t7(x); + CREATE TABLE t8(y); + INSERT INTO t8 VALUES (1), (2), (3); + + CREATE UNIQUE INDEX i8 ON t8(y DESC); + SELECT x FROM t7 WHERE x IN (SELECT y FROM t8) ORDER BY x ASC; +} {1 2 3} + +finish_test