From 382bdeabefc740398f8fd6e55d12a8d952965d85 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 27 Mar 2014 14:05:38 +0000 Subject: [PATCH 1/9] Enhance the logest.c utility with new operators: "dup", "inv", "log", and "nlogn". Provide help on an invalid input. FossilOrigin-Name: b4bd2a062c4baf5f622d61b7411f00de5904ef56 --- manifest | 14 ++++++------ manifest.uuid | 2 +- tool/logest.c | 62 ++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 52 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index fed419c7cf..fc133ce7b9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\san\sextra\stest\scase\sfor\sthe\spotential\sbuffer\soverread\spatched\sby\s[28ddecff04]. -D 2014-03-26T15:14:59.762 +C Enhance\sthe\slogest.c\sutility\swith\snew\soperators:\s"dup",\s"inv",\s"log",\sand\n"nlogn".\s\sProvide\shelp\son\san\sinvalid\sinput. +D 2014-03-27T14:05:38.733 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1121,7 +1121,7 @@ F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/lemon.c 07aba6270d5a5016ba8107b09e431eea4ecdc123 F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc -F tool/logest.c 7ad625cac3d54012b27d468b7af6612f78b9ba75 +F tool/logest.c 388c318c7ac8b52b7c08ca1e2de0f4ca9a8f7e81 F tool/mkautoconfamal.sh f8d8dbf7d62f409ebed5134998bf5b51d7266383 F tool/mkkeywordhash.c c9e05e4a7bcab8fab9f583d5b321fb72f565ad97 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e @@ -1159,7 +1159,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 2b28e8d582cf10936fa1faca04a16ca2eeead66f -R 76c12b0a4284d7654cb2771b2fc9c8eb -U dan -Z 22c3e1f8cdae5a20dae420dc313d8edd +P f585f5d7a0f9bf8c590388654a3638231eba8892 +R fc449dde2f7cf3aac00c9e1a5da52aee +U drh +Z ebedee01c152a936b8dfbac0e8a85bc4 diff --git a/manifest.uuid b/manifest.uuid index bdc4496d4e..bf7192882e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f585f5d7a0f9bf8c590388654a3638231eba8892 \ No newline at end of file +b4bd2a062c4baf5f622d61b7411f00de5904ef56 \ No newline at end of file diff --git a/tool/logest.c b/tool/logest.c index 8dad6cc9b6..1ac337d36c 100644 --- a/tool/logest.c +++ b/tool/logest.c @@ -17,13 +17,7 @@ ** ** ./LogEst ARGS ** -** Arguments: -** -** 'x' Multiple the top two elements of the stack -** '+' Add the top two elements of the stack -** NUM Convert NUM from integer to LogEst and push onto the stack -** ^NUM Interpret NUM as a LogEst and push onto stack. -** +** See the showHelp() routine for a description of valid arguments. ** Examples: ** ** To convert 123 from LogEst to integer: @@ -97,12 +91,31 @@ static LogEst logEstFromDouble(double x){ return e*10; } +int isInteger(const char *z){ + while( z[0]>='0' && z[0]<='9' ) z++; + return z[0]==0; +} + int isFloat(const char *z){ - while( z[0] ){ - if( z[0]=='.' || z[0]=='E' || z[0]=='e' ) return 1; - z++; - } - return 0; + char c; + while( ((c=z[0])>='0' && c<='9') || c=='.' || c=='E' || c=='e' + || c=='+' || c=='-' ) z++; + return z[0]==0; +} + +static void showHelp(const char *zArgv0){ + printf("Usage: %s ARGS...\n", zArgv0); + printf("Arguments:\n" + " NUM Convert NUM from integer to LogEst and push onto the stack\n" + " ^NUM Interpret NUM as a LogEst and push onto stack\n" + " x Multiple the top two elements of the stack\n" + " + Add the top two elements of the stack\n" + " dup Dupliate the top element on the stack\n" + " inv Take the reciprocal of the top of stack. N = 1/N.\n" + " log Find the LogEst of the number on top of stack\n" + " nlogn Compute NlogN where N is the top of stack\n" + ); + exit(1); } int main(int argc, char **argv){ @@ -111,30 +124,43 @@ int main(int argc, char **argv){ LogEst a[100]; for(i=1; i=2 ){ a[n-2] = logEstAdd(a[n-2],a[n-1]); n--; } - }else if( z[0]=='x' ){ + }else if( strcmp(z,"x")==0 ){ if( n>=2 ){ a[n-2] = logEstMultiply(a[n-2],a[n-1]); n--; } + }else if( strcmp(z,"dup")==0 ){ + if( n>0 ){ + a[n] = a[n-1]; + n++; + } + }else if( strcmp(z,"log")==0 ){ + if( n>0 ) a[n-1] = logEstFromInteger(a[n-1]) - 33; + }else if( strcmp(z,"nlogn")==0 ){ + if( n>0 ) a[n-1] += logEstFromInteger(a[n-1]) - 33; + }else if( strcmp(z,"inv")==0 ){ + if( n>0 ) a[n-1] = -a[n-1]; }else if( z[0]=='^' ){ a[n++] = atoi(z+1); - }else if( isFloat(z) ){ + }else if( isInteger(z) ){ + a[n++] = logEstFromInteger(atoi(z)); + }else if( isFloat(z) && z[0]!='-' ){ a[n++] = logEstFromDouble(atof(z)); }else{ - a[n++] = logEstFromInteger(atoi(z)); + showHelp(argv[0]); } } for(i=n-1; i>=0; i--){ if( a[i]<0 ){ - printf("%d (%f)\n", a[i], 1.0/(double)logEstToInt(-a[i])); + printf("%5d (%f)\n", a[i], 1.0/(double)logEstToInt(-a[i])); }else{ sqlite3_uint64 x = logEstToInt(a[i]+100)*100/1024; - printf("%d (%lld.%02lld)\n", a[i], x/100, x%100); + printf("%5d (%lld.%02lld)\n", a[i], x/100, x%100); } } return 0; From 27de5c5cb623fcdbfe4aa128a30a08a5efa268f4 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 27 Mar 2014 18:36:34 +0000 Subject: [PATCH 2/9] Minor cleanup of the code in the query planner that computes the costs estimates for the various plans. There are no changes to the costs at this time. But the code is slightly more readable now and that might facilitate future enhancements. FossilOrigin-Name: 9b4d7226bcee38be5ac68a54bee03b4179cb69fc --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 44 ++++++++++++++++++++++++++++++++++---------- 3 files changed, 41 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index fc133ce7b9..c8233bfa12 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\slogest.c\sutility\swith\snew\soperators:\s"dup",\s"inv",\s"log",\sand\n"nlogn".\s\sProvide\shelp\son\san\sinvalid\sinput. -D 2014-03-27T14:05:38.733 +C Minor\scleanup\sof\sthe\scode\sin\sthe\squery\splanner\sthat\scomputes\sthe\scosts\s\nestimates\sfor\sthe\svarious\splans.\s\sThere\sare\sno\schanges\sto\sthe\scosts\sat\sthis\ntime.\s\sBut\sthe\scode\sis\sslightly\smore\sreadable\snow\sand\sthat\smight\sfacilitate\nfuture\senhancements. +D 2014-03-27T18:36:34.321 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -291,7 +291,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c da8ec216f14af617505799b0b4e52c73dda7a5ca +F src/where.c 7c53de68bd6762848b746510cf4eb077ffd7d70d F src/whereInt.h 2564055b440e44ebec8b47f237bbccae6719b7af F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1159,7 +1159,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P f585f5d7a0f9bf8c590388654a3638231eba8892 -R fc449dde2f7cf3aac00c9e1a5da52aee +P b4bd2a062c4baf5f622d61b7411f00de5904ef56 +R 96966a646967b8a2388d32a924ac0ae2 U drh -Z ebedee01c152a936b8dfbac0e8a85bc4 +Z 308d20d60c0618b1b3ae79dc397c2638 diff --git a/manifest.uuid b/manifest.uuid index bf7192882e..65bd2a013d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b4bd2a062c4baf5f622d61b7411f00de5904ef56 \ No newline at end of file +9b4d7226bcee38be5ac68a54bee03b4179cb69fc \ No newline at end of file diff --git a/src/where.c b/src/where.c index 15084f099a..16e7e40bc3 100644 --- a/src/where.c +++ b/src/where.c @@ -4328,18 +4328,34 @@ static int whereLoopAddBtree( ) ){ pNew->iSortIdx = b ? iSortIdx : 0; + /* TUNING: The base cost of an index scan is N + log2(N). + ** The log2(N) is for the initial seek to the beginning and the N + ** is for the scan itself. */ + pNew->rRun = sqlite3LogEstAdd(rSize, rLogSize); if( m==0 ){ /* TUNING: Cost of a covering index scan is K*(N + log2(N)). ** + The extra factor K of between 1.1 and 3.0 that depends ** on the relative sizes of the table and the index. K ** is smaller for smaller indices, thus favoring them. + ** The upper bound on K (3.0) matches the penalty factor + ** on a full table scan that tries to encourage the use of + ** indexed lookups over full scans. */ - pNew->rRun = sqlite3LogEstAdd(rSize,rLogSize) + 1 + - (15*pProbe->szIdxRow)/pTab->szTabRow; + pNew->rRun += 1 + (15*pProbe->szIdxRow)/pTab->szTabRow; }else{ - /* TUNING: Cost of scanning a non-covering index is (N+1)*log2(N) - ** which we will simplify to just N*log2(N) */ - pNew->rRun = rSize + rLogSize; + /* TUNING: The cost of scanning a non-covering index is multiplied + ** by log2(N) to account for the binary search of the main table + ** that must happen for each row of the index. + ** TODO: Should there be a multiplier here, analogous to the 3x + ** multiplier for a fulltable scan or covering index scan, to + ** further discourage the use of an index scan? Or is the log2(N) + ** term sufficient discouragement? + ** TODO: What if some or all of the WHERE clause terms can be + ** computed without reference to the original table. Then the + ** penality should reduce to logK where K is the number of output + ** rows. + */ + pNew->rRun += rLogSize; } whereLoopOutputAdjust(pWC, pNew); rc = whereLoopInsert(pBuilder, pNew); @@ -5041,11 +5057,19 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags, iLoop, pWLoop, &revMask); if( isOrdered>=0 && isOrdered0 ); + rScale = sqlite3LogEst((nOrderBy-isOrdered)*100/nOrderBy) - 66; + rSortCost = nRowEst + estLog(nRowEst) + rScale; /* TUNING: The cost of implementing DISTINCT using a B-TREE is ** also N*log(N) but it has a larger constant of proportionality. ** Multiply by 3.0. */ From a1f7c0a21c65431a3fbfeba25ab7f1e9ad827273 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 28 Mar 2014 03:12:48 +0000 Subject: [PATCH 3/9] Enhance the sqlite3VdbeRecordCompare() routines so that if they encounter database corruption, they will set the UnpackedRecord.isCorrupt field and return 0. The sqlite3BtreeMovetoUnpacked() routine detects this and returns SQLITE_CORRUPT, causing the corruption to be reported back to the top-level. FossilOrigin-Name: 7fa85eaaaf6d211378620d728a759fdfe30a15b0 --- manifest | 24 ++++++++++++------------ manifest.uuid | 2 +- src/btree.c | 3 +++ src/sqliteInt.h | 1 + src/vdbe.h | 4 ++-- src/vdbeInt.h | 2 +- src/vdbeaux.c | 27 +++++++++++++++++++-------- test/corruptG.test | 11 +++-------- test/corruptI.test | 2 +- 9 files changed, 43 insertions(+), 33 deletions(-) diff --git a/manifest b/manifest index c8233bfa12..48ca1421b2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\scleanup\sof\sthe\scode\sin\sthe\squery\splanner\sthat\scomputes\sthe\scosts\s\nestimates\sfor\sthe\svarious\splans.\s\sThere\sare\sno\schanges\sto\sthe\scosts\sat\sthis\ntime.\s\sBut\sthe\scode\sis\sslightly\smore\sreadable\snow\sand\sthat\smight\sfacilitate\nfuture\senhancements. -D 2014-03-27T18:36:34.321 +C Enhance\sthe\ssqlite3VdbeRecordCompare()\sroutines\sso\sthat\sif\sthey\sencounter\ndatabase\scorruption,\sthey\swill\sset\sthe\sUnpackedRecord.isCorrupt\sfield\sand\nreturn\s0.\s\sThe\ssqlite3BtreeMovetoUnpacked()\sroutine\sdetects\sthis\sand\sreturns\nSQLITE_CORRUPT,\scausing\sthe\scorruption\sto\sbe\sreported\sback\sto\sthe\stop-level. +D 2014-03-28T03:12:48.763 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -164,7 +164,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 8d7e432bdd27d63182865c708ea0e7606489b6d1 +F src/btree.c a59a199f21338ae1847d69f5db87c3e8ef1b1578 F src/btree.h 232836cb51753f2e96aa8ce0f052c6df850f76ba F src/btreeInt.h 0be66063468a520e4d66b80c7a1dc26d04ee6ea4 F src/build.c 0d50ef95aad63f4c4fc47f3fa2670d4557c45db0 @@ -222,7 +222,7 @@ F src/shell.c cee9f46f2688a261601b1fd3d7f4b3cddf9b5cdf F src/sqlite.h.in a2ef671f92747a5a1c8a47bad5c585a8dd9eca80 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h afbf39e96736ceb85e1d896b281ba2406dd70aa0 +F src/sqliteInt.h cc9582a91b2910404ccda7b7e198815ea0f75948 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -279,10 +279,10 @@ F src/utf.c 6dc9ec9f1b3db43ae8ba0365377f11df1ee4c01c F src/util.c c46c90459ef9bdc0c6c73803cf4c55425b4771cf F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 F src/vdbe.c 74c7386e83eee56f921a17bb4a0396c9551f5bc7 -F src/vdbe.h fb2c48c198300a7c632f09fc940011d2ad2fc2ae -F src/vdbeInt.h 2b9a6849166d0014c843ae3fd83a062be4efa325 +F src/vdbe.h 394464909ed682334aa3d5831aae0c2fe2abef94 +F src/vdbeInt.h e6d83e5bfd62fc6685ba1ed6153f7099f82de9f7 F src/vdbeapi.c 0ed6053f947edd0b30f64ce5aeb811872a3450a4 -F src/vdbeaux.c f81ef920dcf76aceaa1ce77081e9fc5d7a0993dd +F src/vdbeaux.c 1153175fb57a8454e1c8cf79b59b7bf92b26779d F src/vdbeblob.c 15377abfb59251bccedd5a9c7d014a895f0c04aa F src/vdbemem.c 6fc77594c60f6155404f3f8d71bf36d1fdeb4447 F src/vdbesort.c 4abb7c0f8f19b7d7d82f4558d5da1a30fdf9ea38 @@ -403,9 +403,9 @@ F test/corruptC.test 02405cf7ed0c1e989060e1aab6d02ffbc3906fbb F test/corruptD.test b3c205fac7952b1de645ce44bb02335cd9e3e040 F test/corruptE.test 193b4ca4e927e77c1d5f4f56203ddc998432a7ee F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4 -F test/corruptG.test 58ec333a01997fe655e34e5bea52b7a2a6b9704d +F test/corruptG.test 1ab3bf97ee7bdba70e0ff3ba2320657df55d1804 F test/corruptH.test 88ed71a086e13591c917aac6de32750e7c7281cb -F test/corruptI.test 1b796461e5b635e0a74e3c4ecb1121c82d319dff +F test/corruptI.test b3e4203d420490fc3d3062711597bc1dea06a789 F test/count.test 42a251178e32f617eda33f76236a7f79825a50b5 F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62 F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f @@ -1159,7 +1159,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P b4bd2a062c4baf5f622d61b7411f00de5904ef56 -R 96966a646967b8a2388d32a924ac0ae2 +P 9b4d7226bcee38be5ac68a54bee03b4179cb69fc +R e6ff5922142fb694f528da1c1b2a1baf U drh -Z 308d20d60c0618b1b3ae79dc397c2638 +Z 2ba581858b0e7a94365bc5b4fc44e179 diff --git a/manifest.uuid b/manifest.uuid index 65bd2a013d..ef58fd2f6f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9b4d7226bcee38be5ac68a54bee03b4179cb69fc \ No newline at end of file +7fa85eaaaf6d211378620d728a759fdfe30a15b0 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 43d41d67e9..c3055836c9 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4588,6 +4588,7 @@ int sqlite3BtreeMovetoUnpacked( if( pIdxKey ){ xRecordCompare = sqlite3VdbeFindCompare(pIdxKey); + pIdxKey->isCorrupt = 0; assert( pIdxKey->default_rc==1 || pIdxKey->default_rc==0 || pIdxKey->default_rc==-1 @@ -4711,6 +4712,7 @@ int sqlite3BtreeMovetoUnpacked( c = xRecordCompare(nCell, pCellKey, pIdxKey, 0); sqlite3_free(pCellKey); } + assert( pIdxKey->isCorrupt==0 || c==0 ); if( c<0 ){ lwr = idx+1; }else if( c>0 ){ @@ -4720,6 +4722,7 @@ int sqlite3BtreeMovetoUnpacked( *pRes = 0; rc = SQLITE_OK; pCur->aiIdx[pCur->iPage] = (u16)idx; + if( pIdxKey->isCorrupt ) rc = SQLITE_CORRUPT; goto moveto_finish; } if( lwr>upr ) break; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 5e0dd91ec9..0f67748fc8 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1627,6 +1627,7 @@ struct UnpackedRecord { KeyInfo *pKeyInfo; /* Collation and sort-order information */ u16 nField; /* Number of entries in apMem[] */ i8 default_rc; /* Comparison result if keys are equal */ + u8 isCorrupt; /* Corruption detected by xRecordCompare() */ Mem *aMem; /* Values */ int r1; /* Value to return if (lhs > rhs) */ int r2; /* Value to return if (rhs < lhs) */ diff --git a/src/vdbe.h b/src/vdbe.h index 8e300b88a6..10a4140ee1 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -211,10 +211,10 @@ void sqlite3VdbeSetVarmask(Vdbe*, int); #endif void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); -int sqlite3VdbeRecordCompare(int,const void*,const UnpackedRecord*,int); +int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*,int); UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **); -typedef int (*RecordCompare)(int,const void*,const UnpackedRecord*,int); +typedef int (*RecordCompare)(int,const void*,UnpackedRecord*,int); RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*); #ifndef SQLITE_OMIT_TRIGGER diff --git a/src/vdbeInt.h b/src/vdbeInt.h index b752478035..043b56da59 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -392,7 +392,7 @@ u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); void sqlite3VdbeDeleteAuxData(Vdbe*, int, int); int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); -int sqlite3VdbeIdxKeyCompare(VdbeCursor*,const UnpackedRecord*,int*); +int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*); int sqlite3VdbeIdxRowid(sqlite3*, BtCursor *, i64 *); int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); int sqlite3VdbeExec(Vdbe*); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index f5e4b0a9fc..0ce21378d5 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3405,10 +3405,13 @@ static i64 vdbeRecordDecodeInt(u32 serial_type, const u8 *aKey){ ** Key1 and Key2 do not have to contain the same number of fields. If all ** fields that appear in both keys are equal, then pPKey2->default_rc is ** returned. +** +** If database corruption is discovered, set pPKey2->isCorrupt to non-zero +** and return 0. */ int sqlite3VdbeRecordCompare( int nKey1, const void *pKey1, /* Left key */ - const UnpackedRecord *pPKey2, /* Right key */ + UnpackedRecord *pPKey2, /* Right key */ int bSkip /* If true, skip the first field */ ){ u32 d1; /* Offset into aKey[] of next data element */ @@ -3434,7 +3437,10 @@ int sqlite3VdbeRecordCompare( }else{ idx1 = getVarint32(aKey1, szHdr1); d1 = szHdr1; - if( d1>(unsigned)nKey1 ) return 1; /* Corruption */ + if( d1>(unsigned)nKey1 ){ + pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT; + return 0; /* Corruption */ + } i = 0; } @@ -3511,7 +3517,8 @@ int sqlite3VdbeRecordCompare( testcase( (d1+mem1.n)==(unsigned)nKey1 ); testcase( (d1+mem1.n+1)==(unsigned)nKey1 ); if( (d1+mem1.n) > (unsigned)nKey1 ){ - rc = 1; /* Corruption */ + pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT; + return 0; /* Corruption */ }else if( pKeyInfo->aColl[i] ){ mem1.enc = pKeyInfo->enc; mem1.db = pKeyInfo->db; @@ -3537,7 +3544,8 @@ int sqlite3VdbeRecordCompare( testcase( (d1+nStr)==(unsigned)nKey1 ); testcase( (d1+nStr+1)==(unsigned)nKey1 ); if( (d1+nStr) > (unsigned)nKey1 ){ - rc = 1; /* Corruption */ + pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT; + return 0; /* Corruption */ }else{ int nCmp = MIN(nStr, pRhs->n); rc = memcmp(&aKey1[d1], pRhs->z, nCmp); @@ -3596,7 +3604,7 @@ int sqlite3VdbeRecordCompare( */ static int vdbeRecordCompareInt( int nKey1, const void *pKey1, /* Left key */ - const UnpackedRecord *pPKey2, /* Right key */ + UnpackedRecord *pPKey2, /* Right key */ int bSkip /* Ignored */ ){ const u8 *aKey = &((const u8*)pKey1)[*(const u8*)pKey1 & 0x3F]; @@ -3694,7 +3702,7 @@ static int vdbeRecordCompareInt( */ static int vdbeRecordCompareString( int nKey1, const void *pKey1, /* Left key */ - const UnpackedRecord *pPKey2, /* Right key */ + UnpackedRecord *pPKey2, /* Right key */ int bSkip ){ const u8 *aKey1 = (const u8*)pKey1; @@ -3715,7 +3723,10 @@ static int vdbeRecordCompareString( int szHdr = aKey1[0]; nStr = (serial_type-12) / 2; - if( (szHdr + nStr) > nKey1 ) return 0; /* Corruption */ + if( (szHdr + nStr) > nKey1 ){ + pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT; + return 0; /* Corruption */ + } nCmp = MIN( pPKey2->aMem[0].n, nStr ); res = memcmp(&aKey1[szHdr], pPKey2->aMem[0].z, nCmp); @@ -3880,7 +3891,7 @@ idx_rowid_corruption: */ int sqlite3VdbeIdxKeyCompare( VdbeCursor *pC, /* The cursor to compare against */ - const UnpackedRecord *pUnpacked, /* Unpacked version of key */ + UnpackedRecord *pUnpacked, /* Unpacked version of key */ int *res /* Write the comparison result here */ ){ i64 nCellKey = 0; diff --git a/test/corruptG.test b/test/corruptG.test index 1ec5d6f6a9..af920edf41 100644 --- a/test/corruptG.test +++ b/test/corruptG.test @@ -47,12 +47,12 @@ do_test 1.2 { catchsql { SELECT c FROM t1 WHERE a>'abc'; } -} {0 {}} +} {1 {database disk image is malformed}} do_test 1.3 { catchsql { PRAGMA integrity_check } -} {0 ok} +} {1 {database disk image is malformed}} do_test 1.4 { catchsql { SELECT c FROM t1 ORDER BY a; @@ -71,11 +71,6 @@ do_test 2.1 { catchsql { SELECT rowid FROM t1 WHERE a='abc' and b='xyz123456789XYZ'; } - # The following test result is brittle. The point above is to try to - # force a buffer overread by a corrupt database file. If we get an - # incorrect answer from a corrupt database file, that is OK. If the - # result below changes, that just means that "undefined behavior" has - # changed. -} {/0 .*/} +} {1 {database disk image is malformed}} finish_test diff --git a/test/corruptI.test b/test/corruptI.test index 087a0f3b01..ed34c0f8c3 100644 --- a/test/corruptI.test +++ b/test/corruptI.test @@ -51,7 +51,7 @@ do_test 1.3 { hexio_write test.db $off FFFF7f02 sqlite3 db test.db catchsql { SELECT * FROM t1 WHERE a = 10 } -} {0 {}} +} {1 {database disk image is malformed}} do_test 2.0 { execsql { From 36ed03428d501b8de6b86aeca09f27c9ec5869ad Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 28 Mar 2014 12:56:57 +0000 Subject: [PATCH 4/9] Fix a harmless compiler warning. FossilOrigin-Name: a4e47150f32b3a4120b1f89ccc66d633d829e3bb --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 48ca1421b2..3f74055a6f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\ssqlite3VdbeRecordCompare()\sroutines\sso\sthat\sif\sthey\sencounter\ndatabase\scorruption,\sthey\swill\sset\sthe\sUnpackedRecord.isCorrupt\sfield\sand\nreturn\s0.\s\sThe\ssqlite3BtreeMovetoUnpacked()\sroutine\sdetects\sthis\sand\sreturns\nSQLITE_CORRUPT,\scausing\sthe\scorruption\sto\sbe\sreported\sback\sto\sthe\stop-level. -D 2014-03-28T03:12:48.763 +C Fix\sa\sharmless\scompiler\swarning. +D 2014-03-28T12:56:57.685 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -291,7 +291,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c 7c53de68bd6762848b746510cf4eb077ffd7d70d +F src/where.c 7d539cedb1c6a6d6b5d2075b8fea3a48db4838eb F src/whereInt.h 2564055b440e44ebec8b47f237bbccae6719b7af F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1159,7 +1159,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 9b4d7226bcee38be5ac68a54bee03b4179cb69fc -R e6ff5922142fb694f528da1c1b2a1baf +P 7fa85eaaaf6d211378620d728a759fdfe30a15b0 +R 84c408a5c4c5e7a44048ef6100ea9043 U drh -Z 2ba581858b0e7a94365bc5b4fc44e179 +Z 645b10a99877639c66e2a5f7ed2d5a66 diff --git a/manifest.uuid b/manifest.uuid index ef58fd2f6f..b73eec43f2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7fa85eaaaf6d211378620d728a759fdfe30a15b0 \ No newline at end of file +a4e47150f32b3a4120b1f89ccc66d633d829e3bb \ No newline at end of file diff --git a/src/where.c b/src/where.c index 16e7e40bc3..93ee8c59c3 100644 --- a/src/where.c +++ b/src/where.c @@ -4936,7 +4936,7 @@ static i8 wherePathSatisfiesOrderBy( } } } /* End the loop over all WhereLoops from outer-most down to inner-most */ - if( obSat==obDone ) return nOrderBy; + if( obSat==obDone ) return (i8)nOrderBy; if( !isOrderDistinct ){ for(i=nOrderBy-1; i>0; i--){ Bitmask m = MASKBIT(i) - 1; From 70c93204ea3e1b37750dd7f362dfe379101cba68 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 28 Mar 2014 14:41:35 +0000 Subject: [PATCH 5/9] Disable the wal64k.test script for non-unix systems since it depends on unix-only features. FossilOrigin-Name: 27deb6e49bcc76714dbdc61b34748603155ac770 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/wal64k.test | 6 +++++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 3f74055a6f..52d212de1d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sharmless\scompiler\swarning. -D 2014-03-28T12:56:57.685 +C Disable\sthe\swal64k.test\sscript\sfor\snon-unix\ssystems\ssince\sit\sdepends\son\nunix-only\sfeatures. +D 2014-03-28T14:41:35.536 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1056,7 +1056,7 @@ F test/wal3.test b22eb662bcbc148c5f6d956eaf94b047f7afe9c0 F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c F test/wal5.test 8f888b50f66b78821e61ed0e233ded5de378224b F test/wal6.test 527581f5527bf9c24394991e2be83000aace5f9e -F test/wal64k.test 63828c2161ad76ddd4109dee0a096b6ef6895698 +F test/wal64k.test 163655ecd2cb8afef4737cac2a40fdd2eeaf20b8 F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd F test/wal8.test 75c42e1bc4545c277fed212f8fc9b7723cd02216 F test/wal9.test 378e76a9ad09cd9bee06c172ad3547b0129a6750 @@ -1159,7 +1159,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 7fa85eaaaf6d211378620d728a759fdfe30a15b0 -R 84c408a5c4c5e7a44048ef6100ea9043 +P a4e47150f32b3a4120b1f89ccc66d633d829e3bb +R 578568415288cd31fe0adba6128329da U drh -Z 645b10a99877639c66e2a5f7ed2d5a66 +Z 045e2748905f8bd05ecf1197b97d7f20 diff --git a/manifest.uuid b/manifest.uuid index b73eec43f2..d9c988d4d5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a4e47150f32b3a4120b1f89ccc66d633d829e3bb \ No newline at end of file +27deb6e49bcc76714dbdc61b34748603155ac770 \ No newline at end of file diff --git a/test/wal64k.test b/test/wal64k.test index afd820778e..e962da128e 100644 --- a/test/wal64k.test +++ b/test/wal64k.test @@ -19,6 +19,11 @@ set testprefix wal64k ifcapable !wal {finish_test ; return } +if {$tcl_platform(platform) != "unix"} { + finish_test + return +} + db close test_syscall pagesize 65536 sqlite3 db test.db @@ -44,4 +49,3 @@ integrity_check 1.3 db close test_syscall pagesize -1 finish_test - From b663587890f557c9926964710f6f1e8121040c88 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 31 Mar 2014 13:42:42 +0000 Subject: [PATCH 6/9] Avoid a (harmless) buffer overread that is possible on an OOM when MEMSYS5 is engaged. FossilOrigin-Name: b3296267fb67b9f59719a37093253062edde3746 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/mem5.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 52d212de1d..887bb92f5b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\sthe\swal64k.test\sscript\sfor\snon-unix\ssystems\ssince\sit\sdepends\son\nunix-only\sfeatures. -D 2014-03-28T14:41:35.536 +C Avoid\sa\s(harmless)\sbuffer\soverread\sthat\sis\spossible\son\san\sOOM\swhen\nMEMSYS5\sis\sengaged. +D 2014-03-31T13:42:42.977 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -192,7 +192,7 @@ F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b F src/mem2.c dce31758da87ec2cfa52ba4c5df1aed6e07d8e8f F src/mem3.c 61c9d47b792908c532ca3a62b999cf21795c6534 -F src/mem5.c aeb019f271ea53de83d651ec526877e6ba863450 +F src/mem5.c 74670012946c4adc8a6ad84d03acc80959c3e529 F src/memjournal.c 0683aac6cab6ec2b5374c0db37c0deb2436a3785 F src/mutex.c d3b66a569368015e0fcb1ac15f81c119f504d3bc F src/mutex.h 5bc526e19dccc412b7ff04642f6fdad3fdfdabea @@ -1159,7 +1159,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P a4e47150f32b3a4120b1f89ccc66d633d829e3bb -R 578568415288cd31fe0adba6128329da +P 27deb6e49bcc76714dbdc61b34748603155ac770 +R 74e3f11f049d7792447568e00e413b7f U drh -Z 045e2748905f8bd05ecf1197b97d7f20 +Z 4989508149fff1b415b46911a02fce9e diff --git a/manifest.uuid b/manifest.uuid index d9c988d4d5..70f95ac337 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -27deb6e49bcc76714dbdc61b34748603155ac770 \ No newline at end of file +b3296267fb67b9f59719a37093253062edde3746 \ No newline at end of file diff --git a/src/mem5.c b/src/mem5.c index 5d75611a32..67615bb964 100644 --- a/src/mem5.c +++ b/src/mem5.c @@ -248,7 +248,7 @@ static void *memsys5MallocUnsafe(int nByte){ ** block. If not, then split a block of the next larger power of ** two in order to create a new free block of size iLogsize. */ - for(iBin=iLogsize; mem5.aiFreelist[iBin]<0 && iBin<=LOGMAX; iBin++){} + for(iBin=iLogsize; iBin<=LOGMAX && mem5.aiFreelist[iBin]<0; iBin++){} if( iBin>LOGMAX ){ testcase( sqlite3GlobalConfig.xLog!=0 ); sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes", nByte); From 54d0d2dd9a5898ac33363877b0aba360a81d1d5e Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 3 Apr 2014 00:32:13 +0000 Subject: [PATCH 7/9] In the command-line shell, run set writable_schema before running the ".clone" command. FossilOrigin-Name: 9d2ae6342c8afa904bec591ebe134ff7f536b71c --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 2 ++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 887bb92f5b..8f224e8e55 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sa\s(harmless)\sbuffer\soverread\sthat\sis\spossible\son\san\sOOM\swhen\nMEMSYS5\sis\sengaged. -D 2014-03-31T13:42:42.977 +C In\sthe\scommand-line\sshell,\srun\sset\swritable_schema\sbefore\srunning\sthe\n".clone"\scommand. +D 2014-04-03T00:32:13.777 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -218,7 +218,7 @@ F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 273d5f47c4e2c05b2d3d2bffeda939551ab59e66 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 269c3e31a450fce642a10569221a49180348c88e -F src/shell.c cee9f46f2688a261601b1fd3d7f4b3cddf9b5cdf +F src/shell.c 5260f2ada8dd06e9f5ae0a448c8c01e7a75dd881 F src/sqlite.h.in a2ef671f92747a5a1c8a47bad5c585a8dd9eca80 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc @@ -1159,7 +1159,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 27deb6e49bcc76714dbdc61b34748603155ac770 -R 74e3f11f049d7792447568e00e413b7f +P b3296267fb67b9f59719a37093253062edde3746 +R 3857796e3bb74e57525267a0574c950a U drh -Z 4989508149fff1b415b46911a02fce9e +Z e5eef1fbe323934e85f2b63b760c4a7b diff --git a/manifest.uuid b/manifest.uuid index 70f95ac337..e11bac748d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b3296267fb67b9f59719a37093253062edde3746 \ No newline at end of file +9d2ae6342c8afa904bec591ebe134ff7f536b71c \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 1313112709..f380962a86 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2130,10 +2130,12 @@ static void tryToClone(struct callback_data *p, const char *zNewDb){ fprintf(stderr, "Cannot create output database: %s\n", sqlite3_errmsg(newDb)); }else{ + sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0); sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0); tryToCloneSchema(p, newDb, "type='table'", tryToCloneData); tryToCloneSchema(p, newDb, "type!='table'", 0); sqlite3_exec(newDb, "COMMIT;", 0, 0, 0); + sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0); } sqlite3_close(newDb); } From 831116d1646b01498ca8d7d2b2280eaaea61052b Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 3 Apr 2014 14:31:00 +0000 Subject: [PATCH 8/9] Fix a typo in the "Synopsis:" comment for the OP_VFilter opcode. FossilOrigin-Name: 48ecdd4aff03741f96c070dced69c3c273b652cb --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 8f224e8e55..a63a365841 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\scommand-line\sshell,\srun\sset\swritable_schema\sbefore\srunning\sthe\n".clone"\scommand. -D 2014-04-03T00:32:13.777 +C Fix\sa\stypo\sin\sthe\s"Synopsis:"\scomment\sfor\sthe\sOP_VFilter\sopcode. +D 2014-04-03T14:31:00.074 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -278,7 +278,7 @@ F src/update.c 5b3e74a03b3811e586b4f2b4cbd7c49f01c93115 F src/utf.c 6dc9ec9f1b3db43ae8ba0365377f11df1ee4c01c F src/util.c c46c90459ef9bdc0c6c73803cf4c55425b4771cf F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 74c7386e83eee56f921a17bb4a0396c9551f5bc7 +F src/vdbe.c e811a0081149fb90db367026d154cd7efb3c7098 F src/vdbe.h 394464909ed682334aa3d5831aae0c2fe2abef94 F src/vdbeInt.h e6d83e5bfd62fc6685ba1ed6153f7099f82de9f7 F src/vdbeapi.c 0ed6053f947edd0b30f64ce5aeb811872a3450a4 @@ -1159,7 +1159,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P b3296267fb67b9f59719a37093253062edde3746 -R 3857796e3bb74e57525267a0574c950a +P 9d2ae6342c8afa904bec591ebe134ff7f536b71c +R 06523ad1e0d97e48aa9a162217a28d3b U drh -Z e5eef1fbe323934e85f2b63b760c4a7b +Z 64c7c8526eed6d4962d61576f8ab00f6 diff --git a/manifest.uuid b/manifest.uuid index e11bac748d..5984b7794c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9d2ae6342c8afa904bec591ebe134ff7f536b71c \ No newline at end of file +48ecdd4aff03741f96c070dced69c3c273b652cb \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 84f720b526..2d1d23e079 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5929,7 +5929,7 @@ case OP_VOpen: { #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VFilter P1 P2 P3 P4 * -** Synopsis: iPlan=r[P3] zPlan='P4' +** Synopsis: iplan=r[P3] zplan='P4' ** ** P1 is a cursor opened using VOpen. P2 is an address to jump to if ** the filtered result set is empty. From c438df1be06f636ef68265f083aff4af95d326e6 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 3 Apr 2014 16:29:31 +0000 Subject: [PATCH 9/9] Use OP_Copy instead of OP_SCopy when moving results out of a subquery, to prevent the subquery results from changing out from under the outer query. Fix for ticket [1e64dd782a126f48d78]. FossilOrigin-Name: d5513dfa23baa0b0a095aaf17d19aacd30dcef61 --- manifest | 15 ++++++++------- manifest.uuid | 2 +- src/where.c | 2 +- test/whereG.test | 13 +++++++++++++ 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index a63a365841..4bcee0a832 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sin\sthe\s"Synopsis:"\scomment\sfor\sthe\sOP_VFilter\sopcode. -D 2014-04-03T14:31:00.074 +C Use\sOP_Copy\sinstead\sof\sOP_SCopy\swhen\smoving\sresults\sout\sof\sa\ssubquery,\nto\sprevent\sthe\ssubquery\sresults\sfrom\schanging\sout\sfrom\sunder\sthe\souter\nquery.\s\sFix\sfor\sticket\s[1e64dd782a126f48d78]. +D 2014-04-03T16:29:31.330 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -291,7 +291,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c 7d539cedb1c6a6d6b5d2075b8fea3a48db4838eb +F src/where.c ebad891b7494d0c5f925cf7ab135380bd958cba3 F src/whereInt.h 2564055b440e44ebec8b47f237bbccae6719b7af F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1092,7 +1092,7 @@ F test/whereC.test d6f4ecd4fa2d9429681a5b22a25d2bda8e86ab8a F test/whereD.test 6c2feb79ef1f68381b07f39017fe5f9b96da8d62 F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f F test/whereF.test 5b2ba0dbe8074aa13e416b37c753991f0a2492d7 -F test/whereG.test eb3a46b3eaf38e25e3013433b2db8a25a866c215 +F test/whereG.test 2533b72ed4a31fd1687230a499b557b911525344 F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31 F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c @@ -1159,7 +1159,8 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 9d2ae6342c8afa904bec591ebe134ff7f536b71c -R 06523ad1e0d97e48aa9a162217a28d3b +P 48ecdd4aff03741f96c070dced69c3c273b652cb +Q +ec6a06246e04eee5f25f1c28507df73b697099c0 +R b6a2fefa5b61ea0e64da4db2aaa10286 U drh -Z 64c7c8526eed6d4962d61576f8ab00f6 +Z f1f1ceb5f31f4e26d736a13a2a5aca0f diff --git a/manifest.uuid b/manifest.uuid index 5984b7794c..601b0b4f2e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -48ecdd4aff03741f96c070dced69c3c273b652cb \ No newline at end of file +d5513dfa23baa0b0a095aaf17d19aacd30dcef61 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 93ee8c59c3..dd6893f69f 100644 --- a/src/where.c +++ b/src/where.c @@ -5924,7 +5924,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ for(; kp1!=pLevel->iTabCur ) continue; if( pOp->opcode==OP_Column ){ - pOp->opcode = OP_SCopy; + pOp->opcode = OP_Copy; pOp->p1 = pOp->p2 + pTabItem->regResult; pOp->p2 = pOp->p3; pOp->p3 = 0; diff --git a/test/whereG.test b/test/whereG.test index 490fffe64e..17d5653223 100644 --- a/test/whereG.test +++ b/test/whereG.test @@ -166,5 +166,18 @@ do_eqp_test whereG-3.4 { SELECT * FROM a, b WHERE a2=5 AND a1=b1; } {/.*SCAN TABLE a.*SEARCH TABLE b USING INDEX .*b_1 .b1=..*/} +# Ticket [1e64dd782a126f48d78c43a664844a41d0e6334e]: +# Incorrect result in a nested GROUP BY/DISTINCT due to the use of an OP_SCopy +# where an OP_Copy was needed. +# +do_execsql_test whereG-4.0 { + CREATE TABLE t4(x); + INSERT INTO t4 VALUES('right'),('wrong'); + SELECT DISTINCT x + FROM (SELECT x FROM t4 GROUP BY x) + WHERE x='right' + ORDER BY x; +} {right} + finish_test