From 62f560f805db23e0619740c730e737c9989e75ec Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 9 Jul 2021 13:52:01 +0000 Subject: [PATCH 01/49] Enhance the sqlite3_create_function() interfaces to assume a value of SQLITE_UTF8 is presented with a nonsense value for the preferred encoding. This is undocumented behavior added for robustness. FossilOrigin-Name: c1bb5cff527af6a97b025d646581c68ac9b56924ae199f86964026a7bc9724fd --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/main.c | 37 ++++++++++++++++++++++++------------- 3 files changed, 32 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 5254c5394e..634c8b0085 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\susual\s"#ifdef\s__cplusplus"\smagic\sto\sheader\sfile\sext/misc/carray.h.\sAlso\supdate\scarray.h/carray.c\sto\suse\sSQLITE_API\sin\sthe\susual\sway. -D 2021-07-09T11:52:53.967 +C Enhance\sthe\ssqlite3_create_function()\sinterfaces\sto\sassume\sa\svalue\sof\nSQLITE_UTF8\sis\spresented\swith\sa\snonsense\svalue\sfor\sthe\spreferred\sencoding.\nThis\sis\sundocumented\sbehavior\sadded\sfor\srobustness. +D 2021-07-09T13:52:01.084 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -508,7 +508,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c d560dc585c50e01b015cbf924c173de88f61c8c85b3d1adb9d4865b92fff2d72 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 0aa9e7f08e168e3874cb54984408e3976dafdf5616d511952c425b5ac088ea3e -F src/main.c aedd8596e4dbdedacbf69fc4ff0462404effb9e6528146a1fdf4adee004053c9 +F src/main.c 6df43445e0c0c45642aff43726c0b2d42fcbb73c0c5a1e805c3b5b3c9b4eb106 F src/malloc.c cbc93cdd429c4594912017d92ab656e2579aca64dbd1c6888551275bed46f25b F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P eb8af9a494fb68c0a1c600b3ac71467645b51b296fc6e2116d7d855319d59a59 -R 4921ff9c6662da771dcaa161286cae4d -U dan -Z a202a1f73cdb865aaa148dd68fbda945 +P 0f97c2a459bfadc2fe19e710e8845039b4434010656d311074b9594b02d0826a +R 7868302cf3bc690aec9205f019a549f7 +U drh +Z f8eef76cb448b8627630bf5bdf905136 diff --git a/manifest.uuid b/manifest.uuid index ff5ad7c1a3..cd3ae0f9ee 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0f97c2a459bfadc2fe19e710e8845039b4434010656d311074b9594b02d0826a \ No newline at end of file +c1bb5cff527af6a97b025d646581c68ac9b56924ae199f86964026a7bc9724fd \ No newline at end of file diff --git a/src/main.c b/src/main.c index e2ebb1ef2f..ca796b12c7 100644 --- a/src/main.c +++ b/src/main.c @@ -1854,22 +1854,33 @@ int sqlite3CreateFunc( ** If SQLITE_ANY is specified, add three versions of the function ** to the hash table. */ - if( enc==SQLITE_UTF16 ){ - enc = SQLITE_UTF16NATIVE; - }else if( enc==SQLITE_ANY ){ - int rc; - rc = sqlite3CreateFunc(db, zFunctionName, nArg, - (SQLITE_UTF8|extraFlags)^SQLITE_FUNC_UNSAFE, - pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor); - if( rc==SQLITE_OK ){ + switch( enc ){ + case SQLITE_UTF16: + enc = SQLITE_UTF16NATIVE; + break; + case SQLITE_ANY: { + int rc; rc = sqlite3CreateFunc(db, zFunctionName, nArg, - (SQLITE_UTF16LE|extraFlags)^SQLITE_FUNC_UNSAFE, + (SQLITE_UTF8|extraFlags)^SQLITE_FUNC_UNSAFE, pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor); + if( rc==SQLITE_OK ){ + rc = sqlite3CreateFunc(db, zFunctionName, nArg, + (SQLITE_UTF16LE|extraFlags)^SQLITE_FUNC_UNSAFE, + pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor); + } + if( rc!=SQLITE_OK ){ + return rc; + } + enc = SQLITE_UTF16BE; + break; } - if( rc!=SQLITE_OK ){ - return rc; - } - enc = SQLITE_UTF16BE; + case SQLITE_UTF8: + case SQLITE_UTF16LE: + case SQLITE_UTF16BE: + break; + default: + enc = SQLITE_UTF8; + break; } #else enc = SQLITE_UTF8; From 8eed58478677dd9f61920af4df97e86d1b789552 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 9 Jul 2021 14:59:12 +0000 Subject: [PATCH 02/49] Fix an assert() that might fail if sqlite3_create_function_v2() is invoked with NULL xStep and xFinal callbacks and a non-NULL xDestroy. FossilOrigin-Name: ab1550a608684b6b9104b555a975482cfabca5053b7d7dcc60d63a0e3a8d707d --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/main.c | 2 +- test/func3.test | 8 ++++++++ 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 634c8b0085..50089e82aa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\ssqlite3_create_function()\sinterfaces\sto\sassume\sa\svalue\sof\nSQLITE_UTF8\sis\spresented\swith\sa\snonsense\svalue\sfor\sthe\spreferred\sencoding.\nThis\sis\sundocumented\sbehavior\sadded\sfor\srobustness. -D 2021-07-09T13:52:01.084 +C Fix\san\sassert()\sthat\smight\sfail\sif\ssqlite3_create_function_v2()\sis\sinvoked\swith\sNULL\sxStep\sand\sxFinal\scallbacks\sand\sa\snon-NULL\sxDestroy. +D 2021-07-09T14:59:12.343 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -508,7 +508,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c d560dc585c50e01b015cbf924c173de88f61c8c85b3d1adb9d4865b92fff2d72 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 0aa9e7f08e168e3874cb54984408e3976dafdf5616d511952c425b5ac088ea3e -F src/main.c 6df43445e0c0c45642aff43726c0b2d42fcbb73c0c5a1e805c3b5b3c9b4eb106 +F src/main.c 5d024b9b96d9c6809e66b7f4864c3745bc8caf2a6af3b27dc0f05328f4439dfd F src/malloc.c cbc93cdd429c4594912017d92ab656e2579aca64dbd1c6888551275bed46f25b F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -1037,7 +1037,7 @@ F test/fts4upfrom.test f25835162c989dffd5e2ef91ec24c4848cc9973093e2d492d1c7b32af F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d F test/func.test 77f6ea02c97d9ea64074461d347276a75df22d2cf51045a40f90857569e985f0 F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f -F test/func3.test 2bb0f31ab7baaed690b962a88544d7be6b34fa389364bc36a44e441ed3e3f1e6 +F test/func3.test 600a632c305a88f3946d38f9a51efe145c989b2e13bd2b2a488db47fe76bab6a F test/func4.test 2285fb5792d593fef442358763f0fd9de806eda47dbc7a5934df57ffdc484c31 F test/func5.test 863e6d1bd0013d09c17236f8a13ea34008dd857d87d85a13a673960e4c25d82a F test/func6.test 90e42b64c4f9fb6f04f44cb8a1da586c8542502e926b19c76504fe74ff2a9b7c @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0f97c2a459bfadc2fe19e710e8845039b4434010656d311074b9594b02d0826a -R 7868302cf3bc690aec9205f019a549f7 -U drh -Z f8eef76cb448b8627630bf5bdf905136 +P c1bb5cff527af6a97b025d646581c68ac9b56924ae199f86964026a7bc9724fd +R 2f585f1a71d6f5a7312cf10f6b97e250 +U dan +Z 417b62b479932df1736f5199ded86ec1 diff --git a/manifest.uuid b/manifest.uuid index cd3ae0f9ee..1f814b7629 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c1bb5cff527af6a97b025d646581c68ac9b56924ae199f86964026a7bc9724fd \ No newline at end of file +ab1550a608684b6b9104b555a975482cfabca5053b7d7dcc60d63a0e3a8d707d \ No newline at end of file diff --git a/src/main.c b/src/main.c index ca796b12c7..fc0fa6ad16 100644 --- a/src/main.c +++ b/src/main.c @@ -1977,7 +1977,7 @@ static int createFunctionApi( xSFunc, xStep, xFinal, xValue, xInverse, pArg ); if( pArg && pArg->nRef==0 ){ - assert( rc!=SQLITE_OK ); + assert( rc!=SQLITE_OK || (xStep==0 && xFinal==0) ); xDestroy(p); sqlite3_free(pArg); } diff --git a/test/func3.test b/test/func3.test index a535bae7b9..0221a0dfd6 100644 --- a/test/func3.test +++ b/test/func3.test @@ -198,6 +198,14 @@ do_test func3-5.59 { } [db eval {EXPLAIN SELECT min(1.0+'2.0',4*11)}] +# Test the outcome of specifying NULL xStep and xFinal pointers (normally +# used to delete any existing function) and a non-NULL xDestroy when there +# is no existing function to destroy. +# +do_test func3-6.0 { + sqlite3_create_function_v2 db nofunc 1 utf8 +} {} + finish_test From a73c306065e0a31d972e94cfbb1b3246a125a057 Mon Sep 17 00:00:00 2001 From: larrybr Date: Fri, 9 Jul 2021 23:12:42 +0000 Subject: [PATCH 03/49] Clarify comment on sqlite3.h's interface decaration macros. FossilOrigin-Name: 7cb09aef49c0b98c0c5e332d953a2eeb71ae9e243b1e37ab1c8ed4af15d46f50 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 4 +++- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 50089e82aa..a354ffea57 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sassert()\sthat\smight\sfail\sif\ssqlite3_create_function_v2()\sis\sinvoked\swith\sNULL\sxStep\sand\sxFinal\scallbacks\sand\sa\snon-NULL\sxDestroy. -D 2021-07-09T14:59:12.343 +C Clarify\scomment\son\ssqlite3.h's\sinterface\sdecaration\smacros. +D 2021-07-09T23:12:42.486 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -546,7 +546,7 @@ F src/resolve.c b379c5ffe3b692e9c64fa37817cc0efa204b7c9468a818309dde85fd132d9d81 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 1c1230aaa4e5979edd3c5a9f7a90ab856a302cca4962e8a7d08f42dd2e7e1a49 F src/shell.c.in 856de2945bb7fdfdeebe7136cf1b59d24618845aa5e5f3937fda7ff37c623b51 -F src/sqlite.h.in ecf5aa981da30c33da3e9f353bf3ebf055d3c380c80d6a4f954e58d18ccd6df1 +F src/sqlite.h.in 8ddae2ca8a31132336c385cd7b938fbcadf5ed57873dbe529d3c75d28241685b F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510 F src/sqliteInt.h 129619232aa632fa85db7792bfe4b378ed28d3361bf9cbcdb4522353fd04b89b @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c1bb5cff527af6a97b025d646581c68ac9b56924ae199f86964026a7bc9724fd -R 2f585f1a71d6f5a7312cf10f6b97e250 -U dan -Z 417b62b479932df1736f5199ded86ec1 +P ab1550a608684b6b9104b555a975482cfabca5053b7d7dcc60d63a0e3a8d707d +R ccb396cfbaef0a2b4107a89e839d38ef +U larrybr +Z 05b6e9c94023ac4e996b4a1256a4c2d0 diff --git a/manifest.uuid b/manifest.uuid index 1f814b7629..44b147f611 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ab1550a608684b6b9104b555a975482cfabca5053b7d7dcc60d63a0e3a8d707d \ No newline at end of file +7cb09aef49c0b98c0c5e332d953a2eeb71ae9e243b1e37ab1c8ed4af15d46f50 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index cad89b37b1..cdf9e5c0d0 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -43,7 +43,9 @@ extern "C" { /* -** Provide the ability to override linkage features of the interface. +** Facilitate override of interface linkage and calling conventions. +** Be aware that some or many of these next few defined macros may +** not be used within this particular translation of sqlite.h.in . */ #ifndef SQLITE_EXTERN # define SQLITE_EXTERN extern From 4b1c3eb5f9a5b8d4c709d17d7eeadc40e97b7d2a Mon Sep 17 00:00:00 2001 From: larrybr Date: Tue, 13 Jul 2021 01:45:04 +0000 Subject: [PATCH 04/49] Amalgamation has #line directives by default. Minor mksqlite3c.tcl changes FossilOrigin-Name: ba3eff71973064cbc0ddf51aa822a246c162bbb65387e9523692c60e5340acda --- Makefile.in | 3 +- configure | 22 ++++++++++++++ manifest | 19 +++++++----- manifest.uuid | 2 +- tool/mksqlite3c.tcl | 74 ++++++++++++++++++++++----------------------- 5 files changed, 72 insertions(+), 48 deletions(-) diff --git a/Makefile.in b/Makefile.in index 2795ffa9e8..d04d81c164 100644 --- a/Makefile.in +++ b/Makefile.in @@ -165,6 +165,7 @@ LTINSTALL = $(LIBTOOL) --mode=install $(INSTALL) ############################################################################### USE_AMALGAMATION = @USE_AMALGAMATION@ +AMALGAMATION_LINE_TAGS = @AMALGAMATION_LINE_TAGS@ # Object files for the SQLite library (non-amalgamation). # @@ -756,7 +757,7 @@ mptest: mptester$(TEXE) touch .target_source sqlite3.c: .target_source $(TOP)/tool/mksqlite3c.tcl - $(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl + $(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_LINE_TAGS) cp tsrc/sqlite3ext.h . cp $(TOP)/ext/session/sqlite3session.h . diff --git a/configure b/configure index 542ee5a1fe..52d8a120b2 100755 --- a/configure +++ b/configure @@ -774,6 +774,7 @@ USE_GCOV OPT_FEATURE_FLAGS HAVE_ZLIB USE_AMALGAMATION +AMALGAMATION_LINE_TAGS TARGET_DEBUG TARGET_HAVE_EDITLINE TARGET_HAVE_READLINE @@ -902,6 +903,7 @@ with_readline_lib with_readline_inc enable_debug enable_amalgamation +amalgamation_line_tags enable_load_extension enable_math enable_all @@ -10305,6 +10307,13 @@ done # USE_AMALGAMATION=1 +######### +# By default, amalgamation sqlite3.c will have #line directives. +# This is a build option not shown by ./configure --help +# To control it, use configure option: amalgamation_line_tags=? +# where ? is no to suppress #line directives or yes to create them. +AMALGAMATION_LINE_TAGS=--linemacros=1 + ######### # See whether we can run specific tclsh versions known to work well; # if not, then we fall back to plain tclsh. @@ -11275,6 +11284,19 @@ if test "${enable_amalgamation}" = "no" ; then USE_AMALGAMATION=0 fi +######## +# See whether --disable +if test "${amalgamation_line_tags+set}" = set; then : + enableval=$amalgamation_line_tags; +fi + +if test "${amalgamation_line_tags}" = "yes" ; then + AMALGAMATION_LINE_TAGS=--linemacros=1 +fi +if test "${amalgamation_line_tags}" = "no" ; then + AMALGAMATION_LINE_TAGS=--linemacros=0 +fi + ######### # Look for zlib. Only needed by extensions and by the sqlite3.exe shell diff --git a/manifest b/manifest index a354ffea57..6b80d1d47c 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Clarify\scomment\son\ssqlite3.h's\sinterface\sdecaration\smacros. -D 2021-07-09T23:12:42.486 +C Amalgamation\shas\s#line\sdirectives\sby\sdefault.\sMinor\smksqlite3c.tcl\schanges +D 2021-07-13T01:45:04.109 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in ff5ac24ec9cb700135ee4453fa14c18ea371e94250d3673bda1f2cb56e1108ce +F Makefile.in 31b3f386d47577c610dedf116aa5deab039c749d36b7735e9bc01a6f31c90f2b F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241 F Makefile.msc 8285e1ea7264f32b08702866d69dd127c0f663bbc2002323d853c68c27c6b6e4 F README.md 27fb76aa7eb57ed63a53bbba7292b6bf71f51125554f79f16b5d040edd1e6110 @@ -34,7 +34,7 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6 F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559 -F configure 9712ea724ff2a1d48fadcf04b29fa1852f325792462c55f4fc71ab972653b20d x +F configure 0c8ec49c8c57e549748fd3c9df50f997272649fdba3be5b91ebf9f2546856157 x F configure.ac 4e4b58b32f88c8da9914a2f2c3158f80e69907eccc019fcc7e3ba14ffd91c640 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd @@ -1858,7 +1858,7 @@ F tool/mkshellc.tcl 5fe7e518112b262e25726f248c0f33dd153192867453984b6af0a76a88e9 F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f -F tool/mksqlite3c.tcl b4a930a4c3f8f43273cde45a459eb8881479be3c2845526c92b2513a4995aab8 +F tool/mksqlite3c.tcl bfbdf3661d82a9d5913a52dfa8d78b2a069a8af1a4b457162609bd6b55700de0 F tool/mksqlite3h.tcl 1f5e4a1dbbbc43c83cc6e74fe32c6c620502240b66c7c0f33a51378e78fc4edf F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5 @@ -1920,7 +1920,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ab1550a608684b6b9104b555a975482cfabca5053b7d7dcc60d63a0e3a8d707d -R ccb396cfbaef0a2b4107a89e839d38ef +P 7cb09aef49c0b98c0c5e332d953a2eeb71ae9e243b1e37ab1c8ed4af15d46f50 +R 6df1eb2d72698e3e5d1e65e62fb29077 +T *branch * line_tags +T *sym-line_tags * +T -sym-trunk * U larrybr -Z 05b6e9c94023ac4e996b4a1256a4c2d0 +Z 26f306c76e23d1272de3ca395f0d82ae diff --git a/manifest.uuid b/manifest.uuid index 44b147f611..84b3831a8c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7cb09aef49c0b98c0c5e332d953a2eeb71ae9e243b1e37ab1c8ed4af15d46f50 \ No newline at end of file +ba3eff71973064cbc0ddf51aa822a246c162bbb65387e9523692c60e5340acda \ No newline at end of file diff --git a/tool/mksqlite3c.tcl b/tool/mksqlite3c.tcl index 054e0fd1b9..ad2488d83f 100644 --- a/tool/mksqlite3c.tcl +++ b/tool/mksqlite3c.tcl @@ -17,31 +17,52 @@ # After the "tsrc" directory has been created and populated, run # this script: # -# tclsh mksqlite3c.tcl --srcdir $SRC +# tclsh mksqlite3c.tcl # # The amalgamated SQLite code will be written into sqlite3.c # +set help {Usage: tclsh mksqlite3c.tcl + where is zero or more of the following with these effects: + --nostatic => Do not generate with compile-time modifiable linkage. + --linemacros=? => Insert #line directives into the output or not. (1 or 0) + --useapicall => Prepend functions with SQLITE_APICALL or SQLITE_CDECL. + --srcdir $SRC => Specify the directory containing constituent sources. + --help => See this. +} + # Begin by reading the "sqlite3.h" header file. Extract the version number # from in this file. The version number is needed to generate the header # comment of the amalgamation. # + set addstatic 1 -set linemacros 0 +set linemacros 1 set useapicall 0 +set srcdir tsrc + for {set i 0} {$i<[llength $argv]} {incr i} { set x [lindex $argv $i] - if {[regexp {^-+nostatic$} $x]} { + if {[regexp {^-?-nostatic$} $x]} { set addstatic 0 - } elseif {[regexp {^-+linemacros} $x]} { - set linemacros 1 - } elseif {[regexp {^-+useapicall} $x]} { + } elseif {[regexp {^-?-linemacros=([01])$} $x ma ulm]} { + set linemacros $ulm + } elseif {[regexp {^-?-useapicall$} $x]} { set useapicall 1 + } elseif {[regexp {^-?-srcdir$} $x]} { + incr i + if {$i==[llength $argv]} { + error "No argument following $x" + } + set srcdir [lindex $argv $i] + } elseif {[regexp {^-?-((help)|\?)$} $x]} { + puts $help + exit 0 } else { error "unknown command-line option: $x" } } -set in [open tsrc/sqlite3.h] +set in [open $srcdir/sqlite3.h] set cnt 0 set VERSION ????? while {![eof $in]} { @@ -94,7 +115,7 @@ if {$addstatic} { # # then set the SQLITE_UDL_CAPABLE_PARSER flag in the amalgamation. # -set in [open tsrc/parse.c] +set in [open $srcdir/parse.c] if {[regexp {ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT} [read $in]]} { puts $out "#define SQLITE_UDL_CAPABLE_PARSER 1" } @@ -182,7 +203,7 @@ proc section_comment {text} { # proc copy_file {filename} { global seen_hdr available_hdr varonly_hdr cdecllist out - global addstatic linemacros useapicall + global addstatic linemacros useapicall srcdir set ln 0 set tail [file tail $filename] section_comment "Begin file $tail" @@ -204,7 +225,7 @@ proc copy_file {filename} { set available_hdr($hdr) 0 } section_comment "Include $hdr in the middle of $tail" - copy_file tsrc/$hdr + copy_file $srcdir/$hdr section_comment "Continuing where we left off in $tail" if {$linemacros} {puts $out "#line [expr {$ln+1}] \"$filename\""} } else { @@ -255,7 +276,7 @@ proc copy_file {filename} { } } append line $funcname $rest - if {$funcname=="sqlite3_sourceid" && !$linemacros} { + if {$funcname=="sqlite3_sourceid"} { # The sqlite3_sourceid() routine is synthesized at the end of # the amalgamation puts $out "/* $line */" @@ -417,36 +438,13 @@ foreach file { fts5.c stmt.c } { - copy_file tsrc/$file + copy_file $srcdir/$file } -# Synthesize an alternative sqlite3_sourceid() implementation that -# that tries to detects changes in the amalgamation source text -# and modify returns a modified source-id if changes are detected. -# -# The only detection mechanism we have is the __LINE__ macro. So only -# edits that changes the number of lines of source code are detected. -# -if {!$linemacros} { - flush $out - set in2 [open sqlite3.c] - set cnt 0 - set oldsrcid {} - while {![eof $in2]} { - incr cnt - gets $in2 line - if {[regexp {^#define SQLITE_SOURCE_ID } $line]} {set oldsrcid $line} - } - close $in2 - regsub {[0-9a-flt]{4}"} $oldsrcid {alt2"} oldsrcid - puts $out \ -"#if __LINE__!=[expr {$cnt+0}] -#undef SQLITE_SOURCE_ID -$oldsrcid -#endif -/* Return the source-id for this library */ +puts $out \ +"/* Return the source-id for this library */ SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }" -} + puts $out \ "/************************** End of sqlite3.c ******************************/" From f1cacb76b74a9e1f207e21fa6f15cbb15d6ec9fa Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 13 Jul 2021 11:30:46 +0000 Subject: [PATCH 05/49] Do not attempt to run Tcl sessions tests unless both SQLITE_ENABLE_PREUPDATE_HOOK and SQLITE_ENABLE_SESSIONS are defined. FossilOrigin-Name: 385db794477e046b5dde726489375786d7565b113084f6e730efb050b08f9a6e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/test_config.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index a354ffea57..0657e74438 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Clarify\scomment\son\ssqlite3.h's\sinterface\sdecaration\smacros. -D 2021-07-09T23:12:42.486 +C Do\snot\sattempt\sto\srun\sTcl\ssessions\stests\sunless\sboth\sSQLITE_ENABLE_PREUPDATE_HOOK\sand\sSQLITE_ENABLE_SESSIONS\sare\sdefined. +D 2021-07-13T11:30:46.013 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -569,7 +569,7 @@ F src/test_backup.c bf5da90c9926df0a4b941f2d92825a01bbe090a0 F src/test_bestindex.c 78809f11026f18a93fcfd798d9479cba37e1201c830260bf1edc674b2fa9b857 F src/test_blob.c ae4a0620b478548afb67963095a7417cd06a4ec0a56adb453542203bfdcb31ce F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274 -F src/test_config.c 9c8e12823c46082a01765addf43be9309889f4e9dfb5a512a6c974e1c4efb413 +F src/test_config.c 284c29912736f68b0a583a920bf63fd8f9125dffb8a75cb0676e58502b2f7908 F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f F src/test_demovfs.c 86142ba864d4297d54c5b2e972e74f3141ae4b30f05b3a95824184ed2d3d7f91 F src/test_devsym.c aff2255ea290d7718da08af30cdf18e470ff7325a5eff63e0057b1496ed66593 @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ab1550a608684b6b9104b555a975482cfabca5053b7d7dcc60d63a0e3a8d707d -R ccb396cfbaef0a2b4107a89e839d38ef -U larrybr -Z 05b6e9c94023ac4e996b4a1256a4c2d0 +P 7cb09aef49c0b98c0c5e332d953a2eeb71ae9e243b1e37ab1c8ed4af15d46f50 +R ffe5fcedbe611fc5d143174623ac9c96 +U dan +Z 4dfdb08b45660ff4713e22026b265656 diff --git a/manifest.uuid b/manifest.uuid index 44b147f611..713c3371de 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7cb09aef49c0b98c0c5e332d953a2eeb71ae9e243b1e37ab1c8ed4af15d46f50 \ No newline at end of file +385db794477e046b5dde726489375786d7565b113084f6e730efb050b08f9a6e \ No newline at end of file diff --git a/src/test_config.c b/src/test_config.c index 86e4df38f7..acf98e36d8 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -589,7 +589,7 @@ Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY); Tcl_SetVar2(interp, "sqlite_options", "schema_version", "1", TCL_GLOBAL_ONLY); #endif -#ifdef SQLITE_ENABLE_SESSION +#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK) Tcl_SetVar2(interp, "sqlite_options", "session", "1", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "session", "0", TCL_GLOBAL_ONLY); From 06a0ea9a681338d5165703ec5eb6601301df56fb Mon Sep 17 00:00:00 2001 From: larrybr Date: Tue, 13 Jul 2021 20:55:26 +0000 Subject: [PATCH 06/49] Get correct #line tags into amalgamation for other builds too. FossilOrigin-Name: 999eb80018f1bb8a8ad73483610400faf5fb37b1be446ce30edbf7028340f50b --- Makefile.msc | 11 ++++++----- main.mk | 3 ++- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 4f20c0c0c1..2b369d7b09 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -235,8 +235,9 @@ DEBUG = 0 !ENDIF # <> -# Disable use of the --linemacros argument to the mksqlite3c.tcl tool, which -# is used to build the amalgamation. +# By default, use --line_tags=1 argument to the mksqlite3c.tcl tool, which +# is used to build the amalgamation. This can be turned off to ease debug +# of the amalgamation away from the source tree. # !IFNDEF NO_LINEMACROS NO_LINEMACROS = 0 @@ -787,10 +788,10 @@ MKSQLITE3C_TOOL = $(TOP)\tool\mksqlite3c.tcl !ENDIF !IFNDEF MKSQLITE3C_ARGS -!IF $(DEBUG)>1 && $(NO_LINEMACROS)==0 -MKSQLITE3C_ARGS = --linemacros +!IF $(NO_LINEMACROS)==0 +MKSQLITE3C_ARGS = --line_tags=1 !ELSE -MKSQLITE3C_ARGS = +MKSQLITE3C_ARGS = --line_tags=0 !ENDIF !IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0 MKSQLITE3C_ARGS = $(MKSQLITE3C_ARGS) --useapicall diff --git a/main.mk b/main.mk index 16d72ff924..152202cefc 100644 --- a/main.mk +++ b/main.mk @@ -1,3 +1,4 @@ + ############################################################################### # The following macros should be defined before this script is # invoked: @@ -663,7 +664,7 @@ sqlite3ext.h: target_source cp tsrc/sqlite3ext.h . sqlite3.c-debug: target_source $(TOP)/tool/mksqlite3c.tcl - tclsh $(TOP)/tool/mksqlite3c.tcl --linemacros + tclsh $(TOP)/tool/mksqlite3c.tcl --line_tags=1 echo '#ifndef USE_SYSTEM_SQLITE' >tclsqlite3.c cat sqlite3.c >>tclsqlite3.c echo '#endif /* USE_SYSTEM_SQLITE */' >>tclsqlite3.c diff --git a/manifest b/manifest index 935a4ad9f9..023e749344 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C Get\s#line\stags\sinto\samalgamation,\ssubject\sto\sconfigure. -D 2021-07-13T11:59:17.680 +C Get\scorrect\s#line\stags\sinto\samalgamation\sfor\sother\sbuilds\stoo. +D 2021-07-13T20:55:26.417 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F Makefile.in 31b3f386d47577c610dedf116aa5deab039c749d36b7735e9bc01a6f31c90f2b F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241 -F Makefile.msc 8285e1ea7264f32b08702866d69dd127c0f663bbc2002323d853c68c27c6b6e4 +F Makefile.msc a44ead80b4676506954d27c2de6a4d669153f2f7967dedf588b6d9c7c5f46edc F README.md 27fb76aa7eb57ed63a53bbba7292b6bf71f51125554f79f16b5d040edd1e6110 F VERSION c6595fef606851f2bc3ebed6a7386c73751835fc909feab7c093739fa4b3c1d1 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -466,7 +466,7 @@ F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk c0c95f0aa2e3b731eb0c5a85869d4d6abef91647ec8e87a4013059bd1b910c0a +F main.mk 6e3aceeb728ac72a6c265e24817166c4eb126e17cc49d419591b53372d9db817 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 385db794477e046b5dde726489375786d7565b113084f6e730efb050b08f9a6e 9327f73c1b87fb9ca78e261d16b092763f497bb9c6f9784a33eabdc961b06343 -R dbca2ff374fa12dc1b7d55e8c48721d1 +P 5d81b598a7cd2cea2553fdf6ca38d2f65f0f1b2d5a8eea8a01c1800f68aa2422 +R 8047cbd4c8070d900b13d435b1c9a26f U larrybr -Z 63da48257739363f6cf3cff556a25d79 +Z cd87850b5562004651d7c32e14873964 diff --git a/manifest.uuid b/manifest.uuid index 31c27e4dfb..bf85853f3f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5d81b598a7cd2cea2553fdf6ca38d2f65f0f1b2d5a8eea8a01c1800f68aa2422 \ No newline at end of file +999eb80018f1bb8a8ad73483610400faf5fb37b1be446ce30edbf7028340f50b \ No newline at end of file From 696555d7b5e7aa7468109901f73308461cb3ab9f Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 13 Jul 2021 21:59:22 +0000 Subject: [PATCH 07/49] Further revisions to #line handling for amalgamation builds. FossilOrigin-Name: 9a84321229ad499ee0f7c85732c2728afb4476c72073a510401a559dda9be38f --- Makefile.in | 4 ++-- Makefile.msc | 8 ++++---- configure | 20 ++++++++++---------- main.mk | 2 +- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- tool/mksqlite3c.tcl | 19 ++++++++++--------- 7 files changed, 39 insertions(+), 38 deletions(-) diff --git a/Makefile.in b/Makefile.in index d04d81c164..c771b5bada 100644 --- a/Makefile.in +++ b/Makefile.in @@ -165,7 +165,7 @@ LTINSTALL = $(LIBTOOL) --mode=install $(INSTALL) ############################################################################### USE_AMALGAMATION = @USE_AMALGAMATION@ -AMALGAMATION_LINE_TAGS = @AMALGAMATION_LINE_TAGS@ +AMALGAMATION_LINE_MACROS = @AMALGAMATION_LINE_MACROS@ # Object files for the SQLite library (non-amalgamation). # @@ -757,7 +757,7 @@ mptest: mptester$(TEXE) touch .target_source sqlite3.c: .target_source $(TOP)/tool/mksqlite3c.tcl - $(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_LINE_TAGS) + $(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_LINE_MACROS) cp tsrc/sqlite3ext.h . cp $(TOP)/ext/session/sqlite3session.h . diff --git a/Makefile.msc b/Makefile.msc index 2b369d7b09..7fd43055ec 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -235,7 +235,7 @@ DEBUG = 0 !ENDIF # <> -# By default, use --line_tags=1 argument to the mksqlite3c.tcl tool, which +# By default, use --linemacros=1 argument to the mksqlite3c.tcl tool, which # is used to build the amalgamation. This can be turned off to ease debug # of the amalgamation away from the source tree. # @@ -788,10 +788,10 @@ MKSQLITE3C_TOOL = $(TOP)\tool\mksqlite3c.tcl !ENDIF !IFNDEF MKSQLITE3C_ARGS -!IF $(NO_LINEMACROS)==0 -MKSQLITE3C_ARGS = --line_tags=1 +!IF $(DEBUG)>1 && $(NO_LINEMACROS)==0 +MKSQLITE3C_ARGS = --linemacros=1 !ELSE -MKSQLITE3C_ARGS = --line_tags=0 +MKSQLITE3C_ARGS = --linemacros=0 !ENDIF !IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0 MKSQLITE3C_ARGS = $(MKSQLITE3C_ARGS) --useapicall diff --git a/configure b/configure index 9ec5ed9005..30f3ed7de0 100755 --- a/configure +++ b/configure @@ -774,7 +774,7 @@ USE_GCOV OPT_FEATURE_FLAGS HAVE_ZLIB USE_AMALGAMATION -AMALGAMATION_LINE_TAGS +AMALGAMATION_LINE_MACROS TARGET_DEBUG TARGET_HAVE_EDITLINE TARGET_HAVE_READLINE @@ -903,7 +903,7 @@ with_readline_lib with_readline_inc enable_debug enable_amalgamation -amalgamation_line_tags +amalgamation_line_macros enable_load_extension enable_math enable_all @@ -10310,9 +10310,9 @@ USE_AMALGAMATION=1 ######### # By default, amalgamation sqlite3.c will have #line directives. # This is a build option not shown by ./configure --help -# To control it, use configure option: amalgamation_line_tags=? +# To control it, use configure option: amalgamation_line_macros=? # where ? is no to suppress #line directives or yes to create them. -AMALGAMATION_LINE_TAGS=--line_tags=1 +AMALGAMATION_LINE_MACROS=--linemacros=1 ######### # See whether we can run specific tclsh versions known to work well; @@ -11286,15 +11286,15 @@ fi ######## # See whether --disable -if test "${amalgamation_line_tags+set}" = set; then : - enableval=$amalgamation_line_tags; +if test "${amalgamation_line_macros+set}" = set; then : + enableval=$amalgamation_line_macros; fi -if test "${amalgamation_line_tags}" = "yes" ; then - AMALGAMATION_LINE_TAGS=--line_tags=1 +if test "${amalgamation_line_macros}" = "yes" ; then + AMALGAMATION_LINE_MACROS=--linemacros=1 fi -if test "${amalgamation_line_tags}" = "no" ; then - AMALGAMATION_LINE_TAGS=--line_tags=0 +if test "${amalgamation_line_macros}" = "no" ; then + AMALGAMATION_LINE_MACROS=--linemacros=0 fi diff --git a/main.mk b/main.mk index 152202cefc..64c25a5139 100644 --- a/main.mk +++ b/main.mk @@ -664,7 +664,7 @@ sqlite3ext.h: target_source cp tsrc/sqlite3ext.h . sqlite3.c-debug: target_source $(TOP)/tool/mksqlite3c.tcl - tclsh $(TOP)/tool/mksqlite3c.tcl --line_tags=1 + tclsh $(TOP)/tool/mksqlite3c.tcl --linemacros=1 echo '#ifndef USE_SYSTEM_SQLITE' >tclsqlite3.c cat sqlite3.c >>tclsqlite3.c echo '#endif /* USE_SYSTEM_SQLITE */' >>tclsqlite3.c diff --git a/manifest b/manifest index 023e749344..8d184cc0c8 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C Get\scorrect\s#line\stags\sinto\samalgamation\sfor\sother\sbuilds\stoo. -D 2021-07-13T20:55:26.417 +C Further\srevisions\sto\s#line\shandling\sfor\samalgamation\sbuilds. +D 2021-07-13T21:59:22.649 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 31b3f386d47577c610dedf116aa5deab039c749d36b7735e9bc01a6f31c90f2b +F Makefile.in 83c348515cb62f6f2a2ddf3fd014113ff20564b776e1a614079722c88c6ff43d F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241 -F Makefile.msc a44ead80b4676506954d27c2de6a4d669153f2f7967dedf588b6d9c7c5f46edc +F Makefile.msc d481375cd138e705f749dad2549b2f80d5d76e23132c5fc9be337f7416cb9fc8 F README.md 27fb76aa7eb57ed63a53bbba7292b6bf71f51125554f79f16b5d040edd1e6110 F VERSION c6595fef606851f2bc3ebed6a7386c73751835fc909feab7c093739fa4b3c1d1 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -34,7 +34,7 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6 F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559 -F configure 6d4409696c9f91a4a9108123ea52b97d8f2b4f056565e0a4ab62f899944f3acb x +F configure b392a2f2a44673f1e31a5bb266a08256a5bb1428e71fd8c6fbc90f60a88286fe x F configure.ac 4e4b58b32f88c8da9914a2f2c3158f80e69907eccc019fcc7e3ba14ffd91c640 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd @@ -466,7 +466,7 @@ F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 6e3aceeb728ac72a6c265e24817166c4eb126e17cc49d419591b53372d9db817 +F main.mk 200bf75c882c4822ea722840fc5212f22e5e18773851352c2a0d077958de8b7f F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -1858,7 +1858,7 @@ F tool/mkshellc.tcl 5fe7e518112b262e25726f248c0f33dd153192867453984b6af0a76a88e9 F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f -F tool/mksqlite3c.tcl e5d1c5b61f530e9307f7dc9c2880ebe5d0578cb3817d8223933f24ca8a74cc2d +F tool/mksqlite3c.tcl 8127f4c2b11078f9dc4956fa1401291b6d6dd81e41a4fd3f74a9710ab16a791c F tool/mksqlite3h.tcl 1f5e4a1dbbbc43c83cc6e74fe32c6c620502240b66c7c0f33a51378e78fc4edf F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5 @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5d81b598a7cd2cea2553fdf6ca38d2f65f0f1b2d5a8eea8a01c1800f68aa2422 -R 8047cbd4c8070d900b13d435b1c9a26f -U larrybr -Z cd87850b5562004651d7c32e14873964 +P 999eb80018f1bb8a8ad73483610400faf5fb37b1be446ce30edbf7028340f50b +R f35bd0cfcf360e047d19fadb646cae86 +U mistachkin +Z d52b02f968087a7fee10f230044f7d8b diff --git a/manifest.uuid b/manifest.uuid index bf85853f3f..176f226770 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -999eb80018f1bb8a8ad73483610400faf5fb37b1be446ce30edbf7028340f50b \ No newline at end of file +9a84321229ad499ee0f7c85732c2728afb4476c72073a510401a559dda9be38f \ No newline at end of file diff --git a/tool/mksqlite3c.tcl b/tool/mksqlite3c.tcl index afb9740d2b..863eeba801 100644 --- a/tool/mksqlite3c.tcl +++ b/tool/mksqlite3c.tcl @@ -25,11 +25,11 @@ set help {Usage: tclsh mksqlite3c.tcl where is zero or more of the following with these effects: --nostatic => Do not generate with compile-time modifiable linkage. - --line_tags=? => Emit #line directives into output or not. (? = 1 or 0) + --linemacros=? => Emit #line directives into output or not. (? = 1 or 0) --useapicall => Prepend functions with SQLITE_APICALL or SQLITE_CDECL. --srcdir $SRC => Specify the directory containing constituent sources. --help => See this. - The value setting options default to --line_tags=1 and '--srcdir tsrc' . + The value setting options default to --linemacros=1 and '--srcdir tsrc' . } # Begin by reading the "sqlite3.h" header file. Extract the version number @@ -38,7 +38,7 @@ set help {Usage: tclsh mksqlite3c.tcl # set addstatic 1 -set line_tags 1 +set linemacros 1 set useapicall 0 set srcdir tsrc @@ -46,8 +46,9 @@ for {set i 0} {$i<[llength $argv]} {incr i} { set x [lindex $argv $i] if {[regexp {^-?-nostatic$} $x]} { set addstatic 0 - } elseif {[regexp {^-?-line_tags=([01])$} $x ma ulm]} { - set line_tags $ulm + } elseif {[regexp {^-?-linemacros(?:=([01]))?$} $x ma ulm]} { + if {$ulm == ""} {set ulm 1} + set linemacros $ulm } elseif {[regexp {^-?-useapicall$} $x]} { set useapicall 1 } elseif {[regexp {^-?-srcdir$} $x]} { @@ -204,11 +205,11 @@ proc section_comment {text} { # proc copy_file {filename} { global seen_hdr available_hdr varonly_hdr cdecllist out - global addstatic line_tags useapicall srcdir + global addstatic linemacros useapicall srcdir set ln 0 set tail [file tail $filename] section_comment "Begin file $tail" - if {$line_tags} {puts $out "#line 1 \"$filename\""} + if {$linemacros} {puts $out "#line 1 \"$filename\""} set in [open $filename r] set varpattern {^[a-zA-Z][a-zA-Z_0-9 *]+(sqlite3[_a-zA-Z0-9]+)(\[|;| =)} set declpattern {([a-zA-Z][a-zA-Z_0-9 ]+ \**)(sqlite3[_a-zA-Z0-9]+)(\(.*)} @@ -228,7 +229,7 @@ proc copy_file {filename} { section_comment "Include $hdr in the middle of $tail" copy_file $srcdir/$hdr section_comment "Continuing where we left off in $tail" - if {$line_tags} {puts $out "#line [expr {$ln+1}] \"$filename\""} + if {$linemacros} {puts $out "#line [expr {$ln+1}] \"$filename\""} } else { # Comment out the entire line, replacing any nested comment # begin/end markers with the harmless substring "**". @@ -250,7 +251,7 @@ proc copy_file {filename} { } } elseif {[regexp {^#ifdef __cplusplus} $line]} { puts $out "#if 0" - } elseif {!$line_tags && [regexp {^#line} $line]} { + } elseif {!$linemacros && [regexp {^#line} $line]} { # Skip #line directives. } elseif {$addstatic && ![regexp {^(static|typedef|SQLITE_PRIVATE)} $line]} { From acae2b485ea7325c6031102f5ad58e9f282cb214 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 13 Jul 2021 22:49:02 +0000 Subject: [PATCH 08/49] Enhance comments pertaining to the interface linkage / calling convention macros. FossilOrigin-Name: c378e99250fe06fae8ca40c62185b607f004d6806e07dbb9f964dd849b4e55f8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 25 +++++++++++++++++++++++-- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 8d184cc0c8..218b1abbf1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\srevisions\sto\s#line\shandling\sfor\samalgamation\sbuilds. -D 2021-07-13T21:59:22.649 +C Enhance\scomments\spertaining\sto\sthe\sinterface\slinkage\s/\scalling\sconvention\smacros. +D 2021-07-13T22:49:02.204 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -546,7 +546,7 @@ F src/resolve.c b379c5ffe3b692e9c64fa37817cc0efa204b7c9468a818309dde85fd132d9d81 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 1c1230aaa4e5979edd3c5a9f7a90ab856a302cca4962e8a7d08f42dd2e7e1a49 F src/shell.c.in 856de2945bb7fdfdeebe7136cf1b59d24618845aa5e5f3937fda7ff37c623b51 -F src/sqlite.h.in 8ddae2ca8a31132336c385cd7b938fbcadf5ed57873dbe529d3c75d28241685b +F src/sqlite.h.in a5d5641afa335226231231c7b6e424de327f17577d9e8aeaaaab78d9bbbcf381 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510 F src/sqliteInt.h 129619232aa632fa85db7792bfe4b378ed28d3361bf9cbcdb4522353fd04b89b @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 999eb80018f1bb8a8ad73483610400faf5fb37b1be446ce30edbf7028340f50b -R f35bd0cfcf360e047d19fadb646cae86 +P 9a84321229ad499ee0f7c85732c2728afb4476c72073a510401a559dda9be38f +R 3789b43d6e6200974e3100b41a3c444f U mistachkin -Z d52b02f968087a7fee10f230044f7d8b +Z eb61d76fb75de1f468d1b3d6692793bb diff --git a/manifest.uuid b/manifest.uuid index 176f226770..f6b958ea40 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9a84321229ad499ee0f7c85732c2728afb4476c72073a510401a559dda9be38f \ No newline at end of file +c378e99250fe06fae8ca40c62185b607f004d6806e07dbb9f964dd849b4e55f8 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index cdf9e5c0d0..73c1adeae1 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -44,8 +44,29 @@ extern "C" { /* ** Facilitate override of interface linkage and calling conventions. -** Be aware that some or many of these next few defined macros may -** not be used within this particular translation of sqlite.h.in . +** Be aware that these macros may not be used within this particular +** translation of the amalgamation and its associated header file. +** +** The SQLITE_EXTERN and SQLITE_API macros are used to instruct the +** compiler that the target identifier should have external linkage. +** +** The SQLITE_CDECL macro is used to set the calling convention for +** public functions that accept a variable number of arguments. +** +** The SQLITE_APICALL macro is used to set the calling convention for +** public functions that accept a fixed number of arguments. +** +** The SQLITE_STDCALL macro is no longer used and is now deprecated. +** +** The SQLITE_CALLBACK macro is used to set the calling convention for +** function pointers. +** +** The SQLITE_SYSAPI macro is used to set the calling convention for +** functions provided by the operating system. +** +** Currently, the SQLITE_CDECL, SQLITE_APICALL, SQLITE_CALLBACK, and +** SQLITE_SYSAPI macros are used only when building for environments +** that require non-default calling conventions. */ #ifndef SQLITE_EXTERN # define SQLITE_EXTERN extern From 20235e56f71b38788dd2e113eebdc6d564ff1bbc Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 14 Jul 2021 21:18:31 +0000 Subject: [PATCH 09/49] Fix a use-after-free error in ioerr.test caused by an error in test code. FossilOrigin-Name: 1594056aab068b9fae82f6b885828c7127d9bedcc37c4340486e32791bc87c7a --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/tester.tcl | 32 +++++++++++++++++--------------- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index 218b1abbf1..8d6d4c6f24 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\scomments\spertaining\sto\sthe\sinterface\slinkage\s/\scalling\sconvention\smacros. -D 2021-07-13T22:49:02.204 +C Fix\sa\suse-after-free\serror\sin\sioerr.test\scaused\sby\san\serror\sin\stest\scode. +D 2021-07-14T21:18:31.520 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1454,7 +1454,7 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptable2.test d2940417496e2b9548e01d09990763fbe88c316504033256d51493e1f1a5ce6a F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc -F test/tester.tcl 19d2a19a6dd55a2b4e2b943963959a05a2c088495dd5f5274b04e0494ce86d66 +F test/tester.tcl 0b7957eb669371250008a5e1fef5902257905fd6d560e8834be1ac4a0620063a F test/thread001.test b61a29dd87cf669f5f6ac96124a7c97d71b0c80d9012746072055877055cf9ef F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9a84321229ad499ee0f7c85732c2728afb4476c72073a510401a559dda9be38f -R 3789b43d6e6200974e3100b41a3c444f -U mistachkin -Z eb61d76fb75de1f468d1b3d6692793bb +P c378e99250fe06fae8ca40c62185b607f004d6806e07dbb9f964dd849b4e55f8 +R 5dc9e7510bb681a9844c30d96bdfacf1 +U dan +Z ab55d4571a2b3927d12f63db9cd8ac86 diff --git a/manifest.uuid b/manifest.uuid index f6b958ea40..ca45e83989 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c378e99250fe06fae8ca40c62185b607f004d6806e07dbb9f964dd849b4e55f8 \ No newline at end of file +1594056aab068b9fae82f6b885828c7127d9bedcc37c4340486e32791bc87c7a \ No newline at end of file diff --git a/test/tester.tcl b/test/tester.tcl index 304808b6bc..d7dc21157a 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -1904,21 +1904,23 @@ proc do_ioerr_test {testname args} { set ::sqlite_io_error_hardhit 0 set r [catch $::ioerrorbody msg] set ::errseen $r - set rc [sqlite3_errcode $::DB] - if {$::ioerropts(-erc)} { - # If we are in extended result code mode, make sure all of the - # IOERRs we get back really do have their extended code values. - # If an extended result code is returned, the sqlite3_errcode - # TCLcommand will return a string of the form: SQLITE_IOERR+nnnn - # where nnnn is a number - if {[regexp {^SQLITE_IOERR} $rc] && ![regexp {IOERR\+\d} $rc]} { - return $rc - } - } else { - # If we are not in extended result code mode, make sure no - # extended error codes are returned. - if {[regexp {\+\d} $rc]} { - return $rc + if {[info commands db]!=""} { + set rc [sqlite3_errcode db] + if {$::ioerropts(-erc)} { + # If we are in extended result code mode, make sure all of the + # IOERRs we get back really do have their extended code values. + # If an extended result code is returned, the sqlite3_errcode + # TCLcommand will return a string of the form: SQLITE_IOERR+nnnn + # where nnnn is a number + if {[regexp {^SQLITE_IOERR} $rc] && ![regexp {IOERR\+\d} $rc]} { + return $rc + } + } else { + # If we are not in extended result code mode, make sure no + # extended error codes are returned. + if {[regexp {\+\d} $rc]} { + return $rc + } } } # The test repeats as long as $::go is non-zero. $::go starts out From 480f5e3e6e70e803b35ddeab947988a89b0163a0 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 15 Jul 2021 16:39:42 +0000 Subject: [PATCH 10/49] Change references to the schema table in sqlite3_analyzer to the new SQLITE_SCHEMA name. FossilOrigin-Name: 3beb77d6a792d07ca605ec8e5402b8a305860cba4044fcafeed00b9fa862fa16 --- manifest | 14 +++++++------- manifest.uuid | 2 +- tool/spaceanal.tcl | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 8d6d4c6f24..7bb4e1d07c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\suse-after-free\serror\sin\sioerr.test\scaused\sby\san\serror\sin\stest\scode. -D 2021-07-14T21:18:31.520 +C Change\sreferences\sto\sthe\sschema\stable\sin\ssqlite3_analyzer\sto\sthe\snew\nSQLITE_SCHEMA\sname. +D 2021-07-15T16:39:42.407 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1877,7 +1877,7 @@ F tool/showshm.c a0ab6ec32dd1f11218ca2a4018f8fb875b59414801ab8ceed8b2e69b7b45a80 F tool/showstat4.c 0682ebea7abf4d3657f53c4a243f2e7eab48eab344ed36a94bb75dcd19a5c2a1 F tool/showwal.c ad9d768f96ca6199ad3a8c9562d679680bd032dd01204ea3e5ea6fb931d81847 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe -F tool/spaceanal.tcl a95036b36622e25cffd65a55b22d6af53dfbbff0de02d45dd0059bb3c9978609 +F tool/spaceanal.tcl 1b5be34c6223cb1af06da2a10fb77863eb869b1962d055820b0a11cf2336ab45 F tool/speed-check.sh 8ba7c7c0dba37e664679974f5954f2282275271a5b92f890756e282df0bfc458 F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355 F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c378e99250fe06fae8ca40c62185b607f004d6806e07dbb9f964dd849b4e55f8 -R 5dc9e7510bb681a9844c30d96bdfacf1 -U dan -Z ab55d4571a2b3927d12f63db9cd8ac86 +P 1594056aab068b9fae82f6b885828c7127d9bedcc37c4340486e32791bc87c7a +R 559c73747c40f0a1a7e76968f3947fcc +U drh +Z 82febd786cf0b2a285b7ed5af3f23080 diff --git a/manifest.uuid b/manifest.uuid index ca45e83989..e28955bcd3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1594056aab068b9fae82f6b885828c7127d9bedcc37c4340486e32791bc87c7a \ No newline at end of file +3beb77d6a792d07ca605ec8e5402b8a305860cba4044fcafeed00b9fa862fa16 \ No newline at end of file diff --git a/tool/spaceanal.tcl b/tool/spaceanal.tcl index e026a90efd..d0c5e65e38 100644 --- a/tool/spaceanal.tcl +++ b/tool/spaceanal.tcl @@ -731,7 +731,7 @@ Pages of auto-vacuum overhead Number of tables in the database - The number of tables in the database, including the SQLITE_MASTER table + The number of tables in the database, including the SQLITE_SCHEMA table used to store schema information. Number of indices @@ -754,7 +754,7 @@ Size of the file in bytes Bytes of user payload stored The total number of bytes of user payload stored in the database. The - schema information in the SQLITE_MASTER table is not counted when + schema information in the SQLITE_SCHEMA table is not counted when computing this number. The percentage at the right shows the payload divided by the total file size. From bb301231788a7ca2292005ecf8d924dbf122f2d2 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 15 Jul 2021 19:29:43 +0000 Subject: [PATCH 11/49] Attempt to omit ORDER BY clauses from FROM-clause subqueries if those ORDER BY clauses do not affect the output. See [forum:/forumpost/2d76f2bcf65d256a|forum thread 2d76f2bcf65d256a] for discussion. This can help the query flattener in some cases, resulting in faster query plans. The current implemention does not always work. FossilOrigin-Name: ef97c3e7c3ea2cf1a4db6591328fe7ce3f1d189afc2d578159135824ec89e620 --- manifest | 23 ++++++++++------- manifest.uuid | 2 +- src/func.c | 9 ++++--- src/resolve.c | 25 +++++++++++------- src/select.c | 25 ++++++++++++++++++ src/sqliteInt.h | 69 +++++++++++++++++++++++++++---------------------- src/window.c | 2 +- 7 files changed, 98 insertions(+), 57 deletions(-) diff --git a/manifest b/manifest index 7bb4e1d07c..71e6789069 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sreferences\sto\sthe\sschema\stable\sin\ssqlite3_analyzer\sto\sthe\snew\nSQLITE_SCHEMA\sname. -D 2021-07-15T16:39:42.407 +C Attempt\sto\somit\sORDER\sBY\sclauses\sfrom\sFROM-clause\ssubqueries\sif\sthose\sORDER\sBY\nclauses\sdo\snot\saffect\sthe\soutput.\s\sSee\n[forum:/forumpost/2d76f2bcf65d256a|forum\sthread\s2d76f2bcf65d256a]\sfor\ndiscussion.\s\sThis\scan\shelp\sthe\squery\sflattener\sin\nsome\scases,\sresulting\sin\sfaster\squery\splans.\s\sThe\scurrent\simplemention\sdoes\nnot\salways\swork. +D 2021-07-15T19:29:43.004 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -499,7 +499,7 @@ F src/delete.c 62451bba9fe641159e9c0b7d9d2bab1c48d0cff11e16de2d14000603d2af1fcf F src/expr.c 62b6d0ac8ee30a4749b78b7b75ae951a911a5d49321af5fe41c05af4df9e7537 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c e9063648396c58778f77583a678342fe4a9bc82436bf23c5f9f444f2df0fdaa4 -F src/func.c c96ac6f7c4f2d684217c4673a80446e1b50e25b5ea79366f333f484622d010a0 +F src/func.c c224240cbc97fa5e9c4fe9acb128716cb835ca045532bca6951b7c45b020c56c F src/global.c 25ba4d58476f6be29bba9d9d14f7f146b78476d3a4d75ebb8c3b736328afe0f9 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 @@ -542,14 +542,14 @@ F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf F src/prepare.c 0d53d20532aada295c1690792a125adbd6435f5ce703ff0adf1b9b3605238b67 F src/printf.c 78fabb49b9ac9a12dd1c89d744abdc9b67fd3205e62967e158f78b965a29ec4b F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c -F src/resolve.c b379c5ffe3b692e9c64fa37817cc0efa204b7c9468a818309dde85fd132d9d81 +F src/resolve.c 9b54a60702c35b3efbeb5d0439a94d67c4cb93a896e1afa89f21d7a9d183a071 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 1c1230aaa4e5979edd3c5a9f7a90ab856a302cca4962e8a7d08f42dd2e7e1a49 +F src/select.c cc61c6b86617387803d67994fec6131365f6a049399aa28b11028ad0b4ee53b8 F src/shell.c.in 856de2945bb7fdfdeebe7136cf1b59d24618845aa5e5f3937fda7ff37c623b51 F src/sqlite.h.in a5d5641afa335226231231c7b6e424de327f17577d9e8aeaaaab78d9bbbcf381 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510 -F src/sqliteInt.h 129619232aa632fa85db7792bfe4b378ed28d3361bf9cbcdb4522353fd04b89b +F src/sqliteInt.h 74ca9667448fa7aaadcb91bd3fd22732c7f7e05903a53429e653a4a01e4c8efd F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -635,7 +635,7 @@ F src/where.c 07a4097fe42a01b1f99d2a136598654051f0bdcd6c17cbef7fa285a9cf21e4d2 F src/whereInt.h 9248161dd004f625ce5d3841ca9b99fed3fc8d61522cf76340fc5217dbe1375b F src/wherecode.c 9f1f65d11437b25cd0a1497a170514c785f19ce6ad9d3e6fc73719cb5a49012f F src/whereexpr.c 2bfb1cd24b9b63fc5e32b9b85f2b3f88765bdac2aab51102d94d1fb56ec2917b -F src/window.c 559961a731f67a0873744960bdeeb034a5c74cc0a09badb14bc43f74744a2a9d +F src/window.c 420167512050a0dfc0f0115b9f0c7d299da9759c9bb2ae83a61fb8d730a5707f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 F test/affinity3.test eecb0dabee4b7765a8465439d5e99429279ffba23ca74a7eae270a452799f9e7 @@ -1920,7 +1920,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1594056aab068b9fae82f6b885828c7127d9bedcc37c4340486e32791bc87c7a -R 559c73747c40f0a1a7e76968f3947fcc +P 3beb77d6a792d07ca605ec8e5402b8a305860cba4044fcafeed00b9fa862fa16 +R be1da55dd559418ff2dfd4ecbe7a006e +T *branch * omit-subquery-order-by +T *sym-omit-subquery-order-by * +T -sym-trunk * U drh -Z 82febd786cf0b2a285b7ed5af3f23080 +Z fa9c090cb9dd3863cd70130aca6f84ef diff --git a/manifest.uuid b/manifest.uuid index e28955bcd3..efbb411e0e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3beb77d6a792d07ca605ec8e5402b8a305860cba4044fcafeed00b9fa862fa16 \ No newline at end of file +ef97c3e7c3ea2cf1a4db6591328fe7ce3f1d189afc2d578159135824ec89e620 \ No newline at end of file diff --git a/src/func.c b/src/func.c index bb2f6c7b4e..f79b541718 100644 --- a/src/func.c +++ b/src/func.c @@ -2160,11 +2160,11 @@ void sqlite3RegisterBuiltinFunctions(void){ FUNCTION(min, -1, 0, 1, minmaxFunc ), FUNCTION(min, 0, 0, 1, 0 ), WAGGREGATE(min, 1, 0, 1, minmaxStep, minMaxFinalize, minMaxValue, 0, - SQLITE_FUNC_MINMAX ), + SQLITE_FUNC_MINMAX|SQLITE_FUNC_ANYORDER ), FUNCTION(max, -1, 1, 1, minmaxFunc ), FUNCTION(max, 0, 1, 1, 0 ), WAGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize, minMaxValue, 0, - SQLITE_FUNC_MINMAX ), + SQLITE_FUNC_MINMAX|SQLITE_FUNC_ANYORDER ), FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF), FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH), FUNCTION(instr, 2, 0, 0, instrFunc ), @@ -2200,9 +2200,10 @@ void sqlite3RegisterBuiltinFunctions(void){ WAGGREGATE(total, 1,0,0, sumStep,totalFinalize,totalFinalize,sumInverse, 0), WAGGREGATE(avg, 1,0,0, sumStep, avgFinalize, avgFinalize, sumInverse, 0), WAGGREGATE(count, 0,0,0, countStep, - countFinalize, countFinalize, countInverse, SQLITE_FUNC_COUNT ), + countFinalize, countFinalize, countInverse, + SQLITE_FUNC_COUNT|SQLITE_FUNC_ANYORDER ), WAGGREGATE(count, 1,0,0, countStep, - countFinalize, countFinalize, countInverse, 0 ), + countFinalize, countFinalize, countInverse, SQLITE_FUNC_ANYORDER ), WAGGREGATE(group_concat, 1, 0, 0, groupConcatStep, groupConcatFinalize, groupConcatValue, groupConcatInverse, 0), WAGGREGATE(group_concat, 2, 0, 0, groupConcatStep, diff --git a/src/resolve.c b/src/resolve.c index 3bf84d3223..955148a2f5 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -1087,9 +1087,12 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ assert( pDef!=0 || IN_RENAME_OBJECT ); if( pNC2 && pDef ){ assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg ); + assert( SQLITE_FUNC_ANYORDER==NC_OrderAgg ); testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 ); - pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX); - + testcase( (pDef->funcFlags & SQLITE_FUNC_ANYORDER)!=0 ); + pNC2->ncFlags |= NC_HasAgg + | ((pDef->funcFlags^SQLITE_FUNC_ANYORDER) + & (SQLITE_FUNC_MINMAX|SQLITE_FUNC_ANYORDER)); } } pNC->ncFlags |= savedAllowFlags; @@ -1676,7 +1679,8 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ pGroupBy = p->pGroupBy; if( pGroupBy || (sNC.ncFlags & NC_HasAgg)!=0 ){ assert( NC_MinMaxAgg==SF_MinMaxAgg ); - p->selFlags |= SF_Aggregate | (sNC.ncFlags&NC_MinMaxAgg); + assert( NC_OrderAgg==SF_OrderByReqd ); + p->selFlags |= SF_Aggregate | (sNC.ncFlags&(NC_MinMaxAgg|NC_OrderAgg)); }else{ sNC.ncFlags &= ~NC_AllowAgg; } @@ -1859,8 +1863,8 @@ int sqlite3ResolveExprNames( Walker w; if( pExpr==0 ) return SQLITE_OK; - savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin); - pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin); + savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); + pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); w.pParse = pNC->pParse; w.xExprCallback = resolveExprStep; w.xSelectCallback = (pNC->ncFlags & NC_NoSelect) ? 0 : resolveSelectStep; @@ -1903,8 +1907,8 @@ int sqlite3ResolveExprListNames( w.xSelectCallback = resolveSelectStep; w.xSelectCallback2 = 0; w.u.pNC = pNC; - savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin); - pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin); + savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); + pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); for(i=0; inExpr; i++){ Expr *pExpr = pList->a[i].pExpr; if( pExpr==0 ) continue; @@ -1922,10 +1926,11 @@ int sqlite3ResolveExprListNames( assert( EP_Win==NC_HasWin ); testcase( pNC->ncFlags & NC_HasAgg ); testcase( pNC->ncFlags & NC_HasWin ); - if( pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin) ){ + if( pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg) ){ ExprSetProperty(pExpr, pNC->ncFlags & (NC_HasAgg|NC_HasWin) ); - savedHasAgg |= pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin); - pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin); + savedHasAgg |= pNC->ncFlags & + (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); + pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); } if( w.pParse->nErr>0 ) return WRC_Abort; } diff --git a/src/select.c b/src/select.c index d36839264d..a6513afca5 100644 --- a/src/select.c +++ b/src/select.c @@ -6384,6 +6384,31 @@ int sqlite3Select( if( (pSub->selFlags & SF_Aggregate)!=0 ) continue; assert( pSub->pGroupBy==0 ); + /* If a FROM-clause subquery has an ORDER BY clause that is not + ** really doing anything, then delete it now so that it does not + ** interfere with query flattening. + ** + ** Beware of these cases where the ORDER BY clause may not be safely + ** omitted: + ** + ** (1) There is also a LIMIT clause + ** (2) The subquery was added to help with window-function + ** processing + ** (3) The outer query uses an aggregate function other than + ** the built-in count(), min(), or max(). + */ + if( pSub->pOrderBy!=0 + && pSub->pLimit==0 /* Condition (1) */ + && (pSub->selFlags & SF_OrderByReqd)==0 /* Condition (2) */ + && (p->selFlags & SF_OrderByReqd)==0 /* Condition (3) */ + && OptimizationEnabled(db, SQLITE_OmitOrderBy) + ){ + SELECTTRACE(0x100,pParse,p, + ("omit superfluous ORDER BY on %r FROM-clause subquery\n",i+1)); + sqlite3ExprListDelete(db, pSub->pOrderBy); + pSub->pOrderBy = 0; + } + /* If the outer query contains a "complex" result set (that is, ** if the result set of the outer query uses functions or subqueries) ** and if the subquery contains an ORDER BY clause and if diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 81774c1f01..7d0b7ecb37 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1744,6 +1744,7 @@ struct sqlite3 { #define SQLITE_PropagateConst 0x00008000 /* The constant propagation opt */ #define SQLITE_MinMaxOpt 0x00010000 /* The min/max optimization */ #define SQLITE_SeekScan 0x00020000 /* The OP_SeekScan optimization */ +#define SQLITE_OmitOrderBy 0x00040000 /* Omit pointless ORDER BY */ #define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* @@ -1823,12 +1824,13 @@ struct FuncDestructor { ** are assert() statements in the code to verify this. ** ** Value constraints (enforced via assert()): -** SQLITE_FUNC_MINMAX == NC_MinMaxAgg == SF_MinMaxAgg -** SQLITE_FUNC_LENGTH == OPFLAG_LENGTHARG -** SQLITE_FUNC_TYPEOF == OPFLAG_TYPEOFARG -** SQLITE_FUNC_CONSTANT == SQLITE_DETERMINISTIC from the API -** SQLITE_FUNC_DIRECT == SQLITE_DIRECTONLY from the API -** SQLITE_FUNC_UNSAFE == SQLITE_INNOCUOUS +** SQLITE_FUNC_MINMAX == NC_MinMaxAgg == SF_MinMaxAgg +** SQLITE_FUNC_ANYORDER == NC_OrderAgg == SF_OrderByReqd +** SQLITE_FUNC_LENGTH == OPFLAG_LENGTHARG +** SQLITE_FUNC_TYPEOF == OPFLAG_TYPEOFARG +** SQLITE_FUNC_CONSTANT == SQLITE_DETERMINISTIC from the API +** SQLITE_FUNC_DIRECT == SQLITE_DIRECTONLY from the API +** SQLITE_FUNC_UNSAFE == SQLITE_INNOCUOUS ** SQLITE_FUNC_ENCMASK depends on SQLITE_UTF* macros in the API */ #define SQLITE_FUNC_ENCMASK 0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */ @@ -1853,6 +1855,7 @@ struct FuncDestructor { #define SQLITE_FUNC_SUBTYPE 0x00100000 /* Result likely to have sub-type */ #define SQLITE_FUNC_UNSAFE 0x00200000 /* Function has side effects */ #define SQLITE_FUNC_INLINE 0x00400000 /* Functions implemented in-line */ +#define SQLITE_FUNC_ANYORDER 0x08000000 /* count/min/max aggregate */ /* Identifier numbers for each in-line function */ #define INLINEFUNC_coalesce 0 @@ -3088,31 +3091,33 @@ struct NameContext { ** Allowed values for the NameContext, ncFlags field. ** ** Value constraints (all checked via assert()): -** NC_HasAgg == SF_HasAgg == EP_Agg -** NC_MinMaxAgg == SF_MinMaxAgg == SQLITE_FUNC_MINMAX +** NC_HasAgg == SF_HasAgg == EP_Agg +** NC_MinMaxAgg == SF_MinMaxAgg == SQLITE_FUNC_MINMAX +** NC_OrderAgg == SF_OrderByReqd == SQLITE_FUNC_ANYORDER ** NC_HasWin == EP_Win ** */ -#define NC_AllowAgg 0x00001 /* Aggregate functions are allowed here */ -#define NC_PartIdx 0x00002 /* True if resolving a partial index WHERE */ -#define NC_IsCheck 0x00004 /* True if resolving a CHECK constraint */ -#define NC_GenCol 0x00008 /* True for a GENERATED ALWAYS AS clause */ -#define NC_HasAgg 0x00010 /* One or more aggregate functions seen */ -#define NC_IdxExpr 0x00020 /* True if resolving columns of CREATE INDEX */ -#define NC_SelfRef 0x0002e /* Combo: PartIdx, isCheck, GenCol, and IdxExpr */ -#define NC_VarSelect 0x00040 /* A correlated subquery has been seen */ -#define NC_UEList 0x00080 /* True if uNC.pEList is used */ -#define NC_UAggInfo 0x00100 /* True if uNC.pAggInfo is used */ -#define NC_UUpsert 0x00200 /* True if uNC.pUpsert is used */ -#define NC_UBaseReg 0x00400 /* True if uNC.iBaseReg is used */ -#define NC_MinMaxAgg 0x01000 /* min/max aggregates seen. See note above */ -#define NC_Complex 0x02000 /* True if a function or subquery seen */ -#define NC_AllowWin 0x04000 /* Window functions are allowed here */ -#define NC_HasWin 0x08000 /* One or more window functions seen */ -#define NC_IsDDL 0x10000 /* Resolving names in a CREATE statement */ -#define NC_InAggFunc 0x20000 /* True if analyzing arguments to an agg func */ -#define NC_FromDDL 0x40000 /* SQL text comes from sqlite_schema */ -#define NC_NoSelect 0x80000 /* Do not descend into sub-selects */ +#define NC_AllowAgg 0x000001 /* Aggregate functions are allowed here */ +#define NC_PartIdx 0x000002 /* True if resolving a partial index WHERE */ +#define NC_IsCheck 0x000004 /* True if resolving a CHECK constraint */ +#define NC_GenCol 0x000008 /* True for a GENERATED ALWAYS AS clause */ +#define NC_HasAgg 0x000010 /* One or more aggregate functions seen */ +#define NC_IdxExpr 0x000020 /* True if resolving columns of CREATE INDEX */ +#define NC_SelfRef 0x00002e /* Combo: PartIdx, isCheck, GenCol, and IdxExpr */ +#define NC_VarSelect 0x000040 /* A correlated subquery has been seen */ +#define NC_UEList 0x000080 /* True if uNC.pEList is used */ +#define NC_UAggInfo 0x000100 /* True if uNC.pAggInfo is used */ +#define NC_UUpsert 0x000200 /* True if uNC.pUpsert is used */ +#define NC_UBaseReg 0x000400 /* True if uNC.iBaseReg is used */ +#define NC_MinMaxAgg 0x001000 /* min/max aggregates seen. See note above */ +#define NC_Complex 0x002000 /* True if a function or subquery seen */ +#define NC_AllowWin 0x004000 /* Window functions are allowed here */ +#define NC_HasWin 0x008000 /* One or more window functions seen */ +#define NC_IsDDL 0x010000 /* Resolving names in a CREATE statement */ +#define NC_InAggFunc 0x020000 /* True if analyzing arguments to an agg func */ +#define NC_FromDDL 0x040000 /* SQL text comes from sqlite_schema */ +#define NC_NoSelect 0x080000 /* Do not descend into sub-selects */ +#define NC_OrderAgg 0x8000000 /* Has an aggregate other than count/min/max */ /* ** An instance of the following object describes a single ON CONFLICT @@ -3195,9 +3200,10 @@ struct Select { ** "Select Flag". ** ** Value constraints (all checked via assert()) -** SF_HasAgg == NC_HasAgg -** SF_MinMaxAgg == NC_MinMaxAgg == SQLITE_FUNC_MINMAX -** SF_FixedLimit == WHERE_USE_LIMIT +** SF_HasAgg == NC_HasAgg +** SF_MinMaxAgg == NC_MinMaxAgg == SQLITE_FUNC_MINMAX +** SF_OrderByReqd == NC_OrderAgg == SQLITE_FUNC_ANYORDER +** SF_FixedLimit == WHERE_USE_LIMIT */ #define SF_Distinct 0x0000001 /* Output should be DISTINCT */ #define SF_All 0x0000002 /* Includes the ALL keyword */ @@ -3226,6 +3232,7 @@ struct Select { #define SF_PushDown 0x1000000 /* SELECT has be modified by push-down opt */ #define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */ #define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */ +#define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be purged */ /* ** The results of a SELECT can be distributed in several ways, as defined diff --git a/src/window.c b/src/window.c index f33c51150a..4a05392ad8 100644 --- a/src/window.c +++ b/src/window.c @@ -1070,7 +1070,7 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){ Table *pTab2; p->pSrc->a[0].pSelect = pSub; sqlite3SrcListAssignCursors(pParse, p->pSrc); - pSub->selFlags |= SF_Expanded; + pSub->selFlags |= SF_Expanded|SF_OrderByReqd; pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE); pSub->selFlags |= (selFlags & SF_Aggregate); if( pTab2==0 ){ From e13dfe4b19628c1d7b25eb155aa8c6abf614f926 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 15 Jul 2021 23:34:14 +0000 Subject: [PATCH 12/49] By default, do not emit #line directives in the amalgamation. FossilOrigin-Name: bacfa93677fbe014737fab7dbdb4e7a168a310bc5b914b17896ae2a48435c7b1 --- configure | 2 +- manifest | 16 ++++++++-------- manifest.uuid | 2 +- tool/mksqlite3c.tcl | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/configure b/configure index 30f3ed7de0..8da48f587a 100755 --- a/configure +++ b/configure @@ -10312,7 +10312,7 @@ USE_AMALGAMATION=1 # This is a build option not shown by ./configure --help # To control it, use configure option: amalgamation_line_macros=? # where ? is no to suppress #line directives or yes to create them. -AMALGAMATION_LINE_MACROS=--linemacros=1 +AMALGAMATION_LINE_MACROS=--linemacros=0 ######### # See whether we can run specific tclsh versions known to work well; diff --git a/manifest b/manifest index 7bb4e1d07c..011650c27d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sreferences\sto\sthe\sschema\stable\sin\ssqlite3_analyzer\sto\sthe\snew\nSQLITE_SCHEMA\sname. -D 2021-07-15T16:39:42.407 +C By\sdefault,\sdo\snot\semit\s#line\sdirectives\sin\sthe\samalgamation. +D 2021-07-15T23:34:14.480 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -34,7 +34,7 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6 F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559 -F configure b392a2f2a44673f1e31a5bb266a08256a5bb1428e71fd8c6fbc90f60a88286fe x +F configure e8003577b8c433cf61371d27d4beeca3a3ed37611a504ff5f4d4286923b87d03 x F configure.ac 4e4b58b32f88c8da9914a2f2c3158f80e69907eccc019fcc7e3ba14ffd91c640 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd @@ -1858,7 +1858,7 @@ F tool/mkshellc.tcl 5fe7e518112b262e25726f248c0f33dd153192867453984b6af0a76a88e9 F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f -F tool/mksqlite3c.tcl 8127f4c2b11078f9dc4956fa1401291b6d6dd81e41a4fd3f74a9710ab16a791c +F tool/mksqlite3c.tcl cf5686da672bc2e62cf868b7d53fc9a2aebf1b0e497164cbb9f647ec724ce0b2 F tool/mksqlite3h.tcl 1f5e4a1dbbbc43c83cc6e74fe32c6c620502240b66c7c0f33a51378e78fc4edf F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5 @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1594056aab068b9fae82f6b885828c7127d9bedcc37c4340486e32791bc87c7a -R 559c73747c40f0a1a7e76968f3947fcc -U drh -Z 82febd786cf0b2a285b7ed5af3f23080 +P 3beb77d6a792d07ca605ec8e5402b8a305860cba4044fcafeed00b9fa862fa16 +R daf164cb48477e7248acc5698977e210 +U mistachkin +Z 68baf9b3461559a5c1573182f5e84392 diff --git a/manifest.uuid b/manifest.uuid index e28955bcd3..7c267ab8e0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3beb77d6a792d07ca605ec8e5402b8a305860cba4044fcafeed00b9fa862fa16 \ No newline at end of file +bacfa93677fbe014737fab7dbdb4e7a168a310bc5b914b17896ae2a48435c7b1 \ No newline at end of file diff --git a/tool/mksqlite3c.tcl b/tool/mksqlite3c.tcl index 863eeba801..f9c40f6609 100644 --- a/tool/mksqlite3c.tcl +++ b/tool/mksqlite3c.tcl @@ -38,7 +38,7 @@ set help {Usage: tclsh mksqlite3c.tcl # set addstatic 1 -set linemacros 1 +set linemacros 0 set useapicall 0 set srcdir tsrc From 0fb78f0cca4eedc1f2e68fc7fa3395ab6d46576a Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 16 Jul 2021 01:19:19 +0000 Subject: [PATCH 13/49] Get the "omit ORDER BY in FROM-clause subqueries" optimization working for the core test cases. FossilOrigin-Name: e31c5888659ffd4c6d8b68627123df3bbb84bb010b7766b0a74877bf3ba1e52b --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/select.c | 14 +++++++++++--- src/update.c | 1 + 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 71e6789069..0764582fb3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Attempt\sto\somit\sORDER\sBY\sclauses\sfrom\sFROM-clause\ssubqueries\sif\sthose\sORDER\sBY\nclauses\sdo\snot\saffect\sthe\soutput.\s\sSee\n[forum:/forumpost/2d76f2bcf65d256a|forum\sthread\s2d76f2bcf65d256a]\sfor\ndiscussion.\s\sThis\scan\shelp\sthe\squery\sflattener\sin\nsome\scases,\sresulting\sin\sfaster\squery\splans.\s\sThe\scurrent\simplemention\sdoes\nnot\salways\swork. -D 2021-07-15T19:29:43.004 +C Get\sthe\s"omit\sORDER\sBY\sin\sFROM-clause\ssubqueries"\soptimization\sworking\sfor\sthe\ncore\stest\scases. +D 2021-07-16T01:19:19.310 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -544,7 +544,7 @@ F src/printf.c 78fabb49b9ac9a12dd1c89d744abdc9b67fd3205e62967e158f78b965a29ec4b F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 9b54a60702c35b3efbeb5d0439a94d67c4cb93a896e1afa89f21d7a9d183a071 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c cc61c6b86617387803d67994fec6131365f6a049399aa28b11028ad0b4ee53b8 +F src/select.c 0c783511b5f35b37d971dcd653c554d21f74d7cb63a4979991a61d068480c40f F src/shell.c.in 856de2945bb7fdfdeebe7136cf1b59d24618845aa5e5f3937fda7ff37c623b51 F src/sqlite.h.in a5d5641afa335226231231c7b6e424de327f17577d9e8aeaaaab78d9bbbcf381 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -611,7 +611,7 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c bae853ad129d1129c063de8630a3e99e306283bc40146f359b1bb91be2c08f1e F src/treeview.c ce7a3da38caba094c78d888d2366f749ea33dc8cbafb04218b57768fb8669a6c F src/trigger.c 7d16aa09e63226b6d8b3f0fc60b21cbfa596fc406288b2ebcf4266633d1ba222 -F src/update.c ff10c7ca6dc9007cdebb3eee6630e87639ef9f949ccb574c34f9d34c52c32fb9 +F src/update.c 30465f9accc854e8a7932b413578027fbb68186132abbb36e01d2022473fc83d F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 41c7a72da1df47864faa378a1c720b38adb288c6838cb6be5594511b6287a048 @@ -1920,10 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3beb77d6a792d07ca605ec8e5402b8a305860cba4044fcafeed00b9fa862fa16 -R be1da55dd559418ff2dfd4ecbe7a006e -T *branch * omit-subquery-order-by -T *sym-omit-subquery-order-by * -T -sym-trunk * +P ef97c3e7c3ea2cf1a4db6591328fe7ce3f1d189afc2d578159135824ec89e620 +R f27eb88a1585b6967c8257fe374701ea U drh -Z fa9c090cb9dd3863cd70130aca6f84ef +Z 493c03b78cdd1bd0aeff046f5ac8dff0 diff --git a/manifest.uuid b/manifest.uuid index efbb411e0e..58e9bee337 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ef97c3e7c3ea2cf1a4db6591328fe7ce3f1d189afc2d578159135824ec89e620 \ No newline at end of file +e31c5888659ffd4c6d8b68627123df3bbb84bb010b7766b0a74877bf3ba1e52b \ No newline at end of file diff --git a/src/select.c b/src/select.c index a6513afca5..e0ac9db97b 100644 --- a/src/select.c +++ b/src/select.c @@ -6386,7 +6386,8 @@ int sqlite3Select( /* If a FROM-clause subquery has an ORDER BY clause that is not ** really doing anything, then delete it now so that it does not - ** interfere with query flattening. + ** interfere with query flattening. See the discussion at + ** https://sqlite.org/forum/forumpost/2d76f2bcf65d256a ** ** Beware of these cases where the ORDER BY clause may not be safely ** omitted: @@ -6394,13 +6395,20 @@ int sqlite3Select( ** (1) There is also a LIMIT clause ** (2) The subquery was added to help with window-function ** processing - ** (3) The outer query uses an aggregate function other than + ** (3) The subquery is in the FROM clause of an UPDATE + ** (4) The outer query uses an aggregate function other than ** the built-in count(), min(), or max(). + ** (5) The ORDER BY isn't going to accomplish anything because + ** one of: + ** (a) The outer query has a different ORDER BY clause + ** (b) The subquery is part of a join + ** See forum post 062d576715d277c8 */ if( pSub->pOrderBy!=0 + && (p->pOrderBy!=0 || pTabList->nSrc>1) /* Condition (5) */ && pSub->pLimit==0 /* Condition (1) */ && (pSub->selFlags & SF_OrderByReqd)==0 /* Condition (2) */ - && (p->selFlags & SF_OrderByReqd)==0 /* Condition (3) */ + && (p->selFlags & SF_OrderByReqd)==0 /* Condition (3) and (4) */ && OptimizationEnabled(db, SQLITE_OmitOrderBy) ){ SELECTTRACE(0x100,pParse,p, diff --git a/src/update.c b/src/update.c index 45f332bf37..c5a01f8969 100644 --- a/src/update.c +++ b/src/update.c @@ -261,6 +261,7 @@ static void updateFromSelect( pSelect = sqlite3SelectNew(pParse, pList, pSrc, pWhere2, pGrp, 0, pOrderBy2, SF_UFSrcCheck|SF_IncludeHidden, pLimit2 ); + if( pSelect ) pSelect->selFlags |= SF_OrderByReqd; sqlite3SelectDestInit(&dest, eDest, iEph); dest.iSDParm2 = (pPk ? pPk->nKeyCol : -1); sqlite3Select(pParse, pSelect, &dest); From 111c3cc9fb1cdcbdb66bbe858732cacaf3a9482d Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 16 Jul 2021 15:30:19 +0000 Subject: [PATCH 14/49] Fix the "main.mk" makefile so that "series.c" is a dependency of "shell.c". FossilOrigin-Name: ff959917918495ef352ce48c240b1de6da162f2a5e76e37dcc53fa50bce27642 --- main.mk | 1 + manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/main.mk b/main.mk index 64c25a5139..eb45de8238 100644 --- a/main.mk +++ b/main.mk @@ -749,6 +749,7 @@ SHELL_SRC = \ $(TOP)/ext/misc/fileio.c \ $(TOP)/ext/misc/ieee754.c \ $(TOP)/ext/misc/regexp.c \ + $(TOP)/ext/misc/series.c \ $(TOP)/ext/misc/shathree.c \ $(TOP)/ext/misc/sqlar.c \ $(TOP)/ext/misc/uint.c \ diff --git a/manifest b/manifest index 011650c27d..82fdd292ec 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C By\sdefault,\sdo\snot\semit\s#line\sdirectives\sin\sthe\samalgamation. -D 2021-07-15T23:34:14.480 +C Fix\sthe\s"main.mk"\smakefile\sso\sthat\s"series.c"\sis\sa\sdependency\sof\s"shell.c". +D 2021-07-16T15:30:19.396 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -466,7 +466,7 @@ F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 200bf75c882c4822ea722840fc5212f22e5e18773851352c2a0d077958de8b7f +F main.mk 4e075c9618c06c55d1cc723087b0722f384247b6b8db1ac2cb161f864c953c97 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3beb77d6a792d07ca605ec8e5402b8a305860cba4044fcafeed00b9fa862fa16 -R daf164cb48477e7248acc5698977e210 -U mistachkin -Z 68baf9b3461559a5c1573182f5e84392 +P bacfa93677fbe014737fab7dbdb4e7a168a310bc5b914b17896ae2a48435c7b1 +R c8ff11932c350e983e9fb8ccf092c387 +U drh +Z fd34dc6395fc4ba0b62b54a8700203f9 diff --git a/manifest.uuid b/manifest.uuid index 7c267ab8e0..312c0f7513 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bacfa93677fbe014737fab7dbdb4e7a168a310bc5b914b17896ae2a48435c7b1 \ No newline at end of file +ff959917918495ef352ce48c240b1de6da162f2a5e76e37dcc53fa50bce27642 \ No newline at end of file From e46ec734c7d709d773e75827378747ef298cc05a Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 16 Jul 2021 17:04:17 +0000 Subject: [PATCH 15/49] Modify the generate_series() table-valued functions so that its first argument (the START value) is required. Throw an error if that argument is not supplied. In this was the series.c loadable extension can be used as a demonstration of how to code an xBestIndex function to require certain parameters. Compile with -DZERO_ARGUMENT_GENERATE_SERIES to obtain the legacy behavior. FossilOrigin-Name: 459d85a2898d6a53f43b4ad48d2f39edd1bbe37a4f97426a5d666c39c52576a4 --- ext/misc/series.c | 18 ++++++++++++++++-- manifest | 14 +++++++------- manifest.uuid | 2 +- test/tabfunc01.test | 10 ++++++++-- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/ext/misc/series.c b/ext/misc/series.c index a4e92ace88..08e1829b8c 100644 --- a/ext/misc/series.c +++ b/ext/misc/series.c @@ -323,11 +323,12 @@ static int seriesFilter( ** (8) output in descending order */ static int seriesBestIndex( - sqlite3_vtab *tabUnused, + sqlite3_vtab *pVTab, sqlite3_index_info *pIdxInfo ){ int i, j; /* Loop over constraints */ int idxNum = 0; /* The query plan bitmask */ + int bStartSeen = 0; /* EQ constraint seen on the START column */ int unusableMask = 0; /* Mask of unusable constraints */ int nArg = 0; /* Number of arguments that seriesFilter() expects */ int aIdx[3]; /* Constraints on start, stop, and step */ @@ -337,7 +338,7 @@ static int seriesBestIndex( ** are the last three columns in the virtual table. */ assert( SERIES_COLUMN_STOP == SERIES_COLUMN_START+1 ); assert( SERIES_COLUMN_STEP == SERIES_COLUMN_START+2 ); - (void)tabUnused; + aIdx[0] = aIdx[1] = aIdx[2] = -1; pConstraint = pIdxInfo->aConstraint; for(i=0; inConstraint; i++, pConstraint++){ @@ -347,6 +348,7 @@ static int seriesBestIndex( iCol = pConstraint->iColumn - SERIES_COLUMN_START; assert( iCol>=0 && iCol<=2 ); iMask = 1 << iCol; + if( iCol==0 ) bStartSeen = 1; if( pConstraint->usable==0 ){ unusableMask |= iMask; continue; @@ -361,6 +363,18 @@ static int seriesBestIndex( pIdxInfo->aConstraintUsage[j].omit = !SQLITE_SERIES_CONSTRAINT_VERIFY; } } + /* The current generate_column() implementation requires at least one + ** argument (the START value). Legacy versions assumed START=0 if the + ** first argument was omitted. Compile with -DZERO_ARGUMENT_GENERATE_SERIES + ** to obtain the legacy behavior */ +#ifndef ZERO_ARGUMENT_GENERATE_SERIES + if( !bStartSeen ){ + sqlite3_free(pVTab->zErrMsg); + pVTab->zErrMsg = sqlite3_mprintf( + "first argument to \"generate_series()\" missing or unusable"); + return SQLITE_ERROR; + } +#endif if( (unusableMask & ~idxNum)!=0 ){ /* The start, stop, and step columns are inputs. Therefore if there ** are unusable constraints on any of start, stop, or step then diff --git a/manifest b/manifest index 82fdd292ec..d7a7bff296 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\s"main.mk"\smakefile\sso\sthat\s"series.c"\sis\sa\sdependency\sof\s"shell.c". -D 2021-07-16T15:30:19.396 +C Modify\sthe\sgenerate_series()\stable-valued\sfunctions\sso\sthat\sits\sfirst\nargument\s(the\sSTART\svalue)\sis\srequired.\s\sThrow\san\serror\sif\sthat\sargument\nis\snot\ssupplied.\s\sIn\sthis\swas\sthe\sseries.c\sloadable\sextension\scan\sbe\sused\nas\sa\sdemonstration\sof\show\sto\scode\san\sxBestIndex\sfunction\sto\srequire\scertain\nparameters.\s\sCompile\swith\s-DZERO_ARGUMENT_GENERATE_SERIES\sto\sobtain\sthe\nlegacy\sbehavior. +D 2021-07-16T17:04:17.942 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -319,7 +319,7 @@ F ext/misc/regexp.c 5853b0e5ed40c47f7ded2b0bf2ff73796f7cb21543089c5f07308e003264 F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946 -F ext/misc/series.c c6bd5d249e5199a1b55aeee4d0e6576ff3a68702fc475dbd64503a32903516c7 +F ext/misc/series.c 233804fd4e07de94ecae42b487fb38bbd819b249114bb34bb46f227c8c7111df F ext/misc/sha1.c c8f2253c8792ffab9517695ea7d88c079f0395a5505eefef5c8198fe184ed5ac F ext/misc/shathree.c e984f31731de4cf302a0386be5fe664580f63d8204c47b9b41cc4b997745f9ec F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 @@ -1442,7 +1442,7 @@ F test/sync.test 89539f4973c010eda5638407e71ca7fddbcd8e0594f4c9980229f804d433309 F test/sync2.test 8f9f7d4f6d5be8ca8941a8dadcc4299e558cb6a1ff653a9469146c7a76ef2039 F test/syscall.test a39d9a36f852ae6e4800f861bc2f2e83f68bbc2112d9399931ecfadeabd2d69d F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 -F test/tabfunc01.test acb5be558868c65d8cf3495539fff23093d77139eb1e4e8c4580568099f98645 +F test/tabfunc01.test d6821e7042e5653104dac0c63d75eff24a2415ab1889fc68b5db7fde59464c59 F test/table.test eb3463b7add9f16a5bb836badf118cf391b809d09fdccd1f79684600d07ec132 F test/tableapi.test ecbcc29c4ab62c1912c3717c48ea5c5e59f7d64e4a91034e6148bd2b82f177f4 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bacfa93677fbe014737fab7dbdb4e7a168a310bc5b914b17896ae2a48435c7b1 -R c8ff11932c350e983e9fb8ccf092c387 +P ff959917918495ef352ce48c240b1de6da162f2a5e76e37dcc53fa50bce27642 +R aa3d348b2c34c0c9b3d3fd2a8d2ce220 U drh -Z fd34dc6395fc4ba0b62b54a8700203f9 +Z 4342f932cf72c33e96387442e529227b diff --git a/manifest.uuid b/manifest.uuid index 312c0f7513..e8c7b1ff07 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ff959917918495ef352ce48c240b1de6da162f2a5e76e37dcc53fa50bce27642 \ No newline at end of file +459d85a2898d6a53f43b4ad48d2f39edd1bbe37a4f97426a5d666c39c52576a4 \ No newline at end of file diff --git a/test/tabfunc01.test b/test/tabfunc01.test index 797267b338..d3d93792da 100644 --- a/test/tabfunc01.test +++ b/test/tabfunc01.test @@ -32,8 +32,14 @@ do_execsql_test tabfunc01-1.1b { PRAGMA table_xinfo(generate_series); } {0 value {} 0 {} 0 0 1 start {} 0 {} 0 1 2 stop {} 0 {} 0 1 3 step {} 0 {} 0 1} do_execsql_test tabfunc01-1.2 { - SELECT *, '|' FROM generate_series LIMIT 5; + SELECT *, '|' FROM generate_series(0) LIMIT 5; } {0 | 1 | 2 | 3 | 4 |} +do_catchsql_test tabfunc01-1.2b { + SELECT *, '|' FROM generate_series LIMIT 5; +} {1 {first argument to "generate_series()" missing or unusable}} +do_catchsql_test tabfunc01-1.2c { + SELECT *, '|' FROM generate_series(value) LIMIT 5; +} {1 {first argument to "generate_series()" missing or unusable}} do_catchsql_test tabfunc01-1.3 { CREATE VIRTUAL TABLE t1 USING generate_series; } {1 {no such module: generate_series}} @@ -104,7 +110,7 @@ do_execsql_test tabfunc01-2.2 { } {2 1 | 2 2 | 3 1 | 3 2 | 3 3 |} do_execsql_test tabfunc01-2.50 { - SELECT * FROM generate_series() LIMIT 5; + SELECT * FROM generate_series(0) LIMIT 5; } {0 1 2 3 4} do_execsql_test tabfunc01-3.1 { From d51a2d8b8f227c71c81c1116a2ea8d61c5f8d4bb Mon Sep 17 00:00:00 2001 From: larrybr Date: Fri, 16 Jul 2021 17:11:21 +0000 Subject: [PATCH 16/49] De-typo sqlite3_expanded_sql() doc FossilOrigin-Name: 56b0f5418dad34d1e83d53741916e2a38a5448369031d959b8a44867774be657 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index d7a7bff296..867598a0d0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Modify\sthe\sgenerate_series()\stable-valued\sfunctions\sso\sthat\sits\sfirst\nargument\s(the\sSTART\svalue)\sis\srequired.\s\sThrow\san\serror\sif\sthat\sargument\nis\snot\ssupplied.\s\sIn\sthis\swas\sthe\sseries.c\sloadable\sextension\scan\sbe\sused\nas\sa\sdemonstration\sof\show\sto\scode\san\sxBestIndex\sfunction\sto\srequire\scertain\nparameters.\s\sCompile\swith\s-DZERO_ARGUMENT_GENERATE_SERIES\sto\sobtain\sthe\nlegacy\sbehavior. -D 2021-07-16T17:04:17.942 +C De-typo\ssqlite3_expanded_sql()\sdoc +D 2021-07-16T17:11:21.925 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -546,7 +546,7 @@ F src/resolve.c b379c5ffe3b692e9c64fa37817cc0efa204b7c9468a818309dde85fd132d9d81 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 1c1230aaa4e5979edd3c5a9f7a90ab856a302cca4962e8a7d08f42dd2e7e1a49 F src/shell.c.in 856de2945bb7fdfdeebe7136cf1b59d24618845aa5e5f3937fda7ff37c623b51 -F src/sqlite.h.in a5d5641afa335226231231c7b6e424de327f17577d9e8aeaaaab78d9bbbcf381 +F src/sqlite.h.in f716b8a9fb30c6928752fd75b3f824e8ac4d225d31494029dee8454aeb9aa01a F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510 F src/sqliteInt.h 129619232aa632fa85db7792bfe4b378ed28d3361bf9cbcdb4522353fd04b89b @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ff959917918495ef352ce48c240b1de6da162f2a5e76e37dcc53fa50bce27642 -R aa3d348b2c34c0c9b3d3fd2a8d2ce220 -U drh -Z 4342f932cf72c33e96387442e529227b +P 459d85a2898d6a53f43b4ad48d2f39edd1bbe37a4f97426a5d666c39c52576a4 +R 586dff70e9760c1426027997891782a1 +U larrybr +Z 508402e0d81680ab955ec6d0adae92e8 diff --git a/manifest.uuid b/manifest.uuid index e8c7b1ff07..524955bd4f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -459d85a2898d6a53f43b4ad48d2f39edd1bbe37a4f97426a5d666c39c52576a4 \ No newline at end of file +56b0f5418dad34d1e83d53741916e2a38a5448369031d959b8a44867774be657 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 73c1adeae1..3ac46fb55a 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -4197,7 +4197,7 @@ int sqlite3_prepare16_v3( ** are managed by SQLite and are automatically freed when the prepared ** statement is finalized. ** ^The string returned by sqlite3_expanded_sql(P), on the other hand, -** is obtained from [sqlite3_malloc()] and must be free by the application +** is obtained from [sqlite3_malloc()] and must be freed by the application ** by passing it to [sqlite3_free()]. ** ** ^The sqlite3_normalized_sql() interface is only available if From ee612e2a5df430b35f7937704a0f109bea71dc40 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 16 Jul 2021 20:16:19 +0000 Subject: [PATCH 17/49] Minor comment improvements. FossilOrigin-Name: 6854b5919beefa43da21ba739e82d583183c8cdfe5dd63e27a810ac1ffe2330b --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/resolve.c | 2 +- src/sqliteInt.h | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 0764582fb3..4a30fc798b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Get\sthe\s"omit\sORDER\sBY\sin\sFROM-clause\ssubqueries"\soptimization\sworking\sfor\sthe\ncore\stest\scases. -D 2021-07-16T01:19:19.310 +C Minor\scomment\simprovements. +D 2021-07-16T20:16:19.970 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -542,14 +542,14 @@ F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf F src/prepare.c 0d53d20532aada295c1690792a125adbd6435f5ce703ff0adf1b9b3605238b67 F src/printf.c 78fabb49b9ac9a12dd1c89d744abdc9b67fd3205e62967e158f78b965a29ec4b F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c -F src/resolve.c 9b54a60702c35b3efbeb5d0439a94d67c4cb93a896e1afa89f21d7a9d183a071 +F src/resolve.c ea205123fba6bb254666f50b6c220270913eae54eb03d263abaa432c703f5857 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 0c783511b5f35b37d971dcd653c554d21f74d7cb63a4979991a61d068480c40f F src/shell.c.in 856de2945bb7fdfdeebe7136cf1b59d24618845aa5e5f3937fda7ff37c623b51 F src/sqlite.h.in a5d5641afa335226231231c7b6e424de327f17577d9e8aeaaaab78d9bbbcf381 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510 -F src/sqliteInt.h 74ca9667448fa7aaadcb91bd3fd22732c7f7e05903a53429e653a4a01e4c8efd +F src/sqliteInt.h a71d18dc76a2768ec2b7671b5b5996a8725677bf77a987b451323b4451099061 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ef97c3e7c3ea2cf1a4db6591328fe7ce3f1d189afc2d578159135824ec89e620 -R f27eb88a1585b6967c8257fe374701ea +P e31c5888659ffd4c6d8b68627123df3bbb84bb010b7766b0a74877bf3ba1e52b +R 2b5d3bf35c291d863ff2cdabf1b23aa4 U drh -Z 493c03b78cdd1bd0aeff046f5ac8dff0 +Z 8fd4496f447f68e71867e0b05442b99f diff --git a/manifest.uuid b/manifest.uuid index 58e9bee337..3a27d75dee 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e31c5888659ffd4c6d8b68627123df3bbb84bb010b7766b0a74877bf3ba1e52b \ No newline at end of file +6854b5919beefa43da21ba739e82d583183c8cdfe5dd63e27a810ac1ffe2330b \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index 955148a2f5..ae5a574056 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -1635,7 +1635,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ p->pOrderBy = 0; } - /* Recursively resolve names in all subqueries + /* Recursively resolve names in all subqueries in the FROM clause */ for(i=0; ipSrc->nSrc; i++){ SrcItem *pItem = &p->pSrc->a[i]; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7d0b7ecb37..6f02a5184c 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3232,7 +3232,7 @@ struct Select { #define SF_PushDown 0x1000000 /* SELECT has be modified by push-down opt */ #define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */ #define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */ -#define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be purged */ +#define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */ /* ** The results of a SELECT can be distributed in several ways, as defined From 05de5048b4e531eeb455dd8c3fa287e591eee6a0 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 19 Jul 2021 03:38:13 +0000 Subject: [PATCH 18/49] Fix minor spacing issues in the MSVC makefile. FossilOrigin-Name: d78c272b3966cc1b12bc7e83fbe909a3c517d553a942d7f1c07bddf69f2e2164 --- Makefile.msc | 8 ++++---- manifest | 15 +++++++-------- manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 7fd43055ec..b1b4e22cd6 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -2209,11 +2209,11 @@ SHELL_SRC = \ $(TOP)\src\shell.c.in \ $(TOP)\ext\misc\appendvfs.c \ $(TOP)\ext\misc\completion.c \ - $(TOP)\ext\misc\decimal.c \ + $(TOP)\ext\misc\decimal.c \ $(TOP)\ext\misc\fileio.c \ - $(TOP)\ext\misc\ieee754.c \ - $(TOP)\ext\misc\regexp.c \ - $(TOP)\ext\misc\series.c \ + $(TOP)\ext\misc\ieee754.c \ + $(TOP)\ext\misc\regexp.c \ + $(TOP)\ext\misc\series.c \ $(TOP)\ext\misc\shathree.c \ $(TOP)\ext\misc\uint.c \ $(TOP)\ext\expert\sqlite3expert.c \ diff --git a/manifest b/manifest index 304acc49f7..9f23e74798 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C Try\sto\somit\sthe\sORDER\sBY\sclause\sin\ssubqueries\sif\sdoing\sso\sdoes\snot\schange\nthe\sresult\sin\sany\sway.\sSee\n[forum:/forumpost/2d76f2bcf65d256a|Forum\spost\s2d76f2bcf65d256a]\sfor\ndetails\sand\shistory. -D 2021-07-16T22:43:00.597 +C Fix\sminor\sspacing\sissues\sin\sthe\sMSVC\smakefile. +D 2021-07-19T03:38:13.243 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F Makefile.in 83c348515cb62f6f2a2ddf3fd014113ff20564b776e1a614079722c88c6ff43d F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241 -F Makefile.msc d481375cd138e705f749dad2549b2f80d5d76e23132c5fc9be337f7416cb9fc8 +F Makefile.msc f889e0dcf8668cccac0c68be2ea09fc585dd40ac44ca37e9fb15638ee9315a92 F README.md 27fb76aa7eb57ed63a53bbba7292b6bf71f51125554f79f16b5d040edd1e6110 F VERSION c6595fef606851f2bc3ebed6a7386c73751835fc909feab7c093739fa4b3c1d1 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -1920,8 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 56b0f5418dad34d1e83d53741916e2a38a5448369031d959b8a44867774be657 6854b5919beefa43da21ba739e82d583183c8cdfe5dd63e27a810ac1ffe2330b -R 6e75e47df06fbba5ca701a4a4bf4039e -T +closed 6854b5919beefa43da21ba739e82d583183c8cdfe5dd63e27a810ac1ffe2330b -U drh -Z f23b8c5ab82b5bff69635213de4f5afb +P 85ddaf1b59a19cbd9efe7724a163b30c14bafabfaf2cfced07b463e76f73e494 +R 4eef8627720563ebb21acd0bdf777bd1 +U mistachkin +Z 3b091060036ec0c06d6ff58dfb637bd5 diff --git a/manifest.uuid b/manifest.uuid index b1da6c4a23..06510e881a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -85ddaf1b59a19cbd9efe7724a163b30c14bafabfaf2cfced07b463e76f73e494 \ No newline at end of file +d78c272b3966cc1b12bc7e83fbe909a3c517d553a942d7f1c07bddf69f2e2164 \ No newline at end of file From 73983658c98ab2a474d26c8c0284e99af5f79428 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 19 Jul 2021 14:00:29 +0000 Subject: [PATCH 19/49] In defensive mode, allow statements that write to shadow tables to be prepared from with virtual-table xSync() calls. FossilOrigin-Name: c8601d83fbecf84ca7991d339449b380deb5a7620dc84756a91c2880f030b423 --- ext/fts5/test/fts5misc.test | 29 +++++++++++++++++++++++++++++ manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/build.c | 1 + 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/ext/fts5/test/fts5misc.test b/ext/fts5/test/fts5misc.test index 9abc92b23f..e354d20e2c 100644 --- a/ext/fts5/test/fts5misc.test +++ b/ext/fts5/test/fts5misc.test @@ -323,5 +323,34 @@ do_execsql_test 12.3 { SELECT * FROM t2 JOIN ft USING (ft) } {3 4 b b} +#------------------------------------------------------------------------- +# Forum post https://sqlite.org/forum/forumpost/21127c1160 +# +reset_db +sqlite3_db_config db DEFENSIVE 1 + +do_execsql_test 13.0 { + CREATE TABLE a (id INTEGER PRIMARY KEY, name TEXT); + CREATE VIRTUAL TABLE b USING fts5(name); + CREATE TRIGGER a_trigger AFTER INSERT ON a BEGIN + INSERT INTO b (name) VALUES ('foo'); + END; +} + +do_test 13.1 { + set ::STMT [ + sqlite3_prepare db "INSERT INTO a VALUES (1, 'foo') RETURNING id;" -1 dummy + ] + sqlite3_step $::STMT +} {SQLITE_ROW} + +do_test 13.2 { + sqlite3_finalize $::STMT +} {SQLITE_OK} + +do_test 13.3 { + sqlite3_errmsg db +} {not an error} + finish_test diff --git a/manifest b/manifest index 9f23e74798..c4eeee5ecd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sminor\sspacing\sissues\sin\sthe\sMSVC\smakefile. -D 2021-07-19T03:38:13.243 +C In\sdefensive\smode,\sallow\sstatements\sthat\swrite\sto\sshadow\stables\sto\sbe\sprepared\sfrom\swith\svirtual-table\sxSync()\scalls. +D 2021-07-19T14:00:29.519 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -193,7 +193,7 @@ F ext/fts5/test/fts5leftjoin.test c0b4cafb9661379e576dc4405c0891d8fcc27826807405 F ext/fts5/test/fts5matchinfo.test 10c9a6f7fe61fb132299c4183c012770b10c4d5c2f2edb6df0b6607f683d737a F ext/fts5/test/fts5merge.test e92a8db28b45931e7a9c7b1bbd36101692759d00274df74d83fd29d25d53b3a6 F ext/fts5/test/fts5merge2.test 3ebad1a59d6ad3fb66eff6523a09e95dc6367cbefb3cd73196801dea0425c8e2 -F ext/fts5/test/fts5misc.test 088ac5f0f5de1ad45b0f83197ab5263bcae8130156cdc901bff2375ff2b8af86 +F ext/fts5/test/fts5misc.test 4d7d20372242cc618688de029b87d897d09fa1640302c254abee63cf3ffa2c10 F ext/fts5/test/fts5multi.test a15bc91cdb717492e6e1b66fec1c356cb57386b980c7ba5af1915f97fe878581 F ext/fts5/test/fts5multiclient.test 5ff811c028d6108045ffef737f1e9f05028af2458e456c0937c1d1b8dea56d45 F ext/fts5/test/fts5near.test 211477940142d733ac04fad97cb24095513ab2507073a99c2765c3ddd2ef58bd @@ -488,7 +488,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c e204a9c8fb4fe5dbb910a863ba487f4af9b5c501254ec4ccbfcdd6b1f65b7fb4 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0 -F src/build.c 98e23c9197fd4c979f7d59360bd3b0050b37e683e078715f6f2fbfef77971f0d +F src/build.c a27511863001ba088afd5e19efc9c37ea660983bd6ddf012def10f6cc4456a01 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 8159d5f706551861c18ec6c8f6bdf105e15ea00367f05d9ab65d31a1077facc1 @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 85ddaf1b59a19cbd9efe7724a163b30c14bafabfaf2cfced07b463e76f73e494 -R 4eef8627720563ebb21acd0bdf777bd1 -U mistachkin -Z 3b091060036ec0c06d6ff58dfb637bd5 +P d78c272b3966cc1b12bc7e83fbe909a3c517d553a942d7f1c07bddf69f2e2164 +R db28e0ca4ea83a622e82068e2a2a636b +U dan +Z 8b08dd57f21b0e772cbc6de26df5a8fe diff --git a/manifest.uuid b/manifest.uuid index 06510e881a..7e93b98bd8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d78c272b3966cc1b12bc7e83fbe909a3c517d553a942d7f1c07bddf69f2e2164 \ No newline at end of file +c8601d83fbecf84ca7991d339449b380deb5a7620dc84756a91c2880f030b423 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 00fa447957..4eca21a3f7 100644 --- a/src/build.c +++ b/src/build.c @@ -3181,6 +3181,7 @@ int sqlite3ReadOnlyShadowTables(sqlite3 *db){ if( (db->flags & SQLITE_Defensive)!=0 && db->pVtabCtx==0 && db->nVdbeExec==0 + && !sqlite3VtabInSync(db) ){ return 1; } From bb2d2a50f9bbeacb83ca7d8d1e2fe08d4f5e9580 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 19 Jul 2021 16:49:13 +0000 Subject: [PATCH 20/49] Updates so that "threadtest3[.exe]" can be built for windows with MSVC. FossilOrigin-Name: 4ce585fb07274284e3add6adcb66ed06e4b109584704d1ec7152bf43ca8d5d85 --- Makefile.msc | 11 +++++ manifest | 16 ++++---- manifest.uuid | 2 +- test/threadtest3.c | 95 ++++++++++++++++++++++++++++++++++--------- test/tt3_checkpoint.c | 4 +- 5 files changed, 98 insertions(+), 30 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index b1b4e22cd6..57ddbe7854 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -2586,6 +2586,17 @@ rbu.exe: $(TOP)\ext\rbu\rbu.c $(TOP)\ext\rbu\sqlite3rbu.c $(SQLITE3C) $(SQLITE3H $(LTLINK) $(NO_WARN) -DSQLITE_ENABLE_RBU \ $(TOP)\ext\rbu\rbu.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) + +THREADTEST3_SRC = $(TOP)\test\threadtest3.c \ + $(TOP)\test\tt3_checkpoint.c \ + $(TOP)\test\tt3_index.c \ + $(TOP)\test\tt3_vacuum.c \ + $(TOP)\test\tt3_stress.c \ + $(TOP)\test\tt3_lookaside1.c + +threadtest3.exe: sqlite3.obj $(THREADTEST3_SRC) $(TOP)/src/test_multiplex.c + $(LTLINK) $(TOP)\test\threadtest3.c $(TOP)\src\test_multiplex.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) + LSMDIR=$(TOP)\ext\lsm1 !INCLUDE $(LSMDIR)\Makefile.msc diff --git a/manifest b/manifest index c4eeee5ecd..c28c4a8667 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C In\sdefensive\smode,\sallow\sstatements\sthat\swrite\sto\sshadow\stables\sto\sbe\sprepared\sfrom\swith\svirtual-table\sxSync()\scalls. -D 2021-07-19T14:00:29.519 +C Updates\sso\sthat\s"threadtest3[.exe]"\scan\sbe\sbuilt\sfor\swindows\swith\sMSVC. +D 2021-07-19T16:49:13.643 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F Makefile.in 83c348515cb62f6f2a2ddf3fd014113ff20564b776e1a614079722c88c6ff43d F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241 -F Makefile.msc f889e0dcf8668cccac0c68be2ea09fc585dd40ac44ca37e9fb15638ee9315a92 +F Makefile.msc be23161cf225f0574c34b866ade20824bef4e5473e924e0941fe954ccb253286 F README.md 27fb76aa7eb57ed63a53bbba7292b6bf71f51125554f79f16b5d040edd1e6110 F VERSION c6595fef606851f2bc3ebed6a7386c73751835fc909feab7c093739fa4b3c1d1 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -1465,7 +1465,7 @@ F test/thread2.test f35d2106452b77523b3a2b7d1dcde2e5ee8f9e46 F test/thread_common.tcl 334639cadcb9f912bf82aa73f49efd5282e6cadd F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b F test/threadtest2.c a70a8e94bef23339d34226eb9521015ef99f4df8 -F test/threadtest3.c e63013af10cf236c7610eb06d33bde08c861806dc64be811940ff4d9ddd34a4f +F test/threadtest3.c fee869dba633f8403a7eef03bb038a3fc45f0814b9f829ea79a914fcc11f0218 F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925 F test/threadtest5.c 9b4d782c58d8915d7e955ff8051f3d03628bda0d33b82971ea8c0f2f2808c421 F test/time-wordcount.sh 8e0b0f8109367827ad5d58f5cc849705731e4b90 @@ -1639,7 +1639,7 @@ F test/triggerF.test 5d76f0a8c428ff87a4d5ed52da06f6096a2c787a1e21b846111dfac4123 F test/triggerG.test 2b816093c91ba73c733cfa8aedcc210ad819d72a98b1da30768a3c56505233e9 F test/triggerupfrom.test d1f9e56090408115c522bee626cc33a2f3370f627a5e341d832589d72e3aa271 F test/trustschema1.test 4e970aef0bfe0cee139703cc7209d0e0f07725d999b180ba50770f49edef1494 -F test/tt3_checkpoint.c 9e75cf7c1c364f52e1c47fd0f14c4340a9db0fe1 +F test/tt3_checkpoint.c ac7ca661d739280c89d9c253897df64a59a49369bd1247207ac0f655b622579d F test/tt3_index.c 39eec10a35f57672225be4d182862152896dee4a F test/tt3_lookaside1.c 0377e202c3c2a50d688cb65ba203afeda6fafeb9 F test/tt3_shared.c b37d22defc944a2ac4c91c927fd06c1d48cd51e2ce9d004fe868625bd2399f93 @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d78c272b3966cc1b12bc7e83fbe909a3c517d553a942d7f1c07bddf69f2e2164 -R db28e0ca4ea83a622e82068e2a2a636b +P c8601d83fbecf84ca7991d339449b380deb5a7620dc84756a91c2880f030b423 +R e7c3798c4e8afbc59f637b8a384b4003 U dan -Z 8b08dd57f21b0e772cbc6de26df5a8fe +Z 4507211c89102df26f9a64f266826b29 diff --git a/manifest.uuid b/manifest.uuid index 7e93b98bd8..7723021063 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c8601d83fbecf84ca7991d339449b380deb5a7620dc84756a91c2880f030b423 \ No newline at end of file +4ce585fb07274284e3add6adcb66ed06e4b109584704d1ec7152bf43ca8d5d85 \ No newline at end of file diff --git a/test/threadtest3.c b/test/threadtest3.c index 41c0fb9ac6..f427324a23 100644 --- a/test/threadtest3.c +++ b/test/threadtest3.c @@ -78,15 +78,31 @@ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include + +#ifdef _WIN32 +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#else +# include +# include +# include +# include +# include +# include +# include +# include +# include + +# define O_BINARY 0 +#endif #include "test_multiplex.h" @@ -436,8 +452,13 @@ struct Thread { int iTid; /* Thread number within test */ void* pArg; /* Pointer argument passed by caller */ +#ifdef _WIN32 + uintptr_t winTid; /* Thread handle */ +#else pthread_t tid; /* Thread id */ +#endif char *(*xProc)(int, void*); /* Thread main proc */ + char *zRes; /* Value returned by xProc */ Thread *pNext; /* Next in this list of threads */ }; @@ -471,9 +492,13 @@ static void print_and_free_err(Error *p){ static void system_error(Error *pErr, int iSys){ pErr->rc = iSys; +#if _WIN32 + pErr->zErr = sqlite3_mprintf("%s", strerror(iSys)); +#else pErr->zErr = (char *)sqlite3_malloc(512); strerror_r(iSys, pErr->zErr, 512); pErr->zErr[511] = '\0'; +#endif } static void sqlite_error( @@ -512,7 +537,7 @@ static void clear_error_x( } static int busyhandler(void *pArg, int n){ - usleep(10*1000); + sqlite3_sleep(10); return 1; } @@ -749,10 +774,20 @@ static void integrity_check_x( } } +#ifdef _WIN32 +static unsigned __stdcall launch_thread_main(void *pArg){ + Thread *p = (Thread *)pArg; + p->zRes = p->xProc(p->iTid, p->pArg); + _endthreadex(0); + return 0; /* NOT REACHED */ +} +#else static void *launch_thread_main(void *pArg){ Thread *p = (Thread *)pArg; - return (void *)p->xProc(p->iTid, p->pArg); + p->zRes = p->xProc(p->iTid, p->pArg); + return 0; } +#endif static void launch_thread_x( Error *pErr, /* IN/OUT: Error code */ @@ -771,7 +806,13 @@ static void launch_thread_x( p->pArg = pArg; p->xProc = xProc; +#ifdef _WIN32 + rc = SQLITE_OK; + p->winTid = _beginthreadex(0, 0, launch_thread_main, (void*)p, 0, 0); + if( p->winTid==0 ) rc = errno ? errno : rc; +#else rc = pthread_create(&p->tid, NULL, launch_thread_main, (void *)p); +#endif if( rc!=0 ){ system_error(pErr, rc); sqlite3_free(p); @@ -790,28 +831,44 @@ static void join_all_threads_x( Thread *pNext; for(p=pThreads->pThread; p; p=pNext){ void *ret; - pNext = p->pNext; int rc; + pNext = p->pNext; + +#ifdef _WIN32 + do { + rc = WaitForSingleObjectEx((HANDLE)p->winTid, INFINITE, TRUE); + }while( rc==WAIT_IO_COMPLETION ); + CloseHandle((HANDLE)p->winTid); +#else rc = pthread_join(p->tid, &ret); +#endif + if( rc!=0 ){ if( pErr->rc==SQLITE_OK ) system_error(pErr, rc); }else{ - printf("Thread %d says: %s\n", p->iTid, (ret==0 ? "..." : (char *)ret)); + printf("Thread %d says: %s\n", p->iTid, (p->zRes==0 ? "..." : p->zRes)); fflush(stdout); } + sqlite3_free(p->zRes); sqlite3_free(p); } pThreads->pThread = 0; } +#ifdef _WIN32 +# define THREADTEST3_STAT _stat +#else +# define THREADTEST3_STAT stat +#endif + static i64 filesize_x( Error *pErr, const char *zFile ){ i64 iRet = 0; if( pErr->rc==SQLITE_OK ){ - struct stat sStat; - if( stat(zFile, &sStat) ){ + struct THREADTEST3_STAT sStat; + if( THREADTEST3_STAT(zFile, &sStat) ){ iRet = -1; }else{ iRet = sStat.st_size; @@ -836,12 +893,12 @@ static void filecopy_x( int fd2; unlink(zTo); - fd1 = open(zFrom, O_RDONLY); + fd1 = open(zFrom, O_RDONLY|O_BINARY); if( fd1<0 ){ system_error(pErr, errno); return; } - fd2 = open(zTo, O_RDWR|O_CREAT|O_EXCL, 0644); + fd2 = open(zTo, O_RDWR|O_CREAT|O_EXCL|O_BINARY, 0644); if( fd2<0 ){ system_error(pErr, errno); close(fd1); @@ -967,7 +1024,7 @@ static char *walthread1_ckpt_thread(int iTid, void *pArg){ opendb(&err, &db, "test.db", 0); while( !timetostop(&err) ){ - usleep(500*1000); + sqlite3_sleep(500); execsql(&err, &db, "PRAGMA wal_checkpoint"); if( err.rc==SQLITE_OK ) nCkpt++; clear_error(&err, SQLITE_BUSY); @@ -1415,7 +1472,7 @@ static void dynamic_triggers(int nMs){ launch_thread(&err, &threads, dynamic_triggers_2, 0); launch_thread(&err, &threads, dynamic_triggers_2, 0); - sleep(2); + sqlite3_sleep(2*1000); sqlite3_enable_shared_cache(0); launch_thread(&err, &threads, dynamic_triggers_2, 0); diff --git a/test/tt3_checkpoint.c b/test/tt3_checkpoint.c index 060a698211..ec9d0727e6 100644 --- a/test/tt3_checkpoint.c +++ b/test/tt3_checkpoint.c @@ -75,7 +75,7 @@ static char *checkpoint_starvation_reader(int iTid, void *pArg){ i64 iCount1, iCount2; sql_script(&err, &db, "BEGIN"); iCount1 = execsql_i64(&err, &db, "SELECT count(x) FROM t1"); - usleep(CHECKPOINT_STARVATION_READMS*1000); + sqlite3_sleep(CHECKPOINT_STARVATION_READMS); iCount2 = execsql_i64(&err, &db, "SELECT count(x) FROM t1"); sql_script(&err, &db, "COMMIT"); @@ -107,7 +107,7 @@ static void checkpoint_starvation_main(int nMs, CheckpointStarvationCtx *p){ for(i=0; i<4; i++){ launch_thread(&err, &threads, checkpoint_starvation_reader, 0); - usleep(CHECKPOINT_STARVATION_READMS*1000/4); + sqlite3_sleep(CHECKPOINT_STARVATION_READMS/4); } sqlite3_wal_hook(db.db, checkpoint_starvation_walhook, (void *)p); From de3246176bcce89de803ae298afd455648a6a57f Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 19 Jul 2021 20:52:31 +0000 Subject: [PATCH 21/49] More precision in comparing integers and floating point values while processing the integer primary key for OP_SeekGE and similar. [forum:/forumpost/2bdb86a068|Forum post 2bdb86a068]. FossilOrigin-Name: f9c6426de3b413ff8fcf04a00931ca5f123f996c572b35181af114afa8d811d7 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/vdbe.c | 8 +++++--- src/vdbeInt.h | 1 + src/vdbeaux.c | 2 +- test/where.test | 15 +++++++++++++++ 6 files changed, 33 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index c28c4a8667..7bb2b8c7ad 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Updates\sso\sthat\s"threadtest3[.exe]"\scan\sbe\sbuilt\sfor\swindows\swith\sMSVC. -D 2021-07-19T16:49:13.643 +C More\sprecision\sin\scomparing\sintegers\sand\sfloating\spoint\svalues\swhile\nprocessing\sthe\sinteger\sprimary\skey\sfor\sOP_SeekGE\sand\ssimilar.\n[forum:/forumpost/2bdb86a068|Forum\spost\s2bdb86a068]. +D 2021-07-19T20:52:31.773 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -616,11 +616,11 @@ F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 41c7a72da1df47864faa378a1c720b38adb288c6838cb6be5594511b6287a048 F src/vacuum.c 454973a59fb20bb982efc2df568a098616db6328a0491b6e84e2e07f7333db45 -F src/vdbe.c 27149413d6b09684b83746eb8f26210baf50eb23925b64261b6d93119a218435 +F src/vdbe.c b73a5ec9940185eb001ff8cff2cfd429bb438c7e89f2885e0bfdb56c3ff13386 F src/vdbe.h 25dabb25c7e157b84e59260cfb5b466c3ac103ede9f36f4db371332c47601abe -F src/vdbeInt.h 1fc1e3581afcd3f56bdbe930639edac84ee823c034f31da97f49c35522f4c8c2 +F src/vdbeInt.h 38206c8dd6b60ff03d9fd4f626b1b4fd0eef7cdc44f2fc2c1973b0f932a3f26b F src/vdbeapi.c aa5aaf2c37676b83af5724c6cd8207a3064ed46a217fd180957f75ac84f7a2a5 -F src/vdbeaux.c 23f9800742b11eb6d1d775fd332a88252e44e9f7ba94b826e211a5d9dbfe0ced +F src/vdbeaux.c 564622045316eb2eed1370714426e81ab96d86e7894a368e80a83e0baff23346 F src/vdbeblob.c c6b8db50b227f66fb404215732068df76485b5b433e5f9d4d9ac27410b218193 F src/vdbemem.c 53881aa0a7845922a075b3f375695588618098871a7a4120af4c297b80fa3e64 F src/vdbesort.c cd5130f683706c1a43e165a74187745fb3351cb56052cf9dc91de820634bbde2 @@ -1746,7 +1746,7 @@ F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2a F test/walvfs.test bccb3e0d235ef85e276f491d34db32c9ada1ea67be8d9f10aabe7b30319ec656 F test/wapp.tcl b440cd8cf57953d3a49e7ee81e6a18f18efdaf113b69f7d8482b0710a64566ec F test/wapptest.tcl 899594e25684861d5b0c0880fb012364def50ef8097041b8ddf74be5ba7fa270 x -F test/where.test 4f7a3939e5190845ef42142031a1819070f65e065e6a840a09adc54dccfef01f +F test/where.test 0be35396a509439d1c38919381feaed3d1e820e08254d246f96e499c5cbf8565 F test/where2.test 03c21a11e7b90e2845fc3c8b4002fc44cc2797fa74c86ee47d70bd7ea4f29ed6 F test/where3.test 5b4ffc0ac2ea0fe92f02b1244b7531522fe4d7bccf6fa8741d54e82c10e67753 F test/where4.test 4a371bfcc607f41d233701bdec33ac2972908ba8 @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c8601d83fbecf84ca7991d339449b380deb5a7620dc84756a91c2880f030b423 -R e7c3798c4e8afbc59f637b8a384b4003 -U dan -Z 4507211c89102df26f9a64f266826b29 +P 4ce585fb07274284e3add6adcb66ed06e4b109584704d1ec7152bf43ca8d5d85 +R 000488406edbffc8806e75458a922494 +U drh +Z 26015d8f2da64898ae34fc3a47735d30 diff --git a/manifest.uuid b/manifest.uuid index 7723021063..bfd7a78e8b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4ce585fb07274284e3add6adcb66ed06e4b109584704d1ec7152bf43ca8d5d85 \ No newline at end of file +f9c6426de3b413ff8fcf04a00931ca5f123f996c572b35181af114afa8d811d7 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 5b42976a0e..cfcd62266a 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4275,6 +4275,7 @@ case OP_SeekGT: { /* jump, in3, group */ /* If the P3 value could not be converted into an integer without ** loss of information, then special processing is required... */ if( (newType & (MEM_Int|MEM_IntReal))==0 ){ + int c; if( (newType & MEM_Real)==0 ){ if( (newType & MEM_Null) || oc>=OP_SeekGE ){ VdbeBranchTaken(1,2); @@ -4284,7 +4285,8 @@ case OP_SeekGT: { /* jump, in3, group */ if( rc!=SQLITE_OK ) goto abort_due_to_error; goto seek_not_found; } - }else + } + c = sqlite3IntFloatCompare(iKey, pIn3->u.r); /* If the approximation iKey is larger than the actual real search ** term, substitute >= for > and < for <=. e.g. if the search term @@ -4293,7 +4295,7 @@ case OP_SeekGT: { /* jump, in3, group */ ** (x > 4.9) -> (x >= 5) ** (x <= 4.9) -> (x < 5) */ - if( pIn3->u.r<(double)iKey ){ + if( c>0 ){ assert( OP_SeekGE==(OP_SeekGT-1) ); assert( OP_SeekLT==(OP_SeekLE-1) ); assert( (OP_SeekLE & 0x0001)==(OP_SeekGT & 0x0001) ); @@ -4302,7 +4304,7 @@ case OP_SeekGT: { /* jump, in3, group */ /* If the approximation iKey is smaller than the actual real search ** term, substitute <= for < and > for >=. */ - else if( pIn3->u.r>(double)iKey ){ + else if( c<0 ){ assert( OP_SeekLE==(OP_SeekLT+1) ); assert( OP_SeekGT==(OP_SeekGE+1) ); assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) ); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 4a41c43a52..763c4ed094 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -533,6 +533,7 @@ int sqlite3VdbeMemIsRowSet(const Mem*); int sqlite3VdbeMemSetRowSet(Mem*); int sqlite3VdbeMemMakeWriteable(Mem*); int sqlite3VdbeMemStringify(Mem*, u8, u8); +int sqlite3IntFloatCompare(i64,double); i64 sqlite3VdbeIntValue(Mem*); int sqlite3VdbeMemIntegerify(Mem*); double sqlite3VdbeRealValue(Mem*); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 7f08b5d25b..5c9ab11c7d 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -4285,7 +4285,7 @@ SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){ ** number. Return negative, zero, or positive if the first (i64) is less than, ** equal to, or greater than the second (double). */ -static int sqlite3IntFloatCompare(i64 i, double r){ +int sqlite3IntFloatCompare(i64 i, double r){ if( sizeof(LONGDOUBLE_TYPE)>8 ){ LONGDOUBLE_TYPE x = (LONGDOUBLE_TYPE)i; testcase( x=0 AND '-1'<=t1.c0 FROM t1; } {1} +# 2021-07-19 https://sqlite.org/forum/forumpost/2bdb86a068 +# Lose of precision when doing comparisons between integer and +# floating point values that are near 9223372036854775807 in the +# OP_SeekGE opcode (and similar). +# +reset_db +do_execsql_test where-27.1 { + CREATE TABLE t1(a INTEGER PRIMARY KEY); + INSERT INTO t1(a) VALUES(9223372036854775807); + SELECT 1 FROM t1 WHERE a>=(9223372036854775807+1); +} {} +do_execsql_test where-27.2 { + SELECT a>=9223372036854775807+1 FROM t1; +} {0} + finish_test From f5b70d06eac76742b052864d25d59caa3d64ce7d Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 20 Jul 2021 00:18:22 +0000 Subject: [PATCH 22/49] Fix compilation of 'threadtest3' for some older versions of MSVC. FossilOrigin-Name: b5ede6a68891820bd5b6d051b1b641bc1cd49104cad2466db184134d14f58f5b --- Makefile.msc | 20 ++++++++++---------- manifest | 18 +++++++++--------- manifest.uuid | 2 +- test/threadtest3.c | 2 ++ test/tt3_vacuum.c | 2 +- 5 files changed, 23 insertions(+), 21 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 57ddbe7854..6a7f2a3a75 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -2586,16 +2586,16 @@ rbu.exe: $(TOP)\ext\rbu\rbu.c $(TOP)\ext\rbu\sqlite3rbu.c $(SQLITE3C) $(SQLITE3H $(LTLINK) $(NO_WARN) -DSQLITE_ENABLE_RBU \ $(TOP)\ext\rbu\rbu.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) +THREADTEST3_SRC = \ + $(TOP)\test\threadtest3.c \ + $(TOP)\test\tt3_checkpoint.c \ + $(TOP)\test\tt3_index.c \ + $(TOP)\test\tt3_vacuum.c \ + $(TOP)\test\tt3_stress.c \ + $(TOP)\test\tt3_lookaside1.c -THREADTEST3_SRC = $(TOP)\test\threadtest3.c \ - $(TOP)\test\tt3_checkpoint.c \ - $(TOP)\test\tt3_index.c \ - $(TOP)\test\tt3_vacuum.c \ - $(TOP)\test\tt3_stress.c \ - $(TOP)\test\tt3_lookaside1.c - -threadtest3.exe: sqlite3.obj $(THREADTEST3_SRC) $(TOP)/src/test_multiplex.c - $(LTLINK) $(TOP)\test\threadtest3.c $(TOP)\src\test_multiplex.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) +threadtest3.exe: $(THREADTEST3_SRC) $(TOP)\src\test_multiplex.c $(SQLITE3C) $(SQLITE3H) + $(LTLINK) $(NO_WARN) $(TOP)\test\threadtest3.c $(TOP)\src\test_multiplex.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) LSMDIR=$(TOP)\ext\lsm1 !INCLUDE $(LSMDIR)\Makefile.msc @@ -2634,7 +2634,7 @@ clean: del /Q sqlite-*-output.vsix 2>NUL del /Q fuzzershell.exe fuzzcheck.exe sqldiff.exe dbhash.exe 2>NUL del /Q sqltclsh.* 2>NUL - del /Q dbfuzz.exe sessionfuzz.exe 2>NUL + del /Q dbfuzz.exe sessionfuzz.exe threadtest3.exe 2>NUL del /Q kvtest.exe ossshell.exe scrub.exe 2>NUL del /Q showshm.exe sqlite3_checker.* sqlite3_expert.exe 2>NUL del /Q fts5.* fts5parse.* 2>NUL diff --git a/manifest b/manifest index 7bb2b8c7ad..7a8f5db481 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C More\sprecision\sin\scomparing\sintegers\sand\sfloating\spoint\svalues\swhile\nprocessing\sthe\sinteger\sprimary\skey\sfor\sOP_SeekGE\sand\ssimilar.\n[forum:/forumpost/2bdb86a068|Forum\spost\s2bdb86a068]. -D 2021-07-19T20:52:31.773 +C Fix\scompilation\sof\s'threadtest3'\sfor\ssome\solder\sversions\sof\sMSVC. +D 2021-07-20T00:18:22.983 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F Makefile.in 83c348515cb62f6f2a2ddf3fd014113ff20564b776e1a614079722c88c6ff43d F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241 -F Makefile.msc be23161cf225f0574c34b866ade20824bef4e5473e924e0941fe954ccb253286 +F Makefile.msc 7dc32ba195639311ef4fa3d8f8ec218de37fde12d7ef5a33e9a7de921b0025ca F README.md 27fb76aa7eb57ed63a53bbba7292b6bf71f51125554f79f16b5d040edd1e6110 F VERSION c6595fef606851f2bc3ebed6a7386c73751835fc909feab7c093739fa4b3c1d1 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -1465,7 +1465,7 @@ F test/thread2.test f35d2106452b77523b3a2b7d1dcde2e5ee8f9e46 F test/thread_common.tcl 334639cadcb9f912bf82aa73f49efd5282e6cadd F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b F test/threadtest2.c a70a8e94bef23339d34226eb9521015ef99f4df8 -F test/threadtest3.c fee869dba633f8403a7eef03bb038a3fc45f0814b9f829ea79a914fcc11f0218 +F test/threadtest3.c 655bff6c0895ec03f014126aa65e808fac9aae8c5a7a7da58a510cbe8b43b781 F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925 F test/threadtest5.c 9b4d782c58d8915d7e955ff8051f3d03628bda0d33b82971ea8c0f2f2808c421 F test/time-wordcount.sh 8e0b0f8109367827ad5d58f5cc849705731e4b90 @@ -1644,7 +1644,7 @@ F test/tt3_index.c 39eec10a35f57672225be4d182862152896dee4a F test/tt3_lookaside1.c 0377e202c3c2a50d688cb65ba203afeda6fafeb9 F test/tt3_shared.c b37d22defc944a2ac4c91c927fd06c1d48cd51e2ce9d004fe868625bd2399f93 F test/tt3_stress.c f9a769ca8b026ecc76ee93ca8c9700a5619f8e51c581107c4053ba6ac97f616f -F test/tt3_vacuum.c 1753f45917699c9c1f66b64c717a717c9379f776 +F test/tt3_vacuum.c 71b254cde1fc49d6c8c44efd54f4668f3e57d7b3a8f4601ade069f75a999ba39 F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff F test/types2.test 1aeb81976841a91eef292723649b5c4fe3bc3cac F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4ce585fb07274284e3add6adcb66ed06e4b109584704d1ec7152bf43ca8d5d85 -R 000488406edbffc8806e75458a922494 -U drh -Z 26015d8f2da64898ae34fc3a47735d30 +P f9c6426de3b413ff8fcf04a00931ca5f123f996c572b35181af114afa8d811d7 +R 4a4b4d7f4609ee7ad98f970aafca21aa +U mistachkin +Z d79e981ec4950b9bac6d5abcb02f1221 diff --git a/manifest.uuid b/manifest.uuid index bfd7a78e8b..7fc59ca525 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f9c6426de3b413ff8fcf04a00931ca5f123f996c572b35181af114afa8d811d7 \ No newline at end of file +b5ede6a68891820bd5b6d051b1b641bc1cd49104cad2466db184134d14f58f5b \ No newline at end of file diff --git a/test/threadtest3.c b/test/threadtest3.c index f427324a23..3a12c5889b 100644 --- a/test/threadtest3.c +++ b/test/threadtest3.c @@ -830,7 +830,9 @@ static void join_all_threads_x( Thread *p; Thread *pNext; for(p=pThreads->pThread; p; p=pNext){ +#ifndef _WIN32 void *ret; +#endif int rc; pNext = p->pNext; diff --git a/test/tt3_vacuum.c b/test/tt3_vacuum.c index 023fdfd74d..c41a6b487d 100644 --- a/test/tt3_vacuum.c +++ b/test/tt3_vacuum.c @@ -23,9 +23,9 @@ static char *vacuum1_thread_writer(int iTid, void *pArg){ Error err = {0}; /* Error code and message */ Sqlite db = {0}; /* SQLite database connection */ - opendb(&err, &db, "test.db", 0); i64 i = 0; + opendb(&err, &db, "test.db", 0); while( !timetostop(&err) ){ i++; From 53fa02507b2025db7b74a155c8df4a8a2e4db4d8 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 20 Jul 2021 02:02:24 +0000 Subject: [PATCH 23/49] It does not work to deserialized into TEMP, so do not allow it. The sqlite3_deserialize() routine now returns SQLITE_ERROR if you try. FossilOrigin-Name: 18068cc60698d4944a9d682cdf34b14b4d4b32f043f8d584dbf41c2bb5ac6220 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/memdb.c | 5 +++-- src/sqlite.h.in | 4 ++++ test/memdb1.test | 16 ++++++++++++++++ 5 files changed, 33 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 7a8f5db481..fed613db3a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\scompilation\sof\s'threadtest3'\sfor\ssome\solder\sversions\sof\sMSVC. -D 2021-07-20T00:18:22.983 +C It\sdoes\snot\swork\sto\sdeserialized\sinto\sTEMP,\sso\sdo\snot\sallow\sit.\s\sThe\nsqlite3_deserialize()\sroutine\snow\sreturns\sSQLITE_ERROR\sif\syou\stry. +D 2021-07-20T02:02:24.771 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -515,7 +515,7 @@ F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de F src/mem2.c b93b8762ab999a29ae7751532dadf0a1ac78040308a5fb1d17fcc365171d67eb F src/mem3.c 30301196cace2a085cbedee1326a49f4b26deff0af68774ca82c1f7c06fda4f6 F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944 -F src/memdb.c 2f2e8efc6e531c59cf8255f0bf4ad81f2e88e0a394581244154c8cf5141757ce +F src/memdb.c 73622017aa03a3cabd1c4d6fca97eedada2155817dd0d74d6c1aeb42573b515d F src/memjournal.c a85f0dc5c02a42453d0bc3819ecfb5666cb6433e5deefcd93ccbe05c9f088b83 F src/msvc.h 3a15918220367a8876be3fa4f2abe423a861491e84b864fb2b7426bf022a28f8 F src/mutex.c 5e3409715552348732e97b9194abe92fdfcd934cfb681df4ba0ab87ac6c18d25 @@ -546,7 +546,7 @@ F src/resolve.c ea205123fba6bb254666f50b6c220270913eae54eb03d263abaa432c703f5857 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 0c783511b5f35b37d971dcd653c554d21f74d7cb63a4979991a61d068480c40f F src/shell.c.in 856de2945bb7fdfdeebe7136cf1b59d24618845aa5e5f3937fda7ff37c623b51 -F src/sqlite.h.in f716b8a9fb30c6928752fd75b3f824e8ac4d225d31494029dee8454aeb9aa01a +F src/sqlite.h.in 43fcf0fe2af04081f420a906fc020bde1243851ba44b0aa567a27f94bf8c3145 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510 F src/sqliteInt.h b3762f49d8b6b4bf7bf30d154f007d6f9421c86343042d7a246a79988d1fec1a @@ -1191,7 +1191,7 @@ F test/malloctraceviewer.tcl b7a54595270c1d201abf1c3f3d461f27eaf24cdef623ad08a0f F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f F test/memdb.test c1f2a343ad14398d5d6debda6ea33e80d0dafcc7 -F test/memdb1.test 7b76c3262d63c46dd6b408d18f5721071776f2df4ffeb11e668824e427127594 +F test/memdb1.test 1705e850e32969b61e19cbbc9d8a3ba3ba310092812d10948b8303394bf00f40 F test/memjournal.test 70f3a00c7f84ee2978ad14e831231caa1e7f23915a2c54b4f775a021d5740c6c F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2 F test/memsubsys1.test 9e7555a22173b8f1c96c281ce289b338fcba2abe8b157f8798ca195bbf1d347e @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f9c6426de3b413ff8fcf04a00931ca5f123f996c572b35181af114afa8d811d7 -R 4a4b4d7f4609ee7ad98f970aafca21aa -U mistachkin -Z d79e981ec4950b9bac6d5abcb02f1221 +P b5ede6a68891820bd5b6d051b1b641bc1cd49104cad2466db184134d14f58f5b +R e22cd931ae144bced3e3587611f0e114 +U drh +Z b4c2ab277c13106aeed921dd3a580a07 diff --git a/manifest.uuid b/manifest.uuid index 7fc59ca525..dd0503215c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b5ede6a68891820bd5b6d051b1b641bc1cd49104cad2466db184134d14f58f5b \ No newline at end of file +18068cc60698d4944a9d682cdf34b14b4d4b32f043f8d584dbf41c2bb5ac6220 \ No newline at end of file diff --git a/src/memdb.c b/src/memdb.c index 4e5751f931..dc29a2db7f 100644 --- a/src/memdb.c +++ b/src/memdb.c @@ -809,10 +809,11 @@ int sqlite3_deserialize( sqlite3_mutex_enter(db->mutex); if( zSchema==0 ) zSchema = db->aDb[0].zDbSName; iDb = sqlite3FindDbName(db, zSchema); - if( iDb<0 ){ + testcase( iDb==1 ); + if( iDb<2 && iDb!=0 ){ rc = SQLITE_ERROR; goto end_deserialize; - } + } zSql = sqlite3_mprintf("ATTACH x AS %Q", zSchema); if( zSql==0 ){ rc = SQLITE_NOMEM; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 3ac46fb55a..e4ea66a725 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -9923,6 +9923,10 @@ unsigned char *sqlite3_serialize( ** database is currently in a read transaction or is involved in a backup ** operation. ** +** It is not possible to deserialized into the TEMP database. If the +** S argument to sqlite3_deserialize(D,S,P,N,M,F) is "temp" then the +** function returns SQLITE_ERROR. +** ** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the ** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then ** [sqlite3_free()] is invoked on argument P prior to returning. diff --git a/test/memdb1.test b/test/memdb1.test index ae2f5d50d1..93b638feaa 100644 --- a/test/memdb1.test +++ b/test/memdb1.test @@ -195,6 +195,22 @@ do_test 620 { lappend rc $msg } {1 {wrong # args: should be "db serialize ?DATABASE?"}} +# 2021-07-19 https://sqlite.org/forum/forumpost/e1cbb5f450b98aa6 +# The TEMP database cannot participate in serialization or +# deserialization. +# +reset_db +do_test 650 { + db eval { + CREATE TEMP TABLE t0(a); + CREATE TABLE t1(x); + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<1000) + INSERT INTO t1(x) SELECT random() FROM c; + } + set rc [catch {db deserialize temp [db serialize main]} err] + lappend rc err +} {1 err} + #------------------------------------------------------------------------- ifcapable vtab { reset_db From b4d9b2b5376e6c6605933a7b9904c795235ff3ff Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 20 Jul 2021 07:35:07 +0000 Subject: [PATCH 24/49] Demonstration code to show how NOT NULL and CHECK constraints can be verified after an ALTER TABLE ADD COLUMN. FossilOrigin-Name: 039f540373b03af9e0c87499e5e0423eb093d1d343829282a5ac1de2d600b881 --- manifest | 23 +++++++++++++---------- manifest.uuid | 2 +- src/alter.c | 29 ++++++++++++++++++++++------- src/build.c | 1 + src/pragma.h | 4 ++-- src/sqliteInt.h | 3 ++- tool/mkpragmatab.tcl | 4 ++-- 7 files changed, 43 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index fed613db3a..e3d642bf01 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C It\sdoes\snot\swork\sto\sdeserialized\sinto\sTEMP,\sso\sdo\snot\sallow\sit.\s\sThe\nsqlite3_deserialize()\sroutine\snow\sreturns\sSQLITE_ERROR\sif\syou\stry. -D 2021-07-20T02:02:24.771 +C Demonstration\scode\sto\sshow\show\sNOT\sNULL\sand\sCHECK\sconstraints\scan\sbe\nverified\safter\san\sALTER\sTABLE\sADD\sCOLUMN. +D 2021-07-20T07:35:07.295 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -478,7 +478,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 774a2a175ec747b55046ec62f5c1208d730ee22b10bdad5f182591fa247946a8 +F src/alter.c 1589ea8a5dcef74e12b49182928062cbd2958cc223004bb6d534e44521c59d0a F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c F src/attach.c a514e81758ba7b3a3a0501faf70af6cfc509de8810235db726cfc9f25165e929 F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 @@ -488,7 +488,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c e204a9c8fb4fe5dbb910a863ba487f4af9b5c501254ec4ccbfcdd6b1f65b7fb4 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0 -F src/build.c a27511863001ba088afd5e19efc9c37ea660983bd6ddf012def10f6cc4456a01 +F src/build.c 602ab2f5b49df357a70ac4ff64bc6cc23effd97a6ae16b60e947f5ab25866f44 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 8159d5f706551861c18ec6c8f6bdf105e15ea00367f05d9ab65d31a1077facc1 @@ -538,7 +538,7 @@ F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 388304fd2d91c39591080b5e0f3c62cfba87db20370e7e0554062bfb29740e9f F src/pragma.c 9fe75aa29e8706a2cf6b9c1600ac05a2efc55c44ce719b65aa45d10ff58acc9d -F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf +F src/pragma.h a11b4798f9c49f156f130e1f7041a9fcc9d316a64f3501b6013acdd2e4c6f549 F src/prepare.c 0d53d20532aada295c1690792a125adbd6435f5ce703ff0adf1b9b3605238b67 F src/printf.c 78fabb49b9ac9a12dd1c89d744abdc9b67fd3205e62967e158f78b965a29ec4b F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c @@ -549,7 +549,7 @@ F src/shell.c.in 856de2945bb7fdfdeebe7136cf1b59d24618845aa5e5f3937fda7ff37c623b5 F src/sqlite.h.in 43fcf0fe2af04081f420a906fc020bde1243851ba44b0aa567a27f94bf8c3145 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510 -F src/sqliteInt.h b3762f49d8b6b4bf7bf30d154f007d6f9421c86343042d7a246a79988d1fec1a +F src/sqliteInt.h 0982664df2e04968d9588535efa0f3987a7f23fb6d6872f0a7a0c5fa97e53933 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1853,7 +1853,7 @@ F tool/mkmsvcmin.tcl 6ecab9fe22c2c8de4d82d4c46797bda3d2deac8e763885f5a38d0c44a89 F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl 130b88697da6ec5b89b41844d955d08fb62c2552e889dec8c7bcecb28d8f50bd F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa -F tool/mkpragmatab.tcl ae5585ae76ca26e4d6ccd5ea9cdebaf5efefb318bf989497a0e846cd711d9ab1 +F tool/mkpragmatab.tcl 7f6db47d1995bc08247255622524567b2ab8962d98063f8aef97e35c3c54e3b8 F tool/mkshellc.tcl 5fe7e518112b262e25726f248c0f33dd153192867453984b6af0a76a88e97cb2 F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 @@ -1920,7 +1920,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b5ede6a68891820bd5b6d051b1b641bc1cd49104cad2466db184134d14f58f5b -R e22cd931ae144bced3e3587611f0e114 +P 18068cc60698d4944a9d682cdf34b14b4d4b32f043f8d584dbf41c2bb5ac6220 +R 32477a4a8d73756ec29530de57bdffab +T *branch * add-column-constraint-check +T *sym-add-column-constraint-check * +T -sym-trunk * U drh -Z b4c2ab277c13106aeed921dd3a580a07 +Z 445808b8851b3290a628722ea679d598 diff --git a/manifest.uuid b/manifest.uuid index dd0503215c..e3d6c1ab6a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -18068cc60698d4944a9d682cdf34b14b4d4b32f043f8d584dbf41c2bb5ac6220 \ No newline at end of file +039f540373b03af9e0c87499e5e0423eb093d1d343829282a5ac1de2d600b881 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index f998b893c2..7b313dae46 100644 --- a/src/alter.c +++ b/src/alter.c @@ -427,12 +427,12 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ db->mDbFlags = savedDbFlags; } - /* Make sure the schema version is at least 3. But do not upgrade - ** from less than 3 to 4, as that will corrupt any preexisting DESC - ** index. - */ v = sqlite3GetVdbe(pParse); if( v ){ + /* Make sure the schema version is at least 3. But do not upgrade + ** from less than 3 to 4, as that will corrupt any preexisting DESC + ** index. + */ r1 = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT); sqlite3VdbeUsesBtree(v, iDb); @@ -441,10 +441,25 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3); sqlite3ReleaseTempReg(pParse, r1); - } - /* Reload the table definition */ - renameReloadSchema(pParse, iDb, INITFLAG_AlterRename); + /* Reload the table definition */ + renameReloadSchema(pParse, iDb, INITFLAG_AlterRename); + + /* Verify that constraints are still satisfied */ + if( pParse->bDiscardCheck + || (pCol->notNull && (pCol->colFlags & COLFLAG_GENERATED)!=0) + ){ + sqlite3NestedParse(pParse, + "SELECT CASE WHEN quick_check GLOB 'CHECK*'" + " THEN raise(ABORT,'CHECK constraint failed')" + " WHEN quick_check GLOB 'NULL*'" + " THEN raise(ABORT,'NOT NULL constraint failed')" + " END" + " FROM pragma_quick_check(\"%w\",\"%w\")", + zTab, zDb + ); + } + } } /* diff --git a/src/build.c b/src/build.c index 4eca21a3f7..c1dea15aaf 100644 --- a/src/build.c +++ b/src/build.c @@ -1769,6 +1769,7 @@ void sqlite3AddCheckConstraint( }else #endif { + pParse->bDiscardCheck = 1; sqlite3ExprDelete(pParse->db, pCheckExpr); } } diff --git a/src/pragma.h b/src/pragma.h index be99befb2a..fe3cdf1e32 100644 --- a/src/pragma.h +++ b/src/pragma.h @@ -370,7 +370,7 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_INTEGRITY_CHECK) {/* zName: */ "integrity_check", /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, - /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1|PragFlg_SchemaOpt, /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif @@ -478,7 +478,7 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_INTEGRITY_CHECK) {/* zName: */ "quick_check", /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, - /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1|PragFlg_SchemaOpt, /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 651116aa9e..420698830b 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3437,7 +3437,8 @@ struct Parse { Vdbe *pVdbe; /* An engine for executing database bytecode */ int rc; /* Return code from execution */ u8 colNamesSet; /* TRUE after OP_ColumnName has been issued to pVdbe */ - u8 checkSchema; /* Causes schema cookie check after an error */ + u8 checkSchema : 1; /* Causes schema cookie check after an error */ + u8 bDiscardCheck :1; /* A CHECK constraint was discarded by the parser */ u8 nested; /* Number of nested calls to the parser/code generator */ u8 nTempReg; /* Number of temporary registers in aTempReg[] */ u8 isMultiWrite; /* True if statement may modify/insert multiple rows */ diff --git a/tool/mkpragmatab.tcl b/tool/mkpragmatab.tcl index 7c15765631..b24706ab95 100644 --- a/tool/mkpragmatab.tcl +++ b/tool/mkpragmatab.tcl @@ -304,12 +304,12 @@ set pragma_def { IF: !defined(SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA) NAME: integrity_check - FLAG: NeedSchema Result0 Result1 + FLAG: NeedSchema Result0 Result1 SchemaOpt IF: !defined(SQLITE_OMIT_INTEGRITY_CHECK) NAME: quick_check TYPE: INTEGRITY_CHECK - FLAG: NeedSchema Result0 Result1 + FLAG: NeedSchema Result0 Result1 SchemaOpt IF: !defined(SQLITE_OMIT_INTEGRITY_CHECK) NAME: encoding From 0f91a5352b7bb81beb27306d44ad630f3fd9d3cc Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 20 Jul 2021 08:23:54 +0000 Subject: [PATCH 25/49] Fix issues in the new ADD COLUMN constraint checking. Add preliminary test cases. FossilOrigin-Name: 48434ad3fa9504c063d812d119bc8f622548fd02b3d478ff247b11474c4ce5db --- manifest | 21 +++++++++------------ manifest.uuid | 2 +- src/alter.c | 8 ++++---- src/build.c | 1 - src/sqliteInt.h | 3 +-- test/alter3.test | 49 ++++++++++++++++++++++++++++++++++++++++++++++-- 6 files changed, 62 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index e3d642bf01..9886467871 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Demonstration\scode\sto\sshow\show\sNOT\sNULL\sand\sCHECK\sconstraints\scan\sbe\nverified\safter\san\sALTER\sTABLE\sADD\sCOLUMN. -D 2021-07-20T07:35:07.295 +C Fix\sissues\sin\sthe\snew\sADD\sCOLUMN\sconstraint\schecking.\s\sAdd\spreliminary\ntest\scases. +D 2021-07-20T08:23:54.879 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -478,7 +478,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 1589ea8a5dcef74e12b49182928062cbd2958cc223004bb6d534e44521c59d0a +F src/alter.c 8b6d394cca07e1aa0bd9364111098017dee578e2edad6ce6eb6a0cf78738413c F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c F src/attach.c a514e81758ba7b3a3a0501faf70af6cfc509de8810235db726cfc9f25165e929 F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 @@ -488,7 +488,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c e204a9c8fb4fe5dbb910a863ba487f4af9b5c501254ec4ccbfcdd6b1f65b7fb4 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0 -F src/build.c 602ab2f5b49df357a70ac4ff64bc6cc23effd97a6ae16b60e947f5ab25866f44 +F src/build.c a27511863001ba088afd5e19efc9c37ea660983bd6ddf012def10f6cc4456a01 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 8159d5f706551861c18ec6c8f6bdf105e15ea00367f05d9ab65d31a1077facc1 @@ -549,7 +549,7 @@ F src/shell.c.in 856de2945bb7fdfdeebe7136cf1b59d24618845aa5e5f3937fda7ff37c623b5 F src/sqlite.h.in 43fcf0fe2af04081f420a906fc020bde1243851ba44b0aa567a27f94bf8c3145 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510 -F src/sqliteInt.h 0982664df2e04968d9588535efa0f3987a7f23fb6d6872f0a7a0c5fa97e53933 +F src/sqliteInt.h b3762f49d8b6b4bf7bf30d154f007d6f9421c86343042d7a246a79988d1fec1a F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -645,7 +645,7 @@ F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 F test/all.test 2ecb8bbd52416642e41c9081182a8df05d42c75637afd4488aace78cc4b69e13 F test/alter.test f53d8a4ecd35f051c07e54a36beec5d0a30d30a9d98bc723f6cde6afbfb3c5ca F test/alter2.test a966ccfcddf9ce0a4e0e6ff1aca9e6e7948e0e242cd7e43fc091948521807687 -F test/alter3.test e487958dec7932453e0b83baf21d6b1e71d5e7d9a55bc20eadfa62a51ddffc29 +F test/alter3.test ffc4ab29ce78a3517a66afd69b2730667e3471622509c283b2bd4c46f680fba3 F test/alter4.test 716caa071dd8a3c6d57225778d15d3c3cbf5e34b2e84ae44199aeb2bbf50a707 F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959 F test/alterauth2.test 381b1ab603c9ef96314a3158528ea17f7964449385a28eeaf8191120b2e24a8d @@ -1920,10 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 18068cc60698d4944a9d682cdf34b14b4d4b32f043f8d584dbf41c2bb5ac6220 -R 32477a4a8d73756ec29530de57bdffab -T *branch * add-column-constraint-check -T *sym-add-column-constraint-check * -T -sym-trunk * +P 039f540373b03af9e0c87499e5e0423eb093d1d343829282a5ac1de2d600b881 +R a9df6797ac98d60db9408d8a0375d0a2 U drh -Z 445808b8851b3290a628722ea679d598 +Z 8c3fc1d16a03a8cd3196e7a282e45db6 diff --git a/manifest.uuid b/manifest.uuid index e3d6c1ab6a..b1aa9536fd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -039f540373b03af9e0c87499e5e0423eb093d1d343829282a5ac1de2d600b881 \ No newline at end of file +48434ad3fa9504c063d812d119bc8f622548fd02b3d478ff247b11474c4ce5db \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 7b313dae46..9c5b46261a 100644 --- a/src/alter.c +++ b/src/alter.c @@ -446,16 +446,16 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ renameReloadSchema(pParse, iDb, INITFLAG_AlterRename); /* Verify that constraints are still satisfied */ - if( pParse->bDiscardCheck + if( pNew->pCheck!=0 || (pCol->notNull && (pCol->colFlags & COLFLAG_GENERATED)!=0) ){ sqlite3NestedParse(pParse, "SELECT CASE WHEN quick_check GLOB 'CHECK*'" " THEN raise(ABORT,'CHECK constraint failed')" - " WHEN quick_check GLOB 'NULL*'" - " THEN raise(ABORT,'NOT NULL constraint failed')" + " ELSE raise(ABORT,'NOT NULL constraint failed')" " END" - " FROM pragma_quick_check(\"%w\",\"%w\")", + " FROM pragma_quick_check(\"%w\",\"%w\")" + " WHERE quick_check GLOB 'CHECK*' OR quick_check GLOB 'NULL*'", zTab, zDb ); } diff --git a/src/build.c b/src/build.c index c1dea15aaf..4eca21a3f7 100644 --- a/src/build.c +++ b/src/build.c @@ -1769,7 +1769,6 @@ void sqlite3AddCheckConstraint( }else #endif { - pParse->bDiscardCheck = 1; sqlite3ExprDelete(pParse->db, pCheckExpr); } } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 420698830b..651116aa9e 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3437,8 +3437,7 @@ struct Parse { Vdbe *pVdbe; /* An engine for executing database bytecode */ int rc; /* Return code from execution */ u8 colNamesSet; /* TRUE after OP_ColumnName has been issued to pVdbe */ - u8 checkSchema : 1; /* Causes schema cookie check after an error */ - u8 bDiscardCheck :1; /* A CHECK constraint was discarded by the parser */ + u8 checkSchema; /* Causes schema cookie check after an error */ u8 nested; /* Number of nested calls to the parser/code generator */ u8 nTempReg; /* Number of temporary registers in aTempReg[] */ u8 isMultiWrite; /* True if statement may modify/insert multiple rows */ diff --git a/test/alter3.test b/test/alter3.test index 30bc1cbba2..c6f26b0c50 100644 --- a/test/alter3.test +++ b/test/alter3.test @@ -13,8 +13,6 @@ # file format change that may be used in the future to implement # "ALTER TABLE ... ADD COLUMN". # -# $Id: alter3.test,v 1.11 2008/03/19 00:21:31 drh Exp $ -# set testdir [file dirname $argv0] @@ -395,4 +393,51 @@ do_test alter3-8.2 { } } [list $::sql] +# 2021-07-20: Add support for detecting CHECK and NOT NULL constraint +# violations in ALTER TABLE ADD COLUMN +# +reset_db +do_execsql_test alter3-9.1 { + CREATE TABLE t1(a,b); + INSERT INTO t1 VALUES(1, 2), ('null!',NULL), (3,4); +} {} +do_catchsql_test alter3-9.2 { + ALTER TABLE t1 ADD COLUMN c CHECK(a!=1); +} {1 {CHECK constraint failed}} +do_catchsql_test alter3-9.3 { + ALTER TABLE t1 ADD COLUMN c CHECK(a!=3); +} {1 {CHECK constraint failed}} +do_catchsql_test alter3-9.4 { + ALTER TABLE t1 ADD COLUMN c CHECK(a!=2); +} {0 {}} +do_catchsql_test alter3-9.5 { + ALTER TABLE t1 ADD COLUMN d AS (b+1) NOT NULL; +} {1 {NOT NULL constraint failed}} +do_catchsql_test alter3-9.6 { + ALTER TABLE t1 ADD COLUMN d AS (b+1) NOT NULL CHECK(a!=1); +} {1 {CHECK constraint failed}} +do_catchsql_test alter3-9.7 { + ALTER TABLE t1 ADD COLUMN d AS (b+1) NOT NULL CHECK(a!=3); +} {1 {NOT NULL constraint failed}} + +do_execsql_test alter3-9.10 { + CREATE TEMP TABLE t0(m,n); + INSERT INTO t0 VALUES(1, 2), ('null!',NULL), (3,4); + ATTACH ':memory:' AS aux1; + CREATE TABLE aux1.t2(x,y); + INSERT INTO t2 VALUES(1, 2), ('null!',NULL), (3,4); +} {} +do_catchsql_test alter3-9.11 { + ALTER TABLE t0 ADD COLUMN xtra1 AS (n+1) NOT NULL CHECK(m!=1); +} {1 {CHECK constraint failed}} +do_catchsql_test alter3-9.12 { + ALTER TABLE t0 ADD COLUMN xtra1 AS (n+1) NOT NULL CHECK(m!=3); +} {1 {NOT NULL constraint failed}} +do_catchsql_test alter3-9.13 { + ALTER TABLE t2 ADD COLUMN xtra1 AS (y+1) NOT NULL CHECK(x!=1); +} {1 {CHECK constraint failed}} +do_catchsql_test alter3-9.14 { + ALTER TABLE t2 ADD COLUMN xtra1 AS (y+1) NOT NULL CHECK(x!=3); +} {1 {NOT NULL constraint failed}} + finish_test From d59f98350199898f9448b994766902c7cf0a219c Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 20 Jul 2021 14:57:49 +0000 Subject: [PATCH 26/49] Avoid a malfunction that could occur if the same correlated column reference appears in both the GROUP BY and the HAVING clause of a sub-select. dbsqlfuzz a779227f721a834df95f4f42d0c31550a1f8b8a2. FossilOrigin-Name: 1e35cc6d5c2f563c6bb163bb150d7bc6ede4c993efa828af1face3261bf65a2c --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/select.c | 8 ++++++++ test/aggnested.test | 42 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index fed613db3a..d324909d0d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C It\sdoes\snot\swork\sto\sdeserialized\sinto\sTEMP,\sso\sdo\snot\sallow\sit.\s\sThe\nsqlite3_deserialize()\sroutine\snow\sreturns\sSQLITE_ERROR\sif\syou\stry. -D 2021-07-20T02:02:24.771 +C Avoid\sa\smalfunction\sthat\scould\soccur\sif\sthe\ssame\scorrelated\scolumn\sreference\sappears\sin\sboth\sthe\sGROUP\sBY\sand\sthe\sHAVING\sclause\sof\sa\ssub-select.\sdbsqlfuzz\sa779227f721a834df95f4f42d0c31550a1f8b8a2. +D 2021-07-20T14:57:49.212 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -544,7 +544,7 @@ F src/printf.c 78fabb49b9ac9a12dd1c89d744abdc9b67fd3205e62967e158f78b965a29ec4b F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c ea205123fba6bb254666f50b6c220270913eae54eb03d263abaa432c703f5857 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 0c783511b5f35b37d971dcd653c554d21f74d7cb63a4979991a61d068480c40f +F src/select.c bc9767ab4972c63ca6def53d7b5c8cc8e4df78b63bf51981ae14a82084089a5b F src/shell.c.in 856de2945bb7fdfdeebe7136cf1b59d24618845aa5e5f3937fda7ff37c623b51 F src/sqlite.h.in 43fcf0fe2af04081f420a906fc020bde1243851ba44b0aa567a27f94bf8c3145 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -640,7 +640,7 @@ F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 F test/affinity3.test eecb0dabee4b7765a8465439d5e99429279ffba23ca74a7eae270a452799f9e7 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 -F test/aggnested.test 2f65ec8132e0ca896de550b9908094d49ad65a99116a9d79deeb6017604ad4f6 +F test/aggnested.test cc47afa5e11e0d6771a85a4993fa6ff721480ddb53ea538ec3fdbafb720bd505 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 F test/all.test 2ecb8bbd52416642e41c9081182a8df05d42c75637afd4488aace78cc4b69e13 F test/alter.test f53d8a4ecd35f051c07e54a36beec5d0a30d30a9d98bc723f6cde6afbfb3c5ca @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b5ede6a68891820bd5b6d051b1b641bc1cd49104cad2466db184134d14f58f5b -R e22cd931ae144bced3e3587611f0e114 -U drh -Z b4c2ab277c13106aeed921dd3a580a07 +P 18068cc60698d4944a9d682cdf34b14b4d4b32f043f8d584dbf41c2bb5ac6220 +R facd06e35d967824eff05936c4ae18f7 +U dan +Z 1eb6cf39f57a9c2d1d0141c8c9e6030e diff --git a/manifest.uuid b/manifest.uuid index dd0503215c..8d6dce630e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -18068cc60698d4944a9d682cdf34b14b4d4b32f043f8d584dbf41c2bb5ac6220 \ No newline at end of file +1e35cc6d5c2f563c6bb163bb150d7bc6ede4c993efa828af1face3261bf65a2c \ No newline at end of file diff --git a/src/select.c b/src/select.c index e0ac9db97b..b74999a8f2 100644 --- a/src/select.c +++ b/src/select.c @@ -6019,8 +6019,16 @@ static void explainSimpleCount( static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){ if( pExpr->op!=TK_AND ){ Select *pS = pWalker->u.pSelect; + /* This routine is called before the HAVING clause of the current + ** SELECT is analyzed for aggregates. So if pExpr->pAggInfo is set + ** here, it indicates that the expression is a correlated reference to a + ** column from an outer aggregate query, or an aggregate function that + ** belongs to an outer query. Do not move the expression to the WHERE + ** clause in this obscure case, as doing so may corrupt the outer Select + ** statements AggInfo structure. */ if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, pS->pGroupBy) && ExprAlwaysFalse(pExpr)==0 + && pExpr->pAggInfo==0 ){ sqlite3 *db = pWalker->pParse->db; Expr *pNew = sqlite3Expr(db, TK_INTEGER, "1"); diff --git a/test/aggnested.test b/test/aggnested.test index dcb1f95c99..35d5f1e3a6 100644 --- a/test/aggnested.test +++ b/test/aggnested.test @@ -306,6 +306,48 @@ do_execsql_test 5.5 { b, b; } +#------------------------------------------------------------------------- +# dbsqlfuzz a779227f721a834df95f4f42d0c31550a1f8b8a2 +# +reset_db +do_execsql_test 6.0 { + CREATE TABLE t1(a); + CREATE TABLE t2(b); + + INSERT INTO t1 VALUES('x'); + INSERT INTO t2 VALUES(1); +} + +do_execsql_test 6.1.1 { + SELECT ( + SELECT t2.b FROM (SELECT t2.b AS c FROM t1) GROUP BY 1 HAVING t2.b + ) + FROM t2 GROUP BY 'constant_string'; +} {1} +do_execsql_test 6.1.2 { + SELECT ( + SELECT c FROM (SELECT t2.b AS c FROM t1) GROUP BY c HAVING t2.b + ) + FROM t2 GROUP BY 'constant_string'; +} {1} + +do_execsql_test 6.2.0 { + UPDATE t2 SET b=0 +} +do_execsql_test 6.2.1 { + SELECT ( + SELECT t2.b FROM (SELECT t2.b AS c FROM t1) GROUP BY 1 HAVING t2.b + ) + FROM t2 GROUP BY 'constant_string'; +} {{}} +do_execsql_test 6.2.2 { + SELECT ( + SELECT c FROM (SELECT t2.b AS c FROM t1) GROUP BY c HAVING t2.b + ) + FROM t2 GROUP BY 'constant_string'; +} {{}} + + From c8d214711f39045a079c7ee9aa33b933e3a037a7 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 21 Jul 2021 15:42:05 +0000 Subject: [PATCH 27/49] Improved robustness of cursor renumbering in the UNION ALL flattener when operating on vector assignments of an UPDATE FROM. dbsqlfuzz 417d2b053b9b3c9edaf22dd515564f06999e029c FossilOrigin-Name: 60695359dc5d3bcba68a68e1842c40f4a01650eb5af408e02fb856fd8245e16d --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/select.c | 34 +++++++++++++++++++++++----------- 3 files changed, 30 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 7567fa9ecc..af32e732b7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Run\sa\s"PRAGMA\squick_check",\sif\snecessary,\son\sthe\smodified\stable\safter\s\nan\sALTER\sTABLE\sADD\sCOLUMN\sto\sverify\sthat\sadded\sNOT\sNULL\sor\sCHECK\sconstraints\nare\ssatisfied\sby\sexisting\srows.\s\sAbort\sthe\sADD\sCOLUMN\sif\snot.\n[forum:/forumpost/c04814903d6ec4f7|Forum\spost\sc04814903d6ec4f7]. -D 2021-07-20T16:07:15.775 +C Improved\srobustness\sof\scursor\srenumbering\sin\sthe\sUNION\sALL\sflattener\nwhen\soperating\son\svector\sassignments\sof\san\sUPDATE\sFROM.\ndbsqlfuzz\s417d2b053b9b3c9edaf22dd515564f06999e029c +D 2021-07-21T15:42:05.099 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -544,7 +544,7 @@ F src/printf.c 78fabb49b9ac9a12dd1c89d744abdc9b67fd3205e62967e158f78b965a29ec4b F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c ea205123fba6bb254666f50b6c220270913eae54eb03d263abaa432c703f5857 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c bc9767ab4972c63ca6def53d7b5c8cc8e4df78b63bf51981ae14a82084089a5b +F src/select.c 3896009f30352985b28511a0c4d7dbb77ba418e91db80ab7745a7f6dcbe1031f F src/shell.c.in 856de2945bb7fdfdeebe7136cf1b59d24618845aa5e5f3937fda7ff37c623b51 F src/sqlite.h.in 43fcf0fe2af04081f420a906fc020bde1243851ba44b0aa567a27f94bf8c3145 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1920,8 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1e35cc6d5c2f563c6bb163bb150d7bc6ede4c993efa828af1face3261bf65a2c 48434ad3fa9504c063d812d119bc8f622548fd02b3d478ff247b11474c4ce5db -R 6d35c00da4d952e8a1f7a6cbfeee134e -T +closed 48434ad3fa9504c063d812d119bc8f622548fd02b3d478ff247b11474c4ce5db +P e3794997c34f03db2a4ac0ca5b76727d0e031778d92b08eaaf9631689ec3e56d +R 1d0984f765e8e6292164e6d1f063ec4e U drh -Z 90f3914d2224c6dcb594ff0c1dfca96d +Z a6d780ffb6dd6089f7ed6e79e41c67b8 diff --git a/manifest.uuid b/manifest.uuid index 6c3497ea9b..e5cb1f1da4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e3794997c34f03db2a4ac0ca5b76727d0e031778d92b08eaaf9631689ec3e56d \ No newline at end of file +60695359dc5d3bcba68a68e1842c40f4a01650eb5af408e02fb856fd8245e16d \ No newline at end of file diff --git a/src/select.c b/src/select.c index b74999a8f2..a50595413a 100644 --- a/src/select.c +++ b/src/select.c @@ -3754,10 +3754,10 @@ static void recomputeColumnsUsed( ** new cursor number assigned, set an entry in the aCsrMap[] array ** to map the old cursor number to the new: ** -** aCsrMap[iOld] = iNew; +** aCsrMap[iOld+1] = iNew; ** ** The array is guaranteed by the caller to be large enough for all -** existing cursor numbers in pSrc. +** existing cursor numbers in pSrc. aCsrMap[0] is the array size. ** ** If pSrc contains any sub-selects, call this routine recursively ** on the FROM clause of each such sub-select, with iExcept set to -1. @@ -3773,10 +3773,11 @@ static void srclistRenumberCursors( for(i=0, pItem=pSrc->a; inSrc; i++, pItem++){ if( i!=iExcept ){ Select *p; - if( !pItem->fg.isRecursive || aCsrMap[pItem->iCursor]==0 ){ - aCsrMap[pItem->iCursor] = pParse->nTab++; + assert( pItem->iCursor < aCsrMap[0] ); + if( !pItem->fg.isRecursive || aCsrMap[pItem->iCursor+1]==0 ){ + aCsrMap[pItem->iCursor+1] = pParse->nTab++; } - pItem->iCursor = aCsrMap[pItem->iCursor]; + pItem->iCursor = aCsrMap[pItem->iCursor+1]; for(p=pItem->pSelect; p; p=p->pPrior){ srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1); } @@ -3784,18 +3785,28 @@ static void srclistRenumberCursors( } } +/* +** *piCursor is a cursor number. Change it if it needs to be mapped. +*/ +static void renumberCursorDoMapping(Walker *pWalker, int *piCursor){ + int *aCsrMap = pWalker->u.aiCol; + int iCsr = *piCursor; + if( iCsr < aCsrMap[0] && aCsrMap[iCsr+1]>0 ){ + *piCursor = aCsrMap[iCsr+1]; + } +} + /* ** Expression walker callback used by renumberCursors() to update ** Expr objects to match newly assigned cursor numbers. */ static int renumberCursorsCb(Walker *pWalker, Expr *pExpr){ - int *aCsrMap = pWalker->u.aiCol; int op = pExpr->op; - if( (op==TK_COLUMN || op==TK_IF_NULL_ROW) && aCsrMap[pExpr->iTable] ){ - pExpr->iTable = aCsrMap[pExpr->iTable]; + if( op==TK_COLUMN || op==TK_IF_NULL_ROW ){ + renumberCursorDoMapping(pWalker, &pExpr->iTable); } - if( ExprHasProperty(pExpr, EP_FromJoin) && aCsrMap[pExpr->iRightJoinTable] ){ - pExpr->iRightJoinTable = aCsrMap[pExpr->iRightJoinTable]; + if( ExprHasProperty(pExpr, EP_FromJoin) ){ + renumberCursorDoMapping(pWalker, &pExpr->iRightJoinTable); } return WRC_Continue; } @@ -4139,7 +4150,8 @@ static int flattenSubquery( if( pSrc->nSrc>1 ){ if( pParse->nSelect>500 ) return 0; - aCsrMap = sqlite3DbMallocZero(db, pParse->nTab*sizeof(int)); + aCsrMap = sqlite3DbMallocZero(db, (pParse->nTab+1)*sizeof(int)); + if( aCsrMap ) aCsrMap[0] = pParse->nTab; } } From 348e002ec90494809e8151e3738157edf5483ff6 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 22 Jul 2021 16:07:01 +0000 Subject: [PATCH 28/49] One of the optimizations of check-in [de9c86c9e4cdb34f] does not work for terms originating in the ON/USING clause, as demonstrated by [forum:/forumpost/6cf3bb457c3f4685|forum post 6cf3bb457c3f4685]. This check-in disables that optimization for ON/USING terms. Also improve the TreeView display for the resulting "true"/"false" nodes to show that they originate from the ON/USING clause. Add a testcase() to the other optimization to show that it can still be used for ON/USING terms. FossilOrigin-Name: 1f6796044008e6f3a61bcf390c0c7eb31947e971f0edada74e7a3a211f8ae76a --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/resolve.c | 1 + src/treeview.c | 4 ++-- src/whereexpr.c | 6 +++++- test/notnull2.test | 20 ++++++++++++++++++++ 6 files changed, 38 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index af32e732b7..37ce94583a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\srobustness\sof\scursor\srenumbering\sin\sthe\sUNION\sALL\sflattener\nwhen\soperating\son\svector\sassignments\sof\san\sUPDATE\sFROM.\ndbsqlfuzz\s417d2b053b9b3c9edaf22dd515564f06999e029c -D 2021-07-21T15:42:05.099 +C One\sof\sthe\soptimizations\sof\scheck-in\s[de9c86c9e4cdb34f]\sdoes\snot\swork\sfor\nterms\soriginating\sin\sthe\sON/USING\sclause,\sas\sdemonstrated\sby\n[forum:/forumpost/6cf3bb457c3f4685|forum\spost\s6cf3bb457c3f4685].\s\sThis\ncheck-in\sdisables\sthat\soptimization\sfor\sON/USING\sterms.\s\sAlso\simprove\sthe\nTreeView\sdisplay\sfor\sthe\sresulting\s"true"/"false"\snodes\sto\sshow\sthat\sthey\noriginate\sfrom\sthe\sON/USING\sclause.\s\sAdd\sa\stestcase()\sto\sthe\sother\soptimization\nto\sshow\sthat\sit\scan\sstill\sbe\sused\sfor\sON/USING\sterms. +D 2021-07-22T16:07:01.039 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -542,7 +542,7 @@ F src/pragma.h a11b4798f9c49f156f130e1f7041a9fcc9d316a64f3501b6013acdd2e4c6f549 F src/prepare.c 0d53d20532aada295c1690792a125adbd6435f5ce703ff0adf1b9b3605238b67 F src/printf.c 78fabb49b9ac9a12dd1c89d744abdc9b67fd3205e62967e158f78b965a29ec4b F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c -F src/resolve.c ea205123fba6bb254666f50b6c220270913eae54eb03d263abaa432c703f5857 +F src/resolve.c 047a822844cea769f6fdd8418a335dd4bcd8b75ab5e264f2506a0804f869b562 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 3896009f30352985b28511a0c4d7dbb77ba418e91db80ab7745a7f6dcbe1031f F src/shell.c.in 856de2945bb7fdfdeebe7136cf1b59d24618845aa5e5f3937fda7ff37c623b51 @@ -609,7 +609,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c bae853ad129d1129c063de8630a3e99e306283bc40146f359b1bb91be2c08f1e -F src/treeview.c ce7a3da38caba094c78d888d2366f749ea33dc8cbafb04218b57768fb8669a6c +F src/treeview.c 43f88d0fd19976a60aee6867959213b438593276f1e8179048df85f416a1ab19 F src/trigger.c 7d16aa09e63226b6d8b3f0fc60b21cbfa596fc406288b2ebcf4266633d1ba222 F src/update.c 30465f9accc854e8a7932b413578027fbb68186132abbb36e01d2022473fc83d F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 @@ -634,7 +634,7 @@ F src/walker.c 7342becedf3f8a26f9817f08436bdf8b56ad69af83705f6b9320a0ad3092c2ac F src/where.c 07a4097fe42a01b1f99d2a136598654051f0bdcd6c17cbef7fa285a9cf21e4d2 F src/whereInt.h 9248161dd004f625ce5d3841ca9b99fed3fc8d61522cf76340fc5217dbe1375b F src/wherecode.c 9f1f65d11437b25cd0a1497a170514c785f19ce6ad9d3e6fc73719cb5a49012f -F src/whereexpr.c 2bfb1cd24b9b63fc5e32b9b85f2b3f88765bdac2aab51102d94d1fb56ec2917b +F src/whereexpr.c 3a9144a9d52e110efdc012a73b1574e7b2b4df4bf98949387cb620295eba0975 F src/window.c 420167512050a0dfc0f0115b9f0c7d299da9759c9bb2ae83a61fb8d730a5707f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -1230,7 +1230,7 @@ F test/notify1.test 669b2b743618efdc18ca4b02f45423d5d2304abf F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161 F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934 F test/notnull.test a37b663d5bb728d66fc182016613fb8e4a0a4bbf3d75b8876a7527f7d4ed3f18 -F test/notnull2.test 131365171d973c57fe694fcc46c1e645f6e24ceb43b230ad5011a0ea2182f215 +F test/notnull2.test 8e1aa4f311df37f9d2cd4f5563eea955b8028c692151404e9cc896420a01a3dc F test/notnullfault.test fc4bb7845582a2b3db376001ef49118393b1b11abe0d24adb03db057ee2b73d5 F test/null.test b7ff206a1c60fe01aa2abd33ef9ea83c93727d993ca8a613de86e925c9f2bc6f F test/nulls1.test 7a5e4346ee4285034100b4cd20e6784f16a9d6c927e44ecdf10034086bbee9c9 @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e3794997c34f03db2a4ac0ca5b76727d0e031778d92b08eaaf9631689ec3e56d -R 1d0984f765e8e6292164e6d1f063ec4e +P 60695359dc5d3bcba68a68e1842c40f4a01650eb5af408e02fb856fd8245e16d +R eca5325aa2c3da54beb61a6b6add5177 U drh -Z a6d780ffb6dd6089f7ed6e79e41c67b8 +Z 1ef4dd4c6275cc3be5203d6443662cc5 diff --git a/manifest.uuid b/manifest.uuid index e5cb1f1da4..0a5529aea5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -60695359dc5d3bcba68a68e1842c40f4a01650eb5af408e02fb856fd8245e16d \ No newline at end of file +1f6796044008e6f3a61bcf390c0c7eb31947e971f0edada74e7a3a211f8ae76a \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index ae5a574056..d509de7953 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -818,6 +818,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ } sqlite3WalkExpr(pWalker, pExpr->pLeft); if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) && !IN_RENAME_OBJECT ){ + testcase( ExprHasProperty(pExpr, EP_FromJoin) ); if( pExpr->op==TK_NOTNULL ){ pExpr->u.zToken = "true"; ExprSetProperty(pExpr, EP_IsTrue); diff --git a/src/treeview.c b/src/treeview.c index 165ceb537a..654e01a3ea 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -474,8 +474,8 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ break; } case TK_TRUEFALSE: { - sqlite3TreeViewLine(pView, - sqlite3ExprTruthValue(pExpr) ? "TRUE" : "FALSE"); + sqlite3TreeViewLine(pView,"%s%s", + sqlite3ExprTruthValue(pExpr) ? "TRUE" : "FALSE", zFlgs); break; } #ifndef SQLITE_OMIT_BLOB_LITERAL diff --git a/src/whereexpr.c b/src/whereexpr.c index b9aa702e22..3492769db9 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1144,7 +1144,11 @@ static void exprAnalyze( pNew->prereqRight = prereqLeft | extraRight; pNew->prereqAll = prereqAll; pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask; - }else if( op==TK_ISNULL && 0==sqlite3ExprCanBeNull(pLeft) ){ + }else + if( op==TK_ISNULL + && !ExprHasProperty(pExpr,EP_FromJoin) + && 0==sqlite3ExprCanBeNull(pLeft) + ){ pExpr->op = TK_TRUEFALSE; pExpr->u.zToken = "false"; ExprSetProperty(pExpr, EP_IsFalse); diff --git a/test/notnull2.test b/test/notnull2.test index 75a519e9a3..12fffe28ce 100644 --- a/test/notnull2.test +++ b/test/notnull2.test @@ -109,4 +109,24 @@ do_execsql_test 3.1 { SELECT * FROM t0 WHERE ((c0 NOT NULL) AND 1) OR (c0 == NULL); } {0} +# 2021-07-22 https://sqlite.org/forum/forumpost/2078b7edd2 +# +reset_db +do_execsql_test 4.0 { + SELECT *, '/' + FROM ( + SELECT NULL val FROM (SELECT 1) + UNION ALL + SELECT 'missing' FROM (SELECT 1) + ) a + LEFT JOIN (SELECT 1) + ON a.val IS NULL; +} {{} 1 / missing {} /} +do_execsql_test 4.1 { + CREATE TABLE t1(a INT); + INSERT INTO t1(a) VALUES(1); + CREATE TABLE t2(b INT); + SELECT * FROM (SELECT 3 AS c FROM t1) AS t3 LEFT JOIN t2 ON c IS NULL; +} {3 {}} + finish_test From 55b8b73e749aa1dca43febaa9c546ca23e3bc0a7 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 22 Jul 2021 18:22:51 +0000 Subject: [PATCH 29/49] Fix ALTER TABLE DROP COLUMN so that it generates valid bytecode even when operating on a corrupt database and using PRAGMA writable_schema=ON. dbsqlfuzz 5f09e7bcc78b4954d06bf9f2400d7715f48d1fef FossilOrigin-Name: b65f4f763979ee9e0b943c787609ea22d6f7e01d41dfc1e084ec50a085a3550c --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/alter.c | 6 ++++++ test/fuzzdata8.db | Bin 2503680 -> 2504704 bytes 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 37ce94583a..2bedfaa2cd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C One\sof\sthe\soptimizations\sof\scheck-in\s[de9c86c9e4cdb34f]\sdoes\snot\swork\sfor\nterms\soriginating\sin\sthe\sON/USING\sclause,\sas\sdemonstrated\sby\n[forum:/forumpost/6cf3bb457c3f4685|forum\spost\s6cf3bb457c3f4685].\s\sThis\ncheck-in\sdisables\sthat\soptimization\sfor\sON/USING\sterms.\s\sAlso\simprove\sthe\nTreeView\sdisplay\sfor\sthe\sresulting\s"true"/"false"\snodes\sto\sshow\sthat\sthey\noriginate\sfrom\sthe\sON/USING\sclause.\s\sAdd\sa\stestcase()\sto\sthe\sother\soptimization\nto\sshow\sthat\sit\scan\sstill\sbe\sused\sfor\sON/USING\sterms. -D 2021-07-22T16:07:01.039 +C Fix\sALTER\sTABLE\sDROP\sCOLUMN\sso\sthat\sit\sgenerates\svalid\sbytecode\seven\swhen\noperating\son\sa\scorrupt\sdatabase\sand\susing\sPRAGMA\swritable_schema=ON.\ndbsqlfuzz\s5f09e7bcc78b4954d06bf9f2400d7715f48d1fef +D 2021-07-22T18:22:51.707 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -478,7 +478,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 8b6d394cca07e1aa0bd9364111098017dee578e2edad6ce6eb6a0cf78738413c +F src/alter.c a54e0a5ae778271a0bc67bdb590c1b3bba0ee59669474f976afb862ccee0026e F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c F src/attach.c a514e81758ba7b3a3a0501faf70af6cfc509de8810235db726cfc9f25165e929 F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 @@ -1057,7 +1057,7 @@ F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e4 F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5 F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7 F test/fuzzdata7.db 0166b56fd7a6b9636a1d60ef0a060f86ddaecf99400a666bb6e5bbd7199ad1f2 -F test/fuzzdata8.db da92a0e336bf34ae89e407b375aaa57581b73b5f8f99b4de5e2557f64a3ca33c +F test/fuzzdata8.db 4581978d13472885cf33c0bbebb236a69f73f1b7316678d266422f4b96cfdf2c F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 60695359dc5d3bcba68a68e1842c40f4a01650eb5af408e02fb856fd8245e16d -R eca5325aa2c3da54beb61a6b6add5177 +P 1f6796044008e6f3a61bcf390c0c7eb31947e971f0edada74e7a3a211f8ae76a +R 7315df7a3ffb1a7d3694104258ba6a80 U drh -Z 1ef4dd4c6275cc3be5203d6443662cc5 +Z 1036f3ec1711682b3c2317c34f22e66c diff --git a/manifest.uuid b/manifest.uuid index 0a5529aea5..15c0f5c0d8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1f6796044008e6f3a61bcf390c0c7eb31947e971f0edada74e7a3a211f8ae76a \ No newline at end of file +b65f4f763979ee9e0b943c787609ea22d6f7e01d41dfc1e084ec50a085a3550c \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 9c5b46261a..c29be3f6e0 100644 --- a/src/alter.c +++ b/src/alter.c @@ -2174,6 +2174,12 @@ void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, Token *pName){ nField++; } } + if( nField==0 ){ + /* dbsqlfuzz 5f09e7bcc78b4954d06bf9f2400d7715f48d1fef */ + pParse->nMem++; + sqlite3VdbeAddOp2(v, OP_Null, 0, reg+1); + nField = 1; + } sqlite3VdbeAddOp3(v, OP_MakeRecord, reg+1, nField, regRec); if( pPk ){ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iCur, regRec, reg+1, pPk->nKeyCol); diff --git a/test/fuzzdata8.db b/test/fuzzdata8.db index f3a67bc7048bd937145827b4645940bd52ec2404..5273e5883c28846a9f5935e5e385964f1d17c43f 100644 GIT binary patch delta 40064 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 O4?(ode?_|jivJHu6?-oL delta 39602 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 Date: Thu, 22 Jul 2021 21:11:06 +0000 Subject: [PATCH 30/49] Set the checkSchema flag if a CREATE TABLE parse fails because the table already exists, to ensure that the table was not previously deleted by some other connection. FossilOrigin-Name: 91bcb9621529b58d28e91a2763eb9eef3951400d5eaef105073258f3dd331872 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 2bedfaa2cd..5883a6aee2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sALTER\sTABLE\sDROP\sCOLUMN\sso\sthat\sit\sgenerates\svalid\sbytecode\seven\swhen\noperating\son\sa\scorrupt\sdatabase\sand\susing\sPRAGMA\swritable_schema=ON.\ndbsqlfuzz\s5f09e7bcc78b4954d06bf9f2400d7715f48d1fef -D 2021-07-22T18:22:51.707 +C Set\sthe\scheckSchema\sflag\sif\sa\sCREATE\sTABLE\sparse\sfails\sbecause\sthe\stable\nalready\sexists,\sto\sensure\sthat\sthe\stable\swas\snot\spreviously\sdeleted\sby\nsome\sother\sconnection. +D 2021-07-22T21:11:06.648 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -488,7 +488,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c e204a9c8fb4fe5dbb910a863ba487f4af9b5c501254ec4ccbfcdd6b1f65b7fb4 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0 -F src/build.c a27511863001ba088afd5e19efc9c37ea660983bd6ddf012def10f6cc4456a01 +F src/build.c 9978caf1e5c6c82d04d85e290d46979abc2219fb79bcd970258d1ebe368d184e F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 8159d5f706551861c18ec6c8f6bdf105e15ea00367f05d9ab65d31a1077facc1 @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1f6796044008e6f3a61bcf390c0c7eb31947e971f0edada74e7a3a211f8ae76a -R 7315df7a3ffb1a7d3694104258ba6a80 +P b65f4f763979ee9e0b943c787609ea22d6f7e01d41dfc1e084ec50a085a3550c +R ed9a1584f4d75ade417ceb251baf5a51 U drh -Z 1036f3ec1711682b3c2317c34f22e66c +Z f439f5ab1be78d6d001ae417ae6fc683 diff --git a/manifest.uuid b/manifest.uuid index 15c0f5c0d8..2645917039 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b65f4f763979ee9e0b943c787609ea22d6f7e01d41dfc1e084ec50a085a3550c \ No newline at end of file +91bcb9621529b58d28e91a2763eb9eef3951400d5eaef105073258f3dd331872 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 4eca21a3f7..824c104743 100644 --- a/src/build.c +++ b/src/build.c @@ -1272,6 +1272,7 @@ void sqlite3StartTable( /* If an error occurs, we jump here */ begin_table_error: + pParse->checkSchema = 1; sqlite3DbFree(db, zName); return; } From 37407126777ade303ed954cbb2243a15fe26f1a0 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 23 Jul 2021 18:43:58 +0000 Subject: [PATCH 31/49] Enhance the CLI with the ".connection" command that can switch between up to five different database connections. Used for manual testing of multiple database connections in the same process. FossilOrigin-Name: 54eaf076c05887157179459ab39c2556953f6fef9c1b14f17a8aa74087da3023 --- manifest | 12 +-- manifest.uuid | 2 +- src/shell.c.in | 202 ++++++++++++++++++++++++++++++++----------------- 3 files changed, 138 insertions(+), 78 deletions(-) diff --git a/manifest b/manifest index 5883a6aee2..99fe0fda6a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Set\sthe\scheckSchema\sflag\sif\sa\sCREATE\sTABLE\sparse\sfails\sbecause\sthe\stable\nalready\sexists,\sto\sensure\sthat\sthe\stable\swas\snot\spreviously\sdeleted\sby\nsome\sother\sconnection. -D 2021-07-22T21:11:06.648 +C Enhance\sthe\sCLI\swith\sthe\s".connection"\scommand\sthat\scan\sswitch\sbetween\nup\sto\sfive\sdifferent\sdatabase\sconnections.\s\sUsed\sfor\smanual\stesting\sof\smultiple\ndatabase\sconnections\sin\sthe\ssame\sprocess. +D 2021-07-23T18:43:58.652 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -545,7 +545,7 @@ F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 047a822844cea769f6fdd8418a335dd4bcd8b75ab5e264f2506a0804f869b562 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 3896009f30352985b28511a0c4d7dbb77ba418e91db80ab7745a7f6dcbe1031f -F src/shell.c.in 856de2945bb7fdfdeebe7136cf1b59d24618845aa5e5f3937fda7ff37c623b51 +F src/shell.c.in dc889872292ce143ab43080e7eb48b95f9b13beabf85ae729388a6b9ee08bab7 F src/sqlite.h.in 43fcf0fe2af04081f420a906fc020bde1243851ba44b0aa567a27f94bf8c3145 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510 @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b65f4f763979ee9e0b943c787609ea22d6f7e01d41dfc1e084ec50a085a3550c -R ed9a1584f4d75ade417ceb251baf5a51 +P 91bcb9621529b58d28e91a2763eb9eef3951400d5eaef105073258f3dd331872 +R 0cfa2cb9dd20ef662e91de1cc8d85fce U drh -Z f439f5ab1be78d6d001ae417ae6fc683 +Z 13547b3fed83ea2295e7d5c9afd10815 diff --git a/manifest.uuid b/manifest.uuid index 2645917039..a66844c71c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -91bcb9621529b58d28e91a2763eb9eef3951400d5eaef105073258f3dd331872 \ No newline at end of file +54eaf076c05887157179459ab39c2556953f6fef9c1b14f17a8aa74087da3023 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 248bc0dc0e..713050555c 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -983,7 +983,7 @@ static void shellAddSchemaName( sqlite3 *db = sqlite3_context_db_handle(pCtx); UNUSED_PARAMETER(nVal); if( zIn!=0 && strncmp(zIn, "CREATE ", 7)==0 ){ - for(i=0; i<(int)(sizeof(aPrefix)/sizeof(aPrefix[0])); i++){ + for(i=0; inSession; i++){ - session_close(&p->aSession[i]); +static void session_close_all(ShellState *p, int i){ + int j; + struct AuxDb *pAuxDb = i<0 ? p->pAuxDb : &p->aAuxDb[i]; + for(j=0; jnSession; j++){ + session_close(&pAuxDb->aSession[j]); } - p->nSession = 0; + pAuxDb->nSession = 0; } #else -# define session_close_all(X) +# define session_close_all(X,Y) #endif /* @@ -4317,8 +4322,8 @@ int deduceDatabaseType(const char *zName, int dfltZip){ #ifndef SQLITE_OMIT_DESERIALIZE /* ** Reconstruct an in-memory database using the output from the "dbtotxt" -** program. Read content from the file in p->zDbFilename. If p->zDbFilename -** is 0, then read from standard input. +** program. Read content from the file in p->aAuxDb[].zDbFilename. +** If p->aAuxDb[].zDbFilename is 0, then read from standard input. */ static unsigned char *readHexDb(ShellState *p, int *pnData){ unsigned char *a = 0; @@ -4329,12 +4334,13 @@ static unsigned char *readHexDb(ShellState *p, int *pnData){ int j, k; int rc; FILE *in; + const char *zDbFilename = p->pAuxDb->zDbFilename; unsigned int x[16]; char zLine[1000]; - if( p->zDbFilename ){ - in = fopen(p->zDbFilename, "r"); + if( zDbFilename ){ + in = fopen(zDbFilename, "r"); if( in==0 ){ - utf8_printf(stderr, "cannot open \"%s\" for reading\n", p->zDbFilename); + utf8_printf(stderr, "cannot open \"%s\" for reading\n", zDbFilename); return 0; } nLine = 0; @@ -4576,17 +4582,18 @@ static void shellEscapeCrnl( */ static void open_db(ShellState *p, int openFlags){ if( p->db==0 ){ + const char *zDbFilename = p->pAuxDb->zDbFilename; if( p->openMode==SHELL_OPEN_UNSPEC ){ - if( p->zDbFilename==0 || p->zDbFilename[0]==0 ){ + if( zDbFilename==0 || zDbFilename[0]==0 ){ p->openMode = SHELL_OPEN_NORMAL; }else{ - p->openMode = (u8)deduceDatabaseType(p->zDbFilename, + p->openMode = (u8)deduceDatabaseType(zDbFilename, (openFlags & OPEN_DB_ZIPFILE)!=0); } } switch( p->openMode ){ case SHELL_OPEN_APPENDVFS: { - sqlite3_open_v2(p->zDbFilename, &p->db, + sqlite3_open_v2(zDbFilename, &p->db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, "apndvfs"); break; } @@ -4600,13 +4607,13 @@ static void open_db(ShellState *p, int openFlags){ break; } case SHELL_OPEN_READONLY: { - sqlite3_open_v2(p->zDbFilename, &p->db, + sqlite3_open_v2(zDbFilename, &p->db, SQLITE_OPEN_READONLY|p->openFlags, 0); break; } case SHELL_OPEN_UNSPEC: case SHELL_OPEN_NORMAL: { - sqlite3_open_v2(p->zDbFilename, &p->db, + sqlite3_open_v2(zDbFilename, &p->db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, 0); break; } @@ -4614,7 +4621,7 @@ static void open_db(ShellState *p, int openFlags){ globalDb = p->db; if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){ utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n", - p->zDbFilename, sqlite3_errmsg(p->db)); + zDbFilename, sqlite3_errmsg(p->db)); if( openFlags & OPEN_DB_KEEPALIVE ){ sqlite3_open(":memory:", &p->db); return; @@ -4661,7 +4668,7 @@ static void open_db(ShellState *p, int openFlags){ #endif if( p->openMode==SHELL_OPEN_ZIPFILE ){ char *zSql = sqlite3_mprintf( - "CREATE VIRTUAL TABLE zip USING zipfile(%Q);", p->zDbFilename); + "CREATE VIRTUAL TABLE zip USING zipfile(%Q);", zDbFilename); sqlite3_exec(p->db, zSql, 0, 0, 0); sqlite3_free(zSql); } @@ -4672,7 +4679,7 @@ static void open_db(ShellState *p, int openFlags){ int nData = 0; unsigned char *aData; if( p->openMode==SHELL_OPEN_DESERIALIZE ){ - aData = (unsigned char*)readFile(p->zDbFilename, &nData); + aData = (unsigned char*)readFile(zDbFilename, &nData); }else{ aData = readHexDb(p, &nData); if( aData==0 ){ @@ -7393,7 +7400,6 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ } #endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */ - /* ** If an input line begins with "." then invoke this routine to ** process that line. @@ -7558,6 +7564,13 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else + /* The undocumented ".breakpoint" command causes a call to the no-op + ** routine named test_breakpoint(). + */ + if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){ + test_breakpoint(); + }else + if( c=='c' && strcmp(azArg[0],"cd")==0 ){ if( nArg==2 ){ #if defined(_WIN32) || defined(WIN32) @@ -7577,13 +7590,6 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else - /* The undocumented ".breakpoint" command causes a call to the no-op - ** routine named test_breakpoint(). - */ - if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){ - test_breakpoint(); - }else - if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){ if( nArg==2 ){ setOrClearFlag(p, SHFLG_CountChanges, azArg[1]); @@ -7627,6 +7633,52 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else + if( c=='c' && strncmp(azArg[0], "connection", n)==0 ){ + if( nArg==1 ){ + /* List available connections */ + int i; + for(i=0; iaAuxDb); i++){ + const char *zFile = p->aAuxDb[i].zDbFilename; + if( p->aAuxDb[i].db==0 && p->pAuxDb!=&p->aAuxDb[i] ){ + zFile = "(not open)"; + }else if( zFile==0 ){ + zFile = "(memory)"; + }else if( zFile[0]==0 ){ + zFile = "(temporary-file)"; + } + if( p->pAuxDb == &p->aAuxDb[i] ){ + utf8_printf(stdout, "ACTIVE %d: %s\n", i, zFile); + }else if( p->aAuxDb[i].db!=0 ){ + utf8_printf(stdout, " %d: %s\n", i, zFile); + } + } + }else if( nArg==2 && IsDigit(azArg[1][0]) && azArg[1][1]==0 ){ + int i = azArg[1][0] - '0'; + if( p->pAuxDb != &p->aAuxDb[i] && i>=0 && iaAuxDb) ){ + p->pAuxDb->db = p->db; + p->pAuxDb = &p->aAuxDb[i]; + globalDb = p->db = p->pAuxDb->db; + p->pAuxDb->db = 0; + } + }else if( nArg==3 && strcmp(azArg[1], "close")==0 + && IsDigit(azArg[2][0]) && azArg[2][1]==0 ){ + int i = azArg[2][0] - '0'; + if( i<0 || i>=ArraySize(p->aAuxDb) ){ + /* No-op */ + }else if( p->pAuxDb == &p->aAuxDb[i] ){ + raw_printf(stderr, "cannot close the active database connection\n"); + rc = 1; + }else if( p->aAuxDb[i].db ){ + session_close_all(p, i); + close_db(p->aAuxDb[i].db); + p->aAuxDb[i].db = 0; + } + }else{ + raw_printf(stderr, "Usage: .connection [close] [CONNECTION-NUMBER]\n"); + rc = 1; + } + }else + if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){ char **azName = 0; int nName = 0; @@ -8716,12 +8768,12 @@ static int do_meta_command(char *zLine, ShellState *p){ int iName = 1; /* Index in azArg[] of the filename */ int newFlag = 0; /* True to delete file before opening */ /* Close the existing database */ - session_close_all(p); + session_close_all(p, -1); close_db(p->db); p->db = 0; - p->zDbFilename = 0; - sqlite3_free(p->zFreeOnClose); - p->zFreeOnClose = 0; + p->pAuxDb->zDbFilename = 0; + sqlite3_free(p->pAuxDb->zFreeOnClose); + p->pAuxDb->zFreeOnClose = 0; p->openMode = SHELL_OPEN_UNSPEC; p->openFlags = 0; p->szMax = 0; @@ -8765,18 +8817,18 @@ static int do_meta_command(char *zLine, ShellState *p){ /* If a filename is specified, try to open it first */ if( zNewFilename || p->openMode==SHELL_OPEN_HEXDB ){ if( newFlag ) shellDeleteFile(zNewFilename); - p->zDbFilename = zNewFilename; + p->pAuxDb->zDbFilename = zNewFilename; open_db(p, OPEN_DB_KEEPALIVE); if( p->db==0 ){ utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename); sqlite3_free(zNewFilename); }else{ - p->zFreeOnClose = zNewFilename; + p->pAuxDb->zFreeOnClose = zNewFilename; } } if( p->db==0 ){ /* As a fall-back open a TEMP database */ - p->zDbFilename = 0; + p->pAuxDb->zDbFilename = 0; open_db(p, 0); } }else @@ -9305,7 +9357,8 @@ static int do_meta_command(char *zLine, ShellState *p){ #if defined(SQLITE_ENABLE_SESSION) if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){ - OpenSession *pSession = &p->aSession[0]; + struct AuxDb *pAuxDb = p->pAuxDb; + OpenSession *pSession = &pAuxDb->aSession[0]; char **azCmd = &azArg[1]; int iSes = 0; int nCmd = nArg - 1; @@ -9313,15 +9366,15 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nArg<=1 ) goto session_syntax_error; open_db(p, 0); if( nArg>=3 ){ - for(iSes=0; iSesnSession; iSes++){ - if( strcmp(p->aSession[iSes].zName, azArg[1])==0 ) break; + for(iSes=0; iSesnSession; iSes++){ + if( strcmp(pAuxDb->aSession[iSes].zName, azArg[1])==0 ) break; } - if( iSesnSession ){ - pSession = &p->aSession[iSes]; + if( iSesnSession ){ + pSession = &pAuxDb->aSession[iSes]; azCmd++; nCmd--; }else{ - pSession = &p->aSession[0]; + pSession = &pAuxDb->aSession[0]; iSes = 0; } } @@ -9383,9 +9436,9 @@ static int do_meta_command(char *zLine, ShellState *p){ */ if( strcmp(azCmd[0], "close")==0 ){ if( nCmd!=1 ) goto session_syntax_error; - if( p->nSession ){ + if( pAuxDb->nSession ){ session_close(pSession); - p->aSession[iSes] = p->aSession[--p->nSession]; + pAuxDb->aSession[iSes] = pAuxDb->aSession[--pAuxDb->nSession]; } }else @@ -9396,7 +9449,7 @@ static int do_meta_command(char *zLine, ShellState *p){ int ii; if( nCmd>2 ) goto session_syntax_error; ii = nCmd==1 ? -1 : booleanValue(azCmd[1]); - if( p->nSession ){ + if( pAuxDb->nSession ){ ii = sqlite3session_enable(pSession->p, ii); utf8_printf(p->out, "session %s enable flag = %d\n", pSession->zName, ii); @@ -9409,7 +9462,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( strcmp(azCmd[0], "filter")==0 ){ int ii, nByte; if( nCmd<2 ) goto session_syntax_error; - if( p->nSession ){ + if( pAuxDb->nSession ){ for(ii=0; iinFilter; ii++){ sqlite3_free(pSession->azFilter[ii]); } @@ -9434,7 +9487,7 @@ static int do_meta_command(char *zLine, ShellState *p){ int ii; if( nCmd>2 ) goto session_syntax_error; ii = nCmd==1 ? -1 : booleanValue(azCmd[1]); - if( p->nSession ){ + if( pAuxDb->nSession ){ ii = sqlite3session_indirect(pSession->p, ii); utf8_printf(p->out, "session %s indirect flag = %d\n", pSession->zName, ii); @@ -9447,7 +9500,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( strcmp(azCmd[0], "isempty")==0 ){ int ii; if( nCmd!=1 ) goto session_syntax_error; - if( p->nSession ){ + if( pAuxDb->nSession ){ ii = sqlite3session_isempty(pSession->p); utf8_printf(p->out, "session %s isempty flag = %d\n", pSession->zName, ii); @@ -9458,8 +9511,8 @@ static int do_meta_command(char *zLine, ShellState *p){ ** List all currently open sessions */ if( strcmp(azCmd[0],"list")==0 ){ - for(i=0; inSession; i++){ - utf8_printf(p->out, "%d %s\n", i, p->aSession[i].zName); + for(i=0; inSession; i++){ + utf8_printf(p->out, "%d %s\n", i, pAuxDb->aSession[i].zName); } }else @@ -9472,17 +9525,17 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nCmd!=3 ) goto session_syntax_error; zName = azCmd[2]; if( zName[0]==0 ) goto session_syntax_error; - for(i=0; inSession; i++){ - if( strcmp(p->aSession[i].zName,zName)==0 ){ + for(i=0; inSession; i++){ + if( strcmp(pAuxDb->aSession[i].zName,zName)==0 ){ utf8_printf(stderr, "Session \"%s\" already exists\n", zName); goto meta_command_exit; } } - if( p->nSession>=ArraySize(p->aSession) ){ - raw_printf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession)); + if( pAuxDb->nSession>=ArraySize(pAuxDb->aSession) ){ + raw_printf(stderr, "Maximum of %d sessions\n", ArraySize(pAuxDb->aSession)); goto meta_command_exit; } - pSession = &p->aSession[p->nSession]; + pSession = &pAuxDb->aSession[pAuxDb->nSession]; rc = sqlite3session_create(p->db, azCmd[1], &pSession->p); if( rc ){ raw_printf(stderr, "Cannot open session: error code=%d\n", rc); @@ -9491,7 +9544,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } pSession->nFilter = 0; sqlite3session_table_filter(pSession->p, session_filter, pSession); - p->nSession++; + pAuxDb->nSession++; pSession->zName = sqlite3_mprintf("%s", zName); }else /* If no command name matches, show a syntax error */ @@ -9820,7 +9873,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } raw_printf(p->out, "\n"); utf8_printf(p->out, "%12.12s: %s\n", "filename", - p->zDbFilename ? p->zDbFilename : ""); + p->pAuxDb->zDbFilename ? p->pAuxDb->zDbFilename : ""); }else if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){ @@ -10841,6 +10894,7 @@ static void main_init(ShellState *data) { memset(data, 0, sizeof(*data)); data->normalMode = data->cMode = data->mode = MODE_List; data->autoExplain = 1; + data->pAuxDb = &data->aAuxDb[0]; memcpy(data->colSeparator,SEP_Column, 2); memcpy(data->rowSeparator,SEP_Row, 2); data->showHeader = 0; @@ -11004,7 +11058,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ ** this compile-time option to embed this shell program in larger ** applications. */ extern void SQLITE_SHELL_DBNAME_PROC(const char**); - SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename); + SQLITE_SHELL_DBNAME_PROC(&data.pAuxDb->zDbFilename); warnInmemoryDb = 0; } #endif @@ -11019,8 +11073,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ char *z; z = argv[i]; if( z[0]!='-' ){ - if( data.zDbFilename==0 ){ - data.zDbFilename = z; + if( data.aAuxDb->zDbFilename==0 ){ + data.aAuxDb->zDbFilename = z; }else{ /* Excesss arguments are interpreted as SQL (or dot-commands) and ** mean that nothing is read from stdin */ @@ -11160,9 +11214,9 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ } } - if( data.zDbFilename==0 ){ + if( data.pAuxDb->zDbFilename==0 ){ #ifndef SQLITE_OMIT_MEMORYDB - data.zDbFilename = ":memory:"; + data.pAuxDb->zDbFilename = ":memory:"; warnInmemoryDb = argc==1; #else utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0); @@ -11177,7 +11231,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ ** files from being created if a user mistypes the database name argument ** to the sqlite command-line tool. */ - if( access(data.zDbFilename, 0)==0 ){ + if( access(data.pAuxDb->zDbFilename, 0)==0 ){ open_db(&data, 0); } @@ -11431,10 +11485,16 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ free(azCmd); set_table_name(&data, 0); if( data.db ){ - session_close_all(&data); + session_close_all(&data, -1); close_db(data.db); } - sqlite3_free(data.zFreeOnClose); + for(i=0; i Date: Mon, 26 Jul 2021 18:28:24 +0000 Subject: [PATCH 32/49] Give sqldiff --visible-controls option to deal with non-graphic text content robustly across platforms FossilOrigin-Name: 68d2373f5d578cf3aff9d1ac4b1ab3ac00b466e94e1eb516523fc7660dfc0549 --- manifest | 14 +++++++------- manifest.uuid | 2 +- tool/sqldiff.c | 45 ++++++++++++++++++++++++++++++++++++++------- 3 files changed, 46 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 99fe0fda6a..c4f06a0d91 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\sCLI\swith\sthe\s".connection"\scommand\sthat\scan\sswitch\sbetween\nup\sto\sfive\sdifferent\sdatabase\sconnections.\s\sUsed\sfor\smanual\stesting\sof\smultiple\ndatabase\sconnections\sin\sthe\ssame\sprocess. -D 2021-07-23T18:43:58.652 +C Give\ssqldiff\s--visible-controls\soption\sto\sdeal\swith\snon-graphic\stext\scontent\srobustly\sacross\splatforms +D 2021-07-26T18:28:24.001 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1885,7 +1885,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd F tool/split-sqlite3c.tcl 3efcd4240b738f6bb2b5af0aea7e1e0ef9bc1c61654f645076cec883030b710c -F tool/sqldiff.c 21226ef092ec1e543b237c5d3d2d32d344a60f2437eadfea04f65b348fbd00e4 +F tool/sqldiff.c b4906b8a88252c94a77f2080f10c2624ba9b11f2577f25c1b29c3324a7a76c83 F tool/sqlite3_analyzer.c.in 7eeaae8b0d7577662acaabbb11107af0659d1b41bc1dfdd4d91422de27127968 F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898 F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848 @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 91bcb9621529b58d28e91a2763eb9eef3951400d5eaef105073258f3dd331872 -R 0cfa2cb9dd20ef662e91de1cc8d85fce -U drh -Z 13547b3fed83ea2295e7d5c9afd10815 +P 54eaf076c05887157179459ab39c2556953f6fef9c1b14f17a8aa74087da3023 +R a514ddb4ecddc8a67fe058834fe110d9 +U larrybr +Z 948d1027dff68e9d9c973736292e2ed9 diff --git a/manifest.uuid b/manifest.uuid index a66844c71c..f8be94e571 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -54eaf076c05887157179459ab39c2556953f6fef9c1b14f17a8aa74087da3023 \ No newline at end of file +68d2373f5d578cf3aff9d1ac4b1ab3ac00b466e94e1eb516523fc7660dfc0549 \ No newline at end of file diff --git a/tool/sqldiff.c b/tool/sqldiff.c index 9844cbadf0..fea40b9fe0 100644 --- a/tool/sqldiff.c +++ b/tool/sqldiff.c @@ -34,6 +34,7 @@ struct GlobalVars { int bSchemaOnly; /* Only show schema differences */ int bSchemaPK; /* Use the schema-defined PK, not the true PK */ int bHandleVtab; /* Handle fts3, fts4, fts5 and rtree vtabs */ + int bDarkCtl; /* Render controls in text as blob literals */ unsigned fDebug; /* Debug flags */ sqlite3 *db; /* The database connection */ } g; @@ -386,13 +387,39 @@ static void printQuoted(FILE *out, sqlite3_value *X){ fprintf(out, "NULL"); }else{ fprintf(out, "'"); - for(i=j=0; zArg[i]; i++){ - if( zArg[i]=='\'' ){ - fprintf(out, "%.*s'", i-j+1, &zArg[j]); - j = i+1; - } - } - fprintf(out, "%s'", &zArg[j]); + if( !g.bDarkCtl ){ + for(i=j=0; zArg[i]; i++){ + if( zArg[i]=='\'' ){ + fprintf(out, "%.*s'", i-j+1, &zArg[j]); + j = i+1; + } + } + fprintf(out, "%s'", &zArg[j]); + }else{ + int inctl = 0; + for(i=j=0; zArg[i]; i++){ + char c = zArg[i]; + int ctl = iscntrl(c); + if( ctl>inctl ){ + inctl = ctl; + fprintf(out, "%.*s'||X'%02x", i-j, &zArg[j], c); + j = i+1; + }else if( ctl ){ + fprintf(out, "%02x", c); + j = i+1; + }else{ + if( inctl ){ + inctl = 0; + fprintf(out, "'\n||'"); + } + if( c=='\'' ){ + fprintf(out, "%.*s'", i-j+1, &zArg[j]); + j = i+1; + } + } + } + fprintf(out, "%s'", &zArg[j]); + } } break; } @@ -1875,6 +1902,7 @@ static void showHelp(void){ " --table TAB Show only differences in table TAB\n" " --transaction Show SQL output inside a transaction\n" " --vtab Handle fts3, fts4, fts5 and rtree tables\n" +" --visible-controls Render controls in text as blob literals\n" ); } @@ -1948,6 +1976,9 @@ int main(int argc, char **argv){ if( strcmp(z,"vtab")==0 ){ g.bHandleVtab = 1; }else + if( strcmp(z, "visible-controls")==0 ){ + g.bDarkCtl = 1; + }else { cmdlineError("unknown option: %s", argv[i]); } From 1ae057d8735b85bc97346c0b6a83b8f86c4d949b Mon Sep 17 00:00:00 2001 From: larrybr Date: Mon, 26 Jul 2021 19:49:01 +0000 Subject: [PATCH 33/49] Remove sqldiff --visible-controls option, make it always happen. Add test cases for controls made visible FossilOrigin-Name: ff74c0cc4cefa5271b12ecfff3f2fd4749852d9d1d01f4ae64a07a26decc001b --- manifest | 14 ++++++------ manifest.uuid | 2 +- test/sqldiff1.test | 9 ++++++++ tool/sqldiff.c | 53 +++++++++++++++++----------------------------- 4 files changed, 36 insertions(+), 42 deletions(-) diff --git a/manifest b/manifest index c4f06a0d91..516e0cdb39 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Give\ssqldiff\s--visible-controls\soption\sto\sdeal\swith\snon-graphic\stext\scontent\srobustly\sacross\splatforms -D 2021-07-26T18:28:24.001 +C Remove\ssqldiff\s--visible-controls\soption,\smake\sit\salways\shappen.\sAdd\stest\scases\sfor\scontrols\smade\svisible +D 2021-07-26T19:49:01.920 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1417,7 +1417,7 @@ F test/spellfix.test 951a6405d49d1a23d6b78027d3877b4a33eeb8221dcab5704b499755bb4 F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 F test/spellfix4.test 51c7c26514ade169855c66bcf130bd5acfb4d7fd090cc624645ab275ae6a41fb -F test/sqldiff1.test 28cd737cf1b0078b1ec1bbf425e674c47785835e +F test/sqldiff1.test 182058e09c7082de5c6a470ff9c291337bbeb650052c2cc68fbb3d7e25861d91 F test/sqllimits1.test 3f9030e5d35375ad3b912b4908094aa806335c8e9d804b8ffff70c5e9c664ab2 F test/sqllog.test 6af6cb0b09f4e44e1917e06ce85be7670302517a F test/startup.c 1beb5ca66fcc0fce95c3444db9d1674f90fc605499a574ae2434dcfc10d22805 @@ -1885,7 +1885,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd F tool/split-sqlite3c.tcl 3efcd4240b738f6bb2b5af0aea7e1e0ef9bc1c61654f645076cec883030b710c -F tool/sqldiff.c b4906b8a88252c94a77f2080f10c2624ba9b11f2577f25c1b29c3324a7a76c83 +F tool/sqldiff.c a94207d8a8b8ae20973012756362a850ba1f95bb4ed02cf950fd469eb556717c F tool/sqlite3_analyzer.c.in 7eeaae8b0d7577662acaabbb11107af0659d1b41bc1dfdd4d91422de27127968 F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898 F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848 @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 54eaf076c05887157179459ab39c2556953f6fef9c1b14f17a8aa74087da3023 -R a514ddb4ecddc8a67fe058834fe110d9 +P 68d2373f5d578cf3aff9d1ac4b1ab3ac00b466e94e1eb516523fc7660dfc0549 +R b342ee6ef1ac53ce3fb2ee3a5429a66d U larrybr -Z 948d1027dff68e9d9c973736292e2ed9 +Z 6a37992a46fe8182f8f9e189a49d79b9 diff --git a/manifest.uuid b/manifest.uuid index f8be94e571..a27edc6b0a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -68d2373f5d578cf3aff9d1ac4b1ab3ac00b466e94e1eb516523fc7660dfc0549 \ No newline at end of file +ff74c0cc4cefa5271b12ecfff3f2fd4749852d9d1d01f4ae64a07a26decc001b \ No newline at end of file diff --git a/test/sqldiff1.test b/test/sqldiff1.test index ea4e1f9993..4ea5efbbfa 100644 --- a/test/sqldiff1.test +++ b/test/sqldiff1.test @@ -35,6 +35,10 @@ do_test sqldiff-1.0 { DELETE FROM x2.t2 WHERE a=48; INSERT INTO x2.t1(a,b) VALUES(1234,'hello'); INSERT INTO x2.t2(a,b) VALUES(50.5,'xyzzy'); + INSERT INTO x2.t2(a,b) VALUES(51.5,''); + INSERT INTO x2.t2(a,b) VALUES(52.5,''||X'0d0a'); + INSERT INTO x2.t2(a,b) VALUES(53.5,'one'||X'0a0d'); + INSERT INTO x2.t2(a,b) VALUES(54.5,'one'||X'0a'||'two'); CREATE TABLE x2.t3(a,b,c); INSERT INTO x2.t3 VALUES(111,222,333); CREATE TABLE main.t4(x,y,z); @@ -50,6 +54,11 @@ do_test sqldiff-1.1 { INSERT INTO t1(a,b) VALUES(1234,'hello'); DELETE FROM t2 WHERE a=48; INSERT INTO t2(a,b) VALUES(50.5,'xyzzy'); +INSERT INTO t2(a,b) VALUES(51.5,''); +INSERT INTO t2(a,b) VALUES(52.5,''||X'0d0a'); +INSERT INTO t2(a,b) VALUES(53.5,'one'||X'0a0d'); +INSERT INTO t2(a,b) VALUES(54.5,'one'||X'0a' +||'two'); CREATE TABLE t3(a,b,c); INSERT INTO t3(rowid,a,b,c) VALUES(1,111,222,333); DROP TABLE t4;} diff --git a/tool/sqldiff.c b/tool/sqldiff.c index fea40b9fe0..b8b9e005b9 100644 --- a/tool/sqldiff.c +++ b/tool/sqldiff.c @@ -34,7 +34,6 @@ struct GlobalVars { int bSchemaOnly; /* Only show schema differences */ int bSchemaPK; /* Use the schema-defined PK, not the true PK */ int bHandleVtab; /* Handle fts3, fts4, fts5 and rtree vtabs */ - int bDarkCtl; /* Render controls in text as blob literals */ unsigned fDebug; /* Debug flags */ sqlite3 *db; /* The database connection */ } g; @@ -381,45 +380,35 @@ static void printQuoted(FILE *out, sqlite3_value *X){ } case SQLITE_TEXT: { const unsigned char *zArg = sqlite3_value_text(X); - int i, j; if( zArg==0 ){ fprintf(out, "NULL"); }else{ + int inctl = 0; + int i, j; fprintf(out, "'"); - if( !g.bDarkCtl ){ - for(i=j=0; zArg[i]; i++){ - if( zArg[i]=='\'' ){ + for(i=j=0; zArg[i]; i++){ + char c = zArg[i]; + int ctl = iscntrl(c); + if( ctl>inctl ){ + inctl = ctl; + fprintf(out, "%.*s'||X'%02x", i-j, &zArg[j], c); + j = i+1; + }else if( ctl ){ + fprintf(out, "%02x", c); + j = i+1; + }else{ + if( inctl ){ + inctl = 0; + fprintf(out, "'\n||'"); + } + if( c=='\'' ){ fprintf(out, "%.*s'", i-j+1, &zArg[j]); j = i+1; } } - fprintf(out, "%s'", &zArg[j]); - }else{ - int inctl = 0; - for(i=j=0; zArg[i]; i++){ - char c = zArg[i]; - int ctl = iscntrl(c); - if( ctl>inctl ){ - inctl = ctl; - fprintf(out, "%.*s'||X'%02x", i-j, &zArg[j], c); - j = i+1; - }else if( ctl ){ - fprintf(out, "%02x", c); - j = i+1; - }else{ - if( inctl ){ - inctl = 0; - fprintf(out, "'\n||'"); - } - if( c=='\'' ){ - fprintf(out, "%.*s'", i-j+1, &zArg[j]); - j = i+1; - } - } - } - fprintf(out, "%s'", &zArg[j]); } + fprintf(out, "%s'", &zArg[j]); } break; } @@ -1902,7 +1891,6 @@ static void showHelp(void){ " --table TAB Show only differences in table TAB\n" " --transaction Show SQL output inside a transaction\n" " --vtab Handle fts3, fts4, fts5 and rtree tables\n" -" --visible-controls Render controls in text as blob literals\n" ); } @@ -1976,9 +1964,6 @@ int main(int argc, char **argv){ if( strcmp(z,"vtab")==0 ){ g.bHandleVtab = 1; }else - if( strcmp(z, "visible-controls")==0 ){ - g.bDarkCtl = 1; - }else { cmdlineError("unknown option: %s", argv[i]); } From 9045e7d69680dba14ea6ac9d93fbb421abc568e0 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 28 Jul 2021 01:22:23 +0000 Subject: [PATCH 34/49] Reduce the scope of a variable in order to fix a harmless compiler warning that occurs under -DSQLITE_OMIT_AUTOMATIC_INDEX. FossilOrigin-Name: 36d5dbbe13562f4ea6435e620d102f8515bd0e6b8e66fd1841062a4e4621e330 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 516e0cdb39..2e1e23359b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\ssqldiff\s--visible-controls\soption,\smake\sit\salways\shappen.\sAdd\stest\scases\sfor\scontrols\smade\svisible -D 2021-07-26T19:49:01.920 +C Reduce\sthe\sscope\sof\sa\svariable\sin\sorder\sto\sfix\sa\sharmless\scompiler\swarning\nthat\soccurs\sunder\s-DSQLITE_OMIT_AUTOMATIC_INDEX. +D 2021-07-28T01:22:23.386 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -631,7 +631,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c c8ec20a1ca161d5635a4f19c2a4efec2e006e19a8a61f272bf6bce1c80ab7436 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c 7342becedf3f8a26f9817f08436bdf8b56ad69af83705f6b9320a0ad3092c2ac -F src/where.c 07a4097fe42a01b1f99d2a136598654051f0bdcd6c17cbef7fa285a9cf21e4d2 +F src/where.c 07c63dde6ab72477b964f4c81bee61ef78a246ca149bb9a560784f2e85cd78d7 F src/whereInt.h 9248161dd004f625ce5d3841ca9b99fed3fc8d61522cf76340fc5217dbe1375b F src/wherecode.c 9f1f65d11437b25cd0a1497a170514c785f19ce6ad9d3e6fc73719cb5a49012f F src/whereexpr.c 3a9144a9d52e110efdc012a73b1574e7b2b4df4bf98949387cb620295eba0975 @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 68d2373f5d578cf3aff9d1ac4b1ab3ac00b466e94e1eb516523fc7660dfc0549 -R b342ee6ef1ac53ce3fb2ee3a5429a66d -U larrybr -Z 6a37992a46fe8182f8f9e189a49d79b9 +P ff74c0cc4cefa5271b12ecfff3f2fd4749852d9d1d01f4ae64a07a26decc001b +R 0b9907c89e298e6ec44e54b431c85ab9 +U drh +Z bd3d716a77b8cb99bd8719b71b186559 diff --git a/manifest.uuid b/manifest.uuid index a27edc6b0a..97f636a899 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ff74c0cc4cefa5271b12ecfff3f2fd4749852d9d1d01f4ae64a07a26decc001b \ No newline at end of file +36d5dbbe13562f4ea6435e620d102f8515bd0e6b8e66fd1841062a4e4621e330 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 467963fda5..4ea04e5c8e 100644 --- a/src/where.c +++ b/src/where.c @@ -2984,7 +2984,6 @@ static int whereLoopAddBtree( int iSortIdx = 1; /* Index number */ int b; /* A boolean value */ LogEst rSize; /* number of rows in the table */ - LogEst rLogSize; /* Logarithm of the number of rows in the table */ WhereClause *pWC; /* The parsed WHERE clause */ Table *pTab; /* Table being queried */ @@ -3027,7 +3026,6 @@ static int whereLoopAddBtree( pProbe = &sPk; } rSize = pTab->nRowLogEst; - rLogSize = estLog(rSize); #ifndef SQLITE_OMIT_AUTOMATIC_INDEX /* Automatic indexes */ @@ -3041,8 +3039,10 @@ static int whereLoopAddBtree( && !pSrc->fg.isRecursive /* Not a recursive common table expression. */ ){ /* Generate auto-index WhereLoops */ + LogEst rLogSize; /* Logarithm of the number of rows in the table */ WhereTerm *pTerm; WhereTerm *pWCEnd = pWC->a + pWC->nTerm; + rLogSize = estLog(rSize); for(pTerm=pWC->a; rc==SQLITE_OK && pTermprereqRight & pNew->maskSelf ) continue; if( termCanDriveIndex(pTerm, pSrc, 0) ){ From c6da6dba691736f2eb156b419d63eb42b5a55cfa Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 28 Jul 2021 02:04:58 +0000 Subject: [PATCH 35/49] Fix a harmless uninitialized variable read that occurs after an error associated with a subquery that uses DISTINCT. Found by a fuzzer. FossilOrigin-Name: e9719f975f61c4c9f40ea077b049eed97d0957b925a4b6149d9ee21ce827b6a1 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 4 +++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 2e1e23359b..6d4f0ee275 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reduce\sthe\sscope\sof\sa\svariable\sin\sorder\sto\sfix\sa\sharmless\scompiler\swarning\nthat\soccurs\sunder\s-DSQLITE_OMIT_AUTOMATIC_INDEX. -D 2021-07-28T01:22:23.386 +C Fix\sa\sharmless\suninitialized\svariable\sread\sthat\soccurs\safter\san\serror\nassociated\swith\sa\ssubquery\sthat\suses\sDISTINCT.\s\sFound\sby\sa\sfuzzer. +D 2021-07-28T02:04:58.814 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -544,7 +544,7 @@ F src/printf.c 78fabb49b9ac9a12dd1c89d744abdc9b67fd3205e62967e158f78b965a29ec4b F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 047a822844cea769f6fdd8418a335dd4bcd8b75ab5e264f2506a0804f869b562 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 3896009f30352985b28511a0c4d7dbb77ba418e91db80ab7745a7f6dcbe1031f +F src/select.c 99c36dd4e7c2207ebdfd8c30986ab5aaeae74d0cdbbc471420807d50c417c241 F src/shell.c.in dc889872292ce143ab43080e7eb48b95f9b13beabf85ae729388a6b9ee08bab7 F src/sqlite.h.in 43fcf0fe2af04081f420a906fc020bde1243851ba44b0aa567a27f94bf8c3145 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ff74c0cc4cefa5271b12ecfff3f2fd4749852d9d1d01f4ae64a07a26decc001b -R 0b9907c89e298e6ec44e54b431c85ab9 +P 36d5dbbe13562f4ea6435e620d102f8515bd0e6b8e66fd1841062a4e4621e330 +R f3f844f66ceec878dd9e2f813d0ea286 U drh -Z bd3d716a77b8cb99bd8719b71b186559 +Z 2e0111a600397f530b0a2c274b105089 diff --git a/manifest.uuid b/manifest.uuid index 97f636a899..badb8c266c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -36d5dbbe13562f4ea6435e620d102f8515bd0e6b8e66fd1841062a4e4621e330 \ No newline at end of file +e9719f975f61c4c9f40ea077b049eed97d0957b925a4b6149d9ee21ce827b6a1 \ No newline at end of file diff --git a/src/select.c b/src/select.c index a50595413a..66e1434a31 100644 --- a/src/select.c +++ b/src/select.c @@ -873,7 +873,9 @@ static void fixDistinctOpenEph( int iVal, /* Value returned by codeDistinct() */ int iOpenEphAddr /* Address of OP_OpenEphemeral instruction for iTab */ ){ - if( eTnctType==WHERE_DISTINCT_UNIQUE || eTnctType==WHERE_DISTINCT_ORDERED ){ + if( pParse->nErr==0 + && (eTnctType==WHERE_DISTINCT_UNIQUE || eTnctType==WHERE_DISTINCT_ORDERED) + ){ Vdbe *v = pParse->pVdbe; sqlite3VdbeChangeToNoop(v, iOpenEphAddr); if( sqlite3VdbeGetOp(v, iOpenEphAddr+1)->opcode==OP_Explain ){ From 779e9906292c635ed4de646f05312fbf421c467d Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 28 Jul 2021 18:13:28 +0000 Subject: [PATCH 36/49] Add test case to ensure that sessions works with DELETE statements that use the truncate optimization (i.e. a DELETE without a WHERE clause). FossilOrigin-Name: a2fc531177c3a061f2881198bb711d502db7cd831351b6a5dd415936845b6625 --- ext/session/session1.test | 20 ++++++++++++++++++++ manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/shell.c.in | 8 ++++++++ 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/ext/session/session1.test b/ext/session/session1.test index 0eb850a795..bcd7b03d5c 100644 --- a/ext/session/session1.test +++ b/ext/session/session1.test @@ -152,6 +152,26 @@ do_changeset_test $tn.2.4.2 S {} do_changeset_invert_test $tn.2.4.3 S {} do_test $tn.2.4.4 { S delete } {} +do_execsql_test $tn.2.5.0 { + SELECT * FROM t1 ORDER BY x +} { + 2 Surin + 10 Sukhothai + 20 Thapae +} + +do_test $tn.2.5.1 { + sqlite3session S db main + S attach t1 + execsql { DELETE FROM t1 } +} {} +do_changeset_test $tn.2.5.2 S { + {DELETE t1 0 X. {i 10 t Sukhothai} {}} + {DELETE t1 0 X. {i 2 t Surin} {}} + {DELETE t1 0 X. {i 20 t Thapae} {}} +} +do_test $tn.2.5.3 { S delete } {} + #------------------------------------------------------------------------- # Test the application of simple changesets. These tests also test that # the conflict callback is invoked correctly. For these tests, the diff --git a/manifest b/manifest index 6d4f0ee275..0f6db671a1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sharmless\suninitialized\svariable\sread\sthat\soccurs\safter\san\serror\nassociated\swith\sa\ssubquery\sthat\suses\sDISTINCT.\s\sFound\sby\sa\sfuzzer. -D 2021-07-28T02:04:58.814 +C Add\stest\scase\sto\sensure\sthat\ssessions\sworks\swith\sDELETE\sstatements\sthat\suse\sthe\struncate\soptimization\s(i.e.\sa\sDELETE\swithout\sa\sWHERE\sclause). +D 2021-07-28T18:13:28.074 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -427,7 +427,7 @@ F ext/rtree/visual01.txt e9c2564083bcd30ec51b07f881bffbf0e12b50a3f6fced0c222c5c1 F ext/session/changeset.c 7a1e6a14c7e92d36ca177e92e88b5281acd709f3b726298dc34ec0fb58869cb5 F ext/session/changesetfuzz.c 227076ab0ae4447d742c01ee88a564da6478bbf26b65108bf8fac9cd8b0b24aa F ext/session/changesetfuzz1.test 2e1b90d888fbf0eea5e1bd2f1e527a48cc85f8e0ff75df1ec4e320b21f580b3a -F ext/session/session1.test 0b2f88995832ea040ae8e83a1ad4afa99c00b85c779d213da73a95ea4113233e +F ext/session/session1.test e94f764fbfb672147c0ef7026b195988133b371dc8cf9e52423eba6cad69717e F ext/session/session2.test 7f53d755d921e0baf815c4258348e0ed460dfd8a772351bca5ad3ccbb1dc786e F ext/session/session3.test ce9ce3dfa489473987f899e9f6a0f2db9bde3479 F ext/session/session4.test 6778997065b44d99c51ff9cece047ff9244a32856b328735ae27ddef68979c40 @@ -545,7 +545,7 @@ F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 047a822844cea769f6fdd8418a335dd4bcd8b75ab5e264f2506a0804f869b562 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 99c36dd4e7c2207ebdfd8c30986ab5aaeae74d0cdbbc471420807d50c417c241 -F src/shell.c.in dc889872292ce143ab43080e7eb48b95f9b13beabf85ae729388a6b9ee08bab7 +F src/shell.c.in 24b99dae8818d1a234732d73f4d5b49f12b510bc62735a41c04e314fafae09e3 F src/sqlite.h.in 43fcf0fe2af04081f420a906fc020bde1243851ba44b0aa567a27f94bf8c3145 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510 @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 36d5dbbe13562f4ea6435e620d102f8515bd0e6b8e66fd1841062a4e4621e330 -R f3f844f66ceec878dd9e2f813d0ea286 -U drh -Z 2e0111a600397f530b0a2c274b105089 +P e9719f975f61c4c9f40ea077b049eed97d0957b925a4b6149d9ee21ce827b6a1 +R 965bb65399cafcbf059e35da2cd76d6c +U dan +Z 2c36fca53731dd91ccb072aba7586086 diff --git a/manifest.uuid b/manifest.uuid index badb8c266c..49a4fbbb8f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e9719f975f61c4c9f40ea077b049eed97d0957b925a4b6149d9ee21ce827b6a1 \ No newline at end of file +a2fc531177c3a061f2881198bb711d502db7cd831351b6a5dd415936845b6625 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 713050555c..7e610fdeef 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -10040,6 +10040,7 @@ static int do_meta_command(char *zLine, ShellState *p){ { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE, "" }, { "prng_seed", SQLITE_TESTCTRL_PRNG_SEED, "SEED ?db?" }, { "seek_count", SQLITE_TESTCTRL_SEEK_COUNT, "" }, + { "sorter_mmap", SQLITE_TESTCTRL_SORTER_MMAP, "NMAX" }, { "tune", SQLITE_TESTCTRL_TUNE, "ID VALUE" }, }; int testctrl = -1; @@ -10220,6 +10221,13 @@ static int do_meta_command(char *zLine, ShellState *p){ break; } #endif + case SQLITE_TESTCTRL_SORTER_MMAP: + if( nArg==3 ){ + int opt = (unsigned int)integerValue(azArg[2]); + rc2 = sqlite3_test_control(testctrl, p->db, opt); + isOk = 3; + } + break; } } if( isOk==0 && iCtrl>=0 ){ From 02a9996e40dd60a11b614f797550abe2449a7ff9 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 29 Jul 2021 00:33:20 +0000 Subject: [PATCH 37/49] Remove ALWAYS() macros that can be true if the internal test function implies_nonnull_row() is used in the result set of a query and contains comparison operator against a computed column. dbsqlfuzz 4c34db5bff6247f33ee49e341a1f3018e72be0a0. FossilOrigin-Name: 4d1dbfa35c7dc0f09321b2e274a00e506f4ca65322454652d5891d815a6966d3 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 0f6db671a1..9a4cb795d9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\scase\sto\sensure\sthat\ssessions\sworks\swith\sDELETE\sstatements\sthat\suse\sthe\struncate\soptimization\s(i.e.\sa\sDELETE\swithout\sa\sWHERE\sclause). -D 2021-07-28T18:13:28.074 +C Remove\sALWAYS()\smacros\sthat\scan\sbe\strue\sif\sthe\sinternal\stest\sfunction\nimplies_nonnull_row()\sis\sused\sin\sthe\sresult\sset\sof\sa\squery\sand\scontains\ncomparison\soperator\sagainst\sa\scomputed\scolumn.\ndbsqlfuzz\s4c34db5bff6247f33ee49e341a1f3018e72be0a0. +D 2021-07-29T00:33:20.860 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -496,7 +496,7 @@ F src/date.c e0632f335952b32401482d099321bbf12716b29d6e72836b53ae49683ebae4bf F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c F src/delete.c 62451bba9fe641159e9c0b7d9d2bab1c48d0cff11e16de2d14000603d2af1fcf -F src/expr.c 62b6d0ac8ee30a4749b78b7b75ae951a911a5d49321af5fe41c05af4df9e7537 +F src/expr.c b1bcf90afb7dcc0fae4d81116177e3d02e0803f81fd543c10fcd0691390b6adf F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c e9063648396c58778f77583a678342fe4a9bc82436bf23c5f9f444f2df0fdaa4 F src/func.c c224240cbc97fa5e9c4fe9acb128716cb835ca045532bca6951b7c45b020c56c @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e9719f975f61c4c9f40ea077b049eed97d0957b925a4b6149d9ee21ce827b6a1 -R 965bb65399cafcbf059e35da2cd76d6c -U dan -Z 2c36fca53731dd91ccb072aba7586086 +P a2fc531177c3a061f2881198bb711d502db7cd831351b6a5dd415936845b6625 +R 302893be0ad635d55b2ba074ef459057 +U drh +Z 214bc8f469ab254a07e1605231d14a09 diff --git a/manifest.uuid b/manifest.uuid index 49a4fbbb8f..7ce3f9f163 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a2fc531177c3a061f2881198bb711d502db7cd831351b6a5dd415936845b6625 \ No newline at end of file +4d1dbfa35c7dc0f09321b2e274a00e506f4ca65322454652d5891d815a6966d3 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 4ad1902d25..dea2695461 100644 --- a/src/expr.c +++ b/src/expr.c @@ -5681,9 +5681,9 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ testcase( pExpr->op==TK_GE ); /* The y.pTab=0 assignment in wherecode.c always happens after the ** impliesNotNullRow() test */ - if( (pLeft->op==TK_COLUMN && ALWAYS(pLeft->y.pTab!=0) + if( (pLeft->op==TK_COLUMN && pLeft->y.pTab!=0 && IsVirtual(pLeft->y.pTab)) - || (pRight->op==TK_COLUMN && ALWAYS(pRight->y.pTab!=0) + || (pRight->op==TK_COLUMN && pRight->y.pTab!=0 && IsVirtual(pRight->y.pTab)) ){ return WRC_Prune; From fd4c7862eeb7eddb9989f5fa8a495e1504ac9cd8 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 29 Jul 2021 16:48:21 +0000 Subject: [PATCH 38/49] Improve comments and add new assert() statements in WAL to help document how everything works. FossilOrigin-Name: 23b08fe9db24a953cc231b093cf74d140c9965d22964d0401ff8ab3d4ecba443 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/wal.c | 37 ++++++++++++++++++++++++++++++++++--- 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 9a4cb795d9..02d491aeb1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sALWAYS()\smacros\sthat\scan\sbe\strue\sif\sthe\sinternal\stest\sfunction\nimplies_nonnull_row()\sis\sused\sin\sthe\sresult\sset\sof\sa\squery\sand\scontains\ncomparison\soperator\sagainst\sa\scomputed\scolumn.\ndbsqlfuzz\s4c34db5bff6247f33ee49e341a1f3018e72be0a0. -D 2021-07-29T00:33:20.860 +C Improve\scomments\sand\sadd\snew\sassert()\sstatements\sin\sWAL\sto\shelp\sdocument\nhow\severything\sworks. +D 2021-07-29T16:48:21.089 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -628,7 +628,7 @@ F src/vdbetrace.c 666c6fd9f1b62be6999e072a45b913e3c2c3518bc60dfd4d54fe304130acb7 F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c F src/vtab.c 3a9a6ae1fd14f7c00af184233cb9f3bced89ae277a75a312f85fb77297a3cdfa F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c c8ec20a1ca161d5635a4f19c2a4efec2e006e19a8a61f272bf6bce1c80ab7436 +F src/wal.c 1b1e7311d3f12ab60c012734e49ebf048d6eeb4485b6f077bd79f340e9c36731 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c 7342becedf3f8a26f9817f08436bdf8b56ad69af83705f6b9320a0ad3092c2ac F src/where.c 07c63dde6ab72477b964f4c81bee61ef78a246ca149bb9a560784f2e85cd78d7 @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a2fc531177c3a061f2881198bb711d502db7cd831351b6a5dd415936845b6625 -R 302893be0ad635d55b2ba074ef459057 +P 4d1dbfa35c7dc0f09321b2e274a00e506f4ca65322454652d5891d815a6966d3 +R 7a7643ec86e1f4d8e14a77c61b23a38c U drh -Z 214bc8f469ab254a07e1605231d14a09 +Z faf097f1ce1cc5bd6964b75ff7d837f7 diff --git a/manifest.uuid b/manifest.uuid index 7ce3f9f163..7ff76c7e5c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4d1dbfa35c7dc0f09321b2e274a00e506f4ca65322454652d5891d815a6966d3 \ No newline at end of file +23b08fe9db24a953cc231b093cf74d140c9965d22964d0401ff8ab3d4ecba443 \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index c3f84dd2ef..4b1d63e8d0 100644 --- a/src/wal.c +++ b/src/wal.c @@ -161,7 +161,10 @@ ** HASHTABLE_NPAGE_ONE frames. The values of HASHTABLE_NPAGE_ONE and ** HASHTABLE_NPAGE are selected so that together the wal-index header and ** first index block are the same size as all other index blocks in the -** wal-index. +** wal-index. The values are: +** +** HASHTABLE_NPAGE 4096 +** HASHTABLE_NPAGE_ONE 4062 ** ** Each index block contains two sections, a page-mapping that contains the ** database page number associated with each wal frame, and a hash-table @@ -1410,14 +1413,42 @@ int sqlite3WalOpen( assert( zWalName && zWalName[0] ); assert( pDbFd ); + /* Verify the values of various constants. Any changes to the values + ** of these constants would result in an incompatible on-disk format + ** for the -shm file. Any change that causes one of these asserts to + ** fail is a backward compatibility problem, even if the change otherwise + ** works. + ** + ** This table also serves as a helpful cross-reference when trying to + ** interpret hex dumps of the -shm file. + */ + assert( 48 == sizeof(WalIndexHdr) ); + assert( 40 == sizeof(WalCkptInfo) ); + assert( 120 == WALINDEX_LOCK_OFFSET ); + assert( 136 == WALINDEX_HDR_SIZE ); + assert( 4096 == HASHTABLE_NPAGE ); + assert( 4062 == HASHTABLE_NPAGE_ONE ); + assert( 8192 == HASHTABLE_NSLOT ); + assert( 383 == HASHTABLE_HASH_1 ); + assert( 32768 == WALINDEX_PGSZ ); + assert( 8 == SQLITE_SHM_NLOCK ); + assert( 5 == WAL_NREADER ); + assert( 24 == WAL_HDRSIZE ); + assert( 120 == WALINDEX_LOCK_OFFSET + WAL_WRITE_LOCK ); + assert( 121 == WALINDEX_LOCK_OFFSET + WAL_CKPT_LOCK ); + assert( 122 == WALINDEX_LOCK_OFFSET + WAL_RECOVER_LOCK ); + assert( 123 == WALINDEX_LOCK_OFFSET + WAL_READ_LOCK(0) ); + assert( 124 == WALINDEX_LOCK_OFFSET + WAL_READ_LOCK(1) ); + assert( 125 == WALINDEX_LOCK_OFFSET + WAL_READ_LOCK(2) ); + assert( 126 == WALINDEX_LOCK_OFFSET + WAL_READ_LOCK(3) ); + assert( 127 == WALINDEX_LOCK_OFFSET + WAL_READ_LOCK(4) ); + /* In the amalgamation, the os_unix.c and os_win.c source files come before ** this source file. Verify that the #defines of the locking byte offsets ** in os_unix.c and os_win.c agree with the WALINDEX_LOCK_OFFSET value. ** For that matter, if the lock offset ever changes from its initial design ** value of 120, we need to know that so there is an assert() to check it. */ - assert( 120==WALINDEX_LOCK_OFFSET ); - assert( 136==WALINDEX_HDR_SIZE ); #ifdef WIN_SHM_BASE assert( WIN_SHM_BASE==WALINDEX_LOCK_OFFSET ); #endif From 20de9f6cb11276ed8f6b53915d5d6d999230039b Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 29 Jul 2021 16:49:28 +0000 Subject: [PATCH 39/49] Minor tweaks to various TCL build scripts so that they work even for TCL 8.4, which is obsolete, but is also all that is available for some legacy platforms. FossilOrigin-Name: 2269ce64f707c4a198fcb9a72933648ea61a80b4251024b8058ff28ad81b4917 --- ext/fts5/tool/mkfts5c.tcl | 3 ++- manifest | 16 ++++++++-------- manifest.uuid | 2 +- tool/mkopcodec.tcl | 3 ++- tool/mkshellc.tcl | 6 ++++-- 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/ext/fts5/tool/mkfts5c.tcl b/ext/fts5/tool/mkfts5c.tcl index 797811d46e..b1a55fa4ae 100644 --- a/ext/fts5/tool/mkfts5c.tcl +++ b/ext/fts5/tool/mkfts5c.tcl @@ -60,7 +60,8 @@ proc fts5_source_id {zDir} { set L [split [readfile [file join $top manifest]]] set date [lindex $L [expr [lsearch -exact $L D]+1]] - set date [string range $date 0 [string last . $date]-1] + set idx [expr {[string last . $date]-1}] + set date [string range $date 0 $idx] set date [string map {T { }} $date] return "fts5: $date $uuid" diff --git a/manifest b/manifest index 02d491aeb1..120bb226b7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\scomments\sand\sadd\snew\sassert()\sstatements\sin\sWAL\sto\shelp\sdocument\nhow\severything\sworks. -D 2021-07-29T16:48:21.089 +C Minor\stweaks\sto\svarious\sTCL\sbuild\sscripts\sso\sthat\sthey\swork\seven\sfor\sTCL\s8.4,\nwhich\sis\sobsolete,\sbut\sis\salso\sall\sthat\sis\savailable\sfor\ssome\slegacy\splatforms. +D 2021-07-29T16:49:28.900 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -233,7 +233,7 @@ F ext/fts5/test/fts5vocab2.test c0a8397523561eb780b4f439e75d4969fade0ac40bc73e0c F ext/fts5/tool/fts5speed.tcl b0056f91a55b2d1a3684ec05729de92b042e2f85 F ext/fts5/tool/fts5txt2db.tcl c0d43c8590656f8240e622b00957b3a0facc49482411a9fdc2870b45c0c82f9f F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093 -F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45 +F ext/fts5/tool/mkfts5c.tcl 3eba8e9bee4221ed165f3304b51b2a74a705f4ec5df3d044573a2be539534af8 F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c F ext/icu/README.txt 1c48ffaf7f255bd73d00a35f68f6de357c2a6594f16cb00506a151be23694706 F ext/icu/icu.c 91c021c7e3e8bbba286960810fa303295c622e323567b2e6def4ce58e4466e60 @@ -1850,11 +1850,11 @@ F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650 F tool/mkctimec.tcl 5ef1891ed3d0e8143ff39bad7c01ed60c2817a2fb2d9a09487f7ccad2df621e4 F tool/mkkeywordhash.c 08b6e4d7a482a7f37a9a0032e7ba968e26624a027b6b2e9ba589be6f5e3d8c2c F tool/mkmsvcmin.tcl 6ecab9fe22c2c8de4d82d4c46797bda3d2deac8e763885f5a38d0c44a895ab33 -F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c +F tool/mkopcodec.tcl 33d20791e191df43209b77d37f0ff0904620b28465cca6990cf8d60da61a07ef F tool/mkopcodeh.tcl 130b88697da6ec5b89b41844d955d08fb62c2552e889dec8c7bcecb28d8f50bd F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa F tool/mkpragmatab.tcl 7f6db47d1995bc08247255622524567b2ab8962d98063f8aef97e35c3c54e3b8 -F tool/mkshellc.tcl 5fe7e518112b262e25726f248c0f33dd153192867453984b6af0a76a88e97cb2 +F tool/mkshellc.tcl df5d249617f9cc94d5c48eb0401673eb3f31f383ecbc54e8a13ca3dd97e89450 F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4d1dbfa35c7dc0f09321b2e274a00e506f4ca65322454652d5891d815a6966d3 -R 7a7643ec86e1f4d8e14a77c61b23a38c +P 23b08fe9db24a953cc231b093cf74d140c9965d22964d0401ff8ab3d4ecba443 +R 7cc2835397664c86246e99abe4a64984 U drh -Z faf097f1ce1cc5bd6964b75ff7d837f7 +Z 6820ddb47fc7506cf54e2e30c650a734 diff --git a/manifest.uuid b/manifest.uuid index 7ff76c7e5c..dd5cdfac06 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -23b08fe9db24a953cc231b093cf74d140c9965d22964d0401ff8ab3d4ecba443 \ No newline at end of file +2269ce64f707c4a198fcb9a72933648ea61a80b4251024b8058ff28ad81b4917 \ No newline at end of file diff --git a/tool/mkopcodec.tcl b/tool/mkopcodec.tcl index abdeaaeb32..5eac05fc02 100644 --- a/tool/mkopcodec.tcl +++ b/tool/mkopcodec.tcl @@ -22,7 +22,8 @@ puts "const char *sqlite3OpcodeName(int i)\173" puts " static const char *const azName\[\] = \173" set mx 0 -set in [open [lindex $argv 0] rb] +set in [open [lindex $argv 0]] +fconfigure $in -translation binary while {![eof $in]} { set line [gets $in] if {[regexp {^#define OP_} $line]} { diff --git a/tool/mkshellc.tcl b/tool/mkshellc.tcl index 46c2a528fe..82ecd2f61a 100644 --- a/tool/mkshellc.tcl +++ b/tool/mkshellc.tcl @@ -30,7 +30,8 @@ puts $out {/* DO NOT EDIT! ** edit the src/shell.c.in" and/or some of the other files that are included ** by "src/shell.c.in", then rerun the tool/mkshellc.tcl script. */} -set in [open $topdir/src/shell.c.in rb] +set in [open $topdir/src/shell.c.in] +fconfigure $in -translation binary proc omit_redundant_typedefs {line} { global typedef_seen if {[regexp {^typedef .*;} $line]} { @@ -50,7 +51,8 @@ while {1} { set cfile [lindex $lx 1] puts $out "/************************* Begin $cfile ******************/" # puts $out "#line 1 \"$cfile\"" - set in2 [open $topdir/src/$cfile rb] + set in2 [open $topdir/src/$cfile] + fconfigure $in2 -translation binary while {![eof $in2]} { set lx [omit_redundant_typedefs [gets $in2]] if {[regexp {^#include "sqlite} $lx]} { From 944d85dfe23b12d7055c0e4452f8b5d99c1906a9 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 29 Jul 2021 17:01:44 +0000 Subject: [PATCH 40/49] Fix an error in one of the assert() statements added by [23b08fe9db24a953]. FossilOrigin-Name: ad24334bc06dc9ae52825a1873a1eab6c258d77fcc00dec55884ddddecd9932e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/wal.c | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 120bb226b7..8846c82ec0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\stweaks\sto\svarious\sTCL\sbuild\sscripts\sso\sthat\sthey\swork\seven\sfor\sTCL\s8.4,\nwhich\sis\sobsolete,\sbut\sis\salso\sall\sthat\sis\savailable\sfor\ssome\slegacy\splatforms. -D 2021-07-29T16:49:28.900 +C Fix\san\serror\sin\sone\sof\sthe\sassert()\sstatements\sadded\sby\s[23b08fe9db24a953]. +D 2021-07-29T17:01:44.518 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -628,7 +628,7 @@ F src/vdbetrace.c 666c6fd9f1b62be6999e072a45b913e3c2c3518bc60dfd4d54fe304130acb7 F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c F src/vtab.c 3a9a6ae1fd14f7c00af184233cb9f3bced89ae277a75a312f85fb77297a3cdfa F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c 1b1e7311d3f12ab60c012734e49ebf048d6eeb4485b6f077bd79f340e9c36731 +F src/wal.c ce589eddfba84f9f89e789d08ea5ffe9e85454cbbfaba8fd42a258e3e08cf5e5 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c 7342becedf3f8a26f9817f08436bdf8b56ad69af83705f6b9320a0ad3092c2ac F src/where.c 07c63dde6ab72477b964f4c81bee61ef78a246ca149bb9a560784f2e85cd78d7 @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 23b08fe9db24a953cc231b093cf74d140c9965d22964d0401ff8ab3d4ecba443 -R 7cc2835397664c86246e99abe4a64984 +P 2269ce64f707c4a198fcb9a72933648ea61a80b4251024b8058ff28ad81b4917 +R d8e804ce8738bf098491021b76160220 U drh -Z 6820ddb47fc7506cf54e2e30c650a734 +Z 804b14c8c136144aca6d8b2088fe3d7f diff --git a/manifest.uuid b/manifest.uuid index dd5cdfac06..81ebe7246f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2269ce64f707c4a198fcb9a72933648ea61a80b4251024b8058ff28ad81b4917 \ No newline at end of file +ad24334bc06dc9ae52825a1873a1eab6c258d77fcc00dec55884ddddecd9932e \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index 4b1d63e8d0..ce9394d156 100644 --- a/src/wal.c +++ b/src/wal.c @@ -1433,7 +1433,8 @@ int sqlite3WalOpen( assert( 32768 == WALINDEX_PGSZ ); assert( 8 == SQLITE_SHM_NLOCK ); assert( 5 == WAL_NREADER ); - assert( 24 == WAL_HDRSIZE ); + assert( 24 == WAL_FRAME_HDRSIZE ); + assert( 32 == WAL_HDRSIZE ); assert( 120 == WALINDEX_LOCK_OFFSET + WAL_WRITE_LOCK ); assert( 121 == WALINDEX_LOCK_OFFSET + WAL_CKPT_LOCK ); assert( 122 == WALINDEX_LOCK_OFFSET + WAL_RECOVER_LOCK ); From 5025cb581f4c1949342b491ec8ce4d9dab749b0b Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 29 Jul 2021 17:23:23 +0000 Subject: [PATCH 41/49] Complete warning-free build on old PPC iBook. FossilOrigin-Name: ef2a0850394b1c6c1fc84b26694a3712ae1e50d52bb78fea2ec40148a7d833de --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqliteInt.h | 1 + src/vdbeaux.c | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 8846c82ec0..08aa89e51f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\serror\sin\sone\sof\sthe\sassert()\sstatements\sadded\sby\s[23b08fe9db24a953]. -D 2021-07-29T17:01:44.518 +C Complete\swarning-free\sbuild\son\sold\sPPC\siBook. +D 2021-07-29T17:23:23.932 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -549,7 +549,7 @@ F src/shell.c.in 24b99dae8818d1a234732d73f4d5b49f12b510bc62735a41c04e314fafae09e F src/sqlite.h.in 43fcf0fe2af04081f420a906fc020bde1243851ba44b0aa567a27f94bf8c3145 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510 -F src/sqliteInt.h b3762f49d8b6b4bf7bf30d154f007d6f9421c86343042d7a246a79988d1fec1a +F src/sqliteInt.h 441f226f8e5de526fcbddc092d6fa7f99df12985bf29411399219e79196caf82 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -620,7 +620,7 @@ F src/vdbe.c b73a5ec9940185eb001ff8cff2cfd429bb438c7e89f2885e0bfdb56c3ff13386 F src/vdbe.h 25dabb25c7e157b84e59260cfb5b466c3ac103ede9f36f4db371332c47601abe F src/vdbeInt.h 38206c8dd6b60ff03d9fd4f626b1b4fd0eef7cdc44f2fc2c1973b0f932a3f26b F src/vdbeapi.c aa5aaf2c37676b83af5724c6cd8207a3064ed46a217fd180957f75ac84f7a2a5 -F src/vdbeaux.c 564622045316eb2eed1370714426e81ab96d86e7894a368e80a83e0baff23346 +F src/vdbeaux.c 202dbaf7d1570cd53678f6b0bcad7b0642e88bc5d77abc1d5b8b9a202a6a19fd F src/vdbeblob.c c6b8db50b227f66fb404215732068df76485b5b433e5f9d4d9ac27410b218193 F src/vdbemem.c 53881aa0a7845922a075b3f375695588618098871a7a4120af4c297b80fa3e64 F src/vdbesort.c cd5130f683706c1a43e165a74187745fb3351cb56052cf9dc91de820634bbde2 @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2269ce64f707c4a198fcb9a72933648ea61a80b4251024b8058ff28ad81b4917 -R d8e804ce8738bf098491021b76160220 +P ad24334bc06dc9ae52825a1873a1eab6c258d77fcc00dec55884ddddecd9932e +R 0cc81a8b442d38496113a96ee86b0452 U drh -Z 804b14c8c136144aca6d8b2088fe3d7f +Z fb51ecf5d08ca6d7c7f076fcbd12aa41 diff --git a/manifest.uuid b/manifest.uuid index 81ebe7246f..843b94000a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ad24334bc06dc9ae52825a1873a1eab6c258d77fcc00dec55884ddddecd9932e \ No newline at end of file +ef2a0850394b1c6c1fc84b26694a3712ae1e50d52bb78fea2ec40148a7d833de \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 651116aa9e..25eb9f1089 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -861,6 +861,7 @@ typedef INT16_TYPE LogEst; # define SQLITE_PTRSIZE __SIZEOF_POINTER__ # elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \ defined(_M_ARM) || defined(__arm__) || defined(__x86) || \ + (defined(__APPLE__) && defined(__POWERPC__)) || \ (defined(__TOS_AIX__) && !defined(__64BIT__)) # define SQLITE_PTRSIZE 4 # else diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 5c9ab11c7d..a6bb915e1c 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1660,7 +1660,7 @@ char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){ case P4_COLLSEQ: { static const char *const encnames[] = {"?", "8", "16LE", "16BE"}; CollSeq *pColl = pOp->p4.pColl; - assert( pColl->enc>=0 && pColl->enc<4 ); + assert( pColl->enc<4 ); sqlite3_str_appendf(&x, "%.18s-%s", pColl->zName, encnames[pColl->enc]); break; From f873392dde80f3628c1582d6b026778b07e1e3cf Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 29 Jul 2021 18:34:35 +0000 Subject: [PATCH 42/49] Enhance the wal.c source file with an ASCII-art schematic of the -shm file header. FossilOrigin-Name: a6c160e08a61d105f8aab959440ac5ec4f1aaca8f0d393e08e7c2c67815b5bb2 --- manifest | 13 +++++------ manifest.uuid | 2 +- src/wal.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 2adaf55f14..43773f70d7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sasserts\sto\senforce\smagic\snumbers\sin\sthe\swal-index\sformat.\nAlso\simprove\sautomatic\sconfigure\sand\smake\sbuilds\son\slegacy\sPPC\siBooks. -D 2021-07-29T17:31:40.386 +C Enhance\sthe\swal.c\ssource\sfile\swith\san\sASCII-art\sschematic\sof\sthe\s-shm\sfile\nheader. +D 2021-07-29T18:34:35.597 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -628,7 +628,7 @@ F src/vdbetrace.c 666c6fd9f1b62be6999e072a45b913e3c2c3518bc60dfd4d54fe304130acb7 F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c F src/vtab.c 3a9a6ae1fd14f7c00af184233cb9f3bced89ae277a75a312f85fb77297a3cdfa F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c ce589eddfba84f9f89e789d08ea5ffe9e85454cbbfaba8fd42a258e3e08cf5e5 +F src/wal.c 2be08331d798237ad5d7ae0b252700ffb2b63189cb18d993496d009a93e2f81c F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c 7342becedf3f8a26f9817f08436bdf8b56ad69af83705f6b9320a0ad3092c2ac F src/where.c 07c63dde6ab72477b964f4c81bee61ef78a246ca149bb9a560784f2e85cd78d7 @@ -1920,8 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4d1dbfa35c7dc0f09321b2e274a00e506f4ca65322454652d5891d815a6966d3 ef2a0850394b1c6c1fc84b26694a3712ae1e50d52bb78fea2ec40148a7d833de -R 0cc81a8b442d38496113a96ee86b0452 -T +closed ef2a0850394b1c6c1fc84b26694a3712ae1e50d52bb78fea2ec40148a7d833de +P 87b8d47889f1990442aa90398614656658207085d064381074f72bda9bdcbfa5 +R d8c25bc87f149d13a2a70b86ca69893f U drh -Z 98161da94e50e1df5812fdb04f331f1a +Z 666b852ed7a04d1347b165527afd3943 diff --git a/manifest.uuid b/manifest.uuid index 3b5473b5ca..0e2535e1ad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -87b8d47889f1990442aa90398614656658207085d064381074f72bda9bdcbfa5 \ No newline at end of file +a6c160e08a61d105f8aab959440ac5ec4f1aaca8f0d393e08e7c2c67815b5bb2 \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index ce9394d156..83929ea467 100644 --- a/src/wal.c +++ b/src/wal.c @@ -400,6 +400,70 @@ struct WalCkptInfo { }; #define READMARK_NOT_USED 0xffffffff +/* +** This is a schematic view of the complete 136-byte header of the +** wal-index file (also known as the -shm file): +** +** +-----------------------------+ +** 0: | iVersion | \ +** +-----------------------------+ | +** 4: | (unused padding) | | +** +-----------------------------+ | +** 8: | iChange | | +** +-------+-------+-------------+ | +** 12: | bInit | bBig | szPage | | +** +-------+-------+-------------+ | +** 16: | mxFrame | | First copy of the +** +-----------------------------+ | WalIndexHdr object +** 20: | nPage | | +** +-----------------------------+ | +** 24: | aFrameCksum | | +** | | | +** +-----------------------------+ | +** 32: | aSalt | | +** | | | +** +-----------------------------+ | +** 40: | aCksum | | +** | | / +** +-----------------------------+ +** 48: | iVersion | \ +** +-----------------------------+ | +** 52: | (unused padding) | | +** +-----------------------------+ | +** 56: | iChange | | +** +-------+-------+-------------+ | +** 60: | bInit | bBig | szPage | | +** +-------+-------+-------------+ | Second copy of the +** 64: | mxFrame | | WalIndexHdr +** +-----------------------------+ | +** 68: | nPage | | +** +-----------------------------+ | +** 72: | aFrameCksum | | +** | | | +** +-----------------------------+ | +** 80: | aSalt | | +** | | | +** +-----------------------------+ | +** 88: | aCksum | | +** | | / +** +-----------------------------+ +** 96: | nBackfill | +** +-----------------------------+ +** 100: | 5 read marks | +** | | +** | | +** | | +** | | +** +-------+-------+------+------+ +** 120: | Write | Ckpt | Rcvr | Rd0 | \ +** +-------+-------+------+------+ ) 8 lock bytes +** | Read1 | Read2 | Rd3 | Rd4 | / +** +-------+-------+------+------+ +** 128: | nBackfillAttempted | +** +-----------------------------+ +** 132: | (unused padding) | +** +-----------------------------+ +*/ /* A block of WALINDEX_LOCK_RESERVED bytes beginning at ** WALINDEX_LOCK_OFFSET is reserved for locks. Since some systems From 7b3c514b5324156c8ba4c9fbb0548f374ccdb629 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 30 Jul 2021 12:47:35 +0000 Subject: [PATCH 43/49] Reduce clownfooting in the allocation of the Table.aCol array. This reduces the amount of heap space required to hold large schemas by about 11%. FossilOrigin-Name: 2941ded0acbdcf914567bf7451cfd9b770269545c20d3fa7107c40492689afad --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 14 ++++++-------- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 43773f70d7..edf0ee35b2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\swal.c\ssource\sfile\swith\san\sASCII-art\sschematic\sof\sthe\s-shm\sfile\nheader. -D 2021-07-29T18:34:35.597 +C Reduce\sclownfooting\sin\sthe\sallocation\sof\sthe\sTable.aCol\sarray.\s\sThis\sreduces\nthe\samount\sof\sheap\sspace\srequired\sto\shold\slarge\sschemas\sby\sabout\s11%. +D 2021-07-30T12:47:35.850 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -488,7 +488,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c e204a9c8fb4fe5dbb910a863ba487f4af9b5c501254ec4ccbfcdd6b1f65b7fb4 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0 -F src/build.c 9978caf1e5c6c82d04d85e290d46979abc2219fb79bcd970258d1ebe368d184e +F src/build.c 218628f5743e2329959f66269928ac9521cc5e7f69d8bcc0e90a57f2715fe0ae F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 8159d5f706551861c18ec6c8f6bdf105e15ea00367f05d9ab65d31a1077facc1 @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 87b8d47889f1990442aa90398614656658207085d064381074f72bda9bdcbfa5 -R d8c25bc87f149d13a2a70b86ca69893f +P a6c160e08a61d105f8aab959440ac5ec4f1aaca8f0d393e08e7c2c67815b5bb2 +R 05be268cc1d65b192983539c10fe9664 U drh -Z 666b852ed7a04d1347b165527afd3943 +Z 293e50cb88f37ee66f4747a547b7dd6f diff --git a/manifest.uuid b/manifest.uuid index 0e2535e1ad..bfefc3402b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a6c160e08a61d105f8aab959440ac5ec4f1aaca8f0d393e08e7c2c67815b5bb2 \ No newline at end of file +2941ded0acbdcf914567bf7451cfd9b770269545c20d3fa7107c40492689afad \ No newline at end of file diff --git a/src/build.c b/src/build.c index 824c104743..4f6f50a20c 100644 --- a/src/build.c +++ b/src/build.c @@ -1381,6 +1381,7 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ Column *pCol; sqlite3 *db = pParse->db; u8 hName; + Column *aNew; if( (p = pParse->pNewTable)==0 ) return; if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){ @@ -1401,15 +1402,12 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ return; } } - if( (p->nCol & 0x7)==0 ){ - Column *aNew; - aNew = sqlite3DbRealloc(db,p->aCol,(p->nCol+8)*sizeof(p->aCol[0])); - if( aNew==0 ){ - sqlite3DbFree(db, z); - return; - } - p->aCol = aNew; + aNew = sqlite3DbRealloc(db,p->aCol,(p->nCol+1)*sizeof(p->aCol[0])); + if( aNew==0 ){ + sqlite3DbFree(db, z); + return; } + p->aCol = aNew; pCol = &p->aCol[p->nCol]; memset(pCol, 0, sizeof(p->aCol[0])); pCol->zName = z; From 77441faff5f4d5cee08c747116fae97b48eeb9b0 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 30 Jul 2021 18:39:59 +0000 Subject: [PATCH 44/49] Avoid clownfeet in the names columns when the column names are quoted in the original CREATE TABLE statement. FossilOrigin-Name: 980f7292afd45a8e73272e2139b55b99ab86167febec9fd0bf0356e8167b2ee9 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/build.c | 17 +++++++++-------- src/parse.y | 2 +- src/sqliteInt.h | 3 ++- src/util.c | 29 +++++++++++++++++++++++++++-- 6 files changed, 49 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index edf0ee35b2..4346c12927 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reduce\sclownfooting\sin\sthe\sallocation\sof\sthe\sTable.aCol\sarray.\s\sThis\sreduces\nthe\samount\sof\sheap\sspace\srequired\sto\shold\slarge\sschemas\sby\sabout\s11%. -D 2021-07-30T12:47:35.850 +C Avoid\sclownfeet\sin\sthe\snames\scolumns\swhen\sthe\scolumn\snames\sare\squoted\nin\sthe\soriginal\sCREATE\sTABLE\sstatement. +D 2021-07-30T18:39:59.675 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -488,7 +488,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c e204a9c8fb4fe5dbb910a863ba487f4af9b5c501254ec4ccbfcdd6b1f65b7fb4 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0 -F src/build.c 218628f5743e2329959f66269928ac9521cc5e7f69d8bcc0e90a57f2715fe0ae +F src/build.c 8b0a6aa7dbce272c66f282f7aeec6e37ee1c7ded21e8f5a6e3864b0ab6ccdb29 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 8159d5f706551861c18ec6c8f6bdf105e15ea00367f05d9ab65d31a1077facc1 @@ -533,7 +533,7 @@ F src/os_win.c 77d39873836f1831a9b0b91894fec45ab0e9ca8e067dc8c549e1d1eca1566fe9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 95c255256b13827caf038c8f963d334784073f38ab6ef9d70371d9d04f3c43e0 F src/pager.h 4bf9b3213a4b2bebbced5eaa8b219cf25d4a82f385d093cd64b7e93e5285f66f -F src/parse.y 6d90c816edf65e99fb978c3b5486df5e661c3534347efac2842b80eb02263e68 +F src/parse.y 0ba0baec5de6921ec8ba8bbcf1018969144ef29d26112e17539d8fbb1662e3eb F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 388304fd2d91c39591080b5e0f3c62cfba87db20370e7e0554062bfb29740e9f @@ -549,7 +549,7 @@ F src/shell.c.in 24b99dae8818d1a234732d73f4d5b49f12b510bc62735a41c04e314fafae09e F src/sqlite.h.in 43fcf0fe2af04081f420a906fc020bde1243851ba44b0aa567a27f94bf8c3145 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510 -F src/sqliteInt.h 441f226f8e5de526fcbddc092d6fa7f99df12985bf29411399219e79196caf82 +F src/sqliteInt.h 1041c70f63687392665dde29f87f8af27d27bc1e18d29c8b804360fc915c2fde F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -614,7 +614,7 @@ F src/trigger.c 7d16aa09e63226b6d8b3f0fc60b21cbfa596fc406288b2ebcf4266633d1ba222 F src/update.c 30465f9accc854e8a7932b413578027fbb68186132abbb36e01d2022473fc83d F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 -F src/util.c 41c7a72da1df47864faa378a1c720b38adb288c6838cb6be5594511b6287a048 +F src/util.c b2cb568393144b05df06871b2c61b0f0240f1835aee2843c736391507fac2780 F src/vacuum.c 454973a59fb20bb982efc2df568a098616db6328a0491b6e84e2e07f7333db45 F src/vdbe.c b73a5ec9940185eb001ff8cff2cfd429bb438c7e89f2885e0bfdb56c3ff13386 F src/vdbe.h 25dabb25c7e157b84e59260cfb5b466c3ac103ede9f36f4db371332c47601abe @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a6c160e08a61d105f8aab959440ac5ec4f1aaca8f0d393e08e7c2c67815b5bb2 -R 05be268cc1d65b192983539c10fe9664 +P 2941ded0acbdcf914567bf7451cfd9b770269545c20d3fa7107c40492689afad +R 34387fa0540aea58caf42bd33cbb64b5 U drh -Z 293e50cb88f37ee66f4747a547b7dd6f +Z a43263f36582e13af1a30f741180b3be diff --git a/manifest.uuid b/manifest.uuid index bfefc3402b..50ed690d5f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2941ded0acbdcf914567bf7451cfd9b770269545c20d3fa7107c40492689afad \ No newline at end of file +980f7292afd45a8e73272e2139b55b99ab86167febec9fd0bf0356e8167b2ee9 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 4f6f50a20c..5d2936f5b9 100644 --- a/src/build.c +++ b/src/build.c @@ -1373,7 +1373,7 @@ void sqlite3AddReturning(Parse *pParse, ExprList *pList){ ** first to get things going. Then this routine is called for each ** column. */ -void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ +void sqlite3AddColumn(Parse *pParse, Token sName, Token sType){ Table *p; int i; char *z; @@ -1388,11 +1388,12 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName); return; } - z = sqlite3DbMallocRaw(db, pName->n + pType->n + 2); + if( !IN_RENAME_OBJECT ) sqlite3DequoteToken(&sName); + z = sqlite3DbMallocRaw(db, sName.n + sType.n + 2); if( z==0 ) return; - if( IN_RENAME_OBJECT ) sqlite3RenameTokenMap(pParse, (void*)z, pName); - memcpy(z, pName->z, pName->n); - z[pName->n] = 0; + if( IN_RENAME_OBJECT ) sqlite3RenameTokenMap(pParse, (void*)z, &sName); + memcpy(z, sName.z, sName.n); + z[sName.n] = 0; sqlite3Dequote(z); hName = sqlite3StrIHash(z); for(i=0; inCol; i++){ @@ -1414,7 +1415,7 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ pCol->hName = hName; sqlite3ColumnPropertiesFromName(p, pCol); - if( pType->n==0 ){ + if( sType.n==0 ){ /* If there is no type specified, columns have the default affinity ** 'BLOB' with a default size of 4 bytes. */ pCol->affinity = SQLITE_AFF_BLOB; @@ -1426,8 +1427,8 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ #endif }else{ zType = z + sqlite3Strlen30(z) + 1; - memcpy(zType, pType->z, pType->n); - zType[pType->n] = 0; + memcpy(zType, sType.z, sType.n); + zType[sType.n] = 0; sqlite3Dequote(zType); pCol->affinity = sqlite3AffinityType(zType, pCol); pCol->colFlags |= COLFLAG_HASTYPE; diff --git a/src/parse.y b/src/parse.y index 1e07825589..24c539bdb3 100644 --- a/src/parse.y +++ b/src/parse.y @@ -215,7 +215,7 @@ table_options(A) ::= WITHOUT nm(X). { } columnlist ::= columnlist COMMA columnname carglist. columnlist ::= columnname carglist. -columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);} +columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,A,Y);} // Declare some tokens early in order to influence their values, to // improve performance and reduce the executable size. The goal here is diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 25eb9f1089..7d6fda4c66 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4317,6 +4317,7 @@ void sqlite3ErrorMsg(Parse*, const char*, ...); int sqlite3ErrorToParser(sqlite3*,int); void sqlite3Dequote(char*); void sqlite3DequoteExpr(Expr*); +void sqlite3DequoteToken(Token*); void sqlite3TokenInit(Token*,char*); int sqlite3KeywordCode(const unsigned char*, int); int sqlite3RunParser(Parse*, const char*, char **); @@ -4383,7 +4384,7 @@ void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int); #else # define sqlite3ColumnPropertiesFromName(T,C) /* no-op */ #endif -void sqlite3AddColumn(Parse*,Token*,Token*); +void sqlite3AddColumn(Parse*,Token,Token); void sqlite3AddNotNull(Parse*, int); void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int); void sqlite3AddCheckConstraint(Parse*, Expr*, const char*, const char*); diff --git a/src/util.c b/src/util.c index fc0c2042bd..8bcf1d261a 100644 --- a/src/util.c +++ b/src/util.c @@ -89,8 +89,11 @@ int sqlite3Strlen30(const char *z){ ** the column name if and only if the COLFLAG_HASTYPE flag is set. */ char *sqlite3ColumnType(Column *pCol, char *zDflt){ - if( (pCol->colFlags & COLFLAG_HASTYPE)==0 ) return zDflt; - return pCol->zName + strlen(pCol->zName) + 1; + if( pCol->colFlags & COLFLAG_HASTYPE ){ + return pCol->zName + strlen(pCol->zName) + 1; + }else{ + return zDflt; + } } /* @@ -266,6 +269,28 @@ void sqlite3DequoteExpr(Expr *p){ sqlite3Dequote(p->u.zToken); } +/* +** If the input token p is quoted, try to adjust the token to remove +** the quotes. This is not always possible: +** +** "abc" -> abc +** "ab""cd" -> (not possible because of the interior "") +** +** Remove the quotes if possible. This is a optimization. The overall +** system should still return the correct answer even if this routine +** is always a no-op. +*/ +void sqlite3DequoteToken(Token *p){ + int i; + if( p->n<2 ) return; + if( !sqlite3Isquote(p->z[0]) ) return; + for(i=1; in-1; i++){ + if( sqlite3Isquote(p->z[i]) ) return; + } + p->n -= 2; + p->z++; +} + /* ** Generate a Token object from a string */ From e48f261ebfd36b4935c2d700269790239dac37e5 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 30 Jul 2021 20:09:08 +0000 Subject: [PATCH 45/49] If a generated column uses the optional keywords GENERATE ALWAYS, try to avoid putting those keywords in the typename of the column. [forum:/forumpost/ff3ffe09251c105b|Forum post ff3ffe09251c105b] FossilOrigin-Name: 3c954863f45271a3518acf51fd685a641878811fb5cfcbdbad85154aeccdc902 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/build.c | 18 ++++++++++++++++++ test/gencol1.test | 16 ++++++++++++++++ 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 4346c12927..f62c0433cf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sclownfeet\sin\sthe\snames\scolumns\swhen\sthe\scolumn\snames\sare\squoted\nin\sthe\soriginal\sCREATE\sTABLE\sstatement. -D 2021-07-30T18:39:59.675 +C If\sa\sgenerated\scolumn\suses\sthe\soptional\skeywords\sGENERATE\sALWAYS,\stry\sto\savoid\nputting\sthose\skeywords\sin\sthe\stypename\sof\sthe\scolumn.\n[forum:/forumpost/ff3ffe09251c105b|Forum\spost\sff3ffe09251c105b] +D 2021-07-30T20:09:08.819 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -488,7 +488,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c e204a9c8fb4fe5dbb910a863ba487f4af9b5c501254ec4ccbfcdd6b1f65b7fb4 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0 -F src/build.c 8b0a6aa7dbce272c66f282f7aeec6e37ee1c7ded21e8f5a6e3864b0ab6ccdb29 +F src/build.c fedaf923ea61eed3496f5ef6fca6e3162344faf109e8d0228f61c7a24b92fe6a F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 8159d5f706551861c18ec6c8f6bdf105e15ea00367f05d9ab65d31a1077facc1 @@ -1062,7 +1062,7 @@ F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc F test/gcfault.test dd28c228a38976d6336a3fc42d7e5f1ad060cb8c -F test/gencol1.test b05e6c5edb9b10d48efb634ed07342441bddc89d225043e17095c36e567521a0 +F test/gencol1.test 26c55577b15f78069bacf8afee994b74b9d69aa690577db9cff926b10e4e6be2 F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 F test/having.test a89236dd8d55aa50c4805f82ac9daf64d477a44d712d8209c118978d0ca21ec9 F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751 @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2941ded0acbdcf914567bf7451cfd9b770269545c20d3fa7107c40492689afad -R 34387fa0540aea58caf42bd33cbb64b5 +P 980f7292afd45a8e73272e2139b55b99ab86167febec9fd0bf0356e8167b2ee9 +R 5e0d17f3eda249159c66a4dab795bade U drh -Z a43263f36582e13af1a30f741180b3be +Z b92983df8210770e5aba5b5d6965da26 diff --git a/manifest.uuid b/manifest.uuid index 50ed690d5f..b98c86df86 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -980f7292afd45a8e73272e2139b55b99ab86167febec9fd0bf0356e8167b2ee9 \ No newline at end of file +3c954863f45271a3518acf51fd685a641878811fb5cfcbdbad85154aeccdc902 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 5d2936f5b9..43112a4cd0 100644 --- a/src/build.c +++ b/src/build.c @@ -1389,6 +1389,24 @@ void sqlite3AddColumn(Parse *pParse, Token sName, Token sType){ return; } if( !IN_RENAME_OBJECT ) sqlite3DequoteToken(&sName); + + /* Because keywords GENERATE ALWAYS can be converted into indentifiers + ** by the parser, we can sometimes end up with a typename that ends + ** with "generated always". Check for this case and omit the surplus + ** text. */ + if( sType.n>=16 + && sqlite3_strnicmp(sType.z+(sType.n-6),"always",6)==0 + ){ + sType.n -= 6; + while( ALWAYS(sType.n>0) && sqlite3Isspace(sType.z[sType.n-1]) ) sType.n--; + if( sType.n>=9 + && sqlite3_strnicmp(sType.z+(sType.n-9),"generated",9)==0 + ){ + sType.n -= 9; + while( sType.n>0 && sqlite3Isspace(sType.z[sType.n-1]) ) sType.n--; + } + } + z = sqlite3DbMallocRaw(db, sName.n + sType.n + 2); if( z==0 ) return; if( IN_RENAME_OBJECT ) sqlite3RenameTokenMap(pParse, (void*)z, &sName); diff --git a/test/gencol1.test b/test/gencol1.test index 43f48dff78..c0bb52361e 100644 --- a/test/gencol1.test +++ b/test/gencol1.test @@ -585,5 +585,21 @@ do_execsql_test gencol1-20.2 { SELECT * FROM tab; } {2001-01-01 0 0 5 {}} +# 2021-07-30 forum https://sqlite.org/forum/forumpost/ff3ffe09251c105b?t=h +# +reset_db +do_execsql_test gencol1-21.1 { + CREATE TABLE t1( + a integer primary key, + b int generated always as (a+5), + c text GENERATED ALWAYS as (printf('%08x',a)), + d Generated + Always + AS ('xyzzy'), + e int Always default(5) + ); + INSERT INTO t1(a) VALUES(5); + SELECT name, type FROM pragma_table_xinfo('t1'); +} {a integer b int c text d {} e {int}} finish_test From c2df4d6adb44e5f9587bf962c917c46c603825c9 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 30 Jul 2021 23:30:30 +0000 Subject: [PATCH 46/49] Recognize certain standard datatypes ("INT", "INTEGER", "REAL", "TEXT", and "BLOB") and if a column has one of those datatypes, store the type part of the bit-field information in the Column structure to save space. FossilOrigin-Name: d2da62a9df63036b02dadca3798de9e623c2680b3ef0c37d2b18bb88693afd7f --- manifest | 28 ++++++++++++++-------------- manifest.uuid | 2 +- src/build.c | 36 ++++++++++++++++++++++++++++++------ src/global.c | 20 ++++++++++++++++++++ src/sqliteInt.h | 19 +++++++++++++++++++ src/util.c | 3 +++ test/capi2.test | 12 ++++++------ test/gencol1.test | 2 +- test/pragma.test | 2 +- test/tclsqlite.test | 2 +- test/vtabA.test | 2 +- 11 files changed, 97 insertions(+), 31 deletions(-) diff --git a/manifest b/manifest index f62c0433cf..e3ec8ecc4f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C If\sa\sgenerated\scolumn\suses\sthe\soptional\skeywords\sGENERATE\sALWAYS,\stry\sto\savoid\nputting\sthose\skeywords\sin\sthe\stypename\sof\sthe\scolumn.\n[forum:/forumpost/ff3ffe09251c105b|Forum\spost\sff3ffe09251c105b] -D 2021-07-30T20:09:08.819 +C Recognize\scertain\sstandard\sdatatypes\s("INT",\s"INTEGER",\s"REAL",\s"TEXT",\sand\n"BLOB")\sand\sif\sa\scolumn\shas\sone\sof\sthose\sdatatypes,\sstore\sthe\stype\spart\sof\nthe\sbit-field\sinformation\sin\sthe\sColumn\sstructure\sto\ssave\sspace. +D 2021-07-30T23:30:30.921 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -488,7 +488,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c e204a9c8fb4fe5dbb910a863ba487f4af9b5c501254ec4ccbfcdd6b1f65b7fb4 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0 -F src/build.c fedaf923ea61eed3496f5ef6fca6e3162344faf109e8d0228f61c7a24b92fe6a +F src/build.c e9ff9104d6d64dd2a000ca9cc7d25c80a5b1a3fd2422b4e0d84afee8c8bef78b F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 8159d5f706551861c18ec6c8f6bdf105e15ea00367f05d9ab65d31a1077facc1 @@ -500,7 +500,7 @@ F src/expr.c b1bcf90afb7dcc0fae4d81116177e3d02e0803f81fd543c10fcd0691390b6adf F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c e9063648396c58778f77583a678342fe4a9bc82436bf23c5f9f444f2df0fdaa4 F src/func.c c224240cbc97fa5e9c4fe9acb128716cb835ca045532bca6951b7c45b020c56c -F src/global.c 25ba4d58476f6be29bba9d9d14f7f146b78476d3a4d75ebb8c3b736328afe0f9 +F src/global.c 5eba017ebbd887e2365e6e6e815e1619e41406b8946d17594e94116174787df5 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144 @@ -549,7 +549,7 @@ F src/shell.c.in 24b99dae8818d1a234732d73f4d5b49f12b510bc62735a41c04e314fafae09e F src/sqlite.h.in 43fcf0fe2af04081f420a906fc020bde1243851ba44b0aa567a27f94bf8c3145 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510 -F src/sqliteInt.h 1041c70f63687392665dde29f87f8af27d27bc1e18d29c8b804360fc915c2fde +F src/sqliteInt.h e2fbf849a7e0ee1842a4775952a61c966f9eb25075297dd2f3aff5b5e4418415 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -614,7 +614,7 @@ F src/trigger.c 7d16aa09e63226b6d8b3f0fc60b21cbfa596fc406288b2ebcf4266633d1ba222 F src/update.c 30465f9accc854e8a7932b413578027fbb68186132abbb36e01d2022473fc83d F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 -F src/util.c b2cb568393144b05df06871b2c61b0f0240f1835aee2843c736391507fac2780 +F src/util.c 6ca9cf268dfaf2393866990788c0797240e20e7ba7e3a22cd076e6a3c7b1a132 F src/vacuum.c 454973a59fb20bb982efc2df568a098616db6328a0491b6e84e2e07f7333db45 F src/vdbe.c b73a5ec9940185eb001ff8cff2cfd429bb438c7e89f2885e0bfdb56c3ff13386 F src/vdbe.h 25dabb25c7e157b84e59260cfb5b466c3ac103ede9f36f4db371332c47601abe @@ -747,7 +747,7 @@ F test/busy2.test dbfb61b3265e7a962d3bcd32cd542bbe3d7801edbda6438d35af5aa707cae9 F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de F test/cacheflush.test af25bb1509df04c1da10e38d8f322d66eceedf61 F test/cachespill.test 895997f84a25b323b166aecb69baab2d6380ea98f9e0bcc688c4493c535cfab9 -F test/capi2.test 34a1a9a96d543a2ec2c209696b11b164444f57253b1f2cba1c2e53fadede6c7b +F test/capi2.test 4ee545824adc3eb33bf57ef89f77440b28188ec3da72e5425ff0fcdba32e8d5a F test/capi3.test 3910a73c38ac76d69778dd9eb481ab7cd6ed59117fc047b4f6056a5c72529de1 F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 F test/capi3c.test 54e2dc0c8fd7c34ad1590d1be6864397da2438c95a9f5aee2f8fbc60c112e44b @@ -1062,7 +1062,7 @@ F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc F test/gcfault.test dd28c228a38976d6336a3fc42d7e5f1ad060cb8c -F test/gencol1.test 26c55577b15f78069bacf8afee994b74b9d69aa690577db9cff926b10e4e6be2 +F test/gencol1.test 6912c4280d0ad26d6e3d133a93c5abd6db0e00bc5c95d6159131a62ab4e6f586 F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 F test/having.test a89236dd8d55aa50c4805f82ac9daf64d477a44d712d8209c118978d0ca21ec9 F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751 @@ -1270,7 +1270,7 @@ F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff F test/permutations.test 63da39a4234eed2ccd10bf7872de58e24d53a50d11014dc8a8ab9f252368e880 F test/pg_common.tcl 3b27542224db1e713ae387459b5d117c836a5f6e328846922993b6d2b7640d9f -F test/pragma.test 50b91bedea9324d3ab48e793f908ee7d2c7dcf84bfa2281e792838be59641ec8 +F test/pragma.test 30d5bbebd5e9cb5383155cf3f3c81297b98f6642d152e9d4100cf6888630da2c F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f F test/pragma3.test 92a46bbea12322dd94a404f49edcfbfc913a2c98115f0d030a7459bb4712ef31 F test/pragma4.test ca5e4dfc46adfe490f75d73734f70349d95a199e6510973899e502eef2c8b1f8 @@ -1446,7 +1446,7 @@ F test/tabfunc01.test d6821e7042e5653104dac0c63d75eff24a2415ab1889fc68b5db7fde59 F test/table.test eb3463b7add9f16a5bb836badf118cf391b809d09fdccd1f79684600d07ec132 F test/tableapi.test ecbcc29c4ab62c1912c3717c48ea5c5e59f7d64e4a91034e6148bd2b82f177f4 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 -F test/tclsqlite.test 79a473f5797e317c08f2c4f8192edb3eea6a67329b1087453328b66a7cb31070 +F test/tclsqlite.test 316c96f974f0e6d7480186e3f5bb53413e5ee5480596544a97484888912a365c F test/tempdb.test 4cdaa23ddd8acb4d79cbb1b68ccdfd09b0537aaba909ca69a876157c2a2cbd08 F test/tempdb2.test 353864e96fd3ae2f70773d0ffbf8b1fe48589b02c2ec05013b540879410c3440 F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900 @@ -1695,7 +1695,7 @@ F test/vtab6.test 8e789f526e6594cf7ae933d1adee0caa87dc9f78 F test/vtab7.test 70c6f4a1d6177144a8236e4172d5fba92e683440374664ad1f04851fbb335d3c F test/vtab8.test e19fa4a538fcd1bb66c22825fa8f71618fb13583 F test/vtab9.test ea58d2b95d61955f87226381716b2d0b1d4e4f9b -F test/vtabA.test 1317f06a03597eee29f40a49b6c21e1aaba4285f +F test/vtabA.test 325a77e7f0f80aa78ab388875c0ad6fb853acc6ac54d85514650b0ae15da24ff F test/vtabB.test 04df5dc531b9f44d9ca65b9c1b79f12b5922a796 F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292 F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96 @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 980f7292afd45a8e73272e2139b55b99ab86167febec9fd0bf0356e8167b2ee9 -R 5e0d17f3eda249159c66a4dab795bade +P 3c954863f45271a3518acf51fd685a641878811fb5cfcbdbad85154aeccdc902 +R 6b5f2c664834813a7df89f39b77ebda9 U drh -Z b92983df8210770e5aba5b5d6965da26 +Z 12d963d3ccf8007e48d95666e4982a9e diff --git a/manifest.uuid b/manifest.uuid index b98c86df86..639f1a3b26 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3c954863f45271a3518acf51fd685a641878811fb5cfcbdbad85154aeccdc902 \ No newline at end of file +d2da62a9df63036b02dadca3798de9e623c2680b3ef0c37d2b18bb88693afd7f \ No newline at end of file diff --git a/src/build.c b/src/build.c index 43112a4cd0..8b45df3cad 100644 --- a/src/build.c +++ b/src/build.c @@ -1382,6 +1382,9 @@ void sqlite3AddColumn(Parse *pParse, Token sName, Token sType){ sqlite3 *db = pParse->db; u8 hName; Column *aNew; + u8 eType = COLTYPE_CUSTOM; + u8 szEst = 1; + char affinity = SQLITE_AFF_BLOB; if( (p = pParse->pNewTable)==0 ) return; if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){ @@ -1407,7 +1410,25 @@ void sqlite3AddColumn(Parse *pParse, Token sName, Token sType){ } } - z = sqlite3DbMallocRaw(db, sName.n + sType.n + 2); + /* Check for standard typenames. For standard typenames we will + ** set the Column.eType field rather than storing the typename after + ** the column name, in order to save space. */ + if( sType.n>=3 ){ + sqlite3DequoteToken(&sType); + for(i=0; i0) ); if( z==0 ) return; if( IN_RENAME_OBJECT ) sqlite3RenameTokenMap(pParse, (void*)z, &sName); memcpy(z, sName.z, sName.n); @@ -1436,11 +1457,14 @@ void sqlite3AddColumn(Parse *pParse, Token sName, Token sType){ if( sType.n==0 ){ /* If there is no type specified, columns have the default affinity ** 'BLOB' with a default size of 4 bytes. */ - pCol->affinity = SQLITE_AFF_BLOB; - pCol->szEst = 1; + pCol->affinity = affinity; + pCol->eType = eType; + pCol->szEst = szEst; #ifdef SQLITE_ENABLE_SORTER_REFERENCES - if( 4>=sqlite3GlobalConfig.szSorterRef ){ - pCol->colFlags |= COLFLAG_SORTERREF; + if( affinity==SQLITE_AFF_BLOB ){ + if( 4>=sqlite3GlobalConfig.szSorterRef ){ + pCol->colFlags |= COLFLAG_SORTERREF; + } } #endif }else{ @@ -1729,7 +1753,7 @@ void sqlite3AddPrimaryKey( } if( nTerm==1 && pCol - && sqlite3StrICmp(sqlite3ColumnType(pCol,""), "INTEGER")==0 + && pCol->eType==COLTYPE_INTEGER && sortOrder!=SQLITE_SO_DESC ){ if( IN_RENAME_OBJECT && pList ){ diff --git a/src/global.c b/src/global.c index 4648c26d95..a1398fef5d 100644 --- a/src/global.c +++ b/src/global.c @@ -347,3 +347,23 @@ const unsigned char sqlite3OpcodeProperty[] = OPFLG_INITIALIZER; ** Name of the default collating sequence */ const char sqlite3StrBINARY[] = "BINARY"; + +/* +** Standard typenames. These names must match the COLTYPE_* definitions. +** Adjust the SQLITE_N_STDTYPE value if adding or removing entries. +*/ +const unsigned char sqlite3StdTypeLen[] = { 4, 3, 7, 4, 4 }; +const char sqlite3StdTypeAffinity[] = { + SQLITE_AFF_BLOB, + SQLITE_AFF_INTEGER, + SQLITE_AFF_INTEGER, + SQLITE_AFF_REAL, + SQLITE_AFF_TEXT +}; +const char *sqlite3StdType[] = { + "BLOB", + "INT", + "INTEGER", + "REAL", + "TEXT" +}; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7d6fda4c66..8f63d777ab 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2037,9 +2037,25 @@ struct Column { char affinity; /* One of the SQLITE_AFF_... values */ u8 szEst; /* Estimated size of value in this column. sizeof(INT)==1 */ u8 hName; /* Column name hash for faster lookup */ + u8 eType; /* One of the standard types */ u16 colFlags; /* Boolean properties. See COLFLAG_ defines below */ }; +/* Allowed values for Column.eType. +** +** Values must match entries in the global constant arrays +** sqlite3StdTypeLen[] and sqlite3StdType[]. Each value is one more +** than the offset into these arrays for the corresponding name. +** Adjust the SQLITE_N_STDTYPE value if adding or removing entries. +*/ +#define COLTYPE_CUSTOM 0 /* Type appended to zName */ +#define COLTYPE_BLOB 1 +#define COLTYPE_INT 2 +#define COLTYPE_INTEGER 3 +#define COLTYPE_REAL 4 +#define COLTYPE_TEXT 5 +#define SQLITE_N_STDTYPE 5 /* Number of standard types */ + /* Allowed values for Column.colFlags. ** ** Constraints: @@ -4794,6 +4810,9 @@ void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8); #ifndef SQLITE_AMALGAMATION extern const unsigned char sqlite3OpcodeProperty[]; extern const char sqlite3StrBINARY[]; +extern const unsigned char sqlite3StdTypeLen[]; +extern const char sqlite3StdTypeAffinity[]; +extern const char *sqlite3StdType[]; extern const unsigned char sqlite3UpperToLower[]; extern const unsigned char *sqlite3aLTb; extern const unsigned char *sqlite3aEQb; diff --git a/src/util.c b/src/util.c index 8bcf1d261a..d513d8f79b 100644 --- a/src/util.c +++ b/src/util.c @@ -91,6 +91,9 @@ int sqlite3Strlen30(const char *z){ char *sqlite3ColumnType(Column *pCol, char *zDflt){ if( pCol->colFlags & COLFLAG_HASTYPE ){ return pCol->zName + strlen(pCol->zName) + 1; + }else if( pCol->eType ){ + assert( pCol->eType<=SQLITE_N_STDTYPE ); + return (char*)sqlite3StdType[pCol->eType-1]; }else{ return zDflt; } diff --git a/test/capi2.test b/test/capi2.test index 0680cf530c..de47ab3d4f 100644 --- a/test/capi2.test +++ b/test/capi2.test @@ -64,13 +64,13 @@ do_test capi2-1.4 { } {t1 1} do_test capi2-1.5 { get_column_names $VM -} {name rowid text INTEGER} +} {name rowid TEXT INTEGER} do_test capi2-1.6 { sqlite3_step $VM } {SQLITE_DONE} do_test capi2-1.7 { list [sqlite3_column_count $VM] [get_row_values $VM] [get_column_names $VM] -} {2 {} {name rowid text INTEGER}} +} {2 {} {name rowid TEXT INTEGER}} # This used to be SQLITE_MISUSE. But now we automatically reset prepared # statements. @@ -91,7 +91,7 @@ ifcapable autoreset { do_test capi2-1.9 { sqlite3_reset $VM list [sqlite3_column_count $VM] [get_row_values $VM] [get_column_names $VM] -} {2 {} {name rowid text INTEGER}} +} {2 {} {name rowid TEXT INTEGER}} do_test capi2-1.10 { sqlite3_data_count $VM } {0} @@ -120,13 +120,13 @@ do_test capi2-2.2 { lappend r [sqlite3_column_count $VM] \ [get_row_values $VM] \ [get_column_names $VM] -} {SQLITE_ROW 2 {t1 1} {name rowid text INTEGER}} +} {SQLITE_ROW 2 {t1 1} {name rowid TEXT INTEGER}} do_test capi2-2.3 { set r [sqlite3_step $VM] lappend r [sqlite3_column_count $VM] \ [get_row_values $VM] \ [get_column_names $VM] -} {SQLITE_DONE 2 {} {name rowid text INTEGER}} +} {SQLITE_DONE 2 {} {name rowid TEXT INTEGER}} do_test capi2-2.4 { sqlite3_finalize $VM } {SQLITE_OK} @@ -141,7 +141,7 @@ do_test capi2-2.6 { lappend r [sqlite3_column_count $VM] \ [get_row_values $VM] \ [get_column_names $VM] -} {SQLITE_DONE 2 {} {name rowid text INTEGER}} +} {SQLITE_DONE 2 {} {name rowid TEXT INTEGER}} do_test capi2-2.7 { sqlite3_finalize $VM } {SQLITE_OK} diff --git a/test/gencol1.test b/test/gencol1.test index c0bb52361e..f09b880d67 100644 --- a/test/gencol1.test +++ b/test/gencol1.test @@ -600,6 +600,6 @@ do_execsql_test gencol1-21.1 { ); INSERT INTO t1(a) VALUES(5); SELECT name, type FROM pragma_table_xinfo('t1'); -} {a integer b int c text d {} e {int}} +} {a INTEGER b INT c TEXT d {} e INT} finish_test diff --git a/test/pragma.test b/test/pragma.test index 04f5bd0fbe..c4b9d334ae 100644 --- a/test/pragma.test +++ b/test/pragma.test @@ -815,7 +815,7 @@ do_test pragma-6.7 { ORDER BY cid} } [concat \ {0 one INT 1 -1 0} \ - {1 two text 0 {} 0} \ + {1 two TEXT 0 {} 0} \ {2 three {VARCHAR(45, 65)} 0 'abcde' 0} \ {3 four REAL 0 X'abcdef' 0} \ {4 five {} 0 CURRENT_TIME 0} \ diff --git a/test/tclsqlite.test b/test/tclsqlite.test index c111325bcb..b7e160e07e 100644 --- a/test/tclsqlite.test +++ b/test/tclsqlite.test @@ -166,7 +166,7 @@ do_test tcl-2.1 { ifcapable schema_pragmas { do_test tcl-2.2 { execsql "PRAGMA table_info(t\u0123x)" - } "0 a int 0 {} 0 1 b\u1235 float 0 {} 0" + } "0 a INT 0 {} 0 1 b\u1235 float 0 {} 0" } do_test tcl-2.3 { execsql "INSERT INTO t\u0123x VALUES(1,2.3)" diff --git a/test/vtabA.test b/test/vtabA.test index eddaa70d1f..4c9beae026 100644 --- a/test/vtabA.test +++ b/test/vtabA.test @@ -128,7 +128,7 @@ proc analyse_parse {columns decltype_list} { do_test vtabA-2.1 { analyse_parse {(a text, b integer hidden, c hidden)} {a b c} -} {a text integer {}} +} {a TEXT integer {}} do_test vtabA-2.2 { analyse_parse {(a hidden , b integerhidden, c hidden1)} {a b c} From 79cf2b7120ea382a2649698656860d09740e6205 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 31 Jul 2021 20:30:41 +0000 Subject: [PATCH 47/49] Refactor the way that DEFAULT expressions are stored on columns, in order to save memory in the common case where the column has no DEFAULT clause. FossilOrigin-Name: 8646547e54211d44c415663c33775c4268550f8332949c4731a4bb6ec9cc663a --- manifest | 28 +++++++++++----------- manifest.uuid | 2 +- src/alter.c | 12 ++++++---- src/build.c | 63 +++++++++++++++++++++++++++++++++++++++---------- src/expr.c | 13 +++++----- src/fkey.c | 2 +- src/insert.c | 39 +++++++++++++++++++----------- src/pragma.c | 7 ++++-- src/sqliteInt.h | 11 +++++---- src/update.c | 9 ++++--- src/vtab.c | 2 ++ 11 files changed, 126 insertions(+), 62 deletions(-) diff --git a/manifest b/manifest index e3ec8ecc4f..e1878e788b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Recognize\scertain\sstandard\sdatatypes\s("INT",\s"INTEGER",\s"REAL",\s"TEXT",\sand\n"BLOB")\sand\sif\sa\scolumn\shas\sone\sof\sthose\sdatatypes,\sstore\sthe\stype\spart\sof\nthe\sbit-field\sinformation\sin\sthe\sColumn\sstructure\sto\ssave\sspace. -D 2021-07-30T23:30:30.921 +C Refactor\sthe\sway\sthat\sDEFAULT\sexpressions\sare\sstored\son\scolumns,\sin\sorder\nto\ssave\smemory\sin\sthe\scommon\scase\swhere\sthe\scolumn\shas\sno\sDEFAULT\sclause. +D 2021-07-31T20:30:41.189 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -478,7 +478,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c a54e0a5ae778271a0bc67bdb590c1b3bba0ee59669474f976afb862ccee0026e +F src/alter.c 87c9b91d15826cbb2d289f4cff3bc5671935ec3b238e307407087e615220788a F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c F src/attach.c a514e81758ba7b3a3a0501faf70af6cfc509de8810235db726cfc9f25165e929 F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 @@ -488,7 +488,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c e204a9c8fb4fe5dbb910a863ba487f4af9b5c501254ec4ccbfcdd6b1f65b7fb4 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0 -F src/build.c e9ff9104d6d64dd2a000ca9cc7d25c80a5b1a3fd2422b4e0d84afee8c8bef78b +F src/build.c 19d9283feae27045cfd5712ae4cabcac91a9b7bf619e651f1571e9637bd7f65d F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 8159d5f706551861c18ec6c8f6bdf105e15ea00367f05d9ab65d31a1077facc1 @@ -496,16 +496,16 @@ F src/date.c e0632f335952b32401482d099321bbf12716b29d6e72836b53ae49683ebae4bf F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c F src/delete.c 62451bba9fe641159e9c0b7d9d2bab1c48d0cff11e16de2d14000603d2af1fcf -F src/expr.c b1bcf90afb7dcc0fae4d81116177e3d02e0803f81fd543c10fcd0691390b6adf +F src/expr.c 84691a9d63baddcc6c735080a9b347e7f6feedb04c293730284999c92af95371 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 -F src/fkey.c e9063648396c58778f77583a678342fe4a9bc82436bf23c5f9f444f2df0fdaa4 +F src/fkey.c 1df6ad21908d84adb6d1297d7657ccd239c8ef0836e3a457d1fe15318393933b F src/func.c c224240cbc97fa5e9c4fe9acb128716cb835ca045532bca6951b7c45b020c56c F src/global.c 5eba017ebbd887e2365e6e6e815e1619e41406b8946d17594e94116174787df5 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c d560dc585c50e01b015cbf924c173de88f61c8c85b3d1adb9d4865b92fff2d72 +F src/insert.c 6f10127cc5c8bb3631f25bad89f6d2f9c53606df789449f6af7b8647d8f97b4f F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 0aa9e7f08e168e3874cb54984408e3976dafdf5616d511952c425b5ac088ea3e F src/main.c 5d024b9b96d9c6809e66b7f4864c3745bc8caf2a6af3b27dc0f05328f4439dfd @@ -537,7 +537,7 @@ F src/parse.y 0ba0baec5de6921ec8ba8bbcf1018969144ef29d26112e17539d8fbb1662e3eb F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 388304fd2d91c39591080b5e0f3c62cfba87db20370e7e0554062bfb29740e9f -F src/pragma.c 9fe75aa29e8706a2cf6b9c1600ac05a2efc55c44ce719b65aa45d10ff58acc9d +F src/pragma.c e8efa185aaaa4c4036fc40572b74ff9bb5317520c3a1886567093b5ac8b15381 F src/pragma.h a11b4798f9c49f156f130e1f7041a9fcc9d316a64f3501b6013acdd2e4c6f549 F src/prepare.c 0d53d20532aada295c1690792a125adbd6435f5ce703ff0adf1b9b3605238b67 F src/printf.c 78fabb49b9ac9a12dd1c89d744abdc9b67fd3205e62967e158f78b965a29ec4b @@ -549,7 +549,7 @@ F src/shell.c.in 24b99dae8818d1a234732d73f4d5b49f12b510bc62735a41c04e314fafae09e F src/sqlite.h.in 43fcf0fe2af04081f420a906fc020bde1243851ba44b0aa567a27f94bf8c3145 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510 -F src/sqliteInt.h e2fbf849a7e0ee1842a4775952a61c966f9eb25075297dd2f3aff5b5e4418415 +F src/sqliteInt.h ea94bc5f087522abe62550bb73ef1d7f78d28337fc3834cd676ef39d143ef2c2 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -611,7 +611,7 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c bae853ad129d1129c063de8630a3e99e306283bc40146f359b1bb91be2c08f1e F src/treeview.c 43f88d0fd19976a60aee6867959213b438593276f1e8179048df85f416a1ab19 F src/trigger.c 7d16aa09e63226b6d8b3f0fc60b21cbfa596fc406288b2ebcf4266633d1ba222 -F src/update.c 30465f9accc854e8a7932b413578027fbb68186132abbb36e01d2022473fc83d +F src/update.c d2648c47202cf54104c94b427209be0350e667fbf4b825a61cae54ef86aaf1d9 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 6ca9cf268dfaf2393866990788c0797240e20e7ba7e3a22cd076e6a3c7b1a132 @@ -626,7 +626,7 @@ F src/vdbemem.c 53881aa0a7845922a075b3f375695588618098871a7a4120af4c297b80fa3e64 F src/vdbesort.c cd5130f683706c1a43e165a74187745fb3351cb56052cf9dc91de820634bbde2 F src/vdbetrace.c 666c6fd9f1b62be6999e072a45b913e3c2c3518bc60dfd4d54fe304130acb724 F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c -F src/vtab.c 3a9a6ae1fd14f7c00af184233cb9f3bced89ae277a75a312f85fb77297a3cdfa +F src/vtab.c 516cb50e2a57359155db7f71d98f1690dc9cae84d359a1c6801b2615dc3cf362 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 2be08331d798237ad5d7ae0b252700ffb2b63189cb18d993496d009a93e2f81c F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3c954863f45271a3518acf51fd685a641878811fb5cfcbdbad85154aeccdc902 -R 6b5f2c664834813a7df89f39b77ebda9 +P d2da62a9df63036b02dadca3798de9e623c2680b3ef0c37d2b18bb88693afd7f +R 2bd36d7d73ef054d58c2b5fa1473f7b9 U drh -Z 12d963d3ccf8007e48d95666e4982a9e +Z d1f622cc8631b67a8482f1c93905c30a diff --git a/manifest.uuid b/manifest.uuid index 639f1a3b26..c4363aa39e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d2da62a9df63036b02dadca3798de9e623c2680b3ef0c37d2b18bb88693afd7f \ No newline at end of file +8646547e54211d44c415663c33775c4268550f8332949c4731a4bb6ec9cc663a \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index c29be3f6e0..1d1e2d811b 100644 --- a/src/alter.c +++ b/src/alter.c @@ -337,7 +337,7 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ zDb = db->aDb[iDb].zDbSName; zTab = &pNew->zName[16]; /* Skip the "sqlite_altertab_" prefix on the name */ pCol = &pNew->aCol[pNew->nCol-1]; - pDflt = pCol->pDflt; + pDflt = sqlite3ColumnExpr(pNew, pCol); pTab = sqlite3FindTable(db, zTab, zDb); assert( pTab ); @@ -539,8 +539,8 @@ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ pCol->zName = sqlite3DbStrDup(db, pCol->zName); pCol->hName = sqlite3StrIHash(pCol->zName); pCol->zColl = 0; - pCol->pDflt = 0; } + pNew->pDfltList = sqlite3ExprListDup(db, pTab->pDfltList, 0); pNew->pSchema = db->aDb[iDb].pSchema; pNew->addColOffset = pTab->addColOffset; pNew->nTabRef = 1; @@ -1528,7 +1528,9 @@ static void renameColumnFunc( } #ifndef SQLITE_OMIT_GENERATED_COLUMNS for(i=0; inCol; i++){ - sqlite3WalkExpr(&sWalker, sParse.pNewTable->aCol[i].pDflt); + Expr *pExpr = sqlite3ColumnExpr(sParse.pNewTable, + &sParse.pNewTable->aCol[i]); + sqlite3WalkExpr(&sWalker, pExpr); } #endif } @@ -1874,7 +1876,9 @@ static void renameQuotefixFunc( sqlite3WalkExprList(&sWalker, sParse.pNewTable->pCheck); #ifndef SQLITE_OMIT_GENERATED_COLUMNS for(i=0; inCol; i++){ - sqlite3WalkExpr(&sWalker, sParse.pNewTable->aCol[i].pDflt); + sqlite3WalkExpr(&sWalker, + sqlite3ColumnExpr(sParse.pNewTable, + &sParse.pNewTable->aCol[i])); } #endif /* SQLITE_OMIT_GENERATED_COLUMNS */ } diff --git a/src/build.c b/src/build.c index 8b45df3cad..33f0015fd7 100644 --- a/src/build.c +++ b/src/build.c @@ -667,6 +667,42 @@ void sqlite3CommitInternalChanges(sqlite3 *db){ db->mDbFlags &= ~DBFLAG_SchemaChange; } +/* +** Set the expression associated with a column. This is usually +** the DEFAULT value, but might also be the expression that computes +** the value for a generated column. +*/ +void sqlite3ColumnSetExpr( + Parse *pParse, /* Parsing context */ + Table *pTab, /* The table containing the column */ + Column *pCol, /* The column to receive the new DEFAULT expression */ + Expr *pExpr /* The new default expression */ +){ + ExprList *pList = pTab->pDfltList; + if( pCol->iDflt==0 + || pList==0 + || pList->nExpriDflt + ){ + pCol->iDflt = pList==0 ? 1 : pList->nExpr+1; + pTab->pDfltList = sqlite3ExprListAppend(pParse, pList, pExpr); + }else{ + sqlite3ExprDelete(pParse->db, pList->a[pCol->iDflt-1].pExpr); + pList->a[pCol->iDflt-1].pExpr = pExpr; + } +} + +/* +** Return the expression associated with a column. The expression might be +** the DEFAULT clause or the AS clause of a generated column. +** Return NULL if the column has no associated expression. +*/ +Expr *sqlite3ColumnExpr(Table *pTab, Column *pCol){ + if( pCol->iDflt==0 ) return 0; + if( pTab->pDfltList==0 ) return 0; + if( pTab->pDfltList->nExpriDflt ) return 0; + return pTab->pDfltList->a[pCol->iDflt-1].pExpr; +} + /* ** Delete memory allocated for the column names of a table or view (the ** Table.aCol[] array). @@ -679,10 +715,15 @@ void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){ for(i=0; inCol; i++, pCol++){ assert( pCol->zName==0 || pCol->hName==sqlite3StrIHash(pCol->zName) ); sqlite3DbFree(db, pCol->zName); - sqlite3ExprDelete(db, pCol->pDflt); sqlite3DbFree(db, pCol->zColl); } sqlite3DbFree(db, pTable->aCol); + sqlite3ExprListDelete(db, pTable->pDfltList); + if( db==0 || db->pnBytesFreed==0 ){ + pTable->aCol = 0; + pTable->nCol = 0; + pTable->pDfltList = 0; + } } } @@ -1636,15 +1677,15 @@ void sqlite3AddDefaultValue( /* A copy of pExpr is used instead of the original, as pExpr contains ** tokens that point to volatile memory. */ - Expr x; - sqlite3ExprDelete(db, pCol->pDflt); + Expr x, *pDfltExpr; memset(&x, 0, sizeof(x)); x.op = TK_SPAN; x.u.zToken = sqlite3DbSpanDup(db, zStart, zEnd); x.pLeft = pExpr; x.flags = EP_Skip; - pCol->pDflt = sqlite3ExprDup(db, &x, EXPRDUP_REDUCE); + pDfltExpr = sqlite3ExprDup(db, &x, EXPRDUP_REDUCE); sqlite3DbFree(db, x.u.zToken); + sqlite3ColumnSetExpr(pParse, p, pCol, pDfltExpr); } } if( IN_RENAME_OBJECT ){ @@ -1868,7 +1909,7 @@ void sqlite3AddGenerated(Parse *pParse, Expr *pExpr, Token *pType){ sqlite3ErrorMsg(pParse, "virtual tables cannot use computed columns"); goto generated_done; } - if( pCol->pDflt ) goto generated_error; + if( pCol->iDflt>0 ) goto generated_error; if( pType ){ if( pType->n==7 && sqlite3StrNICmp("virtual",pType->z,7)==0 ){ /* no-op */ @@ -1886,7 +1927,7 @@ void sqlite3AddGenerated(Parse *pParse, Expr *pExpr, Token *pType){ if( pCol->colFlags & COLFLAG_PRIMKEY ){ makeColumnPartOfPrimaryKey(pParse, pCol); /* For the error message */ } - pCol->pDflt = pExpr; + sqlite3ColumnSetExpr(pParse, pTab, pCol, pExpr); pExpr = 0; goto generated_done; @@ -2540,7 +2581,7 @@ void sqlite3EndTable( for(ii=0; iinCol; ii++){ u32 colFlags = p->aCol[ii].colFlags; if( (colFlags & COLFLAG_GENERATED)!=0 ){ - Expr *pX = p->aCol[ii].pDflt; + Expr *pX = sqlite3ColumnExpr(p, &p->aCol[ii]); testcase( colFlags & COLFLAG_VIRTUAL ); testcase( colFlags & COLFLAG_STORED ); if( sqlite3ResolveSelfReference(pParse, p, NC_GenCol, pX, 0) ){ @@ -2550,8 +2591,8 @@ void sqlite3EndTable( ** tree that have been allocated from lookaside memory, which is ** illegal in a schema and will lead to errors or heap corruption ** when the database connection closes. */ - sqlite3ExprDelete(db, pX); - p->aCol[ii].pDflt = sqlite3ExprAlloc(db, TK_NULL, 0, 0); + sqlite3ColumnSetExpr(pParse, p, &p->aCol[ii], + sqlite3ExprAlloc(db, TK_NULL, 0, 0)); } }else{ nNG++; @@ -2965,8 +3006,6 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ pTable->pSchema->schemaFlags |= DB_UnresetViews; if( db->mallocFailed ){ sqlite3DeleteColumnNames(db, pTable); - pTable->aCol = 0; - pTable->nCol = 0; } #endif /* SQLITE_OMIT_VIEW */ return nErr; @@ -2985,8 +3024,6 @@ static void sqliteViewResetAll(sqlite3 *db, int idx){ Table *pTab = sqliteHashData(i); if( pTab->pSelect ){ sqlite3DeleteColumnNames(db, pTab); - pTab->aCol = 0; - pTab->nCol = 0; } } DbClearProperty(db, idx, DB_UnresetViews); diff --git a/src/expr.c b/src/expr.c index dea2695461..04881be8ca 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3643,9 +3643,10 @@ void sqlite3ExprCodeLoadIndexColumn( ** and store the result in register regOut */ void sqlite3ExprCodeGeneratedColumn( - Parse *pParse, - Column *pCol, - int regOut + Parse *pParse, /* Parsing context */ + Table *pTab, /* Table containing the generated column */ + Column *pCol, /* The generated column */ + int regOut /* Put the result in this register */ ){ int iAddr; Vdbe *v = pParse->pVdbe; @@ -3656,7 +3657,7 @@ void sqlite3ExprCodeGeneratedColumn( }else{ iAddr = 0; } - sqlite3ExprCodeCopy(pParse, pCol->pDflt, regOut); + sqlite3ExprCodeCopy(pParse, sqlite3ColumnExpr(pTab,pCol), regOut); if( pCol->affinity>=SQLITE_AFF_TEXT ){ sqlite3VdbeAddOp4(v, OP_Affinity, regOut, 1, 0, &pCol->affinity, 1); } @@ -3697,7 +3698,7 @@ void sqlite3ExprCodeGetColumnOfTable( int savedSelfTab = pParse->iSelfTab; pCol->colFlags |= COLFLAG_BUSY; pParse->iSelfTab = iTabCur+1; - sqlite3ExprCodeGeneratedColumn(pParse, pCol, regOut); + sqlite3ExprCodeGeneratedColumn(pParse, pTab, pCol, regOut); pParse->iSelfTab = savedSelfTab; pCol->colFlags &= ~COLFLAG_BUSY; } @@ -4031,7 +4032,7 @@ expr_code_doover: } pCol->colFlags |= COLFLAG_BUSY; if( pCol->colFlags & COLFLAG_NOTAVAIL ){ - sqlite3ExprCodeGeneratedColumn(pParse, pCol, iSrc); + sqlite3ExprCodeGeneratedColumn(pParse, pTab, pCol, iSrc); } pCol->colFlags &= ~(COLFLAG_BUSY|COLFLAG_NOTAVAIL); return iSrc; diff --git a/src/fkey.c b/src/fkey.c index 9f622f40c6..2e743c7022 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -1279,7 +1279,7 @@ static Trigger *fkActionTrigger( testcase( pCol->colFlags & COLFLAG_STORED ); pDflt = 0; }else{ - pDflt = pCol->pDflt; + pDflt = sqlite3ColumnExpr(pFKey->pFrom, pCol); } if( pDflt ){ pNew = sqlite3ExprDup(db, pDflt, 0); diff --git a/src/insert.c b/src/insert.c index 63ffa5edd0..867ab76fd1 100644 --- a/src/insert.c +++ b/src/insert.c @@ -293,7 +293,7 @@ void sqlite3ComputeGeneratedColumns( int x; pCol->colFlags |= COLFLAG_BUSY; w.eCode = 0; - sqlite3WalkExpr(&w, pCol->pDflt); + sqlite3WalkExpr(&w, sqlite3ColumnExpr(pTab, pCol)); pCol->colFlags &= ~COLFLAG_BUSY; if( w.eCode & COLFLAG_NOTAVAIL ){ pRedo = pCol; @@ -302,7 +302,7 @@ void sqlite3ComputeGeneratedColumns( eProgress = 1; assert( pCol->colFlags & COLFLAG_GENERATED ); x = sqlite3TableColumnToStorage(pTab, i) + iRegStore; - sqlite3ExprCodeGeneratedColumn(pParse, pCol, x); + sqlite3ExprCodeGeneratedColumn(pParse, pTab, pCol, x); pCol->colFlags &= ~COLFLAG_NOTAVAIL; } } @@ -1088,7 +1088,9 @@ void sqlite3Insert( }else if( pColumn==0 ){ /* Hidden columns that are not explicitly named in the INSERT ** get there default value */ - sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore); + sqlite3ExprCodeFactorable(pParse, + sqlite3ColumnExpr(pTab, &pTab->aCol[i]), + iRegStore); continue; } } @@ -1097,13 +1099,17 @@ void sqlite3Insert( if( j>=pColumn->nId ){ /* A column not named in the insert column list gets its ** default value */ - sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore); + sqlite3ExprCodeFactorable(pParse, + sqlite3ColumnExpr(pTab, &pTab->aCol[i]), + iRegStore); continue; } k = j; }else if( nColumn==0 ){ /* This is INSERT INTO ... DEFAULT VALUES. Load the default value. */ - sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore); + sqlite3ExprCodeFactorable(pParse, + sqlite3ColumnExpr(pTab, &pTab->aCol[i]), + iRegStore); continue; }else{ k = i - nHidden; @@ -1669,7 +1675,7 @@ void sqlite3GenerateConstraintChecks( } if( onError==OE_Replace ){ if( b2ndPass /* REPLACE becomes ABORT on the 2nd pass */ - || pCol->pDflt==0 /* REPLACE is ABORT if no DEFAULT value */ + || pCol->iDflt==0 /* REPLACE is ABORT if no DEFAULT value */ ){ testcase( pCol->colFlags & COLFLAG_VIRTUAL ); testcase( pCol->colFlags & COLFLAG_STORED ); @@ -1691,7 +1697,8 @@ void sqlite3GenerateConstraintChecks( VdbeCoverage(v); assert( (pCol->colFlags & COLFLAG_GENERATED)==0 ); nSeenReplace++; - sqlite3ExprCodeCopy(pParse, pCol->pDflt, iReg); + sqlite3ExprCodeCopy(pParse, + sqlite3ColumnExpr(pTab, pCol), iReg); sqlite3VdbeJumpHere(v, addr1); break; } @@ -2412,7 +2419,7 @@ void sqlite3SetMakeRecordP5(Vdbe *v, Table *pTab){ if( pTab->pSchema->file_format<2 ) return; for(i=pTab->nCol-1; i>0; i--){ - if( pTab->aCol[i].pDflt!=0 ) break; + if( pTab->aCol[i].iDflt!=0 ) break; if( pTab->aCol[i].colFlags & COLFLAG_PRIMKEY ) break; } sqlite3VdbeChangeP5(v, i+1); @@ -2829,7 +2836,9 @@ static int xferOptimization( ** This requirement could be relaxed for VIRTUAL columns, I suppose. */ if( (pDestCol->colFlags & COLFLAG_GENERATED)!=0 ){ - if( sqlite3ExprCompare(0, pSrcCol->pDflt, pDestCol->pDflt, -1)!=0 ){ + if( sqlite3ExprCompare(0, + sqlite3ColumnExpr(pSrc, pSrcCol), + sqlite3ColumnExpr(pDest, pDestCol), -1)!=0 ){ testcase( pDestCol->colFlags & COLFLAG_VIRTUAL ); testcase( pDestCol->colFlags & COLFLAG_STORED ); return 0; /* Different generator expressions */ @@ -2847,11 +2856,13 @@ static int xferOptimization( } /* Default values for second and subsequent columns need to match. */ if( (pDestCol->colFlags & COLFLAG_GENERATED)==0 && i>0 ){ - assert( pDestCol->pDflt==0 || pDestCol->pDflt->op==TK_SPAN ); - assert( pSrcCol->pDflt==0 || pSrcCol->pDflt->op==TK_SPAN ); - if( (pDestCol->pDflt==0)!=(pSrcCol->pDflt==0) - || (pDestCol->pDflt && strcmp(pDestCol->pDflt->u.zToken, - pSrcCol->pDflt->u.zToken)!=0) + Expr *pDestExpr = sqlite3ColumnExpr(pDest, pDestCol); + Expr *pSrcExpr = sqlite3ColumnExpr(pSrc, pSrcCol); + assert( pDestExpr==0 || pDestExpr->op==TK_SPAN ); + assert( pSrcExpr==0 || pSrcExpr->op==TK_SPAN ); + if( (pDestExpr==0)!=(pSrcExpr==0) + || (pDestExpr!=0 && strcmp(pDestExpr->u.zToken, + pSrcExpr->u.zToken)!=0) ){ return 0; /* Default values must be the same for all columns */ } diff --git a/src/pragma.c b/src/pragma.c index e0cf5ced50..0427bb972f 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1177,13 +1177,16 @@ void sqlite3Pragma( }else{ for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){} } - assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN || isHidden>=2 ); + assert( sqlite3ColumnExpr(pTab,pCol)==0 + || sqlite3ColumnExpr(pTab,pCol)->op==TK_SPAN + || isHidden>=2 ); sqlite3VdbeMultiLoad(v, 1, pPragma->iArg ? "issisii" : "issisi", i-nHidden, pCol->zName, sqlite3ColumnType(pCol,""), pCol->notNull ? 1 : 0, - pCol->pDflt && isHidden<2 ? pCol->pDflt->u.zToken : 0, + isHidden>=2 || sqlite3ColumnExpr(pTab,pCol)==0 ? 0 : + sqlite3ColumnExpr(pTab,pCol)->u.zToken, k, isHidden); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 8f63d777ab..3fbb148d40 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2031,13 +2031,13 @@ struct Module { */ struct Column { char *zName; /* Name of this column, \000, then the type */ - Expr *pDflt; /* Default value or GENERATED ALWAYS AS value */ char *zColl; /* Collating sequence. If NULL, use the default */ - u8 notNull; /* An OE_ code for handling a NOT NULL constraint */ + u8 notNull : 4; /* An OE_ code for handling a NOT NULL constraint */ + u8 eType : 4; /* One of the standard types */ char affinity; /* One of the SQLITE_AFF_... values */ u8 szEst; /* Estimated size of value in this column. sizeof(INT)==1 */ u8 hName; /* Column name hash for faster lookup */ - u8 eType; /* One of the standard types */ + u16 iDflt; /* 1-based index of DEFAULT. 0 means "none" */ u16 colFlags; /* Boolean properties. See COLFLAG_ defines below */ }; @@ -2213,6 +2213,7 @@ struct Table { char *zColAff; /* String defining the affinity of each column */ ExprList *pCheck; /* All CHECK constraints */ /* ... also used as column name list in a VIEW */ + ExprList *pDfltList; /* DEFAULT clauses on various columns */ Pgno tnum; /* Root BTree page for this table */ u32 nTabRef; /* Number of pointers to this Table */ u32 tabFlags; /* Mask of TF_* values */ @@ -4379,6 +4380,8 @@ void sqlite3ResetAllSchemasOfConnection(sqlite3*); void sqlite3ResetOneSchema(sqlite3*,int); void sqlite3CollapseDatabaseArray(sqlite3*); void sqlite3CommitInternalChanges(sqlite3*); +void sqlite3ColumnSetExpr(Parse*,Table*,Column*,Expr*); +Expr *sqlite3ColumnExpr(Table*,Column*); void sqlite3DeleteColumnNames(sqlite3*,Table*); void sqlite3GenerateColumnNames(Parse *pParse, Select *pSelect); int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**); @@ -4517,7 +4520,7 @@ void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); void sqlite3ExprCodeMove(Parse*, int, int, int); void sqlite3ExprCode(Parse*, Expr*, int); #ifndef SQLITE_OMIT_GENERATED_COLUMNS -void sqlite3ExprCodeGeneratedColumn(Parse*, Column*, int); +void sqlite3ExprCodeGeneratedColumn(Parse*, Table*, Column*, int); #endif void sqlite3ExprCodeCopy(Parse*, Expr*, int); void sqlite3ExprCodeFactorable(Parse*, Expr*, int); diff --git a/src/update.c b/src/update.c index c5a01f8969..f93d85bd5e 100644 --- a/src/update.c +++ b/src/update.c @@ -66,7 +66,8 @@ void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ Column *pCol = &pTab->aCol[i]; VdbeComment((v, "%s.%s", pTab->zName, pCol->zName)); assert( inCol ); - sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc, + sqlite3ValueFromExpr(sqlite3VdbeDb(v), + sqlite3ColumnExpr(pTab,pCol), enc, pCol->affinity, &pValue); if( pValue ){ sqlite3VdbeAppendP4(v, pValue, P4_MEM); @@ -526,8 +527,10 @@ void sqlite3Update( for(i=0; inCol; i++){ if( aXRef[i]>=0 ) continue; if( (pTab->aCol[i].colFlags & COLFLAG_GENERATED)==0 ) continue; - if( sqlite3ExprReferencesUpdatedColumn(pTab->aCol[i].pDflt, - aXRef, chngRowid) ){ + if( sqlite3ExprReferencesUpdatedColumn( + sqlite3ColumnExpr(pTab, &pTab->aCol[i]), + aXRef, chngRowid) + ){ aXRef[i] = 99999; bProgress = 1; } diff --git a/src/vtab.c b/src/vtab.c index 1a9457c24d..25672bcce0 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -829,10 +829,12 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ Table *pNew = sParse.pNewTable; Index *pIdx; pTab->aCol = pNew->aCol; + pTab->pDfltList = pNew->pDfltList; pTab->nNVCol = pTab->nCol = pNew->nCol; pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid); pNew->nCol = 0; pNew->aCol = 0; + pNew->pDfltList = 0; assert( pTab->pIndex==0 ); assert( HasRowid(pNew) || sqlite3PrimaryKeyIndex(pNew)!=0 ); if( !HasRowid(pNew) From f38524d20db165c94dc94e06b62f0aad5942a03b Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 2 Aug 2021 16:41:57 +0000 Subject: [PATCH 48/49] Refactor the Table object to reduce its memory footprint. FossilOrigin-Name: bbb6759bcf6e01d36dfc787a82a610d359f50aaeac8104b73883a84906d54e1f --- manifest | 40 ++++++++++++------------ manifest.uuid | 2 +- src/alter.c | 54 +++++++++++++++++--------------- src/build.c | 73 ++++++++++++++++++++++++++----------------- src/delete.c | 8 ++--- src/expr.c | 2 +- src/fkey.c | 23 ++++++++------ src/insert.c | 21 +++++-------- src/main.c | 2 +- src/pragma.c | 12 +++++--- src/select.c | 29 ++++++++--------- src/sqliteInt.h | 82 +++++++++++++++++++++++++++++-------------------- src/trigger.c | 4 +-- src/update.c | 6 ++-- src/vdbeblob.c | 5 +-- src/vtab.c | 82 ++++++++++++++++++++++++------------------------- src/where.c | 6 ++-- 17 files changed, 246 insertions(+), 205 deletions(-) diff --git a/manifest b/manifest index e1878e788b..1a7d194773 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Refactor\sthe\sway\sthat\sDEFAULT\sexpressions\sare\sstored\son\scolumns,\sin\sorder\nto\ssave\smemory\sin\sthe\scommon\scase\swhere\sthe\scolumn\shas\sno\sDEFAULT\sclause. -D 2021-07-31T20:30:41.189 +C Refactor\sthe\sTable\sobject\sto\sreduce\sits\smemory\sfootprint. +D 2021-08-02T16:41:57.123 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -478,7 +478,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 87c9b91d15826cbb2d289f4cff3bc5671935ec3b238e307407087e615220788a +F src/alter.c e73e2dad9338274b53c04ba5fdcb8653fef898e4709b65d7f6f3197573e4d992 F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c F src/attach.c a514e81758ba7b3a3a0501faf70af6cfc509de8810235db726cfc9f25165e929 F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 @@ -488,27 +488,27 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c e204a9c8fb4fe5dbb910a863ba487f4af9b5c501254ec4ccbfcdd6b1f65b7fb4 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0 -F src/build.c 19d9283feae27045cfd5712ae4cabcac91a9b7bf619e651f1571e9637bd7f65d +F src/build.c d13fc40575b08422ddb44286537b0d3d80b03f063e0c3b6577d4bf84258f1f5e F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 8159d5f706551861c18ec6c8f6bdf105e15ea00367f05d9ab65d31a1077facc1 F src/date.c e0632f335952b32401482d099321bbf12716b29d6e72836b53ae49683ebae4bf F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c -F src/delete.c 62451bba9fe641159e9c0b7d9d2bab1c48d0cff11e16de2d14000603d2af1fcf -F src/expr.c 84691a9d63baddcc6c735080a9b347e7f6feedb04c293730284999c92af95371 +F src/delete.c b43f0f4db586acf0b4078e3982485c26fbec984674df513d5ade48a08a323c5a +F src/expr.c 4e2878324f6be88a766f4e83bc3132106a9913f2bd029a4b92447626501996ce F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 -F src/fkey.c 1df6ad21908d84adb6d1297d7657ccd239c8ef0836e3a457d1fe15318393933b +F src/fkey.c bcd5006ce061ef7b331154d176a0869440b1049c67c14c92f0233a14a701f2cc F src/func.c c224240cbc97fa5e9c4fe9acb128716cb835ca045532bca6951b7c45b020c56c F src/global.c 5eba017ebbd887e2365e6e6e815e1619e41406b8946d17594e94116174787df5 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 6f10127cc5c8bb3631f25bad89f6d2f9c53606df789449f6af7b8647d8f97b4f +F src/insert.c 167b286e3e289dbd1dad8f5a90858e9a6221bd83902985adf110e9db9fc2db67 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 0aa9e7f08e168e3874cb54984408e3976dafdf5616d511952c425b5ac088ea3e -F src/main.c 5d024b9b96d9c6809e66b7f4864c3745bc8caf2a6af3b27dc0f05328f4439dfd +F src/main.c 6921ce667627d0d38e67f8508d5903e074134386427688e6b4588bfe57ce06a4 F src/malloc.c cbc93cdd429c4594912017d92ab656e2579aca64dbd1c6888551275bed46f25b F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -537,19 +537,19 @@ F src/parse.y 0ba0baec5de6921ec8ba8bbcf1018969144ef29d26112e17539d8fbb1662e3eb F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 388304fd2d91c39591080b5e0f3c62cfba87db20370e7e0554062bfb29740e9f -F src/pragma.c e8efa185aaaa4c4036fc40572b74ff9bb5317520c3a1886567093b5ac8b15381 +F src/pragma.c 4a510b24e5b2321fd6bb509cd0dc8003514cb574b872dd535f49870b84ee54b1 F src/pragma.h a11b4798f9c49f156f130e1f7041a9fcc9d316a64f3501b6013acdd2e4c6f549 F src/prepare.c 0d53d20532aada295c1690792a125adbd6435f5ce703ff0adf1b9b3605238b67 F src/printf.c 78fabb49b9ac9a12dd1c89d744abdc9b67fd3205e62967e158f78b965a29ec4b F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 047a822844cea769f6fdd8418a335dd4bcd8b75ab5e264f2506a0804f869b562 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 99c36dd4e7c2207ebdfd8c30986ab5aaeae74d0cdbbc471420807d50c417c241 +F src/select.c 2b25a79706c8a71e40f5fbc8705073c54f6a3d25f556dac9d6d91676026a0413 F src/shell.c.in 24b99dae8818d1a234732d73f4d5b49f12b510bc62735a41c04e314fafae09e3 F src/sqlite.h.in 43fcf0fe2af04081f420a906fc020bde1243851ba44b0aa567a27f94bf8c3145 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510 -F src/sqliteInt.h ea94bc5f087522abe62550bb73ef1d7f78d28337fc3834cd676ef39d143ef2c2 +F src/sqliteInt.h 8601c620280dcb514e6e9dfb1fa7ee005ccc56c244ac82cb48a1045ed2e7003c F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -610,8 +610,8 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c bae853ad129d1129c063de8630a3e99e306283bc40146f359b1bb91be2c08f1e F src/treeview.c 43f88d0fd19976a60aee6867959213b438593276f1e8179048df85f416a1ab19 -F src/trigger.c 7d16aa09e63226b6d8b3f0fc60b21cbfa596fc406288b2ebcf4266633d1ba222 -F src/update.c d2648c47202cf54104c94b427209be0350e667fbf4b825a61cae54ef86aaf1d9 +F src/trigger.c 43d76cf913e65a5d06ed0768d8ded7259a5d6e284641a18acb355a302792cd05 +F src/update.c 985a8a45b4ff86a0231fedd584e2bd87fd6fac5168286935195ad006d032d555 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 6ca9cf268dfaf2393866990788c0797240e20e7ba7e3a22cd076e6a3c7b1a132 @@ -621,17 +621,17 @@ F src/vdbe.h 25dabb25c7e157b84e59260cfb5b466c3ac103ede9f36f4db371332c47601abe F src/vdbeInt.h 38206c8dd6b60ff03d9fd4f626b1b4fd0eef7cdc44f2fc2c1973b0f932a3f26b F src/vdbeapi.c aa5aaf2c37676b83af5724c6cd8207a3064ed46a217fd180957f75ac84f7a2a5 F src/vdbeaux.c 202dbaf7d1570cd53678f6b0bcad7b0642e88bc5d77abc1d5b8b9a202a6a19fd -F src/vdbeblob.c c6b8db50b227f66fb404215732068df76485b5b433e5f9d4d9ac27410b218193 +F src/vdbeblob.c 2f3c2ada0429045c54e5ebd48f45281c52addf4648e0d234a2718dbdeab01c80 F src/vdbemem.c 53881aa0a7845922a075b3f375695588618098871a7a4120af4c297b80fa3e64 F src/vdbesort.c cd5130f683706c1a43e165a74187745fb3351cb56052cf9dc91de820634bbde2 F src/vdbetrace.c 666c6fd9f1b62be6999e072a45b913e3c2c3518bc60dfd4d54fe304130acb724 F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c -F src/vtab.c 516cb50e2a57359155db7f71d98f1690dc9cae84d359a1c6801b2615dc3cf362 +F src/vtab.c 75bdaec808be883b8bb69a1f0a479c3a359823c5a85a26497cd5d90d3c30b74b F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 2be08331d798237ad5d7ae0b252700ffb2b63189cb18d993496d009a93e2f81c F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c 7342becedf3f8a26f9817f08436bdf8b56ad69af83705f6b9320a0ad3092c2ac -F src/where.c 07c63dde6ab72477b964f4c81bee61ef78a246ca149bb9a560784f2e85cd78d7 +F src/where.c 6e27c9f9438ddbb8aebbb83d24574a75398942b5e73b3f8cc572a39dc00f7482 F src/whereInt.h 9248161dd004f625ce5d3841ca9b99fed3fc8d61522cf76340fc5217dbe1375b F src/wherecode.c 9f1f65d11437b25cd0a1497a170514c785f19ce6ad9d3e6fc73719cb5a49012f F src/whereexpr.c 3a9144a9d52e110efdc012a73b1574e7b2b4df4bf98949387cb620295eba0975 @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d2da62a9df63036b02dadca3798de9e623c2680b3ef0c37d2b18bb88693afd7f -R 2bd36d7d73ef054d58c2b5fa1473f7b9 +P 8646547e54211d44c415663c33775c4268550f8332949c4731a4bb6ec9cc663a +R 8143bc84e57e339634d6338dda56d190 U drh -Z d1f622cc8631b67a8482f1c93905c30a +Z 0d31e4d81e774d8d4cc71b3c0a3d1311 diff --git a/manifest.uuid b/manifest.uuid index c4363aa39e..aecc9c1e1c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8646547e54211d44c415663c33775c4268550f8332949c4731a4bb6ec9cc663a \ No newline at end of file +bbb6759bcf6e01d36dfc787a82a610d359f50aaeac8104b73883a84906d54e1f \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 1d1e2d811b..75220a1de3 100644 --- a/src/alter.c +++ b/src/alter.c @@ -175,7 +175,7 @@ void sqlite3AlterRenameTable( } #ifndef SQLITE_OMIT_VIEW - if( pTab->pSelect ){ + if( IsView(pTab) ){ sqlite3ErrorMsg(pParse, "view %s may not be altered", pTab->zName); goto exit_rename_table; } @@ -371,7 +371,7 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ if( pDflt && pDflt->pLeft->op==TK_NULL ){ pDflt = 0; } - if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){ + if( (db->flags&SQLITE_ForeignKeys) && pNew->u.tab.pFKey && pDflt ){ sqlite3ErrorIfNotEmpty(pParse, zDb, zTab, "Cannot add a REFERENCES column with non-NULL default value"); } @@ -415,12 +415,13 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ db->mDbFlags |= DBFLAG_PreferBuiltin; /* substr() operations on characters, but addColOffset is in bytes. So we ** have to use printf() to translate between these units: */ + assert( !IsVirtual(pTab) ); sqlite3NestedParse(pParse, "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET " "sql = printf('%%.%ds, ',sql) || %Q" " || substr(sql,1+length(printf('%%.%ds',sql))) " "WHERE type = 'table' AND name = %Q", - zDb, pNew->addColOffset, zCol, pNew->addColOffset, + zDb, pNew->u.tab.addColOffset, zCol, pNew->u.tab.addColOffset, zTab ); sqlite3DbFree(db, zCol); @@ -500,7 +501,7 @@ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ #endif /* Make sure this is not an attempt to ALTER a view. */ - if( pTab->pSelect ){ + if( IsView(pTab) ){ sqlite3ErrorMsg(pParse, "Cannot add a column to a view"); goto exit_begin_add_column; } @@ -509,7 +510,7 @@ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ } sqlite3MayAbort(pParse); - assert( pTab->addColOffset>0 ); + assert( pTab->u.tab.addColOffset>0 ); iDb = sqlite3SchemaToIndex(db, pTab->pSchema); /* Put a copy of the Table struct in Parse.pNewTable for the @@ -540,9 +541,10 @@ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ pCol->hName = sqlite3StrIHash(pCol->zName); pCol->zColl = 0; } - pNew->pDfltList = sqlite3ExprListDup(db, pTab->pDfltList, 0); + assert( !IsVirtual(pNew) ); + pNew->u.tab.pDfltList = sqlite3ExprListDup(db, pTab->u.tab.pDfltList, 0); pNew->pSchema = db->aDb[iDb].pSchema; - pNew->addColOffset = pTab->addColOffset; + pNew->u.tab.addColOffset = pTab->u.tab.addColOffset; pNew->nTabRef = 1; exit_begin_add_column: @@ -562,7 +564,7 @@ exit_begin_add_column: static int isRealTable(Parse *pParse, Table *pTab, int bDrop){ const char *zType = 0; #ifndef SQLITE_OMIT_VIEW - if( pTab->pSelect ){ + if( IsView(pTab) ){ zType = "view"; } #endif @@ -1494,8 +1496,8 @@ static void renameColumnFunc( sCtx.pTab = pTab; if( rc!=SQLITE_OK ) goto renameColumnFunc_done; if( sParse.pNewTable ){ - Select *pSelect = sParse.pNewTable->pSelect; - if( pSelect ){ + if( IsView(sParse.pNewTable) ){ + Select *pSelect = sParse.pNewTable->u.view.pSelect; pSelect->selFlags &= ~SF_View; sParse.rc = SQLITE_OK; sqlite3SelectPrep(&sParse, pSelect, 0); @@ -1504,11 +1506,10 @@ static void renameColumnFunc( sqlite3WalkSelect(&sWalker, pSelect); } if( rc!=SQLITE_OK ) goto renameColumnFunc_done; - }else{ + }else if( IsOrdinaryTable(sParse.pNewTable) ){ /* A regular table */ int bFKOnly = sqlite3_stricmp(zTable, sParse.pNewTable->zName); FKey *pFKey; - assert( sParse.pNewTable->pSelect==0 ); sCtx.pTab = sParse.pNewTable; if( bFKOnly==0 ){ if( iColnCol ){ @@ -1535,7 +1536,8 @@ static void renameColumnFunc( #endif } - for(pFKey=sParse.pNewTable->pFKey; pFKey; pFKey=pFKey->pNextFrom){ + assert( !IsVirtual(sParse.pNewTable) ); + for(pFKey=sParse.pNewTable->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){ for(i=0; inCol; i++){ if( bFKOnly==0 && pFKey->aCol[i].iFrom==iCol ){ renameTokenFind(&sParse, &sCtx, (void*)&pFKey->aCol[i]); @@ -1701,28 +1703,31 @@ static void renameTableFunc( if( sParse.pNewTable ){ Table *pTab = sParse.pNewTable; - if( pTab->pSelect ){ + if( IsView(pTab) ){ if( isLegacy==0 ){ - Select *pSelect = pTab->pSelect; + Select *pSelect = pTab->u.view.pSelect; NameContext sNC; memset(&sNC, 0, sizeof(sNC)); sNC.pParse = &sParse; assert( pSelect->selFlags & SF_View ); pSelect->selFlags &= ~SF_View; - sqlite3SelectPrep(&sParse, pTab->pSelect, &sNC); + sqlite3SelectPrep(&sParse, pTab->u.view.pSelect, &sNC); if( sParse.nErr ){ rc = sParse.rc; }else{ - sqlite3WalkSelect(&sWalker, pTab->pSelect); + sqlite3WalkSelect(&sWalker, pTab->u.view.pSelect); } } }else{ /* Modify any FK definitions to point to the new table. */ #ifndef SQLITE_OMIT_FOREIGN_KEY - if( isLegacy==0 || (db->flags & SQLITE_ForeignKeys) ){ + if( (isLegacy==0 || (db->flags & SQLITE_ForeignKeys)) + && !IsVirtual(pTab) + ){ FKey *pFKey; - for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){ + assert( !IsVirtual(pTab) ); + for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){ if( sqlite3_stricmp(pFKey->zTo, zOld)==0 ){ renameTokenFind(&sParse, &sCtx, (void*)pFKey->zTo); } @@ -1862,8 +1867,8 @@ static void renameQuotefixFunc( sWalker.u.pRename = &sCtx; if( sParse.pNewTable ){ - Select *pSelect = sParse.pNewTable->pSelect; - if( pSelect ){ + if( IsView(sParse.pNewTable) ){ + Select *pSelect = sParse.pNewTable->u.view.pSelect; pSelect->selFlags &= ~SF_View; sParse.rc = SQLITE_OK; sqlite3SelectPrep(&sParse, pSelect, 0); @@ -1961,11 +1966,11 @@ static void renameTableTest( rc = renameParseSql(&sParse, zDb, db, zInput, bTemp); db->flags |= (flags & (SQLITE_DqsDML|SQLITE_DqsDDL)); if( rc==SQLITE_OK ){ - if( isLegacy==0 && sParse.pNewTable && sParse.pNewTable->pSelect ){ + if( isLegacy==0 && sParse.pNewTable && IsView(sParse.pNewTable) ){ NameContext sNC; memset(&sNC, 0, sizeof(sNC)); sNC.pParse = &sParse; - sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, &sNC); + sqlite3SelectPrep(&sParse, sParse.pNewTable->u.view.pSelect, &sNC); if( sParse.nErr ) rc = sParse.rc; } @@ -2042,7 +2047,8 @@ static void dropColumnFunc( pEnd = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol+1].zName); zEnd = (const char*)pEnd->t.z; }else{ - zEnd = (const char*)&zSql[pTab->addColOffset]; + assert( !IsVirtual(pTab) ); + zEnd = (const char*)&zSql[pTab->u.tab.addColOffset]; while( ALWAYS(pCol->t.z[0]!=0) && pCol->t.z[0]!=',' ) pCol->t.z--; } diff --git a/src/build.c b/src/build.c index 33f0015fd7..09222acf81 100644 --- a/src/build.c +++ b/src/build.c @@ -678,13 +678,15 @@ void sqlite3ColumnSetExpr( Column *pCol, /* The column to receive the new DEFAULT expression */ Expr *pExpr /* The new default expression */ ){ - ExprList *pList = pTab->pDfltList; + ExprList *pList; + assert( !IsVirtual(pTab) ); + pList = pTab->u.tab.pDfltList; if( pCol->iDflt==0 || pList==0 || pList->nExpriDflt ){ pCol->iDflt = pList==0 ? 1 : pList->nExpr+1; - pTab->pDfltList = sqlite3ExprListAppend(pParse, pList, pExpr); + pTab->u.tab.pDfltList = sqlite3ExprListAppend(pParse, pList, pExpr); }else{ sqlite3ExprDelete(pParse->db, pList->a[pCol->iDflt-1].pExpr); pList->a[pCol->iDflt-1].pExpr = pExpr; @@ -698,9 +700,10 @@ void sqlite3ColumnSetExpr( */ Expr *sqlite3ColumnExpr(Table *pTab, Column *pCol){ if( pCol->iDflt==0 ) return 0; - if( pTab->pDfltList==0 ) return 0; - if( pTab->pDfltList->nExpriDflt ) return 0; - return pTab->pDfltList->a[pCol->iDflt-1].pExpr; + if( IsVirtual(pTab) ) return 0; + if( pTab->u.tab.pDfltList==0 ) return 0; + if( pTab->u.tab.pDfltList->nExpriDflt ) return 0; + return pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr; } /* @@ -718,11 +721,15 @@ void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){ sqlite3DbFree(db, pCol->zColl); } sqlite3DbFree(db, pTable->aCol); - sqlite3ExprListDelete(db, pTable->pDfltList); + if( !IsVirtual(pTable) ){ + sqlite3ExprListDelete(db, pTable->u.tab.pDfltList); + } if( db==0 || db->pnBytesFreed==0 ){ pTable->aCol = 0; pTable->nCol = 0; - pTable->pDfltList = 0; + if( !IsVirtual(pTable) ){ + pTable->u.tab.pDfltList = 0; + } } } } @@ -775,19 +782,25 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){ sqlite3FreeIndex(db, pIndex); } - /* Delete any foreign keys attached to this table. */ - sqlite3FkDelete(db, pTable); + if( IsOrdinaryTable(pTable) ){ + sqlite3FkDelete(db, pTable); + } +#ifndef SQLITE_OMIT_VIRTUAL_TABLE + else if( IsVirtual(pTable) ){ + sqlite3VtabClear(db, pTable); + } +#endif + else{ + assert( IsView(pTable) ); + sqlite3SelectDelete(db, pTable->u.view.pSelect); + } /* Delete the Table structure itself. */ sqlite3DeleteColumnNames(db, pTable); sqlite3DbFree(db, pTable->zName); sqlite3DbFree(db, pTable->zColAff); - sqlite3SelectDelete(db, pTable->pSelect); sqlite3ExprListDelete(db, pTable->pCheck); -#ifndef SQLITE_OMIT_VIRTUALTABLE - sqlite3VtabClear(db, pTable); -#endif sqlite3DbFree(db, pTable); /* Verify that no lookaside memory was used by schema tables */ @@ -2420,7 +2433,7 @@ int sqlite3IsShadowTableOf(sqlite3 *db, Table *pTab, const char *zName){ nName = sqlite3Strlen30(pTab->zName); if( sqlite3_strnicmp(zName, pTab->zName, nName)!=0 ) return 0; if( zName[nName]!='_' ) return 0; - pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]); + pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->u.vtab.azArg[0]); if( pMod==0 ) return 0; if( pMod->pModule->iVersion<3 ) return 0; if( pMod->pModule->xShadowName==0 ) return 0; @@ -2632,7 +2645,7 @@ void sqlite3EndTable( /* ** Initialize zType for the new view or table. */ - if( p->pSelect==0 ){ + if( IsOrdinaryTable(p) ){ /* A regular table */ zType = "table"; zType2 = "TABLE"; @@ -2782,12 +2795,12 @@ void sqlite3EndTable( } #ifndef SQLITE_OMIT_ALTERTABLE - if( !pSelect && !p->pSelect ){ + if( !pSelect && IsOrdinaryTable(p) ){ assert( pCons && pEnd ); if( pCons->z==0 ){ pCons = pEnd; } - p->addColOffset = 13 + (int)(pCons->z - pParse->sNameToken.z); + p->u.tab.addColOffset = 13 + (int)(pCons->z - pParse->sNameToken.z); } #endif } @@ -2844,12 +2857,13 @@ void sqlite3CreateView( */ pSelect->selFlags |= SF_View; if( IN_RENAME_OBJECT ){ - p->pSelect = pSelect; + p->u.view.pSelect = pSelect; pSelect = 0; }else{ - p->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); + p->u.view.pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); } p->pCheck = sqlite3ExprListDup(db, pCNames, EXPRDUP_REDUCE); + p->eTabType = TABTYP_VIEW; if( db->mallocFailed ) goto create_view_fail; /* Locate the end of the CREATE VIEW statement. Make sEnd point to @@ -2946,8 +2960,8 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ ** to be permanent. So the computation is done on a copy of the SELECT ** statement that defines the view. */ - assert( pTable->pSelect ); - pSel = sqlite3SelectDup(db, pTable->pSelect, 0); + assert( IsView(pTable) ); + pSel = sqlite3SelectDup(db, pTable->u.view.pSelect, 0); if( pSel ){ u8 eParseMode = pParse->eParseMode; pParse->eParseMode = PARSE_MODE_NORMAL; @@ -3022,7 +3036,7 @@ static void sqliteViewResetAll(sqlite3 *db, int idx){ if( !DbHasProperty(db, idx, DB_UnresetViews) ) return; for(i=sqliteHashFirst(&db->aDb[idx].pSchema->tblHash); i;i=sqliteHashNext(i)){ Table *pTab = sqliteHashData(i); - if( pTab->pSelect ){ + if( IsView(pTab) ){ sqlite3DeleteColumnNames(db, pTab); } } @@ -3364,11 +3378,11 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ /* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used ** on a table. */ - if( isView && pTab->pSelect==0 ){ + if( isView && !IsView(pTab) ){ sqlite3ErrorMsg(pParse, "use DROP TABLE to delete table %s", pTab->zName); goto exit_drop_table; } - if( !isView && pTab->pSelect ){ + if( !isView && IsView(pTab) ){ sqlite3ErrorMsg(pParse, "use DROP VIEW to delete view %s", pTab->zName); goto exit_drop_table; } @@ -3455,7 +3469,7 @@ void sqlite3CreateForeignKey( goto fk_end; } pFKey->pFrom = p; - pFKey->pNextFrom = p->pFKey; + pFKey->pNextFrom = p->u.tab.pFKey; z = (char*)&pFKey->aCol[nCol]; pFKey->zTo = z; if( IN_RENAME_OBJECT ){ @@ -3520,7 +3534,8 @@ void sqlite3CreateForeignKey( /* Link the foreign key to the table as the last step. */ - p->pFKey = pFKey; + assert( !IsVirtual(p) ); + p->u.tab.pFKey = pFKey; pFKey = 0; fk_end: @@ -3541,7 +3556,9 @@ void sqlite3DeferForeignKey(Parse *pParse, int isDeferred){ #ifndef SQLITE_OMIT_FOREIGN_KEY Table *pTab; FKey *pFKey; - if( (pTab = pParse->pNewTable)==0 || (pFKey = pTab->pFKey)==0 ) return; + if( (pTab = pParse->pNewTable)==0 ) return; + if( IsVirtual(pTab) ) return; + if( (pFKey = pTab->u.tab.pFKey)==0 ) return; assert( isDeferred==0 || isDeferred==1 ); /* EV: R-30323-21917 */ pFKey->isDeferred = (u8)isDeferred; #endif @@ -3833,7 +3850,7 @@ void sqlite3CreateIndex( goto exit_create_index; } #ifndef SQLITE_OMIT_VIEW - if( pTab->pSelect ){ + if( IsView(pTab) ){ sqlite3ErrorMsg(pParse, "views may not be indexed"); goto exit_create_index; } diff --git a/src/delete.c b/src/delete.c index dd074bb352..459e932b5e 100644 --- a/src/delete.c +++ b/src/delete.c @@ -84,7 +84,7 @@ int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){ return 1; } #ifndef SQLITE_OMIT_VIEW - if( !viewOk && pTab->pSelect ){ + if( !viewOk && IsView(pTab) ){ sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName); return 1; } @@ -301,7 +301,7 @@ void sqlite3DeleteFrom( */ #ifndef SQLITE_OMIT_TRIGGER pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); - isView = pTab->pSelect!=0; + isView = IsView(pTab); #else # define pTrigger 0 # define isView 0 @@ -551,7 +551,7 @@ void sqlite3DeleteFrom( if( eOnePass!=ONEPASS_OFF ){ assert( nKey==nPk ); /* OP_Found will use an unpacked key */ if( !IsVirtual(pTab) && aToOpen[iDataCur-iTabCur] ){ - assert( pPk!=0 || pTab->pSelect!=0 ); + assert( pPk!=0 || IsView(pTab) ); sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey); VdbeCoverage(v); } @@ -785,7 +785,7 @@ void sqlite3GenerateRowDelete( ** the update-hook is not invoked for rows removed by REPLACE, but the ** pre-update-hook is. */ - if( pTab->pSelect==0 ){ + if( !IsView(pTab) ){ u8 p5 = 0; sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek); sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0)); diff --git a/src/expr.c b/src/expr.c index 04881be8ca..ca0c00a14d 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2513,7 +2513,7 @@ static Select *isCandidateForInOpt(Expr *pX){ if( pSrc->a[0].pSelect ) return 0; /* FROM is not a subquery or view */ pTab = pSrc->a[0].pTab; assert( pTab!=0 ); - assert( pTab->pSelect==0 ); /* FROM clause is not a view */ + assert( !IsView(pTab) ); /* FROM clause is not a view */ if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */ pEList = p->pEList; assert( pEList!=0 ); diff --git a/src/fkey.c b/src/fkey.c index 2e743c7022..ffb3a732eb 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -723,7 +723,8 @@ void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){ Vdbe *v = sqlite3GetVdbe(pParse); assert( v ); /* VDBE has already been allocated */ - assert( pTab->pSelect==0 ); /* Not a view */ + assert( !IsView(pTab) ); /* Not a view */ + assert( !IsVirtual(pTab) ); if( sqlite3FkReferences(pTab)==0 ){ /* Search for a deferred foreign key constraint for which this table ** is the child table. If one cannot be found, return without @@ -731,7 +732,7 @@ void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){ ** the entire DELETE if there are no outstanding deferred constraints ** when this statement is run. */ FKey *p; - for(p=pTab->pFKey; p; p=p->pNextFrom){ + for(p=pTab->u.tab.pFKey; p; p=p->pNextFrom){ if( p->isDeferred || (db->flags & SQLITE_DeferFKs) ) break; } if( !p ) return; @@ -893,7 +894,8 @@ void sqlite3FkCheck( /* Loop through all the foreign key constraints for which pTab is the ** child table (the table that the foreign key definition is part of). */ - for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){ + assert( !IsVirtual(pTab) ); + for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){ Table *pTo; /* Parent table of foreign key pFKey */ Index *pIdx = 0; /* Index on key columns in pTo */ int *aiFree = 0; @@ -1078,7 +1080,8 @@ u32 sqlite3FkOldmask( if( pParse->db->flags&SQLITE_ForeignKeys ){ FKey *p; int i; - for(p=pTab->pFKey; p; p=p->pNextFrom){ + assert( !IsVirtual(pTab) ); + for(p=pTab->u.tab.pFKey; p; p=p->pNextFrom){ for(i=0; inCol; i++) mask |= COLUMN_MASK(p->aCol[i].iFrom); } for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ @@ -1128,19 +1131,19 @@ int sqlite3FkRequired( ){ int eRet = 1; /* Value to return if bHaveFK is true */ int bHaveFK = 0; /* If FK processing is required */ - if( pParse->db->flags&SQLITE_ForeignKeys ){ + if( pParse->db->flags&SQLITE_ForeignKeys && !IsVirtual(pTab) ){ if( !aChange ){ /* A DELETE operation. Foreign key processing is required if the ** table in question is either the child or parent table for any ** foreign key constraint. */ - bHaveFK = (sqlite3FkReferences(pTab) || pTab->pFKey); + bHaveFK = (sqlite3FkReferences(pTab) || pTab->u.tab.pFKey); }else{ /* This is an UPDATE. Foreign key processing is only required if the ** operation modifies one or more child or parent key columns. */ FKey *p; /* Check if any child key columns are being modified. */ - for(p=pTab->pFKey; p; p=p->pNextFrom){ + for(p=pTab->u.tab.pFKey; p; p=p->pNextFrom){ if( fkChildIsModified(pTab, p, aChange, chngRowid) ){ if( 0==sqlite3_stricmp(pTab->zName, p->zTo) ) eRet = 2; bHaveFK = 1; @@ -1416,9 +1419,9 @@ void sqlite3FkDelete(sqlite3 *db, Table *pTab){ FKey *pFKey; /* Iterator variable */ FKey *pNext; /* Copy of pFKey->pNextFrom */ - assert( db==0 || IsVirtual(pTab) - || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) ); - for(pFKey=pTab->pFKey; pFKey; pFKey=pNext){ + assert( !IsVirtual(pTab) ); + assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) ); + for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pNext){ /* Remove the FK from the fkeyHash hash table. */ if( !db || db->pnBytesFreed==0 ){ diff --git a/src/insert.c b/src/insert.c index 867ab76fd1..bff75a0a69 100644 --- a/src/insert.c +++ b/src/insert.c @@ -703,7 +703,7 @@ void sqlite3Insert( */ #ifndef SQLITE_OMIT_TRIGGER pTrigger = sqlite3TriggersExist(pParse, pTab, TK_INSERT, 0, &tmask); - isView = pTab->pSelect!=0; + isView = IsView(pTab); #else # define pTrigger 0 # define tmask 0 @@ -989,7 +989,7 @@ void sqlite3Insert( pTab->zName); goto insert_cleanup; } - if( pTab->pSelect ){ + if( IsView(pTab) ){ sqlite3ErrorMsg(pParse, "cannot UPSERT a view"); goto insert_cleanup; } @@ -1624,7 +1624,7 @@ void sqlite3GenerateConstraintChecks( db = pParse->db; v = pParse->pVdbe; assert( v!=0 ); - assert( pTab->pSelect==0 ); /* This table is not a VIEW */ + assert( !IsView(pTab) ); /* This table is not a VIEW */ nCol = pTab->nCol; /* pPk is the PRIMARY KEY index for WITHOUT ROWID tables and NULL for @@ -2185,7 +2185,7 @@ void sqlite3GenerateConstraintChecks( && ( 0==(db->flags&SQLITE_RecTriggers) || /* Condition 4 */ 0==sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0)) && ( 0==(db->flags&SQLITE_ForeignKeys) || /* Condition 5 */ - (0==pTab->pFKey && 0==sqlite3FkReferences(pTab))) + (0==pTab->u.tab.pFKey && 0==sqlite3FkReferences(pTab))) ){ sqlite3VdbeResolveLabel(v, addrUniqueOk); continue; @@ -2484,7 +2484,7 @@ void sqlite3CompleteInsertion( v = pParse->pVdbe; assert( v!=0 ); - assert( pTab->pSelect==0 ); /* This table is not a VIEW */ + assert( !IsView(pTab) ); /* This table is not a VIEW */ for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ /* All REPLACE indexes are at the end of the list */ assert( pIdx->onError!=OE_Replace @@ -2786,13 +2786,8 @@ static int xferOptimization( if( HasRowid(pDest)!=HasRowid(pSrc) ){ return 0; /* source and destination must both be WITHOUT ROWID or not */ } -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( IsVirtual(pSrc) ){ - return 0; /* tab2 must not be a virtual table */ - } -#endif - if( pSrc->pSelect ){ - return 0; /* tab2 may not be a view */ + if( !IsOrdinaryTable(pSrc) ){ + return 0; /* tab2 may not be a view or virtual table */ } if( pDest->nCol!=pSrc->nCol ){ return 0; /* Number of columns must be the same in tab1 and tab2 */ @@ -2899,7 +2894,7 @@ static int xferOptimization( ** the extra complication to make this rule less restrictive is probably ** not worth the effort. Ticket [6284df89debdfa61db8073e062908af0c9b6118e] */ - if( (db->flags & SQLITE_ForeignKeys)!=0 && pDest->pFKey!=0 ){ + if( (db->flags & SQLITE_ForeignKeys)!=0 && pDest->u.tab.pFKey!=0 ){ return 0; } #endif diff --git a/src/main.c b/src/main.c index fc0fa6ad16..2dc29593dc 100644 --- a/src/main.c +++ b/src/main.c @@ -3731,7 +3731,7 @@ int sqlite3_table_column_metadata( /* Locate the table in question */ pTab = sqlite3FindTable(db, zTableName, zDbName); - if( !pTab || pTab->pSelect ){ + if( !pTab || IsView(pTab) ){ pTab = 0; goto error_out; } diff --git a/src/pragma.c b/src/pragma.c index 0427bb972f..2606e85506 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1360,8 +1360,8 @@ void sqlite3Pragma( FKey *pFK; Table *pTab; pTab = sqlite3FindTable(db, zRight, zDb); - if( pTab ){ - pFK = pTab->pFKey; + if( pTab && !IsVirtual(pTab) ){ + pFK = pTab->u.tab.pFKey; if( pFK ){ int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); int i = 0; @@ -1420,7 +1420,7 @@ void sqlite3Pragma( pTab = (Table*)sqliteHashData(k); k = sqliteHashNext(k); } - if( pTab==0 || pTab->pFKey==0 ) continue; + if( pTab==0 || IsVirtual(pTab) || pTab->u.tab.pFKey==0 ) continue; iDb = sqlite3SchemaToIndex(db, pTab->pSchema); zDb = db->aDb[iDb].zDbSName; sqlite3CodeVerifySchema(pParse, iDb); @@ -1428,7 +1428,8 @@ void sqlite3Pragma( if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow; sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead); sqlite3VdbeLoadString(v, regResult, pTab->zName); - for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){ + assert( !IsVirtual(pTab) ); + for(i=1, pFK=pTab->u.tab.pFKey; pFK; i++, pFK=pFK->pNextFrom){ pParent = sqlite3FindTable(db, pFK->zTo, zDb); if( pParent==0 ) continue; pIdx = 0; @@ -1450,7 +1451,8 @@ void sqlite3Pragma( if( pFK ) break; if( pParse->nTabnTab = i; addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0); VdbeCoverage(v); - for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){ + assert( !IsVirtual(pTab) ); + for(i=1, pFK=pTab->u.tab.pFKey; pFK; i++, pFK=pFK->pNextFrom){ pParent = sqlite3FindTable(db, pFK->zTo, zDb); pIdx = 0; aiCols = 0; diff --git a/src/select.c b/src/select.c index 66e1434a31..d6708c231f 100644 --- a/src/select.c +++ b/src/select.c @@ -4933,7 +4933,7 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){ } pTab = p->pSrc->a[0].pTab; pExpr = p->pEList->a[0].pExpr; - assert( pTab && !pTab->pSelect && pExpr ); + assert( pTab && !IsView(pTab) && pExpr ); if( IsVirtual(pTab) ) return 0; if( pExpr->op!=TK_AGG_FUNCTION ) return 0; @@ -5478,30 +5478,31 @@ static int selectExpander(Walker *pWalker, Select *p){ return WRC_Abort; } #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) - if( IsVirtual(pTab) || pTab->pSelect ){ + if( !IsOrdinaryTable(pTab) ){ i16 nCol; u8 eCodeOrig = pWalker->eCode; if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; assert( pFrom->pSelect==0 ); - if( pTab->pSelect - && (db->flags & SQLITE_EnableView)==0 - && pTab->pSchema!=db->aDb[1].pSchema - ){ - sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited", - pTab->zName); - } + if( IsView(pTab) ){ + if( (db->flags & SQLITE_EnableView)==0 + && pTab->pSchema!=db->aDb[1].pSchema + ){ + sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited", + pTab->zName); + } + pFrom->pSelect = sqlite3SelectDup(db, pTab->u.view.pSelect, 0); + }else #ifndef SQLITE_OMIT_VIRTUALTABLE - assert( SQLITE_VTABRISK_Normal==1 && SQLITE_VTABRISK_High==2 ); - if( IsVirtual(pTab) + if( ALWAYS(IsVirtual(pTab)) && pFrom->fg.fromDDL - && ALWAYS(pTab->pVTable!=0) - && pTab->pVTable->eVtabRisk > ((db->flags & SQLITE_TrustedSchema)!=0) + && ALWAYS(pTab->u.vtab.p!=0) + && pTab->u.vtab.p->eVtabRisk > ((db->flags & SQLITE_TrustedSchema)!=0) ){ sqlite3ErrorMsg(pParse, "unsafe use of virtual table \"%s\"", pTab->zName); } + assert( SQLITE_VTABRISK_Normal==1 && SQLITE_VTABRISK_High==2 ); #endif - pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0); nCol = pTab->nCol; pTab->nCol = -1; pWalker->eCode = 1; /* Turn on Select.selId renumbering */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 3fbb148d40..9a2c49e526 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2201,19 +2201,16 @@ struct VTable { #define SQLITE_VTABRISK_High 2 /* -** The schema for each SQL table and view is represented in memory -** by an instance of the following structure. +** The schema for each SQL table, virtual table, and view is represented +** in memory by an instance of the following structure. */ struct Table { char *zName; /* Name of the table or view */ Column *aCol; /* Information about each column */ Index *pIndex; /* List of SQL indexes on this table. */ - Select *pSelect; /* NULL for tables. Points to definition if a view. */ - FKey *pFKey; /* Linked list of all foreign keys in this table */ char *zColAff; /* String defining the affinity of each column */ ExprList *pCheck; /* All CHECK constraints */ /* ... also used as column name list in a VIEW */ - ExprList *pDfltList; /* DEFAULT clauses on various columns */ Pgno tnum; /* Root BTree page for this table */ u32 nTabRef; /* Number of pointers to this Table */ u32 tabFlags; /* Mask of TF_* values */ @@ -2226,15 +2223,24 @@ struct Table { LogEst costMult; /* Cost multiplier for using this table */ #endif 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 - int nModuleArg; /* Number of arguments to the module */ - char **azModuleArg; /* 0: module 1: schema 2: vtab name 3...: args */ - VTable *pVTable; /* List of VTable objects. */ -#endif - Trigger *pTrigger; /* List of triggers stored in pSchema */ + u8 eTabType; /* 0: normal, 1: virtual, 2: view */ + union { + struct { /* Used by ordinary tables: */ + int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */ + FKey *pFKey; /* Linked list of all foreign keys in this table */ + ExprList *pDfltList; /* DEFAULT clauses on various columns. + ** Or the AS clause for generated columns. */ + } tab; + struct { /* Used by views: */ + Select *pSelect; /* View definition */ + } view; + struct { /* Used by virtual tables only: */ + int nArg; /* Number of arguments to the module */ + char **azArg; /* 0: module 1: schema 2: vtab name 3...: args */ + VTable *p; /* List of VTable objects. */ + } vtab; + } u; + Trigger *pTrigger; /* List of triggers on this object */ Schema *pSchema; /* Schema that contains this table */ }; @@ -2253,24 +2259,34 @@ struct Table { ** TF_HasStored == COLFLAG_STORED ** TF_HasHidden == COLFLAG_HIDDEN */ -#define TF_Readonly 0x0001 /* Read-only system table */ -#define TF_HasHidden 0x0002 /* Has one or more hidden columns */ -#define TF_HasPrimaryKey 0x0004 /* Table has a primary key */ -#define TF_Autoincrement 0x0008 /* Integer primary key is autoincrement */ -#define TF_HasStat1 0x0010 /* nRowLogEst set from sqlite_stat1 */ -#define TF_HasVirtual 0x0020 /* Has one or more VIRTUAL columns */ -#define TF_HasStored 0x0040 /* Has one or more STORED columns */ -#define TF_HasGenerated 0x0060 /* Combo: HasVirtual + HasStored */ -#define TF_WithoutRowid 0x0080 /* No rowid. PRIMARY KEY is the key */ -#define TF_StatsUsed 0x0100 /* Query planner decisions affected by +#define TF_Readonly 0x00000001 /* Read-only system table */ +#define TF_HasHidden 0x00000002 /* Has one or more hidden columns */ +#define TF_HasPrimaryKey 0x00000004 /* Table has a primary key */ +#define TF_Autoincrement 0x00000008 /* Integer primary key is autoincrement */ +#define TF_HasStat1 0x00000010 /* nRowLogEst set from sqlite_stat1 */ +#define TF_HasVirtual 0x00000020 /* Has one or more VIRTUAL columns */ +#define TF_HasStored 0x00000040 /* Has one or more STORED columns */ +#define TF_HasGenerated 0x00000060 /* Combo: HasVirtual + HasStored */ +#define TF_WithoutRowid 0x00000080 /* No rowid. PRIMARY KEY is the key */ +#define TF_StatsUsed 0x00000100 /* Query planner decisions affected by ** Index.aiRowLogEst[] values */ -#define TF_NoVisibleRowid 0x0200 /* No user-visible "rowid" column */ -#define TF_OOOHidden 0x0400 /* Out-of-Order hidden columns */ -#define TF_HasNotNull 0x0800 /* Contains NOT NULL constraints */ -#define TF_Shadow 0x1000 /* True for a shadow table */ -#define TF_HasStat4 0x2000 /* STAT4 info available for this table */ -#define TF_Ephemeral 0x4000 /* An ephemeral table */ -#define TF_Eponymous 0x8000 /* An eponymous virtual table */ +#define TF_NoVisibleRowid 0x00000200 /* No user-visible "rowid" column */ +#define TF_OOOHidden 0x00000400 /* Out-of-Order hidden columns */ +#define TF_HasNotNull 0x00000800 /* Contains NOT NULL constraints */ +#define TF_Shadow 0x00001000 /* True for a shadow table */ +#define TF_HasStat4 0x00002000 /* STAT4 info available for this table */ +#define TF_Ephemeral 0x00004000 /* An ephemeral table */ +#define TF_Eponymous 0x00008000 /* An eponymous virtual table */ + +/* +** Allowed values for Table.eTabType +*/ +#define TABTYP_NORM 0 /* Ordinary table */ +#define TABTYP_VTAB 1 /* Virtual table */ +#define TABTYP_VIEW 2 /* A view */ + +#define IsView(X) ((X)->eTabType==TABTYP_VIEW) +#define IsOrdinaryTable(X) ((X)->eTabType==TABTYP_NORM) /* ** Test to see whether or not a table is a virtual table. This is @@ -2278,9 +2294,9 @@ struct Table { ** table support is omitted from the build. */ #ifndef SQLITE_OMIT_VIRTUALTABLE -# define IsVirtual(X) ((X)->nModuleArg) +# define IsVirtual(X) ((X)->eTabType==TABTYP_VTAB) # define ExprIsVtab(X) \ - ((X)->op==TK_COLUMN && (X)->y.pTab!=0 && (X)->y.pTab->nModuleArg) + ((X)->op==TK_COLUMN && (X)->y.pTab!=0 && (X)->y.pTab->eTabType==TABTYP_VTAB) #else # define IsVirtual(X) 0 # define ExprIsVtab(X) 0 diff --git a/src/trigger.c b/src/trigger.c index c5beeb9844..4db697c655 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -219,12 +219,12 @@ void sqlite3BeginTrigger( /* INSTEAD of triggers are only for views and views only support INSTEAD ** of triggers. */ - if( pTab->pSelect && tr_tm!=TK_INSTEAD ){ + if( IsView(pTab) && tr_tm!=TK_INSTEAD ){ sqlite3ErrorMsg(pParse, "cannot create %s trigger on view: %S", (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName->a); goto trigger_orphan_error; } - if( !pTab->pSelect && tr_tm==TK_INSTEAD ){ + if( !IsView(pTab) && tr_tm==TK_INSTEAD ){ sqlite3ErrorMsg(pParse, "cannot create INSTEAD OF" " trigger on table: %S", pTableName->a); goto trigger_orphan_error; diff --git a/src/update.c b/src/update.c index f93d85bd5e..6f503c32f8 100644 --- a/src/update.c +++ b/src/update.c @@ -60,7 +60,7 @@ static void updateVirtualTable( */ void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ assert( pTab!=0 ); - if( !pTab->pSelect ){ + if( !IsView(pTab) ){ sqlite3_value *pValue = 0; u8 enc = ENC(sqlite3VdbeDb(v)); Column *pCol = &pTab->aCol[i]; @@ -237,7 +237,7 @@ static void updateFromSelect( pList = sqlite3ExprListAppend(pParse, pList, pNew); } eDest = IsVirtual(pTab) ? SRT_Table : SRT_Upfrom; - }else if( pTab->pSelect ){ + }else if( IsView(pTab) ){ for(i=0; inCol; i++){ pList = sqlite3ExprListAppend(pParse, pList, exprRowColumn(pParse, i)); } @@ -362,7 +362,7 @@ void sqlite3Update( */ #ifndef SQLITE_OMIT_TRIGGER pTrigger = sqlite3TriggersExist(pParse, pTab, TK_UPDATE, pChanges, &tmask); - isView = pTab->pSelect!=0; + isView = IsView(pTab); assert( pTrigger || tmask==0 ); #else # define pTrigger 0 diff --git a/src/vdbeblob.c b/src/vdbeblob.c index a4e79bf89b..34cf880eca 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -167,7 +167,7 @@ int sqlite3_blob_open( sqlite3ErrorMsg(&sParse, "cannot open table without rowid: %s", zTable); } #ifndef SQLITE_OMIT_VIEW - if( pTab && pTab->pSelect ){ + if( pTab && IsView(pTab) ){ pTab = 0; sqlite3ErrorMsg(&sParse, "cannot open view: %s", zTable); } @@ -212,7 +212,8 @@ int sqlite3_blob_open( ** key columns must be indexed. The check below will pick up this ** case. */ FKey *pFKey; - for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){ + assert( !IsVirtual(pTab) ); + for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){ int j; for(j=0; jnCol; j++){ if( pFKey->aCol[j].iFrom==iCol ){ diff --git a/src/vtab.c b/src/vtab.c index 25672bcce0..c66a154678 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -192,7 +192,7 @@ void sqlite3VtabLock(VTable *pVTab){ VTable *sqlite3GetVTable(sqlite3 *db, Table *pTab){ VTable *pVtab; assert( IsVirtual(pTab) ); - for(pVtab=pTab->pVTable; pVtab && pVtab->db!=db; pVtab=pVtab->pNext); + for(pVtab=pTab->u.vtab.p; pVtab && pVtab->db!=db; pVtab=pVtab->pNext); return pVtab; } @@ -220,21 +220,21 @@ void sqlite3VtabUnlock(VTable *pVTab){ /* ** Table p is a virtual table. This function moves all elements in the -** p->pVTable list to the sqlite3.pDisconnect lists of their associated +** p->u.vtab.p list to the sqlite3.pDisconnect lists of their associated ** database connections to be disconnected at the next opportunity. ** Except, if argument db is not NULL, then the entry associated with -** connection db is left in the p->pVTable list. +** connection db is left in the p->u.vtab.p list. */ static VTable *vtabDisconnectAll(sqlite3 *db, Table *p){ VTable *pRet = 0; - VTable *pVTable = p->pVTable; - p->pVTable = 0; + VTable *pVTable = p->u.vtab.p; + p->u.vtab.p = 0; /* Assert that the mutex (if any) associated with the BtShared database ** that contains table p is held by the caller. See header comments ** above function sqlite3VtabUnlockList() for an explanation of why ** this makes it safe to access the sqlite3.pDisconnect list of any - ** database connection that may have an entry in the p->pVTable list. + ** database connection that may have an entry in the p->u.vtab.p list. */ assert( db==0 || sqlite3SchemaMutexHeld(db, 0, p->pSchema) ); @@ -244,7 +244,7 @@ static VTable *vtabDisconnectAll(sqlite3 *db, Table *p){ assert( db2 ); if( db2==db ){ pRet = pVTable; - p->pVTable = pRet; + p->u.vtab.p = pRet; pRet->pNext = 0; }else{ pVTable->pNext = db2->pDisconnect; @@ -272,7 +272,7 @@ void sqlite3VtabDisconnect(sqlite3 *db, Table *p){ assert( sqlite3BtreeHoldsAllMutexes(db) ); assert( sqlite3_mutex_held(db->mutex) ); - for(ppVTab=&p->pVTable; *ppVTab; ppVTab=&(*ppVTab)->pNext){ + for(ppVTab=&p->u.vtab.p; *ppVTab; ppVTab=&(*ppVTab)->pNext){ if( (*ppVTab)->db==db ){ VTable *pVTab = *ppVTab; *ppVTab = pVTab->pNext; @@ -336,36 +336,36 @@ void sqlite3VtabUnlockList(sqlite3 *db){ */ void sqlite3VtabClear(sqlite3 *db, Table *p){ if( !db || db->pnBytesFreed==0 ) vtabDisconnectAll(0, p); - if( p->azModuleArg ){ + if( p->u.vtab.azArg ){ int i; - for(i=0; inModuleArg; i++){ - if( i!=1 ) sqlite3DbFree(db, p->azModuleArg[i]); + for(i=0; iu.vtab.nArg; i++){ + if( i!=1 ) sqlite3DbFree(db, p->u.vtab.azArg[i]); } - sqlite3DbFree(db, p->azModuleArg); + sqlite3DbFree(db, p->u.vtab.azArg); } } /* -** Add a new module argument to pTable->azModuleArg[]. +** Add a new module argument to pTable->u.vtab.azArg[]. ** The string is not copied - the pointer is stored. The ** string will be freed automatically when the table is ** deleted. */ static void addModuleArgument(Parse *pParse, Table *pTable, char *zArg){ - sqlite3_int64 nBytes = sizeof(char *)*(2+pTable->nModuleArg); + sqlite3_int64 nBytes = sizeof(char *)*(2+pTable->u.vtab.nArg); char **azModuleArg; sqlite3 *db = pParse->db; - if( pTable->nModuleArg+3>=db->aLimit[SQLITE_LIMIT_COLUMN] ){ + if( pTable->u.vtab.nArg+3>=db->aLimit[SQLITE_LIMIT_COLUMN] ){ sqlite3ErrorMsg(pParse, "too many columns on %s", pTable->zName); } - azModuleArg = sqlite3DbRealloc(db, pTable->azModuleArg, nBytes); + azModuleArg = sqlite3DbRealloc(db, pTable->u.vtab.azArg, nBytes); if( azModuleArg==0 ){ sqlite3DbFree(db, zArg); }else{ - int i = pTable->nModuleArg++; + int i = pTable->u.vtab.nArg++; azModuleArg[i] = zArg; azModuleArg[i+1] = 0; - pTable->azModuleArg = azModuleArg; + pTable->u.vtab.azArg = azModuleArg; } } @@ -388,10 +388,11 @@ void sqlite3VtabBeginParse( pTable = pParse->pNewTable; if( pTable==0 ) return; assert( 0==pTable->pIndex ); + pTable->eTabType = TABTYP_VTAB; db = pParse->db; - assert( pTable->nModuleArg==0 ); + assert( pTable->u.vtab.nArg==0 ); addModuleArgument(pParse, pTable, sqlite3NameFromToken(db, pModuleName)); addModuleArgument(pParse, pTable, 0); addModuleArgument(pParse, pTable, sqlite3DbStrDup(db, pTable->zName)); @@ -408,11 +409,11 @@ void sqlite3VtabBeginParse( ** sqlite_schema table, has already been made by sqlite3StartTable(). ** The second call, to obtain permission to create the table, is made now. */ - if( pTable->azModuleArg ){ + if( pTable->u.vtab.azArg ){ int iDb = sqlite3SchemaToIndex(db, pTable->pSchema); assert( iDb>=0 ); /* The database the table is being created in */ sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName, - pTable->azModuleArg[0], pParse->db->aDb[iDb].zDbSName); + pTable->u.vtab.azArg[0], pParse->db->aDb[iDb].zDbSName); } #endif } @@ -442,7 +443,7 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ if( pTab==0 ) return; addArgumentToVtab(pParse); pParse->sArg.z = 0; - if( pTab->nModuleArg<1 ) return; + if( pTab->u.vtab.nArg<1 ) return; /* If the CREATE VIRTUAL TABLE statement is being entered for the ** first time (in other words if the virtual table is actually being @@ -557,8 +558,8 @@ static int vtabCallConstructor( VtabCtx sCtx; VTable *pVTable; int rc; - const char *const*azArg = (const char *const*)pTab->azModuleArg; - int nArg = pTab->nModuleArg; + const char *const*azArg = (const char *const*)pTab->u.vtab.azArg; + int nArg = pTab->u.vtab.nArg; char *zErr = 0; char *zModuleName; int iDb; @@ -590,7 +591,7 @@ static int vtabCallConstructor( pVTable->eVtabRisk = SQLITE_VTABRISK_Normal; iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - pTab->azModuleArg[1] = db->aDb[iDb].zDbSName; + pTab->u.vtab.azArg[1] = db->aDb[iDb].zDbSName; /* Invoke the virtual table constructor */ assert( &db->pVtabCtx ); @@ -629,12 +630,12 @@ static int vtabCallConstructor( int iCol; u16 oooHidden = 0; /* If everything went according to plan, link the new VTable structure - ** into the linked list headed by pTab->pVTable. Then loop through the + ** into the linked list headed by pTab->u.vtab.p. Then loop through the ** columns of the table to see if any of them contain the token "hidden". ** If so, set the Column COLFLAG_HIDDEN flag and remove the token from ** the type string. */ - pVTable->pNext = pTab->pVTable; - pTab->pVTable = pVTable; + pVTable->pNext = pTab->u.vtab.p; + pTab->u.vtab.p = pVTable; for(iCol=0; iColnCol; iCol++){ char *zType = sqlite3ColumnType(&pTab->aCol[iCol], ""); @@ -692,11 +693,11 @@ int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){ } /* Locate the required virtual table module */ - zMod = pTab->azModuleArg[0]; + zMod = pTab->u.vtab.azArg[0]; pMod = (Module*)sqlite3HashFind(&db->aModule, zMod); if( !pMod ){ - const char *zModule = pTab->azModuleArg[0]; + const char *zModule = pTab->u.vtab.azArg[0]; sqlite3ErrorMsg(pParse, "no such module: %s", zModule); rc = SQLITE_ERROR; }else{ @@ -759,10 +760,10 @@ int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){ const char *zMod; pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName); - assert( pTab && IsVirtual(pTab) && !pTab->pVTable ); + assert( pTab && IsVirtual(pTab) && !pTab->u.vtab.p ); /* Locate the required virtual table module */ - zMod = pTab->azModuleArg[0]; + zMod = pTab->u.vtab.azArg[0]; pMod = (Module*)sqlite3HashFind(&db->aModule, zMod); /* If the module has been registered and includes a Create method, @@ -822,19 +823,17 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable, &zErr) && sParse.pNewTable && !db->mallocFailed - && !sParse.pNewTable->pSelect - && !IsVirtual(sParse.pNewTable) + && IsOrdinaryTable(sParse.pNewTable) ){ if( !pTab->aCol ){ Table *pNew = sParse.pNewTable; Index *pIdx; pTab->aCol = pNew->aCol; - pTab->pDfltList = pNew->pDfltList; + sqlite3ExprListDelete(db, pNew->u.tab.pDfltList); pTab->nNVCol = pTab->nCol = pNew->nCol; pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid); pNew->nCol = 0; pNew->aCol = 0; - pNew->pDfltList = 0; assert( pTab->pIndex==0 ); assert( HasRowid(pNew) || sqlite3PrimaryKeyIndex(pNew)!=0 ); if( !HasRowid(pNew) @@ -885,10 +884,10 @@ int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){ Table *pTab; pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName); - if( pTab!=0 && ALWAYS(pTab->pVTable!=0) ){ + if( pTab!=0 && ALWAYS(pTab->u.vtab.p!=0) ){ VTable *p; int (*xDestroy)(sqlite3_vtab *); - for(p=pTab->pVTable; p; p=p->pNext){ + for(p=pTab->u.vtab.p; p; p=p->pNext){ assert( p->pVtab ); if( p->pVtab->nRef>0 ){ return SQLITE_LOCKED; @@ -902,9 +901,9 @@ int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){ rc = xDestroy(p->pVtab); /* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */ if( rc==SQLITE_OK ){ - assert( pTab->pVTable==p && p->pNext==0 ); + assert( pTab->u.vtab.p==p && p->pNext==0 ); p->pVtab = 0; - pTab->pVTable = 0; + pTab->u.vtab.p = 0; sqlite3VtabUnlock(p); } sqlite3DeleteTable(db, pTab); @@ -1221,8 +1220,9 @@ int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){ } pMod->pEpoTab = pTab; pTab->nTabRef = 1; + pTab->eTabType = TABTYP_VTAB; pTab->pSchema = db->aDb[0].pSchema; - assert( pTab->nModuleArg==0 ); + assert( pTab->u.vtab.nArg==0 ); pTab->iPKey = -1; pTab->tabFlags |= TF_Eponymous; addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName)); diff --git a/src/where.c b/src/where.c index 4ea04e5c8e..d7ef319b57 100644 --- a/src/where.c +++ b/src/where.c @@ -3060,7 +3060,7 @@ static int whereLoopAddBtree( ** those objects, since there is no opportunity to add schema ** indexes on subqueries and views. */ pNew->rSetup = rLogSize + rSize; - if( pTab->pSelect==0 && (pTab->tabFlags & TF_Ephemeral)==0 ){ + if( !IsView(pTab) && (pTab->tabFlags & TF_Ephemeral)==0 ){ pNew->rSetup += 28; }else{ pNew->rSetup -= 10; @@ -5211,7 +5211,7 @@ WhereInfo *sqlite3WhereBegin( pTab = pTabItem->pTab; iDb = sqlite3SchemaToIndex(db, pTab->pSchema); pLoop = pLevel->pWLoop; - if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ){ + if( (pTab->tabFlags & TF_Ephemeral)!=0 || IsView(pTab) ){ /* Do nothing */ }else #ifndef SQLITE_OMIT_VIRTUALTABLE @@ -5580,7 +5580,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ ** created for the ONEPASS optimization. */ if( (pTab->tabFlags & TF_Ephemeral)==0 - && pTab->pSelect==0 + && !IsView(pTab) && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){ int ws = pLoop->wsFlags; From cf9d36d1b3a84fb68d2e13acb790c449bff51c15 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 2 Aug 2021 18:03:43 +0000 Subject: [PATCH 49/49] Refactor field names in the Column object, zCnName and zCnColl, to make them unique and thus easier to find amid all the other code. FossilOrigin-Name: 8b781dcaf68e0cf12a844708c82eee00193e340195cbca915d077e4846983bf3 --- manifest | 48 ++++++++++++++++++++++++------------------------ manifest.uuid | 2 +- src/alter.c | 16 ++++++++-------- src/analyze.c | 2 +- src/auth.c | 4 ++-- src/build.c | 42 +++++++++++++++++++++--------------------- src/expr.c | 12 +++++++----- src/fkey.c | 22 ++++++++++++---------- src/insert.c | 14 +++++++------- src/main.c | 4 ++-- src/pragma.c | 8 ++++---- src/resolve.c | 8 ++++++-- src/select.c | 28 ++++++++++++++-------------- src/sqliteInt.h | 4 ++-- src/trigger.c | 4 ++-- src/update.c | 11 +++++++---- src/upsert.c | 2 +- src/util.c | 2 +- src/vdbeblob.c | 2 +- src/where.c | 2 +- src/wherecode.c | 6 +++--- 21 files changed, 127 insertions(+), 116 deletions(-) diff --git a/manifest b/manifest index 1a7d194773..837fef528d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Refactor\sthe\sTable\sobject\sto\sreduce\sits\smemory\sfootprint. -D 2021-08-02T16:41:57.123 +C Refactor\sfield\snames\sin\sthe\sColumn\sobject,\szCnName\sand\szCnColl,\sto\smake\sthem\nunique\sand\sthus\seasier\sto\sfind\samid\sall\sthe\sother\scode. +D 2021-08-02T18:03:43.555 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -478,17 +478,17 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c e73e2dad9338274b53c04ba5fdcb8653fef898e4709b65d7f6f3197573e4d992 -F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c +F src/alter.c 3ce23a6f06a789de05e0bfd581f9dd6367a50135def2688cfd0af78675cae676 +F src/analyze.c abbaaf7dca79d1c31c713500324fc0b55bf3eeac5b7b07001452a3d0f210de4f F src/attach.c a514e81758ba7b3a3a0501faf70af6cfc509de8810235db726cfc9f25165e929 -F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 +F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c e204a9c8fb4fe5dbb910a863ba487f4af9b5c501254ec4ccbfcdd6b1f65b7fb4 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0 -F src/build.c d13fc40575b08422ddb44286537b0d3d80b03f063e0c3b6577d4bf84258f1f5e +F src/build.c 8b1f2a80155a1e140030848fdc951ceb31c055212768d992d62d3bca1c588942 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 8159d5f706551861c18ec6c8f6bdf105e15ea00367f05d9ab65d31a1077facc1 @@ -496,19 +496,19 @@ F src/date.c e0632f335952b32401482d099321bbf12716b29d6e72836b53ae49683ebae4bf F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c F src/delete.c b43f0f4db586acf0b4078e3982485c26fbec984674df513d5ade48a08a323c5a -F src/expr.c 4e2878324f6be88a766f4e83bc3132106a9913f2bd029a4b92447626501996ce +F src/expr.c 0d541b9f9ecddf9d6d310f31922006f03509d7264ef53ac39c391b82a62383f9 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 -F src/fkey.c bcd5006ce061ef7b331154d176a0869440b1049c67c14c92f0233a14a701f2cc +F src/fkey.c 7713a4e87755afbe85d1cb3e3e36b6a9989dc24a210a4e99bf2af9a9ae2851c2 F src/func.c c224240cbc97fa5e9c4fe9acb128716cb835ca045532bca6951b7c45b020c56c F src/global.c 5eba017ebbd887e2365e6e6e815e1619e41406b8946d17594e94116174787df5 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 167b286e3e289dbd1dad8f5a90858e9a6221bd83902985adf110e9db9fc2db67 +F src/insert.c c6419bc4b447f3d4cdb7b1167690baaea3b796a80cea48e7cf26da65487d430d F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 0aa9e7f08e168e3874cb54984408e3976dafdf5616d511952c425b5ac088ea3e -F src/main.c 6921ce667627d0d38e67f8508d5903e074134386427688e6b4588bfe57ce06a4 +F src/main.c 2c17a667133d2d1666319cfef975a48aa640a3de0c57d68b362372a12ad5557b F src/malloc.c cbc93cdd429c4594912017d92ab656e2579aca64dbd1c6888551275bed46f25b F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -537,19 +537,19 @@ F src/parse.y 0ba0baec5de6921ec8ba8bbcf1018969144ef29d26112e17539d8fbb1662e3eb F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 388304fd2d91c39591080b5e0f3c62cfba87db20370e7e0554062bfb29740e9f -F src/pragma.c 4a510b24e5b2321fd6bb509cd0dc8003514cb574b872dd535f49870b84ee54b1 +F src/pragma.c af0f43789545622fd5377d71f6d4c0e7c9b9295a3f5d5b1242e4032d38ca12b5 F src/pragma.h a11b4798f9c49f156f130e1f7041a9fcc9d316a64f3501b6013acdd2e4c6f549 F src/prepare.c 0d53d20532aada295c1690792a125adbd6435f5ce703ff0adf1b9b3605238b67 F src/printf.c 78fabb49b9ac9a12dd1c89d744abdc9b67fd3205e62967e158f78b965a29ec4b F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c -F src/resolve.c 047a822844cea769f6fdd8418a335dd4bcd8b75ab5e264f2506a0804f869b562 +F src/resolve.c 42b94d37a54200707a95566eff4f7e8a380e32d080016b699f23bd79a73a5028 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 2b25a79706c8a71e40f5fbc8705073c54f6a3d25f556dac9d6d91676026a0413 +F src/select.c 52041124629704feb24b1bc7dabf8ec03a0857c69d23f2dd0c33c9ed3d074adb F src/shell.c.in 24b99dae8818d1a234732d73f4d5b49f12b510bc62735a41c04e314fafae09e3 F src/sqlite.h.in 43fcf0fe2af04081f420a906fc020bde1243851ba44b0aa567a27f94bf8c3145 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510 -F src/sqliteInt.h 8601c620280dcb514e6e9dfb1fa7ee005ccc56c244ac82cb48a1045ed2e7003c +F src/sqliteInt.h 6f02ceb8d6b8784faf7218bd58b59580837c9e95e54a5b34d48ae93504ba67ce F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -610,18 +610,18 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c bae853ad129d1129c063de8630a3e99e306283bc40146f359b1bb91be2c08f1e F src/treeview.c 43f88d0fd19976a60aee6867959213b438593276f1e8179048df85f416a1ab19 -F src/trigger.c 43d76cf913e65a5d06ed0768d8ded7259a5d6e284641a18acb355a302792cd05 -F src/update.c 985a8a45b4ff86a0231fedd584e2bd87fd6fac5168286935195ad006d032d555 -F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 +F src/trigger.c 3f612ce5f0858b6c23460a3c799d01f408b49b0b29d931d8b8e6fc224a8667de +F src/update.c 69c4c10bc6873a80c0a77cb578f9fc60ee90003d03f9530bc3370fa24615772d +F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 -F src/util.c 6ca9cf268dfaf2393866990788c0797240e20e7ba7e3a22cd076e6a3c7b1a132 +F src/util.c b18a971c8936e9299fecc00474269a11135989d6fe9bd91b1e52137d6f27bd8c F src/vacuum.c 454973a59fb20bb982efc2df568a098616db6328a0491b6e84e2e07f7333db45 F src/vdbe.c b73a5ec9940185eb001ff8cff2cfd429bb438c7e89f2885e0bfdb56c3ff13386 F src/vdbe.h 25dabb25c7e157b84e59260cfb5b466c3ac103ede9f36f4db371332c47601abe F src/vdbeInt.h 38206c8dd6b60ff03d9fd4f626b1b4fd0eef7cdc44f2fc2c1973b0f932a3f26b F src/vdbeapi.c aa5aaf2c37676b83af5724c6cd8207a3064ed46a217fd180957f75ac84f7a2a5 F src/vdbeaux.c 202dbaf7d1570cd53678f6b0bcad7b0642e88bc5d77abc1d5b8b9a202a6a19fd -F src/vdbeblob.c 2f3c2ada0429045c54e5ebd48f45281c52addf4648e0d234a2718dbdeab01c80 +F src/vdbeblob.c 60a7694760e35b2bba166cf49eb6a1eb0b31581102b49de78008ca3032406065 F src/vdbemem.c 53881aa0a7845922a075b3f375695588618098871a7a4120af4c297b80fa3e64 F src/vdbesort.c cd5130f683706c1a43e165a74187745fb3351cb56052cf9dc91de820634bbde2 F src/vdbetrace.c 666c6fd9f1b62be6999e072a45b913e3c2c3518bc60dfd4d54fe304130acb724 @@ -631,9 +631,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 2be08331d798237ad5d7ae0b252700ffb2b63189cb18d993496d009a93e2f81c F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c 7342becedf3f8a26f9817f08436bdf8b56ad69af83705f6b9320a0ad3092c2ac -F src/where.c 6e27c9f9438ddbb8aebbb83d24574a75398942b5e73b3f8cc572a39dc00f7482 +F src/where.c 99b6e13664a7bd9a553c554978d0e253066995dade621f44cffa8928c8b493b5 F src/whereInt.h 9248161dd004f625ce5d3841ca9b99fed3fc8d61522cf76340fc5217dbe1375b -F src/wherecode.c 9f1f65d11437b25cd0a1497a170514c785f19ce6ad9d3e6fc73719cb5a49012f +F src/wherecode.c ef36790a797fa679f58dbd51930e3ee7ef7cb6c906ae412032e4d319a36a2eef F src/whereexpr.c 3a9144a9d52e110efdc012a73b1574e7b2b4df4bf98949387cb620295eba0975 F src/window.c 420167512050a0dfc0f0115b9f0c7d299da9759c9bb2ae83a61fb8d730a5707f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8646547e54211d44c415663c33775c4268550f8332949c4731a4bb6ec9cc663a -R 8143bc84e57e339634d6338dda56d190 +P bbb6759bcf6e01d36dfc787a82a610d359f50aaeac8104b73883a84906d54e1f +R 7046be8b76bab8142bfe76e50eb88e2a U drh -Z 0d31e4d81e774d8d4cc71b3c0a3d1311 +Z 5e85f685bd644cac3700fa74d443a453 diff --git a/manifest.uuid b/manifest.uuid index aecc9c1e1c..2028f8b686 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bbb6759bcf6e01d36dfc787a82a610d359f50aaeac8104b73883a84906d54e1f \ No newline at end of file +8b781dcaf68e0cf12a844708c82eee00193e340195cbca915d077e4846983bf3 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 75220a1de3..0ca68c04f5 100644 --- a/src/alter.c +++ b/src/alter.c @@ -537,9 +537,9 @@ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol); for(i=0; inCol; i++){ Column *pCol = &pNew->aCol[i]; - pCol->zName = sqlite3DbStrDup(db, pCol->zName); - pCol->hName = sqlite3StrIHash(pCol->zName); - pCol->zColl = 0; + pCol->zCnName = sqlite3DbStrDup(db, pCol->zCnName); + pCol->hName = sqlite3StrIHash(pCol->zCnName); + pCol->zCnColl = 0; } assert( !IsVirtual(pNew) ); pNew->u.tab.pDfltList = sqlite3ExprListDup(db, pTab->u.tab.pDfltList, 0); @@ -631,7 +631,7 @@ void sqlite3AlterRenameColumn( zOld = sqlite3NameFromToken(db, pOld); if( !zOld ) goto exit_rename_column; for(iCol=0; iColnCol; iCol++){ - if( 0==sqlite3StrICmp(pTab->aCol[iCol].zName, zOld) ) break; + if( 0==sqlite3StrICmp(pTab->aCol[iCol].zCnName, zOld) ) break; } if( iCol==pTab->nCol ){ sqlite3ErrorMsg(pParse, "no such column: \"%s\"", zOld); @@ -1477,7 +1477,7 @@ static void renameColumnFunc( sqlite3BtreeLeaveAll(db); return; } - zOld = pTab->aCol[iCol].zName; + zOld = pTab->aCol[iCol].zCnName; memset(&sCtx, 0, sizeof(sCtx)); sCtx.iCol = ((iCol==pTab->iPKey) ? -1 : iCol); @@ -1514,7 +1514,7 @@ static void renameColumnFunc( if( bFKOnly==0 ){ if( iColnCol ){ renameTokenFind( - &sParse, &sCtx, (void*)sParse.pNewTable->aCol[iCol].zName + &sParse, &sCtx, (void*)sParse.pNewTable->aCol[iCol].zCnName ); } if( sCtx.iCol<0 ){ @@ -2041,10 +2041,10 @@ static void dropColumnFunc( goto drop_column_done; } - pCol = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol].zName); + pCol = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol].zCnName); if( iColnCol-1 ){ RenameToken *pEnd; - pEnd = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol+1].zName); + pEnd = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol+1].zCnName); zEnd = (const char*)pEnd->t.z; }else{ assert( !IsVirtual(pTab) ); diff --git a/src/analyze.c b/src/analyze.c index dc77220a53..41b993fb3f 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -968,7 +968,7 @@ static void analyzeVdbeCommentIndexWithColumnName( }else if( i==XN_EXPR ){ VdbeComment((v,"%s.expr(%d)",pIdx->zName, k)); }else{ - VdbeComment((v,"%s.%s", pIdx->zName, pIdx->pTable->aCol[i].zName)); + VdbeComment((v,"%s.%s", pIdx->zName, pIdx->pTable->aCol[i].zCnName)); } } #else diff --git a/src/auth.c b/src/auth.c index 33420f5839..3a4f73a234 100644 --- a/src/auth.c +++ b/src/auth.c @@ -175,10 +175,10 @@ void sqlite3AuthRead( if( iCol>=0 ){ assert( iColnCol ); - zCol = pTab->aCol[iCol].zName; + zCol = pTab->aCol[iCol].zCnName; }else if( pTab->iPKey>=0 ){ assert( pTab->iPKeynCol ); - zCol = pTab->aCol[pTab->iPKey].zName; + zCol = pTab->aCol[pTab->iPKey].zCnName; }else{ zCol = "ROWID"; } diff --git a/src/build.c b/src/build.c index 09222acf81..10a15189b0 100644 --- a/src/build.c +++ b/src/build.c @@ -716,9 +716,9 @@ void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){ assert( pTable!=0 ); if( (pCol = pTable->aCol)!=0 ){ for(i=0; inCol; i++, pCol++){ - assert( pCol->zName==0 || pCol->hName==sqlite3StrIHash(pCol->zName) ); - sqlite3DbFree(db, pCol->zName); - sqlite3DbFree(db, pCol->zColl); + assert( pCol->zCnName==0 || pCol->hName==sqlite3StrIHash(pCol->zCnName) ); + sqlite3DbFree(db, pCol->zCnName); + sqlite3DbFree(db, pCol->zCnColl); } sqlite3DbFree(db, pTable->aCol); if( !IsVirtual(pTable) ){ @@ -1336,7 +1336,7 @@ begin_table_error: */ #if SQLITE_ENABLE_HIDDEN_COLUMNS void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){ - if( sqlite3_strnicmp(pCol->zName, "__hidden__", 10)==0 ){ + if( sqlite3_strnicmp(pCol->zCnName, "__hidden__", 10)==0 ){ pCol->colFlags |= COLFLAG_HIDDEN; if( pTab ) pTab->tabFlags |= TF_HasHidden; }else if( pTab && pCol!=pTab->aCol && (pCol[-1].colFlags & COLFLAG_HIDDEN) ){ @@ -1490,7 +1490,7 @@ void sqlite3AddColumn(Parse *pParse, Token sName, Token sType){ sqlite3Dequote(z); hName = sqlite3StrIHash(z); for(i=0; inCol; i++){ - if( p->aCol[i].hName==hName && sqlite3StrICmp(z, p->aCol[i].zName)==0 ){ + if( p->aCol[i].hName==hName && sqlite3StrICmp(z, p->aCol[i].zCnName)==0 ){ sqlite3ErrorMsg(pParse, "duplicate column name: %s", z); sqlite3DbFree(db, z); return; @@ -1504,7 +1504,7 @@ void sqlite3AddColumn(Parse *pParse, Token sName, Token sType){ p->aCol = aNew; pCol = &p->aCol[p->nCol]; memset(pCol, 0, sizeof(p->aCol[0])); - pCol->zName = z; + pCol->zCnName = z; pCol->hName = hName; sqlite3ColumnPropertiesFromName(p, pCol); @@ -1679,7 +1679,7 @@ void sqlite3AddDefaultValue( pCol = &(p->aCol[p->nCol-1]); if( !sqlite3ExprIsConstantOrFunction(pExpr, isInit) ){ sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant", - pCol->zName); + pCol->zCnName); #ifndef SQLITE_OMIT_GENERATED_COLUMNS }else if( pCol->colFlags & COLFLAG_GENERATED ){ testcase( pCol->colFlags & COLFLAG_VIRTUAL ); @@ -1796,7 +1796,7 @@ void sqlite3AddPrimaryKey( if( pCExpr->op==TK_ID ){ const char *zCName = pCExpr->u.zToken; for(iCol=0; iColnCol; iCol++){ - if( sqlite3StrICmp(zCName, pTab->aCol[iCol].zName)==0 ){ + if( sqlite3StrICmp(zCName, pTab->aCol[iCol].zCnName)==0 ){ pCol = &pTab->aCol[iCol]; makeColumnPartOfPrimaryKey(pParse, pCol); break; @@ -1887,8 +1887,8 @@ void sqlite3AddCollateType(Parse *pParse, Token *pToken){ if( sqlite3LocateCollSeq(pParse, zColl) ){ Index *pIdx; - sqlite3DbFree(db, p->aCol[i].zColl); - p->aCol[i].zColl = zColl; + sqlite3DbFree(db, p->aCol[i].zCnColl); + p->aCol[i].zCnColl = zColl; /* If the column is declared as " PRIMARY KEY COLLATE ", ** then an index may have been created on this column before the @@ -1897,7 +1897,7 @@ void sqlite3AddCollateType(Parse *pParse, Token *pToken){ for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){ assert( pIdx->nKeyCol==1 ); if( pIdx->aiColumn[0]==i ){ - pIdx->azColl[0] = p->aCol[i].zColl; + pIdx->azColl[0] = p->aCol[i].zCnColl; } } }else{ @@ -1946,7 +1946,7 @@ void sqlite3AddGenerated(Parse *pParse, Expr *pExpr, Token *pType){ generated_error: sqlite3ErrorMsg(pParse, "error in generated column \"%s\"", - pCol->zName); + pCol->zCnName); generated_done: sqlite3ExprDelete(pParse->db, pExpr); #else @@ -2048,7 +2048,7 @@ static char *createTableStmt(sqlite3 *db, Table *p){ Column *pCol; n = 0; for(pCol = p->aCol, i=0; inCol; i++, pCol++){ - n += identLength(pCol->zName) + 5; + n += identLength(pCol->zCnName) + 5; } n += identLength(p->zName); if( n<50 ){ @@ -2084,7 +2084,7 @@ static char *createTableStmt(sqlite3 *db, Table *p){ sqlite3_snprintf(n-k, &zStmt[k], zSep); k += sqlite3Strlen30(&zStmt[k]); zSep = zSep2; - identPut(zStmt, &k, pCol->zName); + identPut(zStmt, &k, pCol->zCnName); assert( pCol->affinity-SQLITE_AFF_BLOB >= 0 ); assert( pCol->affinity-SQLITE_AFF_BLOB < ArraySize(azType) ); testcase( pCol->affinity==SQLITE_AFF_BLOB ); @@ -2303,7 +2303,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ if( pTab->iPKey>=0 ){ ExprList *pList; Token ipkToken; - sqlite3TokenInit(&ipkToken, pTab->aCol[pTab->iPKey].zName); + sqlite3TokenInit(&ipkToken, pTab->aCol[pTab->iPKey].zCnName); pList = sqlite3ExprListAppend(pParse, 0, sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0)); if( pList==0 ){ @@ -3446,7 +3446,7 @@ void sqlite3CreateForeignKey( if( pToCol && pToCol->nExpr!=1 ){ sqlite3ErrorMsg(pParse, "foreign key on %s" " should reference only one column of table %T", - p->aCol[iCol].zName, pTo); + p->aCol[iCol].zCnName, pTo); goto fk_end; } nCol = 1; @@ -3486,7 +3486,7 @@ void sqlite3CreateForeignKey( for(i=0; inCol; j++){ - if( sqlite3StrICmp(p->aCol[j].zName, pFromCol->a[i].zEName)==0 ){ + if( sqlite3StrICmp(p->aCol[j].zCnName, pFromCol->a[i].zEName)==0 ){ pFKey->aCol[i].iFrom = j; break; } @@ -3941,7 +3941,7 @@ void sqlite3CreateIndex( Token prevCol; Column *pCol = &pTab->aCol[pTab->nCol-1]; pCol->colFlags |= COLFLAG_UNIQUE; - sqlite3TokenInit(&prevCol, pCol->zName); + sqlite3TokenInit(&prevCol, pCol->zCnName); pList = sqlite3ExprListAppend(pParse, 0, sqlite3ExprAlloc(db, TK_ID, &prevCol, 0)); if( pList==0 ) goto exit_create_index; @@ -4062,7 +4062,7 @@ void sqlite3CreateIndex( zExtra += nColl; nExtra -= nColl; }else if( j>=0 ){ - zColl = pTab->aCol[j].zColl; + zColl = pTab->aCol[j].zCnColl; } if( !zColl ) zColl = sqlite3StrBINARY; if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){ @@ -5154,7 +5154,7 @@ void sqlite3UniqueConstraint( for(j=0; jnKeyCol; j++){ char *zCol; assert( pIdx->aiColumn[j]>=0 ); - zCol = pTab->aCol[pIdx->aiColumn[j]].zName; + zCol = pTab->aCol[pIdx->aiColumn[j]].zCnName; if( j ) sqlite3_str_append(&errMsg, ", ", 2); sqlite3_str_appendall(&errMsg, pTab->zName); sqlite3_str_append(&errMsg, ".", 1); @@ -5181,7 +5181,7 @@ void sqlite3RowidConstraint( int rc; if( pTab->iPKey>=0 ){ zMsg = sqlite3MPrintf(pParse->db, "%s.%s", pTab->zName, - pTab->aCol[pTab->iPKey].zName); + pTab->aCol[pTab->iPKey].zCnName); rc = SQLITE_CONSTRAINT_PRIMARYKEY; }else{ zMsg = sqlite3MPrintf(pParse->db, "%s.rowid", pTab->zName); diff --git a/src/expr.c b/src/expr.c index ca0c00a14d..0f900c0c6c 100644 --- a/src/expr.c +++ b/src/expr.c @@ -173,7 +173,7 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr){ ** a TK_COLUMN but was previously evaluated and cached in a register */ int j = p->iColumn; if( j>=0 ){ - const char *zColl = p->y.pTab->aCol[j].zColl; + const char *zColl = p->y.pTab->aCol[j].zCnColl; pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0); } break; @@ -3693,7 +3693,8 @@ void sqlite3ExprCodeGetColumnOfTable( }else if( (pCol = &pTab->aCol[iCol])->colFlags & COLFLAG_VIRTUAL ){ Parse *pParse = sqlite3VdbeParser(v); if( pCol->colFlags & COLFLAG_BUSY ){ - sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", pCol->zName); + sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", + pCol->zCnName); }else{ int savedSelfTab = pParse->iSelfTab; pCol->colFlags |= COLFLAG_BUSY; @@ -3966,7 +3967,8 @@ expr_code_doover: if( pCol->iColumn<0 ){ VdbeComment((v,"%s.rowid",pTab->zName)); }else{ - VdbeComment((v,"%s.%s",pTab->zName,pTab->aCol[pCol->iColumn].zName)); + VdbeComment((v,"%s.%s", + pTab->zName, pTab->aCol[pCol->iColumn].zCnName)); if( pTab->aCol[pCol->iColumn].affinity==SQLITE_AFF_REAL ){ sqlite3VdbeAddOp1(v, OP_RealAffinity, target); } @@ -4027,7 +4029,7 @@ expr_code_doover: if( pCol->colFlags & COLFLAG_GENERATED ){ if( pCol->colFlags & COLFLAG_BUSY ){ sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", - pCol->zName); + pCol->zCnName); return 0; } pCol->colFlags |= COLFLAG_BUSY; @@ -4510,7 +4512,7 @@ expr_code_doover: sqlite3VdbeAddOp2(v, OP_Param, p1, target); VdbeComment((v, "r[%d]=%s.%s", target, (pExpr->iTable ? "new" : "old"), - (pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[iCol].zName) + (pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[iCol].zCnName) )); #ifndef SQLITE_OMIT_FLOATING_POINT diff --git a/src/fkey.c b/src/fkey.c index ffb3a732eb..ee5aa5d98f 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -215,7 +215,9 @@ int sqlite3FkLocateIndex( */ if( pParent->iPKey>=0 ){ if( !zKey ) return 0; - if( !sqlite3StrICmp(pParent->aCol[pParent->iPKey].zName, zKey) ) return 0; + if( !sqlite3StrICmp(pParent->aCol[pParent->iPKey].zCnName, zKey) ){ + return 0; + } } }else if( paiCol ){ assert( nCol>1 ); @@ -257,11 +259,11 @@ int sqlite3FkLocateIndex( /* If the index uses a collation sequence that is different from ** the default collation sequence for the column, this index is ** unusable. Bail out early in this case. */ - zDfltColl = pParent->aCol[iCol].zColl; + zDfltColl = pParent->aCol[iCol].zCnColl; if( !zDfltColl ) zDfltColl = sqlite3StrBINARY; if( sqlite3StrICmp(pIdx->azColl[i], zDfltColl) ) break; - zIdxCol = pParent->aCol[iCol].zName; + zIdxCol = pParent->aCol[iCol].zCnName; for(j=0; jaCol[j].zCol, zIdxCol)==0 ){ if( aiCol ) aiCol[i] = pFKey->aCol[j].iFrom; @@ -485,7 +487,7 @@ static Expr *exprTableRegister( pCol = &pTab->aCol[iCol]; pExpr->iTable = regBase + sqlite3TableColumnToStorage(pTab,iCol) + 1; pExpr->affExpr = pCol->affinity; - zColl = pCol->zColl; + zColl = pCol->zCnColl; if( zColl==0 ) zColl = db->pDfltColl->zName; pExpr = sqlite3ExprAddCollateString(pParse, pExpr, zColl); }else{ @@ -594,7 +596,7 @@ static void fkScanChildren( pLeft = exprTableRegister(pParse, pTab, regData, iCol); iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom; assert( iCol>=0 ); - zCol = pFKey->pFrom->aCol[iCol].zName; + zCol = pFKey->pFrom->aCol[iCol].zCnName; pRight = sqlite3Expr(db, TK_ID, zCol); pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight); pWhere = sqlite3ExprAnd(pParse, pWhere, pEq); @@ -629,7 +631,7 @@ static void fkScanChildren( i16 iCol = pIdx->aiColumn[i]; assert( iCol>=0 ); pLeft = exprTableRegister(pParse, pTab, regData, iCol); - pRight = sqlite3Expr(db, TK_ID, pTab->aCol[iCol].zName); + pRight = sqlite3Expr(db, TK_ID, pTab->aCol[iCol].zCnName); pEq = sqlite3PExpr(pParse, TK_IS, pLeft, pRight); pAll = sqlite3ExprAnd(pParse, pAll, pEq); } @@ -821,7 +823,7 @@ static int fkParentIsModified( if( aChange[iKey]>=0 || (iKey==pTab->iPKey && bChngRowid) ){ Column *pCol = &pTab->aCol[iKey]; if( zKey ){ - if( 0==sqlite3StrICmp(pCol->zName, zKey) ) return 1; + if( 0==sqlite3StrICmp(pCol->zCnName, zKey) ) return 1; }else if( pCol->colFlags & COLFLAG_PRIMKEY ){ return 1; } @@ -962,7 +964,7 @@ void sqlite3FkCheck( ** values read from the parent table are NULL. */ if( db->xAuth ){ int rcauth; - char *zCol = pTo->aCol[pIdx ? pIdx->aiColumn[i] : pTo->iPKey].zName; + char *zCol = pTo->aCol[pIdx ? pIdx->aiColumn[i] : pTo->iPKey].zCnName; rcauth = sqlite3AuthReadCol(pParse, pTo->zName, zCol, iDb); bIgnore = (rcauth==SQLITE_IGNORE); } @@ -1236,8 +1238,8 @@ static Trigger *fkActionTrigger( assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKeynCol) ); assert( pIdx==0 || pIdx->aiColumn[i]>=0 ); sqlite3TokenInit(&tToCol, - pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName); - sqlite3TokenInit(&tFromCol, pFKey->pFrom->aCol[iFromCol].zName); + pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zCnName); + sqlite3TokenInit(&tFromCol, pFKey->pFrom->aCol[iFromCol].zCnName); /* Create the expression "OLD.zToCol = zFromCol". It is important ** that the "OLD.zToCol" term is on the LHS of the = operator, so diff --git a/src/insert.c b/src/insert.c index bff75a0a69..06952586b0 100644 --- a/src/insert.c +++ b/src/insert.c @@ -308,7 +308,7 @@ void sqlite3ComputeGeneratedColumns( } }while( pRedo && eProgress ); if( pRedo ){ - sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", pRedo->zName); + sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", pRedo->zCnName); } pParse->iSelfTab = 0; } @@ -794,7 +794,7 @@ void sqlite3Insert( } for(i=0; inId; i++){ for(j=0; jnCol; j++){ - if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){ + if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zCnName)==0 ){ pColumn->a[i].idx = j; if( i!=j ) bIdListInOrder = 0; if( j==pTab->iPKey ){ @@ -804,7 +804,7 @@ void sqlite3Insert( if( pTab->aCol[j].colFlags & (COLFLAG_STORED|COLFLAG_VIRTUAL) ){ sqlite3ErrorMsg(pParse, "cannot INSERT into generated column \"%s\"", - pTab->aCol[j].zName); + pTab->aCol[j].zCnName); goto insert_cleanup; } #endif @@ -1708,7 +1708,7 @@ void sqlite3GenerateConstraintChecks( case OE_Rollback: case OE_Fail: { char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName, - pCol->zName); + pCol->zCnName); sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError, iReg); sqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC); @@ -2126,7 +2126,7 @@ void sqlite3GenerateConstraintChecks( testcase( sqlite3TableColumnToStorage(pTab, iField)!=iField ); x = sqlite3TableColumnToStorage(pTab, iField) + regNewData + 1; sqlite3VdbeAddOp2(v, OP_SCopy, x, regIdx+i); - VdbeComment((v, "%s", pTab->aCol[iField].zName)); + VdbeComment((v, "%s", pTab->aCol[iField].zCnName)); } } sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]); @@ -2220,7 +2220,7 @@ void sqlite3GenerateConstraintChecks( x = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[i]); sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i); VdbeComment((v, "%s.%s", pTab->zName, - pTab->aCol[pPk->aiColumn[i]].zName)); + pTab->aCol[pPk->aiColumn[i]].zCnName)); } } if( isUpdate ){ @@ -2843,7 +2843,7 @@ static int xferOptimization( if( pDestCol->affinity!=pSrcCol->affinity ){ return 0; /* Affinity must be the same on all columns */ } - if( sqlite3_stricmp(pDestCol->zColl, pSrcCol->zColl)!=0 ){ + if( sqlite3_stricmp(pDestCol->zCnColl, pSrcCol->zCnColl)!=0 ){ return 0; /* Collating sequence must be the same on all columns */ } if( pDestCol->notNull && !pSrcCol->notNull ){ diff --git a/src/main.c b/src/main.c index 2dc29593dc..3c1191c368 100644 --- a/src/main.c +++ b/src/main.c @@ -3742,7 +3742,7 @@ int sqlite3_table_column_metadata( }else{ for(iCol=0; iColnCol; iCol++){ pCol = &pTab->aCol[iCol]; - if( 0==sqlite3StrICmp(pCol->zName, zColumnName) ){ + if( 0==sqlite3StrICmp(pCol->zCnName, zColumnName) ){ break; } } @@ -3769,7 +3769,7 @@ int sqlite3_table_column_metadata( */ if( pCol ){ zDataType = sqlite3ColumnType(pCol,0); - zCollSeq = pCol->zColl; + zCollSeq = pCol->zCnColl; notnull = pCol->notNull!=0; primarykey = (pCol->colFlags & COLFLAG_PRIMKEY)!=0; autoinc = pTab->iPKey==iCol && (pTab->tabFlags & TF_Autoincrement)!=0; diff --git a/src/pragma.c b/src/pragma.c index 2606e85506..c931dd2acb 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1182,7 +1182,7 @@ void sqlite3Pragma( || isHidden>=2 ); sqlite3VdbeMultiLoad(v, 1, pPragma->iArg ? "issisii" : "issisi", i-nHidden, - pCol->zName, + pCol->zCnName, sqlite3ColumnType(pCol,""), pCol->notNull ? 1 : 0, isHidden>=2 || sqlite3ColumnExpr(pTab,pCol)==0 ? 0 : @@ -1253,7 +1253,7 @@ void sqlite3Pragma( for(i=0; iaiColumn[i]; sqlite3VdbeMultiLoad(v, 1, "iisX", i, cnum, - cnum<0 ? 0 : pTab->aCol[cnum].zName); + cnum<0 ? 0 : pTab->aCol[cnum].zCnName); if( pPragma->iArg ){ sqlite3VdbeMultiLoad(v, 4, "isiX", pIdx->aSortOrder[i], @@ -1374,7 +1374,7 @@ void sqlite3Pragma( i, j, pFK->zTo, - pTab->aCol[pFK->aCol[j].iFrom].zName, + pTab->aCol[pFK->aCol[j].iFrom].zCnName, pFK->aCol[j].zCol, actionName(pFK->aAction[1]), /* ON UPDATE */ actionName(pFK->aAction[0]), /* ON DELETE */ @@ -1687,7 +1687,7 @@ void sqlite3Pragma( } jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v); zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName, - pTab->aCol[j].zName); + pTab->aCol[j].zCnName); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); integrityCheckResultRow(v); sqlite3VdbeJumpHere(v, jmp2); diff --git a/src/resolve.c b/src/resolve.c index d509de7953..3c1311417b 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -333,7 +333,9 @@ static int lookupName( } hCol = sqlite3StrIHash(zCol); for(j=0, pCol=pTab->aCol; jnCol; j++, pCol++){ - if( pCol->hName==hCol && sqlite3StrICmp(pCol->zName, zCol)==0 ){ + if( pCol->hName==hCol + && sqlite3StrICmp(pCol->zCnName, zCol)==0 + ){ /* If there has been exactly one prior match and this match ** is for the right-hand table of a NATURAL JOIN or is in a ** USING clause, then skip this match. @@ -410,7 +412,9 @@ static int lookupName( pSchema = pTab->pSchema; cntTab++; for(iCol=0, pCol=pTab->aCol; iColnCol; iCol++, pCol++){ - if( pCol->hName==hCol && sqlite3StrICmp(pCol->zName, zCol)==0 ){ + if( pCol->hName==hCol + && sqlite3StrICmp(pCol->zCnName, zCol)==0 + ){ if( iCol==pTab->iPKey ){ iCol = -1; } diff --git a/src/select.c b/src/select.c index d6708c231f..064ea758d8 100644 --- a/src/select.c +++ b/src/select.c @@ -271,7 +271,7 @@ int sqlite3ColumnIndex(Table *pTab, const char *zCol){ u8 h = sqlite3StrIHash(zCol); Column *pCol; for(pCol=pTab->aCol, i=0; inCol; pCol++, i++){ - if( pCol->hName==h && sqlite3StrICmp(pCol->zName, zCol)==0 ) return i; + if( pCol->hName==h && sqlite3StrICmp(pCol->zCnName, zCol)==0 ) return i; } return -1; } @@ -470,7 +470,7 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ int iLeftCol; /* Matching column in the left table */ if( IsHiddenColumn(&pRightTab->aCol[j]) ) continue; - zName = pRightTab->aCol[j].zName; + zName = pRightTab->aCol[j].zCnName; if( tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, 1) ){ addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, j, isOuter, &p->pWhere); @@ -1837,7 +1837,7 @@ static const char *columnTypeImpl( zType = "INTEGER"; zOrigCol = "rowid"; }else{ - zOrigCol = pTab->aCol[iCol].zName; + zOrigCol = pTab->aCol[iCol].zCnName; zType = sqlite3ColumnType(&pTab->aCol[iCol],0); } zOrigTab = pTab->zName; @@ -2009,7 +2009,7 @@ void sqlite3GenerateColumnNames( if( iCol<0 ){ zCol = "rowid"; }else{ - zCol = pTab->aCol[iCol].zName; + zCol = pTab->aCol[iCol].zCnName; } if( fullName ){ char *zName = 0; @@ -2094,7 +2094,7 @@ int sqlite3ColumnsFromExprList( /* For columns use the column name name */ int iCol = pColExpr->iColumn; if( iCol<0 ) iCol = pTab->iPKey; - zName = iCol>=0 ? pTab->aCol[iCol].zName : "rowid"; + zName = iCol>=0 ? pTab->aCol[iCol].zCnName : "rowid"; }else if( pColExpr->op==TK_ID ){ assert( !ExprHasProperty(pColExpr, EP_IntValue) ); zName = pColExpr->u.zToken; @@ -2122,7 +2122,7 @@ int sqlite3ColumnsFromExprList( zName = sqlite3MPrintf(db, "%.*z:%u", nName, zName, ++cnt); if( cnt>3 ) sqlite3_randomness(sizeof(cnt), &cnt); } - pCol->zName = zName; + pCol->zCnName = zName; pCol->hName = sqlite3StrIHash(zName); sqlite3ColumnPropertiesFromName(0, pCol); if( zName && sqlite3HashInsert(&ht, zName, pCol)==pCol ){ @@ -2132,7 +2132,7 @@ int sqlite3ColumnsFromExprList( sqlite3HashClear(&ht); if( db->mallocFailed ){ for(j=0; jaffinity = sqlite3ExprAffinity(p); if( zType ){ m = sqlite3Strlen30(zType); - n = sqlite3Strlen30(pCol->zName); - pCol->zName = sqlite3DbReallocOrFree(db, pCol->zName, n+m+2); - if( pCol->zName ){ - memcpy(&pCol->zName[n+1], zType, m+1); + n = sqlite3Strlen30(pCol->zCnName); + pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+m+2); + if( pCol->zCnName ){ + memcpy(&pCol->zCnName[n+1], zType, m+1); pCol->colFlags |= COLFLAG_HASTYPE; } } if( pCol->affinity<=SQLITE_AFF_NONE ) pCol->affinity = aff; pColl = sqlite3ExprCollSeq(pParse, p); - if( pColl && pCol->zColl==0 ){ - pCol->zColl = sqlite3DbStrDup(db, pColl->zName); + if( pColl && pCol->zCnColl==0 ){ + pCol->zCnColl = sqlite3DbStrDup(db, pColl->zName); } } pTab->szTabRow = 1; /* Any non-zero value works */ @@ -5602,7 +5602,7 @@ static int selectExpander(Walker *pWalker, Select *p){ zSchemaName = iDb>=0 ? db->aDb[iDb].zDbSName : "*"; } for(j=0; jnCol; j++){ - char *zName = pTab->aCol[j].zName; + char *zName = pTab->aCol[j].zCnName; char *zColname; /* The computed column name */ char *zToFree; /* Malloced string that needs to be freed */ Token sColname; /* Computed column name as a token */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 9a2c49e526..083ba5a335 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2030,8 +2030,8 @@ struct Module { ** columns to the left. */ struct Column { - char *zName; /* Name of this column, \000, then the type */ - char *zColl; /* Collating sequence. If NULL, use the default */ + char *zCnName; /* Name of this column */ + char *zCnColl; /* Collating sequence. If NULL, use the default */ u8 notNull : 4; /* An OE_ code for handling a NOT NULL constraint */ u8 eType : 4; /* One of the standard types */ char affinity; /* One of the SQLITE_AFF_... values */ diff --git a/src/trigger.c b/src/trigger.c index 4db697c655..d7a4507e80 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -877,11 +877,11 @@ static ExprList *sqlite3ExpandReturning( for(jj=0; jjnCol; jj++){ Expr *pNewExpr; if( IsHiddenColumn(pTab->aCol+jj) ) continue; - pNewExpr = sqlite3Expr(db, TK_ID, pTab->aCol[jj].zName); + pNewExpr = sqlite3Expr(db, TK_ID, pTab->aCol[jj].zCnName); pNew = sqlite3ExprListAppend(pParse, pNew, pNewExpr); if( !db->mallocFailed ){ struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1]; - pItem->zEName = sqlite3DbStrDup(db, pTab->aCol[jj].zName); + pItem->zEName = sqlite3DbStrDup(db, pTab->aCol[jj].zCnName); pItem->eEName = ENAME_NAME; } } diff --git a/src/update.c b/src/update.c index 6f503c32f8..484bee47cd 100644 --- a/src/update.c +++ b/src/update.c @@ -64,7 +64,7 @@ void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ sqlite3_value *pValue = 0; u8 enc = ENC(sqlite3VdbeDb(v)); Column *pCol = &pTab->aCol[i]; - VdbeComment((v, "%s.%s", pTab->zName, pCol->zName)); + VdbeComment((v, "%s.%s", pTab->zName, pCol->zCnName)); assert( inCol ); sqlite3ValueFromExpr(sqlite3VdbeDb(v), sqlite3ColumnExpr(pTab,pCol), enc, @@ -451,13 +451,16 @@ void sqlite3Update( */ chngRowid = chngPk = 0; for(i=0; inExpr; i++){ + u8 hCol = sqlite3StrIHash(pChanges->a[i].zEName); /* If this is an UPDATE with a FROM clause, do not resolve expressions ** here. The call to sqlite3Select() below will do that. */ if( nChangeFrom==0 && sqlite3ResolveExprNames(&sNC, pChanges->a[i].pExpr) ){ goto update_cleanup; } for(j=0; jnCol; j++){ - if( sqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zEName)==0 ){ + if( pTab->aCol[j].hName==hCol + && sqlite3StrICmp(pTab->aCol[j].zCnName, pChanges->a[i].zEName)==0 + ){ if( j==pTab->iPKey ){ chngRowid = 1; pRowidExpr = pChanges->a[i].pExpr; @@ -471,7 +474,7 @@ void sqlite3Update( testcase( pTab->aCol[j].colFlags & COLFLAG_STORED ); sqlite3ErrorMsg(pParse, "cannot UPDATE generated column \"%s\"", - pTab->aCol[j].zName); + pTab->aCol[j].zCnName); goto update_cleanup; } #endif @@ -495,7 +498,7 @@ void sqlite3Update( { int rc; rc = sqlite3AuthCheck(pParse, SQLITE_UPDATE, pTab->zName, - j<0 ? "ROWID" : pTab->aCol[j].zName, + j<0 ? "ROWID" : pTab->aCol[j].zCnName, db->aDb[iDb].zDbSName); if( rc==SQLITE_DENY ){ goto update_cleanup; diff --git a/src/upsert.c b/src/upsert.c index 982dc7dbc1..fb6c7c0c07 100644 --- a/src/upsert.c +++ b/src/upsert.c @@ -287,7 +287,7 @@ void sqlite3UpsertDoUpdate( k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[i]); sqlite3VdbeAddOp3(v, OP_Column, iCur, k, iPk+i); VdbeComment((v, "%s.%s", pIdx->zName, - pTab->aCol[pPk->aiColumn[i]].zName)); + pTab->aCol[pPk->aiColumn[i]].zCnName)); } sqlite3VdbeVerifyAbortable(v, OE_Abort); i = sqlite3VdbeAddOp4Int(v, OP_Found, iDataCur, 0, iPk, nPk); diff --git a/src/util.c b/src/util.c index d513d8f79b..08c2949b17 100644 --- a/src/util.c +++ b/src/util.c @@ -90,7 +90,7 @@ int sqlite3Strlen30(const char *z){ */ char *sqlite3ColumnType(Column *pCol, char *zDflt){ if( pCol->colFlags & COLFLAG_HASTYPE ){ - return pCol->zName + strlen(pCol->zName) + 1; + return pCol->zCnName + strlen(pCol->zCnName) + 1; }else if( pCol->eType ){ assert( pCol->eType<=SQLITE_N_STDTYPE ); return (char*)sqlite3StdType[pCol->eType-1]; diff --git a/src/vdbeblob.c b/src/vdbeblob.c index 34cf880eca..cc427b9c34 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -187,7 +187,7 @@ int sqlite3_blob_open( /* Now search pTab for the exact column. */ for(iCol=0; iColnCol; iCol++) { - if( sqlite3StrICmp(pTab->aCol[iCol].zName, zColumn)==0 ){ + if( sqlite3StrICmp(pTab->aCol[iCol].zCnName, zColumn)==0 ){ break; } } diff --git a/src/where.c b/src/where.c index d7ef319b57..5073b6c82c 100644 --- a/src/where.c +++ b/src/where.c @@ -805,7 +805,7 @@ static void constructAutomaticIndex( if( !sentWarning ){ sqlite3_log(SQLITE_WARNING_AUTOINDEX, "automatic index on %s(%s)", pTable->zName, - pTable->aCol[iCol].zName); + pTable->aCol[iCol].zCnName); sentWarning = 1; } if( (idxCols & cMask)==0 ){ diff --git a/src/wherecode.c b/src/wherecode.c index 84fa1a1410..f3589bb0ac 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -29,7 +29,7 @@ static const char *explainIndexColumnName(Index *pIdx, int i){ i = pIdx->aiColumn[i]; if( i==XN_EXPR ) return ""; if( i==XN_ROWID ) return "rowid"; - return pIdx->pTable->aCol[i].zName; + return pIdx->pTable->aCol[i].zCnName; } /* @@ -1241,8 +1241,8 @@ static void whereIndexExprTrans( #ifndef SQLITE_OMIT_GENERATED_COLUMNS }else if( iRef>=0 && (pTab->aCol[iRef].colFlags & COLFLAG_VIRTUAL)!=0 - && (pTab->aCol[iRef].zColl==0 - || sqlite3StrICmp(pTab->aCol[iRef].zColl, sqlite3StrBINARY)==0) + && (pTab->aCol[iRef].zCnColl==0 + || sqlite3StrICmp(pTab->aCol[iRef].zCnColl, sqlite3StrBINARY)==0) ){ /* Check to see if there are direct references to generated columns ** that are contained in the index. Pulling the generated column