From e0d058c6d8f3b1a959fd5c84be78b3df5dd7c9f5 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 31 Aug 2012 14:55:05 +0000 Subject: [PATCH 01/60] In the spellfix phonehash() function, add letter W into the same character class as V. FossilOrigin-Name: 7536101317c00fbb5bf555120feb55b9bc40e8ba --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/test_spellfix.c | 30 ++++++++++++++---------------- test/spellfix.test | 2 +- 4 files changed, 23 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index 26d0c4d7e6..efe83245c0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Changes\sfor\sERROR_PATH_NOT_FOUND\sin\saddition\sto\sERROR_FILE_NOT_FOUND\sin\s\nwinAccess(). -D 2012-08-31T12:31:18.969 +C In\sthe\sspellfix\sphonehash()\sfunction,\sadd\sletter\sW\sinto\sthe\ssame\scharacter\nclass\sas\sV. +D 2012-08-31T14:55:05.521 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in abd5c10d21d1395f140d9e50ea999df8fa4d6376 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -221,7 +221,7 @@ F src/test_quota.h 8761e463b25e75ebc078bd67d70e39b9c817a0cb F src/test_rtree.c aba603c949766c4193f1068b91c787f57274e0d9 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f -F src/test_spellfix.c 0a5b5b27fc48b00f9e6fd6700f9535de538a964f +F src/test_spellfix.c 0f03970686403fe33fca1a74b0b60af42fb5929e F src/test_stat.c d1569c7a4839f13e80187e2c26b2ab4da2d03935 F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd F src/test_syscall.c a992d8c80ea91fbf21fb2dd570db40e77dd7e6ae @@ -719,7 +719,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/spellfix.test 4e339920585e7555660bd3b11cf338af82c656ae +F test/spellfix.test 2953e9da0e46dab5f83059ef6bfdebca66e13418 F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/stat.test 08e8185b3fd5b010c90d7ad82b9dd4ea1cbf14b0 F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9 @@ -1013,7 +1013,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P d3cf6832a59fe4c5723761abb4c89614406b03db -R 3b56b1cf438f03ed04a187d25a245ed3 +P 527340abff18aedbcb0f82ac1296a9f548e24ac4 +R 12ea0046f8ada46a86a2cc753f34f9c0 U drh -Z 950f4ab8e7c8c7fcad5f5a96fb146fb0 +Z 80f09e05bcc34157b6c058b371e0115a diff --git a/manifest.uuid b/manifest.uuid index 526f75c90c..ad95b5a920 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -527340abff18aedbcb0f82ac1296a9f548e24ac4 \ No newline at end of file +7536101317c00fbb5bf555120feb55b9bc40e8ba \ No newline at end of file diff --git a/src/test_spellfix.c b/src/test_spellfix.c index e5fdac42bc..d98a244389 100644 --- a/src/test_spellfix.c +++ b/src/test_spellfix.c @@ -30,18 +30,17 @@ ** ** 0 '' Silent letters: H W ** 1 'A' Any vowel: A E I O U (Y) -** 2 'B' A bilabeal stop or fricative: B F P V +** 2 'B' A bilabeal stop or fricative: B F P V W ** 3 'C' Other fricatives or back stops: C G J K Q S X Z ** 4 'D' Alveolar stops: D T ** 5 'H' Letter H at the beginning of a word ** 6 'L' Glide: L ** 7 'R' Semivowel: R ** 8 'M' Nasals: M N -** 9 'W' Letter W at the beginning of a word -** 10 'Y' Letter Y at the beginning of a word. -** 11 '9' Digits: 0 1 2 3 4 5 6 7 8 9 -** 12 ' ' White space -** 13 '?' Other. +** 9 'Y' Letter Y at the beginning of a word. +** 10 '9' Digits: 0 1 2 3 4 5 6 7 8 9 +** 11 ' ' White space +** 12 '?' Other. */ #define CCLASS_SILENT 0 #define CCLASS_VOWEL 1 @@ -52,11 +51,10 @@ #define CCLASS_L 6 #define CCLASS_R 7 #define CCLASS_M 8 -#define CCLASS_W 9 -#define CCLASS_Y 10 -#define CCLASS_DIGIT 11 -#define CCLASS_SPACE 12 -#define CCLASS_OTHER 13 +#define CCLASS_Y 9 +#define CCLASS_DIGIT 10 +#define CCLASS_SPACE 11 +#define CCLASS_OTHER 12 /* ** The following table gives the character class for non-initial ASCII @@ -92,7 +90,7 @@ static const unsigned char midClass[] = { /* N */ CCLASS_M, /* O */ CCLASS_VOWEL, /* P */ CCLASS_B, /* Q */ CCLASS_C, /* R */ CCLASS_R, /* S */ CCLASS_C, /* T */ CCLASS_D, /* U */ CCLASS_VOWEL, /* V */ CCLASS_B, - /* W */ CCLASS_SILENT, /* X */ CCLASS_C, /* Y */ CCLASS_VOWEL, + /* W */ CCLASS_B, /* X */ CCLASS_C, /* Y */ CCLASS_VOWEL, /* Z */ CCLASS_C, /* [ */ CCLASS_OTHER, /* \ */ CCLASS_OTHER, /* ] */ CCLASS_OTHER, /* ^ */ CCLASS_OTHER, /* _ */ CCLASS_OTHER, /* ` */ CCLASS_OTHER, /* a */ CCLASS_VOWEL, /* b */ CCLASS_B, @@ -102,7 +100,7 @@ static const unsigned char midClass[] = { /* l */ CCLASS_L, /* m */ CCLASS_M, /* n */ CCLASS_M, /* o */ CCLASS_VOWEL, /* p */ CCLASS_B, /* q */ CCLASS_C, /* r */ CCLASS_R, /* s */ CCLASS_C, /* t */ CCLASS_D, - /* u */ CCLASS_VOWEL, /* v */ CCLASS_B, /* w */ CCLASS_SILENT, + /* u */ CCLASS_VOWEL, /* v */ CCLASS_B, /* w */ CCLASS_B, /* x */ CCLASS_C, /* y */ CCLASS_VOWEL, /* z */ CCLASS_C, /* { */ CCLASS_OTHER, /* | */ CCLASS_OTHER, /* } */ CCLASS_OTHER, /* ~ */ CCLASS_OTHER, /* */ CCLASS_OTHER, @@ -142,7 +140,7 @@ static const unsigned char initClass[] = { /* N */ CCLASS_M, /* O */ CCLASS_VOWEL, /* P */ CCLASS_B, /* Q */ CCLASS_C, /* R */ CCLASS_R, /* S */ CCLASS_C, /* T */ CCLASS_D, /* U */ CCLASS_VOWEL, /* V */ CCLASS_B, - /* W */ CCLASS_W, /* X */ CCLASS_C, /* Y */ CCLASS_Y, + /* W */ CCLASS_B, /* X */ CCLASS_C, /* Y */ CCLASS_Y, /* Z */ CCLASS_C, /* [ */ CCLASS_OTHER, /* \ */ CCLASS_OTHER, /* ] */ CCLASS_OTHER, /* ^ */ CCLASS_OTHER, /* _ */ CCLASS_OTHER, /* ` */ CCLASS_OTHER, /* a */ CCLASS_VOWEL, /* b */ CCLASS_B, @@ -152,7 +150,7 @@ static const unsigned char initClass[] = { /* l */ CCLASS_L, /* m */ CCLASS_M, /* n */ CCLASS_M, /* o */ CCLASS_VOWEL, /* p */ CCLASS_B, /* q */ CCLASS_C, /* r */ CCLASS_R, /* s */ CCLASS_C, /* t */ CCLASS_D, - /* u */ CCLASS_VOWEL, /* v */ CCLASS_B, /* w */ CCLASS_W, + /* u */ CCLASS_VOWEL, /* v */ CCLASS_B, /* w */ CCLASS_B, /* x */ CCLASS_C, /* y */ CCLASS_Y, /* z */ CCLASS_C, /* { */ CCLASS_OTHER, /* | */ CCLASS_OTHER, /* } */ CCLASS_OTHER, /* ~ */ CCLASS_OTHER, /* */ CCLASS_OTHER, @@ -163,7 +161,7 @@ static const unsigned char initClass[] = { ** character class. Note that initClass[] can be used to map the class ** symbol back into the class number. */ -static const unsigned char className[] = ".ABCDHLRMWY9 ?"; +static const unsigned char className[] = ".ABCDHLRMY9 ?"; /* ** Generate a "phonetic hash" from a string of ASCII characters diff --git a/test/spellfix.test b/test/spellfix.test index 245fee24e1..afef981d25 100644 --- a/test/spellfix.test +++ b/test/spellfix.test @@ -68,7 +68,7 @@ do_test 1.1 { } {} foreach {tn word res} { - 1 raxpi* {rasping 5 rasped 5 raspberry 6 rasp 4 rasps 4} + 1 raxpi* {rasping 5 rasped 5 ragweed 5 raspberry 6 rasp 4} 2 ril* {rail 4 railed 4 railer 4 railers 4 railing 4} 3 rilis* {realism 6 realist 6 realistic 6 realistically 6 realists 6} 4 reail* {real 3 realest 3 realign 3 realigned 3 realigning 3} From 4d9d1f472218eb1a5f7972854aa77c4c08d469c4 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 3 Sep 2012 10:32:32 +0000 Subject: [PATCH 02/60] Add Win32 version resources to the applicable binaries built by the MSVC makefile. FossilOrigin-Name: e2f27d28b590164bc6b0d856e79c9345e2188d03 --- Makefile.msc | 70 ++++++++++++++++++++++++++++++++++++++++---------- manifest | 18 ++++++++----- manifest.uuid | 2 +- src/sqlite3.rc | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 138 insertions(+), 21 deletions(-) create mode 100644 src/sqlite3.rc diff --git a/Makefile.msc b/Makefile.msc index 9a160c4287..bc80e27c8c 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -82,6 +82,14 @@ CC = cl.exe LD = link.exe !ENDIF +# Check for the predefined command macro RC. This should point to the resource +# compiler binary for the target platform. If it is not defined, simply define +# it to the legacy default value 'rc.exe'. +# +!IFNDEF RC +RC = rc.exe +!ENDIF + # Check for the command macro NCC. This should point to the compiler binary # for the platform the compilation process is taking place on. If it is not # defined, simply define it to have the same value as the CC macro. When @@ -150,6 +158,7 @@ NLTLIBPATHS = "/LIBPATH:$(NCRTLIBPATH)" "/LIBPATH:$(NSDKLIBPATH)" # same unless your are cross-compiling.) # TCC = $(CC) -W3 -DSQLITE_OS_WIN=1 -I. -I$(TOP)\src -fp:precise +RCC = $(RC) -DSQLITE_OS_WIN=1 -I. -I$(TOP)\src # When compiling the library for use in the WinRT environment, # the following compile-time options must be used as well to @@ -158,7 +167,9 @@ TCC = $(CC) -W3 -DSQLITE_OS_WIN=1 -I. -I$(TOP)\src -fp:precise # !IF $(FOR_WINRT)!=0 TCC = $(TCC) -DSQLITE_OS_WINRT=1 +RCC = $(RCC) -DSQLITE_OS_WINRT=1 TCC = $(TCC) -DWINAPI_FAMILY=WINAPI_PARTITION_APP +RCC = $(RCC) -DWINAPI_FAMILY=WINAPI_PARTITION_APP !ENDIF # Also, we need to dynamically link to the correct MSVC runtime @@ -186,7 +197,9 @@ TCC = $(TCC) -MT # !IF $(USE_AMALGAMATION)==0 TCC = $(TCC) -I$(TOP)\ext\fts3 +RCC = $(RCC) -I$(TOP)\ext\fts3 TCC = $(TCC) -I$(TOP)\ext\rtree +RCC = $(RCC) -I$(TOP)\ext\rtree !ENDIF # Define -DNDEBUG to compile without debugging (i.e., for production usage) @@ -196,18 +209,22 @@ TCC = $(TCC) -I$(TOP)\ext\rtree !IF $(DEBUG)==0 TCC = $(TCC) -DNDEBUG BCC = $(BCC) -DNDEBUG +RCC = $(RCC) -DNDEBUG !ENDIF !IF $(DEBUG)>1 TCC = $(TCC) -DSQLITE_DEBUG +RCC = $(RCC) -DSQLITE_DEBUG !ENDIF !IF $(DEBUG)>3 TCC = $(TCC) -DSQLITE_DEBUG_OS_TRACE=1 +RCC = $(RCC) -DSQLITE_DEBUG_OS_TRACE=1 !ENDIF !IF $(DEBUG)>4 TCC = $(TCC) -DSQLITE_ENABLE_IOTRACE +RCC = $(RCC) -DSQLITE_ENABLE_IOTRACE !ENDIF # @@ -216,30 +233,35 @@ TCC = $(TCC) -DSQLITE_ENABLE_IOTRACE # TCC = $(TCC) -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS BCC = $(BCC) -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS +RCC = $(RCC) -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS # # Prevent warnings about "deprecated" POSIX functions being used. # TCC = $(TCC) -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS BCC = $(BCC) -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS +RCC = $(RCC) -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS # # Use the SQLite debugging heap subsystem? # !IF $(MEMDEBUG)!=0 TCC = $(TCC) -DSQLITE_MEMDEBUG=1 +RCC = $(RCC) -DSQLITE_MEMDEBUG=1 # # Use native Win32 heap subsystem instead of malloc/free? # !ELSEIF $(WIN32HEAP)!=0 TCC = $(TCC) -DSQLITE_WIN32_MALLOC=1 +RCC = $(RCC) -DSQLITE_WIN32_MALLOC=1 # # Validate the heap on every call into the native Win32 heap subsystem? # !IF $(DEBUG)>2 TCC = $(TCC) -DSQLITE_WIN32_MALLOC_VALIDATE=1 +RCC = $(RCC) -DSQLITE_WIN32_MALLOC_VALIDATE=1 !ENDIF !ENDIF @@ -298,10 +320,12 @@ LIBREADLINE = # Should the database engine be compiled threadsafe # TCC = $(TCC) -DSQLITE_THREADSAFE=1 +RCC = $(RCC) -DSQLITE_THREADSAFE=1 # Do threads override each others locks by default (1), or do we test (-1) # TCC = $(TCC) -DSQLITE_THREAD_OVERRIDE_LOCK=-1 +RCC = $(RCC) -DSQLITE_THREAD_OVERRIDE_LOCK=-1 # Any target libraries which libsqlite must be linked against # @@ -316,6 +340,7 @@ TLIBS = # tables to always be in memory. # TCC = $(TCC) -DSQLITE_TEMP_STORE=1 +RCC = $(RCC) -DSQLITE_TEMP_STORE=1 # Enable/disable loadable extensions, and other optional features # based on configuration. (-DSQLITE_OMIT*, -DSQLITE_ENABLE*). @@ -333,16 +358,19 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_MAX_TRIGGER_DEPTH=100 # END required Windows option TCC = $(TCC) $(OPT_FEATURE_FLAGS) +RCC = $(RCC) $(OPT_FEATURE_FLAGS) # Add in any optional parameters specified on the make commane line # ie. make "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1". TCC = $(TCC) $(OPTS) +RCC = $(RCC) $(OPTS) # If symbols are enabled, enable PDBs. # If debugging is enabled, disable all optimizations and enable PDBs. !IF $(DEBUG)>0 TCC = $(TCC) -Od -D_DEBUG BCC = $(BCC) -Od -D_DEBUG +RCC = $(RCC) -D_DEBUG !ELSE TCC = $(TCC) -O2 BCC = $(BCC) -O2 @@ -356,12 +384,17 @@ BCC = $(BCC) -Zi # If ICU support is enabled, add the compiler options for it. !IF $(USE_ICU)!=0 TCC = $(TCC) -DSQLITE_ENABLE_ICU=1 +RCC = $(RCC) -DSQLITE_ENABLE_ICU=1 TCC = $(TCC) -I$(TOP)\ext\icu +RCC = $(RCC) -I$(TOP)\ext\icu TCC = $(TCC) -I$(ICUINCDIR) +RCC = $(RCC) -I$(ICUINCDIR) !ENDIF -# libtool compile/link +# Command line prefixes for compiling code, compiling resources, +# linking, etc. LTCOMPILE = $(TCC) -Fo$@ +LTRCOMPILE = $(RCC) -r LTLIB = lib.exe LTLINK = $(TCC) -Fe$@ @@ -733,10 +766,10 @@ libsqlite3.lib: $(LIBOBJ) libtclsqlite3.lib: tclsqlite.lo libsqlite3.lib $(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCL:tcl=tclstub) $(TLIBS) -sqlite3.exe: $(TOP)\src\shell.c libsqlite3.lib sqlite3.h +sqlite3.exe: $(TOP)\src\shell.c libsqlite3.lib sqlite3res.lo sqlite3.h $(LTLINK) $(READLINE_FLAGS) \ $(TOP)\src\shell.c \ - /link $(LTLINKOPTS) $(LTLIBPATHS) libsqlite3.lib $(LIBREADLINE) $(LTLIBS) $(TLIBS) + /link $(LTLINKOPTS) $(LTLIBPATHS) libsqlite3.lib sqlite3res.lo $(LIBREADLINE) $(LTLIBS) $(TLIBS) # This target creates a directory named "tsrc" and fills it with # copies of all of the C source code and header files needed to @@ -784,6 +817,17 @@ parse.lo: parse.c $(HDR) opcodes.lo: opcodes.c $(LTCOMPILE) -c opcodes.c +# Rule to build the Win32 resources object file. +# +sqlite3res.lo: $(TOP)\src\sqlite3.rc $(HDR) + echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h + for /F %%V in ('type VERSION') do ( \ + echo #define SQLITE_RESOURCE_VERSION %%V \ + | $(NAWK) "/.*/ { gsub(/[.]/,\",\");print }" >> sqlite3rc.h \ + ) + echo #endif >> sqlite3rc.h + $(LTRCOMPILE) -fo sqlite3res.lo $(TOP)\src\sqlite3.rc + # Rules to build individual *.lo files from files in the src directory. # alter.lo: $(TOP)\src\alter.c $(HDR) @@ -999,9 +1043,9 @@ tclsqlite.lo: $(TOP)\src\tclsqlite.c $(HDR) tclsqlite-shell.lo: $(TOP)\src\tclsqlite.c $(HDR) $(LTCOMPILE) -DTCLSH=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c -tclsqlite3.exe: tclsqlite-shell.lo libsqlite3.lib +tclsqlite3.exe: tclsqlite-shell.lo libsqlite3.lib sqlite3res.lo $(LTLINK) tclsqlite-shell.lo \ - /link $(LTLINKOPTS) $(LTLIBPATHS) libsqlite3.lib $(LTLIBS) $(TLIBS) + /link $(LTLINKOPTS) $(LTLIBPATHS) libsqlite3.lib sqlite3res.lo $(LTLIBS) $(TLIBS) # Rules to build opcodes.c and opcodes.h # @@ -1114,11 +1158,11 @@ TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC0) TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC1) !ENDIF -testfixture.exe: $(TESTFIXTURE_SRC) $(HDR) +testfixture.exe: $(TESTFIXTURE_SRC) sqlite3res.lo $(HDR) $(LTLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \ -DBUILD_sqlite -I$(TCLINCDIR) \ $(TESTFIXTURE_SRC) \ - /link $(LTLINKOPTS) $(LTLIBPATHS) $(LTLIBS) $(TLIBS) + /link $(LTLINKOPTS) $(LTLIBPATHS) sqlite3res.lo $(LTLIBS) $(TLIBS) fulltest: testfixture.exe sqlite3.exe .\testfixture.exe $(TOP)\test\all.test @@ -1136,9 +1180,9 @@ sqlite3_analyzer.c: sqlite3.c $(TOP)\src\test_stat.c $(TOP)\src\tclsqlite.c $(TO $(NAWK) -f $(TOP)\tool\tostr.awk $(TOP)\tool\spaceanal.tcl >> $@ echo ; return zMainloop; } >> $@ -sqlite3_analyzer.exe: sqlite3_analyzer.c +sqlite3_analyzer.exe: sqlite3_analyzer.c sqlite3res.lo $(LTLINK) -DBUILD_sqlite -DTCLSH=2 -I$(TCLINCDIR) sqlite3_analyzer.c \ - /link $(LTLINKOPTS) $(LTLIBPATHS) $(LTLIBS) $(TLIBS) + /link $(LTLINKOPTS) $(LTLIBPATHS) sqlite3res.lo $(LTLIBS) $(TLIBS) clean: del /Q *.lo *.ilk *.lib *.obj *.pdb sqlite3.exe libsqlite3.lib @@ -1157,11 +1201,11 @@ clean: del /Q testfixture.exe testfixture.exp test.db del /Q sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def del /Q sqlite3.c + del /Q sqlite3rc.h del /Q sqlite3_analyzer.exe sqlite3_analyzer.exp sqlite3_analyzer.c del /Q sqlite-output.vsix -# -# Windows section +# Dynamic link library section. # dll: sqlite3.dll @@ -1171,5 +1215,5 @@ sqlite3.def: libsqlite3.lib | $(NAWK) "/ 1 _?sqlite3_/ { sub(/^.* _?/,\"\");print }" \ | sort >> sqlite3.def -sqlite3.dll: $(LIBOBJ) sqlite3.def - $(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /DEF:sqlite3.def /OUT:$@ $(LIBOBJ) $(LTLIBS) $(TLIBS) +sqlite3.dll: $(LIBOBJ) sqlite3res.lo sqlite3.def + $(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /DEF:sqlite3.def /OUT:$@ $(LIBOBJ) sqlite3res.lo $(LTLIBS) $(TLIBS) diff --git a/manifest b/manifest index efe83245c0..02deface94 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C In\sthe\sspellfix\sphonehash()\sfunction,\sadd\sletter\sW\sinto\sthe\ssame\scharacter\nclass\sas\sV. -D 2012-08-31T14:55:05.521 +C Add\sWin32\sversion\sresources\sto\sthe\sapplicable\sbinaries\sbuilt\sby\sthe\sMSVC\smakefile. +D 2012-09-03T10:32:32.046 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in abd5c10d21d1395f140d9e50ea999df8fa4d6376 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 -F Makefile.msc f00ec5dc2e78eb63d32c3125ab7a999aa7fcf924 +F Makefile.msc d6127b1d8488a7733a23c89175ab9b7899987adf F Makefile.vxworks 879f034a64062a364b21000266bbd5bc6e0c19b9 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 F VERSION a71848df48082f1d6585d4b0819d530fc455485d @@ -179,6 +179,7 @@ F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c f843c872a97baa1594c2cc3d4c003409a7bd03af F src/shell.c 87953c5d9c73d9494db97d1607e2e2280418f261 F src/sqlite.h.in c447d35212736c4c77d86bc2d00f6cf4d4c12131 +F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h 053e03a532beb909ead2df0721db67cdb4c48ae8 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d @@ -1013,7 +1014,10 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 527340abff18aedbcb0f82ac1296a9f548e24ac4 -R 12ea0046f8ada46a86a2cc753f34f9c0 -U drh -Z 80f09e05bcc34157b6c058b371e0115a +P 7536101317c00fbb5bf555120feb55b9bc40e8ba +R 24121e4a9d0fc498cf79976cfed87444 +T *branch * win32Resources +T *sym-win32Resources * +T -sym-trunk * +U mistachkin +Z 3bf23bfb661a7d15378c710920999b0d diff --git a/manifest.uuid b/manifest.uuid index ad95b5a920..fc61106319 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7536101317c00fbb5bf555120feb55b9bc40e8ba \ No newline at end of file +e2f27d28b590164bc6b0d856e79c9345e2188d03 \ No newline at end of file diff --git a/src/sqlite3.rc b/src/sqlite3.rc new file mode 100644 index 0000000000..969876da1e --- /dev/null +++ b/src/sqlite3.rc @@ -0,0 +1,69 @@ +/* +** 2012 September 2 +** +** 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 and resources that are specific to Windows. +*/ + +#if !defined(_WIN32_WCE) +#include "winresrc.h" +#else +#include "windows.h" +#endif + +#include "sqlite3.h" +#include "sqlite3rc.h" + +/* + * English (U.S.) resources + */ + +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif /* _WIN32 */ + +/* + * Version + */ + +VS_VERSION_INFO VERSIONINFO + FILEVERSION SQLITE_RESOURCE_VERSION + PRODUCTVERSION SQLITE_RESOURCE_VERSION + FILEFLAGSMASK 0x3F +#if defined(_DEBUG) + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE VFT2_UNKNOWN +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "SQLite Development Team" + VALUE "FileDescription", "SQLite is a software library that implements a self-contained, serverless, zero-configuration, transactional SQL database engine." + VALUE "FileVersion", SQLITE_VERSION + VALUE "InternalName", "sqlite3" + VALUE "LegalCopyright", "http://www.sqlite.org/copyright.html" + VALUE "ProductName", "SQLite" + VALUE "ProductVersion", SQLITE_VERSION + VALUE "SourceId", SQLITE_SOURCE_ID + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END From 0f104d57005d313ad44248e71b4242844a43e44f Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 3 Sep 2012 11:01:21 +0000 Subject: [PATCH 03/60] Linking and cleaning fixes for the tclsqlite3.exe target in the MSVC makefile. FossilOrigin-Name: 96d43c7a35684cd8ca6ac0d8325193e69f102fb8 --- Makefile.msc | 5 ++--- manifest | 15 ++++++--------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index bc80e27c8c..f688fa2fcc 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1044,8 +1044,7 @@ tclsqlite-shell.lo: $(TOP)\src\tclsqlite.c $(HDR) $(LTCOMPILE) -DTCLSH=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c tclsqlite3.exe: tclsqlite-shell.lo libsqlite3.lib sqlite3res.lo - $(LTLINK) tclsqlite-shell.lo \ - /link $(LTLINKOPTS) $(LTLIBPATHS) libsqlite3.lib sqlite3res.lo $(LTLIBS) $(TLIBS) + $(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /OUT:$@ libsqlite3.lib tclsqlite-shell.lo sqlite3res.lo $(LTLIBS) $(TLIBS) # Rules to build opcodes.c and opcodes.h # @@ -1197,7 +1196,7 @@ clean: -rmdir /Q/S quota2c -rmdir /Q/S tsrc del /Q .target_source - del /Q tclsqlite3.exe + del /Q tclsqlite3.exe tclsqlite3.exp del /Q testfixture.exe testfixture.exp test.db del /Q sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def del /Q sqlite3.c diff --git a/manifest b/manifest index 02deface94..252fe7dbed 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Add\sWin32\sversion\sresources\sto\sthe\sapplicable\sbinaries\sbuilt\sby\sthe\sMSVC\smakefile. -D 2012-09-03T10:32:32.046 +C Linking\sand\scleaning\sfixes\sfor\sthe\stclsqlite3.exe\starget\sin\sthe\sMSVC\smakefile. +D 2012-09-03T11:01:21.786 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in abd5c10d21d1395f140d9e50ea999df8fa4d6376 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 -F Makefile.msc d6127b1d8488a7733a23c89175ab9b7899987adf +F Makefile.msc 494e71889c5f3480c53b83e3c42156ac17c99d68 F Makefile.vxworks 879f034a64062a364b21000266bbd5bc6e0c19b9 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 F VERSION a71848df48082f1d6585d4b0819d530fc455485d @@ -1014,10 +1014,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 7536101317c00fbb5bf555120feb55b9bc40e8ba -R 24121e4a9d0fc498cf79976cfed87444 -T *branch * win32Resources -T *sym-win32Resources * -T -sym-trunk * +P e2f27d28b590164bc6b0d856e79c9345e2188d03 +R 45efbc31964d33080b484210f8dbf86c U mistachkin -Z 3bf23bfb661a7d15378c710920999b0d +Z 5f858f893a53076d6a54458ec310e24b diff --git a/manifest.uuid b/manifest.uuid index fc61106319..0db4ee0bbb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e2f27d28b590164bc6b0d856e79c9345e2188d03 \ No newline at end of file +96d43c7a35684cd8ca6ac0d8325193e69f102fb8 \ No newline at end of file From 597a8c5f32261890eac9e2c61724442db8d71393 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 3 Sep 2012 11:14:53 +0000 Subject: [PATCH 04/60] Insert additional tab character. FossilOrigin-Name: 3af7c1a6afacea7b5e47bebce2541aa340c6e946 --- Makefile.msc | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index f688fa2fcc..2b79c2b9b7 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -823,7 +823,7 @@ sqlite3res.lo: $(TOP)\src\sqlite3.rc $(HDR) echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h for /F %%V in ('type VERSION') do ( \ echo #define SQLITE_RESOURCE_VERSION %%V \ - | $(NAWK) "/.*/ { gsub(/[.]/,\",\");print }" >> sqlite3rc.h \ + | $(NAWK) "/.*/ { gsub(/[.]/,\",\");print }" >> sqlite3rc.h \ ) echo #endif >> sqlite3rc.h $(LTRCOMPILE) -fo sqlite3res.lo $(TOP)\src\sqlite3.rc diff --git a/manifest b/manifest index 252fe7dbed..02d98c2ef2 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Linking\sand\scleaning\sfixes\sfor\sthe\stclsqlite3.exe\starget\sin\sthe\sMSVC\smakefile. -D 2012-09-03T11:01:21.786 +C Insert\sadditional\stab\scharacter. +D 2012-09-03T11:14:53.144 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in abd5c10d21d1395f140d9e50ea999df8fa4d6376 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 -F Makefile.msc 494e71889c5f3480c53b83e3c42156ac17c99d68 +F Makefile.msc 2d696f01c228995e98b3b953a08b7bba1d48c130 F Makefile.vxworks 879f034a64062a364b21000266bbd5bc6e0c19b9 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 F VERSION a71848df48082f1d6585d4b0819d530fc455485d @@ -1014,7 +1014,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P e2f27d28b590164bc6b0d856e79c9345e2188d03 -R 45efbc31964d33080b484210f8dbf86c +P 96d43c7a35684cd8ca6ac0d8325193e69f102fb8 +R d73e64771e785a3e221346e08be6714e U mistachkin -Z 5f858f893a53076d6a54458ec310e24b +Z d6bddee65b5cfbe6b9d103d9c0b5c02d diff --git a/manifest.uuid b/manifest.uuid index 0db4ee0bbb..5e19b66df3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -96d43c7a35684cd8ca6ac0d8325193e69f102fb8 \ No newline at end of file +3af7c1a6afacea7b5e47bebce2541aa340c6e946 \ No newline at end of file From 9265d0bdc27f039fc0d405a61cc59d5c444ba12f Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 3 Sep 2012 12:40:32 +0000 Subject: [PATCH 05/60] Fix compiler warnings in test_spellfix1.c FossilOrigin-Name: ebb08d0b4d1ed674e4a23c3754206ca2df9063ff --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/test_spellfix.c | 10 +++++----- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 17821daf94..82653197c5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sresources\sdescribing\sthe\sversion\snumber\sand\sother\sinformation\sto\sEXEs\nand\sDLLs\sgenerated\susing\sMSVC. -D 2012-09-03T11:39:59.391 +C Fix\scompiler\swarnings\sin\stest_spellfix1.c +D 2012-09-03T12:40:32.238 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in abd5c10d21d1395f140d9e50ea999df8fa4d6376 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -222,7 +222,7 @@ F src/test_quota.h 8761e463b25e75ebc078bd67d70e39b9c817a0cb F src/test_rtree.c aba603c949766c4193f1068b91c787f57274e0d9 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f -F src/test_spellfix.c 0f03970686403fe33fca1a74b0b60af42fb5929e +F src/test_spellfix.c 76dd8d3111d2f5354c374f71fa23b752bd0b029c F src/test_stat.c d1569c7a4839f13e80187e2c26b2ab4da2d03935 F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd F src/test_syscall.c a992d8c80ea91fbf21fb2dd570db40e77dd7e6ae @@ -1014,7 +1014,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 7536101317c00fbb5bf555120feb55b9bc40e8ba 3af7c1a6afacea7b5e47bebce2541aa340c6e946 -R d73e64771e785a3e221346e08be6714e +P a15a70840e1af55ffe4035f53e894a2d582d8f74 +R 8bdf9ef517616ac5a5043f12bec4acdb U drh -Z 8fd21ce3038c1c5a5efd757200a7f3c6 +Z ba78db3487c242fdc928a99a33b20e48 diff --git a/manifest.uuid b/manifest.uuid index 9425268834..0c25cb9b59 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a15a70840e1af55ffe4035f53e894a2d582d8f74 \ No newline at end of file +ebb08d0b4d1ed674e4a23c3754206ca2df9063ff \ No newline at end of file diff --git a/src/test_spellfix.c b/src/test_spellfix.c index d98a244389..3f21d732b6 100644 --- a/src/test_spellfix.c +++ b/src/test_spellfix.c @@ -1894,7 +1894,7 @@ static int spellfix1Init( int rc = SQLITE_OK; int i; - nDbName = strlen(zDbName); + nDbName = (int)strlen(zDbName); pNew = sqlite3_malloc( sizeof(*pNew) + nDbName + 1); if( pNew==0 ){ rc = SQLITE_NOMEM; @@ -2234,7 +2234,7 @@ static void spellfix1RunQuery(MatchQuery *p, const char *zQuery, int nQuery){ p->rc = SQLITE_NOMEM; return; } - nClass = strlen(zClass); + nClass = (int)strlen(zClass); if( nClass>SPELLFIX_MX_HASH-2 ){ nClass = SPELLFIX_MX_HASH-2; zClass[nClass] = 0; @@ -2408,7 +2408,7 @@ static int spellfix1FilterForMatch( x.rc = SQLITE_NOMEM; goto filter_exit; } - nPattern = strlen(zPattern); + nPattern = (int)strlen(zPattern); if( zPattern[nPattern-1]=='*' ) nPattern--; zSql = sqlite3_mprintf( "SELECT id, word, rank, k1" @@ -2569,9 +2569,9 @@ static int spellfix1Column( case SPELLFIX_COL_MATCHLEN: { int iMatchlen = pCur->a[pCur->iRow].iMatchlen; if( iMatchlen<0 ){ - int nPattern = strlen(pCur->zPattern); + int nPattern = (int)strlen(pCur->zPattern); char *zWord = pCur->a[pCur->iRow].zWord; - int nWord = strlen(zWord); + int nWord = (int)strlen(zWord); if( nPattern>0 && pCur->zPattern[nPattern-1]=='*' ){ char *zTranslit; From 8a7c142887077adb590cb95a46941cb5149a7287 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 3 Sep 2012 15:42:36 +0000 Subject: [PATCH 06/60] Version 3.7.14 FossilOrigin-Name: c0d89d4a9752922f9e367362366efde4f1b06f2a --- manifest | 11 +++++++---- manifest.uuid | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/manifest b/manifest index 82653197c5..033d6654a3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\scompiler\swarnings\sin\stest_spellfix1.c -D 2012-09-03T12:40:32.238 +C Version\s3.7.14 +D 2012-09-03T15:42:36.217 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in abd5c10d21d1395f140d9e50ea999df8fa4d6376 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1014,7 +1014,10 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P a15a70840e1af55ffe4035f53e894a2d582d8f74 +P ebb08d0b4d1ed674e4a23c3754206ca2df9063ff R 8bdf9ef517616ac5a5043f12bec4acdb +T +bgcolor * #d0c0ff +T +sym-release * +T +sym-version-3.7.14 * U drh -Z ba78db3487c242fdc928a99a33b20e48 +Z 126ab1aaea0f3a8cb5c4792cf0a82989 diff --git a/manifest.uuid b/manifest.uuid index 0c25cb9b59..05cc345a30 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ebb08d0b4d1ed674e4a23c3754206ca2df9063ff \ No newline at end of file +c0d89d4a9752922f9e367362366efde4f1b06f2a \ No newline at end of file From 37f58e99022b329ba0007bc6509675a22a151eef Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 4 Sep 2012 21:34:26 +0000 Subject: [PATCH 07/60] Avoid repeating calls to the sqlite3_trace() callback when the same statement is evaluted multiple times by sqlite3_step() due to an SQLITE_SCHEMA reprepare. FossilOrigin-Name: 39f763bfc04174ee0fe2cdf6a92b7c12f726bd1b --- manifest | 19 ++++++++----------- manifest.uuid | 2 +- src/vdbe.c | 5 ++++- src/vdbeInt.h | 22 ++++++++++++++-------- src/vdbeapi.c | 2 ++ 5 files changed, 29 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 033d6654a3..deddb04066 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Version\s3.7.14 -D 2012-09-03T15:42:36.217 +C Avoid\srepeating\scalls\sto\sthe\ssqlite3_trace()\scallback\swhen\sthe\ssame\sstatement\nis\sevaluted\smultiple\stimes\sby\ssqlite3_step()\sdue\sto\san\sSQLITE_SCHEMA\nreprepare. +D 2012-09-04T21:34:26.807 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in abd5c10d21d1395f140d9e50ea999df8fa4d6376 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -238,10 +238,10 @@ F src/update.c 28d2d098b43a2c70dae399896ea8a02f622410ef F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84 F src/util.c 0af2e515dc0dabacec931bca39525f6c3f1c5455 F src/vacuum.c 587a52bb8833d7ac15af8916f25437e2575028bd -F src/vdbe.c 9c524bded348fd0a53adc19f2d7cad76ba3442b2 +F src/vdbe.c 64de1142b9f3a84f500a6ce964175c828f1e41da F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb -F src/vdbeInt.h 986b6b11a13c517337355009e5438703ba5b0a40 -F src/vdbeapi.c 88ea823bbcb4320f5a6607f39cd7c2d3cc4c26b1 +F src/vdbeInt.h a668b303644377433e31a18d3d9efb87eefb6332 +F src/vdbeapi.c 4c2418161cf45392ba76a7ca92f9a5f06b96f89c F src/vdbeaux.c 9c293fd3040211687e83d5d27bef2382933146c2 F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb F src/vdbemem.c cb55e84b8e2c15704968ee05f0fae25883299b74 @@ -1014,10 +1014,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P ebb08d0b4d1ed674e4a23c3754206ca2df9063ff -R 8bdf9ef517616ac5a5043f12bec4acdb -T +bgcolor * #d0c0ff -T +sym-release * -T +sym-version-3.7.14 * +P c0d89d4a9752922f9e367362366efde4f1b06f2a +R f99616c13334ce584a8b1ebfcd476fa4 U drh -Z 126ab1aaea0f3a8cb5c4792cf0a82989 +Z 2084e672100937502093a8dd98a48d0f diff --git a/manifest.uuid b/manifest.uuid index 05cc345a30..28881c5c18 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c0d89d4a9752922f9e367362366efde4f1b06f2a \ No newline at end of file +39f763bfc04174ee0fe2cdf6a92b7c12f726bd1b \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 1a3c412a78..965eec2acc 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6075,7 +6075,10 @@ case OP_Trace: { char *zTrace; char *z; - if( db->xTrace && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 ){ + if( db->xTrace + && !p->doingRerun + && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 + ){ z = sqlite3VdbeExpandSql(p, zTrace); db->xTrace(db->pTraceArg, z); sqlite3DbFree(db, z); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 1f5694a595..e559bc2bd2 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -273,6 +273,11 @@ struct Explain { char zBase[100]; /* Initial space */ }; +/* A bitfield type for use inside of structures. Always follow with :N where +** N is the number of bits. +*/ +typedef unsigned bft; /* Bit Field Type */ + /* ** An instance of the virtual machine. This structure contains the complete ** state of the virtual machine. @@ -314,15 +319,16 @@ struct Vdbe { int pc; /* The program counter */ int rc; /* Value to return */ u8 errorAction; /* Recovery action to do in case of an error */ - u8 explain; /* True if EXPLAIN present on SQL command */ - u8 changeCntOn; /* True to update the change-counter */ - u8 expired; /* True if the VM needs to be recompiled */ - u8 runOnlyOnce; /* Automatically expire on reset */ u8 minWriteFileFormat; /* Minimum file format for writable database files */ - u8 inVtabMethod; /* See comments above */ - u8 usesStmtJournal; /* True if uses a statement journal */ - u8 readOnly; /* True for read-only statements */ - u8 isPrepareV2; /* True if prepared with prepare_v2() */ + bft explain:2; /* True if EXPLAIN present on SQL command */ + bft inVtabMethod:2; /* See comments above */ + bft changeCntOn:1; /* True to update the change-counter */ + bft expired:1; /* True if the VM needs to be recompiled */ + bft runOnlyOnce:1; /* Automatically expire on reset */ + bft usesStmtJournal:1; /* True if uses a statement journal */ + bft readOnly:1; /* True for read-only statements */ + bft isPrepareV2:1; /* True if prepared with prepare_v2() */ + bft doingRerun:1; /* True if rerunning after an auto-reprepare */ int nChange; /* Number of db changes made since last reset */ yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */ yDbMask lockMask; /* Subset of btreeMask that requires a lock */ diff --git a/src/vdbeapi.c b/src/vdbeapi.c index b9a88a6ab8..b48826680a 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -478,10 +478,12 @@ int sqlite3_step(sqlite3_stmt *pStmt){ } db = v->db; sqlite3_mutex_enter(db->mutex); + v->doingRerun = 0; while( (rc = sqlite3Step(v))==SQLITE_SCHEMA && cnt++ < SQLITE_MAX_SCHEMA_RETRY && (rc2 = rc = sqlite3Reprepare(v))==SQLITE_OK ){ sqlite3_reset(pStmt); + v->doingRerun = 1; assert( v->expired==0 ); } if( rc2!=SQLITE_OK && ALWAYS(v->isPrepareV2) && ALWAYS(db->pErr) ){ From f360396c47661cd814b1d9860ef004b3ac2891fc Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 7 Sep 2012 16:46:59 +0000 Subject: [PATCH 08/60] Add an experimental busy_timeout pragma to facilitate access to the sqlite3_busy_timeout() interfaces for programmers that are working from behind a language wrapper that does not expose that interface. FossilOrigin-Name: 22ebc668516bc3dd5782d6d3d42dc7fd2eed7d79 --- manifest | 19 +++++++++++-------- manifest.uuid | 2 +- src/main.c | 1 + src/pragma.c | 16 ++++++++++++++++ test/lock.test | 23 +++++++++++++++++++++++ 5 files changed, 52 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index deddb04066..fd801aab24 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\srepeating\scalls\sto\sthe\ssqlite3_trace()\scallback\swhen\sthe\ssame\sstatement\nis\sevaluted\smultiple\stimes\sby\ssqlite3_step()\sdue\sto\san\sSQLITE_SCHEMA\nreprepare. -D 2012-09-04T21:34:26.807 +C Add\san\sexperimental\sbusy_timeout\spragma\sto\sfacilitate\saccess\sto\sthe\nsqlite3_busy_timeout()\sinterfaces\sfor\sprogrammers\sthat\sare\sworking\sfrom\nbehind\sa\slanguage\swrapper\sthat\sdoes\snot\sexpose\sthat\sinterface. +D 2012-09-07T16:46:59.378 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in abd5c10d21d1395f140d9e50ea999df8fa4d6376 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -145,7 +145,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d -F src/main.c 02255cf1da50956c5427c469abddb15bccc4ba09 +F src/main.c 31af732aa4363e85816b09794429c79fe4baa3ac F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa @@ -170,7 +170,7 @@ F src/parse.y f29df90bd3adc64b33114ab1de9fb7768fcf2099 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h 1b5dcc3dc8103d03e625b177023ee67764fa6b7c F src/pcache1.c 9fd22671c270b35131ef480bbc00392b8b5f8ab9 -F src/pragma.c 97f9357f0e7e5fb46a2519f14539550aa07db49f +F src/pragma.c e09950b9d0a35c1bf2329038c10f38589e754ae8 F src/prepare.c 33291b83cca285718048d219c67b8298501fa3a5 F src/printf.c 4a9f882f1c1787a8b494a2987765acf9d97ac21f F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 @@ -571,7 +571,7 @@ F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da F test/limit.test 2db7b3b34fb925b8e847d583d2eb67531d0ce67e F test/loadext.test 2b5e249c51c986a5aff1f0950cf7ba30976c8f22 F test/loadext2.test 0bcaeb4d81cd5b6e883fdfea3c1bdbe1f173cbca -F test/lock.test db74fdf5a73bad29ab3d862ea78bf1068972cc1d +F test/lock.test 7e9eddd991b3af3a01caec2d9f030e0798deef74 F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff F test/lock3.test f271375930711ae044080f4fe6d6eda930870d00 F test/lock4.test e175ae13865bc87680607563bafba21f31a26f12 @@ -1014,7 +1014,10 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P c0d89d4a9752922f9e367362366efde4f1b06f2a -R f99616c13334ce584a8b1ebfcd476fa4 +P 39f763bfc04174ee0fe2cdf6a92b7c12f726bd1b +R 7a209eaa28bbe6aeaf699b5d2296eb6d +T *branch * busy-timeout-pragma +T *sym-busy-timeout-pragma * +T -sym-trunk * U drh -Z 2084e672100937502093a8dd98a48d0f +Z 3457f6820fedfafcfc1fb25157630cb3 diff --git a/manifest.uuid b/manifest.uuid index 28881c5c18..3068fe9942 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -39f763bfc04174ee0fe2cdf6a92b7c12f726bd1b \ No newline at end of file +22ebc668516bc3dd5782d6d3d42dc7fd2eed7d79 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 16294a6199..fa565982fa 100644 --- a/src/main.c +++ b/src/main.c @@ -1156,6 +1156,7 @@ int sqlite3_busy_timeout(sqlite3 *db, int ms){ db->busyTimeout = ms; sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db); }else{ + db->busyTimeout = 0; sqlite3_busy_handler(db, 0, 0); } return SQLITE_OK; diff --git a/src/pragma.c b/src/pragma.c index a41e0e433f..c686265a22 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1536,6 +1536,22 @@ void sqlite3Pragma( sqlite3_db_release_memory(db); }else + /* + ** PRAGMA busy_timeout + ** PRAGMA busy_timeout = N + ** + ** Call sqlite3_busy_timeout(db, N). Return the current timeout value + ** if one is set. If the busy handler is not set to the default + ** busy callback, then the return value is undefined. A value of N + ** which is 0 or negative disables the busy handler. + */ + if( sqlite3StrICmp(zLeft, "busy_timeout")==0 ){ + if( zRight ){ + sqlite3_busy_timeout(db, sqlite3Atoi(zRight)); + } + returnSingleInt(pParse, "timeout", db->busyTimeout); + }else + #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) /* ** Report the current state of file logs for all databases diff --git a/test/lock.test b/test/lock.test index 22f359c1a2..e3b1daad88 100644 --- a/test/lock.test +++ b/test/lock.test @@ -247,11 +247,34 @@ do_test lock-2.8 { execsql {UPDATE t1 SET a = 0 WHERE 0} catchsql {BEGIN EXCLUSIVE;} db2 } {1 {database is locked}} +do_test lock-2.8b { + db2 eval {PRAGMA busy_timeout} +} {400} do_test lock-2.9 { db2 timeout 0 execsql COMMIT } {} +do_test lock-2.9b { + db2 eval {PRAGMA busy_timeout} +} {0} integrity_check lock-2.10 +do_test lock-2.11 { + db2 eval {PRAGMA busy_timeout(400)} + execsql BEGIN + execsql {UPDATE t1 SET a = 0 WHERE 0} + catchsql {BEGIN EXCLUSIVE;} db2 +} {1 {database is locked}} +do_test lock-2.11b { + db2 eval {PRAGMA busy_timeout} +} {400} +do_test lock-2.12 { + db2 eval {PRAGMA busy_timeout(0)} + execsql COMMIT +} {} +do_test lock-2.11b { + db2 eval {PRAGMA busy_timeout} +} {0} +integrity_check lock-2.12 # Try to start two transactions in a row # From c0c7b5ee7448039476edb920c076dcb01f218fa8 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 7 Sep 2012 18:49:57 +0000 Subject: [PATCH 09/60] Have PRAGMA busy_timeout return 0 if the busy handler has been changed or cancelled. FossilOrigin-Name: 7be5bc36798d30f50658b70fc0bd31af897f3a87 --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/main.c | 4 ++-- src/pragma.c | 6 +++--- 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index fd801aab24..558095f7ba 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\san\sexperimental\sbusy_timeout\spragma\sto\sfacilitate\saccess\sto\sthe\nsqlite3_busy_timeout()\sinterfaces\sfor\sprogrammers\sthat\sare\sworking\sfrom\nbehind\sa\slanguage\swrapper\sthat\sdoes\snot\sexpose\sthat\sinterface. -D 2012-09-07T16:46:59.378 +C Have\sPRAGMA\sbusy_timeout\sreturn\s0\sif\sthe\sbusy\shandler\shas\sbeen\schanged\nor\scancelled. +D 2012-09-07T18:49:57.818 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in abd5c10d21d1395f140d9e50ea999df8fa4d6376 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -145,7 +145,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d -F src/main.c 31af732aa4363e85816b09794429c79fe4baa3ac +F src/main.c 0b321fc873ff2c09b996dea9f74443e4cd9ae28d F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa @@ -170,7 +170,7 @@ F src/parse.y f29df90bd3adc64b33114ab1de9fb7768fcf2099 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h 1b5dcc3dc8103d03e625b177023ee67764fa6b7c F src/pcache1.c 9fd22671c270b35131ef480bbc00392b8b5f8ab9 -F src/pragma.c e09950b9d0a35c1bf2329038c10f38589e754ae8 +F src/pragma.c 360ac85ad9bfbab2302e8b7ba524af842f497cef F src/prepare.c 33291b83cca285718048d219c67b8298501fa3a5 F src/printf.c 4a9f882f1c1787a8b494a2987765acf9d97ac21f F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 @@ -1014,10 +1014,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 39f763bfc04174ee0fe2cdf6a92b7c12f726bd1b -R 7a209eaa28bbe6aeaf699b5d2296eb6d -T *branch * busy-timeout-pragma -T *sym-busy-timeout-pragma * -T -sym-trunk * +P 22ebc668516bc3dd5782d6d3d42dc7fd2eed7d79 +R 123b3377f1885f394458b43e10ba3388 U drh -Z 3457f6820fedfafcfc1fb25157630cb3 +Z ffcbc3d2ba50a5d9635e1edbbde2b179 diff --git a/manifest.uuid b/manifest.uuid index 3068fe9942..c4246a80ba 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -22ebc668516bc3dd5782d6d3d42dc7fd2eed7d79 \ No newline at end of file +7be5bc36798d30f50658b70fc0bd31af897f3a87 \ No newline at end of file diff --git a/src/main.c b/src/main.c index fa565982fa..745122559d 100644 --- a/src/main.c +++ b/src/main.c @@ -1116,6 +1116,7 @@ int sqlite3_busy_handler( db->busyHandler.xFunc = xBusy; db->busyHandler.pArg = pArg; db->busyHandler.nBusy = 0; + db->busyTimeout = 0; sqlite3_mutex_leave(db->mutex); return SQLITE_OK; } @@ -1153,10 +1154,9 @@ void sqlite3_progress_handler( */ int sqlite3_busy_timeout(sqlite3 *db, int ms){ if( ms>0 ){ - db->busyTimeout = ms; sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db); + db->busyTimeout = ms; }else{ - db->busyTimeout = 0; sqlite3_busy_handler(db, 0, 0); } return SQLITE_OK; diff --git a/src/pragma.c b/src/pragma.c index c686265a22..57978c22cc 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1541,9 +1541,9 @@ void sqlite3Pragma( ** PRAGMA busy_timeout = N ** ** Call sqlite3_busy_timeout(db, N). Return the current timeout value - ** if one is set. If the busy handler is not set to the default - ** busy callback, then the return value is undefined. A value of N - ** which is 0 or negative disables the busy handler. + ** if one is set. If no busy handler or a different busy handler is set + ** then 0 is returned. Setting the busy_timeout to 0 or negative + ** disables the timeout. */ if( sqlite3StrICmp(zLeft, "busy_timeout")==0 ){ if( zRight ){ From 50610df8ae1a03d971d732685549443c6a6c26d3 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 7 Sep 2012 20:10:30 +0000 Subject: [PATCH 10/60] Correct two test names to make them unique. FossilOrigin-Name: 43e474d3e9364e6ed417db06e98faa3e5bc2eb26 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/lock.test | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 558095f7ba..4ffa80d78b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Have\sPRAGMA\sbusy_timeout\sreturn\s0\sif\sthe\sbusy\shandler\shas\sbeen\schanged\nor\scancelled. -D 2012-09-07T18:49:57.818 +C Correct\stwo\stest\snames\sto\smake\sthem\sunique. +D 2012-09-07T20:10:30.599 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in abd5c10d21d1395f140d9e50ea999df8fa4d6376 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -571,7 +571,7 @@ F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da F test/limit.test 2db7b3b34fb925b8e847d583d2eb67531d0ce67e F test/loadext.test 2b5e249c51c986a5aff1f0950cf7ba30976c8f22 F test/loadext2.test 0bcaeb4d81cd5b6e883fdfea3c1bdbe1f173cbca -F test/lock.test 7e9eddd991b3af3a01caec2d9f030e0798deef74 +F test/lock.test 87af515b0c4cf928576d0f89946d67d7c265dfb4 F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff F test/lock3.test f271375930711ae044080f4fe6d6eda930870d00 F test/lock4.test e175ae13865bc87680607563bafba21f31a26f12 @@ -1014,7 +1014,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 22ebc668516bc3dd5782d6d3d42dc7fd2eed7d79 -R 123b3377f1885f394458b43e10ba3388 -U drh -Z ffcbc3d2ba50a5d9635e1edbbde2b179 +P 7be5bc36798d30f50658b70fc0bd31af897f3a87 +R 0d92940b96f13ff3dc822c3dd51f8373 +U mistachkin +Z ac2b57c54956518a08fcca693b6facfe diff --git a/manifest.uuid b/manifest.uuid index c4246a80ba..b0647f7277 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7be5bc36798d30f50658b70fc0bd31af897f3a87 \ No newline at end of file +43e474d3e9364e6ed417db06e98faa3e5bc2eb26 \ No newline at end of file diff --git a/test/lock.test b/test/lock.test index e3b1daad88..6ec85eea3c 100644 --- a/test/lock.test +++ b/test/lock.test @@ -271,10 +271,10 @@ do_test lock-2.12 { db2 eval {PRAGMA busy_timeout(0)} execsql COMMIT } {} -do_test lock-2.11b { +do_test lock-2.12b { db2 eval {PRAGMA busy_timeout} } {0} -integrity_check lock-2.12 +integrity_check lock-2.13 # Try to start two transactions in a row # From 60a7523bd3b2f1b95a35641e1dd1435d977125d9 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 10 Sep 2012 06:02:57 +0000 Subject: [PATCH 11/60] Fix typo in documentation for sqlite3_open_v2. No changes to code. FossilOrigin-Name: b532120a4a567a3fa54b87dd8ab94cc2c0347c7c --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index deddb04066..58bb4bc076 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\srepeating\scalls\sto\sthe\ssqlite3_trace()\scallback\swhen\sthe\ssame\sstatement\nis\sevaluted\smultiple\stimes\sby\ssqlite3_step()\sdue\sto\san\sSQLITE_SCHEMA\nreprepare. -D 2012-09-04T21:34:26.807 +C Fix\stypo\sin\sdocumentation\sfor\ssqlite3_open_v2.\s\sNo\schanges\sto\scode. +D 2012-09-10T06:02:57.720 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in abd5c10d21d1395f140d9e50ea999df8fa4d6376 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -178,7 +178,7 @@ F src/resolve.c 9e28280ec98035f31900fdd1db01f86f68ca6c32 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c f843c872a97baa1594c2cc3d4c003409a7bd03af F src/shell.c 87953c5d9c73d9494db97d1607e2e2280418f261 -F src/sqlite.h.in c447d35212736c4c77d86bc2d00f6cf4d4c12131 +F src/sqlite.h.in 39ddd714b62c651bfb5646440c594ca7ff6c7453 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h 053e03a532beb909ead2df0721db67cdb4c48ae8 @@ -1014,7 +1014,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P c0d89d4a9752922f9e367362366efde4f1b06f2a -R f99616c13334ce584a8b1ebfcd476fa4 -U drh -Z 2084e672100937502093a8dd98a48d0f +P 39f763bfc04174ee0fe2cdf6a92b7c12f726bd1b +R db2d221f8ec5049bd5a2f586e1b59db8 +U mistachkin +Z 1863f6017f0a62e08566b39d66980410 diff --git a/manifest.uuid b/manifest.uuid index 28881c5c18..7f89d5e7c4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -39f763bfc04174ee0fe2cdf6a92b7c12f726bd1b \ No newline at end of file +b532120a4a567a3fa54b87dd8ab94cc2c0347c7c \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 9a31e22773..e66dcc72b3 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2595,7 +2595,7 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** an error)^. ** ^If "ro" is specified, then the database is opened for read-only ** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the -** third argument to sqlite3_prepare_v2(). ^If the mode option is set to +** third argument to sqlite3_open_v2(). ^If the mode option is set to ** "rw", then the database is opened for read-write (but not create) ** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had ** been set. ^Value "rwc" is equivalent to setting both From 540ebf82718987d243e169b19c20ccc2588407a8 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 10 Sep 2012 07:29:29 +0000 Subject: [PATCH 12/60] Refine error messages in the sqlite3 Tcl command when a NULL database connection is returned from sqlite3_open_v2. FossilOrigin-Name: f260d7d567a1239c483c437d0b18a95bd0c96724 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/tclsqlite.c | 21 ++++++++++++++++----- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 58bb4bc076..d5ed22538f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypo\sin\sdocumentation\sfor\ssqlite3_open_v2.\s\sNo\schanges\sto\scode. -D 2012-09-10T06:02:57.720 +C Refine\serror\smessages\sin\sthe\ssqlite3\sTcl\scommand\swhen\sa\sNULL\sdatabase\sconnection\sis\sreturned\sfrom\ssqlite3_open_v2. +D 2012-09-10T07:29:29.388 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in abd5c10d21d1395f140d9e50ea999df8fa4d6376 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -185,7 +185,7 @@ F src/sqliteInt.h 053e03a532beb909ead2df0721db67cdb4c48ae8 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e -F src/tclsqlite.c fe5406573e1527957e00dcaf51edd9d8bd31b918 +F src/tclsqlite.c 192dd01625381fb0614bc35f686de5b9d5fbe2bf F src/test1.c 3d70f7c5987f186884cfebbfa7151a7d3d67d86e F src/test2.c 4178056dd1e7d70f954ad8a1e3edb71a2a784daf F src/test3.c 3c3c2407fa6ec7a19e24ae23f7cb439d0275a60d @@ -1014,7 +1014,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 39f763bfc04174ee0fe2cdf6a92b7c12f726bd1b -R db2d221f8ec5049bd5a2f586e1b59db8 +P b532120a4a567a3fa54b87dd8ab94cc2c0347c7c +R 478bc906eac043275283b34d14cafa90 U mistachkin -Z 1863f6017f0a62e08566b39d66980410 +Z 925d5e6a92a3b6e3fa634cf86d33ca4c diff --git a/manifest.uuid b/manifest.uuid index 7f89d5e7c4..97729d657f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b532120a4a567a3fa54b87dd8ab94cc2c0347c7c \ No newline at end of file +f260d7d567a1239c483c437d0b18a95bd0c96724 \ No newline at end of file diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 51f8c517df..bb930f0c75 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -41,6 +41,12 @@ #endif #include +/* +** This function is used to translate a return code into an error +** message. +*/ +const char *sqlite3ErrStr(int rc); + /* * Windows needs to know which symbols to export. Unix does not. * BUILD_sqlite should be undefined for Unix. @@ -2929,6 +2935,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ void *pKey = 0; int nKey = 0; #endif + int rc; /* In normal use, each TCL interpreter runs in a single thread. So ** by default, we can turn of mutexing on SQLite database connections. @@ -3033,12 +3040,16 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ memset(p, 0, sizeof(*p)); zFile = Tcl_GetStringFromObj(objv[2], 0); zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename); - sqlite3_open_v2(zFile, &p->db, flags, zVfs); + rc = sqlite3_open_v2(zFile, &p->db, flags, zVfs); Tcl_DStringFree(&translatedFilename); - if( SQLITE_OK!=sqlite3_errcode(p->db) ){ - zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db)); - sqlite3_close(p->db); - p->db = 0; + if( p->db ){ + if( SQLITE_OK!=sqlite3_errcode(p->db) ){ + zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db)); + sqlite3_close(p->db); + p->db = 0; + } + }else{ + zErrMsg = sqlite3_mprintf("%s", sqlite3ErrStr(rc)); } #ifdef SQLITE_HAS_CODEC if( p->db ){ From 8765b4660e77375a5c61c746e84c84c22c2eaf7f Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 10 Sep 2012 08:48:05 +0000 Subject: [PATCH 13/60] Make header comments for some Tcl test commands more consistent. No changes to code. FossilOrigin-Name: af870ca9827d2079a35dbb545660f670c7ca9512 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/test_malloc.c | 18 +++++++----------- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index d5ed22538f..101345d6e5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Refine\serror\smessages\sin\sthe\ssqlite3\sTcl\scommand\swhen\sa\sNULL\sdatabase\sconnection\sis\sreturned\sfrom\ssqlite3_open_v2. -D 2012-09-10T07:29:29.388 +C Make\sheader\scomments\sfor\ssome\sTcl\stest\scommands\smore\sconsistent.\s\sNo\schanges\sto\scode. +D 2012-09-10T08:48:05.199 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in abd5c10d21d1395f140d9e50ea999df8fa4d6376 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -210,7 +210,7 @@ F src/test_intarray.c d879bbf8e4ce085ab966d1f3c896a7c8b4f5fc99 F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c f5c0a05b7b3d5930db769b5ee6c3766dc2221a64 F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e -F src/test_malloc.c 3f5903a1528fd32fe4c472a3bd0259128d8faaef +F src/test_malloc.c 7c8e2511d9d9661c2fcf91960ce0fb801bae8d0a F src/test_multiplex.c ac0fbc1748e5b86a41a1d7a84654fae0d53a881d F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e @@ -1014,7 +1014,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P b532120a4a567a3fa54b87dd8ab94cc2c0347c7c -R 478bc906eac043275283b34d14cafa90 +P f260d7d567a1239c483c437d0b18a95bd0c96724 +R 36da01c96777fdf02072bd5dbf03de91 U mistachkin -Z 925d5e6a92a3b6e3fa634cf86d33ca4c +Z d0e3237f44c1c6720ed7722cbf05a54d diff --git a/manifest.uuid b/manifest.uuid index 97729d657f..0e425a9598 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f260d7d567a1239c483c437d0b18a95bd0c96724 \ No newline at end of file +af870ca9827d2079a35dbb545660f670c7ca9512 \ No newline at end of file diff --git a/src/test_malloc.c b/src/test_malloc.c index 09b8f738e8..f52894d9e5 100644 --- a/src/test_malloc.c +++ b/src/test_malloc.c @@ -1094,9 +1094,7 @@ static int test_db_config_lookaside( } /* -** Usage: -** -** sqlite3_config_heap NBYTE NMINALLOC +** Usage: sqlite3_config_heap NBYTE NMINALLOC */ static int test_config_heap( void * clientData, @@ -1133,7 +1131,7 @@ static int test_config_heap( } /* -** tclcmd: sqlite3_config_error [DB] +** Usage: sqlite3_config_error [DB] ** ** Invoke sqlite3_config() or sqlite3_db_config() with invalid ** opcodes and verify that they return errors. @@ -1171,10 +1169,10 @@ static int test_config_error( } /* -** tclcmd: sqlite3_config_uri BOOLEAN +** Usage: sqlite3_config_uri BOOLEAN ** -** Invoke sqlite3_config() or sqlite3_db_config() with invalid -** opcodes and verify that they return errors. +** Enables or disables interpretation of URI parameters by default using +** SQLITE_CONFIG_URI. */ static int test_config_uri( void * clientData, @@ -1200,10 +1198,8 @@ static int test_config_uri( } /* -** Usage: -** -** sqlite3_dump_memsys3 FILENAME -** sqlite3_dump_memsys5 FILENAME +** Usage: sqlite3_dump_memsys3 FILENAME +** sqlite3_dump_memsys5 FILENAME ** ** Write a summary of unfreed memsys3 allocations to FILENAME. */ From 9dc2a7366229218173c64b47341b7f6ce437c939 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 10 Sep 2012 09:33:09 +0000 Subject: [PATCH 14/60] Avoid using the sqlite3ErrStr function in the Tcl package if USE_SYSTEM_SQLITE is defined. FossilOrigin-Name: a716b9a3091072774d067c0a1258b0f4c39a4180 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/tclsqlite.c | 6 ++++++ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 101345d6e5..cf4d0a240c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sheader\scomments\sfor\ssome\sTcl\stest\scommands\smore\sconsistent.\s\sNo\schanges\sto\scode. -D 2012-09-10T08:48:05.199 +C Avoid\susing\sthe\ssqlite3ErrStr\sfunction\sin\sthe\sTcl\spackage\sif\sUSE_SYSTEM_SQLITE\sis\sdefined. +D 2012-09-10T09:33:09.064 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in abd5c10d21d1395f140d9e50ea999df8fa4d6376 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -185,7 +185,7 @@ F src/sqliteInt.h 053e03a532beb909ead2df0721db67cdb4c48ae8 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e -F src/tclsqlite.c 192dd01625381fb0614bc35f686de5b9d5fbe2bf +F src/tclsqlite.c f6bc566b5a52128759d6eb954b53930a6353ed58 F src/test1.c 3d70f7c5987f186884cfebbfa7151a7d3d67d86e F src/test2.c 4178056dd1e7d70f954ad8a1e3edb71a2a784daf F src/test3.c 3c3c2407fa6ec7a19e24ae23f7cb439d0275a60d @@ -1014,7 +1014,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P f260d7d567a1239c483c437d0b18a95bd0c96724 -R 36da01c96777fdf02072bd5dbf03de91 +P af870ca9827d2079a35dbb545660f670c7ca9512 +R 41116711b74a4531ffcdbedf61877a05 U mistachkin -Z d0e3237f44c1c6720ed7722cbf05a54d +Z 81d27ccc240f2f1ae0e0280e87c1196f diff --git a/manifest.uuid b/manifest.uuid index 0e425a9598..d65f797478 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -af870ca9827d2079a35dbb545660f670c7ca9512 \ No newline at end of file +a716b9a3091072774d067c0a1258b0f4c39a4180 \ No newline at end of file diff --git a/src/tclsqlite.c b/src/tclsqlite.c index bb930f0c75..abec51e67a 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -45,7 +45,9 @@ ** This function is used to translate a return code into an error ** message. */ +#ifndef USE_SYSTEM_SQLITE const char *sqlite3ErrStr(int rc); +#endif /* * Windows needs to know which symbols to export. Unix does not. @@ -3042,15 +3044,19 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename); rc = sqlite3_open_v2(zFile, &p->db, flags, zVfs); Tcl_DStringFree(&translatedFilename); +#ifndef USE_SYSTEM_SQLITE if( p->db ){ +#endif if( SQLITE_OK!=sqlite3_errcode(p->db) ){ zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db)); sqlite3_close(p->db); p->db = 0; } +#ifndef USE_SYSTEM_SQLITE }else{ zErrMsg = sqlite3_mprintf("%s", sqlite3ErrStr(rc)); } +#endif #ifdef SQLITE_HAS_CODEC if( p->db ){ sqlite3_key(p->db, pKey, nKey); From 0fdbdbea038527a9c739ff0c785a61e4fea4e738 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Sep 2012 15:02:32 +0000 Subject: [PATCH 15/60] Remove the stale implementation of the ifnull and coalesce functions - code that has been commented out for ages. No functional changes. FossilOrigin-Name: c2ad691174b8af2e8b158d8840cfc93f75d7db71 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/func.c | 31 ++++++------------------------- 3 files changed, 14 insertions(+), 33 deletions(-) diff --git a/manifest b/manifest index cf4d0a240c..5ef943677b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\susing\sthe\ssqlite3ErrStr\sfunction\sin\sthe\sTcl\spackage\sif\sUSE_SYSTEM_SQLITE\sis\sdefined. -D 2012-09-10T09:33:09.064 +C Remove\sthe\sstale\simplementation\sof\sthe\sifnull\sand\scoalesce\sfunctions\s-\scode\nthat\shas\sbeen\scommented\sout\sfor\sages.\s\sNo\sfunctional\schanges. +D 2012-09-10T15:02:32.827 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in abd5c10d21d1395f140d9e50ea999df8fa4d6376 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -135,7 +135,7 @@ F src/delete.c 335f36750dc6ac88d580aa36a6487459be9889de F src/expr.c 217840a107dcc1e5dbb57cea311daad04bedbb9a F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 9c77d842dc9961d92a06a65abb80c64ef1750296 -F src/func.c 18dfedfb857e100b05755a1b12e88b389f957879 +F src/func.c b4e88b92838fdab8e0088cc8411c06664b4dcf55 F src/global.c 4cfdca5cb0edd33c4d021baec4ede958cb2c793b F src/hash.c a4031441741932da9e7a65bee2b36b5d0e81c073 F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 @@ -1014,7 +1014,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P af870ca9827d2079a35dbb545660f670c7ca9512 -R 41116711b74a4531ffcdbedf61877a05 -U mistachkin -Z 81d27ccc240f2f1ae0e0280e87c1196f +P a716b9a3091072774d067c0a1258b0f4c39a4180 +R e24ef4a70ae15b9fa5b9d09102845b46 +U drh +Z fa9683e591df1b702d6598781636d3de diff --git a/manifest.uuid b/manifest.uuid index d65f797478..0fb54be896 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a716b9a3091072774d067c0a1258b0f4c39a4180 \ No newline at end of file +c2ad691174b8af2e8b158d8840cfc93f75d7db71 \ No newline at end of file diff --git a/src/func.c b/src/func.c index e56561e4ec..9d81d0c741 100644 --- a/src/func.c +++ b/src/func.c @@ -367,33 +367,14 @@ static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ } } - -#if 0 /* This function is never used. */ /* -** The COALESCE() and IFNULL() functions used to be implemented as shown -** here. But now they are implemented as VDBE code so that unused arguments -** do not have to be computed. This legacy implementation is retained as -** comment. +** The COALESCE() and IFNULL() functions are implemented as VDBE code so +** that unused argument values do not have to be computed. However, we +** still need some kind of function implementation for this routines in +** the function table. That function implementation will never be called +** so it doesn't matter what the implementation is. We might as well use +** the "version()" function as a substitute. */ -/* -** Implementation of the IFNULL(), NVL(), and COALESCE() functions. -** All three do the same thing. They return the first non-NULL -** argument. -*/ -static void ifnullFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - int i; - for(i=0; i Date: Mon, 10 Sep 2012 23:44:12 +0000 Subject: [PATCH 16/60] Correct two duplicated test names. FossilOrigin-Name: ced49974a969f11e5ebe2280bd7eec20b059e501 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/tclsqlite.test | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 5ef943677b..42bc0d99d9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\sstale\simplementation\sof\sthe\sifnull\sand\scoalesce\sfunctions\s-\scode\nthat\shas\sbeen\scommented\sout\sfor\sages.\s\sNo\sfunctional\schanges. -D 2012-09-10T15:02:32.827 +C Correct\stwo\sduplicated\stest\snames. +D 2012-09-10T23:44:12.573 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in abd5c10d21d1395f140d9e50ea999df8fa4d6376 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -734,7 +734,7 @@ F test/syscall.test bea9bf329bff733c791310244617c2a76974e64a F test/sysfault.test c79441d88d23696fbec7b147dba98d42a04f523f F test/table.test a59d985ca366e39b17b175f387f9d5db5a18d4e2 F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 -F test/tclsqlite.test 1597d353308531527583481d14d9da52ea8ed0af +F test/tclsqlite.test a3d2df21ee98957f5de4f9dc1db0eab68047ab5d F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c F test/temptable.test 51edd31c65ed1560dd600b1796e8325df96318e2 F test/temptrigger.test 26670ed7a39cf2296a7f0a9e0a1d7bdb7abe936d @@ -1014,7 +1014,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P a716b9a3091072774d067c0a1258b0f4c39a4180 -R e24ef4a70ae15b9fa5b9d09102845b46 -U drh -Z fa9683e591df1b702d6598781636d3de +P c2ad691174b8af2e8b158d8840cfc93f75d7db71 +R 01a5d1c903c9a5a720ae8b76fe55d59d +U mistachkin +Z 8f15859569cbba9d92e0949a6ba62979 diff --git a/manifest.uuid b/manifest.uuid index 0fb54be896..0542b3d17d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c2ad691174b8af2e8b158d8840cfc93f75d7db71 \ No newline at end of file +ced49974a969f11e5ebe2280bd7eec20b059e501 \ No newline at end of file diff --git a/test/tclsqlite.test b/test/tclsqlite.test index c8b0303296..5761e1604c 100644 --- a/test/tclsqlite.test +++ b/test/tclsqlite.test @@ -143,11 +143,11 @@ do_test tcl-1.21 { set v [catch {db total_changes xyz} msg] lappend v $msg } {1 {wrong # args: should be "db total_changes "}} -do_test tcl-1.20 { +do_test tcl-1.22 { set v [catch {db copy} msg] lappend v $msg } {1 {wrong # args: should be "db copy CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?"}} -do_test tcl-1.21 { +do_test tcl-1.23 { set v [catch {sqlite3 db2 test.db -vfs nosuchvfs} msg] lappend v $msg } {1 {no such vfs: nosuchvfs}} From 5dac84323351d847aa818d87a345309bc3e84b68 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 11 Sep 2012 02:00:25 +0000 Subject: [PATCH 17/60] Added sqlite3_errstr API to translate a result code to the corresponding error message. FossilOrigin-Name: bf8a9ca5b58404112a8af666f5840b462b7bbfe1 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/main.c | 9 +++++++++ src/sqlite.h.in | 6 ++++++ src/tclsqlite.c | 16 ++-------------- 5 files changed, 26 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index 42bc0d99d9..a88fd0f6b9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Correct\stwo\sduplicated\stest\snames. -D 2012-09-10T23:44:12.573 +C Added\ssqlite3_errstr\sAPI\sto\stranslate\sa\sresult\scode\sto\sthe\scorresponding\serror\smessage. +D 2012-09-11T02:00:25.116 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in abd5c10d21d1395f140d9e50ea999df8fa4d6376 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -145,7 +145,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d -F src/main.c 02255cf1da50956c5427c469abddb15bccc4ba09 +F src/main.c 259472ec0c694fe6a4fb6e8781be7fd8feacb09c F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa @@ -178,14 +178,14 @@ F src/resolve.c 9e28280ec98035f31900fdd1db01f86f68ca6c32 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c f843c872a97baa1594c2cc3d4c003409a7bd03af F src/shell.c 87953c5d9c73d9494db97d1607e2e2280418f261 -F src/sqlite.h.in 39ddd714b62c651bfb5646440c594ca7ff6c7453 +F src/sqlite.h.in 193c0496be6046604d1b8aa518012d3cf411f57f F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h 053e03a532beb909ead2df0721db67cdb4c48ae8 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e -F src/tclsqlite.c f6bc566b5a52128759d6eb954b53930a6353ed58 +F src/tclsqlite.c e4de2458b3ef38fdd0498bc4e5ea5367a241b0f3 F src/test1.c 3d70f7c5987f186884cfebbfa7151a7d3d67d86e F src/test2.c 4178056dd1e7d70f954ad8a1e3edb71a2a784daf F src/test3.c 3c3c2407fa6ec7a19e24ae23f7cb439d0275a60d @@ -1014,7 +1014,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P c2ad691174b8af2e8b158d8840cfc93f75d7db71 -R 01a5d1c903c9a5a720ae8b76fe55d59d +P ced49974a969f11e5ebe2280bd7eec20b059e501 +R 96b0793061802196b5e5b329338c3e20 U mistachkin -Z 8f15859569cbba9d92e0949a6ba62979 +Z 09221de0840bfda8cdeb1fd3b6a60ff7 diff --git a/manifest.uuid b/manifest.uuid index 0542b3d17d..6f8cf23f11 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ced49974a969f11e5ebe2280bd7eec20b059e501 \ No newline at end of file +bf8a9ca5b58404112a8af666f5840b462b7bbfe1 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 16294a6199..cc19f78a81 100644 --- a/src/main.c +++ b/src/main.c @@ -1767,6 +1767,15 @@ int sqlite3_extended_errcode(sqlite3 *db){ return db->errCode; } +/* +** Return a string that describes the kind of error specified in the +** argument. For now, this simply calls the internal sqlite3ErrStr() +** function. +*/ +const char *sqlite3_errstr(int rc){ + return sqlite3ErrStr(rc); +} + /* ** Create a new collating function for database "db". The name is zName ** and the encoding is enc. diff --git a/src/sqlite.h.in b/src/sqlite.h.in index e66dcc72b3..3729ae6dcb 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2747,6 +2747,11 @@ sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64); ** However, the error string might be overwritten or deallocated by ** subsequent calls to other SQLite interface functions.)^ ** +** ^The sqlite3_errstr() interface returns the English-language text +** that describes the [result code], as UTF-8. +** ^(Memory to hold the error message string is managed internally +** and must not be freed by the application)^. +** ** When the serialized [threading mode] is in use, it might be the ** case that a second error occurs on a separate thread in between ** the time of the first error and the call to these interfaces. @@ -2765,6 +2770,7 @@ int sqlite3_errcode(sqlite3 *db); int sqlite3_extended_errcode(sqlite3 *db); const char *sqlite3_errmsg(sqlite3*); const void *sqlite3_errmsg16(sqlite3*); +const char *sqlite3_errstr(int); /* ** CAPI3REF: SQL Statement Object diff --git a/src/tclsqlite.c b/src/tclsqlite.c index abec51e67a..0a586e489f 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -41,14 +41,6 @@ #endif #include -/* -** This function is used to translate a return code into an error -** message. -*/ -#ifndef USE_SYSTEM_SQLITE -const char *sqlite3ErrStr(int rc); -#endif - /* * Windows needs to know which symbols to export. Unix does not. * BUILD_sqlite should be undefined for Unix. @@ -2566,7 +2558,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey); rc = sqlite3_rekey(pDb->db, pKey, nKey); if( rc ){ - Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0); + Tcl_AppendResult(interp, sqlite3_errstr(rc), 0); rc = TCL_ERROR; } #endif @@ -3044,19 +3036,15 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename); rc = sqlite3_open_v2(zFile, &p->db, flags, zVfs); Tcl_DStringFree(&translatedFilename); -#ifndef USE_SYSTEM_SQLITE if( p->db ){ -#endif if( SQLITE_OK!=sqlite3_errcode(p->db) ){ zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db)); sqlite3_close(p->db); p->db = 0; } -#ifndef USE_SYSTEM_SQLITE }else{ - zErrMsg = sqlite3_mprintf("%s", sqlite3ErrStr(rc)); + zErrMsg = sqlite3_mprintf("%s", sqlite3_errstr(rc)); } -#endif #ifdef SQLITE_HAS_CODEC if( p->db ){ sqlite3_key(p->db, pKey, nKey); From 8cca95d7aa07fb55bed3ae8697e9747a4e060bba Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 12 Sep 2012 00:11:20 +0000 Subject: [PATCH 18/60] Update version number to 3.7.15. Delete some obsolete build scripts. FossilOrigin-Name: 9402f81fade5fcae0a3a6efdc7a5cdf71fc2e79f --- VERSION | 2 +- configure | 18 +++---- manifest | 18 +++---- manifest.uuid | 2 +- publish.sh | 138 ------------------------------------------------- publish_osx.sh | 35 ------------- 6 files changed, 19 insertions(+), 194 deletions(-) delete mode 100644 publish.sh delete mode 100644 publish_osx.sh diff --git a/VERSION b/VERSION index 35c6ac5179..03d7b8fb9b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.7.14 +3.7.15 diff --git a/configure b/configure index af10fe3bd1..0986b63667 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.7.14. +# Generated by GNU Autoconf 2.62 for sqlite 3.7.15. # # 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.7.14' -PACKAGE_STRING='sqlite 3.7.14' +PACKAGE_VERSION='3.7.15' +PACKAGE_STRING='sqlite 3.7.15' PACKAGE_BUGREPORT='' # Factoring default headers for most tests. @@ -1485,7 +1485,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.7.14 to adapt to many kinds of systems. +\`configure' configures sqlite 3.7.15 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1550,7 +1550,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of sqlite 3.7.14:";; + short | recursive ) echo "Configuration of sqlite 3.7.15:";; esac cat <<\_ACEOF @@ -1666,7 +1666,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sqlite configure 3.7.14 +sqlite configure 3.7.15 generated by GNU Autoconf 2.62 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -1680,7 +1680,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.7.14, which was +It was created by sqlite $as_me 3.7.15, which was generated by GNU Autoconf 2.62. Invocation command line was $ $0 $@ @@ -14034,7 +14034,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.7.14, which was +This file was extended by sqlite $as_me 3.7.15, which was generated by GNU Autoconf 2.62. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -14087,7 +14087,7 @@ Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_version="\\ -sqlite config.status 3.7.14 +sqlite config.status 3.7.15 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 a88fd0f6b9..d2a266f241 100644 --- a/manifest +++ b/manifest @@ -1,12 +1,12 @@ -C Added\ssqlite3_errstr\sAPI\sto\stranslate\sa\sresult\scode\sto\sthe\scorresponding\serror\smessage. -D 2012-09-11T02:00:25.116 +C Update\sversion\snumber\sto\s3.7.15.\s\sDelete\ssome\sobsolete\sbuild\sscripts. +D 2012-09-12T00:11:20.574 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in abd5c10d21d1395f140d9e50ea999df8fa4d6376 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.msc 2d696f01c228995e98b3b953a08b7bba1d48c130 F Makefile.vxworks 879f034a64062a364b21000266bbd5bc6e0c19b9 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 -F VERSION a71848df48082f1d6585d4b0819d530fc455485d +F VERSION edab4af5a4623f8198833ea481ce98ab53750a8d F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F addopcodes.awk 17dc593f791f874d2c23a0f9360850ded0286531 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 @@ -15,7 +15,7 @@ F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 F config.h.in 0921066a13130082764ab4ab6456f7b5bebe56de F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 -F configure e2d0e3b67d2b1b1049d389fd671275d79bb80457 x +F configure 4907207e1627a394e8892cce8dcc8068fbe5f7cd x F configure.ac 6e909664785b8184db2179013cd9d574f96ca3a3 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1 @@ -110,8 +110,6 @@ F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac F mkopcodec.awk f6fccee29e68493bfd90a2e0466ede5fa94dd2fc F mkopcodeh.awk 29b84656502eee5f444c3147f331ee686956ab0e F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 -F publish.sh 313c5b2425f2cf5e547db7549a9796acc4508f22 -F publish_osx.sh 2ad2ee7d50632dff99949edc9c162dbb052f7534 F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc @@ -1014,7 +1012,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P ced49974a969f11e5ebe2280bd7eec20b059e501 -R 96b0793061802196b5e5b329338c3e20 -U mistachkin -Z 09221de0840bfda8cdeb1fd3b6a60ff7 +P bf8a9ca5b58404112a8af666f5840b462b7bbfe1 +R 847379dec46339e4d4e3d3e07e9871f0 +U drh +Z a42f3ee2165757bae1503891985c3bca diff --git a/manifest.uuid b/manifest.uuid index 6f8cf23f11..9a08d83f21 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bf8a9ca5b58404112a8af666f5840b462b7bbfe1 \ No newline at end of file +9402f81fade5fcae0a3a6efdc7a5cdf71fc2e79f \ No newline at end of file diff --git a/publish.sh b/publish.sh deleted file mode 100644 index 6c4dea1efe..0000000000 --- a/publish.sh +++ /dev/null @@ -1,138 +0,0 @@ -#!/bin/sh -# -# This script is used to compile SQLite and package everything up -# so that it is ready to move to the SQLite website. -# - -# Set srcdir to the name of the directory that contains the publish.sh -# script. -# -srcdir=`echo "$0" | sed 's%\(^.*\)/[^/][^/]*$%\1%'` - -# Get the makefile. -# -cp $srcdir/Makefile.linux-gcc ./Makefile -chmod +x $srcdir/install-sh - -# Get the current version number - needed to help build filenames -# -VERS=`cat $srcdir/VERSION` -VERSW=`sed 's/\./_/g' $srcdir/VERSION` -echo "VERSIONS: $VERS $VERSW" - -# Start by building an sqlite shell for linux. -# -make clean -make sqlite3.c -CFLAGS="-Os -DSQLITE_ENABLE_FTS3=0 -DSQLITE_ENABLE_RTREE=0" -CFLAGS="$CFLAGS -DSQLITE_THREADSAFE=0" -echo '***** '"COMPILING sqlite3-$VERS.bin..." -gcc $CFLAGS -Itsrc sqlite3.c tsrc/shell.c -o sqlite3 -ldl -strip sqlite3 -mv sqlite3 sqlite3-$VERS.bin -gzip sqlite3-$VERS.bin -chmod 644 sqlite3-$VERS.bin.gz -mv sqlite3-$VERS.bin.gz doc - -# Build the sqlite.so and tclsqlite.so shared libraries -# under Linux -# -TCLDIR=/home/drh/tcltk/846/linux/846linux -TCLSTUBLIB=$TCLDIR/libtclstub8.4g.a -CFLAGS="-Os -DSQLITE_ENABLE_FTS3=3 -DSQLITE_ENABLE_RTREE=1" -CFLAGS="$CFLAGS -DHAVE_LOCALTIME_R=1 -DHAVE_GMTIME_R=1" -CFLAGS="$CFLAGS -DSQLITE_ENABLE_COLUMN_METADATA=1" -echo '***** BUILDING shared libraries for linux' -gcc $CFLAGS -shared tclsqlite3.c $TCLSTUBLIB -o tclsqlite3.so -lpthread -strip tclsqlite3.so -chmod 644 tclsqlite3.so -mv tclsqlite3.so tclsqlite-$VERS.so -gzip tclsqlite-$VERS.so -mv tclsqlite-$VERS.so.gz doc -gcc $CFLAGS -shared sqlite3.c -o sqlite3.so -lpthread -strip sqlite3.so -chmod 644 sqlite3.so -mv sqlite3.so sqlite-$VERS.so -gzip sqlite-$VERS.so -mv sqlite-$VERS.so.gz doc - - -# Build the tclsqlite3.dll and sqlite3.dll shared libraries. -# -. $srcdir/mkdll.sh -echo '***** PACKAGING shared libraries for windows' -echo zip doc/tclsqlite-$VERSW.zip tclsqlite3.dll -zip doc/tclsqlite-$VERSW.zip tclsqlite3.dll -echo zip doc/sqlitedll-$VERSW.zip sqlite3.dll sqlite3.def -zip doc/sqlitedll-$VERSW.zip sqlite3.dll sqlite3.def - -# Build the sqlite.exe executable for windows. -# -OPTS='-DSTATIC_BUILD=1 -DNDEBUG=1 -DSQLITE_THREADSAFE=0' -OPTS="$OPTS -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_RTREE=1" -i386-mingw32msvc-gcc -Os $OPTS -Itsrc -I$TCLDIR sqlite3.c tsrc/shell.c \ - -o sqlite3.exe -zip doc/sqlite-$VERSW.zip sqlite3.exe - -# Build a source archive useful for windows. -# -make target_source -cd tsrc -echo '***** BUILDING preprocessed source archives' -rm fts[12]* icu* -rm -f ../doc/sqlite-source-$VERSW.zip -zip ../doc/sqlite-source-$VERSW.zip * -cd .. -cp tsrc/sqlite3.h tsrc/sqlite3ext.h . -cp tsrc/shell.c . -pwd -zip doc/sqlite-amalgamation-$VERSW.zip sqlite3.c sqlite3.h sqlite3ext.h shell.c sqlite3.def - -# Construct a tarball of the source tree -# -echo '***** BUILDING source archive' -ORIGIN=`pwd` -cd $srcdir -chmod +x configure -cd .. -mv sqlite sqlite-$VERS -EXCLUDE=`find sqlite-$VERS -print | egrep '(www/|art/|doc/|contrib/|_FOSSIL_)' | sed 's,^, --exclude ,'` -echo "tar czf $ORIGIN/doc/sqlite-$VERS.tar.gz $EXCLUDE sqlite-$VERS" -tar czf $ORIGIN/doc/sqlite-$VERS.tar.gz $EXCLUDE sqlite-$VERS -mv sqlite-$VERS sqlite -cd $ORIGIN - -# -# Build RPMS (binary) and Source RPM -# - -# Make sure we are properly setup to build RPMs -# -echo "%HOME %{expand:%%(cd; pwd)}" > $HOME/.rpmmacros -echo "%_topdir %{HOME}/rpm" >> $HOME/.rpmmacros -mkdir $HOME/rpm -mkdir $HOME/rpm/BUILD -mkdir $HOME/rpm/SOURCES -mkdir $HOME/rpm/RPMS -mkdir $HOME/rpm/SRPMS -mkdir $HOME/rpm/SPECS - -# create the spec file from the template -sed s/SQLITE_VERSION/$VERS/g $srcdir/spec.template > $HOME/rpm/SPECS/sqlite.spec - -# copy the source tarball to the rpm directory -cp doc/sqlite-$VERS.tar.gz $HOME/rpm/SOURCES/. - -# build all the rpms -rpm -ba $HOME/rpm/SPECS/sqlite.spec >& rpm-$vers.log - -# copy the RPMs into the build directory. -mv $HOME/rpm/RPMS/i386/sqlite*-$vers*.rpm doc -mv $HOME/rpm/SRPMS/sqlite-$vers*.rpm doc - -# Build the website -# -#cp $srcdir/../historical/* doc -#make doc -#cd doc -#chmod 644 *.gz diff --git a/publish_osx.sh b/publish_osx.sh deleted file mode 100644 index 508b623942..0000000000 --- a/publish_osx.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/sh -# -# This script is used to compile SQLite and package everything up -# so that it is ready to move to the SQLite website. -# - -# Set srcdir to the name of the directory that contains the publish.sh -# script. -# -srcdir=`echo "$0" | sed 's%\(^.*\)/[^/][^/]*$%\1%'` - -# Get the makefile. -# -cp $srcdir/Makefile.linux-gcc ./Makefile -chmod +x $srcdir/install-sh - -# Get the current version number - needed to help build filenames -# -VERS=`cat $srcdir/VERSION` -VERSW=`sed 's/\./_/g' $srcdir/VERSION` -echo "VERSIONS: $VERS $VERSW" - -# Start by building an sqlite shell for linux. -# -make clean -make sqlite3.c -CFLAGS="-Os -DSQLITE_ENABLE_FTS3=1 -DSQLITE_THREADSAFE=0" -NAME=sqlite3-$VERS-osx-x86.bin -echo '***** '"COMPILING $NAME..." -gcc $CFLAGS -Itsrc sqlite3.c tsrc/shell.c -o $NAME -ldl -strip $NAME -chmod 644 $NAME -gzip $NAME -mkdir -p doc -mv $NAME.gz doc From c60941f8147895ec222fd2ba97bd71aebd89bd23 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 13 Sep 2012 01:51:02 +0000 Subject: [PATCH 19/60] Allow SQLite to work on Win32 with SQLITE_OS_WINNT=0 as long as WAL is disabled. FossilOrigin-Name: c1a8557008e56aa9bcb4565e4178fc57295c563d --- Makefile.in | 3 + Makefile.msc | 3 + Makefile.vxworks | 3 + main.mk | 3 + manifest | 39 ++++----- manifest.uuid | 2 +- src/os_win.c | 169 ++++++++++++++++++++++----------------- test/backcompat.test | 1 + test/dbstatus2.test | 10 ++- test/full.test | 20 +++++ test/permutations.test | 2 +- test/tester.tcl | 12 ++- test/tkt-5d863f876e.test | 2 + test/tkt-80ba201079.test | 2 +- test/wal8.test | 1 + test/zerodamage.test | 54 +++++++------ 16 files changed, 201 insertions(+), 125 deletions(-) create mode 100644 test/full.test diff --git a/Makefile.in b/Makefile.in index db7f88eebf..f374aa451c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -889,6 +889,9 @@ fulltest: testfixture$(TEXE) sqlite3$(TEXE) soaktest: testfixture$(TEXE) sqlite3$(TEXE) ./testfixture$(TEXE) $(TOP)/test/all.test -soak=1 +fulltestonly: testfixture$(TEXE) sqlite3$(TEXE) + ./testfixture$(TEXE) $(TOP)/test/full.test + test: testfixture$(TEXE) sqlite3$(TEXE) ./testfixture$(TEXE) $(TOP)/test/veryquick.test diff --git a/Makefile.msc b/Makefile.msc index 2b79c2b9b7..5cad8931d9 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1169,6 +1169,9 @@ fulltest: testfixture.exe sqlite3.exe soaktest: testfixture.exe sqlite3.exe .\testfixture.exe $(TOP)\test\all.test -soak=1 +fulltestonly: testfixture.exe sqlite3.exe + .\testfixture.exe $(TOP)\test\full.test + test: testfixture.exe sqlite3.exe .\testfixture.exe $(TOP)\test\veryquick.test diff --git a/Makefile.vxworks b/Makefile.vxworks index 25bc853943..d04028833c 100644 --- a/Makefile.vxworks +++ b/Makefile.vxworks @@ -625,6 +625,9 @@ fulltest: testfixture$(EXE) sqlite3$(EXE) soaktest: testfixture$(EXE) sqlite3$(EXE) ./testfixture$(EXE) $(TOP)/test/all.test -soak=1 +fulltestonly: testfixture$(EXE) sqlite3$(EXE) + ./testfixture$(EXE) $(TOP)/test/full.test + test: testfixture$(EXE) sqlite3$(EXE) ./testfixture$(EXE) $(TOP)/test/veryquick.test diff --git a/main.mk b/main.mk index 408e609b8e..7acae2fe7f 100644 --- a/main.mk +++ b/main.mk @@ -565,6 +565,9 @@ fulltest: testfixture$(EXE) sqlite3$(EXE) soaktest: testfixture$(EXE) sqlite3$(EXE) ./testfixture$(EXE) $(TOP)/test/all.test -soak=1 +fulltestonly: testfixture$(EXE) sqlite3$(EXE) + ./testfixture$(EXE) $(TOP)/test/full.test + test: testfixture$(EXE) sqlite3$(EXE) ./testfixture$(EXE) $(TOP)/test/veryquick.test diff --git a/manifest b/manifest index d2a266f241..1694f55d16 100644 --- a/manifest +++ b/manifest @@ -1,10 +1,10 @@ -C Update\sversion\snumber\sto\s3.7.15.\s\sDelete\ssome\sobsolete\sbuild\sscripts. -D 2012-09-12T00:11:20.574 +C Allow\sSQLite\sto\swork\son\sWin32\swith\sSQLITE_OS_WINNT=0\sas\slong\sas\sWAL\sis\sdisabled. +D 2012-09-13T01:51:02.094 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f -F Makefile.in abd5c10d21d1395f140d9e50ea999df8fa4d6376 +F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 -F Makefile.msc 2d696f01c228995e98b3b953a08b7bba1d48c130 -F Makefile.vxworks 879f034a64062a364b21000266bbd5bc6e0c19b9 +F Makefile.msc d97ae1025a1b7bb2b365b135fc0aa25247e736b2 +F Makefile.vxworks b18ad88e9a8c6a001f5cf4a389116a4f1a7ab45f F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 F VERSION edab4af5a4623f8198833ea481ce98ab53750a8d F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -103,7 +103,7 @@ F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 -F main.mk 72026405046ed5b1f0368943b89c0aa29ad558b6 +F main.mk 7b60c2663388270258f01b59fbf8b9bd78f946bf F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac @@ -161,7 +161,7 @@ F src/os.c e1acdc09ff3ac2412945cca9766e2dcf4675f31c F src/os.h 027491c77d2404c0a678bb3fb06286f331eb9b57 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c 69b2fe66316524eebf5f1ce85c1fdfe2952307e9 -F src/os_win.c 5dec8fe85ee547152075c020db72aec4382f0d0a +F src/os_win.c d5f19e444b85f18b06f42958f20b5fedec1b9fc4 F src/pager.c 5665fa9ecec51f11dabdfd8eefefa89391856007 F src/pager.h 8b8c9bc065a3c66769df8724dfdf492ee1aab3c5 F src/parse.y f29df90bd3adc64b33114ab1de9fb7768fcf2099 @@ -286,7 +286,7 @@ F test/autoindex1.test 058d0b331ae6840a61bbee910d8cbae27bfd5991 F test/autovacuum.test fcaf4616ae5bb18098db1cb36262565e5c841c3c F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4 F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85 -F test/backcompat.test bccbc64769d9c755ad65ee7c2f7336b86e3cc0c8 +F test/backcompat.test e0d5a36828cc338754125059cf354c5813a4405f F test/backup.test c9cdd23a495864b9edf75a9fa66f5cb7e10fcf62 F test/backup2.test 34986ef926ea522911a51dfdb2f8e99b7b75ebcf F test/backup_ioerr.test 40d208bc9224b666ee3ed423f49bc9062a36a9d0 @@ -364,7 +364,7 @@ F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 F test/date.test f3228180c87bbe5d39c9397bf001c0095c3821b9 F test/dbstatus.test 207e5b63fcb7b9c3bb8e1fdf38ebd4654ad0e54b -F test/dbstatus2.test b1de8250fde1f3474d6b86f0e89de38d84794f56 +F test/dbstatus2.test bf7396af964b89e39435babbcdf296ae8fc5f10a F test/default.test 6faf23ccb300114924353007795aa9a8ec0aa9dc F test/delete.test a065b05d2ebf60fd16639c579a4adfb7c381c701 F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa @@ -501,6 +501,7 @@ F test/fts4merge.test c424309743fdd203f8e56a1f1cd7872cd66cc0ee F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891 F test/fts4merge3.test aab02a09f50fe6baaddc2e159c3eabc116d45fc7 F test/fts4unicode.test aad033abdcfa0f87ce5f56468f59fdf2a0acbcef +F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d F test/func.test 0d89043dab9a8853358d14c68e028ee0093bf066 F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f F test/func3.test 001021e5b88bd02a3b365a5c5fd8f6f49d39744a @@ -642,7 +643,7 @@ F test/pageropt.test 9191867ed19a2b3db6c42d1b36b6fbc657cd1ab0 F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0 F test/pcache.test 065aa286e722ab24f2e51792c1f093bf60656b16 F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025 -F test/permutations.test 1a8ac849b659445a0b3883caf42fa2c2a289f4a1 +F test/permutations.test 360b92859c0af814b3fe10b68746936389606501 F test/pragma.test a62f73293b0f0d79b0c87f8dd32d46fe53b0bd17 F test/pragma2.test 3a55f82b954242c642f8342b17dffc8b47472947 F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552 @@ -736,7 +737,7 @@ F test/tclsqlite.test a3d2df21ee98957f5de4f9dc1db0eab68047ab5d F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c F test/temptable.test 51edd31c65ed1560dd600b1796e8325df96318e2 F test/temptrigger.test 26670ed7a39cf2296a7f0a9e0a1d7bdb7abe936d -F test/tester.tcl 2665f64c9ce71944b4d41269114e658fb81bda05 +F test/tester.tcl ed47103d30a1a4b3c1d8de207606a407e55cc5c2 F test/thread001.test 7cc2ce08f9cde95964736d11e91f9ab610f82f91 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -762,13 +763,13 @@ F test/tkt-3a77c9714e.test 32bb28afa8c63fc76e972e996193139b63551ed9 F test/tkt-3fe897352e.test 10de1a67bd5c66b238a4c96abe55531b37bb4f00 F test/tkt-4a03edc4c8.test 2865e4edbc075b954daa82f8da7cc973033ec76e F test/tkt-54844eea3f.test a12b851128f46a695e4e378cca67409b9b8f5894 -F test/tkt-5d863f876e.test 884072c2de496ddbb90c387c9ebc0d4f44a91b8e +F test/tkt-5d863f876e.test c9f36ca503fa154a3655f92a69d2c30da1747bfa F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84 F test/tkt-5ee23731f.test 9db6e1d7209dc0794948b260d6f82b2b1de83a9f F test/tkt-752e1646fc.test ea78d88d14fe9866bdd991c634483334639e13bf F test/tkt-78e04e52ea.test ab52f0c1e2de6e46c910f4cc16b086bba05952b7 F test/tkt-7bbfb7d442.test dfa5c8097a8c353ae40705d6cddeb1f99c18b81a -F test/tkt-80ba201079.test 9eb040d81c404f56838a6af93593f42790def63f +F test/tkt-80ba201079.test 105a721e6aad0ae3c5946d7615d1e4d03f6145b8 F test/tkt-80e031a00f.test 9a154173461a4dbe2de49cda73963e04842d52f7 F test/tkt-8454a207b9.test c583a9f814a82a2b5ba95207f55001c9f0cd816c F test/tkt-91e2e8ba6f.test 08c4f94ae07696b05c9b822da0b4e5337a2f54c5 @@ -934,7 +935,7 @@ F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c F test/wal5.test f58ed4b8b542f71c7441da12fbd769d99b362437 F test/wal6.test 2e3bc767d9c2ce35c47106148d43fcbd072a93b3 F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd -F test/wal8.test 5ab217d21f7e5e86af2933a4ffd0d8357cc2c0bd +F test/wal8.test b3ee739fe8f7586aaebdc2367f477ebcf3e3b034 F test/wal_common.tcl a98f17fba96206122eff624db0ab13ec377be4fe F test/walbak.test b9f68e39646375c2b877be906babcc15d38b4877 F test/walbig.test f437473a16cfb314867c6b5d1dbcd519e73e3434 @@ -968,7 +969,7 @@ F test/whereD.test 304ccbe3c77e0d0764f37c91d43b8c4792a5e02f F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31 F test/win32lock.test b2a539e85ae6b2d78475e016a9636b4451dc7fb9 F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688 -F test/zerodamage.test 0de750389990b1078bab203c712dc3fefd1d8b82 +F test/zerodamage.test e7f77fded01dfcdf92ac2c5400f1e35d7a21463c F tool/build-all-msvc.bat 1a18aa39983ae7354d834bc55a850a54fc007576 x F tool/build-shell.sh b64a481901fc9ffe5ca8812a2a9255b6cfb77381 F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 @@ -1012,7 +1013,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P bf8a9ca5b58404112a8af666f5840b462b7bbfe1 -R 847379dec46339e4d4e3d3e07e9871f0 -U drh -Z a42f3ee2165757bae1503891985c3bca +P 9402f81fade5fcae0a3a6efdc7a5cdf71fc2e79f +R daf813c87e17f5252bebfe0af09b2572 +U mistachkin +Z 66d6c356671ca3d281bc85c60ca24a37 diff --git a/manifest.uuid b/manifest.uuid index 9a08d83f21..c1c8fdacbf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9402f81fade5fcae0a3a6efdc7a5cdf71fc2e79f \ No newline at end of file +c1a8557008e56aa9bcb4565e4178fc57295c563d \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index cbf17b1517..af0c21156a 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -24,6 +24,15 @@ */ #include "os_common.h" +/* +** Compiling and using WAL mode requires several APIs that are only +** available in Windows platforms based on the NT kernel. +*/ +#if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL) +# error "WAL mode requires support from the Windows NT kernel, compile\ + with SQLITE_OMIT_WAL." +#endif + /* ** Macro to find the minimum of two numeric values. */ @@ -308,6 +317,16 @@ static struct win_syscall { #define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \ LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent) +#if (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \ + !defined(SQLITE_OMIT_WAL)) + { "CreateFileMappingA", (SYSCALL)CreateFileMappingA, 0 }, +#else + { "CreateFileMappingA", (SYSCALL)0, 0 }, +#endif + +#define osCreateFileMappingA ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \ + DWORD,DWORD,DWORD,LPCSTR))aSyscall[6].pCurrent) + #if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \ !defined(SQLITE_OMIT_WAL)) { "CreateFileMappingW", (SYSCALL)CreateFileMappingW, 0 }, @@ -316,7 +335,7 @@ static struct win_syscall { #endif #define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \ - DWORD,DWORD,DWORD,LPCWSTR))aSyscall[6].pCurrent) + DWORD,DWORD,DWORD,LPCWSTR))aSyscall[7].pCurrent) #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) { "CreateMutexW", (SYSCALL)CreateMutexW, 0 }, @@ -325,7 +344,7 @@ static struct win_syscall { #endif #define osCreateMutexW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,BOOL, \ - LPCWSTR))aSyscall[7].pCurrent) + LPCWSTR))aSyscall[8].pCurrent) #if defined(SQLITE_WIN32_HAS_ANSI) { "DeleteFileA", (SYSCALL)DeleteFileA, 0 }, @@ -333,7 +352,7 @@ static struct win_syscall { { "DeleteFileA", (SYSCALL)0, 0 }, #endif -#define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[8].pCurrent) +#define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[9].pCurrent) #if defined(SQLITE_WIN32_HAS_WIDE) { "DeleteFileW", (SYSCALL)DeleteFileW, 0 }, @@ -341,7 +360,7 @@ static struct win_syscall { { "DeleteFileW", (SYSCALL)0, 0 }, #endif -#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[9].pCurrent) +#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[10].pCurrent) #if SQLITE_OS_WINCE { "FileTimeToLocalFileTime", (SYSCALL)FileTimeToLocalFileTime, 0 }, @@ -350,7 +369,7 @@ static struct win_syscall { #endif #define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(CONST FILETIME*, \ - LPFILETIME))aSyscall[10].pCurrent) + LPFILETIME))aSyscall[11].pCurrent) #if SQLITE_OS_WINCE { "FileTimeToSystemTime", (SYSCALL)FileTimeToSystemTime, 0 }, @@ -359,11 +378,11 @@ static struct win_syscall { #endif #define osFileTimeToSystemTime ((BOOL(WINAPI*)(CONST FILETIME*, \ - LPSYSTEMTIME))aSyscall[11].pCurrent) + LPSYSTEMTIME))aSyscall[12].pCurrent) { "FlushFileBuffers", (SYSCALL)FlushFileBuffers, 0 }, -#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[12].pCurrent) +#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[13].pCurrent) #if defined(SQLITE_WIN32_HAS_ANSI) { "FormatMessageA", (SYSCALL)FormatMessageA, 0 }, @@ -372,7 +391,7 @@ static struct win_syscall { #endif #define osFormatMessageA ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPSTR, \ - DWORD,va_list*))aSyscall[13].pCurrent) + DWORD,va_list*))aSyscall[14].pCurrent) #if defined(SQLITE_WIN32_HAS_WIDE) { "FormatMessageW", (SYSCALL)FormatMessageW, 0 }, @@ -381,15 +400,15 @@ static struct win_syscall { #endif #define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \ - DWORD,va_list*))aSyscall[14].pCurrent) + DWORD,va_list*))aSyscall[15].pCurrent) { "FreeLibrary", (SYSCALL)FreeLibrary, 0 }, -#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[15].pCurrent) +#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[16].pCurrent) { "GetCurrentProcessId", (SYSCALL)GetCurrentProcessId, 0 }, -#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[16].pCurrent) +#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[17].pCurrent) #if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI) { "GetDiskFreeSpaceA", (SYSCALL)GetDiskFreeSpaceA, 0 }, @@ -398,7 +417,7 @@ static struct win_syscall { #endif #define osGetDiskFreeSpaceA ((BOOL(WINAPI*)(LPCSTR,LPDWORD,LPDWORD,LPDWORD, \ - LPDWORD))aSyscall[17].pCurrent) + LPDWORD))aSyscall[18].pCurrent) #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) { "GetDiskFreeSpaceW", (SYSCALL)GetDiskFreeSpaceW, 0 }, @@ -407,7 +426,7 @@ static struct win_syscall { #endif #define osGetDiskFreeSpaceW ((BOOL(WINAPI*)(LPCWSTR,LPDWORD,LPDWORD,LPDWORD, \ - LPDWORD))aSyscall[18].pCurrent) + LPDWORD))aSyscall[19].pCurrent) #if defined(SQLITE_WIN32_HAS_ANSI) { "GetFileAttributesA", (SYSCALL)GetFileAttributesA, 0 }, @@ -415,7 +434,7 @@ static struct win_syscall { { "GetFileAttributesA", (SYSCALL)0, 0 }, #endif -#define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[19].pCurrent) +#define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[20].pCurrent) #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) { "GetFileAttributesW", (SYSCALL)GetFileAttributesW, 0 }, @@ -423,7 +442,7 @@ static struct win_syscall { { "GetFileAttributesW", (SYSCALL)0, 0 }, #endif -#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[20].pCurrent) +#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[21].pCurrent) #if defined(SQLITE_WIN32_HAS_WIDE) { "GetFileAttributesExW", (SYSCALL)GetFileAttributesExW, 0 }, @@ -432,7 +451,7 @@ static struct win_syscall { #endif #define osGetFileAttributesExW ((BOOL(WINAPI*)(LPCWSTR,GET_FILEEX_INFO_LEVELS, \ - LPVOID))aSyscall[21].pCurrent) + LPVOID))aSyscall[22].pCurrent) #if !SQLITE_OS_WINRT { "GetFileSize", (SYSCALL)GetFileSize, 0 }, @@ -440,7 +459,7 @@ static struct win_syscall { { "GetFileSize", (SYSCALL)0, 0 }, #endif -#define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[22].pCurrent) +#define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[23].pCurrent) #if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI) { "GetFullPathNameA", (SYSCALL)GetFullPathNameA, 0 }, @@ -449,7 +468,7 @@ static struct win_syscall { #endif #define osGetFullPathNameA ((DWORD(WINAPI*)(LPCSTR,DWORD,LPSTR, \ - LPSTR*))aSyscall[23].pCurrent) + LPSTR*))aSyscall[24].pCurrent) #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) { "GetFullPathNameW", (SYSCALL)GetFullPathNameW, 0 }, @@ -458,11 +477,11 @@ static struct win_syscall { #endif #define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \ - LPWSTR*))aSyscall[24].pCurrent) + LPWSTR*))aSyscall[25].pCurrent) { "GetLastError", (SYSCALL)GetLastError, 0 }, -#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[25].pCurrent) +#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent) #if SQLITE_OS_WINCE /* The GetProcAddressA() routine is only available on Windows CE. */ @@ -474,7 +493,7 @@ static struct win_syscall { #endif #define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \ - LPCSTR))aSyscall[26].pCurrent) + LPCSTR))aSyscall[27].pCurrent) #if !SQLITE_OS_WINRT { "GetSystemInfo", (SYSCALL)GetSystemInfo, 0 }, @@ -482,11 +501,11 @@ static struct win_syscall { { "GetSystemInfo", (SYSCALL)0, 0 }, #endif -#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[27].pCurrent) +#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[28].pCurrent) { "GetSystemTime", (SYSCALL)GetSystemTime, 0 }, -#define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[28].pCurrent) +#define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[29].pCurrent) #if !SQLITE_OS_WINCE { "GetSystemTimeAsFileTime", (SYSCALL)GetSystemTimeAsFileTime, 0 }, @@ -495,7 +514,7 @@ static struct win_syscall { #endif #define osGetSystemTimeAsFileTime ((VOID(WINAPI*)( \ - LPFILETIME))aSyscall[29].pCurrent) + LPFILETIME))aSyscall[30].pCurrent) #if defined(SQLITE_WIN32_HAS_ANSI) { "GetTempPathA", (SYSCALL)GetTempPathA, 0 }, @@ -503,7 +522,7 @@ static struct win_syscall { { "GetTempPathA", (SYSCALL)0, 0 }, #endif -#define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[30].pCurrent) +#define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[31].pCurrent) #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) { "GetTempPathW", (SYSCALL)GetTempPathW, 0 }, @@ -511,7 +530,7 @@ static struct win_syscall { { "GetTempPathW", (SYSCALL)0, 0 }, #endif -#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[31].pCurrent) +#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[32].pCurrent) #if !SQLITE_OS_WINRT { "GetTickCount", (SYSCALL)GetTickCount, 0 }, @@ -519,7 +538,7 @@ static struct win_syscall { { "GetTickCount", (SYSCALL)0, 0 }, #endif -#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[32].pCurrent) +#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent) #if defined(SQLITE_WIN32_HAS_ANSI) { "GetVersionExA", (SYSCALL)GetVersionExA, 0 }, @@ -528,12 +547,12 @@ static struct win_syscall { #endif #define osGetVersionExA ((BOOL(WINAPI*)( \ - LPOSVERSIONINFOA))aSyscall[33].pCurrent) + LPOSVERSIONINFOA))aSyscall[34].pCurrent) { "HeapAlloc", (SYSCALL)HeapAlloc, 0 }, #define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \ - SIZE_T))aSyscall[34].pCurrent) + SIZE_T))aSyscall[35].pCurrent) #if !SQLITE_OS_WINRT { "HeapCreate", (SYSCALL)HeapCreate, 0 }, @@ -542,7 +561,7 @@ static struct win_syscall { #endif #define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \ - SIZE_T))aSyscall[35].pCurrent) + SIZE_T))aSyscall[36].pCurrent) #if !SQLITE_OS_WINRT { "HeapDestroy", (SYSCALL)HeapDestroy, 0 }, @@ -550,21 +569,21 @@ static struct win_syscall { { "HeapDestroy", (SYSCALL)0, 0 }, #endif -#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[36].pCurrent) +#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[37].pCurrent) { "HeapFree", (SYSCALL)HeapFree, 0 }, -#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[37].pCurrent) +#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[38].pCurrent) { "HeapReAlloc", (SYSCALL)HeapReAlloc, 0 }, #define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \ - SIZE_T))aSyscall[38].pCurrent) + SIZE_T))aSyscall[39].pCurrent) { "HeapSize", (SYSCALL)HeapSize, 0 }, #define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \ - LPCVOID))aSyscall[39].pCurrent) + LPCVOID))aSyscall[40].pCurrent) #if !SQLITE_OS_WINRT { "HeapValidate", (SYSCALL)HeapValidate, 0 }, @@ -573,7 +592,7 @@ static struct win_syscall { #endif #define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \ - LPCVOID))aSyscall[40].pCurrent) + LPCVOID))aSyscall[41].pCurrent) #if defined(SQLITE_WIN32_HAS_ANSI) { "LoadLibraryA", (SYSCALL)LoadLibraryA, 0 }, @@ -581,7 +600,7 @@ static struct win_syscall { { "LoadLibraryA", (SYSCALL)0, 0 }, #endif -#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[41].pCurrent) +#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[42].pCurrent) #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) { "LoadLibraryW", (SYSCALL)LoadLibraryW, 0 }, @@ -589,7 +608,7 @@ static struct win_syscall { { "LoadLibraryW", (SYSCALL)0, 0 }, #endif -#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[42].pCurrent) +#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[43].pCurrent) #if !SQLITE_OS_WINRT { "LocalFree", (SYSCALL)LocalFree, 0 }, @@ -597,7 +616,7 @@ static struct win_syscall { { "LocalFree", (SYSCALL)0, 0 }, #endif -#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[43].pCurrent) +#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[44].pCurrent) #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT { "LockFile", (SYSCALL)LockFile, 0 }, @@ -607,7 +626,7 @@ static struct win_syscall { #ifndef osLockFile #define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ - DWORD))aSyscall[44].pCurrent) + DWORD))aSyscall[45].pCurrent) #endif #if !SQLITE_OS_WINCE @@ -618,7 +637,7 @@ static struct win_syscall { #ifndef osLockFileEx #define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \ - LPOVERLAPPED))aSyscall[45].pCurrent) + LPOVERLAPPED))aSyscall[46].pCurrent) #endif #if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)) @@ -628,26 +647,26 @@ static struct win_syscall { #endif #define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ - SIZE_T))aSyscall[46].pCurrent) + SIZE_T))aSyscall[47].pCurrent) { "MultiByteToWideChar", (SYSCALL)MultiByteToWideChar, 0 }, #define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \ - int))aSyscall[47].pCurrent) + int))aSyscall[48].pCurrent) { "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 }, #define osQueryPerformanceCounter ((BOOL(WINAPI*)( \ - LARGE_INTEGER*))aSyscall[48].pCurrent) + LARGE_INTEGER*))aSyscall[49].pCurrent) { "ReadFile", (SYSCALL)ReadFile, 0 }, #define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \ - LPOVERLAPPED))aSyscall[49].pCurrent) + LPOVERLAPPED))aSyscall[50].pCurrent) { "SetEndOfFile", (SYSCALL)SetEndOfFile, 0 }, -#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[50].pCurrent) +#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[51].pCurrent) #if !SQLITE_OS_WINRT { "SetFilePointer", (SYSCALL)SetFilePointer, 0 }, @@ -656,7 +675,7 @@ static struct win_syscall { #endif #define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \ - DWORD))aSyscall[51].pCurrent) + DWORD))aSyscall[52].pCurrent) #if !SQLITE_OS_WINRT { "Sleep", (SYSCALL)Sleep, 0 }, @@ -664,12 +683,12 @@ static struct win_syscall { { "Sleep", (SYSCALL)0, 0 }, #endif -#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[52].pCurrent) +#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[53].pCurrent) { "SystemTimeToFileTime", (SYSCALL)SystemTimeToFileTime, 0 }, #define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \ - LPFILETIME))aSyscall[53].pCurrent) + LPFILETIME))aSyscall[54].pCurrent) #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT { "UnlockFile", (SYSCALL)UnlockFile, 0 }, @@ -679,7 +698,7 @@ static struct win_syscall { #ifndef osUnlockFile #define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ - DWORD))aSyscall[54].pCurrent) + DWORD))aSyscall[55].pCurrent) #endif #if !SQLITE_OS_WINCE @@ -689,7 +708,7 @@ static struct win_syscall { #endif #define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ - LPOVERLAPPED))aSyscall[55].pCurrent) + LPOVERLAPPED))aSyscall[56].pCurrent) #if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL) { "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 }, @@ -697,17 +716,17 @@ static struct win_syscall { { "UnmapViewOfFile", (SYSCALL)0, 0 }, #endif -#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[56].pCurrent) +#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[57].pCurrent) { "WideCharToMultiByte", (SYSCALL)WideCharToMultiByte, 0 }, #define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \ - LPCSTR,LPBOOL))aSyscall[57].pCurrent) + LPCSTR,LPBOOL))aSyscall[58].pCurrent) { "WriteFile", (SYSCALL)WriteFile, 0 }, #define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \ - LPOVERLAPPED))aSyscall[58].pCurrent) + LPOVERLAPPED))aSyscall[59].pCurrent) #if SQLITE_OS_WINRT { "CreateEventExW", (SYSCALL)CreateEventExW, 0 }, @@ -716,7 +735,7 @@ static struct win_syscall { #endif #define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \ - DWORD,DWORD))aSyscall[59].pCurrent) + DWORD,DWORD))aSyscall[60].pCurrent) #if !SQLITE_OS_WINRT { "WaitForSingleObject", (SYSCALL)WaitForSingleObject, 0 }, @@ -725,7 +744,7 @@ static struct win_syscall { #endif #define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \ - DWORD))aSyscall[60].pCurrent) + DWORD))aSyscall[61].pCurrent) #if SQLITE_OS_WINRT { "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 }, @@ -734,7 +753,7 @@ static struct win_syscall { #endif #define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \ - BOOL))aSyscall[61].pCurrent) + BOOL))aSyscall[62].pCurrent) #if SQLITE_OS_WINRT { "SetFilePointerEx", (SYSCALL)SetFilePointerEx, 0 }, @@ -743,7 +762,7 @@ static struct win_syscall { #endif #define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER, \ - PLARGE_INTEGER,DWORD))aSyscall[62].pCurrent) + PLARGE_INTEGER,DWORD))aSyscall[63].pCurrent) #if SQLITE_OS_WINRT { "GetFileInformationByHandleEx", (SYSCALL)GetFileInformationByHandleEx, 0 }, @@ -752,7 +771,7 @@ static struct win_syscall { #endif #define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \ - FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[63].pCurrent) + FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[64].pCurrent) #if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL) { "MapViewOfFileFromApp", (SYSCALL)MapViewOfFileFromApp, 0 }, @@ -761,7 +780,7 @@ static struct win_syscall { #endif #define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \ - SIZE_T))aSyscall[64].pCurrent) + SIZE_T))aSyscall[65].pCurrent) #if SQLITE_OS_WINRT { "CreateFile2", (SYSCALL)CreateFile2, 0 }, @@ -770,7 +789,7 @@ static struct win_syscall { #endif #define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \ - LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[65].pCurrent) + LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[66].pCurrent) #if SQLITE_OS_WINRT { "LoadPackagedLibrary", (SYSCALL)LoadPackagedLibrary, 0 }, @@ -779,7 +798,7 @@ static struct win_syscall { #endif #define osLoadPackagedLibrary ((HMODULE(WINAPI*)(LPCWSTR, \ - DWORD))aSyscall[66].pCurrent) + DWORD))aSyscall[67].pCurrent) #if SQLITE_OS_WINRT { "GetTickCount64", (SYSCALL)GetTickCount64, 0 }, @@ -787,7 +806,7 @@ static struct win_syscall { { "GetTickCount64", (SYSCALL)0, 0 }, #endif -#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[67].pCurrent) +#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[68].pCurrent) #if SQLITE_OS_WINRT { "GetNativeSystemInfo", (SYSCALL)GetNativeSystemInfo, 0 }, @@ -796,7 +815,7 @@ static struct win_syscall { #endif #define osGetNativeSystemInfo ((VOID(WINAPI*)( \ - LPSYSTEM_INFO))aSyscall[68].pCurrent) + LPSYSTEM_INFO))aSyscall[69].pCurrent) #if defined(SQLITE_WIN32_HAS_ANSI) { "OutputDebugStringA", (SYSCALL)OutputDebugStringA, 0 }, @@ -804,7 +823,7 @@ static struct win_syscall { { "OutputDebugStringA", (SYSCALL)0, 0 }, #endif -#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[69].pCurrent) +#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[70].pCurrent) #if defined(SQLITE_WIN32_HAS_WIDE) { "OutputDebugStringW", (SYSCALL)OutputDebugStringW, 0 }, @@ -812,11 +831,11 @@ static struct win_syscall { { "OutputDebugStringW", (SYSCALL)0, 0 }, #endif -#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[70].pCurrent) +#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[71].pCurrent) { "GetProcessHeap", (SYSCALL)GetProcessHeap, 0 }, -#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[71].pCurrent) +#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[72].pCurrent) #if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL) { "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 }, @@ -825,7 +844,7 @@ static struct win_syscall { #endif #define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \ - LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[72].pCurrent) + LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[73].pCurrent) }; /* End of the overrideable system calls */ @@ -983,6 +1002,8 @@ void sqlite3_win32_sleep(DWORD milliseconds){ */ #if SQLITE_OS_WINCE || SQLITE_OS_WINRT # define isNT() (1) +#elif !defined(SQLITE_WIN32_HAS_WIDE) +# define isNT() (0) #else static int isNT(void){ if( sqlite3_os_type==0 ){ @@ -993,7 +1014,7 @@ void sqlite3_win32_sleep(DWORD milliseconds){ } return sqlite3_os_type==2; } -#endif /* SQLITE_OS_WINCE */ +#endif #ifdef SQLITE_WIN32_MALLOC /* @@ -3280,17 +3301,21 @@ static int winShmMap( pShmNode->aRegion = apNew; while( pShmNode->nRegion<=iRegion ){ - HANDLE hMap; /* file-mapping handle */ + HANDLE hMap = NULL; /* file-mapping handle */ void *pMap = 0; /* Mapped memory region */ #if SQLITE_OS_WINRT hMap = osCreateFileMappingFromApp(pShmNode->hFile.h, NULL, PAGE_READWRITE, nByte, NULL ); -#else +#elif defined(SQLITE_WIN32_HAS_WIDE) hMap = osCreateFileMappingW(pShmNode->hFile.h, NULL, PAGE_READWRITE, 0, nByte, NULL ); +#elif defined(SQLITE_WIN32_HAS_ANSI) + hMap = osCreateFileMappingA(pShmNode->hFile.h, + NULL, PAGE_READWRITE, 0, nByte, NULL + ); #endif OSTRACE(("SHM-MAP pid-%d create region=%d nbyte=%d %s\n", (int)osGetCurrentProcessId(), pShmNode->nRegion, nByte, @@ -4351,7 +4376,7 @@ int sqlite3_os_init(void){ /* Double-check that the aSyscall[] array has been constructed ** correctly. See ticket [bb3a86e890c8e96ab] */ - assert( ArraySize(aSyscall)==73 ); + assert( ArraySize(aSyscall)==74 ); #ifndef SQLITE_OMIT_WAL /* get memory map allocation granularity */ @@ -4370,7 +4395,7 @@ int sqlite3_os_init(void){ int sqlite3_os_end(void){ #if SQLITE_OS_WINRT - if( sleepObj != NULL ){ + if( sleepObj!=NULL ){ osCloseHandle(sleepObj); sleepObj = NULL; } diff --git a/test/backcompat.test b/test/backcompat.test index 509dfe530c..6c002b8341 100644 --- a/test/backcompat.test +++ b/test/backcompat.test @@ -214,6 +214,7 @@ unset ::incompatible do_allbackcompat_test { if {[code1 {sqlite3 -version}] >= "3.7.0" && [code2 {sqlite3 -version}] >= "3.7.0" + && [capable wal] } { do_test backcompat-2.1.1 { sql1 { diff --git a/test/dbstatus2.test b/test/dbstatus2.test index b2ec156655..18bb0870bd 100644 --- a/test/dbstatus2.test +++ b/test/dbstatus2.test @@ -85,10 +85,12 @@ do_test 2.3 { db_write db 1 } {0 4 0} do_test 2.4 { db_write db 0 } {0 0 0} do_test 2.5 { db_write db 1 } {0 0 0} -do_test 2.6 { - execsql { PRAGMA journal_mode = WAL } - db_write db 1 -} {0 1 0} +ifcapable wal { + do_test 2.6 { + execsql { PRAGMA journal_mode = WAL } + db_write db 1 + } {0 1 0} +} do_test 2.7 { execsql { INSERT INTO t1 VALUES(5, randomblob(600)) } db_write db diff --git a/test/full.test b/test/full.test new file mode 100644 index 0000000000..a8fe371449 --- /dev/null +++ b/test/full.test @@ -0,0 +1,20 @@ +# 2012 September 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. +# +#*********************************************************************** +# This file runs the "full" test suite. It is a peer of the quick.test +# and all.test scripts. +# + +set testdir [file dirname $argv0] +source $testdir/permutations.test + +run_test_suite full + +finish_test diff --git a/test/permutations.test b/test/permutations.test index 2ff77f9de2..711d4e57d3 100644 --- a/test/permutations.test +++ b/test/permutations.test @@ -96,7 +96,7 @@ if {$::tcl_platform(platform)!="unix"} { set alltests [test_set $alltests -exclude { all.test async.test quick.test veryquick.test memleak.test permutations.test soak.test fts3.test - mallocAll.test rtree.test + mallocAll.test rtree.test full.test }] set allquicktests [test_set $alltests -exclude { diff --git a/test/tester.tcl b/test/tester.tcl index 68b2c8df4c..74f1e2a1b3 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -31,6 +31,7 @@ # Test the capability of the SQLite version built into the interpreter to # determine if a specific test can be run: # +# capable EXPR # ifcapable EXPR # # Calulate checksums based on database contents: @@ -134,7 +135,7 @@ proc getFileRetries {} { # NOTE: Return the default number of retries for [file] operations. A # value of zero or less here means "disabled". # - return [expr {$::tcl_platform(platform) eq "windows" ? 10 : 0}] + return [expr {$::tcl_platform(platform) eq "windows" ? 50 : 0}] } return $::G(file-retries) } @@ -547,6 +548,9 @@ proc do_test {name cmd expected} { set ok [expr {[string compare $result $expected]==0}] } if {!$ok} { + # if {![info exists ::testprefix] || $::testprefix eq ""} { + # error "no test prefix" + # } puts "\nExpected: \[$expected\]\n Got: \[$result\]" fail_test $name } else { @@ -994,6 +998,12 @@ proc fix_ifcapable_expr {expr} { return $ret } +# Returns non-zero if the capabilities are present; zero otherwise. +# +proc capable {expr} { + set e [fix_ifcapable_expr $expr]; return [expr ($e)] +} + # Evaluate a boolean expression of capabilities. If true, execute the # code. Omit the code if false. # diff --git a/test/tkt-5d863f876e.test b/test/tkt-5d863f876e.test index 0a9017de11..86024e300b 100644 --- a/test/tkt-5d863f876e.test +++ b/test/tkt-5d863f876e.test @@ -17,6 +17,8 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl +set ::testprefix tkt-5d863f876e +ifcapable !wal {finish_test ; return } do_multiclient_test tn { do_test $tn.1 { diff --git a/test/tkt-80ba201079.test b/test/tkt-80ba201079.test index 0122e95f2f..ea0799b568 100644 --- a/test/tkt-80ba201079.test +++ b/test/tkt-80ba201079.test @@ -17,7 +17,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl -set ::testprefix tkt-80ba2 +set ::testprefix tkt-80ba201079 do_test tkt-80ba2-100 { db eval { diff --git a/test/wal8.test b/test/wal8.test index 4b97de7ae7..339953895c 100644 --- a/test/wal8.test +++ b/test/wal8.test @@ -26,6 +26,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl set ::testprefix wal8 +ifcapable !wal {finish_test ; return } db close forcedelete test.db test.db-wal diff --git a/test/zerodamage.test b/test/zerodamage.test index 3d18c8dea8..217749a4a4 100644 --- a/test/zerodamage.test +++ b/test/zerodamage.test @@ -18,7 +18,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl -set testprefix wal5 +set testprefix zerodamage ifcapable !vtab { finish_test @@ -89,31 +89,33 @@ do_test zerodamage-2.1 { concat [file_control_powersafe_overwrite db -1] [set ::max_journal_size] } {0 0 24704} -# Run a WAL-mode transaction with POWERSAFE_OVERWRITE on to verify that the -# WAL file does not get too big. -# -do_test zerodamage-3.0 { - db eval { - PRAGMA journal_mode=WAL; - } - db close - sqlite3 db file:test.db?psow=TRUE -uri 1 - db eval { - UPDATE t1 SET y=randomblob(50) WHERE x=124; - } - file size test.db-wal -} {1080} +ifcapable wal { + # Run a WAL-mode transaction with POWERSAFE_OVERWRITE on to verify that the + # WAL file does not get too big. + # + do_test zerodamage-3.0 { + db eval { + PRAGMA journal_mode=WAL; + } + db close + sqlite3 db file:test.db?psow=TRUE -uri 1 + db eval { + UPDATE t1 SET y=randomblob(50) WHERE x=124; + } + file size test.db-wal + } {1080} -# Repeat the previous with POWERSAFE_OVERWRITE off. Verify that the WAL file -# is padded. -# -do_test zerodamage-3.1 { - db close - sqlite3 db file:test.db?psow=FALSE -uri 1 - db eval { - UPDATE t1 SET y=randomblob(50) WHERE x=124; - } - file size test.db-wal -} {8416} + # Repeat the previous with POWERSAFE_OVERWRITE off. Verify that the WAL file + # is padded. + # + do_test zerodamage-3.1 { + db close + sqlite3 db file:test.db?psow=FALSE -uri 1 + db eval { + UPDATE t1 SET y=randomblob(50) WHERE x=124; + } + file size test.db-wal + } {8416} +} finish_test From df32414d993cf2d43ed533b578baa76274c1fc38 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 13 Sep 2012 12:10:55 +0000 Subject: [PATCH 20/60] Add the RTREE_INT_ONLY configuration parameter to the compile-time options logic. FossilOrigin-Name: 98b971fb24e0ee5f881b13401c7af51fc6effd0e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/ctime.c | 3 +++ 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 1694f55d16..12d75e5897 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sSQLite\sto\swork\son\sWin32\swith\sSQLITE_OS_WINNT=0\sas\slong\sas\sWAL\sis\sdisabled. -D 2012-09-13T01:51:02.094 +C Add\sthe\sRTREE_INT_ONLY\sconfiguration\sparameter\sto\sthe\scompile-time\soptions\nlogic. +D 2012-09-13T12:10:55.801 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -127,7 +127,7 @@ F src/btreeInt.h 4e5c2bd0f9b36b2a815a6d84f771a61a65830621 F src/build.c a3b700afd475e6387da59be6f2e86161e80d6d87 F src/callback.c 0cb4228cdcd827dcc5def98fb099edcc9142dbcd F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac -F src/ctime.c 500d019da966631ad957c37705642be87524463b +F src/ctime.c 72a70dcfda75d3a1f81041ce4573e7afddcd8e4e F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/delete.c 335f36750dc6ac88d580aa36a6487459be9889de F src/expr.c 217840a107dcc1e5dbb57cea311daad04bedbb9a @@ -1013,7 +1013,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 9402f81fade5fcae0a3a6efdc7a5cdf71fc2e79f -R daf813c87e17f5252bebfe0af09b2572 -U mistachkin -Z 66d6c356671ca3d281bc85c60ca24a37 +P c1a8557008e56aa9bcb4565e4178fc57295c563d +R 9676de67e3c4ff5e7a6d746a8553a98b +U drh +Z b8cdbfa4893d7c86c8f143ff32f7432d diff --git a/manifest.uuid b/manifest.uuid index c1c8fdacbf..4b38c1dc4b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c1a8557008e56aa9bcb4565e4178fc57295c563d \ No newline at end of file +98b971fb24e0ee5f881b13401c7af51fc6effd0e \ No newline at end of file diff --git a/src/ctime.c b/src/ctime.c index 61cf4e3df1..5dee724747 100644 --- a/src/ctime.c +++ b/src/ctime.c @@ -338,6 +338,9 @@ static const char * const azCompileOpt[] = { #ifdef SQLITE_PROXY_DEBUG "PROXY_DEBUG", #endif +#ifdef SQLITE_RTREE_INT_ONLY + "RTREE_INT_ONLY", +#endif #ifdef SQLITE_SECURE_DELETE "SECURE_DELETE", #endif From a371ace426602b717eca66e589a8f48022e2d04a Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 13 Sep 2012 14:22:47 +0000 Subject: [PATCH 21/60] Change boolean fields in the Column object from unsigned characters into bits in a single bit mask variable. FossilOrigin-Name: 4163f5f194741bc2bdf141973912661c6aac70f1 --- manifest | 24 ++++++++++++------------ manifest.uuid | 2 +- src/alter.c | 2 +- src/build.c | 4 ++-- src/fkey.c | 3 ++- src/main.c | 2 +- src/pragma.c | 3 ++- src/sqliteInt.h | 14 ++++++++------ src/vtab.c | 4 ++-- 9 files changed, 31 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index 12d75e5897..a1442fc40e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sRTREE_INT_ONLY\sconfiguration\sparameter\sto\sthe\scompile-time\soptions\nlogic. -D 2012-09-13T12:10:55.801 +C Change\sboolean\sfields\sin\sthe\sColumn\sobject\sfrom\sunsigned\scharacters\sinto\nbits\sin\sa\ssingle\sbit\smask\svariable. +D 2012-09-13T14:22:47.070 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -114,7 +114,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad -F src/alter.c 149cc80d9257971b0bff34e58fb2263e01998289 +F src/alter.c 0c1716aa8d248bd6bc750e23be4c68ad05f8668c F src/analyze.c 7553068d21e32a57fc33ab6b2393fc8c1ba41410 F src/attach.c 577bf5675b0c50495fc28549f2fcbdb1bac71143 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 @@ -124,7 +124,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 9cf6de113d23d47967df24b8d8ce6501c879d7e6 F src/btree.h 4aee02e879211bfcfd3f551769578d2e940ab6c2 F src/btreeInt.h 4e5c2bd0f9b36b2a815a6d84f771a61a65830621 -F src/build.c a3b700afd475e6387da59be6f2e86161e80d6d87 +F src/build.c c4555e16f8ccdadb2616014c617ed8166c5a93f7 F src/callback.c 0cb4228cdcd827dcc5def98fb099edcc9142dbcd F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 72a70dcfda75d3a1f81041ce4573e7afddcd8e4e @@ -132,7 +132,7 @@ F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/delete.c 335f36750dc6ac88d580aa36a6487459be9889de F src/expr.c 217840a107dcc1e5dbb57cea311daad04bedbb9a F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb -F src/fkey.c 9c77d842dc9961d92a06a65abb80c64ef1750296 +F src/fkey.c c82a04e7a92bb728f9ab972b76590403283be2af F src/func.c b4e88b92838fdab8e0088cc8411c06664b4dcf55 F src/global.c 4cfdca5cb0edd33c4d021baec4ede958cb2c793b F src/hash.c a4031441741932da9e7a65bee2b36b5d0e81c073 @@ -143,7 +143,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d -F src/main.c 259472ec0c694fe6a4fb6e8781be7fd8feacb09c +F src/main.c 3977ac9c4f6cf7382258b6e92f8bedb5a3e52527 F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa @@ -168,7 +168,7 @@ F src/parse.y f29df90bd3adc64b33114ab1de9fb7768fcf2099 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h 1b5dcc3dc8103d03e625b177023ee67764fa6b7c F src/pcache1.c 9fd22671c270b35131ef480bbc00392b8b5f8ab9 -F src/pragma.c 97f9357f0e7e5fb46a2519f14539550aa07db49f +F src/pragma.c de7f3bc6176a7ef8f0e39da61b77ab08789e28a0 F src/prepare.c 33291b83cca285718048d219c67b8298501fa3a5 F src/printf.c 4a9f882f1c1787a8b494a2987765acf9d97ac21f F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 @@ -179,7 +179,7 @@ F src/shell.c 87953c5d9c73d9494db97d1607e2e2280418f261 F src/sqlite.h.in 193c0496be6046604d1b8aa518012d3cf411f57f F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h 053e03a532beb909ead2df0721db67cdb4c48ae8 +F src/sqliteInt.h 3f34cdf7244eaf982bb34db8f12a5008554ed5b5 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -245,7 +245,7 @@ F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb F src/vdbemem.c cb55e84b8e2c15704968ee05f0fae25883299b74 F src/vdbesort.c 0dc1b274dcb4d4c8e71b0b2b15261f286caba39b F src/vdbetrace.c 8bd5da325fc90f28464335e4cc4ad1407fe30835 -F src/vtab.c d2c54fd22aa83eb34fc6f7cd9b097f2fc2b1e9de +F src/vtab.c d8020c0a0e8ccc490ca449d7e665311b6e9f3ba9 F src/wal.c 5acb3e7bbd31f10ba39acad9ce6b399055337a9d F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b @@ -1013,7 +1013,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P c1a8557008e56aa9bcb4565e4178fc57295c563d -R 9676de67e3c4ff5e7a6d746a8553a98b +P 98b971fb24e0ee5f881b13401c7af51fc6effd0e +R 37404b7ee37f0075d77806a21f845cbf U drh -Z b8cdbfa4893d7c86c8f143ff32f7432d +Z 57c2a904e2436b132fb5cdefc09cde48 diff --git a/manifest.uuid b/manifest.uuid index 4b38c1dc4b..e1e8ad0c22 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -98b971fb24e0ee5f881b13401c7af51fc6effd0e \ No newline at end of file +4163f5f194741bc2bdf141973912661c6aac70f1 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 7f56ce7e0b..8a96ab704d 100644 --- a/src/alter.c +++ b/src/alter.c @@ -664,7 +664,7 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ ** If there is a NOT NULL constraint, then the default value for the ** column must not be NULL. */ - if( pCol->isPrimKey ){ + if( pCol->colFlags & COLFLAG_PRIMKEY ){ sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column"); return; } diff --git a/src/build.c b/src/build.c index 25e474031f..8910bbd981 100644 --- a/src/build.c +++ b/src/build.c @@ -1169,7 +1169,7 @@ void sqlite3AddPrimaryKey( pTab->tabFlags |= TF_HasPrimaryKey; if( pList==0 ){ iCol = pTab->nCol - 1; - pTab->aCol[iCol].isPrimKey = 1; + pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY; }else{ for(i=0; inExpr; i++){ for(iCol=0; iColnCol; iCol++){ @@ -1178,7 +1178,7 @@ void sqlite3AddPrimaryKey( } } if( iColnCol ){ - pTab->aCol[iCol].isPrimKey = 1; + pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY; } } if( pList->nExpr>1 ) iCol = -1; diff --git a/src/fkey.c b/src/fkey.c index 9db3a71c38..a3214a94da 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -925,7 +925,8 @@ int sqlite3FkRequired( int iKey; for(iKey=0; iKeynCol; iKey++){ Column *pCol = &pTab->aCol[iKey]; - if( (zKey ? !sqlite3StrICmp(pCol->zName, zKey) : pCol->isPrimKey) ){ + if( (zKey ? !sqlite3StrICmp(pCol->zName, zKey) + : (pCol->colFlags & COLFLAG_PRIMKEY)!=0) ){ if( aChange[iKey]>=0 ) return 1; if( iKey==pTab->iPKey && chngRowid ) return 1; } diff --git a/src/main.c b/src/main.c index cc19f78a81..08e62a97ea 100644 --- a/src/main.c +++ b/src/main.c @@ -2750,7 +2750,7 @@ int sqlite3_table_column_metadata( zDataType = pCol->zType; zCollSeq = pCol->zColl; notnull = pCol->notNull!=0; - primarykey = pCol->isPrimKey!=0; + primarykey = (pCol->colFlags & COLFLAG_PRIMKEY)!=0; autoinc = pTab->iPKey==iCol && (pTab->tabFlags & TF_Autoincrement)!=0; }else{ zDataType = "INTEGER"; diff --git a/src/pragma.c b/src/pragma.c index a41e0e433f..6fbc7e9bb4 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -974,7 +974,8 @@ void sqlite3Pragma( }else{ sqlite3VdbeAddOp2(v, OP_Null, 0, 5); } - sqlite3VdbeAddOp2(v, OP_Integer, pCol->isPrimKey, 6); + sqlite3VdbeAddOp2(v, OP_Integer, + (pCol->colFlags&COLFLAG_PRIMKEY)!=0, 6); sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6); } } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 09163bf69c..615aa2098e 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1122,14 +1122,16 @@ struct Column { char *zDflt; /* Original text of the default value */ char *zType; /* Data type for this column */ char *zColl; /* Collating sequence. If NULL, use the default */ - u8 notNull; /* True if there is a NOT NULL constraint */ - u8 isPrimKey; /* True if this column is part of the PRIMARY KEY */ + u8 notNull; /* An OE_ code for handling a NOT NULL constraint */ char affinity; /* One of the SQLITE_AFF_... values */ -#ifndef SQLITE_OMIT_VIRTUALTABLE - u8 isHidden; /* True if this column is 'hidden' */ -#endif + u16 colFlags; /* Boolean properties. See COLFLAG_ defines below */ }; +/* Allowed values for Column.colFlags: +*/ +#define COLFLAG_PRIMKEY 0x0001 /* Column is part of the primary key */ +#define COLFLAG_HIDDEN 0x0002 /* A hidden column in a virtual table */ + /* ** A "Collating Sequence" is defined by an instance of the following ** structure. Conceptually, a collating sequence consists of a name and @@ -1330,7 +1332,7 @@ struct Table { */ #ifndef SQLITE_OMIT_VIRTUALTABLE # define IsVirtual(X) (((X)->tabFlags & TF_Virtual)!=0) -# define IsHiddenColumn(X) ((X)->isHidden) +# define IsHiddenColumn(X) (((X)->colFlags & COLFLAG_HIDDEN)!=0) #else # define IsVirtual(X) 0 # define IsHiddenColumn(X) 0 diff --git a/src/vtab.c b/src/vtab.c index 50d576fc38..29f097da44 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -528,7 +528,7 @@ static int vtabCallConstructor( /* If everything went according to plan, link the new VTable structure ** into the linked list headed by pTab->pVTable. Then loop through the ** columns of the table to see if any of them contain the token "hidden". - ** If so, set the Column.isHidden flag and remove the token from + ** If so, set the Column COLFLAG_HIDDEN flag and remove the token from ** the type string. */ pVTable->pNext = pTab->pVTable; pTab->pVTable = pVTable; @@ -559,7 +559,7 @@ static int vtabCallConstructor( assert(zType[i-1]==' '); zType[i-1] = '\0'; } - pTab->aCol[iCol].isHidden = 1; + pTab->aCol[iCol].colFlags |= COLFLAG_HIDDEN; } } } From d815f17dabd69ca2d77a47f2dd2b61c9137f831e Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 13 Sep 2012 14:42:43 +0000 Subject: [PATCH 22/60] Reduce the size of the Table object by 16 bytes on 64-bit machines, mostly by avoiding intermixing pointer fields with integer fields. FossilOrigin-Name: 1cb9aedfcf81f0086fa741cb29a062ee87724a5e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 2 +- src/sqliteInt.h | 16 ++++++++-------- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index a1442fc40e..cfe94bca48 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sboolean\sfields\sin\sthe\sColumn\sobject\sfrom\sunsigned\scharacters\sinto\nbits\sin\sa\ssingle\sbit\smask\svariable. -D 2012-09-13T14:22:47.070 +C Reduce\sthe\ssize\sof\sthe\sTable\sobject\sby\s16\sbytes\son\s64-bit\smachines,\smostly\nby\savoiding\sintermixing\spointer\sfields\swith\sinteger\sfields. +D 2012-09-13T14:42:43.405 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -174,12 +174,12 @@ F src/printf.c 4a9f882f1c1787a8b494a2987765acf9d97ac21f F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 9e28280ec98035f31900fdd1db01f86f68ca6c32 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c f843c872a97baa1594c2cc3d4c003409a7bd03af +F src/select.c 171ec5fd5eae6d7a19b54f8f0abdfdd9a1c8f3ad F src/shell.c 87953c5d9c73d9494db97d1607e2e2280418f261 F src/sqlite.h.in 193c0496be6046604d1b8aa518012d3cf411f57f F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h 3f34cdf7244eaf982bb34db8f12a5008554ed5b5 +F src/sqliteInt.h f31b576c4d72e8baeb52ef7318d202ecc8cae205 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1013,7 +1013,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 98b971fb24e0ee5f881b13401c7af51fc6effd0e -R 37404b7ee37f0075d77806a21f845cbf +P 4163f5f194741bc2bdf141973912661c6aac70f1 +R 778304ec4a7e956ad83c3af5d186ae35 U drh -Z 57c2a904e2436b132fb5cdefc09cde48 +Z f76221926d07d84fb53ed6ba4b6e00d7 diff --git a/manifest.uuid b/manifest.uuid index e1e8ad0c22..b92a750709 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4163f5f194741bc2bdf141973912661c6aac70f1 \ No newline at end of file +1cb9aedfcf81f0086fa741cb29a062ee87724a5e \ No newline at end of file diff --git a/src/select.c b/src/select.c index 6ec9da39a1..0bf47e8521 100644 --- a/src/select.c +++ b/src/select.c @@ -1246,7 +1246,7 @@ static void generateColumnNames( static int selectColumnsFromExprList( Parse *pParse, /* Parsing context */ ExprList *pEList, /* Expr list from which to derive column names */ - int *pnCol, /* Write the number of columns here */ + i16 *pnCol, /* Write the number of columns here */ Column **paCol /* Write the new column list here */ ){ sqlite3 *db = pParse->db; /* Database connection */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 615aa2098e..0b87add19a 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1287,28 +1287,28 @@ struct VTable { */ struct Table { char *zName; /* Name of the table or view */ - int iPKey; /* If not negative, use aCol[iPKey] as the primary key */ - int nCol; /* Number of columns in this table */ Column *aCol; /* Information about each column */ Index *pIndex; /* List of SQL indexes on this table. */ - int tnum; /* Root BTree node for this table (see note above) */ - tRowcnt nRowEst; /* Estimated rows in table - from sqlite_stat1 table */ Select *pSelect; /* NULL for tables. Points to definition if a view. */ - u16 nRef; /* Number of pointers to this Table */ - u8 tabFlags; /* Mask of TF_* values */ - u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */ FKey *pFKey; /* Linked list of all foreign keys in this table */ char *zColAff; /* String defining the affinity of each column */ #ifndef SQLITE_OMIT_CHECK ExprList *pCheck; /* All CHECK constraints */ #endif + tRowcnt nRowEst; /* Estimated rows in table - from sqlite_stat1 table */ + int tnum; /* Root BTree node for this table (see note above) */ + i16 iPKey; /* If not negative, use aCol[iPKey] as the primary key */ + i16 nCol; /* Number of columns in this table */ + u16 nRef; /* Number of pointers to this Table */ + u8 tabFlags; /* Mask of TF_* values */ + u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */ #ifndef SQLITE_OMIT_ALTERTABLE int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */ #endif #ifndef SQLITE_OMIT_VIRTUALTABLE - VTable *pVTable; /* List of VTable objects. */ int nModuleArg; /* Number of arguments to the module */ char **azModuleArg; /* Text of all module args. [0] is module name */ + VTable *pVTable; /* List of VTable objects. */ #endif Trigger *pTrigger; /* List of triggers stored in pSchema */ Schema *pSchema; /* Schema that contains this table */ From 7ea11af2d6baf67bd8e5d7ee379515b2a31aa5e7 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 13 Sep 2012 15:24:29 +0000 Subject: [PATCH 23/60] Improved reporting of filename translation errors in the Windows VFS. FossilOrigin-Name: eb0f1c292e6fb00c4d9dbb2317fdc4717c5be96b --- manifest | 16 +++++++------- manifest.uuid | 2 +- src/os_win.c | 56 ++++++++++++++++++++++++++++++++++++------------- src/sqlite.h.in | 1 + 4 files changed, 51 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index cfe94bca48..6342de3895 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reduce\sthe\ssize\sof\sthe\sTable\sobject\sby\s16\sbytes\son\s64-bit\smachines,\smostly\nby\savoiding\sintermixing\spointer\sfields\swith\sinteger\sfields. -D 2012-09-13T14:42:43.405 +C Improved\sreporting\sof\sfilename\stranslation\serrors\sin\sthe\sWindows\sVFS. +D 2012-09-13T15:24:29.956 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -161,7 +161,7 @@ F src/os.c e1acdc09ff3ac2412945cca9766e2dcf4675f31c F src/os.h 027491c77d2404c0a678bb3fb06286f331eb9b57 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c 69b2fe66316524eebf5f1ce85c1fdfe2952307e9 -F src/os_win.c d5f19e444b85f18b06f42958f20b5fedec1b9fc4 +F src/os_win.c 90c7a1fe2698867555ba4266f5bd436c85d0d1dc F src/pager.c 5665fa9ecec51f11dabdfd8eefefa89391856007 F src/pager.h 8b8c9bc065a3c66769df8724dfdf492ee1aab3c5 F src/parse.y f29df90bd3adc64b33114ab1de9fb7768fcf2099 @@ -176,7 +176,7 @@ F src/resolve.c 9e28280ec98035f31900fdd1db01f86f68ca6c32 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 171ec5fd5eae6d7a19b54f8f0abdfdd9a1c8f3ad F src/shell.c 87953c5d9c73d9494db97d1607e2e2280418f261 -F src/sqlite.h.in 193c0496be6046604d1b8aa518012d3cf411f57f +F src/sqlite.h.in d1071b0fc6de9a0d11392bc01305803122c3ec61 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h f31b576c4d72e8baeb52ef7318d202ecc8cae205 @@ -1013,7 +1013,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 4163f5f194741bc2bdf141973912661c6aac70f1 -R 778304ec4a7e956ad83c3af5d186ae35 -U drh -Z f76221926d07d84fb53ed6ba4b6e00d7 +P 1cb9aedfcf81f0086fa741cb29a062ee87724a5e +R afbad264292e31d19f2e6ab3cf693fdb +U mistachkin +Z 0cf06bb96aad3721d20115c48db504c9 diff --git a/manifest.uuid b/manifest.uuid index b92a750709..5f276e7322 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1cb9aedfcf81f0086fa741cb29a062ee87724a5e \ No newline at end of file +eb0f1c292e6fb00c4d9dbb2317fdc4717c5be96b \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index af0c21156a..c4d87b92c5 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -1224,7 +1224,7 @@ static LPWSTR utf8ToUnicode(const char *zFilename){ if( nChar==0 ){ return 0; } - zWideFilename = sqlite3_malloc( nChar*sizeof(zWideFilename[0]) ); + zWideFilename = sqlite3MallocZero( nChar*sizeof(zWideFilename[0]) ); if( zWideFilename==0 ){ return 0; } @@ -1249,7 +1249,7 @@ static char *unicodeToUtf8(LPCWSTR zWideFilename){ if( nByte == 0 ){ return 0; } - zFilename = sqlite3_malloc( nByte ); + zFilename = sqlite3MallocZero( nByte ); if( zFilename==0 ){ return 0; } @@ -1279,7 +1279,7 @@ static LPWSTR mbcsToUnicode(const char *zFilename){ if( nByte==0 ){ return 0; } - zMbcsFilename = sqlite3_malloc( nByte*sizeof(zMbcsFilename[0]) ); + zMbcsFilename = sqlite3MallocZero( nByte*sizeof(zMbcsFilename[0]) ); if( zMbcsFilename==0 ){ return 0; } @@ -1308,7 +1308,7 @@ static char *unicodeToMbcs(LPCWSTR zWideFilename){ if( nByte == 0 ){ return 0; } - zFilename = sqlite3_malloc( nByte ); + zFilename = sqlite3MallocZero( nByte ); if( zFilename==0 ){ return 0; } @@ -2955,16 +2955,14 @@ static int winOpenSharedMemory(winFile *pDbFd){ /* Allocate space for the new sqlite3_shm object. Also speculatively ** allocate space for a new winShmNode and filename. */ - p = sqlite3_malloc( sizeof(*p) ); + p = sqlite3MallocZero( sizeof(*p) ); if( p==0 ) return SQLITE_IOERR_NOMEM; - memset(p, 0, sizeof(*p)); nName = sqlite3Strlen30(pDbFd->zPath); - pNew = sqlite3_malloc( sizeof(*pShmNode) + nName + 17 ); + pNew = sqlite3MallocZero( sizeof(*pShmNode) + nName + 17 ); if( pNew==0 ){ sqlite3_free(p); return SQLITE_IOERR_NOMEM; } - memset(pNew, 0, sizeof(*pNew) + nName + 17); pNew->zFilename = (char*)&pNew[1]; sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath); sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename); @@ -4064,7 +4062,7 @@ static int winFullPathname( #endif #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__) - int nByte; + DWORD nByte; void *zConverted; char *zOut; @@ -4098,13 +4096,27 @@ static int winFullPathname( } if( isNT() ){ LPWSTR zTemp; - nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0) + 3; - zTemp = sqlite3_malloc( nByte*sizeof(zTemp[0]) ); + nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0); + if( nByte==0 ){ + winLogError(SQLITE_ERROR, osGetLastError(), + "GetFullPathNameW1", zConverted); + sqlite3_free(zConverted); + return SQLITE_CANTOPEN_FULLPATH; + } + nByte += 3; + zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); if( zTemp==0 ){ sqlite3_free(zConverted); return SQLITE_IOERR_NOMEM; } - osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0); + nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0); + if( nByte==0 ){ + winLogError(SQLITE_ERROR, osGetLastError(), + "GetFullPathNameW2", zConverted); + sqlite3_free(zConverted); + sqlite3_free(zTemp); + return SQLITE_CANTOPEN_FULLPATH; + } sqlite3_free(zConverted); zOut = unicodeToUtf8(zTemp); sqlite3_free(zTemp); @@ -4112,13 +4124,27 @@ static int winFullPathname( #ifdef SQLITE_WIN32_HAS_ANSI else{ char *zTemp; - nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0) + 3; - zTemp = sqlite3_malloc( nByte*sizeof(zTemp[0]) ); + nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0); + if( nByte==0 ){ + winLogError(SQLITE_ERROR, osGetLastError(), + "GetFullPathNameA1", zConverted); + sqlite3_free(zConverted); + return SQLITE_CANTOPEN_FULLPATH; + } + nByte += 3; + zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); if( zTemp==0 ){ sqlite3_free(zConverted); return SQLITE_IOERR_NOMEM; } - osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0); + nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0); + if( nByte==0 ){ + winLogError(SQLITE_ERROR, osGetLastError(), + "GetFullPathNameA2", zConverted); + sqlite3_free(zConverted); + sqlite3_free(zTemp); + return SQLITE_CANTOPEN_FULLPATH; + } sqlite3_free(zConverted); zOut = sqlite3_win32_mbcs_to_utf8(zTemp); sqlite3_free(zTemp); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 3729ae6dcb..3660c442d9 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -473,6 +473,7 @@ int sqlite3_exec( #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) +#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) From 59ee77c7d1e90f3175e5005d09a746c206890920 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 13 Sep 2012 15:26:44 +0000 Subject: [PATCH 24/60] Fix an unused variable warning with SQLITE_OMIT_WAL. FossilOrigin-Name: 39866c0ede5d6ef4dd4fd57c797f0e86a2d0dc5d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 2 ++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 6342de3895..e68463b53d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\sreporting\sof\sfilename\stranslation\serrors\sin\sthe\sWindows\sVFS. -D 2012-09-13T15:24:29.956 +C Fix\san\sunused\svariable\swarning\swith\sSQLITE_OMIT_WAL. +D 2012-09-13T15:26:44.979 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -236,7 +236,7 @@ F src/update.c 28d2d098b43a2c70dae399896ea8a02f622410ef F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84 F src/util.c 0af2e515dc0dabacec931bca39525f6c3f1c5455 F src/vacuum.c 587a52bb8833d7ac15af8916f25437e2575028bd -F src/vdbe.c 64de1142b9f3a84f500a6ce964175c828f1e41da +F src/vdbe.c fd82787f9fb5bfb48dea822d41f28c2a73c25e2e F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb F src/vdbeInt.h a668b303644377433e31a18d3d9efb87eefb6332 F src/vdbeapi.c 4c2418161cf45392ba76a7ca92f9a5f06b96f89c @@ -1013,7 +1013,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 1cb9aedfcf81f0086fa741cb29a062ee87724a5e -R afbad264292e31d19f2e6ab3cf693fdb +P eb0f1c292e6fb00c4d9dbb2317fdc4717c5be96b +R ab65e0d8e1f7196d9ddf588f14254b2c U mistachkin -Z 0cf06bb96aad3721d20115c48db504c9 +Z 38005c55be0cabcef82c948cca80388d diff --git a/manifest.uuid b/manifest.uuid index 5f276e7322..1de6bff72f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eb0f1c292e6fb00c4d9dbb2317fdc4717c5be96b \ No newline at end of file +39866c0ede5d6ef4dd4fd57c797f0e86a2d0dc5d \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 965eec2acc..16815d9d38 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5495,7 +5495,9 @@ case OP_JournalMode: { /* out2-prerelease */ Pager *pPager; /* Pager associated with pBt */ int eNew; /* New journal mode */ int eOld; /* The old journal mode */ +#ifndef SQLITE_OMIT_WAL const char *zFilename; /* Name of database file for pPager */ +#endif eNew = pOp->p3; assert( eNew==PAGER_JOURNALMODE_DELETE From 66498ae87125a3d4bf90ff5a120bef6c68272550 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 13 Sep 2012 16:12:20 +0000 Subject: [PATCH 25/60] Fix WAL capability checking in one of the test files. FossilOrigin-Name: 0ebe7cc57408d6d85910cc976fb8af4436d6e594 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/backcompat.test | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index e68463b53d..7a6df4290d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sunused\svariable\swarning\swith\sSQLITE_OMIT_WAL. -D 2012-09-13T15:26:44.979 +C Fix\sWAL\scapability\schecking\sin\sone\sof\sthe\stest\sfiles. +D 2012-09-13T16:12:20.159 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -286,7 +286,7 @@ F test/autoindex1.test 058d0b331ae6840a61bbee910d8cbae27bfd5991 F test/autovacuum.test fcaf4616ae5bb18098db1cb36262565e5c841c3c F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4 F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85 -F test/backcompat.test e0d5a36828cc338754125059cf354c5813a4405f +F test/backcompat.test ecd841f3a3bfb81518721879cc56a760670e3198 F test/backup.test c9cdd23a495864b9edf75a9fa66f5cb7e10fcf62 F test/backup2.test 34986ef926ea522911a51dfdb2f8e99b7b75ebcf F test/backup_ioerr.test 40d208bc9224b666ee3ed423f49bc9062a36a9d0 @@ -1013,7 +1013,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P eb0f1c292e6fb00c4d9dbb2317fdc4717c5be96b -R ab65e0d8e1f7196d9ddf588f14254b2c +P 39866c0ede5d6ef4dd4fd57c797f0e86a2d0dc5d +R d2910a5e24c19f1da317dcfddcbc3001 U mistachkin -Z 38005c55be0cabcef82c948cca80388d +Z aabb08e0d4d9a13d909ab92ad6b20ffc diff --git a/manifest.uuid b/manifest.uuid index 1de6bff72f..63f1fe1107 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -39866c0ede5d6ef4dd4fd57c797f0e86a2d0dc5d \ No newline at end of file +0ebe7cc57408d6d85910cc976fb8af4436d6e594 \ No newline at end of file diff --git a/test/backcompat.test b/test/backcompat.test index 6c002b8341..dd40fed23a 100644 --- a/test/backcompat.test +++ b/test/backcompat.test @@ -213,8 +213,9 @@ unset ::incompatible # do_allbackcompat_test { if {[code1 {sqlite3 -version}] >= "3.7.0" + && [code1 {set ::sqlite_options(wal)}] && [code2 {sqlite3 -version}] >= "3.7.0" - && [capable wal] + && [code2 {set ::sqlite_options(wal)}] } { do_test backcompat-2.1.1 { sql1 { From 6ec65491583c3aa2aa2a1230ef0d12d54c089dcc Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 13 Sep 2012 19:59:09 +0000 Subject: [PATCH 26/60] Improved alignment of fields in the Expr object gives an 8-byte size reduction on 64-bit machines. FossilOrigin-Name: 6b252a0d1a78db7bf2d650bafc214ea4064eef9e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqliteInt.h | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 7a6df4290d..d6993c1906 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sWAL\scapability\schecking\sin\sone\sof\sthe\stest\sfiles. -D 2012-09-13T16:12:20.159 +C Improved\salignment\sof\sfields\sin\sthe\sExpr\sobject\sgives\san\s8-byte\ssize\nreduction\son\s64-bit\smachines. +D 2012-09-13T19:59:09.165 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -179,7 +179,7 @@ F src/shell.c 87953c5d9c73d9494db97d1607e2e2280418f261 F src/sqlite.h.in d1071b0fc6de9a0d11392bc01305803122c3ec61 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h f31b576c4d72e8baeb52ef7318d202ecc8cae205 +F src/sqliteInt.h 03ad3f925f07599cc39a7eebdb250c7f17fd57e6 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1013,7 +1013,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 39866c0ede5d6ef4dd4fd57c797f0e86a2d0dc5d -R d2910a5e24c19f1da317dcfddcbc3001 -U mistachkin -Z aabb08e0d4d9a13d909ab92ad6b20ffc +P 0ebe7cc57408d6d85910cc976fb8af4436d6e594 +R b742c79022ff08cfe99db98bba004b78 +U drh +Z 3cb58e8f20dd1433c3550c4182838eb5 diff --git a/manifest.uuid b/manifest.uuid index 63f1fe1107..fb4dcf356f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0ebe7cc57408d6d85910cc976fb8af4436d6e594 \ No newline at end of file +6b252a0d1a78db7bf2d650bafc214ea4064eef9e \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 0b87add19a..b42af1f7c5 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1684,6 +1684,9 @@ struct Expr { ** access them will result in a segfault or malfunction. *********************************************************************/ +#if SQLITE_MAX_EXPR_DEPTH>0 + int nHeight; /* Height of the tree headed by this node */ +#endif int iTable; /* TK_COLUMN: cursor number of table holding column ** TK_REGISTER: register number ** TK_TRIGGER: 1 -> new, 0 -> old */ @@ -1697,9 +1700,6 @@ struct Expr { ** TK_AGG_FUNCTION: nesting depth */ AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ Table *pTab; /* Table for TK_COLUMN expressions. */ -#if SQLITE_MAX_EXPR_DEPTH>0 - int nHeight; /* Height of the tree headed by this node */ -#endif }; /* From 5f085269370232e31efc969cb0641ead30cef73d Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 15 Sep 2012 13:29:23 +0000 Subject: [PATCH 27/60] Factor out the code that generates a co-routine for evaluating the SELECT on the RHS of an INSERT statement so that the same code can potentially be reused in other places. FossilOrigin-Name: a93ee09cdc15987848bf9023e69892ce9a5f989e --- manifest | 14 ++--- manifest.uuid | 2 +- src/insert.c | 140 +++++++++++++++++++++++++++++++++--------------- src/sqliteInt.h | 1 + 4 files changed, 105 insertions(+), 52 deletions(-) diff --git a/manifest b/manifest index d6993c1906..1f583a1c34 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\salignment\sof\sfields\sin\sthe\sExpr\sobject\sgives\san\s8-byte\ssize\nreduction\son\s64-bit\smachines. -D 2012-09-13T19:59:09.165 +C Factor\sout\sthe\scode\sthat\sgenerates\sa\sco-routine\sfor\sevaluating\sthe\sSELECT\non\sthe\sRHS\sof\san\sINSERT\sstatement\sso\sthat\sthe\ssame\scode\scan\spotentially\nbe\sreused\sin\sother\splaces. +D 2012-09-15T13:29:23.328 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -138,7 +138,7 @@ F src/global.c 4cfdca5cb0edd33c4d021baec4ede958cb2c793b F src/hash.c a4031441741932da9e7a65bee2b36b5d0e81c073 F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c b090d0a9fb9ff2dbdeaf66aedccf98cd13b1af60 +F src/insert.c 6e2aa7fbb5d4c5f34d412772751ed0aff0b9e87b F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 @@ -179,7 +179,7 @@ F src/shell.c 87953c5d9c73d9494db97d1607e2e2280418f261 F src/sqlite.h.in d1071b0fc6de9a0d11392bc01305803122c3ec61 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h 03ad3f925f07599cc39a7eebdb250c7f17fd57e6 +F src/sqliteInt.h 0423f0a673e7365827584e86dfbab8c33cf32cf8 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1013,7 +1013,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 0ebe7cc57408d6d85910cc976fb8af4436d6e594 -R b742c79022ff08cfe99db98bba004b78 +P 6b252a0d1a78db7bf2d650bafc214ea4064eef9e +R df7cddb2132aa1a021f32020fc480477 U drh -Z 3cb58e8f20dd1433c3550c4182838eb5 +Z c609d2d14d939fff56bf9fbc82b9e705 diff --git a/manifest.uuid b/manifest.uuid index fb4dcf356f..904fea2c79 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6b252a0d1a78db7bf2d650bafc214ea4064eef9e \ No newline at end of file +a93ee09cdc15987848bf9023e69892ce9a5f989e \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index a24e8f9481..969f9fcf64 100644 --- a/src/insert.c +++ b/src/insert.c @@ -320,6 +320,97 @@ void sqlite3AutoincrementEnd(Parse *pParse){ #endif /* SQLITE_OMIT_AUTOINCREMENT */ +/* +** Generate code for a co-routine that will evaluate a subquery one +** row at a time. +** +** The pSelect parameter is the subquery that the co-routine will evaluation. +** Information about the location of co-routine and the registers it will use +** is returned by filling in the pDest object. +** +** Registers are allocated as follows: +** +** pDest->iSDParm The register holding the next entry-point of the +** co-routine. Run the co-routine to its next breakpoint +** by calling "OP_Yield $X" where $X is pDest->iSDParm. +** +** pDest->iSDParm+1 The register holding the "completed" flag for the +** co-routine. This register is 0 if the previous Yield +** generated a new result row, or 1 if the subquery +** has completed. If the Yield is called again +** after this register becomes 1, then the VDBE will +** halt with an SQLITE_INTERNAL error. +** +** pDest->iSdst First result register. +** +** pDest->nSdst Number of result registers. +** +** This routine handles all of the register allocation and fills in the +** pDest structure appropriately. +** +** Here is a schematic of the generated code assuming that X is the +** co-routine entry-point register reg[pDest->iSDParm], that EOF is the +** completed flag reg[pDest->iSDParm+1], and R and S are the range of +** registers that hold the result set, reg[pDest->iSdst] through +** reg[pDest->iSdst+pDest->nSdst-1]: +** +** X <- A +** EOF <- 0 +** goto B +** A: setup for the SELECT +** loop rows in the SELECT +** load results into registers R..S +** yield X +** end loop +** cleanup after the SELECT +** EOF <- 1 +** yield X +** halt-error +** B: +** +** To use this subroutine, the caller generates code as follows: +** +** [ Co-routine generated by this subroutine, shown above ] +** S: yield X +** if EOF goto E +** if skip this row, goto C +** if terminate loop, goto E +** deal with this row +** C: goto S +** E: +*/ +int sqlite3CodeCoroutine(Parse *pParse, Select *pSelect, SelectDest *pDest){ + int regYield; /* Register holding co-routine entry-point */ + int regEof; /* Register holding co-routine completion flag */ + int addrTop; /* Top of the co-routine */ + int j1; /* Jump instruction */ + int rc; /* Result code */ + Vdbe *v; /* VDBE under construction */ + + regYield = ++pParse->nMem; + regEof = ++pParse->nMem; + v = sqlite3GetVdbe(pParse); + addrTop = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_Integer, addrTop+2, regYield); /* X <- A */ + VdbeComment((v, "Co-routine entry point")); + sqlite3VdbeAddOp2(v, OP_Integer, 0, regEof); /* EOF <- 0 */ + VdbeComment((v, "Co-routine completion flag")); + sqlite3SelectDestInit(pDest, SRT_Coroutine, regYield); + j1 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); + rc = sqlite3Select(pParse, pSelect, pDest); + assert( pParse->nErr==0 || rc ); + if( pParse->db->mallocFailed && rc==SQLITE_OK ) rc = SQLITE_NOMEM; + if( rc ) return rc; + sqlite3VdbeAddOp2(v, OP_Integer, 1, regEof); /* EOF <- 1 */ + sqlite3VdbeAddOp1(v, OP_Yield, regYield); /* yield X */ + sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_INTERNAL, OE_Abort); + VdbeComment((v, "End of coroutine")); + sqlite3VdbeJumpHere(v, j1); /* label B: */ + return rc; +} + + + /* Forward declaration */ static int xferOptimization( Parse *pParse, /* Parser context */ @@ -568,51 +659,12 @@ void sqlite3Insert( ** co-routine is the common header to the 3rd and 4th templates. */ if( pSelect ){ - /* Data is coming from a SELECT. Generate code to implement that SELECT - ** as a co-routine. The code is common to both the 3rd and 4th - ** templates: - ** - ** EOF <- 0 - ** X <- A - ** goto B - ** A: setup for the SELECT - ** loop over the tables in the SELECT - ** load value into register R..R+n - ** yield X - ** end loop - ** cleanup after the SELECT - ** EOF <- 1 - ** yield X - ** halt-error - ** - ** On each invocation of the co-routine, it puts a single row of the - ** SELECT result into registers dest.iMem...dest.iMem+dest.nMem-1. - ** (These output registers are allocated by sqlite3Select().) When - ** the SELECT completes, it sets the EOF flag stored in regEof. - */ - int rc, j1; - - regEof = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_Integer, 0, regEof); /* EOF <- 0 */ - VdbeComment((v, "SELECT eof flag")); - sqlite3SelectDestInit(&dest, SRT_Coroutine, ++pParse->nMem); - addrSelect = sqlite3VdbeCurrentAddr(v)+2; - sqlite3VdbeAddOp2(v, OP_Integer, addrSelect-1, dest.iSDParm); - j1 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); - VdbeComment((v, "Jump over SELECT coroutine")); - - /* Resolve the expressions in the SELECT statement and execute it. */ - rc = sqlite3Select(pParse, pSelect, &dest); - assert( pParse->nErr==0 || rc ); - if( rc || NEVER(pParse->nErr) || db->mallocFailed ){ - goto insert_cleanup; - } - sqlite3VdbeAddOp2(v, OP_Integer, 1, regEof); /* EOF <- 1 */ - sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); /* yield X */ - sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_INTERNAL, OE_Abort); - VdbeComment((v, "End of SELECT coroutine")); - sqlite3VdbeJumpHere(v, j1); /* label B: */ + /* Data is coming from a SELECT. Generate a co-routine to run that + ** SELECT. */ + int rc = sqlite3CodeCoroutine(pParse, pSelect, &dest); + if( rc ) goto insert_cleanup; + regEof = dest.iSDParm + 1; regFromSelect = dest.iSdst; assert( pSelect->pEList ); nColumn = pSelect->pEList->nExpr; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index b42af1f7c5..6f6bfdb148 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2780,6 +2780,7 @@ void sqlite3DeleteTable(sqlite3*, Table*); # define sqlite3AutoincrementBegin(X) # define sqlite3AutoincrementEnd(X) #endif +int sqlite3CodeCoroutine(Parse*, Select*, SelectDest*); void sqlite3Insert(Parse*, SrcList*, ExprList*, Select*, IdList*, int); void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*); IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*); From 55b4c226d1e505e8c4a8d67458dec9765ced22da Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 15 Sep 2012 13:39:24 +0000 Subject: [PATCH 28/60] Make sure the name of rollback journal files are double-zero terminated when they are passed into the VFS. FossilOrigin-Name: 8711a8447d28275602287faf533de3d6e50d535d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 1f583a1c34..816c07ad80 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Factor\sout\sthe\scode\sthat\sgenerates\sa\sco-routine\sfor\sevaluating\sthe\sSELECT\non\sthe\sRHS\sof\san\sINSERT\sstatement\sso\sthat\sthe\ssame\scode\scan\spotentially\nbe\sreused\sin\sother\splaces. -D 2012-09-15T13:29:23.328 +C Make\ssure\sthe\sname\sof\srollback\sjournal\sfiles\sare\sdouble-zero\sterminated\nwhen\sthey\sare\spassed\sinto\sthe\sVFS. +D 2012-09-15T13:39:24.735 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -162,7 +162,7 @@ F src/os.h 027491c77d2404c0a678bb3fb06286f331eb9b57 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c 69b2fe66316524eebf5f1ce85c1fdfe2952307e9 F src/os_win.c 90c7a1fe2698867555ba4266f5bd436c85d0d1dc -F src/pager.c 5665fa9ecec51f11dabdfd8eefefa89391856007 +F src/pager.c 9c59818c480261c1c5a4772532e0df92a27745a1 F src/pager.h 8b8c9bc065a3c66769df8724dfdf492ee1aab3c5 F src/parse.y f29df90bd3adc64b33114ab1de9fb7768fcf2099 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 @@ -1013,7 +1013,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 6b252a0d1a78db7bf2d650bafc214ea4064eef9e -R df7cddb2132aa1a021f32020fc480477 +P a93ee09cdc15987848bf9023e69892ce9a5f989e +R ecaebb814f51bb6e38f5c9d70e5c1467 U drh -Z c609d2d14d939fff56bf9fbc82b9e705 +Z a699a11a3dac3cfd2b9a3a76bfd53ddc diff --git a/manifest.uuid b/manifest.uuid index 904fea2c79..e60e09e0ac 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a93ee09cdc15987848bf9023e69892ce9a5f989e \ No newline at end of file +8711a8447d28275602287faf533de3d6e50d535d \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 09c2a5f90d..a094e0da20 100644 --- a/src/pager.c +++ b/src/pager.c @@ -4448,7 +4448,7 @@ int sqlite3PagerOpen( memcpy(pPager->zFilename, zPathname, nPathname); if( nUri ) memcpy(&pPager->zFilename[nPathname+1], zUri, nUri); memcpy(pPager->zJournal, zPathname, nPathname); - memcpy(&pPager->zJournal[nPathname], "-journal\000", 8+1); + memcpy(&pPager->zJournal[nPathname], "-journal\000", 8+2); sqlite3FileSuffix3(pPager->zFilename, pPager->zJournal); #ifndef SQLITE_OMIT_WAL pPager->zWal = &pPager->zJournal[nPathname+8+1]; From 3f4d1d1b02cf6416049cf15d21da7f0952fa2ce2 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 15 Sep 2012 18:45:54 +0000 Subject: [PATCH 29/60] Attempt to use a covering index even on a full table scan, under the theory that the index will be smaller and require less disk I/O and thus be faster. FossilOrigin-Name: cfaa7bc12847a7006ccc93815f2395ad5259744a --- manifest | 55 +++++++++++++++++++++------------------- manifest.uuid | 2 +- src/where.c | 31 +++++++++++++++++----- test/analyze6.test | 4 +-- test/autovacuum.test | 2 +- test/collate4.test | 25 ++++++++++-------- test/corruptD.test | 4 +-- test/corruptE.test | 2 +- test/distinct.test | 2 +- test/e_createtable.test | 2 +- test/e_fkey.test | 8 +++--- test/e_select.test | 2 +- test/eqp.test | 16 ++++++------ test/incrblob.test | 2 +- test/intpkey.test | 2 +- test/like.test | 6 ++--- test/stat.test | 15 +++++++---- test/tkt-385a5b56b9.test | 3 +-- test/tkt-78e04e52ea.test | 2 +- test/triggerC.test | 16 ++++++------ test/unordered.test | 2 +- test/where.test | 10 ++++---- test/where9.test | 2 +- 23 files changed, 121 insertions(+), 94 deletions(-) diff --git a/manifest b/manifest index 816c07ad80..d4a4939a51 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthe\sname\sof\srollback\sjournal\sfiles\sare\sdouble-zero\sterminated\nwhen\sthey\sare\spassed\sinto\sthe\sVFS. -D 2012-09-15T13:39:24.735 +C Attempt\sto\suse\sa\scovering\sindex\seven\son\sa\sfull\stable\sscan,\sunder\sthe\stheory\nthat\sthe\sindex\swill\sbe\ssmaller\sand\srequire\sless\sdisk\sI/O\sand\sthus\sbe\sfaster. +D 2012-09-15T18:45:54.834 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -249,7 +249,7 @@ F src/vtab.c d8020c0a0e8ccc490ca449d7e665311b6e9f3ba9 F src/wal.c 5acb3e7bbd31f10ba39acad9ce6b399055337a9d F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b -F src/where.c 22783f4275f6fc09b663115a6091837cb5c510e0 +F src/where.c 0d9970a606d64559a969b9d663ed2db7439c6668 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 0be144b453e0622a085fae8665c32f5676708e00 @@ -264,7 +264,7 @@ F test/analyze.test f8ab7d15858b4093b06caf5e57e2a5ff7104bdae F test/analyze3.test c3c7f6c3951900c188cf94b2d5ee3246d6b3ff89 F test/analyze4.test 757b37875cf9bb528d46f74497bc789c88365045 F test/analyze5.test 713354664c5ff1853ab2cbcb740f0cf5cb7c802e -F test/analyze6.test bd3625806a5ee6f7bef72d06295bd319f0290af2 +F test/analyze6.test aa8dae5066bbed35c5f45a507fb87f2d342f2c99 F test/analyze7.test d3587aa5af75c9048d031b94fceca2534fa75d1d F test/analyze8.test 4ca170de2ba30ccb1af2c0406803db72262f9691 F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b @@ -283,7 +283,7 @@ F test/auth2.test 270baddc8b9c273682760cffba6739d907bd2882 F test/auth3.test a4755e6a2a2fea547ffe63c874eb569e60a28eb5 F test/autoinc.test bd30d372d00045252f6c2e41b5f41455e1975acf F test/autoindex1.test 058d0b331ae6840a61bbee910d8cbae27bfd5991 -F test/autovacuum.test fcaf4616ae5bb18098db1cb36262565e5c841c3c +F test/autovacuum.test 9f22a7733f39c56ef6a5665d10145ac25d8cb574 F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4 F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85 F test/backcompat.test ecd841f3a3bfb81518721879cc56a760670e3198 @@ -324,7 +324,7 @@ F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91 F test/collate1.test e3eaa48c21e150814be1a7b852d2a8af24458d04 F test/collate2.test 04cebe4a033be319d6ddbb3bbc69464e01700b49 F test/collate3.test d28d2cfab2c3a3d4628ae4b2b7afc9965daa3b4c -F test/collate4.test 3d3f123f83fd8ccda6f48d617e44e661b9870c7d +F test/collate4.test d37682293d3c32223dec2e6afdeaf9de18415248 F test/collate5.test 67f1d3e848e230ff4802815a79acb0a8b5e69bd7 F test/collate6.test 8be65a182abaac8011a622131486dafb8076e907 F test/collate7.test 8ec29d98f3ee4ccebce6e16ce3863fb6b8c7b868 @@ -346,8 +346,8 @@ F test/corrupt9.test 959179e68dc0b7b99f424cf3e0381c86dcdd0112 F test/corruptA.test fafa652aa585753be4f6b62ff0bb250266eaf7ce F test/corruptB.test 20d4a20cbed23958888c3e8995b424a47223d647 F test/corruptC.test 62a767fe64acb1975f58cc6171192839c783edbb -F test/corruptD.test 99b1999dbfa7cc04aaeac9d695a2445d4e7c7458 -F test/corruptE.test 1b9eb20a8711251ce57b44a257e241085b39b52d +F test/corruptD.test 3b09903a2e2fe07ecafe775fea94177f8a4bb34f +F test/corruptE.test d3a3d7e864a95978195741744dda4abfd8286018 F test/corruptF.test 984b1706c9c0e4248141b056c21124612628d12e F test/count.test 454e1ce985c94d13efeac405ce54439f49336163 F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f @@ -373,19 +373,19 @@ F test/descidx1.test 533dcbda614b0463b0ea029527fd27e5a9ab2d66 F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d F test/descidx3.test fe720e8b37d59f4cef808b0bf4e1b391c2e56b6f F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e -F test/distinct.test da36612d05b9ed17e0425d4bfd7ab978d28a7e46 +F test/distinct.test 328c3930fc00da96147351aa48f91bd085ed226a F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376 -F test/e_createtable.test 48598b15e8fe6554d301e7b65a10c9851f177e84 +F test/e_createtable.test 0a2465736199cb5e084645a8714ee04299b81721 F test/e_delete.test 89aa84d3d1bd284a0689ede04bce10226a5aeaa5 F test/e_droptrigger.test afd5c4d27dec607f5997a66bf7e2498a082cb235 F test/e_dropview.test 583411e470458c5d76148542cfb5a5fa84c8f93e F test/e_expr.test 5489424d3d9a452ac3701cdf4b680ae31a157894 -F test/e_fkey.test 057eed81a41a2b21b1790032f4e8aaba0b2b0e17 +F test/e_fkey.test a79ab1d3213c7ac64621eec28f8e8bb219775445 F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459 F test/e_insert.test c6ac239a97cb16dfbd0c16496f8cd871b4068c0c F test/e_reindex.test dfedfc32c5a282b0596c6537cbcd4217fbb1a216 F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6 -F test/e_select.test f5d4b81205701deacfae42051ae200969c41d2c0 +F test/e_select.test 69013a64b469458820abb7f3281a7eaa6c1fda76 F test/e_select2.test 5c3d3da19c7b3e90ae444579db2b70098599ab92 F test/e_update.test 161d5dc6a3ed9dd08f5264d13e20735d7a89f00c F test/e_uri.test 9e190ca799d9190eec6e43f2aadf1d10c06a57a3 @@ -394,7 +394,7 @@ F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea F test/enc2.test 796c59832e2b9a52842f382ffda8f3e989db03ad F test/enc3.test 90683ad0e6ea587b9d5542ca93568af9a9858c40 F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020 -F test/eqp.test 6a389bba6ea113fd5179515001be788a38d53ec7 +F test/eqp.test 103243f86c2ab85dac79eef5b6a80c333407504e F test/errmsg.test 3bb606db9d040cc6854459f8f5e5a2bcd9b7fd2a F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3 F test/exclusive.test a1b324cb21834a490cd052d409d34789cfef57cb @@ -519,7 +519,7 @@ F test/in.test 5941096407d8c133b9eff15bd3e666624b6cbde3 F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0 F test/in4.test 64f3cc1acde1b9161ccdd8e5bde3daefdb5b2617 -F test/incrblob.test 26fde912a1e0aff158b3a84ef3b265f046aad3be +F test/incrblob.test 34765fa6fb5d8e0f256fc7d6497c04b205398849 F test/incrblob2.test edc3a96e557bd61fb39acc8d2edd43371fbbaa19 F test/incrblob3.test aedbb35ea1b6450c33b98f2b6ed98e5020be8dc7 F test/incrblob4.test 09be37d3dd996a31ea6993bba7837ece549414a8 @@ -543,7 +543,7 @@ F test/insert4.test 87f6798f31d60c4e177622fcc3663367e6ecbd90 F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6 F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4 F test/interrupt.test 42e7cf98646fd9cb4a3b131a93ed3c50b9e149f1 -F test/intpkey.test 537669fd535f62632ca64828e435b9e54e8d677f +F test/intpkey.test 7af30f6ae852d8d1c2b70e4bf1551946742e92d8 F test/io.test 36d251507d72e92b965fb2f0801c2f0b56335bcf F test/ioerr.test 40bb2cfcab63fb6aa7424cd97812a84bc16b5fb8 F test/ioerr2.test 9d71166f8466eda510f1af6137bdabaa82b5408d @@ -565,7 +565,7 @@ F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa F test/keyword1.test a2400977a2e4fde43bf33754c2929fda34dbca05 F test/lastinsert.test 474d519c68cb79d07ecae56a763aa7f322c72f51 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 -F test/like.test 7b4aaa4a8192fdec90e0a905984c92a688c51e48 +F test/like.test 0e5412f4dac4a849f613e1ef8b529d56a6e31d08 F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da F test/limit.test 2db7b3b34fb925b8e847d583d2eb67531d0ce67e F test/loadext.test 2b5e249c51c986a5aff1f0950cf7ba30976c8f22 @@ -721,7 +721,7 @@ F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b F test/spellfix.test 2953e9da0e46dab5f83059ef6bfdebca66e13418 F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 -F test/stat.test 08e8185b3fd5b010c90d7ad82b9dd4ea1cbf14b0 +F test/stat.test be8d477306006ec696bc86757cfb34bec79447ce F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9 F test/subquery.test d4aea23ac267463d4aa604bf937c3992347b20f7 F test/subquery2.test edcad5c118f0531c2e21bf16a09bbb105252d4cd @@ -756,7 +756,7 @@ F test/tkt-2d1a5c67d.test b028a811049eb472cb2d3a43fc8ce4f6894eebda F test/tkt-2ea2425d34.test 1cf13e6f75d149b3209a0cb32927a82d3d79fb28 F test/tkt-31338dca7e.test 1f714c14b6682c5db715e0bda347926a3456f7a9 F test/tkt-313723c356.test c47f8a9330523e6f35698bf4489bcb29609b53ac -F test/tkt-385a5b56b9.test 8eb87c4bbcc3fd4f33d73719de7e9d64973fa196 +F test/tkt-385a5b56b9.test 7782a382912a51f09f1d1a1442bca1e75f9c549b F test/tkt-38cb5df375.test f3cc8671f1eb604d4ae9cf886ed4366bec656678 F test/tkt-3998683a16.test 6d1d04d551ed1704eb3396ca87bb9ccc8c5c1eb7 F test/tkt-3a77c9714e.test 32bb28afa8c63fc76e972e996193139b63551ed9 @@ -767,7 +767,7 @@ F test/tkt-5d863f876e.test c9f36ca503fa154a3655f92a69d2c30da1747bfa F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84 F test/tkt-5ee23731f.test 9db6e1d7209dc0794948b260d6f82b2b1de83a9f F test/tkt-752e1646fc.test ea78d88d14fe9866bdd991c634483334639e13bf -F test/tkt-78e04e52ea.test ab52f0c1e2de6e46c910f4cc16b086bba05952b7 +F test/tkt-78e04e52ea.test 703e0bfb23d543edf0426a97e3bbd0ca346508ec F test/tkt-7bbfb7d442.test dfa5c8097a8c353ae40705d6cddeb1f99c18b81a F test/tkt-80ba201079.test 105a721e6aad0ae3c5946d7615d1e4d03f6145b8 F test/tkt-80e031a00f.test 9a154173461a4dbe2de49cda73963e04842d52f7 @@ -891,7 +891,7 @@ F test/trigger8.test 30cb0530bd7c4728055420e3f739aa00412eafa4 F test/trigger9.test 5b0789f1c5c4600961f8e68511b825b87be53e31 F test/triggerA.test e0aaba16d3547193d36bbd82a1b0ed75e9c88d40 F test/triggerB.test 56780c031b454abac2340dbb3b71ac5c56c3d7fe -F test/triggerC.test 4d4bdaf0230c206b50d350330107ef9802bc2d4f +F test/triggerC.test 29173df06f8e91bec2b95ea7048b30d1e1c7b9db F test/triggerD.test 8e7f3921a92a5797d472732108109e44575fa650 F test/tt3_checkpoint.c 415eccce672d681b297485fc20f44cdf0eac93af F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff @@ -899,7 +899,7 @@ F test/types2.test 3555aacf8ed8dc883356e59efc314707e6247a84 F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a F test/unique.test 083c7fff74695bcc27a71d75699deba3595bc9c2 F test/unixexcl.test a9870e46cc6f8390a494513d4f2bf55b5a8b3e46 -F test/unordered.test f53095cee37851bf30130fa1bf299a8845e837bb +F test/unordered.test 93dce7b6c97a817a4fe26980c484605a4511f614 F test/update.test 8bc86fd7ef1a00014f76dc6a6a7c974df4aef172 F test/uri.test 63e03df051620a18f794b4f4adcdefb3c23b6751 F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae @@ -952,7 +952,7 @@ F test/walro.test a31deb621033442a76c3a61e44929250d06f81b1 F test/walshared.test 6dda2293880c300baf5d791c307f653094585761 F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e -F test/where.test 4c9f69987ed2aa0173fa930f2b41ab9879478cd8 +F test/where.test 59cf231e6edaf0f20b106a26d4294847e7c6eb25 F test/where2.test 43d4becaf5a5df854e6c21d624a1cb84c6904554 F test/where3.test 667e75642102c97a00bf9b23d3cb267db321d006 F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2 @@ -961,7 +961,7 @@ F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b F test/where7.test 5c566388f0cc318b0032ce860f4ac5548e3c265a F test/where8.test a6c740fd286d7883e274e17b6230a9d672a7ab1f F test/where8m.test da346596e19d54f0aba35ebade032a7c47d79739 -F test/where9.test ae98dc22ef9b6f2bc81e9f164e41b38faa9bda06 +F test/where9.test bcab47eff78f1412a6aec1d6b8a3939d4a9db098 F test/whereA.test 24c234263c8fe358f079d5e57d884fb569d2da0a F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5 F test/whereC.test 13ff5ec0dba407c0e0c075980c75b3275a6774e5 @@ -1013,7 +1013,10 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P a93ee09cdc15987848bf9023e69892ce9a5f989e -R ecaebb814f51bb6e38f5c9d70e5c1467 +P 8711a8447d28275602287faf533de3d6e50d535d +R 2846d857dac01099378b7c9963f9bce9 +T *branch * fullscan-covering-index +T *sym-fullscan-covering-index * +T -sym-trunk * U drh -Z a699a11a3dac3cfd2b9a3a76bfd53ddc +Z 9efee896d171017e16fb900a826f2665 diff --git a/manifest.uuid b/manifest.uuid index e60e09e0ac..88bb4d6dd1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8711a8447d28275602287faf533de3d6e50d535d \ No newline at end of file +cfaa7bc12847a7006ccc93815f2395ad5259744a \ No newline at end of file diff --git a/src/where.c b/src/where.c index 9bbbd43d10..c28386e29f 100644 --- a/src/where.c +++ b/src/where.c @@ -264,6 +264,7 @@ struct WhereCost { #define WHERE_MULTI_OR 0x10000000 /* OR using multiple indices */ #define WHERE_TEMP_INDEX 0x20000000 /* Uses an ephemeral index */ #define WHERE_DISTINCT 0x40000000 /* Correct order for DISTINCT */ +#define WHERE_COVER_SCAN 0x80000000 /* Full scan of a covering index */ /* ** Initialize a preallocated WhereClause structure. @@ -3133,7 +3134,7 @@ static void bestBtreeIndex( ** using the main table (i.e. if the index is a covering ** index for this query). If it is, set the WHERE_IDX_ONLY flag in ** wsFlags. Otherwise, set the bLookup variable to true. */ - if( pIdx && wsFlags ){ + if( pIdx ){ Bitmask m = pSrc->colUsed; int j; for(j=0; jnColumn; j++){ @@ -3198,7 +3199,16 @@ static void bestBtreeIndex( ** So this computation assumes table records are about twice as big ** as index records */ - if( (wsFlags & WHERE_NOT_FULLSCAN)==0 ){ + if( wsFlags==WHERE_IDX_ONLY + && (pWC->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 + ){ + /* This index is not useful for indexing, but it is a covering index. + ** A full-scan of the index might be a little faster than a full-scan + ** of the table, so give this case a cost slightly less than a table + ** scan. */ + cost = aiRowEst[0]*3; + wsFlags |= WHERE_COVER_SCAN|WHERE_COLUMN_RANGE; + }else if( (wsFlags & WHERE_NOT_FULLSCAN)==0 ){ /* The cost of a full table scan is a number of move operations equal ** to the number of rows in the table. ** @@ -4252,6 +4262,11 @@ static Bitmask codeOneLoopStart( pLevel->op = OP_Next; } pLevel->p1 = iIdxCur; + if( pLevel->plan.wsFlags & WHERE_COVER_SCAN ){ + pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; + }else{ + assert( pLevel->p5==0 ); + } }else #ifndef SQLITE_OMIT_OR_OPTIMIZATION @@ -5128,13 +5143,15 @@ WhereInfo *sqlite3WhereBegin( for(i=0; ia[i]; + w = pLevel->plan.wsFlags; pTabItem = &pTabList->a[pLevel->iFrom]; z = pTabItem->zAlias; if( z==0 ) z = pTabItem->pTab->zName; n = sqlite3Strlen30(z); if( n+nQPlan < sizeof(sqlite3_query_plan)-10 ){ - if( pLevel->plan.wsFlags & WHERE_IDX_ONLY ){ + if( (w & WHERE_IDX_ONLY)!=0 && (w & WHERE_COVER_SCAN)==0 ){ memcpy(&sqlite3_query_plan[nQPlan], "{}", 2); nQPlan += 2; }else{ @@ -5143,12 +5160,12 @@ WhereInfo *sqlite3WhereBegin( } sqlite3_query_plan[nQPlan++] = ' '; } - testcase( pLevel->plan.wsFlags & WHERE_ROWID_EQ ); - testcase( pLevel->plan.wsFlags & WHERE_ROWID_RANGE ); - if( pLevel->plan.wsFlags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){ + testcase( w & WHERE_ROWID_EQ ); + testcase( w & WHERE_ROWID_RANGE ); + if( w & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){ memcpy(&sqlite3_query_plan[nQPlan], "* ", 2); nQPlan += 2; - }else if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){ + }else if( (w & WHERE_INDEXED)!=0 && (w & WHERE_COVER_SCAN)==0 ){ n = sqlite3Strlen30(pLevel->plan.u.pIdx->zName); if( n+nQPlan < sizeof(sqlite3_query_plan)-2 ){ memcpy(&sqlite3_query_plan[nQPlan], pLevel->plan.u.pIdx->zName, n); diff --git a/test/analyze6.test b/test/analyze6.test index 74b7ec7984..eaa9d731b0 100644 --- a/test/analyze6.test +++ b/test/analyze6.test @@ -61,14 +61,14 @@ do_test analyze6-1.0 { # do_test analyze6-1.1 { eqp {SELECT count(*) FROM ev, cat WHERE x=y} -} {0 0 1 {SCAN TABLE cat (~16 rows)} 0 1 0 {SEARCH TABLE ev USING COVERING INDEX evy (y=?) (~32 rows)}} +} {0 0 1 {SCAN TABLE cat USING COVERING INDEX catx (~16 rows)} 0 1 0 {SEARCH TABLE ev USING COVERING INDEX evy (y=?) (~32 rows)}} # The same plan is chosen regardless of the order of the tables in the # FROM clause. # do_test analyze6-1.2 { eqp {SELECT count(*) FROM cat, ev WHERE x=y} -} {0 0 0 {SCAN TABLE cat (~16 rows)} 0 1 1 {SEARCH TABLE ev USING COVERING INDEX evy (y=?) (~32 rows)}} +} {0 0 0 {SCAN TABLE cat USING COVERING INDEX catx (~16 rows)} 0 1 1 {SEARCH TABLE ev USING COVERING INDEX evy (y=?) (~32 rows)}} # Ticket [83ea97620bd3101645138b7b0e71c12c5498fe3d] 2011-03-30 diff --git a/test/autovacuum.test b/test/autovacuum.test index 1aef18f33e..bba40e3013 100644 --- a/test/autovacuum.test +++ b/test/autovacuum.test @@ -114,7 +114,7 @@ foreach delete_order $delete_orders { } do_test autovacuum-1.$tn.($delete).3 { execsql { - select a from av1 + select a from av1 order by rowid } } $::tbl_data } diff --git a/test/collate4.test b/test/collate4.test index 12bc16ef2e..6b3a1c7aee 100644 --- a/test/collate4.test +++ b/test/collate4.test @@ -94,7 +94,7 @@ do_test collate4-1.1.5 { cksort {SELECT b FROM collate4t1 ORDER BY b COLLATE TEXT} } {{} A B a b nosort} do_test collate4-1.1.6 { - cksort {SELECT b FROM collate4t1 ORDER BY b COLLATE NOCASE} + cksort {SELECT b FROM collate4t1 ORDER BY b COLLATE NOCASE, rowid} } {{} a A b B sort} do_test collate4-1.1.7 { @@ -171,13 +171,13 @@ do_test collate4-1.1.21 { } } {} do_test collate4-1.1.22 { - cksort {SELECT a FROM collate4t4 ORDER BY a} + cksort {SELECT a FROM collate4t4 ORDER BY a, rowid} } {{} a A b B sort} do_test collate4-1.1.23 { - cksort {SELECT a FROM collate4t4 ORDER BY a COLLATE NOCASE} + cksort {SELECT a FROM collate4t4 ORDER BY a COLLATE NOCASE, rowid} } {{} a A b B sort} do_test collate4-1.1.24 { - cksort {SELECT a FROM collate4t4 ORDER BY a COLLATE TEXT} + cksort {SELECT a FROM collate4t4 ORDER BY a COLLATE TEXT, rowid} } {{} A B a b nosort} do_test collate4-1.1.25 { cksort {SELECT b FROM collate4t4 ORDER BY b} @@ -222,7 +222,7 @@ do_test collate4-1.2.4 { cksort {SELECT a FROM collate4t1 ORDER BY a, b} } {{} A a B b nosort} do_test collate4-1.2.5 { - cksort {SELECT a FROM collate4t1 ORDER BY a, b COLLATE nocase} + cksort {SELECT a FROM collate4t1 ORDER BY a, b COLLATE nocase, rowid} } {{} a A b B sort} do_test collate4-1.2.6 { cksort {SELECT a FROM collate4t1 ORDER BY a, b COLLATE text} @@ -271,10 +271,10 @@ do_test collate4-1.2.14 { } } {} do_test collate4-1.2.15 { - cksort {SELECT a FROM collate4t3 ORDER BY a} + cksort {SELECT a FROM collate4t3 ORDER BY a, rowid} } {{} a A b B sort} do_test collate4-1.2.16 { - cksort {SELECT a FROM collate4t3 ORDER BY a COLLATE nocase} + cksort {SELECT a FROM collate4t3 ORDER BY a COLLATE nocase, rowid} } {{} a A b B sort} do_test collate4-1.2.17 { cksort {SELECT a FROM collate4t3 ORDER BY a COLLATE text} @@ -364,7 +364,8 @@ do_test collate4-2.1.4 { CREATE INDEX collate4i1 ON collate4t1(a COLLATE TEXT); } count { - SELECT * FROM collate4t2, collate4t1 WHERE a = b; + SELECT * FROM collate4t2, collate4t1 WHERE a = b + ORDER BY collate4t2.rowid, collate4t1.rowid } } {A a A A 19} do_test collate4-2.1.5 { @@ -375,7 +376,8 @@ do_test collate4-2.1.5 { ifcapable subquery { do_test collate4-2.1.6 { count { - SELECT a FROM collate4t1 WHERE a IN (SELECT * FROM collate4t2); + SELECT a FROM collate4t1 WHERE a IN (SELECT * FROM collate4t2) + ORDER BY rowid } } {a A 10} do_test collate4-2.1.7 { @@ -384,7 +386,8 @@ ifcapable subquery { CREATE INDEX collate4i1 ON collate4t1(a); } count { - SELECT a FROM collate4t1 WHERE a IN (SELECT * FROM collate4t2); + SELECT a FROM collate4t1 WHERE a IN (SELECT * FROM collate4t2) + ORDER BY rowid } } {a A 6} do_test collate4-2.1.8 { @@ -398,7 +401,7 @@ ifcapable subquery { CREATE INDEX collate4i1 ON collate4t1(a COLLATE TEXT); } count { - SELECT a FROM collate4t1 WHERE a IN ('z', 'a'); + SELECT a FROM collate4t1 WHERE a IN ('z', 'a') ORDER BY rowid; } } {a A 9} } diff --git a/test/corruptD.test b/test/corruptD.test index 393d41ee36..2423cd428e 100644 --- a/test/corruptD.test +++ b/test/corruptD.test @@ -107,12 +107,12 @@ proc restore_file {} { do_test corruptD-1.1.1 { incr_change_counter hexio_write test.db [expr 1024+1] FFFF - catchsql { SELECT * FROM t1 } + catchsql { SELECT * FROM t1 ORDER BY rowid } } {1 {database disk image is malformed}} do_test corruptD-1.1.2 { incr_change_counter hexio_write test.db [expr 1024+1] [hexio_render_int32 1021] - catchsql { SELECT * FROM t1 } + catchsql { SELECT * FROM t1 ORDER BY rowid } } {1 {database disk image is malformed}} #------------------------------------------------------------------------- diff --git a/test/corruptE.test b/test/corruptE.test index 507721d85e..48292ab2e9 100644 --- a/test/corruptE.test +++ b/test/corruptE.test @@ -49,7 +49,7 @@ do_test corruptE-1.1 { INSERT OR IGNORE INTO t1 SELECT x*17,y FROM t1; INSERT OR IGNORE INTO t1 SELECT x*19,y FROM t1; CREATE INDEX t1i1 ON t1(x); - CREATE TABLE t2 AS SELECT x,2 as y FROM t1 WHERE rowid%5!=0; + CREATE TABLE t2 AS SELECT x,2 as y FROM t1 WHERE rowid%5!=0 ORDER BY rowid; COMMIT; } } {} diff --git a/test/distinct.test b/test/distinct.test index 3a33544561..1e87246cf4 100644 --- a/test/distinct.test +++ b/test/distinct.test @@ -175,7 +175,7 @@ foreach {tn sql temptables res} { } do_execsql_test 2.A { - SELECT (SELECT DISTINCT o.a FROM t1 AS i) FROM t1 AS o; + SELECT (SELECT DISTINCT o.a FROM t1 AS i) FROM t1 AS o ORDER BY rowid; } {a A a A} diff --git a/test/e_createtable.test b/test/e_createtable.test index 8221828153..35f7330c4b 100644 --- a/test/e_createtable.test +++ b/test/e_createtable.test @@ -1591,7 +1591,7 @@ foreach {tn tbl res ac data} { " $res do_test e_createtable-4.17.$tn.3 { sqlite3_get_autocommit db } $ac - do_execsql_test 4.17.$tn.4 "SELECT * FROM $tbl" $data + do_execsql_test 4.17.$tn.4 "SELECT * FROM $tbl ORDER BY rowid" $data } catchsql COMMIT diff --git a/test/e_fkey.test b/test/e_fkey.test index 5b27e03b5a..69e0868642 100644 --- a/test/e_fkey.test +++ b/test/e_fkey.test @@ -2060,7 +2060,7 @@ do_test e_fkey-45.1 { do_test e_fkey-45.2 { execsql { DELETE FROM pA WHERE rowid = 3; - SELECT quote(x) FROM pA; + SELECT quote(x) FROM pA ORDER BY rowid; } } {X'0000' X'9999' X'1234'} do_test e_fkey-45.3 { @@ -2069,7 +2069,7 @@ do_test e_fkey-45.3 { do_test e_fkey-45.4 { execsql { UPDATE pA SET x = X'8765' WHERE rowid = 4; - SELECT quote(x) FROM pA; + SELECT quote(x) FROM pA ORDER BY rowid; } } {X'0000' X'9999' X'8765'} do_test e_fkey-45.5 { @@ -2325,7 +2325,7 @@ do_test e_fkey-51.1 { do_test e_fkey-51.2 { execsql { UPDATE parent SET x = 22; - SELECT * FROM parent ; SELECT 'xxx' ; SELECT a FROM child; + SELECT * FROM parent ORDER BY rowid; SELECT 'xxx' ; SELECT a FROM child; } } {22 21 23 xxx 22} do_test e_fkey-51.3 { @@ -2335,7 +2335,7 @@ do_test e_fkey-51.3 { INSERT INTO parent VALUES(-1); INSERT INTO child VALUES(-1); UPDATE parent SET x = 22; - SELECT * FROM parent ; SELECT 'xxx' ; SELECT a FROM child; + SELECT * FROM parent ORDER BY rowid; SELECT 'xxx' ; SELECT a FROM child; } } {22 23 21 xxx 23} diff --git a/test/e_select.test b/test/e_select.test index e5949af67b..9f26f6fcd3 100644 --- a/test/e_select.test +++ b/test/e_select.test @@ -1026,7 +1026,7 @@ do_select_tests e_select-4.9 { 4,5 f 1 o 7,6 s 3,2 t } 2 "SELECT group_concat(one), sum(one) FROM b1 GROUP BY (one>4)" { - 1,4,3,2 10 5,7,6 18 + 1,2,3,4 10 5,6,7 18 } 3 "SELECT group_concat(one) FROM b1 GROUP BY (two>'o'), one%2" { 4 1,5 2,6 3,7 diff --git a/test/eqp.test b/test/eqp.test index 0e663f0a38..04eccc844e 100644 --- a/test/eqp.test +++ b/test/eqp.test @@ -62,7 +62,7 @@ do_eqp_test 1.3 { do_eqp_test 1.4 { SELECT a FROM t1 ORDER BY +a } { - 0 0 0 {SCAN TABLE t1 (~1000000 rows)} + 0 0 0 {SCAN TABLE t1 USING COVERING INDEX i1 (~1000000 rows)} 0 0 0 {USE TEMP B-TREE FOR ORDER BY} } do_eqp_test 1.5 { @@ -166,7 +166,7 @@ det 2.3.2 "SELECT min(x) FROM t2" { 0 0 0 {SEARCH TABLE t2 USING COVERING INDEX t2i1 (~1 rows)} } det 2.3.3 "SELECT min(x), max(x) FROM t2" { - 0 0 0 {SCAN TABLE t2 (~1000000 rows)} + 0 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1 (~1000000 rows)} } det 2.4.1 "SELECT * FROM t1 WHERE rowid=?" { @@ -339,7 +339,7 @@ do_eqp_test 4.3.1 { SELECT x FROM t1 UNION SELECT x FROM t2 } { 1 0 0 {SCAN TABLE t1 (~1000000 rows)} - 2 0 0 {SCAN TABLE t2 (~1000000 rows)} + 2 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1 (~1000000 rows)} 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 USING TEMP B-TREE (UNION)} } @@ -347,7 +347,7 @@ do_eqp_test 4.3.2 { SELECT x FROM t1 UNION SELECT x FROM t2 UNION SELECT x FROM t1 } { 2 0 0 {SCAN TABLE t1 (~1000000 rows)} - 3 0 0 {SCAN TABLE t2 (~1000000 rows)} + 3 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1 (~1000000 rows)} 1 0 0 {COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (UNION)} 4 0 0 {SCAN TABLE t1 (~1000000 rows)} 0 0 0 {COMPOUND SUBQUERIES 1 AND 4 USING TEMP B-TREE (UNION)} @@ -447,7 +447,7 @@ det 5.8.1 "SELECT c, d FROM t2 ORDER BY c" { det 5.9 { SELECT (SELECT b FROM t1 WHERE a=0), (SELECT a FROM t1 WHERE b=t2.c) FROM t2 } { - 0 0 0 {SCAN TABLE t2 (~1000000 rows)} + 0 0 0 {SCAN TABLE t2 USING COVERING INDEX i4 (~1000000 rows)} 0 0 0 {EXECUTE SCALAR SUBQUERY 1} 1 0 0 {SEARCH TABLE t1 USING COVERING INDEX i2 (a=?) (~10 rows)} 0 0 0 {EXECUTE CORRELATED SCALAR SUBQUERY 2} @@ -471,7 +471,7 @@ det 5.10 { # (c=?) (~10 rows) 0|1|1|SCAN TABLE t1 (~1000000 rows) det 5.11 "SELECT * FROM (SELECT * FROM t2 WHERE c=1), t1" { 0 0 0 {SEARCH TABLE t2 USING INDEX i4 (c=?) (~10 rows)} - 0 1 1 {SCAN TABLE t1 (~1000000 rows)} + 0 1 1 {SCAN TABLE t1 USING COVERING INDEX i2 (~1000000 rows)} } # EVIDENCE-OF: R-40701-42164 sqlite> EXPLAIN QUERY PLAN SELECT a FROM @@ -479,8 +479,8 @@ det 5.11 "SELECT * FROM (SELECT * FROM t2 WHERE c=1), t1" { # 2|0|0|SCAN TABLE t2 (~1000000 rows) 0|0|0|COMPOUND SUBQUERIES 1 AND 2 # USING TEMP B-TREE (UNION) det 5.12 "SELECT a FROM t1 UNION SELECT c FROM t2" { - 1 0 0 {SCAN TABLE t1 (~1000000 rows)} - 2 0 0 {SCAN TABLE t2 (~1000000 rows)} + 1 0 0 {SCAN TABLE t1 USING COVERING INDEX i2 (~1000000 rows)} + 2 0 0 {SCAN TABLE t2 USING COVERING INDEX i4 (~1000000 rows)} 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 USING TEMP B-TREE (UNION)} } diff --git a/test/incrblob.test b/test/incrblob.test index 1880128f83..7cc99dd983 100644 --- a/test/incrblob.test +++ b/test/incrblob.test @@ -437,7 +437,7 @@ if {[permutation] != "memsubsys1"} { } {} do_test incrblob-6.2 { execsql { - SELECT rowid FROM blobs + SELECT rowid FROM blobs ORDER BY rowid } } {1 2 3} do_test incrblob-6.3 { diff --git a/test/intpkey.test b/test/intpkey.test index 05b6cdf04c..db39421284 100644 --- a/test/intpkey.test +++ b/test/intpkey.test @@ -376,7 +376,7 @@ do_test intpkey-5.1 { } {0 zero entry 0} do_test intpkey-5.2 { execsql { - SELECT rowid, a FROM t1 + SELECT rowid, a FROM t1 ORDER BY rowid } } {-4 -4 0 0 5 5 6 6 11 11} diff --git a/test/like.test b/test/like.test index 767efd5828..80ba418588 100644 --- a/test/like.test +++ b/test/like.test @@ -406,7 +406,7 @@ do_test like-5.2 { do_test like-5.3 { execsql { CREATE TABLE t2(x TEXT COLLATE NOCASE); - INSERT INTO t2 SELECT * FROM t1; + INSERT INTO t2 SELECT * FROM t1 ORDER BY rowid; CREATE INDEX i2 ON t2(x COLLATE NOCASE); } set sqlite_like_count 0 @@ -662,8 +662,8 @@ ifcapable like_opt&&!icu { set res [sqlite3_exec_hex db { EXPLAIN QUERY PLAN SELECT x FROM t2 WHERE x LIKE '%ff%25' }] - regexp {INDEX i2} $res - } {0} + regexp {SCAN TABLE t2} $res + } {1} } do_test like-9.5.1 { set res [sqlite3_exec_hex db { diff --git a/test/stat.test b/test/stat.test index 926d9b7406..ac88f7acb3 100644 --- a/test/stat.test +++ b/test/stat.test @@ -76,11 +76,16 @@ do_test stat-1.4 { do_execsql_test stat-2.1 { CREATE TABLE t3(a PRIMARY KEY, b); INSERT INTO t3(rowid, a, b) VALUES(2, a_string(111), a_string(222)); - INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3; - INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3; - INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3; - INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3; - INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3; + INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3 + ORDER BY rowid; + INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3 + ORDER BY rowid; + INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3 + ORDER BY rowid; + INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3 + ORDER BY rowid; + INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3 + ORDER BY rowid; SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload FROM stat WHERE name != 'sqlite_master'; } [list \ diff --git a/test/tkt-385a5b56b9.test b/test/tkt-385a5b56b9.test index 614e82d0d5..8184864865 100644 --- a/test/tkt-385a5b56b9.test +++ b/test/tkt-385a5b56b9.test @@ -39,7 +39,7 @@ do_eqp_test 2.1 { SELECT DISTINCT x FROM t2 } { } do_eqp_test 2.2 { SELECT DISTINCT y FROM t2 } { - 0 0 0 {SCAN TABLE t2 (~1000000 rows)} + 0 0 0 {SCAN TABLE t2 USING COVERING INDEX t2y (~1000000 rows)} } do_eqp_test 2.3 { SELECT DISTINCT x, y FROM t2 WHERE y=10 } { @@ -51,4 +51,3 @@ do_eqp_test 2.4 { SELECT DISTINCT x, y FROM t2 WHERE x=10 } { } finish_test - diff --git a/test/tkt-78e04e52ea.test b/test/tkt-78e04e52ea.test index 9524d845e2..a664ceb9e6 100644 --- a/test/tkt-78e04e52ea.test +++ b/test/tkt-78e04e52ea.test @@ -44,7 +44,7 @@ do_test tkt-78e04-1.4 { execsql { EXPLAIN QUERY PLAN SELECT * FROM "" WHERE "" LIKE 'abc%'; } -} {0 0 0 {SCAN TABLE (~500000 rows)}} +} {0 0 0 {SCAN TABLE USING COVERING INDEX i1 (~500000 rows)}} do_test tkt-78e04-1.5 { execsql { DROP TABLE ""; diff --git a/test/triggerC.test b/test/triggerC.test index 12a5e4ac08..db37ab3b66 100644 --- a/test/triggerC.test +++ b/test/triggerC.test @@ -222,7 +222,7 @@ foreach {n tdefn rc} { execsql $tdefn catchsql { INSERT INTO t2 VALUES(10); - SELECT * FROM t2; + SELECT * FROM t2 ORDER BY rowid; } } $rc } @@ -547,7 +547,7 @@ foreach {n insert log} { eval concat [execsql " DELETE FROM log; $insert ; - SELECT * FROM log; + SELECT * FROM log ORDER BY rowid; "] } [join $log " "] } @@ -584,8 +584,8 @@ foreach {n dml t5g t5} { execsql " BEGIN; $dml ; - SELECT * FROM t5g; - SELECT * FROM t5; + SELECT * FROM t5g ORDER BY rowid; + SELECT * FROM t5 ORDER BY rowid; ROLLBACK; " } [concat $t5g $t5] @@ -611,8 +611,8 @@ foreach {n dml t5g t5} { execsql " BEGIN; $dml ; - SELECT * FROM t5g; - SELECT * FROM t5; + SELECT * FROM t5g ORDER BY rowid; + SELECT * FROM t5 ORDER BY rowid; ROLLBACK; " } [concat $t5g $t5] @@ -633,8 +633,8 @@ foreach {n dml t5g t5} { execsql " BEGIN; $dml ; - SELECT * FROM t5g; - SELECT * FROM t5; + SELECT * FROM t5g ORDER BY rowid; + SELECT * FROM t5 ORDER BY rowid; ROLLBACK; " } [concat $t5g $t5] diff --git a/test/unordered.test b/test/unordered.test index 6c7c2bb25b..4aa8310f89 100644 --- a/test/unordered.test +++ b/test/unordered.test @@ -51,7 +51,7 @@ foreach idxmode {ordered unordered} { 0 0 0 {USE TEMP B-TREE FOR ORDER BY}} 4 "SELECT max(a) FROM t1" {0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i1 (~1 rows)}} - {0 0 0 {SEARCH TABLE t1 (~1 rows)}} + {0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i1 (~1 rows)}} 5 "SELECT group_concat(b) FROM t1 GROUP BY a" {0 0 0 {SCAN TABLE t1 USING INDEX i1 (~128 rows)}} {0 0 0 {SCAN TABLE t1 (~128 rows)} 0 0 0 {USE TEMP B-TREE FOR GROUP BY}} diff --git a/test/where.test b/test/where.test index 3826a5f64a..1dab38ce55 100644 --- a/test/where.test +++ b/test/where.test @@ -1098,24 +1098,24 @@ do_test where-14.3 { cksort { SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.a, x.b } -} {1/1 1/4 4/1 4/4 nosort} +} {1/4 1/1 4/4 4/1 nosort} do_test where-14.4 { cksort { SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.a, x.b DESC } -} {1/1 1/4 4/1 4/4 nosort} +} {1/4 1/1 4/4 4/1 nosort} do_test where-14.5 { # This test case changed from "nosort" to "sort". See ticket 2a5629202f. cksort { SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, x.a||x.b } -} {4/1 4/4 1/1 1/4 sort} +} {4/4 4/1 1/4 1/1 sort} do_test where-14.6 { # This test case changed from "nosort" to "sort". See ticket 2a5629202f. cksort { SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, x.a||x.b DESC } -} {4/1 4/4 1/1 1/4 sort} +} {4/4 4/1 1/4 1/1 sort} do_test where-14.7 { cksort { SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, y.a||y.b @@ -1130,7 +1130,7 @@ do_test where-14.7.2 { cksort { SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, x.a, x.a||x.b } -} {4/1 4/4 1/1 1/4 nosort} +} {4/4 4/1 1/4 1/1 nosort} do_test where-14.8 { cksort { SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, y.a||y.b DESC diff --git a/test/where9.test b/test/where9.test index 23260a6b65..d618208ad6 100644 --- a/test/where9.test +++ b/test/where9.test @@ -692,7 +692,7 @@ do_test where9-6.5.3 { do_test where9-6.5.4 { db eval { SELECT count(*) FROM t1 UNION ALL - SELECT a FROM t1 WHERE a%100 IN (5,31,57,82,83,84,85,86,87); + SELECT a FROM t1 WHERE a%100 IN (5,31,57,82,83,84,85,86,87) ORDER BY rowid; ROLLBACK; } } {99 105 131 157 182 183 184 185 186 187} From 56690b3d4935766cbe6a2d936e6371b03232ac04 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 17 Sep 2012 15:36:31 +0000 Subject: [PATCH 30/60] Performance enhancement in the sqlite3VdbeSerialType() routine. FossilOrigin-Name: ad298f52efd0ff123a1a4d6a0fa16fbd4c6b6dad --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 7 +++---- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 816c07ad80..0a9b567d70 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthe\sname\sof\srollback\sjournal\sfiles\sare\sdouble-zero\sterminated\nwhen\sthey\sare\spassed\sinto\sthe\sVFS. -D 2012-09-15T13:39:24.735 +C Performance\senhancement\sin\sthe\ssqlite3VdbeSerialType()\sroutine. +D 2012-09-17T15:36:31.241 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -240,7 +240,7 @@ F src/vdbe.c fd82787f9fb5bfb48dea822d41f28c2a73c25e2e F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb F src/vdbeInt.h a668b303644377433e31a18d3d9efb87eefb6332 F src/vdbeapi.c 4c2418161cf45392ba76a7ca92f9a5f06b96f89c -F src/vdbeaux.c 9c293fd3040211687e83d5d27bef2382933146c2 +F src/vdbeaux.c aeeee6c97e0c2ad31c376a781cb7462090b9827b F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb F src/vdbemem.c cb55e84b8e2c15704968ee05f0fae25883299b74 F src/vdbesort.c 0dc1b274dcb4d4c8e71b0b2b15261f286caba39b @@ -1013,7 +1013,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P a93ee09cdc15987848bf9023e69892ce9a5f989e -R ecaebb814f51bb6e38f5c9d70e5c1467 +P 8711a8447d28275602287faf533de3d6e50d535d +R 34d4f192c96f51569b1d84a4c81787ab U drh -Z a699a11a3dac3cfd2b9a3a76bfd53ddc +Z c99f61ab4f3b0b408fc647ac1fcea198 diff --git a/manifest.uuid b/manifest.uuid index e60e09e0ac..3a105ea7dc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8711a8447d28275602287faf533de3d6e50d535d \ No newline at end of file +ad298f52efd0ff123a1a4d6a0fa16fbd4c6b6dad \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index d4f9864b14..dd23d395bd 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2583,9 +2583,6 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){ # define MAX_6BYTE ((((i64)0x00008000)<<32)-1) i64 i = pMem->u.i; u64 u; - if( file_format>=4 && (i&1)==i ){ - return 8+(u32)i; - } if( i<0 ){ if( i<(-MAX_6BYTE) ) return 6; /* Previous test prevents: u = -(-9223372036854775808) */ @@ -2593,7 +2590,9 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){ }else{ u = i; } - if( u<=127 ) return 1; + if( u<=127 ){ + return ((i&1)==i && file_format>=4) ? 8+(u32)u : 1; + } if( u<=32767 ) return 2; if( u<=8388607 ) return 3; if( u<=2147483647 ) return 4; From e1a022e48be1e7f40a8310e0f917fac8593c66a4 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 17 Sep 2012 17:16:53 +0000 Subject: [PATCH 31/60] Make sure the KeyInfo.aSortOrder array is always allocated so that we never have to test for KeyInfo.aSortOrder==0 in performance-critical loops. FossilOrigin-Name: 45793f0b844fee7445bc9269b403f89a58f77150 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 3 +++ src/select.c | 1 + src/vdbeaux.c | 14 ++++++++------ 5 files changed, 21 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 0a9b567d70..949d71190f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\senhancement\sin\sthe\ssqlite3VdbeSerialType()\sroutine. -D 2012-09-17T15:36:31.241 +C Make\ssure\sthe\sKeyInfo.aSortOrder\sarray\sis\salways\sallocated\sso\sthat\swe\snever\nhave\sto\stest\sfor\sKeyInfo.aSortOrder==0\sin\sperformance-critical\sloops. +D 2012-09-17T17:16:53.958 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -130,7 +130,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 72a70dcfda75d3a1f81041ce4573e7afddcd8e4e F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/delete.c 335f36750dc6ac88d580aa36a6487459be9889de -F src/expr.c 217840a107dcc1e5dbb57cea311daad04bedbb9a +F src/expr.c 70ded09d6ac529718aec57589ddb378c23153693 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c c82a04e7a92bb728f9ab972b76590403283be2af F src/func.c b4e88b92838fdab8e0088cc8411c06664b4dcf55 @@ -174,7 +174,7 @@ F src/printf.c 4a9f882f1c1787a8b494a2987765acf9d97ac21f F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 9e28280ec98035f31900fdd1db01f86f68ca6c32 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 171ec5fd5eae6d7a19b54f8f0abdfdd9a1c8f3ad +F src/select.c 1278b07a8c9a7f2f65b8efa8565993a56c4a58a3 F src/shell.c 87953c5d9c73d9494db97d1607e2e2280418f261 F src/sqlite.h.in d1071b0fc6de9a0d11392bc01305803122c3ec61 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 @@ -240,7 +240,7 @@ F src/vdbe.c fd82787f9fb5bfb48dea822d41f28c2a73c25e2e F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb F src/vdbeInt.h a668b303644377433e31a18d3d9efb87eefb6332 F src/vdbeapi.c 4c2418161cf45392ba76a7ca92f9a5f06b96f89c -F src/vdbeaux.c aeeee6c97e0c2ad31c376a781cb7462090b9827b +F src/vdbeaux.c fac025c798ad19070451b41eddc5dcd4696fdd1e F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb F src/vdbemem.c cb55e84b8e2c15704968ee05f0fae25883299b74 F src/vdbesort.c 0dc1b274dcb4d4c8e71b0b2b15261f286caba39b @@ -1013,7 +1013,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 8711a8447d28275602287faf533de3d6e50d535d -R 34d4f192c96f51569b1d84a4c81787ab +P ad298f52efd0ff123a1a4d6a0fa16fbd4c6b6dad +R 399ab3eadb581c96415fb9d89f0fbcd1 U drh -Z c99f61ab4f3b0b408fc647ac1fcea198 +Z 939733a13ef406dcc12020fe5915f839 diff --git a/manifest.uuid b/manifest.uuid index 3a105ea7dc..ddfbcb8578 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ad298f52efd0ff123a1a4d6a0fa16fbd4c6b6dad \ No newline at end of file +45793f0b844fee7445bc9269b403f89a58f77150 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 89172f94bf..3fb51cf11f 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1662,6 +1662,7 @@ int sqlite3CodeSubselect( case TK_IN: { char affinity; /* Affinity of the LHS of the IN */ KeyInfo keyInfo; /* Keyinfo for the generated table */ + static u8 sortOrder = 0; /* Fake aSortOrder for keyInfo */ int addr; /* Address of OP_OpenEphemeral instruction */ Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */ @@ -1689,6 +1690,7 @@ int sqlite3CodeSubselect( if( rMayHaveNull==0 ) sqlite3VdbeChangeP5(v, BTREE_UNORDERED); memset(&keyInfo, 0, sizeof(keyInfo)); keyInfo.nField = 1; + keyInfo.aSortOrder = &sortOrder; if( ExprHasProperty(pExpr, EP_xIsSelect) ){ /* Case 1: expr IN (SELECT ...) @@ -1729,6 +1731,7 @@ int sqlite3CodeSubselect( affinity = SQLITE_AFF_NONE; } keyInfo.aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft); + keyInfo.aSortOrder = &sortOrder; /* Loop through each expression in . */ r1 = sqlite3GetTempReg(pParse); diff --git a/src/select.c b/src/select.c index 0bf47e8521..656f39d6e8 100644 --- a/src/select.c +++ b/src/select.c @@ -1892,6 +1892,7 @@ static int multiSelect( *apColl = db->pDfltColl; } } + pKeyInfo->aSortOrder = (u8*)apColl; for(pLoop=p; pLoop; pLoop=pLoop->pPrior){ for(i=0; i<2; i++){ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index dd23d395bd..9db3bf435c 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -745,10 +745,9 @@ void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){ u8 *aSortOrder; memcpy((char*)pKeyInfo, zP4, nByte - nField); aSortOrder = pKeyInfo->aSortOrder; - if( aSortOrder ){ - pKeyInfo->aSortOrder = (unsigned char*)&pKeyInfo->aColl[nField]; - memcpy(pKeyInfo->aSortOrder, aSortOrder, nField); - } + assert( aSortOrder!=0 ); + pKeyInfo->aSortOrder = (unsigned char*)&pKeyInfo->aColl[nField]; + memcpy(pKeyInfo->aSortOrder, aSortOrder, nField); pOp->p4type = P4_KEYINFO; }else{ p->db->mallocFailed = 1; @@ -861,6 +860,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ case P4_KEYINFO: { int i, j; KeyInfo *pKeyInfo = pOp->p4.pKeyInfo; + assert( pKeyInfo->aSortOrder!=0 ); sqlite3_snprintf(nTemp, zTemp, "keyinfo(%d", pKeyInfo->nField); i = sqlite3Strlen30(zTemp); for(j=0; jnField; j++){ @@ -872,7 +872,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ break; } zTemp[i++] = ','; - if( pKeyInfo->aSortOrder && pKeyInfo->aSortOrder[j] ){ + if( pKeyInfo->aSortOrder[j] ){ zTemp[i++] = '-'; } memcpy(&zTemp[i], pColl->zName,n+1); @@ -2877,6 +2877,7 @@ UnpackedRecord *sqlite3VdbeAllocUnpackedRecord( } p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))]; + assert( pKeyInfo->aSortOrder!=0 ); p->pKeyInfo = pKeyInfo; p->nField = pKeyInfo->nField + 1; return p; @@ -2970,6 +2971,7 @@ int sqlite3VdbeRecordCompare( idx1 = getVarint32(aKey1, szHdr1); d1 = szHdr1; nField = pKeyInfo->nField; + assert( pKeyInfo->aSortOrder!=0 ); while( idx1nField ){ u32 serial_type1; @@ -2989,7 +2991,7 @@ int sqlite3VdbeRecordCompare( assert( mem1.zMalloc==0 ); /* See comment below */ /* Invert the result if we are using DESC sort order. */ - if( pKeyInfo->aSortOrder && iaSortOrder[i] ){ + if( iaSortOrder[i] ){ rc = -rc; } From 4261096124d777b383ae7db34f3752d01be05192 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 17 Sep 2012 18:56:32 +0000 Subject: [PATCH 32/60] Remove an unnecessary parameter from sqlite3Utf8Read() resulting in a slight performance increase. FossilOrigin-Name: 8b962c94a2f829f71efdd0ca770469b02feea3e1 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/func.c | 38 +++++++++++++++++++------------------- src/sqliteInt.h | 2 +- src/utf.c | 16 ++++++---------- 5 files changed, 35 insertions(+), 39 deletions(-) diff --git a/manifest b/manifest index 949d71190f..92fce0dba0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthe\sKeyInfo.aSortOrder\sarray\sis\salways\sallocated\sso\sthat\swe\snever\nhave\sto\stest\sfor\sKeyInfo.aSortOrder==0\sin\sperformance-critical\sloops. -D 2012-09-17T17:16:53.958 +C Remove\san\sunnecessary\sparameter\sfrom\ssqlite3Utf8Read()\sresulting\sin\sa\sslight\nperformance\sincrease. +D 2012-09-17T18:56:32.167 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -133,7 +133,7 @@ F src/delete.c 335f36750dc6ac88d580aa36a6487459be9889de F src/expr.c 70ded09d6ac529718aec57589ddb378c23153693 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c c82a04e7a92bb728f9ab972b76590403283be2af -F src/func.c b4e88b92838fdab8e0088cc8411c06664b4dcf55 +F src/func.c cbb90dc84b22eea25caf39528d342279e61b8898 F src/global.c 4cfdca5cb0edd33c4d021baec4ede958cb2c793b F src/hash.c a4031441741932da9e7a65bee2b36b5d0e81c073 F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 @@ -179,7 +179,7 @@ F src/shell.c 87953c5d9c73d9494db97d1607e2e2280418f261 F src/sqlite.h.in d1071b0fc6de9a0d11392bc01305803122c3ec61 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h 0423f0a673e7365827584e86dfbab8c33cf32cf8 +F src/sqliteInt.h 3f2ed42529ad54561e6c8d565afbfc9bca27da9d F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -233,7 +233,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c 1e86210d3976717a19238ea7b047fac481fe8c12 F src/trigger.c 3f258307040173aff383eb23fb74c44fe829078c F src/update.c 28d2d098b43a2c70dae399896ea8a02f622410ef -F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84 +F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f F src/util.c 0af2e515dc0dabacec931bca39525f6c3f1c5455 F src/vacuum.c 587a52bb8833d7ac15af8916f25437e2575028bd F src/vdbe.c fd82787f9fb5bfb48dea822d41f28c2a73c25e2e @@ -1013,7 +1013,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P ad298f52efd0ff123a1a4d6a0fa16fbd4c6b6dad -R 399ab3eadb581c96415fb9d89f0fbcd1 +P 45793f0b844fee7445bc9269b403f89a58f77150 +R 8cd942fbb7e8235e37ae22bd18b6fe8b U drh -Z 939733a13ef406dcc12020fe5915f839 +Z af8c124e8114c6e290ead5d3153e615a diff --git a/manifest.uuid b/manifest.uuid index ddfbcb8578..0019e1e823 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -45793f0b844fee7445bc9269b403f89a58f77150 \ No newline at end of file +8b962c94a2f829f71efdd0ca770469b02feea3e1 \ No newline at end of file diff --git a/src/func.c b/src/func.c index 9d81d0c741..cc74a4ddda 100644 --- a/src/func.c +++ b/src/func.c @@ -493,7 +493,7 @@ struct compareInfo { ** whereas only characters less than 0x80 do in ASCII. */ #if defined(SQLITE_EBCDIC) -# define sqlite3Utf8Read(A,C) (*(A++)) +# define sqlite3Utf8Read(A) (*((*A)++)) # define GlogUpperToLower(A) A = sqlite3UpperToLower[A] #else # define GlogUpperToLower(A) if( !((A)&~0x7f) ){ A = sqlite3UpperToLower[A]; } @@ -550,18 +550,18 @@ static int patternCompare( u8 noCase = pInfo->noCase; int prevEscape = 0; /* True if the previous character was 'escape' */ - while( (c = sqlite3Utf8Read(zPattern,&zPattern))!=0 ){ - if( !prevEscape && c==matchAll ){ - while( (c=sqlite3Utf8Read(zPattern,&zPattern)) == matchAll + while( (c = sqlite3Utf8Read(&zPattern))!=0 ){ + if( c==matchAll && !prevEscape ){ + while( (c=sqlite3Utf8Read(&zPattern)) == matchAll || c == matchOne ){ - if( c==matchOne && sqlite3Utf8Read(zString, &zString)==0 ){ + if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){ return 0; } } if( c==0 ){ return 1; }else if( c==esc ){ - c = sqlite3Utf8Read(zPattern, &zPattern); + c = sqlite3Utf8Read(&zPattern); if( c==0 ){ return 0; } @@ -573,25 +573,25 @@ static int patternCompare( } return *zString!=0; } - while( (c2 = sqlite3Utf8Read(zString,&zString))!=0 ){ + while( (c2 = sqlite3Utf8Read(&zString))!=0 ){ if( noCase ){ GlogUpperToLower(c2); GlogUpperToLower(c); while( c2 != 0 && c2 != c ){ - c2 = sqlite3Utf8Read(zString, &zString); + c2 = sqlite3Utf8Read(&zString); GlogUpperToLower(c2); } }else{ while( c2 != 0 && c2 != c ){ - c2 = sqlite3Utf8Read(zString, &zString); + c2 = sqlite3Utf8Read(&zString); } } if( c2==0 ) return 0; if( patternCompare(zPattern,zString,pInfo,esc) ) return 1; } return 0; - }else if( !prevEscape && c==matchOne ){ - if( sqlite3Utf8Read(zString, &zString)==0 ){ + }else if( c==matchOne && !prevEscape ){ + if( sqlite3Utf8Read(&zString)==0 ){ return 0; } }else if( c==matchSet ){ @@ -599,20 +599,20 @@ static int patternCompare( assert( esc==0 ); /* This only occurs for GLOB, not LIKE */ seen = 0; invert = 0; - c = sqlite3Utf8Read(zString, &zString); + c = sqlite3Utf8Read(&zString); if( c==0 ) return 0; - c2 = sqlite3Utf8Read(zPattern, &zPattern); + c2 = sqlite3Utf8Read(&zPattern); if( c2=='^' ){ invert = 1; - c2 = sqlite3Utf8Read(zPattern, &zPattern); + c2 = sqlite3Utf8Read(&zPattern); } if( c2==']' ){ if( c==']' ) seen = 1; - c2 = sqlite3Utf8Read(zPattern, &zPattern); + c2 = sqlite3Utf8Read(&zPattern); } while( c2 && c2!=']' ){ if( c2=='-' && zPattern[0]!=']' && zPattern[0]!=0 && prior_c>0 ){ - c2 = sqlite3Utf8Read(zPattern, &zPattern); + c2 = sqlite3Utf8Read(&zPattern); if( c>=prior_c && c<=c2 ) seen = 1; prior_c = 0; }else{ @@ -621,7 +621,7 @@ static int patternCompare( } prior_c = c2; } - c2 = sqlite3Utf8Read(zPattern, &zPattern); + c2 = sqlite3Utf8Read(&zPattern); } if( c2==0 || (seen ^ invert)==0 ){ return 0; @@ -629,7 +629,7 @@ static int patternCompare( }else if( esc==c && !prevEscape ){ prevEscape = 1; }else{ - c2 = sqlite3Utf8Read(zString, &zString); + c2 = sqlite3Utf8Read(&zString); if( noCase ){ GlogUpperToLower(c); GlogUpperToLower(c2); @@ -701,7 +701,7 @@ static void likeFunc( "ESCAPE expression must be a single character", -1); return; } - escape = sqlite3Utf8Read(zEsc, &zEsc); + escape = sqlite3Utf8Read(&zEsc); } if( zA && zB ){ struct compareInfo *pInfo = sqlite3_user_data(context); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 6f6bfdb148..ccd12451ed 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2956,7 +2956,7 @@ int sqlite3GetInt32(const char *, int*); int sqlite3Atoi(const char*); int sqlite3Utf16ByteLen(const void *pData, int nChar); int sqlite3Utf8CharLen(const char *pData, int nByte); -u32 sqlite3Utf8Read(const u8*, const u8**); +u32 sqlite3Utf8Read(const u8**); /* ** Routines to read and write variable-length integers. These used to diff --git a/src/utf.c b/src/utf.c index e94815b5ab..6d5b1bfe40 100644 --- a/src/utf.c +++ b/src/utf.c @@ -164,25 +164,23 @@ static const unsigned char sqlite3Utf8Trans1[] = { || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \ } u32 sqlite3Utf8Read( - const unsigned char *zIn, /* First byte of UTF-8 character */ - const unsigned char **pzNext /* Write first byte past UTF-8 char here */ + const unsigned char **pz /* Pointer to string from which to read char */ ){ unsigned int c; /* Same as READ_UTF8() above but without the zTerm parameter. ** For this routine, we assume the UTF8 string is always zero-terminated. */ - c = *(zIn++); + c = *((*pz)++); if( c>=0xc0 ){ c = sqlite3Utf8Trans1[c-0xc0]; - while( (*zIn & 0xc0)==0x80 ){ - c = (c<<6) + (0x3f & *(zIn++)); + while( (*(*pz) & 0xc0)==0x80 ){ + c = (c<<6) + (0x3f & *((*pz)++)); } if( c<0x80 || (c&0xFFFFF800)==0xD800 || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } } - *pzNext = zIn; return c; } @@ -283,7 +281,6 @@ int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){ if( desiredEnc==SQLITE_UTF16LE ){ /* UTF-8 -> UTF-16 Little-endian */ while( zIn UTF-16 Big-endian */ while( zIn0 && n<=4 ); z[0] = 0; z = zBuf; - c = sqlite3Utf8Read(z, (const u8**)&z); + c = sqlite3Utf8Read((const u8**)&z); t = i; if( i>=0xD800 && i<=0xDFFF ) t = 0xFFFD; if( (i&0xFFFFFFFE)==0xFFFE ) t = 0xFFFD; From f4af1089ab1e8f9cb0ef4f9c69f445253510d8e0 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 17 Sep 2012 19:12:39 +0000 Subject: [PATCH 33/60] Remove obsolete bits from the bitvector that defines disabled optimizations in the SQLITE_TESTCTRL_OPTIMIZATIONS verb of sqlite3_test_control(). FossilOrigin-Name: 4c21ee2d26466f83dec525153e2b1506bd956701 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqliteInt.h | 17 +++++++---------- src/test1.c | 4 +--- 4 files changed, 16 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 92fce0dba0..423fd99e01 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\sparameter\sfrom\ssqlite3Utf8Read()\sresulting\sin\sa\sslight\nperformance\sincrease. -D 2012-09-17T18:56:32.167 +C Remove\sobsolete\sbits\sfrom\sthe\sbitvector\sthat\sdefines\sdisabled\soptimizations\nin\sthe\sSQLITE_TESTCTRL_OPTIMIZATIONS\sverb\sof\ssqlite3_test_control(). +D 2012-09-17T19:12:39.992 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -179,12 +179,12 @@ F src/shell.c 87953c5d9c73d9494db97d1607e2e2280418f261 F src/sqlite.h.in d1071b0fc6de9a0d11392bc01305803122c3ec61 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h 3f2ed42529ad54561e6c8d565afbfc9bca27da9d +F src/sqliteInt.h 1228a3d21694dc08e019735b1a5634e5764d11ea F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/tclsqlite.c e4de2458b3ef38fdd0498bc4e5ea5367a241b0f3 -F src/test1.c 3d70f7c5987f186884cfebbfa7151a7d3d67d86e +F src/test1.c 1ad391d930ff94404768f0ca3c08936f74544fa2 F src/test2.c 4178056dd1e7d70f954ad8a1e3edb71a2a784daf F src/test3.c 3c3c2407fa6ec7a19e24ae23f7cb439d0275a60d F src/test4.c bf9fa9bece01de08e6f5e02314e4af5c13590dfa @@ -1013,7 +1013,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 45793f0b844fee7445bc9269b403f89a58f77150 -R 8cd942fbb7e8235e37ae22bd18b6fe8b +P 8b962c94a2f829f71efdd0ca770469b02feea3e1 +R 67168a23b15c492a24fe7dbe4ad81c6a U drh -Z af8c124e8114c6e290ead5d3153e615a +Z 95f03cf63c4263171e5518be35ff05c6 diff --git a/manifest.uuid b/manifest.uuid index 0019e1e823..d1f3d5acfc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8b962c94a2f829f71efdd0ca770469b02feea3e1 \ No newline at end of file +4c21ee2d26466f83dec525153e2b1506bd956701 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index ccd12451ed..b0135f44c9 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -962,16 +962,13 @@ struct sqlite3 { ** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface. ** These must be the low-order bits of the flags field. */ -#define SQLITE_QueryFlattener 0x01 /* Disable query flattening */ -#define SQLITE_ColumnCache 0x02 /* Disable the column cache */ -#define SQLITE_IndexSort 0x04 /* Disable indexes for sorting */ -#define SQLITE_IndexSearch 0x08 /* Disable indexes for searching */ -#define SQLITE_IndexCover 0x10 /* Disable index covering table */ -#define SQLITE_GroupByOrder 0x20 /* Disable GROUPBY cover of ORDERBY */ -#define SQLITE_FactorOutConst 0x40 /* Disable factoring out constants */ -#define SQLITE_IdxRealAsInt 0x80 /* Store REAL as INT in indices */ -#define SQLITE_DistinctOpt 0x80 /* DISTINCT using indexes */ -#define SQLITE_OptMask 0xff /* Mask of all disablable opts */ +#define SQLITE_QueryFlattener 0x01 /* Disable query flattening */ +#define SQLITE_ColumnCache 0x02 /* Disable the column cache */ +#define SQLITE_GroupByOrder 0x04 /* Disable GROUPBY cover of ORDERBY */ +#define SQLITE_FactorOutConst 0x08 /* Disable factoring out constants */ +#define SQLITE_IdxRealAsInt 0x10 /* Store REAL as INT in indices */ +#define SQLITE_DistinctOpt 0x20 /* DISTINCT using indexes */ +#define SQLITE_OptMask 0xff /* Mask of all disablable opts */ /* ** Possible values for the sqlite.magic field. diff --git a/src/test1.c b/src/test1.c index c3dac06212..55e2df5534 100644 --- a/src/test1.c +++ b/src/test1.c @@ -5936,12 +5936,10 @@ static int optimization_control( { "all", SQLITE_OptMask }, { "query-flattener", SQLITE_QueryFlattener }, { "column-cache", SQLITE_ColumnCache }, - { "index-sort", SQLITE_IndexSort }, - { "index-search", SQLITE_IndexSearch }, - { "index-cover", SQLITE_IndexCover }, { "groupby-order", SQLITE_GroupByOrder }, { "factor-constants", SQLITE_FactorOutConst }, { "real-as-int", SQLITE_IdxRealAsInt }, + { "distinct-opt", SQLITE_DistinctOpt }, }; if( objc!=4 ){ From de9a7b8a942d1b4066abdb03e661b3bc174d9d73 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 17 Sep 2012 20:44:46 +0000 Subject: [PATCH 34/60] Add the ability to disable the covering-index-scan optimization at compile-time, start-time, or at run-time. Add test cases to check this configurability. FossilOrigin-Name: ccb8ecc30c8e6c7760131250297c2e452bbac43b --- manifest | 27 ++++++------ manifest.uuid | 2 +- src/global.c | 5 +++ src/main.c | 5 +++ src/sqlite.h.in | 13 ++++++ src/sqliteInt.h | 2 + src/test1.c | 1 + src/test_malloc.c | 30 ++++++++++++++ src/where.c | 6 ++- test/coveridxscan.test | 93 ++++++++++++++++++++++++++++++++++++++++++ test/eqp.test | 2 +- 11 files changed, 170 insertions(+), 16 deletions(-) create mode 100644 test/coveridxscan.test diff --git a/manifest b/manifest index ace53db22c..ca8e166804 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\srecent\strunk\schanges\sinto\sthe\sfullscan-covering-index\sbranch. -D 2012-09-17T19:26:02.587 +C Add\sthe\sability\sto\sdisable\sthe\scovering-index-scan\soptimization\sat\scompile-time,\nstart-time,\sor\sat\srun-time.\s\sAdd\stest\scases\sto\scheck\sthis\sconfigurability. +D 2012-09-17T20:44:46.604 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -134,7 +134,7 @@ F src/expr.c 70ded09d6ac529718aec57589ddb378c23153693 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c c82a04e7a92bb728f9ab972b76590403283be2af F src/func.c cbb90dc84b22eea25caf39528d342279e61b8898 -F src/global.c 4cfdca5cb0edd33c4d021baec4ede958cb2c793b +F src/global.c fb44b11e02e06c995e6ed6642509edd23599d584 F src/hash.c a4031441741932da9e7a65bee2b36b5d0e81c073 F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 @@ -143,7 +143,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d -F src/main.c 3977ac9c4f6cf7382258b6e92f8bedb5a3e52527 +F src/main.c 97d13e749ae84fe62238a5940c5b46b2b22cd369 F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa @@ -176,15 +176,15 @@ F src/resolve.c 9e28280ec98035f31900fdd1db01f86f68ca6c32 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 1278b07a8c9a7f2f65b8efa8565993a56c4a58a3 F src/shell.c 87953c5d9c73d9494db97d1607e2e2280418f261 -F src/sqlite.h.in d1071b0fc6de9a0d11392bc01305803122c3ec61 +F src/sqlite.h.in c76c38f9635590ff5844684a7976843878327137 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h 1228a3d21694dc08e019735b1a5634e5764d11ea +F src/sqliteInt.h 5cbd4340146b609a8b98b908d46020d8d15153fe F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/tclsqlite.c e4de2458b3ef38fdd0498bc4e5ea5367a241b0f3 -F src/test1.c 1ad391d930ff94404768f0ca3c08936f74544fa2 +F src/test1.c bec5295347a7bc38a53ca955f01cfcaf116fdb88 F src/test2.c 4178056dd1e7d70f954ad8a1e3edb71a2a784daf F src/test3.c 3c3c2407fa6ec7a19e24ae23f7cb439d0275a60d F src/test4.c bf9fa9bece01de08e6f5e02314e4af5c13590dfa @@ -208,7 +208,7 @@ F src/test_intarray.c d879bbf8e4ce085ab966d1f3c896a7c8b4f5fc99 F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c f5c0a05b7b3d5930db769b5ee6c3766dc2221a64 F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e -F src/test_malloc.c 7c8e2511d9d9661c2fcf91960ce0fb801bae8d0a +F src/test_malloc.c 01cd65ae7ae93de9fbf8214d1ee6b4eba4850700 F src/test_multiplex.c ac0fbc1748e5b86a41a1d7a84654fae0d53a881d F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e @@ -249,7 +249,7 @@ F src/vtab.c d8020c0a0e8ccc490ca449d7e665311b6e9f3ba9 F src/wal.c 5acb3e7bbd31f10ba39acad9ce6b399055337a9d F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b -F src/where.c 0d9970a606d64559a969b9d663ed2db7439c6668 +F src/where.c b124d9d7c6fba803ae31fbcf605e2c1dca0d9b51 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 0be144b453e0622a085fae8665c32f5676708e00 @@ -350,6 +350,7 @@ F test/corruptD.test 3b09903a2e2fe07ecafe775fea94177f8a4bb34f F test/corruptE.test d3a3d7e864a95978195741744dda4abfd8286018 F test/corruptF.test 984b1706c9c0e4248141b056c21124612628d12e F test/count.test 454e1ce985c94d13efeac405ce54439f49336163 +F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62 F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f F test/crash2.test 5b14d4eb58b880e231361d3b609b216acda86651 F test/crash3.test 8f5de9d32ab9ab95475a9efe7f47a940aa889418 @@ -394,7 +395,7 @@ F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea F test/enc2.test 796c59832e2b9a52842f382ffda8f3e989db03ad F test/enc3.test 90683ad0e6ea587b9d5542ca93568af9a9858c40 F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020 -F test/eqp.test 103243f86c2ab85dac79eef5b6a80c333407504e +F test/eqp.test 46aa946dd55c90635327898275d3e533d23a9845 F test/errmsg.test 3bb606db9d040cc6854459f8f5e5a2bcd9b7fd2a F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3 F test/exclusive.test a1b324cb21834a490cd052d409d34789cfef57cb @@ -1013,7 +1014,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P cfaa7bc12847a7006ccc93815f2395ad5259744a 4c21ee2d26466f83dec525153e2b1506bd956701 -R 3fd45fd88344b4ac62768e374c7ae8ba +P 1c0bf0305ce9528a0d07c86a390c5872e16bdb57 +R ea4a1c70fdbc9c60f0a72361b504925d U drh -Z 9e1f7223ea78afc960fb1c0adce4036d +Z b5d12e2225cca01e9d4be0a180222322 diff --git a/manifest.uuid b/manifest.uuid index cc97eda3af..cc1a403e52 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1c0bf0305ce9528a0d07c86a390c5872e16bdb57 \ No newline at end of file +ccb8ecc30c8e6c7760131250297c2e452bbac43b \ No newline at end of file diff --git a/src/global.c b/src/global.c index 7de0668250..dc86e1e081 100644 --- a/src/global.c +++ b/src/global.c @@ -133,6 +133,10 @@ const unsigned char sqlite3CtypeMap[256] = { # define SQLITE_USE_URI 0 #endif +#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN +# define SQLITE_ALLOW_COVERING_INDEX_SCAN 1 +#endif + /* ** The following singleton contains the global configuration for ** the SQLite library. @@ -142,6 +146,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = { 1, /* bCoreMutex */ SQLITE_THREADSAFE==1, /* bFullMutex */ SQLITE_USE_URI, /* bOpenUri */ + SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */ 0x7ffffffe, /* mxStrlen */ 128, /* szLookaside */ 500, /* nLookaside */ diff --git a/src/main.c b/src/main.c index 08e62a97ea..466dee5516 100644 --- a/src/main.c +++ b/src/main.c @@ -475,6 +475,11 @@ int sqlite3_config(int op, ...){ break; } + case SQLITE_CONFIG_COVERING_INDEX_SCAN: { + sqlite3GlobalConfig.bUseCis = va_arg(ap, int); + break; + } + default: { rc = SQLITE_ERROR; break; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 3660c442d9..cab0b8418c 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -1563,6 +1563,18 @@ struct sqlite3_mem_methods { ** disabled. The default value may be changed by compiling with the ** [SQLITE_USE_URI] symbol defined. ** +** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]]
SQLITE_CONFIG_COVERING_INDEX_SCAN +**
This option taks a single integer argument which is interpreted as +** a boolean in order to enable or disable the use of covering indices for +** full table scans in the query optimizer. The default setting is determined +** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on" +** if that compile-time option is omitted. +** The ability to disable the use of covering indices for full table scans +** is because some incorrectly coded legacy applications might malfunction +** malfunction when the optimization is enabled. Providing the ability to +** disable the optimization allows the older, buggy application code to work +** without change even with newer versions of SQLite. +** ** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]] **
SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE **
These options are obsolete and should not be used by new code. @@ -1588,6 +1600,7 @@ struct sqlite3_mem_methods { #define SQLITE_CONFIG_URI 17 /* int */ #define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */ #define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */ +#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */ /* ** CAPI3REF: Database Connection Configuration Options diff --git a/src/sqliteInt.h b/src/sqliteInt.h index b0135f44c9..e20e797747 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -968,6 +968,7 @@ struct sqlite3 { #define SQLITE_FactorOutConst 0x08 /* Disable factoring out constants */ #define SQLITE_IdxRealAsInt 0x10 /* Store REAL as INT in indices */ #define SQLITE_DistinctOpt 0x20 /* DISTINCT using indexes */ +#define SQLITE_CoverIdxScan 0x40 /* Disable covering index scans */ #define SQLITE_OptMask 0xff /* Mask of all disablable opts */ /* @@ -2461,6 +2462,7 @@ struct Sqlite3Config { int bCoreMutex; /* True to enable core mutexing */ int bFullMutex; /* True to enable full mutexing */ int bOpenUri; /* True to interpret filenames as URIs */ + int bUseCis; /* Use covering indices for full-scans */ int mxStrlen; /* Maximum string length */ int szLookaside; /* Default lookaside buffer size */ int nLookaside; /* Default lookaside buffer count */ diff --git a/src/test1.c b/src/test1.c index 55e2df5534..0b9b812e8f 100644 --- a/src/test1.c +++ b/src/test1.c @@ -5940,6 +5940,7 @@ static int optimization_control( { "factor-constants", SQLITE_FactorOutConst }, { "real-as-int", SQLITE_IdxRealAsInt }, { "distinct-opt", SQLITE_DistinctOpt }, + { "cover-idx-scan", SQLITE_CoverIdxScan }, }; if( objc!=4 ){ diff --git a/src/test_malloc.c b/src/test_malloc.c index f52894d9e5..e1420de648 100644 --- a/src/test_malloc.c +++ b/src/test_malloc.c @@ -1197,6 +1197,35 @@ static int test_config_uri( return TCL_OK; } +/* +** Usage: sqlite3_config_cis BOOLEAN +** +** Enables or disables the use of the covering-index scan optimization. +** SQLITE_CONFIG_COVERING_INDEX_SCAN. +*/ +static int test_config_cis( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + int rc; + int bUseCis; + + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "BOOL"); + return TCL_ERROR; + } + if( Tcl_GetBooleanFromObj(interp, objv[1], &bUseCis) ){ + return TCL_ERROR; + } + + rc = sqlite3_config(SQLITE_CONFIG_COVERING_INDEX_SCAN, bUseCis); + Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE); + + return TCL_OK; +} + /* ** Usage: sqlite3_dump_memsys3 FILENAME ** sqlite3_dump_memsys5 FILENAME @@ -1447,6 +1476,7 @@ int Sqlitetest_malloc_Init(Tcl_Interp *interp){ { "sqlite3_config_lookaside", test_config_lookaside ,0 }, { "sqlite3_config_error", test_config_error ,0 }, { "sqlite3_config_uri", test_config_uri ,0 }, + { "sqlite3_config_cis", test_config_cis ,0 }, { "sqlite3_db_config_lookaside",test_db_config_lookaside ,0 }, { "sqlite3_dump_memsys3", test_dump_memsys3 ,3 }, { "sqlite3_dump_memsys5", test_dump_memsys3 ,5 }, diff --git a/src/where.c b/src/where.c index c28386e29f..9922d2b3d9 100644 --- a/src/where.c +++ b/src/where.c @@ -3201,12 +3201,16 @@ static void bestBtreeIndex( */ if( wsFlags==WHERE_IDX_ONLY && (pWC->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 + && sqlite3GlobalConfig.bUseCis +#ifndef SQLITE_OMIT_BUILTIN_TEST + && (pParse->db->flags & SQLITE_CoverIdxScan)==0 +#endif ){ /* This index is not useful for indexing, but it is a covering index. ** A full-scan of the index might be a little faster than a full-scan ** of the table, so give this case a cost slightly less than a table ** scan. */ - cost = aiRowEst[0]*3; + cost = aiRowEst[0]*3 + pProbe->nColumn; wsFlags |= WHERE_COVER_SCAN|WHERE_COLUMN_RANGE; }else if( (wsFlags & WHERE_NOT_FULLSCAN)==0 ){ /* The cost of a full table scan is a number of move operations equal diff --git a/test/coveridxscan.test b/test/coveridxscan.test new file mode 100644 index 0000000000..7b3c0b0be9 --- /dev/null +++ b/test/coveridxscan.test @@ -0,0 +1,93 @@ +# 2012 September 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. +# +#*********************************************************************** +# +# Tests for the optimization which attempts to use a covering index +# for a full-table scan (under the theory that the index will be smaller +# and require less I/O and hence will run faster.) +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +set testprefix coveridxscan + +do_test 1.1 { + db eval { + CREATE TABLE t1(a,b,c); + INSERT INTO t1 VALUES(5,4,3), (4,8,2), (3,2,1); + CREATE INDEX t1ab ON t1(a,b); + CREATE INDEX t1b ON t1(b); + SELECT a FROM t1; + } + # covering index used for the scan, hence values are increasing +} {3 4 5} + +do_test 1.2 { + db eval { + SELECT a, c FROM t1; + } + # There is no covering index, hence the values are in rowid order +} {5 3 4 2 3 1} + +do_test 1.3 { + db eval { + SELECT b FROM t1; + } + # Choice of two indices: use the one with fewest columns +} {2 4 8} + +do_test 2.1 { + optimization_control db cover-idx-scan 0 + db eval {SELECT a FROM t1} + # With the optimization turned off, output in rowid order +} {5 4 3} +do_test 2.2 { + db eval {SELECT a, c FROM t1} +} {5 3 4 2 3 1} +do_test 2.3 { + db eval {SELECT b FROM t1} +} {4 8 2} + +db close +sqlite3_shutdown +sqlite3_config_cis 0 +sqlite3 db test.db + +do_test 3.1 { + db eval {SELECT a FROM t1} + # With the optimization configured off, output in rowid order +} {5 4 3} +do_test 3.2 { + db eval {SELECT a, c FROM t1} +} {5 3 4 2 3 1} +do_test 3.3 { + db eval {SELECT b FROM t1} +} {4 8 2} + +db close +sqlite3_shutdown +sqlite3_config_cis 1 +sqlite3 db test.db + +# The CIS optimization is enabled again. Covering indices are once again +# used for all table scans. +do_test 4.1 { + db eval {SELECT a FROM t1} +} {3 4 5} +do_test 4.2 { + db eval {SELECT a, c FROM t1} +} {5 3 4 2 3 1} +do_test 4.3 { + db eval {SELECT b FROM t1} +} {2 4 8} + + +finish_test diff --git a/test/eqp.test b/test/eqp.test index 04eccc844e..454f2afbdd 100644 --- a/test/eqp.test +++ b/test/eqp.test @@ -479,7 +479,7 @@ det 5.11 "SELECT * FROM (SELECT * FROM t2 WHERE c=1), t1" { # 2|0|0|SCAN TABLE t2 (~1000000 rows) 0|0|0|COMPOUND SUBQUERIES 1 AND 2 # USING TEMP B-TREE (UNION) det 5.12 "SELECT a FROM t1 UNION SELECT c FROM t2" { - 1 0 0 {SCAN TABLE t1 USING COVERING INDEX i2 (~1000000 rows)} + 1 0 0 {SCAN TABLE t1 USING COVERING INDEX i1 (~1000000 rows)} 2 0 0 {SCAN TABLE t2 USING COVERING INDEX i4 (~1000000 rows)} 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 USING TEMP B-TREE (UNION)} } From d2e2bf9ff71e28d9b30b7edaeb8373fb2a5d699c Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 17 Sep 2012 21:24:01 +0000 Subject: [PATCH 35/60] Make sure the WHERE_IDX_ONLY flag is not set on query plans that will not be using an index. FossilOrigin-Name: 698b2a28004a9a2f0eabaadf36d833da4400b2bf --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index ca8e166804..fd4846b9d6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sability\sto\sdisable\sthe\scovering-index-scan\soptimization\sat\scompile-time,\nstart-time,\sor\sat\srun-time.\s\sAdd\stest\scases\sto\scheck\sthis\sconfigurability. -D 2012-09-17T20:44:46.604 +C Make\ssure\sthe\sWHERE_IDX_ONLY\sflag\sis\snot\sset\son\squery\splans\sthat\swill\snot\nbe\susing\san\sindex. +D 2012-09-17T21:24:01.339 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -249,7 +249,7 @@ F src/vtab.c d8020c0a0e8ccc490ca449d7e665311b6e9f3ba9 F src/wal.c 5acb3e7bbd31f10ba39acad9ce6b399055337a9d F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b -F src/where.c b124d9d7c6fba803ae31fbcf605e2c1dca0d9b51 +F src/where.c cc3ef08bb6a6832e888291a89993ad0828689a36 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 0be144b453e0622a085fae8665c32f5676708e00 @@ -1014,7 +1014,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 1c0bf0305ce9528a0d07c86a390c5872e16bdb57 -R ea4a1c70fdbc9c60f0a72361b504925d +P ccb8ecc30c8e6c7760131250297c2e452bbac43b +R 954468a602d729e7590459a0c0d2a8fc U drh -Z b5d12e2225cca01e9d4be0a180222322 +Z 17e6bbfde6ba16331a4c164b47402211 diff --git a/manifest.uuid b/manifest.uuid index cc1a403e52..6105b408ba 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ccb8ecc30c8e6c7760131250297c2e452bbac43b \ No newline at end of file +698b2a28004a9a2f0eabaadf36d833da4400b2bf \ No newline at end of file diff --git a/src/where.c b/src/where.c index 9922d2b3d9..976492e845 100644 --- a/src/where.c +++ b/src/where.c @@ -3223,6 +3223,7 @@ static void bestBtreeIndex( ** it seems to be working well enough at the moment. */ cost = aiRowEst[0]*4; + wsFlags &= ~WHERE_IDX_ONLY; }else{ log10N = estLog(aiRowEst[0]); cost = nRow; From 3a949878194e1437f1de8861b2dc1c36e041cc99 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 18 Sep 2012 13:20:13 +0000 Subject: [PATCH 36/60] Update the vdbe-compress.tcl script so that it accepts variable declarations inside of #ifdef...#endif. This enhancement is needed due to the change of check-in [39866c0ede5d6ef4]. FossilOrigin-Name: e7db056a0d76b2411cadbae077890df189e49414 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 3 +++ tool/vdbe-compress.tcl | 3 +++ 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 423fd99e01..2a95ccf0de 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sobsolete\sbits\sfrom\sthe\sbitvector\sthat\sdefines\sdisabled\soptimizations\nin\sthe\sSQLITE_TESTCTRL_OPTIMIZATIONS\sverb\sof\ssqlite3_test_control(). -D 2012-09-17T19:12:39.992 +C Update\sthe\svdbe-compress.tcl\sscript\sso\sthat\sit\saccepts\svariable\sdeclarations\ninside\sof\s#ifdef...#endif.\nThis\senhancement\sis\sneeded\sdue\sto\sthe\schange\sof\scheck-in\s[39866c0ede5d6ef4]. +D 2012-09-18T13:20:13.054 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -236,7 +236,7 @@ F src/update.c 28d2d098b43a2c70dae399896ea8a02f622410ef F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f F src/util.c 0af2e515dc0dabacec931bca39525f6c3f1c5455 F src/vacuum.c 587a52bb8833d7ac15af8916f25437e2575028bd -F src/vdbe.c fd82787f9fb5bfb48dea822d41f28c2a73c25e2e +F src/vdbe.c 16e894bd59d11c4a2c184627906c794a6bdc6eff F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb F src/vdbeInt.h a668b303644377433e31a18d3d9efb87eefb6332 F src/vdbeapi.c 4c2418161cf45392ba76a7ca92f9a5f06b96f89c @@ -1009,11 +1009,11 @@ F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 -F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f +F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 8b962c94a2f829f71efdd0ca770469b02feea3e1 -R 67168a23b15c492a24fe7dbe4ad81c6a +P 4c21ee2d26466f83dec525153e2b1506bd956701 +R b047ef3cdc6a088ac63e246ab78c4764 U drh -Z 95f03cf63c4263171e5518be35ff05c6 +Z bfcdd96844256469f85fbd5fa7f23556 diff --git a/manifest.uuid b/manifest.uuid index d1f3d5acfc..e4d7cd2c9e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4c21ee2d26466f83dec525153e2b1506bd956701 \ No newline at end of file +e7db056a0d76b2411cadbae077890df189e49414 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 16815d9d38..68b0ebb93e 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3278,6 +3278,7 @@ case OP_OpenEphemeral: { */ case OP_SorterOpen: { VdbeCursor *pCx; + #ifndef SQLITE_OMIT_MERGE_SORT pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); if( pCx==0 ) goto no_mem; @@ -4168,6 +4169,7 @@ case OP_SorterCompare: { */ case OP_SorterData: { VdbeCursor *pC; + #ifndef SQLITE_OMIT_MERGE_SORT pOut = &aMem[pOp->p2]; pC = p->apCsr[pOp->p1]; @@ -4706,6 +4708,7 @@ case OP_Destroy: { /* out2-prerelease */ int iCnt; Vdbe *pVdbe; int iDb; + #ifndef SQLITE_OMIT_VIRTUALTABLE iCnt = 0; for(pVdbe=db->pVdbe; pVdbe; pVdbe = pVdbe->pNext){ diff --git a/tool/vdbe-compress.tcl b/tool/vdbe-compress.tcl index 3bcff9e5f0..95cc1ebf5a 100644 --- a/tool/vdbe-compress.tcl +++ b/tool/vdbe-compress.tcl @@ -79,6 +79,9 @@ while {![eof stdin]} { append unionDef " $line\n" append afterUnion $line\n lappend vlist $vname + } elseif {[regexp {^#(if|endif)} $line] && [llength $vlist]>0} { + append unionDef "$line\n" + append afterUnion $line\n } else { break } From c65714ddf063c14c95f8194f96e1b9ca2147f7ea Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 18 Sep 2012 14:00:54 +0000 Subject: [PATCH 37/60] Add the stack_usage.tcl script for analyzing the output of objdump on the amalgamation and estimating the sizes of stack frames on each function. FossilOrigin-Name: 030013ff0c7af5f146a64f9ede31297ff003e0c4 --- manifest | 11 ++--- manifest.uuid | 2 +- tool/stack_usage.tcl | 98 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 6 deletions(-) create mode 100644 tool/stack_usage.tcl diff --git a/manifest b/manifest index 2a95ccf0de..be30a3c7e9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\svdbe-compress.tcl\sscript\sso\sthat\sit\saccepts\svariable\sdeclarations\ninside\sof\s#ifdef...#endif.\nThis\senhancement\sis\sneeded\sdue\sto\sthe\schange\sof\scheck-in\s[39866c0ede5d6ef4]. -D 2012-09-18T13:20:13.054 +C Add\sthe\sstack_usage.tcl\sscript\sfor\sanalyzing\sthe\soutput\sof\sobjdump\son\sthe\namalgamation\sand\sestimating\sthe\ssizes\sof\sstack\sframes\son\seach\sfunction. +D 2012-09-18T14:00:54.587 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1006,6 +1006,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c +F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 @@ -1013,7 +1014,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 4c21ee2d26466f83dec525153e2b1506bd956701 -R b047ef3cdc6a088ac63e246ab78c4764 +P e7db056a0d76b2411cadbae077890df189e49414 +R 563f678f5a4a0eeba1c7bc783391bc58 U drh -Z bfcdd96844256469f85fbd5fa7f23556 +Z 77a009fbade94f20c493a281c0066dcb diff --git a/manifest.uuid b/manifest.uuid index e4d7cd2c9e..6adf74d6ac 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e7db056a0d76b2411cadbae077890df189e49414 \ No newline at end of file +030013ff0c7af5f146a64f9ede31297ff003e0c4 \ No newline at end of file diff --git a/tool/stack_usage.tcl b/tool/stack_usage.tcl new file mode 100644 index 0000000000..b3574f026e --- /dev/null +++ b/tool/stack_usage.tcl @@ -0,0 +1,98 @@ +#!/usr/bin/tclsh +# +# Parse the output of +# +# objdump -d sqlite3.o +# +# for x64 and generate a report showing: +# +# (1) Stack used by each function +# (2) Recursion paths and their aggregate stack depth +# +set getStack 0 +while {![eof stdin]} { + set line [gets stdin] + if {[regexp {^[0-9a-f]+ <([^>]+)>:\s*$} $line all procname]} { + set curfunc $procname + set root($curfunc) 1 + set calls($curfunc) {} + set calledby($curfunc) {} + set recursive($curfunc) {} + set stkdepth($curfunc) 0 + set getStack 1 + continue + } + if {[regexp {callq? +[0-9a-z]+ <([^>]+)>} $line all other]} { + set key [list $curfunc $other] + set callpair($key) 1 + unset -nocomplain root($curfunc) + continue + } + if {[regexp {sub +\$(0x[0-9a-z]+),%[er]sp} $line all xdepth]} { + if {$getStack} { + scan $xdepth %x depth + set stkdepth($curfunc) $depth + set getStack 0 + } + continue + } +} + +puts "****************** Stack Usage By Function ********************" +set sdlist {} +foreach f [array names stkdepth] { + lappend sdlist [list $stkdepth($f) $f] +} +foreach sd [lsort -integer -decr -index 0 $sdlist] { + foreach {depth fname} $sd break + puts [format {%6d %s} $depth $fname] +} + +puts "****************** Stack Usage By Recursion *******************" +foreach key [array names callpair] { + foreach {from to} $key break + lappend calls($from) $to + # lappend calledby($to) $from +} +proc all_descendents {root} { + global calls recursive + set todo($root) $root + set go 1 + while {$go} { + set go 0 + foreach f [array names todo] { + set path $todo($f) + unset todo($f) + if {![info exists calls($f)]} continue + foreach x $calls($f) { + if {$x==$root} { + lappend recursive($root) [concat $path $root] + } elseif {![info exists d($x)]} { + set go 1 + set todo($x) [concat $path $x] + set d($x) 1 + } + } + } + } + return [array names d] +} +set pathlist {} +foreach f [array names recursive] { + all_descendents $f + foreach m $recursive($f) { + set depth 0 + foreach b [lrange $m 0 end-1] { + set depth [expr {$depth+$stkdepth($b)}] + } + lappend pathlist [list $depth $m] + } +} +foreach path [lsort -integer -decr -index 0 $pathlist] { + foreach {depth m} $path break + set first [lindex $m 0] + puts [format {%6d %s %d} $depth $first $stkdepth($first)] + foreach b [lrange $m 1 end] { + puts " $b $stkdepth($b)" + } +} From d4305ca61c06ccaf255666bc8887194b3e0caaac Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 18 Sep 2012 17:08:33 +0000 Subject: [PATCH 38/60] Enhancements to the comments on sqlite3FindInIndex(). No code changes. FossilOrigin-Name: b1a4c394995eb90b3fb43ab204704bda03799303 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 23 ++++++++++++++++------- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index be30a3c7e9..469e571c77 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sstack_usage.tcl\sscript\sfor\sanalyzing\sthe\soutput\sof\sobjdump\son\sthe\namalgamation\sand\sestimating\sthe\ssizes\sof\sstack\sframes\son\seach\sfunction. -D 2012-09-18T14:00:54.587 +C Enhancements\sto\sthe\scomments\son\ssqlite3FindInIndex().\s\sNo\scode\schanges. +D 2012-09-18T17:08:33.701 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -130,7 +130,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 72a70dcfda75d3a1f81041ce4573e7afddcd8e4e F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/delete.c 335f36750dc6ac88d580aa36a6487459be9889de -F src/expr.c 70ded09d6ac529718aec57589ddb378c23153693 +F src/expr.c f0fc0101879ac92d145f625811f34f647b767f71 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c c82a04e7a92bb728f9ab972b76590403283be2af F src/func.c cbb90dc84b22eea25caf39528d342279e61b8898 @@ -1014,7 +1014,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P e7db056a0d76b2411cadbae077890df189e49414 -R 563f678f5a4a0eeba1c7bc783391bc58 +P 030013ff0c7af5f146a64f9ede31297ff003e0c4 +R 52fabcd4dbff22d0436068b591f13147 U drh -Z 77a009fbade94f20c493a281c0066dcb +Z 0c0f749b44c88277a286b4f0b71de6ea diff --git a/manifest.uuid b/manifest.uuid index 6adf74d6ac..9a4110e2ab 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -030013ff0c7af5f146a64f9ede31297ff003e0c4 \ No newline at end of file +b1a4c394995eb90b3fb43ab204704bda03799303 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 3fb51cf11f..36dec2c846 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1420,12 +1420,16 @@ int sqlite3CodeOnce(Parse *pParse){ /* ** This function is used by the implementation of the IN (...) operator. -** It's job is to find or create a b-tree structure that may be used -** either to test for membership of the (...) set or to iterate through -** its members, skipping duplicates. +** The pX parameter is the expression on the RHS of the IN operator, which +** might be either a list of expressions or a subquery. +** +** The job of this routine is to find or create a b-tree object that can +** be used either to test for membership in the RHS set or to iterate through +** all members of the RHS set, skipping duplicates. +** +** A cursor is opened on the b-tree object that the RHS of the IN operator +** and pX->iTable is set to the index of that cursor. ** -** The index of the cursor opened on the b-tree (database table, database index -** or ephermal table) is stored in pX->iTable before this function returns. ** The returned value of this function indicates the b-tree type, as follows: ** ** IN_INDEX_ROWID - The cursor was opened on a database table. @@ -1433,11 +1437,16 @@ int sqlite3CodeOnce(Parse *pParse){ ** IN_INDEX_EPH - The cursor was opened on a specially created and ** populated epheremal table. ** -** An existing b-tree may only be used if the SELECT is of the simple -** form: +** An existing b-tree might be used if the RHS expression pX is a simple +** subquery such as: ** ** SELECT FROM ** +** If the RHS of the IN operator is a list or a more complex subquery, then +** an ephemeral table might need to be generated from the RHS and then +** pX->iTable made to point to the ephermeral table instead of an +** existing table. +** ** If the prNotFound parameter is 0, then the b-tree will be used to iterate ** through the set members, skipping any duplicates. In this case an ** epheremal table must be used unless the selected is guaranteed From dbaee5e3422b236463d603c2ae233dc7f5e283ab Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 18 Sep 2012 19:29:06 +0000 Subject: [PATCH 39/60] Enhance IN processing to allow efficient use of indices with numeric affinities. Add test cases for IN processing that would have spotted the error in the [2be661a48023f4] check-in. FossilOrigin-Name: 5ded9b68388f4024425c11f09b03529ac89454ce --- manifest | 13 ++--- manifest.uuid | 2 +- src/expr.c | 3 +- test/in5.test | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 147 insertions(+), 9 deletions(-) create mode 100644 test/in5.test diff --git a/manifest b/manifest index 469e571c77..1295a95098 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhancements\sto\sthe\scomments\son\ssqlite3FindInIndex().\s\sNo\scode\schanges. -D 2012-09-18T17:08:33.701 +C Enhance\sIN\sprocessing\sto\sallow\sefficient\suse\sof\sindices\swith\snumeric\saffinities.\nAdd\stest\scases\sfor\sIN\sprocessing\sthat\swould\shave\sspotted\sthe\serror\sin\sthe\n[2be661a48023f4]\scheck-in. +D 2012-09-18T19:29:06.434 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -130,7 +130,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 72a70dcfda75d3a1f81041ce4573e7afddcd8e4e F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/delete.c 335f36750dc6ac88d580aa36a6487459be9889de -F src/expr.c f0fc0101879ac92d145f625811f34f647b767f71 +F src/expr.c bfed2f8ad9272aa1dd759dcae4310959b5b4c741 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c c82a04e7a92bb728f9ab972b76590403283be2af F src/func.c cbb90dc84b22eea25caf39528d342279e61b8898 @@ -519,6 +519,7 @@ F test/in.test 5941096407d8c133b9eff15bd3e666624b6cbde3 F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0 F test/in4.test 64f3cc1acde1b9161ccdd8e5bde3daefdb5b2617 +F test/in5.test 99f9a40af01711b06d2d614ecfe96129f334fba3 F test/incrblob.test 26fde912a1e0aff158b3a84ef3b265f046aad3be F test/incrblob2.test edc3a96e557bd61fb39acc8d2edd43371fbbaa19 F test/incrblob3.test aedbb35ea1b6450c33b98f2b6ed98e5020be8dc7 @@ -1014,7 +1015,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 030013ff0c7af5f146a64f9ede31297ff003e0c4 -R 52fabcd4dbff22d0436068b591f13147 +P b1a4c394995eb90b3fb43ab204704bda03799303 +R da249403d2133608cefd8edfe45e399b U drh -Z 0c0f749b44c88277a286b4f0b71de6ea +Z 42a764f0a55cecb2c00b9d26b3eb328f diff --git a/manifest.uuid b/manifest.uuid index 9a4110e2ab..40511d0079 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b1a4c394995eb90b3fb43ab204704bda03799303 \ No newline at end of file +5ded9b68388f4024425c11f09b03529ac89454ce \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 36dec2c846..23a15c4dc9 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1542,8 +1542,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ ** comparison is the same as the affinity of the column. If ** it is not, it is not possible to use any index. */ - char aff = comparisonAffinity(pX); - int affinity_ok = (pTab->aCol[iCol].affinity==aff||aff==SQLITE_AFF_NONE); + int affinity_ok = sqlite3IndexAffinityOk(pX, pTab->aCol[iCol].affinity); for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){ if( (pIdx->aiColumn[0]==iCol) diff --git a/test/in5.test b/test/in5.test new file mode 100644 index 0000000000..8a43b8d44a --- /dev/null +++ b/test/in5.test @@ -0,0 +1,138 @@ +# 2012 September 18 +# +# 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 + +do_test in5-1.1 { + execsql { + CREATE TABLE t1x(x INTEGER PRIMARY KEY); + INSERT INTO t1x VALUES(1),(3),(5),(7),(9); + CREATE TABLE t1y(y INTEGER UNIQUE); + INSERT INTO t1y VALUES(2),(4),(6),(8); + CREATE TABLE t1z(z TEXT UNIQUE); + INSERT INTO t1z VALUES('a'),('c'),('e'),('g'); + CREATE TABLE t2(a INTEGER, b INTEGER, c TEXT, d TEXT); + INSERT INTO t2 VALUES(1,2,'a','12a'),(1,2,'b','12b'), + (2,3,'g','23g'),(3,5,'c','35c'), + (4,6,'h','46h'),(5,6,'e','56e'); + CREATE TABLE t3x AS SELECT x FROM t1x; + CREATE TABLE t3y AS SELECT y FROM t1y; + CREATE TABLE t3z AS SELECT z FROM t1z; + SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t1z ORDER BY c; + } +} {12a 56e} +do_test in5-1.2 { + execsql { + SELECT d FROM t2 WHERE a IN t1y AND b IN t1x AND c IN t1z ORDER BY d; + } +} {23g} +do_test in5-1.3 { + execsql { + SELECT d FROM t2 WHERE a IN t3x AND b IN t3y AND c IN t3z ORDER BY d; + } +} {12a 56e} + + +do_test in5-2.1 { + execsql { + CREATE INDEX t2abc ON t2(a,b,c); + SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t1z ORDER BY d; + } +} {12a 56e} +do_test in5-2.2 { + execsql { + SELECT d FROM t2 WHERE a IN t1y AND b IN t1x AND c IN t1z ORDER BY d; + } +} {23g} +do_test in5-2.3 { + regexp {OpenEphemeral} [db eval { + EXPLAIN SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t1z + }] +} {0} +do_test in5-2.4 { + execsql { + SELECT d FROM t2 WHERE a IN t3x AND b IN t3y AND c IN t3z ORDER BY d; + } +} {12a 56e} +do_test in5-2.5.1 { + regexp {OpenEphemeral} [db eval { + EXPLAIN SELECT d FROM t2 WHERE a IN t3x AND b IN t1y AND c IN t1z + }] +} {1} +do_test in5-2.5.2 { + regexp {OpenEphemeral} [db eval { + EXPLAIN SELECT d FROM t2 WHERE a IN t1x AND b IN t3y AND c IN t1z + }] +} {1} +do_test in5-2.5.3 { + regexp {OpenEphemeral} [db eval { + EXPLAIN SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t3z + }] +} {1} + +do_test in5-3.1 { + execsql { + DROP INDEX t2abc; + CREATE INDEX t2ab ON t2(a,b); + SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t1z ORDER BY d; + } +} {12a 56e} +do_test in5-3.2 { + execsql { + SELECT d FROM t2 WHERE a IN t1y AND b IN t1x AND c IN t1z ORDER BY d; + } +} {23g} +do_test in5-3.3 { + regexp {OpenEphemeral} [db eval { + EXPLAIN SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t1z + }] +} {0} + +do_test in5-4.1 { + execsql { + DROP INDEX t2ab; + CREATE INDEX t2abcd ON t2(a,b,c,d); + SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t1z ORDER BY d; + } +} {12a 56e} +do_test in5-4.2 { + execsql { + SELECT d FROM t2 WHERE a IN t1y AND b IN t1x AND c IN t1z ORDER BY d; + } +} {23g} +do_test in5-4.3 { + regexp {OpenEphemeral} [db eval { + EXPLAIN SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t1z + }] +} {0} + + +do_test in5-5.1 { + execsql { + DROP INDEX t2abcd; + CREATE INDEX t2cbad ON t2(c,b,a,d); + SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t1z ORDER BY d; + } +} {12a 56e} +do_test in5-5.2 { + execsql { + SELECT d FROM t2 WHERE a IN t1y AND b IN t1x AND c IN t1z ORDER BY d; + } +} {23g} +do_test in5-5.3 { + regexp {OpenEphemeral} [db eval { + EXPLAIN SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t1z + }] +} {0} + +finish_test From ba2bba3c3257c1abf6844519ed85e5759b5ce831 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 18 Sep 2012 23:21:32 +0000 Subject: [PATCH 40/60] Silence harmless compiler warning seen with SQLITE_OMIT_DEPRECATED. FossilOrigin-Name: c5cee969322d14114e4136510c3891a2e743520d --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/prepare.c | 2 ++ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 1295a95098..0e71cfb7e7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sIN\sprocessing\sto\sallow\sefficient\suse\sof\sindices\swith\snumeric\saffinities.\nAdd\stest\scases\sfor\sIN\sprocessing\sthat\swould\shave\sspotted\sthe\serror\sin\sthe\n[2be661a48023f4]\scheck-in. -D 2012-09-18T19:29:06.434 +C Silence\sharmless\scompiler\swarning\sseen\swith\sSQLITE_OMIT_DEPRECATED. +D 2012-09-18T23:21:32.844 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -169,7 +169,7 @@ F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h 1b5dcc3dc8103d03e625b177023ee67764fa6b7c F src/pcache1.c 9fd22671c270b35131ef480bbc00392b8b5f8ab9 F src/pragma.c de7f3bc6176a7ef8f0e39da61b77ab08789e28a0 -F src/prepare.c 33291b83cca285718048d219c67b8298501fa3a5 +F src/prepare.c 931ad0d852a0df48f79adcba6ce79ca5f475625c F src/printf.c 4a9f882f1c1787a8b494a2987765acf9d97ac21f F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 9e28280ec98035f31900fdd1db01f86f68ca6c32 @@ -1015,7 +1015,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P b1a4c394995eb90b3fb43ab204704bda03799303 -R da249403d2133608cefd8edfe45e399b -U drh -Z 42a764f0a55cecb2c00b9d26b3eb328f +P 5ded9b68388f4024425c11f09b03529ac89454ce +R 8ee6066863b4421bc9631f7846e15100 +U mistachkin +Z 92a1a23d1a7ee985df165e62f42bd758 diff --git a/manifest.uuid b/manifest.uuid index 40511d0079..6227346cb8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5ded9b68388f4024425c11f09b03529ac89454ce \ No newline at end of file +c5cee969322d14114e4136510c3891a2e743520d \ No newline at end of file diff --git a/src/prepare.c b/src/prepare.c index bd2cf7aafc..5ac8de7296 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -134,7 +134,9 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ int rc; int i; +#ifndef SQLITE_OMIT_DEPRECATED int size; +#endif Table *pTab; Db *pDb; char const *azArg[4]; From ae651d614e6ebc7e738ea44e885a122b03943bfb Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 19 Sep 2012 17:31:15 +0000 Subject: [PATCH 41/60] Add comments to the WHERE_DISTINCT_* macros. No changes to code. FossilOrigin-Name: 82320501904f65030622a67836ba30f412169056 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqliteInt.h | 8 +++++--- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index ba71fd957e..2ccfddd78b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\scovering-index-scan\soptimization\sinto\strunk. -D 2012-09-19T00:35:31.172 +C Add\scomments\sto\sthe\sWHERE_DISTINCT_*\smacros.\s\sNo\schanges\sto\scode. +D 2012-09-19T17:31:15.874 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -179,7 +179,7 @@ F src/shell.c 87953c5d9c73d9494db97d1607e2e2280418f261 F src/sqlite.h.in c76c38f9635590ff5844684a7976843878327137 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h 5cbd4340146b609a8b98b908d46020d8d15153fe +F src/sqliteInt.h 7fa267db5593970061523081b29d8da7f5399a2c F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1016,7 +1016,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P c5cee969322d14114e4136510c3891a2e743520d 698b2a28004a9a2f0eabaadf36d833da4400b2bf -R 8da95659b7aa774aee09e1ca7926ee73 +P ddd5d789e7ae4a66cd7b7fa79e48d2777f95350b +R e46138ca39f138f4ac7a97431cbdd838 U drh -Z aa8acee5d32b23220a1be1b14b7c681d +Z 26ec9a3d31b656e70959884bbce24366 diff --git a/manifest.uuid b/manifest.uuid index 484bfb980b..47d3161ee7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ddd5d789e7ae4a66cd7b7fa79e48d2777f95350b \ No newline at end of file +82320501904f65030622a67836ba30f412169056 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index e20e797747..9d8d742eab 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1985,7 +1985,7 @@ struct WhereInfo { u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */ u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE or DELETE */ u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */ - u8 eDistinct; + u8 eDistinct; /* One of the WHERE_DISTINCT_* values below */ SrcList *pTabList; /* List of tables in the join */ int iTop; /* The very beginning of the WHERE loop */ int iContinue; /* Jump here to continue with next record */ @@ -1997,8 +1997,10 @@ struct WhereInfo { WhereLevel a[1]; /* Information about each nest loop in WHERE */ }; -#define WHERE_DISTINCT_UNIQUE 1 -#define WHERE_DISTINCT_ORDERED 2 +/* Allowed values for WhereInfo.eDistinct */ +#define WHERE_DISTINCT_NOT 0 /* May contain non-adjacent duplicates */ +#define WHERE_DISTINCT_UNIQUE 1 /* No duplicates */ +#define WHERE_DISTINCT_ORDERED 2 /* All duplicates are adjacent */ /* ** A NameContext defines a context in which to resolve table and column From 053a128f5534a1c55032b9c13df40342b5323fb0 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 19 Sep 2012 21:15:46 +0000 Subject: [PATCH 42/60] Tighter VDBE code for the WHERE_DISTINCT_ORDERED case of DISTINCT keyword handling. FossilOrigin-Name: 94b48064db3cbb43e911fdf7183218b08146ec10 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/select.c | 32 +++++++++++++++++++------------- src/vdbe.c | 29 +++++++++++++++++++++++------ src/vdbeInt.h | 4 +++- test/distinct.test | 20 ++++++++++++++++++-- 6 files changed, 73 insertions(+), 32 deletions(-) diff --git a/manifest b/manifest index 2ccfddd78b..4afd96e7ed 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\scomments\sto\sthe\sWHERE_DISTINCT_*\smacros.\s\sNo\schanges\sto\scode. -D 2012-09-19T17:31:15.874 +C Tighter\sVDBE\scode\sfor\sthe\sWHERE_DISTINCT_ORDERED\scase\sof\sDISTINCT\skeyword\nhandling. +D 2012-09-19T21:15:46.053 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -174,7 +174,7 @@ F src/printf.c 4a9f882f1c1787a8b494a2987765acf9d97ac21f F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 9e28280ec98035f31900fdd1db01f86f68ca6c32 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 1278b07a8c9a7f2f65b8efa8565993a56c4a58a3 +F src/select.c 63206bbfd19e0f85e609307041db9276ddf9f2c2 F src/shell.c 87953c5d9c73d9494db97d1607e2e2280418f261 F src/sqlite.h.in c76c38f9635590ff5844684a7976843878327137 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 @@ -236,9 +236,9 @@ F src/update.c 28d2d098b43a2c70dae399896ea8a02f622410ef F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f F src/util.c 0af2e515dc0dabacec931bca39525f6c3f1c5455 F src/vacuum.c 587a52bb8833d7ac15af8916f25437e2575028bd -F src/vdbe.c 16e894bd59d11c4a2c184627906c794a6bdc6eff +F src/vdbe.c b0ac98789b74dfd58106578aee425c094ecb5c53 F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb -F src/vdbeInt.h a668b303644377433e31a18d3d9efb87eefb6332 +F src/vdbeInt.h 573a43ab5697b648a1e8f3dfc7d8667d5ca55729 F src/vdbeapi.c 4c2418161cf45392ba76a7ca92f9a5f06b96f89c F src/vdbeaux.c fac025c798ad19070451b41eddc5dcd4696fdd1e F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb @@ -374,7 +374,7 @@ F test/descidx1.test 533dcbda614b0463b0ea029527fd27e5a9ab2d66 F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d F test/descidx3.test fe720e8b37d59f4cef808b0bf4e1b391c2e56b6f F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e -F test/distinct.test 328c3930fc00da96147351aa48f91bd085ed226a +F test/distinct.test c239558222e5ae357aade535bfe61aaabcb00bbf F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376 F test/e_createtable.test 0a2465736199cb5e084645a8714ee04299b81721 F test/e_delete.test 89aa84d3d1bd284a0689ede04bce10226a5aeaa5 @@ -1016,7 +1016,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P ddd5d789e7ae4a66cd7b7fa79e48d2777f95350b -R e46138ca39f138f4ac7a97431cbdd838 +P 82320501904f65030622a67836ba30f412169056 +R 9541e63a94fc58e6e6ac938d40479670 U drh -Z 26ec9a3d31b656e70959884bbce24366 +Z 981d7e657532e16949d872fc02730646 diff --git a/manifest.uuid b/manifest.uuid index 47d3161ee7..1ae05cab56 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -82320501904f65030622a67836ba30f412169056 \ No newline at end of file +94b48064db3cbb43e911fdf7183218b08146ec10 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 656f39d6e8..fdd9931e31 100644 --- a/src/select.c +++ b/src/select.c @@ -4059,29 +4059,35 @@ int sqlite3Select( if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED ){ int iJump; int iExpr; - int iFlag = ++pParse->nMem; + int nExpr = pEList->nExpr; int iBase = pParse->nMem+1; - int iBase2 = iBase + pEList->nExpr; + int iBase2 = iBase + nExpr; pParse->nMem += (pEList->nExpr*2); - /* Change the OP_OpenEphemeral coded earlier to an OP_Integer. The - ** OP_Integer initializes the "first row" flag. */ - pOp->opcode = OP_Integer; + /* Change the OP_OpenEphemeral coded earlier to an OP_Null + ** sets the MEM_Cleared bit on the first register of the + ** previous value. This will cause the OP_Ne below to always + ** fail on the first iteration of the loop even if the first + ** row is all NULLs. + */ + pOp->opcode = OP_Null; pOp->p1 = 1; - pOp->p2 = iFlag; + pOp->p2 = iBase2; + pOp->p3 = iBase2 + nExpr - 1; sqlite3ExprCodeExprList(pParse, pEList, iBase, 1); - iJump = sqlite3VdbeCurrentAddr(v) + 1 + pEList->nExpr + 1 + 1; - sqlite3VdbeAddOp2(v, OP_If, iFlag, iJump-1); - for(iExpr=0; iExprnExpr; iExpr++){ + iJump = sqlite3VdbeCurrentAddr(v) + pEList->nExpr; + for(iExpr=0; iExpra[iExpr].pExpr); - sqlite3VdbeAddOp3(v, OP_Ne, iBase+iExpr, iJump, iBase2+iExpr); + if( iExpriContinue, + iBase2+iExpr); + } sqlite3VdbeChangeP4(v, -1, (const char *)pColl, P4_COLLSEQ); sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); } - sqlite3VdbeAddOp2(v, OP_Goto, 0, pWInfo->iContinue); - - sqlite3VdbeAddOp2(v, OP_Integer, 0, iFlag); assert( sqlite3VdbeCurrentAddr(v)==iJump ); sqlite3VdbeAddOp3(v, OP_Move, iBase, iBase2, pEList->nExpr); }else{ diff --git a/src/vdbe.c b/src/vdbe.c index 68b0ebb93e..b1772c3f42 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -956,23 +956,28 @@ case OP_String: { /* out2-prerelease */ break; } -/* Opcode: Null * P2 P3 * * +/* Opcode: Null P1 P2 P3 * * ** ** Write a NULL into registers P2. If P3 greater than P2, then also write -** NULL into register P3 and ever register in between P2 and P3. If P3 +** NULL into register P3 and every register in between P2 and P3. If P3 ** is less than P2 (typically P3 is zero) then only register P2 is -** set to NULL +** set to NULL. +** +** If the P1 value is non-zero, then also set the MEM_Cleared flag so that +** NULL values will not compare equal even if SQLITE_NULLEQ is set on +** OP_Ne or OP_Eq. */ case OP_Null: { /* out2-prerelease */ int cnt; + u16 nullFlag; cnt = pOp->p3-pOp->p2; assert( pOp->p3<=p->nMem ); - pOut->flags = MEM_Null; + pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null; while( cnt>0 ){ pOut++; memAboutToChange(p, pOut); VdbeMemRelease(pOut); - pOut->flags = MEM_Null; + pOut->flags = nullFlag; cnt--; } break; @@ -1737,6 +1742,10 @@ case OP_ToReal: { /* same as TK_TO_REAL, in1 */ ** ** If the SQLITE_STOREP2 bit of P5 is set, then do not jump. Instead, ** store a boolean result (either 0, or 1, or NULL) in register P2. +** +** If the SQLITE_NULLEQ bit is set in P5, then NULL values are considered +** equal to one another, provided that they do not have their MEM_Cleared +** bit set. */ /* Opcode: Ne P1 P2 P3 P4 P5 ** @@ -1803,7 +1812,15 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ ** or not both operands are null. */ assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne ); - res = (flags1 & flags3 & MEM_Null)==0; + assert( (flags1 & MEM_Cleared)==0 ); + if( (flags1&MEM_Null)!=0 + && (flags3&MEM_Null)!=0 + && (flags3&MEM_Cleared)==0 + ){ + res = 0; /* Results are equal */ + }else{ + res = 1; /* Results are not equal */ + } }else{ /* SQLITE_NULLEQ is clear and at least one operand is NULL, ** then the result is always NULL. diff --git a/src/vdbeInt.h b/src/vdbeInt.h index e559bc2bd2..aecada6038 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -187,7 +187,9 @@ struct Mem { #define MEM_RowSet 0x0020 /* Value is a RowSet object */ #define MEM_Frame 0x0040 /* Value is a VdbeFrame object */ #define MEM_Invalid 0x0080 /* Value is undefined */ -#define MEM_TypeMask 0x00ff /* Mask of type bits */ +#define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */ +#define MEM_TypeMask 0x01ff /* Mask of type bits */ + /* Whenever Mem contains a valid string or blob representation, one of ** the following flags must be set to determine the memory management diff --git a/test/distinct.test b/test/distinct.test index 1e87246cf4..0d32628ef3 100644 --- a/test/distinct.test +++ b/test/distinct.test @@ -178,7 +178,23 @@ do_execsql_test 2.A { SELECT (SELECT DISTINCT o.a FROM t1 AS i) FROM t1 AS o ORDER BY rowid; } {a A a A} - - +do_test 3.0 { + db eval { + CREATE TABLE t3(a INTEGER, b INTEGER, c, UNIQUE(a,b)); + INSERT INTO t3 VALUES + (null, null, 1), + (null, null, 2), + (null, 3, 4), + (null, 3, 5), + (6, null, 7), + (6, null, 8); + SELECT DISTINCT a, b FROM t3 ORDER BY +a, +b; + } +} {{} {} {} 3 6 {}} +do_test 3.1 { + regexp {OpenEphemeral} [db eval { + EXPLAIN SELECT DISTINCT a, b FROM t3 ORDER BY +a, +b; + }] +} {0} finish_test From 2c79733f3ce52846df25d1a7a063fa35e8f19b57 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 20 Sep 2012 14:26:22 +0000 Subject: [PATCH 43/60] Refactoring of DISTINCT code. Change the name of the local variable "distinct" to "distinctTab". Generate cleaner code w/o unnecessary P4 and P5 values on the OP_Null for WHERE_DISTINCT_ORDERED. FossilOrigin-Name: 0cda241a2bcb3c6f2ae6c48f522780bc4eddfc02 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 28 +++++++++++++--------------- src/sqliteInt.h | 2 +- 4 files changed, 22 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index 4afd96e7ed..8c9cfcf868 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Tighter\sVDBE\scode\sfor\sthe\sWHERE_DISTINCT_ORDERED\scase\sof\sDISTINCT\skeyword\nhandling. -D 2012-09-19T21:15:46.053 +C Refactoring\sof\sDISTINCT\scode.\s\sChange\sthe\sname\sof\sthe\slocal\svariable\n"distinct"\sto\s"distinctTab".\s\sGenerate\scleaner\scode\sw/o\sunnecessary\sP4\nand\sP5\svalues\son\sthe\sOP_Null\sfor\sWHERE_DISTINCT_ORDERED. +D 2012-09-20T14:26:22.088 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -174,12 +174,12 @@ F src/printf.c 4a9f882f1c1787a8b494a2987765acf9d97ac21f F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 9e28280ec98035f31900fdd1db01f86f68ca6c32 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 63206bbfd19e0f85e609307041db9276ddf9f2c2 +F src/select.c 7878dd564f5ec107e9b58af5f3eeb27ac640770b F src/shell.c 87953c5d9c73d9494db97d1607e2e2280418f261 F src/sqlite.h.in c76c38f9635590ff5844684a7976843878327137 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h 7fa267db5593970061523081b29d8da7f5399a2c +F src/sqliteInt.h bcfaf463a0fecda2d10efd68a52fea11f1cff388 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1016,7 +1016,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 82320501904f65030622a67836ba30f412169056 -R 9541e63a94fc58e6e6ac938d40479670 +P 94b48064db3cbb43e911fdf7183218b08146ec10 +R 5e2afb7573559eb5eba9ed47e068d0d2 U drh -Z 981d7e657532e16949d872fc02730646 +Z 5042a680f6b5da609676733ff0c80d03 diff --git a/manifest.uuid b/manifest.uuid index 1ae05cab56..6c9b3f4ffe 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -94b48064db3cbb43e911fdf7183218b08146ec10 \ No newline at end of file +0cda241a2bcb3c6f2ae6c48f522780bc4eddfc02 \ No newline at end of file diff --git a/src/select.c b/src/select.c index fdd9931e31..d9266e2f33 100644 --- a/src/select.c +++ b/src/select.c @@ -541,7 +541,7 @@ static void selectInnerLoop( int srcTab, /* Pull data from this table */ int nColumn, /* Number of columns in the source table */ ExprList *pOrderBy, /* If not NULL, sort results using this key */ - int distinct, /* If >=0, make sure results are distinct */ + int distinctTab, /* If >=0, make sure results are distinct */ SelectDest *pDest, /* How to dispose of the results */ int iContinue, /* Jump here to continue with next row */ int iBreak /* Jump here to break out of the inner loop */ @@ -557,7 +557,7 @@ static void selectInnerLoop( assert( v ); if( NEVER(v==0) ) return; assert( pEList!=0 ); - hasDistinct = distinct>=0; + hasDistinct = distinctTab>=0; if( pOrderBy==0 && !hasDistinct ){ codeOffset(v, p, iContinue); } @@ -597,7 +597,7 @@ static void selectInnerLoop( if( hasDistinct ){ assert( pEList!=0 ); assert( pEList->nExpr==nColumn ); - codeDistinct(pParse, distinct, iContinue, nColumn, regResult); + codeDistinct(pParse, distinctTab, iContinue, nColumn, regResult); if( pOrderBy==0 ){ codeOffset(v, p, iContinue); } @@ -3787,7 +3787,7 @@ int sqlite3Select( ExprList *pGroupBy; /* The GROUP BY clause. May be NULL */ Expr *pHaving; /* The HAVING clause. May be NULL */ int isDistinct; /* True if the DISTINCT keyword is present */ - int distinct; /* Table to use for the distinct set */ + int distinctTab; /* Table to use for the distinct set */ int rc = 1; /* Value to return from this function */ int addrSortIndex; /* Address of an OP_OpenEphemeral instruction */ int addrDistinctIndex; /* Address of an OP_OpenEphemeral instruction */ @@ -4018,13 +4018,13 @@ int sqlite3Select( */ if( p->selFlags & SF_Distinct ){ KeyInfo *pKeyInfo; - distinct = pParse->nTab++; + distinctTab = pParse->nTab++; pKeyInfo = keyInfoFromExprList(pParse, p->pEList); - addrDistinctIndex = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, distinct, 0, 0, - (char*)pKeyInfo, P4_KEYINFO_HANDOFF); + addrDistinctIndex = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, distinctTab, + 0, 0, (char*)pKeyInfo, P4_KEYINFO_HANDOFF); sqlite3VdbeChangeP5(v, BTREE_UNORDERED); }else{ - distinct = addrDistinctIndex = -1; + distinctTab = addrDistinctIndex = -1; } /* Aggregate and non-aggregate queries are handled differently */ @@ -4049,13 +4049,14 @@ int sqlite3Select( VdbeOp *pOp; /* No longer required OpenEphemeral instr. */ assert( addrDistinctIndex>=0 ); + sqlite3VdbeChangeToNoop(v, addrDistinctIndex); pOp = sqlite3VdbeGetOp(v, addrDistinctIndex); assert( isDistinct ); assert( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED || pWInfo->eDistinct==WHERE_DISTINCT_UNIQUE ); - distinct = -1; + distinctTab = -1; if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED ){ int iJump; int iExpr; @@ -4073,7 +4074,6 @@ int sqlite3Select( pOp->opcode = OP_Null; pOp->p1 = 1; pOp->p2 = iBase2; - pOp->p3 = iBase2 + nExpr - 1; sqlite3ExprCodeExprList(pParse, pEList, iBase, 1); iJump = sqlite3VdbeCurrentAddr(v) + pEList->nExpr; @@ -4090,13 +4090,11 @@ int sqlite3Select( } assert( sqlite3VdbeCurrentAddr(v)==iJump ); sqlite3VdbeAddOp3(v, OP_Move, iBase, iBase2, pEList->nExpr); - }else{ - pOp->opcode = OP_Noop; } } /* Use the standard inner loop. */ - selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinct, pDest, + selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinctTab, pDest, pWInfo->iContinue, pWInfo->iBreak); /* End the database scan loop. @@ -4364,7 +4362,7 @@ int sqlite3Select( finalizeAggFunctions(pParse, &sAggInfo); sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL); selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy, - distinct, pDest, + distinctTab, pDest, addrOutputRow+1, addrSetAbort); sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); VdbeComment((v, "end groupby result generator")); @@ -4505,7 +4503,7 @@ int sqlite3Select( } /* endif aggregate query */ - if( distinct>=0 ){ + if( distinctTab>=0 ){ explainTempTable(pParse, "DISTINCT"); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 9d8d742eab..00aa480caf 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2059,7 +2059,7 @@ struct NameContext { ** as the OP_OpenEphm instruction is coded because not ** enough information about the compound query is known at that point. ** The KeyInfo for addrOpenTran[0] and [1] contains collating sequences -** for the result set. The KeyInfo for addrOpenTran[2] contains collating +** for the result set. The KeyInfo for addrOpenEphm[2] contains collating ** sequences for the ORDER BY clause. */ struct Select { From 634d81dee0bb3cf1034556c7dee97f6c0e6d021d Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 20 Sep 2012 15:41:31 +0000 Subject: [PATCH 44/60] Continuing incremental enhancements of SELECT code generation: Remove the Select.affinity field. Use SelectDest.affSdst instead. FossilOrigin-Name: cf40b7b5ebdacc3215d769aadacce8c9e7e9dfbb --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 12 +++++++----- src/sqliteInt.h | 11 +++++------ 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 8c9cfcf868..ed33bcc178 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Refactoring\sof\sDISTINCT\scode.\s\sChange\sthe\sname\sof\sthe\slocal\svariable\n"distinct"\sto\s"distinctTab".\s\sGenerate\scleaner\scode\sw/o\sunnecessary\sP4\nand\sP5\svalues\son\sthe\sOP_Null\sfor\sWHERE_DISTINCT_ORDERED. -D 2012-09-20T14:26:22.088 +C Continuing\sincremental\senhancements\sof\sSELECT\scode\sgeneration:\nRemove\sthe\sSelect.affinity\sfield.\s\sUse\sSelectDest.affSdst\sinstead. +D 2012-09-20T15:41:31.865 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -174,12 +174,12 @@ F src/printf.c 4a9f882f1c1787a8b494a2987765acf9d97ac21f F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 9e28280ec98035f31900fdd1db01f86f68ca6c32 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 7878dd564f5ec107e9b58af5f3eeb27ac640770b +F src/select.c 7c6d028755131a47c0521a8b697428ebd382dbd3 F src/shell.c 87953c5d9c73d9494db97d1607e2e2280418f261 F src/sqlite.h.in c76c38f9635590ff5844684a7976843878327137 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h bcfaf463a0fecda2d10efd68a52fea11f1cff388 +F src/sqliteInt.h a9708835335a62d691602f25dacaab9cdab53613 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1016,7 +1016,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 94b48064db3cbb43e911fdf7183218b08146ec10 -R 5e2afb7573559eb5eba9ed47e068d0d2 +P 0cda241a2bcb3c6f2ae6c48f522780bc4eddfc02 +R 70c119f908e0321bfe68ed5f9f70b2c3 U drh -Z 5042a680f6b5da609676733ff0c80d03 +Z 768851de231def4398f466b3e6b7ba54 diff --git a/manifest.uuid b/manifest.uuid index 6c9b3f4ffe..d4387c5465 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0cda241a2bcb3c6f2ae6c48f522780bc4eddfc02 \ No newline at end of file +cf40b7b5ebdacc3215d769aadacce8c9e7e9dfbb \ No newline at end of file diff --git a/src/select.c b/src/select.c index d9266e2f33..e456e40db8 100644 --- a/src/select.c +++ b/src/select.c @@ -655,7 +655,8 @@ static void selectInnerLoop( */ case SRT_Set: { assert( nColumn==1 ); - p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affSdst); + pDest->affSdst = + sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affSdst); if( pOrderBy ){ /* At first glance you would think we could optimize out the ** ORDER BY in this case since the order of entries in the set @@ -664,7 +665,7 @@ static void selectInnerLoop( pushOntoSorter(pParse, pOrderBy, p, regResult); }else{ int r1 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, 1, r1, &p->affinity, 1); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult,1,r1, &pDest->affSdst, 1); sqlite3ExprCacheAffinityChange(pParse, regResult, 1); sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); sqlite3ReleaseTempReg(pParse, r1); @@ -931,7 +932,8 @@ static void generateSortTail( #ifndef SQLITE_OMIT_SUBQUERY case SRT_Set: { assert( nColumn==1 ); - sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRowid, &p->affinity, 1); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRowid, + &pDest->affSdst, 1); sqlite3ExprCacheAffinityChange(pParse, regRow, 1); sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, regRowid); break; @@ -2001,10 +2003,10 @@ static int generateOutputSubroutine( case SRT_Set: { int r1; assert( pIn->nSdst==1 ); - p->affinity = + pDest->affSdst = sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affSdst); r1 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, 1, r1, &p->affinity, 1); + sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, 1, r1, &pDest->affSdst,1); sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, 1); sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iSDParm, r1); sqlite3ReleaseTempReg(pParse, r1); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 00aa480caf..8ade753a58 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -661,6 +661,7 @@ typedef struct Parse Parse; typedef struct RowSet RowSet; typedef struct Savepoint Savepoint; typedef struct Select Select; +typedef struct SelectDest SelectDest; typedef struct SrcList SrcList; typedef struct StrAccum StrAccum; typedef struct Table Table; @@ -2065,7 +2066,6 @@ struct NameContext { struct Select { ExprList *pEList; /* The fields of the result */ u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */ - char affinity; /* MakeRecord with this affinity for SRT_Set */ u16 selFlags; /* Various SF_* values */ int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */ int addrOpenEphm[3]; /* OP_OpenEphem opcodes related to this select */ @@ -2116,13 +2116,12 @@ struct Select { #define SRT_Coroutine 10 /* Generate a single row of result */ /* -** A structure used to customize the behavior of sqlite3Select(). See -** comments above sqlite3Select() for details. +** An instance of this object describes where to put of the results of +** a SELECT statement. */ -typedef struct SelectDest SelectDest; struct SelectDest { - u8 eDest; /* How to dispose of the results */ - u8 affSdst; /* Affinity used when eDest==SRT_Set */ + u8 eDest; /* How to dispose of the results. On of SRT_* above. */ + char affSdst; /* Affinity used when eDest==SRT_Set */ int iSDParm; /* A parameter used by the eDest disposal method */ int iSdst; /* Base register where results are written */ int nSdst; /* Number of registers allocated */ From e8e4af7697fb383a6ae2b7ebd16ea136007094c4 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 21 Sep 2012 00:04:28 +0000 Subject: [PATCH 45/60] Consolidate more of the DISTINCT processing logic into a single spot in the code. Reduce the number of OP_Column operations needed to perform a WHERE_DISTINCT_ORDERED. FossilOrigin-Name: 79e922f7ae29bbe06d639d648fbd72523cf9a28e --- manifest | 20 +++--- manifest.uuid | 2 +- src/expr.c | 16 +---- src/pragma.c | 2 +- src/select.c | 163 +++++++++++++++++++++++++++--------------------- src/sqliteInt.h | 10 +-- src/vdbe.c | 28 ++++++--- 7 files changed, 128 insertions(+), 113 deletions(-) diff --git a/manifest b/manifest index ed33bcc178..4edf8b5385 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Continuing\sincremental\senhancements\sof\sSELECT\scode\sgeneration:\nRemove\sthe\sSelect.affinity\sfield.\s\sUse\sSelectDest.affSdst\sinstead. -D 2012-09-20T15:41:31.865 +C Consolidate\smore\sof\sthe\sDISTINCT\sprocessing\slogic\sinto\sa\ssingle\sspot\sin\sthe\ncode.\s\sReduce\sthe\snumber\sof\sOP_Column\soperations\sneeded\sto\sperform\sa\nWHERE_DISTINCT_ORDERED. +D 2012-09-21T00:04:28.345 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -130,7 +130,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 72a70dcfda75d3a1f81041ce4573e7afddcd8e4e F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/delete.c 335f36750dc6ac88d580aa36a6487459be9889de -F src/expr.c bfed2f8ad9272aa1dd759dcae4310959b5b4c741 +F src/expr.c 4d1cef0fae6f3cf3c754773fd413f3e221021003 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c c82a04e7a92bb728f9ab972b76590403283be2af F src/func.c cbb90dc84b22eea25caf39528d342279e61b8898 @@ -168,18 +168,18 @@ F src/parse.y f29df90bd3adc64b33114ab1de9fb7768fcf2099 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h 1b5dcc3dc8103d03e625b177023ee67764fa6b7c F src/pcache1.c 9fd22671c270b35131ef480bbc00392b8b5f8ab9 -F src/pragma.c de7f3bc6176a7ef8f0e39da61b77ab08789e28a0 +F src/pragma.c 44304a69ae1486d7c3fd2d3bdd52cb555398a347 F src/prepare.c 931ad0d852a0df48f79adcba6ce79ca5f475625c F src/printf.c 4a9f882f1c1787a8b494a2987765acf9d97ac21f F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 9e28280ec98035f31900fdd1db01f86f68ca6c32 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 7c6d028755131a47c0521a8b697428ebd382dbd3 +F src/select.c c2a83ada835d3554a4d724c5358d4475aa7e1e77 F src/shell.c 87953c5d9c73d9494db97d1607e2e2280418f261 F src/sqlite.h.in c76c38f9635590ff5844684a7976843878327137 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h a9708835335a62d691602f25dacaab9cdab53613 +F src/sqliteInt.h 6d02f0bbca677887bbbe1a69c69cdde6f54adb9c F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -236,7 +236,7 @@ F src/update.c 28d2d098b43a2c70dae399896ea8a02f622410ef F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f F src/util.c 0af2e515dc0dabacec931bca39525f6c3f1c5455 F src/vacuum.c 587a52bb8833d7ac15af8916f25437e2575028bd -F src/vdbe.c b0ac98789b74dfd58106578aee425c094ecb5c53 +F src/vdbe.c 31523df2b986fc6c959dd54ca640ba865884641b F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb F src/vdbeInt.h 573a43ab5697b648a1e8f3dfc7d8667d5ca55729 F src/vdbeapi.c 4c2418161cf45392ba76a7ca92f9a5f06b96f89c @@ -1016,7 +1016,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 0cda241a2bcb3c6f2ae6c48f522780bc4eddfc02 -R 70c119f908e0321bfe68ed5f9f70b2c3 +P cf40b7b5ebdacc3215d769aadacce8c9e7e9dfbb +R d02ff4711c6f63d54e76f1ced6a5b15a U drh -Z 768851de231def4398f466b3e6b7ba54 +Z 9a19995b7c09e7ae5080d30ca61a0cd3 diff --git a/manifest.uuid b/manifest.uuid index d4387c5465..82b6711f74 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cf40b7b5ebdacc3215d769aadacce8c9e7e9dfbb \ No newline at end of file +79e922f7ae29bbe06d639d648fbd72523cf9a28e \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 23a15c4dc9..3d63738813 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2263,8 +2263,8 @@ void sqlite3ExprCacheAffinityChange(Parse *pParse, int iStart, int iCount){ void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){ int i; struct yColCache *p; - if( NEVER(iFrom==iTo) ) return; - sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg); + assert( iFrom>=iTo+nReg || iFrom+nReg<=iTo ); + sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg-1); for(i=0, p=pParse->aColCache; iiReg; if( x>=iFrom && xpVdbe, OP_Copy, iFrom+i, iTo+i); - } -} - #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) /* ** Return true if any register in the range iFrom..iTo (inclusive) diff --git a/src/pragma.c b/src/pragma.c index 6fbc7e9bb4..bee62d8718 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1234,7 +1234,7 @@ void sqlite3Pragma( sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName), P4_DYNAMIC); - sqlite3VdbeAddOp3(v, OP_Move, 2, 4, 1); + sqlite3VdbeAddOp2(v, OP_Move, 2, 4); sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2); sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1); sqlite3VdbeJumpHere(v, addr); diff --git a/src/select.c b/src/select.c index e456e40db8..39787de80a 100644 --- a/src/select.c +++ b/src/select.c @@ -525,6 +525,19 @@ static int checkForMultiColumnSelectError( } #endif +/* +** An instance of the following object is used to record information about +** how to process the DISTINCT keyword, to simplify passing that information +** into the selectInnerLoop() routine. +*/ +typedef struct DistinctCtx DistinctCtx; +struct DistinctCtx { + u8 isTnct; /* True if the DISTINCT keyword is present */ + u8 eTnctType; /* One of the WHERE_DISTINCT_* operators */ + int tabTnct; /* Ephemeral table used for DISTINCT processing */ + int addrTnct; /* Address of OP_OpenEphemeral opcode for tabTnct */ +}; + /* ** This routine generates the code for the inside of the inner loop ** of a SELECT. @@ -541,7 +554,7 @@ static void selectInnerLoop( int srcTab, /* Pull data from this table */ int nColumn, /* Number of columns in the source table */ ExprList *pOrderBy, /* If not NULL, sort results using this key */ - int distinctTab, /* If >=0, make sure results are distinct */ + DistinctCtx *pDistinct, /* If not NULL, info on how to process DISTINCT */ SelectDest *pDest, /* How to dispose of the results */ int iContinue, /* Jump here to continue with next row */ int iBreak /* Jump here to break out of the inner loop */ @@ -557,7 +570,7 @@ static void selectInnerLoop( assert( v ); if( NEVER(v==0) ) return; assert( pEList!=0 ); - hasDistinct = distinctTab>=0; + hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP; if( pOrderBy==0 && !hasDistinct ){ codeOffset(v, p, iContinue); } @@ -597,7 +610,55 @@ static void selectInnerLoop( if( hasDistinct ){ assert( pEList!=0 ); assert( pEList->nExpr==nColumn ); - codeDistinct(pParse, distinctTab, iContinue, nColumn, regResult); + switch( pDistinct->eTnctType ){ + case WHERE_DISTINCT_ORDERED: { + VdbeOp *pOp; /* No longer required OpenEphemeral instr. */ + int iJump; /* Jump destination */ + int regPrev; /* Previous row content */ + + /* Allocate space for the previous row */ + regPrev = pParse->nMem+1; + pParse->nMem += nColumn; + + /* Change the OP_OpenEphemeral coded earlier to an OP_Null + ** sets the MEM_Cleared bit on the first register of the + ** previous value. This will cause the OP_Ne below to always + ** fail on the first iteration of the loop even if the first + ** row is all NULLs. + */ + sqlite3VdbeChangeToNoop(v, pDistinct->addrTnct); + pOp = sqlite3VdbeGetOp(v, pDistinct->addrTnct); + pOp->opcode = OP_Null; + pOp->p1 = 1; + pOp->p2 = regPrev; + + iJump = sqlite3VdbeCurrentAddr(v) + nColumn; + for(i=0; ia[i].pExpr); + if( iaddrTnct); + break; + } + + default: { + assert( pDistinct->eTnctType==WHERE_DISTINCT_UNORDERED ); + codeDistinct(pParse, pDistinct->tabTnct, iContinue, nColumn, regResult); + break; + } + } if( pOrderBy==0 ){ codeOffset(v, p, iContinue); } @@ -1770,7 +1831,7 @@ static int multiSelect( sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); iStart = sqlite3VdbeCurrentAddr(v); selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr, - 0, -1, &dest, iCont, iBreak); + 0, 0, &dest, iCont, iBreak); sqlite3VdbeResolveLabel(v, iCont); sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); sqlite3VdbeResolveLabel(v, iBreak); @@ -1848,7 +1909,7 @@ static int multiSelect( sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); sqlite3ReleaseTempReg(pParse, r1); selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr, - 0, -1, &dest, iCont, iBreak); + 0, 0, &dest, iCont, iBreak); sqlite3VdbeResolveLabel(v, iCont); sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); sqlite3VdbeResolveLabel(v, iBreak); @@ -1968,7 +2029,7 @@ static int generateOutputSubroutine( (char*)pKeyInfo, p4type); sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2); sqlite3VdbeJumpHere(v, j1); - sqlite3ExprCodeCopy(pParse, pIn->iSdst, regPrev+1, pIn->nSdst); + sqlite3VdbeAddOp3(v, OP_Copy, pIn->iSdst, regPrev+1, pIn->nSdst-1); sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev); } if( pParse->db->mallocFailed ) return 0; @@ -3788,11 +3849,9 @@ int sqlite3Select( ExprList *pOrderBy; /* The ORDER BY clause. May be NULL */ ExprList *pGroupBy; /* The GROUP BY clause. May be NULL */ Expr *pHaving; /* The HAVING clause. May be NULL */ - int isDistinct; /* True if the DISTINCT keyword is present */ - int distinctTab; /* Table to use for the distinct set */ int rc = 1; /* Value to return from this function */ int addrSortIndex; /* Address of an OP_OpenEphemeral instruction */ - int addrDistinctIndex; /* Address of an OP_OpenEphemeral instruction */ + DistinctCtx sDistinct; /* Info on how to code the DISTINCT keyword */ AggInfo sAggInfo; /* Information used by aggregate queries */ int iEnd; /* Address of the end of the query */ sqlite3 *db; /* The database connection */ @@ -3918,7 +3977,7 @@ int sqlite3Select( pWhere = p->pWhere; pGroupBy = p->pGroupBy; pHaving = p->pHaving; - isDistinct = (p->selFlags & SF_Distinct)!=0; + sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0; #ifndef SQLITE_OMIT_COMPOUND_SELECT /* If there is are a sequence of queries, do the earlier ones first. @@ -3979,6 +4038,10 @@ int sqlite3Select( p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0); pGroupBy = p->pGroupBy; pOrderBy = 0; + /* Notice that even thought SF_Distinct has been cleared from p->selFlags, + ** the sDistinct.isTnct is still set. Hence, isTnct represents the + ** original setting of the SF_Distinct flag, not the current setting */ + assert( sDistinct.isTnct ); } /* If there is an ORDER BY clause, then this sorting @@ -4019,24 +4082,26 @@ int sqlite3Select( /* Open a virtual index to use for the distinct set. */ if( p->selFlags & SF_Distinct ){ - KeyInfo *pKeyInfo; - distinctTab = pParse->nTab++; - pKeyInfo = keyInfoFromExprList(pParse, p->pEList); - addrDistinctIndex = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, distinctTab, - 0, 0, (char*)pKeyInfo, P4_KEYINFO_HANDOFF); + sDistinct.tabTnct = pParse->nTab++; + sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, + sDistinct.tabTnct, 0, 0, + (char*)keyInfoFromExprList(pParse, p->pEList), + P4_KEYINFO_HANDOFF); sqlite3VdbeChangeP5(v, BTREE_UNORDERED); + sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED; }else{ - distinctTab = addrDistinctIndex = -1; + sDistinct.eTnctType = WHERE_DISTINCT_NOOP; } - /* Aggregate and non-aggregate queries are handled differently */ if( !isAgg && pGroupBy==0 ){ - ExprList *pDist = (isDistinct ? p->pEList : 0); + /* No aggregate functions and no GROUP BY clause */ + ExprList *pDist = (sDistinct.isTnct ? p->pEList : 0); /* Begin the database scan. */ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pOrderBy, pDist, 0,0); if( pWInfo==0 ) goto select_end; if( pWInfo->nRowOut < p->nSelectRow ) p->nSelectRow = pWInfo->nRowOut; + if( pWInfo->eDistinct ) sDistinct.eTnctType = pWInfo->eDistinct; /* If sorting index that was created by a prior OP_OpenEphemeral ** instruction ended up not being needed, then change the OP_OpenEphemeral @@ -4047,63 +4112,16 @@ int sqlite3Select( p->addrOpenEphm[2] = -1; } - if( pWInfo->eDistinct ){ - VdbeOp *pOp; /* No longer required OpenEphemeral instr. */ - - assert( addrDistinctIndex>=0 ); - sqlite3VdbeChangeToNoop(v, addrDistinctIndex); - pOp = sqlite3VdbeGetOp(v, addrDistinctIndex); - - assert( isDistinct ); - assert( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED - || pWInfo->eDistinct==WHERE_DISTINCT_UNIQUE - ); - distinctTab = -1; - if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED ){ - int iJump; - int iExpr; - int nExpr = pEList->nExpr; - int iBase = pParse->nMem+1; - int iBase2 = iBase + nExpr; - pParse->nMem += (pEList->nExpr*2); - - /* Change the OP_OpenEphemeral coded earlier to an OP_Null - ** sets the MEM_Cleared bit on the first register of the - ** previous value. This will cause the OP_Ne below to always - ** fail on the first iteration of the loop even if the first - ** row is all NULLs. - */ - pOp->opcode = OP_Null; - pOp->p1 = 1; - pOp->p2 = iBase2; - - sqlite3ExprCodeExprList(pParse, pEList, iBase, 1); - iJump = sqlite3VdbeCurrentAddr(v) + pEList->nExpr; - for(iExpr=0; iExpra[iExpr].pExpr); - if( iExpriContinue, - iBase2+iExpr); - } - sqlite3VdbeChangeP4(v, -1, (const char *)pColl, P4_COLLSEQ); - sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); - } - assert( sqlite3VdbeCurrentAddr(v)==iJump ); - sqlite3VdbeAddOp3(v, OP_Move, iBase, iBase2, pEList->nExpr); - } - } - /* Use the standard inner loop. */ - selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinctTab, pDest, + selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, &sDistinct, pDest, pWInfo->iContinue, pWInfo->iBreak); /* End the database scan loop. */ sqlite3WhereEnd(pWInfo); }else{ - /* This is the processing for aggregate queries */ + /* This case when there exist aggregate functions or a GROUP BY clause + ** or both */ NameContext sNC; /* Name context for processing aggregate information */ int iAMem; /* First Mem address for storing current GROUP BY */ int iBMem; /* First Mem address for previous GROUP BY */ @@ -4232,7 +4250,8 @@ int sqlite3Select( int nGroupBy; explainTempTable(pParse, - isDistinct && !(p->selFlags&SF_Distinct)?"DISTINCT":"GROUP BY"); + (sDistinct.isTnct && (p->selFlags&SF_Distinct)==0) ? + "DISTINCT" : "GROUP BY"); groupBySort = 1; nGroupBy = pGroupBy->nExpr; @@ -4364,7 +4383,7 @@ int sqlite3Select( finalizeAggFunctions(pParse, &sAggInfo); sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL); selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy, - distinctTab, pDest, + &sDistinct, pDest, addrOutputRow+1, addrSetAbort); sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); VdbeComment((v, "end groupby result generator")); @@ -4497,7 +4516,7 @@ int sqlite3Select( pOrderBy = 0; sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL); - selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, -1, + selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, 0, pDest, addrEnd, addrEnd); sqlite3ExprListDelete(db, pDel); } @@ -4505,7 +4524,7 @@ int sqlite3Select( } /* endif aggregate query */ - if( distinctTab>=0 ){ + if( sDistinct.eTnctType==WHERE_DISTINCT_UNORDERED ){ explainTempTable(pParse, "DISTINCT"); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 8ade753a58..7701b6d7cb 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1998,10 +1998,11 @@ struct WhereInfo { WhereLevel a[1]; /* Information about each nest loop in WHERE */ }; -/* Allowed values for WhereInfo.eDistinct */ -#define WHERE_DISTINCT_NOT 0 /* May contain non-adjacent duplicates */ -#define WHERE_DISTINCT_UNIQUE 1 /* No duplicates */ -#define WHERE_DISTINCT_ORDERED 2 /* All duplicates are adjacent */ +/* Allowed values for WhereInfo.eDistinct and DistinctCtx.eTnctType */ +#define WHERE_DISTINCT_NOOP 0 /* DISTINCT keyword not used */ +#define WHERE_DISTINCT_UNIQUE 1 /* No duplicates */ +#define WHERE_DISTINCT_ORDERED 2 /* All duplicates are adjacent */ +#define WHERE_DISTINCT_UNORDERED 3 /* Duplicates are scattered */ /* ** A NameContext defines a context in which to resolve table and column @@ -2816,7 +2817,6 @@ void sqlite3WhereEnd(WhereInfo*); int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8); void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); void sqlite3ExprCodeMove(Parse*, int, int, int); -void sqlite3ExprCodeCopy(Parse*, int, int, int); void sqlite3ExprCacheStore(Parse*, int, int, int); void sqlite3ExprCachePush(Parse*); void sqlite3ExprCachePop(Parse*, int); diff --git a/src/vdbe.c b/src/vdbe.c index b1772c3f42..c8066d63c0 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1020,10 +1020,10 @@ case OP_Variable: { /* out2-prerelease */ /* Opcode: Move P1 P2 P3 * * ** -** Move the values in register P1..P1+P3-1 over into -** registers P2..P2+P3-1. Registers P1..P1+P1-1 are +** Move the values in register P1..P1+P3 over into +** registers P2..P2+P3. Registers P1..P1+P3 are ** left holding a NULL. It is an error for register ranges -** P1..P1+P3-1 and P2..P2+P3-1 to overlap. +** P1..P1+P3 and P2..P2+P3 to overlap. */ case OP_Move: { char *zMalloc; /* Holding variable for allocated memory */ @@ -1031,7 +1031,7 @@ case OP_Move: { int p1; /* Register to copy from */ int p2; /* Register to copy to */ - n = pOp->p3; + n = pOp->p3 + 1; p1 = pOp->p1; p2 = pOp->p2; assert( n>0 && p1>0 && p2>0 ); @@ -1060,20 +1060,28 @@ case OP_Move: { break; } -/* Opcode: Copy P1 P2 * * * +/* Opcode: Copy P1 P2 P3 * * ** -** Make a copy of register P1 into register P2. +** Make a copy of registers P1..P1+P3 into registers P2..P2+P3. ** ** This instruction makes a deep copy of the value. A duplicate ** is made of any string or blob constant. See also OP_SCopy. */ -case OP_Copy: { /* in1, out2 */ +case OP_Copy: { + int n; + + n = pOp->p3; pIn1 = &aMem[pOp->p1]; pOut = &aMem[pOp->p2]; assert( pOut!=pIn1 ); - sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); - Deephemeralize(pOut); - REGISTER_TRACE(pOp->p2, pOut); + while( 1 ){ + sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); + Deephemeralize(pOut); + REGISTER_TRACE(pOp->p2+pOp->p3-n, pOut); + if( (n--)==0 ) break; + pOut++; + pIn1++; + } break; } From 078b1fda3421c3ea7b922ab40646c8a2d8063dda Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 21 Sep 2012 13:40:02 +0000 Subject: [PATCH 46/60] Command-line shell enhancements: Added the ".print" command. Enhanced the ".width" command so that negative widths will right-justify. FossilOrigin-Name: a1d8269da3868e41a6603c1a683e324fe21fb317 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c | 30 +++++++++++++++++++++++++----- test/shell1.test | 13 +++++++++++++ 4 files changed, 46 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 4edf8b5385..7d7d5142e9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Consolidate\smore\sof\sthe\sDISTINCT\sprocessing\slogic\sinto\sa\ssingle\sspot\sin\sthe\ncode.\s\sReduce\sthe\snumber\sof\sOP_Column\soperations\sneeded\sto\sperform\sa\nWHERE_DISTINCT_ORDERED. -D 2012-09-21T00:04:28.345 +C Command-line\sshell\senhancements:\s\sAdded\sthe\s".print"\scommand.\s\sEnhanced\nthe\s".width"\scommand\sso\sthat\snegative\swidths\swill\sright-justify. +D 2012-09-21T13:40:02.707 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -175,7 +175,7 @@ F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 9e28280ec98035f31900fdd1db01f86f68ca6c32 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c c2a83ada835d3554a4d724c5358d4475aa7e1e77 -F src/shell.c 87953c5d9c73d9494db97d1607e2e2280418f261 +F src/shell.c f41fbf4c21003a37d69b863d3c3c562a3db180a6 F src/sqlite.h.in c76c38f9635590ff5844684a7976843878327137 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 @@ -702,7 +702,7 @@ F test/shared7.test 960760bc8d03e1419e70dea69cf41db62853616e F test/shared8.test b27befbefbe7f4517f1d6b7ff8f64a41ec74165d F test/shared_err.test 91e26ec4f3fbe07951967955585137e2f18993de F test/sharedlock.test ffa0a3c4ac192145b310f1254f8afca4d553eabf -F test/shell1.test 9895ee3013742a02e5afd8d77793729967ffd195 +F test/shell1.test 272384163432c0efd2c6817396beb0d119565d53 F test/shell2.test 037d6ad16e873354195d30bb2dc4b5321788154a F test/shell3.test 9196c42772d575685e722c92b4b39053c6ebba59 F test/shell4.test aa4eef8118b412d1a01477a53426ece169ea86a9 @@ -1016,7 +1016,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P cf40b7b5ebdacc3215d769aadacce8c9e7e9dfbb -R d02ff4711c6f63d54e76f1ced6a5b15a +P 79e922f7ae29bbe06d639d648fbd72523cf9a28e +R e0319168dcbdc9e6aaca1f64320b5398 U drh -Z 9a19995b7c09e7ae5080d30ca61a0cd3 +Z e9c67fc218434dfa019e9bea621d5ceb diff --git a/manifest.uuid b/manifest.uuid index 82b6711f74..a7c439faca 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -79e922f7ae29bbe06d639d648fbd72523cf9a28e \ No newline at end of file +a1d8269da3868e41a6603c1a683e324fe21fb317 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index a17d966245..b37ddf1524 100644 --- a/src/shell.c +++ b/src/shell.c @@ -696,7 +696,7 @@ static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int }else{ w = 0; } - if( w<=0 ){ + if( w==0 ){ w = strlen30(azCol[i] ? azCol[i] : ""); if( w<10 ) w = 10; n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue); @@ -706,7 +706,11 @@ static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int p->actualWidth[i] = w; } if( p->showHeader ){ - fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " "); + if( w<0 ){ + fprintf(p->out,"%*.*s%s",-w,-w,azCol[i], i==nArg-1 ? "\n": " "); + }else{ + fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " "); + } } } if( p->showHeader ){ @@ -714,6 +718,7 @@ static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int int w; if( iactualWidth) ){ w = p->actualWidth[i]; + if( w<0 ) w = -w; }else{ w = 10; } @@ -735,8 +740,13 @@ static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int strlen30(azArg[i])>w ){ w = strlen30(azArg[i]); } - fprintf(p->out,"%-*.*s%s",w,w, - azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " "); + if( w<0 ){ + fprintf(p->out,"%*.*s%s",-w,-w, + azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " "); + }else{ + fprintf(p->out,"%-*.*s%s",w,w, + azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " "); + } } break; } @@ -1416,9 +1426,10 @@ static char zHelp[] = " list Values delimited by .separator string\n" " tabs Tab-separated values\n" " tcl TCL list elements\n" - ".nullvalue STRING Print STRING in place of NULL values\n" + ".nullvalue STRING Use STRING in place of NULL values\n" ".output FILENAME Send output to FILENAME\n" ".output stdout Send output to the screen\n" + ".print STRING... Print literal STRING\n" ".prompt MAIN CONTINUE Replace the standard prompts\n" ".quit Exit this program\n" ".read FILENAME Execute SQL in FILENAME\n" @@ -2070,6 +2081,15 @@ static int do_meta_command(char *zLine, struct callback_data *p){ } }else + if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){ + int i; + for(i=1; i1 ) fprintf(p->out, " "); + fprintf(p->out, "%s", azArg[i]); + } + fprintf(p->out, "\n"); + }else + if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){ if( nArg >= 2) { strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1); diff --git a/test/shell1.test b/test/shell1.test index 47f9e41d02..5c49d90532 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -680,6 +680,15 @@ do_test shell1-3.26.4 { catchcmd "test.db" ".width 1 1" # this should be treated the same as a '1' width for col 1 and 2 } {0 {}} +do_test shell1-3.26.5 { + catchcmd "test.db" ".mode column\n.width 10 -10\nSELECT 'abcdefg', 123456;" + # this should be treated the same as a '1' width for col 1 and 2 +} {0 {abcdefg 123456}} +do_test shell1-3.26.6 { + catchcmd "test.db" ".mode column\n.width -10 10\nSELECT 'abcdefg', 123456;" + # this should be treated the same as a '1' width for col 1 and 2 +} {0 { abcdefg 123456 }} + # .timer ON|OFF Turn the CPU timer measurement on or off do_test shell1-3.27.1 { @@ -701,6 +710,10 @@ do_test shell1-3-28.1 { ".log stdout\nSELECT coalesce(sqlite_log(123,'hello'),'456');" } "0 {(123) hello\n456}" +do_test shell1-3-29.1 { + catchcmd "test.db" ".print this is a test" +} {0 {this is a test}} + # Test the output of the ".dump" command # do_test shell1-4.1 { From cef4fc89c49cb9173abd33ed7b495e98aa363d5c Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 21 Sep 2012 22:50:45 +0000 Subject: [PATCH 47/60] Enable query planner tracing using the new (and undocumented) ".wheretrace 1" command in the command-line shell if both the shell and the core are compiled with SQLITE_DEBUG and SQLITE_ENABLE_WHERETRACE. This is not a supported API. Use for testing and debugging only. FossilOrigin-Name: 1be4b16b9e900181ae6848f2920ea646f407c9dc --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c | 7 +++++++ src/where.c | 5 +++-- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 7d7d5142e9..3c83527892 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Command-line\sshell\senhancements:\s\sAdded\sthe\s".print"\scommand.\s\sEnhanced\nthe\s".width"\scommand\sso\sthat\snegative\swidths\swill\sright-justify. -D 2012-09-21T13:40:02.707 +C Enable\squery\splanner\stracing\susing\sthe\snew\s(and\sundocumented)\s".wheretrace\s1"\ncommand\sin\sthe\scommand-line\sshell\sif\sboth\sthe\sshell\sand\sthe\score\sare\ncompiled\swith\sSQLITE_DEBUG\sand\sSQLITE_ENABLE_WHERETRACE.\s\sThis\sis\snot\sa\s\nsupported\sAPI.\sUse\sfor\stesting\sand\sdebugging\sonly. +D 2012-09-21T22:50:45.067 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -175,7 +175,7 @@ F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 9e28280ec98035f31900fdd1db01f86f68ca6c32 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c c2a83ada835d3554a4d724c5358d4475aa7e1e77 -F src/shell.c f41fbf4c21003a37d69b863d3c3c562a3db180a6 +F src/shell.c 8ee5a3cb502e2d574f97b43972e6c1e275e7bec7 F src/sqlite.h.in c76c38f9635590ff5844684a7976843878327137 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 @@ -249,7 +249,7 @@ F src/vtab.c d8020c0a0e8ccc490ca449d7e665311b6e9f3ba9 F src/wal.c 5acb3e7bbd31f10ba39acad9ce6b399055337a9d F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b -F src/where.c cc3ef08bb6a6832e888291a89993ad0828689a36 +F src/where.c 3b52eeffab96e6ee3e1593af0967206cde09c221 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 0be144b453e0622a085fae8665c32f5676708e00 @@ -1016,7 +1016,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 79e922f7ae29bbe06d639d648fbd72523cf9a28e -R e0319168dcbdc9e6aaca1f64320b5398 +P a1d8269da3868e41a6603c1a683e324fe21fb317 +R bef0447b960d60db80499ed2c662a2c0 U drh -Z e9c67fc218434dfa019e9bea621d5ceb +Z 02d70638aa79d9b39eaea60d061c0a70 diff --git a/manifest.uuid b/manifest.uuid index a7c439faca..47b6481493 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a1d8269da3868e41a6603c1a683e324fe21fb317 \ No newline at end of file +1be4b16b9e900181ae6848f2920ea646f407c9dc \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index b37ddf1524..7ad60c505b 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2513,6 +2513,13 @@ static int do_meta_command(char *zLine, struct callback_data *p){ } }else +#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) + if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){ + extern int sqlite3WhereTrace; + sqlite3WhereTrace = atoi(azArg[1]); + }else +#endif + if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){ int j; assert( nArg<=ArraySize(azArg) ); diff --git a/src/where.c b/src/where.c index 976492e845..d5a1f41f80 100644 --- a/src/where.c +++ b/src/where.c @@ -23,9 +23,10 @@ ** Trace output macros */ #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) -int sqlite3WhereTrace = 0; +/***/ int sqlite3WhereTrace = 0; #endif -#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) +#if defined(SQLITE_DEBUG) \ + && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE)) # define WHERETRACE(X) if(sqlite3WhereTrace) sqlite3DebugPrintf X #else # define WHERETRACE(X) From 86ae51c9916a660ec9ee9f7222ab8ab2a76e1123 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 24 Sep 2012 11:43:43 +0000 Subject: [PATCH 48/60] Update documentation to describe the threadsafety of sqlite3_enable_shared_cache(). FossilOrigin-Name: e081890cd77ad8de4bf55a8f8cf9d63bfaaf8218 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 3 +++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 3c83527892..8f9cec3047 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enable\squery\splanner\stracing\susing\sthe\snew\s(and\sundocumented)\s".wheretrace\s1"\ncommand\sin\sthe\scommand-line\sshell\sif\sboth\sthe\sshell\sand\sthe\score\sare\ncompiled\swith\sSQLITE_DEBUG\sand\sSQLITE_ENABLE_WHERETRACE.\s\sThis\sis\snot\sa\s\nsupported\sAPI.\sUse\sfor\stesting\sand\sdebugging\sonly. -D 2012-09-21T22:50:45.067 +C Update\sdocumentation\sto\sdescribe\sthe\sthreadsafety\sof\s\nsqlite3_enable_shared_cache(). +D 2012-09-24T11:43:43.748 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -176,7 +176,7 @@ F src/resolve.c 9e28280ec98035f31900fdd1db01f86f68ca6c32 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c c2a83ada835d3554a4d724c5358d4475aa7e1e77 F src/shell.c 8ee5a3cb502e2d574f97b43972e6c1e275e7bec7 -F src/sqlite.h.in c76c38f9635590ff5844684a7976843878327137 +F src/sqlite.h.in cbe846facaba903654b4136c97e7f57b3ac0bac7 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h 6d02f0bbca677887bbbe1a69c69cdde6f54adb9c @@ -1016,7 +1016,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P a1d8269da3868e41a6603c1a683e324fe21fb317 -R bef0447b960d60db80499ed2c662a2c0 +P 1be4b16b9e900181ae6848f2920ea646f407c9dc +R 0efc5261436fa50b53879d926ef0509e U drh -Z 02d70638aa79d9b39eaea60d061c0a70 +Z f86abf9bd38d08dcead454a5f06f2799 diff --git a/manifest.uuid b/manifest.uuid index 47b6481493..11bb5536da 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1be4b16b9e900181ae6848f2920ea646f407c9dc \ No newline at end of file +e081890cd77ad8de4bf55a8f8cf9d63bfaaf8218 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index cab0b8418c..bf97679ab8 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -4747,6 +4747,9 @@ void *sqlite3_update_hook( ** future releases of SQLite. Applications that care about shared ** cache setting should set it explicitly. ** +** This interface is threadsafe on processors where writing a +** 32-bit integer is atomic. +** ** See Also: [SQLite Shared-Cache Mode] */ int sqlite3_enable_shared_cache(int); From 46ec5b63e2534242a7c608fab9c663eb3af62c81 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 24 Sep 2012 15:30:54 +0000 Subject: [PATCH 49/60] Change the internal sqlite3WhereBegin() to report that the ORDER BY clause is satisfied by indices using the WhereInfo.nOBSat field of the returned structure. FossilOrigin-Name: 22989f3588531efd555cc29d6c576e7a34b7edc4 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/select.c | 13 +++++++------ src/sqliteInt.h | 32 ++++++++++++++++---------------- src/where.c | 30 +++++++++++++++--------------- 5 files changed, 47 insertions(+), 46 deletions(-) diff --git a/manifest b/manifest index 8f9cec3047..534ea306e5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sdocumentation\sto\sdescribe\sthe\sthreadsafety\sof\s\nsqlite3_enable_shared_cache(). -D 2012-09-24T11:43:43.748 +C Change\sthe\sinternal\ssqlite3WhereBegin()\sto\sreport\sthat\sthe\sORDER\sBY\sclause\nis\ssatisfied\sby\sindices\susing\sthe\sWhereInfo.nOBSat\sfield\sof\sthe\sreturned\nstructure. +D 2012-09-24T15:30:54.533 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -174,12 +174,12 @@ F src/printf.c 4a9f882f1c1787a8b494a2987765acf9d97ac21f F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 9e28280ec98035f31900fdd1db01f86f68ca6c32 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c c2a83ada835d3554a4d724c5358d4475aa7e1e77 +F src/select.c 1fad66b73a69c4004c9969a95b46d1f03390677d F src/shell.c 8ee5a3cb502e2d574f97b43972e6c1e275e7bec7 F src/sqlite.h.in cbe846facaba903654b4136c97e7f57b3ac0bac7 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h 6d02f0bbca677887bbbe1a69c69cdde6f54adb9c +F src/sqliteInt.h 6b17114bb5c6ae30d360aeeef30ab40587afad4e F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -249,7 +249,7 @@ F src/vtab.c d8020c0a0e8ccc490ca449d7e665311b6e9f3ba9 F src/wal.c 5acb3e7bbd31f10ba39acad9ce6b399055337a9d F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b -F src/where.c 3b52eeffab96e6ee3e1593af0967206cde09c221 +F src/where.c af126a6cdb290c2d79ef18bb41bbca949c9cad61 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 0be144b453e0622a085fae8665c32f5676708e00 @@ -1016,7 +1016,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 1be4b16b9e900181ae6848f2920ea646f407c9dc -R 0efc5261436fa50b53879d926ef0509e +P e081890cd77ad8de4bf55a8f8cf9d63bfaaf8218 +R 4ad3ce4fdebd545cd663ab5469164871 U drh -Z f86abf9bd38d08dcead454a5f06f2799 +Z 1dbcfbc31e18555fa81506ef779ada01 diff --git a/manifest.uuid b/manifest.uuid index 11bb5536da..79fb09f471 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e081890cd77ad8de4bf55a8f8cf9d63bfaaf8218 \ No newline at end of file +22989f3588531efd555cc29d6c576e7a34b7edc4 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 39787de80a..01fe27694f 100644 --- a/src/select.c +++ b/src/select.c @@ -4098,10 +4098,11 @@ int sqlite3Select( ExprList *pDist = (sDistinct.isTnct ? p->pEList : 0); /* Begin the database scan. */ - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pOrderBy, pDist, 0,0); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pOrderBy, pDist, 0,0); if( pWInfo==0 ) goto select_end; if( pWInfo->nRowOut < p->nSelectRow ) p->nSelectRow = pWInfo->nRowOut; if( pWInfo->eDistinct ) sDistinct.eTnctType = pWInfo->eDistinct; + if( pOrderBy && pWInfo->nOBSat==pOrderBy->nExpr ) pOrderBy = 0; /* If sorting index that was created by a prior OP_OpenEphemeral ** instruction ended up not being needed, then change the OP_OpenEphemeral @@ -4229,14 +4230,13 @@ int sqlite3Select( ** in the right order to begin with. */ sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pGroupBy, 0, 0, 0); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, 0, 0); if( pWInfo==0 ) goto select_end; - if( pGroupBy==0 ){ + if( pWInfo->nOBSat==pGroupBy->nExpr ){ /* The optimizer is able to deliver rows in group by order so ** we do not have to sort. The OP_OpenEphemeral table will be ** cancelled later because we still need to use the pKeyInfo */ - pGroupBy = p->pGroupBy; groupBySort = 0; }else{ /* Rows are coming out in undetermined order. We have to push @@ -4486,6 +4486,7 @@ int sqlite3Select( u8 flag = minMaxQuery(p); if( flag ){ assert( !ExprHasProperty(p->pEList->a[0].pExpr, EP_xIsSelect) ); + assert( p->pEList->a[0].pExpr->x.pList->nExpr==1 ); pMinMax = sqlite3ExprListDup(db, p->pEList->a[0].pExpr->x.pList,0); pDel = pMinMax; if( pMinMax && !db->mallocFailed ){ @@ -4499,13 +4500,13 @@ int sqlite3Select( ** of output. */ resetAccumulator(pParse, &sAggInfo); - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pMinMax,0,flag,0); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMax,0,flag,0); if( pWInfo==0 ){ sqlite3ExprListDelete(db, pDel); goto select_end; } updateAccumulator(pParse, &sAggInfo); - if( !pMinMax && flag ){ + if( pWInfo->nOBSat>0 ){ sqlite3VdbeAddOp2(v, OP_Goto, 0, pWInfo->iBreak); VdbeComment((v, "%s() by index", (flag==WHERE_ORDERBY_MIN?"min":"max"))); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7701b6d7cb..7b9894254a 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1982,20 +1982,21 @@ struct WhereLevel { ** into the second half to give some continuity. */ struct WhereInfo { - Parse *pParse; /* Parsing and code generating context */ - u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */ - u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE or DELETE */ - u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */ - u8 eDistinct; /* One of the WHERE_DISTINCT_* values below */ - SrcList *pTabList; /* List of tables in the join */ - int iTop; /* The very beginning of the WHERE loop */ - int iContinue; /* Jump here to continue with next record */ - int iBreak; /* Jump here to break out of the loop */ - int nLevel; /* Number of nested loop */ - struct WhereClause *pWC; /* Decomposition of the WHERE clause */ - double savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */ - double nRowOut; /* Estimated number of output rows */ - WhereLevel a[1]; /* Information about each nest loop in WHERE */ + Parse *pParse; /* Parsing and code generating context */ + SrcList *pTabList; /* List of tables in the join */ + u16 nOBSat; /* Number of ORDER BY terms satisfied by indices */ + u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */ + u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE/DELETE */ + u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */ + u8 eDistinct; /* One of the WHERE_DISTINCT_* values below */ + int iTop; /* The very beginning of the WHERE loop */ + int iContinue; /* Jump here to continue with next record */ + int iBreak; /* Jump here to break out of the loop */ + int nLevel; /* Number of nested loop */ + struct WhereClause *pWC; /* Decomposition of the WHERE clause */ + double savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */ + double nRowOut; /* Estimated number of output rows */ + WhereLevel a[1]; /* Information about each nest loop in WHERE */ }; /* Allowed values for WhereInfo.eDistinct and DistinctCtx.eTnctType */ @@ -2811,8 +2812,7 @@ Expr *sqlite3LimitWhere(Parse *, SrcList *, Expr *, ExprList *, Expr *, Expr *, #endif void sqlite3DeleteFrom(Parse*, SrcList*, Expr*); void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int); -WhereInfo *sqlite3WhereBegin( - Parse*,SrcList*,Expr*,ExprList**,ExprList*,u16,int); +WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int); void sqlite3WhereEnd(WhereInfo*); int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8); void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); diff --git a/src/where.c b/src/where.c index d5a1f41f80..ba885f1304 100644 --- a/src/where.c +++ b/src/where.c @@ -4667,24 +4667,24 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ ** ** ORDER BY CLAUSE PROCESSING ** -** *ppOrderBy is a pointer to the ORDER BY clause of a SELECT statement, +** pOrderBy is a pointer to the ORDER BY clause of a SELECT statement, ** if there is one. If there is no ORDER BY clause or if this routine -** is called from an UPDATE or DELETE statement, then ppOrderBy is NULL. +** is called from an UPDATE or DELETE statement, then pOrderBy is NULL. ** ** If an index can be used so that the natural output order of the table ** scan is correct for the ORDER BY clause, then that index is used and -** *ppOrderBy is set to NULL. This is an optimization that prevents an -** unnecessary sort of the result set if an index appropriate for the -** ORDER BY clause already exists. +** the returned WhereInfo.nOBSat field is set to pOrderBy->nExpr. This +** is an optimization that prevents an unnecessary sort of the result set +** if an index appropriate for the ORDER BY clause already exists. ** ** If the where clause loops cannot be arranged to provide the correct -** output order, then the *ppOrderBy is unchanged. +** output order, then WhereInfo.nOBSat is 0. */ WhereInfo *sqlite3WhereBegin( Parse *pParse, /* The parser context */ SrcList *pTabList, /* A list of all tables to be scanned */ Expr *pWhere, /* The WHERE clause */ - ExprList **ppOrderBy, /* An ORDER BY clause, or NULL */ + ExprList *pOrderBy, /* An ORDER BY clause, or NULL */ ExprList *pDistinct, /* The select-list for DISTINCT queries - or NULL */ u16 wctrlFlags, /* One of the WHERE_* flags defined in sqliteInt.h */ int iIdxCur /* If WHERE_ONETABLE_ONLY is set, index cursor number */ @@ -4909,7 +4909,7 @@ WhereInfo *sqlite3WhereBegin( for(j=iFrom, pTabItem=&pTabList->a[j]; jjointype & (JT_LEFT|JT_CROSS))!=0; @@ -4920,7 +4920,7 @@ WhereInfo *sqlite3WhereBegin( continue; } mask = (isOptimal ? m : notReady); - pOrderBy = ((i==0 && ppOrderBy )?*ppOrderBy:0); + pOB = (i==0) ? pOrderBy : 0; pDist = (i==0 ? pDistinct : 0); if( pTabItem->pIndex==0 ) nUnconstrained++; @@ -4930,12 +4930,12 @@ WhereInfo *sqlite3WhereBegin( #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pTabItem->pTab) ){ sqlite3_index_info **pp = &pWInfo->a[j].pIdxInfo; - bestVirtualIndex(pParse, pWC, pTabItem, mask, notReady, pOrderBy, + bestVirtualIndex(pParse, pWC, pTabItem, mask, notReady, pOB, &sCost, pp); }else #endif { - bestBtreeIndex(pParse, pWC, pTabItem, mask, notReady, pOrderBy, + bestBtreeIndex(pParse, pWC, pTabItem, mask, notReady, pOB, pDist, &sCost); } assert( isOptimal || (sCost.used¬Ready)==0 ); @@ -4995,8 +4995,8 @@ WhereInfo *sqlite3WhereBegin( " with cost=%g and nRow=%g\n", bestJ, pLevel-pWInfo->a, bestPlan.rCost, bestPlan.plan.nRow)); /* The ALWAYS() that follows was added to hush up clang scan-build */ - if( (bestPlan.plan.wsFlags & WHERE_ORDERBY)!=0 && ALWAYS(ppOrderBy) ){ - *ppOrderBy = 0; + if( (bestPlan.plan.wsFlags & WHERE_ORDERBY)!=0 ){ + pWInfo->nOBSat = pOrderBy->nExpr; } if( (bestPlan.plan.wsFlags & WHERE_DISTINCT)!=0 ){ assert( pWInfo->eDistinct==0 ); @@ -5049,8 +5049,8 @@ WhereInfo *sqlite3WhereBegin( /* If the total query only selects a single row, then the ORDER BY ** clause is irrelevant. */ - if( (andFlags & WHERE_UNIQUE)!=0 && ppOrderBy ){ - *ppOrderBy = 0; + if( (andFlags & WHERE_UNIQUE)!=0 && pOrderBy ){ + pWInfo->nOBSat = pOrderBy->nExpr; } /* If the caller is an UPDATE or DELETE statement that is requesting From 4d85fa760f28582b4482e98878f7777f8d1fa873 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 24 Sep 2012 19:50:00 +0000 Subject: [PATCH 50/60] Remove an unused subfunction parameter and an obsolete comment from the query planner logic in where.c. FossilOrigin-Name: 349a55cd8ba9ce65ebfd987ecfebd1204f7d0a85 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 20 ++++++++++++-------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 534ea306e5..2e6bf42149 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sinternal\ssqlite3WhereBegin()\sto\sreport\sthat\sthe\sORDER\sBY\sclause\nis\ssatisfied\sby\sindices\susing\sthe\sWhereInfo.nOBSat\sfield\sof\sthe\sreturned\nstructure. -D 2012-09-24T15:30:54.533 +C Remove\san\sunused\ssubfunction\sparameter\sand\san\sobsolete\scomment\sfrom\sthe\nquery\splanner\slogic\sin\swhere.c. +D 2012-09-24T19:50:00.842 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -249,7 +249,7 @@ F src/vtab.c d8020c0a0e8ccc490ca449d7e665311b6e9f3ba9 F src/wal.c 5acb3e7bbd31f10ba39acad9ce6b399055337a9d F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b -F src/where.c af126a6cdb290c2d79ef18bb41bbca949c9cad61 +F src/where.c 40708330a0e9bf79c0ab97109b8014fa04cce858 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 0be144b453e0622a085fae8665c32f5676708e00 @@ -1016,7 +1016,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P e081890cd77ad8de4bf55a8f8cf9d63bfaaf8218 -R 4ad3ce4fdebd545cd663ab5469164871 +P 22989f3588531efd555cc29d6c576e7a34b7edc4 +R af274415395e47bec73279dd70f3872e U drh -Z 1dbcfbc31e18555fa81506ef779ada01 +Z 2c59ca6ec247c019d5fe7043b4d83355 diff --git a/manifest.uuid b/manifest.uuid index 79fb09f471..2d6a191e78 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -22989f3588531efd555cc29d6c576e7a34b7edc4 \ No newline at end of file +349a55cd8ba9ce65ebfd987ecfebd1204f7d0a85 \ No newline at end of file diff --git a/src/where.c b/src/where.c index ba885f1304..85fb1ed4f0 100644 --- a/src/where.c +++ b/src/where.c @@ -1813,7 +1813,7 @@ static void TRACE_IDX_OUTPUTS(sqlite3_index_info *p){ */ static void bestIndex( Parse*, WhereClause*, struct SrcList_item*, - Bitmask, Bitmask, ExprList*, WhereCost*); + Bitmask, Bitmask, WhereCost*); /* ** This routine attempts to find an scanning strategy that can be used @@ -1867,7 +1867,7 @@ static void bestOrClauseIndex( )); if( pOrTerm->eOperator==WO_AND ){ WhereClause *pAndWC = &pOrTerm->u.pAndInfo->wc; - bestIndex(pParse, pAndWC, pSrc, notReady, notValid, 0, &sTermCost); + bestIndex(pParse, pAndWC, pSrc, notReady, notValid, &sTermCost); }else if( pOrTerm->leftCursor==iCur ){ WhereClause tempWC; tempWC.pParse = pWC->pParse; @@ -1877,7 +1877,7 @@ static void bestOrClauseIndex( tempWC.a = pOrTerm; tempWC.wctrlFlags = 0; tempWC.nTerm = 1; - bestIndex(pParse, &tempWC, pSrc, notReady, notValid, 0, &sTermCost); + bestIndex(pParse, &tempWC, pSrc, notReady, notValid, &sTermCost); }else{ continue; } @@ -3388,6 +3388,12 @@ static void bestBtreeIndex( ** best query plan and its cost into the WhereCost object supplied ** as the last parameter. This function may calculate the cost of ** both real and virtual table scans. +** +** This function does not take ORDER BY or DISTINCT into account. Nor +** does it remember the virtual table query plan. All it does is compute +** the cost while determining if an OR optimization is applicable. The +** details will be reconsidered later if the optimization is found to be +** applicable. */ static void bestIndex( Parse *pParse, /* The parsing context */ @@ -3395,13 +3401,12 @@ static void bestIndex( struct SrcList_item *pSrc, /* The FROM clause term to search */ Bitmask notReady, /* Mask of cursors not available for indexing */ Bitmask notValid, /* Cursors not available for any purpose */ - ExprList *pOrderBy, /* The ORDER BY clause */ WhereCost *pCost /* Lowest cost query plan */ ){ #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pSrc->pTab) ){ sqlite3_index_info *p = 0; - bestVirtualIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost,&p); + bestVirtualIndex(pParse, pWC, pSrc, notReady, notValid, 0, pCost, &p); if( p->needToFreeIdxStr ){ sqlite3_free(p->idxStr); } @@ -3409,7 +3414,7 @@ static void bestIndex( }else #endif { - bestBtreeIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, 0, pCost); + bestBtreeIndex(pParse, pWC, pSrc, notReady, notValid, 0, 0, pCost); } } @@ -4698,7 +4703,7 @@ WhereInfo *sqlite3WhereBegin( WhereMaskSet *pMaskSet; /* The expression mask set */ WhereClause *pWC; /* Decomposition of the WHERE clause */ struct SrcList_item *pTabItem; /* A single entry from pTabList */ - WhereLevel *pLevel; /* A single level in the pWInfo list */ + WhereLevel *pLevel; /* A single level in pWInfo->a[] */ int iFrom; /* First unused FROM clause element */ int andFlags; /* AND-ed combination of all pWC->a[].wtFlags */ sqlite3 *db; /* Database connection */ @@ -4994,7 +4999,6 @@ WhereInfo *sqlite3WhereBegin( WHERETRACE(("*** Optimizer selects table %d for loop %d" " with cost=%g and nRow=%g\n", bestJ, pLevel-pWInfo->a, bestPlan.rCost, bestPlan.plan.nRow)); - /* The ALWAYS() that follows was added to hush up clang scan-build */ if( (bestPlan.plan.wsFlags & WHERE_ORDERBY)!=0 ){ pWInfo->nOBSat = pOrderBy->nExpr; } From 56f1b99d4dd96241b1ba7101bbc1cfacd80c1eec Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 25 Sep 2012 14:29:39 +0000 Subject: [PATCH 51/60] Pass information around between the major routines of the query planner using a single pointer to a structure rather than a long list of parameters. FossilOrigin-Name: 1104d42e104d561ce60d05d158acfe499ee9fd50 --- manifest | 15 +- manifest.uuid | 2 +- src/where.c | 372 +++++++++++++++++++++++++------------------------- 3 files changed, 195 insertions(+), 194 deletions(-) diff --git a/manifest b/manifest index 2e6bf42149..9b64595abd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunused\ssubfunction\sparameter\sand\san\sobsolete\scomment\sfrom\sthe\nquery\splanner\slogic\sin\swhere.c. -D 2012-09-24T19:50:00.842 +C Pass\sinformation\saround\sbetween\sthe\smajor\sroutines\sof\sthe\squery\splanner\nusing\sa\ssingle\spointer\sto\sa\sstructure\srather\sthan\sa\slong\slist\sof\sparameters. +D 2012-09-25T14:29:39.134 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -249,7 +249,7 @@ F src/vtab.c d8020c0a0e8ccc490ca449d7e665311b6e9f3ba9 F src/wal.c 5acb3e7bbd31f10ba39acad9ce6b399055337a9d F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b -F src/where.c 40708330a0e9bf79c0ab97109b8014fa04cce858 +F src/where.c 82be1d2f8f27012de0ed9d0977753ed24312b791 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 0be144b453e0622a085fae8665c32f5676708e00 @@ -1016,7 +1016,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 22989f3588531efd555cc29d6c576e7a34b7edc4 -R af274415395e47bec73279dd70f3872e +P 349a55cd8ba9ce65ebfd987ecfebd1204f7d0a85 +R b0986bef8aa73322a60d8a15dd219873 +T *branch * qp-enhancements +T *sym-qp-enhancements * +T -sym-trunk * U drh -Z 2c59ca6ec247c019d5fe7043b4d83355 +Z 6cfa0793222da70bc8fbd646a62c8a2a diff --git a/manifest.uuid b/manifest.uuid index 2d6a191e78..4dfae10d21 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -349a55cd8ba9ce65ebfd987ecfebd1204f7d0a85 \ No newline at end of file +1104d42e104d561ce60d05d158acfe499ee9fd50 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 85fb1ed4f0..66fe0516a6 100644 --- a/src/where.c +++ b/src/where.c @@ -267,6 +267,26 @@ struct WhereCost { #define WHERE_DISTINCT 0x40000000 /* Correct order for DISTINCT */ #define WHERE_COVER_SCAN 0x80000000 /* Full scan of a covering index */ +/* +** This module contains many separate subroutines that work together to +** find the best indices to use for accessing a particular table in a query. +** An instance of the following structure holds context information about the +** index search so that it can be more easily passed between the various +** routines. +*/ +typedef struct WhereBestIdx WhereBestIdx; +struct WhereBestIdx { + Parse *pParse; /* Parser context */ + WhereClause *pWC; /* The WHERE clause */ + struct SrcList_item *pSrc; /* The FROM clause term to search */ + Bitmask notReady; /* Mask of cursors not available */ + Bitmask notValid; /* Cursors not available for any purpose */ + ExprList *pOrderBy; /* The ORDER BY clause */ + ExprList *pDistinct; /* The select-list if query is DISTINCT */ + sqlite3_index_info **ppIdxInfo; /* Index information passed to xBestIndex */ + WhereCost cost; /* Lowest cost query plan */ +}; + /* ** Initialize a preallocated WhereClause structure. */ @@ -1811,9 +1831,7 @@ static void TRACE_IDX_OUTPUTS(sqlite3_index_info *p){ /* ** Required because bestIndex() is called by bestOrClauseIndex() */ -static void bestIndex( - Parse*, WhereClause*, struct SrcList_item*, - Bitmask, Bitmask, WhereCost*); +static void bestIndex(WhereBestIdx*); /* ** This routine attempts to find an scanning strategy that can be used @@ -1822,20 +1840,14 @@ static void bestIndex( ** The table associated with FROM clause term pSrc may be either a ** regular B-Tree table or a virtual table. */ -static void bestOrClauseIndex( - Parse *pParse, /* The parsing context */ - WhereClause *pWC, /* The WHERE clause */ - struct SrcList_item *pSrc, /* The FROM clause term to search */ - Bitmask notReady, /* Mask of cursors not available for indexing */ - Bitmask notValid, /* Cursors not available for any purpose */ - ExprList *pOrderBy, /* The ORDER BY clause */ - WhereCost *pCost /* Lowest cost query plan */ -){ +static void bestOrClauseIndex(WhereBestIdx *p){ #ifndef SQLITE_OMIT_OR_OPTIMIZATION - const int iCur = pSrc->iCursor; /* The cursor of the table to be accessed */ + WhereClause *pWC = p->pWC; /* The WHERE clause */ + struct SrcList_item *pSrc = p->pSrc; /* The FROM clause term to search */ + const int iCur = pSrc->iCursor; /* The cursor of the table */ const Bitmask maskSrc = getMask(pWC->pMaskSet, iCur); /* Bitmask for pSrc */ WhereTerm * const pWCEnd = &pWC->a[pWC->nTerm]; /* End of pWC->a[] */ - WhereTerm *pTerm; /* A single term of the WHERE clause */ + WhereTerm *pTerm; /* A single term of the WHERE clause */ /* The OR-clause optimization is disallowed if the INDEXED BY or ** NOT INDEXED clauses are used or if the WHERE_AND_ONLY bit is set. */ @@ -1849,7 +1861,7 @@ static void bestOrClauseIndex( /* Search the WHERE clause terms for a usable WO_OR term. */ for(pTerm=pWC->a; pTermeOperator==WO_OR - && ((pTerm->prereqAll & ~maskSrc) & notReady)==0 + && ((pTerm->prereqAll & ~maskSrc) & p->notReady)==0 && (pTerm->u.pOrInfo->indexable & maskSrc)!=0 ){ WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc; @@ -1859,15 +1871,19 @@ static void bestOrClauseIndex( double rTotal = 0; double nRow = 0; Bitmask used = 0; + WhereBestIdx sBOI; + sBOI = *p; + sBOI.pOrderBy = 0; + sBOI.pDistinct = 0; + sBOI.ppIdxInfo = 0; for(pOrTerm=pOrWC->a; pOrTerma), (pTerm - pWC->a) )); if( pOrTerm->eOperator==WO_AND ){ - WhereClause *pAndWC = &pOrTerm->u.pAndInfo->wc; - bestIndex(pParse, pAndWC, pSrc, notReady, notValid, &sTermCost); + sBOI.pWC = &pOrTerm->u.pAndInfo->wc; + bestIndex(&sBOI); }else if( pOrTerm->leftCursor==iCur ){ WhereClause tempWC; tempWC.pParse = pWC->pParse; @@ -1877,19 +1893,20 @@ static void bestOrClauseIndex( tempWC.a = pOrTerm; tempWC.wctrlFlags = 0; tempWC.nTerm = 1; - bestIndex(pParse, &tempWC, pSrc, notReady, notValid, &sTermCost); + sBOI.pWC = &tempWC; + bestIndex(&sBOI); }else{ continue; } - rTotal += sTermCost.rCost; - nRow += sTermCost.plan.nRow; - used |= sTermCost.used; - if( rTotal>=pCost->rCost ) break; + rTotal += sBOI.cost.rCost; + nRow += sBOI.cost.plan.nRow; + used |= sBOI.cost.used; + if( rTotal>=p->cost.rCost ) break; } /* If there is an ORDER BY clause, increase the scan cost to account ** for the cost of the sort. */ - if( pOrderBy!=0 ){ + if( p->pOrderBy!=0 ){ WHERETRACE(("... sorting increases OR cost %.9g to %.9g\n", rTotal, rTotal+nRow*estLog(nRow))); rTotal += nRow*estLog(nRow); @@ -1899,12 +1916,12 @@ static void bestOrClauseIndex( ** less than the current cost stored in pCost, replace the contents ** of pCost. */ WHERETRACE(("... multi-index OR cost=%.9g nrow=%.9g\n", rTotal, nRow)); - if( rTotalrCost ){ - pCost->rCost = rTotal; - pCost->used = used; - pCost->plan.nRow = nRow; - pCost->plan.wsFlags = flags; - pCost->plan.u.pTerm = pTerm; + if( rTotalcost.rCost ){ + p->cost.rCost = rTotal; + p->cost.used = used; + p->cost.plan.nRow = nRow; + p->cost.plan.wsFlags = flags; + p->cost.plan.u.pTerm = pTerm; } } } @@ -1941,15 +1958,12 @@ static int termCanDriveIndex( ** is taken into account, then alter the query plan to use the ** transient index. */ -static void bestAutomaticIndex( - Parse *pParse, /* The parsing context */ - WhereClause *pWC, /* The WHERE clause */ - struct SrcList_item *pSrc, /* The FROM clause term to search */ - Bitmask notReady, /* Mask of cursors that are not available */ - WhereCost *pCost /* Lowest cost query plan */ -){ - double nTableRow; /* Rows in the input table */ - double logN; /* log(nTableRow) */ +static void bestAutomaticIndex(WhereBestIdx *p){ + Parse *pParse = p->pParse; /* The parsing context */ + WhereClause *pWC = p->pWC; /* The WHERE clause */ + struct SrcList_item *pSrc = p->pSrc; /* The FROM clause term to search */ + double nTableRow; /* Rows in the input table */ + double logN; /* log(nTableRow) */ double costTempIdx; /* per-query cost of the transient index */ WhereTerm *pTerm; /* A single term of the WHERE clause */ WhereTerm *pWCEnd; /* End of pWC->a[] */ @@ -1963,7 +1977,7 @@ static void bestAutomaticIndex( /* Automatic indices are disabled at run-time */ return; } - if( (pCost->plan.wsFlags & WHERE_NOT_FULLSCAN)!=0 ){ + if( (p->cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0 ){ /* We already have some kind of index in use for this query. */ return; } @@ -1981,7 +1995,7 @@ static void bestAutomaticIndex( nTableRow = pTable->nRowEst; logN = estLog(nTableRow); costTempIdx = 2*logN*(nTableRow/pParse->nQueryLoop + 1); - if( costTempIdx>=pCost->rCost ){ + if( costTempIdx>=p->cost.rCost ){ /* The cost of creating the transient table would be greater than ** doing the full table scan */ return; @@ -1990,19 +2004,19 @@ static void bestAutomaticIndex( /* Search for any equality comparison term */ pWCEnd = &pWC->a[pWC->nTerm]; for(pTerm=pWC->a; pTermnotReady) ){ WHERETRACE(("auto-index reduces cost from %.1f to %.1f\n", - pCost->rCost, costTempIdx)); - pCost->rCost = costTempIdx; - pCost->plan.nRow = logN + 1; - pCost->plan.wsFlags = WHERE_TEMP_INDEX; - pCost->used = pTerm->prereqRight; + p->cost.rCost, costTempIdx)); + p->cost.rCost = costTempIdx; + p->cost.plan.nRow = logN + 1; + p->cost.plan.wsFlags = WHERE_TEMP_INDEX; + p->cost.used = pTerm->prereqRight; break; } } } #else -# define bestAutomaticIndex(A,B,C,D,E) /* no-op */ +# define bestAutomaticIndex(A) /* no-op */ #endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ @@ -2163,12 +2177,11 @@ static void constructAutomaticIndex( ** responsibility of the caller to eventually release the structure ** by passing the pointer returned by this function to sqlite3_free(). */ -static sqlite3_index_info *allocateIndexInfo( - Parse *pParse, - WhereClause *pWC, - struct SrcList_item *pSrc, - ExprList *pOrderBy -){ +static sqlite3_index_info *allocateIndexInfo(WhereBestIdx *p){ + Parse *pParse = p->pParse; + WhereClause *pWC = p->pWC; + struct SrcList_item *pSrc = p->pSrc; + ExprList *pOrderBy = p->pOrderBy; int i, j; int nTerm; struct sqlite3_index_constraint *pIdxCons; @@ -2198,12 +2211,13 @@ static sqlite3_index_info *allocateIndexInfo( */ nOrderBy = 0; if( pOrderBy ){ - for(i=0; inExpr; i++){ + int n = pOrderBy->nExpr; + for(i=0; ia[i].pExpr; if( pExpr->op!=TK_COLUMN || pExpr->iTable!=pSrc->iCursor ) break; } - if( i==pOrderBy->nExpr ){ - nOrderBy = pOrderBy->nExpr; + if( i==n){ + nOrderBy = n; } } @@ -2327,16 +2341,10 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ ** routine takes care of freeing the sqlite3_index_info structure after ** everybody has finished with it. */ -static void bestVirtualIndex( - Parse *pParse, /* The parsing context */ - WhereClause *pWC, /* The WHERE clause */ - struct SrcList_item *pSrc, /* The FROM clause term to search */ - Bitmask notReady, /* Mask of cursors not available for index */ - Bitmask notValid, /* Cursors not valid for any purpose */ - ExprList *pOrderBy, /* The order by clause */ - WhereCost *pCost, /* Lowest cost query plan */ - sqlite3_index_info **ppIdxInfo /* Index information passed to xBestIndex */ -){ +static void bestVirtualIndex(WhereBestIdx *p){ + Parse *pParse = p->pParse; /* The parsing context */ + WhereClause *pWC = p->pWC; /* The WHERE clause */ + struct SrcList_item *pSrc = p->pSrc; /* The FROM clause term to search */ Table *pTab = pSrc->pTab; sqlite3_index_info *pIdxInfo; struct sqlite3_index_constraint *pIdxCons; @@ -2350,15 +2358,15 @@ static void bestVirtualIndex( ** malloc in allocateIndexInfo() fails and this function returns leaving ** wsFlags in an uninitialized state, the caller may behave unpredictably. */ - memset(pCost, 0, sizeof(*pCost)); - pCost->plan.wsFlags = WHERE_VIRTUALTABLE; + memset(&p->cost, 0, sizeof(p->cost)); + p->cost.plan.wsFlags = WHERE_VIRTUALTABLE; /* If the sqlite3_index_info structure has not been previously ** allocated and initialized, then allocate and initialize it now. */ - pIdxInfo = *ppIdxInfo; + pIdxInfo = *p->ppIdxInfo; if( pIdxInfo==0 ){ - *ppIdxInfo = pIdxInfo = allocateIndexInfo(pParse, pWC, pSrc, pOrderBy); + *p->ppIdxInfo = pIdxInfo = allocateIndexInfo(p); } if( pIdxInfo==0 ){ return; @@ -2403,7 +2411,7 @@ static void bestVirtualIndex( for(i=0; inConstraint; i++, pIdxCons++){ j = pIdxCons->iTermOffset; pTerm = &pWC->a[j]; - pIdxCons->usable = (pTerm->prereqRight¬Ready) ? 0 : 1; + pIdxCons->usable = (pTerm->prereqRight&p->notReady) ? 0 : 1; } memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint); if( pIdxInfo->needToFreeIdxStr ){ @@ -2416,7 +2424,7 @@ static void bestVirtualIndex( /* ((double)2) In case of SQLITE_OMIT_FLOATING_POINT... */ pIdxInfo->estimatedCost = SQLITE_BIG_DBL / ((double)2); nOrderBy = pIdxInfo->nOrderBy; - if( !pOrderBy ){ + if( !p->pOrderBy ){ pIdxInfo->nOrderBy = 0; } @@ -2427,7 +2435,7 @@ static void bestVirtualIndex( pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; for(i=0; inConstraint; i++){ if( pUsage[i].argvIndex>0 ){ - pCost->used |= pWC->a[pIdxCons[i].iTermOffset].prereqRight; + p->cost.used |= pWC->a[pIdxCons[i].iTermOffset].prereqRight; } } @@ -2436,7 +2444,7 @@ static void bestVirtualIndex( ** matches the processing for non-virtual tables in bestBtreeIndex(). */ rCost = pIdxInfo->estimatedCost; - if( pOrderBy && pIdxInfo->orderByConsumed==0 ){ + if( p->pOrderBy && pIdxInfo->orderByConsumed==0 ){ rCost += estLog(rCost)*rCost; } @@ -2448,21 +2456,21 @@ static void bestVirtualIndex( ** is defined. */ if( (SQLITE_BIG_DBL/((double)2))rCost = (SQLITE_BIG_DBL/((double)2)); + p->cost.rCost = (SQLITE_BIG_DBL/((double)2)); }else{ - pCost->rCost = rCost; + p->cost.rCost = rCost; } - pCost->plan.u.pVtabIdx = pIdxInfo; + p->cost.plan.u.pVtabIdx = pIdxInfo; if( pIdxInfo->orderByConsumed ){ - pCost->plan.wsFlags |= WHERE_ORDERBY; + p->cost.plan.wsFlags |= WHERE_ORDERBY; } - pCost->plan.nEq = 0; + p->cost.plan.nEq = 0; pIdxInfo->nOrderBy = nOrderBy; /* Try to find a more efficient access pattern by using multiple indexes ** to optimize an OR expression within the WHERE clause. */ - bestOrClauseIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost); + bestOrClauseIndex(p); } #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -2864,8 +2872,7 @@ static int whereInScanEst( /* ** Find the best query plan for accessing a particular table. Write the -** best query plan and its cost into the WhereCost object supplied as the -** last parameter. +** best query plan and its cost into the p->cost. ** ** The lowest cost plan wins. The cost is an estimate of the amount of ** CPU and disk I/O needed to process the requested result. @@ -2890,16 +2897,10 @@ static int whereInScanEst( ** selected plan may still take advantage of the built-in rowid primary key ** index. */ -static void bestBtreeIndex( - Parse *pParse, /* The parsing context */ - WhereClause *pWC, /* The WHERE clause */ - struct SrcList_item *pSrc, /* The FROM clause term to search */ - Bitmask notReady, /* Mask of cursors not available for indexing */ - Bitmask notValid, /* Cursors not available for any purpose */ - ExprList *pOrderBy, /* The ORDER BY clause */ - ExprList *pDistinct, /* The select-list if query is DISTINCT */ - WhereCost *pCost /* Lowest cost query plan */ -){ +static void bestBtreeIndex(WhereBestIdx *p){ + Parse *pParse = p->pParse; /* The parsing context */ + WhereClause *pWC = p->pWC; /* The WHERE clause */ + struct SrcList_item *pSrc = p->pSrc; /* The FROM clause term to search */ int iCur = pSrc->iCursor; /* The cursor of the table to be accessed */ Index *pProbe; /* An index we are evaluating */ Index *pIdx; /* Copy of pProbe, or zero for IPK index */ @@ -2908,11 +2909,11 @@ static void bestBtreeIndex( Index sPk; /* A fake index object for the primary key */ tRowcnt aiRowEstPk[2]; /* The aiRowEst[] value for the sPk index */ int aiColumnPk = -1; /* The aColumn[] value for the sPk index */ - int wsFlagMask; /* Allowed flags in pCost->plan.wsFlag */ + int wsFlagMask; /* Allowed flags in p->cost.plan.wsFlag */ /* Initialize the cost to a worst-case value */ - memset(pCost, 0, sizeof(*pCost)); - pCost->rCost = SQLITE_BIG_DBL; + memset(&p->cost, 0, sizeof(p->cost)); + p->cost.rCost = SQLITE_BIG_DBL; /* If the pSrc table is the right table of a LEFT JOIN then we may not ** use an index to satisfy IS NULL constraints on that table. This is @@ -3036,8 +3037,8 @@ static void bestBtreeIndex( int nInMul = 1; /* Number of distinct equalities to lookup */ double rangeDiv = (double)1; /* Estimated reduction in search space */ int nBound = 0; /* Number of range constraints seen */ - int bSort = !!pOrderBy; /* True if external sort required */ - int bDist = !!pDistinct; /* True if index cannot help with DISTINCT */ + int bSort = !!p->pOrderBy; /* True if external sort required */ + int bDist = !!p->pDistinct; /* True if index cannot help with DISTINCT */ int bLookup = 0; /* True if not a covering index */ WhereTerm *pTerm; /* A single term of the WHERE clause */ #ifdef SQLITE_ENABLE_STAT3 @@ -3047,7 +3048,7 @@ static void bestBtreeIndex( /* Determine the values of nEq and nInMul */ for(nEq=0; nEqnColumn; nEq++){ int j = pProbe->aiColumn[nEq]; - pTerm = findTerm(pWC, iCur, j, notReady, eqTermMask, pIdx); + pTerm = findTerm(pWC, iCur, j, p->notReady, eqTermMask, pIdx); if( pTerm==0 ) break; wsFlags |= (WHERE_COLUMN_EQ|WHERE_ROWID_EQ); testcase( pTerm->pWC!=pWC ); @@ -3088,9 +3089,10 @@ static void bestBtreeIndex( } }else if( pProbe->bUnordered==0 ){ int j = (nEq==pProbe->nColumn ? -1 : pProbe->aiColumn[nEq]); - if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){ - WhereTerm *pTop = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pIdx); - WhereTerm *pBtm = findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pIdx); + if( findTerm(pWC, iCur, j, p->notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){ + WhereTerm *pTop, *pBtm; + pTop = findTerm(pWC, iCur, j, p->notReady, WO_LT|WO_LE, pIdx); + pBtm = findTerm(pWC, iCur, j, p->notReady, WO_GT|WO_GE, pIdx); whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &rangeDiv); if( pTop ){ nBound = 1; @@ -3113,7 +3115,7 @@ static void bestBtreeIndex( ** in wsFlags. Otherwise, if there is an ORDER BY clause but the index ** will scan rows in a different order, set the bSort variable. */ if( isSortingIndex( - pParse, pWC->pMaskSet, pProbe, iCur, pOrderBy, nEq, wsFlags, &rev) + pParse, pWC->pMaskSet, pProbe, iCur, p->pOrderBy, nEq, wsFlags, &rev) ){ bSort = 0; wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_ORDERBY; @@ -3123,7 +3125,7 @@ static void bestBtreeIndex( /* If there is a DISTINCT qualifier and this index will scan rows in ** order of the DISTINCT expressions, clear bDist and set the appropriate ** flags in wsFlags. */ - if( isDistinctIndex(pParse, pWC, pProbe, iCur, pDistinct, nEq) + if( isDistinctIndex(pParse, pWC, pProbe, iCur, p->pDistinct, nEq) && (wsFlags & WHERE_COLUMN_IN)==0 ){ bDist = 0; @@ -3283,7 +3285,7 @@ static void bestBtreeIndex( ** might be selected even when there exists an optimal index that has ** no such dependency. */ - if( nRow>2 && cost<=pCost->rCost ){ + if( nRow>2 && cost<=p->cost.rCost ){ int k; /* Loop counter */ int nSkipEq = nEq; /* Number of == constraints to skip */ int nSkipRange = nBound; /* Number of < constraints to skip */ @@ -3292,7 +3294,7 @@ static void bestBtreeIndex( thisTab = getMask(pWC->pMaskSet, iCur); for(pTerm=pWC->a, k=pWC->nTerm; nRow>2 && k; k--, pTerm++){ if( pTerm->wtFlags & TERM_VIRTUAL ) continue; - if( (pTerm->prereqAll & notValid)!=thisTab ) continue; + if( (pTerm->prereqAll & p->notValid)!=thisTab ) continue; if( pTerm->eOperator & (WO_EQ|WO_IN|WO_ISNULL) ){ if( nSkipEq ){ /* Ignore the first nEq equality matches since the index @@ -3331,21 +3333,21 @@ static void bestBtreeIndex( " notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f used=0x%llx\n", pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk"), nEq, nInMul, (int)rangeDiv, bSort, bLookup, wsFlags, - notReady, log10N, nRow, cost, used + p->notReady, log10N, nRow, cost, used )); /* If this index is the best we have seen so far, then record this ** index and its cost in the pCost structure. */ if( (!pIdx || wsFlags) - && (costrCost || (cost<=pCost->rCost && nRowplan.nRow)) + && (costcost.rCost || (cost<=p->cost.rCost && nRowcost.plan.nRow)) ){ - pCost->rCost = cost; - pCost->used = used; - pCost->plan.nRow = nRow; - pCost->plan.wsFlags = (wsFlags&wsFlagMask); - pCost->plan.nEq = nEq; - pCost->plan.u.pIdx = pIdx; + p->cost.rCost = cost; + p->cost.used = used; + p->cost.plan.nRow = nRow; + p->cost.plan.wsFlags = (wsFlags&wsFlagMask); + p->cost.plan.nEq = nEq; + p->cost.plan.u.pIdx = pIdx; } /* If there was an INDEXED BY clause, then only that one index is @@ -3362,25 +3364,25 @@ static void bestBtreeIndex( ** in. This is used for application testing, to help find cases ** where application behaviour depends on the (undefined) order that ** SQLite outputs rows in in the absence of an ORDER BY clause. */ - if( !pOrderBy && pParse->db->flags & SQLITE_ReverseOrder ){ - pCost->plan.wsFlags |= WHERE_REVERSE; + if( !p->pOrderBy && pParse->db->flags & SQLITE_ReverseOrder ){ + p->cost.plan.wsFlags |= WHERE_REVERSE; } - assert( pOrderBy || (pCost->plan.wsFlags&WHERE_ORDERBY)==0 ); - assert( pCost->plan.u.pIdx==0 || (pCost->plan.wsFlags&WHERE_ROWID_EQ)==0 ); + assert( p->pOrderBy || (p->cost.plan.wsFlags&WHERE_ORDERBY)==0 ); + assert( p->cost.plan.u.pIdx==0 || (p->cost.plan.wsFlags&WHERE_ROWID_EQ)==0 ); assert( pSrc->pIndex==0 - || pCost->plan.u.pIdx==0 - || pCost->plan.u.pIdx==pSrc->pIndex + || p->cost.plan.u.pIdx==0 + || p->cost.plan.u.pIdx==pSrc->pIndex ); WHERETRACE(("best index is: %s\n", - ((pCost->plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ? "none" : - pCost->plan.u.pIdx ? pCost->plan.u.pIdx->zName : "ipk") + ((p->cost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ? "none" : + p->cost.plan.u.pIdx ? p->cost.plan.u.pIdx->zName : "ipk") )); - bestOrClauseIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost); - bestAutomaticIndex(pParse, pWC, pSrc, notReady, pCost); - pCost->plan.wsFlags |= eqTermMask; + bestOrClauseIndex(p); + bestAutomaticIndex(p); + p->cost.plan.wsFlags |= eqTermMask; } /* @@ -3395,26 +3397,20 @@ static void bestBtreeIndex( ** details will be reconsidered later if the optimization is found to be ** applicable. */ -static void bestIndex( - Parse *pParse, /* The parsing context */ - WhereClause *pWC, /* The WHERE clause */ - struct SrcList_item *pSrc, /* The FROM clause term to search */ - Bitmask notReady, /* Mask of cursors not available for indexing */ - Bitmask notValid, /* Cursors not available for any purpose */ - WhereCost *pCost /* Lowest cost query plan */ -){ +static void bestIndex(WhereBestIdx *p){ #ifndef SQLITE_OMIT_VIRTUALTABLE - if( IsVirtual(pSrc->pTab) ){ - sqlite3_index_info *p = 0; - bestVirtualIndex(pParse, pWC, pSrc, notReady, notValid, 0, pCost, &p); - if( p->needToFreeIdxStr ){ - sqlite3_free(p->idxStr); + if( IsVirtual(p->pSrc->pTab) ){ + sqlite3_index_info *pIdxInfo = 0; + p->ppIdxInfo = &pIdxInfo; + bestVirtualIndex(p); + if( pIdxInfo->needToFreeIdxStr ){ + sqlite3_free(pIdxInfo->idxStr); } - sqlite3DbFree(pParse->db, p); + sqlite3DbFree(p->pParse->db, pIdxInfo); }else #endif { - bestBtreeIndex(pParse, pWC, pSrc, notReady, notValid, 0, 0, pCost); + bestBtreeIndex(p); } } @@ -4700,14 +4696,18 @@ WhereInfo *sqlite3WhereBegin( WhereInfo *pWInfo; /* Will become the return value of this function */ Vdbe *v = pParse->pVdbe; /* The virtual database engine */ Bitmask notReady; /* Cursors that are not yet positioned */ + WhereBestIdx sWBI; /* Best index search context */ WhereMaskSet *pMaskSet; /* The expression mask set */ - WhereClause *pWC; /* Decomposition of the WHERE clause */ - struct SrcList_item *pTabItem; /* A single entry from pTabList */ - WhereLevel *pLevel; /* A single level in pWInfo->a[] */ - int iFrom; /* First unused FROM clause element */ + WhereLevel *pLevel; /* A single level in pWInfo->a[] */ + int iFrom; /* First unused FROM clause element */ int andFlags; /* AND-ed combination of all pWC->a[].wtFlags */ sqlite3 *db; /* Database connection */ + + /* Variable initialization */ + memset(&sWBI, 0, sizeof(sWBI)); + sWBI.pParse = pParse; + /* The number of tables in the FROM clause is limited by the number of ** bits in a Bitmask */ @@ -4747,10 +4747,10 @@ WhereInfo *sqlite3WhereBegin( pWInfo->pParse = pParse; pWInfo->pTabList = pTabList; pWInfo->iBreak = sqlite3VdbeMakeLabel(v); - pWInfo->pWC = pWC = (WhereClause *)&((u8 *)pWInfo)[nByteWInfo]; + pWInfo->pWC = sWBI.pWC = (WhereClause *)&((u8 *)pWInfo)[nByteWInfo]; pWInfo->wctrlFlags = wctrlFlags; pWInfo->savedNQueryLoop = pParse->nQueryLoop; - pMaskSet = (WhereMaskSet*)&pWC[1]; + pMaskSet = (WhereMaskSet*)&sWBI.pWC[1]; /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */ @@ -4760,9 +4760,9 @@ WhereInfo *sqlite3WhereBegin( ** subexpression is separated by an AND operator. */ initMaskSet(pMaskSet); - whereClauseInit(pWC, pParse, pMaskSet, wctrlFlags); + whereClauseInit(sWBI.pWC, pParse, pMaskSet, wctrlFlags); sqlite3ExprCodeConstants(pParse, pWhere); - whereSplit(pWC, pWhere, TK_AND); /* IMP: R-15842-53296 */ + whereSplit(sWBI.pWC, pWhere, TK_AND); /* IMP: R-15842-53296 */ /* Special case: a WHERE clause that is constant. Evaluate the ** expression and either jump over all of the code or fall thru. @@ -4793,12 +4793,12 @@ WhereInfo *sqlite3WhereBegin( ** equal to pTabList->nSrc but might be shortened to 1 if the ** WHERE_ONETABLE_ONLY flag is set. */ - assert( pWC->vmask==0 && pMaskSet->n==0 ); + assert( sWBI.pWC->vmask==0 && pMaskSet->n==0 ); for(i=0; inSrc; i++){ createMask(pMaskSet, pTabList->a[i].iCursor); #ifndef SQLITE_OMIT_VIRTUALTABLE if( ALWAYS(pTabList->a[i].pTab) && IsVirtual(pTabList->a[i].pTab) ){ - pWC->vmask |= ((Bitmask)1 << i); + sWBI.pWC->vmask |= ((Bitmask)1 << i); } #endif } @@ -4818,7 +4818,7 @@ WhereInfo *sqlite3WhereBegin( ** want to analyze these virtual terms, so start analyzing at the end ** and work forward so that the added virtual terms are never processed. */ - exprAnalyzeAll(pTabList, pWC); + exprAnalyzeAll(pTabList, sWBI.pWC); if( db->mallocFailed ){ goto whereBeginError; } @@ -4827,7 +4827,7 @@ WhereInfo *sqlite3WhereBegin( ** If it is, then set pDistinct to NULL and WhereInfo.eDistinct to ** WHERE_DISTINCT_UNIQUE to tell the caller to ignore the DISTINCT. */ - if( pDistinct && isDistinctRedundant(pParse, pTabList, pWC, pDistinct) ){ + if( pDistinct && isDistinctRedundant(pParse, pTabList, sWBI.pWC, pDistinct) ){ pDistinct = 0; pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; } @@ -4910,48 +4910,43 @@ WhereInfo *sqlite3WhereBegin( nUnconstrained = 0; notIndexed = 0; for(isOptimal=(iFrom=0 && bestJ<0; isOptimal--){ - Bitmask mask; /* Mask of tables not yet ready */ - for(j=iFrom, pTabItem=&pTabList->a[j]; ja[j]; jjointype & (JT_LEFT|JT_CROSS))!=0; + doNotReorder = (sWBI.pSrc->jointype & (JT_LEFT|JT_CROSS))!=0; if( j!=iFrom && doNotReorder ) break; - m = getMask(pMaskSet, pTabItem->iCursor); + m = getMask(pMaskSet, sWBI.pSrc->iCursor); if( (m & notReady)==0 ){ if( j==iFrom ) iFrom++; continue; } - mask = (isOptimal ? m : notReady); - pOB = (i==0) ? pOrderBy : 0; - pDist = (i==0 ? pDistinct : 0); - if( pTabItem->pIndex==0 ) nUnconstrained++; + sWBI.notValid = notReady; + sWBI.notReady = (isOptimal ? m : notReady); + sWBI.pOrderBy = (i==0) ? pOrderBy : 0; + sWBI.pDistinct = (i==0 ? pDistinct : 0); + if( sWBI.pSrc->pIndex==0 ) nUnconstrained++; WHERETRACE(("=== trying table %d with isOptimal=%d ===\n", j, isOptimal)); - assert( pTabItem->pTab ); + assert( sWBI.pSrc->pTab ); #ifndef SQLITE_OMIT_VIRTUALTABLE - if( IsVirtual(pTabItem->pTab) ){ - sqlite3_index_info **pp = &pWInfo->a[j].pIdxInfo; - bestVirtualIndex(pParse, pWC, pTabItem, mask, notReady, pOB, - &sCost, pp); + if( IsVirtual(sWBI.pSrc->pTab) ){ + sWBI.ppIdxInfo = &pWInfo->a[j].pIdxInfo; + bestVirtualIndex(&sWBI); }else #endif { - bestBtreeIndex(pParse, pWC, pTabItem, mask, notReady, pOB, - pDist, &sCost); + bestBtreeIndex(&sWBI); } - assert( isOptimal || (sCost.used¬Ready)==0 ); + assert( isOptimal || (sWBI.cost.used¬Ready)==0 ); /* If an INDEXED BY clause is present, then the plan must use that ** index if it uses any index at all */ - assert( pTabItem->pIndex==0 - || (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 - || sCost.plan.u.pIdx==pTabItem->pIndex ); + assert( sWBI.pSrc->pIndex==0 + || (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 + || sWBI.cost.plan.u.pIdx==sWBI.pSrc->pIndex ); - if( isOptimal && (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ){ + if( isOptimal && (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ){ notIndexed |= m; } @@ -4975,20 +4970,20 @@ WhereInfo *sqlite3WhereBegin( ** (4) The plan cost must be lower than prior plans or else the ** cost must be the same and the number of rows must be lower. */ - if( (sCost.used¬Ready)==0 /* (1) */ - && (bestJ<0 || (notIndexed&m)!=0 /* (2) */ + if( (sWBI.cost.used¬Ready)==0 /* (1) */ + && (bestJ<0 || (notIndexed&m)!=0 /* (2) */ || (bestPlan.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 - || (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0) - && (nUnconstrained==0 || pTabItem->pIndex==0 /* (3) */ - || NEVER((sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0)) - && (bestJ<0 || sCost.rCostpIndex==0 /* (3) */ + || NEVER((sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0)) + && (bestJ<0 || sWBI.cost.rCosta; ia[pLevel->iFrom]; pTab = pTabItem->pTab; @@ -5112,7 +5108,7 @@ WhereInfo *sqlite3WhereBegin( } #ifndef SQLITE_OMIT_AUTOMATIC_INDEX if( (pLevel->plan.wsFlags & WHERE_TEMP_INDEX)!=0 ){ - constructAutomaticIndex(pParse, pWC, pTabItem, notReady, pLevel); + constructAutomaticIndex(pParse, sWBI.pWC, pTabItem, notReady, pLevel); }else #endif if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){ @@ -5126,7 +5122,7 @@ WhereInfo *sqlite3WhereBegin( VdbeComment((v, "%s", pIx->zName)); } sqlite3CodeVerifySchema(pParse, iDb); - notReady &= ~getMask(pWC->pMaskSet, pTabItem->iCursor); + notReady &= ~getMask(sWBI.pWC->pMaskSet, pTabItem->iCursor); } pWInfo->iTop = sqlite3VdbeCurrentAddr(v); if( db->mallocFailed ) goto whereBeginError; @@ -5154,6 +5150,8 @@ WhereInfo *sqlite3WhereBegin( char *z; int n; int w; + struct SrcList_item *pTabItem; + pLevel = &pWInfo->a[i]; w = pLevel->plan.wsFlags; pTabItem = &pTabList->a[pLevel->iFrom]; From 9cd1c99fe1f786e32623c4614d9b0b0c086ff441 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 25 Sep 2012 20:43:35 +0000 Subject: [PATCH 52/60] Augment the WhereBestIdx structure to pass down into the query planner information that might be used to better detect ORDER BY and DISTINCT optimizations spanning multiple tables of a join. FossilOrigin-Name: 4226e51ff837f0ffe16355491a655d919d13488e --- manifest | 15 ++++------ manifest.uuid | 2 +- src/where.c | 79 ++++++++++++++++++++++++++++++--------------------- 3 files changed, 53 insertions(+), 43 deletions(-) diff --git a/manifest b/manifest index 9b64595abd..28323b288a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Pass\sinformation\saround\sbetween\sthe\smajor\sroutines\sof\sthe\squery\splanner\nusing\sa\ssingle\spointer\sto\sa\sstructure\srather\sthan\sa\slong\slist\sof\sparameters. -D 2012-09-25T14:29:39.134 +C Augment\sthe\sWhereBestIdx\sstructure\sto\spass\sdown\sinto\sthe\squery\splanner\s\ninformation\sthat\smight\sbe\sused\sto\sbetter\sdetect\sORDER\sBY\sand\sDISTINCT\noptimizations\sspanning\smultiple\stables\sof\sa\sjoin. +D 2012-09-25T20:43:35.989 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -249,7 +249,7 @@ F src/vtab.c d8020c0a0e8ccc490ca449d7e665311b6e9f3ba9 F src/wal.c 5acb3e7bbd31f10ba39acad9ce6b399055337a9d F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b -F src/where.c 82be1d2f8f27012de0ed9d0977753ed24312b791 +F src/where.c e75e67f0631182be4ff0d325c5a1e4c4ec3d0962 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 0be144b453e0622a085fae8665c32f5676708e00 @@ -1016,10 +1016,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 349a55cd8ba9ce65ebfd987ecfebd1204f7d0a85 -R b0986bef8aa73322a60d8a15dd219873 -T *branch * qp-enhancements -T *sym-qp-enhancements * -T -sym-trunk * +P 1104d42e104d561ce60d05d158acfe499ee9fd50 +R 660ef52f8cc671ae827c548793cfd963 U drh -Z 6cfa0793222da70bc8fbd646a62c8a2a +Z 10b5de991bc34ec524f2e3adc126c5c7 diff --git a/manifest.uuid b/manifest.uuid index 4dfae10d21..1edaad7ba3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1104d42e104d561ce60d05d158acfe499ee9fd50 \ No newline at end of file +4226e51ff837f0ffe16355491a655d919d13488e \ No newline at end of file diff --git a/src/where.c b/src/where.c index 66fe0516a6..63823f277d 100644 --- a/src/where.c +++ b/src/where.c @@ -284,6 +284,8 @@ struct WhereBestIdx { ExprList *pOrderBy; /* The ORDER BY clause */ ExprList *pDistinct; /* The select-list if query is DISTINCT */ sqlite3_index_info **ppIdxInfo; /* Index information passed to xBestIndex */ + int i, n; /* Which loop is being coded; # of loops */ + WhereLevel *a; /* Info about outer loops */ WhereCost cost; /* Lowest cost query plan */ }; @@ -3037,14 +3039,22 @@ static void bestBtreeIndex(WhereBestIdx *p){ int nInMul = 1; /* Number of distinct equalities to lookup */ double rangeDiv = (double)1; /* Estimated reduction in search space */ int nBound = 0; /* Number of range constraints seen */ - int bSort = !!p->pOrderBy; /* True if external sort required */ - int bDist = !!p->pDistinct; /* True if index cannot help with DISTINCT */ + int bSort; /* True if external sort required */ + int bDist; /* True if index cannot help with DISTINCT */ int bLookup = 0; /* True if not a covering index */ WhereTerm *pTerm; /* A single term of the WHERE clause */ #ifdef SQLITE_ENABLE_STAT3 WhereTerm *pFirstTerm = 0; /* First term matching the index */ #endif + if( (p->i) > 0 ){ + bSort = 0; + bDist = 0; + }else{ + bSort = p->pOrderBy!=0; + bDist = p->pDistinct!=0; + } + /* Determine the values of nEq and nInMul */ for(nEq=0; nEqnColumn; nEq++){ int j = pProbe->aiColumn[nEq]; @@ -3114,7 +3124,7 @@ static void bestBtreeIndex(WhereBestIdx *p){ ** naturally scan rows in the required order, set the appropriate flags ** in wsFlags. Otherwise, if there is an ORDER BY clause but the index ** will scan rows in a different order, set the bSort variable. */ - if( isSortingIndex( + if( bSort && isSortingIndex( pParse, pWC->pMaskSet, pProbe, iCur, p->pOrderBy, nEq, wsFlags, &rev) ){ bSort = 0; @@ -3125,7 +3135,8 @@ static void bestBtreeIndex(WhereBestIdx *p){ /* If there is a DISTINCT qualifier and this index will scan rows in ** order of the DISTINCT expressions, clear bDist and set the appropriate ** flags in wsFlags. */ - if( isDistinctIndex(pParse, pWC, pProbe, iCur, p->pDistinct, nEq) + if( bDist + && isDistinctIndex(pParse, pWC, pProbe, iCur, p->pDistinct, nEq) && (wsFlags & WHERE_COLUMN_IN)==0 ){ bDist = 0; @@ -4690,7 +4701,6 @@ WhereInfo *sqlite3WhereBegin( u16 wctrlFlags, /* One of the WHERE_* flags defined in sqliteInt.h */ int iIdxCur /* If WHERE_ONETABLE_ONLY is set, index cursor number */ ){ - int i; /* Loop counter */ int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */ int nTabList; /* Number of elements in pTabList */ WhereInfo *pWInfo; /* Will become the return value of this function */ @@ -4701,6 +4711,7 @@ WhereInfo *sqlite3WhereBegin( WhereLevel *pLevel; /* A single level in pWInfo->a[] */ int iFrom; /* First unused FROM clause element */ int andFlags; /* AND-ed combination of all pWC->a[].wtFlags */ + int ii; /* Loop counter */ sqlite3 *db; /* Database connection */ @@ -4751,6 +4762,7 @@ WhereInfo *sqlite3WhereBegin( pWInfo->wctrlFlags = wctrlFlags; pWInfo->savedNQueryLoop = pParse->nQueryLoop; pMaskSet = (WhereMaskSet*)&sWBI.pWC[1]; + sWBI.a = pWInfo->a; /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */ @@ -4794,19 +4806,19 @@ WhereInfo *sqlite3WhereBegin( ** WHERE_ONETABLE_ONLY flag is set. */ assert( sWBI.pWC->vmask==0 && pMaskSet->n==0 ); - for(i=0; inSrc; i++){ - createMask(pMaskSet, pTabList->a[i].iCursor); + for(ii=0; iinSrc; ii++){ + createMask(pMaskSet, pTabList->a[ii].iCursor); #ifndef SQLITE_OMIT_VIRTUALTABLE - if( ALWAYS(pTabList->a[i].pTab) && IsVirtual(pTabList->a[i].pTab) ){ - sWBI.pWC->vmask |= ((Bitmask)1 << i); + if( ALWAYS(pTabList->a[ii].pTab) && IsVirtual(pTabList->a[ii].pTab) ){ + sWBI.pWC->vmask |= ((Bitmask)1 << ii); } #endif } #ifndef NDEBUG { Bitmask toTheLeft = 0; - for(i=0; inSrc; i++){ - Bitmask m = getMask(pMaskSet, pTabList->a[i].iCursor); + for(ii=0; iinSrc; ii++){ + Bitmask m = getMask(pMaskSet, pTabList->a[ii].iCursor); assert( (m-1)==toTheLeft ); toTheLeft |= m; } @@ -4847,10 +4859,13 @@ WhereInfo *sqlite3WhereBegin( ** This loop also figures out the nesting order of tables in the FROM ** clause. */ - notReady = ~(Bitmask)0; + sWBI.notValid = ~(Bitmask)0; + sWBI.pOrderBy = pOrderBy; + sWBI.n = nTabList; + sWBI.pDistinct = pDistinct; andFlags = ~0; WHERETRACE(("*** Optimizer Start ***\n")); - for(i=iFrom=0, pLevel=pWInfo->a; ia; sWBI.ijointype & (JT_LEFT|JT_CROSS))!=0; if( j!=iFrom && doNotReorder ) break; m = getMask(pMaskSet, sWBI.pSrc->iCursor); - if( (m & notReady)==0 ){ + if( (m & sWBI.notValid)==0 ){ if( j==iFrom ) iFrom++; continue; } - sWBI.notValid = notReady; - sWBI.notReady = (isOptimal ? m : notReady); - sWBI.pOrderBy = (i==0) ? pOrderBy : 0; - sWBI.pDistinct = (i==0 ? pDistinct : 0); + sWBI.notReady = (isOptimal ? m : sWBI.notValid); if( sWBI.pSrc->pIndex==0 ) nUnconstrained++; WHERETRACE(("=== trying table %d with isOptimal=%d ===\n", @@ -4938,7 +4950,7 @@ WhereInfo *sqlite3WhereBegin( { bestBtreeIndex(&sWBI); } - assert( isOptimal || (sWBI.cost.used¬Ready)==0 ); + assert( isOptimal || (sWBI.cost.used&sWBI.notValid)==0 ); /* If an INDEXED BY clause is present, then the plan must use that ** index if it uses any index at all */ @@ -4953,7 +4965,8 @@ WhereInfo *sqlite3WhereBegin( /* Conditions under which this table becomes the best so far: ** ** (1) The table must not depend on other tables that have not - ** yet run. + ** yet run. (In other words, it must not depend on tables + ** in inner loops.) ** ** (2) A full-table-scan plan cannot supercede indexed plan unless ** the full-table-scan is an "optimal" plan as defined above. @@ -4970,7 +4983,7 @@ WhereInfo *sqlite3WhereBegin( ** (4) The plan cost must be lower than prior plans or else the ** cost must be the same and the number of rows must be lower. */ - if( (sWBI.cost.used¬Ready)==0 /* (1) */ + if( (sWBI.cost.used&sWBI.notValid)==0 /* (1) */ && (bestJ<0 || (notIndexed&m)!=0 /* (2) */ || (bestPlan.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 || (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0) @@ -4990,7 +5003,7 @@ WhereInfo *sqlite3WhereBegin( } } assert( bestJ>=0 ); - assert( notReady & getMask(pMaskSet, pTabList->a[bestJ].iCursor) ); + assert( sWBI.notValid & getMask(pMaskSet, pTabList->a[bestJ].iCursor) ); WHERETRACE(("*** Optimizer selects table %d for loop %d" " with cost=%g and nRow=%g\n", bestJ, pLevel-pWInfo->a, bestPlan.rCost, bestPlan.plan.nRow)); @@ -5016,7 +5029,7 @@ WhereInfo *sqlite3WhereBegin( }else{ pLevel->iIdxCur = -1; } - notReady &= ~getMask(pMaskSet, pTabList->a[bestJ].iCursor); + sWBI.notValid &= ~getMask(pMaskSet, pTabList->a[bestJ].iCursor); pLevel->iFrom = (u8)bestJ; if( bestPlan.plan.nRow>=(double)1 ){ pParse->nQueryLoop *= bestPlan.plan.nRow; @@ -5069,7 +5082,7 @@ WhereInfo *sqlite3WhereBegin( sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */ notReady = ~(Bitmask)0; pWInfo->nRowOut = (double)1; - for(i=0, pLevel=pWInfo->a; ia; iia[i]; - explainOneScan(pParse, pTabList, pLevel, i, pLevel->iFrom, wctrlFlags); - notReady = codeOneLoopStart(pWInfo, i, wctrlFlags, notReady); + for(ii=0; iia[ii]; + explainOneScan(pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags); + notReady = codeOneLoopStart(pWInfo, ii, wctrlFlags, notReady); pWInfo->iContinue = pLevel->addrCont; } @@ -5146,13 +5159,13 @@ WhereInfo *sqlite3WhereBegin( ** the index is listed as "{}". If the primary key is used the ** index name is '*'. */ - for(i=0; ia[i]; + pLevel = &pWInfo->a[ii]; w = pLevel->plan.wsFlags; pTabItem = &pTabList->a[pLevel->iFrom]; z = pTabItem->zAlias; From 46c35f9b208e7a46718e16fb2551fc940f26abd7 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 26 Sep 2012 23:17:01 +0000 Subject: [PATCH 53/60] Further refactoring of the ORDER BY related query-planning logic in order to make it easier to extend to support optimizing out ORDER BY on joins. No actual behavior changes, yet. FossilOrigin-Name: 96496ddae12a239b30a1fc997fbea43e3a75bfe7 --- manifest | 16 ++-- manifest.uuid | 2 +- src/select.c | 1 + src/sqliteInt.h | 3 +- src/where.c | 216 +++++++++++++++++++++++++++--------------------- 5 files changed, 135 insertions(+), 103 deletions(-) diff --git a/manifest b/manifest index 28323b288a..b047d69df4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Augment\sthe\sWhereBestIdx\sstructure\sto\spass\sdown\sinto\sthe\squery\splanner\s\ninformation\sthat\smight\sbe\sused\sto\sbetter\sdetect\sORDER\sBY\sand\sDISTINCT\noptimizations\sspanning\smultiple\stables\sof\sa\sjoin. -D 2012-09-25T20:43:35.989 +C Further\srefactoring\sof\sthe\sORDER\sBY\srelated\squery-planning\slogic\sin\sorder\nto\smake\sit\seasier\sto\sextend\sto\ssupport\soptimizing\sout\sORDER\sBY\son\sjoins.\nNo\sactual\sbehavior\schanges,\syet. +D 2012-09-26T23:17:01.276 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -174,12 +174,12 @@ F src/printf.c 4a9f882f1c1787a8b494a2987765acf9d97ac21f F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 9e28280ec98035f31900fdd1db01f86f68ca6c32 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 1fad66b73a69c4004c9969a95b46d1f03390677d +F src/select.c a91b651652b43a8baaeec0ad13a6a6b290a4d0af F src/shell.c 8ee5a3cb502e2d574f97b43972e6c1e275e7bec7 F src/sqlite.h.in cbe846facaba903654b4136c97e7f57b3ac0bac7 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h 6b17114bb5c6ae30d360aeeef30ab40587afad4e +F src/sqliteInt.h cbcd2dd649338598a1a773a9adaf9f62e7256852 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -249,7 +249,7 @@ F src/vtab.c d8020c0a0e8ccc490ca449d7e665311b6e9f3ba9 F src/wal.c 5acb3e7bbd31f10ba39acad9ce6b399055337a9d F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b -F src/where.c e75e67f0631182be4ff0d325c5a1e4c4ec3d0962 +F src/where.c 59b852d51d86fd3bf5935067994114bf88affbef F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 0be144b453e0622a085fae8665c32f5676708e00 @@ -1016,7 +1016,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 1104d42e104d561ce60d05d158acfe499ee9fd50 -R 660ef52f8cc671ae827c548793cfd963 +P 4226e51ff837f0ffe16355491a655d919d13488e +R 82e96539fb8ddcfab6615c786a34a1ea U drh -Z 10b5de991bc34ec524f2e3adc126c5c7 +Z e46432508017f3912d4e7cd1bd8daf63 diff --git a/manifest.uuid b/manifest.uuid index 1edaad7ba3..52ca9470ee 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4226e51ff837f0ffe16355491a655d919d13488e \ No newline at end of file +96496ddae12a239b30a1fc997fbea43e3a75bfe7 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 01fe27694f..0f2320f59c 100644 --- a/src/select.c +++ b/src/select.c @@ -4506,6 +4506,7 @@ int sqlite3Select( goto select_end; } updateAccumulator(pParse, &sAggInfo); + assert( pMinMax==0 || pMinMax->nExpr==1 ); if( pWInfo->nOBSat>0 ){ sqlite3VdbeAddOp2(v, OP_Goto, 0, pWInfo->iBreak); VdbeComment((v, "%s() by index", diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7b9894254a..cd38dc8707 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1906,7 +1906,8 @@ struct SrcList { */ struct WherePlan { u32 wsFlags; /* WHERE_* flags that describe the strategy */ - u32 nEq; /* Number of == constraints */ + u16 nEq; /* Number of == constraints */ + u16 nOBSat; /* Number of ORDER BY terms satisfied */ double nRow; /* Estimated number of rows (for EQP) */ union { Index *pIdx; /* Index when WHERE_INDEXED is true */ diff --git a/src/where.c b/src/where.c index 63823f277d..05f5bcc414 100644 --- a/src/where.c +++ b/src/where.c @@ -285,7 +285,7 @@ struct WhereBestIdx { ExprList *pDistinct; /* The select-list if query is DISTINCT */ sqlite3_index_info **ppIdxInfo; /* Index information passed to xBestIndex */ int i, n; /* Which loop is being coded; # of loops */ - WhereLevel *a; /* Info about outer loops */ + WhereLevel *aLevel; /* Info about outer loops */ WhereCost cost; /* Lowest cost query plan */ }; @@ -1431,22 +1431,18 @@ static void exprAnalyze( } /* -** Return TRUE if any of the expressions in pList->a[iFirst...] contain -** a reference to any table other than the iBase table. +** Return TRUE if the given index is UNIQUE and all columns past the +** first nSkip columns are NOT NULL. */ -static int referencesOtherTables( - ExprList *pList, /* Search expressions in ths list */ - WhereMaskSet *pMaskSet, /* Mapping from tables to bitmaps */ - int iFirst, /* Be searching with the iFirst-th expression */ - int iBase /* Ignore references to this table */ -){ - Bitmask allowed = ~getMask(pMaskSet, iBase); - while( iFirstnExpr ){ - if( (exprTableUsage(pMaskSet, pList->a[iFirst++].pExpr)&allowed)!=0 ){ - return 1; - } +static int indexIsUniqueNotNull(Index *pIdx, int nSkip){ + Table *pTab = pIdx->pTable; + int i; + if( pIdx->onError==OE_None ) return 0; + for(i=nSkip; inColumn; i++){ + int j = pIdx->aiColumn[i]; + if( j>=0 && pTab->aCol[j].notNull==0 ) return 0; } - return 0; + return 1; } /* @@ -1612,43 +1608,54 @@ static int isDistinctRedundant( /* ** This routine decides if pIdx can be used to satisfy the ORDER BY -** clause. If it can, it returns 1. If pIdx cannot satisfy the -** ORDER BY clause, this routine returns 0. +** clause, either in whole or in part. The return value is the +** cumulative number of terms in the ORDER BY clause that are satisfied +** by the index pIdx and other indices in outer loops. ** -** pOrderBy is an ORDER BY clause from a SELECT statement. pTab is the -** left-most table in the FROM clause of that same SELECT statement and -** the table has a cursor number of "base". pIdx is an index on pTab. +** The table being queried has a cursor number of "base". pIdx is the +** index that is postulated for use to access the table. ** ** nEqCol is the number of columns of pIdx that are used as equality -** constraints. Any of these columns may be missing from the ORDER BY -** clause and the match can still be a success. +** constraints and where the other side of the == is an ordered column +** or constant. An "order column" in the previous sentence means a column +** in table from an outer loop whose values will always appear in the +** correct order due to othre index, or because the outer loop generates +** a unique result. Any of the first nEqCol columns of pIdx may be missing +** from the ORDER BY clause and the match can still be a success. ** -** All terms of the ORDER BY that match against the index must be either -** ASC or DESC. (Terms of the ORDER BY clause past the end of a UNIQUE -** index do not need to satisfy this constraint.) The *pbRev value is -** set to 1 if the ORDER BY clause is all DESC and it is set to 0 if -** the ORDER BY clause is all ASC. +** The *pbRev value is set to 0 order 1 depending on whether or not +** pIdx should be run in the forward order or in reverse order. */ static int isSortingIndex( - Parse *pParse, /* Parsing context */ - WhereMaskSet *pMaskSet, /* Mapping from table cursor numbers to bitmaps */ - Index *pIdx, /* The index we are testing */ - int base, /* Cursor number for the table to be sorted */ - ExprList *pOrderBy, /* The ORDER BY clause */ - int nEqCol, /* Number of index columns with == constraints */ - int wsFlags, /* Index usages flags */ - int *pbRev /* Set to 1 if ORDER BY is DESC */ + WhereBestIdx *p, /* Best index search context */ + Index *pIdx, /* The index we are testing */ + int base, /* Cursor number for the table to be sorted */ + int nEqCol, /* Number of index columns with ordered == constraints */ + int wsFlags, /* Index usages flags */ + int bOuterRev, /* True if outer loops scan in reverse order */ + int *pbRev /* Set to 1 for reverse-order scan of pIdx */ ){ - int i, j; /* Loop counters */ - int sortOrder = 0; /* XOR of index and ORDER BY sort direction */ - int nTerm; /* Number of ORDER BY terms */ - struct ExprList_item *pTerm; /* A term of the ORDER BY clause */ - sqlite3 *db = pParse->db; - - if( !pOrderBy ) return 0; - if( wsFlags & WHERE_COLUMN_IN ) return 0; - if( pIdx->bUnordered ) return 0; + int i; /* Number of pIdx terms used */ + int j; /* Number of ORDER BY terms satisfied */ + int sortOrder = 0; /* XOR of index and ORDER BY sort direction */ + int nTerm; /* Number of ORDER BY terms */ + struct ExprList_item *pTerm; /* A term of the ORDER BY clause */ + ExprList *pOrderBy; /* The ORDER BY clause */ + Parse *pParse = p->pParse; /* Parser context */ + sqlite3 *db = pParse->db; /* Database connection */ + int nPriorSat; /* ORDER BY terms satisfied by outer loops */ + int seenRowid = 0; /* True if an ORDER BY rowid term is seen */ + if( p->i==0 ){ + nPriorSat = 0; + }else{ + nPriorSat = p->aLevel[p->i-1].plan.nOBSat; + } + if( p->i>0 && nEqCol==0 /*&& !allOuterLoopsUnique(p)*/ ) return nPriorSat; + pOrderBy = p->pOrderBy; + if( !pOrderBy ) return nPriorSat; + if( wsFlags & WHERE_COLUMN_IN ) return nPriorSat; + if( pIdx->bUnordered ) return nPriorSat; nTerm = pOrderBy->nExpr; assert( nTerm>0 ); @@ -1665,7 +1672,7 @@ static int isSortingIndex( ** of the index is also allowed to match against the ORDER BY ** clause. */ - for(i=j=0, pTerm=pOrderBy->a; jnColumn; i++){ + for(i=0,j=nPriorSat,pTerm=&pOrderBy->a[j]; jnColumn; i++){ Expr *pExpr; /* The expression of the ORDER BY pTerm */ CollSeq *pColl; /* The collating sequence of pExpr */ int termSortOrder; /* Sort order for this term */ @@ -1709,7 +1716,7 @@ static int isSortingIndex( /* If an index column fails to match and is not constrained by == ** then the index cannot satisfy the ORDER BY constraint. */ - return 0; + return nPriorSat; } } assert( pIdx->aSortOrder!=0 || iColumn==-1 ); @@ -1720,53 +1727,38 @@ static int isSortingIndex( if( termSortOrder!=sortOrder ){ /* Indices can only be used if all ORDER BY terms past the ** equality constraints are all either DESC or ASC. */ - return 0; + break; } }else{ sortOrder = termSortOrder; } j++; pTerm++; - if( iColumn<0 && !referencesOtherTables(pOrderBy, pMaskSet, j, base) ){ - /* If the indexed column is the primary key and everything matches - ** so far and none of the ORDER BY terms to the right reference other - ** tables in the join, then we are assured that the index can be used - ** to sort because the primary key is unique and so none of the other - ** columns will make any difference - */ - j = nTerm; + if( iColumn<0 ){ + seenRowid = 1; + break; } } + *pbRev = bOuterRev ^ sortOrder; - *pbRev = sortOrder!=0; - if( j>=nTerm ){ - /* All terms of the ORDER BY clause are covered by this index so - ** this index can be used for sorting. */ - return 1; - } - if( pIdx->onError!=OE_None && i==pIdx->nColumn - && (wsFlags & WHERE_COLUMN_NULL)==0 - && !referencesOtherTables(pOrderBy, pMaskSet, j, base) + /* If there was an "ORDER BY rowid" term that matched, or it is only + ** possible for a single row from this table to match, then skip over + ** any additional ORDER BY terms dealing with this table. + */ + if( seenRowid || + ( (wsFlags & WHERE_COLUMN_NULL)==0 + && i>=pIdx->nColumn + && indexIsUniqueNotNull(pIdx, nEqCol) + ) ){ - Column *aCol = pIdx->pTable->aCol; - - /* All terms of this index match some prefix of the ORDER BY clause, - ** the index is UNIQUE, and no terms on the tail of the ORDER BY - ** refer to other tables in a join. So, assuming that the index entries - ** visited contain no NULL values, then this index delivers rows in - ** the required order. - ** - ** It is not possible for any of the first nEqCol index fields to be - ** NULL (since the corresponding "=" operator in the WHERE clause would - ** not be true). So if all remaining index columns have NOT NULL - ** constaints attached to them, we can be confident that the visited - ** index entries are free of NULLs. */ - for(i=nEqCol; inColumn; i++){ - if( aCol[pIdx->aiColumn[i]].notNull==0 ) break; + /* Advance j over additional ORDER BY terms associated with base */ + WhereMaskSet *pMS = p->pWC->pMaskSet; + Bitmask m = ~getMask(pMS, base); + while( ja[j].pExpr)&m)==0 ){ + j++; } - return (i==pIdx->nColumn); } - return 0; + return j; } /* @@ -2871,6 +2863,22 @@ static int whereInScanEst( } #endif /* defined(SQLITE_ENABLE_STAT3) */ +/* +** pTerm is an == constraint. Check to see if the other side of +** the == is a constant or a value that is guaranteed to be ordered +** by outer loops. Return 1 if pTerm is ordered, and 0 if not. +*/ +static int isOrderedTerm(WhereBestIdx *p, WhereTerm *pTerm, int *pbRev){ + if( p->i==0 ){ + return 1; /* All == are ordered in the outer loop */ + } + + + + /* If we cannot prove that the constraint is ordered, assume it is not */ + return 0; +} + /* ** Find the best query plan for accessing a particular table. Write the @@ -2968,7 +2976,7 @@ static void bestBtreeIndex(WhereBestIdx *p){ double cost; /* Cost of using pProbe */ double nRow; /* Estimated number of rows in result set */ double log10N = (double)1; /* base-10 logarithm of nRow (inexact) */ - int rev; /* True to scan in reverse order */ + int bRev = 2; /* 0=forward scan. 1=reverse. 2=undecided */ int wsFlags = 0; Bitmask used = 0; @@ -3001,6 +3009,10 @@ static void bestBtreeIndex(WhereBestIdx *p){ ** the sub-select is assumed to return 25 rows for the purposes of ** determining nInMul. ** + ** nOrdered: + ** The number of equality terms that are constrainted by outer loop + ** variables that are well-ordered. + ** ** bInEst: ** Set to true if there was at least one "x IN (SELECT ...)" term used ** in determining the value of nInMul. Note that the RHS of the @@ -3019,6 +3031,10 @@ static void bestBtreeIndex(WhereBestIdx *p){ ** external sort (i.e. scanning the index being evaluated will not ** correctly order records). ** + ** bDistinct: + ** Boolean. True if there is a DISTINCT clause that will require an + ** external btree. + ** ** bLookup: ** Boolean. True if a table lookup is required for each index entry ** visited. In other words, true if this is not a covering index. @@ -3035,6 +3051,7 @@ static void bestBtreeIndex(WhereBestIdx *p){ ** SELECT a, b, c FROM tbl WHERE a = 1; */ int nEq; /* Number of == or IN terms matching index */ + int nOrdered; /* Number of ordered terms matching index */ int bInEst = 0; /* True if "x IN (SELECT...)" seen */ int nInMul = 1; /* Number of distinct equalities to lookup */ double rangeDiv = (double)1; /* Estimated reduction in search space */ @@ -3042,11 +3059,14 @@ static void bestBtreeIndex(WhereBestIdx *p){ int bSort; /* True if external sort required */ int bDist; /* True if index cannot help with DISTINCT */ int bLookup = 0; /* True if not a covering index */ + int nOBSat = 0; /* Number of ORDER BY terms satisfied */ + int nOrderBy; /* Number of ORDER BY terms */ WhereTerm *pTerm; /* A single term of the WHERE clause */ #ifdef SQLITE_ENABLE_STAT3 WhereTerm *pFirstTerm = 0; /* First term matching the index */ #endif + nOrderBy = p->pOrderBy ? p->pOrderBy->nExpr : 0; if( (p->i) > 0 ){ bSort = 0; bDist = 0; @@ -3056,7 +3076,7 @@ static void bestBtreeIndex(WhereBestIdx *p){ } /* Determine the values of nEq and nInMul */ - for(nEq=0; nEqnColumn; nEq++){ + for(nEq=nOrdered=0; nEqnColumn; nEq++){ int j = pProbe->aiColumn[nEq]; pTerm = findTerm(pWC, iCur, j, p->notReady, eqTermMask, pIdx); if( pTerm==0 ) break; @@ -3075,6 +3095,8 @@ static void bestBtreeIndex(WhereBestIdx *p){ } }else if( pTerm->eOperator & WO_ISNULL ){ wsFlags |= WHERE_COLUMN_NULL; + }else if( bSort && nEq==nOrdered && isOrderedTerm(p, pTerm, &bRev) ){ + nOrdered++; } #ifdef SQLITE_ENABLE_STAT3 if( nEq==0 && pProbe->aSample ) pFirstTerm = pTerm; @@ -3124,12 +3146,18 @@ static void bestBtreeIndex(WhereBestIdx *p){ ** naturally scan rows in the required order, set the appropriate flags ** in wsFlags. Otherwise, if there is an ORDER BY clause but the index ** will scan rows in a different order, set the bSort variable. */ - if( bSort && isSortingIndex( - pParse, pWC->pMaskSet, pProbe, iCur, p->pOrderBy, nEq, wsFlags, &rev) - ){ - bSort = 0; - wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_ORDERBY; - wsFlags |= (rev ? WHERE_REVERSE : 0); + assert( bRev>=0 && bRev<=2 ); + if( bSort ){ + testcase( bRev==0 ); + testcase( bRev==1 ); + testcase( bRev==2 ); + nOBSat = isSortingIndex(p, pProbe, iCur, nOrdered, + wsFlags, bRev&1, &bRev); + if( nOrderBy==nOBSat ){ + bSort = 0; + wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_ORDERBY; + wsFlags |= (bRev==1 ? WHERE_REVERSE : 0); + } } /* If there is a DISTINCT qualifier and this index will scan rows in @@ -3272,7 +3300,7 @@ static void bestBtreeIndex(WhereBestIdx *p){ ** difference and select C of 3.0. */ if( bSort ){ - cost += nRow*estLog(nRow)*3; + cost += nRow*estLog(nRow*(nOrderBy - nOBSat)/nOrderBy)*3; } if( bDist ){ cost += nRow*estLog(nRow)*3; @@ -3341,10 +3369,11 @@ static void bestBtreeIndex(WhereBestIdx *p){ WHERETRACE(( "%s(%s): nEq=%d nInMul=%d rangeDiv=%d bSort=%d bLookup=%d wsFlags=0x%x\n" - " notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f used=0x%llx\n", + " notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f used=0x%llx\n" + " nOrdered=%d nOBSat=%d\n", pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk"), nEq, nInMul, (int)rangeDiv, bSort, bLookup, wsFlags, - p->notReady, log10N, nRow, cost, used + p->notReady, log10N, nRow, cost, used, nOrdered, nOBSat )); /* If this index is the best we have seen so far, then record this @@ -3358,6 +3387,7 @@ static void bestBtreeIndex(WhereBestIdx *p){ p->cost.plan.nRow = nRow; p->cost.plan.wsFlags = (wsFlags&wsFlagMask); p->cost.plan.nEq = nEq; + p->cost.plan.nOBSat = nOBSat; p->cost.plan.u.pIdx = pIdx; } @@ -4762,7 +4792,7 @@ WhereInfo *sqlite3WhereBegin( pWInfo->wctrlFlags = wctrlFlags; pWInfo->savedNQueryLoop = pParse->nQueryLoop; pMaskSet = (WhereMaskSet*)&sWBI.pWC[1]; - sWBI.a = pWInfo->a; + sWBI.aLevel = pWInfo->a; /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */ From ff2d52117bd54c88229d4e46471d9dd2b257ad0e Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 27 Sep 2012 12:05:09 +0000 Subject: [PATCH 54/60] Further tweaks to the query planner logic in preparation for adding ORDER BY opt-out for joins. FossilOrigin-Name: 53efc10af990d3f293551f3cd8ef2f8be2d9d716 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 23 ++++++++++------------- 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index b047d69df4..5f591e9ff6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\srefactoring\sof\sthe\sORDER\sBY\srelated\squery-planning\slogic\sin\sorder\nto\smake\sit\seasier\sto\sextend\sto\ssupport\soptimizing\sout\sORDER\sBY\son\sjoins.\nNo\sactual\sbehavior\schanges,\syet. -D 2012-09-26T23:17:01.276 +C Further\stweaks\sto\sthe\squery\splanner\slogic\sin\spreparation\sfor\sadding\nORDER\sBY\sopt-out\sfor\sjoins. +D 2012-09-27T12:05:09.522 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -249,7 +249,7 @@ F src/vtab.c d8020c0a0e8ccc490ca449d7e665311b6e9f3ba9 F src/wal.c 5acb3e7bbd31f10ba39acad9ce6b399055337a9d F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b -F src/where.c 59b852d51d86fd3bf5935067994114bf88affbef +F src/where.c 67438c6192c5f777139e7abb642a9186a21a718d F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 0be144b453e0622a085fae8665c32f5676708e00 @@ -1016,7 +1016,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 4226e51ff837f0ffe16355491a655d919d13488e -R 82e96539fb8ddcfab6615c786a34a1ea +P 96496ddae12a239b30a1fc997fbea43e3a75bfe7 +R 57ad7fba1d5db0bb9191afb65acee747 U drh -Z e46432508017f3912d4e7cd1bd8daf63 +Z 58fdbd300662a0c1ec2665b77df5f795 diff --git a/manifest.uuid b/manifest.uuid index 52ca9470ee..2e377696fc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -96496ddae12a239b30a1fc997fbea43e3a75bfe7 \ No newline at end of file +53efc10af990d3f293551f3cd8ef2f8be2d9d716 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 05f5bcc414..0405860c9a 100644 --- a/src/where.c +++ b/src/where.c @@ -3067,13 +3067,8 @@ static void bestBtreeIndex(WhereBestIdx *p){ #endif nOrderBy = p->pOrderBy ? p->pOrderBy->nExpr : 0; - if( (p->i) > 0 ){ - bSort = 0; - bDist = 0; - }else{ - bSort = p->pOrderBy!=0; - bDist = p->pDistinct!=0; - } + bSort = nOrderBy>0 && (p->i==0 || p->aLevel[p->i-1].plan.nOBSati==0 && p->pDistinct!=0; /* Determine the values of nEq and nInMul */ for(nEq=nOrdered=0; nEqnColumn; nEq++){ @@ -3369,8 +3364,8 @@ static void bestBtreeIndex(WhereBestIdx *p){ WHERETRACE(( "%s(%s): nEq=%d nInMul=%d rangeDiv=%d bSort=%d bLookup=%d wsFlags=0x%x\n" - " notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f used=0x%llx\n" - " nOrdered=%d nOBSat=%d\n", + " notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f\n" + " used=0x%llx nOrdered=%d nOBSat=%d\n", pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk"), nEq, nInMul, (int)rangeDiv, bSort, bLookup, wsFlags, p->notReady, log10N, nRow, cost, used, nOrdered, nOBSat @@ -5024,8 +5019,9 @@ WhereInfo *sqlite3WhereBegin( && sWBI.cost.plan.nRow=0 ); assert( sWBI.notValid & getMask(pMaskSet, pTabList->a[bestJ].iCursor) ); WHERETRACE(("*** Optimizer selects table %d for loop %d" - " with cost=%g and nRow=%g\n", - bestJ, pLevel-pWInfo->a, bestPlan.rCost, bestPlan.plan.nRow)); + " with cost=%.1f, nRow=%.1f, nOBSat=%d\n", + bestJ, pLevel-pWInfo->a, bestPlan.rCost, bestPlan.plan.nRow, + bestPlan.plan.nOBSat)); if( (bestPlan.plan.wsFlags & WHERE_ORDERBY)!=0 ){ pWInfo->nOBSat = pOrderBy->nExpr; } From 32634d270ce9de65ac8a1cec14df671a477ce91c Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 27 Sep 2012 14:11:36 +0000 Subject: [PATCH 55/60] Enable ORDER BY clauses that span joins to be optimized out. FossilOrigin-Name: c29538f9b1ee4d4869999570604c9618ca0d08ac --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 59 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 5f591e9ff6..a66358269a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\stweaks\sto\sthe\squery\splanner\slogic\sin\spreparation\sfor\sadding\nORDER\sBY\sopt-out\sfor\sjoins. -D 2012-09-27T12:05:09.522 +C Enable\sORDER\sBY\sclauses\sthat\sspan\sjoins\sto\sbe\soptimized\sout. +D 2012-09-27T14:11:36.514 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -249,7 +249,7 @@ F src/vtab.c d8020c0a0e8ccc490ca449d7e665311b6e9f3ba9 F src/wal.c 5acb3e7bbd31f10ba39acad9ce6b399055337a9d F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b -F src/where.c 67438c6192c5f777139e7abb642a9186a21a718d +F src/where.c 36af33a92ccbf8b5be3bc7eae08a7f022afb60d8 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 0be144b453e0622a085fae8665c32f5676708e00 @@ -1016,7 +1016,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 96496ddae12a239b30a1fc997fbea43e3a75bfe7 -R 57ad7fba1d5db0bb9191afb65acee747 +P 53efc10af990d3f293551f3cd8ef2f8be2d9d716 +R d9d746ad3fd7e5c77ffbaf4f5251f6f8 U drh -Z 58fdbd300662a0c1ec2665b77df5f795 +Z 769b41d4cd58dfa3626d0858103449b9 diff --git a/manifest.uuid b/manifest.uuid index 2e377696fc..c7339ef5c5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -53efc10af990d3f293551f3cd8ef2f8be2d9d716 \ No newline at end of file +c29538f9b1ee4d4869999570604c9618ca0d08ac \ No newline at end of file diff --git a/src/where.c b/src/where.c index 0405860c9a..ce5437a9f5 100644 --- a/src/where.c +++ b/src/where.c @@ -2863,17 +2863,67 @@ static int whereInScanEst( } #endif /* defined(SQLITE_ENABLE_STAT3) */ +/* +** Check to see if column iCol of the table with cursor iTab will appear +** in sorted order according to the current query plan. Return true if +** it will and false if not. +** +** If *pbRev is initially 2 (meaning "unknown") then set *pbRev to the +** sort order of iTab.iCol. If *pbRev is 0 or 1 but does not match +** the sort order of iTab.iCol, then consider the column to be unordered. +*/ +static int isOrderedColumn(WhereBestIdx *p, int iTab, int iCol, int *pbRev){ + int i, j; + WhereLevel *pLevel = &p->aLevel[p->i-1]; + Index *pIdx; + u8 sortOrder; + for(i=p->i-1; i>=0; i--, pLevel--){ + if( pLevel->iTabCur!=iTab ) continue; + if( (pLevel->plan.wsFlags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE))!=0 ){ + if( iCol!=(-1) ) return 0; + sortOrder = 0; + }else if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){ + pIdx = pLevel->plan.u.pIdx; + for(j=0; jnColumn; j++){ + if( iCol==pIdx->aiColumn[j] ) break; + } + if( j>=pIdx->nColumn ) return 0; + sortOrder = pIdx->aSortOrder[j]; + }else{ + if( iCol!=(-1) ) return 0; + sortOrder = 0; + } + if( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 ) sortOrder = 1 - sortOrder; + if( *pbRev==2 ){ + *pbRev = sortOrder; + return 1; + } + return (*pbRev==sortOrder); + } + return 0; +} + /* ** pTerm is an == constraint. Check to see if the other side of ** the == is a constant or a value that is guaranteed to be ordered ** by outer loops. Return 1 if pTerm is ordered, and 0 if not. */ static int isOrderedTerm(WhereBestIdx *p, WhereTerm *pTerm, int *pbRev){ + Expr *pExpr = pTerm->pExpr; + assert( pExpr->op==TK_EQ ); + assert( pExpr->pLeft!=0 && pExpr->pLeft->op==TK_COLUMN ); + assert( pExpr->pRight!=0 ); if( p->i==0 ){ return 1; /* All == are ordered in the outer loop */ } - - + if( pTerm->prereqRight==0 ){ + return 1; /* RHS of the == is a constant */ + } + if( pExpr->pRight->op==TK_COLUMN + && isOrderedColumn(p, pExpr->pRight->iTable, pExpr->pRight->iColumn, pbRev) + ){ + return 1; + } /* If we cannot prove that the constraint is ordered, assume it is not */ return 0; From 7e5418e4a487f7579c1249857bf69b7a6985bf32 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 27 Sep 2012 15:05:54 +0000 Subject: [PATCH 56/60] Add more bits to the bit vector that is used to disable optimizations for built-in test. Add specific bit patterns to disable ORDER BY using an index in general and for joins. Use macros to test for bits in the disabled-optimization bit vector, in order to make the code clearer. FossilOrigin-Name: d2fcba1e143beca8c45724d2108870657c269e17 --- manifest | 24 +++++++-------- manifest.uuid | 2 +- src/delete.c | 4 ++- src/expr.c | 4 +-- src/main.c | 3 +- src/select.c | 4 +-- src/sqliteInt.h | 82 +++++++++++++++++++++++++++++-------------------- src/test1.c | 4 ++- src/where.c | 13 +++----- 9 files changed, 77 insertions(+), 63 deletions(-) diff --git a/manifest b/manifest index a66358269a..1bbd906b74 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enable\sORDER\sBY\sclauses\sthat\sspan\sjoins\sto\sbe\soptimized\sout. -D 2012-09-27T14:11:36.514 +C Add\smore\sbits\sto\sthe\sbit\svector\sthat\sis\sused\sto\sdisable\soptimizations\sfor\nbuilt-in\stest.\s\sAdd\sspecific\sbit\spatterns\sto\sdisable\sORDER\sBY\susing\san\nindex\sin\sgeneral\sand\sfor\sjoins.\s\sUse\smacros\sto\stest\sfor\sbits\sin\sthe\s\ndisabled-optimization\sbit\svector,\sin\sorder\sto\smake\sthe\scode\sclearer. +D 2012-09-27T15:05:54.735 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -129,8 +129,8 @@ F src/callback.c 0cb4228cdcd827dcc5def98fb099edcc9142dbcd F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 72a70dcfda75d3a1f81041ce4573e7afddcd8e4e F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 -F src/delete.c 335f36750dc6ac88d580aa36a6487459be9889de -F src/expr.c 4d1cef0fae6f3cf3c754773fd413f3e221021003 +F src/delete.c 4f7d773ec44b7db22b30ec9144f58a69154e09b7 +F src/expr.c 4de967b85f577ba00a7cdcb53d22070def6198db F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c c82a04e7a92bb728f9ab972b76590403283be2af F src/func.c cbb90dc84b22eea25caf39528d342279e61b8898 @@ -143,7 +143,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d -F src/main.c 97d13e749ae84fe62238a5940c5b46b2b22cd369 +F src/main.c c5fec9814efaa64fa1de83497553f5904aa1bbec F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa @@ -174,17 +174,17 @@ F src/printf.c 4a9f882f1c1787a8b494a2987765acf9d97ac21f F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 9e28280ec98035f31900fdd1db01f86f68ca6c32 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c a91b651652b43a8baaeec0ad13a6a6b290a4d0af +F src/select.c 75c5e37cc882c468383c9d9e07496b9a16cfae3e F src/shell.c 8ee5a3cb502e2d574f97b43972e6c1e275e7bec7 F src/sqlite.h.in cbe846facaba903654b4136c97e7f57b3ac0bac7 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h cbcd2dd649338598a1a773a9adaf9f62e7256852 +F src/sqliteInt.h 6ad55f4efbd1bb209711032e40b7c81c8855d634 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/tclsqlite.c e4de2458b3ef38fdd0498bc4e5ea5367a241b0f3 -F src/test1.c bec5295347a7bc38a53ca955f01cfcaf116fdb88 +F src/test1.c 9000293bfdcd67de05bf91d257343392c4b194f4 F src/test2.c 4178056dd1e7d70f954ad8a1e3edb71a2a784daf F src/test3.c 3c3c2407fa6ec7a19e24ae23f7cb439d0275a60d F src/test4.c bf9fa9bece01de08e6f5e02314e4af5c13590dfa @@ -249,7 +249,7 @@ F src/vtab.c d8020c0a0e8ccc490ca449d7e665311b6e9f3ba9 F src/wal.c 5acb3e7bbd31f10ba39acad9ce6b399055337a9d F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b -F src/where.c 36af33a92ccbf8b5be3bc7eae08a7f022afb60d8 +F src/where.c 4b837884c4747b022cf36bd00d9eddbb6b451241 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 0be144b453e0622a085fae8665c32f5676708e00 @@ -1016,7 +1016,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 53efc10af990d3f293551f3cd8ef2f8be2d9d716 -R d9d746ad3fd7e5c77ffbaf4f5251f6f8 +P c29538f9b1ee4d4869999570604c9618ca0d08ac +R 112951e028390501419dede06d50cf2d U drh -Z 769b41d4cd58dfa3626d0858103449b9 +Z 58d07d9f2619813e6ef0c2cb6bcd8ae9 diff --git a/manifest.uuid b/manifest.uuid index c7339ef5c5..17a2e618d2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c29538f9b1ee4d4869999570604c9618ca0d08ac \ No newline at end of file +d2fcba1e143beca8c45724d2108870657c269e17 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 44e5995a69..f7f52865e1 100644 --- a/src/delete.c +++ b/src/delete.c @@ -638,7 +638,9 @@ int sqlite3GenerateIndexKey( } if( doMakeRec ){ const char *zAff; - if( pTab->pSelect || (pParse->db->flags & SQLITE_IdxRealAsInt)!=0 ){ + if( pTab->pSelect + || OptimizationDisabled(pParse->db, SQLITE_IdxRealAsInt) + ){ zAff = 0; }else{ zAff = sqlite3IndexAffinityStr(v, pIdx); diff --git a/src/expr.c b/src/expr.c index 3d63738813..2d1fb38ede 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2066,7 +2066,7 @@ void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){ ** for testing only - to verify that SQLite always gets the same answer ** with and without the column cache. */ - if( pParse->db->flags & SQLITE_ColumnCache ) return; + if( OptimizationDisabled(pParse->db, SQLITE_ColumnCache) ) return; /* First replace any existing entry. ** @@ -3382,7 +3382,7 @@ static int evalConstExpr(Walker *pWalker, Expr *pExpr){ void sqlite3ExprCodeConstants(Parse *pParse, Expr *pExpr){ Walker w; if( pParse->cookieGoto ) return; - if( (pParse->db->flags & SQLITE_FactorOutConst)!=0 ) return; + if( OptimizationDisabled(pParse->db, SQLITE_FactorOutConst) ) return; w.xExprCallback = evalConstExpr; w.xSelectCallback = 0; w.pParse = pParse; diff --git a/src/main.c b/src/main.c index 466dee5516..8713c790c9 100644 --- a/src/main.c +++ b/src/main.c @@ -3018,8 +3018,7 @@ int sqlite3_test_control(int op, ...){ */ case SQLITE_TESTCTRL_OPTIMIZATIONS: { sqlite3 *db = va_arg(ap, sqlite3*); - int x = va_arg(ap,int); - db->flags = (x & SQLITE_OptMask) | (db->flags & ~SQLITE_OptMask); + db->dbOptFlags = (u16)(va_arg(ap, int) & 0xffff); break; } diff --git a/src/select.c b/src/select.c index 0f2320f59c..2da14d93ed 100644 --- a/src/select.c +++ b/src/select.c @@ -2809,7 +2809,7 @@ static int flattenSubquery( */ assert( p!=0 ); assert( p->pPrior==0 ); /* Unable to flatten compound queries */ - if( db->flags & SQLITE_QueryFlattener ) return 0; + if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0; pSrc = p->pSrc; assert( pSrc && iFrom>=0 && iFromnSrc ); pSubitem = &pSrc->a[iFrom]; @@ -4012,7 +4012,7 @@ int sqlite3Select( ** to disable this optimization for testing purposes. */ if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy)==0 - && (db->flags & SQLITE_GroupByOrder)==0 ){ + && OptimizationEnabled(db, SQLITE_GroupByOrder) ){ pOrderBy = 0; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index cd38dc8707..4501c737f3 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -827,6 +827,7 @@ struct sqlite3 { unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ int errCode; /* Most recent error code (SQLITE_*) */ int errMask; /* & result codes with this before returning */ + u16 dbOptFlags; /* Flags to enable/disable optimizations */ u8 autoCommit; /* The auto-commit flag. */ u8 temp_store; /* 1: file 2: memory 0: default */ u8 mallocFailed; /* True if we have seen a malloc failure */ @@ -931,46 +932,59 @@ struct sqlite3 { /* ** Possible values for the sqlite3.flags. */ -#define SQLITE_VdbeTrace 0x00000100 /* True to trace VDBE execution */ -#define SQLITE_InternChanges 0x00000200 /* Uncommitted Hash table changes */ -#define SQLITE_FullColNames 0x00000400 /* Show full column names on SELECT */ -#define SQLITE_ShortColNames 0x00000800 /* Show short columns names */ -#define SQLITE_CountRows 0x00001000 /* Count rows changed by INSERT, */ +#define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */ +#define SQLITE_InternChanges 0x00000002 /* Uncommitted Hash table changes */ +#define SQLITE_FullColNames 0x00000004 /* Show full column names on SELECT */ +#define SQLITE_ShortColNames 0x00000008 /* Show short columns names */ +#define SQLITE_CountRows 0x00000010 /* Count rows changed by INSERT, */ /* DELETE, or UPDATE and return */ /* the count using a callback. */ -#define SQLITE_NullCallback 0x00002000 /* Invoke the callback once if the */ +#define SQLITE_NullCallback 0x00000020 /* Invoke the callback once if the */ /* result set is empty */ -#define SQLITE_SqlTrace 0x00004000 /* Debug print SQL as it executes */ -#define SQLITE_VdbeListing 0x00008000 /* Debug listings of VDBE programs */ -#define SQLITE_WriteSchema 0x00010000 /* OK to update SQLITE_MASTER */ - /* 0x00020000 Unused */ -#define SQLITE_IgnoreChecks 0x00040000 /* Do not enforce check constraints */ -#define SQLITE_ReadUncommitted 0x0080000 /* For shared-cache mode */ -#define SQLITE_LegacyFileFmt 0x00100000 /* Create new databases in format 1 */ -#define SQLITE_FullFSync 0x00200000 /* Use full fsync on the backend */ -#define SQLITE_CkptFullFSync 0x00400000 /* Use full fsync for checkpoint */ -#define SQLITE_RecoveryMode 0x00800000 /* Ignore schema errors */ -#define SQLITE_ReverseOrder 0x01000000 /* Reverse unordered SELECTs */ -#define SQLITE_RecTriggers 0x02000000 /* Enable recursive triggers */ -#define SQLITE_ForeignKeys 0x04000000 /* Enforce foreign key constraints */ -#define SQLITE_AutoIndex 0x08000000 /* Enable automatic indexes */ -#define SQLITE_PreferBuiltin 0x10000000 /* Preference to built-in funcs */ -#define SQLITE_LoadExtension 0x20000000 /* Enable load_extension */ -#define SQLITE_EnableTrigger 0x40000000 /* True to enable triggers */ +#define SQLITE_SqlTrace 0x00000040 /* Debug print SQL as it executes */ +#define SQLITE_VdbeListing 0x00000080 /* Debug listings of VDBE programs */ +#define SQLITE_WriteSchema 0x00000100 /* OK to update SQLITE_MASTER */ + /* 0x00000200 Unused */ +#define SQLITE_IgnoreChecks 0x00000400 /* Do not enforce check constraints */ +#define SQLITE_ReadUncommitted 0x0000800 /* For shared-cache mode */ +#define SQLITE_LegacyFileFmt 0x00001000 /* Create new databases in format 1 */ +#define SQLITE_FullFSync 0x00002000 /* Use full fsync on the backend */ +#define SQLITE_CkptFullFSync 0x00004000 /* Use full fsync for checkpoint */ +#define SQLITE_RecoveryMode 0x00008000 /* Ignore schema errors */ +#define SQLITE_ReverseOrder 0x00010000 /* Reverse unordered SELECTs */ +#define SQLITE_RecTriggers 0x00020000 /* Enable recursive triggers */ +#define SQLITE_ForeignKeys 0x00040000 /* Enforce foreign key constraints */ +#define SQLITE_AutoIndex 0x00080000 /* Enable automatic indexes */ +#define SQLITE_PreferBuiltin 0x00100000 /* Preference to built-in funcs */ +#define SQLITE_LoadExtension 0x00200000 /* Enable load_extension */ +#define SQLITE_EnableTrigger 0x00400000 /* True to enable triggers */ /* -** Bits of the sqlite3.flags field that are used by the -** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface. -** These must be the low-order bits of the flags field. +** Bits of the sqlite3.dbOptFlags field that are used by the +** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to +** selectively disable various optimizations. */ -#define SQLITE_QueryFlattener 0x01 /* Disable query flattening */ -#define SQLITE_ColumnCache 0x02 /* Disable the column cache */ -#define SQLITE_GroupByOrder 0x04 /* Disable GROUPBY cover of ORDERBY */ -#define SQLITE_FactorOutConst 0x08 /* Disable factoring out constants */ -#define SQLITE_IdxRealAsInt 0x10 /* Store REAL as INT in indices */ -#define SQLITE_DistinctOpt 0x20 /* DISTINCT using indexes */ -#define SQLITE_CoverIdxScan 0x40 /* Disable covering index scans */ -#define SQLITE_OptMask 0xff /* Mask of all disablable opts */ +#define SQLITE_QueryFlattener 0x0001 /* Query flattening */ +#define SQLITE_ColumnCache 0x0002 /* Column cache */ +#define SQLITE_GroupByOrder 0x0004 /* GROUPBY cover of ORDERBY */ +#define SQLITE_FactorOutConst 0x0008 /* Constant factoring */ +#define SQLITE_IdxRealAsInt 0x0010 /* Store REAL as INT in indices */ +#define SQLITE_DistinctOpt 0x0020 /* DISTINCT using indexes */ +#define SQLITE_CoverIdxScan 0x0040 /* Covering index scans */ +#define SQLITE_OrderByIdx 0x0180 /* ORDER BY using indices */ +#define SQLITE_OrderByIdxJoin 0x0100 /* ORDER BY of joins via index */ +#define SQLITE_AllOpts 0x01ff /* All optimizations */ + +/* +** Macros for testing whether or not optimizations are enabled or disabled. +*/ +#ifndef SQLITE_OMIT_BUILTIN_TEST +#define OptimizationDisabled(db, mask) (((db)->dbOptFlags&(mask))!=0) +#define OptimizationEnabled(db, mask) (((db)->dbOptFlags&(mask))==0) +#else +#define OptimizationDisabled(db, mask) 0 +#define OptimizationEnabled(db, mask) 1 +#endif /* ** Possible values for the sqlite.magic field. diff --git a/src/test1.c b/src/test1.c index 0b9b812e8f..45ca124bb2 100644 --- a/src/test1.c +++ b/src/test1.c @@ -5933,7 +5933,7 @@ static int optimization_control( const char *zOptName; int mask; } aOpt[] = { - { "all", SQLITE_OptMask }, + { "all", SQLITE_AllOpts }, { "query-flattener", SQLITE_QueryFlattener }, { "column-cache", SQLITE_ColumnCache }, { "groupby-order", SQLITE_GroupByOrder }, @@ -5941,6 +5941,8 @@ static int optimization_control( { "real-as-int", SQLITE_IdxRealAsInt }, { "distinct-opt", SQLITE_DistinctOpt }, { "cover-idx-scan", SQLITE_CoverIdxScan }, + { "order-by-idx", SQLITE_OrderByIdx }, + { "order-by-idx-join",SQLITE_OrderByIdxJoin }, }; if( objc!=4 ){ diff --git a/src/where.c b/src/where.c index ce5437a9f5..0395496572 100644 --- a/src/where.c +++ b/src/where.c @@ -1646,9 +1646,11 @@ static int isSortingIndex( int nPriorSat; /* ORDER BY terms satisfied by outer loops */ int seenRowid = 0; /* True if an ORDER BY rowid term is seen */ + if( OptimizationDisabled(db, SQLITE_OrderByIdx) ) return 0; if( p->i==0 ){ nPriorSat = 0; }else{ + if( OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ) return 0; nPriorSat = p->aLevel[p->i-1].plan.nOBSat; } if( p->i>0 && nEqCol==0 /*&& !allOuterLoopsUnique(p)*/ ) return nPriorSat; @@ -2879,10 +2881,7 @@ static int isOrderedColumn(WhereBestIdx *p, int iTab, int iCol, int *pbRev){ u8 sortOrder; for(i=p->i-1; i>=0; i--, pLevel--){ if( pLevel->iTabCur!=iTab ) continue; - if( (pLevel->plan.wsFlags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE))!=0 ){ - if( iCol!=(-1) ) return 0; - sortOrder = 0; - }else if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){ + if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){ pIdx = pLevel->plan.u.pIdx; for(j=0; jnColumn; j++){ if( iCol==pIdx->aiColumn[j] ) break; @@ -3289,9 +3288,7 @@ static void bestBtreeIndex(WhereBestIdx *p){ if( wsFlags==WHERE_IDX_ONLY && (pWC->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 && sqlite3GlobalConfig.bUseCis -#ifndef SQLITE_OMIT_BUILTIN_TEST - && (pParse->db->flags & SQLITE_CoverIdxScan)==0 -#endif + && OptimizationEnabled(pParse->db, SQLITE_CoverIdxScan) ){ /* This index is not useful for indexing, but it is a covering index. ** A full-scan of the index might be a little faster than a full-scan @@ -4841,7 +4838,7 @@ WhereInfo *sqlite3WhereBegin( /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */ - if( db->flags & SQLITE_DistinctOpt ) pDistinct = 0; + if( OptimizationDisabled(db, SQLITE_DistinctOpt) ) pDistinct = 0; /* Split the WHERE clause into separate subexpressions where each ** subexpression is separated by an AND operator. From 6b10a6a7edaa09b0e9151fe5b0185d33dce0f06f Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 27 Sep 2012 17:31:32 +0000 Subject: [PATCH 57/60] Test cases and bug fixes applied to the ORDER BY optimization for joins. Some test cases fail, but except for the new orderby1.test failures, all failures appear to be issues with the tests, not with the core code. FossilOrigin-Name: 75cda864ededb6dc0f84bd52ed3311753a58e351 --- manifest | 17 ++--- manifest.uuid | 2 +- src/where.c | 23 +++++-- test/collate4.test | 2 +- test/collate5.test | 4 +- test/orderby1.test | 155 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 185 insertions(+), 18 deletions(-) create mode 100644 test/orderby1.test diff --git a/manifest b/manifest index 1bbd906b74..e8dbbe14e0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\smore\sbits\sto\sthe\sbit\svector\sthat\sis\sused\sto\sdisable\soptimizations\sfor\nbuilt-in\stest.\s\sAdd\sspecific\sbit\spatterns\sto\sdisable\sORDER\sBY\susing\san\nindex\sin\sgeneral\sand\sfor\sjoins.\s\sUse\smacros\sto\stest\sfor\sbits\sin\sthe\s\ndisabled-optimization\sbit\svector,\sin\sorder\sto\smake\sthe\scode\sclearer. -D 2012-09-27T15:05:54.735 +C Test\scases\sand\sbug\sfixes\sapplied\sto\sthe\sORDER\sBY\soptimization\sfor\sjoins.\nSome\stest\scases\sfail,\sbut\sexcept\sfor\sthe\snew\sorderby1.test\sfailures,\sall\nfailures\sappear\sto\sbe\sissues\swith\sthe\stests,\snot\swith\sthe\score\scode. +D 2012-09-27T17:31:32.268 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -249,7 +249,7 @@ F src/vtab.c d8020c0a0e8ccc490ca449d7e665311b6e9f3ba9 F src/wal.c 5acb3e7bbd31f10ba39acad9ce6b399055337a9d F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b -F src/where.c 4b837884c4747b022cf36bd00d9eddbb6b451241 +F src/where.c a537824b2eec986c203a6a370090520b955f258b F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 0be144b453e0622a085fae8665c32f5676708e00 @@ -324,8 +324,8 @@ F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91 F test/collate1.test e3eaa48c21e150814be1a7b852d2a8af24458d04 F test/collate2.test 04cebe4a033be319d6ddbb3bbc69464e01700b49 F test/collate3.test d28d2cfab2c3a3d4628ae4b2b7afc9965daa3b4c -F test/collate4.test d37682293d3c32223dec2e6afdeaf9de18415248 -F test/collate5.test 67f1d3e848e230ff4802815a79acb0a8b5e69bd7 +F test/collate4.test 27adc324b58ec367bdd0bc6baab628af5129e9f1 +F test/collate5.test 65d928034d30d2d263a80f6359f7549ee1598ec6 F test/collate6.test 8be65a182abaac8011a622131486dafb8076e907 F test/collate7.test 8ec29d98f3ee4ccebce6e16ce3863fb6b8c7b868 F test/collate8.test df26649cfcbddf109c04122b340301616d3a88f6 @@ -634,6 +634,7 @@ F test/notify3.test a86259abbfb923aa27d30f0fc038c88e5251488a F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347 F test/null.test a8b09b8ed87852742343b33441a9240022108993 F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394 +F test/orderby1.test 868a4f88c4f4565684bcc18e8ed61a990ece431b F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3 F test/pager1.test 2163c6ef119f497a71a84137c957c63763e640ab F test/pager2.test 745b911dde3d1f24ae0870bd433dfa83d7c658c1 @@ -1016,7 +1017,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P c29538f9b1ee4d4869999570604c9618ca0d08ac -R 112951e028390501419dede06d50cf2d +P d2fcba1e143beca8c45724d2108870657c269e17 +R 388197fbdd69fccc34c9d73c7bc9f9e7 U drh -Z 58d07d9f2619813e6ef0c2cb6bcd8ae9 +Z f07796285dcd213d3100411a37b9d38f diff --git a/manifest.uuid b/manifest.uuid index 17a2e618d2..38f15f501f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d2fcba1e143beca8c45724d2108870657c269e17 \ No newline at end of file +75cda864ededb6dc0f84bd52ed3311753a58e351 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 0395496572..01155c14d3 100644 --- a/src/where.c +++ b/src/where.c @@ -2883,16 +2883,27 @@ static int isOrderedColumn(WhereBestIdx *p, int iTab, int iCol, int *pbRev){ if( pLevel->iTabCur!=iTab ) continue; if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){ pIdx = pLevel->plan.u.pIdx; - for(j=0; jnColumn; j++){ - if( iCol==pIdx->aiColumn[j] ) break; + if( iCol<0 ){ + sortOrder = 0; + testcase( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 ); + }else{ + for(j=0; jnColumn; j++){ + if( iCol==pIdx->aiColumn[j] ) break; + } + if( j>=pIdx->nColumn ) return 0; + sortOrder = pIdx->aSortOrder[j]; + testcase( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 ); } - if( j>=pIdx->nColumn ) return 0; - sortOrder = pIdx->aSortOrder[j]; }else{ if( iCol!=(-1) ) return 0; sortOrder = 0; + testcase( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 ); + } + if( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 ){ + assert( sortOrder==0 || sortOrder==1 ); + testcase( sortOrder==1 ); + sortOrder = 1 - sortOrder; } - if( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 ) sortOrder = 1 - sortOrder; if( *pbRev==2 ){ *pbRev = sortOrder; return 1; @@ -3200,8 +3211,8 @@ static void bestBtreeIndex(WhereBestIdx *p){ if( nOrderBy==nOBSat ){ bSort = 0; wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_ORDERBY; - wsFlags |= (bRev==1 ? WHERE_REVERSE : 0); } + if( bRev ) wsFlags |= WHERE_REVERSE; } /* If there is a DISTINCT qualifier and this index will scan rows in diff --git a/test/collate4.test b/test/collate4.test index 6b3a1c7aee..1cf8caf04c 100644 --- a/test/collate4.test +++ b/test/collate4.test @@ -389,7 +389,7 @@ ifcapable subquery { SELECT a FROM collate4t1 WHERE a IN (SELECT * FROM collate4t2) ORDER BY rowid } - } {a A 6} + } {a A 5} do_test collate4-2.1.8 { count { SELECT a FROM collate4t1 WHERE a IN ('z', 'a'); diff --git a/test/collate5.test b/test/collate5.test index e5bea7a5a5..5f8697ea51 100644 --- a/test/collate5.test +++ b/test/collate5.test @@ -221,7 +221,7 @@ do_test collate5-3.0 { execsql { SELECT a FROM collate5t1 UNION ALL SELECT a FROM collate5t2 ORDER BY 1; } -} {a A a A b B b B n N} +} {/[aA] [aA] [aA] [aA] [bB] [bB] [bB] [bB] [nN] [nN]/} do_test collate5-3.1 { execsql { SELECT a FROM collate5t2 UNION ALL SELECT a FROM collate5t1 ORDER BY 1; @@ -282,7 +282,7 @@ do_test collate5-4.2 { execsql { SELECT a, b, count(*) FROM collate5t1 GROUP BY a, b ORDER BY a, b; } -} {A 1.0 2 b 2 1 B 3 1} +} {/[aA] 1(.0)? 2 [bB] 2 1 [bB] 3 1/} do_test collate5-4.3 { execsql { DROP TABLE collate5t1; diff --git a/test/orderby1.test b/test/orderby1.test new file mode 100644 index 0000000000..2837dfcab3 --- /dev/null +++ b/test/orderby1.test @@ -0,0 +1,155 @@ +# 2012 Sept 27 +# +# 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 that the optimizations that disable +# ORDER BY clauses when the natural order of a query is correct. +# + + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set ::testprefix orderby1 + +# Generate test data for a join. Verify that the join gets the +# correct answer. +# +do_test 1.0 { + db eval { + BEGIN; + CREATE TABLE album( + aid INTEGER PRIMARY KEY, + title TEXT UNIQUE NOT NULL + ); + CREATE TABLE track( + tid INTEGER PRIMARY KEY, + aid INTEGER NOT NULL REFERENCES album, + tn INTEGER NOT NULL, + name TEXT, + UNIQUE(aid, tn) + ); + INSERT INTO album VALUES(1, '1-one'), (2, '2-two'), (3, '3-three'); + INSERT INTO track VALUES + (NULL, 1, 1, 'one-a'), + (NULL, 2, 2, 'two-b'), + (NULL, 3, 3, 'three-c'), + (NULL, 1, 3, 'one-c'), + (NULL, 2, 1, 'two-a'), + (NULL, 3, 1, 'three-a'); + COMMIT; + } +} {} +do_test 1.1a { + db eval { + SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn + } +} {one-a one-c two-a two-b three-a three-c} + +# Verify that the ORDER BY clause is optimized out +# +do_test 1.1b { + db eval { + EXPLAIN QUERY PLAN + SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn + } +} {~/ORDER BY/} ;# ORDER BY optimized out + +# The same query with ORDER BY clause optimization disabled via + operators +# should give exactly the same answer. +# +do_test 1.2a { + db eval { + SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn + } +} {one-a one-c two-a two-b three-a three-c} + +# The output is sorted manually in this case. +# +do_test 1.2b { + db eval { + EXPLAIN QUERY PLAN + SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn + } +} {/ORDER BY/} ;# separate sorting pass due to "+" on ORDER BY terms + +# The same query with ORDER BY optimizations turned off via built-in test. +# +do_test 1.3a { + optimization_control db order-by-idx-join 0 + db cache flush + db eval { + SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn + } +} {one-a one-c two-a two-b three-a three-c} +do_test 1.3b { + db eval { + EXPLAIN QUERY PLAN + SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn + } +} {/ORDER BY/} ;# separate sorting pass due to disabled optimization +optimization_control db all 1 +db cache flush + +# Reverse order sorts +# +do_test 1.4a { + db eval { + SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn + } +} {three-a three-c two-a two-b one-a one-c} +do_test 1.4b { + db eval { + SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn + } +} {three-a three-c two-a two-b one-a one-c} ;# verify same order after sorting +do_test 1.4c { + db eval { + EXPLAIN QUERY PLAN + SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn + } +} {~/ORDER BY/} ;# ORDER BY optimized-out + + +do_test 1.5a { + db eval { + SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC + } +} {one-c one-a two-b two-a three-c three-a} +do_test 1.5b { + db eval { + SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC + } +} {one-c one-a two-b two-a three-c three-a} ;# verify same order after sorting +do_test 1.5c { + db eval { + EXPLAIN QUERY PLAN + SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn + } +} {~/ORDER BY/} ;# ORDER BY optimized-out + +do_test 1.6a { + db eval { + SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC + } +} {three-c three-a two-b two-a one-c one-a} +do_test 1.6b { + db eval { + SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn DESC + } +} {three-c three-a two-b two-a one-c one-a} ;# verify same order after sorting +do_test 1.6c { + db eval { + EXPLAIN QUERY PLAN + SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC + } +} {~/ORDER BY/} ;# ORDER BY optimized-out + + +finish_test From 5343b2d4a8f778672cffe9ea2d2dd2d0bce7d6ac Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 27 Sep 2012 19:53:38 +0000 Subject: [PATCH 58/60] More test cases an bug fixes for the ORDER BY optimization of joins. All veryquick tests now pass. FossilOrigin-Name: 0d573320057b0903a5589cabfb1b1ece1c57958e --- manifest | 22 ++-- manifest.uuid | 2 +- src/where.c | 23 ++-- test/e_select.test | 16 +-- test/orderby1.test | 277 ++++++++++++++++++++++++++++++++++++++- test/tester.tcl | 4 +- test/tkt-cbd054fa6b.test | 4 +- test/where.test | 6 +- 8 files changed, 315 insertions(+), 39 deletions(-) diff --git a/manifest b/manifest index e8dbbe14e0..1b05b5bd9b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Test\scases\sand\sbug\sfixes\sapplied\sto\sthe\sORDER\sBY\soptimization\sfor\sjoins.\nSome\stest\scases\sfail,\sbut\sexcept\sfor\sthe\snew\sorderby1.test\sfailures,\sall\nfailures\sappear\sto\sbe\sissues\swith\sthe\stests,\snot\swith\sthe\score\scode. -D 2012-09-27T17:31:32.268 +C More\stest\scases\san\sbug\sfixes\sfor\sthe\sORDER\sBY\soptimization\sof\sjoins.\s\sAll\nveryquick\stests\snow\spass. +D 2012-09-27T19:53:38.142 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -249,7 +249,7 @@ F src/vtab.c d8020c0a0e8ccc490ca449d7e665311b6e9f3ba9 F src/wal.c 5acb3e7bbd31f10ba39acad9ce6b399055337a9d F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b -F src/where.c a537824b2eec986c203a6a370090520b955f258b +F src/where.c cd047c1223f6364f869d44b7d3941a687de7fcb6 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 0be144b453e0622a085fae8665c32f5676708e00 @@ -386,7 +386,7 @@ F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459 F test/e_insert.test c6ac239a97cb16dfbd0c16496f8cd871b4068c0c F test/e_reindex.test dfedfc32c5a282b0596c6537cbcd4217fbb1a216 F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6 -F test/e_select.test 69013a64b469458820abb7f3281a7eaa6c1fda76 +F test/e_select.test 07e8d81268ba1ffcaf1dc4bec48956af150c42f9 F test/e_select2.test 5c3d3da19c7b3e90ae444579db2b70098599ab92 F test/e_update.test 161d5dc6a3ed9dd08f5264d13e20735d7a89f00c F test/e_uri.test 9e190ca799d9190eec6e43f2aadf1d10c06a57a3 @@ -634,7 +634,7 @@ F test/notify3.test a86259abbfb923aa27d30f0fc038c88e5251488a F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347 F test/null.test a8b09b8ed87852742343b33441a9240022108993 F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394 -F test/orderby1.test 868a4f88c4f4565684bcc18e8ed61a990ece431b +F test/orderby1.test 31c9865626046666e81cd22ecf8e1c24a4ea41b6 F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3 F test/pager1.test 2163c6ef119f497a71a84137c957c63763e640ab F test/pager2.test 745b911dde3d1f24ae0870bd433dfa83d7c658c1 @@ -740,7 +740,7 @@ F test/tclsqlite.test a3d2df21ee98957f5de4f9dc1db0eab68047ab5d F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c F test/temptable.test 51edd31c65ed1560dd600b1796e8325df96318e2 F test/temptrigger.test 26670ed7a39cf2296a7f0a9e0a1d7bdb7abe936d -F test/tester.tcl ed47103d30a1a4b3c1d8de207606a407e55cc5c2 +F test/tester.tcl 2f383e811010b05a83c0f00fc168cae1dd63a6d9 F test/thread001.test 7cc2ce08f9cde95964736d11e91f9ab610f82f91 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -784,7 +784,7 @@ F test/tkt-b72787b1.test a95e8cdad0b98af1853ac7f0afd4ab27b77bf5f3 F test/tkt-bd484a090c.test 60460bf946f79a79712b71f202eda501ca99b898 F test/tkt-bdc6bbbb38.test fc38bb09bdd440e3513a1f5f98fc60a075182d7d F test/tkt-c48d99d690.test bed446e3513ae10eec1b86fdd186ef750226c408 -F test/tkt-cbd054fa6b.test bd9fb546f63bc0c79d1776978d059fa51c5b1c63 +F test/tkt-cbd054fa6b.test 9c27ed07b333eed458e5d4543f91ecdcf05aeb19 F test/tkt-d11f09d36e.test fb44f7961aa6d4b632fb7b9768239832210b5fc7 F test/tkt-d635236375.test 9d37e988b47d87505bc9445be0ca447002df5d09 F test/tkt-d82e3f3721.test bcc0dfba658d15bab30fd4a9320c9e35d214ce30 @@ -955,7 +955,7 @@ F test/walro.test a31deb621033442a76c3a61e44929250d06f81b1 F test/walshared.test 6dda2293880c300baf5d791c307f653094585761 F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e -F test/where.test 59cf231e6edaf0f20b106a26d4294847e7c6eb25 +F test/where.test ea9659ff6e31681d0cdaf964747139cb10808200 F test/where2.test 43d4becaf5a5df854e6c21d624a1cb84c6904554 F test/where3.test 667e75642102c97a00bf9b23d3cb267db321d006 F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2 @@ -1017,7 +1017,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P d2fcba1e143beca8c45724d2108870657c269e17 -R 388197fbdd69fccc34c9d73c7bc9f9e7 +P 75cda864ededb6dc0f84bd52ed3311753a58e351 +R 2ac4d1c44b199e10f1d07ecdc3868045 U drh -Z f07796285dcd213d3100411a37b9d38f +Z 9df007fa9fa34b8089a8009c6ca9320b diff --git a/manifest.uuid b/manifest.uuid index 38f15f501f..f52b6aaffd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -75cda864ededb6dc0f84bd52ed3311753a58e351 \ No newline at end of file +0d573320057b0903a5589cabfb1b1ece1c57958e \ No newline at end of file diff --git a/src/where.c b/src/where.c index 01155c14d3..9bdcd536c4 100644 --- a/src/where.c +++ b/src/where.c @@ -1645,13 +1645,17 @@ static int isSortingIndex( sqlite3 *db = pParse->db; /* Database connection */ int nPriorSat; /* ORDER BY terms satisfied by outer loops */ int seenRowid = 0; /* True if an ORDER BY rowid term is seen */ + int nEqOneRow; /* Idx columns that ref unique values */ if( OptimizationDisabled(db, SQLITE_OrderByIdx) ) return 0; if( p->i==0 ){ nPriorSat = 0; + nEqOneRow = nEqCol; }else{ if( OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ) return 0; nPriorSat = p->aLevel[p->i-1].plan.nOBSat; + sortOrder = bOuterRev; + nEqOneRow = 0; } if( p->i>0 && nEqCol==0 /*&& !allOuterLoopsUnique(p)*/ ) return nPriorSat; pOrderBy = p->pOrderBy; @@ -1725,7 +1729,7 @@ static int isSortingIndex( assert( pTerm->sortOrder==0 || pTerm->sortOrder==1 ); assert( iSortOrder==0 || iSortOrder==1 ); termSortOrder = iSortOrder ^ pTerm->sortOrder; - if( i>nEqCol ){ + if( i>nEqOneRow ){ if( termSortOrder!=sortOrder ){ /* Indices can only be used if all ORDER BY terms past the ** equality constraints are all either DESC or ASC. */ @@ -1741,7 +1745,7 @@ static int isSortingIndex( break; } } - *pbRev = bOuterRev ^ sortOrder; + *pbRev = sortOrder; /* If there was an "ORDER BY rowid" term that matched, or it is only ** possible for a single row from this table to match, then skip over @@ -3296,7 +3300,7 @@ static void bestBtreeIndex(WhereBestIdx *p){ ** So this computation assumes table records are about twice as big ** as index records */ - if( wsFlags==WHERE_IDX_ONLY + if( (wsFlags&~WHERE_REVERSE)==WHERE_IDX_ONLY && (pWC->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 && sqlite3GlobalConfig.bUseCis && OptimizationEnabled(pParse->db, SQLITE_CoverIdxScan) @@ -3421,9 +3425,10 @@ static void bestBtreeIndex(WhereBestIdx *p){ WHERETRACE(( - "%s(%s): nEq=%d nInMul=%d rangeDiv=%d bSort=%d bLookup=%d wsFlags=0x%x\n" - " notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f\n" - " used=0x%llx nOrdered=%d nOBSat=%d\n", + "%s(%s):\n" + " nEq=%d nInMul=%d rangeDiv=%d bSort=%d bLookup=%d wsFlags=0x%08x\n" + " notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f\n" + " used=0x%llx nOrdered=%d nOBSat=%d\n", pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk"), nEq, nInMul, (int)rangeDiv, bSort, bLookup, wsFlags, p->notReady, log10N, nRow, cost, used, nOrdered, nOBSat @@ -5088,10 +5093,10 @@ WhereInfo *sqlite3WhereBegin( } assert( bestJ>=0 ); assert( sWBI.notValid & getMask(pMaskSet, pTabList->a[bestJ].iCursor) ); - WHERETRACE(("*** Optimizer selects table %d for loop %d" - " with cost=%.1f, nRow=%.1f, nOBSat=%d\n", + WHERETRACE(("*** Optimizer selects table %d for loop %d with:\n" + " cost=%.1f, nRow=%.1f, nOBSat=%d wsFlags=0x%08x\n", bestJ, pLevel-pWInfo->a, bestPlan.rCost, bestPlan.plan.nRow, - bestPlan.plan.nOBSat)); + bestPlan.plan.nOBSat, bestPlan.plan.wsFlags)); if( (bestPlan.plan.wsFlags & WHERE_ORDERBY)!=0 ){ pWInfo->nOBSat = pOrderBy->nExpr; } diff --git a/test/e_select.test b/test/e_select.test index 9f26f6fcd3..fb63d051de 100644 --- a/test/e_select.test +++ b/test/e_select.test @@ -1023,7 +1023,7 @@ do_execsql_test e_select-4.9.0 { # do_select_tests e_select-4.9 { 1 "SELECT group_concat(one), two FROM b1 GROUP BY two" { - 4,5 f 1 o 7,6 s 3,2 t + /#,# f 1 o #,# s #,# t/ } 2 "SELECT group_concat(one), sum(one) FROM b1 GROUP BY (one>4)" { 1,2,3,4 10 5,6,7 18 @@ -1040,7 +1040,7 @@ do_select_tests e_select-4.9 { # values are considered equal. # do_select_tests e_select-4.10 { - 1 "SELECT group_concat(y) FROM b2 GROUP BY x" {0,1 3 2,4} + 1 "SELECT group_concat(y) FROM b2 GROUP BY x" {/#,# 3 #,#/} 2 "SELECT count(*) FROM b2 GROUP BY CASE WHEN y<4 THEN NULL ELSE 0 END" {4 1} } @@ -1745,12 +1745,12 @@ do_select_tests e_select-8.4 { 1 2 7 1 2 8 1 4 93 1 5 -1 } 8 "SELECT z, x FROM d1 ORDER BY 2" { - 3 1 8 1 7 1 -20 1 - 93 1 -1 1 -1 2 93 2 + /# 1 # 1 # 1 # 1 + # 1 # 1 # 2 # 2/ } 9 "SELECT z, x FROM d1 ORDER BY 1" { - -20 1 -1 2 -1 1 3 1 - 7 1 8 1 93 2 93 1 + /-20 1 -1 # -1 # 3 1 + 7 1 8 1 93 # 93 #/ } } @@ -1766,10 +1766,10 @@ do_select_tests e_select-8.5 { 94 94 9 8 4 0 0 -19 } 3 "SELECT z AS x, x AS z FROM d1 ORDER BY z" { - 3 1 8 1 7 1 -20 1 93 1 -1 1 -1 2 93 2 + /# 1 # 1 # 1 # 1 # 1 # 1 # 2 # 2/ } 4 "SELECT z AS x, x AS z FROM d1 ORDER BY x" { - -20 1 -1 2 -1 1 3 1 7 1 8 1 93 2 93 1 + /-20 1 -1 # -1 # 3 1 7 1 8 1 93 # 93 #/ } } diff --git a/test/orderby1.test b/test/orderby1.test index 2837dfcab3..400659b475 100644 --- a/test/orderby1.test +++ b/test/orderby1.test @@ -114,7 +114,7 @@ do_test 1.4c { EXPLAIN QUERY PLAN SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn } -} {~/ORDER BY/} ;# ORDER BY optimized-out +} {/ORDER BY/} ;# separate sorting pass due to mixed DESC/ASC do_test 1.5a { @@ -130,9 +130,9 @@ do_test 1.5b { do_test 1.5c { db eval { EXPLAIN QUERY PLAN - SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn + SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC } -} {~/ORDER BY/} ;# ORDER BY optimized-out +} {/ORDER BY/} ;# separate sorting pass due to mixed DESC/ASC do_test 1.6a { db eval { @@ -152,4 +152,275 @@ do_test 1.6c { } {~/ORDER BY/} ;# ORDER BY optimized-out +# Reconstruct the test data to use indices rather than integer primary keys. +# +do_test 2.0 { + db eval { + BEGIN; + DROP TABLE album; + DROP TABLE track; + CREATE TABLE album( + aid INT PRIMARY KEY, + title TEXT NOT NULL + ); + CREATE INDEX album_i1 ON album(title, aid); + CREATE TABLE track( + aid INTEGER NOT NULL REFERENCES album, + tn INTEGER NOT NULL, + name TEXT, + UNIQUE(aid, tn) + ); + INSERT INTO album VALUES(1, '1-one'), (2, '2-two'), (3, '3-three'); + INSERT INTO track VALUES + (1, 1, 'one-a'), + (2, 2, 'two-b'), + (3, 3, 'three-c'), + (1, 3, 'one-c'), + (2, 1, 'two-a'), + (3, 1, 'three-a'); + COMMIT; + } +} {} +do_test 2.1a { + db eval { + SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn + } +} {one-a one-c two-a two-b three-a three-c} + +# Verify that the ORDER BY clause is optimized out +# +do_test 2.1b { + db eval { + EXPLAIN QUERY PLAN + SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn + } +} {~/ORDER BY/} ;# ORDER BY optimized out + +# The same query with ORDER BY clause optimization disabled via + operators +# should give exactly the same answer. +# +do_test 2.2a { + db eval { + SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn + } +} {one-a one-c two-a two-b three-a three-c} + +# The output is sorted manually in this case. +# +do_test 2.2b { + db eval { + EXPLAIN QUERY PLAN + SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn + } +} {/ORDER BY/} ;# separate sorting pass due to "+" on ORDER BY terms + +# The same query with ORDER BY optimizations turned off via built-in test. +# +do_test 2.3a { + optimization_control db order-by-idx-join 0 + db cache flush + db eval { + SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn + } +} {one-a one-c two-a two-b three-a three-c} +do_test 2.3b { + db eval { + EXPLAIN QUERY PLAN + SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn + } +} {/ORDER BY/} ;# separate sorting pass due to disabled optimization +optimization_control db all 1 +db cache flush + +# Reverse order sorts +# +do_test 2.4a { + db eval { + SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn + } +} {three-a three-c two-a two-b one-a one-c} +do_test 2.4b { + db eval { + SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn + } +} {three-a three-c two-a two-b one-a one-c} ;# verify same order after sorting +do_test 2.4c { + db eval { + EXPLAIN QUERY PLAN + SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn + } +} {/ORDER BY/} ;# separate sorting pass due to mixed DESC/ASC + + +do_test 2.5a { + db eval { + SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC + } +} {one-c one-a two-b two-a three-c three-a} +do_test 2.5b { + db eval { + SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC + } +} {one-c one-a two-b two-a three-c three-a} ;# verify same order after sorting +do_test 2.5c { + db eval { + EXPLAIN QUERY PLAN + SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC + } +} {/ORDER BY/} ;# separate sorting pass due to mixed ASC/DESC + +do_test 2.6a { + db eval { + SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC + } +} {three-c three-a two-b two-a one-c one-a} +do_test 2.6b { + db eval { + SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn DESC + } +} {three-c three-a two-b two-a one-c one-a} ;# verify same order after sorting +do_test 2.6c { + db eval { + EXPLAIN QUERY PLAN + SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC + } +} {~/ORDER BY/} ;# ORDER BY optimized-out + + +# Generate another test dataset, but this time using mixed ASC/DESC indices. +# +do_test 3.0 { + db eval { + BEGIN; + DROP TABLE album; + DROP TABLE track; + CREATE TABLE album( + aid INTEGER PRIMARY KEY, + title TEXT UNIQUE NOT NULL + ); + CREATE TABLE track( + tid INTEGER PRIMARY KEY, + aid INTEGER NOT NULL REFERENCES album, + tn INTEGER NOT NULL, + name TEXT, + UNIQUE(aid ASC, tn DESC) + ); + INSERT INTO album VALUES(1, '1-one'), (2, '2-two'), (3, '3-three'); + INSERT INTO track VALUES + (NULL, 1, 1, 'one-a'), + (NULL, 2, 2, 'two-b'), + (NULL, 3, 3, 'three-c'), + (NULL, 1, 3, 'one-c'), + (NULL, 2, 1, 'two-a'), + (NULL, 3, 1, 'three-a'); + COMMIT; + } +} {} +do_test 3.1a { + db eval { + SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC + } +} {one-c one-a two-b two-a three-c three-a} + +# Verify that the ORDER BY clause is optimized out +# +do_test 3.1b { + db eval { + EXPLAIN QUERY PLAN + SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC + } +} {~/ORDER BY/} ;# ORDER BY optimized out + +# The same query with ORDER BY clause optimization disabled via + operators +# should give exactly the same answer. +# +do_test 3.2a { + db eval { + SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC + } +} {one-c one-a two-b two-a three-c three-a} + +# The output is sorted manually in this case. +# +do_test 3.2b { + db eval { + EXPLAIN QUERY PLAN + SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC + } +} {/ORDER BY/} ;# separate sorting pass due to "+" on ORDER BY terms + +# The same query with ORDER BY optimizations turned off via built-in test. +# +do_test 3.3a { + optimization_control db order-by-idx-join 0 + db cache flush + db eval { + SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC + } +} {one-c one-a two-b two-a three-c three-a} +do_test 3.3b { + db eval { + EXPLAIN QUERY PLAN + SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC + } +} {/ORDER BY/} ;# separate sorting pass due to disabled optimization +optimization_control db all 1 +db cache flush + +# Without the mixed ASC/DESC on ORDER BY +# +do_test 3.4a { + db eval { + SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn + } +} {one-a one-c two-a two-b three-a three-c} +do_test 3.4b { + db eval { + SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn + } +} {one-a one-c two-a two-b three-a three-c} ;# verify same order after sorting +do_test 3.4c { + db eval { + EXPLAIN QUERY PLAN + SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn + } +} {/ORDER BY/} ;# separate sorting pass due to mismatched DESC/ASC + + +do_test 3.5a { + db eval { + SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC + } +} {three-c three-a two-b two-a one-c one-a} +do_test 3.5b { + db eval { + SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn DESC + } +} {three-c three-a two-b two-a one-c one-a} ;# verify same order after sorting +do_test 3.5c { + db eval { + EXPLAIN QUERY PLAN + SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC + } +} {/ORDER BY/} ;# separate sorting pass due to mismatched ASC/DESC + + +do_test 3.6a { + db eval { + SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn + } +} {three-a three-c two-a two-b one-a one-c} +do_test 3.6b { + db eval { + SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn + } +} {three-a three-c two-a two-b one-a one-c} ;# verify same order after sorting +do_test 3.6c { + db eval { + EXPLAIN QUERY PLAN + SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn + } +} {~/ORDER BY/} ;# inverted ASC/DESC is optimized out + + finish_test diff --git a/test/tester.tcl b/test/tester.tcl index 74f1e2a1b3..d3fa607d32 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -538,10 +538,10 @@ proc do_test {name cmd expected} { } else { if {[regexp {^~?/.*/$} $expected]} { if {[string index $expected 0]=="~"} { - set re [string range $expected 2 end-1] + set re [string map {# {[-0-9.]+}} [string range $expected 2 end-1]] set ok [expr {![regexp $re $result]}] } else { - set re [string range $expected 1 end-1] + set re [string map {# {[-0-9.]+}} [string range $expected 1 end-1]] set ok [regexp $re $result] } } else { diff --git a/test/tkt-cbd054fa6b.test b/test/tkt-cbd054fa6b.test index 180acf56df..51e01991d4 100644 --- a/test/tkt-cbd054fa6b.test +++ b/test/tkt-cbd054fa6b.test @@ -50,7 +50,7 @@ do_test tkt-cbd05-1.3 { WHERE idx = 't1_x' GROUP BY tbl,idx } -} {t1 t1_x { A B C D E F G H I}} +} {/t1 t1_x .[ ABCDEFGHI]{10}./} do_test tkt-cbd05-2.1 { db eval { @@ -82,6 +82,6 @@ do_test tkt-cbd05-2.3 { WHERE idx = 't1_x' GROUP BY tbl,idx } -} {t1 t1_x { A B C D E F G H I}} +} {/t1 t1_x .[ ABCDEFGHI]{10}./} finish_test diff --git a/test/where.test b/test/where.test index 1dab38ce55..e57722c430 100644 --- a/test/where.test +++ b/test/where.test @@ -383,7 +383,7 @@ ifcapable subquery { count { SELECT * FROM t1 WHERE w IN (-1,1,2,3) order by 1; } - } {1 0 4 2 1 9 3 1 16 14} + } {1 0 4 2 1 9 3 1 16 13} do_test where-5.4 { count { SELECT * FROM t1 WHERE w+0 IN (-1,1,2,3) order by 1; @@ -1109,13 +1109,13 @@ do_test where-14.5 { cksort { SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, x.a||x.b } -} {4/4 4/1 1/4 1/1 sort} +} {/4/[14] 4/[14] 1/[14] 1/[14] sort/} do_test where-14.6 { # This test case changed from "nosort" to "sort". See ticket 2a5629202f. cksort { SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, x.a||x.b DESC } -} {4/4 4/1 1/4 1/1 sort} +} {/4/[14] 4/[14] 1/[14] 1/[14] sort/} do_test where-14.7 { cksort { SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, y.a||y.b From 8ccc6d4076631f3fd97751ce1451453e70c6e329 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 27 Sep 2012 21:03:53 +0000 Subject: [PATCH 59/60] Modify generation of resource header file for MSVC so that it can work from outside the working directory. FossilOrigin-Name: 20caf80cb3b65e69a99dbc142db8ee435fb2dbdc --- Makefile.msc | 6 +++--- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 5cad8931d9..1f8b5bfe82 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -157,8 +157,8 @@ NLTLIBPATHS = "/LIBPATH:$(NCRTLIBPATH)" "/LIBPATH:$(NSDKLIBPATH)" # will run on the target platform. (BCC and TCC are usually the # same unless your are cross-compiling.) # -TCC = $(CC) -W3 -DSQLITE_OS_WIN=1 -I. -I$(TOP)\src -fp:precise -RCC = $(RC) -DSQLITE_OS_WIN=1 -I. -I$(TOP)\src +TCC = $(CC) -W3 -DSQLITE_OS_WIN=1 -I$(TOP) -I$(TOP)\src -fp:precise +RCC = $(RC) -DSQLITE_OS_WIN=1 -I$(TOP) -I$(TOP)\src # When compiling the library for use in the WinRT environment, # the following compile-time options must be used as well to @@ -821,7 +821,7 @@ opcodes.lo: opcodes.c # sqlite3res.lo: $(TOP)\src\sqlite3.rc $(HDR) echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h - for /F %%V in ('type VERSION') do ( \ + for /F %%V in ('type "$(TOP)\VERSION"') do ( \ echo #define SQLITE_RESOURCE_VERSION %%V \ | $(NAWK) "/.*/ { gsub(/[.]/,\",\");print }" >> sqlite3rc.h \ ) diff --git a/manifest b/manifest index 88b0955609..ef93e95f00 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Merge\sthe\s"PRAGMA\sbusy_timeout"\schange\sinto\strunk. -D 2012-09-27T12:11:25.613 +C Modify\sgeneration\sof\sresource\sheader\sfile\sfor\sMSVC\sso\sthat\sit\scan\swork\sfrom\soutside\sthe\sworking\sdirectory. +D 2012-09-27T21:03:53.180 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 -F Makefile.msc d97ae1025a1b7bb2b365b135fc0aa25247e736b2 +F Makefile.msc 1102ce2c75965b9b5534efce380007ffcb08c52e F Makefile.vxworks b18ad88e9a8c6a001f5cf4a389116a4f1a7ab45f F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 F VERSION edab4af5a4623f8198833ea481ce98ab53750a8d @@ -1016,7 +1016,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 349a55cd8ba9ce65ebfd987ecfebd1204f7d0a85 43e474d3e9364e6ed417db06e98faa3e5bc2eb26 -R 5a669a0b1c46b5fd25601e00205c57db -U drh -Z 91e60aa7644657f70b6c3a01cca7ec80 +P 1a679a1ef3b4f2d898c8cd83432d2b4c12bd93fa +R 7d7f62653f839631b2ae10b7e4925e7c +U mistachkin +Z 55006677d3f8e37d2f9043a0e5e0a385 diff --git a/manifest.uuid b/manifest.uuid index 4e4eaae004..a8c2936eb8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1a679a1ef3b4f2d898c8cd83432d2b4c12bd93fa \ No newline at end of file +20caf80cb3b65e69a99dbc142db8ee435fb2dbdc \ No newline at end of file From a9e3fc05f58a055ffdb67dca2a8215efb698a955 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 27 Sep 2012 23:27:23 +0000 Subject: [PATCH 60/60] Fix some corner case behavior in the new ORDER BY optimization logic. Remove the SQLITE_OrderByIdx bit from the SQLITE_TESTCTRL_OPTIMIZATIONS mask, since enabling it caused many TH3 tests to fail when the NO_OPT configuration parameter was engaged, and since there really isn't any need to turn that optimization off. The SQLITE_OrderByIdxJoin bit remains. FossilOrigin-Name: 98b633717a1c9a08f6a1d00bc6bc891564ae7e9b --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/sqliteInt.h | 7 +++---- src/test1.c | 1 - src/where.c | 4 ++-- test/collate4.test | 2 +- test/where.test | 2 +- 7 files changed, 18 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 1b05b5bd9b..5624000edc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\stest\scases\san\sbug\sfixes\sfor\sthe\sORDER\sBY\soptimization\sof\sjoins.\s\sAll\nveryquick\stests\snow\spass. -D 2012-09-27T19:53:38.142 +C Fix\ssome\scorner\scase\sbehavior\sin\sthe\snew\sORDER\sBY\soptimization\slogic.\nRemove\sthe\sSQLITE_OrderByIdx\sbit\sfrom\sthe\s\nSQLITE_TESTCTRL_OPTIMIZATIONS\smask,\ssince\senabling\sit\scaused\smany\nTH3\stests\sto\sfail\swhen\sthe\sNO_OPT\sconfiguration\sparameter\swas\sengaged,\nand\ssince\sthere\sreally\sisn't\sany\sneed\sto\sturn\sthat\soptimization\soff.\nThe\sSQLITE_OrderByIdxJoin\sbit\sremains. +D 2012-09-27T23:27:23.679 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -179,12 +179,12 @@ F src/shell.c 8ee5a3cb502e2d574f97b43972e6c1e275e7bec7 F src/sqlite.h.in cbe846facaba903654b4136c97e7f57b3ac0bac7 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h 6ad55f4efbd1bb209711032e40b7c81c8855d634 +F src/sqliteInt.h c29395d6e68cfbcb2661787ae4820e5e256c916a F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/tclsqlite.c e4de2458b3ef38fdd0498bc4e5ea5367a241b0f3 -F src/test1.c 9000293bfdcd67de05bf91d257343392c4b194f4 +F src/test1.c 0354b555639c92d2a63c0ad4e74ed152ba47e604 F src/test2.c 4178056dd1e7d70f954ad8a1e3edb71a2a784daf F src/test3.c 3c3c2407fa6ec7a19e24ae23f7cb439d0275a60d F src/test4.c bf9fa9bece01de08e6f5e02314e4af5c13590dfa @@ -249,7 +249,7 @@ F src/vtab.c d8020c0a0e8ccc490ca449d7e665311b6e9f3ba9 F src/wal.c 5acb3e7bbd31f10ba39acad9ce6b399055337a9d F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b -F src/where.c cd047c1223f6364f869d44b7d3941a687de7fcb6 +F src/where.c d836df3a2096c41c39e48ab5636f09f94ba02676 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 0be144b453e0622a085fae8665c32f5676708e00 @@ -324,7 +324,7 @@ F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91 F test/collate1.test e3eaa48c21e150814be1a7b852d2a8af24458d04 F test/collate2.test 04cebe4a033be319d6ddbb3bbc69464e01700b49 F test/collate3.test d28d2cfab2c3a3d4628ae4b2b7afc9965daa3b4c -F test/collate4.test 27adc324b58ec367bdd0bc6baab628af5129e9f1 +F test/collate4.test d37682293d3c32223dec2e6afdeaf9de18415248 F test/collate5.test 65d928034d30d2d263a80f6359f7549ee1598ec6 F test/collate6.test 8be65a182abaac8011a622131486dafb8076e907 F test/collate7.test 8ec29d98f3ee4ccebce6e16ce3863fb6b8c7b868 @@ -955,7 +955,7 @@ F test/walro.test a31deb621033442a76c3a61e44929250d06f81b1 F test/walshared.test 6dda2293880c300baf5d791c307f653094585761 F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e -F test/where.test ea9659ff6e31681d0cdaf964747139cb10808200 +F test/where.test a6bfb5a29286811d798d326a8f1153a58c0fb2bd F test/where2.test 43d4becaf5a5df854e6c21d624a1cb84c6904554 F test/where3.test 667e75642102c97a00bf9b23d3cb267db321d006 F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2 @@ -1017,7 +1017,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P 75cda864ededb6dc0f84bd52ed3311753a58e351 -R 2ac4d1c44b199e10f1d07ecdc3868045 +P 0d573320057b0903a5589cabfb1b1ece1c57958e +R 346b48b15f539e2a05bf762bef6378fa U drh -Z 9df007fa9fa34b8089a8009c6ca9320b +Z 489ee88372e320839eda2ae45521e844 diff --git a/manifest.uuid b/manifest.uuid index f52b6aaffd..2b03b066ba 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0d573320057b0903a5589cabfb1b1ece1c57958e \ No newline at end of file +98b633717a1c9a08f6a1d00bc6bc891564ae7e9b \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 4501c737f3..a03b7ac1e7 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -827,7 +827,7 @@ struct sqlite3 { unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ int errCode; /* Most recent error code (SQLITE_*) */ int errMask; /* & result codes with this before returning */ - u16 dbOptFlags; /* Flags to enable/disable optimizations */ + u8 dbOptFlags; /* Flags to enable/disable optimizations */ u8 autoCommit; /* The auto-commit flag. */ u8 temp_store; /* 1: file 2: memory 0: default */ u8 mallocFailed; /* True if we have seen a malloc failure */ @@ -971,9 +971,8 @@ struct sqlite3 { #define SQLITE_IdxRealAsInt 0x0010 /* Store REAL as INT in indices */ #define SQLITE_DistinctOpt 0x0020 /* DISTINCT using indexes */ #define SQLITE_CoverIdxScan 0x0040 /* Covering index scans */ -#define SQLITE_OrderByIdx 0x0180 /* ORDER BY using indices */ -#define SQLITE_OrderByIdxJoin 0x0100 /* ORDER BY of joins via index */ -#define SQLITE_AllOpts 0x01ff /* All optimizations */ +#define SQLITE_OrderByIdxJoin 0x0080 /* ORDER BY of joins via index */ +#define SQLITE_AllOpts 0x00ff /* All optimizations */ /* ** Macros for testing whether or not optimizations are enabled or disabled. diff --git a/src/test1.c b/src/test1.c index 45ca124bb2..3d2fb02034 100644 --- a/src/test1.c +++ b/src/test1.c @@ -5941,7 +5941,6 @@ static int optimization_control( { "real-as-int", SQLITE_IdxRealAsInt }, { "distinct-opt", SQLITE_DistinctOpt }, { "cover-idx-scan", SQLITE_CoverIdxScan }, - { "order-by-idx", SQLITE_OrderByIdx }, { "order-by-idx-join",SQLITE_OrderByIdxJoin }, }; diff --git a/src/where.c b/src/where.c index 9bdcd536c4..7f386289c6 100644 --- a/src/where.c +++ b/src/where.c @@ -1647,7 +1647,6 @@ static int isSortingIndex( int seenRowid = 0; /* True if an ORDER BY rowid term is seen */ int nEqOneRow; /* Idx columns that ref unique values */ - if( OptimizationDisabled(db, SQLITE_OrderByIdx) ) return 0; if( p->i==0 ){ nPriorSat = 0; nEqOneRow = nEqCol; @@ -3154,6 +3153,7 @@ static void bestBtreeIndex(WhereBestIdx *p){ } }else if( pTerm->eOperator & WO_ISNULL ){ wsFlags |= WHERE_COLUMN_NULL; + if( nEq==nOrdered ) nOrdered++; }else if( bSort && nEq==nOrdered && isOrderedTerm(p, pTerm, &bRev) ){ nOrdered++; } @@ -3216,7 +3216,7 @@ static void bestBtreeIndex(WhereBestIdx *p){ bSort = 0; wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_ORDERBY; } - if( bRev ) wsFlags |= WHERE_REVERSE; + if( bRev & 1 ) wsFlags |= WHERE_REVERSE; } /* If there is a DISTINCT qualifier and this index will scan rows in diff --git a/test/collate4.test b/test/collate4.test index 1cf8caf04c..6b3a1c7aee 100644 --- a/test/collate4.test +++ b/test/collate4.test @@ -389,7 +389,7 @@ ifcapable subquery { SELECT a FROM collate4t1 WHERE a IN (SELECT * FROM collate4t2) ORDER BY rowid } - } {a A 5} + } {a A 6} do_test collate4-2.1.8 { count { SELECT a FROM collate4t1 WHERE a IN ('z', 'a'); diff --git a/test/where.test b/test/where.test index e57722c430..83fec2cf60 100644 --- a/test/where.test +++ b/test/where.test @@ -383,7 +383,7 @@ ifcapable subquery { count { SELECT * FROM t1 WHERE w IN (-1,1,2,3) order by 1; } - } {1 0 4 2 1 9 3 1 16 13} + } {1 0 4 2 1 9 3 1 16 14} do_test where-5.4 { count { SELECT * FROM t1 WHERE w+0 IN (-1,1,2,3) order by 1;