From 9d356fbe6ec6a340f196cb0c31f949dd86de4796 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 27 Feb 2015 20:28:08 +0000 Subject: [PATCH 01/57] New requirements marks and a few new test cases to go with them. No changes to code. FossilOrigin-Name: 8c2b29d9acb92d47f4deec21a7c2dca52db63345 --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/sqliteLimit.h | 10 ++++++++-- test/autoindex1.test | 3 +++ test/fkey5.test | 29 +++++++++++++++++++++++++++-- test/lock.test | 3 +++ test/pragma.test | 8 +++++++- test/pragma2.test | 4 ++++ 8 files changed, 64 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index b4667b6c06..701ff27033 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\scouple\sof\srequirements\smarks. -D 2015-02-27T00:33:15.390 +C New\srequirements\smarks\sand\sa\sfew\snew\stest\scases\sto\sgo\swith\sthem.\s\sNo\schanges\nto\scode. +D 2015-02-27T20:28:08.104 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 6b9e7677829aa94b9f30949656e27312aefb9a46 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -236,7 +236,7 @@ F src/sqlite.h.in 62d3997824038cc32335b04aaa18cc8f4c19e9be F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d F src/sqliteInt.h 57a405ae6d2ed10fff52de376d18f21e04d96609 -F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d +F src/sqliteLimit.h a3bf51a7484db35a7b1d0634a8a8788cccd4e986 F src/status.c 81712116e826b0089bb221b018929536b2b5406f F src/table.c e7a09215315a978057fb42c640f890160dbcc45e F src/tclsqlite.c b290774586f022e16e04ba8ed2f0b8edd86b5b77 @@ -347,7 +347,7 @@ F test/auth.test 855233ef26eb3601b6886567ea4e326c72959360 F test/auth2.test 264c6af53cad9aba5218c68bbe18036e39007bfa F test/auth3.test 5cfa94ed90c6617c42b7ba4b133fd79678b251c7 F test/autoinc.test c58912526998a39e11f66b533e23cfabea7f25b7 -F test/autoindex1.test 6ff78b94f43a59616c06c11c55b12935173506d7 +F test/autoindex1.test 7008c9f604141fdabe31b7bb95b5ff31b518251f F test/autoindex2.test af7e595c6864cc6ef5fc38d5db579a3e34940cb8 F test/autoindex3.test a3be0d1a53a7d2edff208a5e442312957047e972 F test/autoindex4.test 49d3cd791a9baa16fb461d7ea3de80d019a819cf @@ -503,7 +503,7 @@ F test/fkey1.test e1d1fa84cde579185ea01358436839703e415a5b F test/fkey2.test 1db212cda86b0d3ce72714001f7b6381c321341c F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49 F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d -F test/fkey5.test 488601fbda8350619b3029487e56830447056fd2 +F test/fkey5.test 56bcb5a6e8b725b17febc267fb041a6695e86853 F test/fkey6.test abb59f866c1b44926fd02d1fdd217d831fe04f48 F test/fkey7.test 72e915890ee4a005daaf3002cb208e8fe973ac13 F test/fkey8.test 8f08203458321e6c19a263829de4cfc936274ab0 @@ -693,7 +693,7 @@ F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da F test/limit.test 3d7df19c35ac672a11f7de406cd3205d592babbb F test/loadext.test 648cb95f324d1775c54a55c12271b2d1156b633b F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7 -F test/lock.test 87af515b0c4cf928576d0f89946d67d7c265dfb4 +F test/lock.test b984ab9034e7389be0d863fe4e64cbbc4d2028f5 F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff F test/lock3.test f271375930711ae044080f4fe6d6eda930870d00 F test/lock4.test e175ae13865bc87680607563bafba21f31a26f12 @@ -787,8 +787,8 @@ F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff F test/permutations.test f9cc1dd987986c9d4949211c7a4ed55ec9aecba1 -F test/pragma.test 6cf0f0ce4618e841457aa42745afda55ddbc95fe -F test/pragma2.test aea7b3d82c76034a2df2b38a13745172ddc0bc13 +F test/pragma.test a6187e24d55ddad2b2af46022e473a605a260f27 +F test/pragma2.test f624a496a95ee878e81e59961eade66d5c00c028 F test/pragma3.test 6f849ccffeee7e496d2f2b5e74152306c0b8757c F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552 F test/printf2.test b4acd4bf8734243257f01ddefa17c4fb090acc8a @@ -1239,7 +1239,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 3bc34fd427d9d7819cd9740237b1f5d4180341fa -R ea56360259f5f37b0ed4591b0dd003bd +P d70b0fd4c94f2b70cf31c2ab9ef7a2fb2e71c182 +R 5e6d1ff7a404da4f62d2b00fe21c4e92 U drh -Z c0882f7c7d1c49cd54726f112c10b39e +Z 7d013f116627badc7b6152666136f166 diff --git a/manifest.uuid b/manifest.uuid index 1881ff1d28..e9a4409b59 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d70b0fd4c94f2b70cf31c2ab9ef7a2fb2e71c182 \ No newline at end of file +8c2b29d9acb92d47f4deec21a7c2dca52db63345 \ No newline at end of file diff --git a/src/sqliteLimit.h b/src/sqliteLimit.h index c7aee53ceb..3abad8437f 100644 --- a/src/sqliteLimit.h +++ b/src/sqliteLimit.h @@ -98,8 +98,14 @@ #endif /* -** The maximum number of in-memory pages to use for the main database -** table and for temporary tables. The SQLITE_DEFAULT_CACHE_SIZE +** The suggested maximum number of in-memory pages to use for +** the main database table and for temporary tables. +** +** EVIDENCE-OF: R-31093-59126 The default suggested cache size is 2000 +** pages. +** +** EVIDENCE-OF: R-45985-54577 The default cache sizes can be adjusted by +** the SQLITE_DEFAULT_CACHE_SIZE compile-time options. */ #ifndef SQLITE_DEFAULT_CACHE_SIZE # define SQLITE_DEFAULT_CACHE_SIZE 2000 diff --git a/test/autoindex1.test b/test/autoindex1.test index bcde5bc2e7..c5ce42c1d4 100644 --- a/test/autoindex1.test +++ b/test/autoindex1.test @@ -11,6 +11,9 @@ # This file implements regression tests for SQLite library. The # focus of this script is testing automatic index creation logic. # +# EVIDENCE-OF: R-34271-33106 PRAGMA automatic_index; PRAGMA +# automatic_index = boolean; Query, set, or clear the automatic indexing +# capability. set testdir [file dirname $argv0] source $testdir/tester.tcl diff --git a/test/fkey5.test b/test/fkey5.test index dc866cbdb8..21feb2bb8b 100644 --- a/test/fkey5.test +++ b/test/fkey5.test @@ -12,8 +12,13 @@ # # This file tests the PRAGMA foreign_key_check command. # -# EVIDENCE-OF: R-05426-18119 PRAGMA foreign_key_check; PRAGMA -# foreign_key_check(table-name); +# EVIDENCE-OF: R-01427-50262 PRAGMA database.foreign_key_check; PRAGMA +# database.foreign_key_check(table-name); +# +# EVIDENCE-OF: R-23918-17301 The foreign_key_check pragma checks the +# database, or the table called "table-name", for foreign key +# constraints that are violated and returns one row of output for each +# violation. set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -74,6 +79,16 @@ do_test fkey5-1.2 { PRAGMA foreign_key_check; } } {c1 87 p1 0 c1 90 p1 0} +do_test fkey5-1.2b { + db eval { + PRAGMA main.foreign_key_check; + } +} {c1 87 p1 0 c1 90 p1 0} +do_test fkey5-1.2c { + db eval { + PRAGMA temp.foreign_key_check; + } +} {} do_test fkey5-1.3 { db eval { PRAGMA foreign_key_check(c1); @@ -84,6 +99,16 @@ do_test fkey5-1.4 { PRAGMA foreign_key_check(c2); } } {} +do_test fkey5-1.5 { + db eval { + PRAGMA main.foreign_key_check(c2); + } +} {} +do_test fkey5-1.6 { + catchsql { + PRAGMA temp.foreign_key_check(c2); + } +} {1 {no such table: temp.c2}} # EVIDENCE-OF: R-45728-08709 There are four columns in each result row. # diff --git a/test/lock.test b/test/lock.test index 6ec85eea3c..f785c4bb23 100644 --- a/test/lock.test +++ b/test/lock.test @@ -241,6 +241,9 @@ execsql {ROLLBACK} # Test the built-in busy timeout handler # +# EVIDENCE-OF: R-23579-05241 PRAGMA busy_timeout; PRAGMA busy_timeout = +# milliseconds; Query or change the setting of the busy timeout. +# do_test lock-2.8 { db2 timeout 400 execsql BEGIN diff --git a/test/pragma.test b/test/pragma.test index e2673d3eef..912c2f956d 100644 --- a/test/pragma.test +++ b/test/pragma.test @@ -83,7 +83,11 @@ delete_file test.db test.db-journal delete_file test3.db test3.db-journal sqlite3 db test.db; set DB [sqlite3_connection_pointer db] - +# EVIDENCE-OF: R-24197-42751 PRAGMA database.cache_size; PRAGMA +# database.cache_size = pages; PRAGMA database.cache_size = -kibibytes; +# Query or change the suggested maximum number of database disk pages +# that SQLite will hold in memory at once per open database file. +# ifcapable pager_pragmas { set DFLT_CACHE_SZ [db one {PRAGMA default_cache_size}] set TEMP_CACHE_SZ [db one {PRAGMA temp.default_cache_size}] @@ -95,6 +99,8 @@ do_test pragma-1.1 { } } [list $DFLT_CACHE_SZ $DFLT_CACHE_SZ 2] do_test pragma-1.2 { + # EVIDENCE-OF: R-42059-47211 If the argument N is positive then the + # suggested cache size is set to N. execsql { PRAGMA synchronous=OFF; PRAGMA cache_size=1234; diff --git a/test/pragma2.test b/test/pragma2.test index 0dbc9777d2..3ade8c1a07 100644 --- a/test/pragma2.test +++ b/test/pragma2.test @@ -39,6 +39,10 @@ delete_file test3.db test3.db-journal sqlite3 db test.db; set DB [sqlite3_connection_pointer db] db eval {PRAGMA auto_vacuum=0} + +# EVIDENCE-OF: R-17887-14874 PRAGMA database.freelist_count; Return the +# number of unused pages in the database file. +# do_test pragma2-1.1 { execsql { PRAGMA freelist_count; From e0e8429543d22f15d711be3bb4672fce05b55987 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 27 Feb 2015 21:53:35 +0000 Subject: [PATCH 02/57] Remove all references to SQLITE_DEFAULT_TEMP_CACHE_SIZE. Add requirements marks related to cache_size changing. FossilOrigin-Name: 766ad65025a9d5815300978e6e349f5af5db6012 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/pcache.c | 10 +++++++++- src/sqliteLimit.h | 12 ++++-------- src/test_config.c | 1 - 5 files changed, 22 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 701ff27033..1a03048bea 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\srequirements\smarks\sand\sa\sfew\snew\stest\scases\sto\sgo\swith\sthem.\s\sNo\schanges\nto\scode. -D 2015-02-27T20:28:08.104 +C Remove\sall\sreferences\sto\sSQLITE_DEFAULT_TEMP_CACHE_SIZE.\s\sAdd\srequirements\nmarks\srelated\sto\scache_size\schanging. +D 2015-02-27T21:53:35.613 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 6b9e7677829aa94b9f30949656e27312aefb9a46 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -220,7 +220,7 @@ F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 4120a49ecd37697e28f5ed807f470b9c0b88410c F src/pager.h c3476e7c89cdf1c6914e50a11f3714e30b4e0a77 F src/parse.y 0f8e7d60f0ab3cb53d270adef69259ac307d83a8 -F src/pcache.c d210cf90d04365a74f85d21374dded65af67b0cb +F src/pcache.c 10539fb959849ad6efff80050541cab3d25089d4 F src/pcache.h b44658c9c932d203510279439d891a2a83e12ba8 F src/pcache1.c 1e77432b40b7d3288327d9cdf399dcdfd2b6d3bf F src/pragma.c ea0be138a99784b14e87bd4522fea40e7b979e9c @@ -236,7 +236,7 @@ F src/sqlite.h.in 62d3997824038cc32335b04aaa18cc8f4c19e9be F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d F src/sqliteInt.h 57a405ae6d2ed10fff52de376d18f21e04d96609 -F src/sqliteLimit.h a3bf51a7484db35a7b1d0634a8a8788cccd4e986 +F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c 81712116e826b0089bb221b018929536b2b5406f F src/table.c e7a09215315a978057fb42c640f890160dbcc45e F src/tclsqlite.c b290774586f022e16e04ba8ed2f0b8edd86b5b77 @@ -254,7 +254,7 @@ F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12 F src/test_backup.c 2e6e6a081870150f20c526a2e9d0d29cda47d803 F src/test_blob.c 1f2e3e25255b731c4fcf15ee7990d06347cb6c09 F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f -F src/test_config.c e7b2e1634324d746aa5e1c7e0929470e8be27953 +F src/test_config.c c2d3ff6c129d50183900c7eff14158ff7e9b3f03 F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f @@ -1239,7 +1239,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P d70b0fd4c94f2b70cf31c2ab9ef7a2fb2e71c182 -R 5e6d1ff7a404da4f62d2b00fe21c4e92 +P 8c2b29d9acb92d47f4deec21a7c2dca52db63345 +R 5f8145ea43512db7c8608bf7ec930759 U drh -Z 7d013f116627badc7b6152666136f166 +Z 93d3230e7c0b0c9e7f5924677c91b2f3 diff --git a/manifest.uuid b/manifest.uuid index e9a4409b59..042235b07c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8c2b29d9acb92d47f4deec21a7c2dca52db63345 \ No newline at end of file +766ad65025a9d5815300978e6e349f5af5db6012 \ No newline at end of file diff --git a/src/pcache.c b/src/pcache.c index 467e2b3dee..d768fe00c8 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -114,12 +114,20 @@ static void pcacheUnpin(PgHdr *p){ } /* -** Compute the number of pages of cache requested. +** Compute the number of pages of cache requested. p->szCache is the +** cache size requested by the "PRAGMA cache_size" statement. +** +** */ static int numberOfCachePages(PCache *p){ if( p->szCache>=0 ){ + /* IMPLEMENTATION-OF: R-42059-47211 If the argument N is positive then the + ** suggested cache size is set to N. */ return p->szCache; }else{ + /* IMPLEMENTATION-OF: R-61436-13639 If the argument N is negative, then + ** the number of cache pages is adjusted to use approximately abs(N*1024) + ** bytes of memory. */ return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra)); } } diff --git a/src/sqliteLimit.h b/src/sqliteLimit.h index 3abad8437f..75cad1274b 100644 --- a/src/sqliteLimit.h +++ b/src/sqliteLimit.h @@ -101,18 +101,14 @@ ** The suggested maximum number of in-memory pages to use for ** the main database table and for temporary tables. ** -** EVIDENCE-OF: R-31093-59126 The default suggested cache size is 2000 -** pages. -** -** EVIDENCE-OF: R-45985-54577 The default cache sizes can be adjusted by -** the SQLITE_DEFAULT_CACHE_SIZE compile-time options. +** IMPLEMENTATION-OF: R-31093-59126 The default suggested cache size +** is 2000 pages. +** IMPLEMENTATION-OF: R-48205-43578 The default suggested cache size can be +** altered using the SQLITE_DEFAULT_CACHE_SIZE compile-time options. */ #ifndef SQLITE_DEFAULT_CACHE_SIZE # define SQLITE_DEFAULT_CACHE_SIZE 2000 #endif -#ifndef SQLITE_DEFAULT_TEMP_CACHE_SIZE -# define SQLITE_DEFAULT_TEMP_CACHE_SIZE 500 -#endif /* ** The default number of frames to accumulate in the log file before diff --git a/src/test_config.c b/src/test_config.c index 25e6a5698f..0be2a23d3a 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -650,7 +650,6 @@ Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY); LINKVAR( MAX_PAGE_COUNT ); LINKVAR( MAX_LIKE_PATTERN_LENGTH ); LINKVAR( MAX_TRIGGER_DEPTH ); - LINKVAR( DEFAULT_TEMP_CACHE_SIZE ); LINKVAR( DEFAULT_CACHE_SIZE ); LINKVAR( DEFAULT_PAGE_SIZE ); LINKVAR( DEFAULT_FILE_FORMAT ); From 51a74d4cbd5ed5c9b6b726b301a036a0ee65319d Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 28 Feb 2015 01:04:27 +0000 Subject: [PATCH 03/57] More test cases and requirements marks for pragmas. FossilOrigin-Name: fc51037cd97063069620213a62efdeff5d898706 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/pragma.c | 13 +++++++++---- src/vdbe.c | 7 ++++++- test/pragma.test | 13 +++++++++---- test/softheap1.test | 8 ++++++++ 6 files changed, 42 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 1a03048bea..b5975aaf29 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sall\sreferences\sto\sSQLITE_DEFAULT_TEMP_CACHE_SIZE.\s\sAdd\srequirements\nmarks\srelated\sto\scache_size\schanging. -D 2015-02-27T21:53:35.613 +C More\stest\scases\sand\srequirements\smarks\sfor\spragmas. +D 2015-02-28T01:04:27.551 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 6b9e7677829aa94b9f30949656e27312aefb9a46 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -223,7 +223,7 @@ F src/parse.y 0f8e7d60f0ab3cb53d270adef69259ac307d83a8 F src/pcache.c 10539fb959849ad6efff80050541cab3d25089d4 F src/pcache.h b44658c9c932d203510279439d891a2a83e12ba8 F src/pcache1.c 1e77432b40b7d3288327d9cdf399dcdfd2b6d3bf -F src/pragma.c ea0be138a99784b14e87bd4522fea40e7b979e9c +F src/pragma.c d1abcc070698e5853205dc1d1cd3f01845c1804b F src/pragma.h 09c89bca58e9a44de2116cc8272b8d454657129f F src/prepare.c 173a5a499138451b2561614ecb87d78f9f4644b9 F src/printf.c 8da9a2687a396daa19860f4dc90975d319304744 @@ -293,7 +293,7 @@ F src/update.c 3c4ecc282accf12d39edb8d524cf089645e55a13 F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/util.c 98a7627ca48ad3265b6940915a1d08355eb3fc7e F src/vacuum.c 9460b9de7b2d4e34b0d374894aa6c8a0632be8ec -F src/vdbe.c ddfc977981cd6324668aa6b114045eb1c677421a +F src/vdbe.c 991e9b2c38cdc987ed214249b3c72ea73a06fb2e F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3 F src/vdbeInt.h bb56fd199d8af1a2c1b9639ee2f70724b4338e3a F src/vdbeapi.c dac0d0d8009a8aa549cd77d9c29da44c0344f0c4 @@ -787,7 +787,7 @@ F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff F test/permutations.test f9cc1dd987986c9d4949211c7a4ed55ec9aecba1 -F test/pragma.test a6187e24d55ddad2b2af46022e473a605a260f27 +F test/pragma.test 64f11ec7f4100e873c67e888a56c33d395cb75d6 F test/pragma2.test f624a496a95ee878e81e59961eade66d5c00c028 F test/pragma3.test 6f849ccffeee7e496d2f2b5e74152306c0b8757c F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552 @@ -873,7 +873,7 @@ F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5 F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2 F test/skipscan6.test 5866039d03a56f5bd0b3d172a012074a1d90a15b F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f -F test/softheap1.test 40562fe6cac6d9827b7b42b86d45aedf12c15e24 +F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087 F test/sort.test 3f492e5b7be1d3f756728d2ff6edf4f6091e84cb F test/sort2.test 37afbc03f5559f2eb0f18940b55d38dfbb5172ac F test/sort3.test 6178ade30810ac9166fcdf14b7065e49c0f534e2 @@ -1239,7 +1239,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8c2b29d9acb92d47f4deec21a7c2dca52db63345 -R 5f8145ea43512db7c8608bf7ec930759 +P 766ad65025a9d5815300978e6e349f5af5db6012 +R 8204e8f9043c535de0f2497c8e561323 U drh -Z 93d3230e7c0b0c9e7f5924677c91b2f3 +Z a56e97eeca3c59d6452815bc1cc7253f diff --git a/manifest.uuid b/manifest.uuid index 042235b07c..8cfe091b9c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -766ad65025a9d5815300978e6e349f5af5db6012 \ No newline at end of file +fc51037cd97063069620213a62efdeff5d898706 \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index ac217d4597..75db9a6765 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1802,8 +1802,9 @@ void sqlite3Pragma( /* ** PRAGMA shrink_memory ** - ** This pragma attempts to free as much memory as possible from the - ** current database connection. + ** IMPLEMENTATION-OF: R-23445-46109 This pragma causes the database + ** connection on which it is invoked to free up as much memory as it + ** can, by calling sqlite3_db_release_memory(). */ case PragTyp_SHRINK_MEMORY: { sqlite3_db_release_memory(db); @@ -1832,8 +1833,12 @@ void sqlite3Pragma( ** PRAGMA soft_heap_limit ** PRAGMA soft_heap_limit = N ** - ** Call sqlite3_soft_heap_limit64(N). Return the result. If N is omitted, - ** use -1. + ** IMPLEMENTATION-OF: R-26343-45930 This pragma invokes the + ** sqlite3_soft_heap_limit64() interface with the argument N, if N is + ** specified and is a non-negative integer. + ** IMPLEMENTATION-OF: R-64451-07163 The soft_heap_limit pragma always + ** returns the same integer that would be returned by the + ** sqlite3_soft_heap_limit64(-1) C-language function. */ case PragTyp_SOFT_HEAP_LIMIT: { sqlite3_int64 N; diff --git a/src/vdbe.c b/src/vdbe.c index 1e0ff96af4..39a334f29f 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3050,7 +3050,12 @@ case OP_Transaction: { p->nStmtDefImmCons = db->nDeferredImmCons; } - /* Gather the schema version number for checking */ + /* Gather the schema version number for checking: + ** IMPLEMENTATION-OF: R-32195-19465 The schema version is used by SQLite + ** each time a query is executed to ensure that the internal cache of the + ** schema used when compiling the SQL query matches the schema of the + ** database against which the compiled query is actually executed. + */ sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta); iGen = db->aDb[pOp->p1].pSchema->iGeneration; }else{ diff --git a/test/pragma.test b/test/pragma.test index 912c2f956d..619fc7fd60 100644 --- a/test/pragma.test +++ b/test/pragma.test @@ -1316,18 +1316,23 @@ ifcapable pager_pragmas { db close forcedelete test.db sqlite3 db test.db - + + # EVIDENCE-OF: R-13905-26312 PRAGMA database.page_count; Return the + # total number of pages in the database file. + # do_test pragma-14.1 { execsql { pragma auto_vacuum = 0 } - execsql { pragma page_count } - } {0} + execsql { pragma page_count; pragma main.page_count } + } {0 0} do_test pragma-14.2 { execsql { CREATE TABLE abc(a, b, c); PRAGMA page_count; + PRAGMA main.page_count; + PRAGMA temp.page_count; } - } {2} + } {2 2 0} do_test pragma-14.2uc { execsql {pragma PAGE_COUNT} } {2} diff --git a/test/softheap1.test b/test/softheap1.test index 522e455e33..07f981e50a 100644 --- a/test/softheap1.test +++ b/test/softheap1.test @@ -24,6 +24,14 @@ ifcapable !integrityck { return } +# EVIDENCE-OF: R-26343-45930 This pragma invokes the +# sqlite3_soft_heap_limit64() interface with the argument N, if N is +# specified and is a non-negative integer. +# +# EVIDENCE-OF: R-64451-07163 The soft_heap_limit pragma always returns +# the same integer that would be returned by the +# sqlite3_soft_heap_limit64(-1) C-language function. +# do_test softheap1-1.0 { execsql {PRAGMA soft_heap_limit} } [sqlite3_soft_heap_limit -1] From 534f4dfa3c85250b56ecc2c746edf3427da4d5e3 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 28 Feb 2015 14:03:35 +0000 Subject: [PATCH 04/57] In the command-line shell, the inability to read ~/.sqliterc is no longer a fatal error. A warning is issued, but processing continues. FossilOrigin-Name: 6bf6246306e6fd490766c0a05932be52a0ed66f2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 18 ++++++------------ 3 files changed, 13 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index b5975aaf29..4ccc83a559 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\stest\scases\sand\srequirements\smarks\sfor\spragmas. -D 2015-02-28T01:04:27.551 +C In\sthe\scommand-line\sshell,\sthe\sinability\sto\sread\s~/.sqliterc\sis\sno\slonger\na\sfatal\serror.\s\sA\swarning\sis\sissued,\sbut\sprocessing\scontinues. +D 2015-02-28T14:03:35.210 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 6b9e7677829aa94b9f30949656e27312aefb9a46 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -231,7 +231,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c f4d79e31ffa5820c2e3d1740baa5e9b190425f2b F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c e46cef4c224549b439384c88fc7f57ba064dad54 -F src/shell.c f06cca68a3f07e03d35d2f879375967169db6a61 +F src/shell.c a552c1ffc33aac6ab9246c55938835434130432d F src/sqlite.h.in 62d3997824038cc32335b04aaa18cc8f4c19e9be F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d @@ -1239,7 +1239,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 766ad65025a9d5815300978e6e349f5af5db6012 -R 8204e8f9043c535de0f2497c8e561323 +P fc51037cd97063069620213a62efdeff5d898706 +R 6857d3f3463c24fa73a9fc0de2ae11e8 U drh -Z a56e97eeca3c59d6452815bc1cc7253f +Z b9ffbe353e645ecee0849e3fef86b4ab diff --git a/manifest.uuid b/manifest.uuid index 8cfe091b9c..16a50d0d9d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fc51037cd97063069620213a62efdeff5d898706 \ No newline at end of file +6bf6246306e6fd490766c0a05932be52a0ed66f2 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 4aaa2d90ec..47b16f4e6f 100644 --- a/src/shell.c +++ b/src/shell.c @@ -4189,7 +4189,7 @@ static char *find_home_dir(void){ ** ** Returns the number of errors. */ -static int process_sqliterc( +static void process_sqliterc( ShellState *p, /* Configuration data */ const char *sqliterc_override /* Name of config file. NULL to use default */ ){ @@ -4197,15 +4197,13 @@ static int process_sqliterc( const char *sqliterc = sqliterc_override; char *zBuf = 0; FILE *in = NULL; - int rc = 0; if (sqliterc == NULL) { home_dir = find_home_dir(); if( home_dir==0 ){ -#if !defined(__RTP__) && !defined(_WRS_KERNEL) - fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0); -#endif - return 1; + fprintf(stderr, "-- warning: cannot find home directory;" + " cannot read ~/.sqliterc\n"); + return; } sqlite3_initialize(); zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir); @@ -4216,11 +4214,10 @@ static int process_sqliterc( if( stdin_is_interactive ){ fprintf(stderr,"-- Loading resources from %s\n",sqliterc); } - rc = process_input(p,in); + process_input(p,in); fclose(in); } sqlite3_free(zBuf); - return rc; } /* @@ -4496,10 +4493,7 @@ int main(int argc, char **argv){ ** is given on the command line, look for a file named ~/.sqliterc and ** try to process it. */ - rc = process_sqliterc(&data,zInitFile); - if( rc>0 ){ - return rc; - } + process_sqliterc(&data,zInitFile); /* Make a second pass through the command-line argument and set ** options. This second pass is delayed until after the initialization From 8e8e7ef363378212defd273c1324d9bd1a004010 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 2 Mar 2015 17:25:00 +0000 Subject: [PATCH 05/57] Ensure that automatic indexes are *not* considered when doing the the subqueries of the OR-optimization. FossilOrigin-Name: 17890292cf1776b3334fca7eff693cdbea458304 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqliteInt.h | 2 +- src/where.c | 4 +++- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 4ccc83a559..69be4b7763 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\scommand-line\sshell,\sthe\sinability\sto\sread\s~/.sqliterc\sis\sno\slonger\na\sfatal\serror.\s\sA\swarning\sis\sissued,\sbut\sprocessing\scontinues. -D 2015-02-28T14:03:35.210 +C Ensure\sthat\sautomatic\sindexes\sare\s*not*\sconsidered\swhen\sdoing\sthe\sthe\ssubqueries\nof\sthe\sOR-optimization. +D 2015-03-02T17:25:00.374 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 6b9e7677829aa94b9f30949656e27312aefb9a46 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -235,7 +235,7 @@ F src/shell.c a552c1ffc33aac6ab9246c55938835434130432d F src/sqlite.h.in 62d3997824038cc32335b04aaa18cc8f4c19e9be F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d -F src/sqliteInt.h 57a405ae6d2ed10fff52de376d18f21e04d96609 +F src/sqliteInt.h 14e1648f616c1136949a80cd3e3baeca89663cfd F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c 81712116e826b0089bb221b018929536b2b5406f F src/table.c e7a09215315a978057fb42c640f890160dbcc45e @@ -306,7 +306,7 @@ F src/vtab.c 699f2b8d509cfe379c33dde33827875d5b030e01 F src/wal.c 39303f2c9db02a4e422cd8eb2c8760420c6a51fe F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 -F src/where.c a50d5082b0fecd2bcf1725cdd012732d9d1e9d5c +F src/where.c c1b3706929fe918966227f3b91ff433a825037fd F src/whereInt.h d3633e9b592103241b74b0ec76185f3e5b8b62e0 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1239,7 +1239,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P fc51037cd97063069620213a62efdeff5d898706 -R 6857d3f3463c24fa73a9fc0de2ae11e8 +P 6bf6246306e6fd490766c0a05932be52a0ed66f2 +R 769a7b9588243a9203c45ee90503a7f0 U drh -Z b9ffbe353e645ecee0849e3fef86b4ab +Z 06079288f464b37dcc72ce54dc75845f diff --git a/manifest.uuid b/manifest.uuid index 16a50d0d9d..f602fc368a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6bf6246306e6fd490766c0a05932be52a0ed66f2 \ No newline at end of file +17890292cf1776b3334fca7eff693cdbea458304 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 3f9a3a7cc7..4930789c2a 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2250,7 +2250,7 @@ struct SrcList { #define WHERE_OMIT_OPEN_CLOSE 0x0010 /* Table cursors are already open */ #define WHERE_FORCE_TABLE 0x0020 /* Do not use an index-only search */ #define WHERE_ONETABLE_ONLY 0x0040 /* Only code the 1st table in pTabList */ - /* 0x0080 // not currently used */ +#define WHERE_NO_AUTOINDEX 0x0080 /* Disallow automatic indexes */ #define WHERE_GROUPBY 0x0100 /* pOrderBy is really a GROUP BY */ #define WHERE_DISTINCTBY 0x0200 /* pOrderby is really a DISTINCT clause */ #define WHERE_WANT_DISTINCT 0x0400 /* All output needs to be distinct */ diff --git a/src/where.c b/src/where.c index d01945de7f..fedc67a791 100644 --- a/src/where.c +++ b/src/where.c @@ -3614,7 +3614,8 @@ static Bitmask codeOneLoopStart( */ wctrlFlags = WHERE_OMIT_OPEN_CLOSE | WHERE_FORCE_TABLE - | WHERE_ONETABLE_ONLY; + | WHERE_ONETABLE_ONLY + | WHERE_NO_AUTOINDEX; for(ii=0; iinTerm; ii++){ WhereTerm *pOrTerm = &pOrWc->a[ii]; if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){ @@ -4808,6 +4809,7 @@ static int whereLoopAddBtree( #ifndef SQLITE_OMIT_AUTOMATIC_INDEX /* Automatic indexes */ if( !pBuilder->pOrSet + && (pWInfo->wctrlFlags & WHERE_NO_AUTOINDEX)==0 && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0 && pSrc->pIndex==0 && !pSrc->viaCoroutine From 8cd5b2546f6f3ce8cec16542cb239de75b8706b7 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 2 Mar 2015 22:06:43 +0000 Subject: [PATCH 06/57] Changes so that the amalgamation and the command-line shell build without modifications on VxWorks 7. Still gives a few compiler warnings, and still mostly untested on that platform. FossilOrigin-Name: 7d92f1f11ee69b0ba7d5a48f0611016d77d41c78 --- Makefile.in | 2 ++ Makefile.msc | 2 ++ main.mk | 2 ++ manifest | 25 +++++++++++++------------ manifest.uuid | 2 +- src/os_unix.c | 36 +++++++++++++----------------------- src/shell.c | 33 +++++++++++++++++++++++++++++---- src/sqliteInt.h | 5 +++++ src/vxworks.h | 29 +++++++++++++++++++++++++++++ tool/mksqlite3c.tcl | 1 + 10 files changed, 97 insertions(+), 40 deletions(-) create mode 100644 src/vxworks.h diff --git a/Makefile.in b/Makefile.in index 750b8fd8b5..058a13a655 100644 --- a/Makefile.in +++ b/Makefile.in @@ -287,6 +287,7 @@ SRC = \ $(TOP)/src/vdbetrace.c \ $(TOP)/src/vdbeInt.h \ $(TOP)/src/vtab.c \ + $(TOP)/src/vxworks.h \ $(TOP)/src/wal.c \ $(TOP)/src/wal.h \ $(TOP)/src/walker.c \ @@ -482,6 +483,7 @@ HDR = \ $(TOP)/src/sqliteLimit.h \ $(TOP)/src/vdbe.h \ $(TOP)/src/vdbeInt.h \ + $(TOP)/src/vxworks.h \ $(TOP)/src/whereInt.h \ config.h diff --git a/Makefile.msc b/Makefile.msc index 1d491c432f..58d370fcde 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -805,6 +805,7 @@ SRC2 = \ $(TOP)\src\vdbetrace.c \ $(TOP)\src\vdbeInt.h \ $(TOP)\src\vtab.c \ + $(TOP)\src\vxworks.h \ $(TOP)\src\wal.c \ $(TOP)\src\wal.h \ $(TOP)\src\walker.c \ @@ -1004,6 +1005,7 @@ HDR = \ $(TOP)\src\sqliteLimit.h \ $(TOP)\src\vdbe.h \ $(TOP)\src\vdbeInt.h \ + $(TOP)\src\vxworks.h \ $(TOP)\src\whereInt.h # Header files used by extensions diff --git a/main.mk b/main.mk index f72922b4c1..7d21dbb25e 100644 --- a/main.mk +++ b/main.mk @@ -165,6 +165,7 @@ SRC = \ $(TOP)/src/vdbetrace.c \ $(TOP)/src/vdbeInt.h \ $(TOP)/src/vtab.c \ + $(TOP)/src/vxworks.h \ $(TOP)/src/wal.c \ $(TOP)/src/wal.h \ $(TOP)/src/walker.c \ @@ -364,6 +365,7 @@ HDR = \ $(TOP)/src/sqliteLimit.h \ $(TOP)/src/vdbe.h \ $(TOP)/src/vdbeInt.h \ + $(TOP)/src/vxworks.h \ $(TOP)/src/whereInt.h # Header files used by extensions diff --git a/manifest b/manifest index 69be4b7763..0fd2ceef53 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Ensure\sthat\sautomatic\sindexes\sare\s*not*\sconsidered\swhen\sdoing\sthe\sthe\ssubqueries\nof\sthe\sOR-optimization. -D 2015-03-02T17:25:00.374 +C Changes\sso\sthat\sthe\samalgamation\sand\sthe\scommand-line\sshell\sbuild\swithout\nmodifications\son\sVxWorks\s7.\s\sStill\sgives\sa\sfew\scompiler\swarnings,\sand\sstill\nmostly\suntested\son\sthat\splatform. +D 2015-03-02T22:06:43.573 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f -F Makefile.in 6b9e7677829aa94b9f30949656e27312aefb9a46 +F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 -F Makefile.msc edbe2e2a9d27a4a56bd2891808a7c013bc322f6e +F Makefile.msc 529e61cd9d29a3934758b4b3a0bb649b6c653481 F Makefile.vxworks e1b65dea203f054e71653415bd8f96dcaed47858 F README.md d58e3bebc0a4145e0f2a87994015fdb575a8e866 F VERSION d846487aff892625eb8e75960234e7285f0462fe @@ -152,7 +152,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 0bae136db3f3ce451079ae335124b46163d37020 +F main.mk 04c49c495795b18a7b70053eef285be1e4d43fa4 F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea F mkopcodeh.awk c6b3fa301db6ef7ac916b14c60868aeaec1337b5 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 @@ -214,7 +214,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c c06b1b263d52e14473ccc619422af6b64570a3b8 +F src/os_unix.c 190c726a2881b0b0366cba0906eec80baf6c6781 F src/os_win.c 8223e7db5b7c4a81d8b161098ac3959400434cdb F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 4120a49ecd37697e28f5ed807f470b9c0b88410c @@ -231,11 +231,11 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c f4d79e31ffa5820c2e3d1740baa5e9b190425f2b F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c e46cef4c224549b439384c88fc7f57ba064dad54 -F src/shell.c a552c1ffc33aac6ab9246c55938835434130432d +F src/shell.c e2e5b63a759d304c1ada5b77dc5a518dc8e5396c F src/sqlite.h.in 62d3997824038cc32335b04aaa18cc8f4c19e9be F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d -F src/sqliteInt.h 14e1648f616c1136949a80cd3e3baeca89663cfd +F src/sqliteInt.h fae682c2b4dfbe489b134d74521c41c088f16ab1 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c 81712116e826b0089bb221b018929536b2b5406f F src/table.c e7a09215315a978057fb42c640f890160dbcc45e @@ -303,6 +303,7 @@ F src/vdbemem.c 31d8eabb0cd78bfeab4e5124c7363c3e9e54db9f F src/vdbesort.c 6d64c5448b64851b99931ede980addc3af70d5e2 F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010 F src/vtab.c 699f2b8d509cfe379c33dde33827875d5b030e01 +F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 39303f2c9db02a4e422cd8eb2c8760420c6a51fe F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 @@ -1206,7 +1207,7 @@ F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkpragmatab.tcl 94f196c9961e0ca3513e29f57125a3197808be2d F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl 9ef48e1748dce7b844f67e2450ff9dfeb0fb4ab5 -F tool/mksqlite3c.tcl 6b8e572a90eb4e0086e3ba90d88b76c085919863 +F tool/mksqlite3c.tcl 95ab31eda659e7ffb091e04bd83178f260d8edfd F tool/mksqlite3h.tcl ba24038056f51fde07c0079c41885ab85e2cff12 F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b F tool/mkvsix.tcl 52a4c613707ac34ae9c226e5ccc69cb948556105 @@ -1239,7 +1240,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6bf6246306e6fd490766c0a05932be52a0ed66f2 -R 769a7b9588243a9203c45ee90503a7f0 +P 17890292cf1776b3334fca7eff693cdbea458304 +R d2f100fda951bb397431a320fd5da8c3 U drh -Z 06079288f464b37dcc72ce54dc75845f +Z 298d458a8c4fd11618e1bcf6179fdf9d diff --git a/manifest.uuid b/manifest.uuid index f602fc368a..98d4babbc9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -17890292cf1776b3334fca7eff693cdbea458304 \ No newline at end of file +7d92f1f11ee69b0ba7d5a48f0611016d77d41c78 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 48aac166d0..6e2429880b 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -71,18 +71,6 @@ # endif #endif -/* -** Define the OS_VXWORKS pre-processor macro to 1 if building on -** vxworks, or 0 otherwise. -*/ -#ifndef OS_VXWORKS -# if defined(__RTP__) || defined(_WRS_KERNEL) -# define OS_VXWORKS 1 -# else -# define OS_VXWORKS 0 -# endif -#endif - /* ** standard include files. */ @@ -237,7 +225,7 @@ struct unixFile { ** method was called. If xOpen() is called from a different process id, ** indicating that a fork() has occurred, the PRNG will be reset. */ -static int randomnessPid = 0; +static pid_t randomnessPid = 0; /* ** Allowed values for the unixFile.ctrlFlags bitmask: @@ -2456,7 +2444,7 @@ static int flockClose(sqlite3_file *id) { ** to a non-zero value otherwise *pResOut is set to zero. The return value ** is set to SQLITE_OK unless an I/O error occurs during lock checking. */ -static int semCheckReservedLock(sqlite3_file *id, int *pResOut) { +static int semXCheckReservedLock(sqlite3_file *id, int *pResOut) { int rc = SQLITE_OK; int reserved = 0; unixFile *pFile = (unixFile*)id; @@ -2523,7 +2511,7 @@ static int semCheckReservedLock(sqlite3_file *id, int *pResOut) { ** This routine will only increase a lock. Use the sqlite3OsUnlock() ** routine to lower a locking level. */ -static int semLock(sqlite3_file *id, int eFileLock) { +static int semXLock(sqlite3_file *id, int eFileLock) { unixFile *pFile = (unixFile*)id; sem_t *pSem = pFile->pInode->pSem; int rc = SQLITE_OK; @@ -2556,7 +2544,7 @@ static int semLock(sqlite3_file *id, int eFileLock) { ** If the locking level of the file descriptor is already at or below ** the requested locking level, this routine is a no-op. */ -static int semUnlock(sqlite3_file *id, int eFileLock) { +static int semXUnlock(sqlite3_file *id, int eFileLock) { unixFile *pFile = (unixFile*)id; sem_t *pSem = pFile->pInode->pSem; @@ -2593,10 +2581,10 @@ static int semUnlock(sqlite3_file *id, int eFileLock) { /* ** Close a file. */ -static int semClose(sqlite3_file *id) { +static int semXClose(sqlite3_file *id) { if( id ){ unixFile *pFile = (unixFile*)id; - semUnlock(id, NO_LOCK); + semXUnlock(id, NO_LOCK); assert( pFile ); unixEnterMutex(); releaseInodeInfo(pFile); @@ -4002,7 +3990,9 @@ static int unixDeviceCharacteristics(sqlite3_file *id){ ** Instead, it should be called via macro osGetpagesize(). */ static int unixGetpagesize(void){ -#if defined(_BSD_SOURCE) +#if OS_VXWORKS + return 1024; +#elif defined(_BSD_SOURCE) return getpagesize(); #else return (int)sysconf(_SC_PAGESIZE); @@ -5052,10 +5042,10 @@ IOMETHODS( semIoFinder, /* Finder function name */ semIoMethods, /* sqlite3_io_methods object name */ 1, /* shared memory is disabled */ - semClose, /* xClose method */ - semLock, /* xLock method */ - semUnlock, /* xUnlock method */ - semCheckReservedLock, /* xCheckReservedLock method */ + semXClose, /* xClose method */ + semXLock, /* xLock method */ + semXUnlock, /* xUnlock method */ + semXCheckReservedLock, /* xCheckReservedLock method */ 0 /* xShmMap method */ ) #endif diff --git a/src/shell.c b/src/shell.c index 47b16f4e6f..81bfa0b4b3 100644 --- a/src/shell.c +++ b/src/shell.c @@ -24,6 +24,13 @@ #include "msvc.h" #endif +/* +** No support for loadable extensions in VxWorks. +*/ +#if defined(_WRS_KERNEL) && !SQLITE_OMIT_LOAD_EXTENSION +# define SQLITE_OMIT_LOAD_EXTENSION 1 +#endif + /* ** Enable large-file support for fopen() and friends on unix. */ @@ -107,10 +114,15 @@ */ extern int isatty(int); -/* popen and pclose are not C89 functions and so are sometimes omitted from -** the header */ -extern FILE *popen(const char*,const char*); -extern int pclose(FILE*); +#if !defined(__RTP__) && !defined(_WRS_KERNEL) + /* popen and pclose are not C89 functions and so are sometimes omitted from + ** the header */ + extern FILE *popen(const char*,const char*); + extern int pclose(FILE*); +#else +# define SQLITE_OMIT_POPEN 1 +#endif + #endif #if defined(_WIN32_WCE) @@ -2439,7 +2451,9 @@ static void tryToClone(ShellState *p, const char *zNewDb){ */ static void output_reset(ShellState *p){ if( p->outfile[0]=='|' ){ +#ifndef SQLITE_OMIT_POPEN pclose(p->out); +#endif }else{ output_file_close(p->out); } @@ -2932,9 +2946,14 @@ static int do_meta_command(char *zLine, ShellState *p){ sCtx.zFile = zFile; sCtx.nLine = 1; if( sCtx.zFile[0]=='|' ){ +#ifdef SQLITE_OMIT_POPEN + fprintf(stderr, "Error: pipes are not supporte in this OS\n"); + return 1; +#else sCtx.in = popen(sCtx.zFile+1, "r"); sCtx.zFile = ""; xCloser = pclose; +#endif }else{ sCtx.in = fopen(sCtx.zFile, "rb"); xCloser = fclose; @@ -3257,6 +3276,11 @@ static int do_meta_command(char *zLine, ShellState *p){ } output_reset(p); if( zFile[0]=='|' ){ +#ifdef SQLITE_OMIT_POPEN + fprintf(stderr,"Error: pipes are not supported in this OS\n"); + rc = 1; + p->out = stdout; +#else p->out = popen(zFile + 1, "w"); if( p->out==0 ){ fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1); @@ -3265,6 +3289,7 @@ static int do_meta_command(char *zLine, ShellState *p){ }else{ sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); } +#endif }else{ p->out = output_file_open(zFile); if( p->out==0 ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 4930789c2a..865976659c 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -23,6 +23,11 @@ */ #include "msvc.h" +/* +** Special setup for VxWorks +*/ +#include "vxworks.h" + /* ** These #defines should enable >2GB file support on POSIX if the ** underlying operating system supports it. If the OS lacks diff --git a/src/vxworks.h b/src/vxworks.h new file mode 100644 index 0000000000..45a44453a7 --- /dev/null +++ b/src/vxworks.h @@ -0,0 +1,29 @@ +/* +** 2015-03-02 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains code that is specific to Wind River's VxWorks +*/ +#if defined(__RTP__) || defined(_WRS_KERNEL) +/* This is VxWorks. Set up things specially for that OS +*/ +#include +#include /* amalgamator: dontcache */ +#define OS_VXWORKS 1 +#define SQLITE_OS_OTHER 0 +#define SQLITE_HOMEGROWN_RECURSIVE_MUTEX 1 +#define SQLITE_OMIT_LOAD_EXTENSION 1 +#define SQLITE_ENABLE_LOCKING_STYLE 0 +#define HAVE_UTIME 1 +#else +/* This is not VxWorks. */ +#define OS_VXWORKS 0 +#endif /* defined(_WRS_KERNEL) */ diff --git a/tool/mksqlite3c.tcl b/tool/mksqlite3c.tcl index 4ab8b12b45..fd823385b3 100644 --- a/tool/mksqlite3c.tcl +++ b/tool/mksqlite3c.tcl @@ -119,6 +119,7 @@ foreach hdr { sqliteLimit.h vdbe.h vdbeInt.h + vxworks.h wal.h whereInt.h } { From 3ba689d8baa5973b4dc7a05883c6ef63283f51a5 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 3 Mar 2015 14:00:11 +0000 Subject: [PATCH 07/57] Fix over-length source code lines in the main.c source file. FossilOrigin-Name: debba6f161090bf9db1458fb3767d80d8362a73f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/main.c | 16 ++++++++++------ 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 0fd2ceef53..6d76167d21 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Changes\sso\sthat\sthe\samalgamation\sand\sthe\scommand-line\sshell\sbuild\swithout\nmodifications\son\sVxWorks\s7.\s\sStill\sgives\sa\sfew\scompiler\swarnings,\sand\sstill\nmostly\suntested\son\sthat\splatform. -D 2015-03-02T22:06:43.573 +C Fix\sover-length\ssource\scode\slines\sin\sthe\smain.c\ssource\sfile. +D 2015-03-03T14:00:11.869 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -195,7 +195,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770 F src/loadext.c 86bd4e2fccd520b748cba52492ab60c4a770f660 -F src/main.c 80edeba383aac89f72498b2572a115e21d0ecbbd +F src/main.c 998d6a92f07d7cf55303031f96c5d666a30eb8a5 F src/malloc.c 740db54387204c9a2eb67c6d98e68b08e9ef4eab F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c abe6ee469b6c5a35c7f22bfeb9c9bac664a1c987 @@ -1240,7 +1240,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 17890292cf1776b3334fca7eff693cdbea458304 -R d2f100fda951bb397431a320fd5da8c3 +P 7d92f1f11ee69b0ba7d5a48f0611016d77d41c78 +R 29e1839ec3d428ac80725ec179628136 U drh -Z 298d458a8c4fd11618e1bcf6179fdf9d +Z 6030eba2316c60662ec49bc896566222 diff --git a/manifest.uuid b/manifest.uuid index 98d4babbc9..941f9b8ce5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7d92f1f11ee69b0ba7d5a48f0611016d77d41c78 \ No newline at end of file +debba6f161090bf9db1458fb3767d80d8362a73f \ No newline at end of file diff --git a/src/main.c b/src/main.c index 371bb1fede..a0bb86a116 100644 --- a/src/main.c +++ b/src/main.c @@ -471,7 +471,8 @@ int sqlite3_config(int op, ...){ case SQLITE_CONFIG_HEAP: { /* EVIDENCE-OF: R-19854-42126 There are three arguments to ** SQLITE_CONFIG_HEAP: An 8-byte aligned pointer to the memory, the - ** number of bytes in the memory buffer, and the minimum allocation size. */ + ** number of bytes in the memory buffer, and the minimum allocation size. + */ sqlite3GlobalConfig.pHeap = va_arg(ap, void*); sqlite3GlobalConfig.nHeap = va_arg(ap, int); sqlite3GlobalConfig.mnReq = va_arg(ap, int); @@ -576,7 +577,9 @@ int sqlite3_config(int op, ...){ ** compile-time maximum mmap size set by the SQLITE_MAX_MMAP_SIZE ** compile-time option. */ - if( mxMmap<0 || mxMmap>SQLITE_MAX_MMAP_SIZE ) mxMmap = SQLITE_MAX_MMAP_SIZE; + if( mxMmap<0 || mxMmap>SQLITE_MAX_MMAP_SIZE ){ + mxMmap = SQLITE_MAX_MMAP_SIZE; + } if( szMmap<0 ) szMmap = SQLITE_DEFAULT_MMAP_SIZE; if( szMmap>mxMmap) szMmap = mxMmap; sqlite3GlobalConfig.mxMmap = mxMmap; @@ -2863,7 +2866,8 @@ static int openDatabase( opendb_out: sqlite3_free(zOpen); if( db ){ - assert( db->mutex!=0 || isThreadsafe==0 || sqlite3GlobalConfig.bFullMutex==0 ); + assert( db->mutex!=0 || isThreadsafe==0 + || sqlite3GlobalConfig.bFullMutex==0 ); sqlite3_mutex_leave(db->mutex); } rc = sqlite3_errcode(db); @@ -3608,7 +3612,7 @@ int sqlite3_test_control(int op, ...){ break; } - /* sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, dbName, onOff, tnum); + /* sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, dbName, onOff, tnum); ** ** This test control is used to create imposter tables. "db" is a pointer ** to the database connection. dbName is the database name (ex: "main" or @@ -3617,8 +3621,8 @@ int sqlite3_test_control(int op, ...){ ** table should connect. ** ** Enable imposter mode only when the schema has already been parsed. Then - ** run a single CREATE TABLE statement to construct the imposter table in the - ** parsed schema. Then turn imposter mode back off again. + ** run a single CREATE TABLE statement to construct the imposter table in + ** the parsed schema. Then turn imposter mode back off again. ** ** If onOff==0 and tnum>0 then reset the schema for all databases, causing ** the schema to be reparsed the next time it is needed. This has the From 4a4b1389658a1e2841f07a9ba0690e4214793d26 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 3 Mar 2015 16:58:56 +0000 Subject: [PATCH 08/57] Enhance SQLITE_ALLOW_URI_AUTHORITITY to elide //localhost/ and to deal with dodgy URIs that contain too many "/" characters. FossilOrigin-Name: 39b566a2d0916c57f3fac756c6d6af149b44781d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/main.c | 14 +++++++++++++- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 6d76167d21..97357b8491 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sover-length\ssource\scode\slines\sin\sthe\smain.c\ssource\sfile. -D 2015-03-03T14:00:11.869 +C Enhance\sSQLITE_ALLOW_URI_AUTHORITITY\sto\selide\s//localhost/\sand\sto\sdeal\nwith\sdodgy\sURIs\sthat\scontain\stoo\smany\s"/"\scharacters. +D 2015-03-03T16:58:56.782 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -195,7 +195,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770 F src/loadext.c 86bd4e2fccd520b748cba52492ab60c4a770f660 -F src/main.c 998d6a92f07d7cf55303031f96c5d666a30eb8a5 +F src/main.c 6facbb3214a492d09022ac8414dc83d07d5d5f41 F src/malloc.c 740db54387204c9a2eb67c6d98e68b08e9ef4eab F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c abe6ee469b6c5a35c7f22bfeb9c9bac664a1c987 @@ -1240,7 +1240,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7d92f1f11ee69b0ba7d5a48f0611016d77d41c78 -R 29e1839ec3d428ac80725ec179628136 +P debba6f161090bf9db1458fb3767d80d8362a73f +R c0b7adf9c28144985d9fdda7fbb149ba U drh -Z 6030eba2316c60662ec49bc896566222 +Z 3f9b4ad7f0949adf7d85c9b9b903f5a0 diff --git a/manifest.uuid b/manifest.uuid index 941f9b8ce5..c40b4682a1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -debba6f161090bf9db1458fb3767d80d8362a73f \ No newline at end of file +39b566a2d0916c57f3fac756c6d6af149b44781d \ No newline at end of file diff --git a/src/main.c b/src/main.c index a0bb86a116..c90a95ab80 100644 --- a/src/main.c +++ b/src/main.c @@ -2423,7 +2423,19 @@ int sqlite3ParseUri( if( !zFile ) return SQLITE_NOMEM; iIn = 5; -#ifndef SQLITE_ALLOW_URI_AUTHORITY +#ifdef SQLITE_ALLOW_URI_AUTHORITY + if( strncmp(zUri+5, "///", 3)==0 ){ + iIn = 7; + /* The following condition causes URIs with five leading / characters + ** like file://///host/path to be converted into UNCs like //host/path. + ** The correct URI for that UNC has only two or four leading / characters + ** file://host/path or file:////host/path. But 5 leading slashes is a + ** common error, we are told, so we handle it as a special case. */ + if( strncmp(zUri+7, "///", 3)==0 ){ iIn++; } + }else if( strncmp(zUri+5, "//localhost/", 12)==0 ){ + iIn = 16; + } +#else /* Discard the scheme and authority segments of the URI. */ if( zUri[5]=='/' && zUri[6]=='/' ){ iIn = 7; From 91eb93c797a9aeac8ff1164c82f4a3145f19e7d4 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 3 Mar 2015 19:56:20 +0000 Subject: [PATCH 09/57] Fix compiler warnings when compiling under VxWorks 7. FossilOrigin-Name: 55c21521a64703d7050c7f8975538f4cfae95eb7 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os_unix.c | 42 ++++++++++++++++++++++++------------------ src/shell.c | 14 +++++++++++--- 4 files changed, 43 insertions(+), 29 deletions(-) diff --git a/manifest b/manifest index 97357b8491..d1b20008ac 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sSQLITE_ALLOW_URI_AUTHORITITY\sto\selide\s//localhost/\sand\sto\sdeal\nwith\sdodgy\sURIs\sthat\scontain\stoo\smany\s"/"\scharacters. -D 2015-03-03T16:58:56.782 +C Fix\scompiler\swarnings\swhen\scompiling\sunder\sVxWorks\s7. +D 2015-03-03T19:56:20.675 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -214,7 +214,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 190c726a2881b0b0366cba0906eec80baf6c6781 +F src/os_unix.c 35510fa3a2f38b076a9628557c1ead63bbb49cdc F src/os_win.c 8223e7db5b7c4a81d8b161098ac3959400434cdb F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 4120a49ecd37697e28f5ed807f470b9c0b88410c @@ -231,7 +231,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c f4d79e31ffa5820c2e3d1740baa5e9b190425f2b F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c e46cef4c224549b439384c88fc7f57ba064dad54 -F src/shell.c e2e5b63a759d304c1ada5b77dc5a518dc8e5396c +F src/shell.c cce82ca26392578a4a1ee927dfe55ea3411c7c92 F src/sqlite.h.in 62d3997824038cc32335b04aaa18cc8f4c19e9be F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d @@ -1240,7 +1240,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P debba6f161090bf9db1458fb3767d80d8362a73f -R c0b7adf9c28144985d9fdda7fbb149ba +P 39b566a2d0916c57f3fac756c6d6af149b44781d +R 9a933a4520ccec36872b9bf9ae4c7dcf U drh -Z 3f9b4ad7f0949adf7d85c9b9b903f5a0 +Z d802fbee836547f901f82efaa92d78f9 diff --git a/manifest.uuid b/manifest.uuid index c40b4682a1..149b293ed7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -39b566a2d0916c57f3fac756c6d6af149b44781d \ No newline at end of file +55c21521a64703d7050c7f8975538f4cfae95eb7 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 6e2429880b..a91ab00c67 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -137,6 +137,10 @@ */ #define MAX_PATHNAME 512 +/* Always cast the getpid() return type for compatibility with +** kernel modules in VxWorks. */ +#define osGetpid(X) (pid_t)getpid() + /* ** Only set the lastErrno if the error code is a real error and not ** a normal expected return code of SQLITE_BUSY or SQLITE_OK @@ -1529,7 +1533,8 @@ static int unixLock(sqlite3_file *id, int eFileLock){ assert( pFile ); OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (unix)\n", pFile->h, azFileLock(eFileLock), azFileLock(pFile->eFileLock), - azFileLock(pFile->pInode->eFileLock), pFile->pInode->nShared , getpid())); + azFileLock(pFile->pInode->eFileLock), pFile->pInode->nShared, + osGetpid())); /* If there is already a lock of this type or more restrictive on the ** unixFile, do nothing. Don't use the end_lock: exit path, as @@ -1737,7 +1742,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ assert( pFile ); OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (unix)\n", pFile->h, eFileLock, pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared, - getpid())); + osGetpid())); assert( eFileLock<=SHARED_LOCK ); if( pFile->eFileLock<=eFileLock ){ @@ -2164,7 +2169,7 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) { assert( pFile ); OSTRACE(("UNLOCK %d %d was %d pid=%d (dotlock)\n", pFile->h, eFileLock, - pFile->eFileLock, getpid())); + pFile->eFileLock, osGetpid())); assert( eFileLock<=SHARED_LOCK ); /* no-op if possible */ @@ -2383,7 +2388,7 @@ static int flockUnlock(sqlite3_file *id, int eFileLock) { assert( pFile ); OSTRACE(("UNLOCK %d %d was %d pid=%d (flock)\n", pFile->h, eFileLock, - pFile->eFileLock, getpid())); + pFile->eFileLock, osGetpid())); assert( eFileLock<=SHARED_LOCK ); /* no-op if possible */ @@ -2551,7 +2556,7 @@ static int semXUnlock(sqlite3_file *id, int eFileLock) { assert( pFile ); assert( pSem ); OSTRACE(("UNLOCK %d %d was %d pid=%d (sem)\n", pFile->h, eFileLock, - pFile->eFileLock, getpid())); + pFile->eFileLock, osGetpid())); assert( eFileLock<=SHARED_LOCK ); /* no-op if possible */ @@ -2765,7 +2770,7 @@ static int afpLock(sqlite3_file *id, int eFileLock){ assert( pFile ); OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (afp)\n", pFile->h, azFileLock(eFileLock), azFileLock(pFile->eFileLock), - azFileLock(pInode->eFileLock), pInode->nShared , getpid())); + azFileLock(pInode->eFileLock), pInode->nShared , osGetpid())); /* If there is already a lock of this type or more restrictive on the ** unixFile, do nothing. Don't use the afp_end_lock: exit path, as @@ -2951,7 +2956,7 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) { assert( pFile ); OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (afp)\n", pFile->h, eFileLock, pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared, - getpid())); + osGetpid())); assert( eFileLock<=SHARED_LOCK ); if( pFile->eFileLock<=eFileLock ){ @@ -4621,7 +4626,7 @@ static int unixShmLock( } sqlite3_mutex_leave(pShmNode->mutex); OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n", - p->id, getpid(), p->sharedMask, p->exclMask)); + p->id, osGetpid(), p->sharedMask, p->exclMask)); return rc; } @@ -5718,8 +5723,8 @@ static int unixOpen( ** the same instant might all reset the PRNG. But multiple resets ** are harmless. */ - if( randomnessPid!=getpid() ){ - randomnessPid = getpid(); + if( randomnessPid!=osGetpid() ){ + randomnessPid = osGetpid(); sqlite3_randomness(0,0); } @@ -6110,7 +6115,7 @@ static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){ ** tests repeatable. */ memset(zBuf, 0, nBuf); - randomnessPid = getpid(); + randomnessPid = osGetpid(); #if !defined(SQLITE_TEST) { int fd, got; @@ -6431,7 +6436,7 @@ static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){ { if( !confstr(_CS_DARWIN_USER_TEMP_DIR, lPath, maxLen) ){ OSTRACE(("GETLOCKPATH failed %s errno=%d pid=%d\n", - lPath, errno, getpid())); + lPath, errno, osGetpid())); return SQLITE_IOERR_LOCK; } len = strlcat(lPath, "sqliteplocks", maxLen); @@ -6453,7 +6458,7 @@ static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){ } lPath[i+len]='\0'; strlcat(lPath, ":auto:", maxLen); - OSTRACE(("GETLOCKPATH proxy lock path=%s pid=%d\n", lPath, getpid())); + OSTRACE(("GETLOCKPATH proxy lock path=%s pid=%d\n", lPath, osGetpid())); return SQLITE_OK; } @@ -6480,7 +6485,7 @@ static int proxyCreateLockPath(const char *lockPath){ if( err!=EEXIST ) { OSTRACE(("CREATELOCKPATH FAILED creating %s, " "'%s' proxy lock path=%s pid=%d\n", - buf, strerror(err), lockPath, getpid())); + buf, strerror(err), lockPath, osGetpid())); return err; } } @@ -6489,7 +6494,7 @@ static int proxyCreateLockPath(const char *lockPath){ } buf[i] = lockPath[i]; } - OSTRACE(("CREATELOCKPATH proxy lock path=%s pid=%d\n", lockPath, getpid())); + OSTRACE(("CREATELOCKPATH proxy lock path=%s pid=%d\n", lockPath, osGetpid())); return 0; } @@ -6794,7 +6799,8 @@ static int proxyTakeConch(unixFile *pFile){ int forceNewLockPath = 0; OSTRACE(("TAKECONCH %d for %s pid=%d\n", conchFile->h, - (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), getpid())); + (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), + osGetpid())); rc = proxyGetHostID(myHostID, &pError); if( (rc&0xff)==SQLITE_IOERR ){ @@ -7004,7 +7010,7 @@ static int proxyReleaseConch(unixFile *pFile){ conchFile = pCtx->conchFile; OSTRACE(("RELEASECONCH %d for %s pid=%d\n", conchFile->h, (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), - getpid())); + osGetpid())); if( pCtx->conchHeld>0 ){ rc = conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK); } @@ -7146,7 +7152,7 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) { } OSTRACE(("TRANSPROXY %d for %s pid=%d\n", pFile->h, - (lockPath ? lockPath : ":auto:"), getpid())); + (lockPath ? lockPath : ":auto:"), osGetpid())); pCtx = sqlite3_malloc( sizeof(*pCtx) ); if( pCtx==0 ){ diff --git a/src/shell.c b/src/shell.c index 81bfa0b4b3..cf2481a37c 100644 --- a/src/shell.c +++ b/src/shell.c @@ -177,11 +177,19 @@ static sqlite3_int64 timeOfDay(void){ return t; } -#if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL) \ - && !defined(__minux) +#if !defined(_WIN32) && !defined(WIN32) && !defined(__minux) #include #include +/* VxWorks does not support getrusage() as far as we can determine */ +#if defined(_WRS_KERNEL) || defined(__RTP__) +struct rusage { + struct timeval ru_utime; /* user CPU time used */ + struct timeval ru_stime; /* system CPU time used */ +}; +#define getrusage(A,B) memset(B,0,sizeof(*B)) +#endif + /* Saved resource information for the beginning of an operation */ static struct rusage sBegin; /* CPU time at start */ static sqlite3_int64 iBegin; /* Wall-clock time at start */ @@ -207,8 +215,8 @@ static double timeDiff(struct timeval *pStart, struct timeval *pEnd){ */ static void endTimer(void){ if( enableTimer ){ - struct rusage sEnd; sqlite3_int64 iEnd = timeOfDay(); + struct rusage sEnd; getrusage(RUSAGE_SELF, &sEnd); printf("Run Time: real %.3f user %f sys %f\n", (iEnd - iBegin)*0.001, From e89b291828b54933bf44f79c142c87061aacdced Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 3 Mar 2015 20:42:01 +0000 Subject: [PATCH 10/57] Clean up #ifdef logic dealing with VxWorks in os_unix.c. On VxWorks, automatically use posix advisory locking if it is available or fall back to named semaphore locking if not. FossilOrigin-Name: ac8c7ca3db14ec19be1f19cfaf14b47fdda0c9ef --- manifest | 12 +++++------ manifest.uuid | 2 +- src/os_unix.c | 58 +++++++++++++++++++++++++-------------------------- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/manifest b/manifest index d1b20008ac..86174ec86e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\scompiler\swarnings\swhen\scompiling\sunder\sVxWorks\s7. -D 2015-03-03T19:56:20.675 +C Clean\sup\s#ifdef\slogic\sdealing\swith\sVxWorks\sin\sos_unix.c.\s\sOn\sVxWorks,\s\nautomatically\suse\sposix\sadvisory\slocking\sif\sit\sis\savailable\sor\sfall\sback\nto\snamed\ssemaphore\slocking\sif\snot. +D 2015-03-03T20:42:01.828 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -214,7 +214,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 35510fa3a2f38b076a9628557c1ead63bbb49cdc +F src/os_unix.c 49d06acee4053920e4a6429844f440b5f975cea4 F src/os_win.c 8223e7db5b7c4a81d8b161098ac3959400434cdb F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 4120a49ecd37697e28f5ed807f470b9c0b88410c @@ -1240,7 +1240,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 39b566a2d0916c57f3fac756c6d6af149b44781d -R 9a933a4520ccec36872b9bf9ae4c7dcf +P 55c21521a64703d7050c7f8975538f4cfae95eb7 +R 32d4311730abf3951dfa00f9351fabd2 U drh -Z d802fbee836547f901f82efaa92d78f9 +Z e82a4097b0bf48a2167ca03dbf90a10e diff --git a/manifest.uuid b/manifest.uuid index 149b293ed7..0126e5a3d7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -55c21521a64703d7050c7f8975538f4cfae95eb7 \ No newline at end of file +ac8c7ca3db14ec19be1f19cfaf14b47fdda0c9ef \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index a91ab00c67..927b9e1c54 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -85,18 +85,19 @@ # include #endif -#if SQLITE_ENABLE_LOCKING_STYLE || OS_VXWORKS +#if SQLITE_ENABLE_LOCKING_STYLE # include -# if OS_VXWORKS -# include -# include -# else -# include -# include -# endif +# include +# include #endif /* SQLITE_ENABLE_LOCKING_STYLE */ -#if defined(__APPLE__) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS) +#if OS_VXWORKS +# include +# include +# include +#endif /* OS_VXWORKS */ + +#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE # include #endif @@ -377,7 +378,7 @@ static struct unix_syscall { { "read", (sqlite3_syscall_ptr)read, 0 }, #define osRead ((ssize_t(*)(int,void*,size_t))aSyscall[8].pCurrent) -#if defined(USE_PREAD) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS) +#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE { "pread", (sqlite3_syscall_ptr)pread, 0 }, #else { "pread", (sqlite3_syscall_ptr)0, 0 }, @@ -394,7 +395,7 @@ static struct unix_syscall { { "write", (sqlite3_syscall_ptr)write, 0 }, #define osWrite ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent) -#if defined(USE_PREAD) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS) +#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE { "pwrite", (sqlite3_syscall_ptr)pwrite, 0 }, #else { "pwrite", (sqlite3_syscall_ptr)0, 0 }, @@ -2232,10 +2233,9 @@ static int dotlockClose(sqlite3_file *id) { ** still works when you do this, but concurrency is reduced since ** only a single process can be reading the database at a time. ** -** Omit this section if SQLITE_ENABLE_LOCKING_STYLE is turned off or if -** compiling for VXWORKS. +** Omit this section if SQLITE_ENABLE_LOCKING_STYLE is turned off */ -#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS +#if SQLITE_ENABLE_LOCKING_STYLE /* ** Retry flock() calls that fail with EINTR @@ -5029,7 +5029,7 @@ IOMETHODS( 0 /* xShmMap method */ ) -#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS +#if SQLITE_ENABLE_LOCKING_STYLE IOMETHODS( flockIoFinder, /* Finder function name */ flockIoMethods, /* sqlite3_io_methods object name */ @@ -5174,15 +5174,13 @@ static const sqlite3_io_methods #endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ -#if OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE -/* -** This "finder" function attempts to determine the best locking strategy -** for the database file "filePath". It then returns the sqlite3_io_methods -** object that implements that strategy. -** -** This is for VXWorks only. +#if OS_VXWORKS +/* +** This "finder" function for VxWorks checks to see if posix advisory +** locking works. If it does, then that is what is used. If it does not +** work, then fallback to named semaphore locking. */ -static const sqlite3_io_methods *autolockIoFinderImpl( +static const sqlite3_io_methods *vxworksIoFinderImpl( const char *filePath, /* name of the database file */ unixFile *pNew /* the open file object */ ){ @@ -5208,9 +5206,9 @@ static const sqlite3_io_methods *autolockIoFinderImpl( } } static const sqlite3_io_methods - *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl; + *(*const vxworksIoFinder)(const char*,unixFile*) = vxworksIoFinderImpl; -#endif /* OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE */ +#endif /* OS_VXWORKS */ /* ** An abstract type for a pointer to an IO method finder function: @@ -7493,8 +7491,10 @@ int sqlite3_os_init(void){ ** array cannot be const. */ static sqlite3_vfs aVfs[] = { -#if SQLITE_ENABLE_LOCKING_STYLE && (OS_VXWORKS || defined(__APPLE__)) +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) UNIXVFS("unix", autolockIoFinder ), +#elif OS_VXWORKS + UNIXVFS("unix", vxworksIoFinder ), #else UNIXVFS("unix", posixIoFinder ), #endif @@ -7504,11 +7504,11 @@ int sqlite3_os_init(void){ #if OS_VXWORKS UNIXVFS("unix-namedsem", semIoFinder ), #endif -#if SQLITE_ENABLE_LOCKING_STYLE +#if SQLITE_ENABLE_LOCKING_STYLE || OS_VXWORKS UNIXVFS("unix-posix", posixIoFinder ), -#if !OS_VXWORKS - UNIXVFS("unix-flock", flockIoFinder ), #endif +#if SQLITE_ENABLE_LOCKING_STYLE + UNIXVFS("unix-flock", flockIoFinder ), #endif #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) UNIXVFS("unix-afp", afpIoFinder ), From 39f2d0963ee832d8e6c753d863b47bab1c785d51 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 4 Mar 2015 15:25:03 +0000 Subject: [PATCH 11/57] Remove a surplus </dl> mark in the documentation. No changes to code. FossilOrigin-Name: 5450e4650b2dedf3626bbe5a64b680dbd4011173 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 86174ec86e..c60ce48cf9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Clean\sup\s#ifdef\slogic\sdealing\swith\sVxWorks\sin\sos_unix.c.\s\sOn\sVxWorks,\s\nautomatically\suse\sposix\sadvisory\slocking\sif\sit\sis\savailable\sor\sfall\sback\nto\snamed\ssemaphore\slocking\sif\snot. -D 2015-03-03T20:42:01.828 +C Remove\sa\ssurplus\s</dl>\smark\sin\sthe\sdocumentation.\s\sNo\schanges\sto\scode. +D 2015-03-04T15:25:03.791 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -232,7 +232,7 @@ F src/resolve.c f4d79e31ffa5820c2e3d1740baa5e9b190425f2b F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c e46cef4c224549b439384c88fc7f57ba064dad54 F src/shell.c cce82ca26392578a4a1ee927dfe55ea3411c7c92 -F src/sqlite.h.in 62d3997824038cc32335b04aaa18cc8f4c19e9be +F src/sqlite.h.in 884b08c9902c037083893fbe3b0d7b27fd1f0fd5 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d F src/sqliteInt.h fae682c2b4dfbe489b134d74521c41c088f16ab1 @@ -1240,7 +1240,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 55c21521a64703d7050c7f8975538f4cfae95eb7 -R 32d4311730abf3951dfa00f9351fabd2 +P ac8c7ca3db14ec19be1f19cfaf14b47fdda0c9ef +R cd7064c91421e3d1e88aaf5356f37db1 U drh -Z e82a4097b0bf48a2167ca03dbf90a10e +Z 47f3a860dbaf86244f09252ac6904f50 diff --git a/manifest.uuid b/manifest.uuid index 0126e5a3d7..9d2c3e48e7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ac8c7ca3db14ec19be1f19cfaf14b47fdda0c9ef \ No newline at end of file +5450e4650b2dedf3626bbe5a64b680dbd4011173 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index b7cac497e7..baeb7dfcbd 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -1742,7 +1742,6 @@ struct sqlite3_mem_methods { ** compiled for Windows with the [SQLITE_WIN32_MALLOC] pre-processor macro ** defined. ^SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value ** that specifies the maximum size of the created heap. -** ** ** [[SQLITE_CONFIG_PCACHE_HDRSZ]] **
SQLITE_CONFIG_PCACHE_HDRSZ From 33e1327a2205aa53602fbfd32552ac97fec4d1e4 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 4 Mar 2015 15:35:07 +0000 Subject: [PATCH 12/57] Refinement to the wording of the documentation on depreciated functions. FossilOrigin-Name: 04a59d6f7ecbf769bd127a9071348b51ce8463f8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index c60ce48cf9..b86c208eff 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\ssurplus\s</dl>\smark\sin\sthe\sdocumentation.\s\sNo\schanges\sto\scode. -D 2015-03-04T15:25:03.791 +C Refinement\sto\sthe\swording\sof\sthe\sdocumentation\son\sdepreciated\sfunctions. +D 2015-03-04T15:35:07.522 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -232,7 +232,7 @@ F src/resolve.c f4d79e31ffa5820c2e3d1740baa5e9b190425f2b F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c e46cef4c224549b439384c88fc7f57ba064dad54 F src/shell.c cce82ca26392578a4a1ee927dfe55ea3411c7c92 -F src/sqlite.h.in 884b08c9902c037083893fbe3b0d7b27fd1f0fd5 +F src/sqlite.h.in 6ef96b67f33911454cf9deff72036abdcf98ea71 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d F src/sqliteInt.h fae682c2b4dfbe489b134d74521c41c088f16ab1 @@ -1240,7 +1240,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P ac8c7ca3db14ec19be1f19cfaf14b47fdda0c9ef -R cd7064c91421e3d1e88aaf5356f37db1 +P 5450e4650b2dedf3626bbe5a64b680dbd4011173 +R 56547922ea4d7b893e96d2de0edeed04 U drh -Z 47f3a860dbaf86244f09252ac6904f50 +Z 4776ec7c4b1dc2fec453c5541ed697ae diff --git a/manifest.uuid b/manifest.uuid index 9d2c3e48e7..57208e67f6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5450e4650b2dedf3626bbe5a64b680dbd4011173 \ No newline at end of file +04a59d6f7ecbf769bd127a9071348b51ce8463f8 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index baeb7dfcbd..46d89bef05 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -4217,8 +4217,8 @@ int sqlite3_create_function_v2( ** These functions are [deprecated]. In order to maintain ** backwards compatibility with older code, these functions continue ** to be supported. However, new applications should avoid -** the use of these functions. To help encourage people to avoid -** using these functions, we are not going to tell you what they do. +** the use of these functions. To encourage programmers to avoid +** these functions, we will not explain what they do. */ #ifndef SQLITE_OMIT_DEPRECATED SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*); From 0b7ff5c11bea7b8eb9e74ba8d0f65724bba239ed Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 4 Mar 2015 20:18:55 +0000 Subject: [PATCH 13/57] Fix harmless compiler warning. FossilOrigin-Name: 580dae4615353d73c7d096107571bd60fec5b0f2 --- ext/fts3/fts3_snippet.c | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/fts3/fts3_snippet.c b/ext/fts3/fts3_snippet.c index e40750502b..7933e29a7b 100644 --- a/ext/fts3/fts3_snippet.c +++ b/ext/fts3/fts3_snippet.c @@ -1253,7 +1253,7 @@ void sqlite3Fts3Snippet( */ for(iRead=0; iReadnColumn; iRead++){ SnippetFragment sF = {0, 0, 0, 0}; - int iS; + int iS = 0; if( iCol>=0 && iRead!=iCol ) continue; /* Find the best snippet of nFToken tokens in column iRead. */ diff --git a/manifest b/manifest index b86c208eff..3247c90aa4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Refinement\sto\sthe\swording\sof\sthe\sdocumentation\son\sdepreciated\sfunctions. -D 2015-03-04T15:35:07.522 +C Fix\sharmless\scompiler\swarning. +D 2015-03-04T20:18:55.349 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -87,7 +87,7 @@ F ext/fts3/fts3_hash.c 29b986e43f4e9dd40110eafa377dc0d63c422c60 F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf F ext/fts3/fts3_icu.c e319e108661147bcca8dd511cd562f33a1ba81b5 F ext/fts3/fts3_porter.c 3565faf04b626cddf85f03825e86056a4562c009 -F ext/fts3/fts3_snippet.c f16ef6425f92339a8fecc87d9aaf2b12355c78e4 +F ext/fts3/fts3_snippet.c 52c2dcf410b1f9af5a44d81a2cf8c68ed1cb5283 F ext/fts3/fts3_term.c a521f75132f9a495bdca1bdd45949b3191c52763 F ext/fts3/fts3_test.c 8a3a78c4458b2d7c631fcf4b152a5cd656fa7038 F ext/fts3/fts3_tokenize_vtab.c becc661223db7898b213f9e8a23d75bac02408c9 @@ -1240,7 +1240,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 5450e4650b2dedf3626bbe5a64b680dbd4011173 -R 56547922ea4d7b893e96d2de0edeed04 -U drh -Z 4776ec7c4b1dc2fec453c5541ed697ae +P 04a59d6f7ecbf769bd127a9071348b51ce8463f8 +R eb7760e5f73fea42d82f7f1da509727f +U mistachkin +Z c6ab24c8fd379ad2586877483b56d26f diff --git a/manifest.uuid b/manifest.uuid index 57208e67f6..a2bb6e0dc6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -04a59d6f7ecbf769bd127a9071348b51ce8463f8 \ No newline at end of file +580dae4615353d73c7d096107571bd60fec5b0f2 \ No newline at end of file From 682a6ef6bd5caefc82a2c87e343c5929e13f3ac0 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 4 Mar 2015 23:14:14 +0000 Subject: [PATCH 14/57] New requirements marks on INSERT and INDEXED BY and on some sqlite3_config() options. FossilOrigin-Name: c298ea0bd90d63673435bf8ceafbaeba3db6187d --- manifest | 18 ++++++++--------- manifest.uuid | 2 +- src/main.c | 22 +++++++++++--------- test/e_insert.test | 6 +++--- test/indexedby.test | 49 ++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 71 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index 3247c90aa4..93ce056e11 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarning. -D 2015-03-04T20:18:55.349 +C New\srequirements\smarks\son\sINSERT\sand\sINDEXED\sBY\sand\son\ssome\ssqlite3_config()\noptions. +D 2015-03-04T23:14:14.129 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -195,7 +195,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770 F src/loadext.c 86bd4e2fccd520b748cba52492ab60c4a770f660 -F src/main.c 6facbb3214a492d09022ac8414dc83d07d5d5f41 +F src/main.c fa997fa27d95febc16d57095299384b667a7f762 F src/malloc.c 740db54387204c9a2eb67c6d98e68b08e9ef4eab F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c abe6ee469b6c5a35c7f22bfeb9c9bac664a1c987 @@ -471,7 +471,7 @@ F test/e_dropview.test 0c9f7f60989164a70a67a9d9c26d1083bc808306 F test/e_expr.test 8f5fdd7261e2d746813b0c6a1c0e34824ad3c5ad F test/e_fkey.test a1783fe1f759e1990e6a11adfcf0702dac4d0707 F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459 -F test/e_insert.test 7b2fa9cd1456f83474d6c5d27db3abaeb8be2023 +F test/e_insert.test 0e63edc037afe738bb81a626a676811ed7862c90 F test/e_reindex.test 396b7b4f0a66863b4e95116a67d93b227193e589 F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6 F test/e_select.test 52692ff3849541e828ad4661fe3773a9b8711763 @@ -655,7 +655,7 @@ F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6 F test/index5.test 25b0b451aceed4ac5f7d49f856f6de7257470b3e F test/index6.test 3ae54e53c53f2adcacda269237d8e52bdb05a481 F test/index7.test 917cf1e1c7439bb155abbeabec511b28945e157b -F test/indexedby.test b2f22f3e693a53813aa3f50b812eb609ba6df1ec +F test/indexedby.test 5f527a78bae74c61b8046ae3037f9dfb0bf0c353 F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 F test/insert.test 38742b5e9601c8f8d76e9b7555f7270288c2d371 @@ -1240,7 +1240,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 04a59d6f7ecbf769bd127a9071348b51ce8463f8 -R eb7760e5f73fea42d82f7f1da509727f -U mistachkin -Z c6ab24c8fd379ad2586877483b56d26f +P 580dae4615353d73c7d096107571bd60fec5b0f2 +R 83bea64f65ae4623fef6afe49023010e +U drh +Z 9817df219f494c0715d6d5afc55f3ce5 diff --git a/manifest.uuid b/manifest.uuid index a2bb6e0dc6..b63fbb1519 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -580dae4615353d73c7d096107571bd60fec5b0f2 \ No newline at end of file +c298ea0bd90d63673435bf8ceafbaeba3db6187d \ No newline at end of file diff --git a/src/main.c b/src/main.c index c90a95ab80..092cbf8415 100644 --- a/src/main.c +++ b/src/main.c @@ -340,26 +340,28 @@ int sqlite3_config(int op, ...){ */ #if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-54466-46756 */ case SQLITE_CONFIG_SINGLETHREAD: { - /* Disable all mutexing */ - sqlite3GlobalConfig.bCoreMutex = 0; - sqlite3GlobalConfig.bFullMutex = 0; + /* EVIDENCE-OF: R-02748-19096 This option sets the threading mode to + ** Single-thread. */ + sqlite3GlobalConfig.bCoreMutex = 0; /* Disable mutex on core */ + sqlite3GlobalConfig.bFullMutex = 0; /* Disable mutex on connections */ break; } #endif #if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-20520-54086 */ case SQLITE_CONFIG_MULTITHREAD: { - /* Disable mutexing of database connections */ - /* Enable mutexing of core data structures */ - sqlite3GlobalConfig.bCoreMutex = 1; - sqlite3GlobalConfig.bFullMutex = 0; + /* EVIDENCE-OF: R-14374-42468 This option sets the threading mode to + ** Multi-thread. */ + sqlite3GlobalConfig.bCoreMutex = 1; /* Enable mutex on core */ + sqlite3GlobalConfig.bFullMutex = 0; /* Disable mutex on connections */ break; } #endif #if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-59593-21810 */ case SQLITE_CONFIG_SERIALIZED: { - /* Enable all mutexing */ - sqlite3GlobalConfig.bCoreMutex = 1; - sqlite3GlobalConfig.bFullMutex = 1; + /* EVIDENCE-OF: R-41220-51800 This option sets the threading mode to + ** Serialized. */ + sqlite3GlobalConfig.bCoreMutex = 1; /* Enable mutex on core */ + sqlite3GlobalConfig.bFullMutex = 1; /* Enable mutex on connections */ break; } #endif diff --git a/test/e_insert.test b/test/e_insert.test index 0ea4b76bb5..ffafa0ea52 100644 --- a/test/e_insert.test +++ b/test/e_insert.test @@ -348,9 +348,9 @@ do_insert_tests e_insert-3.2 { 6.2 "SELECT * FROM a1" {{} {} {} {}} } -# EVIDENCE-OF: R-46928-50290 The optional conflict-clause allows the -# specification of an alternative constraint conflict resolution -# algorithm to use during this one INSERT command. +# EVIDENCE-OF: R-03235-45250 The "REPLACE" and "INSERT OR action" forms +# specify an alternative constraint conflict resolution algorithm to use +# during this one INSERT command. # # EVIDENCE-OF: R-23110-47146 the parser allows the use of the single # keyword REPLACE as an alias for "INSERT OR REPLACE". diff --git a/test/indexedby.test b/test/indexedby.test index f95c167f64..413bf07422 100644 --- a/test/indexedby.test +++ b/test/indexedby.test @@ -1,4 +1,4 @@ -# 2008 October 4 +# 2008-10-04 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: @@ -9,7 +9,6 @@ # #*********************************************************************** # -# $Id: indexedby.test,v 1.5 2009/03/22 20:36:19 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -58,20 +57,45 @@ do_execsql_test indexedby-1.4 { # attached to a table in the FROM clause, but not to a sub-select or # SQL view. Also test that specifying an index that does not exist or # is attached to a different table is detected as an error. +# +# EVIDENCE-OF: R-63761-48810 -- syntax diagram qualified-table-name # +# EVIDENCE-OF: R-58230-57098 The "INDEXED BY index-name" phrase +# specifies that the named index must be used in order to look up values +# on the preceding table. +# do_test indexedby-2.1 { execsql { SELECT * FROM t1 NOT INDEXED WHERE a = 'one' AND b = 'two'} } {} +do_test indexedby-2.1b { + execsql { SELECT * FROM main.t1 NOT INDEXED WHERE a = 'one' AND b = 'two'} +} {} do_test indexedby-2.2 { execsql { SELECT * FROM t1 INDEXED BY i1 WHERE a = 'one' AND b = 'two'} } {} +do_test indexedby-2.2b { + execsql { SELECT * FROM main.t1 INDEXED BY i1 WHERE a = 'one' AND b = 'two'} +} {} do_test indexedby-2.3 { execsql { SELECT * FROM t1 INDEXED BY i2 WHERE a = 'one' AND b = 'two'} } {} - +# EVIDENCE-OF: R-44699-55558 The INDEXED BY clause does not give the +# optimizer hints about which index to use; it gives the optimizer a +# requirement of which index to use. +# EVIDENCE-OF: R-15800-25719 If index-name does not exist or cannot be +# used for the query, then the preparation of the SQL statement fails. +# do_test indexedby-2.4 { catchsql { SELECT * FROM t1 INDEXED BY i3 WHERE a = 'one' AND b = 'two'} } {1 {no such index: i3}} + +# EVIDENCE-OF: R-62112-42456 If the query optimizer is unable to use the +# index specified by the INDEX BY clause, then the query will fail with +# an error. +do_test indexedby-2.4.1 { + catchsql { SELECT b FROM t1 INDEXED BY i1 WHERE b = 'two' } +} {1 {no query solution}} + do_test indexedby-2.5 { catchsql { SELECT * FROM t1 INDEXED BY i5 WHERE a = 'one' AND b = 'two'} } {1 {no such index: i5}} @@ -82,11 +106,26 @@ do_test indexedby-2.7 { catchsql { SELECT * FROM v1 INDEXED BY i1 WHERE a = 'one' } } {1 {no such index: i1}} + # Tests for single table cases. # +# EVIDENCE-OF: R-37002-28871 The "NOT INDEXED" clause specifies that no +# index shall be used when accessing the preceding table, including +# implied indices create by UNIQUE and PRIMARY KEY constraints. However, +# the rowid can still be used to look up entries even when "NOT INDEXED" +# is specified. +# do_execsql_test indexedby-3.1 { + EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a = 'one' AND b = 'two' +} {/SEARCH TABLE t1 USING INDEX/} +do_execsql_test indexedby-3.1.1 { EXPLAIN QUERY PLAN SELECT * FROM t1 NOT INDEXED WHERE a = 'one' AND b = 'two' } {0 0 0 {SCAN TABLE t1}} +do_execsql_test indexedby-3.1.2 { + EXPLAIN QUERY PLAN SELECT * FROM t1 NOT INDEXED WHERE rowid=1 +} {/SEARCH TABLE t1 USING INTEGER PRIMARY KEY .rowid=/} + + do_execsql_test indexedby-3.2 { EXPLAIN QUERY PLAN SELECT * FROM t1 INDEXED BY i1 WHERE a = 'one' AND b = 'two' @@ -184,6 +223,10 @@ do_execsql_test indexedby-6.2 { EXPLAIN QUERY PLAN SELECT * FROM t1 NOT INDEXED WHERE b = 10 ORDER BY rowid } {0 0 0 {SCAN TABLE t1}} +# EVIDENCE-OF: R-40297-14464 The INDEXED BY phrase forces the SQLite +# query planner to use a particular named index on a DELETE, SELECT, or +# UPDATE statement. +# # Test that "INDEXED BY" can be used in a DELETE statement. # do_execsql_test indexedby-7.1 { From 2af878ec5e8b73e84f7e621c457e7c7be0abc607 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 5 Mar 2015 01:29:51 +0000 Subject: [PATCH 15/57] New requirements marks on compound SELECT statements. FossilOrigin-Name: e7991bc510f63f3594603a91f6f3b32e94d90e72 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/limit.test | 6 ++++++ test/select4.test | 4 ++++ 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 93ce056e11..f479250fca 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\srequirements\smarks\son\sINSERT\sand\sINDEXED\sBY\sand\son\ssome\ssqlite3_config()\noptions. -D 2015-03-04T23:14:14.129 +C New\srequirements\smarks\son\scompound\sSELECT\sstatements. +D 2015-03-05T01:29:51.655 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -691,7 +691,7 @@ F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/like.test e191e536d0fcd722a6b965e7cd1ee0bfd12a5991 F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da -F test/limit.test 3d7df19c35ac672a11f7de406cd3205d592babbb +F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e F test/loadext.test 648cb95f324d1775c54a55c12271b2d1156b633b F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7 F test/lock.test b984ab9034e7389be0d863fe4e64cbbc4d2028f5 @@ -833,7 +833,7 @@ F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5 F test/select1.test fc2a61f226a649393664ad54bc5376631801517c F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56 F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054 -F test/select4.test 8c5a60d439e2df824aed56223566877a883c5c84 +F test/select4.test e20e8ce47b558de80616102ef273704cf0d48a3b F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535 F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0 F test/select7.test 7fd2ef598cfabb6b9ff6ac13973b91d0527df49d @@ -1240,7 +1240,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 580dae4615353d73c7d096107571bd60fec5b0f2 -R 83bea64f65ae4623fef6afe49023010e +P c298ea0bd90d63673435bf8ceafbaeba3db6187d +R 463fdbb558155c6269c69a1bfa40144b U drh -Z 9817df219f494c0715d6d5afc55f3ce5 +Z 5e6a58975b23cba5372f13d3b292c243 diff --git a/manifest.uuid b/manifest.uuid index b63fbb1519..cd3d78b1d6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c298ea0bd90d63673435bf8ceafbaeba3db6187d \ No newline at end of file +e7991bc510f63f3594603a91f6f3b32e94d90e72 \ No newline at end of file diff --git a/test/limit.test b/test/limit.test index 5d6ef336b2..d72749770c 100644 --- a/test/limit.test +++ b/test/limit.test @@ -251,6 +251,12 @@ do_test limit-6.8 { # Make sure LIMIT works well with compound SELECT statements. # Ticket #393 # +# EVIDENCE-OF: R-13512-64012 In a compound SELECT, only the last or +# right-most simple SELECT may contain a LIMIT clause. +# +# EVIDENCE-OF: R-03782-50113 In a compound SELECT, the LIMIT clause +# applies to the entire compound, not just the final SELECT. +# ifcapable compound { do_test limit-7.1.1 { catchsql { diff --git a/test/select4.test b/test/select4.test index 8fc200d434..47a44081f4 100644 --- a/test/select4.test +++ b/test/select4.test @@ -105,6 +105,10 @@ ifcapable subquery { } } {0 1 2 2 3 3 3 3} } + +# EVIDENCE-OF: R-02644-22131 In a compound SELECT statement, only the +# last or right-most simple SELECT may have an ORDER BY clause. +# do_test select4-1.3 { set v [catch {execsql { SELECT DISTINCT log FROM t1 ORDER BY log From 5e7028c21076b5bed58d8412a0d7b085963db6ff Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 5 Mar 2015 14:29:02 +0000 Subject: [PATCH 16/57] Revert "PRAGMA index_info" to output only three columns, for complete compatibility with prior versions. The new "PRAGMA index_xinfo" can be used to get the extra information in 4th, 5th, and 6th columns. FossilOrigin-Name: fc543c2c5ced30a7dc3a05b0c1ad80fdc838df8e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/pragma.c | 32 ++++++++++++++++++++++---------- test/pragma.test | 4 ++-- 4 files changed, 32 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index f479250fca..4b91df0aa9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\srequirements\smarks\son\scompound\sSELECT\sstatements. -D 2015-03-05T01:29:51.655 +C Revert\s"PRAGMA\sindex_info"\sto\soutput\sonly\sthree\scolumns,\sfor\scomplete\ncompatibility\swith\sprior\sversions.\s\sThe\snew\s"PRAGMA\sindex_xinfo"\scan\sbe\nused\sto\sget\sthe\sextra\sinformation\sin\s4th,\s5th,\sand\s6th\scolumns. +D 2015-03-05T14:29:02.994 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -223,7 +223,7 @@ F src/parse.y 0f8e7d60f0ab3cb53d270adef69259ac307d83a8 F src/pcache.c 10539fb959849ad6efff80050541cab3d25089d4 F src/pcache.h b44658c9c932d203510279439d891a2a83e12ba8 F src/pcache1.c 1e77432b40b7d3288327d9cdf399dcdfd2b6d3bf -F src/pragma.c d1abcc070698e5853205dc1d1cd3f01845c1804b +F src/pragma.c 7f51aba7fae823ea5e40280844d722e5ac402a32 F src/pragma.h 09c89bca58e9a44de2116cc8272b8d454657129f F src/prepare.c 173a5a499138451b2561614ecb87d78f9f4644b9 F src/printf.c 8da9a2687a396daa19860f4dc90975d319304744 @@ -788,7 +788,7 @@ F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff F test/permutations.test f9cc1dd987986c9d4949211c7a4ed55ec9aecba1 -F test/pragma.test 64f11ec7f4100e873c67e888a56c33d395cb75d6 +F test/pragma.test 6929a762e8b09f2f29644bc2a330c2265eb44083 F test/pragma2.test f624a496a95ee878e81e59961eade66d5c00c028 F test/pragma3.test 6f849ccffeee7e496d2f2b5e74152306c0b8757c F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552 @@ -1240,7 +1240,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c298ea0bd90d63673435bf8ceafbaeba3db6187d -R 463fdbb558155c6269c69a1bfa40144b +P e7991bc510f63f3594603a91f6f3b32e94d90e72 +R 0612eee82e15bf764eabd621fde6a161 U drh -Z 5e6a58975b23cba5372f13d3b292c243 +Z b1026128d0af596b6f509b65a6cc3523 diff --git a/manifest.uuid b/manifest.uuid index cd3d78b1d6..b040d41ec0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e7991bc510f63f3594603a91f6f3b32e94d90e72 \ No newline at end of file +fc543c2c5ced30a7dc3a05b0c1ad80fdc838df8e \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 75db9a6765..875d9ec006 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1077,17 +1077,27 @@ void sqlite3Pragma( pIdx = sqlite3FindIndex(db, zRight, zDb); if( pIdx ){ int i; - int mx = pPragma->iArg ? pIdx->nColumn : pIdx->nKeyCol; + int mx; + if( pPragma->iArg ){ + /* PRAGMA index_xinfo (newer version with more rows and columns) */ + mx = pIdx->nColumn; + pParse->nMem = 6; + }else{ + /* PRAGMA index_info (legacy version) */ + mx = pIdx->nKeyCol; + pParse->nMem = 3; + } pTab = pIdx->pTable; - sqlite3VdbeSetNumCols(v, 6); - pParse->nMem = 6; + sqlite3VdbeSetNumCols(v, pParse->nMem); sqlite3CodeVerifySchema(pParse, iDb); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", SQLITE_STATIC); sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", SQLITE_STATIC); sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", SQLITE_STATIC); - sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "desc", SQLITE_STATIC); - sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "coll", SQLITE_STATIC); - sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "key", SQLITE_STATIC); + if( pPragma->iArg ){ + sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "desc", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "coll", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "key", SQLITE_STATIC); + } for(i=0; iaiColumn[i]; sqlite3VdbeAddOp2(v, OP_Integer, i, 1); @@ -1097,10 +1107,12 @@ void sqlite3Pragma( }else{ sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pTab->aCol[cnum].zName, 0); } - sqlite3VdbeAddOp2(v, OP_Integer, pIdx->aSortOrder[i], 4); - sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, pIdx->azColl[i], 0); - sqlite3VdbeAddOp2(v, OP_Integer, inKeyCol, 6); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6); + if( pPragma->iArg ){ + sqlite3VdbeAddOp2(v, OP_Integer, pIdx->aSortOrder[i], 4); + sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, pIdx->azColl[i], 0); + sqlite3VdbeAddOp2(v, OP_Integer, inKeyCol, 6); + } + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, pParse->nMem); } } } diff --git a/test/pragma.test b/test/pragma.test index 619fc7fd60..9d7d6aca1a 100644 --- a/test/pragma.test +++ b/test/pragma.test @@ -1751,8 +1751,8 @@ do_test 23.2a { CREATE INDEX i2 ON t1(c,d,b); } capture_pragma db2 out {PRAGMA index_info(i2)} - db2 eval {SELECT cid, name, "desc", coll, "key", '|' FROM out ORDER BY seqno} -} {2 c 0 BINARY 1 | 3 d 0 BINARY 1 | 1 b 0 BINARY 1 |} + db2 eval {SELECT cid, name, '|' FROM out ORDER BY seqno} +} {2 c | 3 d | 1 b |} do_test 23.2b { breakpoint; capture_pragma db2 out {PRAGMA index_xinfo(i2)} From 7be0fd9c58638a97fccbd336506f21d32d1b207e Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 5 Mar 2015 15:34:15 +0000 Subject: [PATCH 17/57] New test cases and requirements marks for PRAGMA index_info, index_xinfo, and index_list. FossilOrigin-Name: e5b13634d9794e4c75378cea89b64c5ecc5aa3e5 --- manifest | 14 +++---- manifest.uuid | 2 +- test/index7.test | 34 ++++++++++++++++ test/pragma.test | 102 +++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 140 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 4b91df0aa9..00a911ceec 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Revert\s"PRAGMA\sindex_info"\sto\soutput\sonly\sthree\scolumns,\sfor\scomplete\ncompatibility\swith\sprior\sversions.\s\sThe\snew\s"PRAGMA\sindex_xinfo"\scan\sbe\nused\sto\sget\sthe\sextra\sinformation\sin\s4th,\s5th,\sand\s6th\scolumns. -D 2015-03-05T14:29:02.994 +C New\stest\scases\sand\srequirements\smarks\sfor\sPRAGMA\sindex_info,\sindex_xinfo,\nand\sindex_list. +D 2015-03-05T15:34:15.760 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -654,7 +654,7 @@ F test/index3.test 55a90cff99834305e8141df7afaef39674b57062 F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6 F test/index5.test 25b0b451aceed4ac5f7d49f856f6de7257470b3e F test/index6.test 3ae54e53c53f2adcacda269237d8e52bdb05a481 -F test/index7.test 917cf1e1c7439bb155abbeabec511b28945e157b +F test/index7.test 3d54dce09344c4530ea39a458aa304da044c887a F test/indexedby.test 5f527a78bae74c61b8046ae3037f9dfb0bf0c353 F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 @@ -788,7 +788,7 @@ F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff F test/permutations.test f9cc1dd987986c9d4949211c7a4ed55ec9aecba1 -F test/pragma.test 6929a762e8b09f2f29644bc2a330c2265eb44083 +F test/pragma.test ad99d05e411c7687302124be56f3b362204be041 F test/pragma2.test f624a496a95ee878e81e59961eade66d5c00c028 F test/pragma3.test 6f849ccffeee7e496d2f2b5e74152306c0b8757c F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552 @@ -1240,7 +1240,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e7991bc510f63f3594603a91f6f3b32e94d90e72 -R 0612eee82e15bf764eabd621fde6a161 +P fc543c2c5ced30a7dc3a05b0c1ad80fdc838df8e +R db9f4f2755acee2cbbb8badacd04c339 U drh -Z b1026128d0af596b6f509b65a6cc3523 +Z 2b5470d505e73b65c2166edb9eeee198 diff --git a/manifest.uuid b/manifest.uuid index b040d41ec0..f4c97618c5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fc543c2c5ced30a7dc3a05b0c1ad80fdc838df8e \ No newline at end of file +e5b13634d9794e4c75378cea89b64c5ecc5aa3e5 \ No newline at end of file diff --git a/test/index7.test b/test/index7.test index 0f341a3129..9a2444a87e 100644 --- a/test/index7.test +++ b/test/index7.test @@ -21,6 +21,31 @@ ifcapable !vtab { return } +# Capture the output of a pragma in a TEMP table. +# +proc capture_pragma {db tabname sql} { + $db eval "DROP TABLE IF EXISTS temp.$tabname" + set once 1 + $db eval $sql x { + if {$once} { + set once 0 + set ins "INSERT INTO $tabname VALUES" + set crtab "CREATE TEMP TABLE $tabname " + set sep "(" + foreach col $x(*) { + append ins ${sep}\$x($col) + append crtab ${sep}\"$col\" + set sep , + } + append ins ) + append crtab ) + $db eval $crtab + } + $db eval $ins + } +} + + load_static_extension db wholenumber; do_test index7-1.1 { # Able to parse and manage partial indices @@ -37,6 +62,15 @@ do_test index7-1.1 { } } {14 20 ok} +# (The "partial" column of the PRAGMA index_list output is...) +# EVIDENCE-OF: R-34457-09668 "1" if the index is a partial index and "0" +# if not. +# +do_test index7-1.1a { + capture_pragma db out {PRAGMA index_list(t1)} + db eval {SELECT "name", "partial", '|' FROM out ORDER BY "name"} +} {sqlite_autoindex_t1_1 0 | t1a 1 | t1b 1 |} + # Make sure the count(*) optimization works correctly with # partial indices. Ticket [a5c8ed66cae16243be6] 2013-10-03. # diff --git a/test/pragma.test b/test/pragma.test index 9d7d6aca1a..d164702643 100644 --- a/test/pragma.test +++ b/test/pragma.test @@ -668,6 +668,37 @@ do_test pragma-6.5.1 { } db eval {SELECT seqno, cid, name FROM out ORDER BY seqno} } {0 0 a 1 1 b} + +# EVIDENCE-OF: R-23114-21695 The auxiliary index-columns are not shown +# by the index_info pragma, but they are listed by the index_xinfo +# pragma. +# +do_test pragma-6.5.1b { + capture_pragma db out {PRAGMA index_xinfo(t3i1)} + db eval {SELECT seqno, cid, name FROM out ORDER BY seqno} +} {0 0 a 1 1 b 2 -1 {}} + + +# EVIDENCE-OF: R-62725-03366 PRAGMA database.index_info(index-name); +# This pragma returns one row for each key column in the named index. +# +# (The first column of output from PRAGMA index_info is...) +# EVIDENCE-OF: R-34186-52914 The rank of the column within the index. (0 +# means left-most.) +# +# (The second column of output from PRAGMA index_info is...) +# EVIDENCE-OF: R-65019-08383 The rank of the column within the table +# being indexed. +# +# (The third column of output from PRAGMA index_info is...) +# EVIDENCE-OF: R-09773-34266 The name of the column being indexed. +# +do_execsql_test pragma-6.5.1c { + CREATE INDEX t3i2 ON t3(b,a); + PRAGMA index_info='t3i2'; + DROP INDEX t3i2; +} {0 1 b 1 0 a} + do_test pragma-6.5.2 { execsql { pragma index_info(t3i1_bogus); @@ -725,6 +756,9 @@ do_test pragma-6.7 { # Miscellaneous tests # ifcapable schema_pragmas { +# EVIDENCE-OF: R-63500-32024 PRAGMA database.index_list(table-name); +# This pragma returns one row for each index associated with the given +# table. do_test pragma-7.1.1 { # Make sure a pragma knows to read the schema if it needs to db close @@ -1741,10 +1775,11 @@ do_test 23.1 { CREATE TABLE t1(a INTEGER PRIMARY KEY,b,c,d); CREATE INDEX i1 ON t1(b,c); CREATE INDEX i2 ON t1(c,d); + CREATE INDEX i2x ON t1(d COLLATE nocase, c DESC); CREATE TABLE t2(x INTEGER REFERENCES t1); } db2 eval {SELECT name FROM sqlite_master} -} {t1 i1 i2 t2} +} {t1 i1 i2 i2x t2} do_test 23.2a { db eval { DROP INDEX i2; @@ -1753,18 +1788,77 @@ do_test 23.2a { capture_pragma db2 out {PRAGMA index_info(i2)} db2 eval {SELECT cid, name, '|' FROM out ORDER BY seqno} } {2 c | 3 d | 1 b |} + +# EVIDENCE-OF: R-44874-46325 PRAGMA database.index_xinfo(index-name); +# This pragma returns information about every column in an index. +# +# EVIDENCE-OF: R-45970-35618 Unlike this index_info pragma, this pragma +# returns information about every column in the index, not just the key +# columns. +# do_test 23.2b { -breakpoint; capture_pragma db2 out {PRAGMA index_xinfo(i2)} db2 eval {SELECT cid, name, "desc", coll, "key", '|' FROM out ORDER BY seqno} } {2 c 0 BINARY 1 | 3 d 0 BINARY 1 | 1 b 0 BINARY 1 | -1 {} 0 BINARY 0 |} + +# (The first column of output from PRAGMA index_xinfo is...) +# EVIDENCE-OF: R-00197-14279 The rank of the column within the index. (0 +# means left-most. Key columns come before auxiliary columns.) +# +# (The second column of output from PRAGMA index_xinfo is...) +# EVIDENCE-OF: R-40889-06838 The rank of the column within the table +# being indexed, or -1 if the index-column is the rowid of the table +# being indexed. +# +# (The third column of output from PRAGMA index_xinfo is...) +# EVIDENCE-OF: R-22751-28901 The name of the column being indexed, or +# NULL if the index-column is the rowid of the table being indexed. +# +# (The fourth column of output from PRAGMA index_xinfo is...) +# EVIDENCE-OF: R-11847-09179 1 if the index-column is sorted in reverse +# (DESC) order by the index and 0 otherwise. +# +# (The fifth column of output from PRAGMA index_xinfo is...) +# EVIDENCE-OF: R-15313-19540 The name for the collating sequence used to +# compare values in the index-column. +# +# (The sixth column of output from PRAGMA index_xinfo is...) +# EVIDENCE-OF: R-14310-64553 1 if the index-column is a key column and 0 +# if the index-column is an auxiliary column. +# +do_test 23.2c { + db2 eval {PRAGMA index_xinfo(i2)} +} {0 2 c 0 BINARY 1 1 3 d 0 BINARY 1 2 1 b 0 BINARY 1 3 -1 {} 0 BINARY 0} +do_test 23.2d { + db2 eval {PRAGMA index_xinfo(i2x)} +} {0 3 d 0 nocase 1 1 2 c 1 BINARY 1 2 -1 {} 0 BINARY 0} + +# EVIDENCE-OF: R-63500-32024 PRAGMA database.index_list(table-name); +# This pragma returns one row for each index associated with the given +# table. +# +# (The first column of output from PRAGMA index_list is...) +# EVIDENCE-OF: R-02753-24748 A sequence number assigned to each index +# for internal tracking purposes. +# +# (The second column of output from PRAGMA index_list is...) +# EVIDENCE-OF: R-35496-03635 The name of the index. +# +# (The third column of output from PRAGMA index_list is...) +# EVIDENCE-OF: R-57301-64506 "1" if the index is UNIQUE and "0" if not. +# +# (The fourth column of output from PRAGMA index_list is...) +# EVIDENCE-OF: R-36609-39554 "c" if the index was created by a CREATE +# INDEX statement, "u" if the index was created by a UNIQUE constraint, +# or "pk" if the index was created by a PRIMARY KEY constraint. +# do_test 23.3 { db eval { CREATE INDEX i3 ON t1(d,b,c); } capture_pragma db2 out {PRAGMA index_list(t1)} - db2 eval {SELECT name, "unique", origin FROM out ORDER BY seq} -} {i3 0 c i2 0 c i1 0 c} + db2 eval {SELECT seq, name, "unique", origin, '|' FROM out ORDER BY seq} +} {0 i3 0 c | 1 i2 0 c | 2 i2x 0 c | 3 i1 0 c |} do_test 23.4 { db eval { ALTER TABLE t1 ADD COLUMN e; From 0266c05fcbff4063f3a83dad05e6b6a2235e7c38 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 6 Mar 2015 03:31:58 +0000 Subject: [PATCH 18/57] Clarification of documentation on sqlite3_backup. FossilOrigin-Name: 31d5e9b42e5c96207187dcde1cbbb1e79f26fca2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 24 ++++++++++++------------ 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 00a911ceec..ff068474f4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\stest\scases\sand\srequirements\smarks\sfor\sPRAGMA\sindex_info,\sindex_xinfo,\nand\sindex_list. -D 2015-03-05T15:34:15.760 +C Clarification\sof\sdocumentation\son\ssqlite3_backup. +D 2015-03-06T03:31:58.777 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -232,7 +232,7 @@ F src/resolve.c f4d79e31ffa5820c2e3d1740baa5e9b190425f2b F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c e46cef4c224549b439384c88fc7f57ba064dad54 F src/shell.c cce82ca26392578a4a1ee927dfe55ea3411c7c92 -F src/sqlite.h.in 6ef96b67f33911454cf9deff72036abdcf98ea71 +F src/sqlite.h.in 01d70ea11cfc033f2026e725f22c39936e9ea3d1 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d F src/sqliteInt.h fae682c2b4dfbe489b134d74521c41c088f16ab1 @@ -1240,7 +1240,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P fc543c2c5ced30a7dc3a05b0c1ad80fdc838df8e -R db9f4f2755acee2cbbb8badacd04c339 +P e5b13634d9794e4c75378cea89b64c5ecc5aa3e5 +R 2fcf8a15273b53b5f7ba658720892ca0 U drh -Z 2b5470d505e73b65c2166edb9eeee198 +Z 07edb104d96caf5f091f46d1d6c18f99 diff --git a/manifest.uuid b/manifest.uuid index f4c97618c5..691bf89a4d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e5b13634d9794e4c75378cea89b64c5ecc5aa3e5 \ No newline at end of file +31d5e9b42e5c96207187dcde1cbbb1e79f26fca2 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 46d89bef05..130c5fb73f 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -6980,20 +6980,20 @@ typedef struct sqlite3_backup sqlite3_backup; ** is not a permanent error and does not affect the return value of ** sqlite3_backup_finish(). ** -** [[sqlite3_backup__remaining()]] [[sqlite3_backup_pagecount()]] +** [[sqlite3_backup_remaining()]] [[sqlite3_backup_pagecount()]] ** sqlite3_backup_remaining() and sqlite3_backup_pagecount() ** -** ^Each call to sqlite3_backup_step() sets two values inside -** the [sqlite3_backup] object: the number of pages still to be backed -** up and the total number of pages in the source database file. -** The sqlite3_backup_remaining() and sqlite3_backup_pagecount() interfaces -** retrieve these two values, respectively. -** -** ^The values returned by these functions are only updated by -** sqlite3_backup_step(). ^If the source database is modified during a backup -** operation, then the values are not updated to account for any extra -** pages that need to be updated or the size of the source database file -** changing. +** ^The sqlite3_backup_remaining() routine returns the number of pages still +** to be backed up at the conclusion of the most recent sqlite3_backup_step(). +** ^The sqlite3_backup_pagecount() routine returns the total number of pages +** in the source database at the conclusion of the most recent +** sqlite3_backup_step(). +** ^(The values returned by these functions are only updated by +** sqlite3_backup_step(). If the source database is modified in a way that +** changes the size of the source database or the number of pages remaining, +** those changes are not reflected in the output of sqlite3_backup_pagecount() +** and sqlite3_backup_remaining() until after the next +** sqlite3_backup_step().)^ ** ** Concurrent Usage of Database Handles ** From 8dd7a6a9258dda2339b85c993f30f682ad84e21f Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 6 Mar 2015 04:37:26 +0000 Subject: [PATCH 19/57] Clearification of some documentation text. Added requirements marks. FossilOrigin-Name: 8c1e85aab9e0d90726057e25e2ea0663341c070f --- manifest | 26 +++++++++++++------------- manifest.uuid | 2 +- src/pragma.c | 11 +++++++++++ src/sqlite.h.in | 12 ++++++++---- src/test_multiplex.c | 13 +++++++++++++ test/multiplex4.test | 18 ++++++++++++++++++ test/rdonly.test | 5 +++++ test/shrink.test | 3 +++ test/sort4.test | 15 ++++++++++++++- test/sqllimits1.test | 26 ++++++++++++++++++++++++++ 10 files changed, 112 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index ff068474f4..d6db801e6a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Clarification\sof\sdocumentation\son\ssqlite3_backup. -D 2015-03-06T03:31:58.777 +C Clearification\sof\ssome\sdocumentation\stext.\s\sAdded\srequirements\smarks. +D 2015-03-06T04:37:26.939 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -223,7 +223,7 @@ F src/parse.y 0f8e7d60f0ab3cb53d270adef69259ac307d83a8 F src/pcache.c 10539fb959849ad6efff80050541cab3d25089d4 F src/pcache.h b44658c9c932d203510279439d891a2a83e12ba8 F src/pcache1.c 1e77432b40b7d3288327d9cdf399dcdfd2b6d3bf -F src/pragma.c 7f51aba7fae823ea5e40280844d722e5ac402a32 +F src/pragma.c ac4f3f856b4234e85f55b0f069698a4766011100 F src/pragma.h 09c89bca58e9a44de2116cc8272b8d454657129f F src/prepare.c 173a5a499138451b2561614ecb87d78f9f4644b9 F src/printf.c 8da9a2687a396daa19860f4dc90975d319304744 @@ -232,7 +232,7 @@ F src/resolve.c f4d79e31ffa5820c2e3d1740baa5e9b190425f2b F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c e46cef4c224549b439384c88fc7f57ba064dad54 F src/shell.c cce82ca26392578a4a1ee927dfe55ea3411c7c92 -F src/sqlite.h.in 01d70ea11cfc033f2026e725f22c39936e9ea3d1 +F src/sqlite.h.in 356e69db9500b3fd11705c21ca247e19b95884a3 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d F src/sqliteInt.h fae682c2b4dfbe489b134d74521c41c088f16ab1 @@ -266,7 +266,7 @@ F src/test_intarray.h 9dc57417fb65bc7835cc18548852cc08cc062202 F src/test_journal.c 5360fbe1d1e4416ca36290562fd5a2e3f70f32aa F src/test_loadext.c a5251f956ab6af21e138dc1f9c0399394a510cb4 F src/test_malloc.c b9495384e74923aefde8311de974bf9b0f5ba570 -F src/test_multiplex.c 72c0ad1e97af3d6d19975bbd81813072b40c7290 +F src/test_multiplex.c 61edf02530f7511a0529352cd8139ead3af4c401 F src/test_multiplex.h c08e4e8f8651f0c5e0509b138ff4d5b43ed1f5d3 F src/test_mutex.c 293042d623ebba969160f471a82aa1551626454f F src/test_onefile.c 0396f220561f3b4eedc450cef26d40c593c69a25 @@ -753,7 +753,7 @@ F test/mmapfault.test d4c9eff9cd8c2dc14bc43e71e042f175b0a26fe3 F test/multiplex.test efd015ca0b5b4a57dc9535b8feb1273eebeadb60 F test/multiplex2.test 580ca5817c7edbe4cc68fa150609c9473393003a F test/multiplex3.test d228f59eac91839a977eac19f21d053f03e4d101 -F test/multiplex4.test d3e8a5a522c51cbf3ed1c5b0bd496be02c29d7b1 +F test/multiplex4.test e8ae4c4bd70606a5727743241f13b5701990abe4 F test/mutex1.test 78b2b9bb320e51d156c4efdb71b99b051e7a4b41 F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 F test/nan.test e9648b9d007c7045242af35e11a984d4b169443a @@ -803,7 +803,7 @@ F test/quota2.test 7dc12e08b11cbc4c16c9ba2aa2e040ea8d8ab4b8 F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6 F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459 F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df -F test/rdonly.test dd30a4858d8e0fbad2304c2bd74a33d4df36412a +F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8 F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8 F test/reindex.test 44edd3966b474468b823d481eafef0c305022254 F test/releasetest.tcl 13f401c10dd4fe1a2fb811ae6ed27fd7d1300d3c @@ -866,7 +866,7 @@ F test/shell4.test 8a9c08976291e6c6c808b4d718f4a8b299f339f5 F test/shell5.test c04e9f9f948305706b88377c464c7f08ce7479f9 F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5 -F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868 +F test/shrink.test 06deac10d591186017466ce67d10645150bfdeec F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329 F test/skipscan1.test 2ddfe5d168462170c4487f534e2a99fb006b2076 F test/skipscan2.test d1d1450952b7275f0b0a3a981f0230532743951a @@ -878,7 +878,7 @@ F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087 F test/sort.test 3f492e5b7be1d3f756728d2ff6edf4f6091e84cb F test/sort2.test 37afbc03f5559f2eb0f18940b55d38dfbb5172ac F test/sort3.test 6178ade30810ac9166fcdf14b7065e49c0f534e2 -F test/sort4.test d5e8903194ae551551349ce25dc8d0b40ca2b9c3 +F test/sort4.test 5c34d9623a4ae5921d956dfa2b70e77ed0fc6e5c F test/sort5.test a448240a42b49239edc00f85d6d7ac7a1b261e1f F test/sortfault.test d4ccf606a0c77498e2beb542764fd9394acb4d66 F test/speed1.test f2974a91d79f58507ada01864c0e323093065452 @@ -891,7 +891,7 @@ F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b F test/speedtest1.c 2b416dca3a155fcaa849540b2e7fc1df12896c23 F test/spellfix.test 24f676831acddd2f4056a598fd731a72c6311f49 -F test/sqllimits1.test 9014524e7ab16e2a4976b13397db4c29cc29c6d9 +F test/sqllimits1.test e05786eaed7950ff6a2d00031d001d8a26131e68 F test/stat.test 76fd746b85459e812a0193410fb599f0531f22de F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9 F test/subquery.test 666fdecceac258f5fd84bed09a64e49d9f37edd9 @@ -1240,7 +1240,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e5b13634d9794e4c75378cea89b64c5ecc5aa3e5 -R 2fcf8a15273b53b5f7ba658720892ca0 +P 31d5e9b42e5c96207187dcde1cbbb1e79f26fca2 +R e3bd9c89d1416be2fa13657fae649477 U drh -Z 07edb104d96caf5f091f46d1d6c18f99 +Z 0cf6c34744d872d2f1bdb9d1e644babc diff --git a/manifest.uuid b/manifest.uuid index 691bf89a4d..aa2a348ab8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -31d5e9b42e5c96207187dcde1cbbb1e79f26fca2 \ No newline at end of file +8c1e85aab9e0d90726057e25e2ea0663341c070f \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 875d9ec006..ef11d5840f 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -317,6 +317,17 @@ void sqlite3Pragma( /* Send an SQLITE_FCNTL_PRAGMA file-control to the underlying VFS ** connection. If it returns SQLITE_OK, then assume that the VFS ** handled the pragma and generate a no-op prepared statement. + ** + ** IMPLEMENTATION-OF: R-12238-55120 Whenever a PRAGMA statement is parsed, + ** an SQLITE_FCNTL_PRAGMA file control is sent to the open sqlite3_file + ** object corresponding to the database file to which the pragma + ** statement refers. + ** + ** IMPLEMENTATION-OF: R-29875-31678 The argument to the SQLITE_FCNTL_PRAGMA + ** file control is an array of pointers to strings (char**) in which the + ** second element of the array is the name of the pragma and the third + ** element is the argument to the pragma or NULL if the pragma has no + ** argument. */ aFcntl[0] = 0; aFcntl[1] = zLeft; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 130c5fb73f..06e0f7eb9f 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -751,14 +751,16 @@ struct sqlite3_io_methods { ** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()] ** interface. ** +**
    +**
  • [[SQLITE_FCNTL_LOCKSTATE]] ** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This ** opcode causes the xFileControl method to write the current state of ** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], ** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) ** into an integer that the pArg argument points to. This capability -** is used during testing and only needs to be supported when SQLITE_TEST -** is defined. -**
      +** is used during testing and is only available when the SQLITE_TEST +** compile-time option is used. +** **
    • [[SQLITE_FCNTL_SIZE_HINT]] ** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS ** layer a hint of how large the database file will grow to be during the @@ -883,7 +885,9 @@ struct sqlite3_io_methods { ** [PRAGMA] processing continues. ^If the [SQLITE_FCNTL_PRAGMA] ** file control returns [SQLITE_OK], then the parser assumes that the ** VFS has handled the PRAGMA itself and the parser generates a no-op -** prepared statement. ^If the [SQLITE_FCNTL_PRAGMA] file control returns +** prepared statement if result string is NULL, or that returns a copy +** of the result string if the string is non-NULL. +** ^If the [SQLITE_FCNTL_PRAGMA] file control returns ** any result code other than [SQLITE_OK] or [SQLITE_NOTFOUND], that means ** that the VFS encountered an error while handling the [PRAGMA] and the ** compilation of the PRAGMA fails with an error. ^The [SQLITE_FCNTL_PRAGMA] diff --git a/src/test_multiplex.c b/src/test_multiplex.c index 8f204c6694..dbd395d620 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -1004,6 +1004,13 @@ static int multiplexFileControl(sqlite3_file *pConn, int op, void *pArg){ break; case SQLITE_FCNTL_PRAGMA: { char **aFcntl = (char**)pArg; + /* + ** EVIDENCE-OF: R-29875-31678 The argument to the SQLITE_FCNTL_PRAGMA + ** file control is an array of pointers to strings (char**) in which the + ** second element of the array is the name of the pragma and the third + ** element is the argument to the pragma or NULL if the pragma has no + ** argument. + */ if( aFcntl[1] && sqlite3_stricmp(aFcntl[1],"multiplex_truncate")==0 ){ if( aFcntl[2] && aFcntl[2][0] ){ if( sqlite3_stricmp(aFcntl[2], "on")==0 @@ -1015,6 +1022,12 @@ static int multiplexFileControl(sqlite3_file *pConn, int op, void *pArg){ pGroup->bTruncate = 0; } } + /* EVIDENCE-OF: R-27806-26076 The handler for an SQLITE_FCNTL_PRAGMA + ** file control can optionally make the first element of the char** + ** argument point to a string obtained from sqlite3_mprintf() or the + ** equivalent and that string will become the result of the pragma + ** or the error message if the pragma fails. + */ aFcntl[0] = sqlite3_mprintf(pGroup->bTruncate ? "on" : "off"); rc = SQLITE_OK; break; diff --git a/test/multiplex4.test b/test/multiplex4.test index 9c304c314d..2caebeadb7 100644 --- a/test/multiplex4.test +++ b/test/multiplex4.test @@ -59,6 +59,14 @@ do_test multiplex4-1.1 { multiplex_file_list mx4test } {mx4test.db} +# NB: The PRAGMA multiplex_truncate command is implemented using the +# SQLITE_FCNTL_PRAGMA file-control... +# +# EVIDENCE-OF: R-12238-55120 Whenever a PRAGMA statement is parsed, an +# SQLITE_FCNTL_PRAGMA file control is sent to the open sqlite3_file +# object corresponding to the database file to which the pragma +# statement refers. +# do_test multiplex4-1.2 { db eval {PRAGMA multiplex_truncate} } {on} @@ -84,6 +92,16 @@ do_test multiplex4-1.9 { db eval {PRAGMA multiplex_truncate=0} } {off} +# EVIDENCE-OF: R-26188-08449 If the SQLITE_FCNTL_PRAGMA file control +# returns SQLITE_OK, then the parser assumes that the VFS has handled +# the PRAGMA itself and the parser generates a no-op prepared statement +# if result string is NULL, or that returns a copy of the result string +# if the string is non-NULL. +# +do_test multiplex4-1.9-explain { + db eval {EXPLAIN PRAGMA multiplex_truncate=0;} +} {/String8 \d \d \d off/} + do_test multiplex4-1.10 { db eval { INSERT INTO t1(x) VALUES(randomblob(250000)); diff --git a/test/rdonly.test b/test/rdonly.test index 938cc7884c..404c613b21 100644 --- a/test/rdonly.test +++ b/test/rdonly.test @@ -32,6 +32,11 @@ do_test rdonly-1.1 { SELECT * FROM t1; } } {1} + +# EVIDENCE-OF: R-29639-16887 The sqlite3_db_readonly(D,N) interface +# returns 1 if the database N of connection D is read-only, 0 if it is +# read/write, or -1 if N is not the name of a database on connection D. +# do_test rdonly-1.1.1 { sqlite3_db_readonly db main } {0} diff --git a/test/shrink.test b/test/shrink.test index e03ebeeb6e..6cc0786d28 100644 --- a/test/shrink.test +++ b/test/shrink.test @@ -24,6 +24,9 @@ do_test shrink-1.1 { INSERT INTO t1 VALUES(randomblob(1000000),1); } set ::baseline sqlite3_memory_used + # EVIDENCE-OF: R-58814-63508 The sqlite3_db_release_memory(D) interface + # attempts to free as much heap memory as possible from database + # connection D. sqlite3_db_release_memory db expr {$::baseline > [sqlite3_memory_used]+500000} } {1} diff --git a/test/sort4.test b/test/sort4.test index 7b913610da..13d9a5999a 100644 --- a/test/sort4.test +++ b/test/sort4.test @@ -25,7 +25,20 @@ sqlite3 db test.db # Configure the sorter to use 3 background threads. -db eval {PRAGMA threads=3} +# +# EVIDENCE-OF: R-19249-32353 SQLITE_LIMIT_WORKER_THREADS The maximum +# number of auxiliary worker threads that a single prepared statement +# may start. +# +do_test sort4-init001 { + db eval {PRAGMA threads=5} + sqlite3_limit db SQLITE_LIMIT_WORKER_THREADS -1 +} {5} +do_test sort4-init002 { + sqlite3_limit db SQLITE_LIMIT_WORKER_THREADS 3 + db eval {PRAGMA threads} +} {3} + # Minimum number of seconds to run for. If the value is 0, each test # is run exactly once. Otherwise, tests are repeated until the timeout diff --git a/test/sqllimits1.test b/test/sqllimits1.test index 57fc931f7c..39e3aedd8f 100644 --- a/test/sqllimits1.test +++ b/test/sqllimits1.test @@ -250,6 +250,9 @@ do_test sqllimits1-4.10.1 { # Test cases sqllimits1-5.* test that the SQLITE_MAX_LENGTH limit # is enforced. # +# EVIDENCE-OF: R-61987-00541 SQLITE_LIMIT_LENGTH The maximum size of any +# string or BLOB or table row, in bytes. +# db close sqlite3 db test.db set LARGESIZE 99999 @@ -406,6 +409,9 @@ unset strvalue # Test cases sqllimits1-6.* test that the SQLITE_MAX_SQL_LENGTH limit # is enforced. # +# EVIDENCE-OF: R-09808-17554 SQLITE_LIMIT_SQL_LENGTH The maximum length +# of an SQL statement, in bytes. +# do_test sqllimits1-6.1 { sqlite3_limit db SQLITE_LIMIT_SQL_LENGTH 50000 set sql "SELECT 1 WHERE 1==1" @@ -567,6 +573,11 @@ do_test sqllimits1-7.7.4 { #-------------------------------------------------------------------- # Test cases sqllimits1-8.* test the SQLITE_MAX_COLUMN limit. # +# EVIDENCE-OF: R-43996-29471 SQLITE_LIMIT_COLUMN The maximum number of +# columns in a table definition or in the result set of a SELECT or the +# maximum number of columns in an index or in an ORDER BY or GROUP BY +# clause. +# set SQLITE_LIMIT_COLUMN 200 sqlite3_limit db SQLITE_LIMIT_COLUMN $SQLITE_LIMIT_COLUMN do_test sqllimits1-8.1 { @@ -670,6 +681,9 @@ do_test sqllimits1-8.11 { # limit is enforced. The limit refers to the number of terms in # the expression. # +# EVIDENCE-OF: R-12723-08526 SQLITE_LIMIT_EXPR_DEPTH The maximum depth +# of the parse tree on any expression. +# if {$SQLITE_MAX_EXPR_DEPTH==0} { puts -nonewline stderr "WARNING: Compile with -DSQLITE_MAX_EXPR_DEPTH to run " puts stderr "tests sqllimits1-9.X" @@ -729,6 +743,9 @@ if 0 { # Test the SQLITE_LIMIT_FUNCTION_ARG limit works. Test case names # match the pattern "sqllimits1-11.*". # +# EVIDENCE-OF: R-59001-45278 SQLITE_LIMIT_FUNCTION_ARG The maximum +# number of arguments on a function. +# for {set max 5} {$max<=$SQLITE_MAX_FUNCTION_ARG} {incr max} { do_test sqllimits1-11.$max.1 { set vals [list] @@ -762,6 +779,9 @@ for {set max 5} {$max<=$SQLITE_MAX_FUNCTION_ARG} {incr max} { #-------------------------------------------------------------------- # Test cases sqllimits1-12.*: Test the SQLITE_MAX_ATTACHED limit. # +# EVIDENCE-OF: R-41778-26203 SQLITE_LIMIT_ATTACHED The maximum number of +# attached databases. +# ifcapable attach { do_test sqllimits1-12.1 { set max $::SQLITE_MAX_ATTACHED @@ -785,6 +805,9 @@ ifcapable attach { # Test cases sqllimits1-13.*: Check that the SQLITE_MAX_VARIABLE_NUMBER # limit works. # +# EVIDENCE-OF: R-42363-29104 SQLITE_LIMIT_VARIABLE_NUMBER The maximum +# index number of any parameter in an SQL statement. +# do_test sqllimits1-13.1 { set max $::SQLITE_MAX_VARIABLE_NUMBER catchsql "SELECT ?[expr {$max+1}] FROM t1" @@ -806,6 +829,9 @@ do_test sqllimits1-13.2 { # implementation by overriding the like() scalar function bypasses # this limitation. # +# EVIDENCE-OF: R-12940-37052 SQLITE_LIMIT_LIKE_PATTERN_LENGTH The +# maximum length of the pattern argument to the LIKE or GLOB operators. +# # These tests check that the limit is not incorrectly applied to # the left-hand-side of the LIKE operator (the string being tested # against the pattern). From f07cf6e2a54866d913ca8a9b4eaae3d3aecb2601 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 6 Mar 2015 16:45:16 +0000 Subject: [PATCH 20/57] The LIKE optimization must be applied twice, once for strings and a second time for BLOBs. Ticket [05f43be8fdda9f]. This check-in is a proof-of-concept of how that might be done. FossilOrigin-Name: 5757e803cb5759b476bbc6453c58340089611420 --- manifest | 19 +++++++++++-------- manifest.uuid | 2 +- src/vdbe.c | 16 ++++++++++++++-- src/where.c | 49 +++++++++++++++++++++++++++++++++++++++++++------ src/whereInt.h | 5 ++++- 5 files changed, 73 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index d6db801e6a..759c643d71 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Clearification\sof\ssome\sdocumentation\stext.\s\sAdded\srequirements\smarks. -D 2015-03-06T04:37:26.939 +C The\sLIKE\soptimization\smust\sbe\sapplied\stwice,\sonce\sfor\sstrings\sand\sa\ssecond\ntime\sfor\sBLOBs.\s\sTicket\s[05f43be8fdda9f].\s\sThis\scheck-in\sis\sa\sproof-of-concept\nof\show\sthat\smight\sbe\sdone. +D 2015-03-06T16:45:16.543 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -293,7 +293,7 @@ F src/update.c 3c4ecc282accf12d39edb8d524cf089645e55a13 F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/util.c 98a7627ca48ad3265b6940915a1d08355eb3fc7e F src/vacuum.c 9460b9de7b2d4e34b0d374894aa6c8a0632be8ec -F src/vdbe.c 991e9b2c38cdc987ed214249b3c72ea73a06fb2e +F src/vdbe.c 6bee3b85a2f013a8fdc496996089d3b6bedfb525 F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3 F src/vdbeInt.h bb56fd199d8af1a2c1b9639ee2f70724b4338e3a F src/vdbeapi.c dac0d0d8009a8aa549cd77d9c29da44c0344f0c4 @@ -307,8 +307,8 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 39303f2c9db02a4e422cd8eb2c8760420c6a51fe F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 -F src/where.c c1b3706929fe918966227f3b91ff433a825037fd -F src/whereInt.h d3633e9b592103241b74b0ec76185f3e5b8b62e0 +F src/where.c b7e82341d2570ac8a051e133cfc44c7eec79a30e +F src/whereInt.h 0ba6257f2a44acd6262f259d5147cd01c52cc45b F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test b35b4cd69fc913f90d39a575e171e1116c3a4bb7 @@ -1240,7 +1240,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 31d5e9b42e5c96207187dcde1cbbb1e79f26fca2 -R e3bd9c89d1416be2fa13657fae649477 +P 8c1e85aab9e0d90726057e25e2ea0663341c070f +R db06eec232964b57030b876196612d14 +T *branch * like-opt-fix +T *sym-like-opt-fix * +T -sym-trunk * U drh -Z 0cf6c34744d872d2f1bdb9d1e644babc +Z 9b71822fa0ca3d1b398ae4d623871060 diff --git a/manifest.uuid b/manifest.uuid index aa2a348ab8..58f48bf654 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8c1e85aab9e0d90726057e25e2ea0663341c070f \ No newline at end of file +5757e803cb5759b476bbc6453c58340089611420 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 39a334f29f..0c9a67e56b 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1015,7 +1015,7 @@ case OP_Real: { /* same as TK_FLOAT, out2-prerelease */ ** Synopsis: r[P2]='P4' ** ** P4 points to a nul terminated UTF-8 string. This opcode is transformed -** into a String before it is executed for the first time. During +** into a String opcode before it is executed for the first time. During ** this transformation, the length of string P4 is computed and stored ** as the P1 parameter. */ @@ -1047,10 +1047,15 @@ case OP_String8: { /* same as TK_STRING, out2-prerelease */ /* Fall through to the next case, OP_String */ } -/* Opcode: String P1 P2 * P4 * +/* Opcode: String P1 P2 P3 P4 P5 ** Synopsis: r[P2]='P4' (len=P1) ** ** The string value P4 of length P1 (bytes) is stored in register P2. +** +** If P5!=0 and the content of register P3 is greater than zero, then +** the datatype of the register P2 is convert to BLOB. The content is +** the same string text, it is merely interpreted as a BLOB as if it +** had been CAST. */ case OP_String: { /* out2-prerelease */ assert( pOp->p4.z!=0 ); @@ -1059,6 +1064,13 @@ case OP_String: { /* out2-prerelease */ pOut->n = pOp->p1; pOut->enc = encoding; UPDATE_MAX_BLOBSIZE(pOut); + if( pOp->p5 ){ + assert( pOp->p3>0 ); + assert( pOp->p3<=(p->nMem-p->nCursor) ); + pIn3 = &aMem[pOp->p3]; + assert( pIn3->flags & MEM_Int ); + if( pIn3->u.i ) pOut->flags = MEM_Blob|MEM_Static|MEM_Term; + } break; } diff --git a/src/where.c b/src/where.c index fedc67a791..82c7e699f4 100644 --- a/src/where.c +++ b/src/where.c @@ -202,7 +202,7 @@ static void whereClauseClear(WhereClause *pWC){ ** calling this routine. Such pointers may be reinitialized by referencing ** the pWC->a[] array. */ -static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){ +static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){ WhereTerm *pTerm; int idx; testcase( wtFlags & TERM_VIRTUAL ); @@ -627,7 +627,11 @@ static void exprAnalyzeAll( ** so and false if not. ** ** In order for the operator to be optimizible, the RHS must be a string -** literal that does not begin with a wildcard. +** literal that does not begin with a wildcard. The LHS must be a column +** that may only be NULL, a string, or a BLOB, never a number. (This means +** that virtual tables cannot participate in the LIKE optimization.) If the +** collating sequence for the column on the LHS must be appropriate for +** the operator. */ static int isLikeOrGlob( Parse *pParse, /* Parsing and code generating context */ @@ -656,7 +660,7 @@ static int isLikeOrGlob( pLeft = pList->a[1].pExpr; if( pLeft->op!=TK_COLUMN || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT - || IsVirtual(pLeft->pTab) + || IsVirtual(pLeft->pTab) /* Value might be numeric */ ){ /* IMP: R-02065-49465 The left-hand side of the LIKE or GLOB operator must ** be the name of an indexed column with TEXT affinity. */ @@ -1286,7 +1290,8 @@ static void exprAnalyze( sqlite3ExprAddCollateToken(pParse,pNewExpr1,&sCollSeqName), pStr1, 0); transferJoinMarkings(pNewExpr1, pExpr); - idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC); + idxNew1 = whereClauseInsert(pWC, pNewExpr1, + TERM_LIKEOPT|TERM_VIRTUAL|TERM_DYNAMIC); testcase( idxNew1==0 ); exprAnalyze(pSrc, pWC, idxNew1); pNewExpr2 = sqlite3ExprDup(db, pLeft, 0); @@ -1294,7 +1299,8 @@ static void exprAnalyze( sqlite3ExprAddCollateToken(pParse,pNewExpr2,&sCollSeqName), pStr2, 0); transferJoinMarkings(pNewExpr2, pExpr); - idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC); + idxNew2 = whereClauseInsert(pWC, pNewExpr2, + TERM_LIKEOPT|TERM_VIRTUAL|TERM_DYNAMIC); testcase( idxNew2==0 ); exprAnalyze(pSrc, pWC, idxNew2); pTerm = &pWC->a[idxTerm]; @@ -2966,7 +2972,21 @@ static void addScanStatus( # define addScanStatus(a, b, c, d) ((void)d) #endif - +/* +** Look at the last instruction coded. If that instruction is OP_String8 +** and if pLoop->iLikeRepCntr is non-zero, then change the P3 to be +** pLoop->iLikeRepCntr and set P5. +** +** This is part of the LIKE optimization. FIXME: Explain in more detail +*/ +static void whereLikeOptimizationStringFixup(Vdbe *v, WhereLevel *pLevel){ + VdbeOp *pOp; + pOp = sqlite3VdbeGetOp(v, -1); + if( pLevel->iLikeRepCntr && ALWAYS(pOp->opcode==OP_String8) ){ + pOp->p3 = pLevel->iLikeRepCntr; + pOp->p5 = 1; + } +} /* ** Generate code for the start of the iLevel-th loop in the WHERE clause @@ -3300,6 +3320,14 @@ static Bitmask codeOneLoopStart( if( pLoop->wsFlags & WHERE_TOP_LIMIT ){ pRangeEnd = pLoop->aLTerm[j++]; nExtraReg = 1; + if( pRangeStart + && (pRangeStart->wtFlags & TERM_LIKEOPT)!=0 + && (pRangeEnd->wtFlags & TERM_LIKEOPT)!=0 + ){ + pLevel->iLikeRepCntr = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLikeRepCntr); + pLevel->addrLikeRep = sqlite3VdbeCurrentAddr(v); + } if( pRangeStart==0 && (j = pIdx->aiColumn[nEq])>=0 && pIdx->pTable->aCol[j].notNull==0 @@ -3342,6 +3370,7 @@ static Bitmask codeOneLoopStart( if( pRangeStart ){ Expr *pRight = pRangeStart->pExpr->pRight; sqlite3ExprCode(pParse, pRight, regBase+nEq); + whereLikeOptimizationStringFixup(v, pLevel); if( (pRangeStart->wtFlags & TERM_VNULL)==0 && sqlite3ExprCanBeNull(pRight) ){ @@ -3387,6 +3416,7 @@ static Bitmask codeOneLoopStart( Expr *pRight = pRangeEnd->pExpr->pRight; sqlite3ExprCacheRemove(pParse, regBase+nEq, 1); sqlite3ExprCode(pParse, pRight, regBase+nEq); + whereLikeOptimizationStringFixup(v, pLevel); if( (pRangeEnd->wtFlags & TERM_VNULL)==0 && sqlite3ExprCanBeNull(pRight) ){ @@ -6595,6 +6625,13 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ sqlite3VdbeJumpHere(v, pLevel->addrSkip); sqlite3VdbeJumpHere(v, pLevel->addrSkip-2); } + if( pLevel->addrLikeRep ){ + addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLikeRepCntr); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_AddImm, pLevel->iLikeRepCntr, 1); + sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrLikeRep); + sqlite3VdbeJumpHere(v, addr); + } if( pLevel->iLeftJoin ){ addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v); assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 diff --git a/src/whereInt.h b/src/whereInt.h index 2ccc6ec064..6a42af47a8 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -69,6 +69,8 @@ struct WhereLevel { int addrCont; /* Jump here to continue with the next loop cycle */ int addrFirst; /* First instruction of interior of the loop */ int addrBody; /* Beginning of the body of this loop */ + int iLikeRepCntr; /* LIKE range processing counter register */ + int addrLikeRep; /* LIKE range processing address */ u8 iFrom; /* Which entry in the FROM clause */ u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */ int p1, p2; /* Operands of the opcode used to ends the loop */ @@ -253,7 +255,7 @@ struct WhereTerm { } u; LogEst truthProb; /* Probability of truth for this expression */ u16 eOperator; /* A WO_xx value describing */ - u8 wtFlags; /* TERM_xxx bit flags. See below */ + u16 wtFlags; /* TERM_xxx bit flags. See below */ u8 nChild; /* Number of children that must disable us */ WhereClause *pWC; /* The clause this term is part of */ Bitmask prereqRight; /* Bitmask of tables used by pExpr->pRight */ @@ -275,6 +277,7 @@ struct WhereTerm { #else # define TERM_VNULL 0x00 /* Disabled if not using stat3 */ #endif +#define TERM_LIKEOPT 0x100 /* Used by the LIKE optimization */ /* ** An instance of the WhereScan object is used as an iterator for locating From 8f1a7ed33f89a56ed58aa99516014dbf0295df64 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 6 Mar 2015 19:47:38 +0000 Subject: [PATCH 21/57] Fix the LIKE optimization even when comparing mixed-case BLOBs. FossilOrigin-Name: a58aafdb4e1422b6a8ffc07a67984928bbedf919 --- manifest | 17 ++++++-------- manifest.uuid | 2 +- src/where.c | 62 ++++++++++++++++++++++++++++++++++++++++---------- src/whereInt.h | 4 +++- 4 files changed, 61 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index 759c643d71..4af39ccdfb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sLIKE\soptimization\smust\sbe\sapplied\stwice,\sonce\sfor\sstrings\sand\sa\ssecond\ntime\sfor\sBLOBs.\s\sTicket\s[05f43be8fdda9f].\s\sThis\scheck-in\sis\sa\sproof-of-concept\nof\show\sthat\smight\sbe\sdone. -D 2015-03-06T16:45:16.543 +C Fix\sthe\sLIKE\soptimization\seven\swhen\scomparing\smixed-case\sBLOBs. +D 2015-03-06T19:47:38.505 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -307,8 +307,8 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 39303f2c9db02a4e422cd8eb2c8760420c6a51fe F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 -F src/where.c b7e82341d2570ac8a051e133cfc44c7eec79a30e -F src/whereInt.h 0ba6257f2a44acd6262f259d5147cd01c52cc45b +F src/where.c cace7eef1838ea22f549e824236eaaa4195b83e6 +F src/whereInt.h cbe4aa57326998d89e7698ca65bb7c28541d483c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test b35b4cd69fc913f90d39a575e171e1116c3a4bb7 @@ -1240,10 +1240,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8c1e85aab9e0d90726057e25e2ea0663341c070f -R db06eec232964b57030b876196612d14 -T *branch * like-opt-fix -T *sym-like-opt-fix * -T -sym-trunk * +P 5757e803cb5759b476bbc6453c58340089611420 +R 1a18426c5e280ce5513288eef4bf379e U drh -Z 9b71822fa0ca3d1b398ae4d623871060 +Z 4902bd060fa099614e1fc5278ee9e5b6 diff --git a/manifest.uuid b/manifest.uuid index 58f48bf654..95ba3aa550 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5757e803cb5759b476bbc6453c58340089611420 \ No newline at end of file +a58aafdb4e1422b6a8ffc07a67984928bbedf919 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 82c7e699f4..24c3843472 100644 --- a/src/where.c +++ b/src/where.c @@ -1264,9 +1264,25 @@ static void exprAnalyze( int idxNew1; int idxNew2; Token sCollSeqName; /* Name of collating sequence */ + const u16 wtFlags = TERM_LIKEOPT | TERM_VIRTUAL | TERM_DYNAMIC; + pTerm->wtFlags |= TERM_LIKE; pLeft = pExpr->x.pList->a[1].pExpr; pStr2 = sqlite3ExprDup(db, pStr1, 0); + + /* Convert the lower bound to upper-case and the upper bound to + ** lower-case (upper-case is less than lower-case in ASCII) so that + ** the range constraints also work for BLOBs + */ + if( noCase && !pParse->db->mallocFailed ){ + int i; + char c; + for(i=0; (c = pStr1->u.zToken[i])!=0; i++){ + pStr1->u.zToken[i] = sqlite3Toupper(c); + pStr2->u.zToken[i] = sqlite3Tolower(c); + } + } + if( !db->mallocFailed ){ u8 c, *pC; /* Last character before the first wildcard */ pC = (u8*)&pStr2->u.zToken[sqlite3Strlen30(pStr2->u.zToken)-1]; @@ -1286,12 +1302,11 @@ static void exprAnalyze( sCollSeqName.z = noCase ? "NOCASE" : "BINARY"; sCollSeqName.n = 6; pNewExpr1 = sqlite3ExprDup(db, pLeft, 0); - pNewExpr1 = sqlite3PExpr(pParse, TK_GE, + pNewExpr1 = sqlite3PExpr(pParse, TK_GE, sqlite3ExprAddCollateToken(pParse,pNewExpr1,&sCollSeqName), pStr1, 0); transferJoinMarkings(pNewExpr1, pExpr); - idxNew1 = whereClauseInsert(pWC, pNewExpr1, - TERM_LIKEOPT|TERM_VIRTUAL|TERM_DYNAMIC); + idxNew1 = whereClauseInsert(pWC, pNewExpr1, wtFlags); testcase( idxNew1==0 ); exprAnalyze(pSrc, pWC, idxNew1); pNewExpr2 = sqlite3ExprDup(db, pLeft, 0); @@ -1299,8 +1314,7 @@ static void exprAnalyze( sqlite3ExprAddCollateToken(pParse,pNewExpr2,&sCollSeqName), pStr2, 0); transferJoinMarkings(pNewExpr2, pExpr); - idxNew2 = whereClauseInsert(pWC, pNewExpr2, - TERM_LIKEOPT|TERM_VIRTUAL|TERM_DYNAMIC); + idxNew2 = whereClauseInsert(pWC, pNewExpr2, wtFlags); testcase( idxNew2==0 ); exprAnalyze(pSrc, pWC, idxNew2); pTerm = &pWC->a[idxTerm]; @@ -2475,20 +2489,37 @@ static int whereInScanEst( ** but joins might run a little slower. The trick is to disable as much ** as we can without disabling too much. If we disabled in (1), we'd get ** the wrong answer. See ticket #813. +** +** If all the children of a term are disabled, then that term is also +** automatically disabled. In this way, terms get disabled if derived +** virtual terms are tested first. For example: +** +** x GLOB 'abc*' AND x>='abc' AND x<'acd' +** \___________/ \______/ \_____/ +** parent child1 child2 +** +** Only the parent term was in the original WHERE clause. The child1 +** and child2 terms were added by the LIKE optimization. If both of +** the virtual child terms are valid, then testing of the parent can be +** skipped. */ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){ - if( pTerm + int nLoop = 0; + while( pTerm && (pTerm->wtFlags & TERM_CODED)==0 && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin)) && (pLevel->notReady & pTerm->prereqAll)==0 ){ - pTerm->wtFlags |= TERM_CODED; - if( pTerm->iParent>=0 ){ - WhereTerm *pOther = &pTerm->pWC->a[pTerm->iParent]; - if( (--pOther->nChild)==0 ){ - disableTerm(pLevel, pOther); - } + if( nLoop && (pTerm->wtFlags & TERM_LIKE)!=0 ){ + pTerm->wtFlags |= TERM_LIKECOND; + }else{ + pTerm->wtFlags |= TERM_CODED; } + if( pTerm->iParent<0 ) break; + pTerm = &pTerm->pWC->a[pTerm->iParent]; + pTerm->nChild--; + if( pTerm->nChild!=0 ) break; + nLoop++; } } @@ -3807,6 +3838,7 @@ static Bitmask codeOneLoopStart( */ for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){ Expr *pE; + int skipLikeAddr = 0; testcase( pTerm->wtFlags & TERM_VIRTUAL ); testcase( pTerm->wtFlags & TERM_CODED ); if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; @@ -3821,7 +3853,13 @@ static Bitmask codeOneLoopStart( if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){ continue; } + if( pTerm->wtFlags & TERM_LIKECOND ){ + assert( pLevel->iLikeRepCntr>0 ); + skipLikeAddr = sqlite3VdbeAddOp1(v, OP_IfZero, pLevel->iLikeRepCntr); + VdbeCoverage(v); + } sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL); + if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr); pTerm->wtFlags |= TERM_CODED; } diff --git a/src/whereInt.h b/src/whereInt.h index 6a42af47a8..04cc2029d8 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -277,7 +277,9 @@ struct WhereTerm { #else # define TERM_VNULL 0x00 /* Disabled if not using stat3 */ #endif -#define TERM_LIKEOPT 0x100 /* Used by the LIKE optimization */ +#define TERM_LIKEOPT 0x100 /* Virtual terms from the LIKE optimization */ +#define TERM_LIKECOND 0x200 /* Conditionally this LIKE operator term */ +#define TERM_LIKE 0x400 /* The original LIKE operator */ /* ** An instance of the WhereScan object is used as an iterator for locating From a9c18a90673169aa9f39dbfff515dded87654691 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 6 Mar 2015 20:49:52 +0000 Subject: [PATCH 22/57] Test cases added. Comments fixed. Proposed solution for ticket [05f43be8fdda9fbd9]. FossilOrigin-Name: 6b993bd54035b67f4d84941e3f444ca79b7feee1 --- manifest | 21 ++++++++-------- manifest.uuid | 2 +- src/vdbe.c | 6 ++--- src/where.c | 19 +++++++++++---- test/analyze3.test | 24 +++++++++---------- test/like.test | 4 ++-- test/like3.test | 60 ++++++++++++++++++++++++++++++++++++++++++++++ test/where8.test | 4 ++-- 8 files changed, 105 insertions(+), 35 deletions(-) create mode 100644 test/like3.test diff --git a/manifest b/manifest index 4af39ccdfb..254c6a0b57 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sLIKE\soptimization\seven\swhen\scomparing\smixed-case\sBLOBs. -D 2015-03-06T19:47:38.505 +C Test\scases\sadded.\s\sComments\sfixed.\s\sProposed\ssolution\sfor\nticket\s[05f43be8fdda9fbd9]. +D 2015-03-06T20:49:52.770 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -293,7 +293,7 @@ F src/update.c 3c4ecc282accf12d39edb8d524cf089645e55a13 F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/util.c 98a7627ca48ad3265b6940915a1d08355eb3fc7e F src/vacuum.c 9460b9de7b2d4e34b0d374894aa6c8a0632be8ec -F src/vdbe.c 6bee3b85a2f013a8fdc496996089d3b6bedfb525 +F src/vdbe.c c9f4ad2c62bccebed38b1fd253064ed2a2c659ae F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3 F src/vdbeInt.h bb56fd199d8af1a2c1b9639ee2f70724b4338e3a F src/vdbeapi.c dac0d0d8009a8aa549cd77d9c29da44c0344f0c4 @@ -307,7 +307,7 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 39303f2c9db02a4e422cd8eb2c8760420c6a51fe F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 -F src/where.c cace7eef1838ea22f549e824236eaaa4195b83e6 +F src/where.c 8cd4fc29addda0945b28b1f849a7998e3749d8b9 F src/whereInt.h cbe4aa57326998d89e7698ca65bb7c28541d483c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -321,7 +321,7 @@ F test/alter4.test c461150723ac957f3b2214aa0b11552cd72023ec F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f F test/analyze.test 1772936d66471c65221e437b6d1999c3a03166c4 -F test/analyze3.test bf41f0f680dd1e0d44eed5e769531e93a5320275 +F test/analyze3.test 75b9e42ea1e4edc919250450dc5762186965d4e6 F test/analyze4.test eff2df19b8dd84529966420f29ea52edc6b56213 F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4 F test/analyze6.test f1c552ce39cca4ec922a7e4e0e5d0203d6b3281f @@ -689,8 +689,9 @@ F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 -F test/like.test e191e536d0fcd722a6b965e7cd1ee0bfd12a5991 +F test/like.test 4f2a71d36a536233727f71995fef900756705e56 F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da +F test/like3.test 9c85587224f739c81b51d8cdd2727c11ec678526 F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e F test/loadext.test 648cb95f324d1775c54a55c12271b2d1156b633b F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7 @@ -1158,7 +1159,7 @@ F test/where4.test d8420ceeb8323a41ceff1f1841fc528e824e1ecf F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2 F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b F test/where7.test 5a4b0abc207d71da4deecd734ad8579e8dd40aa8 -F test/where8.test 806f1dcec4088be2b826b33f757fe6e17c3236a1 +F test/where8.test 2eafe74e01cc10355985874e1ff868ac03dbae5e F test/where8m.test da346596e19d54f0aba35ebade032a7c47d79739 F test/where9.test 729c3ba9b47e8f9f1aab96bae7dad2a524f1d1a2 F test/whereA.test 4d253178d135ec46d1671e440cd8f2b916aa6e6b @@ -1240,7 +1241,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 5757e803cb5759b476bbc6453c58340089611420 -R 1a18426c5e280ce5513288eef4bf379e +P a58aafdb4e1422b6a8ffc07a67984928bbedf919 +R d75eaf03976986bf457292a7b369e1ff U drh -Z 4902bd060fa099614e1fc5278ee9e5b6 +Z 9b58e75e5227e2cbfcfb68532871937f diff --git a/manifest.uuid b/manifest.uuid index 95ba3aa550..7643f85079 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a58aafdb4e1422b6a8ffc07a67984928bbedf919 \ No newline at end of file +6b993bd54035b67f4d84941e3f444ca79b7feee1 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 0c9a67e56b..6adea67960 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1053,9 +1053,9 @@ case OP_String8: { /* same as TK_STRING, out2-prerelease */ ** The string value P4 of length P1 (bytes) is stored in register P2. ** ** If P5!=0 and the content of register P3 is greater than zero, then -** the datatype of the register P2 is convert to BLOB. The content is -** the same string text, it is merely interpreted as a BLOB as if it -** had been CAST. +** the datatype of the register P2 is converted to BLOB. The content is +** the same sequence of bytes, it is merely interpreted as a BLOB instead +** of a string, as if it had been CAST. */ case OP_String: { /* out2-prerelease */ assert( pOp->p4.z!=0 ); diff --git a/src/where.c b/src/where.c index 24c3843472..e79e7d33bc 100644 --- a/src/where.c +++ b/src/where.c @@ -1109,7 +1109,7 @@ static void exprAnalyze( Bitmask extraRight = 0; /* Extra dependencies on LEFT JOIN */ Expr *pStr1 = 0; /* RHS of LIKE/GLOB operator */ int isComplete = 0; /* RHS of LIKE/GLOB ends with wildcard */ - int noCase = 0; /* LIKE/GLOB distinguishes case */ + int noCase = 0; /* uppercase equivalent to lowercase */ int op; /* Top-level operator. pExpr->op */ Parse *pParse = pWInfo->pParse; /* Parsing context */ sqlite3 *db = pParse->db; /* Database connection */ @@ -1247,12 +1247,15 @@ static void exprAnalyze( /* Add constraints to reduce the search space on a LIKE or GLOB ** operator. ** - ** A like pattern of the form "x LIKE 'abc%'" is changed into constraints + ** A like pattern of the form "x LIKE 'aBc%'" is changed into constraints ** - ** x>='abc' AND x<'abd' AND x LIKE 'abc%' + ** x>='ABC' AND x<'abd' AND x LIKE 'aBc%' ** ** The last character of the prefix "abc" is incremented to form the - ** termination condition "abd". + ** termination condition "abd". If case is not significant (the default + ** for LIKE) then the lower-bound is made all uppercase and the upper- + ** bound is made all lowercase so that the bounds also work when comparing + ** BLOBs. */ if( pWC->op==TK_AND && isLikeOrGlob(pParse, pExpr, &pStr1, &isComplete, &noCase) @@ -1266,7 +1269,6 @@ static void exprAnalyze( Token sCollSeqName; /* Name of collating sequence */ const u16 wtFlags = TERM_LIKEOPT | TERM_VIRTUAL | TERM_DYNAMIC; - pTerm->wtFlags |= TERM_LIKE; pLeft = pExpr->x.pList->a[1].pExpr; pStr2 = sqlite3ExprDup(db, pStr1, 0); @@ -1277,6 +1279,7 @@ static void exprAnalyze( if( noCase && !pParse->db->mallocFailed ){ int i; char c; + pTerm->wtFlags |= TERM_LIKE; for(i=0; (c = pStr1->u.zToken[i])!=0; i++){ pStr1->u.zToken[i] = sqlite3Toupper(c); pStr2->u.zToken[i] = sqlite3Tolower(c); @@ -2502,6 +2505,12 @@ static int whereInScanEst( ** and child2 terms were added by the LIKE optimization. If both of ** the virtual child terms are valid, then testing of the parent can be ** skipped. +** +** Usually the parent term is marked as TERM_CODED. But if the parent +** term was originally TERM_LIKE, then the parent gets TERM_LIKECOND instead. +** The TERM_LIKECOND marking indicates that the term should be coded inside +** a conditional such that is only evaluated on the second pass of a +** LIKE-optimization loop, when scanning BLOBs instead of strings. */ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){ int nLoop = 0; diff --git a/test/analyze3.test b/test/analyze3.test index e7416d5730..d22387dcc3 100644 --- a/test/analyze3.test +++ b/test/analyze3.test @@ -281,35 +281,35 @@ do_eqp_test analyze3-2.3 { do_test analyze3-2.4 { sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE 'a%' } -} {101 0 100} +} {102 0 100} do_test analyze3-2.5 { sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE '%a' } } {999 999 100} -do_test analyze3-2.4 { +do_test analyze3-2.6 { set like "a%" sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like } -} {101 0 100} -do_test analyze3-2.5 { +} {102 0 100} +do_test analyze3-2.7 { set like "%a" sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like } } {999 999 100} -do_test analyze3-2.6 { +do_test analyze3-2.8 { set like "a" sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like } -} {101 0 0} -do_test analyze3-2.7 { +} {102 0 0} +do_test analyze3-2.9 { set like "ab" sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like } -} {11 0 0} -do_test analyze3-2.8 { +} {12 0 0} +do_test analyze3-2.10 { set like "abc" sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like } -} {2 0 1} -do_test analyze3-2.9 { +} {3 0 1} +do_test analyze3-2.11 { set like "a_c" sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like } -} {101 0 10} +} {102 0 10} #------------------------------------------------------------------------- diff --git a/test/like.test b/test/like.test index 923272cfb2..18a01dc996 100644 --- a/test/like.test +++ b/test/like.test @@ -749,7 +749,7 @@ ifcapable like_opt&&!icu { count { SELECT a FROM t10 WHERE f LIKE '12%' ORDER BY +a; } - } {12 123 scan 3 like 0} + } {12 123 scan 4 like 0} do_test like-10.6 { count { SELECT a FROM t10 WHERE a LIKE '12%' ORDER BY +a; @@ -790,7 +790,7 @@ ifcapable like_opt&&!icu { count { SELECT a FROM t10b WHERE f GLOB '12*' ORDER BY +a; } - } {12 123 scan 3 like 0} + } {12 123 scan 4 like 0} do_test like-10.15 { count { SELECT a FROM t10b WHERE a GLOB '12*' ORDER BY +a; diff --git a/test/like3.test b/test/like3.test new file mode 100644 index 0000000000..b3af2cda91 --- /dev/null +++ b/test/like3.test @@ -0,0 +1,60 @@ +# 2015-03-06 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file implements regression tests for SQLite library. The +# focus of this file is testing the LIKE and GLOB operators and +# in particular the optimizations that occur to help those operators +# run faster and that those optimizations work correctly when there +# are both strings and blobs being tested. +# +# Ticket 05f43be8fdda9fbd948d374319b99b054140bc36 shows that the following +# SQL was not working correctly: +# +# CREATE TABLE t1(x TEXT UNIQUE COLLATE nocase); +# INSERT INTO t1(x) VALUES(x'616263'); +# SELECT 'query-1', x FROM t1 WHERE x LIKE 'a%'; +# SELECT 'query-2', x FROM t1 WHERE +x LIKE 'a%'; +# +# This script verifies that it works right now. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +do_execsql_test like3-1.1 { + PRAGMA encoding=UTF8; + CREATE TABLE t1(a,b TEXT COLLATE nocase); + INSERT INTO t1(a,b) + VALUES(1,'abc'), + (2,'ABX'), + (3,'BCD'), + (4,x'616263'), + (5,x'414258'), + (6,x'424344'); + CREATE INDEX t1ba ON t1(b,a); + + SELECT a, b FROM t1 WHERE b LIKE 'aB%' ORDER BY +a; +} {1 abc 2 ABX 4 abc 5 ABX} +do_execsql_test like3-1.2 { + SELECT a, b FROM t1 WHERE +b LIKE 'aB%' ORDER BY +a; +} {1 abc 2 ABX 4 abc 5 ABX} + +do_execsql_test like3-1.3 { + CREATE TABLE t2(a, b TEXT); + INSERT INTO t2 SELECT a, b FROM t1; + CREATE INDEX t2ba ON t2(b,a); + SELECT a, b FROM t2 WHERE b GLOB 'ab*' ORDER BY +a; +} {1 abc 4 abc} +do_execsql_test like3-1.4 { + SELECT a, b FROM t2 WHERE +b GLOB 'ab*' ORDER BY +a; +} {1 abc 4 abc} + +finish_test diff --git a/test/where8.test b/test/where8.test index 139251aa07..a155a95ab2 100644 --- a/test/where8.test +++ b/test/where8.test @@ -66,11 +66,11 @@ do_test where8-1.3 { do_test where8-1.4 { execsql_status2 { SELECT c FROM t1 WHERE a > 8 OR b GLOB 't*' } -} {IX X III II 0 0 9} +} {IX X III II 0 0 10} do_test where8-1.5 { execsql_status2 { SELECT c FROM t1 WHERE a > 8 OR b GLOB 'f*' } -} {IX X V IV 0 0 9} +} {IX X V IV 0 0 10} do_test where8-1.6 { execsql_status { SELECT c FROM t1 WHERE a = 1 OR b = 'three' ORDER BY rowid } From 16897072b5bd1dc5970cc7d3259f538424f502ad Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 7 Mar 2015 00:57:37 +0000 Subject: [PATCH 23/57] Refactor some jump opcodes in the VDBE. Add JumpZeroIncr and DecrJumpZero. Fix the LIKE optimization to work with DESC sort order. FossilOrigin-Name: 26cb5145bf52f8c3fffa8c69b6c24aee4d974883 --- manifest | 20 +++++++++--------- manifest.uuid | 2 +- src/func.c | 5 +++++ src/select.c | 19 +++++++---------- src/vdbe.c | 56 +++++++++++++++++++++++++++++++++++++++++-------- src/where.c | 22 ++++++++++++------- test/like3.test | 14 +++++++++++++ 7 files changed, 100 insertions(+), 38 deletions(-) diff --git a/manifest b/manifest index 254c6a0b57..5043d98fbb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Test\scases\sadded.\s\sComments\sfixed.\s\sProposed\ssolution\sfor\nticket\s[05f43be8fdda9fbd9]. -D 2015-03-06T20:49:52.770 +C Refactor\ssome\sjump\sopcodes\sin\sthe\sVDBE.\s\sAdd\sJumpZeroIncr\sand\sDecrJumpZero.\nFix\sthe\sLIKE\soptimization\sto\swork\swith\sDESC\ssort\sorder. +D 2015-03-07T00:57:37.923 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -185,7 +185,7 @@ F src/delete.c 37964e6c1d73ff49cbea9ff690c9605fb15f600e F src/expr.c 3ef111b88ae2941b84b6b6ea4be8d501ba1af0cb F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e0444b61bed271a76840cbe6182df93a9baa3f12 -F src/func.c f7f0f44b0a2cb568a9c42b1b07e613380ee0b9c6 +F src/func.c 44512c557d6d4a40e51f3980c5854ae3e92862d6 F src/global.c 4f77cadbc5427d00139ba43d0f3979804cbb700e F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 @@ -230,7 +230,7 @@ F src/printf.c 8da9a2687a396daa19860f4dc90975d319304744 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c f4d79e31ffa5820c2e3d1740baa5e9b190425f2b F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e -F src/select.c e46cef4c224549b439384c88fc7f57ba064dad54 +F src/select.c 94e016b6733b1d39a2f4c8d431155b4c2897d907 F src/shell.c cce82ca26392578a4a1ee927dfe55ea3411c7c92 F src/sqlite.h.in 356e69db9500b3fd11705c21ca247e19b95884a3 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad @@ -293,7 +293,7 @@ F src/update.c 3c4ecc282accf12d39edb8d524cf089645e55a13 F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/util.c 98a7627ca48ad3265b6940915a1d08355eb3fc7e F src/vacuum.c 9460b9de7b2d4e34b0d374894aa6c8a0632be8ec -F src/vdbe.c c9f4ad2c62bccebed38b1fd253064ed2a2c659ae +F src/vdbe.c 94cbc2115075b1a562a2a702c29ba48e74f85d34 F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3 F src/vdbeInt.h bb56fd199d8af1a2c1b9639ee2f70724b4338e3a F src/vdbeapi.c dac0d0d8009a8aa549cd77d9c29da44c0344f0c4 @@ -307,7 +307,7 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 39303f2c9db02a4e422cd8eb2c8760420c6a51fe F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 -F src/where.c 8cd4fc29addda0945b28b1f849a7998e3749d8b9 +F src/where.c 7c646a15d0d17850e10319aa31662d5ab61c69af F src/whereInt.h cbe4aa57326998d89e7698ca65bb7c28541d483c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -691,7 +691,7 @@ F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/like.test 4f2a71d36a536233727f71995fef900756705e56 F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da -F test/like3.test 9c85587224f739c81b51d8cdd2727c11ec678526 +F test/like3.test f6fa86d6a81d95bd796c46b0e2ba7444669bdd7e F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e F test/loadext.test 648cb95f324d1775c54a55c12271b2d1156b633b F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7 @@ -1241,7 +1241,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a58aafdb4e1422b6a8ffc07a67984928bbedf919 -R d75eaf03976986bf457292a7b369e1ff +P 6b993bd54035b67f4d84941e3f444ca79b7feee1 +R f90848042fe53f442912e9f9b75887d2 U drh -Z 9b58e75e5227e2cbfcfb68532871937f +Z ceb5f3bff4db8044ae0448ec360f04b2 diff --git a/manifest.uuid b/manifest.uuid index 7643f85079..35dc95ffee 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6b993bd54035b67f4d84941e3f444ca79b7feee1 \ No newline at end of file +26cb5145bf52f8c3fffa8c69b6c24aee4d974883 \ No newline at end of file diff --git a/src/func.c b/src/func.c index 30990a30f3..d917bdbec3 100644 --- a/src/func.c +++ b/src/func.c @@ -1650,6 +1650,11 @@ void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){ ** then set aWc[0] through aWc[2] to the wildcard characters and ** return TRUE. If the function is not a LIKE-style function then ** return FALSE. +** +** *pIsNocase is set to true if uppercase and lowercase are equivalent for +** the function (default for LIKE). If the function makes the distinction +** between uppercase and lowercase (as does GLOB) then *pIsNocase is set to +** false. */ int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){ FuncDef *pDef; diff --git a/src/select.c b/src/select.c index 91b3d4345f..a9cecaa390 100644 --- a/src/select.c +++ b/src/select.c @@ -563,20 +563,17 @@ static void pushOntoSorter( } sqlite3VdbeAddOp2(v, op, pSort->iECursor, regRecord); if( pSelect->iLimit ){ - int addr1, addr2; + int addr; int iLimit; if( pSelect->iOffset ){ iLimit = pSelect->iOffset+1; }else{ iLimit = pSelect->iLimit; } - addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, iLimit); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_AddImm, iLimit, -1); - addr2 = sqlite3VdbeAddOp0(v, OP_Goto); - sqlite3VdbeJumpHere(v, addr1); + addr = sqlite3VdbeAddOp3(v, OP_IfNotZero, iLimit, 0, -1); VdbeCoverage(v); sqlite3VdbeAddOp1(v, OP_Last, pSort->iECursor); sqlite3VdbeAddOp1(v, OP_Delete, pSort->iECursor); - sqlite3VdbeJumpHere(v, addr2); + sqlite3VdbeJumpHere(v, addr); } } @@ -973,7 +970,7 @@ static void selectInnerLoop( ** the output for us. */ if( pSort==0 && p->iLimit ){ - sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak); VdbeCoverage(v); } } @@ -1826,7 +1823,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ sqlite3ExprCode(pParse, p->pLimit, iLimit); sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); VdbeCoverage(v); VdbeComment((v, "LIMIT counter")); - sqlite3VdbeAddOp2(v, OP_IfZero, iLimit, iBreak); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, iBreak); VdbeCoverage(v); } if( p->pOffset ){ p->iOffset = iOffset = ++pParse->nMem; @@ -2045,7 +2042,7 @@ static void generateWithRecursiveQuery( selectInnerLoop(pParse, p, p->pEList, iCurrent, 0, 0, pDest, addrCont, addrBreak); if( regLimit ){ - sqlite3VdbeAddOp3(v, OP_IfZero, regLimit, addrBreak, -1); + sqlite3VdbeAddOp2(v, OP_DecrJumpZero, regLimit, addrBreak); VdbeCoverage(v); } sqlite3VdbeResolveLabel(v, addrCont); @@ -2270,7 +2267,7 @@ static int multiSelect( p->iLimit = pPrior->iLimit; p->iOffset = pPrior->iOffset; if( p->iLimit ){ - addr = sqlite3VdbeAddOp1(v, OP_IfZero, p->iLimit); VdbeCoverage(v); + addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v); VdbeComment((v, "Jump ahead if LIMIT reached")); } explainSetInteger(iSub2, pParse->iNextSelectId); @@ -2671,7 +2668,7 @@ static int generateOutputSubroutine( /* Jump to the end of the loop if the LIMIT is reached. */ if( p->iLimit ){ - sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak); VdbeCoverage(v); } /* Generate the subroutine return diff --git a/src/vdbe.c b/src/vdbe.c index 6adea67960..f81bfa8a79 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5585,10 +5585,12 @@ case OP_MemMax: { /* in2 */ /* Opcode: IfPos P1 P2 * * * ** Synopsis: if r[P1]>0 goto P2 ** -** If the value of register P1 is 1 or greater, jump to P2. +** Register P1 must contain an integer. +** If the value of register P1 is 1 or greater, jump to P2 and +** add the literal value P3 to register P1. ** -** It is illegal to use this instruction on a register that does -** not contain an integer. An assertion fault will result if you try. +** If the initial value of register P1 is less than 1, then the +** value is unchanged and control passes through to the next instruction. */ case OP_IfPos: { /* jump, in1 */ pIn1 = &aMem[pOp->p1]; @@ -5617,16 +5619,34 @@ case OP_IfNeg: { /* jump, in1 */ break; } -/* Opcode: IfZero P1 P2 P3 * * -** Synopsis: r[P1]+=P3, if r[P1]==0 goto P2 +/* Opcode: IfNotZero P1 P2 P3 * * +** Synopsis: if r[P1]!=0 then r[P1]+=P3, goto P2 ** -** The register P1 must contain an integer. Add literal P3 to the -** value in register P1. If the result is exactly 0, jump to P2. +** Register P1 must contain an integer. If the content of register P1 is +** initially nonzero, then add P3 to P1 and jump to P2. If register P1 is +** initially zero, leave it unchanged and fall through. */ -case OP_IfZero: { /* jump, in1 */ +case OP_IfNotZero: { /* jump, in1 */ pIn1 = &aMem[pOp->p1]; assert( pIn1->flags&MEM_Int ); - pIn1->u.i += pOp->p3; + VdbeBranchTaken(pIn1->u.i<0, 2); + if( pIn1->u.i ){ + pIn1->u.i += pOp->p3; + pc = pOp->p2 - 1; + } + break; +} + +/* Opcode: DecrJumpZero P1 P2 * * * +** Synopsis: if (--r[P1])==0 goto P2 +** +** Register P1 must hold an integer. Decrement the value in register P1 +** then jump to P2 if the new value is exactly zero. +*/ +case OP_DecrJumpZero: { /* jump, in1 */ + pIn1 = &aMem[pOp->p1]; + assert( pIn1->flags&MEM_Int ); + pIn1->u.i--; VdbeBranchTaken(pIn1->u.i==0, 2); if( pIn1->u.i==0 ){ pc = pOp->p2 - 1; @@ -5634,6 +5654,24 @@ case OP_IfZero: { /* jump, in1 */ break; } + +/* Opcode: JumpZeroIncr P1 P2 * * * +** Synopsis: if (r[P1]++)==0 ) goto P2 +** +** The register P1 must contain an integer. If register P1 is initially +** zero, then jump to P2. Increment register P1 regardless of whether or +** not the jump is taken. +*/ +case OP_JumpZeroIncr: { /* jump, in1 */ + pIn1 = &aMem[pOp->p1]; + assert( pIn1->flags&MEM_Int ); + VdbeBranchTaken(pIn1->u.i==0, 2); + if( (pIn1->u.i++)==0 ){ + pc = pOp->p2 - 1; + } + break; +} + /* Opcode: AggStep * P2 P3 P4 P5 ** Synopsis: accum=r[P3] step(r[P2@P5]) ** diff --git a/src/where.c b/src/where.c index e79e7d33bc..ece403dfaa 100644 --- a/src/where.c +++ b/src/where.c @@ -3017,12 +3017,17 @@ static void addScanStatus( ** and if pLoop->iLikeRepCntr is non-zero, then change the P3 to be ** pLoop->iLikeRepCntr and set P5. ** -** This is part of the LIKE optimization. FIXME: Explain in more detail +** The LIKE optimization trys to evaluate "x LIKE 'abc%'" as a range +** expression: "x>='ABC' AND x<'abd'". But this requires that the range +** scan loop run twice, once for strings and a second time for BLOBs. +** The OP_String opcodes on the second pass convert the upper and lower +** bound string contants to blobs. This routine makes the necessary changes +** to the OP_String opcodes for that to happen. */ static void whereLikeOptimizationStringFixup(Vdbe *v, WhereLevel *pLevel){ VdbeOp *pOp; pOp = sqlite3VdbeGetOp(v, -1); - if( pLevel->iLikeRepCntr && ALWAYS(pOp->opcode==OP_String8) ){ + if( pLevel->iLikeRepCntr && pOp->opcode==OP_String8 ){ pOp->p3 = pLevel->iLikeRepCntr; pOp->p5 = 1; } @@ -3366,6 +3371,7 @@ static Bitmask codeOneLoopStart( ){ pLevel->iLikeRepCntr = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLikeRepCntr); + VdbeComment((v, "LIKE loop counter")); pLevel->addrLikeRep = sqlite3VdbeCurrentAddr(v); } if( pRangeStart==0 @@ -3395,6 +3401,9 @@ static Bitmask codeOneLoopStart( ){ SWAP(WhereTerm *, pRangeEnd, pRangeStart); SWAP(u8, bSeekPastNull, bStopAtNull); + if( pLevel->addrLikeRep ){ + sqlite3VdbeChangeP1(v, pLevel->addrLikeRep-1, 1); + } } testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 ); @@ -3864,7 +3873,7 @@ static Bitmask codeOneLoopStart( } if( pTerm->wtFlags & TERM_LIKECOND ){ assert( pLevel->iLikeRepCntr>0 ); - skipLikeAddr = sqlite3VdbeAddOp1(v, OP_IfZero, pLevel->iLikeRepCntr); + skipLikeAddr = sqlite3VdbeAddOp1(v, OP_IfNot, pLevel->iLikeRepCntr); VdbeCoverage(v); } sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL); @@ -6673,11 +6682,10 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ sqlite3VdbeJumpHere(v, pLevel->addrSkip-2); } if( pLevel->addrLikeRep ){ - addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLikeRepCntr); + sqlite3VdbeAddOp2(v, + pLevel->op==OP_Prev ? OP_DecrJumpZero : OP_JumpZeroIncr, + pLevel->iLikeRepCntr, pLevel->addrLikeRep); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_AddImm, pLevel->iLikeRepCntr, 1); - sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrLikeRep); - sqlite3VdbeJumpHere(v, addr); } if( pLevel->iLeftJoin ){ addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v); diff --git a/test/like3.test b/test/like3.test index b3af2cda91..7ca45f88c2 100644 --- a/test/like3.test +++ b/test/like3.test @@ -57,4 +57,18 @@ do_execsql_test like3-1.4 { SELECT a, b FROM t2 WHERE +b GLOB 'ab*' ORDER BY +a; } {1 abc 4 abc} +do_execsql_test like3-3.0 { + CREATE TABLE t3(x TEXT PRIMARY KEY COLLATE nocase); + INSERT INTO t3(x) VALUES('aaa'),('abc'),('abd'),('abe'),('acz'); + INSERT INTO t3(x) SELECT CAST(x AS blob) FROM t3; + SELECT quote(x) FROM t3 WHERE x LIKE 'ab%' ORDER BY x; +} {'abc' 'abd' 'abe' X'616263' X'616264' X'616265'} +do_execsql_test like3-3.1 { + SELECT quote(x) FROM t3 WHERE x LIKE 'ab%' ORDER BY x DESC; +} {X'616265' X'616264' X'616263' 'abe' 'abd' 'abc'} +do_execsql_test like3-3.1ck { + SELECT quote(x) FROM t3 WHERE x LIKE 'ab%' ORDER BY +x DESC; +} {X'616265' X'616264' X'616263' 'abe' 'abd' 'abc'} + + finish_test From b7c60ba668a6abd18fb30877a003cb3ff336156d Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 7 Mar 2015 02:51:59 +0000 Subject: [PATCH 24/57] Fix problems with reverse order sorting and indexes in the LIKE optimization. FossilOrigin-Name: 564b8fe79475d7584a21078e6098840b8ce6a6e1 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 18 ++++++++++++++---- test/like3.test | 26 ++++++++++++++++++++++++++ 4 files changed, 48 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 5043d98fbb..5835e728b1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Refactor\ssome\sjump\sopcodes\sin\sthe\sVDBE.\s\sAdd\sJumpZeroIncr\sand\sDecrJumpZero.\nFix\sthe\sLIKE\soptimization\sto\swork\swith\sDESC\ssort\sorder. -D 2015-03-07T00:57:37.923 +C Fix\sproblems\swith\sreverse\sorder\ssorting\sand\sindexes\sin\sthe\sLIKE\soptimization. +D 2015-03-07T02:51:59.332 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -307,7 +307,7 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 39303f2c9db02a4e422cd8eb2c8760420c6a51fe F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 -F src/where.c 7c646a15d0d17850e10319aa31662d5ab61c69af +F src/where.c efa0cef9fdf1c7f15e1f22d8e0a26d989c5fd947 F src/whereInt.h cbe4aa57326998d89e7698ca65bb7c28541d483c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -691,7 +691,7 @@ F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/like.test 4f2a71d36a536233727f71995fef900756705e56 F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da -F test/like3.test f6fa86d6a81d95bd796c46b0e2ba7444669bdd7e +F test/like3.test 2fd1fd45cf7169093206e0d1d848e616df98ed46 F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e F test/loadext.test 648cb95f324d1775c54a55c12271b2d1156b633b F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7 @@ -1241,7 +1241,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6b993bd54035b67f4d84941e3f444ca79b7feee1 -R f90848042fe53f442912e9f9b75887d2 +P 26cb5145bf52f8c3fffa8c69b6c24aee4d974883 +R 26c030dedce138311a8813ea74e14352 U drh -Z ceb5f3bff4db8044ae0448ec360f04b2 +Z 2f44b5f1b4f68b861174549cabd12bcf diff --git a/manifest.uuid b/manifest.uuid index 35dc95ffee..bc078d5c07 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -26cb5145bf52f8c3fffa8c69b6c24aee4d974883 \ No newline at end of file +564b8fe79475d7584a21078e6098840b8ce6a6e1 \ No newline at end of file diff --git a/src/where.c b/src/where.c index ece403dfaa..ed7febf3cb 100644 --- a/src/where.c +++ b/src/where.c @@ -3370,7 +3370,11 @@ static Bitmask codeOneLoopStart( && (pRangeEnd->wtFlags & TERM_LIKEOPT)!=0 ){ pLevel->iLikeRepCntr = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLikeRepCntr); + testcase( bRev ); + testcase( pIdx->aSortOrder[nEq]==SQLITE_SO_DESC ); + sqlite3VdbeAddOp2(v, OP_Integer, + bRev ^ (pIdx->aSortOrder[nEq]==SQLITE_SO_DESC), + pLevel->iLikeRepCntr); VdbeComment((v, "LIKE loop counter")); pLevel->addrLikeRep = sqlite3VdbeCurrentAddr(v); } @@ -3401,9 +3405,11 @@ static Bitmask codeOneLoopStart( ){ SWAP(WhereTerm *, pRangeEnd, pRangeStart); SWAP(u8, bSeekPastNull, bStopAtNull); +#if 0 if( pLevel->addrLikeRep ){ sqlite3VdbeChangeP1(v, pLevel->addrLikeRep-1, 1); } +#endif } testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 ); @@ -6682,9 +6688,13 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ sqlite3VdbeJumpHere(v, pLevel->addrSkip-2); } if( pLevel->addrLikeRep ){ - sqlite3VdbeAddOp2(v, - pLevel->op==OP_Prev ? OP_DecrJumpZero : OP_JumpZeroIncr, - pLevel->iLikeRepCntr, pLevel->addrLikeRep); + int op; + if( sqlite3VdbeGetOp(v, pLevel->addrLikeRep-1)->p1 ){ + op = OP_DecrJumpZero; + }else{ + op = OP_JumpZeroIncr; + } + sqlite3VdbeAddOp2(v, op, pLevel->iLikeRepCntr, pLevel->addrLikeRep); VdbeCoverage(v); } if( pLevel->iLeftJoin ){ diff --git a/test/like3.test b/test/like3.test index 7ca45f88c2..d360363747 100644 --- a/test/like3.test +++ b/test/like3.test @@ -69,6 +69,32 @@ do_execsql_test like3-3.1 { do_execsql_test like3-3.1ck { SELECT quote(x) FROM t3 WHERE x LIKE 'ab%' ORDER BY +x DESC; } {X'616265' X'616264' X'616263' 'abe' 'abd' 'abc'} +do_execsql_test like3-3.2 { + SELECT quote(x) FROM t3 WHERE x LIKE 'ab%' ORDER BY x ASC; +} {'abc' 'abd' 'abe' X'616263' X'616264' X'616265'} +do_execsql_test like3-3.2ck { + SELECT quote(x) FROM t3 WHERE x LIKE 'ab%' ORDER BY +x ASC; +} {'abc' 'abd' 'abe' X'616263' X'616264' X'616265'} + +do_execsql_test like3-4.0 { + CREATE TABLE t4(x TEXT COLLATE nocase); + CREATE INDEX t4x ON t4(x DESC); + INSERT INTO t4(x) SELECT x FROM t3; + SELECT quote(x) FROM t4 WHERE x LIKE 'ab%' ORDER BY x; +} {'abc' 'abd' 'abe' X'616263' X'616264' X'616265'} +do_execsql_test like3-4.1 { + SELECT quote(x) FROM t4 WHERE x LIKE 'ab%' ORDER BY x DESC; +} {X'616265' X'616264' X'616263' 'abe' 'abd' 'abc'} +do_execsql_test like3-4.1ck { + SELECT quote(x) FROM t4 WHERE x LIKE 'ab%' ORDER BY +x DESC; +} {X'616265' X'616264' X'616263' 'abe' 'abd' 'abc'} +do_execsql_test like3-4.2 { + SELECT quote(x) FROM t4 WHERE x LIKE 'ab%' ORDER BY x ASC; +} {'abc' 'abd' 'abe' X'616263' X'616264' X'616265'} +do_execsql_test like3-4.2ck { + SELECT quote(x) FROM t4 WHERE x LIKE 'ab%' ORDER BY +x ASC; +} {'abc' 'abd' 'abe' X'616263' X'616264' X'616265'} + finish_test From ab87a5e5b887b0818f777de45fb630b00e98e1a3 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 7 Mar 2015 03:02:38 +0000 Subject: [PATCH 25/57] Remove some code that is commented out. FossilOrigin-Name: 55ff429177acfdab056a16a67361a5381115c6c7 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 5 ----- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 5835e728b1..80dc152241 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sproblems\swith\sreverse\sorder\ssorting\sand\sindexes\sin\sthe\sLIKE\soptimization. -D 2015-03-07T02:51:59.332 +C Remove\ssome\scode\sthat\sis\scommented\sout. +D 2015-03-07T03:02:38.737 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -307,7 +307,7 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 39303f2c9db02a4e422cd8eb2c8760420c6a51fe F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 -F src/where.c efa0cef9fdf1c7f15e1f22d8e0a26d989c5fd947 +F src/where.c 84104123394d38aa530f4e3e12b4ac7efcd7fe19 F src/whereInt.h cbe4aa57326998d89e7698ca65bb7c28541d483c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1241,7 +1241,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 26cb5145bf52f8c3fffa8c69b6c24aee4d974883 -R 26c030dedce138311a8813ea74e14352 +P 564b8fe79475d7584a21078e6098840b8ce6a6e1 +R fde0ab8284854a8bdb2fb2edfcc14f2f U drh -Z 2f44b5f1b4f68b861174549cabd12bcf +Z 7743073cc3ebbf2511c96fb7b06cce37 diff --git a/manifest.uuid b/manifest.uuid index bc078d5c07..7c3e1a5b9b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -564b8fe79475d7584a21078e6098840b8ce6a6e1 \ No newline at end of file +55ff429177acfdab056a16a67361a5381115c6c7 \ No newline at end of file diff --git a/src/where.c b/src/where.c index ed7febf3cb..64c9652b0b 100644 --- a/src/where.c +++ b/src/where.c @@ -3405,11 +3405,6 @@ static Bitmask codeOneLoopStart( ){ SWAP(WhereTerm *, pRangeEnd, pRangeStart); SWAP(u8, bSeekPastNull, bStopAtNull); -#if 0 - if( pLevel->addrLikeRep ){ - sqlite3VdbeChangeP1(v, pLevel->addrLikeRep-1, 1); - } -#endif } testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 ); From 560b7c72beb1a5bfddf79fdb64ae3e0078c232bc Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 7 Mar 2015 12:58:52 +0000 Subject: [PATCH 26/57] New test cases for LIKE and GLOB with BLOB left-hand side values. FossilOrigin-Name: 50fa3c5fae90bd3b2f4121e99ab52d79963a6fda --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/like3.test | 16 ++++++++++++++-- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 80dc152241..9eb096b756 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\ssome\scode\sthat\sis\scommented\sout. -D 2015-03-07T03:02:38.737 +C New\stest\scases\sfor\sLIKE\sand\sGLOB\swith\sBLOB\sleft-hand\sside\svalues. +D 2015-03-07T12:58:52.057 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -691,7 +691,7 @@ F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/like.test 4f2a71d36a536233727f71995fef900756705e56 F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da -F test/like3.test 2fd1fd45cf7169093206e0d1d848e616df98ed46 +F test/like3.test 7b0525a39e4f25c4fd113de7e2e28eb712dcdedf F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e F test/loadext.test 648cb95f324d1775c54a55c12271b2d1156b633b F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7 @@ -1241,7 +1241,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 564b8fe79475d7584a21078e6098840b8ce6a6e1 -R fde0ab8284854a8bdb2fb2edfcc14f2f +P 55ff429177acfdab056a16a67361a5381115c6c7 +R 2fc7830b1fa14938513120a1368ba854 U drh -Z 7743073cc3ebbf2511c96fb7b06cce37 +Z b3a1ad10fdcf5eac37975294f3354efc diff --git a/manifest.uuid b/manifest.uuid index 7c3e1a5b9b..da4c850322 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -55ff429177acfdab056a16a67361a5381115c6c7 \ No newline at end of file +50fa3c5fae90bd3b2f4121e99ab52d79963a6fda \ No newline at end of file diff --git a/test/like3.test b/test/like3.test index d360363747..a1faf76915 100644 --- a/test/like3.test +++ b/test/like3.test @@ -47,15 +47,27 @@ do_execsql_test like3-1.2 { SELECT a, b FROM t1 WHERE +b LIKE 'aB%' ORDER BY +a; } {1 abc 2 ABX 4 abc 5 ABX} -do_execsql_test like3-1.3 { +do_execsql_test like3-2.0 { CREATE TABLE t2(a, b TEXT); INSERT INTO t2 SELECT a, b FROM t1; CREATE INDEX t2ba ON t2(b,a); SELECT a, b FROM t2 WHERE b GLOB 'ab*' ORDER BY +a; } {1 abc 4 abc} -do_execsql_test like3-1.4 { +do_execsql_test like3-2.1 { SELECT a, b FROM t2 WHERE +b GLOB 'ab*' ORDER BY +a; } {1 abc 4 abc} +do_execsql_test like3-2.2 { + SELECT a, b FROM t2 WHERE b>=x'6162' AND b GLOB 'ab*' +} {4 abc} +do_execsql_test like3-2.3 { + SELECT a, b FROM t2 WHERE +b>=x'6162' AND +b GLOB 'ab*' +} {4 abc} +do_execsql_test like3-2.4 { + SELECT a, b FROM t2 WHERE b GLOB 'ab*' AND b>=x'6162' +} {4 abc} +do_execsql_test like3-2.5 { + SELECT a, b FROM t2 WHERE +b GLOB 'ab*' AND +b>=x'6162' +} {4 abc} do_execsql_test like3-3.0 { CREATE TABLE t3(x TEXT PRIMARY KEY COLLATE nocase); From 52fc05ba1c4c297560ec28906b2902e2a3c522c5 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 7 Mar 2015 20:32:49 +0000 Subject: [PATCH 27/57] Fix another problem with the LIKE optimization. FossilOrigin-Name: 465bfc72d252f94778248253142faeba78ceea02 --- manifest | 16 +++++++++------- manifest.uuid | 2 +- src/where.c | 26 +++++++++++++++----------- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 55fca4b7f9..8ac17721f1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sLIKE\soptimization\sso\sthat\sit\sfinds\sBLOB\sentries\sin\saddition\sto\stext\nentries.\s\sTicket\s[05f43be8fdda9f]. -D 2015-03-07T13:56:48.044 +C Fix\sanother\sproblem\swith\sthe\sLIKE\soptimization. +D 2015-03-07T20:32:49.790 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -307,7 +307,7 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 39303f2c9db02a4e422cd8eb2c8760420c6a51fe F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 -F src/where.c 84104123394d38aa530f4e3e12b4ac7efcd7fe19 +F src/where.c 65813699926c15b7041ff2021731f03183aac493 F src/whereInt.h cbe4aa57326998d89e7698ca65bb7c28541d483c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1241,8 +1241,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8c1e85aab9e0d90726057e25e2ea0663341c070f 50fa3c5fae90bd3b2f4121e99ab52d79963a6fda -R 2fc7830b1fa14938513120a1368ba854 -T +closed 50fa3c5fae90bd3b2f4121e99ab52d79963a6fda +P 74cb0b032fcf598537fae04412771450124ae712 +R 23dd5631417bc0e4cabfa079f9a22509 +T *branch * like-opt-fix +T *sym-like-opt-fix * +T -sym-trunk * U drh -Z 4859c93f290241201b6571a3ac6035f4 +Z c34701a311a2e64477c46e48ef38102d diff --git a/manifest.uuid b/manifest.uuid index e2d06d5c80..e3c0591701 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -74cb0b032fcf598537fae04412771450124ae712 \ No newline at end of file +465bfc72d252f94778248253142faeba78ceea02 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 64c9652b0b..3e2558d00e 100644 --- a/src/where.c +++ b/src/where.c @@ -3024,12 +3024,17 @@ static void addScanStatus( ** bound string contants to blobs. This routine makes the necessary changes ** to the OP_String opcodes for that to happen. */ -static void whereLikeOptimizationStringFixup(Vdbe *v, WhereLevel *pLevel){ - VdbeOp *pOp; - pOp = sqlite3VdbeGetOp(v, -1); - if( pLevel->iLikeRepCntr && pOp->opcode==OP_String8 ){ - pOp->p3 = pLevel->iLikeRepCntr; - pOp->p5 = 1; +static void whereLikeOptimizationStringFixup( + Vdbe *v, /* prepared statement under construction */ + WhereLevel *pLevel, /* The loop that contains the LIKE operator */ + WhereTerm *pTerm /* The upper or lower bound just coded */ +){ + if( pTerm->wtFlags & TERM_LIKEOPT ){ + VdbeOp *pOp = sqlite3VdbeGetOp(v, -1); + if( pLevel->iLikeRepCntr && pOp->opcode==OP_String8 ){ + pOp->p3 = pLevel->iLikeRepCntr; + pOp->p5 = 1; + } } } @@ -3365,9 +3370,8 @@ static Bitmask codeOneLoopStart( if( pLoop->wsFlags & WHERE_TOP_LIMIT ){ pRangeEnd = pLoop->aLTerm[j++]; nExtraReg = 1; - if( pRangeStart - && (pRangeStart->wtFlags & TERM_LIKEOPT)!=0 - && (pRangeEnd->wtFlags & TERM_LIKEOPT)!=0 + if( (pRangeStart && (pRangeStart->wtFlags & TERM_LIKEOPT)!=0) + || (pRangeEnd->wtFlags & TERM_LIKEOPT)!=0 ){ pLevel->iLikeRepCntr = ++pParse->nMem; testcase( bRev ); @@ -3420,7 +3424,7 @@ static Bitmask codeOneLoopStart( if( pRangeStart ){ Expr *pRight = pRangeStart->pExpr->pRight; sqlite3ExprCode(pParse, pRight, regBase+nEq); - whereLikeOptimizationStringFixup(v, pLevel); + whereLikeOptimizationStringFixup(v, pLevel, pRangeStart); if( (pRangeStart->wtFlags & TERM_VNULL)==0 && sqlite3ExprCanBeNull(pRight) ){ @@ -3466,7 +3470,7 @@ static Bitmask codeOneLoopStart( Expr *pRight = pRangeEnd->pExpr->pRight; sqlite3ExprCacheRemove(pParse, regBase+nEq, 1); sqlite3ExprCode(pParse, pRight, regBase+nEq); - whereLikeOptimizationStringFixup(v, pLevel); + whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd); if( (pRangeEnd->wtFlags & TERM_VNULL)==0 && sqlite3ExprCanBeNull(pRight) ){ From 74f4d3e5dffb69cc7f64b4f41655f0fd35de5b6f Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 9 Mar 2015 10:40:48 +0000 Subject: [PATCH 28/57] Increase the version number to 3.8.9 FossilOrigin-Name: e5da5e7d5dc5a3438ced23f1ee83e695abc29c45 --- VERSION | 2 +- configure | 18 +++++++++--------- manifest | 15 +++++++-------- manifest.uuid | 2 +- 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/VERSION b/VERSION index d7d8e42315..203e6d5c9a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.8.8 +3.8.9 diff --git a/configure b/configure index 9e639e7f75..0c519e2216 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.62 for sqlite 3.8.8. +# Generated by GNU Autoconf 2.62 for sqlite 3.8.9. # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. @@ -743,8 +743,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='sqlite' PACKAGE_TARNAME='sqlite' -PACKAGE_VERSION='3.8.8' -PACKAGE_STRING='sqlite 3.8.8' +PACKAGE_VERSION='3.8.9' +PACKAGE_STRING='sqlite 3.8.9' PACKAGE_BUGREPORT='' # Factoring default headers for most tests. @@ -1480,7 +1480,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures sqlite 3.8.8 to adapt to many kinds of systems. +\`configure' configures sqlite 3.8.9 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1545,7 +1545,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of sqlite 3.8.8:";; + short | recursive ) echo "Configuration of sqlite 3.8.9:";; esac cat <<\_ACEOF @@ -1659,7 +1659,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sqlite configure 3.8.8 +sqlite configure 3.8.9 generated by GNU Autoconf 2.62 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -1673,7 +1673,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by sqlite $as_me 3.8.8, which was +It was created by sqlite $as_me 3.8.9, which was generated by GNU Autoconf 2.62. Invocation command line was $ $0 $@ @@ -13951,7 +13951,7 @@ exec 6>&1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by sqlite $as_me 3.8.8, which was +This file was extended by sqlite $as_me 3.8.9, which was generated by GNU Autoconf 2.62. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -14004,7 +14004,7 @@ Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_version="\\ -sqlite config.status 3.8.8 +sqlite config.status 3.8.9 configured by $0, generated by GNU Autoconf 2.62, with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" diff --git a/manifest b/manifest index 55fca4b7f9..b8a1f8b1ae 100644 --- a/manifest +++ b/manifest @@ -1,12 +1,12 @@ -C Fix\sthe\sLIKE\soptimization\sso\sthat\sit\sfinds\sBLOB\sentries\sin\saddition\sto\stext\nentries.\s\sTicket\s[05f43be8fdda9f]. -D 2015-03-07T13:56:48.044 +C Increase\sthe\sversion\snumber\sto\s3.8.9 +D 2015-03-09T10:40:48.276 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.msc 529e61cd9d29a3934758b4b3a0bb649b6c653481 F Makefile.vxworks e1b65dea203f054e71653415bd8f96dcaed47858 F README.md d58e3bebc0a4145e0f2a87994015fdb575a8e866 -F VERSION d846487aff892625eb8e75960234e7285f0462fe +F VERSION 319eb1ced4b4d17a67730f2b7b85f15c1346cb60 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F addopcodes.awk 9eb448a552d5c0185cf62c463f9c173cedae3811 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 @@ -38,7 +38,7 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 F config.h.in 42b71ad3fe21c9e88fa59e8458ca1a6bc72eb0c0 F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 -F configure b2882796ddebd33ac4e9d4ccf5c5ca11888fc30e x +F configure 613b220c2f2c7adcd50eb5ee4144ab581a150b47 x F configure.ac 6a8d145aea6d81f0b90013340780e43ed74fd5f4 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1 @@ -1241,8 +1241,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8c1e85aab9e0d90726057e25e2ea0663341c070f 50fa3c5fae90bd3b2f4121e99ab52d79963a6fda -R 2fc7830b1fa14938513120a1368ba854 -T +closed 50fa3c5fae90bd3b2f4121e99ab52d79963a6fda +P 74cb0b032fcf598537fae04412771450124ae712 +R 9ac10056eb6a3c9d151b86baaf6f566f U drh -Z 4859c93f290241201b6571a3ac6035f4 +Z 5dfd706dc4ee17c10393dacc3c9444b2 diff --git a/manifest.uuid b/manifest.uuid index e2d06d5c80..1a6de51696 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -74cb0b032fcf598537fae04412771450124ae712 \ No newline at end of file +e5da5e7d5dc5a3438ced23f1ee83e695abc29c45 \ No newline at end of file From a40da62dd4712b198fe5579a94a24ccafc4fdf54 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 9 Mar 2015 12:11:56 +0000 Subject: [PATCH 29/57] Always use LIKE optimization range constraints in pairs. FossilOrigin-Name: 0e02dc94fd1bb891d0edd1e34b57e923b17712a7 --- manifest | 15 ++++++--------- manifest.uuid | 2 +- src/where.c | 38 ++++++++++++++++++++++++++++---------- 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 8ac17721f1..1c5b59c033 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sanother\sproblem\swith\sthe\sLIKE\soptimization. -D 2015-03-07T20:32:49.790 +C Always\suse\sLIKE\soptimization\srange\sconstraints\sin\spairs. +D 2015-03-09T12:11:56.889 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -307,7 +307,7 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 39303f2c9db02a4e422cd8eb2c8760420c6a51fe F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 -F src/where.c 65813699926c15b7041ff2021731f03183aac493 +F src/where.c 21c96bc0265228dbca2feb3f65c464bc464ec4c2 F src/whereInt.h cbe4aa57326998d89e7698ca65bb7c28541d483c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1241,10 +1241,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 74cb0b032fcf598537fae04412771450124ae712 -R 23dd5631417bc0e4cabfa079f9a22509 -T *branch * like-opt-fix -T *sym-like-opt-fix * -T -sym-trunk * +P 465bfc72d252f94778248253142faeba78ceea02 +R 3b7b3881e4a2944ad5c0176e96b8fcf3 U drh -Z c34701a311a2e64477c46e48ef38102d +Z 1e9efc602031c231aa2c489f96b95b11 diff --git a/manifest.uuid b/manifest.uuid index e3c0591701..9abd00976e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -465bfc72d252f94778248253142faeba78ceea02 \ No newline at end of file +0e02dc94fd1bb891d0edd1e34b57e923b17712a7 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 3e2558d00e..d6bce65d2e 100644 --- a/src/where.c +++ b/src/where.c @@ -3013,8 +3013,8 @@ static void addScanStatus( #endif /* -** Look at the last instruction coded. If that instruction is OP_String8 -** and if pLoop->iLikeRepCntr is non-zero, then change the P3 to be +** If the most recently coded instruction is a constant range contraint +** that originated from the LIKE optimization, then change the P3 to be ** pLoop->iLikeRepCntr and set P5. ** ** The LIKE optimization trys to evaluate "x LIKE 'abc%'" as a range @@ -3030,11 +3030,14 @@ static void whereLikeOptimizationStringFixup( WhereTerm *pTerm /* The upper or lower bound just coded */ ){ if( pTerm->wtFlags & TERM_LIKEOPT ){ - VdbeOp *pOp = sqlite3VdbeGetOp(v, -1); - if( pLevel->iLikeRepCntr && pOp->opcode==OP_String8 ){ - pOp->p3 = pLevel->iLikeRepCntr; - pOp->p5 = 1; - } + VdbeOp *pOp; + assert( pLevel->iLikeRepCntr>0 ); + pOp = sqlite3VdbeGetOp(v, -1); + assert( pOp!=0 ); + assert( pOp->opcode==OP_String8 + || pTerm->pWC->pWInfo->pParse->db->mallocFailed ); + pOp->p3 = pLevel->iLikeRepCntr; + pOp->p5 = 1; } } @@ -3370,9 +3373,9 @@ static Bitmask codeOneLoopStart( if( pLoop->wsFlags & WHERE_TOP_LIMIT ){ pRangeEnd = pLoop->aLTerm[j++]; nExtraReg = 1; - if( (pRangeStart && (pRangeStart->wtFlags & TERM_LIKEOPT)!=0) - || (pRangeEnd->wtFlags & TERM_LIKEOPT)!=0 - ){ + if( (pRangeEnd->wtFlags & TERM_LIKEOPT)!=0 ){ + assert( pRangeStart!=0 ); + assert( pRangeStart->wtFlags & TERM_LIKEOPT ); pLevel->iLikeRepCntr = ++pParse->nMem; testcase( bRev ); testcase( pIdx->aSortOrder[nEq]==SQLITE_SO_DESC ); @@ -4547,6 +4550,10 @@ static int whereLoopAddBtreeIndex( } if( pTerm->prereqRight & pNew->maskSelf ) continue; + /* Do not allow the upper bound of a LIKE optimization range constraint + ** to mix with a lower range bound from some other source */ + if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue; + pNew->wsFlags = saved_wsFlags; pNew->u.btree.nEq = saved_nEq; pNew->nLTerm = saved_nLTerm; @@ -4590,6 +4597,17 @@ static int whereLoopAddBtreeIndex( pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT; pBtm = pTerm; pTop = 0; + if( pTerm->wtFlags & TERM_LIKEOPT ){ + /* Make sure that range contraints that come from the LIKE + ** optimization are always used in pairs. */ + pTop = &pTerm[1]; + assert( (pTop-(pTerm->pWC->a))pWC->nTerm ); + assert( pTop->wtFlags & TERM_LIKEOPT ); + assert( pTop->eOperator==WO_LT ); + if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ + pNew->aLTerm[pNew->nLTerm++] = pTop; + pNew->wsFlags |= WHERE_TOP_LIMIT; + } }else{ assert( eOp & (WO_LT|WO_LE) ); testcase( eOp & WO_LT ); From 9b5d76bf57ee240bd745bad993027dcd26e957f2 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 10 Mar 2015 13:50:18 +0000 Subject: [PATCH 30/57] Revise test cases in malloc5.test to accommodate varying allocation sizes returned by some system malloc() implementations. FossilOrigin-Name: fbae6bafd74d8da9c72be5f562a62f80b01cc846 --- manifest | 13 ++++++------- manifest.uuid | 2 +- test/malloc5.test | 29 +++++++++++++++++++++++------ 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index a8566de963..3769cadfe2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sLIKE\soptimization\sso\sthat\sit\sworks\seven\sif\sthere\sare\sadditional\nrange\scontraints\son\sthe\scolumn\sthat\sis\ssubject\sto\sthe\sLIKE\sor\sGLOB. -D 2015-03-09T13:01:02.136 +C Revise\stest\scases\sin\smalloc5.test\sto\saccommodate\svarying\sallocation\nsizes\sreturned\sby\ssome\ssystem\smalloc()\simplementations. +D 2015-03-10T13:50:18.414 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -709,7 +709,7 @@ F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9 F test/malloc.test 96939d2d1a6f39667bbebe5bc27c6525f2ab614e F test/malloc3.test e3b32c724b5a124b57cb0ed177f675249ad0c66a F test/malloc4.test 957337613002b7058a85116493a262f679f3a261 -F test/malloc5.test fafce0aa9157060445cd1a56ad50fc79d82f28c3 +F test/malloc5.test 79182b8bffd6d62f77b1a5a8ba8e6bf0e5053b8e F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151 F test/malloc7.test 7c68a32942858bc715284856c5507446bba88c3a F test/malloc8.test 9b7a3f8cb9cf0b12fff566e80a980b1767bd961d @@ -1241,8 +1241,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e5da5e7d5dc5a3438ced23f1ee83e695abc29c45 0e02dc94fd1bb891d0edd1e34b57e923b17712a7 -R c1700660b0fab033a6359aa8c00c1b69 -T +closed 0e02dc94fd1bb891d0edd1e34b57e923b17712a7 +P 984c3fd5261619fb542a5a95dab37707b5d79dbf +R 755476faee751a04385de321ff0c4db7 U drh -Z 0d4bf9b628bd332a63a01f9a77a070c3 +Z d102bfa9bbfc74e74ac15b539033106b diff --git a/manifest.uuid b/manifest.uuid index 5e807e391c..960352f2cd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -984c3fd5261619fb542a5a95dab37707b5d79dbf \ No newline at end of file +fbae6bafd74d8da9c72be5f562a62f80b01cc846 \ No newline at end of file diff --git a/test/malloc5.test b/test/malloc5.test index 6abedf79e1..c046499261 100644 --- a/test/malloc5.test +++ b/test/malloc5.test @@ -71,6 +71,23 @@ do_test malloc5-1.3 { expr $::pgalloc > 0 } {1} +# The sizes of memory allocations from system malloc() might vary, +# depending on the memory allocator algorithms used. The following +# routine is designed to support answers that fall within a range +# of values while also supplying easy-to-understand "expected" values +# when errors occur. +# +proc value_in_range {target x args} { + set v [lindex $args 0] + if {$v!=""} { + if {$v<$target*$x} {return $v} + if {$v>$target/$x} {return $v} + } + return "number between [expr {int($target*$x)}] and [expr {int($target/$x)}]" +} +set mrange 0.98 ;# plus or minus 2% + + do_test malloc5-1.4 { # Commit the transaction and open a new one. Read 1 page into the cache. # Because the page is not dirty, it is eligible for collection even @@ -81,16 +98,16 @@ do_test malloc5-1.4 { BEGIN; SELECT * FROM abc; } - sqlite3_release_memory -} $::pgalloc + value_in_range $::pgalloc $::mrange [sqlite3_release_memory] +} [value_in_range $::pgalloc $::mrange] do_test malloc5-1.5 { # Conclude the transaction opened in the previous [do_test] block. This # causes another page (page 1) to become eligible for recycling. # execsql { COMMIT } - sqlite3_release_memory -} $::pgalloc + value_in_range $::pgalloc $::mrange [sqlite3_release_memory] +} [value_in_range $::pgalloc $::mrange] do_test malloc5-1.6 { # Manipulate the cache so that it contains two unused pages. One requires @@ -101,8 +118,8 @@ do_test malloc5-1.6 { SELECT * FROM abc; CREATE TABLE def(d, e, f); } - sqlite3_release_memory 500 -} $::pgalloc + value_in_range $::pgalloc $::mrange [sqlite3_release_memory 500] +} [value_in_range $::pgalloc $::mrange] do_test malloc5-1.7 { # Database should not be locked this time. From 94929646f109b72bb5f22cb44ce9afd65fc1c9ce Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 10 Mar 2015 15:34:47 +0000 Subject: [PATCH 31/57] Fix an incrblob2 test case so that it works on 32-bit systems. FossilOrigin-Name: 8d0b11c96e15556dd65ced05708a832aef134e69 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/incrblob2.test | 14 ++++++++++++-- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 3769cadfe2..1387322488 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Revise\stest\scases\sin\smalloc5.test\sto\saccommodate\svarying\sallocation\nsizes\sreturned\sby\ssome\ssystem\smalloc()\simplementations. -D 2015-03-10T13:50:18.414 +C Fix\san\sincrblob2\stest\scase\sso\sthat\sit\sworks\son\s32-bit\ssystems. +D 2015-03-10T15:34:47.080 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -639,7 +639,7 @@ F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0 F test/in4.test d2b38cba404bc4320f4fe1b595b3d163f212c068 F test/in5.test 1de657472fa9ac2924be25c2c959ac5ca1aae554 F test/incrblob.test e81846d214f3637622620fbde7cd526781cfe328 -F test/incrblob2.test 0d8821730a84f90af78a9dd547fe7a2480a06240 +F test/incrblob2.test a5ce5ed1d0b01e2ed347245a21170372528af0a5 F test/incrblob3.test d8d036fde015d4a159cd3cbae9d29003b37227a4 F test/incrblob4.test f26502a5697893e5acea268c910f16478c2f0fab F test/incrblob_err.test af1f12ba60d220c9752073ff2bda2ad59e88960d @@ -1241,7 +1241,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 984c3fd5261619fb542a5a95dab37707b5d79dbf -R 755476faee751a04385de321ff0c4db7 +P fbae6bafd74d8da9c72be5f562a62f80b01cc846 +R f19e7f30be378d3111028d8dd74f6a7d U drh -Z d102bfa9bbfc74e74ac15b539033106b +Z 0ddafeebdf23c7d95a3d79f2f7b9a23f diff --git a/manifest.uuid b/manifest.uuid index 960352f2cd..3acf7708d9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fbae6bafd74d8da9c72be5f562a62f80b01cc846 \ No newline at end of file +8d0b11c96e15556dd65ced05708a832aef134e69 \ No newline at end of file diff --git a/test/incrblob2.test b/test/incrblob2.test index 1a235f7d22..b6c75cd6c7 100644 --- a/test/incrblob2.test +++ b/test/incrblob2.test @@ -324,11 +324,21 @@ do_test incrblob2-6.2 { sqlite3_blob_read $rdHandle 0 2 } {AB} -do_test incrblob2-6.2b { +if {$::tcl_platform(pointerSize)>=8} { + do_test incrblob2-6.2b { + set rc [catch { + # Prior to 2015-02-07, the following caused a segfault due to + # integer overflow. + sqlite3_blob_read $rdHandle 2147483647 2147483647 + } errmsg] + lappend rc $errmsg + } {1 SQLITE_ERROR} +} +do_test incrblob2-6.2c { set rc [catch { # Prior to 2015-02-07, the following caused a segfault due to # integer overflow. - sqlite3_blob_read $rdHandle 2147483647 2147483647 + sqlite3_blob_read $rdHandle 2147483647 100 } errmsg] lappend rc $errmsg } {1 SQLITE_ERROR} From bbf76eec342f7a4732b7e38329b6ea1ac8c682da Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 10 Mar 2015 20:22:35 +0000 Subject: [PATCH 32/57] Arrange for some of the transient locks in WAL mode to block, as a single to the OS to fix priority inversions. FossilOrigin-Name: c6e6d5f4e06c3ac0bfb620c0c728fbc7230c4a02 --- manifest | 19 +++++++++++-------- manifest.uuid | 2 +- src/os_unix.c | 28 +++++++++++++++++++--------- src/sqlite.h.in | 8 ++++++++ src/wal.c | 17 +++++++++-------- 5 files changed, 48 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index 1387322488..881ae7d644 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sincrblob2\stest\scase\sso\sthat\sit\sworks\son\s32-bit\ssystems. -D 2015-03-10T15:34:47.080 +C Arrange\sfor\ssome\sof\sthe\stransient\slocks\sin\sWAL\smode\sto\sblock,\sas\sa\ssingle\nto\sthe\sOS\sto\sfix\spriority\sinversions. +D 2015-03-10T20:22:35.302 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -214,7 +214,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 49d06acee4053920e4a6429844f440b5f975cea4 +F src/os_unix.c cc903ecc6ebda90ef703d043ddaa7f33de0cab0f F src/os_win.c 8223e7db5b7c4a81d8b161098ac3959400434cdb F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 4120a49ecd37697e28f5ed807f470b9c0b88410c @@ -232,7 +232,7 @@ F src/resolve.c f4d79e31ffa5820c2e3d1740baa5e9b190425f2b F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c 94e016b6733b1d39a2f4c8d431155b4c2897d907 F src/shell.c cce82ca26392578a4a1ee927dfe55ea3411c7c92 -F src/sqlite.h.in 356e69db9500b3fd11705c21ca247e19b95884a3 +F src/sqlite.h.in 4eb59d93caec4b60eada51d3211087746187edef F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d F src/sqliteInt.h fae682c2b4dfbe489b134d74521c41c088f16ab1 @@ -304,7 +304,7 @@ F src/vdbesort.c 6d64c5448b64851b99931ede980addc3af70d5e2 F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010 F src/vtab.c 699f2b8d509cfe379c33dde33827875d5b030e01 F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb -F src/wal.c 39303f2c9db02a4e422cd8eb2c8760420c6a51fe +F src/wal.c 878c8e1a51cb2ec45c395d26b7d5cd9e1a098e4a F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 F src/where.c eb141b075776e9864d38f279333e2472a8653202 @@ -1241,7 +1241,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P fbae6bafd74d8da9c72be5f562a62f80b01cc846 -R f19e7f30be378d3111028d8dd74f6a7d +P 8d0b11c96e15556dd65ced05708a832aef134e69 +R e3a6235cb886b3e146e5aa9fea4e9436 +T *branch * wal-blocking-lock +T *sym-wal-blocking-lock * +T -sym-trunk * U drh -Z 0ddafeebdf23c7d95a3d79f2f7b9a23f +Z 53b7d268fee9eb6c03e124e757f212c1 diff --git a/manifest.uuid b/manifest.uuid index 3acf7708d9..e908b35f97 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8d0b11c96e15556dd65ced05708a832aef134e69 \ No newline at end of file +c6e6d5f4e06c3ac0bfb620c0c728fbc7230c4a02 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 927b9e1c54..16cb935dec 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -248,6 +248,7 @@ static pid_t randomnessPid = 0; #define UNIXFILE_URI 0x40 /* Filename might have query parameters */ #define UNIXFILE_NOLOCK 0x80 /* Do no file locking */ #define UNIXFILE_WARNED 0x0100 /* verifyDbFile() warnings issued */ +#define UNIXFILE_BLOCK 0x0200 /* Next SHM lock might block */ /* ** Include code that is common to all os_*.c files @@ -4090,15 +4091,17 @@ struct unixShm { ** otherwise. */ static int unixShmSystemLock( - unixShmNode *pShmNode, /* Apply locks to this open shared-memory segment */ + unixFile *pFile, /* Open connection to the WAL file */ int lockType, /* F_UNLCK, F_RDLCK, or F_WRLCK */ int ofst, /* First byte of the locking range */ int n /* Number of bytes to lock */ ){ - struct flock f; /* The posix advisory locking structure */ - int rc = SQLITE_OK; /* Result code form fcntl() */ + unixShmNode *pShmNode; /* Apply locks to this open shared-memory segment */ + struct flock f; /* The posix advisory locking structure */ + int rc = SQLITE_OK; /* Result code form fcntl() */ /* Access to the unixShmNode object is serialized by the caller */ + pShmNode = pFile->pInode->pShmNode; assert( sqlite3_mutex_held(pShmNode->mutex) || pShmNode->nRef==0 ); /* Shared locks never span more than one byte */ @@ -4108,6 +4111,7 @@ static int unixShmSystemLock( assert( n>=1 && nh>=0 ){ + int lkType; /* Initialize the locking parameters */ memset(&f, 0, sizeof(f)); f.l_type = lockType; @@ -4115,8 +4119,10 @@ static int unixShmSystemLock( f.l_start = ofst; f.l_len = n; - rc = osFcntl(pShmNode->h, F_SETLK, &f); + lkType = (pFile->ctrlFlags & UNIXFILE_BLOCK)!=0 ? F_SETLKW : F_SETLK; + rc = osFcntl(pShmNode->h, lkType, &f); rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY; + pFile->ctrlFlags &= ~UNIXFILE_BLOCK; } /* Update the global lock state and do debug tracing */ @@ -4326,13 +4332,13 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ ** If not, truncate the file to zero length. */ rc = SQLITE_OK; - if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){ + if( unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){ if( robust_ftruncate(pShmNode->h, 0) ){ rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename); } } if( rc==SQLITE_OK ){ - rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1); + rc = unixShmSystemLock(pDbFd, F_RDLCK, UNIX_SHM_DMS, 1); } if( rc ) goto shm_open_err; } @@ -4564,7 +4570,7 @@ static int unixShmLock( /* Unlock the system-level locks */ if( (mask & allMask)==0 ){ - rc = unixShmSystemLock(pShmNode, F_UNLCK, ofst+UNIX_SHM_BASE, n); + rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n); }else{ rc = SQLITE_OK; } @@ -4592,7 +4598,7 @@ static int unixShmLock( /* Get shared locks at the system level, if necessary */ if( rc==SQLITE_OK ){ if( (allShared & mask)==0 ){ - rc = unixShmSystemLock(pShmNode, F_RDLCK, ofst+UNIX_SHM_BASE, n); + rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n); }else{ rc = SQLITE_OK; } @@ -4617,7 +4623,7 @@ static int unixShmLock( ** also mark the local connection as being locked. */ if( rc==SQLITE_OK ){ - rc = unixShmSystemLock(pShmNode, F_WRLCK, ofst+UNIX_SHM_BASE, n); + rc = unixShmSystemLock(pDbFd, F_WRLCK, ofst+UNIX_SHM_BASE, n); if( rc==SQLITE_OK ){ assert( (p->sharedMask & mask)==0 ); p->exclMask |= mask; @@ -7222,6 +7228,10 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) { */ static int proxyFileControl(sqlite3_file *id, int op, void *pArg){ switch( op ){ + case SQLITE_FCNTL_WAL_BLOCK: { + id->ctrlFlags |= UNIXFILE_BLOCK; + return SQLITE_OK; + } case SQLITE_FCNTL_GET_LOCKPROXYFILE: { unixFile *pFile = (unixFile*)id; if( pFile->pMethod == &proxyIoMethods ){ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 06e0f7eb9f..f0f6f5ddcf 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -945,6 +945,13 @@ struct sqlite3_io_methods { ** pointed to by the pArg argument. This capability is used during testing ** and only needs to be supported when SQLITE_TEST is defined. ** +**
    • [[SQLITE_FCNTL_WAL_BLOCK]] +** The [SQLITE_FCNTL_WAL_BLOCK] is a single to the VFS layer that it might +** be advantageous to block on the next WAL lock if the lock is not immediately +** available. The WAL subsystem issues this ioctl() during some rare +** circumstances in order to fix a problem with priority inversion. +** Applications should not use this file-control. +** **
    */ #define SQLITE_FCNTL_LOCKSTATE 1 @@ -969,6 +976,7 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_SYNC 21 #define SQLITE_FCNTL_COMMIT_PHASETWO 22 #define SQLITE_FCNTL_WIN32_SET_HANDLE 23 +#define SQLITE_FCNTL_WAL_BLOCK 24 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE diff --git a/src/wal.c b/src/wal.c index 71f4a3d452..558adbcad2 100644 --- a/src/wal.c +++ b/src/wal.c @@ -788,9 +788,10 @@ static void walUnlockShared(Wal *pWal, int lockIdx){ SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED); WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx))); } -static int walLockExclusive(Wal *pWal, int lockIdx, int n){ +static int walLockExclusive(Wal *pWal, int lockIdx, int n, int fBlock){ int rc; if( pWal->exclusiveMode ) return SQLITE_OK; + if( fBlock ) sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_WAL_BLOCK, 0); rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE); WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal, @@ -1076,7 +1077,7 @@ static int walIndexRecover(Wal *pWal){ assert( pWal->writeLock ); iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock; nLock = SQLITE_SHM_NLOCK - iLock; - rc = walLockExclusive(pWal, iLock, nLock); + rc = walLockExclusive(pWal, iLock, nLock, 0); if( rc ){ return rc; } @@ -1610,7 +1611,7 @@ static int walBusyLock( ){ int rc; do { - rc = walLockExclusive(pWal, lockIdx, n); + rc = walLockExclusive(pWal, lockIdx, n, 0); }while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) ); return rc; } @@ -2043,7 +2044,7 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){ walUnlockShared(pWal, WAL_WRITE_LOCK); rc = SQLITE_READONLY_RECOVERY; } - }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){ + }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1, 1)) ){ pWal->writeLock = 1; if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){ badHdr = walIndexTryHdr(pWal, pChanged); @@ -2249,7 +2250,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ && (mxReadMarkhdr.mxFrame || mxI==0) ){ for(i=1; iaReadMark[i] = pWal->hdr.mxFrame; mxI = i; @@ -2505,7 +2506,7 @@ int sqlite3WalBeginWriteTransaction(Wal *pWal){ /* Only one writer allowed at a time. Get the write lock. Return ** SQLITE_BUSY if unable. */ - rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1); + rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1, 0); if( rc ){ return rc; } @@ -2650,7 +2651,7 @@ static int walRestartLog(Wal *pWal){ if( pInfo->nBackfill>0 ){ u32 salt1; sqlite3_randomness(4, &salt1); - rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); + rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1, 0); if( rc==SQLITE_OK ){ /* If all readers are using WAL_READ_LOCK(0) (in other words if no ** readers are currently using the WAL), then the transactions @@ -2975,7 +2976,7 @@ int sqlite3WalCheckpoint( /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive ** "checkpoint" lock on the database file. */ - rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); + rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1, 0); if( rc ){ /* EVIDENCE-OF: R-10421-19736 If any other process is running a ** checkpoint operation at the same time, the lock cannot be obtained and From cc285c5ab021e8973142b7cedce90e2451ba5cf3 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 11 Mar 2015 14:34:38 +0000 Subject: [PATCH 33/57] Expand the multi-process test cases to repeat each case 20 times and to repeat tests using different journal modes. FossilOrigin-Name: a2715b049a86555990abccc7aa363c524ddb9982 --- Makefile.in | 16 ++++++++++++---- manifest | 18 +++++++++--------- manifest.uuid | 2 +- mptest/crash01.test | 4 ++++ mptest/mptest.c | 21 +++++++++++++++++---- mptest/multiwrite01.test | 10 ++++++++++ 6 files changed, 53 insertions(+), 18 deletions(-) diff --git a/Makefile.in b/Makefile.in index 058a13a655..4ac06938fd 100644 --- a/Makefile.in +++ b/Makefile.in @@ -540,11 +540,19 @@ mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c $(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \ $(TLIBS) -rpath "$(libdir)" +MPTEST1=./mptester$(EXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20 +MPTEST2=./mptester$(EXE) mptest.db $(TOP)/mptest/multiwrite01.test --repeat 20 mptest: mptester$(EXE) - rm -f mptest1.db - ./mptester$(EXE) mptest1.db $(TOP)/mptest/crash01.test - rm -f mptest2.db - ./mptester$(EXE) mptest2.db $(TOP)/mptest/multiwrite01.test + rm -f mptest.db + $(MPTEST1) --journalmode DELETE + $(MPTEST2) --journalmode WAL + $(MPTEST1) --journalmode WAL + $(MPTEST2) --journalmode PERSIST + $(MPTEST1) --journalmode PERSIST + $(MPTEST2) --journalmode TRUNCATE + $(MPTEST1) --journalmode TRUNCATE + $(MPTEST2) --journalmode DELETE + # This target creates a directory named "tsrc" and fills it with # copies of all of the C source code and header files needed to diff --git a/manifest b/manifest index 1387322488..abbbe02140 100644 --- a/manifest +++ b/manifest @@ -1,7 +1,7 @@ -C Fix\san\sincrblob2\stest\scase\sso\sthat\sit\sworks\son\s32-bit\ssystems. -D 2015-03-10T15:34:47.080 +C Expand\sthe\smulti-process\stest\scases\sto\srepeat\seach\scase\s20\stimes\sand\nto\srepeat\stests\susing\sdifferent\sjournal\smodes. +D 2015-03-11T14:34:38.239 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f -F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 +F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.msc 529e61cd9d29a3934758b4b3a0bb649b6c653481 F Makefile.vxworks e1b65dea203f054e71653415bd8f96dcaed47858 @@ -158,10 +158,10 @@ F mkopcodeh.awk c6b3fa301db6ef7ac916b14c60868aeaec1337b5 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 -F mptest/crash01.test cce8e306d8596d5a2e497e27112dae1f6e5e3538 +F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 F mptest/crash02.subtest f4ef05adcd15d60e5d2bd654204f2c008b519df8 -F mptest/mptest.c 24c5f72415df2eab7088ef8c9f99f163aed590c8 -F mptest/multiwrite01.test 499ad0310da8dff8e8f98d2e272fc2a8aa741b2e +F mptest/mptest.c 0c0c82c1d9aea0b1a60ef9456a04c35ab1106622 +F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 @@ -1241,7 +1241,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P fbae6bafd74d8da9c72be5f562a62f80b01cc846 -R f19e7f30be378d3111028d8dd74f6a7d +P 8d0b11c96e15556dd65ced05708a832aef134e69 +R 2327229d01e481a57e92de598065db5c U drh -Z 0ddafeebdf23c7d95a3d79f2f7b9a23f +Z cd1fd5866edba6a7b1ae8e17fb546b84 diff --git a/manifest.uuid b/manifest.uuid index 3acf7708d9..57b677aa08 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8d0b11c96e15556dd65ced05708a832aef134e69 \ No newline at end of file +a2715b049a86555990abccc7aa363c524ddb9982 \ No newline at end of file diff --git a/mptest/crash01.test b/mptest/crash01.test index 46f170cecc..f1483dfa1d 100644 --- a/mptest/crash01.test +++ b/mptest/crash01.test @@ -32,6 +32,7 @@ --end --wait 1 --task 2 + DROP TABLE IF EXISTS t2; CREATE TABLE t2(a INTEGER PRIMARY KEY, b); INSERT INTO t2 SELECT a, b FROM t1; UPDATE t1 SET b='x'||a||'y'; @@ -46,6 +47,7 @@ --match 29 28 27 26 25 --end --task 3 + DROP TABLE IF EXISTS t3; CREATE TABLE t3(a INTEGER PRIMARY KEY, b); INSERT INTO t3 SELECT a, b FROM t1; UPDATE t1 SET b='x'||a||'y'; @@ -60,6 +62,7 @@ --match 29 28 27 26 25 --end --task 4 + DROP TABLE IF EXISTS t4; CREATE TABLE t4(a INTEGER PRIMARY KEY, b); INSERT INTO t4 SELECT a, b FROM t1; UPDATE t1 SET b='x'||a||'y'; @@ -74,6 +77,7 @@ --match 29 28 27 26 25 --end --task 5 + DROP TABLE IF EXISTS t5; CREATE TABLE t5(a INTEGER PRIMARY KEY, b); INSERT INTO t5 SELECT a, b FROM t1; UPDATE t1 SET b='x'||a||'y'; diff --git a/mptest/mptest.c b/mptest/mptest.c index 7b56b61902..fdfe5f4a9d 100644 --- a/mptest/mptest.c +++ b/mptest/mptest.c @@ -1262,6 +1262,9 @@ int main(int argc, char **argv){ int taskId; const char *zTrace; const char *zCOption; + const char *zJMode; + const char *zNRep; + int nRep = 1, iRep; g.argv0 = argv[0]; g.iTrace = 1; @@ -1277,6 +1280,10 @@ int main(int argc, char **argv){ } n = argc-2; sqlite3_snprintf(sizeof(g.zName), g.zName, "%05d.mptest", GETPID()); + zJMode = findOption(argv+2, &n, "journalmode", 1); + zNRep = findOption(argv+2, &n, "repeat", 1); + if( zNRep ) nRep = atoi(zNRep); + if( nRep<1 ) nRep = 1; g.zVfs = findOption(argv+2, &n, "vfs", 1); zClient = findOption(argv+2, &n, "client", 1); g.zErrLog = findOption(argv+2, &n, "errlog", 1); @@ -1348,7 +1355,11 @@ int main(int argc, char **argv){ fatalError("missing script filename"); } if( n>1 ) unrecognizedArguments(argv[0], n, argv+2); + if( zJMode ) runSql("PRAGMA journal_mode=%Q;", zJMode); runSql( + "DROP TABLE IF EXISTS task;\n" + "DROP TABLE IF EXISTS counters;\n" + "DROP TABLE IF EXISTS client;\n" "CREATE TABLE task(\n" " id INTEGER PRIMARY KEY,\n" " name TEXT,\n" @@ -1364,10 +1375,12 @@ int main(int argc, char **argv){ "CREATE TABLE client(id INTEGER PRIMARY KEY, wantHalt);\n" ); zScript = readFile(argv[2]); - if( g.iTrace ) logMessage("begin script [%s]\n", argv[2]); - runScript(0, 0, zScript, argv[2]); + for(iRep=1; iRep<=nRep; iRep++){ + if( g.iTrace ) logMessage("begin script [%s] cycle %d\n", argv[2], iRep); + runScript(0, 0, zScript, argv[2]); + if( g.iTrace ) logMessage("end script [%s] cycle %d\n", argv[2], iRep); + } sqlite3_free(zScript); - if( g.iTrace ) logMessage("end script [%s]\n", argv[2]); waitForClient(0, 2000, "during shutdown...\n"); trySql("UPDATE client SET wantHalt=1"); sqlite3_sleep(10); @@ -1391,7 +1404,7 @@ int main(int argc, char **argv){ } sqlite3_finalize(pStmt); } - sqlite3_close(g.db); + sqlite3_close(g.db); maybeClose(g.pLog); maybeClose(g.pErrLog); if( iClient==0 ){ diff --git a/mptest/multiwrite01.test b/mptest/multiwrite01.test index 4f88a68949..7062ae0d51 100644 --- a/mptest/multiwrite01.test +++ b/mptest/multiwrite01.test @@ -361,6 +361,8 @@ PRAGMA integrity_check(10); WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y') ORDER BY t3.a LIMIT 7 --match 45 46 47 48 49 50 51 + PRAGMA integrity_check; + --match ok --end --task 5 SELECT t1.a FROM t1, t2 @@ -371,6 +373,8 @@ PRAGMA integrity_check(10); WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y') ORDER BY t3.a LIMIT 7 --match 45 46 47 48 49 50 51 + PRAGMA integrity_check; + --match ok --end --task 3 SELECT t1.a FROM t1, t2 @@ -381,6 +385,8 @@ PRAGMA integrity_check(10); WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y') ORDER BY t3.a LIMIT 7 --match 45 46 47 48 49 50 51 + PRAGMA integrity_check; + --match ok --end --task 2 SELECT t1.a FROM t1, t2 @@ -391,6 +397,8 @@ PRAGMA integrity_check(10); WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y') ORDER BY t3.a LIMIT 7 --match 45 46 47 48 49 50 51 + PRAGMA integrity_check; + --match ok --end --task 4 SELECT t1.a FROM t1, t2 @@ -401,5 +409,7 @@ PRAGMA integrity_check(10); WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y') ORDER BY t3.a LIMIT 7 --match 45 46 47 48 49 50 51 + PRAGMA integrity_check; + --match ok --end --wait all From 18bf80768934fe2f610de8eb8334806a73c181ff Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 11 Mar 2015 20:06:40 +0000 Subject: [PATCH 34/57] Allow the query planner to evaluate deterministic scalar SQL functions used in WHERE constraints if all arguments are SQL literals in order to compare the results with sqlite_stat4 sample data. FossilOrigin-Name: b7f1fc26d24012e1e7c7f6b3cc0b84ad2b02b8ad --- manifest | 20 ++++--- manifest.uuid | 2 +- src/vdbeapi.c | 13 +++-- src/vdbemem.c | 126 +++++++++++++++++++++++++++++++++++++++++++++ test/analyzeF.test | 78 ++++++++++++++++++++++++++++ 5 files changed, 225 insertions(+), 14 deletions(-) create mode 100644 test/analyzeF.test diff --git a/manifest b/manifest index abbbe02140..60c76c5cba 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Expand\sthe\smulti-process\stest\scases\sto\srepeat\seach\scase\s20\stimes\sand\nto\srepeat\stests\susing\sdifferent\sjournal\smodes. -D 2015-03-11T14:34:38.239 +C Allow\sthe\squery\splanner\sto\sevaluate\sdeterministic\sscalar\sSQL\sfunctions\sused\sin\sWHERE\sconstraints\sif\sall\sarguments\sare\sSQL\sliterals\sin\sorder\sto\scompare\sthe\sresults\swith\ssqlite_stat4\ssample\sdata. +D 2015-03-11T20:06:40.904 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -296,10 +296,10 @@ F src/vacuum.c 9460b9de7b2d4e34b0d374894aa6c8a0632be8ec F src/vdbe.c 94cbc2115075b1a562a2a702c29ba48e74f85d34 F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3 F src/vdbeInt.h bb56fd199d8af1a2c1b9639ee2f70724b4338e3a -F src/vdbeapi.c dac0d0d8009a8aa549cd77d9c29da44c0344f0c4 +F src/vdbeapi.c 5c207659c8a57c12c3f77a8fb97544e032fc2f14 F src/vdbeaux.c 97911edb61074b871ec4aa2d6bb779071643dee5 F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90 -F src/vdbemem.c 31d8eabb0cd78bfeab4e5124c7363c3e9e54db9f +F src/vdbemem.c 8572106eb3b64ad6e02698c0fb312ccb47bb5c9e F src/vdbesort.c 6d64c5448b64851b99931ede980addc3af70d5e2 F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010 F src/vtab.c 699f2b8d509cfe379c33dde33827875d5b030e01 @@ -333,6 +333,7 @@ F test/analyzeB.test 8bf35ee0a548aea831bf56762cb8e7fdb1db083d F test/analyzeC.test 555a6cc388b9818b6eda6df816f01ce0a75d3a93 F test/analyzeD.test 08f9d0bee4e118a66fff3a32d02dbe0ee0a2b594 F test/analyzeE.test 8684e8ac5722fb97c251887ad97e5d496a98af1d +F test/analyzeF.test 299a47183c648d8ad92671f313def8fd7cb09875 F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7 @@ -1241,7 +1242,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8d0b11c96e15556dd65ced05708a832aef134e69 -R 2327229d01e481a57e92de598065db5c -U drh -Z cd1fd5866edba6a7b1ae8e17fb546b84 +P a2715b049a86555990abccc7aa363c524ddb9982 +R 8289f5b5a84378b5cf3294cc8646b1fb +T *branch * stat4-function +T *sym-stat4-function * +T -sym-trunk * +U dan +Z a4cf4e61f3250d5413e8887a5d5cd094 diff --git a/manifest.uuid b/manifest.uuid index 57b677aa08..28f0ab069b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a2715b049a86555990abccc7aa363c524ddb9982 \ No newline at end of file +b7f1fc26d24012e1e7c7f6b3cc0b84ad2b02b8ad \ No newline at end of file diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 8c0038e4e8..fc3d60f20b 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -637,12 +637,13 @@ sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){ */ sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){ Vdbe *v = p->pVdbe; + sqlite3_int64 iTime = 0; int rc; - if( v->iCurrentTime==0 ){ - rc = sqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, &v->iCurrentTime); - if( rc ) v->iCurrentTime = 0; - } - return v->iCurrentTime; + if( v && v->iCurrentTime ) return v->iCurrentTime; + rc = sqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, &iTime); + if( rc ) return 0; + if( v ) v->iCurrentTime = iTime; + return iTime; } /* @@ -712,6 +713,7 @@ void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){ AuxData *pAuxData; assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + if( pCtx->pVdbe==0 ) return 0; for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){ if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break; } @@ -735,6 +737,7 @@ void sqlite3_set_auxdata( assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); if( iArg<0 ) goto failed; + if( pVdbe==0 ) goto failed; for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){ if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break; diff --git a/src/vdbemem.c b/src/vdbemem.c index 870fb5bd89..ce7b73deac 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1134,6 +1134,128 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){ return sqlite3ValueNew(db); } +/* +** The expression object indicated by the second argument is guaranteed +** to be a scalar SQL function. If +** +** * all function arguments are SQL literals, +** * the SQLITE_FUNC_CONSTANT function flag is set, +** * the SQLITE_FUNC_NEEDCOLL function flag is not set, and +** * this routine is being invoked as part of examining stat4 data, +** not as part of handling a default value on a column created using +** ALTER TABLE ADD COLUMN, +** +** then this routine attempts to invoke the SQL function. Assuming no +** error occurs, output parameter (*ppVal) is set to point to a value +** object containing the result before returning SQLITE_OK. +** +** Affinity aff is applied to the result of the function before returning. +** If the result is a text value, the sqlite3_value object uses encoding +** enc. +** +** If the conditions above are not met, this function returns SQLITE_OK +** and sets (*ppVal) to NULL. Or, if an error occurs, (*ppVal) is set to +** NULL and an SQLite error code returned. +*/ +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 +static int valueFromFunction( + sqlite3 *db, /* The database connection */ + Expr *p, /* The expression to evaluate */ + u8 enc, /* Encoding to use */ + u8 aff, /* Affinity to use */ + sqlite3_value **ppVal, /* Write the new value here */ + struct ValueNewStat4Ctx *pCtx /* Second argument for valueNew() */ +){ + sqlite3_context ctx; /* Context object for function invocation */ + sqlite3_value **apVal = 0; /* Function arguments */ + int nVal = 0; /* Size of apVal[] array */ + FuncDef *pFunc = 0; /* Function definition */ + sqlite3_value *pVal = 0; /* New value */ + int rc = SQLITE_OK; /* Return code */ + int nName; /* Size of function name in bytes */ + ExprList *pList; /* Function arguments */ + int i; /* Iterator variable */ + + /* If pCtx==0, then this is probably being called to to obtain an + ** sqlite3_value object for the default value of a column. In that case + ** function expressions are not supported. Function expressions are + ** only supported when extracting values to compare with sqlite_stat4 + ** records. + ** + ** It may also be that this function expression is an argument passed + ** to another function expression. As in "f2(...)" within the query: + ** + ** SELECT * FROM tbl WHERE tbl.c = f1(0, f2(...), 1); + ** + ** For now, extracting the value of "f1(...)" is not supported either. + */ + if( pCtx==0 ) return SQLITE_OK; + + assert( (p->flags & (EP_TokenOnly|EP_Reduced))==0 ); + pList = p->x.pList; + if( pList ) nVal = pList->nExpr; + nName = sqlite3Strlen30(p->u.zToken); + pFunc = sqlite3FindFunction(db, p->u.zToken, nName, nVal, enc, 0); + assert( pFunc ); + if( (pFunc->funcFlags & SQLITE_FUNC_CONSTANT)==0 + || (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL) + ){ + return SQLITE_OK; + } + + if( pList ){ + apVal = (sqlite3_value**)sqlite3DbMallocZero(db, sizeof(apVal[0]) * nVal); + if( apVal==0 ){ + rc = SQLITE_NOMEM; + goto value_from_function_out; + } + for(i=0; ia[i].pExpr, enc, aff, &apVal[i]); + if( apVal[i]==0 ) goto value_from_function_out; + assert( rc==SQLITE_OK ); + } + } + + pVal = valueNew(db, pCtx); + if( pVal==0 ){ + rc = SQLITE_NOMEM; + goto value_from_function_out; + } + + memset(&ctx, 0, sizeof(ctx)); + ctx.pOut = pVal; + ctx.pFunc = pFunc; + pFunc->xFunc(&ctx, nVal, apVal); + if( ctx.isError ){ + rc = ctx.isError; + sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal)); + }else{ + sqlite3ValueApplyAffinity(pVal, aff, SQLITE_UTF8); + if( rc==SQLITE_OK ){ + rc = sqlite3VdbeChangeEncoding(pVal, enc); + } + if( rc==SQLITE_OK && sqlite3VdbeMemTooBig(pVal) ){ + rc = SQLITE_TOOBIG; + } + } + + value_from_function_out: + if( rc!=SQLITE_OK ){ + if( pCtx==0 ) sqlite3ValueFree(pVal); + pVal = 0; + } + for(i=0; i Date: Wed, 11 Mar 2015 20:59:42 +0000 Subject: [PATCH 35/57] Allow the default value for columns added using ALTER TABLE ADD COLUMN to be a function in existing schemas loaded from disk. But prevent this version of SQLite from being used to create such a column. FossilOrigin-Name: ff868e22ca0393eaac417872a4c10738f0d7d970 --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/alter.c | 4 +++- src/vdbemem.c | 33 ++++++++------------------------- 4 files changed, 19 insertions(+), 37 deletions(-) diff --git a/manifest b/manifest index 60c76c5cba..421022d674 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sthe\squery\splanner\sto\sevaluate\sdeterministic\sscalar\sSQL\sfunctions\sused\sin\sWHERE\sconstraints\sif\sall\sarguments\sare\sSQL\sliterals\sin\sorder\sto\scompare\sthe\sresults\swith\ssqlite_stat4\ssample\sdata. -D 2015-03-11T20:06:40.904 +C Allow\sthe\sdefault\svalue\sfor\scolumns\sadded\susing\sALTER\sTABLE\sADD\sCOLUMN\sto\sbe\sa\sfunction\sin\sexisting\sschemas\sloaded\sfrom\sdisk.\sBut\sprevent\sthis\sversion\sof\sSQLite\sfrom\sbeing\sused\sto\screate\ssuch\sa\scolumn. +D 2015-03-11T20:59:42.115 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c ba266a779bc7ce10e52e59e7d3dc79fa342e8fdb +F src/alter.c 809313ddb2dea2a8cdd2d0da944d6a859e3657dc F src/analyze.c 91540f835163d5369ccbae78e2e6c74d0dd53c1d F src/attach.c 880f9b8641a829c563e52dd13c452ce457ae4dd8 F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 @@ -299,7 +299,7 @@ F src/vdbeInt.h bb56fd199d8af1a2c1b9639ee2f70724b4338e3a F src/vdbeapi.c 5c207659c8a57c12c3f77a8fb97544e032fc2f14 F src/vdbeaux.c 97911edb61074b871ec4aa2d6bb779071643dee5 F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90 -F src/vdbemem.c 8572106eb3b64ad6e02698c0fb312ccb47bb5c9e +F src/vdbemem.c 85dd9cb7a98717ad821d388c10053da2fe66f0f7 F src/vdbesort.c 6d64c5448b64851b99931ede980addc3af70d5e2 F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010 F src/vtab.c 699f2b8d509cfe379c33dde33827875d5b030e01 @@ -1242,10 +1242,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a2715b049a86555990abccc7aa363c524ddb9982 -R 8289f5b5a84378b5cf3294cc8646b1fb -T *branch * stat4-function -T *sym-stat4-function * -T -sym-trunk * +P b7f1fc26d24012e1e7c7f6b3cc0b84ad2b02b8ad +R 3e606265a1ac491b0b1ab16052f58807 U dan -Z a4cf4e61f3250d5413e8887a5d5cd094 +Z 8153e0e591b223bdb869dacd2f48bbd5 diff --git a/manifest.uuid b/manifest.uuid index 28f0ab069b..906c7ad764 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b7f1fc26d24012e1e7c7f6b3cc0b84ad2b02b8ad \ No newline at end of file +ff868e22ca0393eaac417872a4c10738f0d7d970 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index dd060248b8..908b251f06 100644 --- a/src/alter.c +++ b/src/alter.c @@ -690,7 +690,9 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ */ if( pDflt ){ sqlite3_value *pVal = 0; - if( sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){ + if( pDflt->op!=TK_FUNCTION + && sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) + ){ db->mallocFailed = 1; return; } diff --git a/src/vdbemem.c b/src/vdbemem.c index ce7b73deac..269afe148c 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1139,11 +1139,8 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){ ** to be a scalar SQL function. If ** ** * all function arguments are SQL literals, -** * the SQLITE_FUNC_CONSTANT function flag is set, -** * the SQLITE_FUNC_NEEDCOLL function flag is not set, and -** * this routine is being invoked as part of examining stat4 data, -** not as part of handling a default value on a column created using -** ALTER TABLE ADD COLUMN, +** * the SQLITE_FUNC_CONSTANT function flag is set, and +** * the SQLITE_FUNC_NEEDCOLL function flag is not set, ** ** then this routine attempts to invoke the SQL function. Assuming no ** error occurs, output parameter (*ppVal) is set to point to a value @@ -1173,27 +1170,13 @@ static int valueFromFunction( sqlite3_value *pVal = 0; /* New value */ int rc = SQLITE_OK; /* Return code */ int nName; /* Size of function name in bytes */ - ExprList *pList; /* Function arguments */ + ExprList *pList = 0; /* Function arguments */ int i; /* Iterator variable */ - /* If pCtx==0, then this is probably being called to to obtain an - ** sqlite3_value object for the default value of a column. In that case - ** function expressions are not supported. Function expressions are - ** only supported when extracting values to compare with sqlite_stat4 - ** records. - ** - ** It may also be that this function expression is an argument passed - ** to another function expression. As in "f2(...)" within the query: - ** - ** SELECT * FROM tbl WHERE tbl.c = f1(0, f2(...), 1); - ** - ** For now, extracting the value of "f1(...)" is not supported either. - */ - if( pCtx==0 ) return SQLITE_OK; - - assert( (p->flags & (EP_TokenOnly|EP_Reduced))==0 ); - pList = p->x.pList; - if( pList ) nVal = pList->nExpr; + if( (p->flags & EP_TokenOnly)==0 ){ + pList = p->x.pList; + if( pList ) nVal = pList->nExpr; + } nName = sqlite3Strlen30(p->u.zToken); pFunc = sqlite3FindFunction(db, p->u.zToken, nName, nVal, enc, 0); assert( pFunc ); @@ -1228,7 +1211,7 @@ static int valueFromFunction( pFunc->xFunc(&ctx, nVal, apVal); if( ctx.isError ){ rc = ctx.isError; - sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal)); + if( pCtx ) sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal)); }else{ sqlite3ValueApplyAffinity(pVal, aff, SQLITE_UTF8); if( rc==SQLITE_OK ){ From 0a0d0560aba40e958d1a4d801041f34120f97fc9 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 12 Mar 2015 05:08:34 +0000 Subject: [PATCH 36/57] Improve the text on one of the opcode documentation comments in vdbe.c. FossilOrigin-Name: 08958f57970d2346f3e98e62225e2b5d351d12d8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index abbbe02140..eb1ce5769c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Expand\sthe\smulti-process\stest\scases\sto\srepeat\seach\scase\s20\stimes\sand\nto\srepeat\stests\susing\sdifferent\sjournal\smodes. -D 2015-03-11T14:34:38.239 +C Improve\sthe\stext\son\sone\sof\sthe\sopcode\sdocumentation\scomments\sin\svdbe.c. +D 2015-03-12T05:08:34.697 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -293,7 +293,7 @@ F src/update.c 3c4ecc282accf12d39edb8d524cf089645e55a13 F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/util.c 98a7627ca48ad3265b6940915a1d08355eb3fc7e F src/vacuum.c 9460b9de7b2d4e34b0d374894aa6c8a0632be8ec -F src/vdbe.c 94cbc2115075b1a562a2a702c29ba48e74f85d34 +F src/vdbe.c a2725107658fd9572637e8e09d46dcfe851edb96 F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3 F src/vdbeInt.h bb56fd199d8af1a2c1b9639ee2f70724b4338e3a F src/vdbeapi.c dac0d0d8009a8aa549cd77d9c29da44c0344f0c4 @@ -1241,7 +1241,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8d0b11c96e15556dd65ced05708a832aef134e69 -R 2327229d01e481a57e92de598065db5c +P a2715b049a86555990abccc7aa363c524ddb9982 +R 1bec88e395839df1ba1894bf7660872a U drh -Z cd1fd5866edba6a7b1ae8e17fb546b84 +Z 0eea53c05ab1bdce3a6e00e90246f492 diff --git a/manifest.uuid b/manifest.uuid index 57b677aa08..8c4aa9928d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a2715b049a86555990abccc7aa363c524ddb9982 \ No newline at end of file +08958f57970d2346f3e98e62225e2b5d351d12d8 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index f81bfa8a79..b67a3e766c 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1517,7 +1517,7 @@ arithmetic_result_is_null: ** ** The interface used by the implementation of the aforementioned functions ** to retrieve the collation sequence set by this opcode is not available -** publicly, only to user functions defined in func.c. +** publicly. Only built-in functions have access to this feature. */ case OP_CollSeq: { assert( pOp->p4type==P4_COLLSEQ ); From a9e03b1b82312b2b99c0b6b443c4a09c8dd70e05 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 12 Mar 2015 06:46:52 +0000 Subject: [PATCH 37/57] The valueFromFunction() routine is better able to handle OOM errors. Omit unreachable branches. FossilOrigin-Name: 8fb6bd9be59d6b04e922d7b246aaefd4851539b6 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/func.c | 4 +++- src/vdbeapi.c | 34 ++++++++++++++++++++++++++-------- src/vdbemem.c | 11 ++++++----- 5 files changed, 45 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index 421022d674..1dc1a5dfbc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sthe\sdefault\svalue\sfor\scolumns\sadded\susing\sALTER\sTABLE\sADD\sCOLUMN\sto\sbe\sa\sfunction\sin\sexisting\sschemas\sloaded\sfrom\sdisk.\sBut\sprevent\sthis\sversion\sof\sSQLite\sfrom\sbeing\sused\sto\screate\ssuch\sa\scolumn. -D 2015-03-11T20:59:42.115 +C The\svalueFromFunction()\sroutine\sis\sbetter\sable\sto\shandle\sOOM\serrors.\nOmit\sunreachable\sbranches. +D 2015-03-12T06:46:52.204 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -185,7 +185,7 @@ F src/delete.c 37964e6c1d73ff49cbea9ff690c9605fb15f600e F src/expr.c 3ef111b88ae2941b84b6b6ea4be8d501ba1af0cb F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e0444b61bed271a76840cbe6182df93a9baa3f12 -F src/func.c 44512c557d6d4a40e51f3980c5854ae3e92862d6 +F src/func.c 1414c24c873c48796ad45942257a179a423ba42f F src/global.c 4f77cadbc5427d00139ba43d0f3979804cbb700e F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 @@ -296,10 +296,10 @@ F src/vacuum.c 9460b9de7b2d4e34b0d374894aa6c8a0632be8ec F src/vdbe.c 94cbc2115075b1a562a2a702c29ba48e74f85d34 F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3 F src/vdbeInt.h bb56fd199d8af1a2c1b9639ee2f70724b4338e3a -F src/vdbeapi.c 5c207659c8a57c12c3f77a8fb97544e032fc2f14 +F src/vdbeapi.c da6551c9a9b9272f9cf7c776a09302ce9ca691d3 F src/vdbeaux.c 97911edb61074b871ec4aa2d6bb779071643dee5 F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90 -F src/vdbemem.c 85dd9cb7a98717ad821d388c10053da2fe66f0f7 +F src/vdbemem.c ba461e1aa9a3b2ef0507748057dd1ab9b850ea45 F src/vdbesort.c 6d64c5448b64851b99931ede980addc3af70d5e2 F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010 F src/vtab.c 699f2b8d509cfe379c33dde33827875d5b030e01 @@ -1242,7 +1242,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b7f1fc26d24012e1e7c7f6b3cc0b84ad2b02b8ad -R 3e606265a1ac491b0b1ab16052f58807 -U dan -Z 8153e0e591b223bdb869dacd2f48bbd5 +P ff868e22ca0393eaac417872a4c10738f0d7d970 +R 116c507ff65f2736c7022117ecad1fa2 +U drh +Z e8a2ef91ffc822055ee072f19f53dce6 diff --git a/manifest.uuid b/manifest.uuid index 906c7ad764..83d9b81077 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ff868e22ca0393eaac417872a4c10738f0d7d970 \ No newline at end of file +8fb6bd9be59d6b04e922d7b246aaefd4851539b6 \ No newline at end of file diff --git a/src/func.c b/src/func.c index d917bdbec3..782a240884 100644 --- a/src/func.c +++ b/src/func.c @@ -22,7 +22,9 @@ ** Return the collating function associated with a function. */ static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){ - VdbeOp *pOp = &context->pVdbe->aOp[context->iOp-1]; + VdbeOp *pOp; + assert( context->pVdbe!=0 ); + pOp = &context->pVdbe->aOp[context->iOp-1]; assert( pOp->opcode==OP_CollSeq ); assert( pOp->p4type==P4_COLLSEQ ); return pOp->p4.pColl; diff --git a/src/vdbeapi.c b/src/vdbeapi.c index fc3d60f20b..42cc715d7c 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -633,17 +633,27 @@ sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){ } /* -** Return the current time for a statement +** Return the current time for a statement. If the current time +** is requested more than once within the same run of a single prepared +** statement, the exact same time is returned for each invocation regardless +** of the amount of time that elapses between invocations. In other words, +** the time returned is always the time of the first call. */ sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){ - Vdbe *v = p->pVdbe; - sqlite3_int64 iTime = 0; int rc; - if( v && v->iCurrentTime ) return v->iCurrentTime; - rc = sqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, &iTime); - if( rc ) return 0; - if( v ) v->iCurrentTime = iTime; - return iTime; + sqlite3_int64 iTime = 0; +#ifndef SQLITE_ENABLE_STAT3_OR_STAT4 + sqlite3_int64 *piTime = &iTime; + assert( p->pVdbe!=0 ); +#else + sqlite3_int64 *piTime = p->pVdbe!=0 ? &p->pVdbe->iCurrentTime : &iTime; + if( *piTime==0 ) +#endif + { + rc = sqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, piTime); + if( rc ) *piTime = 0; + } + return *piTime; } /* @@ -713,7 +723,11 @@ void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){ AuxData *pAuxData; assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); +#if SQLITE_ENABLE_STAT3_OR_STAT4 if( pCtx->pVdbe==0 ) return 0; +#else + assert( pCtx->pVdbe!=0 ); +#endif for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){ if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break; } @@ -737,7 +751,11 @@ void sqlite3_set_auxdata( assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); if( iArg<0 ) goto failed; +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 if( pVdbe==0 ) goto failed; +#else + assert( pVdbe!=0 ); +#endif for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){ if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break; diff --git a/src/vdbemem.c b/src/vdbemem.c index 269afe148c..8b23d678ea 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1194,8 +1194,7 @@ static int valueFromFunction( } for(i=0; ia[i].pExpr, enc, aff, &apVal[i]); - if( apVal[i]==0 ) goto value_from_function_out; - assert( rc==SQLITE_OK ); + if( apVal[i]==0 || rc!=SQLITE_OK ) goto value_from_function_out; } } @@ -1227,10 +1226,12 @@ static int valueFromFunction( if( pCtx==0 ) sqlite3ValueFree(pVal); pVal = 0; } - for(i=0; i Date: Thu, 12 Mar 2015 18:38:51 +0000 Subject: [PATCH 38/57] If an error occurs in the compile-time evaluation of an application-defined function, then propagate back out the exact error code, not just the generic SQLITE_ERROR. FossilOrigin-Name: 93f42586cc9db63c5a4599ce06630e60204a5bc9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbemem.c | 5 ++++- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 1dc1a5dfbc..9c102ed96c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\svalueFromFunction()\sroutine\sis\sbetter\sable\sto\shandle\sOOM\serrors.\nOmit\sunreachable\sbranches. -D 2015-03-12T06:46:52.204 +C If\san\serror\soccurs\sin\sthe\scompile-time\sevaluation\sof\san\sapplication-defined\nfunction,\sthen\spropagate\sback\sout\sthe\sexact\serror\scode,\snot\sjust\sthe\ngeneric\sSQLITE_ERROR. +D 2015-03-12T18:38:51.338 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -299,7 +299,7 @@ F src/vdbeInt.h bb56fd199d8af1a2c1b9639ee2f70724b4338e3a F src/vdbeapi.c da6551c9a9b9272f9cf7c776a09302ce9ca691d3 F src/vdbeaux.c 97911edb61074b871ec4aa2d6bb779071643dee5 F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90 -F src/vdbemem.c ba461e1aa9a3b2ef0507748057dd1ab9b850ea45 +F src/vdbemem.c 981fa5ac239d6a646b5720779844d991277dcd07 F src/vdbesort.c 6d64c5448b64851b99931ede980addc3af70d5e2 F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010 F src/vtab.c 699f2b8d509cfe379c33dde33827875d5b030e01 @@ -1242,7 +1242,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P ff868e22ca0393eaac417872a4c10738f0d7d970 -R 116c507ff65f2736c7022117ecad1fa2 +P 8fb6bd9be59d6b04e922d7b246aaefd4851539b6 +R 46972b8481418c9af660c8cf08bd0f3b U drh -Z e8a2ef91ffc822055ee072f19f53dce6 +Z f07316ba19973dffcb9b3c2ed85bb043 diff --git a/manifest.uuid b/manifest.uuid index 83d9b81077..b430dfd546 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8fb6bd9be59d6b04e922d7b246aaefd4851539b6 \ No newline at end of file +93f42586cc9db63c5a4599ce06630e60204a5bc9 \ No newline at end of file diff --git a/src/vdbemem.c b/src/vdbemem.c index 8b23d678ea..353bfa7255 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1210,7 +1210,10 @@ static int valueFromFunction( pFunc->xFunc(&ctx, nVal, apVal); if( ctx.isError ){ rc = ctx.isError; - if( pCtx ) sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal)); + if( pCtx ){ + sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal)); + pCtx->pParse->rc = rc; + } }else{ sqlite3ValueApplyAffinity(pVal, aff, SQLITE_UTF8); if( rc==SQLITE_OK ){ From 63c088e7835a81d9711b09424df43af87dc62d72 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 12 Mar 2015 19:12:30 +0000 Subject: [PATCH 39/57] Disable multiplexing of master-journal files in the test_multiplex.c module. FossilOrigin-Name: b8684df395b5585a9428417c2bfd076515560f19 --- manifest | 15 +++++---- manifest.uuid | 2 +- src/test_multiplex.c | 3 ++ test/crashM.test | 80 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 92 insertions(+), 8 deletions(-) create mode 100644 test/crashM.test diff --git a/manifest b/manifest index eb1ce5769c..7b21245301 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\sthe\stext\son\sone\sof\sthe\sopcode\sdocumentation\scomments\sin\svdbe.c. -D 2015-03-12T05:08:34.697 +C Disable\smultiplexing\sof\smaster-journal\sfiles\sin\sthe\stest_multiplex.c\smodule. +D 2015-03-12T19:12:30.098 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -266,7 +266,7 @@ F src/test_intarray.h 9dc57417fb65bc7835cc18548852cc08cc062202 F src/test_journal.c 5360fbe1d1e4416ca36290562fd5a2e3f70f32aa F src/test_loadext.c a5251f956ab6af21e138dc1f9c0399394a510cb4 F src/test_malloc.c b9495384e74923aefde8311de974bf9b0f5ba570 -F src/test_multiplex.c 61edf02530f7511a0529352cd8139ead3af4c401 +F src/test_multiplex.c 97813565daa7ee480abcc5dd1e9984ed1f71eb8c F src/test_multiplex.h c08e4e8f8651f0c5e0509b138ff4d5b43ed1f5d3 F src/test_mutex.c 293042d623ebba969160f471a82aa1551626454f F src/test_onefile.c 0396f220561f3b4eedc450cef26d40c593c69a25 @@ -442,6 +442,7 @@ F test/crash5.test 05dd3aa9dbb751a22d5cdaf22a9c49b6667aa219 F test/crash6.test 4c56f1e40d0291e1110790a99807aa875b1647ba F test/crash7.test 1a194c4900a255258cf94b7fcbfd29536db572df F test/crash8.test 61442a9964ab6b124fc5254e4258b45747842e6f +F test/crashM.test d95f59046fa749b0d0822edf18a717788c8f318d F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8 F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c @@ -1241,7 +1242,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a2715b049a86555990abccc7aa363c524ddb9982 -R 1bec88e395839df1ba1894bf7660872a -U drh -Z 0eea53c05ab1bdce3a6e00e90246f492 +P 08958f57970d2346f3e98e62225e2b5d351d12d8 +R 0a12f0c8ae987d613ddb45d39ab86f14 +U dan +Z 376d550a3accda483a2b851b4ef12904 diff --git a/manifest.uuid b/manifest.uuid index 8c4aa9928d..c810d416da 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -08958f57970d2346f3e98e62225e2b5d351d12d8 \ No newline at end of file +b8684df395b5585a9428417c2bfd076515560f19 \ No newline at end of file diff --git a/src/test_multiplex.c b/src/test_multiplex.c index dbd395d620..cd379f18f6 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -573,6 +573,9 @@ static int multiplexOpen( rc = pSubOpen->pMethods->xFileSize(pSubOpen, &sz); if( rc==SQLITE_OK && zName ){ int bExists; + if( flags & SQLITE_OPEN_MASTER_JOURNAL ){ + pGroup->bEnabled = 0; + }else if( sz==0 ){ if( flags & SQLITE_OPEN_MAIN_JOURNAL ){ /* If opening a main journal file and the first chunk is zero diff --git a/test/crashM.test b/test/crashM.test new file mode 100644 index 0000000000..de10c4589a --- /dev/null +++ b/test/crashM.test @@ -0,0 +1,80 @@ +# 2015 Mar 13 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# Crash tests for the multiplex module with 8.3 filenames enabled. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix crashM + +ifcapable !crashtest||!8_3_names { + finish_test + return +} + +db close +sqlite3_shutdown +sqlite3_config_uri 1 + +foreach f [glob -nocomplain test1.* test2.*] { forcedelete $f } +sqlite3_multiplex_initialize "" 1 +sqlite3 db file:test1.db?8_3_names=1 +sqlite3_multiplex_control db main chunk_size [expr 64*1024] + +do_execsql_test 1.0 { + ATTACH 'file:test2.db?8_3_names=1' AS aux; + + CREATE TABLE t1(x, y); + CREATE INDEX t1x ON t1(x); + CREATE INDEX t1y ON t1(y); + + CREATE TABLE aux.t2(x, y); + CREATE INDEX aux.t2x ON t2(x); + CREATE INDEX aux.t2y ON t2(y); + + WITH s(a) AS ( + SELECT 1 UNION ALL SELECT a+1 FROM s WHERE a<1000 + ) + INSERT INTO t1 SELECT a, randomblob(500) FROM s; + + WITH s(a) AS ( + SELECT 1 UNION ALL SELECT a+1 FROM s WHERE a<1000 + ) + INSERT INTO t2 SELECT a, randomblob(500) FROM s; +} {} + +for {set i 0} {$i < 20} {incr i} { + do_test 2.$i.1 { + crashsql -delay 1 -file test1.db -opendb { + sqlite3_shutdown + sqlite3_config_uri 1 + sqlite3_multiplex_initialize crash 1 + sqlite3 db file:test1.db?8_3_names=1 + sqlite3_multiplex_control db main chunk_size [expr 64*1024] + } { + ATTACH 'file:test2.db?8_3_names=1' AS aux; + BEGIN; + UPDATE t1 SET y = randomblob(500) WHERE (x%10)==0; + UPDATE t2 SET y = randomblob(500) WHERE (x%10)==0; + COMMIT; + } + } {1 {child process exited abnormally}} + + do_execsql_test 2.$i.2 { + PRAGMA main.integrity_check; + PRAGMA aux.integrity_check; + } {ok ok} +} + +catch { db close } +sqlite3_multiplex_shutdown +finish_test From 96f4ad20fd9e7f3c5ecd59145cbe3dc8b7ef8465 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 12 Mar 2015 21:02:36 +0000 Subject: [PATCH 40/57] Always disallow functions as the DEFAULT of a column. Add assert()s and FossilOrigin-Name: a991bb1a9eb54bdbd45bd623e8b304bdfeb481a3 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/alter.c | 7 ++++--- src/vdbeapi.c | 2 +- src/vdbemem.c | 30 ++++++++++++++++-------------- 5 files changed, 30 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index 9c102ed96c..06dd27ad1c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C If\san\serror\soccurs\sin\sthe\scompile-time\sevaluation\sof\san\sapplication-defined\nfunction,\sthen\spropagate\sback\sout\sthe\sexact\serror\scode,\snot\sjust\sthe\ngeneric\sSQLITE_ERROR. -D 2015-03-12T18:38:51.338 +C Always\sdisallow\sfunctions\sas\sthe\sDEFAULT\sof\sa\scolumn.\s\sAdd\sassert()s\sand +D 2015-03-12T21:02:36.947 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 809313ddb2dea2a8cdd2d0da944d6a859e3657dc +F src/alter.c d23d6b6991f66b383934f137fd4384d93fb98c81 F src/analyze.c 91540f835163d5369ccbae78e2e6c74d0dd53c1d F src/attach.c 880f9b8641a829c563e52dd13c452ce457ae4dd8 F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 @@ -296,10 +296,10 @@ F src/vacuum.c 9460b9de7b2d4e34b0d374894aa6c8a0632be8ec F src/vdbe.c 94cbc2115075b1a562a2a702c29ba48e74f85d34 F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3 F src/vdbeInt.h bb56fd199d8af1a2c1b9639ee2f70724b4338e3a -F src/vdbeapi.c da6551c9a9b9272f9cf7c776a09302ce9ca691d3 +F src/vdbeapi.c 1295402cabda4473ddee24955c8f7039514497e4 F src/vdbeaux.c 97911edb61074b871ec4aa2d6bb779071643dee5 F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90 -F src/vdbemem.c 981fa5ac239d6a646b5720779844d991277dcd07 +F src/vdbemem.c d52fa9f3bcf75d27d7b7846d81ee7898829c763d F src/vdbesort.c 6d64c5448b64851b99931ede980addc3af70d5e2 F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010 F src/vtab.c 699f2b8d509cfe379c33dde33827875d5b030e01 @@ -1242,7 +1242,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8fb6bd9be59d6b04e922d7b246aaefd4851539b6 -R 46972b8481418c9af660c8cf08bd0f3b +P 93f42586cc9db63c5a4599ce06630e60204a5bc9 +R b3d39823270cf35170812e8663c1c07d U drh -Z f07316ba19973dffcb9b3c2ed85bb043 +Z b97bd037eac2f46713c8bf83215d5d81 diff --git a/manifest.uuid b/manifest.uuid index b430dfd546..22a8fe8715 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -93f42586cc9db63c5a4599ce06630e60204a5bc9 \ No newline at end of file +a991bb1a9eb54bdbd45bd623e8b304bdfeb481a3 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 908b251f06..03605b25aa 100644 --- a/src/alter.c +++ b/src/alter.c @@ -690,9 +690,10 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ */ if( pDflt ){ sqlite3_value *pVal = 0; - if( pDflt->op!=TK_FUNCTION - && sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) - ){ + int rc; + rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal); + assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); + if( rc!=SQLITE_OK ){ db->mallocFailed = 1; return; } diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 42cc715d7c..ae53d93006 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -370,7 +370,7 @@ void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ pCtx->isError = errCode; pCtx->fErrorOrAux = 1; #ifdef SQLITE_DEBUG - pCtx->pVdbe->rcApp = errCode; + if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode; #endif if( pCtx->pOut->flags & MEM_Null ){ sqlite3VdbeMemSetStr(pCtx->pOut, sqlite3ErrStr(errCode), -1, diff --git a/src/vdbemem.c b/src/vdbemem.c index 353bfa7255..0e9bb873ae 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1090,7 +1090,7 @@ struct ValueNewStat4Ctx { ** Otherwise, if the second argument is non-zero, then this function is ** being called indirectly by sqlite3Stat4ProbeSetValue(). If it has not ** already been allocated, allocate the UnpackedRecord structure that -** that function will return to its caller here. Then return a pointer +** that function will return to its caller here. Then return a pointer to ** an sqlite3_value within the UnpackedRecord.a[] array. */ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){ @@ -1173,10 +1173,10 @@ static int valueFromFunction( ExprList *pList = 0; /* Function arguments */ int i; /* Iterator variable */ - if( (p->flags & EP_TokenOnly)==0 ){ - pList = p->x.pList; - if( pList ) nVal = pList->nExpr; - } + assert( pCtx!=0 ); + assert( (p->flags & EP_TokenOnly)==0 ); + pList = p->x.pList; + if( pList ) nVal = pList->nExpr; nName = sqlite3Strlen30(p->u.zToken); pFunc = sqlite3FindFunction(db, p->u.zToken, nName, nVal, enc, 0); assert( pFunc ); @@ -1210,15 +1210,12 @@ static int valueFromFunction( pFunc->xFunc(&ctx, nVal, apVal); if( ctx.isError ){ rc = ctx.isError; - if( pCtx ){ - sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal)); - pCtx->pParse->rc = rc; - } + sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal)); + pCtx->pParse->rc = rc; }else{ sqlite3ValueApplyAffinity(pVal, aff, SQLITE_UTF8); - if( rc==SQLITE_OK ){ - rc = sqlite3VdbeChangeEncoding(pVal, enc); - } + assert( rc==SQLITE_OK ); + rc = sqlite3VdbeChangeEncoding(pVal, enc); if( rc==SQLITE_OK && sqlite3VdbeMemTooBig(pVal) ){ rc = SQLITE_TOOBIG; } @@ -1226,7 +1223,6 @@ static int valueFromFunction( value_from_function_out: if( rc!=SQLITE_OK ){ - if( pCtx==0 ) sqlite3ValueFree(pVal); pVal = 0; } if( apVal ){ @@ -1275,6 +1271,12 @@ static int valueFromExpr( while( (op = pExpr->op)==TK_UPLUS ) pExpr = pExpr->pLeft; if( NEVER(op==TK_REGISTER) ) op = pExpr->op2; + /* Compressed expressions only appear when parsing the DEFAULT clause + ** on a table column definition, and hence only when pCtx==0. This + ** check ensures that an EP_TokenOnly expression is never passed down + ** into valueFromFunction(). */ + assert( (pExpr->flags & EP_TokenOnly)==0 || pCtx==0 ); + if( op==TK_CAST ){ u8 aff = sqlite3AffinityType(pExpr->u.zToken,0); rc = valueFromExpr(db, pExpr->pLeft, enc, aff, ppVal, pCtx); @@ -1351,7 +1353,7 @@ static int valueFromExpr( } #endif - else if( op==TK_FUNCTION ){ + else if( op==TK_FUNCTION && pCtx!=0 ){ rc = valueFromFunction(db, pExpr, enc, affinity, &pVal, pCtx); } From 3df79a9a1fa48c78b0a5d621791de6ad51c46701 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 12 Mar 2015 23:48:27 +0000 Subject: [PATCH 41/57] Fix the "now" option for date-time functions for cases when STAT4 is disabled. FossilOrigin-Name: 3ac1f6a3cf1a8fd3ab1ca96b2564c13c4b8d2234 --- manifest | 15 +++++++-------- manifest.uuid | 2 +- src/vdbeapi.c | 7 +++---- test/date.test | 2 +- 4 files changed, 12 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 3fe0a0e7b9..b5061eb40e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sSTAT4\sis\senabled,\sallow\sprobes\sof\sthe\sSTAT4\stable\susing\sthe\svalue\nof\sconstant\sfunctions\scomputed\sat\scompile-time. -D 2015-03-12T21:22:08.630 +C Fix\sthe\s"now"\soption\sfor\sdate-time\sfunctions\sfor\scases\swhen\sSTAT4\sis\sdisabled. +D 2015-03-12T23:48:27.096 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -296,7 +296,7 @@ F src/vacuum.c 9460b9de7b2d4e34b0d374894aa6c8a0632be8ec F src/vdbe.c a2725107658fd9572637e8e09d46dcfe851edb96 F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3 F src/vdbeInt.h bb56fd199d8af1a2c1b9639ee2f70724b4338e3a -F src/vdbeapi.c 1295402cabda4473ddee24955c8f7039514497e4 +F src/vdbeapi.c 583d56b129dd27f12bed518270de9ebe521e6a75 F src/vdbeaux.c 97911edb61074b871ec4aa2d6bb779071643dee5 F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90 F src/vdbemem.c d52fa9f3bcf75d27d7b7846d81ee7898829c763d @@ -448,7 +448,7 @@ F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8 F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 -F test/date.test 42973251b9429f2c41b77eb98a7b0b0ba2d3b2c0 +F test/date.test 6b7c1261805155be2c6a3ee073529ff75bc773f0 F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204 F test/dbstatus2.test 10418e62b3db5dca070f0c3eef3ea13946f339c2 F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d @@ -1243,8 +1243,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b8684df395b5585a9428417c2bfd076515560f19 a991bb1a9eb54bdbd45bd623e8b304bdfeb481a3 -R 8dac3425ac00e8cb91887f6600a4a803 -T +closed a991bb1a9eb54bdbd45bd623e8b304bdfeb481a3 +P 0f250957cd82be63e44eb99be6cc10760f4fdfc4 +R d3144e9ce0f6932ade646e074c4a6fee U drh -Z f8e2642fd9bb84da1db25f0a4d97336b +Z 40daa56c14064d43d4b007995d358cfd diff --git a/manifest.uuid b/manifest.uuid index 062ef8e236..d23e56ec10 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0f250957cd82be63e44eb99be6cc10760f4fdfc4 \ No newline at end of file +3ac1f6a3cf1a8fd3ab1ca96b2564c13c4b8d2234 \ No newline at end of file diff --git a/src/vdbeapi.c b/src/vdbeapi.c index ae53d93006..e03640dfbd 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -641,15 +641,14 @@ sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){ */ sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){ int rc; - sqlite3_int64 iTime = 0; #ifndef SQLITE_ENABLE_STAT3_OR_STAT4 - sqlite3_int64 *piTime = &iTime; + sqlite3_int64 *piTime = &p->pVdbe->iCurrentTime; assert( p->pVdbe!=0 ); #else + sqlite3_int64 iTime = 0; sqlite3_int64 *piTime = p->pVdbe!=0 ? &p->pVdbe->iCurrentTime : &iTime; - if( *piTime==0 ) #endif - { + if( *piTime==0 ){ rc = sqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, piTime); if( rc ) *piTime = 0; } diff --git a/test/date.test b/test/date.test index b1d1c677c1..51c8ff378b 100644 --- a/test/date.test +++ b/test/date.test @@ -540,7 +540,7 @@ proc sleeper {} {after 100} do_test date-15.1 { db func sleeper sleeper db eval { - SELECT c - a FROM (SELECT julianday('now') AS a, + SELECT c, a, c - a FROM (SELECT julianday('now') AS a, sleeper(), julianday('now') AS c); } } {0.0} From e9b9f7599a1ba4cafc68ebd120824181b1c96752 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 13 Mar 2015 00:11:09 +0000 Subject: [PATCH 42/57] Remove debugging logic accidently included in the previous check-in. FossilOrigin-Name: 2887fb38ffc28712c34028cd38db2b7993d864eb --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/date.test | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index b5061eb40e..1a145c5348 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\s"now"\soption\sfor\sdate-time\sfunctions\sfor\scases\swhen\sSTAT4\sis\sdisabled. -D 2015-03-12T23:48:27.096 +C Remove\sdebugging\slogic\saccidently\sincluded\sin\sthe\sprevious\scheck-in. +D 2015-03-13T00:11:09.762 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -448,7 +448,7 @@ F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8 F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 -F test/date.test 6b7c1261805155be2c6a3ee073529ff75bc773f0 +F test/date.test 42973251b9429f2c41b77eb98a7b0b0ba2d3b2c0 F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204 F test/dbstatus2.test 10418e62b3db5dca070f0c3eef3ea13946f339c2 F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d @@ -1243,7 +1243,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 0f250957cd82be63e44eb99be6cc10760f4fdfc4 -R d3144e9ce0f6932ade646e074c4a6fee +P 3ac1f6a3cf1a8fd3ab1ca96b2564c13c4b8d2234 +R f96af88025cc91d1b5a757f614ed39bf U drh -Z 40daa56c14064d43d4b007995d358cfd +Z e7218e6f8a6b14017f98ae01eb2e9668 diff --git a/manifest.uuid b/manifest.uuid index d23e56ec10..e5cf9c334d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3ac1f6a3cf1a8fd3ab1ca96b2564c13c4b8d2234 \ No newline at end of file +2887fb38ffc28712c34028cd38db2b7993d864eb \ No newline at end of file diff --git a/test/date.test b/test/date.test index 51c8ff378b..b1d1c677c1 100644 --- a/test/date.test +++ b/test/date.test @@ -540,7 +540,7 @@ proc sleeper {} {after 100} do_test date-15.1 { db func sleeper sleeper db eval { - SELECT c, a, c - a FROM (SELECT julianday('now') AS a, + SELECT c - a FROM (SELECT julianday('now') AS a, sleeper(), julianday('now') AS c); } } {0.0} From 3df305925288e177ff386e63dbf32ff2110030a0 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 13 Mar 2015 08:31:54 +0000 Subject: [PATCH 43/57] Extra tests for commit [0f250957]. FossilOrigin-Name: 5aa522dcb9bfa18d49683f7cc889516984e2bcd2 --- manifest | 24 +++++++++++----------- manifest.uuid | 2 +- src/tclsqlite.c | 37 ++++++++++++++++++++++++---------- src/test_func.c | 17 +++++++++++++++- src/vdbemem.c | 4 +++- test/analyzeF.test | 49 +++++++++++++++++++++++++++++++++++++++++++++ test/mallocK.test | 27 +++++++++++++++++++++++++ test/tclsqlite.test | 2 +- 8 files changed, 135 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index 1a145c5348..fd821ade74 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sdebugging\slogic\saccidently\sincluded\sin\sthe\sprevious\scheck-in. -D 2015-03-13T00:11:09.762 +C Extra\stests\sfor\scommit\s[0f250957]. +D 2015-03-13T08:31:54.154 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -239,7 +239,7 @@ F src/sqliteInt.h fae682c2b4dfbe489b134d74521c41c088f16ab1 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c 81712116e826b0089bb221b018929536b2b5406f F src/table.c e7a09215315a978057fb42c640f890160dbcc45e -F src/tclsqlite.c b290774586f022e16e04ba8ed2f0b8edd86b5b77 +F src/tclsqlite.c fa72a7c5278662357c105ba7925c1d0972506ff9 F src/test1.c 90fbedce75330d48d99eadb7d5f4223e86969585 F src/test2.c 577961fe48961b2f2e5c8b56ee50c3f459d3359d F src/test3.c 64d2afdd68feac1bb5e2ffb8226c8c639f798622 @@ -258,7 +258,7 @@ F src/test_config.c c2d3ff6c129d50183900c7eff14158ff7e9b3f03 F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f -F src/test_func.c 14e543ae4d905ee31dc322b2f8d31bfac1769d45 +F src/test_func.c f1ac201465472e76a73e2f3695c3553c63e7322a F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32 F src/test_intarray.c 6c610a21ab8edde85a3a2c7f2b069244ecf4d834 @@ -299,7 +299,7 @@ F src/vdbeInt.h bb56fd199d8af1a2c1b9639ee2f70724b4338e3a F src/vdbeapi.c 583d56b129dd27f12bed518270de9ebe521e6a75 F src/vdbeaux.c 97911edb61074b871ec4aa2d6bb779071643dee5 F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90 -F src/vdbemem.c d52fa9f3bcf75d27d7b7846d81ee7898829c763d +F src/vdbemem.c 78aef62d0298e15485cb5a429c912c9c3ed054b8 F src/vdbesort.c 6d64c5448b64851b99931ede980addc3af70d5e2 F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010 F src/vtab.c 699f2b8d509cfe379c33dde33827875d5b030e01 @@ -333,7 +333,7 @@ F test/analyzeB.test 8bf35ee0a548aea831bf56762cb8e7fdb1db083d F test/analyzeC.test 555a6cc388b9818b6eda6df816f01ce0a75d3a93 F test/analyzeD.test 08f9d0bee4e118a66fff3a32d02dbe0ee0a2b594 F test/analyzeE.test 8684e8ac5722fb97c251887ad97e5d496a98af1d -F test/analyzeF.test 299a47183c648d8ad92671f313def8fd7cb09875 +F test/analyzeF.test 7ccd7a04f7d3061bde1a8a4dacc4792edccf6bf2 F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7 @@ -727,7 +727,7 @@ F test/mallocG.test 0ff91b65c50bdaba680fb75d87fe4ad35bb7934f F test/mallocH.test 79b65aed612c9b3ed2dcdaa727c85895fd1bfbdb F test/mallocI.test a88c2b9627c8506bf4703d8397420043a786cdb6 F test/mallocJ.test b5d1839da331d96223e5f458856f8ffe1366f62e -F test/mallocK.test 223cc80c870c80d4a9c2014e94133efdf0123f82 +F test/mallocK.test da01dcdd316767b8356741f8d33a23a06a23def5 F test/mallocL.test 252ddc7eb4fbf75364eab17b938816085ff1fc17 F test/malloc_common.tcl 3663f9001ce3e29bbaa9677ffe15cd468e3ec7e3 F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e @@ -908,7 +908,7 @@ F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6 F test/table.test 06271d61eb13871490d38168433c1ef3dd82bb2a F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 -F test/tclsqlite.test 37a61c2da7e3bfe3b8c1a2867199f6b860df5d43 +F test/tclsqlite.test 7fb866443c7deceed22b63948ccd6f76b52ad054 F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 @@ -1243,7 +1243,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 3ac1f6a3cf1a8fd3ab1ca96b2564c13c4b8d2234 -R f96af88025cc91d1b5a757f614ed39bf -U drh -Z e7218e6f8a6b14017f98ae01eb2e9668 +P 2887fb38ffc28712c34028cd38db2b7993d864eb +R b89c9ce97b230db0ae63022a487b40cc +U dan +Z ccca41f9c448bc442b12b8c9fe5620ec diff --git a/manifest.uuid b/manifest.uuid index e5cf9c334d..f5b9305905 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2887fb38ffc28712c34028cd38db2b7993d864eb \ No newline at end of file +5aa522dcb9bfa18d49683f7cc889516984e2bcd2 \ No newline at end of file diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 549a410b28..710084b89e 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -2320,34 +2320,49 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ } /* - ** $db function NAME [-argcount N] SCRIPT + ** $db function NAME [-argcount N] [-deterministic] SCRIPT ** ** Create a new SQL function called NAME. Whenever that function is ** called, invoke SCRIPT to evaluate the function. */ case DB_FUNCTION: { + int flags = SQLITE_UTF8; SqlFunc *pFunc; Tcl_Obj *pScript; char *zName; int nArg = -1; - if( objc==6 ){ - const char *z = Tcl_GetString(objv[3]); + int i; + if( objc<4 ){ + Tcl_WrongNumArgs(interp, 2, objv, "NAME ?SWITCHES? SCRIPT"); + return TCL_ERROR; + } + for(i=3; i<(objc-1); i++){ + const char *z = Tcl_GetString(objv[i]); int n = strlen30(z); if( n>2 && strncmp(z, "-argcount",n)==0 ){ - if( Tcl_GetIntFromObj(interp, objv[4], &nArg) ) return TCL_ERROR; + if( i==(objc-2) ){ + Tcl_AppendResult(interp, "option requires an argument: ", z, 0); + return TCL_ERROR; + } + if( Tcl_GetIntFromObj(interp, objv[i+1], &nArg) ) return TCL_ERROR; if( nArg<0 ){ Tcl_AppendResult(interp, "number of arguments must be non-negative", (char*)0); return TCL_ERROR; } + i++; + }else + if( n>2 && strncmp(z, "-deterministic",n)==0 ){ + flags |= SQLITE_DETERMINISTIC; + }else{ + Tcl_AppendResult(interp, "bad option \"", z, + "\": must be -argcount or -deterministic", 0 + ); + return TCL_ERROR; } - pScript = objv[5]; - }else if( objc!=4 ){ - Tcl_WrongNumArgs(interp, 2, objv, "NAME [-argcount N] SCRIPT"); - return TCL_ERROR; - }else{ - pScript = objv[3]; } + + pScript = objv[objc-1]; zName = Tcl_GetStringFromObj(objv[2], 0); pFunc = findSqlFunc(pDb, zName); if( pFunc==0 ) return TCL_ERROR; @@ -2357,7 +2372,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ pFunc->pScript = pScript; Tcl_IncrRefCount(pScript); pFunc->useEvalObjv = safeToUseEvalObjv(interp, pScript); - rc = sqlite3_create_function(pDb->db, zName, nArg, SQLITE_UTF8, + rc = sqlite3_create_function(pDb->db, zName, nArg, flags, pFunc, tclSqlFunc, 0, 0); if( rc!=SQLITE_OK ){ rc = TCL_ERROR; diff --git a/src/test_func.c b/src/test_func.c index c7850631d7..2e34fa074e 100644 --- a/src/test_func.c +++ b/src/test_func.c @@ -600,12 +600,26 @@ static void test_decode( Tcl_DecrRefCount(pRet); } +/* +** The implementation of scalar SQL function "test_zeroblob()". This is +** similar to the built-in zeroblob() function, except that it does not +** check that the integer parameter is within range before passing it +** to sqlite3_result_zeroblob(). +*/ +static void test_zeroblob( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int nZero = sqlite3_value_int(argv[0]); + sqlite3_result_zeroblob(context, nZero); +} static int registerTestFunctions(sqlite3 *db){ static const struct { char *zName; signed char nArg; - unsigned char eTextRep; /* 1: UTF-16. 0: UTF-8 */ + unsigned int eTextRep; /* 1: UTF-16. 0: UTF-8 */ void (*xFunc)(sqlite3_context*,int,sqlite3_value **); } aFuncs[] = { { "randstr", 2, SQLITE_UTF8, randStr }, @@ -626,6 +640,7 @@ static int registerTestFunctions(sqlite3 *db){ { "real2hex", 1, SQLITE_UTF8, real2hex}, { "test_decode", 1, SQLITE_UTF8, test_decode}, { "test_extract", 2, SQLITE_UTF8, test_extract}, + { "test_zeroblob", 1, SQLITE_UTF8|SQLITE_DETERMINISTIC, test_zeroblob}, }; int i; diff --git a/src/vdbemem.c b/src/vdbemem.c index 0e9bb873ae..b92ec84337 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1204,6 +1204,7 @@ static int valueFromFunction( goto value_from_function_out; } + assert( pCtx->pParse->rc==SQLITE_OK ); memset(&ctx, 0, sizeof(ctx)); ctx.pOut = pVal; ctx.pFunc = pFunc; @@ -1211,15 +1212,16 @@ static int valueFromFunction( if( ctx.isError ){ rc = ctx.isError; sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal)); - pCtx->pParse->rc = rc; }else{ sqlite3ValueApplyAffinity(pVal, aff, SQLITE_UTF8); assert( rc==SQLITE_OK ); rc = sqlite3VdbeChangeEncoding(pVal, enc); if( rc==SQLITE_OK && sqlite3VdbeMemTooBig(pVal) ){ rc = SQLITE_TOOBIG; + pCtx->pParse->nErr++; } } + pCtx->pParse->rc = rc; value_from_function_out: if( rc!=SQLITE_OK ){ diff --git a/test/analyzeF.test b/test/analyzeF.test index e96cd87075..670d178a81 100644 --- a/test/analyzeF.test +++ b/test/analyzeF.test @@ -66,6 +66,8 @@ foreach {tn where idx} { do_eqp_test 1.$tn "SELECT * FROM t1 WHERE $where" $res } +# Test that functions that do not exist - "func()" - do not cause an error. +# do_catchsql_test 2.1 { SELECT * FROM t1 WHERE x = substr('145', 2, 1) AND y = func(1, 2, 3) } {1 {no such function: func}} @@ -74,5 +76,52 @@ do_catchsql_test 2.2 { } {1 {no such function: func}} +# Check that functions that accept zero arguments do not cause problems. +# +proc ret {x} { return $x } + +db func det4 -deterministic [list ret 4] +db func nondet4 [list ret 4] +db func det19 -deterministic [list ret 19] +db func nondet19 [list ret 19] + +foreach {tn where idx} { + 1 "x = det4() AND y = det19()" {t1x (x=?)} + 2 "x = det19() AND y = det4()" {t1y (y=?)} + + 3 "x = nondet4() AND y = nondet19()" {t1y (y=?)} + 4 "x = nondet19() AND y = nondet4()" {t1y (y=?)} +} { + set res "0 0 0 {SEARCH TABLE t1 USING INDEX $idx}" + do_eqp_test 3.$tn "SELECT * FROM t1 WHERE $where" $res +} + + +execsql { DELETE FROM t1 } + +proc throw_error {err} { error $err } +db func error -deterministic throw_error +do_catchsql_test 4.1 { + SELECT * FROM t1 WHERE x = error('error one') AND y = 4; +} {1 {error one}} + +do_catchsql_test 4.2 { + SELECT * FROM t1 WHERE x = zeroblob(2000000000) AND y = 4; +} {1 {string or blob too big}} + +sqlite3_limit db SQLITE_LIMIT_LENGTH 1000000 +proc dstr {} { return [string repeat x 1100000] } +db func dstr -deterministic dstr +do_catchsql_test 4.3 { + SELECT * FROM t1 WHERE x = dstr() AND y = 11; +} {1 {string or blob too big}} + +do_catchsql_test 4.4 { + SELECT * FROM t1 WHERE x = test_zeroblob(1100000) AND y = 4; +} {1 {string or blob too big}} + + finish_test + + diff --git a/test/mallocK.test b/test/mallocK.test index 0a21b9fa0a..65791e79ea 100644 --- a/test/mallocK.test +++ b/test/mallocK.test @@ -143,6 +143,33 @@ do_faultsim_test 7.2 -faults oom* -body { faultsim_test_result [list 0 {}] } +reset_db + +proc isqrt {i} { expr { int(sqrt($i)) } } +db func isqrt isqrt + +do_execsql_test 8.0 { + PRAGMA encoding = 'utf-16'; + CREATE TABLE x2(x TEXT, y TEXT); + WITH data(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM data + ) + INSERT INTO x2 SELECT isqrt(i), isqrt(i) FROM data LIMIT 400; + CREATE INDEX x2x ON x2(x); + CREATE INDEX x2y ON x2(y); + ANALYZE; + DELETE FROM x2; +} + +proc str {a} { return $a } +db func str -deterministic str + +do_faultsim_test 8 -faults oom* -body { + execsql { SELECT * FROM x2 WHERE x = str('19') AND y = str('4') } +} -test { + faultsim_test_result [list 0 {}] +} + finish_test diff --git a/test/tclsqlite.test b/test/tclsqlite.test index 3d9cd46ac6..8d7fea0d2a 100644 --- a/test/tclsqlite.test +++ b/test/tclsqlite.test @@ -118,7 +118,7 @@ do_test tcl-1.14 { do_test tcl-1.15 { set v [catch {db function} msg] lappend v $msg -} {1 {wrong # args: should be "db function NAME [-argcount N] SCRIPT"}} +} {1 {wrong # args: should be "db function NAME ?SWITCHES? SCRIPT"}} do_test tcl-1.16 { set v [catch {db last_insert_rowid xyz} msg] lappend v $msg From dfac7016a7b95ed1b65bd62ea1e6dfbb48ab7d54 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 13 Mar 2015 15:44:36 +0000 Subject: [PATCH 44/57] Add tests to ensure "PRAGMA incremental_vacuum" and "PRAGMA auto_vacuum = incremental" handle corrupt databases correctly. FossilOrigin-Name: 1c2166cb2a387a0856f41b399c3648bf8c5fce73 --- manifest | 11 ++-- manifest.uuid | 2 +- test/incrcorrupt.test | 127 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 134 insertions(+), 6 deletions(-) create mode 100644 test/incrcorrupt.test diff --git a/manifest b/manifest index fd821ade74..e1d464f1a0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Extra\stests\sfor\scommit\s[0f250957]. -D 2015-03-13T08:31:54.154 +C Add\stests\sto\sensure\s"PRAGMA\sincremental_vacuum"\sand\s"PRAGMA\sauto_vacuum\s=\sincremental"\shandle\scorrupt\sdatabases\scorrectly. +D 2015-03-13T15:44:36.085 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -646,6 +646,7 @@ F test/incrblob3.test d8d036fde015d4a159cd3cbae9d29003b37227a4 F test/incrblob4.test f26502a5697893e5acea268c910f16478c2f0fab F test/incrblob_err.test af1f12ba60d220c9752073ff2bda2ad59e88960d F test/incrblobfault.test 280474078f6da9e732cd2a215d3d854969014b6e +F test/incrcorrupt.test 9786cba68c5832f01887fde1c06b43c3904d86f6 F test/incrvacuum.test d2a6ddf5e429720b5fe502766af747915ccf6c32 F test/incrvacuum2.test 676c41428765d58f1da7dbe659ef27726d3d30ac F test/incrvacuum3.test 75256fb1377e7c39ef2de62bfc42bbff67be295a @@ -1243,7 +1244,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2887fb38ffc28712c34028cd38db2b7993d864eb -R b89c9ce97b230db0ae63022a487b40cc +P 5aa522dcb9bfa18d49683f7cc889516984e2bcd2 +R a79445283a8ae7c7f85ae571d23bc239 U dan -Z ccca41f9c448bc442b12b8c9fe5620ec +Z d6c136b9ed1be16533c60706d0427e82 diff --git a/manifest.uuid b/manifest.uuid index f5b9305905..e474b58d5e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5aa522dcb9bfa18d49683f7cc889516984e2bcd2 \ No newline at end of file +1c2166cb2a387a0856f41b399c3648bf8c5fce73 \ No newline at end of file diff --git a/test/incrcorrupt.test b/test/incrcorrupt.test new file mode 100644 index 0000000000..eda65e4035 --- /dev/null +++ b/test/incrcorrupt.test @@ -0,0 +1,127 @@ +# 2001 October 12 +# +# 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 that "PRAGMA incremental_vacuum" detects and reports database +# corruption properly. And that "PRAGMA auto_vacuum = INCREMENTAL" +# does as well. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix incrcorrupt + +# If this build of the library does not support auto-vacuum, omit this +# whole file. +ifcapable {!autovacuum} { + finish_test + return +} + +do_execsql_test 1.0 { + PRAGMA auto_vacuum = 2; + CREATE TABLE t1(a PRIMARY KEY, b); + + WITH data(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM data + ) + INSERT INTO t1 SELECT i, randomblob(600) FROM data LIMIT 20; + PRAGMA page_count; +} {24} + +do_execsql_test 1.1 { + PRAGMA incremental_vacuum; +} {} + +do_test 1.2 { + db_save + hexio_write test.db 36 00000019 + catchsql { PRAGMA incremental_vacuum; } +} {1 {database disk image is malformed}} + +do_test 1.3 { + set stmt [sqlite3_prepare_v2 db "PRAGMA incremental_vacuum" -1 dummy] + sqlite3_step $stmt +} {SQLITE_CORRUPT} +do_test 1.4 { sqlite3_errcode db } {SQLITE_CORRUPT} +do_test 1.5 { sqlite3_errmsg db } {database disk image is malformed} +do_test 1.6 { sqlite3_finalize $stmt } {SQLITE_CORRUPT} +do_test 1.7 { sqlite3_errcode db } {SQLITE_CORRUPT} +do_test 1.8 { sqlite3_errmsg db } {database disk image is malformed} + +do_test 1.9 { + set stmt [sqlite3_prepare_v2 db "PRAGMA incremental_vacuum" -1 dummy] + sqlite3_step $stmt +} {SQLITE_CORRUPT} +do_test 1.10 { sqlite3_errcode db } {SQLITE_CORRUPT} +do_test 1.11 { sqlite3_errmsg db } {database disk image is malformed} + +do_test 1.12 { + set stmt2 [sqlite3_prepare_v2 db "SELECT 1" -1 dummy] + sqlite3_finalize $stmt2 +} {SQLITE_OK} +do_test 1.13 { sqlite3_errcode db } {SQLITE_OK} +do_test 1.14 { sqlite3_errmsg db } {not an error} + +do_test 1.15 { sqlite3_finalize $stmt } {SQLITE_CORRUPT} +do_test 1.16 { sqlite3_errcode db } {SQLITE_CORRUPT} +do_test 1.17 { sqlite3_errmsg db } {database disk image is malformed} + +#------------------------------------------------------------------------- +# +reset_db + +do_execsql_test 2.1 { + PRAGMA auto_vacuum = 1; + CREATE TABLE t1(a PRIMARY KEY, b); + WITH data(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM data + ) + INSERT INTO t1 SELECT i, randomblob(600) FROM data LIMIT 20; + PRAGMA page_count; +} {24} + +do_test 2.2 { + db_save + set fd [open test.db r+] + chan truncate $fd [expr 22*1024] + close $fd + catchsql { PRAGMA incremental_vacuum; } +} {1 {database disk image is malformed}} + +do_test 2.3 { + set stmt [sqlite3_prepare_v2 db "PRAGMA auto_vacuum = INCREMENTAL" -1 dummy] + sqlite3_step $stmt +} {SQLITE_CORRUPT} +do_test 2.4 { sqlite3_errcode db } {SQLITE_CORRUPT} +do_test 2.5 { sqlite3_errmsg db } {database disk image is malformed} +do_test 2.6 { sqlite3_finalize $stmt } {SQLITE_CORRUPT} +do_test 2.7 { sqlite3_errcode db } {SQLITE_CORRUPT} +do_test 2.8 { sqlite3_errmsg db } {database disk image is malformed} + +do_test 2.9 { + set stmt [sqlite3_prepare_v2 db "PRAGMA auto_vacuum = INCREMENTAL" -1 dummy] + sqlite3_step $stmt +} {SQLITE_CORRUPT} +do_test 2.10 { sqlite3_errcode db } {SQLITE_CORRUPT} +do_test 2.11 { sqlite3_errmsg db } {database disk image is malformed} + +do_test 2.12 { + set stmt2 [sqlite3_prepare_v2 db "SELECT 1" -1 dummy] + sqlite3_finalize $stmt2 +} {SQLITE_OK} +do_test 2.13 { sqlite3_errcode db } {SQLITE_OK} +do_test 2.14 { sqlite3_errmsg db } {not an error} + +do_test 2.15 { sqlite3_finalize $stmt } {SQLITE_CORRUPT} +do_test 2.16 { sqlite3_errcode db } {SQLITE_CORRUPT} +do_test 2.17 { sqlite3_errmsg db } {database disk image is malformed} + +finish_test + From a3d0c1365470318410d4993375f34b13a7edc96a Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 14 Mar 2015 18:59:58 +0000 Subject: [PATCH 45/57] When estimating the number of rows visited by a range scan for which the keys consist of more than one field, consider prefixes of stat4 samples as well as the full samples. FossilOrigin-Name: e1caf93c9ad0ee15d42030af95619f212d3fcf9d --- manifest | 17 +++-- manifest.uuid | 2 +- src/where.c | 174 +++++++++++++++++++++++++++++++++++---------- test/analyze9.test | 63 ++++++++++++++++ 4 files changed, 210 insertions(+), 46 deletions(-) diff --git a/manifest b/manifest index e1d464f1a0..4946d588ee 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests\sto\sensure\s"PRAGMA\sincremental_vacuum"\sand\s"PRAGMA\sauto_vacuum\s=\sincremental"\shandle\scorrupt\sdatabases\scorrectly. -D 2015-03-13T15:44:36.085 +C When\sestimating\sthe\snumber\sof\srows\svisited\sby\sa\srange\sscan\sfor\swhich\sthe\skeys\sconsist\sof\smore\sthan\sone\sfield,\sconsider\sprefixes\sof\sstat4\ssamples\sas\swell\sas\sthe\sfull\ssamples. +D 2015-03-14T18:59:58.801 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -307,7 +307,7 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 39303f2c9db02a4e422cd8eb2c8760420c6a51fe F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 -F src/where.c eb141b075776e9864d38f279333e2472a8653202 +F src/where.c 5a4e4ab378dbddeca59ad283c61aa67c6e56a913 F src/whereInt.h cbe4aa57326998d89e7698ca65bb7c28541d483c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -327,7 +327,7 @@ F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4 F test/analyze6.test f1c552ce39cca4ec922a7e4e0e5d0203d6b3281f F test/analyze7.test bb1409afc9e8629e414387ef048b8e0e3e0bdc4f F test/analyze8.test c05a461d0a6b05991106467d0c47480f2e709c82 -F test/analyze9.test 72795c8113604b5dcd47a1498a61d6d7fb5d041a +F test/analyze9.test 2f6cfeae1fcc61cc531bd19f68e1e28fb6edafbf F test/analyzeA.test 3335697f6700c7052295cfd0067fc5b2aacddf9a F test/analyzeB.test 8bf35ee0a548aea831bf56762cb8e7fdb1db083d F test/analyzeC.test 555a6cc388b9818b6eda6df816f01ce0a75d3a93 @@ -1244,7 +1244,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 5aa522dcb9bfa18d49683f7cc889516984e2bcd2 -R a79445283a8ae7c7f85ae571d23bc239 +P 1c2166cb2a387a0856f41b399c3648bf8c5fce73 +R f0473fc546184f7826d3d60610130f49 +T *branch * stat4-change +T *sym-stat4-change * +T -sym-trunk * U dan -Z d6c136b9ed1be16533c60706d0427e82 +Z e2a2579617ea31b6dadba1e9a71ba744 diff --git a/manifest.uuid b/manifest.uuid index e474b58d5e..02ad1198b1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1c2166cb2a387a0856f41b399c3648bf8c5fce73 \ No newline at end of file +e1caf93c9ad0ee15d42030af95619f212d3fcf9d \ No newline at end of file diff --git a/src/where.c b/src/where.c index 8b9060b0a7..6ecc9c33c2 100644 --- a/src/where.c +++ b/src/where.c @@ -1931,11 +1931,14 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ ** Estimate the location of a particular key among all keys in an ** index. Store the results in aStat as follows: ** -** aStat[0] Est. number of rows less than pVal -** aStat[1] Est. number of rows equal to pVal +** aStat[0] Est. number of rows less than pRec +** aStat[1] Est. number of rows equal to pRec ** ** Return the index of the sample that is the smallest sample that -** is greater than or equal to pRec. +** is greater than or equal to pRec. Note that this index is not an index +** into the aSample[] array - it is an index into a virtual set of samples +** based on the contents of aSample[] and the number of fields in record +** pRec. */ static int whereKeyStats( Parse *pParse, /* Database connection */ @@ -1946,67 +1949,158 @@ static int whereKeyStats( ){ IndexSample *aSample = pIdx->aSample; int iCol; /* Index of required stats in anEq[] etc. */ + int i; /* Index of first sample >= pRec */ + int iSample; /* Smallest sample larger than or equal to pRec */ int iMin = 0; /* Smallest sample not yet tested */ - int i = pIdx->nSample; /* Smallest sample larger than or equal to pRec */ int iTest; /* Next sample to test */ int res; /* Result of comparison operation */ + int nField; /* Number of fields in pRec */ + tRowcnt iLower = 0; /* anLt[] + anEq[] of largest sample pRec is > */ #ifndef SQLITE_DEBUG UNUSED_PARAMETER( pParse ); #endif assert( pRec!=0 ); - iCol = pRec->nField - 1; assert( pIdx->nSample>0 ); - assert( pRec->nField>0 && iColnSampleCol ); + assert( pRec->nField>0 && pRec->nField<=pIdx->nSampleCol ); + + /* Do a binary search to find the first sample greater than or equal + ** to pRec. If pRec contains a single field, the set of samples to search + ** is simply the aSample[] array. If the samples in aSample[] contain more + ** than one fields, all fields following the first are ignored. + ** + ** If pRec contains N fields, where N is more than one, then as well as the + ** samples in aSample[] (truncated to N fields), the search also has to + ** consider prefixes of those samples. For example, if the set of samples + ** in aSample is: + ** + ** aSample[0] = (a, 5) + ** aSample[1] = (a, 10) + ** aSample[2] = (b, 5) + ** aSample[3] = (c, 100) + ** aSample[4] = (c, 105) + ** + ** Then the search space should ideally be the samples above and the + ** unique prefixes [a], [b] and [c]. But since that is hard to organize, + ** the code actually searches this set: + ** + ** 0: (a) + ** 1: (a, 5) + ** 2: (a, 10) + ** 3: (a, 10) + ** 4: (b) + ** 5: (b, 5) + ** 6: (c) + ** 7: (c, 100) + ** 8: (c, 105) + ** 9: (c, 105) + ** + ** For each sample in the aSample[] array, N samples are present in the + ** effective sample array. In the above, samples 0 and 1 are based on + ** sample aSample[0]. Samples 2 and 3 on aSample[1] etc. + ** + ** Often, sample i of each block of N effective samples has (i+1) fields. + ** Except, each sample may be extended to ensure that it is greater than or + ** equal to the previous sample in the array. For example, in the above, + ** sample 2 is the first sample of a block of N samples, so at first it + ** appears that it should be 1 field in size. However, that would make it + ** smaller than sample 1, so the binary search would not work. As a result, + ** it is extended to two fields. The duplicates that this creates do not + ** cause any problems. + */ + nField = pRec->nField; + iCol = 0; + iSample = pIdx->nSample * nField; do{ - iTest = (iMin+i)/2; - res = sqlite3VdbeRecordCompare(aSample[iTest].n, aSample[iTest].p, pRec); - if( res<0 ){ - iMin = iTest+1; + int iSamp; /* Index in aSample[] of test sample */ + int n; /* Number of fields in test sample */ + + iTest = (iMin+iSample)/2; + iSamp = iTest / nField; + if( iSamp>0 ){ + /* The proposed effective sample is a prefix of sample aSample[iSamp]. + ** Specifically, the shortest prefix of at least (1 + iTest%nField) + ** fields that is greater than the previous effective sample. */ + for(n=(iTest % nField) + 1; nnField = n; + res = sqlite3VdbeRecordCompare(aSample[iSamp].n, aSample[iSamp].p, pRec); + if( res<0 ){ + iLower = aSample[iSamp].anLt[n-1] + aSample[iSamp].anEq[n-1]; + iMin = iTest+1; + }else if( res==0 && nnSample ); - assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec) - || pParse->db->mallocFailed ); - }else{ - /* Otherwise, pRec must be smaller than sample $i and larger than - ** sample ($i-1). */ - assert( i==pIdx->nSample - || sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)>0 - || pParse->db->mallocFailed ); - assert( i==0 - || sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec)<0 - || pParse->db->mallocFailed ); + if( pParse->db->mallocFailed==0 ){ + if( res==0 ){ + /* If (res==0) is true, then pRec must be equal to sample i. */ + assert( inSample ); + assert( iCol==nField-1 ); + pRec->nField = nField; + assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec) + || pParse->db->mallocFailed + ); + }else{ + /* Unless i==pIdx->nSample, indicating that pRec is larger than + ** all samples in the aSample[] array, pRec must be smaller than the + ** (iCol+1) field prefix of sample i. */ + assert( i<=pIdx->nSample && i>=0 ); + pRec->nField = iCol+1; + assert( i==pIdx->nSample + || sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)>0 + || pParse->db->mallocFailed ); + + /* if i==0 and iCol==0, then record pRec is smaller than all samples + ** in the aSample[] array. Otherwise, if (iCol>0) then pRec must + ** be greater than or equal to the (iCol) field prefix of sample i. + ** If (i>0), then pRec must also be greater than sample (i-1). */ + if( iCol>0 ){ + pRec->nField = iCol; + assert( sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)<=0 + || pParse->db->mallocFailed ); + } + if( i>0 ){ + pRec->nField = nField; + assert( sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec)<0 + || pParse->db->mallocFailed ); + } + } } #endif /* ifdef SQLITE_DEBUG */ - /* At this point, aSample[i] is the first sample that is greater than - ** or equal to pVal. Or if i==pIdx->nSample, then all samples are less - ** than pVal. If aSample[i]==pVal, then res==0. - */ if( res==0 ){ + /* Record pRec is equal to sample i */ + assert( iCol==nField-1 ); aStat[0] = aSample[i].anLt[iCol]; aStat[1] = aSample[i].anEq[iCol]; }else{ - tRowcnt iLower, iUpper, iGap; - if( i==0 ){ - iLower = 0; - iUpper = aSample[0].anLt[iCol]; + /* At this point, the (iCol+1) field prefix of aSample[i] is the first + ** sample that is greater than pRec. Or, if i==pIdx->nSample then pRec + ** is larger than all samples in the array. */ + tRowcnt iUpper, iGap; + if( i>=pIdx->nSample ){ + iUpper = sqlite3LogEstToInt(pIdx->aiRowLogEst[0]); }else{ - i64 nRow0 = sqlite3LogEstToInt(pIdx->aiRowLogEst[0]); - iUpper = i>=pIdx->nSample ? nRow0 : aSample[i].anLt[iCol]; - iLower = aSample[i-1].anEq[iCol] + aSample[i-1].anLt[iCol]; + iUpper = aSample[i].anLt[iCol]; } - aStat[1] = pIdx->aAvgEq[iCol]; + if( iLower>=iUpper ){ iGap = 0; }else{ @@ -2018,7 +2112,11 @@ static int whereKeyStats( iGap = iGap/3; } aStat[0] = iLower + iGap; + aStat[1] = pIdx->aAvgEq[iCol]; } + + /* Restore the pRec->nField value before returning. */ + pRec->nField = nField; return i; } #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ diff --git a/test/analyze9.test b/test/analyze9.test index 8572cbea00..6e85272ad6 100644 --- a/test/analyze9.test +++ b/test/analyze9.test @@ -1134,4 +1134,67 @@ ifcapable stat4&&cte { } } +#------------------------------------------------------------------------- +# Check that a problem in they way stat4 data is used has been +# resolved (see below). +# +reset_db +do_test 26.1 { + db transaction { + execsql { + CREATE TABLE t1(x, y, z); + CREATE INDEX t1xy ON t1(x, y); + CREATE INDEX t1z ON t1(z); + } + for {set i 0} {$i < 10000} {incr i} { + execsql { INSERT INTO t1(x, y) VALUES($i, $i) } + } + for {set i 0} {$i < 10} {incr i} { + execsql { + WITH cnt(x) AS (SELECT 1 UNION ALL SELECT x+1 FROM cnt WHERE x<100) + INSERT INTO t1(x, y) SELECT 10000+$i, x FROM cnt; + INSERT INTO t1(x, y) SELECT 10000+$i, 100; + } + } + execsql { + UPDATE t1 SET z = rowid / 20; + ANALYZE; + } + } +} {} + +do_execsql_test 26.2 { + SELECT count(*) FROM t1 WHERE x = 10000 AND y < 50; +} {49} +do_execsql_test 26.3 { + SELECT count(*) FROM t1 WHERE z = 444; +} {20} + +# The analyzer knows that any (z=?) expression matches 20 rows. So it +# will use index "t1z" if the estimate of hits for (x=10000 AND y<50) +# is greater than 20 rows. +# +# And it should be. The analyzer has a stat4 sample as follows: +# +# sample=(x=10000, y=100) nLt=(10000 10099) +# +# There should be no other samples that start with (x=10000). So it knows +# that (x=10000 AND y<50) must match somewhere between 0 and 99 rows, but +# know more than that. Guessing less than 20 is therefore unreasonable. +# +# At one point though, due to a problem in whereKeyStats(), the planner was +# estimating that (x=10000 AND y<50) would match only 2 rows. +# +do_eqp_test 26.4 { + SELECT * FROM t1 WHERE x = 10000 AND y < 50 AND z = 444; +} { + 0 0 0 {SEARCH TABLE t1 USING INDEX t1z (z=?)} +} + + + + finish_test + + + From a0d56aef1859e0d9ee46ca102cc28b2f5da6e756 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 16 Mar 2015 09:21:30 +0000 Subject: [PATCH 46/57] Another test case for the planner change on this branch. FossilOrigin-Name: f2207a0691ed361061719f4dacf021a677a9d892 --- manifest | 15 +++++------- manifest.uuid | 2 +- test/analyze9.test | 57 ++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 60 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 4946d588ee..3b2c011b8e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sestimating\sthe\snumber\sof\srows\svisited\sby\sa\srange\sscan\sfor\swhich\sthe\skeys\sconsist\sof\smore\sthan\sone\sfield,\sconsider\sprefixes\sof\sstat4\ssamples\sas\swell\sas\sthe\sfull\ssamples. -D 2015-03-14T18:59:58.801 +C Another\stest\scase\sfor\sthe\splanner\schange\son\sthis\sbranch. +D 2015-03-16T09:21:30.738 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -327,7 +327,7 @@ F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4 F test/analyze6.test f1c552ce39cca4ec922a7e4e0e5d0203d6b3281f F test/analyze7.test bb1409afc9e8629e414387ef048b8e0e3e0bdc4f F test/analyze8.test c05a461d0a6b05991106467d0c47480f2e709c82 -F test/analyze9.test 2f6cfeae1fcc61cc531bd19f68e1e28fb6edafbf +F test/analyze9.test 3dd9e203fad353ec8027b18a6d9a92af59f4e727 F test/analyzeA.test 3335697f6700c7052295cfd0067fc5b2aacddf9a F test/analyzeB.test 8bf35ee0a548aea831bf56762cb8e7fdb1db083d F test/analyzeC.test 555a6cc388b9818b6eda6df816f01ce0a75d3a93 @@ -1244,10 +1244,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 1c2166cb2a387a0856f41b399c3648bf8c5fce73 -R f0473fc546184f7826d3d60610130f49 -T *branch * stat4-change -T *sym-stat4-change * -T -sym-trunk * +P e1caf93c9ad0ee15d42030af95619f212d3fcf9d +R de6873e674f8f1bad7ecb0349d34590a U dan -Z e2a2579617ea31b6dadba1e9a71ba744 +Z 76e12c27217f9a3f485e4cb06238c66e diff --git a/manifest.uuid b/manifest.uuid index 02ad1198b1..e21139d81b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e1caf93c9ad0ee15d42030af95619f212d3fcf9d \ No newline at end of file +f2207a0691ed361061719f4dacf021a677a9d892 \ No newline at end of file diff --git a/test/analyze9.test b/test/analyze9.test index 6e85272ad6..1ebd69c8d1 100644 --- a/test/analyze9.test +++ b/test/analyze9.test @@ -1139,7 +1139,7 @@ ifcapable stat4&&cte { # resolved (see below). # reset_db -do_test 26.1 { +do_test 26.1.1 { db transaction { execsql { CREATE TABLE t1(x, y, z); @@ -1163,10 +1163,10 @@ do_test 26.1 { } } {} -do_execsql_test 26.2 { +do_execsql_test 26.1.2 { SELECT count(*) FROM t1 WHERE x = 10000 AND y < 50; } {49} -do_execsql_test 26.3 { +do_execsql_test 26.1.3 { SELECT count(*) FROM t1 WHERE z = 444; } {20} @@ -1185,13 +1185,62 @@ do_execsql_test 26.3 { # At one point though, due to a problem in whereKeyStats(), the planner was # estimating that (x=10000 AND y<50) would match only 2 rows. # -do_eqp_test 26.4 { +do_eqp_test 26.1.4 { SELECT * FROM t1 WHERE x = 10000 AND y < 50 AND z = 444; } { 0 0 0 {SEARCH TABLE t1 USING INDEX t1z (z=?)} } +# This test - 26.2.* - tests that another manifestation of the same problem +# is no longer present in the library. Assuming: +# +# CREATE INDEX t1xy ON t1(x, y) +# +# and that have samples for index t1xy as follows: +# +# +# sample=('A', 70) nEq=(100, 2) nLt=(900, 970) +# sample=('B', 70) nEq=(100, 2) nLt=(1000, 1070) +# +# the planner should estimate that (x = 'B' AND y > 25) matches 76 rows +# (70 * 2/3 + 30). Before, due to the problem, the planner was estimating +# that this matched 100 rows. +# +reset_db +do_execsql_test 26.2.1 { + BEGIN; + CREATE TABLE t1(x, y, z); + CREATE INDEX i1 ON t1(x, y); + CREATE INDEX i2 ON t1(z); + + WITH + cnt(y) AS (SELECT 0 UNION ALL SELECT y+1 FROM cnt WHERE y<99), + letters(x) AS ( + SELECT 'A' UNION SELECT 'B' UNION SELECT 'C' UNION SELECT 'D' + ) + INSERT INTO t1(x, y) SELECT x, y FROM letters, cnt; + + WITH + letters(x) AS ( + SELECT 'A' UNION SELECT 'B' UNION SELECT 'C' UNION SELECT 'D' + ) + INSERT INTO t1(x, y) SELECT x, 70 FROM letters; + + WITH + cnt(i) AS (SELECT 0 UNION ALL SELECT i+1 FROM cnt WHERE i<9999) + INSERT INTO t1(x, y) SELECT i, i FROM cnt; + + UPDATE t1 SET z = (rowid / 95); + ANALYZE; + COMMIT; +} + +do_eqp_test 26.2.2 { + SELECT * FROM t1 WHERE x='B' AND y>25 AND z=?; +} { + 0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x=? AND y>?)} +} finish_test From 8426636cdc284888098ecc77a5e2a25c242d4707 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 16 Mar 2015 12:13:31 +0000 Subject: [PATCH 47/57] When a WHERE clause contains disjuncts with the same operands, try to combine them into a single operator. Example: (x=A OR x>A) becomes (x>=A). FossilOrigin-Name: 7a3097689d17625fb0dfc4372712f375f3bdb9a1 --- manifest | 18 +++++---- manifest.uuid | 2 +- src/where.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++- test/whereK.test | 72 +++++++++++++++++++++++++++++++++++ 4 files changed, 180 insertions(+), 10 deletions(-) create mode 100644 test/whereK.test diff --git a/manifest b/manifest index e1d464f1a0..2c8ca54b79 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests\sto\sensure\s"PRAGMA\sincremental_vacuum"\sand\s"PRAGMA\sauto_vacuum\s=\sincremental"\shandle\scorrupt\sdatabases\scorrectly. -D 2015-03-13T15:44:36.085 +C When\sa\sWHERE\sclause\scontains\sdisjuncts\swith\sthe\ssame\soperands,\stry\sto\ncombine\sthem\sinto\sa\ssingle\soperator.\s\sExample:\s\s(x=A\sOR\sx>A)\sbecomes\n(x>=A). +D 2015-03-16T12:13:31.967 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -307,7 +307,7 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 39303f2c9db02a4e422cd8eb2c8760420c6a51fe F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 -F src/where.c eb141b075776e9864d38f279333e2472a8653202 +F src/where.c b879a02e59c27f1447224fa2e79a7f2c7c345fd5 F src/whereInt.h cbe4aa57326998d89e7698ca65bb7c28541d483c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1175,6 +1175,7 @@ F test/whereG.test 69f5ec4b15760a8c860f80e2d55525669390aab3 F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2 F test/whereI.test 1d89199697919d4930be05a71e7fe620f114e622 F test/whereJ.test 55a3221706a7ab706293f17cc8f96da563bf0767 +F test/whereK.test 78fb50c74c9a91efc97a1daa39bcf7b8b68d8bff F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31 F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c @@ -1244,7 +1245,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 5aa522dcb9bfa18d49683f7cc889516984e2bcd2 -R a79445283a8ae7c7f85ae571d23bc239 -U dan -Z d6c136b9ed1be16533c60706d0427e82 +P 1c2166cb2a387a0856f41b399c3648bf8c5fce73 +R 298b36c87aaf9227b23b4ea3e9cfdff1 +T *branch * combine-disjuncts +T *sym-combine-disjuncts * +T -sym-trunk * +U drh +Z 6e64b74890b4611813f6eecbfdcaf110 diff --git a/manifest.uuid b/manifest.uuid index e474b58d5e..ebdd81be91 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1c2166cb2a387a0856f41b399c3648bf8c5fce73 \ No newline at end of file +7a3097689d17625fb0dfc4372712f375f3bdb9a1 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 8b9060b0a7..869ab8ed73 100644 --- a/src/where.c +++ b/src/where.c @@ -770,6 +770,79 @@ static void markTermAsChild(WhereClause *pWC, int iChild, int iParent){ pWC->a[iParent].nChild++; } +/* +** Return the N-th AND-connected subterm of pTerm. Or if pTerm is not +** a conjunction, then return just pTerm when N==0. If N is exceeds +** the number of available subterms, return NULL. +*/ +static WhereTerm *whereNthSubterm(WhereTerm *pTerm, int N){ + if( pTerm->eOperator!=WO_AND ){ + return N==0 ? pTerm : 0; + } + if( Nu.pAndInfo->wc.nTerm ){ + return &pTerm->u.pAndInfo->wc.a[N]; + } + return 0; +} + +/* +** Subterms pOne and pTwo are contained within WHERE clause pWC. The +** two subterms are in disjunction - they are OR-ed together. +** +** If these two terms are both of the form: "A op B" with the same +** A and B values but different operators and if the operators are +** compatible (if one is = and the other is <, for example) then +** add a new virtual term to pWC that is the combination of the +** two. +** +** Some examples: +** +** x x<=y +** x=y OR x=y --> x=y +** x<=y OR x x<=y +** +** The following is NOT generated: +** +** xy --> x!=y +*/ +static void whereCombineDisjuncts( + SrcList *pSrc, /* the FROM clause */ + WhereClause *pWC, /* The complete WHERE clause */ + WhereTerm *pOne, /* First disjunct */ + WhereTerm *pTwo /* Second disjunct */ +){ + u16 eOp = pOne->eOperator | pTwo->eOperator; + sqlite3 *db; /* Database connection (for malloc) */ + Expr *pNew; /* New virtual expression */ + int op; /* Operator for the combined expression */ + int idxNew; /* Index in pWC of the next virtual term */ + + if( (pOne->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE))==0 ) return; + if( (pTwo->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE))==0 ) return; + if( (eOp & (WO_EQ|WO_LT|WO_LE))!=eOp + && (eOp & (WO_EQ|WO_GT|WO_GE))!=eOp ) return; + assert( pOne->pExpr->pLeft!=0 && pOne->pExpr->pRight!=0 ); + assert( pTwo->pExpr->pLeft!=0 && pTwo->pExpr->pRight!=0 ); + if( sqlite3ExprCompare(pOne->pExpr->pLeft, pTwo->pExpr->pLeft, -1) ) return; + if( sqlite3ExprCompare(pOne->pExpr->pRight, pTwo->pExpr->pRight, -1) )return; + /* If we reach this point, it means the two subterms can be combined */ + if( (eOp & (eOp-1))!=0 ){ + if( eOp & (WO_LT|WO_LE) ){ + eOp = WO_LE; + }else{ + assert( eOp & (WO_GT|WO_GE) ); + eOp = WO_GE; + } + } + db = pWC->pWInfo->pParse->db; + pNew = sqlite3ExprDup(db, pOne->pExpr, 0); + if( pNew==0 ) return; + for(op=TK_EQ; eOp!=(WO_EQ<<(op-TK_EQ)); op++){ assert( opop = op; + idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC); + exprAnalyze(pSrc, pWC, idxNew); +} + #if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY) /* ** Analyze a term that consists of two or more OR-connected @@ -794,6 +867,7 @@ static void markTermAsChild(WhereClause *pWC, int iChild, int iParent){ ** (C) t1.x=t2.y OR (t1.x=t2.z AND t1.y=15) ** (D) x=expr1 OR (y>11 AND y<22 AND z LIKE '*hello*') ** (E) (p.a=1 AND q.b=2 AND r.c=3) OR (p.x=4 AND q.y=5 AND r.z=6) +** (F) x>A OR (x=A AND y>=B) ** ** CASE 1: ** @@ -810,6 +884,12 @@ static void markTermAsChild(WhereClause *pWC, int iChild, int iParent){ ** ** CASE 2: ** +** If there is a two-way OR and one side has x>A and the other side +** has x=A (for the same x and A) then add a new virtual term to the +** WHERE clause of the form "x>=A". +** +** CASE 3: +** ** If all subterms are indexable by a single table T, then set ** ** WhereTerm.eOperator = WO_OR @@ -936,12 +1016,26 @@ static void exprAnalyzeOrTerm( } /* - ** Record the set of tables that satisfy case 2. The set might be + ** Record the set of tables that satisfy case 3. The set might be ** empty. */ pOrInfo->indexable = indexable; pTerm->eOperator = indexable==0 ? 0 : WO_OR; + /* For a two-way OR, attempt to implementation case 2. + */ + if( indexable && pOrWc->nTerm==2 ){ + int iOne = 0; + WhereTerm *pOne; + while( (pOne = whereNthSubterm(&pOrWc->a[0],iOne++))!=0 ){ + int iTwo = 0; + WhereTerm *pTwo; + while( (pTwo = whereNthSubterm(&pOrWc->a[1],iTwo++))!=0 ){ + whereCombineDisjuncts(pSrc, pWC, pOne, pTwo); + } + } + } + /* ** chngToIN holds a set of tables that *might* satisfy case 1. But ** we have to do some additional checking to see if case 1 really @@ -1071,7 +1165,7 @@ static void exprAnalyzeOrTerm( }else{ sqlite3ExprListDelete(db, pList); } - pTerm->eOperator = WO_NOOP; /* case 1 trumps case 2 */ + pTerm->eOperator = WO_NOOP; /* case 1 trumps case 3 */ } } } diff --git a/test/whereK.test b/test/whereK.test new file mode 100644 index 0000000000..8d294446a5 --- /dev/null +++ b/test/whereK.test @@ -0,0 +1,72 @@ +# 2015-03-16 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this file is testing OR expressions where terms can be +# factored from either side of the OR and combined into a single new +# AND term that is beneficial to the search. Examples: +# +# (x>A OR x=A) --> ... AND (x>=A) +# (x>A OR (x=A AND y>=B) --> ... AND (x>=A) +# + + + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set ::testprefix whereD + +do_execsql_test 1.1 { + CREATE TABLE t1(a,b,c); + WITH RECURSIVE c(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM c WHERE x<99) + INSERT INTO t1(a,b,c) SELECT x, x/10, x%10 FROM c; + CREATE INDEX t1bc ON t1(b,c); + SELECT a FROM t1 WHERE b>9 OR b=9 ORDER BY +a; +} {90 91 92 93 94 95 96 97 98 99} +do_execsql_test 1.1eqp { + EXPLAIN QUERY PLAN + SELECT a FROM t1 WHERE b>9 OR b=9 ORDER BY +a; +} {/SEARCH TABLE t1 USING INDEX t1bc/} + +do_execsql_test 1.2 { + SELECT a FROM t1 WHERE b>8 OR (b=8 AND c>7) ORDER BY +a; +} {88 89 90 91 92 93 94 95 96 97 98 99} +do_execsql_test 1.2eqp { + EXPLAIN QUERY PLAN + SELECT a FROM t1 WHERE b>8 OR (b=8 AND c>7) ORDER BY +a; +} {/SEARCH TABLE t1 USING INDEX t1bc/} + +do_execsql_test 1.3 { + SELECT a FROM t1 WHERE (b=8 AND c>7) OR b>8 ORDER BY +a; +} {88 89 90 91 92 93 94 95 96 97 98 99} +do_execsql_test 1.3eqp { + EXPLAIN QUERY PLAN + SELECT a FROM t1 WHERE (b=8 AND c>7) OR b>8 ORDER BY +a; +} {/SEARCH TABLE t1 USING INDEX t1bc/} + +do_execsql_test 1.4 { + SELECT a FROM t1 WHERE (b=8 AND c>7) OR 87) OR 87) OR (b>8 AND c NOT IN (4,5,6)) + ORDER BY +a; +} {88 89 90 91 92 93 97 98 99} +do_execsql_test 1.5eqp { + EXPLAIN QUERY PLAN + SELECT a FROM t1 WHERE (b=8 AND c>7) OR (b>8 AND c NOT IN (4,5,6)) + ORDER BY +a; +} {/SEARCH TABLE t1 USING INDEX t1bc/} + +finish_test From c03acf2ea757e4c1c48ebeadb74912d96316c779 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 16 Mar 2015 13:12:34 +0000 Subject: [PATCH 48/57] Improved comments. No code changes. FossilOrigin-Name: 23f71a26386ff2aff9800fe96cec1dc9c805b5b6 --- manifest | 15 ++++++--------- manifest.uuid | 2 +- src/where.c | 12 ++++++++---- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 2c8ca54b79..94c932d5b9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sa\sWHERE\sclause\scontains\sdisjuncts\swith\sthe\ssame\soperands,\stry\sto\ncombine\sthem\sinto\sa\ssingle\soperator.\s\sExample:\s\s(x=A\sOR\sx>A)\sbecomes\n(x>=A). -D 2015-03-16T12:13:31.967 +C Improved\scomments.\s\sNo\scode\schanges. +D 2015-03-16T13:12:34.265 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -307,7 +307,7 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 39303f2c9db02a4e422cd8eb2c8760420c6a51fe F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 -F src/where.c b879a02e59c27f1447224fa2e79a7f2c7c345fd5 +F src/where.c 235b1f50ab851867dc2efc967824d1db571d68ac F src/whereInt.h cbe4aa57326998d89e7698ca65bb7c28541d483c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1245,10 +1245,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 1c2166cb2a387a0856f41b399c3648bf8c5fce73 -R 298b36c87aaf9227b23b4ea3e9cfdff1 -T *branch * combine-disjuncts -T *sym-combine-disjuncts * -T -sym-trunk * +P 7a3097689d17625fb0dfc4372712f375f3bdb9a1 +R 8bbcc33deef1379ead8ffcee920df4a8 U drh -Z 6e64b74890b4611813f6eecbfdcaf110 +Z 9d40483b0a6890b27f9ba16787ef6d6d diff --git a/manifest.uuid b/manifest.uuid index ebdd81be91..86998486a3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7a3097689d17625fb0dfc4372712f375f3bdb9a1 \ No newline at end of file +23f71a26386ff2aff9800fe96cec1dc9c805b5b6 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 869ab8ed73..624e16f7b6 100644 --- a/src/where.c +++ b/src/where.c @@ -792,7 +792,7 @@ static WhereTerm *whereNthSubterm(WhereTerm *pTerm, int N){ ** If these two terms are both of the form: "A op B" with the same ** A and B values but different operators and if the operators are ** compatible (if one is = and the other is <, for example) then -** add a new virtual term to pWC that is the combination of the +** add a new virtual AND term to pWC that is the combination of the ** two. ** ** Some examples: @@ -884,9 +884,13 @@ static void whereCombineDisjuncts( ** ** CASE 2: ** -** If there is a two-way OR and one side has x>A and the other side -** has x=A (for the same x and A) then add a new virtual term to the -** WHERE clause of the form "x>=A". +** If there are exactly two disjuncts one side has x>A and the other side +** has x=A (for the same x and A) then add a new virtual conjunct term to the +** WHERE clause of the form "x>=A". Example: +** +** x>A OR (x=A AND y>B) adds: x>=A +** +** The added conjunct can sometimes be helpful in query planning. ** ** CASE 3: ** From 8cdcd87c5339a9fde0136c9d8356e85b4d86ded8 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 16 Mar 2015 13:48:23 +0000 Subject: [PATCH 49/57] Use #ifdef to omit code that is only used for STAT3 and STAT4. FossilOrigin-Name: f2c9c5b57b7739daafc44e8ec36d4a2beacd5f17 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbemem.c | 2 ++ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index e1d464f1a0..90bbcb29fd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests\sto\sensure\s"PRAGMA\sincremental_vacuum"\sand\s"PRAGMA\sauto_vacuum\s=\sincremental"\shandle\scorrupt\sdatabases\scorrectly. -D 2015-03-13T15:44:36.085 +C Use\s#ifdef\sto\somit\scode\sthat\sis\sonly\sused\sfor\sSTAT3\sand\sSTAT4. +D 2015-03-16T13:48:23.259 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -299,7 +299,7 @@ F src/vdbeInt.h bb56fd199d8af1a2c1b9639ee2f70724b4338e3a F src/vdbeapi.c 583d56b129dd27f12bed518270de9ebe521e6a75 F src/vdbeaux.c 97911edb61074b871ec4aa2d6bb779071643dee5 F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90 -F src/vdbemem.c 78aef62d0298e15485cb5a429c912c9c3ed054b8 +F src/vdbemem.c c0dc81285b7571b0a31c40f17846fe2397ec1cd9 F src/vdbesort.c 6d64c5448b64851b99931ede980addc3af70d5e2 F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010 F src/vtab.c 699f2b8d509cfe379c33dde33827875d5b030e01 @@ -1244,7 +1244,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 5aa522dcb9bfa18d49683f7cc889516984e2bcd2 -R a79445283a8ae7c7f85ae571d23bc239 -U dan -Z d6c136b9ed1be16533c60706d0427e82 +P 1c2166cb2a387a0856f41b399c3648bf8c5fce73 +R e7f2404f34b97aa8b45ff522e4adb3b6 +U drh +Z 2ec6c684a2b78379b1dfd597c8ec878e diff --git a/manifest.uuid b/manifest.uuid index e474b58d5e..f8a6086b6f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1c2166cb2a387a0856f41b399c3648bf8c5fce73 \ No newline at end of file +f2c9c5b57b7739daafc44e8ec36d4a2beacd5f17 \ No newline at end of file diff --git a/src/vdbemem.c b/src/vdbemem.c index b92ec84337..76147442ab 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1355,9 +1355,11 @@ static int valueFromExpr( } #endif +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 else if( op==TK_FUNCTION && pCtx!=0 ){ rc = valueFromFunction(db, pExpr, enc, affinity, &pVal, pCtx); } +#endif *ppVal = pVal; return rc; From 75a4d7c3da500ffd527603d5ec8906498f17c3f7 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 16 Mar 2015 16:44:55 +0000 Subject: [PATCH 50/57] When deleting the master journal to commit a multi-database transaction, do not sync the directory if PRAGMA synchronous=OFF for all participating database files. FossilOrigin-Name: 018d7671402a0f8103d1306641655b69f9fa235d --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbeaux.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index e7e9fb89d8..c965f4df6b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sestimating\sthe\snumber\sof\srows\svisited\sby\sa\srange\sscan\sfor\swhich\sthe\skeys\sconsist\sof\smore\sthan\sone\sfield,\sconsider\sprefixes\sof\sstat4\ssamples\sas\swell\sas\sthe\sfull\ssamples.\sThis\sgenerates\smore\saccurate\sestimates. -D 2015-03-16T16:28:43.573 +C When\sdeleting\sthe\smaster\sjournal\sto\scommit\sa\smulti-database\stransaction,\sdo\nnot\ssync\sthe\sdirectory\sif\sPRAGMA\ssynchronous=OFF\sfor\sall\sparticipating\ndatabase\sfiles. +D 2015-03-16T16:44:55.689 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -297,7 +297,7 @@ F src/vdbe.c a2725107658fd9572637e8e09d46dcfe851edb96 F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3 F src/vdbeInt.h bb56fd199d8af1a2c1b9639ee2f70724b4338e3a F src/vdbeapi.c 583d56b129dd27f12bed518270de9ebe521e6a75 -F src/vdbeaux.c 97911edb61074b871ec4aa2d6bb779071643dee5 +F src/vdbeaux.c 23390670e64f011f3fed8f38a2f25aaccacb74d2 F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90 F src/vdbemem.c c0dc81285b7571b0a31c40f17846fe2397ec1cd9 F src/vdbesort.c 6d64c5448b64851b99931ede980addc3af70d5e2 @@ -1244,7 +1244,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f2c9c5b57b7739daafc44e8ec36d4a2beacd5f17 f2207a0691ed361061719f4dacf021a677a9d892 -R 91b4618acc4046613febfb03ba644299 -U dan -Z a47ebefe49a8b31d8182fc2d2ef4fe70 +P 3e0590dee0e68cc1599858757c650a7378026170 +R b45bc6830f64f8858a6416472978aee0 +U drh +Z 7cd47bb94490a64601179f11e40a837c diff --git a/manifest.uuid b/manifest.uuid index 7834d3d08a..1d6abc47d5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3e0590dee0e68cc1599858757c650a7378026170 \ No newline at end of file +018d7671402a0f8103d1306641655b69f9fa235d \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index cd9ecaa691..9c105cc9e7 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2143,7 +2143,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ ** doing this the directory is synced again before any individual ** transaction files are deleted. */ - rc = sqlite3OsDelete(pVfs, zMaster, 1); + rc = sqlite3OsDelete(pVfs, zMaster, needSync); sqlite3DbFree(db, zMaster); zMaster = 0; if( rc ){ From 07b38959a4db58e856d3cf208a3e064897794b63 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 16 Mar 2015 17:07:09 +0000 Subject: [PATCH 51/57] Modify the fts3query.test script so that it works even when testfixture is built using a version of TCL that is unable to sort the integer -9223372036854775808 FossilOrigin-Name: f61fd24b4d3b686911ea578f77612309099f0cc6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/fts3query.test | 14 +++++++++----- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index c965f4df6b..cfdd9a1b92 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sdeleting\sthe\smaster\sjournal\sto\scommit\sa\smulti-database\stransaction,\sdo\nnot\ssync\sthe\sdirectory\sif\sPRAGMA\ssynchronous=OFF\sfor\sall\sparticipating\ndatabase\sfiles. -D 2015-03-16T16:44:55.689 +C Modify\sthe\sfts3query.test\sscript\sso\sthat\sit\sworks\seven\swhen\stestfixture\sis\nbuilt\susing\sa\sversion\sof\sTCL\sthat\sis\sunable\sto\ssort\sthe\ninteger\s-9223372036854775808 +D 2015-03-16T17:07:09.229 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -594,7 +594,7 @@ F test/fts3matchinfo.test 58544fa4d254000fa4e7f494b0a832f7ba61d45e F test/fts3near.test 7e3354d46f155a822b59c0e957fd2a70c1d7e905 F test/fts3prefix.test b36d4f00b128a51e7b386cc013a874246d9d7dc1 F test/fts3prefix2.test e1f0a822ca661dced7f12ce392e14eaf65609dce -F test/fts3query.test d81ffb0ab1d4e1a2a330b8eb1e160b60603f4745 +F test/fts3query.test c838b18f2b859e15fd31c64be3d79ef1556803ca F test/fts3rnd.test 1320d8826a845e38a96e769562bf83d7a92a15d0 F test/fts3shared.test 57e26a801f21027b7530da77db54286a6fe4997e F test/fts3snippet.test 03c2f3be7d3b7c8bb105ed237f204833392bd57f @@ -1244,7 +1244,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 3e0590dee0e68cc1599858757c650a7378026170 -R b45bc6830f64f8858a6416472978aee0 +P 018d7671402a0f8103d1306641655b69f9fa235d +R 781e204d7688b0ad2593ede4825cc937 U drh -Z 7cd47bb94490a64601179f11e40a837c +Z 1bc9733af443d0b92b43469552bb99df diff --git a/manifest.uuid b/manifest.uuid index 1d6abc47d5..4001277083 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -018d7671402a0f8103d1306641655b69f9fa235d \ No newline at end of file +f61fd24b4d3b686911ea578f77612309099f0cc6 \ No newline at end of file diff --git a/test/fts3query.test b/test/fts3query.test index 0b3c2ce1bd..06019d14e6 100644 --- a/test/fts3query.test +++ b/test/fts3query.test @@ -252,15 +252,21 @@ foreach {tn iFirst iLast} [subst { do_execsql_test 7.2.$tn.1.[llength $res] { SELECT rowid FROM ft4 WHERE rowid BETWEEN $iFirst AND $iLast } $res + set res [db eval { + SELECT rowid FROM t4 WHERE rowid BETWEEN $iFirst AND $iLast + ORDER BY +rowid DESC + } ] do_execsql_test 7.2.$tn.2.[llength $res] { SELECT rowid FROM ft4 WHERE rowid BETWEEN $iFirst AND $iLast ORDER BY rowid DESC - } [lsort -decr -integer $res] + } $res } foreach ii [db eval {SELECT rowid FROM t4}] { set res1 [db eval {SELECT rowid FROM t4 WHERE rowid > $ii}] set res2 [db eval {SELECT rowid FROM t4 WHERE rowid < $ii}] + set res1s [db eval {SELECT rowid FROM t4 WHERE rowid > $ii ORDER BY +rowid DESC}] + set res2s [db eval {SELECT rowid FROM t4 WHERE rowid < $ii ORDER BY +rowid DESC}] do_execsql_test 7.3.$ii.1 { SELECT rowid FROM ft4 WHERE rowid > $ii @@ -272,13 +278,11 @@ foreach ii [db eval {SELECT rowid FROM t4}] { do_execsql_test 7.3.$ii.3 { SELECT rowid FROM ft4 WHERE rowid > $ii ORDER BY rowid DESC - } [lsort -integer -decr $res1] + } $res1s do_execsql_test 7.3.$ii.4 { SELECT rowid FROM ft4 WHERE rowid < $ii ORDER BY rowid DESC - } [lsort -integer -decr $res2] + } $res2s } finish_test - - From 05b6048dbd49fb9507221f34318a69c5d1253f34 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 16 Mar 2015 18:08:56 +0000 Subject: [PATCH 52/57] Fix typo of test prefix in the new WHERE test file. FossilOrigin-Name: 34779c528f1817d6ec34216b58fb4277956b5167 --- manifest | 15 +++++++-------- manifest.uuid | 2 +- test/whereK.test | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index c44128ac44..80af8718b8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sthe\sWHERE\sclause\scontains\stwo\sOR-connected\sterms\swith\sidentical\noperands\sbut\sdifferent\soperators,\stry\sto\scombine\sthem\sinto\sa\ssingle\sterm.\nExample:\s\s(X=A\sOR\sX>A)\sbecomes\s(X>=A). -D 2015-03-16T17:48:12.769 +C Fix\stypo\sof\stest\sprefix\sin\sthe\snew\sWHERE\stest\sfile. +D 2015-03-16T18:08:56.916 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1175,7 +1175,7 @@ F test/whereG.test 69f5ec4b15760a8c860f80e2d55525669390aab3 F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2 F test/whereI.test 1d89199697919d4930be05a71e7fe620f114e622 F test/whereJ.test 55a3221706a7ab706293f17cc8f96da563bf0767 -F test/whereK.test 78fb50c74c9a91efc97a1daa39bcf7b8b68d8bff +F test/whereK.test f8e3cf26a8513ecc7f514f54df9f0572c046c42b F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31 F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c @@ -1245,8 +1245,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f61fd24b4d3b686911ea578f77612309099f0cc6 23f71a26386ff2aff9800fe96cec1dc9c805b5b6 -R 0810c9b992d63ac661e729a83d3536b4 -T +closed 23f71a26386ff2aff9800fe96cec1dc9c805b5b6 -U drh -Z f335a12b6cd889ae802417698f792d1a +P 8bdda827a3d268009297a0216e3d94bf0eceeb2e +R 5cfb4e6342c564787ed07b1b1007b605 +U mistachkin +Z 76cd4818fe183f76c64a28733f84e037 diff --git a/manifest.uuid b/manifest.uuid index ecc96888a0..b5adcae9f4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8bdda827a3d268009297a0216e3d94bf0eceeb2e \ No newline at end of file +34779c528f1817d6ec34216b58fb4277956b5167 \ No newline at end of file diff --git a/test/whereK.test b/test/whereK.test index 8d294446a5..13c86508f9 100644 --- a/test/whereK.test +++ b/test/whereK.test @@ -21,7 +21,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl -set ::testprefix whereD +set ::testprefix whereK do_execsql_test 1.1 { CREATE TABLE t1(a,b,c); From f104abba8417ff2f971580cb1be400c0d6e5fbfe Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 16 Mar 2015 20:40:00 +0000 Subject: [PATCH 53/57] Make SQLite slightly more likely to use an auto-index within a sub-query. FossilOrigin-Name: ab832336f4a28193c4d2b61e833564822a7b86a8 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 80af8718b8..781a270193 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypo\sof\stest\sprefix\sin\sthe\snew\sWHERE\stest\sfile. -D 2015-03-16T18:08:56.916 +C Make\sSQLite\sslightly\smore\slikely\sto\suse\san\sauto-index\swithin\sa\ssub-query. +D 2015-03-16T20:40:00.496 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -307,7 +307,7 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 39303f2c9db02a4e422cd8eb2c8760420c6a51fe F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 -F src/where.c 5ca2899f280c4259a07816f4395d0bea368cfbd7 +F src/where.c 42ce3fd5ec9fe050f623be358cfddee01c1f6286 F src/whereInt.h cbe4aa57326998d89e7698ca65bb7c28541d483c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1245,7 +1245,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8bdda827a3d268009297a0216e3d94bf0eceeb2e -R 5cfb4e6342c564787ed07b1b1007b605 -U mistachkin -Z 76cd4818fe183f76c64a28733f84e037 +P 34779c528f1817d6ec34216b58fb4277956b5167 +R 20e702b8205b517ce2cb7b49f472a434 +U dan +Z 33f45126f2bf7daffd881933acc4eaa9 diff --git a/manifest.uuid b/manifest.uuid index b5adcae9f4..cc066477d9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -34779c528f1817d6ec34216b58fb4277956b5167 \ No newline at end of file +ab832336f4a28193c4d2b61e833564822a7b86a8 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 2fe076ba6d..6a1f481d60 100644 --- a/src/where.c +++ b/src/where.c @@ -6001,10 +6001,10 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ /* Seed the search with a single WherePath containing zero WhereLoops. ** - ** TUNING: Do not let the number of iterations go above 25. If the cost - ** of computing an automatic index is not paid back within the first 25 + ** TUNING: Do not let the number of iterations go above 28. If the cost + ** of computing an automatic index is not paid back within the first 28 ** rows, then do not use the automatic index. */ - aFrom[0].nRow = MIN(pParse->nQueryLoop, 46); assert( 46==sqlite3LogEst(25) ); + aFrom[0].nRow = MIN(pParse->nQueryLoop, 48); assert( 48==sqlite3LogEst(28) ); nFrom = 1; assert( aFrom[0].isOrdered==0 ); if( nOrderBy ){ From 363fc9e724d1597ef58ad699e6667917355f921d Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 17 Mar 2015 16:01:29 +0000 Subject: [PATCH 54/57] Add a test for the change on this branch. FossilOrigin-Name: e22dde187eb0b389d6d93e2e39a26fd0f4e6196e --- manifest | 20 ++++---- manifest.uuid | 2 +- src/test_vfs.c | 13 +++-- test/lock_common.tcl | 58 +++++++++++++++------ test/walblock.test | 117 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 177 insertions(+), 33 deletions(-) create mode 100644 test/walblock.test diff --git a/manifest b/manifest index 881ae7d644..d62ee302a3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Arrange\sfor\ssome\sof\sthe\stransient\slocks\sin\sWAL\smode\sto\sblock,\sas\sa\ssingle\nto\sthe\sOS\sto\sfix\spriority\sinversions. -D 2015-03-10T20:22:35.302 +C Add\sa\stest\sfor\sthe\schange\son\sthis\sbranch. +D 2015-03-17T16:01:29.508 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -283,7 +283,7 @@ F src/test_superlock.c 06797157176eb7085027d9dd278c0d7a105e3ec9 F src/test_syscall.c 2e21ca7f7dc54a028f1967b63f1e76155c356f9b F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa F src/test_thread.c af391ec03d23486dffbcc250b7e58e073f172af9 -F src/test_vfs.c 5a14c63da9579ba148138c1fb233100f2eb58ebb +F src/test_vfs.c b7e6831e6fcf04c5090accff30640ec5c9630739 F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 6bbcc9fe50c917864d48287b4792d46d6e873481 @@ -702,7 +702,7 @@ F test/lock4.test e175ae13865bc87680607563bafba21f31a26f12 F test/lock5.test c6c5e0ebcb21c61a572870cc86c0cb9f14cede38 F test/lock6.test ad5b387a3a8096afd3c68a55b9535056431b0cf5 F test/lock7.test 49f1eaff1cdc491cc5dee3669f3c671d9f172431 -F test/lock_common.tcl 0c270b121d40959fa2f3add382200c27045b3d95 +F test/lock_common.tcl 7ffb45accf6ee91c736df9bafe0806a44358f035 F test/lookaside.test 93f07bac140c5bb1d49f3892d2684decafdc7af2 F test/main.test 16131264ea0c2b93b95201f0c92958e85f2ba11a F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9 @@ -1139,6 +1139,7 @@ F test/wal9.test 378e76a9ad09cd9bee06c172ad3547b0129a6750 F test/wal_common.tcl a98f17fba96206122eff624db0ab13ec377be4fe F test/walbak.test b9f68e39646375c2b877be906babcc15d38b4877 F test/walbig.test f437473a16cfb314867c6b5d1dbcd519e73e3434 +F test/walblock.test f1290524714232c109fb0b14db28f14d81c3ddd0 F test/walcksum.test 9afeb96240296c08c72fc524d199c912cfe34daa F test/walcrash.test 451d79e528add5c42764cea74aa2750754171b25 F test/walcrash2.test a0edab4e5390f03b99a790de89aad15d6ec70b36 @@ -1241,10 +1242,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8d0b11c96e15556dd65ced05708a832aef134e69 -R e3a6235cb886b3e146e5aa9fea4e9436 -T *branch * wal-blocking-lock -T *sym-wal-blocking-lock * -T -sym-trunk * -U drh -Z 53b7d268fee9eb6c03e124e757f212c1 +P c6e6d5f4e06c3ac0bfb620c0c728fbc7230c4a02 +R 15a95b25b03827505e198326f8e27a62 +U dan +Z 12b0ab91b3a13b6777d198c7ff155c7d diff --git a/manifest.uuid b/manifest.uuid index e908b35f97..21c37ab89a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c6e6d5f4e06c3ac0bfb620c0c728fbc7230c4a02 \ No newline at end of file +e22dde187eb0b389d6d93e2e39a26fd0f4e6196e \ No newline at end of file diff --git a/src/test_vfs.c b/src/test_vfs.c index 561addfcc5..2277cf7eb5 100644 --- a/src/test_vfs.c +++ b/src/test_vfs.c @@ -967,16 +967,15 @@ static void tvfsShmBarrier(sqlite3_file *pFile){ TestvfsFd *pFd = tvfsGetFd(pFile); Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData); + if( p->pScript && p->mask&TESTVFS_SHMBARRIER_MASK ){ + const char *z = pFd->pShm ? pFd->pShm->zFile : ""; + tvfsExecTcl(p, "xShmBarrier", Tcl_NewStringObj(z, -1), pFd->pShmId, 0, 0); + } + if( p->isFullshm ){ sqlite3OsShmBarrier(pFd->pReal); return; } - - if( p->pScript && p->mask&TESTVFS_SHMBARRIER_MASK ){ - tvfsExecTcl(p, "xShmBarrier", - Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, 0, 0 - ); - } } static int tvfsShmUnmap( @@ -1532,7 +1531,7 @@ static int testvfs_cmd( return TCL_OK; bad_args: - Tcl_WrongNumArgs(interp, 1, objv, "VFSNAME ?-noshm BOOL? ?-default BOOL? ?-mxpathname INT? ?-szosfile INT? ?-iversion INT?"); + Tcl_WrongNumArgs(interp, 1, objv, "VFSNAME ?-noshm BOOL? ?-fullshm BOOL? ?-default BOOL? ?-mxpathname INT? ?-szosfile INT? ?-iversion INT?"); return TCL_ERROR; } diff --git a/test/lock_common.tcl b/test/lock_common.tcl index bc1eb86bdc..a758e7af2e 100644 --- a/test/lock_common.tcl +++ b/test/lock_common.tcl @@ -86,21 +86,51 @@ proc launch_testfixture {{prg ""}} { # Execute a command in a child testfixture process, connected by two-way # channel $chan. Return the result of the command, or an error message. # -proc testfixture {chan cmd} { - puts $chan $cmd - puts $chan OVER - set r "" - while { 1 } { +proc testfixture {chan cmd args} { + + if {[llength $args] == 0} { + fconfigure $chan -blocking 1 + puts $chan $cmd + puts $chan OVER + + set r "" + while { 1 } { + set line [gets $chan] + if { $line == "OVER" } { + set res [lindex $r 1] + if { [lindex $r 0] } { error $res } + return $res + } + if {[eof $chan]} { + return "ERROR: Child process hung up" + } + append r $line + } + return $r + } else { + set ::tfnb($chan) "" + fconfigure $chan -blocking 0 -buffering none + puts $chan $cmd + puts $chan OVER + fileevent $chan readable [list testfixture_script_cb $chan [lindex $args 0]] + return "" + } +} + +proc testfixture_script_cb {chan script} { + if {[eof $chan]} { + append ::tfnb($chan) "ERROR: Child process hung up" + set line "OVER" + } else { set line [gets $chan] - if { $line == "OVER" } { - set res [lindex $r 1] - if { [lindex $r 0] } { error $res } - return $res - } - if {[eof $chan]} { - return "ERROR: Child process hung up" - } - append r $line + } + + if { $line == "OVER" } { + uplevel #0 $script [list [lindex $::tfnb($chan) 1]] + unset ::tfnb($chan) + fileevent $chan readable "" + } else { + append ::tfnb($chan) $line } } diff --git a/test/walblock.test b/test/walblock.test new file mode 100644 index 0000000000..9a85ea4acc --- /dev/null +++ b/test/walblock.test @@ -0,0 +1,117 @@ +# 2015 Mar 17 +# +# 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 +source $testdir/lock_common.tcl +source $testdir/wal_common.tcl + +ifcapable !wal {finish_test ; return } +if {$::tcl_platform(platform)!="unix"} { finish_test ; return } +set testprefix walblock + +catch { db close } +testvfs tvfs -fullshm 1 +foreach f [glob test.db*] { forcedelete $f } + +sqlite3 db test.db -vfs tvfs +do_execsql_test 1.1.0 { + CREATE TABLE t1(x, y); + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(3, 4); + INSERT INTO t1 VALUES(5, 6); + PRAGMA journal_mode = wal; + INSERT INTO t1 VALUES(7, 8); +} {wal} + +do_test 1.1.1 { + lsort [glob test.db*] +} {test.db test.db-shm test.db-wal} + +do_test 1.1.2 { + set C [launch_testfixture] + testfixture $C { + sqlite3 db test.db + db eval { SELECT * FROM t1 } + } +} {1 2 3 4 5 6 7 8} + +do_test 1.1.3 { + set ::out [list] + testfixture $C { + db eval { SELECT * FROM t1 } + } [list set ::out] + set ::out +} {} + +do_test 1.1.4 { + vwait ::out + set ::out +} {1 2 3 4 5 6 7 8} + +# +# Test that if a read client cannot read the wal-index header because a +# write client is in the middle of updating it, the reader blocks until +# the writer finishes. +# +# 1. Open a write transaction using client [db] in this process. +# +# 2. Attempt to commit the write transaction. Intercept the xShmBarrier() +# call made by the writer between updating the two copies of the +# wal-index header. +# +# 3. Within the xShmBarrier() callback, make an asynchronous request to +# the other process to read from the database. It should block, as it +# cannot get read the wal-index header. +# +# 4. Still in xShmBarrier(), wait for 5 seconds. Check that the other +# process has not answered the request. +# +# 5: Finish committing the transaction. Then wait for 0.5 seconds more. +# Ensure that the second process has by this stage read the database +# and that the snapshot it read included the transaction committed in +# step (4). +# +do_execsql_test 1.2.1 { + BEGIN; + INSERT INTO t1 VALUES(9, 10); +} {} + +tvfs script barrier_callback +tvfs filter xShmBarrier +proc barrier_callback {method args} { + set ::out "" + testfixture $::C { db eval { SELECT * FROM t1 } } {set ::out} + + do_test "1.2.2.(blocking 5 seconds)" { + set ::continue 0 + after 5000 {set ::continue 1} + vwait ::continue + set ::out + } {} +} + +execsql COMMIT + +do_test "1.2.3.(blocking 0.5 seconds)" { + set ::continue 0 + after 500 {set ::continue 1} + vwait ::continue + set ::out +} {1 2 3 4 5 6 7 8 9 10} + + +finish_test + + + + From d671e66337d40fe53625abe36404a155e95aa400 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 17 Mar 2015 20:39:11 +0000 Subject: [PATCH 55/57] Clarify the documentation on sqlite3_errcode(). No changes to code. FossilOrigin-Name: 2c0e0d87fb418d684fba1c83d9fd8e4e96588c54 --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 12 +++++++----- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 47a6aa6b99..b57003d8ce 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Also\smerge\sthe\sWAL\sblocking\slock\stests\sthat\swere\ssomehow\smissed\son\sthe\nprevious\scheck-in. -D 2015-03-17T17:08:35.872 +C Clarify\sthe\sdocumentation\son\ssqlite3_errcode().\s\sNo\schanges\sto\scode. +D 2015-03-17T20:39:11.595 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -232,7 +232,7 @@ F src/resolve.c f4d79e31ffa5820c2e3d1740baa5e9b190425f2b F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c 94e016b6733b1d39a2f4c8d431155b4c2897d907 F src/shell.c cce82ca26392578a4a1ee927dfe55ea3411c7c92 -F src/sqlite.h.in ce547ac4df17e8d996679f7a385911b3a0c52d48 +F src/sqlite.h.in 2d48e05677d0f9b06b7757662eef3cebea02d837 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d F src/sqliteInt.h fae682c2b4dfbe489b134d74521c41c088f16ab1 @@ -1246,8 +1246,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P ec2f46de531ec8ef91981b19b48ab64db7727264 e22dde187eb0b389d6d93e2e39a26fd0f4e6196e -R 35d1aacb5b2efba4948b8dccdeab808c -T +closed e22dde187eb0b389d6d93e2e39a26fd0f4e6196e +P 7214dab7443d35c105904dd69635c1f8b45b2fc8 +R 2fa9dda445b6fbb66c03820d7f35f5b9 U drh -Z 7357efe8421db7654a103c304e504696 +Z b0621e44776b9609d48318da3b5f6489 diff --git a/manifest.uuid b/manifest.uuid index f8ce2770f1..99a0aa5cf4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7214dab7443d35c105904dd69635c1f8b45b2fc8 \ No newline at end of file +2c0e0d87fb418d684fba1c83d9fd8e4e96588c54 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 483534e494..ed0318fe3a 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -3000,11 +3000,13 @@ sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64); /* ** CAPI3REF: Error Codes And Messages ** -** ^The sqlite3_errcode() interface returns the numeric [result code] or -** [extended result code] for the most recent failed sqlite3_* API call -** associated with a [database connection]. If a prior API call failed -** but the most recent API call succeeded, the return value from -** sqlite3_errcode() is undefined. ^The sqlite3_extended_errcode() +** ^If the most recent sqlite3_* API call associated with +** [database connection] D failed, then the sqlite3_errcode(D) interface +** returns the numeric [result code] or [extended result code] for that +** API call. +** If the most recent API call was successful, +** then the return value from sqlite3_errcode() is undefined. +** ^The sqlite3_extended_errcode() ** interface is the same except that it always returns the ** [extended result code] even when extended result codes are ** disabled. From 2b3f1409dbd7f4e0111ba6f11319cdec311f7a03 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 18 Mar 2015 16:00:44 +0000 Subject: [PATCH 56/57] Add another sqlite3FaultSim() to the multi-threaded sorter logic to improve testability. FossilOrigin-Name: 49ea2cded4a76596f85419c820cdaf4a1751d7ac --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbesort.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index b57003d8ce..ca434d481c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Clarify\sthe\sdocumentation\son\ssqlite3_errcode().\s\sNo\schanges\sto\scode. -D 2015-03-17T20:39:11.595 +C Add\sanother\ssqlite3FaultSim()\sto\sthe\smulti-threaded\ssorter\slogic\sto\nimprove\stestability. +D 2015-03-18T16:00:44.998 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -300,7 +300,7 @@ F src/vdbeapi.c 583d56b129dd27f12bed518270de9ebe521e6a75 F src/vdbeaux.c 23390670e64f011f3fed8f38a2f25aaccacb74d2 F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90 F src/vdbemem.c c0dc81285b7571b0a31c40f17846fe2397ec1cd9 -F src/vdbesort.c 6d64c5448b64851b99931ede980addc3af70d5e2 +F src/vdbesort.c 919717d7599fa31d343ec28bffd0f9e91a4ff5f6 F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010 F src/vtab.c 699f2b8d509cfe379c33dde33827875d5b030e01 F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb @@ -1246,7 +1246,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7214dab7443d35c105904dd69635c1f8b45b2fc8 -R 2fa9dda445b6fbb66c03820d7f35f5b9 +P 2c0e0d87fb418d684fba1c83d9fd8e4e96588c54 +R 58ae90a14e230c20fd6999f0bc3305de U drh -Z b0621e44776b9609d48318da3b5f6489 +Z 224b0621dbed3257af56f4d91f4f2bf9 diff --git a/manifest.uuid b/manifest.uuid index 99a0aa5cf4..cc37f4c412 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2c0e0d87fb418d684fba1c83d9fd8e4e96588c54 \ No newline at end of file +49ea2cded4a76596f85419c820cdaf4a1751d7ac \ No newline at end of file diff --git a/src/vdbesort.c b/src/vdbesort.c index 5a43a10542..bbdafa8230 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -1151,6 +1151,7 @@ static int vdbeSorterOpenTempFile( sqlite3_file **ppFd ){ int rc; + if( sqlite3FaultSim(202) ) return SQLITE_IOERR_ACCESS; rc = sqlite3OsOpenMalloc(db->pVfs, 0, ppFd, SQLITE_OPEN_TEMP_JOURNAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | From 657b4a87e57148b16f876038ae1c61a9ca39d281 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 19 Mar 2015 13:30:41 +0000 Subject: [PATCH 57/57] Fix a bug in error handling in the ".trace" command of the command-line shell. FossilOrigin-Name: 6a48b5d794e891fdd167547c76835d677eb5e31d --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c | 2 +- test/shell4.test | 22 ++++++++++++++++++++-- 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index ca434d481c..38d28bca9b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sanother\ssqlite3FaultSim()\sto\sthe\smulti-threaded\ssorter\slogic\sto\nimprove\stestability. -D 2015-03-18T16:00:44.998 +C Fix\sa\sbug\sin\serror\shandling\sin\sthe\s".trace"\scommand\sof\sthe\scommand-line\sshell. +D 2015-03-19T13:30:41.360 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -231,7 +231,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c f4d79e31ffa5820c2e3d1740baa5e9b190425f2b F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c 94e016b6733b1d39a2f4c8d431155b4c2897d907 -F src/shell.c cce82ca26392578a4a1ee927dfe55ea3411c7c92 +F src/shell.c 3e8fc22bc1cd63fe595c84a880bd6184deb6c87b F src/sqlite.h.in 2d48e05677d0f9b06b7757662eef3cebea02d837 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d @@ -866,7 +866,7 @@ F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 F test/shell1.test ca88b14a8fc8b1f3543a24e519d019585ac9c903 F test/shell2.test 12b8bf901b0e3a8ac58cf5c0c63a0a388d4d1862 F test/shell3.test 5e8545ec72c4413a0e8d4c6be56496e3c257ca29 -F test/shell4.test 8a9c08976291e6c6c808b4d718f4a8b299f339f5 +F test/shell4.test 4cd3bd50200bf2efd6a74175d98da65aa86daf26 F test/shell5.test c04e9f9f948305706b88377c464c7f08ce7479f9 F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5 @@ -1246,7 +1246,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2c0e0d87fb418d684fba1c83d9fd8e4e96588c54 -R 58ae90a14e230c20fd6999f0bc3305de +P 49ea2cded4a76596f85419c820cdaf4a1751d7ac +R df8b9299e9511ef4e1117da2a3444343 U drh -Z 224b0621dbed3257af56f4d91f4f2bf9 +Z 8cda5daec6a5d1c3721d0a7774b9a78e diff --git a/manifest.uuid b/manifest.uuid index cc37f4c412..52200038fd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -49ea2cded4a76596f85419c820cdaf4a1751d7ac \ No newline at end of file +6a48b5d794e891fdd167547c76835d677eb5e31d \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index cf2481a37c..436c23d47b 100644 --- a/src/shell.c +++ b/src/shell.c @@ -3841,12 +3841,12 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){ open_db(p, 0); - output_file_close(p->traceOut); if( nArg!=2 ){ fprintf(stderr, "Usage: .trace FILE|off\n"); rc = 1; goto meta_command_exit; } + output_file_close(p->traceOut); p->traceOut = output_file_open(azArg[1]); #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) if( p->traceOut==0 ){ diff --git a/test/shell4.test b/test/shell4.test index c29faf00cf..d1466f638c 100644 --- a/test/shell4.test +++ b/test/shell4.test @@ -12,12 +12,12 @@ # The focus of this file is testing the CLI shell tool. # These tests are specific to the .stats command. # -# $Id: shell4.test,v 1.7 2009/07/17 16:54:48 shaneh Exp $ -# +# 2015-03-19: Added tests for .trace # Test plan: # # shell4-1.*: Basic tests specific to the "stats" command. +# shell4-2.*: Basic tests for ".trace" # set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -113,4 +113,22 @@ SELECT 1; [regexp {Autoindex Inserts} $res] } {1 1 1} +do_test shell4-2.1 { + catchcmd ":memory:" "CREATE TABLE t1(x);\n.trace" +} {1 {Usage: .trace FILE|off}} +do_test shell4-2.2 { + catchcmd ":memory:" "CREATE TABLE t1(x);\n.trace off\n.trace off\n" +} {0 {}} +do_test shell4-2.3 { + catchcmd ":memory:" ".trace stdout\n.trace\n.trace off\n.dump\n" +} {/^1 {PRAGMA.*Usage:.*}$/} +do_test shell4-2.4 { + catchcmd ":memory:" ".trace stdout\nCREATE TABLE t1(x);SELECT * FROM t1;" +} {0 {CREATE TABLE t1(x); +SELECT * FROM t1;}} +do_test shell4-2.5 { + catchcmd ":memory:" "CREATE TABLE t1(x);\n.trace stdout\nSELECT * FROM t1;" +} {0 {SELECT * FROM t1;}} + + finish_test