From a95882ff39517ddcd163fe307134b2705aace26c Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 11 Jul 2013 19:04:23 +0000 Subject: [PATCH 01/47] Change the description of how sqlite3_progress_handler() works so that the N parameter is "approximate". This aligns with the current implementation. This is a documentation change only. No changes to code. FossilOrigin-Name: 7d829bdea3adcda50fbe930acb4e1ce73fd874e6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index a4304ca0f0..5db174f506 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sexperimental\s"query_only"\spragma. -D 2013-07-11T15:22:31.810 +C Change\sthe\sdescription\sof\show\ssqlite3_progress_handler()\sworks\sso\sthat\s\nthe\sN\sparameter\sis\s"approximate".\s\sThis\saligns\swith\sthe\scurrent\simplementation.\nThis\sis\sa\sdocumentation\schange\sonly.\s\sNo\schanges\sto\scode. +D 2013-07-11T19:04:23.647 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -218,7 +218,7 @@ F src/resolve.c 89f9003e8316ee3a172795459efc2a0274e1d5a8 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 91b62654caf8dfe292fb8882715e575d34ad3874 F src/shell.c c8cd06e6b66250a3ea0149c4edec30de14f57b6f -F src/sqlite.h.in 80d11140d401f366f7249f3c4fe031c49a5a06f8 +F src/sqlite.h.in c8b27ba43bb35a26b6067b8f24f06c24af2d1b64 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqliteInt.h 6d3115f774aa3e87737f9447c9c0cea992c5bdbf @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 527121ac3cdc96ac33ad975c227a6685a2f7e999 ece960c496717a3a6c25526ef77dd76b08d607bc -R 9c4545357c659a752e6cc07bddb23b90 +P 6557c407983b067449deb76bc4c5248de64e07dc +R 045649ed68015430e04b85aae90e1909 U drh -Z 7d5f7fd6ecb9e38390dc44516a410268 +Z c98b2f615dfc222d1805fcdb692cca6b diff --git a/manifest.uuid b/manifest.uuid index ac9eed930e..5d6223a30d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6557c407983b067449deb76bc4c5248de64e07dc \ No newline at end of file +7d829bdea3adcda50fbe930acb4e1ce73fd874e6 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 4d8ba21f30..eb5ffe3d4c 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2554,7 +2554,7 @@ SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*, ** interface is to keep a GUI updated during a large query. ** ** ^The parameter P is passed through as the only parameter to the -** callback function X. ^The parameter N is the number of +** callback function X. ^The parameter N is the approximate number of ** [virtual machine instructions] that are evaluated between successive ** invocations of the callback X. ** From 8dd675e43f8c59a2802aec13a9a3d8d0b36dbc8a Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 12 Jul 2013 21:09:24 +0000 Subject: [PATCH 02/47] Make sure the shell does not try to put a zero terminator on the end of an unallocated zero-length string when running ".import" on an empty file. FossilOrigin-Name: 92adaee5bd31c152dbc1592f4aeb5d8da957a1ea --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 4 +--- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 5db174f506..6c619adf69 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sdescription\sof\show\ssqlite3_progress_handler()\sworks\sso\sthat\s\nthe\sN\sparameter\sis\s"approximate".\s\sThis\saligns\swith\sthe\scurrent\simplementation.\nThis\sis\sa\sdocumentation\schange\sonly.\s\sNo\schanges\sto\scode. -D 2013-07-11T19:04:23.647 +C Make\ssure\sthe\sshell\sdoes\snot\stry\sto\sput\sa\szero\sterminator\son\sthe\send\sof\san\nunallocated\szero-length\sstring\swhen\srunning\s".import"\son\san\sempty\sfile. +D 2013-07-12T21:09:24.523 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -217,7 +217,7 @@ F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 89f9003e8316ee3a172795459efc2a0274e1d5a8 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 91b62654caf8dfe292fb8882715e575d34ad3874 -F src/shell.c c8cd06e6b66250a3ea0149c4edec30de14f57b6f +F src/shell.c 4c02ec99e42aeb624bb221b253273da6c910b814 F src/sqlite.h.in c8b27ba43bb35a26b6067b8f24f06c24af2d1b64 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 6557c407983b067449deb76bc4c5248de64e07dc -R 045649ed68015430e04b85aae90e1909 +P 7d829bdea3adcda50fbe930acb4e1ce73fd874e6 +R 3ed94849e5c017401e30c707fda6984e U drh -Z c98b2f615dfc222d1805fcdb692cca6b +Z e4e9f4e449a4a8d9a8571763475fda13 diff --git a/manifest.uuid b/manifest.uuid index 5d6223a30d..83ce9c684d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7d829bdea3adcda50fbe930acb4e1ce73fd874e6 \ No newline at end of file +92adaee5bd31c152dbc1592f4aeb5d8da957a1ea \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 79548fa1e4..f0815538ab 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1721,7 +1721,6 @@ static char *csv_read_one_field(CSVReader *p){ || (c==EOF && pc==cQuote) ){ do{ p->n--; }while( p->z[p->n]!=cQuote ); - p->z[p->n] = 0; p->cTerm = c; break; } @@ -1732,7 +1731,6 @@ static char *csv_read_one_field(CSVReader *p){ if( c==EOF ){ fprintf(stderr, "%s:%d: unterminated %c-quoted field\n", p->zFile, startLine, cQuote); - p->z[p->n] = 0; p->cTerm = EOF; break; } @@ -1748,9 +1746,9 @@ static char *csv_read_one_field(CSVReader *p){ p->nLine++; if( p->n>1 && p->z[p->n-1]=='\r' ) p->n--; } - p->z[p->n] = 0; p->cTerm = c; } + if( p->z ) p->z[p->n] = 0; return p->z; } From 425e27db1247aa12729ded283623c1c0c426a3a3 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 15 Jul 2013 17:02:28 +0000 Subject: [PATCH 03/47] Add the sqlite3_cancel_auto_extension(X) interface which will undo a prior call to sqlite3_auto_extension(X). FossilOrigin-Name: cdce87eb889a43dafcc560d5f97ab517d0266860 --- manifest | 18 ++++++++-------- manifest.uuid | 2 +- src/loadext.c | 29 +++++++++++++++++++++++++ src/sqlite.h.in | 15 ++++++++++++- src/test_autoext.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++ test/loadext2.test | 28 ++++++++++++++++++++++-- 6 files changed, 133 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 6c619adf69..c21740737a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthe\sshell\sdoes\snot\stry\sto\sput\sa\szero\sterminator\son\sthe\send\sof\san\nunallocated\szero-length\sstring\swhen\srunning\s".import"\son\san\sempty\sfile. -D 2013-07-12T21:09:24.523 +C Add\sthe\ssqlite3_cancel_auto_extension(X)\sinterface\swhich\swill\sundo\sa\sprior\ncall\sto\ssqlite3_auto_extension(X). +D 2013-07-15T17:02:28.816 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -184,7 +184,7 @@ F src/insert.c f7cb141e8ce257cb6b15c497f09e4e23d6055599 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b -F src/loadext.c c48f7f3f170e502fe0cc20748e03c6e0b5a016c2 +F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303 F src/main.c e5810b2d7a0bd19f3d75ce60e3ed918cafc0a3f3 F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 @@ -218,7 +218,7 @@ F src/resolve.c 89f9003e8316ee3a172795459efc2a0274e1d5a8 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 91b62654caf8dfe292fb8882715e575d34ad3874 F src/shell.c 4c02ec99e42aeb624bb221b253273da6c910b814 -F src/sqlite.h.in c8b27ba43bb35a26b6067b8f24f06c24af2d1b64 +F src/sqlite.h.in 30c88ce7862096b0aecf4c2c886bc0934eeaa515 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqliteInt.h 6d3115f774aa3e87737f9447c9c0cea992c5bdbf @@ -236,7 +236,7 @@ F src/test7.c 126b886b53f0358b92aba9b81d3fcbfbe9a93cd6 F src/test8.c 7ee77ea522ae34aa691dfe407139dec80d4fc039 F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60 F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8 -F src/test_autoext.c 5c95b5d435eaa09d6c0e7d90371c5ca8cd567701 +F src/test_autoext.c 32cff3d01cdd3202486e623c3f8103ed04cb57fa F src/test_backup.c 3875e899222b651e18b662f86e0e50daa946344e F src/test_btree.c 5b89601dcb42a33ba8b820a6b763cc9cb48bac16 F src/test_config.c 95bb33e9dcaa340a296c0bf0e0ba3d1a1c8004c0 @@ -627,7 +627,7 @@ F test/like.test 935fb4f608e3ea126891496a6e99b9468372bf5c F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da F test/limit.test cc0ab63385239b63c72452b0e93700bf5e8f0b99 F test/loadext.test 92e6dfefd1229c3ef4aaabd87419efd8fa57a7a5 -F test/loadext2.test 0bcaeb4d81cd5b6e883fdfea3c1bdbe1f173cbca +F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7 F test/lock.test 87af515b0c4cf928576d0f89946d67d7c265dfb4 F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff F test/lock3.test f271375930711ae044080f4fe6d6eda930870d00 @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 7d829bdea3adcda50fbe930acb4e1ce73fd874e6 -R 3ed94849e5c017401e30c707fda6984e +P 92adaee5bd31c152dbc1592f4aeb5d8da957a1ea +R 3e75a7374bba2c69c55563b837ab8202 U drh -Z e4e9f4e449a4a8d9a8571763475fda13 +Z a6c699be62fa8981abc8311358615b45 diff --git a/manifest.uuid b/manifest.uuid index 83ce9c684d..bad5c44835 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -92adaee5bd31c152dbc1592f4aeb5d8da957a1ea \ No newline at end of file +cdce87eb889a43dafcc560d5f97ab517d0266860 \ No newline at end of file diff --git a/src/loadext.c b/src/loadext.c index cdcf6a93b8..828e865b61 100644 --- a/src/loadext.c +++ b/src/loadext.c @@ -668,6 +668,35 @@ int sqlite3_auto_extension(void (*xInit)(void)){ } } +/* +** Cancel a prior call to sqlite3_auto_extension. Remove xInit from the +** set of routines that is invoked for each new database connection, if it +** is currently on the list. If xInit is not on the list, then this +** routine is a no-op. +** +** Return 1 if xInit was found on the list and removed. Return 0 if xInit +** was not on the list. +*/ +int sqlite3_cancel_auto_extension(void (*xInit)(void)){ +#if SQLITE_THREADSAFE + sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); +#endif + int i; + int n = 0; + wsdAutoextInit; + sqlite3_mutex_enter(mutex); + for(i=wsdAutoext.nExt-1; i>=0; i--){ + if( wsdAutoext.aExt[i]==xInit ){ + wsdAutoext.nExt--; + wsdAutoext.aExt[i] = wsdAutoext.aExt[wsdAutoext.nExt]; + n++; + break; + } + } + sqlite3_mutex_leave(mutex); + return n; +} + /* ** Reset the automatic extension loading mechanism. */ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index eb5ffe3d4c..3b7237996b 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -5123,10 +5123,23 @@ int sqlite3_enable_load_extension(sqlite3 *db, int onoff); ** on the list of automatic extensions is a harmless no-op. ^No entry point ** will be called more than once for each database connection that is opened. ** -** See also: [sqlite3_reset_auto_extension()]. +** See also: [sqlite3_reset_auto_extension()] +** and [sqlite3_cancel_auto_extension()] */ int sqlite3_auto_extension(void (*xEntryPoint)(void)); +/* +** CAPI3REF: Cancel Automatic Extension Loading +** +** ^The [sqlite3_cancel_auto_extension(X)] interface unregisters the +** initialization routine X that was registered using a prior call to +** [sqlite3_auto_extension(X)]. ^The [sqlite3_cancel_auto_extension(X)] +** routine returns 1 if initialization routine X was successfully +** unregistered and it returns 0 if X was not on the list of initialization +** routines. +*/ +int sqlite3_cancel_auto_extension(void (*xEntryPoint)(void)); + /* ** CAPI3REF: Reset Automatic Extension Loading ** diff --git a/src/test_autoext.c b/src/test_autoext.c index b5013f3173..4a5a5caa08 100644 --- a/src/test_autoext.c +++ b/src/test_autoext.c @@ -98,6 +98,22 @@ static int autoExtSqrObjCmd( return SQLITE_OK; } +/* +** tclcmd: sqlite3_cancel_auto_extension_sqr +** +** Unregister the "sqr" extension. +*/ +static int cancelAutoExtSqrObjCmd( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + int rc = sqlite3_cancel_auto_extension((void*)sqr_init); + Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); + return SQLITE_OK; +} + /* ** tclcmd: sqlite3_auto_extension_cube ** @@ -114,6 +130,22 @@ static int autoExtCubeObjCmd( return SQLITE_OK; } +/* +** tclcmd: sqlite3_cancel_auto_extension_cube +** +** Unregister the "cube" extension. +*/ +static int cancelAutoExtCubeObjCmd( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + int rc = sqlite3_cancel_auto_extension((void*)cube_init); + Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); + return SQLITE_OK; +} + /* ** tclcmd: sqlite3_auto_extension_broken ** @@ -130,6 +162,22 @@ static int autoExtBrokenObjCmd( return SQLITE_OK; } +/* +** tclcmd: sqlite3_cancel_auto_extension_broken +** +** Unregister the broken extension. +*/ +static int cancelAutoExtBrokenObjCmd( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + int rc = sqlite3_cancel_auto_extension((void*)broken_init); + Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); + return SQLITE_OK; +} + #endif /* SQLITE_OMIT_LOAD_EXTENSION */ @@ -161,6 +209,12 @@ int Sqlitetest_autoext_Init(Tcl_Interp *interp){ Tcl_CreateObjCommand(interp, "sqlite3_auto_extension_broken", autoExtBrokenObjCmd, 0, 0); #endif + Tcl_CreateObjCommand(interp, "sqlite3_cancel_auto_extension_sqr", + cancelAutoExtSqrObjCmd, 0, 0); + Tcl_CreateObjCommand(interp, "sqlite3_cancel_auto_extension_cube", + cancelAutoExtCubeObjCmd, 0, 0); + Tcl_CreateObjCommand(interp, "sqlite3_cancel_auto_extension_broken", + cancelAutoExtBrokenObjCmd, 0, 0); Tcl_CreateObjCommand(interp, "sqlite3_reset_auto_extension", resetAutoExtObjCmd, 0, 0); return TCL_OK; diff --git a/test/loadext2.test b/test/loadext2.test index 3d01539b31..d5b6ea8d7f 100644 --- a/test/loadext2.test +++ b/test/loadext2.test @@ -43,6 +43,19 @@ do_test loadext2-1.2 { } } {1 {no such function: cube}} +# Extensions loaders not currently registered +# +do_test loadext2-1.2.1 { + sqlite3_cancel_auto_extension_sqr +} {0} +do_test loadext2-1.2.2 { + sqlite3_cancel_auto_extension_sqr +} {0} +do_test loadext2-1.2.3 { + sqlite3_cancel_auto_extension_sqr +} {0} + + # Register auto-loaders. Still functions do not exist. # do_test loadext2-1.3 { @@ -76,8 +89,19 @@ do_test loadext2-1.6 { # Reset extension auto loading. Existing extensions still exist. # -do_test loadext2-1.7 { - sqlite3_reset_auto_extension +do_test loadext2-1.7.1 { + sqlite3_cancel_auto_extension_sqr +} {1} +do_test loadext2-1.7.2 { + sqlite3_cancel_auto_extension_sqr +} {0} +do_test loadext2-1.7.3 { + sqlite3_cancel_auto_extension_cube +} {1} +do_test loadext2-1.7.4 { + sqlite3_cancel_auto_extension_cube +} {0} +do_test loadext2-1.7.5 { catchsql { SELECT sqr(2) } From aa32e3c60a86442bda394bdab8d520eec0b10ba5 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 16 Jul 2013 21:31:23 +0000 Subject: [PATCH 04/47] Enhance the query planner so that it looks at multiple solutions to OR expressions in the WHERE clause. FossilOrigin-Name: 5e19d054105fb16ff52d265d48cc87a418603f6f --- manifest | 16 ++--- manifest.uuid | 2 +- src/where.c | 179 +++++++++++++++++++++++++++++++++-------------- test/where2.test | 11 +++ test/where8.test | 5 +- 5 files changed, 148 insertions(+), 65 deletions(-) diff --git a/manifest b/manifest index c21740737a..aed4f14e23 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite3_cancel_auto_extension(X)\sinterface\swhich\swill\sundo\sa\sprior\ncall\sto\ssqlite3_auto_extension(X). -D 2013-07-15T17:02:28.816 +C Enhance\sthe\squery\splanner\sso\sthat\sit\slooks\sat\smultiple\ssolutions\sto\sOR\nexpressions\sin\sthe\sWHERE\sclause. +D 2013-07-16T21:31:23.453 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -290,7 +290,7 @@ F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83 F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73 -F src/where.c f5201334501cd23a39315cab479c0dcce0990701 +F src/where.c 927acb798c66af64b5d640e50f0edfe07d6b4085 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 @@ -1037,13 +1037,13 @@ F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417 F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e F test/where.test da54153a4c1571ea1b95659e5bec8119edf786aa -F test/where2.test d712de0ea9a2c3de7b34b0b1e75172556fef5b24 +F test/where2.test b1830f762f837153a4c9743adaab90a5761f73e7 F test/where3.test a0682ba3dc8c8f46ffcc95a3d9f58c4327fc129f F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2 F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2 F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b F test/where7.test 5a4b0abc207d71da4deecd734ad8579e8dd40aa8 -F test/where8.test f6b9559723564a042927ee0f22003ac9bed71b21 +F test/where8.test 6f95896633cf2d307b5263145b942b7d33e837c6 F test/where8m.test da346596e19d54f0aba35ebade032a7c47d79739 F test/where9.test 9a7fda4a4512abc26a855e8b2b6572b200f6019b F test/whereA.test 24c234263c8fe358f079d5e57d884fb569d2da0a @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 92adaee5bd31c152dbc1592f4aeb5d8da957a1ea -R 3e75a7374bba2c69c55563b837ab8202 +P cdce87eb889a43dafcc560d5f97ab517d0266860 +R 5cd2d361c09a0f2b15feaa159f9c349e U drh -Z a6c699be62fa8981abc8311358615b45 +Z cef10e6dbd00a6e9bd88cff94c534444 diff --git a/manifest.uuid b/manifest.uuid index bad5c44835..89366bbd3f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cdce87eb889a43dafcc560d5f97ab517d0266860 \ No newline at end of file +5e19d054105fb16ff52d265d48cc87a418603f6f \ No newline at end of file diff --git a/src/where.c b/src/where.c index e18e88623f..75804782c2 100644 --- a/src/where.c +++ b/src/where.c @@ -45,6 +45,8 @@ typedef struct WherePath WherePath; typedef struct WhereTerm WhereTerm; typedef struct WhereLoopBuilder WhereLoopBuilder; typedef struct WhereScan WhereScan; +typedef struct WhereOrCost WhereOrCost; +typedef struct WhereOrSet WhereOrSet; /* ** Cost X is tracked as 10*log2(X) stored in a 16-bit integer. The @@ -152,6 +154,27 @@ struct WhereLoop { WhereTerm *aLTermSpace[4]; /* Initial aLTerm[] space */ }; +/* This object holds the prerequisites and the cost of running a +** subquery on one operand of an OR operator in the WHERE clause. +** See WhereOrSet for additional information +*/ +struct WhereOrCost { + Bitmask prereq; /* Prerequisites */ + WhereCost rRun; /* Cost of running this subquery */ + WhereCost nOut; /* Number of outputs for this subquery */ +}; + +/* The WhereOrSet object holds a set of possible WhereOrCosts that +** correspond to the subquery(s) of OR-clause processing. At most +** favorable N_OR_COST elements are retained. +*/ +#define N_OR_COST 3 +struct WhereOrSet { + u16 n; /* Number of valid a[] entries */ + WhereOrCost a[N_OR_COST]; /* Set of best costs */ +}; + + /* Forward declaration of methods */ static int whereLoopResize(sqlite3*, WhereLoop*, int); @@ -366,7 +389,7 @@ struct WhereLoopBuilder { WhereClause *pWC; /* WHERE clause terms */ ExprList *pOrderBy; /* ORDER BY clause */ WhereLoop *pNew; /* Template WhereLoop */ - WhereLoop *pBest; /* If non-NULL, store single best loop here */ + WhereOrSet *pOrSet; /* Record best loops here, if not NULL */ }; /* @@ -509,6 +532,54 @@ int sqlite3WhereOkOnePass(WhereInfo *pWInfo){ return pWInfo->okOnePass; } +/* +** Move the content of pSrc into pDest +*/ +static void whereOrMove(WhereOrSet *pDest, WhereOrSet *pSrc){ + pDest->n = pSrc->n; + memcpy(pDest->a, pSrc->a, pDest->n*sizeof(pDest->a[0])); +} + +/* +** Try to insert a new prerequisite/cost entry into the WhereOrSet pSet. +** +** The new entry might overwrite an existing entry, or it might be +** appended, or it might be discarded. Do whatever is the right thing +** so that pSet keeps the N_OR_COST best entries seen so far. +*/ +static int whereOrInsert( + WhereOrSet *pSet, /* The WhereOrSet to be updated */ + Bitmask prereq, /* Prerequisites of the new entry */ + WhereCost rRun, /* Run-cost of the new entry */ + WhereCost nOut /* Number of outputs for the new entry */ +){ + u16 i; + WhereOrCost *p; + for(i=pSet->n, p=pSet->a; i>0; i--, p++){ + if( rRun<=p->rRun && (prereq & p->prereq)==prereq ){ + goto whereOrInsert_done; + } + if( p->rRun<=rRun && (p->prereq & prereq)==p->prereq ){ + return 0; + } + } + if( pSet->na[pSet->n++]; + p->nOut = nOut; + }else{ + p = pSet->a; + for(i=1; in; i++){ + if( p->rRun>pSet->a[i].rRun ) p = pSet->a + i; + } + if( p->rRun<=rRun ) return 0; + } +whereOrInsert_done: + p->prereq = prereq; + p->rRun = rRun; + if( p->nOut>nOut ) p->nOut = nOut; + return 1; +} + /* ** Initialize a preallocated WhereClause structure. */ @@ -3743,8 +3814,9 @@ static Bitmask codeOneLoopStart( int iTerm; for(iTerm=0; iTermnTerm; iTerm++){ Expr *pExpr = pWC->a[iTerm].pExpr; + if( &pWC->a[iTerm] == pTerm ) continue; if( ExprHasProperty(pExpr, EP_FromJoin) ) continue; - if( pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_ORINFO) ) continue; + if( pWC->a[iTerm].wtFlags & (TERM_ORINFO) ) continue; if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue; pExpr = sqlite3ExprDup(pParse->db, pExpr, 0); pAndExpr = sqlite3ExprAnd(pParse->db, pAndExpr, pExpr); @@ -4072,12 +4144,12 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ ** fewer dependencies than the template. Otherwise a new WhereLoop is ** added based on the template. ** -** If pBuilder->pBest is not NULL then we only care about the very -** best template and that template should be stored in pBuilder->pBest. -** If pBuilder->pBest is NULL then a list of the best templates are stored -** in pBuilder->pWInfo->pLoops. +** If pBuilder->pOrSet is not NULL then we only care about only the +** prerequisites and rRun and nOut costs of the N best loops. That +** information is gathered in the pBuilder->pOrSet object. This special +** processing mode is used only for OR clause processing. ** -** When accumulating multiple loops (when pBuilder->pBest is NULL) we +** When accumulating multiple loops (when pBuilder->pOrSet is NULL) we ** still might overwrite similar loops with the new template if the ** template is better. Loops may be overwritten if the following ** conditions are met: @@ -4094,30 +4166,22 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ WhereInfo *pWInfo = pBuilder->pWInfo; sqlite3 *db = pWInfo->pParse->db; - /* If pBuilder->pBest is defined, then only keep track of the single - ** best WhereLoop. pBuilder->pBest->maskSelf==0 indicates that no - ** prior WhereLoops have been evaluated and that the current pTemplate - ** is therefore the first and hence the best and should be retained. + /* If pBuilder->pOrSet is defined, then only keep track of the costs + ** and prereqs. */ - if( (p = pBuilder->pBest)!=0 ){ - if( p->maskSelf!=0 ){ - WhereCost rCost = whereCostAdd(p->rRun,p->rSetup); - WhereCost rTemplate = whereCostAdd(pTemplate->rRun,pTemplate->rSetup); - if( rCost < rTemplate ){ - testcase( rCost==rTemplate-1 ); - goto whereLoopInsert_noop; - } - if( rCost==rTemplate && (p->prereq & pTemplate->prereq)==p->prereq ){ - goto whereLoopInsert_noop; - } - } + if( pBuilder->pOrSet!=0 ){ +#if WHERETRACE_ENABLED + u16 n = pBuilder->pOrSet->n; + int x = +#endif + whereOrInsert(pBuilder->pOrSet, pTemplate->prereq, pTemplate->rRun, + pTemplate->nOut); #if WHERETRACE_ENABLED if( sqlite3WhereTrace & 0x8 ){ - sqlite3DebugPrintf(p->maskSelf==0 ? "ins-init: " : "ins-best: "); + sqlite3DebugPrintf(x?" or-%d: ":" or-X: ", n); whereLoopPrint(pTemplate, pWInfo->pTabList); } #endif - whereLoopXfer(db, p, pTemplate); return SQLITE_OK; } @@ -4211,7 +4275,7 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ whereLoopInsert_noop: #if WHERETRACE_ENABLED if( sqlite3WhereTrace & 0x8 ){ - sqlite3DebugPrintf(pBuilder->pBest ? "ins-skip: " : "ins-noop: "); + sqlite3DebugPrintf("ins-noop: "); whereLoopPrint(pTemplate, pWInfo->pTabList); } #endif @@ -4493,7 +4557,7 @@ static int whereLoopAddBtree( rLogSize = estLog(rSize); /* Automatic indexes */ - if( !pBuilder->pBest + if( !pBuilder->pOrSet && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0 && pSrc->pIndex==0 && !pSrc->viaCoroutine @@ -4779,7 +4843,7 @@ static int whereLoopAddOr(WhereLoopBuilder *pBuilder, Bitmask mExtra){ int iCur; WhereClause tempWC; WhereLoopBuilder sSubBuild; - WhereLoop sBest; + WhereOrSet sSum, sCur, sPrev; struct SrcList_item *pItem; pWC = pBuilder->pWC; @@ -4794,16 +4858,14 @@ static int whereLoopAddOr(WhereLoopBuilder *pBuilder, Bitmask mExtra){ WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc; WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm]; WhereTerm *pOrTerm; - WhereCost rTotal = 0; - WhereCost nRow = 0; - Bitmask prereq = mExtra; + int once = 1; + int i, j; - whereLoopInit(&sBest); pItem = pWInfo->pTabList->a + pNew->iTab; iCur = pItem->iCursor; sSubBuild = *pBuilder; sSubBuild.pOrderBy = 0; - sSubBuild.pBest = &sBest; + sSubBuild.pOrSet = &sCur; for(pOrTerm=pOrWC->a; pOrTermeOperator & WO_AND)!=0 ){ @@ -4818,39 +4880,48 @@ static int whereLoopAddOr(WhereLoopBuilder *pBuilder, Bitmask mExtra){ }else{ continue; } - sBest.maskSelf = 0; - sBest.rSetup = 0; - sBest.rRun = 0; + sCur.n = 0; #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pItem->pTab) ){ rc = whereLoopAddVirtual(&sSubBuild); + for(i=0; inLSlot>=1 ); - if( sBest.maskSelf ){ - pNew->nLTerm = 1; - pNew->aLTerm[0] = pTerm; - pNew->wsFlags = WHERE_MULTI_OR; - pNew->rSetup = 0; + pNew->nLTerm = 1; + pNew->aLTerm[0] = pTerm; + pNew->wsFlags = WHERE_MULTI_OR; + pNew->rSetup = 0; + pNew->iSortIdx = 0; + memset(&pNew->u, 0, sizeof(pNew->u)); + for(i=0; rc==SQLITE_OK && irRun = rTotal + 18; assert( 18==whereCost(7)-whereCost(2) ); - pNew->nOut = nRow; - pNew->prereq = prereq; - memset(&pNew->u, 0, sizeof(pNew->u)); + pNew->rRun = sSum.a[i].rRun + 18; + pNew->nOut = sSum.a[i].nOut; + pNew->prereq = sSum.a[i].prereq; rc = whereLoopInsert(pBuilder, pNew); } - whereLoopClear(pWInfo->pParse->db, &sBest); } } return rc; diff --git a/test/where2.test b/test/where2.test index 3d4dfc9126..c827ecc7b5 100644 --- a/test/where2.test +++ b/test/where2.test @@ -699,5 +699,16 @@ do_test where2-11.4 { } } {4 8 10} +# Verify that the OR clause is used in an outer loop even when +# the OR clause scores slightly better on an inner loop. +do_execsql_test where2-12.1 { + CREATE TABLE t12(x INTEGER PRIMARY KEY, y); + CREATE INDEX t12y ON t12(y); + EXPLAIN QUERY PLAN + SELECT a.x, b.x + FROM t12 AS a JOIN t12 AS b ON a.y=b.x + WHERE (b.x=$abc OR b.y=$abc); +} {/.*SEARCH TABLE t12 AS b .*SEARCH TABLE t12 AS b .*/} + finish_test diff --git a/test/where8.test b/test/where8.test index 6890e3ac59..9127179292 100644 --- a/test/where8.test +++ b/test/where8.test @@ -212,8 +212,9 @@ do_test where8-3.4 { do_test where8-3.5 { execsql_status { SELECT a, d FROM t1, t2 WHERE (a = 2 OR a = 3) AND (d = a OR e = 'sixteen') + ORDER BY +a, +d; } -} {2 2 2 4 3 3 3 4 0 0} +} {2 2 2 4 3 3 3 4 0 1} do_test where8-3.6 { # The first part of the WHERE clause in this query, (a=2 OR a=3) is @@ -233,7 +234,7 @@ do_test where8-3.7 { WHERE a = 2 AND (d = a OR e = 'sixteen') ORDER BY t1.rowid } -} {2 2 2 4 0 0} +} {/2 2 2 4 0 [01]/} do_test where8-3.8 { execsql_status { SELECT a, d From 7232ad070086f762e54683fd282b1d5f3d684ca6 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 16 Jul 2013 23:26:43 +0000 Subject: [PATCH 05/47] Make sure the sqlite3_prepare16 and sqlite3_prepare16_v2 interfaces do not read past a zero-terminator if the nBytes parameter is too large. FossilOrigin-Name: 20dba3a7fb3e7078b95af3beca948467a3af6a89 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/prepare.c | 6 ++++++ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index aed4f14e23..64fb2cf74d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\squery\splanner\sso\sthat\sit\slooks\sat\smultiple\ssolutions\sto\sOR\nexpressions\sin\sthe\sWHERE\sclause. -D 2013-07-16T21:31:23.453 +C Make\ssure\sthe\ssqlite3_prepare16\sand\ssqlite3_prepare16_v2\sinterfaces\sdo\snot\nread\spast\sa\szero-terminator\sif\sthe\snBytes\sparameter\sis\stoo\slarge. +D 2013-07-16T23:26:43.492 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -211,7 +211,7 @@ F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c d23d07716de96c7c0c2503ec5051a4384c3fb938 F src/pragma.c 2790c5175bc3f95d2a0cf39283d144b9b012fec7 -F src/prepare.c 2306be166bbeddf454e18bf8b21dba8388d05328 +F src/prepare.c fa6988589f39af8504a61731614cd4f6ae71554f F src/printf.c 41c49dac366a3a411190001a8ab495fa8887974e F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 89f9003e8316ee3a172795459efc2a0274e1d5a8 @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P cdce87eb889a43dafcc560d5f97ab517d0266860 -R 5cd2d361c09a0f2b15feaa159f9c349e +P 5e19d054105fb16ff52d265d48cc87a418603f6f +R 357dccfdee09362b5c6e0e960cd1b67a U drh -Z cef10e6dbd00a6e9bd88cff94c534444 +Z 735e886cc8d8592981995974ead1c45b diff --git a/manifest.uuid b/manifest.uuid index 89366bbd3f..edde4e1125 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5e19d054105fb16ff52d265d48cc87a418603f6f \ No newline at end of file +20dba3a7fb3e7078b95af3beca948467a3af6a89 \ No newline at end of file diff --git a/src/prepare.c b/src/prepare.c index 28145aa4e7..cfc9c34855 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -810,6 +810,12 @@ static int sqlite3Prepare16( if( !sqlite3SafetyCheckOk(db) ){ return SQLITE_MISUSE_BKPT; } + if( nBytes>=0 ){ + int sz; + const char *z = (const char*)zSql; + for(sz=0; szmutex); zSql8 = sqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE); if( zSql8 ){ From 9f01e582be09d8c05523c65079f3d576e908d754 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 17 Jul 2013 11:54:47 +0000 Subject: [PATCH 06/47] Clear the error string pointer in sqlite3_vtab object after the error string is transferred to SQLite. Ticket [78588b938a11]. FossilOrigin-Name: 64bf8148b84e0ebb45c12b629f49bc9b316aceba --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vtab.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 64fb2cf74d..ef89e7f8d0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthe\ssqlite3_prepare16\sand\ssqlite3_prepare16_v2\sinterfaces\sdo\snot\nread\spast\sa\szero-terminator\sif\sthe\snBytes\sparameter\sis\stoo\slarge. -D 2013-07-16T23:26:43.492 +C Clear\sthe\serror\sstring\spointer\sin\ssqlite3_vtab\sobject\safter\sthe\serror\sstring\nis\stransferred\sto\sSQLite.\s\sTicket\s[78588b938a11]. +D 2013-07-17T11:54:47.775 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -286,7 +286,7 @@ F src/vdbeblob.c 5dc79627775bd9a9b494dd956e26297946417d69 F src/vdbemem.c 833005f1cbbf447289f1973dba2a0c2228c7b8ab F src/vdbesort.c 3937e06b2a0e354500e17dc206ef4c35770a5017 F src/vdbetrace.c e7ec40e1999ff3c6414424365d5941178966dcbc -F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83 +F src/vtab.c 2e8b489db47e20ae36cd247932dc671c9ded0624 F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73 @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 5e19d054105fb16ff52d265d48cc87a418603f6f -R 357dccfdee09362b5c6e0e960cd1b67a +P 20dba3a7fb3e7078b95af3beca948467a3af6a89 +R 013ec1a077b1a785910a41f7774e0baf U drh -Z 735e886cc8d8592981995974ead1c45b +Z 3af7c13fd1f5fd33dd19de7f52cc0abd diff --git a/manifest.uuid b/manifest.uuid index edde4e1125..9726c5d704 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -20dba3a7fb3e7078b95af3beca948467a3af6a89 \ No newline at end of file +64bf8148b84e0ebb45c12b629f49bc9b316aceba \ No newline at end of file diff --git a/src/vtab.c b/src/vtab.c index 958202c31e..a7fd17a35f 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -825,8 +825,8 @@ int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){ if( pVtab && (x = pVtab->pModule->xSync)!=0 ){ rc = x(pVtab); sqlite3DbFree(db, *pzErrmsg); - *pzErrmsg = sqlite3DbStrDup(db, pVtab->zErrMsg); - sqlite3_free(pVtab->zErrMsg); + *pzErrmsg = pVtab->zErrMsg; + pVtab->zErrMsg = 0; } } db->aVTrans = aVTrans; From cc0713057f6d55a7eaa4f2118a55638199c14852 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 17 Jul 2013 18:12:15 +0000 Subject: [PATCH 07/47] Enhance the sqlite3_analyzer tool to give reports on the sizes of individual indices. FossilOrigin-Name: 3b4096cc8a3b4517cdf49dcfe1f33279a5eb8efb --- manifest | 12 +++++----- manifest.uuid | 2 +- tool/spaceanal.tcl | 60 +++++++++++++++++++++++++++++++++------------- 3 files changed, 50 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index ef89e7f8d0..4d4e29e469 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Clear\sthe\serror\sstring\spointer\sin\ssqlite3_vtab\sobject\safter\sthe\serror\sstring\nis\stransferred\sto\sSQLite.\s\sTicket\s[78588b938a11]. -D 2013-07-17T11:54:47.775 +C Enhance\sthe\ssqlite3_analyzer\stool\sto\sgive\sreports\son\sthe\ssizes\sof\sindividual\nindices. +D 2013-07-17T18:12:15.911 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1087,7 +1087,7 @@ F tool/showjournal.c b62cecaab86a4053d944c276bb5232e4d17ece02 F tool/showwal.c 3f7f7da5ec0cba51b1449a75f700493377da57b5 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/space_used.tcl f714c41a59e326b8b9042f415b628b561bafa06b -F tool/spaceanal.tcl 76f583a246a0b027f423252339e711f13198932e +F tool/spaceanal.tcl f87fc8e459e3e42255b52987fe0dda3f8a8c513d F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355 F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 20dba3a7fb3e7078b95af3beca948467a3af6a89 -R 013ec1a077b1a785910a41f7774e0baf +P 64bf8148b84e0ebb45c12b629f49bc9b316aceba +R ec17da139f6652e6c6b8090663c2b7b7 U drh -Z 3af7c13fd1f5fd33dd19de7f52cc0abd +Z f519c532f4fd545ddca3699fd0c0b9a9 diff --git a/manifest.uuid b/manifest.uuid index 9726c5d704..509c4c91b8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -64bf8148b84e0ebb45c12b629f49bc9b316aceba \ No newline at end of file +3b4096cc8a3b4517cdf49dcfe1f33279a5eb8efb \ No newline at end of file diff --git a/tool/spaceanal.tcl b/tool/spaceanal.tcl index 6988f6e8b9..e2f23fe4bf 100644 --- a/tool/spaceanal.tcl +++ b/tool/spaceanal.tcl @@ -246,8 +246,19 @@ mem function int integerify # [quote {hello world's}] == {'hello world''s'} # proc quote {txt} { - regsub -all ' $txt '' q - return '$q' + return [string map {' ''} $txt] +} + +# Output a title line +# +proc titleline {title} { + if {$title==""} { + puts [string repeat * 79] + } else { + set len [string length $title] + set stars [string repeat * [expr 79-$len-5]] + puts "*** $title $stars" + } } # Generate a single line of output in the statistics section of the @@ -255,7 +266,7 @@ proc quote {txt} { # proc statline {title value {extra {}}} { set len [string length $title] - set dots [string range {......................................} $len end] + set dots [string repeat . [expr 50-$len]] set len [string length $value] set sp2 [string range { } $len end] if {$extra ne ""} { @@ -319,9 +330,7 @@ proc subreport {title where} { # Output the sub-report title, nicely decorated with * characters. # puts "" - set len [string length $title] - set stars [string repeat * [expr 65-$len]] - puts "*** $title $stars" + titleline $title puts "" # Calculate statistics and store the results in TCL variables, as follows: @@ -490,9 +499,6 @@ set user_percent [percent $user_payload $file_bytes] # Output the summary statistics calculated above. # puts "/** Disk-Space Utilization Report For $root_filename" -catch { - puts "*** As of [clock format [clock seconds] -format {%Y-%b-%d %H:%M:%S}]" -} puts "" statline {Page size in bytes} $pageSize statline {Pages in the whole file (measured)} $file_pgcnt @@ -517,16 +523,27 @@ statline {Bytes of user payload stored} $user_payload $user_percent # Output table rankings # puts "" -puts "*** Page counts for all tables with their indices ********************" +titleline "Page counts for all tables with their indices" puts "" mem eval {SELECT tblname, count(*) AS cnt, int(sum(int_pages+leaf_pages+ovfl_pages)) AS size FROM space_used GROUP BY tblname ORDER BY size+0 DESC, tblname} {} { statline [string toupper $tblname] $size [percent $size $file_pgcnt] } +puts "" +titleline "Page counts for all tables and indices separately" +puts "" +mem eval { + SELECT + upper(name) AS nm, + int(int_pages+leaf_pages+ovfl_pages) AS size + FROM space_used + ORDER BY size+0 DESC, name} {} { + statline $nm $size [percent $size $file_pgcnt] +} if {$isCompressed} { puts "" - puts "*** Bytes of disk space used after compression ***********************" + titleline "Bytes of disk space used after compression" puts "" set csum 0 mem eval {SELECT tblname, @@ -554,13 +571,22 @@ if {$nindex>0} { } foreach tbl [mem eval {SELECT name FROM space_used WHERE NOT is_index ORDER BY name}] { - regsub ' $tbl '' qn + set qn [quote $tbl] set name [string toupper $tbl] - set n [mem eval "SELECT count(*) FROM space_used WHERE tblname='$qn'"] + set n [mem eval {SELECT count(*) FROM space_used WHERE tblname=$tbl}] if {$n>1} { + set idxlist [mem eval "SELECT name FROM space_used + WHERE tblname='$qn' AND is_index + ORDER BY 1"] subreport "Table $name and all its indices" "tblname='$qn'" subreport "Table $name w/o any indices" "name='$qn'" - subreport "Indices of table $name" "tblname='$qn' AND is_index" + if {[llength $idxlist]>1} { + subreport "Indices of table $name" "tblname='$qn' AND is_index" + } + foreach idx $idxlist { + set qidx [quote $idx] + subreport "Index [string toupper $idx] of table $name" "name='$qidx'" + } } else { subreport "Table $name" "name='$qn'" } @@ -568,9 +594,9 @@ foreach tbl [mem eval {SELECT name FROM space_used WHERE NOT is_index # Output instructions on what the numbers above mean. # +puts "" +titleline Definitions puts { -*** Definitions ****************************************************** - Page size in bytes The number of bytes in a single page of the database file. @@ -722,7 +748,7 @@ Unused bytes on all pages # Output a dump of the in-memory database. This can be used for more # complex offline analysis. # -puts "**********************************************************************" +titleline {} puts "The entire text of this report can be sourced into any SQL database" puts "engine for further analysis. All of the text above is an SQL comment." puts "The data used to generate this report follows:" From 47af6e76d6d815da8d31aaa05ac014fe29076293 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 17 Jul 2013 21:08:49 +0000 Subject: [PATCH 08/47] Fix copy/paste errors in comments in the transitive_closure virtual table. No changes to code. FossilOrigin-Name: b1b0de29fdf7de83722bb85b748f058b9901e77a --- ext/misc/closure.c | 4 ++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/misc/closure.c b/ext/misc/closure.c index 260a783042..30c812d220 100644 --- a/ext/misc/closure.c +++ b/ext/misc/closure.c @@ -496,7 +496,7 @@ static const char *closureValueOfKey(const char *zKey, const char *zStr){ /* ** xConnect/xCreate method for the closure module. Arguments are: ** -** argv[0] -> module name ("approximate_match") +** argv[0] -> module name ("transitive_closure") ** argv[1] -> database name ** argv[2] -> table name ** argv[3...] -> arguments @@ -907,7 +907,7 @@ static int closureBestIndex( } /* -** A virtual table module that implements the "approximate_match". +** A virtual table module that implements the "transitive_closure". */ static sqlite3_module closureModule = { 0, /* iVersion */ diff --git a/manifest b/manifest index 4d4e29e469..959b43b31b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\ssqlite3_analyzer\stool\sto\sgive\sreports\son\sthe\ssizes\sof\sindividual\nindices. -D 2013-07-17T18:12:15.911 +C Fix\scopy/paste\serrors\sin\scomments\sin\sthe\stransitive_closure\svirtual\stable.\nNo\schanges\sto\scode. +D 2013-07-17T21:08:49.318 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -107,7 +107,7 @@ F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43 F ext/icu/icu.c d415ccf984defeb9df2c0e1afcfaa2f6dc05eacb F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/misc/amatch.c eae8454cd9dcb287b2a3ec2e65a865a4ac5f0d06 -F ext/misc/closure.c 997c20ddf35f85ab399f4a02a557a9baa822ec32 +F ext/misc/closure.c 636024302cde41b2bf0c542f81c40c624cfb7012 F ext/misc/fuzzer.c 136533c53cfce0957f0b48fa11dba27e21c5c01d F ext/misc/ieee754.c b0362167289170627659e84173f5d2e8fee8566e F ext/misc/nextchar.c 80ba262d23238efcfcb3d72d71aa4513098e26a6 @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 64bf8148b84e0ebb45c12b629f49bc9b316aceba -R ec17da139f6652e6c6b8090663c2b7b7 +P 3b4096cc8a3b4517cdf49dcfe1f33279a5eb8efb +R 72a343c5196cc394b974aafe1ea79d9a U drh -Z f519c532f4fd545ddca3699fd0c0b9a9 +Z 567058614f26922b80a2886ec42c5224 diff --git a/manifest.uuid b/manifest.uuid index 509c4c91b8..05bc013ddf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3b4096cc8a3b4517cdf49dcfe1f33279a5eb8efb \ No newline at end of file +b1b0de29fdf7de83722bb85b748f058b9901e77a \ No newline at end of file From b8c068329d996dc86787d2407c9237847ca82cb3 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 18 Jul 2013 14:16:48 +0000 Subject: [PATCH 09/47] Documentation changes to warn that sqlite3_set_auxdata() might call the destructor even before it returns. Also fix the regexp extension to deal with that case. Ticket [406d3b2ef91c]. FossilOrigin-Name: 7acc8cd32d593a473c9e9adaf323220a7a46480a --- ext/misc/regexp.c | 6 +++++- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 37 +++++++++++++++++++++++-------------- 4 files changed, 36 insertions(+), 23 deletions(-) diff --git a/ext/misc/regexp.c b/ext/misc/regexp.c index 16fa7d0b96..7244d52998 100644 --- a/ext/misc/regexp.c +++ b/ext/misc/regexp.c @@ -713,6 +713,7 @@ static void re_sql_func( const char *zPattern; /* The regular expression */ const unsigned char *zStr;/* String being searched */ const char *zErr; /* Compile error message */ + int setAux = 0; /* True to invoke sqlite3_set_auxdata() */ pRe = sqlite3_get_auxdata(context, 0); if( pRe==0 ){ @@ -728,12 +729,15 @@ static void re_sql_func( sqlite3_result_error_nomem(context); return; } - sqlite3_set_auxdata(context, 0, pRe, (void(*)(void*))re_free); + setAux = 1; } zStr = (const unsigned char*)sqlite3_value_text(argv[1]); if( zStr!=0 ){ sqlite3_result_int(context, re_match(pRe, zStr, -1)); } + if( setAux ){ + sqlite3_set_auxdata(context, 0, pRe, (void(*)(void*))re_free); + } } /* diff --git a/manifest b/manifest index 959b43b31b..e3da8a2f42 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\scopy/paste\serrors\sin\scomments\sin\sthe\stransitive_closure\svirtual\stable.\nNo\schanges\sto\scode. -D 2013-07-17T21:08:49.318 +C Documentation\schanges\sto\swarn\sthat\ssqlite3_set_auxdata()\smight\scall\sthe\ndestructor\seven\sbefore\sit\sreturns.\s\sAlso\sfix\sthe\sregexp\sextension\sto\sdeal\nwith\sthat\scase.\s\sTicket\s[406d3b2ef91c]. +D 2013-07-18T14:16:48.544 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -112,7 +112,7 @@ F ext/misc/fuzzer.c 136533c53cfce0957f0b48fa11dba27e21c5c01d F ext/misc/ieee754.c b0362167289170627659e84173f5d2e8fee8566e F ext/misc/nextchar.c 80ba262d23238efcfcb3d72d71aa4513098e26a6 F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63 -F ext/misc/regexp.c c25c65fe775f5d9801fb8573e36ebe73f2c0c2e0 +F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a F ext/misc/spellfix.c 5e1d547e9a2aed13897fa91bac924333f62fd2d9 F ext/misc/vtshim.c 5fb6be7fe37659a8cbd1e16982d74cceacbc4543 @@ -218,7 +218,7 @@ F src/resolve.c 89f9003e8316ee3a172795459efc2a0274e1d5a8 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 91b62654caf8dfe292fb8882715e575d34ad3874 F src/shell.c 4c02ec99e42aeb624bb221b253273da6c910b814 -F src/sqlite.h.in 30c88ce7862096b0aecf4c2c886bc0934eeaa515 +F src/sqlite.h.in ab59321198fe4e002890c8154642338e7da75e82 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqliteInt.h 6d3115f774aa3e87737f9447c9c0cea992c5bdbf @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 3b4096cc8a3b4517cdf49dcfe1f33279a5eb8efb -R 72a343c5196cc394b974aafe1ea79d9a +P b1b0de29fdf7de83722bb85b748f058b9901e77a +R 1373096ae79cc1001233efb4a308bce9 U drh -Z 567058614f26922b80a2886ec42c5224 +Z 4c86c705c11f63416d538424aa7f228b diff --git a/manifest.uuid b/manifest.uuid index 05bc013ddf..c3cee86f44 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b1b0de29fdf7de83722bb85b748f058b9901e77a \ No newline at end of file +7acc8cd32d593a473c9e9adaf323220a7a46480a \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 3b7237996b..8c600a1fa3 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -4179,8 +4179,8 @@ sqlite3 *sqlite3_context_db_handle(sqlite3_context*); ** The following two functions may be used by scalar SQL functions to ** associate metadata with argument values. If the same value is passed to ** multiple invocations of the same SQL function during query execution, under -** some circumstances the associated metadata may be preserved. This may -** be used, for example, to add a regular-expression matching scalar +** some circumstances the associated metadata may be preserved. This might +** be used, for example, in a regular-expression matching ** function. The compiled version of the regular expression is stored as ** metadata associated with the SQL value passed as the regular expression ** pattern. The compiled regular expression can be reused on multiple @@ -4194,23 +4194,32 @@ sqlite3 *sqlite3_context_db_handle(sqlite3_context*); ** function parameter has changed since the meta-data was set, ** then sqlite3_get_auxdata() returns a NULL pointer. ** -** ^The sqlite3_set_auxdata() interface saves the metadata -** pointed to by its 3rd parameter as the metadata for the N-th -** argument of the application-defined function. Subsequent -** calls to sqlite3_get_auxdata() might return this data, if it has -** not been destroyed. -** ^If it is not NULL, SQLite will invoke the destructor -** function given by the 4th parameter to sqlite3_set_auxdata() on -** the metadata when the corresponding function parameter changes -** or when the SQL statement completes, whichever comes first. +** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th +** argument of the application-defined function. ^Subsequent +** calls to sqlite3_get_auxdata(C,N) return P from the most recent +** sqlite3_set_auxdata(C,N,P,X) call if the data has not been dropped, or +** NULL if the data has been dropped. +** ^(If it is not NULL, SQLite will invoke the destructor +** function X passed to sqlite3_set_auxdata(C,N,P,X) when
    +**
  • the corresponding function parameter changes, +**
  • [sqlite3_reset()] or [sqlite3_finalize()] is called for the +** SQL statement, +**
  • sqlite3_set_auxdata() is invoked again on the same parameter, or +**
  • a memory allocation error occurs.
)^ ** ** SQLite is free to call the destructor and drop metadata on any ** parameter of any function at any time. ^The only guarantee is that -** the destructor will be called before the metadata is dropped. +** the destructor will be called when the [prepared statement] is destroyed. +** Note in particular that the destructor X in the call to +** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before +** the sqlite3_set_auxdata() call even returns. Hence sqlite3_set_auxdata() +** should be called near the end of the function implementation and the +** implementation should not make any use of P after sqlite3_set_auxdata() +** has been called. ** ** ^(In practice, metadata is preserved between function calls for -** expressions that are constant at compile time. This includes literal -** values and [parameters].)^ +** function parameters that are compile-time constants, including literal +** values and [parameters] and expressions composed from the same.)^ ** ** These routines must be called from the same thread in which ** the SQL function is running. From 1ac87e1e81f2b2f0ebbdcbcef9d6d4fd3986efa5 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 18 Jul 2013 14:50:56 +0000 Subject: [PATCH 10/47] Fix a 8-byte alignment problem in the query planner that might cause problems on sparc when compiled with -m32. FossilOrigin-Name: 5dcffa671f592ae9355628afa439ae9a2d26f0cd --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index e3da8a2f42..7bd39ba9a8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Documentation\schanges\sto\swarn\sthat\ssqlite3_set_auxdata()\smight\scall\sthe\ndestructor\seven\sbefore\sit\sreturns.\s\sAlso\sfix\sthe\sregexp\sextension\sto\sdeal\nwith\sthat\scase.\s\sTicket\s[406d3b2ef91c]. -D 2013-07-18T14:16:48.544 +C Fix\sa\s8-byte\salignment\sproblem\sin\sthe\squery\splanner\sthat\smight\scause\nproblems\son\ssparc\swhen\scompiled\swith\s-m32. +D 2013-07-18T14:50:56.888 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -290,7 +290,7 @@ F src/vtab.c 2e8b489db47e20ae36cd247932dc671c9ded0624 F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73 -F src/where.c 927acb798c66af64b5d640e50f0edfe07d6b4085 +F src/where.c 1a26c37b7b54d198e2ec9aa127d22c3dcfe89de8 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P b1b0de29fdf7de83722bb85b748f058b9901e77a -R 1373096ae79cc1001233efb4a308bce9 +P 7acc8cd32d593a473c9e9adaf323220a7a46480a +R 17b8abd2c5b717cffa3f1d157b1c3142 U drh -Z 4c86c705c11f63416d538424aa7f228b +Z 8aedb025f873aeef3a714ef3251c3e91 diff --git a/manifest.uuid b/manifest.uuid index c3cee86f44..fc61fbc2f7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7acc8cd32d593a473c9e9adaf323220a7a46480a \ No newline at end of file +5dcffa671f592ae9355628afa439ae9a2d26f0cd \ No newline at end of file diff --git a/src/where.c b/src/where.c index 75804782c2..d3182f8094 100644 --- a/src/where.c +++ b/src/where.c @@ -5728,7 +5728,8 @@ WhereInfo *sqlite3WhereBegin( pMaskSet = &pWInfo->sMaskSet; sWLB.pWInfo = pWInfo; sWLB.pWC = &pWInfo->sWC; - sWLB.pNew = (WhereLoop*)&pWInfo->a[nTabList]; + sWLB.pNew = (WhereLoop*)(((char*)pWInfo)+nByteWInfo); + assert( EIGHT_BYTE_ALIGNMENT(sWLB.pNew) ); whereLoopInit(sWLB.pNew); #ifdef SQLITE_DEBUG sWLB.pNew->cId = '*'; From 0c5477997b82bfd4b952414faf9733377d0248f7 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 18 Jul 2013 17:12:08 +0000 Subject: [PATCH 11/47] Ensure that all auxiliary data registered by calls to sqlite3_set_auxdata() is destroyed when the VM is halted. Partial fix for [406d3b2ef9]. FossilOrigin-Name: 71effa59c98d167e6e4b269e59ad5f468e664ac1 --- manifest | 24 ++++++++++++------------ manifest.uuid | 2 +- src/vdbe.c | 19 +++++-------------- src/vdbe.h | 3 --- src/vdbeInt.h | 37 +++++++++++++++++++------------------ src/vdbeapi.c | 43 ++++++++++++++++++++----------------------- src/vdbeaux.c | 46 +++++++++++++++++++++++++++++----------------- test/func.test | 26 ++++++++++++++++++++++++++ 8 files changed, 112 insertions(+), 88 deletions(-) diff --git a/manifest b/manifest index 7bd39ba9a8..6dd3418d1d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\s8-byte\salignment\sproblem\sin\sthe\squery\splanner\sthat\smight\scause\nproblems\son\ssparc\swhen\scompiled\swith\s-m32. -D 2013-07-18T14:50:56.888 +C Ensure\sthat\sall\sauxiliary\sdata\sregistered\sby\scalls\sto\ssqlite3_set_auxdata()\sis\sdestroyed\swhen\sthe\sVM\sis\shalted.\sPartial\sfix\sfor\s[406d3b2ef9]. +D 2013-07-18T17:12:08.417 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -277,11 +277,11 @@ F src/update.c 8e76c3d03e4b7b21cb250bd2df0c05e12993e577 F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f F src/util.c f566b5138099a2df8533b190d0dcc74b7dfbe0c9 F src/vacuum.c d9c5759f4c5a438bb43c2086f72c5d2edabc36c8 -F src/vdbe.c 420ebf1d551a76406cbbe0adc52d22d45aac039a -F src/vdbe.h b52887278cb173e66188da84dfab216bea61119d -F src/vdbeInt.h 5e666c971c555c7977714b0e34cb8d4b20282557 -F src/vdbeapi.c c88222946d657984bdaf394604cb58ed1d641460 -F src/vdbeaux.c 1633408f6dea06129441c5e2f22b2a5ce30fe97e +F src/vdbe.c 7fab3ee5adbcf841fad9db65308ac5dc36c4e0be +F src/vdbe.h f380af2a7fab32ba8a8b05bf042497636afec66d +F src/vdbeInt.h e9b7c6b165a31a4715c5aa97223d20d265515231 +F src/vdbeapi.c 4d13580bd058b39623e8fcfc233b7df4b8191e8b +F src/vdbeaux.c c01594ecf5a78ef41a721f3465152bb91883a942 F src/vdbeblob.c 5dc79627775bd9a9b494dd956e26297946417d69 F src/vdbemem.c 833005f1cbbf447289f1973dba2a0c2228c7b8ab F src/vdbesort.c 3937e06b2a0e354500e17dc206ef4c35770a5017 @@ -556,7 +556,7 @@ F test/fts4merge4.test c19c85ca1faa7b6d536832b49c12e1867235f584 F test/fts4noti.test aed33ba44808852dcb24bf70fa132e7bf530f057 F test/fts4unicode.test c8ac44217bf6c17812b03eaafa6c06995ad304c2 F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d -F test/func.test b0fc34fdc36897769651975a2b0a606312753643 +F test/func.test 9161beda516d6006d31e6ea6119579286512f751 F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f F test/func3.test 001021e5b88bd02a3b365a5c5fd8f6f49d39744a F test/fuzz-oss1.test 4912e528ec9cf2f42134456933659d371c9e0d74 @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 7acc8cd32d593a473c9e9adaf323220a7a46480a -R 17b8abd2c5b717cffa3f1d157b1c3142 -U drh -Z 8aedb025f873aeef3a714ef3251c3e91 +P 5dcffa671f592ae9355628afa439ae9a2d26f0cd +R 5f8d56aac1f51039dd4e137aed108558 +U dan +Z e317751ba4c386bb8e1c47226cf1f704 diff --git a/manifest.uuid b/manifest.uuid index fc61fbc2f7..8e33f834ce 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5dcffa671f592ae9355628afa439ae9a2d26f0cd \ No newline at end of file +71effa59c98d167e6e4b269e59ad5f468e664ac1 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 2e60361e89..c568d51fa5 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1420,19 +1420,14 @@ case OP_Function: { REGISTER_TRACE(pOp->p2+i, pArg); } - assert( pOp->p4type==P4_FUNCDEF || pOp->p4type==P4_VDBEFUNC ); - if( pOp->p4type==P4_FUNCDEF ){ - ctx.pFunc = pOp->p4.pFunc; - ctx.pVdbeFunc = 0; - }else{ - ctx.pVdbeFunc = (VdbeFunc*)pOp->p4.pVdbeFunc; - ctx.pFunc = ctx.pVdbeFunc->pFunc; - } - + assert( pOp->p4type==P4_FUNCDEF ); + ctx.pFunc = pOp->p4.pFunc; ctx.s.flags = MEM_Null; ctx.s.db = db; ctx.s.xDel = 0; ctx.s.zMalloc = 0; + ctx.iOp = pc; + ctx.pVdbe = p; /* The output cell may already have a buffer allocated. Move ** the pointer to ctx.s so in case the user-function can use @@ -1455,11 +1450,7 @@ case OP_Function: { /* If any auxiliary data functions have been called by this user function, ** immediately call the destructor for any non-static values. */ - if( ctx.pVdbeFunc ){ - sqlite3VdbeDeleteAuxData(ctx.pVdbeFunc, pOp->p1); - pOp->p4.pVdbeFunc = ctx.pVdbeFunc; - pOp->p4type = P4_VDBEFUNC; - } + sqlite3VdbeDeleteAuxData(ppc, pc, pOp->p1); if( db->mallocFailed ){ /* Even though a malloc() has failed, the implementation of the diff --git a/src/vdbe.h b/src/vdbe.h index fa7b31b727..4c2e76d562 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -30,7 +30,6 @@ typedef struct Vdbe Vdbe; ** The names of the following types declared in vdbeInt.h are required ** for the VdbeOp definition. */ -typedef struct VdbeFunc VdbeFunc; typedef struct Mem Mem; typedef struct SubProgram SubProgram; @@ -54,7 +53,6 @@ struct VdbeOp { i64 *pI64; /* Used when p4type is P4_INT64 */ double *pReal; /* Used when p4type is P4_REAL */ FuncDef *pFunc; /* Used when p4type is P4_FUNCDEF */ - VdbeFunc *pVdbeFunc; /* Used when p4type is P4_VDBEFUNC */ CollSeq *pColl; /* Used when p4type is P4_COLLSEQ */ Mem *pMem; /* Used when p4type is P4_MEM */ VTable *pVtab; /* Used when p4type is P4_VTAB */ @@ -108,7 +106,6 @@ typedef struct VdbeOpList VdbeOpList; #define P4_COLLSEQ (-4) /* P4 is a pointer to a CollSeq structure */ #define P4_FUNCDEF (-5) /* P4 is a pointer to a FuncDef structure */ #define P4_KEYINFO (-6) /* P4 is a pointer to a KeyInfo structure */ -#define P4_VDBEFUNC (-7) /* P4 is a pointer to a VdbeFunc structure */ #define P4_MEM (-8) /* P4 is a pointer to a Mem* structure */ #define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */ #define P4_VTAB (-10) /* P4 is a pointer to an sqlite3_vtab structure */ diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 11c34fd524..9ee82b4ea0 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -44,6 +44,9 @@ typedef struct VdbeSorter VdbeSorter; /* Opaque type used by the explainer */ typedef struct Explain Explain; +/* Elements of the linked list at Vdbe.pAuxData */ +typedef struct AuxData AuxData; + /* ** A cursor is a pointer into a single BTree within a database file. ** The cursor can seek to a BTree entry with a particular key, or @@ -230,23 +233,19 @@ struct Mem { #define memIsValid(M) ((M)->flags & MEM_Invalid)==0 #endif - -/* A VdbeFunc is just a FuncDef (defined in sqliteInt.h) that contains -** additional information about auxiliary information bound to arguments -** of the function. This is used to implement the sqlite3_get_auxdata() -** and sqlite3_set_auxdata() APIs. The "auxdata" is some auxiliary data -** that can be associated with a constant argument to a function. This -** allows functions such as "regexp" to compile their constant regular -** expression argument once and reused the compiled code for multiple -** invocations. +/* +** Each auxilliary data pointer stored by a user defined function +** implementation calling sqlite3_set_auxdata() is stored in an instance +** of this structure. All such structures associated with a single VM +** are stored in a linked list headed at Vdbe.pAuxData. All are destroyed +** when the VM is halted (if not before). */ -struct VdbeFunc { - FuncDef *pFunc; /* The definition of the function */ - int nAux; /* Number of entries allocated for apAux[] */ - struct AuxData { - void *pAux; /* Aux data for the i-th argument */ - void (*xDelete)(void *); /* Destructor for the aux data */ - } apAux[1]; /* One slot for each function argument */ +struct AuxData { + int iOp; /* Instruction number of OP_Function opcode */ + int iArg; /* Index of function argument. */ + void *pAux; /* Aux data pointer */ + void (*xDelete)(void *); /* Destructor for the aux data */ + AuxData *pNext; /* Next element in list */ }; /* @@ -264,12 +263,13 @@ struct VdbeFunc { */ struct sqlite3_context { FuncDef *pFunc; /* Pointer to function information. MUST BE FIRST */ - VdbeFunc *pVdbeFunc; /* Auxilary data, if created. */ Mem s; /* The return value is stored here */ Mem *pMem; /* Memory cell used to store aggregate context */ CollSeq *pColl; /* Collating sequence */ int isError; /* Error code returned by the function. */ int skipFlag; /* Skip skip accumulator loading if true */ + int iOp; /* Instruction number of OP_Function */ + Vdbe *pVdbe; /* The VM that owns this context */ }; /* @@ -368,6 +368,7 @@ struct Vdbe { SubProgram *pProgram; /* Linked list of all sub-programs used by VM */ int nOnceFlag; /* Size of array aOnceFlag[] */ u8 *aOnceFlag; /* Flags for OP_Once */ + AuxData *pAuxData; /* Linked list of auxdata allocations */ }; /* @@ -391,7 +392,7 @@ u32 sqlite3VdbeSerialTypeLen(u32); u32 sqlite3VdbeSerialType(Mem*, int); u32 sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int); u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); -void sqlite3VdbeDeleteAuxData(VdbeFunc*, int); +void sqlite3VdbeDeleteAuxData(Vdbe*, int, int); int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index ad3eea13a7..7c9db9beec 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -584,14 +584,14 @@ void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){ ** the user-function defined by pCtx. */ void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){ - VdbeFunc *pVdbeFunc; + AuxData *pAuxData; assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); - pVdbeFunc = pCtx->pVdbeFunc; - if( !pVdbeFunc || iArg>=pVdbeFunc->nAux || iArg<0 ){ - return 0; + for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){ + if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break; } - return pVdbeFunc->apAux[iArg].pAux; + + return (pAuxData ? pAuxData->pAux : 0); } /* @@ -605,29 +605,26 @@ void sqlite3_set_auxdata( void *pAux, void (*xDelete)(void*) ){ - struct AuxData *pAuxData; - VdbeFunc *pVdbeFunc; - if( iArg<0 ) goto failed; + AuxData *pAuxData; + Vdbe *pVdbe = pCtx->pVdbe; assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); - pVdbeFunc = pCtx->pVdbeFunc; - if( !pVdbeFunc || pVdbeFunc->nAux<=iArg ){ - int nAux = (pVdbeFunc ? pVdbeFunc->nAux : 0); - int nMalloc = sizeof(VdbeFunc) + sizeof(struct AuxData)*iArg; - pVdbeFunc = sqlite3DbRealloc(pCtx->s.db, pVdbeFunc, nMalloc); - if( !pVdbeFunc ){ - goto failed; - } - pCtx->pVdbeFunc = pVdbeFunc; - memset(&pVdbeFunc->apAux[nAux], 0, sizeof(struct AuxData)*(iArg+1-nAux)); - pVdbeFunc->nAux = iArg+1; - pVdbeFunc->pFunc = pCtx->pFunc; - } + if( iArg<0 ) goto failed; - pAuxData = &pVdbeFunc->apAux[iArg]; - if( pAuxData->pAux && pAuxData->xDelete ){ + for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){ + if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break; + } + if( pAuxData==0 ){ + pAuxData = sqlite3DbMallocZero(pVdbe->db, sizeof(AuxData)); + if( !pAuxData ) goto failed; + pAuxData->iOp = pCtx->iOp; + pAuxData->iArg = iArg; + pAuxData->pNext = pVdbe->pAuxData; + pVdbe->pAuxData = pAuxData; + }else if( pAuxData->xDelete ){ pAuxData->xDelete(pAuxData->pAux); } + pAuxData->pAux = pAux; pAuxData->xDelete = xDelete; return; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index dfdf7800a4..f54685cb71 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -612,13 +612,6 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){ if( db->pnBytesFreed==0 ) sqlite3_free(p4); break; } - case P4_VDBEFUNC: { - VdbeFunc *pVdbeFunc = (VdbeFunc *)p4; - freeEphemeralFunction(db, pVdbeFunc->pFunc); - if( db->pnBytesFreed==0 ) sqlite3VdbeDeleteAuxData(pVdbeFunc, 0); - sqlite3DbFree(db, pVdbeFunc); - break; - } case P4_FUNCDEF: { freeEphemeralFunction(db, (FuncDef*)p4); break; @@ -1648,6 +1641,10 @@ static void closeAllCursors(Vdbe *p){ p->pDelFrame = pDel->pParent; sqlite3VdbeFrameDelete(pDel); } + + /* Delete any auxdata allocations made by the VM */ + sqlite3VdbeDeleteAuxData(p, -1, 0); + assert( p->pAuxData==0 ); } /* @@ -2446,20 +2443,35 @@ int sqlite3VdbeFinalize(Vdbe *p){ } /* -** Call the destructor for each auxdata entry in pVdbeFunc for which -** the corresponding bit in mask is clear. Auxdata entries beyond 31 -** are always destroyed. To destroy all auxdata entries, call this -** routine with mask==0. +** If parameter iOp is less than zero, then invoke the destructor for +** all auxiliary data pointers currently cached by the VM passed as +** the first argument. +** +** Or, if iOp is greater than or equal to zero, then the destructor is +** only invoked for those auxiliary data pointers created by the user +** function invoked by the OP_Function opcode at instruction iOp of +** VM pVdbe, and only then if: +** +** * the associated function parameter is the 32nd or later (counting +** from left to right), or +** +** * the corresponding bit in argument mask is clear (where the first +** function parameter corrsponds to bit 0 etc.). */ -void sqlite3VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int mask){ - int i; - for(i=0; inAux; i++){ - struct AuxData *pAux = &pVdbeFunc->apAux[i]; - if( (i>31 || !(mask&(((u32)1)<pAux ){ +void sqlite3VdbeDeleteAuxData(Vdbe *pVdbe, int iOp, int mask){ + AuxData **pp = &pVdbe->pAuxData; + while( *pp ){ + AuxData *pAux = *pp; + if( (iOp<0) + || (pAux->iOp==iOp && (pAux->iArg>31 || !(mask & ((u32)1<iArg)))) + ){ if( pAux->xDelete ){ pAux->xDelete(pAux->pAux); } - pAux->pAux = 0; + *pp = pAux->pNext; + sqlite3DbFree(pVdbe->db, pAux); + }else{ + pp= &pAux->pNext; } } } diff --git a/test/func.test b/test/func.test index 4ab7688461..06f9f41d01 100644 --- a/test/func.test +++ b/test/func.test @@ -682,6 +682,32 @@ do_test func-13.7 { lappend res [sqlite3_finalize $STMT] } {{0 0} {1 0} SQLITE_OK} +# Test that auxiliary data is discarded when a statement is reset. +do_execsql_test 13.8.1 { + SELECT test_auxdata('constant') FROM t4; +} {0 1} +do_execsql_test 13.8.2 { + SELECT test_auxdata('constant') FROM t4; +} {0 1} +db cache flush +do_execsql_test 13.8.3 { + SELECT test_auxdata('constant') FROM t4; +} {0 1} +set V "one" +do_execsql_test 13.8.4 { + SELECT test_auxdata($V), $V FROM t4; +} {0 one 1 one} +set V "two" +do_execsql_test 13.8.5 { + SELECT test_auxdata($V), $V FROM t4; +} {0 two 1 two} +db cache flush +set V "three" +do_execsql_test 2.3 { + SELECT test_auxdata($V), $V FROM t4; +} {0 three 1 three} + + # Make sure that a function with a very long name is rejected do_test func-14.1 { catch { From 28f8aebf75a95ee67105e0a58ca734ff0ccb2c8b Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 18 Jul 2013 18:28:04 +0000 Subject: [PATCH 12/47] Fix a typo in the previous commit. FossilOrigin-Name: cd9096e64b86c8d45f6744e6eb6ced2aa1a18279 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 6dd3418d1d..721f7cc26d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sall\sauxiliary\sdata\sregistered\sby\scalls\sto\ssqlite3_set_auxdata()\sis\sdestroyed\swhen\sthe\sVM\sis\shalted.\sPartial\sfix\sfor\s[406d3b2ef9]. -D 2013-07-18T17:12:08.417 +C Fix\sa\stypo\sin\sthe\sprevious\scommit. +D 2013-07-18T18:28:04.101 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -277,7 +277,7 @@ F src/update.c 8e76c3d03e4b7b21cb250bd2df0c05e12993e577 F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f F src/util.c f566b5138099a2df8533b190d0dcc74b7dfbe0c9 F src/vacuum.c d9c5759f4c5a438bb43c2086f72c5d2edabc36c8 -F src/vdbe.c 7fab3ee5adbcf841fad9db65308ac5dc36c4e0be +F src/vdbe.c 816e686198c7d83a71545dfb4b34ec65f8071d23 F src/vdbe.h f380af2a7fab32ba8a8b05bf042497636afec66d F src/vdbeInt.h e9b7c6b165a31a4715c5aa97223d20d265515231 F src/vdbeapi.c 4d13580bd058b39623e8fcfc233b7df4b8191e8b @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 5dcffa671f592ae9355628afa439ae9a2d26f0cd -R 5f8d56aac1f51039dd4e137aed108558 +P 71effa59c98d167e6e4b269e59ad5f468e664ac1 +R 4421f283285a2b7794dd87eb2ccfa514 U dan -Z e317751ba4c386bb8e1c47226cf1f704 +Z cf95d409b1004e756caafc3b743bfac7 diff --git a/manifest.uuid b/manifest.uuid index 8e33f834ce..d41deccd47 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -71effa59c98d167e6e4b269e59ad5f468e664ac1 \ No newline at end of file +cd9096e64b86c8d45f6744e6eb6ced2aa1a18279 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index c568d51fa5..af135f5309 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1450,7 +1450,7 @@ case OP_Function: { /* If any auxiliary data functions have been called by this user function, ** immediately call the destructor for any non-static values. */ - sqlite3VdbeDeleteAuxData(ppc, pc, pOp->p1); + sqlite3VdbeDeleteAuxData(p, pc, pOp->p1); if( db->mallocFailed ){ /* Even though a malloc() has failed, the implementation of the From 6b75329ae10cf01a0945c6f2296536ec57500bb8 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 18 Jul 2013 18:45:53 +0000 Subject: [PATCH 13/47] Improved documentation for sqlite3_set_auxdata(). Ticket [406d3b2ef91c]. FossilOrigin-Name: 62465ecba7431e1d71e17a61f1af7dc65fe4fe97 --- manifest | 14 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 57 ++++++++++++++++++++++++------------------------- 3 files changed, 36 insertions(+), 37 deletions(-) diff --git a/manifest b/manifest index e83f006318..a2f9baee61 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sall\sauxiliary\sdata\sregistered\sby\scalls\sto\ssqlite3_set_auxdata()\sis\sdestroyed\swhen\sthe\sVM\sis\shalted. -D 2013-07-18T18:29:24.793 +C Improved\sdocumentation\sfor\ssqlite3_set_auxdata().\nTicket\s[406d3b2ef91c]. +D 2013-07-18T18:45:53.278 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -218,7 +218,7 @@ F src/resolve.c 89f9003e8316ee3a172795459efc2a0274e1d5a8 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 91b62654caf8dfe292fb8882715e575d34ad3874 F src/shell.c 4c02ec99e42aeb624bb221b253273da6c910b814 -F src/sqlite.h.in ab59321198fe4e002890c8154642338e7da75e82 +F src/sqlite.h.in ba19609c0dab076a169b0cd2e7d4a479c5b3f664 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqliteInt.h 6d3115f774aa3e87737f9447c9c0cea992c5bdbf @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 5dcffa671f592ae9355628afa439ae9a2d26f0cd cd9096e64b86c8d45f6744e6eb6ced2aa1a18279 -R 4421f283285a2b7794dd87eb2ccfa514 -U dan -Z 29564540b2246ca0de6b786ea5d703ab +P 153deac8faca3bcc95f6f37e500b659b39b3e872 +R ec74b1ee673935f130bb86648a1098ae +U drh +Z 00f72fcc18f51e2cc40bcf22d8fab123 diff --git a/manifest.uuid b/manifest.uuid index 9c7179c3ce..c41b54ef2b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -153deac8faca3bcc95f6f37e500b659b39b3e872 \ No newline at end of file +62465ecba7431e1d71e17a61f1af7dc65fe4fe97 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 8c600a1fa3..a87e8810f2 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -4176,46 +4176,45 @@ sqlite3 *sqlite3_context_db_handle(sqlite3_context*); /* ** CAPI3REF: Function Auxiliary Data ** -** The following two functions may be used by scalar SQL functions to +** These functions may be used by (non-aggregate) SQL functions to ** associate metadata with argument values. If the same value is passed to ** multiple invocations of the same SQL function during query execution, under -** some circumstances the associated metadata may be preserved. This might -** be used, for example, in a regular-expression matching -** function. The compiled version of the regular expression is stored as -** metadata associated with the SQL value passed as the regular expression -** pattern. The compiled regular expression can be reused on multiple -** invocations of the same function so that the original pattern string -** does not need to be recompiled on each invocation. +** some circumstances the associated metadata may be preserved. An example +** of where this might be useful is in a regular-expression matching +** function. The compiled version of the regular expression can be stored as +** metadata associated with the pattern string. +** Then as long as the pattern string remains the same, +** the compiled regular expression can be reused on multiple +** invocations of the same function. ** ** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata ** associated by the sqlite3_set_auxdata() function with the Nth argument -** value to the application-defined function. ^If no metadata has been ever -** been set for the Nth argument of the function, or if the corresponding -** function parameter has changed since the meta-data was set, -** then sqlite3_get_auxdata() returns a NULL pointer. +** value to the application-defined function. ^If there is no metadata +** associated with the function argument, this sqlite3_get_auxdata() interface +** returns a NULL pointer. ** ** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th ** argument of the application-defined function. ^Subsequent ** calls to sqlite3_get_auxdata(C,N) return P from the most recent -** sqlite3_set_auxdata(C,N,P,X) call if the data has not been dropped, or -** NULL if the data has been dropped. -** ^(If it is not NULL, SQLite will invoke the destructor -** function X passed to sqlite3_set_auxdata(C,N,P,X) when
    -**
  • the corresponding function parameter changes, -**
  • [sqlite3_reset()] or [sqlite3_finalize()] is called for the -** SQL statement, -**
  • sqlite3_set_auxdata() is invoked again on the same parameter, or -**
  • a memory allocation error occurs.
)^ +** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or +** NULL if the metadata has been discarded. +** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL, +** SQLite will invoke the destructor function X with parameter P exactly +** once, when the metadata is discarded. +** SQLite is free to discard the metadata at any time, including:
    +**
  • when the corresponding function parameter changes, or +**
  • when [sqlite3_reset()] or [sqlite3_finalize()] is called for the +** SQL statement, or +**
  • when sqlite3_set_auxdata() is invoked again on the same parameter, or +**
  • during the original sqlite3_set_auxdata() call when a memory +** allocation error occurs.
)^ ** -** SQLite is free to call the destructor and drop metadata on any -** parameter of any function at any time. ^The only guarantee is that -** the destructor will be called when the [prepared statement] is destroyed. -** Note in particular that the destructor X in the call to -** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before -** the sqlite3_set_auxdata() call even returns. Hence sqlite3_set_auxdata() +** Note the last bullet in particular. The destructor X in +** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the +** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata() ** should be called near the end of the function implementation and the -** implementation should not make any use of P after sqlite3_set_auxdata() -** has been called. +** function implementation should not make any use of P after +** sqlite3_set_auxdata() has been called. ** ** ^(In practice, metadata is preserved between function calls for ** function parameters that are compile-time constants, including literal From af66433625076734182114dcd4d74309950805c9 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 18 Jul 2013 20:28:29 +0000 Subject: [PATCH 14/47] Remove unused "codec" code from the command-line shell. FossilOrigin-Name: 37abfe0c1e5da63342389c527a9f7cbe0f8392d9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 12 ++---------- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index a2f9baee61..4996acd786 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\sdocumentation\sfor\ssqlite3_set_auxdata().\nTicket\s[406d3b2ef91c]. -D 2013-07-18T18:45:53.278 +C Remove\sunused\s"codec"\scode\sfrom\sthe\scommand-line\sshell. +D 2013-07-18T20:28:29.811 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -217,7 +217,7 @@ F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 89f9003e8316ee3a172795459efc2a0274e1d5a8 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 91b62654caf8dfe292fb8882715e575d34ad3874 -F src/shell.c 4c02ec99e42aeb624bb221b253273da6c910b814 +F src/shell.c 7da98ff9cbb19d7ef213a295178039bcb457804a F src/sqlite.h.in ba19609c0dab076a169b0cd2e7d4a479c5b3f664 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 153deac8faca3bcc95f6f37e500b659b39b3e872 -R ec74b1ee673935f130bb86648a1098ae +P 62465ecba7431e1d71e17a61f1af7dc65fe4fe97 +R ff789e1ed27e10ae116b350d443e40e4 U drh -Z 00f72fcc18f51e2cc40bcf22d8fab123 +Z 147237eb091c75d2b25ac79bc55dd938 diff --git a/manifest.uuid b/manifest.uuid index c41b54ef2b..a93721bf61 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -62465ecba7431e1d71e17a61f1af7dc65fe4fe97 \ No newline at end of file +37abfe0c1e5da63342389c527a9f7cbe0f8392d9 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index f0815538ab..d6b3159a49 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1797,7 +1797,6 @@ static int do_meta_command(char *zLine, struct callback_data *p){ if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 ){ const char *zDestFile = 0; const char *zDb = 0; - const char *zKey = 0; sqlite3 *pDest; sqlite3_backup *pBackup; int j; @@ -1805,9 +1804,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ const char *z = azArg[j]; if( z[0]=='-' ){ while( z[0]=='-' ) z++; - if( strcmp(z,"key")==0 && jdb, zDb); if( pBackup==0 ){ @@ -2667,7 +2659,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ /* sqlite3_test_control(int, uint) */ case SQLITE_TESTCTRL_PENDING_BYTE: if( nArg==3 ){ - unsigned int opt = (unsigned int)integerValue(azArg[2]); + unsigned int opt = (unsigned int)integerValue(azArg[2]); rc = sqlite3_test_control(testctrl, opt); fprintf(p->out, "%d (0x%08x)\n", rc, rc); } else { From 9ed04ebc8fb16a62e2ec7bfe9b5d689cc96b03ba Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 19 Jul 2013 23:58:41 +0000 Subject: [PATCH 15/47] Fixes to test numbering. FossilOrigin-Name: f755b4b21c885f3e897c2a79fc7ac1220210e653 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/func.test | 3 ++- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 4996acd786..7f4238fd3e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sunused\s"codec"\scode\sfrom\sthe\scommand-line\sshell. -D 2013-07-18T20:28:29.811 +C Fixes\sto\stest\snumbering. +D 2013-07-19T23:58:41.035 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -556,7 +556,7 @@ F test/fts4merge4.test c19c85ca1faa7b6d536832b49c12e1867235f584 F test/fts4noti.test aed33ba44808852dcb24bf70fa132e7bf530f057 F test/fts4unicode.test c8ac44217bf6c17812b03eaafa6c06995ad304c2 F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d -F test/func.test 9161beda516d6006d31e6ea6119579286512f751 +F test/func.test cd25cf605c5a345d038dc7b84232204c6a901c84 F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f F test/func3.test 001021e5b88bd02a3b365a5c5fd8f6f49d39744a F test/fuzz-oss1.test 4912e528ec9cf2f42134456933659d371c9e0d74 @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 62465ecba7431e1d71e17a61f1af7dc65fe4fe97 -R ff789e1ed27e10ae116b350d443e40e4 -U drh -Z 147237eb091c75d2b25ac79bc55dd938 +P 37abfe0c1e5da63342389c527a9f7cbe0f8392d9 +R bf93564123619a1486a6f7766b8ee80b +U mistachkin +Z 75656b834fe7d7733acaf3f05e33a605 diff --git a/manifest.uuid b/manifest.uuid index a93721bf61..823f8655fd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -37abfe0c1e5da63342389c527a9f7cbe0f8392d9 \ No newline at end of file +f755b4b21c885f3e897c2a79fc7ac1220210e653 \ No newline at end of file diff --git a/test/func.test b/test/func.test index 06f9f41d01..d8303f8bf3 100644 --- a/test/func.test +++ b/test/func.test @@ -14,6 +14,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +set testprefix func # Create a table to work with. # @@ -703,7 +704,7 @@ do_execsql_test 13.8.5 { } {0 two 1 two} db cache flush set V "three" -do_execsql_test 2.3 { +do_execsql_test 13.8.6 { SELECT test_auxdata($V), $V FROM t4; } {0 three 1 three} From 036acf36445ff83d689f3d0e22a2949e294e9228 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Sat, 20 Jul 2013 00:34:31 +0000 Subject: [PATCH 16/47] Add 'queryplantest' target to the MSVC makefile. FossilOrigin-Name: ad0551e039ccaa9e7a28682b756b56ac2b8fef0d --- Makefile.msc | 3 +++ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 206f1680d4..dd75e0dac7 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1239,6 +1239,9 @@ soaktest: testfixture.exe sqlite3.exe fulltestonly: testfixture.exe sqlite3.exe .\testfixture.exe $(TOP)\test\full.test +queryplantest: testfixture.exe sqlite3.exe + .\testfixture.exe $(TOP)\test\permutations.test queryplanner + test: testfixture.exe sqlite3.exe .\testfixture.exe $(TOP)\test\veryquick.test diff --git a/manifest b/manifest index 7f4238fd3e..156319adc0 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Fixes\sto\stest\snumbering. -D 2013-07-19T23:58:41.035 +C Add\s'queryplantest'\starget\sto\sthe\sMSVC\smakefile. +D 2013-07-20T00:34:31.920 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 -F Makefile.msc 7d226394826f060f232c0a02a468e8651819b7c2 +F Makefile.msc 1edbab21c991eea719e5abb8067868b63268a371 F Makefile.vxworks db21ed42a01d5740e656b16f92cb5d8d5e5dd315 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 F VERSION f135b651727f978b7191bd6fa12c7fc1e13e13ac @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 37abfe0c1e5da63342389c527a9f7cbe0f8392d9 -R bf93564123619a1486a6f7766b8ee80b +P f755b4b21c885f3e897c2a79fc7ac1220210e653 +R c94bb34849c12b79ab21d48a7e4bfef4 U mistachkin -Z 75656b834fe7d7733acaf3f05e33a605 +Z e904e41c59c0106f85082fb614ea3828 diff --git a/manifest.uuid b/manifest.uuid index 823f8655fd..7a0ddc57b5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f755b4b21c885f3e897c2a79fc7ac1220210e653 \ No newline at end of file +ad0551e039ccaa9e7a28682b756b56ac2b8fef0d \ No newline at end of file From 0d1961e91c41c45574a4806364ba9a7ad7b63c18 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 25 Jul 2013 16:27:51 +0000 Subject: [PATCH 17/47] Enhance the progress handler so that it keeps track of the number of VDBE cycles across sqlite3_step() calls and issues callbacks when the cumulative instruction count reaches threshold. FossilOrigin-Name: 4698a82ef855a8e56163622283fb25317d7efdc4 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/sqlite.h.in | 3 ++- src/vdbe.c | 19 ++++++++++++++++--- 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 156319adc0..91234f232b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\s'queryplantest'\starget\sto\sthe\sMSVC\smakefile. -D 2013-07-20T00:34:31.920 +C Enhance\sthe\sprogress\shandler\sso\sthat\sit\skeeps\strack\sof\sthe\snumber\sof\sVDBE\ncycles\sacross\ssqlite3_step()\scalls\sand\sissues\scallbacks\swhen\sthe\scumulative\ninstruction\scount\sreaches\sthreshold. +D 2013-07-25T16:27:51.835 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -218,7 +218,7 @@ F src/resolve.c 89f9003e8316ee3a172795459efc2a0274e1d5a8 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 91b62654caf8dfe292fb8882715e575d34ad3874 F src/shell.c 7da98ff9cbb19d7ef213a295178039bcb457804a -F src/sqlite.h.in ba19609c0dab076a169b0cd2e7d4a479c5b3f664 +F src/sqlite.h.in d6a7523d6795317aac574fccc67d9df25253771c F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqliteInt.h 6d3115f774aa3e87737f9447c9c0cea992c5bdbf @@ -277,7 +277,7 @@ F src/update.c 8e76c3d03e4b7b21cb250bd2df0c05e12993e577 F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f F src/util.c f566b5138099a2df8533b190d0dcc74b7dfbe0c9 F src/vacuum.c d9c5759f4c5a438bb43c2086f72c5d2edabc36c8 -F src/vdbe.c 816e686198c7d83a71545dfb4b34ec65f8071d23 +F src/vdbe.c d6048a720c197db2f0e7d618e918bd2e2eff0322 F src/vdbe.h f380af2a7fab32ba8a8b05bf042497636afec66d F src/vdbeInt.h e9b7c6b165a31a4715c5aa97223d20d265515231 F src/vdbeapi.c 4d13580bd058b39623e8fcfc233b7df4b8191e8b @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P f755b4b21c885f3e897c2a79fc7ac1220210e653 -R c94bb34849c12b79ab21d48a7e4bfef4 -U mistachkin -Z e904e41c59c0106f85082fb614ea3828 +P ad0551e039ccaa9e7a28682b756b56ac2b8fef0d +R d2338440342f7943c0617ebcafb61de4 +U drh +Z 47bbc05204d6969b9fef882b748d56a7 diff --git a/manifest.uuid b/manifest.uuid index 7a0ddc57b5..21d84aac97 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ad0551e039ccaa9e7a28682b756b56ac2b8fef0d \ No newline at end of file +4698a82ef855a8e56163622283fb25317d7efdc4 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index a87e8810f2..2fc3e80a4a 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2556,7 +2556,8 @@ SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*, ** ^The parameter P is passed through as the only parameter to the ** callback function X. ^The parameter N is the approximate number of ** [virtual machine instructions] that are evaluated between successive -** invocations of the callback X. +** invocations of the callback X. ^If N is less than one then the progress +** handler is disabled. ** ** ^Only a single progress handler may be defined at one time per ** [database connection]; setting a new progress handler cancels the diff --git a/src/vdbe.c b/src/vdbe.c index af135f5309..4752c1a882 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -555,7 +555,7 @@ int sqlite3VdbeExec( int iCompare = 0; /* Result of last OP_Compare operation */ unsigned nVmStep = 0; /* Number of virtual machine steps */ #ifndef SQLITE_OMIT_PROGRESS_CALLBACK - unsigned nProgressOps = 0; /* nVmStep at last progress callback. */ + unsigned nProgressLimit; /* Invoke xProgress() when nVmStep reaches this */ #endif Mem *aMem = p->aMem; /* Copy of p->aMem */ Mem *pIn1 = 0; /* 1st input operand */ @@ -585,6 +585,17 @@ int sqlite3VdbeExec( db->busyHandler.nBusy = 0; CHECK_FOR_INTERRUPT; sqlite3VdbeIOTraceSql(p); +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + if( db->xProgress ){ + assert( 0 < db->nProgressOps ); + nProgressLimit = (unsigned)p->aCounter[SQLITE_STMTSTATUS_VM_STEP-1]; + if( nProgressLimit==0 ){ + nProgressLimit = db->nProgressOps; + }else{ + nProgressLimit %= (unsigned)db->nProgressOps; + } + } +#endif #ifdef SQLITE_DEBUG sqlite3BeginBenignMalloc(); if( p->pc==0 && (p->db->flags & SQLITE_VdbeListing)!=0 ){ @@ -745,14 +756,16 @@ check_for_interrupt: ** If the progress callback returns non-zero, exit the virtual machine with ** a return code SQLITE_ABORT. */ - if( db->xProgress!=0 && (nVmStep - nProgressOps)>=db->nProgressOps ){ + if( db->xProgress!=0 && nVmStep>=nProgressLimit ){ int prc; prc = db->xProgress(db->pProgressArg); if( prc!=0 ){ rc = SQLITE_INTERRUPT; goto vdbe_error_halt; } - nProgressOps = nVmStep; + if( db->xProgress!=0 ){ + nProgressLimit = nVmStep + db->nProgressOps - (nVmStep%db->nProgressOps); + } } #endif From 1d1f07df583750de55d7e3651b46a297741c9116 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 25 Jul 2013 16:41:39 +0000 Subject: [PATCH 18/47] Fix a typo in main.c: SQLITE_DEAULT_AUTOMATIC_INDEX -> SQLITE_DEFAULT_AUTOMATIC_INDEX FossilOrigin-Name: cc78e21c7794948a187e694773735058fc7460d7 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/main.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 91234f232b..a70f958547 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\sprogress\shandler\sso\sthat\sit\skeeps\strack\sof\sthe\snumber\sof\sVDBE\ncycles\sacross\ssqlite3_step()\scalls\sand\sissues\scallbacks\swhen\sthe\scumulative\ninstruction\scount\sreaches\sthreshold. -D 2013-07-25T16:27:51.835 +C Fix\sa\stypo\sin\smain.c:\sSQLITE_DEAULT_AUTOMATIC_INDEX\s->\sSQLITE_DEFAULT_AUTOMATIC_INDEX +D 2013-07-25T16:41:39.550 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -185,7 +185,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303 -F src/main.c e5810b2d7a0bd19f3d75ce60e3ed918cafc0a3f3 +F src/main.c 9286e1f5660ff32bd53a9a64ab09ed9af2542b5d F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P ad0551e039ccaa9e7a28682b756b56ac2b8fef0d -R d2338440342f7943c0617ebcafb61de4 -U drh -Z 47bbc05204d6969b9fef882b748d56a7 +P 4698a82ef855a8e56163622283fb25317d7efdc4 +R 6ed52877d6372e3a1e06cdc8791460bf +U dan +Z 26271be395085fd778fe9c8e8c0dcba3 diff --git a/manifest.uuid b/manifest.uuid index 21d84aac97..bde6301cf5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4698a82ef855a8e56163622283fb25317d7efdc4 \ No newline at end of file +cc78e21c7794948a187e694773735058fc7460d7 \ No newline at end of file diff --git a/src/main.c b/src/main.c index c23a6212d3..9b25ae26b9 100644 --- a/src/main.c +++ b/src/main.c @@ -2455,7 +2455,7 @@ static int openDatabase( db->szMmap = sqlite3GlobalConfig.szMmap; db->nextPagesize = 0; db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger -#if !defined(SQLITE_DEAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX +#if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX | SQLITE_AutoIndex #endif #if SQLITE_DEFAULT_FILE_FORMAT<4 From 53371f90e4e821fd6595d86c5a32d26fb0ad49dd Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 25 Jul 2013 17:07:03 +0000 Subject: [PATCH 19/47] In the command-line shell, work around the fact that popen() and pclose() are not defined in stdio.h. in C89 and later. FossilOrigin-Name: 8bcbb33fd0a970e16a920e1d35571836dbb9ba50 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c | 7 ++++++- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index a70f958547..0267a8bd42 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sin\smain.c:\sSQLITE_DEAULT_AUTOMATIC_INDEX\s->\sSQLITE_DEFAULT_AUTOMATIC_INDEX -D 2013-07-25T16:41:39.550 +C In\sthe\scommand-line\sshell,\swork\saround\sthe\sfact\sthat\spopen()\sand\spclose()\nare\snot\sdefined\sin\sstdio.h.\sin\sC89\sand\slater. +D 2013-07-25T17:07:03.896 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -217,7 +217,7 @@ F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 89f9003e8316ee3a172795459efc2a0274e1d5a8 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 91b62654caf8dfe292fb8882715e575d34ad3874 -F src/shell.c 7da98ff9cbb19d7ef213a295178039bcb457804a +F src/shell.c 52f975eae87c8338c4dfbf4c2842d2a0971f01fd F src/sqlite.h.in d6a7523d6795317aac574fccc67d9df25253771c F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 4698a82ef855a8e56163622283fb25317d7efdc4 -R 6ed52877d6372e3a1e06cdc8791460bf -U dan -Z 26271be395085fd778fe9c8e8c0dcba3 +P cc78e21c7794948a187e694773735058fc7460d7 +R 2224b684736c7849886faa41d9e31dd9 +U drh +Z a0a43d445d787e155974499407392c91 diff --git a/manifest.uuid b/manifest.uuid index bde6301cf5..7a9178900c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cc78e21c7794948a187e694773735058fc7460d7 \ No newline at end of file +8bcbb33fd0a970e16a920e1d35571836dbb9ba50 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index d6b3159a49..7b8a8ad7f3 100644 --- a/src/shell.c +++ b/src/shell.c @@ -65,7 +65,7 @@ #define isatty(h) _isatty(h) #define access(f,m) _access((f),(m)) #undef popen -#define popen(a,b) _popen((a),(b)) +#define popen _popen #undef pclose #define pclose _pclose #else @@ -74,6 +74,11 @@ extern int isatty(int); #endif +/* popen and pclose are not C89 functions and so are sometimes omitted from +** the header */ +FILE *popen(const char*,const char*); +int pclose(FILE*); + #if defined(_WIN32_WCE) /* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty() * thus we always assume that we have a console. That can be From 30a6837c355cbc7a136c6f0924e327de37a7f1bb Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 29 Jul 2013 13:51:54 +0000 Subject: [PATCH 20/47] In main.mk, always recompile vdbe.o and parse.o first, since changes to either parse.y or vdbe.c will cause all files to be recompiled and if there are syntax errors in vdbe.c or parse.y we want to hit them early in the compile process. FossilOrigin-Name: a94a66d10f160ee79fffa8527655c2cc4a0c7103 --- main.mk | 7 ++++--- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/main.mk b/main.mk index d8c4c29168..1d9dd105c5 100644 --- a/main.mk +++ b/main.mk @@ -50,7 +50,8 @@ TCCX += -I$(TOP)/ext/async # Object files for the SQLite library. # -LIBOBJ+= alter.o analyze.o attach.o auth.o \ +LIBOBJ+= vdbe.o parse.o \ + alter.o analyze.o attach.o auth.o \ backup.o bitvec.o btmutex.o btree.o build.o \ callback.o complete.o ctime.o date.o delete.o expr.o fault.o fkey.o \ fts3.o fts3_aux.o fts3_expr.o fts3_hash.o fts3_icu.o fts3_porter.o \ @@ -63,11 +64,11 @@ LIBOBJ+= alter.o analyze.o attach.o auth.o \ memjournal.o \ mutex.o mutex_noop.o mutex_unix.o mutex_w32.o \ notify.o opcodes.o os.o os_unix.o os_win.o \ - pager.o parse.o pcache.o pcache1.o pragma.o prepare.o printf.o \ + pager.o pcache.o pcache1.o pragma.o prepare.o printf.o \ random.o resolve.o rowset.o rtree.o select.o status.o \ table.o tokenize.o trigger.o \ update.o util.o vacuum.o \ - vdbe.o vdbeapi.o vdbeaux.o vdbeblob.o vdbemem.o vdbesort.o \ + vdbeapi.o vdbeaux.o vdbeblob.o vdbemem.o vdbesort.o \ vdbetrace.o wal.o walker.o where.o utf.o vtab.o diff --git a/manifest b/manifest index 0267a8bd42..5b1c91fed1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\scommand-line\sshell,\swork\saround\sthe\sfact\sthat\spopen()\sand\spclose()\nare\snot\sdefined\sin\sstdio.h.\sin\sC89\sand\slater. -D 2013-07-25T17:07:03.896 +C In\smain.mk,\salways\srecompile\svdbe.o\sand\sparse.o\sfirst,\ssince\schanges\sto\seither\nparse.y\sor\svdbe.c\swill\scause\sall\sfiles\sto\sbe\srecompiled\sand\sif\sthere\sare\nsyntax\serrors\sin\svdbe.c\sor\sparse.y\swe\swant\sto\shit\sthem\searly\sin\sthe\scompile\nprocess. +D 2013-07-29T13:51:54.129 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -139,7 +139,7 @@ F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt f2b23a6bde8f1c6e86b957e4d94eab0add520b0d -F main.mk c4335dbdb004d37e00e23d6ff226e55df0db5b21 +F main.mk a10f1925ae3bb545a045d1f1867506f49bee972f F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f F mkextw.sh d2a981497b404d6498f5ff3e3b1f3816bdfcb338 @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P cc78e21c7794948a187e694773735058fc7460d7 -R 2224b684736c7849886faa41d9e31dd9 +P 8bcbb33fd0a970e16a920e1d35571836dbb9ba50 +R ac65f68c338ba95f0df6e2b9636e977b U drh -Z a0a43d445d787e155974499407392c91 +Z 6ff5447967bf3da3ba994ae07683c81d diff --git a/manifest.uuid b/manifest.uuid index 7a9178900c..75982a66eb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8bcbb33fd0a970e16a920e1d35571836dbb9ba50 \ No newline at end of file +a94a66d10f160ee79fffa8527655c2cc4a0c7103 \ No newline at end of file From 443dbcf5ae3fd211245b663ecfa479c86bc86ea2 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 29 Jul 2013 15:54:06 +0000 Subject: [PATCH 21/47] Comment and preprocessor macro cleanup. FossilOrigin-Name: c0809b5e32c2ca0600098447a573e718eaeb319f --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqliteInt.h | 30 ++++++++---------------------- src/test_vfs.c | 1 + 4 files changed, 17 insertions(+), 30 deletions(-) diff --git a/manifest b/manifest index 5b1c91fed1..7ff295a15b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\smain.mk,\salways\srecompile\svdbe.o\sand\sparse.o\sfirst,\ssince\schanges\sto\seither\nparse.y\sor\svdbe.c\swill\scause\sall\sfiles\sto\sbe\srecompiled\sand\sif\sthere\sare\nsyntax\serrors\sin\svdbe.c\sor\sparse.y\swe\swant\sto\shit\sthem\searly\sin\sthe\scompile\nprocess. -D 2013-07-29T13:51:54.129 +C Comment\sand\spreprocessor\smacro\scleanup. +D 2013-07-29T15:54:06.213 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -221,7 +221,7 @@ F src/shell.c 52f975eae87c8338c4dfbf4c2842d2a0971f01fd F src/sqlite.h.in d6a7523d6795317aac574fccc67d9df25253771c F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 6d3115f774aa3e87737f9447c9c0cea992c5bdbf +F src/sqliteInt.h 89b52c053ebafa76f03bab4f0c8ee1e390eb7489 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -268,7 +268,7 @@ F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd F src/test_syscall.c 16dbe79fb320fadb5acd7a0a59f49e52ab2d2091 F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa F src/test_thread.c 1e133a40b50e9c035b00174035b846e7eef481cb -F src/test_vfs.c 12d9931f65acde64961523b6f420ba7cd057fbd7 +F src/test_vfs.c e72f555ef7a59080f898fcf1a233deb9eb704ea9 F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c e0e8fd3cb90a88451f6b6425726c84747b6b20d7 @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 8bcbb33fd0a970e16a920e1d35571836dbb9ba50 -R ac65f68c338ba95f0df6e2b9636e977b +P a94a66d10f160ee79fffa8527655c2cc4a0c7103 +R 40bf3454255194f171fc87e9079822c4 U drh -Z 6ff5447967bf3da3ba994ae07683c81d +Z 077c159fd8ed6b7ef4b9adb97eba8746 diff --git a/manifest.uuid b/manifest.uuid index 75982a66eb..a931d8409b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a94a66d10f160ee79fffa8527655c2cc4a0c7103 \ No newline at end of file +c0809b5e32c2ca0600098447a573e718eaeb319f \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 35a7778a92..795740978f 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -161,9 +161,6 @@ ** will cause HeapValidate to be called. If heap validation should fail, an ** assertion will be triggered. ** -** (Historical note: There used to be several other options, but we've -** pared it down to just these three.) -** ** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as ** the default. */ @@ -201,20 +198,13 @@ # define _XOPEN_SOURCE 600 #endif -/* -** The TCL headers are only needed when compiling the TCL bindings. -*/ -#if defined(SQLITE_TCL) || defined(TCLSH) -# include -#endif - /* ** NDEBUG and SQLITE_DEBUG are opposites. It should always be true that ** defined(NDEBUG)==!defined(SQLITE_DEBUG). If this is not currently true, ** make it true by defining or undefining NDEBUG. ** -** Setting NDEBUG makes the code smaller and run faster by disabling the -** number assert() statements in the code. So we want the default action +** Setting NDEBUG makes the code smaller and faster by disabling the +** assert() statements in the code. So we want the default action ** to be for NDEBUG to be set and NDEBUG to be undefined only if SQLITE_DEBUG ** is set. Thus NDEBUG becomes an opt-in rather than an opt-out ** feature. @@ -284,7 +274,7 @@ ** In other words, ALWAYS and NEVER are added for defensive code. ** ** When doing coverage testing ALWAYS and NEVER are hard-coded to -** be true and false so that the unreachable code then specify will +** be true and false so that the unreachable code they specify will ** not be counted as untested code. */ #if defined(SQLITE_COVERAGE_TEST) @@ -308,16 +298,12 @@ /* ** The macro unlikely() is a hint that surrounds a boolean ** expression that is usually false. Macro likely() surrounds -** a boolean expression that is usually true. GCC is able to -** use these hints to generate better code, sometimes. +** a boolean expression that is usually true. These hints could, +** in theory, be used by the compiler to generate better code, but +** currently they are just comments for human readers. */ -#if defined(__GNUC__) && 0 -# define likely(X) __builtin_expect((X),1) -# define unlikely(X) __builtin_expect((X),0) -#else -# define likely(X) !!(X) -# define unlikely(X) !!(X) -#endif +#define likely(X) (X) +#define unlikely(X) (X) #include "sqlite3.h" #include "hash.h" diff --git a/src/test_vfs.c b/src/test_vfs.c index 8b6b530bb6..613b0fce77 100644 --- a/src/test_vfs.c +++ b/src/test_vfs.c @@ -28,6 +28,7 @@ #include "sqlite3.h" #include "sqliteInt.h" +#include typedef struct Testvfs Testvfs; typedef struct TestvfsShm TestvfsShm; From f67feefffcb6a5e23290184bfa1ccbfc0b839d4f Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 29 Jul 2013 19:03:20 +0000 Subject: [PATCH 22/47] For the MSVC makefile, recompile vdbe.lo and parse.lo first. FossilOrigin-Name: 9e819f0f12b6f2a8e0e7a90251b3115ff1595f25 --- Makefile.msc | 6 +++--- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index dd75e0dac7..23c5b17f08 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -472,7 +472,7 @@ NAWK = gawk.exe # Object files for the SQLite library (non-amalgamation). # -LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \ +LIBOBJS0 = vdbe.lo parse.lo alter.lo analyze.lo attach.lo auth.lo \ backup.lo bitvec.lo btmutex.lo btree.lo build.lo \ callback.lo complete.lo ctime.lo date.lo delete.lo \ expr.lo fault.lo fkey.lo \ @@ -485,11 +485,11 @@ LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \ memjournal.lo \ mutex.lo mutex_noop.lo mutex_unix.lo mutex_w32.lo \ notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \ - pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \ + pager.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \ random.lo resolve.lo rowset.lo rtree.lo select.lo status.lo \ table.lo tokenize.lo trigger.lo \ update.lo util.lo vacuum.lo \ - vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \ + vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \ vdbetrace.lo wal.lo walker.lo where.lo utf.lo vtab.lo # Object files for the amalgamation. diff --git a/manifest b/manifest index 7ff295a15b..da5f889018 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Comment\sand\spreprocessor\smacro\scleanup. -D 2013-07-29T15:54:06.213 +C For\sthe\sMSVC\smakefile,\srecompile\svdbe.lo\sand\sparse.lo\sfirst. +D 2013-07-29T19:03:20.408 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 -F Makefile.msc 1edbab21c991eea719e5abb8067868b63268a371 +F Makefile.msc e9f41f89111627baaabd95cab4988b8d1c3e47c9 F Makefile.vxworks db21ed42a01d5740e656b16f92cb5d8d5e5dd315 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 F VERSION f135b651727f978b7191bd6fa12c7fc1e13e13ac @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P a94a66d10f160ee79fffa8527655c2cc4a0c7103 -R 40bf3454255194f171fc87e9079822c4 -U drh -Z 077c159fd8ed6b7ef4b9adb97eba8746 +P c0809b5e32c2ca0600098447a573e718eaeb319f +R acca2317d80cadebf01ca0291e013836 +U mistachkin +Z 6eb4dac3f80be1a20108b92a7b5da831 diff --git a/manifest.uuid b/manifest.uuid index a931d8409b..a579d0511b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c0809b5e32c2ca0600098447a573e718eaeb319f \ No newline at end of file +9e819f0f12b6f2a8e0e7a90251b3115ff1595f25 \ No newline at end of file From 6b36e82c7b4ec740d872bb6917af53519e63b4ad Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 30 Jul 2013 15:10:32 +0000 Subject: [PATCH 23/47] Reduce the size of the stack required by the codeOneLoopStart() function in where.c. FossilOrigin-Name: eb6d4278b8516e0571269049d1eaa55066f51b1a --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 33 +++++++++++++++++++-------------- 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index da5f889018..327c096cff 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C For\sthe\sMSVC\smakefile,\srecompile\svdbe.lo\sand\sparse.lo\sfirst. -D 2013-07-29T19:03:20.408 +C Reduce\sthe\ssize\sof\sthe\sstack\srequired\sby\sthe\scodeOneLoopStart()\sfunction\sin\nwhere.c. +D 2013-07-30T15:10:32.747 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -290,7 +290,7 @@ F src/vtab.c 2e8b489db47e20ae36cd247932dc671c9ded0624 F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73 -F src/where.c 1a26c37b7b54d198e2ec9aa127d22c3dcfe89de8 +F src/where.c a55e27475c3d4c72c8bf1aaf9ece70e47e8731cf F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P c0809b5e32c2ca0600098447a573e718eaeb319f -R acca2317d80cadebf01ca0291e013836 -U mistachkin -Z 6eb4dac3f80be1a20108b92a7b5da831 +P 9e819f0f12b6f2a8e0e7a90251b3115ff1595f25 +R 8a77f3488eeca7f033bc07ab4b9db562 +U drh +Z 51b3ad13ced3eb326ea64314852a899d diff --git a/manifest.uuid b/manifest.uuid index a579d0511b..116c2adffe 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9e819f0f12b6f2a8e0e7a90251b3115ff1595f25 \ No newline at end of file +eb6d4278b8516e0571269049d1eaa55066f51b1a \ No newline at end of file diff --git a/src/where.c b/src/where.c index d3182f8094..9f65d551a3 100644 --- a/src/where.c +++ b/src/where.c @@ -3250,6 +3250,7 @@ static Bitmask codeOneLoopStart( WhereClause *pWC; /* Decomposition of the entire WHERE clause */ WhereTerm *pTerm; /* A WHERE clause term */ Parse *pParse; /* Parsing context */ + sqlite3 *db; /* Database connection */ Vdbe *v; /* The prepared stmt under constructions */ struct SrcList_item *pTabItem; /* FROM clause term being coded */ int addrBrk; /* Jump here to break out of the loop */ @@ -3261,6 +3262,7 @@ static Bitmask codeOneLoopStart( pParse = pWInfo->pParse; v = pParse->pVdbe; pWC = &pWInfo->sWC; + db = pParse->db; pLevel = &pWInfo->a[iLevel]; pLoop = pLevel->pWLoop; pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; @@ -3551,7 +3553,7 @@ static Bitmask codeOneLoopStart( ** starting at regBase. */ regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff); - zEndAff = sqlite3DbStrDup(pParse->db, zStartAff); + zEndAff = sqlite3DbStrDup(db, zStartAff); addrNxt = pLevel->addrNxt; /* If we are doing a reverse order scan on an ascending index, or @@ -3636,8 +3638,8 @@ static Bitmask codeOneLoopStart( nConstraint++; testcase( pRangeEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */ } - sqlite3DbFree(pParse->db, zStartAff); - sqlite3DbFree(pParse->db, zEndAff); + sqlite3DbFree(db, zStartAff); + sqlite3DbFree(db, zEndAff); /* Top of the loop body */ pLevel->p2 = sqlite3VdbeCurrentAddr(v); @@ -3764,7 +3766,7 @@ static Bitmask codeOneLoopStart( int nNotReady; /* The number of notReady tables */ struct SrcList_item *origSrc; /* Original list of tables */ nNotReady = pWInfo->nLevel - iLevel - 1; - pOrTab = sqlite3StackAllocRaw(pParse->db, + pOrTab = sqlite3StackAllocRaw(db, sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0])); if( pOrTab==0 ) return notReady; pOrTab->nAlloc = (u8)(nNotReady + 1); @@ -3818,8 +3820,8 @@ static Bitmask codeOneLoopStart( if( ExprHasProperty(pExpr, EP_FromJoin) ) continue; if( pWC->a[iTerm].wtFlags & (TERM_ORINFO) ) continue; if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue; - pExpr = sqlite3ExprDup(pParse->db, pExpr, 0); - pAndExpr = sqlite3ExprAnd(pParse->db, pAndExpr, pExpr); + pExpr = sqlite3ExprDup(db, pExpr, 0); + pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr); } if( pAndExpr ){ pAndExpr = sqlite3PExpr(pParse, TK_AND, 0, pAndExpr, 0); @@ -3839,7 +3841,7 @@ static Bitmask codeOneLoopStart( pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY | WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY, iCovCur); - assert( pSubWInfo || pParse->nErr || pParse->db->mallocFailed ); + assert( pSubWInfo || pParse->nErr || db->mallocFailed ); if( pSubWInfo ){ WhereLoop *pSubLoop; explainOneScan( @@ -3894,13 +3896,13 @@ static Bitmask codeOneLoopStart( if( pCov ) pLevel->iIdxCur = iCovCur; if( pAndExpr ){ pAndExpr->pLeft = 0; - sqlite3ExprDelete(pParse->db, pAndExpr); + sqlite3ExprDelete(db, pAndExpr); } sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v)); sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk); sqlite3VdbeResolveLabel(v, iLoopBody); - if( pWInfo->nLevel>1 ) sqlite3StackFree(pParse->db, pOrTab); + if( pWInfo->nLevel>1 ) sqlite3StackFree(db, pOrTab); if( !untestedTerms ) disableTerm(pLevel, pTerm); }else #endif /* SQLITE_OMIT_OR_OPTIMIZATION */ @@ -3955,9 +3957,8 @@ static Bitmask codeOneLoopStart( ** the implied "t1.a=123" constraint. */ for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){ - Expr *pE; + Expr *pE, *pEAlt; WhereTerm *pAlt; - Expr sEq; if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; if( pTerm->eOperator!=(WO_EQUIV|WO_EQ) ) continue; if( pTerm->leftCursor!=iCur ) continue; @@ -3971,9 +3972,13 @@ static Bitmask codeOneLoopStart( testcase( pAlt->eOperator & WO_EQ ); testcase( pAlt->eOperator & WO_IN ); VdbeNoopComment((v, "begin transitive constraint")); - sEq = *pAlt->pExpr; - sEq.pLeft = pE->pLeft; - sqlite3ExprIfFalse(pParse, &sEq, addrCont, SQLITE_JUMPIFNULL); + pEAlt = sqlite3StackAllocRaw(db, sizeof(*pEAlt)); + if( pEAlt ){ + *pEAlt = *pAlt->pExpr; + pEAlt->pLeft = pE->pLeft; + sqlite3ExprIfFalse(pParse, pEAlt, addrCont, SQLITE_JUMPIFNULL); + sqlite3StackFree(db, pEAlt); + } } /* For a LEFT OUTER JOIN, generate code that will record the fact that From 1fe0537e51218d545672f672b923d600d73d7824 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 31 Jul 2013 18:12:26 +0000 Subject: [PATCH 24/47] Here begins an experimental branch for exploring the idea of a partial index. This check-in is able to parse a WHERE clause on a CREATE INDEX statement, but does not actually do anythingn with that WHERE clause yet. FossilOrigin-Name: 6794b2dcb48b3507caccfc7867fc185818cf8291 --- manifest | 20 ++++++++++++-------- manifest.uuid | 2 +- src/build.c | 13 ++++++++----- src/parse.y | 9 +++++---- src/sqliteInt.h | 3 ++- test/index6.test | 33 +++++++++++++++++++++++++++++++++ 6 files changed, 61 insertions(+), 19 deletions(-) create mode 100644 test/index6.test diff --git a/manifest b/manifest index 327c096cff..0a7fe0faee 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reduce\sthe\ssize\sof\sthe\sstack\srequired\sby\sthe\scodeOneLoopStart()\sfunction\sin\nwhere.c. -D 2013-07-30T15:10:32.747 +C Here\sbegins\san\sexperimental\sbranch\sfor\sexploring\sthe\sidea\sof\sa\spartial\sindex.\nThis\scheck-in\sis\sable\sto\sparse\sa\sWHERE\sclause\son\sa\sCREATE\sINDEX\sstatement,\sbut\ndoes\snot\sactually\sdo\sanythingn\swith\sthat\sWHERE\sclause\syet. +D 2013-07-31T18:12:26.006 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 3f7bbfd72efb1cbf6a49515c376a031767ec930a F src/btree.h 6fa8a3ff2483d0bb64a9f0105a8cedeac9e00cca F src/btreeInt.h eecc84f02375b2bb7a44abbcbbe3747dde73edb2 -F src/build.c 42239cfd95533e4aacf4d58b4724c8f858de5ced +F src/build.c c2903be4a825d6be0a518f87b60e0dcf878782d3 F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 4262c227bc91cecc61ae37ed3a40f08069cfa267 @@ -206,7 +206,7 @@ F src/os_unix.c 9eafa5458cf2ff684ddccff82c9bb113c7cad847 F src/os_win.c 074cb2b9bca6a1c2bd72acf04666cdc554bfaa9b F src/pager.c 5d2f7475260a8588f9c441bb309d2b7eaa7ded3b F src/pager.h 5cb78b8e1adfd5451e600be7719f5a99d87ac3b1 -F src/parse.y 9acfcc83ddbf0cf82f0ed9582ccf0ad6c366ff37 +F src/parse.y a950b48d4363f44dd98fef8a89fbd48970ebd9ce F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c d23d07716de96c7c0c2503ec5051a4384c3fb938 @@ -221,7 +221,7 @@ F src/shell.c 52f975eae87c8338c4dfbf4c2842d2a0971f01fd F src/sqlite.h.in d6a7523d6795317aac574fccc67d9df25253771c F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 89b52c053ebafa76f03bab4f0c8ee1e390eb7489 +F src/sqliteInt.h c99f22c5bda01f07e2f9a9a8cb2c0b9adeea696c F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -589,6 +589,7 @@ F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6 F test/index3.test 423a25c789fc8cc51aaf2a4370bbdde2d9e9eed7 F test/index4.test 2983216eb8c86ee62d9ed7cb206b5cc3331c0026 F test/index5.test fc07c14193c0430814e7a08b5da46888ee795c33 +F test/index6.test cbd74aa8604e29982438a7defae9fadaf9605336 F test/indexedby.test 0e959308707c808515c3a51363f7a9835027108c F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 @@ -1103,7 +1104,10 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 9e819f0f12b6f2a8e0e7a90251b3115ff1595f25 -R 8a77f3488eeca7f033bc07ab4b9db562 +P eb6d4278b8516e0571269049d1eaa55066f51b1a +R d0aa2f7065f4153ebb66a1af4210e515 +T *branch * partial-indices +T *sym-partial-indices * +T -sym-trunk * U drh -Z 51b3ad13ced3eb326ea64314852a899d +Z cfed8379e8335c37848dda6e7de0acdf diff --git a/manifest.uuid b/manifest.uuid index 116c2adffe..4d7035783c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eb6d4278b8516e0571269049d1eaa55066f51b1a \ No newline at end of file +6794b2dcb48b3507caccfc7867fc185818cf8291 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 0a3922c952..7ca2ef00cc 100644 --- a/src/build.c +++ b/src/build.c @@ -382,6 +382,7 @@ static void freeIndex(sqlite3 *db, Index *p){ #ifndef SQLITE_OMIT_ANALYZE sqlite3DeleteIndexSamples(db, p); #endif + sqlite3ExprDelete(db, p->pPartIdxWhere); sqlite3DbFree(db, p->zColAff); sqlite3DbFree(db, p); } @@ -1225,7 +1226,8 @@ void sqlite3AddPrimaryKey( #endif }else{ Index *p; - p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0); + p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0, + 0, sortOrder, 0); if( p ){ p->autoIndex = 2; } @@ -2483,6 +2485,7 @@ Index *sqlite3CreateIndex( int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ Token *pStart, /* The CREATE token that begins this statement */ Token *pEnd, /* The ")" that closes the CREATE INDEX statement */ + Expr *pPIWhere, /* WHERE clause for partial indices */ int sortOrder, /* Sort order of primary key when pList==NULL */ int ifNotExist /* Omit error if index already exists */ ){ @@ -2699,6 +2702,8 @@ Index *sqlite3CreateIndex( pIndex->uniqNotNull = onError==OE_Abort; pIndex->autoIndex = (u8)(pName==0); pIndex->pSchema = db->aDb[iDb].pSchema; + pIndex->pPartIdxWhere = pPIWhere; + pPIWhere = 0; assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); /* Check to see if we should honor DESC requests on index columns @@ -2933,10 +2938,8 @@ Index *sqlite3CreateIndex( /* Clean up before exiting */ exit_create_index: - if( pIndex ){ - sqlite3DbFree(db, pIndex->zColAff); - sqlite3DbFree(db, pIndex); - } + if( pIndex ) freeIndex(db, pIndex); + sqlite3ExprDelete(db, pPIWhere); sqlite3ExprListDelete(db, pList); sqlite3SrcListDelete(db, pTblName); sqlite3DbFree(db, zName); diff --git a/src/parse.y b/src/parse.y index d707ee0a82..6ac2c3d440 100644 --- a/src/parse.y +++ b/src/parse.y @@ -300,7 +300,8 @@ ccons ::= NULL onconf. ccons ::= NOT NULL onconf(R). {sqlite3AddNotNull(pParse, R);} ccons ::= PRIMARY KEY sortorder(Z) onconf(R) autoinc(I). {sqlite3AddPrimaryKey(pParse,0,R,I,Z);} -ccons ::= UNIQUE onconf(R). {sqlite3CreateIndex(pParse,0,0,0,0,R,0,0,0,0);} +ccons ::= UNIQUE onconf(R). {sqlite3CreateIndex(pParse,0,0,0,0,R,0, + 0,0,0,0);} ccons ::= CHECK LP expr(X) RP. {sqlite3AddCheckConstraint(pParse,X.pExpr);} ccons ::= REFERENCES nm(T) idxlist_opt(TA) refargs(R). {sqlite3CreateForeignKey(pParse,0,&T,TA,R);} @@ -349,7 +350,7 @@ tcons ::= CONSTRAINT nm(X). {pParse->constraintName = X;} tcons ::= PRIMARY KEY LP idxlist(X) autoinc(I) RP onconf(R). {sqlite3AddPrimaryKey(pParse,X,R,I,0);} tcons ::= UNIQUE LP idxlist(X) RP onconf(R). - {sqlite3CreateIndex(pParse,0,0,0,X,R,0,0,0,0);} + {sqlite3CreateIndex(pParse,0,0,0,X,R,0,0,0,0,0);} tcons ::= CHECK LP expr(E) RP onconf. {sqlite3AddCheckConstraint(pParse,E.pExpr);} tcons ::= FOREIGN KEY LP idxlist(FA) RP @@ -1125,10 +1126,10 @@ nexprlist(A) ::= expr(Y). ///////////////////////////// The CREATE INDEX command /////////////////////// // cmd ::= createkw(S) uniqueflag(U) INDEX ifnotexists(NE) nm(X) dbnm(D) - ON nm(Y) LP idxlist(Z) RP(E). { + ON nm(Y) LP idxlist(Z) RP(E) where_opt(W). { sqlite3CreateIndex(pParse, &X, &D, sqlite3SrcListAppend(pParse->db,0,&Y,0), Z, U, - &S, &E, SQLITE_SO_ASC, NE); + &S, &E, W, SQLITE_SO_ASC, NE); } %type uniqueflag {int} diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 795740978f..dba1e55b83 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1538,6 +1538,7 @@ struct Index { Schema *pSchema; /* Schema containing this index */ u8 *aSortOrder; /* for each column: True==DESC, False==ASC */ char **azColl; /* Array of collation sequence names for index */ + Expr *pPartIdxWhere; /* WHERE clause for partial indices */ int tnum; /* DB Page containing root of this index */ u16 nColumn; /* Number of columns in table used by this index */ u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ @@ -2783,7 +2784,7 @@ void sqlite3SrcListAssignCursors(Parse*, SrcList*); void sqlite3IdListDelete(sqlite3*, IdList*); void sqlite3SrcListDelete(sqlite3*, SrcList*); Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*, - Token*, int, int); + Token*, Expr*, int, int); void sqlite3DropIndex(Parse*, SrcList*, int); int sqlite3Select(Parse*, Select*, SelectDest*); Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*, diff --git a/test/index6.test b/test/index6.test new file mode 100644 index 0000000000..7bd83769f3 --- /dev/null +++ b/test/index6.test @@ -0,0 +1,33 @@ +# 2013-07-31 +# +# 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. +# +#*********************************************************************** +# +# Test cases for partial indices +# + + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +load_static_extension db wholenumber; +do_test index6-1.1 { + execsql { + CREATE TABLE t1(a,b); + CREATE INDEX t1a ON t1(a) WHERE a IS NOT NULL; + CREATE INDEX t1b ON t1(b) WHERE b>10; + CREATE VIRTUAL TABLE nums USING wholenumber; + INSERT INTO t1(a,b) + SELECT CASE WHEN value%3!=0 THEN value END, value + FROM nums WHERE value<=20; + SELECT count(a), count(b) FROM t1; + } +} {14 20} + +finish_test From 3780be115a461f5da136079e5b9002dc70cbf25e Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 31 Jul 2013 19:05:22 +0000 Subject: [PATCH 25/47] Resolve names in CREATE INDEX WHERE clauses and detect errors. Disallow expressions that contain variables, subqueries, or functions. The expression is still not used for anything, however. still unused. FossilOrigin-Name: f2aa7842c8b9df24294f09e2bde27b3f08c455c7 --- manifest | 21 +++++------ manifest.uuid | 2 +- src/build.c | 28 ++++----------- src/resolve.c | 90 ++++++++++++++++++++++++++++++++++++++++++------ src/sqliteInt.h | 2 ++ test/index6.test | 27 +++++++++++++++ 6 files changed, 125 insertions(+), 45 deletions(-) diff --git a/manifest b/manifest index 0a7fe0faee..ac70fd7d00 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Here\sbegins\san\sexperimental\sbranch\sfor\sexploring\sthe\sidea\sof\sa\spartial\sindex.\nThis\scheck-in\sis\sable\sto\sparse\sa\sWHERE\sclause\son\sa\sCREATE\sINDEX\sstatement,\sbut\ndoes\snot\sactually\sdo\sanythingn\swith\sthat\sWHERE\sclause\syet. -D 2013-07-31T18:12:26.006 +C Resolve\snames\sin\sCREATE\sINDEX\sWHERE\sclauses\sand\sdetect\serrors.\s\sDisallow\nexpressions\sthat\scontain\svariables,\ssubqueries,\sor\sfunctions.\nThe\sexpression\sis\sstill\snot\sused\sfor\sanything,\showever.\nstill\sunused. +D 2013-07-31T19:05:22.844 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 3f7bbfd72efb1cbf6a49515c376a031767ec930a F src/btree.h 6fa8a3ff2483d0bb64a9f0105a8cedeac9e00cca F src/btreeInt.h eecc84f02375b2bb7a44abbcbbe3747dde73edb2 -F src/build.c c2903be4a825d6be0a518f87b60e0dcf878782d3 +F src/build.c f1ef982f38df47b11e10edaf03fbcc77b80e4d35 F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 4262c227bc91cecc61ae37ed3a40f08069cfa267 @@ -214,14 +214,14 @@ F src/pragma.c 2790c5175bc3f95d2a0cf39283d144b9b012fec7 F src/prepare.c fa6988589f39af8504a61731614cd4f6ae71554f F src/printf.c 41c49dac366a3a411190001a8ab495fa8887974e F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 -F src/resolve.c 89f9003e8316ee3a172795459efc2a0274e1d5a8 +F src/resolve.c ada80e8df5d4ab0a21cf65ec5be8ba3b826e2b6f F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 91b62654caf8dfe292fb8882715e575d34ad3874 F src/shell.c 52f975eae87c8338c4dfbf4c2842d2a0971f01fd F src/sqlite.h.in d6a7523d6795317aac574fccc67d9df25253771c F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h c99f22c5bda01f07e2f9a9a8cb2c0b9adeea696c +F src/sqliteInt.h ffe632c1de338b459af86e6df712f4583c05b8af F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -589,7 +589,7 @@ F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6 F test/index3.test 423a25c789fc8cc51aaf2a4370bbdde2d9e9eed7 F test/index4.test 2983216eb8c86ee62d9ed7cb206b5cc3331c0026 F test/index5.test fc07c14193c0430814e7a08b5da46888ee795c33 -F test/index6.test cbd74aa8604e29982438a7defae9fadaf9605336 +F test/index6.test 11171203a09b543d6181af59c298d2429ba762e2 F test/indexedby.test 0e959308707c808515c3a51363f7a9835027108c F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 @@ -1104,10 +1104,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P eb6d4278b8516e0571269049d1eaa55066f51b1a -R d0aa2f7065f4153ebb66a1af4210e515 -T *branch * partial-indices -T *sym-partial-indices * -T -sym-trunk * +P 6794b2dcb48b3507caccfc7867fc185818cf8291 +R 1d2a041bdd5863b9d0e35692b3da5ea5 U drh -Z cfed8379e8335c37848dda6e7de0acdf +Z 96979d6477d3e0c5f80978a86c33129b diff --git a/manifest.uuid b/manifest.uuid index 4d7035783c..9efb9eb1f1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6794b2dcb48b3507caccfc7867fc185818cf8291 \ No newline at end of file +f2aa7842c8b9df24294f09e2bde27b3f08c455c7 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 7ca2ef00cc..61a1ae9e3c 100644 --- a/src/build.c +++ b/src/build.c @@ -1522,26 +1522,7 @@ void sqlite3EndTable( /* Resolve names in all CHECK constraint expressions. */ if( p->pCheck ){ - SrcList sSrc; /* Fake SrcList for pParse->pNewTable */ - NameContext sNC; /* Name context for pParse->pNewTable */ - ExprList *pList; /* List of all CHECK constraints */ - int i; /* Loop counter */ - - memset(&sNC, 0, sizeof(sNC)); - memset(&sSrc, 0, sizeof(sSrc)); - sSrc.nSrc = 1; - sSrc.a[0].zName = p->zName; - sSrc.a[0].pTab = p; - sSrc.a[0].iCursor = -1; - sNC.pParse = pParse; - sNC.pSrcList = &sSrc; - sNC.ncFlags = NC_IsCheck; - pList = p->pCheck; - for(i=0; inExpr; i++){ - if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){ - return; - } - } + sqlite3ResolveSelfReference(pParse, p, NC_IsCheck, 0, p->pCheck); } #endif /* !defined(SQLITE_OMIT_CHECK) */ @@ -2702,8 +2683,11 @@ Index *sqlite3CreateIndex( pIndex->uniqNotNull = onError==OE_Abort; pIndex->autoIndex = (u8)(pName==0); pIndex->pSchema = db->aDb[iDb].pSchema; - pIndex->pPartIdxWhere = pPIWhere; - pPIWhere = 0; + if( pPIWhere ){ + sqlite3ResolveSelfReference(pParse, pTab, NC_PartIdx, pPIWhere, 0); + pIndex->pPartIdxWhere = pPIWhere; + pPIWhere = 0; + } assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); /* Check to see if we should honor DESC requests on index columns diff --git a/src/resolve.c b/src/resolve.c index 91efcaa1a1..239e0eb2a0 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -522,6 +522,39 @@ Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){ return p; } +/* +** Report an error that an expression is not valid for a partial index WHERE +** clause. +*/ +static void notValidPartIdxWhere( + Parse *pParse, /* Leave error message here */ + NameContext *pNC, /* The name context */ + const char *zMsg /* Type of error */ +){ + if( (pNC->ncFlags & NC_PartIdx)!=0 ){ + sqlite3ErrorMsg(pParse, "%s prohibited in partial index WHERE clauses", + zMsg); + } +} + +#ifndef SQLITE_OMIT_CHECK +/* +** Report an error that an expression is not valid for a CHECK constraint. +*/ +static void notValidCheckConstraint( + Parse *pParse, /* Leave error message here */ + NameContext *pNC, /* The name context */ + const char *zMsg /* Type of error */ +){ + if( (pNC->ncFlags & NC_IsCheck)!=0 ){ + sqlite3ErrorMsg(pParse,"%s prohibited in CHECK constraints", zMsg); + } +} +#else +# define notValidCheckConstraint(P,N,M) +#endif + + /* ** This routine is callback for sqlite3WalkExpr(). ** @@ -621,6 +654,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ testcase( pExpr->op==TK_CONST_FUNC ); assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); + notValidPartIdxWhere(pParse, pNC, "functions"); zId = pExpr->u.zToken; nId = sqlite3Strlen30(zId); pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0); @@ -686,11 +720,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ testcase( pExpr->op==TK_IN ); if( ExprHasProperty(pExpr, EP_xIsSelect) ){ int nRef = pNC->nRef; -#ifndef SQLITE_OMIT_CHECK - if( (pNC->ncFlags & NC_IsCheck)!=0 ){ - sqlite3ErrorMsg(pParse,"subqueries prohibited in CHECK constraints"); - } -#endif + notValidCheckConstraint(pParse, pNC, "subqueries"); + notValidPartIdxWhere(pParse, pNC, "subqueries"); sqlite3WalkSelect(pWalker, pExpr->x.pSelect); assert( pNC->nRef>=nRef ); if( nRef!=pNC->nRef ){ @@ -699,14 +730,11 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ } break; } -#ifndef SQLITE_OMIT_CHECK case TK_VARIABLE: { - if( (pNC->ncFlags & NC_IsCheck)!=0 ){ - sqlite3ErrorMsg(pParse,"parameters prohibited in CHECK constraints"); - } + notValidCheckConstraint(pParse, pNC, "parameters"); + notValidPartIdxWhere(pParse, pNC, "parameters"); break; } -#endif } return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue; } @@ -1331,3 +1359,45 @@ void sqlite3ResolveSelectNames( w.u.pNC = pOuterNC; sqlite3WalkSelect(&w, p); } + +/* +** Resolve names in expressions that can only reference a single table: +** +** * CHECK constraints +** * WHERE clauses on partial indices +** +** The Expr.iTable value for Expr.op==TK_COLUMN nodes of the expression +** is set to -1 and the Expr.iColumn value is set to the column number. +** +** Any errors cause an error message to be set in pParse. +*/ +void sqlite3ResolveSelfReference( + Parse *pParse, /* Parsing context */ + Table *pTab, /* The table being referenced */ + int type, /* NC_IsCheck or NC_PartIdx */ + Expr *pExpr, /* Expression to resolve. May be NULL. */ + ExprList *pList /* Expression list to resolve. May be NUL. */ +){ + SrcList sSrc; /* Fake SrcList for pParse->pNewTable */ + NameContext sNC; /* Name context for pParse->pNewTable */ + int i; /* Loop counter */ + + assert( type==NC_IsCheck || type==NC_PartIdx ); + memset(&sNC, 0, sizeof(sNC)); + memset(&sSrc, 0, sizeof(sSrc)); + sSrc.nSrc = 1; + sSrc.a[0].zName = pTab->zName; + sSrc.a[0].pTab = pTab; + sSrc.a[0].iCursor = -1; + sNC.pParse = pParse; + sNC.pSrcList = &sSrc; + sNC.ncFlags = type; + if( sqlite3ResolveExprNames(&sNC, pExpr) ) return; + if( pList ){ + for(i=0; inExpr; i++){ + if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){ + return; + } + } + } +} diff --git a/src/sqliteInt.h b/src/sqliteInt.h index dba1e55b83..3d4a57f3a4 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2019,6 +2019,7 @@ struct NameContext { #define NC_InAggFunc 0x08 /* True if analyzing arguments to an agg func */ #define NC_AsMaybe 0x10 /* Resolve to AS terms of the result set only ** if no other resolution is available */ +#define NC_PartIdx 0x20 /* True if resolving a partial index WHERE */ /* ** An instance of the following structure contains all information @@ -3063,6 +3064,7 @@ void sqlite3SelectPrep(Parse*, Select*, NameContext*); int sqlite3MatchSpanName(const char*, const char*, const char*, const char*); int sqlite3ResolveExprNames(NameContext*, Expr*); void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*); +void sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*); int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*); void sqlite3ColumnDefault(Vdbe *, Table *, int, int); void sqlite3AlterFinishAddColumn(Parse *, Token *); diff --git a/test/index6.test b/test/index6.test index 7bd83769f3..89b9c48761 100644 --- a/test/index6.test +++ b/test/index6.test @@ -30,4 +30,31 @@ do_test index6-1.1 { } } {14 20} +do_test index6-1.2 { + catchsql { + CREATE INDEX bad1 ON t1(a,b) WHERE c IS NOT NULL; + } +} {1 {no such column: c}} +do_test index6-1.3 { + catchsql { + CREATE INDEX bad1 ON t1(a,b) WHERE EXISTS(SELECT * FROM t1); + } +} {1 {subqueries prohibited in partial index WHERE clauses}} +do_test index6-1.4 { + catchsql { + CREATE INDEX bad1 ON t1(a,b) WHERE a!=?1; + } +} {1 {parameters prohibited in partial index WHERE clauses}} +do_test index6-1.5 { + catchsql { + CREATE INDEX bad1 ON t1(a,b) WHERE a!=random(); + } +} {1 {functions prohibited in partial index WHERE clauses}} +do_test index6-1.6 { + catchsql { + CREATE INDEX bad1 ON t1(a,b) WHERE a NOT LIKE 'abc%'; + } +} {1 {functions prohibited in partial index WHERE clauses}} + + finish_test From 68f7a9e942132d72d87650449b32d7ec179affda Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 31 Jul 2013 19:55:25 +0000 Subject: [PATCH 26/47] The MAX_PATH constant in windows is measured in characters, so multiple by 3 to get the number of bytes assuming worst-case UTF8 pathnames. FossilOrigin-Name: bb06e1579022c24546ac5117a99846b3c37ef59b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_win.c | 41 ++++++++++++++++++++++++++--------------- 3 files changed, 33 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 327c096cff..af4b04bd88 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reduce\sthe\ssize\sof\sthe\sstack\srequired\sby\sthe\scodeOneLoopStart()\sfunction\sin\nwhere.c. -D 2013-07-30T15:10:32.747 +C The\sMAX_PATH\sconstant\sin\swindows\sis\smeasured\sin\scharacters,\sso\smultiple\sby\s3\nto\sget\sthe\snumber\sof\sbytes\sassuming\sworst-case\sUTF8\spathnames. +D 2013-07-31T19:55:25.865 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -203,7 +203,7 @@ F src/os.c b4ad71336fd96f97776f75587cd9e8218288f5be F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c 9eafa5458cf2ff684ddccff82c9bb113c7cad847 -F src/os_win.c 074cb2b9bca6a1c2bd72acf04666cdc554bfaa9b +F src/os_win.c d0e9774f6dd3975cda31594049ab8216c2d6978b F src/pager.c 5d2f7475260a8588f9c441bb309d2b7eaa7ded3b F src/pager.h 5cb78b8e1adfd5451e600be7719f5a99d87ac3b1 F src/parse.y 9acfcc83ddbf0cf82f0ed9582ccf0ad6c366ff37 @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 9e819f0f12b6f2a8e0e7a90251b3115ff1595f25 -R 8a77f3488eeca7f033bc07ab4b9db562 +P eb6d4278b8516e0571269049d1eaa55066f51b1a +R d0484fd8b656e8cf7cd4ab3eed43ed22 U drh -Z 51b3ad13ced3eb326ea64314852a899d +Z 0de91cecc0135d1602cf04652b34abe4 diff --git a/manifest.uuid b/manifest.uuid index 116c2adffe..ade4fc3681 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eb6d4278b8516e0571269049d1eaa55066f51b1a \ No newline at end of file +bb06e1579022c24546ac5117a99846b3c37ef59b \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index bdf025aa4c..b8136f0e9c 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -230,6 +230,7 @@ struct winFile { # define SQLITE_WIN32_HEAP_FLAGS (0) #endif + /* ** The winMemData structure stores information required by the Win32-specific ** sqlite3_mem_methods implementation. @@ -3866,6 +3867,15 @@ static void *convertUtf8Filename(const char *zFilename){ return zConverted; } +/* +** Maximum pathname length (in bytes) for windows. The MAX_PATH macro is +** in characters, so we allocate 3 bytes per character assuming worst-case +** 3-bytes-per-character UTF8. +*/ +#ifndef SQLITE_WIN32_MAX_PATH +# define SQLITE_WIN32_MAX_PATH (MAX_PATH*3) +#endif + /* ** Create a temporary file name in zBuf. zBuf must be big enough to ** hold at pVfs->mxPathname characters. @@ -3877,7 +3887,7 @@ static int getTempname(int nBuf, char *zBuf){ "0123456789"; size_t i, j; int nTempPath; - char zTempPath[MAX_PATH+2]; + char zTempPath[SQLITE_WIN32_MAX_PATH+2]; /* It's odd to simulate an io-error here, but really this is just ** using the io-error infrastructure to test that SQLite handles this @@ -3885,10 +3895,11 @@ static int getTempname(int nBuf, char *zBuf){ */ SimulateIOError( return SQLITE_IOERR ); - memset(zTempPath, 0, MAX_PATH+2); + memset(zTempPath, 0, SQLITE_WIN32_MAX_PATH+2); if( sqlite3_temp_directory ){ - sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory); + sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s", + sqlite3_temp_directory); } #if !SQLITE_OS_WINRT else if( isNT() ){ @@ -3897,7 +3908,7 @@ static int getTempname(int nBuf, char *zBuf){ osGetTempPathW(MAX_PATH-30, zWidePath); zMulti = unicodeToUtf8(zWidePath); if( zMulti ){ - sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti); + sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s", zMulti); sqlite3_free(zMulti); }else{ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); @@ -3907,11 +3918,11 @@ static int getTempname(int nBuf, char *zBuf){ #ifdef SQLITE_WIN32_HAS_ANSI else{ char *zUtf8; - char zMbcsPath[MAX_PATH]; - osGetTempPathA(MAX_PATH-30, zMbcsPath); + char zMbcsPath[SQLITE_WIN32_MAX_PATH]; + osGetTempPathA(SQLITE_WIN32_MAX_PATH-30, zMbcsPath); zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath); if( zUtf8 ){ - sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8); + sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s", zUtf8); sqlite3_free(zUtf8); }else{ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); @@ -4005,7 +4016,7 @@ static int winOpen( /* If argument zPath is a NULL pointer, this function is required to open ** a temporary file. Use this buffer to store the file name in. */ - char zTmpname[MAX_PATH+2]; /* Buffer used to create temp filename */ + char zTmpname[SQLITE_WIN32_MAX_PATH+2]; /* Buffer used to create temp filename */ int rc = SQLITE_OK; /* Function Return Code */ #if !defined(NDEBUG) || SQLITE_OS_WINCE @@ -4071,8 +4082,8 @@ static int winOpen( */ if( !zUtf8Name ){ assert(isDelete && !isOpenJournal); - memset(zTmpname, 0, MAX_PATH+2); - rc = getTempname(MAX_PATH+2, zTmpname); + memset(zTmpname, 0, SQLITE_WIN32_MAX_PATH+2); + rc = getTempname(SQLITE_WIN32_MAX_PATH+2, zTmpname); if( rc!=SQLITE_OK ){ OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc))); return rc; @@ -4503,7 +4514,7 @@ static int winFullPathname( #if defined(__CYGWIN__) SimulateIOError( return SQLITE_ERROR ); UNUSED_PARAMETER(nFull); - assert( pVfs->mxPathname>=MAX_PATH ); + assert( pVfs->mxPathname>=SQLITE_WIN32_MAX_PATH ); assert( nFull>=pVfs->mxPathname ); if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ /* @@ -4512,10 +4523,10 @@ static int winFullPathname( ** for converting the relative path name to an absolute ** one by prepending the data directory and a slash. */ - char zOut[MAX_PATH+1]; - memset(zOut, 0, MAX_PATH+1); + char zOut[SQLITE_WIN32_MAX_PATH+1]; + memset(zOut, 0, SQLITE_WIN32_MAX_PATH+1); cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut, - MAX_PATH+1); + SQLITE_WIN32_MAX_PATH+1); sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s", sqlite3_data_directory, zOut); }else{ @@ -4861,7 +4872,7 @@ int sqlite3_os_init(void){ static sqlite3_vfs winVfs = { 3, /* iVersion */ sizeof(winFile), /* szOsFile */ - MAX_PATH, /* mxPathname */ + SQLITE_WIN32_MAX_PATH, /* mxPathname */ 0, /* pNext */ "win32", /* zName */ 0, /* pAppData */ From 16a2e7a0536b9a6535ad732ab5a089cdef30087b Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 31 Jul 2013 22:27:16 +0000 Subject: [PATCH 27/47] Use a new error code to represent a failure to get the configured temporary directory on Windows. FossilOrigin-Name: c93d891b03c626b9ed01ed5ef2f246b2d4a40a64 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/main.c | 1 + src/os_win.c | 10 ++++++++-- src/sqlite.h.in | 1 + 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index af4b04bd88..4984c33df6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sMAX_PATH\sconstant\sin\swindows\sis\smeasured\sin\scharacters,\sso\smultiple\sby\s3\nto\sget\sthe\snumber\sof\sbytes\sassuming\sworst-case\sUTF8\spathnames. -D 2013-07-31T19:55:25.865 +C Use\sa\snew\serror\scode\sto\srepresent\sa\sfailure\sto\sget\sthe\sconfigured\stemporary\sdirectory\son\sWindows. +D 2013-07-31T22:27:16.062 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -185,7 +185,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303 -F src/main.c 9286e1f5660ff32bd53a9a64ab09ed9af2542b5d +F src/main.c b2592b4119f9b34d20861d1a73a44f07d061508c F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa @@ -203,7 +203,7 @@ F src/os.c b4ad71336fd96f97776f75587cd9e8218288f5be F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c 9eafa5458cf2ff684ddccff82c9bb113c7cad847 -F src/os_win.c d0e9774f6dd3975cda31594049ab8216c2d6978b +F src/os_win.c aead0182637b77f6b86e2326ee6bce9b1add0637 F src/pager.c 5d2f7475260a8588f9c441bb309d2b7eaa7ded3b F src/pager.h 5cb78b8e1adfd5451e600be7719f5a99d87ac3b1 F src/parse.y 9acfcc83ddbf0cf82f0ed9582ccf0ad6c366ff37 @@ -218,7 +218,7 @@ F src/resolve.c 89f9003e8316ee3a172795459efc2a0274e1d5a8 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 91b62654caf8dfe292fb8882715e575d34ad3874 F src/shell.c 52f975eae87c8338c4dfbf4c2842d2a0971f01fd -F src/sqlite.h.in d6a7523d6795317aac574fccc67d9df25253771c +F src/sqlite.h.in bf3ee0bd13583cc6d09f9649bf26a183b0cc10a6 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqliteInt.h 89b52c053ebafa76f03bab4f0c8ee1e390eb7489 @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P eb6d4278b8516e0571269049d1eaa55066f51b1a -R d0484fd8b656e8cf7cd4ab3eed43ed22 -U drh -Z 0de91cecc0135d1602cf04652b34abe4 +P bb06e1579022c24546ac5117a99846b3c37ef59b +R cd86f9af8b68f6621597cefa17e93ed5 +U mistachkin +Z c86d88dac629a8d9fc1cbd59a4805ab2 diff --git a/manifest.uuid b/manifest.uuid index ade4fc3681..479a98144f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bb06e1579022c24546ac5117a99846b3c37ef59b \ No newline at end of file +c93d891b03c626b9ed01ed5ef2f246b2d4a40a64 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 9b25ae26b9..d848dc7f59 100644 --- a/src/main.c +++ b/src/main.c @@ -1100,6 +1100,7 @@ const char *sqlite3ErrName(int rc){ case SQLITE_IOERR_SEEK: zName = "SQLITE_IOERR_SEEK"; break; case SQLITE_IOERR_DELETE_NOENT: zName = "SQLITE_IOERR_DELETE_NOENT";break; case SQLITE_IOERR_MMAP: zName = "SQLITE_IOERR_MMAP"; break; + case SQLITE_IOERR_GETTEMPPATH: zName = "SQLITE_IOERR_GETTEMPPATH"; break; case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break; case SQLITE_CORRUPT_VTAB: zName = "SQLITE_CORRUPT_VTAB"; break; case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break; diff --git a/src/os_win.c b/src/os_win.c index b8136f0e9c..1f178e1ff3 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -3905,7 +3905,10 @@ static int getTempname(int nBuf, char *zBuf){ else if( isNT() ){ char *zMulti; WCHAR zWidePath[MAX_PATH]; - osGetTempPathW(MAX_PATH-30, zWidePath); + if( osGetTempPathW(MAX_PATH-30, zWidePath)==0 ){ + OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n")); + return SQLITE_IOERR_GETTEMPPATH; + } zMulti = unicodeToUtf8(zWidePath); if( zMulti ){ sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s", zMulti); @@ -3919,7 +3922,10 @@ static int getTempname(int nBuf, char *zBuf){ else{ char *zUtf8; char zMbcsPath[SQLITE_WIN32_MAX_PATH]; - osGetTempPathA(SQLITE_WIN32_MAX_PATH-30, zMbcsPath); + if( osGetTempPathA(SQLITE_WIN32_MAX_PATH-30, zMbcsPath)==0 ){ + OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n")); + return SQLITE_IOERR_GETTEMPPATH; + } zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath); if( zUtf8 ){ sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s", zUtf8); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 2fc3e80a4a..fa33a0a40c 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -473,6 +473,7 @@ int sqlite3_exec( #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) #define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8)) #define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8)) +#define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) From aa82eba40d90cc43bf5c2cc4f0c837c9b03b277b Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 31 Jul 2013 22:39:26 +0000 Subject: [PATCH 28/47] Slight modifications to path name translation handling for Cygwin. FossilOrigin-Name: 33ba1f4c5dc2ef8292adf17a32ade0cde0887d88 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_win.c | 16 ++++++++++++---- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 4984c33df6..3723096546 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\sa\snew\serror\scode\sto\srepresent\sa\sfailure\sto\sget\sthe\sconfigured\stemporary\sdirectory\son\sWindows. -D 2013-07-31T22:27:16.062 +C Slight\smodifications\sto\spath\sname\stranslation\shandling\sfor\sCygwin. +D 2013-07-31T22:39:26.505 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -203,7 +203,7 @@ F src/os.c b4ad71336fd96f97776f75587cd9e8218288f5be F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c 9eafa5458cf2ff684ddccff82c9bb113c7cad847 -F src/os_win.c aead0182637b77f6b86e2326ee6bce9b1add0637 +F src/os_win.c 3a74943b286746533963579337b1de4383cf963b F src/pager.c 5d2f7475260a8588f9c441bb309d2b7eaa7ded3b F src/pager.h 5cb78b8e1adfd5451e600be7719f5a99d87ac3b1 F src/parse.y 9acfcc83ddbf0cf82f0ed9582ccf0ad6c366ff37 @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P bb06e1579022c24546ac5117a99846b3c37ef59b -R cd86f9af8b68f6621597cefa17e93ed5 +P c93d891b03c626b9ed01ed5ef2f246b2d4a40a64 +R 1da5a28da1b68405b6ad12dd77b7c1d9 U mistachkin -Z c86d88dac629a8d9fc1cbd59a4805ab2 +Z 86b10e2366b2108534452cce8a04325b diff --git a/manifest.uuid b/manifest.uuid index 479a98144f..56f062680e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c93d891b03c626b9ed01ed5ef2f246b2d4a40a64 \ No newline at end of file +33ba1f4c5dc2ef8292adf17a32ade0cde0887d88 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 1f178e1ff3..3647b0e474 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -17,6 +17,7 @@ #ifdef __CYGWIN__ # include +# include #endif /* @@ -4530,13 +4531,20 @@ static int winFullPathname( ** one by prepending the data directory and a slash. */ char zOut[SQLITE_WIN32_MAX_PATH+1]; - memset(zOut, 0, SQLITE_WIN32_MAX_PATH+1); - cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut, - SQLITE_WIN32_MAX_PATH+1); + if( cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut, + SQLITE_WIN32_MAX_PATH+1)<0 ){ + winLogError(SQLITE_CANTOPEN_FULLPATH, (DWORD)errno, "cygwin_conv_path", + zRelative); + return SQLITE_CANTOPEN_FULLPATH; + } sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s", sqlite3_data_directory, zOut); }else{ - cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull); + if( cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull)<0 ){ + winLogError(SQLITE_CANTOPEN_FULLPATH, (DWORD)errno, "cygwin_conv_path", + zRelative); + return SQLITE_CANTOPEN_FULLPATH; + } } return SQLITE_OK; #endif From 4bd5f73fa09a7b5c8f1fe1dd39900811d15d1dab Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 31 Jul 2013 23:22:39 +0000 Subject: [PATCH 29/47] Add logic to the query planner to only use partial indices if the WHERE clause constrains the search to rows covered by the partial index. This is just infrastructure. The key routine, sqlite3ExprImpliesExpr(), is currently a no-op so that partial indices will never be used. FossilOrigin-Name: 8ca3eac111e06a1854f878a74bffe8f20eb47f1b --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 20 ++++++++++++++++++++ src/sqliteInt.h | 1 + src/where.c | 18 +++++++++++++++++- 5 files changed, 47 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index ac70fd7d00..71bc8d11ba 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Resolve\snames\sin\sCREATE\sINDEX\sWHERE\sclauses\sand\sdetect\serrors.\s\sDisallow\nexpressions\sthat\scontain\svariables,\ssubqueries,\sor\sfunctions.\nThe\sexpression\sis\sstill\snot\sused\sfor\sanything,\showever.\nstill\sunused. -D 2013-07-31T19:05:22.844 +C Add\slogic\sto\sthe\squery\splanner\sto\sonly\suse\spartial\sindices\sif\sthe\sWHERE\sclause\nconstrains\sthe\ssearch\sto\srows\scovered\sby\sthe\spartial\sindex.\s\sThis\sis\sjust\ninfrastructure.\s\sThe\skey\sroutine,\ssqlite3ExprImpliesExpr(),\sis\scurrently\sa\nno-op\sso\sthat\spartial\sindices\swill\snever\sbe\sused. +D 2013-07-31T23:22:39.876 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -172,7 +172,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 4262c227bc91cecc61ae37ed3a40f08069cfa267 F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/delete.c aeabdabeeeaa0584127f291baa9617153d334778 -F src/expr.c 2b47ae9da6c9f34eff6736962ea2e102c6c4a755 +F src/expr.c 8a5e78f47c4919bd53c2ef3c652088d71d5c4d79 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 914a6bbd987d857c41ac9d244efa6641f36faadb F src/func.c 5c50c1ea31fd864b0fe921fe1a8d4c55acd609ef @@ -221,7 +221,7 @@ F src/shell.c 52f975eae87c8338c4dfbf4c2842d2a0971f01fd F src/sqlite.h.in d6a7523d6795317aac574fccc67d9df25253771c F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h ffe632c1de338b459af86e6df712f4583c05b8af +F src/sqliteInt.h 911e2fe9bbd45c394e6396a1c00a8539285f82e6 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -290,7 +290,7 @@ F src/vtab.c 2e8b489db47e20ae36cd247932dc671c9ded0624 F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73 -F src/where.c a55e27475c3d4c72c8bf1aaf9ece70e47e8731cf +F src/where.c afa338426730378f3d0aa9b24218462b6cca31f3 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 @@ -1104,7 +1104,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 6794b2dcb48b3507caccfc7867fc185818cf8291 -R 1d2a041bdd5863b9d0e35692b3da5ea5 +P f2aa7842c8b9df24294f09e2bde27b3f08c455c7 +R 7502b7f00f8eb060c8cfe6d979c2a415 U drh -Z 96979d6477d3e0c5f80978a86c33129b +Z 8c5239fd3bb5391973b43192e175e4ae diff --git a/manifest.uuid b/manifest.uuid index 9efb9eb1f1..d8663d4175 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f2aa7842c8b9df24294f09e2bde27b3f08c455c7 \ No newline at end of file +8ca3eac111e06a1854f878a74bffe8f20eb47f1b \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 2c0419aa2e..03258c32c9 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3865,6 +3865,26 @@ int sqlite3ExprListCompare(ExprList *pA, ExprList *pB){ return 0; } +/* +** Return true if we can prove the pE2 will always be true if pE1 is +** true. Return false if we cannot complete the proof or if pE2 might +** be false. Examples: +** +** pE1: x==5 pE2: x>0 Result: true +** pE1: x>0 pE2: x==5 Result: false +** pE1: x!=123 pE2: x IS NOT NULL Result: true +** +** When comparing TK_COLUMN nodes between pE1 and pE2, if pE2 has +** Expr.iTable<0 then assume a table number given by iTab. +** +** When in doubt, return false. Returning true might give a performance +** improvement. Returning false might cause a performance reduction, but +** it will always give the correct answer and is hence always safe. +*/ +int sqlite3ExprImpliesExpr(Expr *pE1, Expr *pE2, int iTab){ + return 0; /* FIXME: this needs to be worked out */ +} + /* ** An instance of the following structure is used by the tree walker ** to count references to table columns in the arguments of an diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 3d4a57f3a4..9d5580f928 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2835,6 +2835,7 @@ int sqlite3RunVacuum(char**, sqlite3*); char *sqlite3NameFromToken(sqlite3*, Token*); int sqlite3ExprCompare(Expr*, Expr*); int sqlite3ExprListCompare(ExprList*, ExprList*); +int sqlite3ExprImpliesExpr(Expr*, Expr*, int); void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); int sqlite3FunctionUsesThisSrc(Expr*, SrcList*); diff --git a/src/where.c b/src/where.c index 9f65d551a3..315c4035cb 100644 --- a/src/where.c +++ b/src/where.c @@ -4503,6 +4503,17 @@ static Bitmask columnsInIndex(Index *pIdx){ return m; } +/* Check to see if a partial index with pPartIndexWhere can be used +** in the current query. Return true if it can be and false if not. +*/ +static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){ + int i; + WhereTerm *pTerm; + for(i=0, pTerm=pWC->a; inTerm; i++, pTerm++){ + if( sqlite3ExprImpliesExpr(pTerm->pExpr, pWhere, iTab) ) return 1; + } + return 0; +} /* ** Add all WhereLoop objects for a single table of the join where the table @@ -4526,11 +4537,13 @@ static int whereLoopAddBtree( int b; /* A boolean value */ WhereCost rSize; /* number of rows in the table */ WhereCost rLogSize; /* Logarithm of the number of rows in the table */ + WhereClause *pWC; /* The parsed WHERE clause */ pNew = pBuilder->pNew; pWInfo = pBuilder->pWInfo; pTabList = pWInfo->pTabList; pSrc = pTabList->a + pNew->iTab; + pWC = pBuilder->pWC; assert( !IsVirtual(pSrc->pTab) ); if( pSrc->pIndex ){ @@ -4570,7 +4583,6 @@ static int whereLoopAddBtree( && !pSrc->isCorrelated ){ /* Generate auto-index WhereLoops */ - WhereClause *pWC = pBuilder->pWC; WhereTerm *pTerm; WhereTerm *pWCEnd = pWC->a + pWC->nTerm; for(pTerm=pWC->a; rc==SQLITE_OK && pTermpNext, iSortIdx++){ + if( pProbe->pPartIdxWhere!=0 + && !whereUsablePartialIndex(pNew->iTab, pWC, pProbe->pPartIdxWhere) ){ + continue; /* Partial index inappropriate for this query */ + } pNew->u.btree.nEq = 0; pNew->nLTerm = 0; pNew->iSortIdx = 0; From c6fc65ce08b8f240d6476219aca855fa25aea09c Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 31 Jul 2013 23:28:36 +0000 Subject: [PATCH 30/47] Limit the number of memset() calls used when determining a temporary file name on Windows. Also, fix a harmless compiler warning. FossilOrigin-Name: 136fc2931b156f91cdd76a7a009298cdf09d826a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_win.c | 29 +++++++++++++++++++++-------- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 3723096546..a763743c17 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Slight\smodifications\sto\spath\sname\stranslation\shandling\sfor\sCygwin. -D 2013-07-31T22:39:26.505 +C Limit\sthe\snumber\sof\smemset()\scalls\sused\swhen\sdetermining\sa\stemporary\sfile\sname\son\sWindows.\s\sAlso,\sfix\sa\sharmless\scompiler\swarning. +D 2013-07-31T23:28:36.603 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -203,7 +203,7 @@ F src/os.c b4ad71336fd96f97776f75587cd9e8218288f5be F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c 9eafa5458cf2ff684ddccff82c9bb113c7cad847 -F src/os_win.c 3a74943b286746533963579337b1de4383cf963b +F src/os_win.c 1d84f2079d9b91f91a4b5dbfa5e08f1b1a0ed0ff F src/pager.c 5d2f7475260a8588f9c441bb309d2b7eaa7ded3b F src/pager.h 5cb78b8e1adfd5451e600be7719f5a99d87ac3b1 F src/parse.y 9acfcc83ddbf0cf82f0ed9582ccf0ad6c366ff37 @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P c93d891b03c626b9ed01ed5ef2f246b2d4a40a64 -R 1da5a28da1b68405b6ad12dd77b7c1d9 +P 33ba1f4c5dc2ef8292adf17a32ade0cde0887d88 +R 22ac6c086833ea6790806cfd601e6a5b U mistachkin -Z 86b10e2366b2108534452cce8a04325b +Z 4d19b2638b72ab835325f17f2f967fc6 diff --git a/manifest.uuid b/manifest.uuid index 56f062680e..491b5fb557 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -33ba1f4c5dc2ef8292adf17a32ade0cde0887d88 \ No newline at end of file +136fc2931b156f91cdd76a7a009298cdf09d826a \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 3647b0e474..10c4316448 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -3696,10 +3696,10 @@ static int winMapfile(winFile *pFd, sqlite3_int64 nByte){ return SQLITE_OK; } assert( (nMap % winSysInfo.dwPageSize)==0 ); -#if SQLITE_OS_WINRT - pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, nMap); -#else assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff ); +#if SQLITE_OS_WINRT + pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, (SIZE_T)nMap); +#else pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap); #endif if( pNew==NULL ){ @@ -3896,8 +3896,6 @@ static int getTempname(int nBuf, char *zBuf){ */ SimulateIOError( return SQLITE_IOERR ); - memset(zTempPath, 0, SQLITE_WIN32_MAX_PATH+2); - if( sqlite3_temp_directory ){ sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory); @@ -3936,8 +3934,24 @@ static int getTempname(int nBuf, char *zBuf){ return SQLITE_IOERR_NOMEM; } } -#endif -#endif +#else + else{ + /* + ** Compiled without ANSI support and the current operating system + ** is not Windows NT; therefore, just zero the temporary buffer. + */ + memset(zTempPath, 0, SQLITE_WIN32_MAX_PATH+2); + } +#endif /* SQLITE_WIN32_HAS_ANSI */ +#else + else{ + /* + ** Compiled for WinRT and the sqlite3_temp_directory is not set; + ** therefore, just zero the temporary buffer. + */ + memset(zTempPath, 0, SQLITE_WIN32_MAX_PATH+2); + } +#endif /* !SQLITE_OS_WINRT */ /* Check that the output buffer is large enough for the temporary file ** name. If it is not, return SQLITE_ERROR. @@ -4089,7 +4103,6 @@ static int winOpen( */ if( !zUtf8Name ){ assert(isDelete && !isOpenJournal); - memset(zTmpname, 0, SQLITE_WIN32_MAX_PATH+2); rc = getTempname(SQLITE_WIN32_MAX_PATH+2, zTmpname); if( rc!=SQLITE_OK ){ OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc))); From b2b9d3d7586e93a6e860a27e42094bd670171a6b Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 1 Aug 2013 01:14:43 +0000 Subject: [PATCH 31/47] Add the logic to keep partial indices up to date through DML statements and when new partial indices are created. This new logic is untested except to verify that it does not interfere with full indices. FossilOrigin-Name: fb9044d15ad4fd6ae4a38858c0c0e6fe9d4faa25 --- manifest | 28 ++++++++++++++-------------- manifest.uuid | 2 +- src/build.c | 6 ++++-- src/delete.c | 35 ++++++++++++++++++++++++++++------- src/expr.c | 21 +++++++++++++-------- src/insert.c | 22 +++++++++++++++++++--- src/pragma.c | 5 +++-- src/sqliteInt.h | 3 ++- src/update.c | 2 +- src/vdbeaux.c | 4 ++-- src/where.c | 2 +- 11 files changed, 88 insertions(+), 42 deletions(-) diff --git a/manifest b/manifest index 71bc8d11ba..1e76bc8d3c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\slogic\sto\sthe\squery\splanner\sto\sonly\suse\spartial\sindices\sif\sthe\sWHERE\sclause\nconstrains\sthe\ssearch\sto\srows\scovered\sby\sthe\spartial\sindex.\s\sThis\sis\sjust\ninfrastructure.\s\sThe\skey\sroutine,\ssqlite3ExprImpliesExpr(),\sis\scurrently\sa\nno-op\sso\sthat\spartial\sindices\swill\snever\sbe\sused. -D 2013-07-31T23:22:39.876 +C Add\sthe\slogic\sto\skeep\spartial\sindices\sup\sto\sdate\sthrough\sDML\sstatements\sand\nwhen\snew\spartial\sindices\sare\screated.\s\sThis\snew\slogic\sis\suntested\sexcept\sto\nverify\sthat\sit\sdoes\snot\sinterfere\swith\sfull\sindices. +D 2013-08-01T01:14:43.210 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,13 +166,13 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 3f7bbfd72efb1cbf6a49515c376a031767ec930a F src/btree.h 6fa8a3ff2483d0bb64a9f0105a8cedeac9e00cca F src/btreeInt.h eecc84f02375b2bb7a44abbcbbe3747dde73edb2 -F src/build.c f1ef982f38df47b11e10edaf03fbcc77b80e4d35 +F src/build.c 9422ab5fe5f3ea21575b50c182ebf2081253bed0 F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 4262c227bc91cecc61ae37ed3a40f08069cfa267 F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 -F src/delete.c aeabdabeeeaa0584127f291baa9617153d334778 -F src/expr.c 8a5e78f47c4919bd53c2ef3c652088d71d5c4d79 +F src/delete.c 2317c814866d9aa71fea16b3faf4fdd4d6a49b94 +F src/expr.c 299f1de324676599b818e587b77e683978514461 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 914a6bbd987d857c41ac9d244efa6641f36faadb F src/func.c 5c50c1ea31fd864b0fe921fe1a8d4c55acd609ef @@ -180,7 +180,7 @@ F src/global.c 5caf4deab621abb45b4c607aad1bd21c20aac759 F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4 F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c f7cb141e8ce257cb6b15c497f09e4e23d6055599 +F src/insert.c 1e2eb1d4150c57f41dda8719f1b5ccb28abdacc2 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b @@ -210,7 +210,7 @@ F src/parse.y a950b48d4363f44dd98fef8a89fbd48970ebd9ce F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c d23d07716de96c7c0c2503ec5051a4384c3fb938 -F src/pragma.c 2790c5175bc3f95d2a0cf39283d144b9b012fec7 +F src/pragma.c f8936b23ce3eeddff4ab868c726d1546a6674418 F src/prepare.c fa6988589f39af8504a61731614cd4f6ae71554f F src/printf.c 41c49dac366a3a411190001a8ab495fa8887974e F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 @@ -221,7 +221,7 @@ F src/shell.c 52f975eae87c8338c4dfbf4c2842d2a0971f01fd F src/sqlite.h.in d6a7523d6795317aac574fccc67d9df25253771c F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 911e2fe9bbd45c394e6396a1c00a8539285f82e6 +F src/sqliteInt.h b69d7bac8a7fea89f11558f0659324f0551b0868 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -273,7 +273,7 @@ F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c e0e8fd3cb90a88451f6b6425726c84747b6b20d7 F src/trigger.c 5c0ea9b8755e7c5e1a700f3e27ac4f8d92dd221e -F src/update.c 8e76c3d03e4b7b21cb250bd2df0c05e12993e577 +F src/update.c 7f3fe64d8f3b44c44a1eac293f0f85f87c355b7a F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f F src/util.c f566b5138099a2df8533b190d0dcc74b7dfbe0c9 F src/vacuum.c d9c5759f4c5a438bb43c2086f72c5d2edabc36c8 @@ -281,7 +281,7 @@ F src/vdbe.c d6048a720c197db2f0e7d618e918bd2e2eff0322 F src/vdbe.h f380af2a7fab32ba8a8b05bf042497636afec66d F src/vdbeInt.h e9b7c6b165a31a4715c5aa97223d20d265515231 F src/vdbeapi.c 4d13580bd058b39623e8fcfc233b7df4b8191e8b -F src/vdbeaux.c c01594ecf5a78ef41a721f3465152bb91883a942 +F src/vdbeaux.c 75206d58c2e1ea7ed2758106d591ff7a082ea909 F src/vdbeblob.c 5dc79627775bd9a9b494dd956e26297946417d69 F src/vdbemem.c 833005f1cbbf447289f1973dba2a0c2228c7b8ab F src/vdbesort.c 3937e06b2a0e354500e17dc206ef4c35770a5017 @@ -290,7 +290,7 @@ F src/vtab.c 2e8b489db47e20ae36cd247932dc671c9ded0624 F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73 -F src/where.c afa338426730378f3d0aa9b24218462b6cca31f3 +F src/where.c 14d48fe735a7d5f4d610d8b9396a9e7752539199 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 @@ -1104,7 +1104,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P f2aa7842c8b9df24294f09e2bde27b3f08c455c7 -R 7502b7f00f8eb060c8cfe6d979c2a415 +P 8ca3eac111e06a1854f878a74bffe8f20eb47f1b +R 9dc930e0b891070c4f237bde08c1f247 U drh -Z 8c5239fd3bb5391973b43192e175e4ae +Z dd655b435ca4957c549da40144eccbfa diff --git a/manifest.uuid b/manifest.uuid index d8663d4175..53ef0430bf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8ca3eac111e06a1854f878a74bffe8f20eb47f1b \ No newline at end of file +fb9044d15ad4fd6ae4a38858c0c0e6fe9d4faa25 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 61a1ae9e3c..941bcb269f 100644 --- a/src/build.c +++ b/src/build.c @@ -2374,6 +2374,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ int addr1; /* Address of top of loop */ int addr2; /* Address to jump to for next iteration */ int tnum; /* Root page of index */ + int iPartIdxLabel; /* Jump to this label to skip a row */ Vdbe *v; /* Generate code into this virtual machine */ KeyInfo *pKey; /* KeyInfo for index */ int regRecord; /* Register holding assemblied index record */ @@ -2413,8 +2414,9 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); regRecord = sqlite3GetTempReg(pParse); - sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1); + sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1, &iPartIdxLabel); sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord); + sqlite3VdbeResolveLabel(v, iPartIdxLabel); sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); sqlite3VdbeJumpHere(v, addr1); addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); @@ -2843,7 +2845,7 @@ Index *sqlite3CreateIndex( ** has just been created, it contains no data and the index initialization ** step can be skipped. */ - else{ /* if( db->init.busy==0 ) */ + else if( pParse->nErr==0 ){ Vdbe *v; char *zStmt; int iMem = ++pParse->nMem; diff --git a/src/delete.c b/src/delete.c index 634e115563..af64afc65c 100644 --- a/src/delete.c +++ b/src/delete.c @@ -591,11 +591,14 @@ void sqlite3GenerateRowIndexDelete( int i; Index *pIdx; int r1; + int iPartIdxLabel; + Vdbe *v = pParse->pVdbe; for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ if( aRegIdx!=0 && aRegIdx[i-1]==0 ) continue; - r1 = sqlite3GenerateIndexKey(pParse, pIdx, iCur, 0, 0); - sqlite3VdbeAddOp3(pParse->pVdbe, OP_IdxDelete, iCur+i, r1,pIdx->nColumn+1); + r1 = sqlite3GenerateIndexKey(pParse, pIdx, iCur, 0, 0, &iPartIdxLabel); + sqlite3VdbeAddOp3(v, OP_IdxDelete, iCur+i, r1, pIdx->nColumn+1); + sqlite3VdbeResolveLabel(v, iPartIdxLabel); } } @@ -609,13 +612,21 @@ void sqlite3GenerateRowIndexDelete( ** registers that holds the elements of the index key. The ** block of registers has already been deallocated by the time ** this routine returns. +** +** If *piPartIdxLabel is not NULL, fill it in with a label and jump +** to that label if pIdx is a partial index that should be skipped. +** A partial index should be skipped if its WHERE clause evaluates +** to false or null. If pIdx is not a partial index, *piPartIdxLabel +** will be set to zero which is an empty label that is ignored by +** sqlite3VdbeResolveLabel(). */ int sqlite3GenerateIndexKey( - Parse *pParse, /* Parsing context */ - Index *pIdx, /* The index for which to generate a key */ - int iCur, /* Cursor number for the pIdx->pTable table */ - int regOut, /* Write the new index key to this register */ - int doMakeRec /* Run the OP_MakeRecord instruction if true */ + Parse *pParse, /* Parsing context */ + Index *pIdx, /* The index for which to generate a key */ + int iCur, /* Cursor number for the pIdx->pTable table */ + int regOut, /* Write the new index key to this register */ + int doMakeRec, /* Run the OP_MakeRecord instruction if true */ + int *piPartIdxLabel /* OUT: Jump to this label to skip partial index */ ){ Vdbe *v = pParse->pVdbe; int j; @@ -623,6 +634,16 @@ int sqlite3GenerateIndexKey( int regBase; int nCol; + if( piPartIdxLabel ){ + if( pIdx->pPartIdxWhere ){ + *piPartIdxLabel = sqlite3VdbeMakeLabel(v); + pParse->iPartIdxTab = iCur; + sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, + SQLITE_JUMPIFNULL); + }else{ + *piPartIdxLabel = 0; + } + } nCol = pIdx->nColumn; regBase = sqlite3GetTempRange(pParse, nCol+1); sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regBase+nCol); diff --git a/src/expr.c b/src/expr.c index 03258c32c9..96c05dc3ae 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2362,15 +2362,20 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ /* Otherwise, fall thru into the TK_COLUMN case */ } case TK_COLUMN: { - if( pExpr->iTable<0 ){ - /* This only happens when coding check constraints */ - assert( pParse->ckBase>0 ); - inReg = pExpr->iColumn + pParse->ckBase; - }else{ - inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab, - pExpr->iColumn, pExpr->iTable, target, - pExpr->op2); + int iTab = pExpr->iTable; + if( iTab<0 ){ + if( pParse->ckBase>0 ){ + /* Generating CHECK constraints or inserting into partial index */ + inReg = pExpr->iColumn + pParse->ckBase; + break; + }else{ + /* Deleting from a partial index */ + iTab = pParse->iPartIdxTab; + } } + inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab, + pExpr->iColumn, iTab, target, + pExpr->op2); break; } case TK_INTEGER: { diff --git a/src/insert.c b/src/insert.c index 9a5661f59a..099c07f8b8 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1379,9 +1379,19 @@ void sqlite3GenerateConstraintChecks( for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){ int regIdx; int regR; + int addrSkipRow = 0; if( aRegIdx[iCur]==0 ) continue; /* Skip unused indices */ + if( pIdx->pPartIdxWhere ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[iCur]); + addrSkipRow = sqlite3VdbeMakeLabel(v); + pParse->ckBase = regData; + sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, addrSkipRow, + SQLITE_JUMPIFNULL); + pParse->ckBase = 0; + } + /* Create a key for accessing the index entry */ regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1); for(i=0; inColumn; i++){ @@ -1470,6 +1480,7 @@ void sqlite3GenerateConstraintChecks( } } sqlite3VdbeJumpHere(v, j3); + sqlite3VdbeResolveLabel(v, addrSkipRow); sqlite3ReleaseTempReg(pParse, regR); } @@ -1499,7 +1510,6 @@ void sqlite3CompleteInsertion( ){ int i; Vdbe *v; - int nIdx; Index *pIdx; u8 pik_flags; int regData; @@ -1508,9 +1518,11 @@ void sqlite3CompleteInsertion( v = sqlite3GetVdbe(pParse); assert( v!=0 ); assert( pTab->pSelect==0 ); /* This table is not a VIEW */ - for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){} - for(i=nIdx-1; i>=0; i--){ + for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ if( aRegIdx[i]==0 ) continue; + if( pIdx->pPartIdxWhere ){ + sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2); + } sqlite3VdbeAddOp2(v, OP_IdxInsert, baseCur+i+1, aRegIdx[i]); if( useSeekResult ){ sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); @@ -1612,6 +1624,7 @@ static int xferCompatibleCollation(const char *z1, const char *z2){ ** * The same DESC and ASC markings occurs on all columns ** * The same onError processing (OE_Abort, OE_Ignore, etc) ** * The same collating sequence on each column +** * The index has the exact same WHERE clause */ static int xferCompatibleIndex(Index *pDest, Index *pSrc){ int i; @@ -1634,6 +1647,9 @@ static int xferCompatibleIndex(Index *pDest, Index *pSrc){ return 0; /* Different collating sequences */ } } + if( sqlite3ExprCompare(pSrc->pPartIdxWhere, pDest->pPartIdxWhere) ){ + return 0; /* Different WHERE clauses */ + } /* If no test above fails then the indices must be compatible */ return 1; diff --git a/src/pragma.c b/src/pragma.c index 9bbbfa8aa1..fcbd614fb3 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1432,7 +1432,7 @@ void sqlite3Pragma( loopTop = sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0); sqlite3VdbeAddOp2(v, OP_AddImm, 2, 1); /* increment entry count */ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ - int jmp2; + int jmp2, jmp3; int r1; static const VdbeOpList idxErr[] = { { OP_AddImm, 1, -1, 0}, @@ -1447,7 +1447,7 @@ void sqlite3Pragma( { OP_IfPos, 1, 0, 0}, /* 9 */ { OP_Halt, 0, 0, 0}, }; - r1 = sqlite3GenerateIndexKey(pParse, pIdx, 1, 3, 0); + r1 = sqlite3GenerateIndexKey(pParse, pIdx, 1, 3, 0, &jmp3); jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, j+2, 0, r1, pIdx->nColumn+1); addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr); sqlite3VdbeChangeP4(v, addr+1, "rowid ", P4_STATIC); @@ -1455,6 +1455,7 @@ void sqlite3Pragma( sqlite3VdbeChangeP4(v, addr+4, pIdx->zName, P4_TRANSIENT); sqlite3VdbeJumpHere(v, addr+9); sqlite3VdbeJumpHere(v, jmp2); + sqlite3VdbeResolveLabel(v, jmp3); } sqlite3VdbeAddOp2(v, OP_Next, 1, loopTop+1); sqlite3VdbeJumpHere(v, loopTop); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 9d5580f928..206c8a0300 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2204,6 +2204,7 @@ struct Parse { int nSet; /* Number of sets used so far */ int nOnce; /* Number of OP_Once instructions so far */ int ckBase; /* Base register of data during check constraints */ + int iPartIdxTab; /* Table corresponding to a partial index */ int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */ int iCacheCnt; /* Counter used to generate aColCache[].lru values */ struct yColCache { @@ -2862,7 +2863,7 @@ int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); int sqlite3IsRowid(const char*); void sqlite3GenerateRowDelete(Parse*, Table*, int, int, int, Trigger *, int); void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int*); -int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int); +int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*); void sqlite3GenerateConstraintChecks(Parse*,Table*,int,int, int*,int,int,int,int,int*); void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int); diff --git a/src/update.c b/src/update.c index 5b18ebd6bf..4fbefc3b59 100644 --- a/src/update.c +++ b/src/update.c @@ -246,7 +246,7 @@ void sqlite3Update( } for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ int reg; - if( hasFK || chngRowid ){ + if( hasFK || chngRowid || pIdx->pPartIdxWhere ){ reg = ++pParse->nMem; }else{ reg = 0; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index f54685cb71..e970d5ff6d 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -250,8 +250,8 @@ int sqlite3VdbeMakeLabel(Vdbe *p){ void sqlite3VdbeResolveLabel(Vdbe *p, int x){ int j = -1-x; assert( p->magic==VDBE_MAGIC_INIT ); - assert( j>=0 && jnLabel ); - if( p->aLabel ){ + assert( jnLabel ); + if( j>=0 && p->aLabel ){ p->aLabel[j] = p->nOp; } } diff --git a/src/where.c b/src/where.c index 315c4035cb..fd7efd6478 100644 --- a/src/where.c +++ b/src/where.c @@ -2235,7 +2235,7 @@ static void constructAutomaticIndex( /* Fill the automatic index with content */ addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); regRecord = sqlite3GetTempReg(pParse); - sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 1); + sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 1, 0); sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord); sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); From 8a9789b6c1497e0b4dc7ce6a972f845a0e7a15bc Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 1 Aug 2013 03:36:59 +0000 Subject: [PATCH 32/47] Test cases and bug fixes for the partial index logic. FossilOrigin-Name: 6b73ae7c123801787c8994113cbeb87ee96ba653 --- manifest | 22 ++++++++++---------- manifest.uuid | 2 +- src/build.c | 11 ++++------ src/insert.c | 1 + src/parse.y | 9 ++++---- src/pragma.c | 54 ++++++++++++++++++++---------------------------- src/sqliteInt.h | 2 +- test/index6.test | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 98 insertions(+), 57 deletions(-) diff --git a/manifest b/manifest index 1e76bc8d3c..3e75f02aa7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\slogic\sto\skeep\spartial\sindices\sup\sto\sdate\sthrough\sDML\sstatements\sand\nwhen\snew\spartial\sindices\sare\screated.\s\sThis\snew\slogic\sis\suntested\sexcept\sto\nverify\sthat\sit\sdoes\snot\sinterfere\swith\sfull\sindices. -D 2013-08-01T01:14:43.210 +C Test\scases\sand\sbug\sfixes\sfor\sthe\spartial\sindex\slogic. +D 2013-08-01T03:36:59.964 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 3f7bbfd72efb1cbf6a49515c376a031767ec930a F src/btree.h 6fa8a3ff2483d0bb64a9f0105a8cedeac9e00cca F src/btreeInt.h eecc84f02375b2bb7a44abbcbbe3747dde73edb2 -F src/build.c 9422ab5fe5f3ea21575b50c182ebf2081253bed0 +F src/build.c 4be8975927a7871223311060cf13f5eec28ba3be F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 4262c227bc91cecc61ae37ed3a40f08069cfa267 @@ -180,7 +180,7 @@ F src/global.c 5caf4deab621abb45b4c607aad1bd21c20aac759 F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4 F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c 1e2eb1d4150c57f41dda8719f1b5ccb28abdacc2 +F src/insert.c b09e0aa7513aeda56b595126fb66f0580237f0ff F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b @@ -206,11 +206,11 @@ F src/os_unix.c 9eafa5458cf2ff684ddccff82c9bb113c7cad847 F src/os_win.c 074cb2b9bca6a1c2bd72acf04666cdc554bfaa9b F src/pager.c 5d2f7475260a8588f9c441bb309d2b7eaa7ded3b F src/pager.h 5cb78b8e1adfd5451e600be7719f5a99d87ac3b1 -F src/parse.y a950b48d4363f44dd98fef8a89fbd48970ebd9ce +F src/parse.y 599bc6338f3a6a7e1d656669a5667b9d77aea86b F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c d23d07716de96c7c0c2503ec5051a4384c3fb938 -F src/pragma.c f8936b23ce3eeddff4ab868c726d1546a6674418 +F src/pragma.c aca37128da044cc4e41e1cea49a5e3cf6159df43 F src/prepare.c fa6988589f39af8504a61731614cd4f6ae71554f F src/printf.c 41c49dac366a3a411190001a8ab495fa8887974e F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 @@ -221,7 +221,7 @@ F src/shell.c 52f975eae87c8338c4dfbf4c2842d2a0971f01fd F src/sqlite.h.in d6a7523d6795317aac574fccc67d9df25253771c F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h b69d7bac8a7fea89f11558f0659324f0551b0868 +F src/sqliteInt.h b39d566354613e781d49ffe8d3ee58baa4f7b4f5 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -589,7 +589,7 @@ F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6 F test/index3.test 423a25c789fc8cc51aaf2a4370bbdde2d9e9eed7 F test/index4.test 2983216eb8c86ee62d9ed7cb206b5cc3331c0026 F test/index5.test fc07c14193c0430814e7a08b5da46888ee795c33 -F test/index6.test 11171203a09b543d6181af59c298d2429ba762e2 +F test/index6.test 7030e7b77a0809eea33b2a1865379bb8010fba72 F test/indexedby.test 0e959308707c808515c3a51363f7a9835027108c F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 @@ -1104,7 +1104,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 8ca3eac111e06a1854f878a74bffe8f20eb47f1b -R 9dc930e0b891070c4f237bde08c1f247 +P fb9044d15ad4fd6ae4a38858c0c0e6fe9d4faa25 +R 4044286eb4e933efbb5ac1ee2d79d687 U drh -Z dd655b435ca4957c549da40144eccbfa +Z 8fdacf32e3d306969cff97932cabfb4b diff --git a/manifest.uuid b/manifest.uuid index 53ef0430bf..3d6a3ff142 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fb9044d15ad4fd6ae4a38858c0c0e6fe9d4faa25 \ No newline at end of file +6b73ae7c123801787c8994113cbeb87ee96ba653 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 941bcb269f..cc758b2741 100644 --- a/src/build.c +++ b/src/build.c @@ -1226,7 +1226,7 @@ void sqlite3AddPrimaryKey( #endif }else{ Index *p; - p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0, + p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0); if( p ){ p->autoIndex = 2; @@ -2467,7 +2467,6 @@ Index *sqlite3CreateIndex( ExprList *pList, /* A list of columns to be indexed */ int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ Token *pStart, /* The CREATE token that begins this statement */ - Token *pEnd, /* The ")" that closes the CREATE INDEX statement */ Expr *pPIWhere, /* WHERE clause for partial indices */ int sortOrder, /* Sort order of primary key when pList==NULL */ int ifNotExist /* Omit error if index already exists */ @@ -2490,7 +2489,6 @@ Index *sqlite3CreateIndex( int nExtra = 0; char *zExtra; - assert( pStart==0 || pEnd!=0 ); /* pEnd must be non-NULL if pStart is */ assert( pParse->nErr==0 ); /* Never called with prior errors */ if( db->mallocFailed || IN_DECLARE_VTAB ){ goto exit_create_index; @@ -2863,12 +2861,11 @@ Index *sqlite3CreateIndex( ** the zStmt variable */ if( pStart ){ - assert( pEnd!=0 ); + int n = (pParse->sLastToken.z - pName->z) + 1; + if( pName->z[n-1]==';' ) n--; /* A named index with an explicit CREATE INDEX statement */ zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s", - onError==OE_None ? "" : " UNIQUE", - (int)(pEnd->z - pName->z) + 1, - pName->z); + onError==OE_None ? "" : " UNIQUE", n, pName->z); }else{ /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */ /* zStmt = sqlite3MPrintf(""); */ diff --git a/src/insert.c b/src/insert.c index 099c07f8b8..54821f18b7 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1411,6 +1411,7 @@ void sqlite3GenerateConstraintChecks( onError = pIdx->onError; if( onError==OE_None ){ sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1); + sqlite3VdbeResolveLabel(v, addrSkipRow); continue; /* pIdx is not a UNIQUE index */ } if( overrideError!=OE_Default ){ diff --git a/src/parse.y b/src/parse.y index 6ac2c3d440..139040339c 100644 --- a/src/parse.y +++ b/src/parse.y @@ -300,8 +300,7 @@ ccons ::= NULL onconf. ccons ::= NOT NULL onconf(R). {sqlite3AddNotNull(pParse, R);} ccons ::= PRIMARY KEY sortorder(Z) onconf(R) autoinc(I). {sqlite3AddPrimaryKey(pParse,0,R,I,Z);} -ccons ::= UNIQUE onconf(R). {sqlite3CreateIndex(pParse,0,0,0,0,R,0, - 0,0,0,0);} +ccons ::= UNIQUE onconf(R). {sqlite3CreateIndex(pParse,0,0,0,0,R,0,0,0,0);} ccons ::= CHECK LP expr(X) RP. {sqlite3AddCheckConstraint(pParse,X.pExpr);} ccons ::= REFERENCES nm(T) idxlist_opt(TA) refargs(R). {sqlite3CreateForeignKey(pParse,0,&T,TA,R);} @@ -350,7 +349,7 @@ tcons ::= CONSTRAINT nm(X). {pParse->constraintName = X;} tcons ::= PRIMARY KEY LP idxlist(X) autoinc(I) RP onconf(R). {sqlite3AddPrimaryKey(pParse,X,R,I,0);} tcons ::= UNIQUE LP idxlist(X) RP onconf(R). - {sqlite3CreateIndex(pParse,0,0,0,X,R,0,0,0,0,0);} + {sqlite3CreateIndex(pParse,0,0,0,X,R,0,0,0,0);} tcons ::= CHECK LP expr(E) RP onconf. {sqlite3AddCheckConstraint(pParse,E.pExpr);} tcons ::= FOREIGN KEY LP idxlist(FA) RP @@ -1126,10 +1125,10 @@ nexprlist(A) ::= expr(Y). ///////////////////////////// The CREATE INDEX command /////////////////////// // cmd ::= createkw(S) uniqueflag(U) INDEX ifnotexists(NE) nm(X) dbnm(D) - ON nm(Y) LP idxlist(Z) RP(E) where_opt(W). { + ON nm(Y) LP idxlist(Z) RP where_opt(W). { sqlite3CreateIndex(pParse, &X, &D, sqlite3SrcListAppend(pParse->db,0,&Y,0), Z, U, - &S, &E, W, SQLITE_SO_ASC, NE); + &S, W, SQLITE_SO_ASC, NE); } %type uniqueflag {int} diff --git a/src/pragma.c b/src/pragma.c index fcbd614fb3..4462799db7 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1400,9 +1400,7 @@ void sqlite3Pragma( } /* Make sure sufficient number of registers have been allocated */ - if( pParse->nMem < cnt+4 ){ - pParse->nMem = cnt+4; - } + pParse->nMem = MAX( pParse->nMem, cnt+4 ); /* Do the b-tree integrity checks */ sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1); @@ -1428,9 +1426,11 @@ void sqlite3Pragma( sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); sqlite3VdbeJumpHere(v, addr); sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead); - sqlite3VdbeAddOp2(v, OP_Integer, 0, 2); /* reg(2) will count entries */ - loopTop = sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0); - sqlite3VdbeAddOp2(v, OP_AddImm, 2, 1); /* increment entry count */ + for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ + sqlite3VdbeAddOp2(v, OP_Integer, 0, 7+j); /* index entries counter */ + } + pParse->nMem = MAX(pParse->nMem, 7+j); + loopTop = sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0) + 1; for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ int jmp2, jmp3; int r1; @@ -1448,6 +1448,7 @@ void sqlite3Pragma( { OP_Halt, 0, 0, 0}, }; r1 = sqlite3GenerateIndexKey(pParse, pIdx, 1, 3, 0, &jmp3); + sqlite3VdbeAddOp2(v, OP_AddImm, 7+j, 1); /* increment entry count */ jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, j+2, 0, r1, pIdx->nColumn+1); addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr); sqlite3VdbeChangeP4(v, addr+1, "rowid ", P4_STATIC); @@ -1457,34 +1458,23 @@ void sqlite3Pragma( sqlite3VdbeJumpHere(v, jmp2); sqlite3VdbeResolveLabel(v, jmp3); } - sqlite3VdbeAddOp2(v, OP_Next, 1, loopTop+1); - sqlite3VdbeJumpHere(v, loopTop); - for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ - static const VdbeOpList cntIdx[] = { - { OP_Integer, 0, 3, 0}, - { OP_Rewind, 0, 0, 0}, /* 1 */ - { OP_AddImm, 3, 1, 0}, - { OP_Next, 0, 0, 0}, /* 3 */ - { OP_Eq, 2, 0, 3}, /* 4 */ - { OP_AddImm, 1, -1, 0}, - { OP_String8, 0, 2, 0}, /* 6 */ - { OP_String8, 0, 3, 0}, /* 7 */ - { OP_Concat, 3, 2, 2}, - { OP_ResultRow, 2, 1, 0}, - }; - addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); - sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); - sqlite3VdbeJumpHere(v, addr); - addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx); - sqlite3VdbeChangeP1(v, addr+1, j+2); - sqlite3VdbeChangeP2(v, addr+1, addr+4); - sqlite3VdbeChangeP1(v, addr+3, j+2); - sqlite3VdbeChangeP2(v, addr+3, addr+2); - sqlite3VdbeJumpHere(v, addr+4); - sqlite3VdbeChangeP4(v, addr+6, + sqlite3VdbeAddOp2(v, OP_Next, 1, loopTop); + sqlite3VdbeJumpHere(v, loopTop-1); +#ifndef SQLITE_OMIT_BTREECOUNT + sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, "wrong # of entries in index ", P4_STATIC); - sqlite3VdbeChangeP4(v, addr+7, pIdx->zName, P4_TRANSIENT); + for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ + addr = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2); + sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); + sqlite3VdbeAddOp2(v, OP_Count, j+2, 3); + sqlite3VdbeAddOp3(v, OP_Eq, 7+j, addr+8, 3); + sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pIdx->zName, P4_TRANSIENT); + sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7); + sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1); } +#endif /* SQLITE_OMIT_BTREECOUNT */ } } addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 206c8a0300..21e32ff7b3 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2786,7 +2786,7 @@ void sqlite3SrcListAssignCursors(Parse*, SrcList*); void sqlite3IdListDelete(sqlite3*, IdList*); void sqlite3SrcListDelete(sqlite3*, SrcList*); Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*, - Token*, Expr*, int, int); + Expr*, int, int); void sqlite3DropIndex(Parse*, SrcList*, int); int sqlite3Select(Parse*, Select*, SelectDest*); Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*, diff --git a/test/index6.test b/test/index6.test index 89b9c48761..b561b6333f 100644 --- a/test/index6.test +++ b/test/index6.test @@ -56,5 +56,59 @@ do_test index6-1.6 { } } {1 {functions prohibited in partial index WHERE clauses}} +do_test index6-1.10 { + execsql { + ANALYZE; + SELECT idx, stat FROM sqlite_stat1 ORDER BY idx; + PRAGMA integrity_check; + } +} {t1a {14 1} t1b {10 1} ok} + +do_test index6-1.11 { + execsql { + UPDATE t1 SET a=b; + ANALYZE; + SELECT idx, stat FROM sqlite_stat1 ORDER BY idx; + PRAGMA integrity_check; + } +} {t1a {20 1} t1b {10 1} ok} + +do_test index6-1.11 { + execsql { + UPDATE t1 SET a=NULL WHERE b%3!=0; + UPDATE t1 SET b=b+100; + ANALYZE; + SELECT idx, stat FROM sqlite_stat1 ORDER BY idx; + PRAGMA integrity_check; + } +} {t1a {6 1} t1b {20 1} ok} + +do_test index6-1.12 { + execsql { + UPDATE t1 SET a=CASE WHEN b%3!=0 THEN b END; + UPDATE t1 SET b=b-100; + ANALYZE; + SELECT idx, stat FROM sqlite_stat1 ORDER BY idx; + PRAGMA integrity_check; + } +} {t1a {13 1} t1b {10 1} ok} + +do_test index6-1.13 { + execsql { + DELETE FROM t1 WHERE b BETWEEN 8 AND 12; + ANALYZE; + SELECT idx, stat FROM sqlite_stat1 ORDER BY idx; + PRAGMA integrity_check; + } +} {t1a {10 1} t1b {8 1} ok} + +do_test index6-1.14 { + execsql { + REINDEX; + ANALYZE; + SELECT idx, stat FROM sqlite_stat1 ORDER BY idx; + PRAGMA integrity_check; + } +} {t1a {10 1} t1b {8 1} ok} finish_test From 721dfcf544beeea0a59899d45a7ebd6cb3c2b746 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 1 Aug 2013 04:39:17 +0000 Subject: [PATCH 33/47] Fix the ANALYZE command to work with partial indices. FossilOrigin-Name: 60353124f4e965393ecd864019bdbca1999fb69e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/analyze.c | 33 +++++++++++++++++---------------- test/index6.test | 31 ++++++++++++++++++++----------- 4 files changed, 45 insertions(+), 35 deletions(-) diff --git a/manifest b/manifest index 3e75f02aa7..b7bf7869ea 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Test\scases\sand\sbug\sfixes\sfor\sthe\spartial\sindex\slogic. -D 2013-08-01T03:36:59.964 +C Fix\sthe\sANALYZE\scommand\sto\swork\swith\spartial\sindices. +D 2013-08-01T04:39:17.756 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -157,7 +157,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad F src/alter.c f8db986c03eb0bfb221523fc9bbb9d0b70de3168 -F src/analyze.c 27e541b9b5b48b41eb899b22a49ff42384899151 +F src/analyze.c a33fcb0b3a399d966951feb9f32115106b3ecc2e F src/attach.c 1816f5a9eea8d2010fc2b22b44f0f63eb3a62704 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 43b348822db3e4cef48b2ae5a445fbeb6c73a165 @@ -589,7 +589,7 @@ F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6 F test/index3.test 423a25c789fc8cc51aaf2a4370bbdde2d9e9eed7 F test/index4.test 2983216eb8c86ee62d9ed7cb206b5cc3331c0026 F test/index5.test fc07c14193c0430814e7a08b5da46888ee795c33 -F test/index6.test 7030e7b77a0809eea33b2a1865379bb8010fba72 +F test/index6.test 9db2067dc06bfa4f664193d860297d50775d31e7 F test/indexedby.test 0e959308707c808515c3a51363f7a9835027108c F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 @@ -1104,7 +1104,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P fb9044d15ad4fd6ae4a38858c0c0e6fe9d4faa25 -R 4044286eb4e933efbb5ac1ee2d79d687 +P 6b73ae7c123801787c8994113cbeb87ee96ba653 +R 8f1421e98f999d36a1d28b17b8226989 U drh -Z 8fdacf32e3d306969cff97932cabfb4b +Z 2b1246919b9a91b92ae0d1de51d4ce2b diff --git a/manifest.uuid b/manifest.uuid index 3d6a3ff142..8d65f016b3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6b73ae7c123801787c8994113cbeb87ee96ba653 \ No newline at end of file +60353124f4e965393ecd864019bdbca1999fb69e \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 78bbf28b47..d25a9b196c 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -441,6 +441,7 @@ static void analyzeOneTable( int endOfLoop; /* The end of the loop */ int jZeroRows = -1; /* Jump from here if number of rows is zero */ int iDb; /* Index of database containing pTab */ + u8 needTableCnt = 1; /* True to count the table */ int regTabname = iMem++; /* Register containing table name */ int regIdxname = iMem++; /* Register containing index name */ int regStat1 = iMem++; /* The stat column of sqlite_stat1 */ @@ -500,6 +501,7 @@ static void analyzeOneTable( int *aChngAddr; /* Array of jump instruction addresses */ if( pOnlyIdx && pOnlyIdx!=pIdx ) continue; + if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0; VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName)); nCol = pIdx->nColumn; aChngAddr = sqlite3DbMallocRaw(db, sizeof(int)*nCol); @@ -659,9 +661,7 @@ static void analyzeOneTable( ** is never possible. */ sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regStat1); - if( jZeroRows<0 ){ - jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, iMem); - } + jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, iMem); for(i=0; ipPartIdxWhere!=0 ) sqlite3VdbeJumpHere(v, jZeroRows); sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0); sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid); sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + if( pIdx->pPartIdxWhere==0 ) sqlite3VdbeJumpHere(v, jZeroRows); } - /* If the table has no indices, create a single sqlite_stat1 entry - ** containing NULL as the index name and the row count as the content. + /* Create a single sqlite_stat1 entry containing NULL as the index + ** name and the row count as the content. */ - if( pTab->pIndex==0 ){ + if( pOnlyIdx==0 && needTableCnt ){ sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pTab->tnum, iDb); VdbeComment((v, "%s", pTab->zName)); sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat1); sqlite3VdbeAddOp1(v, OP_Close, iIdxCur); jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1); - }else{ + sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0); + sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); + sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); sqlite3VdbeJumpHere(v, jZeroRows); - jZeroRows = sqlite3VdbeAddOp0(v, OP_Goto); } - sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname); - sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0); - sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); - sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid); - sqlite3VdbeChangeP5(v, OPFLAG_APPEND); if( pParse->nMemnMem = regRec; - sqlite3VdbeJumpHere(v, jZeroRows); } @@ -879,8 +878,10 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){ v = v*10 + c - '0'; z++; } - if( i==0 ) pTable->nRowEst = v; - if( pIndex==0 ) break; + if( i==0 && (pIndex==0 || pIndex->pPartIdxWhere==0) ){ + if( v>0 ) pTable->nRowEst = v; + if( pIndex==0 ) break; + } pIndex->aiRowEst[i] = v; if( *z==' ' ) z++; if( strcmp(z, "unordered")==0 ){ diff --git a/test/index6.test b/test/index6.test index b561b6333f..d283d924c5 100644 --- a/test/index6.test +++ b/test/index6.test @@ -19,12 +19,12 @@ source $testdir/tester.tcl load_static_extension db wholenumber; do_test index6-1.1 { execsql { - CREATE TABLE t1(a,b); + CREATE TABLE t1(a,b,c); CREATE INDEX t1a ON t1(a) WHERE a IS NOT NULL; CREATE INDEX t1b ON t1(b) WHERE b>10; CREATE VIRTUAL TABLE nums USING wholenumber; - INSERT INTO t1(a,b) - SELECT CASE WHEN value%3!=0 THEN value END, value + INSERT INTO t1(a,b,c) + SELECT CASE WHEN value%3!=0 THEN value END, value, value FROM nums WHERE value<=20; SELECT count(a), count(b) FROM t1; } @@ -32,9 +32,9 @@ do_test index6-1.1 { do_test index6-1.2 { catchsql { - CREATE INDEX bad1 ON t1(a,b) WHERE c IS NOT NULL; + CREATE INDEX bad1 ON t1(a,b) WHERE x IS NOT NULL; } -} {1 {no such column: c}} +} {1 {no such column: x}} do_test index6-1.3 { catchsql { CREATE INDEX bad1 ON t1(a,b) WHERE EXISTS(SELECT * FROM t1); @@ -62,7 +62,7 @@ do_test index6-1.10 { SELECT idx, stat FROM sqlite_stat1 ORDER BY idx; PRAGMA integrity_check; } -} {t1a {14 1} t1b {10 1} ok} +} {{} 20 t1a {14 1} t1b {10 1} ok} do_test index6-1.11 { execsql { @@ -71,7 +71,7 @@ do_test index6-1.11 { SELECT idx, stat FROM sqlite_stat1 ORDER BY idx; PRAGMA integrity_check; } -} {t1a {20 1} t1b {10 1} ok} +} {{} 20 t1a {20 1} t1b {10 1} ok} do_test index6-1.11 { execsql { @@ -81,7 +81,7 @@ do_test index6-1.11 { SELECT idx, stat FROM sqlite_stat1 ORDER BY idx; PRAGMA integrity_check; } -} {t1a {6 1} t1b {20 1} ok} +} {{} 20 t1a {6 1} t1b {20 1} ok} do_test index6-1.12 { execsql { @@ -91,7 +91,7 @@ do_test index6-1.12 { SELECT idx, stat FROM sqlite_stat1 ORDER BY idx; PRAGMA integrity_check; } -} {t1a {13 1} t1b {10 1} ok} +} {{} 20 t1a {13 1} t1b {10 1} ok} do_test index6-1.13 { execsql { @@ -100,7 +100,7 @@ do_test index6-1.13 { SELECT idx, stat FROM sqlite_stat1 ORDER BY idx; PRAGMA integrity_check; } -} {t1a {10 1} t1b {8 1} ok} +} {{} 15 t1a {10 1} t1b {8 1} ok} do_test index6-1.14 { execsql { @@ -109,6 +109,15 @@ do_test index6-1.14 { SELECT idx, stat FROM sqlite_stat1 ORDER BY idx; PRAGMA integrity_check; } -} {t1a {10 1} t1b {8 1} ok} +} {{} 15 t1a {10 1} t1b {8 1} ok} + +do_test index6-1.15 { + execsql { + CREATE INDEX t1c ON t1(c); + ANALYZE; + SELECT idx, stat FROM sqlite_stat1 ORDER BY idx; + PRAGMA integrity_check; + } +} {t1a {10 1} t1b {8 1} t1c {15 1} ok} finish_test From cf0fd4a5fd0cbb5f87a2dea65893b76e59d5c413 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 1 Aug 2013 12:21:58 +0000 Subject: [PATCH 34/47] Refactor internal function name sqlite3VdbeGetValue() to sqlite3VdbeGetBoundValue(). FossilOrigin-Name: 81834c3023876487a1188390aae850cf71683701 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/vdbe.h | 2 +- src/vdbeaux.c | 2 +- src/where.c | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index b7bf7869ea..1855b631dd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sANALYZE\scommand\sto\swork\swith\spartial\sindices. -D 2013-08-01T04:39:17.756 +C Refactor\sinternal\sfunction\sname\ssqlite3VdbeGetValue()\sto\nsqlite3VdbeGetBoundValue(). +D 2013-08-01T12:21:58.409 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -278,10 +278,10 @@ F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f F src/util.c f566b5138099a2df8533b190d0dcc74b7dfbe0c9 F src/vacuum.c d9c5759f4c5a438bb43c2086f72c5d2edabc36c8 F src/vdbe.c d6048a720c197db2f0e7d618e918bd2e2eff0322 -F src/vdbe.h f380af2a7fab32ba8a8b05bf042497636afec66d +F src/vdbe.h 4f554b5627f26710c4c36d919110a3fc611ca5c4 F src/vdbeInt.h e9b7c6b165a31a4715c5aa97223d20d265515231 F src/vdbeapi.c 4d13580bd058b39623e8fcfc233b7df4b8191e8b -F src/vdbeaux.c 75206d58c2e1ea7ed2758106d591ff7a082ea909 +F src/vdbeaux.c 492376bd1b37a8350f300380d149282c062c6077 F src/vdbeblob.c 5dc79627775bd9a9b494dd956e26297946417d69 F src/vdbemem.c 833005f1cbbf447289f1973dba2a0c2228c7b8ab F src/vdbesort.c 3937e06b2a0e354500e17dc206ef4c35770a5017 @@ -290,7 +290,7 @@ F src/vtab.c 2e8b489db47e20ae36cd247932dc671c9ded0624 F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73 -F src/where.c 14d48fe735a7d5f4d610d8b9396a9e7752539199 +F src/where.c bad23a54820dd7f4c0ec5048d3cdaed28d7e4a52 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 @@ -1104,7 +1104,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 6b73ae7c123801787c8994113cbeb87ee96ba653 -R 8f1421e98f999d36a1d28b17b8226989 +P 60353124f4e965393ecd864019bdbca1999fb69e +R bb451065c1214431469ba3f19aa1b916 U drh -Z 2b1246919b9a91b92ae0d1de51d4ce2b +Z b1d702840c58e4dca1711593d0bbaf8a diff --git a/manifest.uuid b/manifest.uuid index 8d65f016b3..a0035d8ae7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -60353124f4e965393ecd864019bdbca1999fb69e \ No newline at end of file +81834c3023876487a1188390aae850cf71683701 \ No newline at end of file diff --git a/src/vdbe.h b/src/vdbe.h index 4c2e76d562..a6cc915444 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -204,7 +204,7 @@ sqlite3 *sqlite3VdbeDb(Vdbe*); void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, int); void sqlite3VdbeSwap(Vdbe*,Vdbe*); VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*); -sqlite3_value *sqlite3VdbeGetValue(Vdbe*, int, u8); +sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8); void sqlite3VdbeSetVarmask(Vdbe*, int); #ifndef SQLITE_OMIT_TRACE char *sqlite3VdbeExpandSql(Vdbe*, const char*); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index e970d5ff6d..8181cc1347 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3253,7 +3253,7 @@ sqlite3 *sqlite3VdbeDb(Vdbe *v){ ** ** The returned value must be freed by the caller using sqlite3ValueFree(). */ -sqlite3_value *sqlite3VdbeGetValue(Vdbe *v, int iVar, u8 aff){ +sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff){ assert( iVar>0 ); if( v ){ Mem *pMem = &v->aVar[iVar-1]; diff --git a/src/where.c b/src/where.c index fd7efd6478..bcf52ee823 100644 --- a/src/where.c +++ b/src/where.c @@ -1128,7 +1128,7 @@ static int isLikeOrGlob( if( op==TK_VARIABLE ){ Vdbe *pReprepare = pParse->pReprepare; int iCol = pRight->iColumn; - pVal = sqlite3VdbeGetValue(pReprepare, iCol, SQLITE_AFF_NONE); + pVal = sqlite3VdbeGetBoundValue(pReprepare, iCol, SQLITE_AFF_NONE); if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){ z = (char *)sqlite3_value_text(pVal); } @@ -2592,7 +2592,7 @@ static int valueFromExpr( ){ int iVar = pExpr->iColumn; sqlite3VdbeSetVarmask(pParse->pVdbe, iVar); - *pp = sqlite3VdbeGetValue(pParse->pReprepare, iVar, aff); + *pp = sqlite3VdbeGetBoundValue(pParse->pReprepare, iVar, aff); return SQLITE_OK; } return sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, aff, pp); From 619a1305e77cc6382013fb1e9c406d8fb88ca600 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 1 Aug 2013 13:04:46 +0000 Subject: [PATCH 35/47] Fill out an initial implementation of the sqlite3ExprImpliesExpr() function. FossilOrigin-Name: 8e07aa2ad5579aeb82174ce5bd432ddb9c058bc1 --- manifest | 20 +++++++++--------- manifest.uuid | 2 +- src/expr.c | 54 ++++++++++++++++++++++++++++++++++++------------- src/insert.c | 4 ++-- src/resolve.c | 4 ++-- src/select.c | 4 ++-- src/sqliteInt.h | 4 ++-- 7 files changed, 59 insertions(+), 33 deletions(-) diff --git a/manifest b/manifest index 1855b631dd..aa35525505 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Refactor\sinternal\sfunction\sname\ssqlite3VdbeGetValue()\sto\nsqlite3VdbeGetBoundValue(). -D 2013-08-01T12:21:58.409 +C Fill\sout\san\sinitial\simplementation\sof\sthe\ssqlite3ExprImpliesExpr()\sfunction. +D 2013-08-01T13:04:46.842 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -172,7 +172,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 4262c227bc91cecc61ae37ed3a40f08069cfa267 F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/delete.c 2317c814866d9aa71fea16b3faf4fdd4d6a49b94 -F src/expr.c 299f1de324676599b818e587b77e683978514461 +F src/expr.c 27a451dc75c8f2498199ddbd76e941f60fc31c73 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 914a6bbd987d857c41ac9d244efa6641f36faadb F src/func.c 5c50c1ea31fd864b0fe921fe1a8d4c55acd609ef @@ -180,7 +180,7 @@ F src/global.c 5caf4deab621abb45b4c607aad1bd21c20aac759 F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4 F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c b09e0aa7513aeda56b595126fb66f0580237f0ff +F src/insert.c a66bcdc956145369c1a876709f47f69476973e15 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b @@ -214,14 +214,14 @@ F src/pragma.c aca37128da044cc4e41e1cea49a5e3cf6159df43 F src/prepare.c fa6988589f39af8504a61731614cd4f6ae71554f F src/printf.c 41c49dac366a3a411190001a8ab495fa8887974e F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 -F src/resolve.c ada80e8df5d4ab0a21cf65ec5be8ba3b826e2b6f +F src/resolve.c 8b3c7a439cc6ba242e45566284adb72fa770b7c8 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 91b62654caf8dfe292fb8882715e575d34ad3874 +F src/select.c 20369c82dc38eb4a77b458c8f6e353ef550580c9 F src/shell.c 52f975eae87c8338c4dfbf4c2842d2a0971f01fd F src/sqlite.h.in d6a7523d6795317aac574fccc67d9df25253771c F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h b39d566354613e781d49ffe8d3ee58baa4f7b4f5 +F src/sqliteInt.h 7c6ad474ce49ed18393c027be65c9532b7c9168f F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1104,7 +1104,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 60353124f4e965393ecd864019bdbca1999fb69e -R bb451065c1214431469ba3f19aa1b916 +P 81834c3023876487a1188390aae850cf71683701 +R 97f0c54b3f7128423bcbfe2828fbdcb2 U drh -Z b1d702840c58e4dca1711593d0bbaf8a +Z 2652ffb0448810ae6b88d2be09f88047 diff --git a/manifest.uuid b/manifest.uuid index a0035d8ae7..021a483570 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -81834c3023876487a1188390aae850cf71683701 \ No newline at end of file +8e07aa2ad5579aeb82174ce5bd432ddb9c058bc1 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 96c05dc3ae..6fa34443a3 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3798,6 +3798,9 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ ** by a COLLATE operator at the top level. Return 2 if there are differences ** other than the top-level COLLATE operator. ** +** If any subelement of pB has Expr.iTable==(-1) then it is allowed +** to compare equal to an equivalent element in pA with Expr.iTable==iTab. +** ** Sometimes this routine will return 2 even if the two expressions ** really are equivalent. If we cannot prove that the expressions are ** identical, we return 2 just to be safe. So if this routine @@ -3808,7 +3811,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ ** just might result in some slightly slower code. But returning ** an incorrect 0 or 1 could lead to a malfunction. */ -int sqlite3ExprCompare(Expr *pA, Expr *pB){ +int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){ if( pA==0||pB==0 ){ return pB==pA ? 0 : 2; } @@ -3819,18 +3822,19 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){ } if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2; if( pA->op!=pB->op ){ - if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB)<2 ){ + if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB, iTab)<2 ){ return 1; } - if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft)<2 ){ + if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft, iTab)<2 ){ return 1; } return 2; } - if( sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 2; - if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2; - if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2; - if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 2; + if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2; + if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2; + if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2; + if( pA->iColumn!=pB->iColumn ) return 2; + if( pA->iTable!=pB->iTable && (pA->iTable!=iTab || pB->iTable>=0) ) return 2; if( ExprHasProperty(pA, EP_IntValue) ){ if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){ return 2; @@ -3848,6 +3852,9 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){ ** Compare two ExprList objects. Return 0 if they are identical and ** non-zero if they differ in any way. ** +** If any subelement of pB has Expr.iTable==(-1) then it is allowed +** to compare equal to an equivalent element in pA with Expr.iTable==iTab. +** ** This routine might return non-zero for equivalent ExprLists. The ** only consequence will be disabled optimizations. But this routine ** must never return 0 if the two ExprList objects are different, or @@ -3856,7 +3863,7 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){ ** Two NULL pointers are considered to be the same. But a NULL pointer ** always differs from a non-NULL pointer. */ -int sqlite3ExprListCompare(ExprList *pA, ExprList *pB){ +int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){ int i; if( pA==0 && pB==0 ) return 0; if( pA==0 || pB==0 ) return 1; @@ -3865,7 +3872,7 @@ int sqlite3ExprListCompare(ExprList *pA, ExprList *pB){ Expr *pExprA = pA->a[i].pExpr; Expr *pExprB = pB->a[i].pExpr; if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1; - if( sqlite3ExprCompare(pExprA, pExprB) ) return 1; + if( sqlite3ExprCompare(pExprA, pExprB, iTab) ) return 1; } return 0; } @@ -3875,9 +3882,13 @@ int sqlite3ExprListCompare(ExprList *pA, ExprList *pB){ ** true. Return false if we cannot complete the proof or if pE2 might ** be false. Examples: ** -** pE1: x==5 pE2: x>0 Result: true -** pE1: x>0 pE2: x==5 Result: false -** pE1: x!=123 pE2: x IS NOT NULL Result: true +** pE1: x==5 pE2: x==5 Result: true +** pE1: x>0 pE2: x==5 Result: false +** pE1: x=21 pE2: x=21 OR y=43 Result: true +** pE1: x!=123 pE2: x IS NOT NULL Result: true +** pE1: x!=?1 pE2: x IS NOT NULL Result: true +** pE1: x IS NULL pE2: x IS NOT NULL Result: false +** pE1: x IS ?2 pE2: x IS NOT NULL Reuslt: false ** ** When comparing TK_COLUMN nodes between pE1 and pE2, if pE2 has ** Expr.iTable<0 then assume a table number given by iTab. @@ -3887,7 +3898,22 @@ int sqlite3ExprListCompare(ExprList *pA, ExprList *pB){ ** it will always give the correct answer and is hence always safe. */ int sqlite3ExprImpliesExpr(Expr *pE1, Expr *pE2, int iTab){ - return 0; /* FIXME: this needs to be worked out */ + if( sqlite3ExprCompare(pE1, pE2, iTab)==0 ){ + return 1; + } + if( pE2->op==TK_OR + && (sqlite3ExprImpliesExpr(pE1, pE2->pLeft, iTab) + || sqlite3ExprImpliesExpr(pE1, pE2->pRight, iTab) ) + ){ + return 1; + } + if( pE2->op==TK_NOTNULL + && sqlite3ExprCompare(pE1->pLeft, pE2->pLeft, iTab)==0 + && (pE1->op!=TK_ISNULL && pE1->op!=TK_IS) + ){ + return 1; + } + return 0; } /* @@ -4070,7 +4096,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ */ struct AggInfo_func *pItem = pAggInfo->aFunc; for(i=0; inFunc; i++, pItem++){ - if( sqlite3ExprCompare(pItem->pExpr, pExpr)==0 ){ + if( sqlite3ExprCompare(pItem->pExpr, pExpr, -1)==0 ){ break; } } diff --git a/src/insert.c b/src/insert.c index 54821f18b7..1c2cabb938 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1648,7 +1648,7 @@ static int xferCompatibleIndex(Index *pDest, Index *pSrc){ return 0; /* Different collating sequences */ } } - if( sqlite3ExprCompare(pSrc->pPartIdxWhere, pDest->pPartIdxWhere) ){ + if( sqlite3ExprCompare(pSrc->pPartIdxWhere, pDest->pPartIdxWhere, -1) ){ return 0; /* Different WHERE clauses */ } @@ -1806,7 +1806,7 @@ static int xferOptimization( } } #ifndef SQLITE_OMIT_CHECK - if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck, pDest->pCheck) ){ + if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){ return 0; /* Tables have different CHECK constraints. Ticket #2252 */ } #endif diff --git a/src/resolve.c b/src/resolve.c index 239e0eb2a0..f288ed930c 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -825,7 +825,7 @@ static int resolveOrderByTermToExprList( ** result-set entry. */ for(i=0; inExpr; i++){ - if( sqlite3ExprCompare(pEList->a[i].pExpr, pE)<2 ){ + if( sqlite3ExprCompare(pEList->a[i].pExpr, pE, -1)<2 ){ return i+1; } } @@ -1053,7 +1053,7 @@ static int resolveOrderGroupBy( return 1; } for(j=0; jpEList->nExpr; j++){ - if( sqlite3ExprCompare(pE, pSelect->pEList->a[j].pExpr)==0 ){ + if( sqlite3ExprCompare(pE, pSelect->pEList->a[j].pExpr, -1)==0 ){ pItem->iOrderByCol = j+1; } } diff --git a/src/select.c b/src/select.c index fa35f45871..014feca8f2 100644 --- a/src/select.c +++ b/src/select.c @@ -4177,7 +4177,7 @@ int sqlite3Select( ** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER ** to disable this optimization for testing purposes. */ - if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy)==0 + if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy, -1)==0 && OptimizationEnabled(db, SQLITE_GroupByOrder) ){ pOrderBy = 0; } @@ -4198,7 +4198,7 @@ int sqlite3Select( ** BY and DISTINCT, and an index or separate temp-table for the other. */ if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct - && sqlite3ExprListCompare(pOrderBy, p->pEList)==0 + && sqlite3ExprListCompare(pOrderBy, p->pEList, -1)==0 ){ p->selFlags &= ~SF_Distinct; p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 21e32ff7b3..291957db9e 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2834,8 +2834,8 @@ void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*); void sqlite3Vacuum(Parse*); int sqlite3RunVacuum(char**, sqlite3*); char *sqlite3NameFromToken(sqlite3*, Token*); -int sqlite3ExprCompare(Expr*, Expr*); -int sqlite3ExprListCompare(ExprList*, ExprList*); +int sqlite3ExprCompare(Expr*, Expr*, int); +int sqlite3ExprListCompare(ExprList*, ExprList*, int); int sqlite3ExprImpliesExpr(Expr*, Expr*, int); void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); From 66518ca71f739cc2830b18ffd57b888b284df4b3 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 1 Aug 2013 15:09:57 +0000 Subject: [PATCH 36/47] More test cases and corresponding bug fixes. FossilOrigin-Name: 0c8cfdfae215c95cf167f404a1d346690b28e972 --- manifest | 18 +++++----- manifest.uuid | 2 +- src/expr.c | 9 +++-- src/pragma.c | 3 +- src/where.c | 2 +- test/index6.test | 94 +++++++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 113 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index aa35525505..9ab30e629b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fill\sout\san\sinitial\simplementation\sof\sthe\ssqlite3ExprImpliesExpr()\sfunction. -D 2013-08-01T13:04:46.842 +C More\stest\scases\sand\scorresponding\sbug\sfixes. +D 2013-08-01T15:09:57.772 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -172,7 +172,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 4262c227bc91cecc61ae37ed3a40f08069cfa267 F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/delete.c 2317c814866d9aa71fea16b3faf4fdd4d6a49b94 -F src/expr.c 27a451dc75c8f2498199ddbd76e941f60fc31c73 +F src/expr.c b873f60585cb851963fd8059f8d26c578e8448f6 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 914a6bbd987d857c41ac9d244efa6641f36faadb F src/func.c 5c50c1ea31fd864b0fe921fe1a8d4c55acd609ef @@ -210,7 +210,7 @@ F src/parse.y 599bc6338f3a6a7e1d656669a5667b9d77aea86b F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c d23d07716de96c7c0c2503ec5051a4384c3fb938 -F src/pragma.c aca37128da044cc4e41e1cea49a5e3cf6159df43 +F src/pragma.c 590c75750d93ec5a1f903e4bb0dc6d2a0845bf8b F src/prepare.c fa6988589f39af8504a61731614cd4f6ae71554f F src/printf.c 41c49dac366a3a411190001a8ab495fa8887974e F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 @@ -290,7 +290,7 @@ F src/vtab.c 2e8b489db47e20ae36cd247932dc671c9ded0624 F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73 -F src/where.c bad23a54820dd7f4c0ec5048d3cdaed28d7e4a52 +F src/where.c 5642a0f1d7c45a0f0eb6006e783916a8a715089a F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 @@ -589,7 +589,7 @@ F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6 F test/index3.test 423a25c789fc8cc51aaf2a4370bbdde2d9e9eed7 F test/index4.test 2983216eb8c86ee62d9ed7cb206b5cc3331c0026 F test/index5.test fc07c14193c0430814e7a08b5da46888ee795c33 -F test/index6.test 9db2067dc06bfa4f664193d860297d50775d31e7 +F test/index6.test 203633042a116d98932f3c750c5d2bb60de7bd56 F test/indexedby.test 0e959308707c808515c3a51363f7a9835027108c F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 @@ -1104,7 +1104,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 81834c3023876487a1188390aae850cf71683701 -R 97f0c54b3f7128423bcbfe2828fbdcb2 +P 8e07aa2ad5579aeb82174ce5bd432ddb9c058bc1 +R b61a938ce818e9ac097fb2a064b3215f U drh -Z 2652ffb0448810ae6b88d2be09f88047 +Z 381062f7cdfdb23ad88f9994e93f96ef diff --git a/manifest.uuid b/manifest.uuid index 021a483570..9b8e98a9fd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8e07aa2ad5579aeb82174ce5bd432ddb9c058bc1 \ No newline at end of file +0c8cfdfae215c95cf167f404a1d346690b28e972 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 6fa34443a3..8d6b90dd2f 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3801,6 +3801,9 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ ** If any subelement of pB has Expr.iTable==(-1) then it is allowed ** to compare equal to an equivalent element in pA with Expr.iTable==iTab. ** +** The pA side might be using TK_REGISTER. If that is the case and pB is +** not using TK_REGISTER but is otherwise equivalent, then still return 0. +** ** Sometimes this routine will return 2 even if the two expressions ** really are equivalent. If we cannot prove that the expressions are ** identical, we return 2 just to be safe. So if this routine @@ -3821,7 +3824,7 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){ return 2; } if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2; - if( pA->op!=pB->op ){ + if( pA->op!=pB->op && (pA->op!=TK_REGISTER || pA->op2!=pB->op) ){ if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB, iTab)<2 ){ return 1; } @@ -3834,7 +3837,9 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){ if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2; if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2; if( pA->iColumn!=pB->iColumn ) return 2; - if( pA->iTable!=pB->iTable && (pA->iTable!=iTab || pB->iTable>=0) ) return 2; + if( pA->iTable!=pB->iTable + && pA->op!=TK_REGISTER + && (pA->iTable!=iTab || pB->iTable>=0) ) return 2; if( ExprHasProperty(pA, EP_IntValue) ){ if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){ return 2; diff --git a/src/pragma.c b/src/pragma.c index 4462799db7..f152220d40 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1400,7 +1400,7 @@ void sqlite3Pragma( } /* Make sure sufficient number of registers have been allocated */ - pParse->nMem = MAX( pParse->nMem, cnt+4 ); + pParse->nMem = MAX( pParse->nMem, cnt+7 ); /* Do the b-tree integrity checks */ sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1); @@ -1425,6 +1425,7 @@ void sqlite3Pragma( addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */ sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); sqlite3VdbeJumpHere(v, addr); + sqlite3ExprCacheClear(pParse); sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead); for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ sqlite3VdbeAddOp2(v, OP_Integer, 0, 7+j); /* index entries counter */ diff --git a/src/where.c b/src/where.c index bcf52ee823..51edc8ec39 100644 --- a/src/where.c +++ b/src/where.c @@ -5556,7 +5556,7 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){ pLoop->rRun = 33; /* 33==whereCost(10) */ }else{ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - if( pIdx->onError==OE_None ) continue; + if( pIdx->onError==OE_None || pIdx->pPartIdxWhere!=0 ) continue; for(j=0; jnColumn; j++){ pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 0, WO_EQ, pIdx); if( pTerm==0 ) break; diff --git a/test/index6.test b/test/index6.test index d283d924c5..0b6a9365dc 100644 --- a/test/index6.test +++ b/test/index6.test @@ -18,6 +18,7 @@ source $testdir/tester.tcl load_static_extension db wholenumber; do_test index6-1.1 { + # Able to parse and manage partial indices execsql { CREATE TABLE t1(a,b,c); CREATE INDEX t1a ON t1(a) WHERE a IS NOT NULL; @@ -27,9 +28,12 @@ do_test index6-1.1 { SELECT CASE WHEN value%3!=0 THEN value END, value, value FROM nums WHERE value<=20; SELECT count(a), count(b) FROM t1; + PRAGMA integrity_check; } -} {14 20} +} {14 20 ok} +# Error conditions during parsing... +# do_test index6-1.2 { catchsql { CREATE INDEX bad1 ON t1(a,b) WHERE x IS NOT NULL; @@ -64,6 +68,9 @@ do_test index6-1.10 { } } {{} 20 t1a {14 1} t1b {10 1} ok} +# STAT1 shows the partial indices have a reduced number of +# rows. +# do_test index6-1.11 { execsql { UPDATE t1 SET a=b; @@ -120,4 +127,89 @@ do_test index6-1.15 { } } {t1a {10 1} t1b {8 1} t1c {15 1} ok} +# Queries use partial indices as appropriate times. +# +do_test index6-2.1 { + execsql { + CREATE TABLE t2(a,b); + INSERT INTO t2(a,b) SELECT value, value FROM nums WHERE value<1000; + UPDATE t2 SET a=NULL WHERE b%5==0; + CREATE INDEX t2a1 ON t2(a) WHERE a IS NOT NULL; + SELECT count(*) FROM t2 WHERE a IS NOT NULL; + } +} {800} +do_test index6-2.2 { + execsql { + EXPLAIN QUERY PLAN + SELECT * FROM t2 WHERE a=5; + } +} {/.* TABLE t2 USING INDEX t2a1 .*/} +do_test index6-2.3 { + execsql { + EXPLAIN QUERY PLAN + SELECT * FROM t2 WHERE a IS NOT NULL; + } +} {/.* TABLE t2 USING INDEX t2a1 .*/} +do_test index6-2.4 { + execsql { + EXPLAIN QUERY PLAN + SELECT * FROM t2 WHERE a IS NULL; + } +} {~/.*INDEX t2a1.*/} + +do_execsql_test index6-2.101 { + DROP INDEX t2a1; + UPDATE t2 SET a=b, b=b+10000; + SELECT b FROM t2 WHERE a=15; +} {10015} +do_execsql_test index6-2.102 { + CREATE INDEX t2a2 ON t2(a) WHERE a<100 OR a>200; + SELECT b FROM t2 WHERE a=15; + PRAGMA integrity_check; +} {10015 ok} +do_execsql_test index6-2.102eqp { + EXPLAIN QUERY PLAN + SELECT b FROM t2 WHERE a=15; +} {~/.*INDEX t2a2.*/} +do_execsql_test index6-2.103 { + SELECT b FROM t2 WHERE a=15 AND a<100; +} {10015} +do_execsql_test index6-2.103eqp { + EXPLAIN QUERY PLAN + SELECT b FROM t2 WHERE a=15 AND a<100; +} {/.*INDEX t2a2.*/} +do_execsql_test index6-2.104 { + SELECT b FROM t2 WHERE a=515 AND a>200; +} {10515} +do_execsql_test index6-2.104eqp { + EXPLAIN QUERY PLAN + SELECT b FROM t2 WHERE a=515 AND a>200; +} {/.*INDEX t2a2.*/} + +# Partial UNIQUE indices +# +do_execsql_test index6-3.1 { + CREATE TABLE t3(a,b); + INSERT INTO t3 SELECT value, value FROM nums WHERE value<200; + UPDATE t3 SET a=999 WHERE b%5!=0; + CREATE UNIQUE INDEX t3a ON t3(a) WHERE a<>999; +} {} +do_test index6-3.2 { + # unable to insert a duplicate row a-value that is not 999. + catchsql { + INSERT INTO t3(a,b) VALUES(150, 'test1'); + } +} {1 {column a is not unique}} +do_test index6-3.3 { + # can insert multiple rows with a==999 because such rows are not + # part of the unique index. + catchsql { + INSERT INTO t3(a,b) VALUES(999, 'test1'), (999, 'test2'); + } +} {0 {}} +do_execsql_test index6-3.4 { + SELECT count(*) FROM t3 WHERE a=999; +} {162} +integrity_check index6-3.5 + finish_test From 3bf0ac17095ac5e8a34b5918c7c675f3ce77e717 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 1 Aug 2013 16:02:40 +0000 Subject: [PATCH 37/47] Fix bug in the logic that determines the end of a CREATE INDEX statement. Added a VACUUM test case that exposed the bug. FossilOrigin-Name: 2e3df0bc900c01286d3ce32c2bbf9e5293973f9b --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/build.c | 2 +- test/index6.test | 5 +++++ 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 9ab30e629b..afa35d6829 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\stest\scases\sand\scorresponding\sbug\sfixes. -D 2013-08-01T15:09:57.772 +C Fix\sbug\sin\sthe\slogic\sthat\sdetermines\sthe\send\sof\sa\sCREATE\sINDEX\sstatement.\nAdded\sa\sVACUUM\stest\scase\sthat\sexposed\sthe\sbug. +D 2013-08-01T16:02:40.113 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 3f7bbfd72efb1cbf6a49515c376a031767ec930a F src/btree.h 6fa8a3ff2483d0bb64a9f0105a8cedeac9e00cca F src/btreeInt.h eecc84f02375b2bb7a44abbcbbe3747dde73edb2 -F src/build.c 4be8975927a7871223311060cf13f5eec28ba3be +F src/build.c 7fe3c81e502f899e280446cd053a38dbe15d12a0 F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 4262c227bc91cecc61ae37ed3a40f08069cfa267 @@ -589,7 +589,7 @@ F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6 F test/index3.test 423a25c789fc8cc51aaf2a4370bbdde2d9e9eed7 F test/index4.test 2983216eb8c86ee62d9ed7cb206b5cc3331c0026 F test/index5.test fc07c14193c0430814e7a08b5da46888ee795c33 -F test/index6.test 203633042a116d98932f3c750c5d2bb60de7bd56 +F test/index6.test 3967161678dd5268e6ad1e263cc82e2b8050d055 F test/indexedby.test 0e959308707c808515c3a51363f7a9835027108c F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 @@ -1104,7 +1104,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 8e07aa2ad5579aeb82174ce5bd432ddb9c058bc1 -R b61a938ce818e9ac097fb2a064b3215f +P 0c8cfdfae215c95cf167f404a1d346690b28e972 +R 7829f40a29ab8d32821ed080da801961 U drh -Z 381062f7cdfdb23ad88f9994e93f96ef +Z d181891086829543aa75dfb2ba9cf461 diff --git a/manifest.uuid b/manifest.uuid index 9b8e98a9fd..e50da3aad1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0c8cfdfae215c95cf167f404a1d346690b28e972 \ No newline at end of file +2e3df0bc900c01286d3ce32c2bbf9e5293973f9b \ No newline at end of file diff --git a/src/build.c b/src/build.c index cc758b2741..26e5fe9f77 100644 --- a/src/build.c +++ b/src/build.c @@ -2861,7 +2861,7 @@ Index *sqlite3CreateIndex( ** the zStmt variable */ if( pStart ){ - int n = (pParse->sLastToken.z - pName->z) + 1; + int n = (pParse->sLastToken.z - pName->z) + pParse->sLastToken.n; if( pName->z[n-1]==';' ) n--; /* A named index with an explicit CREATE INDEX statement */ zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s", diff --git a/test/index6.test b/test/index6.test index 0b6a9365dc..ddd200c402 100644 --- a/test/index6.test +++ b/test/index6.test @@ -212,4 +212,9 @@ do_execsql_test index6-3.4 { } {162} integrity_check index6-3.5 +do_execsql_test index6-4.0 { + VACUUM; + PRAGMA integrity_check; +} {ok} + finish_test From 788482c745e00fb416f518326b62c63420c6731c Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 1 Aug 2013 16:52:50 +0000 Subject: [PATCH 38/47] Avoid using left-most column STAT3 samples if the left-most column has an equality constrain and there are inequality constraints on the second column. FossilOrigin-Name: 31b4e63b3c30fcad22340d84d6076a306f26b49e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index a763743c17..02972f03fa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Limit\sthe\snumber\sof\smemset()\scalls\sused\swhen\sdetermining\sa\stemporary\sfile\sname\son\sWindows.\s\sAlso,\sfix\sa\sharmless\scompiler\swarning. -D 2013-07-31T23:28:36.603 +C Avoid\susing\sleft-most\scolumn\sSTAT3\ssamples\sif\sthe\sleft-most\scolumn\shas\san\nequality\sconstrain\sand\sthere\sare\sinequality\sconstraints\son\sthe\ssecond\scolumn. +D 2013-08-01T16:52:50.320 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -290,7 +290,7 @@ F src/vtab.c 2e8b489db47e20ae36cd247932dc671c9ded0624 F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73 -F src/where.c a55e27475c3d4c72c8bf1aaf9ece70e47e8731cf +F src/where.c fe1d056ffa4638fcdc22b4da1315b0ad98c3e872 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 33ba1f4c5dc2ef8292adf17a32ade0cde0887d88 -R 22ac6c086833ea6790806cfd601e6a5b -U mistachkin -Z 4d19b2638b72ab835325f17f2f967fc6 +P 136fc2931b156f91cdd76a7a009298cdf09d826a +R 548b934e9d909f49470ebc18af6d5c19 +U drh +Z e690d571856325e865e41cb4d68cbd8b diff --git a/manifest.uuid b/manifest.uuid index 491b5fb557..f30aafd4cd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -136fc2931b156f91cdd76a7a009298cdf09d826a \ No newline at end of file +31b4e63b3c30fcad22340d84d6076a306f26b49e \ No newline at end of file diff --git a/src/where.c b/src/where.c index 9f65d551a3..8a265a9288 100644 --- a/src/where.c +++ b/src/where.c @@ -4420,7 +4420,7 @@ static int whereLoopAddBtreeIndex( pNew->nOut = saved_nOut>rDiv+10 ? saved_nOut - rDiv : 10; } #ifdef SQLITE_ENABLE_STAT3 - if( pNew->u.btree.nEq==1 && pProbe->nSample + if( pNew->u.btree.nEq==1 && pProbe->nSample && saved_nEq==0 && OptimizationEnabled(db, SQLITE_Stat3) ){ tRowcnt nOut = 0; if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))!=0 ){ From 828463375caa93bf88c5114303ca80b4e6bf2bdc Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 1 Aug 2013 17:21:26 +0000 Subject: [PATCH 39/47] An improved method for avoiding the use of the STAT3 samples to compute the estimated number of outputs when the left-most index is equality constrained. This check-in undoes the previous fix and applies a new one. FossilOrigin-Name: 127a5b776d16e1e23c5b3d454f6aaea67f1ded3a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 02972f03fa..199045ac76 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\susing\sleft-most\scolumn\sSTAT3\ssamples\sif\sthe\sleft-most\scolumn\shas\san\nequality\sconstrain\sand\sthere\sare\sinequality\sconstraints\son\sthe\ssecond\scolumn. -D 2013-08-01T16:52:50.320 +C An\simproved\smethod\sfor\savoiding\sthe\suse\sof\sthe\sSTAT3\ssamples\sto\scompute\nthe\sestimated\snumber\sof\soutputs\swhen\sthe\sleft-most\sindex\sis\sequality\nconstrained.\s\sThis\scheck-in\sundoes\sthe\sprevious\sfix\sand\sapplies\sa\snew\sone. +D 2013-08-01T17:21:26.855 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -290,7 +290,7 @@ F src/vtab.c 2e8b489db47e20ae36cd247932dc671c9ded0624 F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73 -F src/where.c fe1d056ffa4638fcdc22b4da1315b0ad98c3e872 +F src/where.c 38264830c393b0838c18b1f3dfc6c01471d1f70a F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 136fc2931b156f91cdd76a7a009298cdf09d826a -R 548b934e9d909f49470ebc18af6d5c19 +P 31b4e63b3c30fcad22340d84d6076a306f26b49e +R 492afb1fab0455fbbeddb05926432910 U drh -Z e690d571856325e865e41cb4d68cbd8b +Z f007f69644258ace0d976c8e46bfead9 diff --git a/manifest.uuid b/manifest.uuid index f30aafd4cd..3ccbe102ca 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -31b4e63b3c30fcad22340d84d6076a306f26b49e \ No newline at end of file +127a5b776d16e1e23c5b3d454f6aaea67f1ded3a \ No newline at end of file diff --git a/src/where.c b/src/where.c index 8a265a9288..ebdbfcf9fe 100644 --- a/src/where.c +++ b/src/where.c @@ -4420,7 +4420,7 @@ static int whereLoopAddBtreeIndex( pNew->nOut = saved_nOut>rDiv+10 ? saved_nOut - rDiv : 10; } #ifdef SQLITE_ENABLE_STAT3 - if( pNew->u.btree.nEq==1 && pProbe->nSample && saved_nEq==0 + if( pNew->u.btree.nEq==1 && pProbe->nSample && OptimizationEnabled(db, SQLITE_Stat3) ){ tRowcnt nOut = 0; if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))!=0 ){ @@ -4431,7 +4431,8 @@ static int whereLoopAddBtreeIndex( && !ExprHasProperty(pTerm->pExpr, EP_xIsSelect) ){ rc = whereInScanEst(pParse, pProbe, pTerm->pExpr->x.pList, &nOut); } - if( rc==SQLITE_OK ) pNew->nOut = whereCost(nOut); + assert( nOut==0 || rc==SQLITE_OK ); + if( nOut ) pNew->nOut = whereCost(nOut); } #endif if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){ From 2acbc0dd78c34f0c62aeb2b2bb36dfe7c1cf7962 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 1 Aug 2013 17:43:35 +0000 Subject: [PATCH 40/47] Add test case for the problem fixed by [127a5b776d]. FossilOrigin-Name: 65816718b59b286c11d939235a23c7325f25594b --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/analyze3.test | 27 +++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 199045ac76..b1ac07e658 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C An\simproved\smethod\sfor\savoiding\sthe\suse\sof\sthe\sSTAT3\ssamples\sto\scompute\nthe\sestimated\snumber\sof\soutputs\swhen\sthe\sleft-most\sindex\sis\sequality\nconstrained.\s\sThis\scheck-in\sundoes\sthe\sprevious\sfix\sand\sapplies\sa\snew\sone. -D 2013-08-01T17:21:26.855 +C Add\stest\scase\sfor\sthe\sproblem\sfixed\sby\s[127a5b776d]. +D 2013-08-01T17:43:35.105 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -302,7 +302,7 @@ F test/alter3.test 49c9d9fba2b8fcdce2dedeca97bbf1f369cc548d F test/alter4.test b2debc14d8cbe4c1d12ccd6a41eef88a8c1f15d5 F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc F test/analyze.test f8ab7d15858b4093b06caf5e57e2a5ff7104bdae -F test/analyze3.test 69863b446539f8849a996c2aa0b50461c9cecea4 +F test/analyze3.test 53cfd07625d110e70b92b57a6ff656ea844dfbee F test/analyze4.test eff2df19b8dd84529966420f29ea52edc6b56213 F test/analyze5.test 3e57f192307be931f9ab2f6ff456f9063358ac77 F test/analyze6.test cdbf9887d40ab41301f570fe85c6e1525dd3b1c9 @@ -1103,7 +1103,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 31b4e63b3c30fcad22340d84d6076a306f26b49e -R 492afb1fab0455fbbeddb05926432910 -U drh -Z f007f69644258ace0d976c8e46bfead9 +P 127a5b776d16e1e23c5b3d454f6aaea67f1ded3a +R 55095a68bf1e6bed6cc6b3606b16b8da +U dan +Z 4a8fdbd96b68de3d602c8482b890b1d9 diff --git a/manifest.uuid b/manifest.uuid index 3ccbe102ca..43b445a140 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -127a5b776d16e1e23c5b3d454f6aaea67f1ded3a \ No newline at end of file +65816718b59b286c11d939235a23c7325f25594b \ No newline at end of file diff --git a/test/analyze3.test b/test/analyze3.test index c25d04422e..1e95d591b7 100644 --- a/test/analyze3.test +++ b/test/analyze3.test @@ -43,6 +43,8 @@ ifcapable !stat3 { # analyze3-5.*: Check that the query plans of applicable statements are # invalidated if the values of SQL parameter are modified # using the clear_bindings() or transfer_bindings() APIs. +# +# analyze3-6.*: Test that the problem fixed by commit [127a5b776d] is fixed. # proc getvar {varname} { uplevel #0 set $varname } @@ -612,4 +614,29 @@ do_test analyze3-5.1.3 { sqlite3_finalize $S1 } {SQLITE_OK} +#------------------------------------------------------------------------- + +do_test analyze3-6.1 { + execsql { DROP TABLE IF EXISTS t1 } + execsql BEGIN + execsql { CREATE TABLE t1(a, b, c) } + for {set i 0} {$i < 1000} {incr i} { + execsql "INSERT INTO t1 VALUES([expr $i/100], 'x', [expr $i/10])" + } + execsql { + CREATE INDEX i1 ON t1(a, b); + CREATE INDEX i2 ON t1(c); + } + execsql COMMIT + execsql ANALYZE +} {} + +do_eqp_test analyze3-6-3 { + SELECT * FROM t1 WHERE a = 5 AND c = 13; +} {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (c=?)}} + +do_eqp_test analyze3-6-2 { + SELECT * FROM t1 WHERE a = 5 AND b > 'w' AND c = 13; +} {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (c=?)}} + finish_test From df003d61cec51dfef29c58a13d9bd6927f698b32 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 1 Aug 2013 19:17:39 +0000 Subject: [PATCH 41/47] Make sure signed integer overflow does not cause a segfault while attempting to read a corrupt database where the header size varint on a record is larger than the maximum 32-bit signed integer. FossilOrigin-Name: c3baca99f4580652afb2c3f73036ab83796a1557 --- manifest | 15 +++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 4 ++-- test/corruptG.test | 56 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 10 deletions(-) create mode 100644 test/corruptG.test diff --git a/manifest b/manifest index b1ac07e658..304c8f59e1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\scase\sfor\sthe\sproblem\sfixed\sby\s[127a5b776d]. -D 2013-08-01T17:43:35.105 +C Make\ssure\ssigned\sinteger\soverflow\sdoes\snot\scause\sa\ssegfault\swhile\sattempting\nto\sread\sa\scorrupt\sdatabase\swhere\sthe\sheader\ssize\svarint\son\sa\srecord\sis\slarger\nthan\sthe\smaximum\s32-bit\ssigned\sinteger. +D 2013-08-01T19:17:39.891 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -281,7 +281,7 @@ F src/vdbe.c d6048a720c197db2f0e7d618e918bd2e2eff0322 F src/vdbe.h f380af2a7fab32ba8a8b05bf042497636afec66d F src/vdbeInt.h e9b7c6b165a31a4715c5aa97223d20d265515231 F src/vdbeapi.c 4d13580bd058b39623e8fcfc233b7df4b8191e8b -F src/vdbeaux.c c01594ecf5a78ef41a721f3465152bb91883a942 +F src/vdbeaux.c ca0c9d4b5104a3b4e4cf3c557d661938f15e68ac F src/vdbeblob.c 5dc79627775bd9a9b494dd956e26297946417d69 F src/vdbemem.c 833005f1cbbf447289f1973dba2a0c2228c7b8ab F src/vdbesort.c 3937e06b2a0e354500e17dc206ef4c35770a5017 @@ -395,6 +395,7 @@ F test/corruptC.test 62a767fe64acb1975f58cc6171192839c783edbb F test/corruptD.test 3b09903a2e2fe07ecafe775fea94177f8a4bb34f F test/corruptE.test d3a3d7e864a95978195741744dda4abfd8286018 F test/corruptF.test 1c7b6f77cf3f237fb7fbb5b61d6c921fd4c7b993 +F test/corruptG.test 01d94538a0666808dae1b4010f24c25becee13af F test/count.test 454e1ce985c94d13efeac405ce54439f49336163 F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62 F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f @@ -1103,7 +1104,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 127a5b776d16e1e23c5b3d454f6aaea67f1ded3a -R 55095a68bf1e6bed6cc6b3606b16b8da -U dan -Z 4a8fdbd96b68de3d602c8482b890b1d9 +P 65816718b59b286c11d939235a23c7325f25594b +R 40beea5b8511a37f010f0f7e67aa8773 +U drh +Z a89405d573d1d6b7d75b24ed5c21bc2d diff --git a/manifest.uuid b/manifest.uuid index 43b445a140..f815192c25 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -65816718b59b286c11d939235a23c7325f25594b \ No newline at end of file +c3baca99f4580652afb2c3f73036ab83796a1557 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index f54685cb71..0bc5b44261 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2990,7 +2990,7 @@ int sqlite3VdbeRecordCompare( int nKey1, const void *pKey1, /* Left key */ UnpackedRecord *pPKey2 /* Right key */ ){ - int d1; /* Offset into aKey[] of next data element */ + u32 d1; /* Offset into aKey[] of next data element */ u32 idx1; /* Offset into aKey[] of next header element */ u32 szHdr1; /* Number of bytes in header */ int i = 0; @@ -3024,7 +3024,7 @@ int sqlite3VdbeRecordCompare( /* Read the serial types for the next element in each key. */ idx1 += getVarint32( aKey1+idx1, serial_type1 ); - if( d1>=nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break; + if( d1>=(u32)nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break; /* Extract the values to be compared. */ diff --git a/test/corruptG.test b/test/corruptG.test new file mode 100644 index 0000000000..7b95321453 --- /dev/null +++ b/test/corruptG.test @@ -0,0 +1,56 @@ +# 2013-08-01 +# +# 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. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix corruptG + +# Do not use a codec for tests in this file, as the database file is +# manipulated directly using tcl scripts (using the [hexio_write] command). +# +do_not_use_codec + +# Create a simple database with a single entry. Then corrupt the +# header-size varint on the index payload so that it maps into a +# negative number. Try to use the database. +# + +do_execsql_test 1.1 { + PRAGMA page_size=512; + CREATE TABLE t1(a,b,c); + INSERT INTO t1(rowid,a,b,c) VALUES(2,'abc','xyz','123'); + CREATE INDEX t1abc ON t1(a,b,c); +} + +# Corrupt the file +db close +hexio_write test.db [expr {3*512 - 15}] 888080807f +sqlite3 db test.db + +# Try to use the file. +do_test 1.2 { + catchsql { + SELECT c FROM t1 WHERE a>'abc'; + } +} {0 {}} +do_test 1.3 { + catchsql { + PRAGMA integrity_check + } +} {0 ok} +do_test 1.4 { + catchsql { + SELECT c FROM t1 ORDER BY a; + } +} {1 {database disk image is malformed}} + +finish_test From f5601cac4d1526ebbe7ffcff999c8573d53a549f Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 1 Aug 2013 20:26:04 +0000 Subject: [PATCH 42/47] Fix a potential buffer overread in sqlite3VdbeRecordCompare() when a serial_type specifies a field that starts in bounds but is much too large for the allocated buffer. Mostly harmless. The overread is unlikely to go more than one or two bytes past the end of the buffer. FossilOrigin-Name: e436b2f4e5c5e6b2f70e65332c0c7d618e2ef20a --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbeaux.c | 2 +- test/corruptG.test | 16 +++++++++++++++- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 304c8f59e1..d16a98516a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\ssigned\sinteger\soverflow\sdoes\snot\scause\sa\ssegfault\swhile\sattempting\nto\sread\sa\scorrupt\sdatabase\swhere\sthe\sheader\ssize\svarint\son\sa\srecord\sis\slarger\nthan\sthe\smaximum\s32-bit\ssigned\sinteger. -D 2013-08-01T19:17:39.891 +C Fix\sa\spotential\sbuffer\soverread\sin\ssqlite3VdbeRecordCompare()\swhen\sa\nserial_type\sspecifies\sa\sfield\sthat\sstarts\sin\sbounds\sbut\sis\smuch\stoo\slarge\nfor\sthe\sallocated\sbuffer.\s\sMostly\sharmless.\s\sThe\soverread\sis\sunlikely\sto\ngo\smore\sthan\sone\sor\stwo\sbytes\spast\sthe\send\sof\sthe\sbuffer. +D 2013-08-01T20:26:04.768 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -281,7 +281,7 @@ F src/vdbe.c d6048a720c197db2f0e7d618e918bd2e2eff0322 F src/vdbe.h f380af2a7fab32ba8a8b05bf042497636afec66d F src/vdbeInt.h e9b7c6b165a31a4715c5aa97223d20d265515231 F src/vdbeapi.c 4d13580bd058b39623e8fcfc233b7df4b8191e8b -F src/vdbeaux.c ca0c9d4b5104a3b4e4cf3c557d661938f15e68ac +F src/vdbeaux.c 902bc99e72ab3cc5ad38cd344fb0757249839c36 F src/vdbeblob.c 5dc79627775bd9a9b494dd956e26297946417d69 F src/vdbemem.c 833005f1cbbf447289f1973dba2a0c2228c7b8ab F src/vdbesort.c 3937e06b2a0e354500e17dc206ef4c35770a5017 @@ -395,7 +395,7 @@ F test/corruptC.test 62a767fe64acb1975f58cc6171192839c783edbb F test/corruptD.test 3b09903a2e2fe07ecafe775fea94177f8a4bb34f F test/corruptE.test d3a3d7e864a95978195741744dda4abfd8286018 F test/corruptF.test 1c7b6f77cf3f237fb7fbb5b61d6c921fd4c7b993 -F test/corruptG.test 01d94538a0666808dae1b4010f24c25becee13af +F test/corruptG.test 3804cb1b1b66ca82dc809dc80e3957dc7e0111e8 F test/count.test 454e1ce985c94d13efeac405ce54439f49336163 F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62 F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f @@ -1104,7 +1104,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 65816718b59b286c11d939235a23c7325f25594b -R 40beea5b8511a37f010f0f7e67aa8773 +P c3baca99f4580652afb2c3f73036ab83796a1557 +R fcb797895b127e11a00659cd0bcac3ee U drh -Z a89405d573d1d6b7d75b24ed5c21bc2d +Z f701ece092c0412f4414d12aeebc6620 diff --git a/manifest.uuid b/manifest.uuid index f815192c25..08fb1854e2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c3baca99f4580652afb2c3f73036ab83796a1557 \ No newline at end of file +e436b2f4e5c5e6b2f70e65332c0c7d618e2ef20a \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 0bc5b44261..5469ce81e8 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3024,7 +3024,7 @@ int sqlite3VdbeRecordCompare( /* Read the serial types for the next element in each key. */ idx1 += getVarint32( aKey1+idx1, serial_type1 ); - if( d1>=(u32)nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break; + if( d1+sqlite3VdbeSerialTypeLen(serial_type1)>(u32)nKey1 ) break; /* Extract the values to be compared. */ diff --git a/test/corruptG.test b/test/corruptG.test index 7b95321453..da36cfac4b 100644 --- a/test/corruptG.test +++ b/test/corruptG.test @@ -27,7 +27,7 @@ do_not_use_codec do_execsql_test 1.1 { PRAGMA page_size=512; CREATE TABLE t1(a,b,c); - INSERT INTO t1(rowid,a,b,c) VALUES(2,'abc','xyz','123'); + INSERT INTO t1(rowid,a,b,c) VALUES(52,'abc','xyz','123'); CREATE INDEX t1abc ON t1(a,b,c); } @@ -53,4 +53,18 @@ do_test 1.4 { } } {1 {database disk image is malformed}} +# Corrupt the same file in a slightly different way. Make the record header +# sane, but corrupt one of the serial_type value to indicate a huge payload +# such that the payload begins in allocated space but overflows the buffer. +# +db close +hexio_write test.db [expr {3*512-15}] 0611ffff7f01 +sqlite3 db test.db + +do_test 2.1 { + catchsql { + SELECT rowid FROM t1 WHERE a='bc' and b='xyz123456789'; + } +} {0 {}} + finish_test From af4300636af8a0f6addab5f314d81299307e4d58 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 1 Aug 2013 22:26:56 +0000 Subject: [PATCH 43/47] Fix an incorrect expected result in a test case in corruptG.test. FossilOrigin-Name: 6913831ad2892fdc8331ee53426d935386eacb9e --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/corruptG.test | 11 ++++++++--- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index d16a98516a..ae5cb3c0ff 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\spotential\sbuffer\soverread\sin\ssqlite3VdbeRecordCompare()\swhen\sa\nserial_type\sspecifies\sa\sfield\sthat\sstarts\sin\sbounds\sbut\sis\smuch\stoo\slarge\nfor\sthe\sallocated\sbuffer.\s\sMostly\sharmless.\s\sThe\soverread\sis\sunlikely\sto\ngo\smore\sthan\sone\sor\stwo\sbytes\spast\sthe\send\sof\sthe\sbuffer. -D 2013-08-01T20:26:04.768 +C Fix\san\sincorrect\sexpected\sresult\sin\sa\stest\scase\sin\scorruptG.test. +D 2013-08-01T22:26:56.329 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -395,7 +395,7 @@ F test/corruptC.test 62a767fe64acb1975f58cc6171192839c783edbb F test/corruptD.test 3b09903a2e2fe07ecafe775fea94177f8a4bb34f F test/corruptE.test d3a3d7e864a95978195741744dda4abfd8286018 F test/corruptF.test 1c7b6f77cf3f237fb7fbb5b61d6c921fd4c7b993 -F test/corruptG.test 3804cb1b1b66ca82dc809dc80e3957dc7e0111e8 +F test/corruptG.test d18ee5169e10a76bccb7b115e551bc31087a525e F test/count.test 454e1ce985c94d13efeac405ce54439f49336163 F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62 F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f @@ -1104,7 +1104,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P c3baca99f4580652afb2c3f73036ab83796a1557 -R fcb797895b127e11a00659cd0bcac3ee +P e436b2f4e5c5e6b2f70e65332c0c7d618e2ef20a +R b6c71bf72fc88457d8239caf7a219b2b U drh -Z f701ece092c0412f4414d12aeebc6620 +Z d61b007331cedb7cbca3d1493ff2bd3f diff --git a/manifest.uuid b/manifest.uuid index 08fb1854e2..6fa83bc160 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e436b2f4e5c5e6b2f70e65332c0c7d618e2ef20a \ No newline at end of file +6913831ad2892fdc8331ee53426d935386eacb9e \ No newline at end of file diff --git a/test/corruptG.test b/test/corruptG.test index da36cfac4b..bf62efea21 100644 --- a/test/corruptG.test +++ b/test/corruptG.test @@ -58,13 +58,18 @@ do_test 1.4 { # such that the payload begins in allocated space but overflows the buffer. # db close -hexio_write test.db [expr {3*512-15}] 0611ffff7f01 +hexio_write test.db [expr {3*512-15}] 0513ff7f01 sqlite3 db test.db do_test 2.1 { catchsql { - SELECT rowid FROM t1 WHERE a='bc' and b='xyz123456789'; + SELECT rowid FROM t1 WHERE a='abc' and b='xyz123456789XYZ'; } -} {0 {}} + # 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 52} finish_test From 989b116a03166f6aa319fb446206f4d6c5c9a02c Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 1 Aug 2013 22:27:26 +0000 Subject: [PATCH 44/47] Fix the CREATE INDEX statement so that trying to create a TEMP index on a non-TEMP table throws an error rather than segfaulting. FossilOrigin-Name: e3c8935f8736d00dc83644fa21d86ca7fec6d2fc --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/build.c | 7 ++++++- test/index.test | 17 +++++++++++++++++ 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index ae5cb3c0ff..132ab9721b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sincorrect\sexpected\sresult\sin\sa\stest\scase\sin\scorruptG.test. -D 2013-08-01T22:26:56.329 +C Fix\sthe\sCREATE\sINDEX\sstatement\sso\sthat\strying\sto\screate\sa\sTEMP\sindex\son\na\snon-TEMP\stable\sthrows\san\serror\srather\sthan\ssegfaulting. +D 2013-08-01T22:27:26.044 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 3f7bbfd72efb1cbf6a49515c376a031767ec930a F src/btree.h 6fa8a3ff2483d0bb64a9f0105a8cedeac9e00cca F src/btreeInt.h eecc84f02375b2bb7a44abbcbbe3747dde73edb2 -F src/build.c 42239cfd95533e4aacf4d58b4724c8f858de5ced +F src/build.c 1a6db7f48ad5fd050a43ed4dcc653c9be0882c48 F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 4262c227bc91cecc61ae37ed3a40f08069cfa267 @@ -585,7 +585,7 @@ F test/incrvacuum.test d2a6ddf5e429720b5fe502766af747915ccf6c32 F test/incrvacuum2.test 379eeb8740b0ef60c372c439ad4cbea20b34bb9b F test/incrvacuum3.test 75256fb1377e7c39ef2de62bfc42bbff67be295a F test/incrvacuum_ioerr.test 6ae2f783424e47a0033304808fe27789cf93e635 -F test/index.test b5429732b3b983fa810e3ac867d7ca85dae35097 +F test/index.test f2abacfb83d384ae36b8a919fbd94b1319333e55 F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6 F test/index3.test 423a25c789fc8cc51aaf2a4370bbdde2d9e9eed7 F test/index4.test 2983216eb8c86ee62d9ed7cb206b5cc3331c0026 @@ -1104,7 +1104,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P e436b2f4e5c5e6b2f70e65332c0c7d618e2ef20a -R b6c71bf72fc88457d8239caf7a219b2b +P 6913831ad2892fdc8331ee53426d935386eacb9e +R c4336b3c1d9855c02f7d72f3a4291b06 U drh -Z d61b007331cedb7cbca3d1493ff2bd3f +Z 038dfb0c43b0a82e8c8dc532f3798b80 diff --git a/manifest.uuid b/manifest.uuid index 6fa83bc160..9f976a5036 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6913831ad2892fdc8331ee53426d935386eacb9e \ No newline at end of file +e3c8935f8736d00dc83644fa21d86ca7fec6d2fc \ No newline at end of file diff --git a/src/build.c b/src/build.c index 0a3922c952..842a3078b8 100644 --- a/src/build.c +++ b/src/build.c @@ -2550,7 +2550,12 @@ Index *sqlite3CreateIndex( pTab = sqlite3LocateTableItem(pParse, 0, &pTblName->a[0]); assert( db->mallocFailed==0 || pTab==0 ); if( pTab==0 ) goto exit_create_index; - assert( db->aDb[iDb].pSchema==pTab->pSchema ); + if( iDb==1 && db->aDb[iDb].pSchema!=pTab->pSchema ){ + sqlite3ErrorMsg(pParse, + "cannot create a TEMP index on non-TEMP table \"%s\"", + pTab->zName); + goto exit_create_index; + } }else{ assert( pName==0 ); assert( pStart==0 ); diff --git a/test/index.test b/test/index.test index 790bed908e..2b95bad830 100644 --- a/test/index.test +++ b/test/index.test @@ -715,6 +715,23 @@ do_test index-20.2 { DROP INDEX "t6i1"; } } {} + +# Try to create a TEMP index on a non-TEMP table. */ +# +do_test index-21.1 { + catchsql { + CREATE INDEX temp.i21 ON t6(c); + } +} {1 {cannot create a TEMP index on non-TEMP table "t6"}} +do_test index-21.2 { + catchsql { + CREATE TEMP TABLE t6(x); + INSERT INTO temp.t6 values(1),(5),(9); + CREATE INDEX temp.i21 ON t6(x); + SELECT x FROM t6 ORDER BY x DESC; + } +} {0 {9 5 1}} + finish_test From 0b22101b2f00e8b1fb784b3779bf1339d7310991 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 2 Aug 2013 13:31:31 +0000 Subject: [PATCH 45/47] Fix typos in documentation for SQLITE_DBSTATUS_DEFERRED_FKS . No changes to code. FossilOrigin-Name: f3efbfcd515ad6ac833f4b26391dcc44603a96e8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 132ab9721b..75441cbff7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sCREATE\sINDEX\sstatement\sso\sthat\strying\sto\screate\sa\sTEMP\sindex\son\na\snon-TEMP\stable\sthrows\san\serror\srather\sthan\ssegfaulting. -D 2013-08-01T22:27:26.044 +C Fix\stypos\sin\sdocumentation\sfor\sSQLITE_DBSTATUS_DEFERRED_FKS\s.\s\s\nNo\schanges\sto\scode. +D 2013-08-02T13:31:31.821 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -218,7 +218,7 @@ F src/resolve.c 89f9003e8316ee3a172795459efc2a0274e1d5a8 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 91b62654caf8dfe292fb8882715e575d34ad3874 F src/shell.c 52f975eae87c8338c4dfbf4c2842d2a0971f01fd -F src/sqlite.h.in bf3ee0bd13583cc6d09f9649bf26a183b0cc10a6 +F src/sqlite.h.in 442c109e0c3447c34b1794971ecdb673ce08a843 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqliteInt.h 89b52c053ebafa76f03bab4f0c8ee1e390eb7489 @@ -1104,7 +1104,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 6913831ad2892fdc8331ee53426d935386eacb9e -R c4336b3c1d9855c02f7d72f3a4291b06 +P e3c8935f8736d00dc83644fa21d86ca7fec6d2fc +R 0f6aefa6399d232f137b72b60707de79 U drh -Z 038dfb0c43b0a82e8c8dc532f3798b80 +Z f14c6a4259ab5d638ccb7f2022024235 diff --git a/manifest.uuid b/manifest.uuid index 9f976a5036..bdff20e8c9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e3c8935f8736d00dc83644fa21d86ca7fec6d2fc \ No newline at end of file +f3efbfcd515ad6ac833f4b26391dcc44603a96e8 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index fa33a0a40c..90e78d9acc 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -6264,9 +6264,9 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); ** ** ** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(
SQLITE_DBSTATUS_DEFERRED_FKS
-**
This parameter returns the zero for the current value if and only if -** there all foreign key constraints (deferred or immediate) have been -** resolved. The highwater mark is always 0. +**
This parameter returns zero for the current value if and only if +** all foreign key constraints (deferred or immediate) have been +** resolved.)^ ^The highwater mark is always 0. **
** */ From 1e7d43c97718ba62d2afe9caeac65bbfa6b056e5 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 2 Aug 2013 14:18:18 +0000 Subject: [PATCH 46/47] Silently ignore database name qualifiers in CHECK constraints and in partial index WHERE clauses. FossilOrigin-Name: 2e8c845eb5011a2743dace333aa38383588f2080 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/resolve.c | 19 ++++++++++++++----- test/check.test | 6 ++++++ test/index6.test | 10 ++++++++++ 5 files changed, 39 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index afa35d6829..ba20bcdf09 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sbug\sin\sthe\slogic\sthat\sdetermines\sthe\send\sof\sa\sCREATE\sINDEX\sstatement.\nAdded\sa\sVACUUM\stest\scase\sthat\sexposed\sthe\sbug. -D 2013-08-01T16:02:40.113 +C Silently\signore\sdatabase\sname\squalifiers\sin\sCHECK\sconstraints\sand\sin\npartial\sindex\sWHERE\sclauses. +D 2013-08-02T14:18:18.252 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -214,7 +214,7 @@ F src/pragma.c 590c75750d93ec5a1f903e4bb0dc6d2a0845bf8b F src/prepare.c fa6988589f39af8504a61731614cd4f6ae71554f F src/printf.c 41c49dac366a3a411190001a8ab495fa8887974e F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 -F src/resolve.c 8b3c7a439cc6ba242e45566284adb72fa770b7c8 +F src/resolve.c 17e670996729ac41aadf6a31f57b4e6f29b3d819 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 20369c82dc38eb4a77b458c8f6e353ef550580c9 F src/shell.c 52f975eae87c8338c4dfbf4c2842d2a0971f01fd @@ -362,7 +362,7 @@ F test/capi3c.test 93d24621c9ff84da9da060f30431e0453db1cdb0 F test/capi3d.test 6d0fc0a86d73f42dd19a7d8b7761ab9bc02277d0 F test/capi3e.test ad90088b18b0367125ff2d4b5400153fd2f99aab F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 -F test/check.test 2eb93611139a7dfaed3be80067c7dc5ceb5fb287 +F test/check.test 1e9be446eb0bbd47a5f65955802e9632425096ab F test/close.test 340bd24cc58b16c6bc01967402755027c37eb815 F test/closure01.test dbb28f1ea9eeaf0a53ec5bc0fed352e479def8c7 F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91 @@ -589,7 +589,7 @@ F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6 F test/index3.test 423a25c789fc8cc51aaf2a4370bbdde2d9e9eed7 F test/index4.test 2983216eb8c86ee62d9ed7cb206b5cc3331c0026 F test/index5.test fc07c14193c0430814e7a08b5da46888ee795c33 -F test/index6.test 3967161678dd5268e6ad1e263cc82e2b8050d055 +F test/index6.test 0005b3093012c6d0f20cc54d9057210221216143 F test/indexedby.test 0e959308707c808515c3a51363f7a9835027108c F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 @@ -1104,7 +1104,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 0c8cfdfae215c95cf167f404a1d346690b28e972 -R 7829f40a29ab8d32821ed080da801961 +P 2e3df0bc900c01286d3ce32c2bbf9e5293973f9b +R b5d4ae8fe01e42e4e171b69c990dde10 U drh -Z d181891086829543aa75dfb2ba9cf461 +Z 4a98808a1193d1ac659ec78aea29a043 diff --git a/manifest.uuid b/manifest.uuid index e50da3aad1..ed5e4f79d5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2e3df0bc900c01286d3ce32c2bbf9e5293973f9b \ No newline at end of file +2e8c845eb5011a2743dace333aa38383588f2080 \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index f288ed930c..a194a26553 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -240,11 +240,20 @@ static int lookupName( ** resulting in an appropriate error message toward the end of this routine */ if( zDb ){ - for(i=0; inDb; i++){ - assert( db->aDb[i].zName ); - if( sqlite3StrICmp(db->aDb[i].zName,zDb)==0 ){ - pSchema = db->aDb[i].pSchema; - break; + testcase( pNC->ncFlags & NC_PartIdx ); + testcase( pNC->ncFlags & NC_IsCheck ); + if( (pNC->ncFlags & (NC_PartIdx|NC_IsCheck))!=0 ){ + /* Silently ignore database qualifiers inside CHECK constraints and partial + ** indices. Do not raise errors because that might break legacy and + ** because it does not hurt anything to just ignore the database name. */ + zDb = 0; + }else{ + for(i=0; inDb; i++){ + assert( db->aDb[i].zName ); + if( sqlite3StrICmp(db->aDb[i].zName,zDb)==0 ){ + pSchema = db->aDb[i].pSchema; + break; + } } } } diff --git a/test/check.test b/test/check.test index 99b72ac8af..f7ebc2cb4c 100644 --- a/test/check.test +++ b/test/check.test @@ -451,5 +451,11 @@ do_test 7.8 { catchsql { INSERT INTO t6 VALUES(12) } db2 } {1 {constraint failed}} +# 2013-08-02: Silently ignore database name qualifiers in CHECK constraints. +# +do_execsql_test 8.1 { + CREATE TABLE t810(a, CHECK( main.t810.a>0 )); + CREATE TABLE t811(b, CHECK( xyzzy.t811.b BETWEEN 5 AND 10 )); +} {} finish_test diff --git a/test/index6.test b/test/index6.test index ddd200c402..e9ea570b83 100644 --- a/test/index6.test +++ b/test/index6.test @@ -217,4 +217,14 @@ do_execsql_test index6-4.0 { PRAGMA integrity_check; } {ok} +# Silently ignore database name qualifiers in partial indices. +# +do_execsql_test index6-5.0 { + CREATE INDEX t3b ON t3(b) WHERE xyzzy.t3.b BETWEEN 5 AND 10; + /* ^^^^^-- ignored */ + ANALYZE; + SELECT count(*) FROM t3 WHERE t3.b BETWEEN 5 AND 10; + SELECT stat+0 FROM sqlite_stat1 WHERE idx='t3b'; +} {6 6} + finish_test From e0c7efd9ae6706b5e39093bcf2256569032c2b91 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 2 Aug 2013 20:11:19 +0000 Subject: [PATCH 47/47] Add NEVER() and ALWAYS() macros on some unreachable yet prudent branches. FossilOrigin-Name: c5c0a8ab6c222185d5f9d4321e64d9f93cd36b7d --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 2 +- src/vdbeaux.c | 3 +-- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 3d69e1aed5..0bcd68c98d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssupport\sfor\spartial\sindices. -D 2013-08-02T16:41:02.828 +C Add\sNEVER()\sand\sALWAYS()\smacros\son\ssome\sunreachable\syet\sprudent\sbranches. +D 2013-08-02T20:11:19.665 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -172,7 +172,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 4262c227bc91cecc61ae37ed3a40f08069cfa267 F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/delete.c 2317c814866d9aa71fea16b3faf4fdd4d6a49b94 -F src/expr.c b873f60585cb851963fd8059f8d26c578e8448f6 +F src/expr.c 2068a7c17e45f8bee6e44205b059aa30acbc71c5 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 914a6bbd987d857c41ac9d244efa6641f36faadb F src/func.c 5c50c1ea31fd864b0fe921fe1a8d4c55acd609ef @@ -281,7 +281,7 @@ F src/vdbe.c d6048a720c197db2f0e7d618e918bd2e2eff0322 F src/vdbe.h 4f554b5627f26710c4c36d919110a3fc611ca5c4 F src/vdbeInt.h e9b7c6b165a31a4715c5aa97223d20d265515231 F src/vdbeapi.c 4d13580bd058b39623e8fcfc233b7df4b8191e8b -F src/vdbeaux.c b04447e8588f9115013a7207f403832521fbeb80 +F src/vdbeaux.c 4389b3692969b4415fcfd00de36818a02f84df28 F src/vdbeblob.c 5dc79627775bd9a9b494dd956e26297946417d69 F src/vdbemem.c 833005f1cbbf447289f1973dba2a0c2228c7b8ab F src/vdbesort.c 3937e06b2a0e354500e17dc206ef4c35770a5017 @@ -1105,7 +1105,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P f3efbfcd515ad6ac833f4b26391dcc44603a96e8 2e8c845eb5011a2743dace333aa38383588f2080 -R 926aabae00116b2c33a18140f6c4ab7f +P 478113f18b1d28606b107b5a0bed04cb90a82cf2 +R 0448265d2d2404edbe8ef2a70f660350 U drh -Z 821dd68c76d813e125e26bbbc791b042 +Z 563793828301249458f36eed7f3789e7 diff --git a/manifest.uuid b/manifest.uuid index 60493d19b8..06ed0f16cf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -478113f18b1d28606b107b5a0bed04cb90a82cf2 \ No newline at end of file +c5c0a8ab6c222185d5f9d4321e64d9f93cd36b7d \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 8d6b90dd2f..e7ac855f71 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3839,7 +3839,7 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){ if( pA->iColumn!=pB->iColumn ) return 2; if( pA->iTable!=pB->iTable && pA->op!=TK_REGISTER - && (pA->iTable!=iTab || pB->iTable>=0) ) return 2; + && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2; if( ExprHasProperty(pA, EP_IntValue) ){ if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){ return 2; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 4febf06abf..880a6299ca 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -575,8 +575,7 @@ void sqlite3VdbeChangeP5(Vdbe *p, u8 val){ ** the address of the next instruction to be coded. */ void sqlite3VdbeJumpHere(Vdbe *p, int addr){ - assert( addr>=0 || p->db->mallocFailed ); - if( addr>=0 ) sqlite3VdbeChangeP2(p, addr, p->nOp); + if( ALWAYS(addr>=0) ) sqlite3VdbeChangeP2(p, addr, p->nOp); }