From ec8962869a095945fdb59bb443190bce98f54969 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 26 Nov 2020 20:13:54 +0000 Subject: [PATCH 001/257] Update mkunicode.tcl to match the change erroneously made to machine generated file fts5_unicode2.c in [b7b7bde9]. FossilOrigin-Name: 326d579d777fdede6bc64f9525248767f4730de4e50260b0387e614a9d006416 --- ext/fts3/unicode/mkunicode.tcl | 1 + ext/fts5/fts5_unicode2.c | 1 + manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/ext/fts3/unicode/mkunicode.tcl b/ext/fts3/unicode/mkunicode.tcl index a4cc540282..58d90c68c7 100644 --- a/ext/fts3/unicode/mkunicode.tcl +++ b/ext/fts3/unicode/mkunicode.tcl @@ -742,6 +742,7 @@ proc print_categories {lMap} { } iTbl++; } + aAscii[0] = 0; /* 0x00 is never a token character */ } }] } diff --git a/ext/fts5/fts5_unicode2.c b/ext/fts5/fts5_unicode2.c index 843133e82d..3e97264fa8 100644 --- a/ext/fts5/fts5_unicode2.c +++ b/ext/fts5/fts5_unicode2.c @@ -775,3 +775,4 @@ void sqlite3Fts5UnicodeAscii(u8 *aArray, u8 *aAscii){ } aAscii[0] = 0; /* 0x00 is never a token character */ } + diff --git a/manifest b/manifest index 289318d6a1..9bfb1a76e6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sa\srequirement\smark\sin\sthe\se_expr.test\sscript. -D 2020-11-25T18:44:20.962 +C Update\smkunicode.tcl\sto\smatch\sthe\schange\serroneously\smade\sto\smachine\sgenerated\sfile\sfts5_unicode2.c\sin\s[b7b7bde9]. +D 2020-11-26T20:13:54.694 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -109,7 +109,7 @@ F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87 F ext/fts3/tool/fts3view.c 413c346399159df81f86c4928b7c4a455caab73bfbc8cd68f950f632e5751674 F ext/fts3/unicode/CaseFolding.txt 8c678ca52ecc95e16bc7afc2dbf6fc9ffa05db8c F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7 -F ext/fts3/unicode/mkunicode.tcl bf7fcaa6d68e6d38223467983785d054f1cff4d9e3905dd51f6ed8801bb590d5 +F ext/fts3/unicode/mkunicode.tcl d5aebf022fa4577ee8cdf27468f0d847879993959101f6dbd6348ef0cfc324a7 F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h c132a9323f22a972c4c93a8d5a3d901113a6e612faf30ca8e695788438c5ca2a @@ -126,7 +126,7 @@ F ext/fts5/fts5_tcl.c 39bcbae507f594aad778172fa914cad0f585bf92fd3b078c686e249282 F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee F ext/fts5/fts5_test_tok.c f96c6e193c466711d6d7828d5f190407fe7ab897062d371426dd3036f01258e7 F ext/fts5/fts5_tokenize.c 5e251efb0f1af99a25ed50010ba6b1ad1250aca5921af1988fdcabe5ebc3cb43 -F ext/fts5/fts5_unicode2.c 85f64663cbd8ddd09d3a1e8823759b07085018b4a53158632e264cd785f88763 +F ext/fts5/fts5_unicode2.c eca63dbc797f8ff0572e97caf4631389c0ab900d6364861b915bdd4735973f00 F ext/fts5/fts5_varint.c e64d2113f6e1bfee0032972cffc1207b77af63319746951bf1d09885d1dadf80 F ext/fts5/fts5_vocab.c 7a071833064dc8bca236c3c323e56aac36f583aa2c46ce916d52e31ce87462c9 F ext/fts5/fts5parse.y eb526940f892ade5693f22ffd6c4f2702543a9059942772526eac1fde256bb05 @@ -1886,7 +1886,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 25d067c270966d9506db8bedf280883e32b69050b14bdbbeda4bb2d9a362619c -R 9cd6f8c162cd2c68b854e8b486ee65b1 -U drh -Z bbc45b90468712feefc207d4cad5b088 +P bb174a074b5833181900d396edda955254ea1768750a0ab3b6d714530b1fe13f +R 91ee0a5cb564678b1e5faa54bd317a61 +U dan +Z e7dd55de1cb4113d8e7246aed7e2002b diff --git a/manifest.uuid b/manifest.uuid index c9fb9b5e38..d3897dc513 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bb174a074b5833181900d396edda955254ea1768750a0ab3b6d714530b1fe13f \ No newline at end of file +326d579d777fdede6bc64f9525248767f4730de4e50260b0387e614a9d006416 \ No newline at end of file From 1c5b23f170836bdc4c329156741987a7bd772df2 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 27 Nov 2020 15:28:26 +0000 Subject: [PATCH 002/257] Fix a case in the FTS5 integrity check where a corrupt database could cause a buffer overread. FossilOrigin-Name: a32b4f650d2d543bd2773cbc8655c1679a20b35ac9ec4d08c7754ddf6d972acb --- ext/fts5/fts5_index.c | 1 + ext/fts5/test/fts5corrupt3.test | 81 +++++++++++++++++++++++++++++++++ manifest | 14 +++--- manifest.uuid | 2 +- 4 files changed, 90 insertions(+), 8 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index d109a4c176..f83488e2f6 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -6123,6 +6123,7 @@ int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum, int bUseCksum){ }else{ poslist.n = 0; fts5SegiterPoslist(p, &pIter->aSeg[pIter->aFirst[1].iFirst], 0, &poslist); + fts5BufferAppendBlob(&p->rc, &poslist, 4, (const u8*)"\0\0\0\0"); while( 0==sqlite3Fts5PoslistNext64(poslist.p, poslist.n, &iOff, &iPos) ){ int iCol = FTS5_POS2COLUMN(iPos); int iTokOff = FTS5_POS2OFFSET(iPos); diff --git a/ext/fts5/test/fts5corrupt3.test b/ext/fts5/test/fts5corrupt3.test index a8a7ae9a54..1b7b0c9d83 100644 --- a/ext/fts5/test/fts5corrupt3.test +++ b/ext/fts5/test/fts5corrupt3.test @@ -10427,6 +10427,87 @@ do_catchsql_test 70.2 { SELECT snippet(ttt, -1, '', '','',13)FROM ttt('e* NOT ee*e* NOT ee*') } {1 {database disk image is malformed}} +#------------------------------------------------------------------------- +reset_db +do_test 71.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +.open --hexdb +| size 28672 pagesize 4096 filename sql025294.txt.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 00 01 00 40 20 20 00 00 00 00 00 00 00 07 .....@ ........ +| 96: 00 00 00 00 0d 00 00 00 07 0d d2 00 0f c4 0f 6d ...............m +| 112: 0f 02 0e ab 0e 4e 0d f6 0d d2 00 00 00 00 00 00 .....N.......... +| 3536: 00 00 22 07 06 17 11 11 01 31 74 61 62 6c 65 74 .........1tablet +| 3552: 32 74 32 07 43 52 45 41 54 45 20 54 41 42 4c 45 2t2.CREATE TABLE +| 3568: 20 74 32 28 78 29 56 06 06 17 1f 1f 01 7d 74 61 t2(x)V.......ta +| 3584: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c +| 3600: 6f 6e 66 69 67 06 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB +| 3616: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k +| 3632: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v) +| 3648: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 05 WITHOUT ROWID[. +| 3664: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64 ..!!...tablet1_d +| 3680: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 ocsizet1_docsize +| 3696: 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't +| 3712: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN +| 3728: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 TEGER PRIMARY KE +| 3744: 59 2c 20 73 7a 20 42 4c 4f 42 29 55 04 06 17 21 Y, sz BLOB)U...! +| 3760: 21 01 77 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65 !.wtablet1_conte +| 3776: 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 04 43 52 45 ntt1_content.CRE +| 3792: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f ATE TABLE 't1_co +| 3808: 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 45 ntent'(id INTEGE +| 3824: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63 R PRIMARY KEY, c +| 3840: 30 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65 0)i.......-table +| 3856: 74 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45 t1_idxt1_idx.CRE +| 3872: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64 ATE TABLE 't1_id +| 3888: 78 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20 x'(segid, term, +| 3904: 70 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45 pgno, PRIMARY KE +| 3920: 59 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20 Y(segid, term)) +| 3936: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07 WITHOUT ROWIDU.. +| 3952: 17 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61 ......tablet1_da +| 3968: 74 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45 tat1_data.CREATE +| 3984: 20 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27 TABLE 't1_data' +| 4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d (id INTEGER PRIM +| 4016: 41 52 58 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 ARX KEY, block B +| 4032: 4c 4f 42 29 3a 01 06 17 11 11 08 63 74 61 62 6c LOB):......ctabl +| 4048: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54 et1t1CREATE VIRT +| 4064: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49 UAL TABLE t1 USI +| 4080: 4e 47 20 66 74 73 35 28 63 6f 6e 74 65 6e 74 29 NG fts5(content) +| page 2 offset 4096 +| 0: 0d 00 00 00 03 0f bd 00 0f e8 0f ef 0f bd 00 00 ................ +| 4016: 00 00 00 00 00 00 00 00 00 00 00 00 00 24 84 80 .............$.. +| 4032: 80 80 80 01 03 00 4e 00 00 00 1e 06 30 61 62 61 ......N.....0aba +| 4048: 60 eb 01 02 02 04 01 66 74 02 02 02 04 04 6e 64 `......ft.....nd +| 4064: 6f 6e 03 01 f2 04 1a 07 05 01 03 00 10 03 03 0f on.............. +| 4080: 0a 03 00 24 00 00 00 00 01 01 4b 00 01 01 01 01 ...$......K..... +| page 3 offset 8192 +| 0: 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02 ................ +| page 4 offset 12288 +| 0: 0d 00 00 00 03 0f e0 00 0f f6 0f ec 0f e0 00 00 ................ +| 4064: 0a 03 03 00 1b 61 62 61 6e 64 6f 6e 08 02 03 00 .....abandon.... +| 4080: 17 61 62 61 66 74 08 01 03 00 17 61 62 61 63 6b .abaft.....aback +| page 5 offset 16384 +| 0: 0d 00 00 00 03 0f ee 00 0f fa 0f f4 0f ee 00 00 ................ +| 4064: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 03 ................ +| 4080: 03 00 0e 01 04 02 03 00 0e 01 04 01 03 00 0e 01 ................ +| page 6 offset 20480 +| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................ +| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version. +| page 7 offset 24576 +| 0: 0d 00 00 00 03 0f d6 00 0f f4 0f e1 00 00 00 00 ................ +| 4048: 00 00 00 00 00 00 09 03 02 1b 72 65 62 75 69 6c ..........rebuil +| 4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63 d...+integrity-c +| 4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65 heck....optimize +| end sql025294.txt.db +}]} {} + +do_catchsql_test 71.2 { + INSERT INTO t1(t1) VALUES('integrity-check'); +} {1 {database disk image is malformed}} + + sqlite3_fts5_may_be_corrupt 0 finish_test diff --git a/manifest b/manifest index 9bfb1a76e6..a70edd11bc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\smkunicode.tcl\sto\smatch\sthe\schange\serroneously\smade\sto\smachine\sgenerated\sfile\sfts5_unicode2.c\sin\s[b7b7bde9]. -D 2020-11-26T20:13:54.694 +C Fix\sa\scase\sin\sthe\sFTS5\sintegrity\scheck\swhere\sa\scorrupt\sdatabase\scould\scause\sa\sbuffer\soverread. +D 2020-11-27T15:28:26.052 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -119,7 +119,7 @@ F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6 F ext/fts5/fts5_config.c be54f44fca491e96c6923a4b9a736f2da2b13811600eb6e38d1bcc91c4ea2e61 F ext/fts5/fts5_expr.c e527e3a7410393075598cec544e3831798a8c88b3e8878e2cfb7cb147113e925 F ext/fts5/fts5_hash.c 1aa93c9b5f461afba66701ee226297dc78402b3bdde81e90a10de5fe3df14959 -F ext/fts5/fts5_index.c fb8ed13cb8f2ddeb80ea6ade6e35d59b0bc01b9bd741f7e60a1c58a92877d5d7 +F ext/fts5/fts5_index.c 9f152a596df3a2227ddd59adb82549c2b6858ab36bc1d26fd8933f43d3d63d36 F ext/fts5/fts5_main.c b4e4931c7fcc9acfa0c3b8b5e5e80b5b424b8d9207aae3a22b674bd35ccf149d F ext/fts5/fts5_storage.c 58ba71e6cd3d43a5735815e7956ee167babb4d2cbfe206905174792af4d09d75 F ext/fts5/fts5_tcl.c 39bcbae507f594aad778172fa914cad0f585bf92fd3b078c686e249282db0d95 @@ -160,7 +160,7 @@ F ext/fts5/test/fts5connect.test 08030168fc96fc278fa81f28654fb7e90566f33aff269c0 F ext/fts5/test/fts5content.test 213506436fb2c87567b8e31f6d43ab30aab99354cec74ed679f22aad0cdbf283 F ext/fts5/test/fts5corrupt.test 77ae6f41a7eba10620efb921cf7dbe218b0ef232b04519deb43581cb17a57ebe F ext/fts5/test/fts5corrupt2.test 7453752ba12ce91690c469a6449d412561cc604b1dec994e16ab132952e7805f -F ext/fts5/test/fts5corrupt3.test b8d4d6f167b8189999dac7162ddec614ab9dca4fe5e9dcfd315e383a5e15444b +F ext/fts5/test/fts5corrupt3.test dd5435659d5363fc3b3ac32175e2fc793fdc17980b47e3d598695d867eaa77a2 F ext/fts5/test/fts5corrupt4.test ea805c4d7c68b5f185b9db5d2060a7ae5875339738dd48203c92162f41e7ca91 F ext/fts5/test/fts5delete.test 4a15fb03b6c7eac62ac807a3a32b7f0dc74f0d479c410e3e3568ae96b9469290 F ext/fts5/test/fts5detail.test 31b240dbf6d44ac3507e2f8b65f29fdc12465ffd531212378c7ce1066766f54e @@ -1886,7 +1886,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 bb174a074b5833181900d396edda955254ea1768750a0ab3b6d714530b1fe13f -R 91ee0a5cb564678b1e5faa54bd317a61 +P 326d579d777fdede6bc64f9525248767f4730de4e50260b0387e614a9d006416 +R 95253761d6d612cc5027d21e8ab35573 U dan -Z e7dd55de1cb4113d8e7246aed7e2002b +Z ad48f2fb6da30767ac9bcd93dc6b0112 diff --git a/manifest.uuid b/manifest.uuid index d3897dc513..979a551ca4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -326d579d777fdede6bc64f9525248767f4730de4e50260b0387e614a9d006416 \ No newline at end of file +a32b4f650d2d543bd2773cbc8655c1679a20b35ac9ec4d08c7754ddf6d972acb \ No newline at end of file From 66efc393c56a9b6e2c8026762b7c4cc8da2e47af Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 27 Nov 2020 16:05:31 +0000 Subject: [PATCH 003/257] Move an "if( rc==SQLITE_OK )" to outside a loop body in the fts5 bm25() code. FossilOrigin-Name: 14a4dcf3474566d072007a37d214c892397c21dd3b7f8b55ad0e5edfb7130dd6 --- ext/fts5/fts5_aux.c | 12 +++++++----- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/ext/fts5/fts5_aux.c b/ext/fts5/fts5_aux.c index 119091574f..282ea0a333 100644 --- a/ext/fts5/fts5_aux.c +++ b/ext/fts5/fts5_aux.c @@ -673,11 +673,13 @@ static void fts5Bm25Function( } /* Determine the BM25 score for the current row. */ - for(i=0; rc==SQLITE_OK && inPhrase; i++){ - score += pData->aIDF[i] * ( - ( aFreq[i] * (k1 + 1.0) ) / - ( aFreq[i] + k1 * (1 - b + b * D / pData->avgdl) ) - ); + if( rc==SQLITE_OK ){ + for(i=0; inPhrase; i++){ + score += pData->aIDF[i] * ( + ( aFreq[i] * (k1 + 1.0) ) / + ( aFreq[i] + k1 * (1 - b + b * D / pData->avgdl) ) + ); + } } /* If no error has occurred, return the calculated score. Otherwise, diff --git a/manifest b/manifest index a70edd11bc..16a83a26aa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scase\sin\sthe\sFTS5\sintegrity\scheck\swhere\sa\scorrupt\sdatabase\scould\scause\sa\sbuffer\soverread. -D 2020-11-27T15:28:26.052 +C Move\san\s"if(\src==SQLITE_OK\s)"\sto\soutside\sa\sloop\sbody\sin\sthe\sfts5\sbm25()\scode. +D 2020-11-27T16:05:31.818 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -114,7 +114,7 @@ F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a0 F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h c132a9323f22a972c4c93a8d5a3d901113a6e612faf30ca8e695788438c5ca2a F ext/fts5/fts5Int.h 26c74dd5776f798436fbf604a0bf0e8de263b35b5060b05c15f9085845d9fda2 -F ext/fts5/fts5_aux.c dcc627d8b6e3fc773db528ff67b39955dab7b51628f9dba8e15849e5bedfd7fa +F ext/fts5/fts5_aux.c 90483e40206e600e8f3e3104d9fbe161e9fb39d9d02d43fd8a10d89ccd39801a F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6dc8aaca70 F ext/fts5/fts5_config.c be54f44fca491e96c6923a4b9a736f2da2b13811600eb6e38d1bcc91c4ea2e61 F ext/fts5/fts5_expr.c e527e3a7410393075598cec544e3831798a8c88b3e8878e2cfb7cb147113e925 @@ -1886,7 +1886,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 326d579d777fdede6bc64f9525248767f4730de4e50260b0387e614a9d006416 -R 95253761d6d612cc5027d21e8ab35573 +P a32b4f650d2d543bd2773cbc8655c1679a20b35ac9ec4d08c7754ddf6d972acb +R a59e0befa591e0cd3d83961f14ea5c6e U dan -Z ad48f2fb6da30767ac9bcd93dc6b0112 +Z 96d5422c2a135757a9cad036d8e3f038 diff --git a/manifest.uuid b/manifest.uuid index 979a551ca4..f0c155d8a7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a32b4f650d2d543bd2773cbc8655c1679a20b35ac9ec4d08c7754ddf6d972acb \ No newline at end of file +14a4dcf3474566d072007a37d214c892397c21dd3b7f8b55ad0e5edfb7130dd6 \ No newline at end of file From 31817068955c5eeb1488a18daacf3addc818d623 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 27 Nov 2020 16:08:15 +0000 Subject: [PATCH 004/257] Remove a redundant "if( rc==SQLITE_OK )" from the fts5 bm25() code. FossilOrigin-Name: d85f4f27f58adcc75fc7d59e63af95b2a338052d8748a11f22ec1e48d1aff4cc --- ext/fts5/fts5_aux.c | 8 ++------ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/ext/fts5/fts5_aux.c b/ext/fts5/fts5_aux.c index 282ea0a333..a3a89006b2 100644 --- a/ext/fts5/fts5_aux.c +++ b/ext/fts5/fts5_aux.c @@ -672,7 +672,8 @@ static void fts5Bm25Function( D = (double)nTok; } - /* Determine the BM25 score for the current row. */ + /* Determine and return the BM25 score for the current row. Or, if an + ** error has occurred, throw an exception. */ if( rc==SQLITE_OK ){ for(i=0; inPhrase; i++){ score += pData->aIDF[i] * ( @@ -680,11 +681,6 @@ static void fts5Bm25Function( ( aFreq[i] + k1 * (1 - b + b * D / pData->avgdl) ) ); } - } - - /* If no error has occurred, return the calculated score. Otherwise, - ** throw an SQL exception. */ - if( rc==SQLITE_OK ){ sqlite3_result_double(pCtx, -1.0 * score); }else{ sqlite3_result_error_code(pCtx, rc); diff --git a/manifest b/manifest index 16a83a26aa..04f6c7f81b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Move\san\s"if(\src==SQLITE_OK\s)"\sto\soutside\sa\sloop\sbody\sin\sthe\sfts5\sbm25()\scode. -D 2020-11-27T16:05:31.818 +C Remove\sa\sredundant\s"if(\src==SQLITE_OK\s)"\sfrom\sthe\sfts5\sbm25()\scode. +D 2020-11-27T16:08:15.286 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -114,7 +114,7 @@ F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a0 F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h c132a9323f22a972c4c93a8d5a3d901113a6e612faf30ca8e695788438c5ca2a F ext/fts5/fts5Int.h 26c74dd5776f798436fbf604a0bf0e8de263b35b5060b05c15f9085845d9fda2 -F ext/fts5/fts5_aux.c 90483e40206e600e8f3e3104d9fbe161e9fb39d9d02d43fd8a10d89ccd39801a +F ext/fts5/fts5_aux.c e6dbf53bfe21597cf3d52a4385bba006f0a58a8001b1c520d2ed3689f32545f9 F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6dc8aaca70 F ext/fts5/fts5_config.c be54f44fca491e96c6923a4b9a736f2da2b13811600eb6e38d1bcc91c4ea2e61 F ext/fts5/fts5_expr.c e527e3a7410393075598cec544e3831798a8c88b3e8878e2cfb7cb147113e925 @@ -1886,7 +1886,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 a32b4f650d2d543bd2773cbc8655c1679a20b35ac9ec4d08c7754ddf6d972acb -R a59e0befa591e0cd3d83961f14ea5c6e +P 14a4dcf3474566d072007a37d214c892397c21dd3b7f8b55ad0e5edfb7130dd6 +R dd07aa0753904b5aa7d82526799a8608 U dan -Z 96d5422c2a135757a9cad036d8e3f038 +Z 86f990987e42b1dda2e73f9540f5c419 diff --git a/manifest.uuid b/manifest.uuid index f0c155d8a7..9bc890025c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -14a4dcf3474566d072007a37d214c892397c21dd3b7f8b55ad0e5edfb7130dd6 \ No newline at end of file +d85f4f27f58adcc75fc7d59e63af95b2a338052d8748a11f22ec1e48d1aff4cc \ No newline at end of file From 6d19bf9460e136b7cf21732359c63965ee48ce4d Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 27 Nov 2020 16:15:55 +0000 Subject: [PATCH 005/257] Add missing cast to fts5 bm25() code. FossilOrigin-Name: 6ff9673847c0b4174d9435e93d19af0ee7406b1a12edeb6edec98697e1646824 --- ext/fts5/fts5_aux.c | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ext/fts5/fts5_aux.c b/ext/fts5/fts5_aux.c index a3a89006b2..256fc9afd1 100644 --- a/ext/fts5/fts5_aux.c +++ b/ext/fts5/fts5_aux.c @@ -566,7 +566,7 @@ static int fts5Bm25GetData( int rc = SQLITE_OK; /* Return code */ Fts5Bm25Data *p; /* Object to return */ - p = pApi->xGetAuxdata(pFts, 0); + p = (Fts5Bm25Data*)pApi->xGetAuxdata(pFts, 0); if( p==0 ){ int nPhrase; /* Number of phrases in query */ sqlite3_int64 nRow = 0; /* Number of rows in table */ diff --git a/manifest b/manifest index 04f6c7f81b..dea829c2f7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\sredundant\s"if(\src==SQLITE_OK\s)"\sfrom\sthe\sfts5\sbm25()\scode. -D 2020-11-27T16:08:15.286 +C Add\smissing\scast\sto\sfts5\sbm25()\scode. +D 2020-11-27T16:15:55.777 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -114,7 +114,7 @@ F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a0 F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h c132a9323f22a972c4c93a8d5a3d901113a6e612faf30ca8e695788438c5ca2a F ext/fts5/fts5Int.h 26c74dd5776f798436fbf604a0bf0e8de263b35b5060b05c15f9085845d9fda2 -F ext/fts5/fts5_aux.c e6dbf53bfe21597cf3d52a4385bba006f0a58a8001b1c520d2ed3689f32545f9 +F ext/fts5/fts5_aux.c 7dc0cda24be4d32ddaf0fd3ffdd3406564dc28e055f2148d6dc5ecc900858f9e F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6dc8aaca70 F ext/fts5/fts5_config.c be54f44fca491e96c6923a4b9a736f2da2b13811600eb6e38d1bcc91c4ea2e61 F ext/fts5/fts5_expr.c e527e3a7410393075598cec544e3831798a8c88b3e8878e2cfb7cb147113e925 @@ -1886,7 +1886,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 14a4dcf3474566d072007a37d214c892397c21dd3b7f8b55ad0e5edfb7130dd6 -R dd07aa0753904b5aa7d82526799a8608 +P d85f4f27f58adcc75fc7d59e63af95b2a338052d8748a11f22ec1e48d1aff4cc +R 31f1de2e35e2b768451de6161bdb08f9 U dan -Z 86f990987e42b1dda2e73f9540f5c419 +Z ed7ca998689e3eeaf0ec679d62a198f7 diff --git a/manifest.uuid b/manifest.uuid index 9bc890025c..23ea5d7535 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d85f4f27f58adcc75fc7d59e63af95b2a338052d8748a11f22ec1e48d1aff4cc \ No newline at end of file +6ff9673847c0b4174d9435e93d19af0ee7406b1a12edeb6edec98697e1646824 \ No newline at end of file From cad760d16ed403a065dbc90dd5c50f1eb29f5988 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 27 Nov 2020 19:40:13 +0000 Subject: [PATCH 006/257] Fix a compiler warning in fts5_aux.c. FossilOrigin-Name: 8edb983bc87898eff2cd2e7e672a32a47c71b2be9d818513d339e95560d45b2b --- ext/fts5/fts5_aux.c | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ext/fts5/fts5_aux.c b/ext/fts5/fts5_aux.c index 256fc9afd1..77f6d5baba 100644 --- a/ext/fts5/fts5_aux.c +++ b/ext/fts5/fts5_aux.c @@ -640,7 +640,7 @@ static void fts5Bm25Function( ){ const double k1 = 1.2; /* Constant "k1" from BM25 formula */ const double b = 0.75; /* Constant "b" from BM25 formula */ - int rc = SQLITE_OK; /* Error code */ + int rc; /* Error code */ double score = 0.0; /* SQL function return value */ Fts5Bm25Data *pData; /* Values allocated/calculated once only */ int i; /* Iterator variable */ diff --git a/manifest b/manifest index dea829c2f7..ebcd99ac4e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\smissing\scast\sto\sfts5\sbm25()\scode. -D 2020-11-27T16:15:55.777 +C Fix\sa\scompiler\swarning\sin\sfts5_aux.c. +D 2020-11-27T19:40:13.829 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -114,7 +114,7 @@ F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a0 F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h c132a9323f22a972c4c93a8d5a3d901113a6e612faf30ca8e695788438c5ca2a F ext/fts5/fts5Int.h 26c74dd5776f798436fbf604a0bf0e8de263b35b5060b05c15f9085845d9fda2 -F ext/fts5/fts5_aux.c 7dc0cda24be4d32ddaf0fd3ffdd3406564dc28e055f2148d6dc5ecc900858f9e +F ext/fts5/fts5_aux.c f558e1fb9f0f86a4f7489e258c162e1f947de5ff2709087fbb465fddb7092f98 F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6dc8aaca70 F ext/fts5/fts5_config.c be54f44fca491e96c6923a4b9a736f2da2b13811600eb6e38d1bcc91c4ea2e61 F ext/fts5/fts5_expr.c e527e3a7410393075598cec544e3831798a8c88b3e8878e2cfb7cb147113e925 @@ -1886,7 +1886,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 d85f4f27f58adcc75fc7d59e63af95b2a338052d8748a11f22ec1e48d1aff4cc -R 31f1de2e35e2b768451de6161bdb08f9 +P 6ff9673847c0b4174d9435e93d19af0ee7406b1a12edeb6edec98697e1646824 +R b9d507fc84194599f6126b12d3d5bf12 U dan -Z ed7ca998689e3eeaf0ec679d62a198f7 +Z 59431772996995dfd9988b1c0c070b2d diff --git a/manifest.uuid b/manifest.uuid index 23ea5d7535..67d18affcf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6ff9673847c0b4174d9435e93d19af0ee7406b1a12edeb6edec98697e1646824 \ No newline at end of file +8edb983bc87898eff2cd2e7e672a32a47c71b2be9d818513d339e95560d45b2b \ No newline at end of file From d1032f952cad0b1710f6854684afc1f7831caf55 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 27 Nov 2020 20:56:16 +0000 Subject: [PATCH 007/257] Improve the speed of the tokenizer by recognizing that tokens starting with letters "_", "Y", or "Z" can never be SQL keywords and must be ordinary identifiers. FossilOrigin-Name: 16e281ed6219cc229dec7e3f1b40da2304dc270a74fd6ef78d04a088e30e7026 --- manifest | 17 ++++++++++------- manifest.uuid | 2 +- src/tokenize.c | 52 ++++++++++++++++++++++++++------------------------ 3 files changed, 38 insertions(+), 33 deletions(-) diff --git a/manifest b/manifest index ebcd99ac4e..d3f2807345 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scompiler\swarning\sin\sfts5_aux.c. -D 2020-11-27T19:40:13.829 +C Improve\sthe\sspeed\sof\sthe\stokenizer\sby\srecognizing\sthat\stokens\sstarting\nwith\sletters\s"_",\s"Y",\sor\s"Z"\scan\snever\sbe\sSQL\skeywords\sand\smust\sbe\sordinary\nidentifiers. +D 2020-11-27T20:56:16.951 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -603,7 +603,7 @@ F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a9 F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394ba3f F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c -F src/tokenize.c 4dc01b267593537e2a0d0efe9f80dabe24c5b6f7627bc6971c487fa6a1dacbbf +F src/tokenize.c 01dba3023659dc6f6b1e054c14b35a0074bd35de10466b99454d33278191d97f F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda F src/trigger.c 515e79206d40d1d4149129318582e79a6e9db590a7b74e226fdb5b2a6c7e1b10 F src/update.c 9f126204a6acb96bbe47391ae48e0fc579105d8e76a6d9c4fab3271367476580 @@ -1886,7 +1886,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 6ff9673847c0b4174d9435e93d19af0ee7406b1a12edeb6edec98697e1646824 -R b9d507fc84194599f6126b12d3d5bf12 -U dan -Z 59431772996995dfd9988b1c0c070b2d +P 8edb983bc87898eff2cd2e7e672a32a47c71b2be9d818513d339e95560d45b2b +R a0457978bc43ec4e3c0a4c4481e2d29f +T *branch * faster-tokenizer +T *sym-faster-tokenizer * +T -sym-trunk * +U drh +Z 7f6094958178f08bfb909f826361ecf4 diff --git a/manifest.uuid b/manifest.uuid index 67d18affcf..c33fe4a84a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8edb983bc87898eff2cd2e7e672a32a47c71b2be9d818513d339e95560d45b2b \ No newline at end of file +16e281ed6219cc229dec7e3f1b40da2304dc270a74fd6ef78d04a088e30e7026 \ No newline at end of file diff --git a/src/tokenize.c b/src/tokenize.c index 70f0c63678..bafda0322b 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -27,8 +27,8 @@ ** all of them need to be used within the switch. */ #define CC_X 0 /* The letter 'x', or start of BLOB literal */ -#define CC_KYWD 1 /* Alphabetics or '_'. Usable in a keyword */ -#define CC_ID 2 /* unicode characters usable in IDs */ +#define CC_KYWD0 1 /* First letter of a keyword */ +#define CC_KYWD 2 /* Alphabetics or '_'. Usable in a keyword */ #define CC_DIGIT 3 /* Digits */ #define CC_DOLLAR 4 /* '$' */ #define CC_VARALPHA 5 /* '@', '#', ':'. Alphabetic SQL variables */ @@ -53,20 +53,21 @@ #define CC_AND 24 /* '&' */ #define CC_TILDA 25 /* '~' */ #define CC_DOT 26 /* '.' */ -#define CC_ILLEGAL 27 /* Illegal character */ -#define CC_NUL 28 /* 0x00 */ +#define CC_ID 27 /* unicode characters usable in IDs */ +#define CC_ILLEGAL 28 /* Illegal character */ +#define CC_NUL 29 /* 0x00 */ static const unsigned char aiClass[] = { #ifdef SQLITE_ASCII /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */ -/* 0x */ 28, 27, 27, 27, 27, 27, 27, 27, 27, 7, 7, 27, 7, 7, 27, 27, -/* 1x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* 0x */ 29, 28, 28, 28, 28, 28, 28, 28, 28, 7, 7, 28, 7, 7, 28, 28, +/* 1x */ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, /* 2x */ 7, 15, 8, 5, 4, 22, 24, 8, 17, 18, 21, 20, 23, 11, 26, 16, /* 3x */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 19, 12, 14, 13, 6, /* 4x */ 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -/* 5x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 9, 27, 27, 27, 1, +/* 5x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 9, 28, 28, 28, 2, /* 6x */ 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -/* 7x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 27, 10, 27, 25, 27, +/* 7x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 28, 10, 28, 25, 28, /* 8x */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 9x */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* Ax */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -78,22 +79,22 @@ static const unsigned char aiClass[] = { #endif #ifdef SQLITE_EBCDIC /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */ -/* 0x */ 27, 27, 27, 27, 27, 7, 27, 27, 27, 27, 27, 27, 7, 7, 27, 27, -/* 1x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -/* 2x */ 27, 27, 27, 27, 27, 7, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -/* 3x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -/* 4x */ 7, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 26, 12, 17, 20, 10, -/* 5x */ 24, 27, 27, 27, 27, 27, 27, 27, 27, 27, 15, 4, 21, 18, 19, 27, -/* 6x */ 11, 16, 27, 27, 27, 27, 27, 27, 27, 27, 27, 23, 22, 1, 13, 6, -/* 7x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 8, 5, 5, 5, 8, 14, 8, -/* 8x */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, -/* 9x */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, -/* Ax */ 27, 25, 1, 1, 1, 1, 1, 0, 1, 1, 27, 27, 27, 27, 27, 27, -/* Bx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 9, 27, 27, 27, 27, 27, -/* Cx */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, -/* Dx */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, -/* Ex */ 27, 27, 1, 1, 1, 1, 1, 0, 1, 1, 27, 27, 27, 27, 27, 27, -/* Fx */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 27, 27, 27, 27, 27, 27, +/* 0x */ 29, 28, 28, 28, 28, 7, 28, 28, 28, 28, 28, 28, 7, 7, 28, 28, +/* 1x */ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +/* 2x */ 28, 28, 28, 28, 28, 7, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +/* 3x */ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +/* 4x */ 7, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 26, 12, 17, 20, 10, +/* 5x */ 24, 28, 28, 28, 28, 28, 28, 28, 28, 28, 15, 4, 21, 18, 19, 28, +/* 6x */ 11, 16, 28, 28, 28, 28, 28, 28, 28, 28, 28, 23, 22, 2, 13, 6, +/* 7x */ 28, 28, 28, 28, 28, 28, 28, 28, 28, 8, 5, 5, 5, 8, 14, 8, +/* 8x */ 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 28, 28, 28, 28, 28, 28, +/* 9x */ 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 28, 28, 28, 28, 28, 28, +/* Ax */ 28, 25, 1, 1, 1, 1, 1, 0, 2, 2, 28, 28, 28, 28, 28, 28, +/* Bx */ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 9, 28, 28, 28, 28, 28, +/* Cx */ 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 28, 28, 28, 28, 28, 28, +/* Dx */ 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 28, 28, 28, 28, 28, 28, +/* Ex */ 28, 28, 1, 1, 1, 1, 1, 0, 2, 2, 28, 28, 28, 28, 28, 28, +/* Fx */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 28, 28, 28, 28, 28, 28, #endif }; @@ -499,7 +500,7 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ if( n==0 ) *tokenType = TK_ILLEGAL; return i; } - case CC_KYWD: { + case CC_KYWD0: { for(i=1; aiClass[z[i]]<=CC_KYWD; i++){} if( IdChar(z[i]) ){ /* This token started out using characters that can appear in keywords, @@ -529,6 +530,7 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ ** SQL keywords start with the letter 'x'. Fall through */ /* no break */ deliberate_fall_through } + case CC_KYWD: case CC_ID: { i = 1; break; From 56a5747e636f1b5365090e3fd73824fd382f1104 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 30 Nov 2020 14:20:17 +0000 Subject: [PATCH 008/257] Do not reuse the obsolete SQLITE_TESTCTRL_PRNG_RESET value for SQLITE_TESTCTRL_SEEK_COUNT. Give SEEK_COUNT its own unique value. This avoids incompatibility with legacy test code. FossilOrigin-Name: fdba0b129091d607dc0c1aa52f8631a208dbff22476a298bd5428e672593ed18 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index ebcd99ac4e..9aee3f8c2d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scompiler\swarning\sin\sfts5_aux.c. -D 2020-11-27T19:40:13.829 +C Do\snot\sreuse\sthe\sobsolete\sSQLITE_TESTCTRL_PRNG_RESET\svalue\sfor\nSQLITE_TESTCTRL_SEEK_COUNT.\s\sGive\sSEEK_COUNT\sits\sown\sunique\svalue.\nThis\savoids\sincompatibility\swith\slegacy\stest\scode. +D 2020-11-30T14:20:17.728 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -541,7 +541,7 @@ F src/resolve.c 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 31387e56f5e6d1adc798dfa04b946001289a61e65acf4615f7b7130f121f3b9c F src/shell.c.in 55113760ae91a05c6ce4558714a1c8fc7a44bf266f735de6e71ea40f79e69830 -F src/sqlite.h.in 457c991c9d2ff483e17e5b5eb1a83c6793516d478cc63a78e1ea7b362e27e678 +F src/sqlite.h.in 1dbae67057d999161c30b21c3c7fa45d51f665b510d397dd1b7d671287d772b0 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e F src/sqliteInt.h c01115c8dd967f7d334a98ba37ac821eafb04144c8085a795daaf2185743d27a @@ -1886,7 +1886,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 6ff9673847c0b4174d9435e93d19af0ee7406b1a12edeb6edec98697e1646824 -R b9d507fc84194599f6126b12d3d5bf12 -U dan -Z 59431772996995dfd9988b1c0c070b2d +P 8edb983bc87898eff2cd2e7e672a32a47c71b2be9d818513d339e95560d45b2b +R 050282c47b4fc851bae29e813a40a644 +U drh +Z 8621daefa84a7d6030d8188b7808faf8 diff --git a/manifest.uuid b/manifest.uuid index 67d18affcf..cd70bcace5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8edb983bc87898eff2cd2e7e672a32a47c71b2be9d818513d339e95560d45b2b \ No newline at end of file +fdba0b129091d607dc0c1aa52f8631a208dbff22476a298bd5428e672593ed18 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 58fe25dbf2..3ec8efeab0 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -7740,7 +7740,6 @@ int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_PRNG_SAVE 5 #define SQLITE_TESTCTRL_PRNG_RESTORE 6 #define SQLITE_TESTCTRL_PRNG_RESET 7 /* NOT USED */ -#define SQLITE_TESTCTRL_SEEK_COUNT 7 #define SQLITE_TESTCTRL_BITVEC_TEST 8 #define SQLITE_TESTCTRL_FAULT_INSTALL 9 #define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10 @@ -7765,7 +7764,8 @@ int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_RESULT_INTREAL 27 #define SQLITE_TESTCTRL_PRNG_SEED 28 #define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29 -#define SQLITE_TESTCTRL_LAST 29 /* Largest TESTCTRL */ +#define SQLITE_TESTCTRL_SEEK_COUNT 30 +#define SQLITE_TESTCTRL_LAST 30 /* Largest TESTCTRL */ /* ** CAPI3REF: SQL Keyword Checking From aeb4e6eebd227f3e96af8bdc709156bbcc60a50c Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 30 Nov 2020 18:43:40 +0000 Subject: [PATCH 009/257] Update the tea/win/makefile.vc file that ships as part of the autoconf package to use "sqlite3" instead of "tclsqlite3" for the installed dll filename. FossilOrigin-Name: 93d4d9dc05bb86c08a12d56b3ce68ec39b69e57951a936fb3b326812c051c3b4 --- autoconf/tea/win/makefile.vc | 2 +- manifest | 17 ++++++++++------- manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/autoconf/tea/win/makefile.vc b/autoconf/tea/win/makefile.vc index 88b66f173c..d92a8428bf 100644 --- a/autoconf/tea/win/makefile.vc +++ b/autoconf/tea/win/makefile.vc @@ -153,7 +153,7 @@ Please `cd` to its location first. # #------------------------------------------------------------------------- -PROJECT = tclsqlite3 +PROJECT = sqlite3 !include "rules.vc" # nmakehelp -V will search the file for tag, skips until a diff --git a/manifest b/manifest index 9aee3f8c2d..c88b2ee3da 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sreuse\sthe\sobsolete\sSQLITE_TESTCTRL_PRNG_RESET\svalue\sfor\nSQLITE_TESTCTRL_SEEK_COUNT.\s\sGive\sSEEK_COUNT\sits\sown\sunique\svalue.\nThis\savoids\sincompatibility\swith\slegacy\stest\scode. -D 2020-11-30T14:20:17.728 +C Update\sthe\stea/win/makefile.vc\sfile\sthat\sships\sas\spart\sof\sthe\sautoconf\spackage\sto\suse\s"sqlite3"\sinstead\sof\s"tclsqlite3"\sfor\sthe\sinstalled\sdll\sfilename. +D 2020-11-30T18:43:40.569 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -28,7 +28,7 @@ F autoconf/tea/license.terms 13bd403c9610fd2b76ece0ab50c4c5eda933d523 F autoconf/tea/pkgIndex.tcl.in 3ef61715cf1c7bdcff56947ffadb26bc991ca39d F autoconf/tea/tclconfig/install-sh bdd5e293591621ae60d9824d86a4b1c5f22c3d00 F autoconf/tea/tclconfig/tcl.m4 66ddf0a5d5e4b1d29bff472c0985fd7fa89d0fb5 -F autoconf/tea/win/makefile.vc 71915591c07cd5137711dc40ba3e127deb3f4531b9aad220b724cf5b451362bd +F autoconf/tea/win/makefile.vc a5ff708245260c2794c6aaa0151efe5403d5896566eaf096747be0d9075284e4 F autoconf/tea/win/nmakehlp.c 247538ad8e8c508f33c03ec1fbd67d3a07ef6291 F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6 @@ -1886,7 +1886,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 8edb983bc87898eff2cd2e7e672a32a47c71b2be9d818513d339e95560d45b2b -R 050282c47b4fc851bae29e813a40a644 -U drh -Z 8621daefa84a7d6030d8188b7808faf8 +P fdba0b129091d607dc0c1aa52f8631a208dbff22476a298bd5428e672593ed18 +R 02db8b9bcb7f3c64353edbc1fa9fbf5b +T *branch * win-tea-fix +T *sym-win-tea-fix * +T -sym-trunk * +U dan +Z bee03399d891ae58316901d882ad61c9 diff --git a/manifest.uuid b/manifest.uuid index cd70bcace5..e4c809a159 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fdba0b129091d607dc0c1aa52f8631a208dbff22476a298bd5428e672593ed18 \ No newline at end of file +93d4d9dc05bb86c08a12d56b3ce68ec39b69e57951a936fb3b326812c051c3b4 \ No newline at end of file From 384f5c26f48b92e8bfcb168381d4a8caf3ea59e7 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 1 Dec 2020 16:14:00 +0000 Subject: [PATCH 010/257] Version 3.34.0 FossilOrigin-Name: a26b6597e3ae272231b96f9982c3bcc17ddec2f2b6eb4df06a224b91089fed5b --- manifest | 14 ++++++++------ manifest.uuid | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 61cd8a8d88..e80f89eeb9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\stea/win/makefile.vc\sfile\sthat\sships\sas\spart\sof\sthe\sautoconf\spackage\sto\suse\s"sqlite3"\sinstead\sof\s"tclsqlite3"\sfor\sthe\sinstalled\sdll\sfilename. -D 2020-11-30T18:52:08.974 +C Version\s3.34.0 +D 2020-12-01T16:14:00.051 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1886,8 +1886,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 fdba0b129091d607dc0c1aa52f8631a208dbff22476a298bd5428e672593ed18 93d4d9dc05bb86c08a12d56b3ce68ec39b69e57951a936fb3b326812c051c3b4 +P 23212b1a054f05773a9f69f9802035eea6a9d759a2a09e22f46d1046c058b417 R 02db8b9bcb7f3c64353edbc1fa9fbf5b -T +closed 93d4d9dc05bb86c08a12d56b3ce68ec39b69e57951a936fb3b326812c051c3b4 -U dan -Z d576d3f967d94d06fabf606d730f6867 +T +bgcolor * #d0c0ff +T +sym-release * +T +sym-version-3.34.0 * +U drh +Z b7b093d44b407c1b4e832f8c913357ae diff --git a/manifest.uuid b/manifest.uuid index bc6daf0395..275e6f34d5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -23212b1a054f05773a9f69f9802035eea6a9d759a2a09e22f46d1046c058b417 \ No newline at end of file +a26b6597e3ae272231b96f9982c3bcc17ddec2f2b6eb4df06a224b91089fed5b \ No newline at end of file From f461bab265ab2879225b099980719abc94696fed Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 1 Dec 2020 23:18:13 +0000 Subject: [PATCH 011/257] Add the --lookaside SIZE COUNT command-line option to the dbfuzz2 testing tool. FossilOrigin-Name: 2466960c0ba02ef9c325e9a5f8603db518e7529547f614c225fef430421e1643 --- manifest | 15 ++++++--------- manifest.uuid | 2 +- test/dbfuzz2.c | 16 ++++++++++++---- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index e80f89eeb9..c47550693d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Version\s3.34.0 -D 2020-12-01T16:14:00.051 +C Add\sthe\s--lookaside\sSIZE\sCOUNT\scommand-line\soption\sto\sthe\sdbfuzz2\stesting\stool. +D 2020-12-01T23:18:13.197 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -817,7 +817,7 @@ F test/dbdata.test 042f49acff3438f940eeba5868d3af080ae64ddf26ae78f80c92bec3ca7d8 F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e F test/dbfuzz001.test 55e1a3504f8dea84155e09912fe3b1c3ad77e0b1a938ec42ca03b8e51b321e30 F test/dbfuzz2-seed1.db e6225c6f3d7b63f9c5b6867146a5f329d997ab105bee64644dc2b3a2f2aebaee -F test/dbfuzz2.c 40cc4600947f30600f0ab365a2714ec76a899c9adb2c0ccd63ba583b2f71390e +F test/dbfuzz2.c db2a1710c0d30d38e1352ee1b52b717fcb224c8caacc6f10909ef540f73cc9e8 F test/dbpage.test 650234ba683b9d82b899c6c51439819787e7609f17a0cc40e0080a7b6443bc38 F test/dbstatus.test 4a4221a883025ffd39696b3d1b3910b928fb097d77e671351acb35f3aed42759 F test/dbstatus2.test f5fe0afed3fa45e57cfa70d1147606c20d2ba23feac78e9a172f2fe8ab5b78ef @@ -1886,10 +1886,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 23212b1a054f05773a9f69f9802035eea6a9d759a2a09e22f46d1046c058b417 -R 02db8b9bcb7f3c64353edbc1fa9fbf5b -T +bgcolor * #d0c0ff -T +sym-release * -T +sym-version-3.34.0 * +P a26b6597e3ae272231b96f9982c3bcc17ddec2f2b6eb4df06a224b91089fed5b +R 2c2b0393b1f5ca930e6c9ce57f506377 U drh -Z b7b093d44b407c1b4e832f8c913357ae +Z 2700eec066243e283a576b1178e7dd55 diff --git a/manifest.uuid b/manifest.uuid index 275e6f34d5..d124fe677f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a26b6597e3ae272231b96f9982c3bcc17ddec2f2b6eb4df06a224b91089fed5b \ No newline at end of file +2466960c0ba02ef9c325e9a5f8603db518e7529547f614c225fef430421e1643 \ No newline at end of file diff --git a/test/dbfuzz2.c b/test/dbfuzz2.c index e35162937f..6b30490dde 100644 --- a/test/dbfuzz2.c +++ b/test/dbfuzz2.c @@ -287,10 +287,6 @@ int LLVMFuzzerInitialize(int *pArgc, char ***pArgv){ sqlite3MemTraceActivate(stdout); continue; } - if( strcmp(z,"mem")==0 ){ - bVdbeDebug = 1; - continue; - } if( strcmp(z,"max-db-size")==0 ){ if( i+1==argc ){ fprintf(stderr, "missing argument to %s\n", argv[i]); @@ -299,6 +295,18 @@ int LLVMFuzzerInitialize(int *pArgc, char ***pArgv){ szMax = strtol(argv[++i], 0, 0); continue; } + if( strcmp(z, "lookaside")==0 ){ + int sz, nSlot; + if( i+2>=argc ){ + fprintf(stderr, + "--lookaside requires two arguments: slot-size num-slots\n"); + exit(1); + } + sz = atoi(argv[++i]); + nSlot = atoi(argv[++i]); + sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, nSlot); + continue; + } #ifndef _WIN32 if( strcmp(z,"max-stack")==0 || strcmp(z,"max-data")==0 From 636f505864d2c07c1b22f29a45a8c68f773685f5 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 2 Dec 2020 00:22:09 +0000 Subject: [PATCH 012/257] Increase the version number to 3.35.0 to begin the next development cycle. FossilOrigin-Name: edbabaa30823db7c7d169cb93722b5f74bc711359984fb7e139ca9d10fe7dae4 --- VERSION | 2 +- configure | 18 +++++++++--------- manifest | 15 +++++++-------- manifest.uuid | 2 +- 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/VERSION b/VERSION index 5c0e053417..b2f5d1d153 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.34.0 +3.35.0 diff --git a/configure b/configure index a03d6fdb3a..90cb4d25e8 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for sqlite 3.34.0. +# Generated by GNU Autoconf 2.69 for sqlite 3.35.0. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -726,8 +726,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='sqlite' PACKAGE_TARNAME='sqlite' -PACKAGE_VERSION='3.34.0' -PACKAGE_STRING='sqlite 3.34.0' +PACKAGE_VERSION='3.35.0' +PACKAGE_STRING='sqlite 3.35.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1466,7 +1466,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures sqlite 3.34.0 to adapt to many kinds of systems. +\`configure' configures sqlite 3.35.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1531,7 +1531,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of sqlite 3.34.0:";; + short | recursive ) echo "Configuration of sqlite 3.35.0:";; esac cat <<\_ACEOF @@ -1658,7 +1658,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sqlite configure 3.34.0 +sqlite configure 3.35.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2077,7 +2077,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by sqlite $as_me 3.34.0, which was +It was created by sqlite $as_me 3.35.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -12236,7 +12236,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by sqlite $as_me 3.34.0, which was +This file was extended by sqlite $as_me 3.35.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12302,7 +12302,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -sqlite config.status 3.34.0 +sqlite config.status 3.35.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/manifest b/manifest index c44588e565..b9de0f3715 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Slightly\sfaster\stokenization\sof\snon-keyword\sidentifiers. -D 2020-12-02T00:20:00.564 +C Increase\sthe\sversion\snumber\sto\s3.35.0\sto\sbegin\sthe\snext\sdevelopment\scycle. +D 2020-12-02T00:22:09.917 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -7,7 +7,7 @@ F Makefile.in 0e88f5d095213a9ccd45c5bbd871c8ead498f886dff4493471fbf48b1f867f9d F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241 F Makefile.msc dd10dbf63b2f8ac3e2f0542963a21bc69058976ac4355165f212a31c83d17f44 F README.md 1514a365ffca3c138e00c5cc839906108a01011a6b082bad19b09781e3aa498a -F VERSION 4027b9aea92d64385570778ebd14388c0b23e92aafda15e7b89c45886c9b920a +F VERSION 92f3e4c5cdee6f0779aef1eae857dfc21d0eabb1f2af169dc90e63cd76b15bb2 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 @@ -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 e7df2824b6e60d482d919fb3e7d823faf08467093b096ad47a4fe2eec3f0ba99 x +F configure 73234664de11cb7f1f1b198fe6775d8b0f01d25480d325a7b9f9645675bf6b79 x F configure.ac 73545c21eebcef9398d85c982c7be260f07708256778221b541f83ae8c6f61eb F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd @@ -1886,8 +1886,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 2466960c0ba02ef9c325e9a5f8603db518e7529547f614c225fef430421e1643 16e281ed6219cc229dec7e3f1b40da2304dc270a74fd6ef78d04a088e30e7026 -R a8add1c818b1e70c15ae61bdff16cc29 -T +closed 16e281ed6219cc229dec7e3f1b40da2304dc270a74fd6ef78d04a088e30e7026 +P 55fa22bd403cc8f0973efea898a7cfa3a32b57c7e2a7a4c30c3f2c72d5396f07 +R c4c8678c10e3481910a51c944a97bfe0 U drh -Z 1f1b11cb63e506030abbce26b0c97982 +Z becdcb441cd79c3a54faafc3a5147030 diff --git a/manifest.uuid b/manifest.uuid index 290dd4158f..93b5ac4067 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -55fa22bd403cc8f0973efea898a7cfa3a32b57c7e2a7a4c30c3f2c72d5396f07 \ No newline at end of file +edbabaa30823db7c7d169cb93722b5f74bc711359984fb7e139ca9d10fe7dae4 \ No newline at end of file From bb497fe36d5ae897c7cfa809d9c57881fda90349 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 2 Dec 2020 02:58:05 +0000 Subject: [PATCH 013/257] Parameterize the hash function in mkkeywordhash.c. This was an attempt to find a better hash function, which turned out to not be successful. FossilOrigin-Name: 2195d731f51a18f917c4299d8f4c7ee7c139c2527f62869d6da171a6d1d89ea6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/mkkeywordhash.c | 18 ++++++++++++++---- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index b9de0f3715..5a6220aaaf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Increase\sthe\sversion\snumber\sto\s3.35.0\sto\sbegin\sthe\snext\sdevelopment\scycle. -D 2020-12-02T00:22:09.917 +C Parameterize\sthe\shash\sfunction\sin\smkkeywordhash.c.\s\sThis\swas\san\sattempt\sto\nfind\sa\sbetter\shash\sfunction,\swhich\sturned\sout\sto\snot\sbe\ssuccessful. +D 2020-12-02T02:58:05.804 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1814,7 +1814,7 @@ F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439 F tool/mkautoconfamal.sh f62353eb6c06ab264da027fd4507d09914433dbdcab9cb011cdc18016f1ab3b8 F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe x F tool/mkctimec.tcl dd183b73ae1c28249669741c250525f0407e579a70482371668fd5f130d9feb3 -F tool/mkkeywordhash.c 11a3f3af8e787d0c5ca459ed66fe80fd09e661876506e7b978ec08c19477bdc2 +F tool/mkkeywordhash.c 24e4396ae665d985fed9e040e8b748129c1a12d77eeeae7ad4609821c41ba7bf F tool/mkmsvcmin.tcl 6ecab9fe22c2c8de4d82d4c46797bda3d2deac8e763885f5a38d0c44a895ab33 F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl 352a4319c0ad869eb26442bf7c3b015aa15594c21f1cce5a6420dbe999367c21 @@ -1886,7 +1886,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 55fa22bd403cc8f0973efea898a7cfa3a32b57c7e2a7a4c30c3f2c72d5396f07 -R c4c8678c10e3481910a51c944a97bfe0 +P edbabaa30823db7c7d169cb93722b5f74bc711359984fb7e139ca9d10fe7dae4 +R c0ed84786324d0934b9713477bd4d8aa U drh -Z becdcb441cd79c3a54faafc3a5147030 +Z adef5cc1a128c4fbf04c3cd6ce9dd431 diff --git a/manifest.uuid b/manifest.uuid index 93b5ac4067..a48bace843 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -edbabaa30823db7c7d169cb93722b5f74bc711359984fb7e139ca9d10fe7dae4 \ No newline at end of file +2195d731f51a18f917c4299d8f4c7ee7c139c2527f62869d6da171a6d1d89ea6 \ No newline at end of file diff --git a/tool/mkkeywordhash.c b/tool/mkkeywordhash.c index 83ec179ba0..f8537a85bd 100644 --- a/tool/mkkeywordhash.c +++ b/tool/mkkeywordhash.c @@ -381,6 +381,14 @@ static void reorder(int *pFrom){ reorder(&aKeywordTable[i].iNext); } +/* Parameter to the hash function +*/ +#define HASH_OP ^ +#define HASH_CC '^' +#define HASH_C0 4 +#define HASH_C1 3 +#define HASH_C2 1 + /* ** This routine does the work. The generated code is printed on standard ** output. @@ -411,8 +419,9 @@ int main(int argc, char **argv){ assert( p->lenzOrigName) ); memcpy(p->zOrigName, p->zName, p->len+1); totalLen += p->len; - p->hash = (charMap(p->zName[0])*4) ^ - (charMap(p->zName[p->len-1])*3) ^ (p->len*1); + p->hash = (charMap(p->zName[0])*HASH_C0) HASH_OP + (charMap(p->zName[p->len-1])*HASH_C1) HASH_OP + (p->len*HASH_C2); p->id = i+1; } @@ -648,8 +657,9 @@ int main(int argc, char **argv){ printf(" int i, j;\n"); printf(" const char *zKW;\n"); printf(" if( n>=2 ){\n"); - printf(" i = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n) %% %d;\n", - bestSize); + printf(" i = ((charMap(z[0])*%d) %c", HASH_C0, HASH_CC); + printf(" (charMap(z[n-1])*%d) %c", HASH_C1, HASH_CC); + printf(" n*%d) %% %d;\n", HASH_C2, bestSize); printf(" for(i=((int)aKWHash[i])-1; i>=0; i=((int)aKWNext[i])-1){\n"); printf(" if( aKWLen[i]!=n ) continue;\n"); printf(" zKW = &zKWText[aKWOffset[i]];\n"); From 0fa433b40c6609e9cc8b64e9b221c091f6343457 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 2 Dec 2020 16:23:05 +0000 Subject: [PATCH 014/257] Improve performance for fts5 column filters that filter for more than one column. e.g. "{col1 col2 col3}:phrase". FossilOrigin-Name: d8de2f236d43a88fac7550a0451951dd5a945eb304e32f82e662479cea7c2684 --- ext/fts5/fts5_index.c | 119 +++++++++++++++++++++--------------------- manifest | 14 ++--- manifest.uuid | 2 +- 3 files changed, 67 insertions(+), 68 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index f83488e2f6..0b35eee597 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -3133,66 +3133,72 @@ static void fts5SegiterPoslist( } /* -** IN/OUT parameter (*pa) points to a position list n bytes in size. If -** the position list contains entries for column iCol, then (*pa) is set -** to point to the sub-position-list for that column and the number of -** bytes in it returned. Or, if the argument position list does not -** contain any entries for column iCol, return 0. +** Parameter pPos points to a buffer containing a position list, size nPos. +** This function filters it according to pColset (which must be non-NULL) +** and sets pIter->base.pData/nData to point to the new position list. +** If memory is required for the new position list, use buffer pIter->poslist. +** Or, if the new position list is a contiguous subset of the input, set +** pIter->base.pData/nData to point directly to it. +** +** This function is a no-op if *pRc is other than SQLITE_OK when it is +** called. If an OOM error is encountered, *pRc is set to SQLITE_NOMEM +** before returning. */ -static int fts5IndexExtractCol( - const u8 **pa, /* IN/OUT: Pointer to poslist */ - int n, /* IN: Size of poslist in bytes */ - int iCol /* Column to extract from poslist */ -){ - int iCurrent = 0; /* Anything before the first 0x01 is col 0 */ - const u8 *p = *pa; - const u8 *pEnd = &p[n]; /* One byte past end of position list */ - - while( iCol>iCurrent ){ - /* Advance pointer p until it points to pEnd or an 0x01 byte that is - ** not part of a varint. Note that it is not possible for a negative - ** or extremely large varint to occur within an uncorrupted position - ** list. So the last byte of each varint may be assumed to have a clear - ** 0x80 bit. */ - while( *p!=0x01 ){ - while( *p++ & 0x80 ); - if( p>=pEnd ) return 0; - } - *pa = p++; - iCurrent = *p++; - if( iCurrent & 0x80 ){ - p--; - p += fts5GetVarint32(p, iCurrent); - } - } - if( iCol!=iCurrent ) return 0; - - /* Advance pointer p until it points to pEnd or an 0x01 byte that is - ** not part of a varint */ - while( pnCol; i++){ - const u8 *pSub = pPos; - int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]); - if( nSub ){ - fts5BufferAppendBlob(pRc, pBuf, nSub, pSub); + const u8 *p = pPos; + const u8 *aCopy = p; + const u8 *pEnd = &p[nPos]; /* One byte past end of position list */ + int i = 0; + int iCurrent = 0; + + if( pColset->nCol>1 && sqlite3Fts5BufferSize(pRc, &pIter->poslist, nPos) ){ + return; + } + + while( 1 ){ + while( pColset->aiCol[i]nCol ){ + pIter->base.pData = pIter->poslist.p; + pIter->base.nData = pIter->poslist.n; + return; + } + } + + /* Advance pointer p until it points to pEnd or an 0x01 byte that is + ** not part of a varint */ + while( paiCol[i]==iCurrent ){ + if( pColset->nCol==1 ){ + pIter->base.pData = aCopy; + pIter->base.nData = p-aCopy; + return; + } + fts5BufferSafeAppendBlob(&pIter->poslist, aCopy, p-aCopy); + } + if( p==pEnd ){ + pIter->base.pData = pIter->poslist.p; + pIter->base.nData = pIter->poslist.n; + return; + } + aCopy = p++; + iCurrent = *p++; + if( iCurrent & 0x80 ){ + p--; + p += fts5GetVarint32(p, iCurrent); } } } + } /* @@ -3312,16 +3318,9 @@ static void fts5IterSetOutputs_Full(Fts5Iter *pIter, Fts5SegIter *pSeg){ /* All data is stored on the current page. Populate the output ** variables to point into the body of the page object. */ const u8 *a = &pSeg->pLeaf->p[pSeg->iLeafOffset]; - if( pColset->nCol==1 ){ - pIter->base.nData = fts5IndexExtractCol(&a, pSeg->nPos,pColset->aiCol[0]); - pIter->base.pData = a; - }else{ - int *pRc = &pIter->pIndex->rc; - fts5BufferZero(&pIter->poslist); - fts5IndexExtractColset(pRc, pColset, a, pSeg->nPos, &pIter->poslist); - pIter->base.pData = pIter->poslist.p; - pIter->base.nData = pIter->poslist.n; - } + int *pRc = &pIter->pIndex->rc; + fts5BufferZero(&pIter->poslist); + fts5IndexExtractColset(pRc, pColset, a, pSeg->nPos, pIter); }else{ /* The data is distributed over two or more pages. Copy it into the ** Fts5Iter.poslist buffer and then set the output pointer to point diff --git a/manifest b/manifest index 5a6220aaaf..01d95f9e12 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Parameterize\sthe\shash\sfunction\sin\smkkeywordhash.c.\s\sThis\swas\san\sattempt\sto\nfind\sa\sbetter\shash\sfunction,\swhich\sturned\sout\sto\snot\sbe\ssuccessful. -D 2020-12-02T02:58:05.804 +C Improve\sperformance\sfor\sfts5\scolumn\sfilters\sthat\sfilter\sfor\smore\sthan\sone\scolumn.\se.g.\s"{col1\scol2\scol3}:phrase". +D 2020-12-02T16:23:05.119 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -119,7 +119,7 @@ F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6 F ext/fts5/fts5_config.c be54f44fca491e96c6923a4b9a736f2da2b13811600eb6e38d1bcc91c4ea2e61 F ext/fts5/fts5_expr.c e527e3a7410393075598cec544e3831798a8c88b3e8878e2cfb7cb147113e925 F ext/fts5/fts5_hash.c 1aa93c9b5f461afba66701ee226297dc78402b3bdde81e90a10de5fe3df14959 -F ext/fts5/fts5_index.c 9f152a596df3a2227ddd59adb82549c2b6858ab36bc1d26fd8933f43d3d63d36 +F ext/fts5/fts5_index.c 728cb3b5dd5dffec055185ac89bdd441c97cd16de72c6dba8a85c7762cafa68f F ext/fts5/fts5_main.c b4e4931c7fcc9acfa0c3b8b5e5e80b5b424b8d9207aae3a22b674bd35ccf149d F ext/fts5/fts5_storage.c 58ba71e6cd3d43a5735815e7956ee167babb4d2cbfe206905174792af4d09d75 F ext/fts5/fts5_tcl.c 39bcbae507f594aad778172fa914cad0f585bf92fd3b078c686e249282db0d95 @@ -1886,7 +1886,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 edbabaa30823db7c7d169cb93722b5f74bc711359984fb7e139ca9d10fe7dae4 -R c0ed84786324d0934b9713477bd4d8aa -U drh -Z adef5cc1a128c4fbf04c3cd6ce9dd431 +P 2195d731f51a18f917c4299d8f4c7ee7c139c2527f62869d6da171a6d1d89ea6 +R 84d1ef02dfda4edec69fcccc96c127a4 +U dan +Z 1f4e3f795e1d9fc6eeffa6c390d6646c diff --git a/manifest.uuid b/manifest.uuid index a48bace843..5f2c9d4301 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2195d731f51a18f917c4299d8f4c7ee7c139c2527f62869d6da171a6d1d89ea6 \ No newline at end of file +d8de2f236d43a88fac7550a0451951dd5a945eb304e32f82e662479cea7c2684 \ No newline at end of file From f30bbcec900bfc258ccb072f09065a72d5c6dcc0 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 2 Dec 2020 18:27:48 +0000 Subject: [PATCH 015/257] Fix the ".open" command in the CLI so that it accepts command-line options both before and after the filename. FossilOrigin-Name: d330bf0c02e67f70f49496e4b1e484bb4e876622becc6a062b2aefbd585d0117 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c.in | 15 ++++++++++----- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 01d95f9e12..41892ddfab 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\sperformance\sfor\sfts5\scolumn\sfilters\sthat\sfilter\sfor\smore\sthan\sone\scolumn.\se.g.\s"{col1\scol2\scol3}:phrase". -D 2020-12-02T16:23:05.119 +C Fix\sthe\s".open"\scommand\sin\sthe\sCLI\sso\sthat\sit\saccepts\scommand-line\soptions\nboth\sbefore\sand\safter\sthe\sfilename. +D 2020-12-02T18:27:48.742 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -540,7 +540,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 31387e56f5e6d1adc798dfa04b946001289a61e65acf4615f7b7130f121f3b9c -F src/shell.c.in 55113760ae91a05c6ce4558714a1c8fc7a44bf266f735de6e71ea40f79e69830 +F src/shell.c.in 771311fec4e9c7e06af2610f535343bd211ff34f615a72bf5bafe1bf4f63383e F src/sqlite.h.in 1dbae67057d999161c30b21c3c7fa45d51f665b510d397dd1b7d671287d772b0 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e @@ -1886,7 +1886,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 2195d731f51a18f917c4299d8f4c7ee7c139c2527f62869d6da171a6d1d89ea6 -R 84d1ef02dfda4edec69fcccc96c127a4 -U dan -Z 1f4e3f795e1d9fc6eeffa6c390d6646c +P d8de2f236d43a88fac7550a0451951dd5a945eb304e32f82e662479cea7c2684 +R 514e397878ccd7b216cdd7d01f670ef0 +U drh +Z 0bdc6b19b24e33aa04196376633bb49f diff --git a/manifest.uuid b/manifest.uuid index 5f2c9d4301..935ed2e4cf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d8de2f236d43a88fac7550a0451951dd5a945eb304e32f82e662479cea7c2684 \ No newline at end of file +d330bf0c02e67f70f49496e4b1e484bb4e876622becc6a062b2aefbd585d0117 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 2d98d23c2d..e3b7e78283 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -8680,9 +8680,9 @@ static int do_meta_command(char *zLine, ShellState *p){ #endif /* SQLITE_DEBUG */ if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){ - char *zNewFilename; /* Name of the database file to open */ - int iName = 1; /* Index in azArg[] of the filename */ - int newFlag = 0; /* True to delete file before opening */ + char *zNewFilename = 0; /* Name of the database file to open */ + 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); close_db(p->db); @@ -8694,7 +8694,7 @@ static int do_meta_command(char *zLine, ShellState *p){ p->openFlags = 0; p->szMax = 0; /* Check for command-line arguments */ - for(iName=1; iNameiName ? sqlite3_mprintf("%s", azArg[iName]) : 0; if( zNewFilename || p->openMode==SHELL_OPEN_HEXDB ){ if( newFlag ) shellDeleteFile(zNewFilename); p->zDbFilename = zNewFilename; From 64f1ef6abd699f929f9b32a5761a088667f65498 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 2 Dec 2020 19:08:15 +0000 Subject: [PATCH 016/257] Allow a search for an N character prefix in fts5 to use a prefix index of size N+1, if no prefix index of size N exists. FossilOrigin-Name: 78a7801d8fc9e58a62e5168e35b52b7440340549123fc6a537e2abd571f6fe7b --- ext/fts5/fts5_index.c | 32 ++++++++++++++++--- ext/fts5/test/fts5prefix2.test | 57 ++++++++++++++++++++++++++++++++++ manifest | 15 ++++----- manifest.uuid | 2 +- 4 files changed, 94 insertions(+), 12 deletions(-) create mode 100644 ext/fts5/test/fts5prefix2.test diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 0b35eee597..60dc03c3b4 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -5082,7 +5082,8 @@ static void fts5MergePrefixLists( static void fts5SetupPrefixIter( Fts5Index *p, /* Index to read from */ int bDesc, /* True for "ORDER BY rowid DESC" */ - const u8 *pToken, /* Buffer containing prefix to match */ + int iIdx, /* Index to scan for data */ + u8 *pToken, /* Buffer containing prefix to match */ int nToken, /* Size of buffer pToken in bytes */ Fts5Colset *pColset, /* Restrict matches to these columns */ Fts5Iter **ppIter /* OUT: New iterator */ @@ -5116,6 +5117,27 @@ static void fts5SetupPrefixIter( int bNewTerm = 1; memset(&doclist, 0, sizeof(doclist)); + if( iIdx!=0 ){ + int dummy = 0; + const int f2 = FTS5INDEX_QUERY_SKIPEMPTY|FTS5INDEX_QUERY_NOOUTPUT; + pToken[0] = FTS5_MAIN_PREFIX; + fts5MultiIterNew(p, pStruct, f2, pColset, pToken, nToken, -1, 0, &p1); + fts5IterSetOutputCb(&p->rc, p1); + for(; + fts5MultiIterEof(p, p1)==0; + fts5MultiIterNext2(p, p1, &dummy) + ){ + Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ]; + p1->xSetOutputs(p1, pSeg); + if( p1->base.nData ){ + xAppend(p, p1->base.iRowid-iLastRowid, p1, &doclist); + iLastRowid = p1->base.iRowid; + } + } + fts5MultiIterFree(p1); + } + + pToken[0] = FTS5_MAIN_PREFIX + iIdx; fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1); fts5IterSetOutputCb(&p->rc, p1); for( /* no-op */ ; @@ -5411,6 +5433,7 @@ int sqlite3Fts5IndexQuery( if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){ int iIdx = 0; /* Index to search */ + int iPrefixIdx = 0; /* +1 prefix index */ if( nToken ) memcpy(&buf.p[1], pToken, nToken); /* Figure out which index to search and set iIdx accordingly. If this @@ -5432,7 +5455,9 @@ int sqlite3Fts5IndexQuery( if( flags & FTS5INDEX_QUERY_PREFIX ){ int nChar = fts5IndexCharlen(pToken, nToken); for(iIdx=1; iIdx<=pConfig->nPrefix; iIdx++){ - if( pConfig->aPrefix[iIdx-1]==nChar ) break; + int nIdxChar = pConfig->aPrefix[iIdx-1]; + if( nIdxChar==nChar ) break; + if( nIdxChar==nChar+1 ) iPrefixIdx = iIdx; } } @@ -5449,8 +5474,7 @@ int sqlite3Fts5IndexQuery( }else{ /* Scan multiple terms in the main index */ int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0; - buf.p[0] = FTS5_MAIN_PREFIX; - fts5SetupPrefixIter(p, bDesc, buf.p, nToken+1, pColset, &pRet); + fts5SetupPrefixIter(p, bDesc, iPrefixIdx, buf.p, nToken+1, pColset,&pRet); assert( p->rc!=SQLITE_OK || pRet->pColset==0 ); fts5IterSetOutputCb(&p->rc, pRet); if( p->rc==SQLITE_OK ){ diff --git a/ext/fts5/test/fts5prefix2.test b/ext/fts5/test/fts5prefix2.test new file mode 100644 index 0000000000..bf16e81a73 --- /dev/null +++ b/ext/fts5/test/fts5prefix2.test @@ -0,0 +1,57 @@ +# 2020 Dec 3 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file contains tests focused on prefix indexes. +# + +source [file join [file dirname [info script]] fts5_common.tcl] +set testprefix fts5prefix2 + +# If SQLITE_ENABLE_FTS5 is defined, omit this file. +ifcapable !fts5 { + finish_test + return +} + +foreach p {3 2 1} { + reset_db + do_execsql_test 1.$p.0 " + CREATE VIRTUAL TABLE t1 USING fts5(xyz, prefix=$p); + " + do_execsql_test 1.$p.1 { + INSERT INTO t1 VALUES + ('May you do good and not evil.'), + ('May you find forgiveness for yourself and forgive others.'), + ('May you share freely, never taking more than you give f.'); + } + + do_execsql_test 1.$p.2 { + SELECT highlight(t1, 0, '[', ']') FROM t1('f*'); + } { + {May you [find] [forgiveness] [for] yourself and [forgive] others.} + {May you share [freely], never taking more than you give [f].} + } +} + +do_execsql_test 2.0 { + CREATE VIRTUAL TABLE t2 USING fts5(one, prefix=3); + INSERT INTO t2 VALUES('top'); + INSERT INTO t2 VALUES('to'); + INSERT INTO t2 VALUES('tommy'); +} + +do_execsql_test 2.1 { + SELECT * FROM t2('to*'); +} {top to tommy} + + + +finish_test diff --git a/manifest b/manifest index 41892ddfab..6daed48465 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\s".open"\scommand\sin\sthe\sCLI\sso\sthat\sit\saccepts\scommand-line\soptions\nboth\sbefore\sand\safter\sthe\sfilename. -D 2020-12-02T18:27:48.742 +C Allow\sa\ssearch\sfor\san\sN\scharacter\sprefix\sin\sfts5\sto\suse\sa\sprefix\sindex\sof\ssize\sN+1,\sif\sno\sprefix\sindex\sof\ssize\sN\sexists. +D 2020-12-02T19:08:15.960 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -119,7 +119,7 @@ F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6 F ext/fts5/fts5_config.c be54f44fca491e96c6923a4b9a736f2da2b13811600eb6e38d1bcc91c4ea2e61 F ext/fts5/fts5_expr.c e527e3a7410393075598cec544e3831798a8c88b3e8878e2cfb7cb147113e925 F ext/fts5/fts5_hash.c 1aa93c9b5f461afba66701ee226297dc78402b3bdde81e90a10de5fe3df14959 -F ext/fts5/fts5_index.c 728cb3b5dd5dffec055185ac89bdd441c97cd16de72c6dba8a85c7762cafa68f +F ext/fts5/fts5_index.c e4650549c755acadc3974c69952f40867181d6cb7583ab24e9da72354e0f58ad F ext/fts5/fts5_main.c b4e4931c7fcc9acfa0c3b8b5e5e80b5b424b8d9207aae3a22b674bd35ccf149d F ext/fts5/fts5_storage.c 58ba71e6cd3d43a5735815e7956ee167babb4d2cbfe206905174792af4d09d75 F ext/fts5/fts5_tcl.c 39bcbae507f594aad778172fa914cad0f585bf92fd3b078c686e249282db0d95 @@ -204,6 +204,7 @@ F ext/fts5/test/fts5plan.test 79d35b5e83bbdcba48d946a7f008df161f6b0ede1a966892d0 F ext/fts5/test/fts5porter.test 8d08010c28527db66bc3feebd2b8767504aaeb9b101a986342fa7833d49d0d15 F ext/fts5/test/fts5porter2.test 0d251a673f02fa13ca7f011654873b3add20745f7402f108600a23e52d8c7457 F ext/fts5/test/fts5prefix.test a0fa67b06650f2deaa7bf27745899d94e0fb547ad9ecbd08bfad98c04912c056 +F ext/fts5/test/fts5prefix2.test 3847ce46f70b82d61c6095103a9d7c53f2952c40a4704157bc079c04d9c8b18b F ext/fts5/test/fts5query.test ac363b17a442620bb0780e93c24f16a5f963dfe2f23dc85647b869efcfada728 F ext/fts5/test/fts5rank.test c9fd4a1e36b4fa92d572ec13d846469b97da249d1c2f7fd3ee7e017ce46f2416 F ext/fts5/test/fts5rebuild.test 55d6f17715cddbf825680dd6551efbc72ed916d8cf1cde40a46fc5d785b451e7 @@ -1886,7 +1887,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 d8de2f236d43a88fac7550a0451951dd5a945eb304e32f82e662479cea7c2684 -R 514e397878ccd7b216cdd7d01f670ef0 -U drh -Z 0bdc6b19b24e33aa04196376633bb49f +P d330bf0c02e67f70f49496e4b1e484bb4e876622becc6a062b2aefbd585d0117 +R f01d1880d7623e5e268039319f8ab01a +U dan +Z c03fc1ff589c028c9b59c035c598373d diff --git a/manifest.uuid b/manifest.uuid index 935ed2e4cf..341a8fec64 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d330bf0c02e67f70f49496e4b1e484bb4e876622becc6a062b2aefbd585d0117 \ No newline at end of file +78a7801d8fc9e58a62e5168e35b52b7440340549123fc6a537e2abd571f6fe7b \ No newline at end of file From 4338000d479d9826b8baf4870eeebd76f9417b0f Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 2 Dec 2020 20:07:49 +0000 Subject: [PATCH 017/257] Prevent potential segfault in the sqlite-expert idxPopulateStat1 context cleanup code. FossilOrigin-Name: c24f13448b5a55f45b4d4786a878fa73fe3395b5724f3bc2eea22e5e2b074353 --- ext/expert/sqlite3expert.c | 8 +++++--- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/ext/expert/sqlite3expert.c b/ext/expert/sqlite3expert.c index c2a6fe3ba9..5c13423204 100644 --- a/ext/expert/sqlite3expert.c +++ b/ext/expert/sqlite3expert.c @@ -1721,10 +1721,12 @@ static int idxPopulateStat1(sqlite3expert *p, char **pzErr){ idxFinalize(&rc, pIndexXInfo); idxFinalize(&rc, pWrite); - for(i=0; inSlot; i++){ - sqlite3_free(pCtx->aSlot[i].z); + if( pCtx ){ + for(i=0; inSlot; i++){ + sqlite3_free(pCtx->aSlot[i].z); + } + sqlite3_free(pCtx); } - sqlite3_free(pCtx); if( rc==SQLITE_OK ){ rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_schema", 0, 0, 0); diff --git a/manifest b/manifest index 6daed48465..2b8f519af1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sa\ssearch\sfor\san\sN\scharacter\sprefix\sin\sfts5\sto\suse\sa\sprefix\sindex\sof\ssize\sN+1,\sif\sno\sprefix\sindex\sof\ssize\sN\sexists. -D 2020-12-02T19:08:15.960 +C Prevent\spotential\ssegfault\sin\sthe\ssqlite-expert\sidxPopulateStat1\scontext\scleanup\scode. +D 2020-12-02T20:07:49.067 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -51,7 +51,7 @@ F ext/async/sqlite3async.h 46b47c79357b97ad85d20d2795942c0020dc20c532114a4980828 F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3 F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4 F ext/expert/expert1.test dba6e752cc701621771f925f3872b183fa688f7b4a9f4822631fc02bdbffc45a -F ext/expert/sqlite3expert.c 2778d9f06b3a8bfa859cb6b75b82f004477bf5dd78edd17d954319750ca963f3 +F ext/expert/sqlite3expert.c 216e250acc54b8aaa9ff5c1e1b2256788abc3994dd1d757626102718122e6a91 F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72 F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e @@ -1887,7 +1887,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 d330bf0c02e67f70f49496e4b1e484bb4e876622becc6a062b2aefbd585d0117 -R f01d1880d7623e5e268039319f8ab01a -U dan -Z c03fc1ff589c028c9b59c035c598373d +P 78a7801d8fc9e58a62e5168e35b52b7440340549123fc6a537e2abd571f6fe7b +R 0dc0314b410c18e6ec4d64c3768bbb3e +U mistachkin +Z 5b4a67e54f42477a3294e08cc064af19 diff --git a/manifest.uuid b/manifest.uuid index 341a8fec64..ed84246eec 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -78a7801d8fc9e58a62e5168e35b52b7440340549123fc6a537e2abd571f6fe7b \ No newline at end of file +c24f13448b5a55f45b4d4786a878fa73fe3395b5724f3bc2eea22e5e2b074353 \ No newline at end of file From 0b1e70c4cea7f51bfd914b1bd3b7d05b978031f1 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 3 Dec 2020 14:21:26 +0000 Subject: [PATCH 018/257] Enhance the generate_series() table-valued function to support negative step values. FossilOrigin-Name: 9b60fc48706bb77b2d4fe27a7b5834a6dc229b4051a9285032da578e4f2849e6 --- ext/misc/series.c | 16 +++++++++++++--- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/ext/misc/series.c b/ext/misc/series.c index 092383e57e..a4e92ace88 100644 --- a/ext/misc/series.c +++ b/ext/misc/series.c @@ -247,7 +247,8 @@ static int seriesEof(sqlite3_vtab_cursor *cur){ ** 4: step=VALUE ** ** Also, if bit 8 is set, that means that the series should be output -** in descending order rather than in ascending order. +** in descending order rather than in ascending order. If bit 16 is +** set, then output must appear in ascending order. ** ** This routine should initialize the cursor and position it so that it ** is pointing at the first row, or pointing off the end of the table @@ -273,7 +274,12 @@ static int seriesFilter( } if( idxNum & 4 ){ pCur->iStep = sqlite3_value_int64(argv[i++]); - if( pCur->iStep<1 ) pCur->iStep = 1; + if( pCur->iStep==0 ){ + pCur->iStep = 1; + }else if( pCur->iStep<0 ){ + pCur->iStep = -pCur->iStep; + if( (idxNum & 16)==0 ) idxNum |= 8; + } }else{ pCur->iStep = 1; } @@ -367,7 +373,11 @@ static int seriesBestIndex( pIdxInfo->estimatedCost = (double)(2 - ((idxNum&4)!=0)); pIdxInfo->estimatedRows = 1000; if( pIdxInfo->nOrderBy==1 ){ - if( pIdxInfo->aOrderBy[0].desc ) idxNum |= 8; + if( pIdxInfo->aOrderBy[0].desc ){ + idxNum |= 8; + }else{ + idxNum |= 16; + } pIdxInfo->orderByConsumed = 1; } }else{ diff --git a/manifest b/manifest index 2b8f519af1..0ef04d21b3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Prevent\spotential\ssegfault\sin\sthe\ssqlite-expert\sidxPopulateStat1\scontext\scleanup\scode. -D 2020-12-02T20:07:49.067 +C Enhance\sthe\sgenerate_series()\stable-valued\sfunction\sto\ssupport\snegative\nstep\svalues. +D 2020-12-03T14:21:26.970 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 246244c714267f303df76acf73dcf110cf2eaf076896aaaba8db6d6d21a1 F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946 -F ext/misc/series.c fbb8e6be97b54d10d2f235e163fa2f53a8f4421c66ebd532a233fd1c69c3f522 +F ext/misc/series.c c6bd5d249e5199a1b55aeee4d0e6576ff3a68702fc475dbd64503a32903516c7 F ext/misc/sha1.c c8f2253c8792ffab9517695ea7d88c079f0395a5505eefef5c8198fe184ed5ac F ext/misc/shathree.c 135b7c145db4a09b1650c3e7aff9cb538763a9a361e834c015dd1aaf8d5c9a00 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 @@ -1887,7 +1887,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 78a7801d8fc9e58a62e5168e35b52b7440340549123fc6a537e2abd571f6fe7b -R 0dc0314b410c18e6ec4d64c3768bbb3e -U mistachkin -Z 5b4a67e54f42477a3294e08cc064af19 +P c24f13448b5a55f45b4d4786a878fa73fe3395b5724f3bc2eea22e5e2b074353 +R ec29377d1f16dae2ba3a716418cfeb56 +U drh +Z 6d9cf1c7027aa6d139c9ca5d0fe86df8 diff --git a/manifest.uuid b/manifest.uuid index ed84246eec..7ffe25d96e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c24f13448b5a55f45b4d4786a878fa73fe3395b5724f3bc2eea22e5e2b074353 \ No newline at end of file +9b60fc48706bb77b2d4fe27a7b5834a6dc229b4051a9285032da578e4f2849e6 \ No newline at end of file From 1de03abb0305cfc4aefa9f9a5496070ba8f26774 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 3 Dec 2020 19:25:06 +0000 Subject: [PATCH 019/257] Do not simulate OOM faults on the SQLITE_FCNTL_CKPT_START and SQLITE_FCNTL_CKPT_DONE file-controls, as those are write-only and the return value is always ignored. FossilOrigin-Name: 62a2d394835276fabc0f1df2302605a700b2244775bf2e35e86529df8e40a0da --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os.c | 9 ++++++++- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 0ef04d21b3..efb41c979a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\sgenerate_series()\stable-valued\sfunction\sto\ssupport\snegative\nstep\svalues. -D 2020-12-03T14:21:26.970 +C Do\snot\ssimulate\sOOM\sfaults\son\sthe\sSQLITE_FCNTL_CKPT_START\sand\nSQLITE_FCNTL_CKPT_DONE\sfile-controls,\sas\sthose\sare\swrite-only\sand\nthe\sreturn\svalue\sis\salways\signored. +D 2020-12-03T19:25:06.815 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -520,7 +520,7 @@ F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4 F src/mutex_unix.c dd2b3f1cc1863079bc1349ac0fec395a500090c4fe4e11ab775310a49f2f956d F src/mutex_w32.c caa50e1c0258ac4443f52e00fe8aaea73b6d0728bd8856bedfff822cae418541 F src/notify.c 89a97dc854c3aa62ad5f384ef50c5a4a11d70fcc69f86de3e991573421130ed6 -F src/os.c 80e4cf3e5da06be03ca641661e331ce60eeeeabf0d7354dbb1c0e166d0eedbbe +F src/os.c 2d6e646370b1aa78942c68d7edf124e518963adf4a90bce87f365a5a5495529a F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 @@ -1887,7 +1887,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 c24f13448b5a55f45b4d4786a878fa73fe3395b5724f3bc2eea22e5e2b074353 -R ec29377d1f16dae2ba3a716418cfeb56 +P 9b60fc48706bb77b2d4fe27a7b5834a6dc229b4051a9285032da578e4f2849e6 +R f5fab051df652e60eae81cceafe92f35 U drh -Z 6d9cf1c7027aa6d139c9ca5d0fe86df8 +Z b8af11f99fdf7fdf74f4bc2f82c020b8 diff --git a/manifest.uuid b/manifest.uuid index 7ffe25d96e..f21dc089ae 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9b60fc48706bb77b2d4fe27a7b5834a6dc229b4051a9285032da578e4f2849e6 \ No newline at end of file +62a2d394835276fabc0f1df2302605a700b2244775bf2e35e86529df8e40a0da \ No newline at end of file diff --git a/src/os.c b/src/os.c index a1a276f433..693d78dc91 100644 --- a/src/os.c +++ b/src/os.c @@ -129,6 +129,8 @@ int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ #ifdef SQLITE_TEST if( op!=SQLITE_FCNTL_COMMIT_PHASETWO && op!=SQLITE_FCNTL_LOCK_TIMEOUT + && op!=SQLITE_FCNTL_CKPT_DONE + && op!=SQLITE_FCNTL_CKPT_START ){ /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite ** is using a regular VFS, it is called after the corresponding @@ -139,7 +141,12 @@ int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ ** The core must call OsFileControl() though, not OsFileControlHint(), ** as if a custom VFS (e.g. zipvfs) returns an error here, it probably ** means the commit really has failed and an error should be returned - ** to the user. */ + ** to the user. + ** + ** The CKPT_DONE and CKPT_START file-controls are write-only signals + ** to the cksumvfs. Their return code is meaningless and is ignored + ** by the SQLite core, so there is no point in simulating OOMs for them. + */ DO_OS_MALLOC_TEST(id); } #endif From 3190b88e756baa82b7e41bc1ca721192784d7bcd Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 3 Dec 2020 21:22:37 +0000 Subject: [PATCH 020/257] When merging prefix lists in fts5, use 16-way merges instead of 2-way merges. This faster. FossilOrigin-Name: 026a93508ec392ca5cd2578ae9eab64974f58beccda088e10d4cc951f237632f --- ext/fts5/fts5_index.c | 372 ++++++++++++++++++-------------- ext/fts5/test/fts5corrupt3.test | 2 +- ext/fts5/test/fts5corrupt4.test | 2 + manifest | 18 +- manifest.uuid | 2 +- 5 files changed, 224 insertions(+), 172 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 60dc03c3b4..88709f2c35 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -3069,7 +3069,7 @@ static void fts5ChunkIterate( int pgno = pSeg->iLeafPgno; int pgnoSave = 0; - /* This function does notmwork with detail=none databases. */ + /* This function does not work with detail=none databases. */ assert( p->pConfig->eDetail!=FTS5_DETAIL_NONE ); if( (pSeg->flags & FTS5_SEGITER_REVERSE)==0 ){ @@ -3082,6 +3082,9 @@ static void fts5ChunkIterate( fts5DataRelease(pData); if( nRem<=0 ){ break; + }else if( pSeg->pSeg==0 ){ + p->rc = FTS5_CORRUPT; + return; }else{ pgno++; pData = fts5LeafRead(p, FTS5_SEGMENT_ROWID(pSeg->pSeg->iSegid, pgno)); @@ -4803,7 +4806,7 @@ static void fts5AppendPoslist( static void fts5DoclistIterNext(Fts5DoclistIter *pIter){ u8 *p = pIter->aPoslist + pIter->nSize + pIter->nPoslist; - assert( pIter->aPoslist ); + assert( pIter->aPoslist || (p==0 && pIter->aPoslist==0) ); if( p>=pIter->aEof ){ pIter->aPoslist = 0; }else{ @@ -4887,16 +4890,19 @@ static void fts5NextRowid(Fts5Buffer *pBuf, int *piOff, i64 *piRowid){ static void fts5MergeRowidLists( Fts5Index *p, /* FTS5 backend object */ Fts5Buffer *p1, /* First list to merge */ - Fts5Buffer *p2 /* Second list to merge */ + int nBuf, /* Number of entries in apBuf[] */ + Fts5Buffer *aBuf /* Array of other lists to merge into p1 */ ){ int i1 = 0; int i2 = 0; i64 iRowid1 = 0; i64 iRowid2 = 0; i64 iOut = 0; + Fts5Buffer *p2 = &aBuf[0]; Fts5Buffer out; memset(&out, 0, sizeof(out)); + assert( nBuf==1 ); sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n); if( p->rc ) return; @@ -4923,160 +4929,189 @@ static void fts5MergeRowidLists( fts5BufferFree(&out); } +typedef struct PrefixMerger PrefixMerger; +struct PrefixMerger { + Fts5DoclistIter iter; /* Doclist iterator */ + i64 iPos; /* For iterating through a position list */ + int iOff; + u8 *aPos; + PrefixMerger *pNext; /* Next in docid/poslist order */ +}; + +static void fts5PrefixMergerInsertByRowid( + PrefixMerger **ppHead, + PrefixMerger *p +){ + if( p->iter.aPoslist ){ + PrefixMerger **pp = ppHead; + while( *pp && p->iter.iRowid>(*pp)->iter.iRowid ){ + pp = &(*pp)->pNext; + } + p->pNext = *pp; + *pp = p; + } +} + +static void fts5PrefixMergerInsertByPosition( + PrefixMerger **ppHead, + PrefixMerger *p +){ + if( p->iPos>=0 ){ + PrefixMerger **pp = ppHead; + while( *pp && p->iPos>(*pp)->iPos ){ + pp = &(*pp)->pNext; + } + p->pNext = *pp; + *pp = p; + } +} + + /* -** Buffers p1 and p2 contain doclists. This function merges the content -** of the two doclists together and sets buffer p1 to the result before -** returning. -** -** If an error occurs, an error code is left in p->rc. If an error has -** already occurred, this function is a no-op. +** Array aBuf[] contains nBuf doclists. These are all merged in with the +** doclist in buffer p1. */ static void fts5MergePrefixLists( Fts5Index *p, /* FTS5 backend object */ Fts5Buffer *p1, /* First list to merge */ - Fts5Buffer *p2 /* Second list to merge */ + int nBuf, /* Number of buffers in array aBuf[] */ + Fts5Buffer *aBuf /* Other lists to merge in */ ){ - if( p2->n ){ - i64 iLastRowid = 0; - Fts5DoclistIter i1; - Fts5DoclistIter i2; - Fts5Buffer out = {0, 0, 0}; - Fts5Buffer tmp = {0, 0, 0}; +#define fts5PrefixMergerNextPosition(p) \ + sqlite3Fts5PoslistNext64((p)->aPos,(p)->iter.nPoslist,&(p)->iOff,&(p)->iPos); +#define FTS5_MERGE_NLIST 16 + PrefixMerger aMerger[FTS5_MERGE_NLIST]; + PrefixMerger *pHead = 0; + int i; + int nOut = 0; + Fts5Buffer out = {0, 0, 0}; + Fts5Buffer tmp = {0, 0, 0}; + i64 iLastRowid = 0; - /* The maximum size of the output is equal to the sum of the two - ** input sizes + 1 varint (9 bytes). The extra varint is because if the - ** first rowid in one input is a large negative number, and the first in - ** the other a non-negative number, the delta for the non-negative - ** number will be larger on disk than the literal integer value - ** was. - ** - ** Or, if the input position-lists are corrupt, then the output might - ** include up to 2 extra 10-byte positions created by interpreting -1 - ** (the value PoslistNext64() uses for EOF) as a position and appending - ** it to the output. This can happen at most once for each input - ** position-list, hence two 10 byte paddings. */ - if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n + 9+10+10) ) return; - fts5DoclistIterInit(p1, &i1); - fts5DoclistIterInit(p2, &i2); - - while( 1 ){ - if( i1.iRowidp) + (i2.aPoslist-p2->p)+9+10+10) ); - } - else if( i2.iRowid!=i1.iRowid ){ - /* Copy entry from i2 */ - fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid); - fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.nPoslist+i2.nSize); - fts5DoclistIterNext(&i2); - if( i2.aPoslist==0 ) break; - assert( out.n<=((i1.aPoslist-p1->p) + (i2.aPoslist-p2->p)+9+10+10) ); - } - else{ - /* Merge the two position lists. */ - i64 iPos1 = 0; - i64 iPos2 = 0; - int iOff1 = 0; - int iOff2 = 0; - u8 *a1 = &i1.aPoslist[i1.nSize]; - u8 *a2 = &i2.aPoslist[i2.nSize]; - int nCopy; - u8 *aCopy; - - i64 iPrev = 0; - Fts5PoslistWriter writer; - memset(&writer, 0, sizeof(writer)); - - /* See the earlier comment in this function for an explanation of why - ** corrupt input position lists might cause the output to consume - ** at most 20 bytes of unexpected space. */ - fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid); - fts5BufferZero(&tmp); - sqlite3Fts5BufferSize(&p->rc, &tmp, - i1.nPoslist + i2.nPoslist + 10 + 10 + FTS5_DATA_ZERO_PADDING - ); - if( p->rc ) break; - - sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1); - sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2); - assert_nc( iPos1>=0 && iPos2>=0 ); - - if( iPos1=0 && iPos2>=0 ){ - while( 1 ){ - if( iPos1=0 ){ - if( iPos1!=iPrev ){ - sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1); - } - aCopy = &a1[iOff1]; - nCopy = i1.nPoslist - iOff1; - }else{ - assert_nc( iPos2>=0 && iPos2!=iPrev ); - sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2); - aCopy = &a2[iOff2]; - nCopy = i2.nPoslist - iOff2; - } - if( nCopy>0 ){ - fts5BufferSafeAppendBlob(&tmp, aCopy, nCopy); - } - - /* WRITEPOSLISTSIZE */ - assert_nc( tmp.n<=i1.nPoslist+i2.nPoslist ); - assert( tmp.n<=i1.nPoslist+i2.nPoslist+10+10 ); - if( tmp.n>i1.nPoslist+i2.nPoslist ){ - if( p->rc==SQLITE_OK ) p->rc = FTS5_CORRUPT; - break; - } - fts5BufferSafeAppendVarint(&out, tmp.n * 2); - fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n); - fts5DoclistIterNext(&i1); - fts5DoclistIterNext(&i2); - assert_nc( out.n<=(p1->n+p2->n+9) ); - if( i1.aPoslist==0 || i2.aPoslist==0 ) break; - assert( out.n<=((i1.aPoslist-p1->p) + (i2.aPoslist-p2->p)+9+10+10) ); - } - } - - if( i1.aPoslist ){ - fts5MergeAppendDocid(&out, iLastRowid, i1.iRowid); - fts5BufferSafeAppendBlob(&out, i1.aPoslist, i1.aEof - i1.aPoslist); - } - else if( i2.aPoslist ){ - fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid); - fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.aEof - i2.aPoslist); - } - assert_nc( out.n<=(p1->n+p2->n+9) ); - - fts5BufferFree(p1); - fts5BufferFree(&tmp); - memset(&out.p[out.n], 0, FTS5_DATA_ZERO_PADDING); - *p1 = out; + /* Initialize a doclist-iterator for each input buffer. Arrange them in + ** a linked-list starting at pHead in ascending order of rowid. Avoid + ** linking any iterators already at EOF into the linked list at all. */ + assert( nBuf+1<=sizeof(aMerger)/sizeof(aMerger[0]) ); + memset(aMerger, 0, sizeof(PrefixMerger)*(nBuf+1)); + pHead = &aMerger[nBuf]; + fts5DoclistIterInit(p1, &pHead->iter); + for(i=0; in + 9 + 10*nBuf; + + /* The maximum size of the output is equal to the sum of the + ** input sizes + 1 varint (9 bytes). The extra varint is because if the + ** first rowid in one input is a large negative number, and the first in + ** the other a non-negative number, the delta for the non-negative + ** number will be larger on disk than the literal integer value + ** was. + ** + ** Or, if the input position-lists are corrupt, then the output might + ** include up to (nBuf+1) extra 10-byte positions created by interpreting -1 + ** (the value PoslistNext64() uses for EOF) as a position and appending + ** it to the output. This can happen at most once for each input + ** position-list, hence (nBuf+1) 10 byte paddings. */ + if( sqlite3Fts5BufferSize(&p->rc, &out, nOut) ) return; + + while( pHead ){ + fts5MergeAppendDocid(&out, iLastRowid, pHead->iter.iRowid); + + if( pHead->pNext && iLastRowid==pHead->pNext->iter.iRowid ){ + /* Merge data from two or more poslists */ + i64 iPrev = 0; + int nTmp = FTS5_DATA_ZERO_PADDING; + int nMerge = 0; + PrefixMerger *pSave = pHead; + PrefixMerger *pThis = 0; + int nTail = 0; + + pHead = 0; + while( pSave && pSave->iter.iRowid==iLastRowid ){ + PrefixMerger *pNext = pSave->pNext; + pSave->iOff = 0; + pSave->iPos = 0; + pSave->aPos = &pSave->iter.aPoslist[pSave->iter.nSize]; + fts5PrefixMergerNextPosition(pSave); + nTmp += pSave->iter.nPoslist + 10; + nMerge++; + fts5PrefixMergerInsertByPosition(&pHead, pSave); + pSave = pNext; + } + + if( pHead==0 || pHead->pNext==0 ){ + p->rc = FTS5_CORRUPT; + break; + } + + /* See the earlier comment in this function for an explanation of why + ** corrupt input position lists might cause the output to consume + ** at most nMerge*10 bytes of unexpected space. */ + if( sqlite3Fts5BufferSize(&p->rc, &tmp, nTmp+nMerge*10) ){ + break; + } + fts5BufferZero(&tmp); + + pThis = pHead; + pHead = pThis->pNext; + sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, pThis->iPos); + fts5PrefixMergerNextPosition(pThis); + fts5PrefixMergerInsertByPosition(&pHead, pThis); + + while( pHead->pNext ){ + pThis = pHead; + if( pThis->iPos!=iPrev ){ + sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, pThis->iPos); + } + fts5PrefixMergerNextPosition(pThis); + pHead = pThis->pNext; + fts5PrefixMergerInsertByPosition(&pHead, pThis); + } + + if( pHead->iPos!=iPrev ){ + sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, pHead->iPos); + } + nTail = pHead->iter.nPoslist - pHead->iOff; + + /* WRITEPOSLISTSIZE */ + assert( tmp.n+nTail<=nTmp ); + if( tmp.n+nTail>nTmp-FTS5_DATA_ZERO_PADDING ){ + if( p->rc==SQLITE_OK ) p->rc = FTS5_CORRUPT; + break; + } + fts5BufferSafeAppendVarint(&out, (tmp.n+nTail) * 2); + fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n); + if( nTail>0 ){ + fts5BufferSafeAppendBlob(&out, &pHead->aPos[pHead->iOff], nTail); + } + + pHead = pSave; + for(i=0; iiter.aPoslist && pThis->iter.iRowid==iLastRowid ){ + fts5DoclistIterNext(&pThis->iter); + fts5PrefixMergerInsertByRowid(&pHead, pThis); + } + } + + }else{ + /* Copy poslist from pHead to output */ + PrefixMerger *pThis = pHead; + Fts5DoclistIter *pI = &pThis->iter; + fts5BufferSafeAppendBlob(&out, pI->aPoslist, pI->nPoslist+pI->nSize); + fts5DoclistIterNext(pI); + pHead = pThis->pNext; + fts5PrefixMergerInsertByRowid(&pHead, pThis); + } + } + + fts5BufferFree(p1); + fts5BufferFree(&tmp); + memset(&out.p[out.n], 0, FTS5_DATA_ZERO_PADDING); + *p1 = out; } static void fts5SetupPrefixIter( @@ -5090,14 +5125,17 @@ static void fts5SetupPrefixIter( ){ Fts5Structure *pStruct; Fts5Buffer *aBuf; - const int nBuf = 32; + int nBuf = 32; + int nMerge = 1; - void (*xMerge)(Fts5Index*, Fts5Buffer*, Fts5Buffer*); + void (*xMerge)(Fts5Index*, Fts5Buffer*, int, Fts5Buffer*); void (*xAppend)(Fts5Index*, i64, Fts5Iter*, Fts5Buffer*); if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){ xMerge = fts5MergeRowidLists; xAppend = fts5AppendRowid; }else{ + nMerge = FTS5_MERGE_NLIST-1; + nBuf = nMerge*8; /* Sufficient to merge (16^8)==(2^32) lists */ xMerge = fts5MergePrefixLists; xAppend = fts5AppendPoslist; } @@ -5158,13 +5196,21 @@ static void fts5SetupPrefixIter( if( p1->base.iRowid<=iLastRowid && doclist.n>0 ){ for(i=0; p->rc==SQLITE_OK && doclist.n; i++){ - assert( ibase.iRowid; } - for(i=0; irc==SQLITE_OK ){ - xMerge(p, &doclist, &aBuf[i]); + xMerge(p, &doclist, nMerge, &aBuf[i]); + } + for(iFree=i; iFree Date: Fri, 4 Dec 2020 01:17:57 +0000 Subject: [PATCH 021/257] Alternative implementation of ".selecttrace" and ".wheretrace" that uses a test-control rather than global variables. FossilOrigin-Name: d36d6f2923a2393c751c0ac7634433453be20df7567fd914e57cbb1ae15f68b2 --- manifest | 34 +++++++++++++++++----------------- manifest.uuid | 2 +- src/global.c | 5 +++-- src/main.c | 23 ++++++++++++++++++++++- src/select.c | 26 +++++++++++++------------- src/shell.c.in | 40 ++++++++++++---------------------------- src/sqlite.h.in | 3 ++- src/sqliteInt.h | 27 ++++++++++++++++++++------- src/test1.c | 5 +---- src/where.c | 6 ------ src/whereInt.h | 13 ------------- 11 files changed, 91 insertions(+), 93 deletions(-) diff --git a/manifest b/manifest index e80f89eeb9..045332fbdd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Version\s3.34.0 -D 2020-12-01T16:14:00.051 +C Alternative\simplementation\sof\s".selecttrace"\sand\s".wheretrace"\sthat\suses\na\stest-control\srather\sthan\sglobal\svariables. +D 2020-12-04T01:17:57.176 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -495,7 +495,7 @@ F src/expr.c 0d196ed5a2ebf96be7e8df88add4fabfad0dce16c0fed81a4b8f6a26e259797f F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 83372403298e6a7dd989a47aaacdbaa5b4307b5199dbd56e07d4896066b3de72 F src/func.c 574f7e5a67e4b7a7855cf3478037717c8f44686c0cd727e1d7f7773414165c03 -F src/global.c 943256ac44f333039d35a9830c18d075a81fa6b6bf2af05771494a9acfb9a40b +F src/global.c ed55af196a9b66e198aaeda3f5454c3aa7d7d050c6c938181fd044b70d180a81 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144 @@ -503,7 +503,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 7e081d33aab4a9d761c39dccf3c3872c35501565d2ed9db66301918d23bc7901 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 -F src/main.c 54d61d1e94f225636053c862c930d7dd7b29162b93d3f3ecb00439910ccba02a +F src/main.c ca3b209ea63b40eccee188b167d429b7147b26c48e69c72364e248fe5968c33b F src/malloc.c c1af4ac5a463648cd2953fd4ac679b3ba9022ce5ec794a60806150ad69dfd33a F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -539,17 +539,17 @@ F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 31387e56f5e6d1adc798dfa04b946001289a61e65acf4615f7b7130f121f3b9c -F src/shell.c.in 55113760ae91a05c6ce4558714a1c8fc7a44bf266f735de6e71ea40f79e69830 -F src/sqlite.h.in 1dbae67057d999161c30b21c3c7fa45d51f665b510d397dd1b7d671287d772b0 +F src/select.c c9b68506e5d8cc8d0e4b307b97a9800b050ac37dada80ae9c66f680f8fac3e09 +F src/shell.c.in ff0d0cd5c6b871791ce254f0eec6afb6df2a8f59b0a03385951fbbce2e952472 +F src/sqlite.h.in 0e2b4259e49a0eda54d9118eb18a04fcd60e0727a2fd2c81aade0bf57520e706 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h c01115c8dd967f7d334a98ba37ac821eafb04144c8085a795daaf2185743d27a +F src/sqliteInt.h c897ea47eb7dfc1b337e2c5681dbf00eb43c2a1af2f0045a19adc1052aadc03d F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/tclsqlite.c 986b6391f02cd9b53c1d688be55899f6ffddeb8e8014cd83c1b73ff912579a71 -F src/test1.c 465b7a35b7e231bf2833e47c1371b5dfc99bd803ebe73783862399d479d696a5 +F src/test1.c 3543dcebd67dbe8eb35114d7ea1d4306e9aa6ac1dcc1f6bd40aa701ae20fc8ee F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644 F src/test4.c 7c4420e01c577b5c4add2cb03119743b1a357543d347773b9e717195ea967159 @@ -626,8 +626,8 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 69e770e96fd56cc21608992bf2c6f1f3dc5cf2572d0495c6a643b06c3a679f14 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c 3df26a33dc4f54e8771600fb7fdebe1ece0896c2ad68c30ab40b017aa4395049 -F src/where.c ad738741bf45999188a3047f6277063e3f6843304d581e3ad5875419afdeb6b2 -F src/whereInt.h 59077fbd0b3d01bc8715e746c86a99ebf4c85bde8a57077ec04d2a23e59666ec +F src/where.c 2d593bfc6fa24e53dfe7c99bd327af687f8502e5f0e0299dd2c0f503b133f0bb +F src/whereInt.h 9a3f577619f07700d16d89eeb2f3d94d6b7ed7f109c2dacf0ce8844921549506 F src/wherecode.c a3a1aff30fe99a818d8e7c607980f033f40c68d890e03ed25838b9dbb7908bee F src/whereexpr.c 3a463e156ea388083c501502229c2c7f4f5c6b5330ea59bdf40d6eb6e155a25f F src/window.c edd6f5e25a1e8f2b6f5305b7f5f7da7bb35f07f0d432b255b1d4c2fcab4205aa @@ -1886,10 +1886,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 23212b1a054f05773a9f69f9802035eea6a9d759a2a09e22f46d1046c058b417 -R 02db8b9bcb7f3c64353edbc1fa9fbf5b -T +bgcolor * #d0c0ff -T +sym-release * -T +sym-version-3.34.0 * +P a26b6597e3ae272231b96f9982c3bcc17ddec2f2b6eb4df06a224b91089fed5b +R 19e8e719b0f66addec921087b9d4d053 +T *branch * traceflags-test-control +T *sym-traceflags-test-control * +T -sym-trunk * U drh -Z b7b093d44b407c1b4e832f8c913357ae +Z 26dc3f5c826a9bad51cca1ef93b249e4 diff --git a/manifest.uuid b/manifest.uuid index 275e6f34d5..191a79a958 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a26b6597e3ae272231b96f9982c3bcc17ddec2f2b6eb4df06a224b91089fed5b \ No newline at end of file +d36d6f2923a2393c751c0ac7634433453be20df7567fd914e57cbb1ae15f68b2 \ No newline at end of file diff --git a/src/global.c b/src/global.c index 8ef5a8b2d0..b5239ad81a 100644 --- a/src/global.c +++ b/src/global.c @@ -301,9 +301,10 @@ int sqlite3PendingByte = 0x40000000; #endif /* -** Flags for select tracing and the ".selecttrace" macro of the CLI +** Tracing flags set by SQLITE_TESTCTRL_TRACEFLAGS. */ -u32 sqlite3_unsupported_selecttrace = 0; +u32 sqlite3SelectTrace = 0; +u32 sqlite3WhereTrace = 0; #include "opcodes.h" /* diff --git a/src/main.c b/src/main.c index cc1464f136..815583acb3 100644 --- a/src/main.c +++ b/src/main.c @@ -4255,7 +4255,28 @@ int sqlite3_test_control(int op, ...){ break; } - + /* sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, op, ptr) + ** + ** "ptr" is a pointer to a u32. + ** + ** op==0 Store the current sqlite3SelectTrace in *ptr + ** op==1 Set sqlite3SelectTrace to the value *ptr + ** op==3 Store the current sqlite3WhereTrace in *ptr + ** op==3 Set sqlite3WhereTrace to the value *ptr + */ + case SQLITE_TESTCTRL_TRACEFLAGS: { +#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) + int op = va_arg(ap, int); + u32 *ptr = va_arg(ap, u32*); + switch( op ){ + case 0: *ptr = sqlite3SelectTrace; break; + case 1: sqlite3SelectTrace = *ptr; break; + case 2: *ptr = sqlite3WhereTrace; break; + case 3: sqlite3WhereTrace = *ptr; break; + } + break; +#endif + } } va_end(ap); #endif /* SQLITE_UNTESTABLE */ diff --git a/src/select.c b/src/select.c index d7e1ac0eec..c1eba438f9 100644 --- a/src/select.c +++ b/src/select.c @@ -4210,7 +4210,7 @@ static int flattenSubquery( sqlite3SelectDelete(db, pSub1); #if SELECTTRACE_ENABLED - if( sqlite3_unsupported_selecttrace & 0x100 ){ + if( sqlite3SelectTrace & 0x100 ){ SELECTTRACE(0x100,pParse,p,("After flattening:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -5654,7 +5654,7 @@ static void havingToWhere(Parse *pParse, Select *p){ sWalker.u.pSelect = p; sqlite3WalkExpr(&sWalker, p->pHaving); #if SELECTTRACE_ENABLED - if( sWalker.eCode && (sqlite3_unsupported_selecttrace & 0x100)!=0 ){ + if( sWalker.eCode && (sqlite3SelectTrace & 0x100)!=0 ){ SELECTTRACE(0x100,pParse,p,("Move HAVING terms into WHERE:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -5776,7 +5776,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ p->selFlags &= ~SF_Aggregate; #if SELECTTRACE_ENABLED - if( sqlite3_unsupported_selecttrace & 0x400 ){ + if( sqlite3SelectTrace & 0x400 ){ SELECTTRACE(0x400,pParse,p,("After count-of-view optimization:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -5829,7 +5829,7 @@ int sqlite3Select( if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; #if SELECTTRACE_ENABLED SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain)); - if( sqlite3_unsupported_selecttrace & 0x100 ){ + if( sqlite3SelectTrace & 0x100 ){ sqlite3TreeViewSelect(0, p, 0); } #endif @@ -5854,7 +5854,7 @@ int sqlite3Select( } assert( p->pEList!=0 ); #if SELECTTRACE_ENABLED - if( sqlite3_unsupported_selecttrace & 0x104 ){ + if( sqlite3SelectTrace & 0x104 ){ SELECTTRACE(0x104,pParse,p, ("after name resolution:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -5889,7 +5889,7 @@ int sqlite3Select( goto select_end; } #if SELECTTRACE_ENABLED - if( p->pWin && (sqlite3_unsupported_selecttrace & 0x108)!=0 ){ + if( p->pWin && (sqlite3SelectTrace & 0x108)!=0 ){ SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -5996,7 +5996,7 @@ int sqlite3Select( rc = multiSelect(pParse, p, pDest); #if SELECTTRACE_ENABLED SELECTTRACE(0x1,pParse,p,("end compound-select processing\n")); - if( (sqlite3_unsupported_selecttrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ + if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ sqlite3TreeViewSelect(0, p, 0); } #endif @@ -6015,7 +6015,7 @@ int sqlite3Select( && propagateConstants(pParse, p) ){ #if SELECTTRACE_ENABLED - if( sqlite3_unsupported_selecttrace & 0x100 ){ + if( sqlite3SelectTrace & 0x100 ){ SELECTTRACE(0x100,pParse,p,("After constant propagation:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -6103,7 +6103,7 @@ int sqlite3Select( (pItem->fg.jointype & JT_OUTER)!=0) ){ #if SELECTTRACE_ENABLED - if( sqlite3_unsupported_selecttrace & 0x100 ){ + if( sqlite3SelectTrace & 0x100 ){ SELECTTRACE(0x100,pParse,p, ("After WHERE-clause push-down into subquery %d:\n", pSub->selId)); sqlite3TreeViewSelect(0, p, 0); @@ -6203,7 +6203,7 @@ int sqlite3Select( sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0; #if SELECTTRACE_ENABLED - if( sqlite3_unsupported_selecttrace & 0x400 ){ + if( sqlite3SelectTrace & 0x400 ){ SELECTTRACE(0x400,pParse,p,("After all FROM-clause analysis:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -6239,7 +6239,7 @@ int sqlite3Select( assert( sDistinct.isTnct ); #if SELECTTRACE_ENABLED - if( sqlite3_unsupported_selecttrace & 0x400 ){ + if( sqlite3SelectTrace & 0x400 ){ SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -6487,7 +6487,7 @@ int sqlite3Select( pAggInfo->mxReg = pParse->nMem; if( db->mallocFailed ) goto select_end; #if SELECTTRACE_ENABLED - if( sqlite3_unsupported_selecttrace & 0x400 ){ + if( sqlite3SelectTrace & 0x400 ){ int ii; SELECTTRACE(0x400,pParse,p,("After aggregate analysis %p:\n", pAggInfo)); sqlite3TreeViewSelect(0, p, 0); @@ -6906,7 +6906,7 @@ select_end: #if SELECTTRACE_ENABLED SELECTTRACE(0x1,pParse,p,("end processing\n")); - if( (sqlite3_unsupported_selecttrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ + if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ sqlite3TreeViewSelect(0, p, 0); } #endif diff --git a/src/shell.c.in b/src/shell.c.in index 2d98d23c2d..4465ad549d 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -2881,31 +2881,17 @@ static void explain_data_delete(ShellState *p){ /* ** Disable and restore .wheretrace and .selecttrace settings. */ -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) -extern unsigned int sqlite3_unsupported_selecttrace; -static int savedSelectTrace; -#endif -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) -extern int sqlite3WhereTrace; -static int savedWhereTrace; -#endif +static unsigned int savedSelectTrace; +static unsigned int savedWhereTrace; static void disable_debug_trace_modes(void){ -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) - savedSelectTrace = sqlite3_unsupported_selecttrace; - sqlite3_unsupported_selecttrace = 0; -#endif -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) - savedWhereTrace = sqlite3WhereTrace; - sqlite3WhereTrace = 0; -#endif + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 0, &savedSelectTrace); + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, 0); + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 2, &savedWhereTrace); + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, 0); } static void restore_debug_trace_modes(void){ -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) - sqlite3_unsupported_selecttrace = savedSelectTrace; -#endif -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) - sqlite3WhereTrace = savedWhereTrace; -#endif + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &savedSelectTrace); + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &savedWhereTrace); } /* Create the TEMP table used to store parameter bindings */ @@ -9246,11 +9232,10 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){ - sqlite3_unsupported_selecttrace = nArg>=2 ? (int)integerValue(azArg[1]) : 0xffff; + unsigned int x = nArg>=2 ? (int)integerValue(azArg[1]) : 0xffffffff; + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &x); }else -#endif #if defined(SQLITE_ENABLE_SESSION) if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){ @@ -10305,11 +10290,10 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){ - sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff; + unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff; + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &x); }else -#endif if( c=='w' && strncmp(azArg[0], "width", n)==0 ){ int j; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 3ec8efeab0..c975b23351 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -7765,7 +7765,8 @@ int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_PRNG_SEED 28 #define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29 #define SQLITE_TESTCTRL_SEEK_COUNT 30 -#define SQLITE_TESTCTRL_LAST 30 /* Largest TESTCTRL */ +#define SQLITE_TESTCTRL_TRACEFLAGS 31 +#define SQLITE_TESTCTRL_LAST 31 /* Largest TESTCTRL */ /* ** CAPI3REF: SQL Keyword Checking diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 4670622779..1efa621427 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -984,15 +984,14 @@ typedef INT16_TYPE LogEst; ** SELECTTRACE_ENABLED will be either 1 or 0 depending on whether or not ** the Select query generator tracing logic is turned on. */ -#if defined(SQLITE_ENABLE_SELECTTRACE) -# define SELECTTRACE_ENABLED 1 -#else -# define SELECTTRACE_ENABLED 0 +#if !defined(SQLITE_AMALGAMATION) +extern u32 sqlite3SelectTrace; #endif -#if defined(SQLITE_ENABLE_SELECTTRACE) +#if defined(SQLITE_DEBUG) \ + && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_SELECTTRACE)) # define SELECTTRACE_ENABLED 1 # define SELECTTRACE(K,P,S,X) \ - if(sqlite3_unsupported_selecttrace&(K)) \ + if(sqlite3SelectTrace&(K)) \ sqlite3DebugPrintf("%u/%d/%p: ",(S)->selId,(P)->addrExplain,(S)),\ sqlite3DebugPrintf X #else @@ -1000,6 +999,21 @@ typedef INT16_TYPE LogEst; # define SELECTTRACE_ENABLED 0 #endif +/* +** Macros for "wheretrace" +*/ +#if !defined(SQLITE_AMAGAMATION) +extern u32 sqlite3WhereTrace; +#endif +#if defined(SQLITE_DEBUG) \ + && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE)) +# define WHERETRACE(K,X) if(sqlite3WhereTrace&(K)) sqlite3DebugPrintf X +# define WHERETRACE_ENABLED 1 +#else +# define WHERETRACE(K,X) +#endif + + /* ** An instance of the following structure is used to store the busy-handler ** callback for a given sqlite handle. @@ -4594,7 +4608,6 @@ extern const unsigned char sqlite3UpperToLower[]; extern const unsigned char sqlite3CtypeMap[]; extern SQLITE_WSD struct Sqlite3Config sqlite3Config; extern FuncDefHash sqlite3BuiltinFunctions; -extern u32 sqlite3_unsupported_selecttrace; #ifndef SQLITE_OMIT_WSD extern int sqlite3PendingByte; #endif diff --git a/src/test1.c b/src/test1.c index 49461ea5fc..039da74ce5 100644 --- a/src/test1.c +++ b/src/test1.c @@ -8520,9 +8520,6 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ #ifdef SQLITE_ENABLE_FTS3 extern int sqlite3_fts3_enable_parentheses; #endif -#endif -#if defined(SQLITE_ENABLE_SELECTTRACE) - extern u32 sqlite3_unsupported_selecttrace; #endif for(i=0; i Date: Fri, 4 Dec 2020 16:04:45 +0000 Subject: [PATCH 022/257] Further changes to the trace variables to try to eliminate (harmless) compiler warnings in all configurations. FossilOrigin-Name: 3a4c98b989964e3e366fe9519e9b5ed935e893d5b69d92bc0388a14c7e7938e6 --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/main.c | 6 ++---- src/shell.c.in | 2 +- 4 files changed, 11 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 045332fbdd..4d2aaba4aa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Alternative\simplementation\sof\s".selecttrace"\sand\s".wheretrace"\sthat\suses\na\stest-control\srather\sthan\sglobal\svariables. -D 2020-12-04T01:17:57.176 +C Further\schanges\sto\sthe\strace\svariables\sto\stry\sto\seliminate\s(harmless)\scompiler\nwarnings\sin\sall\sconfigurations. +D 2020-12-04T16:04:45.699 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -503,7 +503,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 7e081d33aab4a9d761c39dccf3c3872c35501565d2ed9db66301918d23bc7901 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 -F src/main.c ca3b209ea63b40eccee188b167d429b7147b26c48e69c72364e248fe5968c33b +F src/main.c 97e9f137354bc1f76dc9bb60a0a24f8c45cf73b33e80d3ee4c64155336fb820d F src/malloc.c c1af4ac5a463648cd2953fd4ac679b3ba9022ce5ec794a60806150ad69dfd33a F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -540,7 +540,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c c9b68506e5d8cc8d0e4b307b97a9800b050ac37dada80ae9c66f680f8fac3e09 -F src/shell.c.in ff0d0cd5c6b871791ce254f0eec6afb6df2a8f59b0a03385951fbbce2e952472 +F src/shell.c.in 3568822723cea63b4a6c6ce0704c606d2ea207d4fe024c67729a105230d4b148 F src/sqlite.h.in 0e2b4259e49a0eda54d9118eb18a04fcd60e0727a2fd2c81aade0bf57520e706 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e @@ -1886,10 +1886,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 a26b6597e3ae272231b96f9982c3bcc17ddec2f2b6eb4df06a224b91089fed5b -R 19e8e719b0f66addec921087b9d4d053 -T *branch * traceflags-test-control -T *sym-traceflags-test-control * -T -sym-trunk * +P d36d6f2923a2393c751c0ac7634433453be20df7567fd914e57cbb1ae15f68b2 +R ef71c1d96862a5ef1769c7803a088f57 U drh -Z 26dc3f5c826a9bad51cca1ef93b249e4 +Z 7ead96ffcfc794dcb28dd96880ba576c diff --git a/manifest.uuid b/manifest.uuid index 191a79a958..6a640acd8d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d36d6f2923a2393c751c0ac7634433453be20df7567fd914e57cbb1ae15f68b2 \ No newline at end of file +3a4c98b989964e3e366fe9519e9b5ed935e893d5b69d92bc0388a14c7e7938e6 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 815583acb3..bbf81e778e 100644 --- a/src/main.c +++ b/src/main.c @@ -4265,17 +4265,15 @@ int sqlite3_test_control(int op, ...){ ** op==3 Set sqlite3WhereTrace to the value *ptr */ case SQLITE_TESTCTRL_TRACEFLAGS: { -#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) - int op = va_arg(ap, int); + int opTrace = va_arg(ap, int); u32 *ptr = va_arg(ap, u32*); - switch( op ){ + switch( opTrace ){ case 0: *ptr = sqlite3SelectTrace; break; case 1: sqlite3SelectTrace = *ptr; break; case 2: *ptr = sqlite3WhereTrace; break; case 3: sqlite3WhereTrace = *ptr; break; } break; -#endif } } va_end(ap); diff --git a/src/shell.c.in b/src/shell.c.in index 4465ad549d..826523870d 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -9233,7 +9233,7 @@ static int do_meta_command(char *zLine, ShellState *p){ }else if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){ - unsigned int x = nArg>=2 ? (int)integerValue(azArg[1]) : 0xffffffff; + unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff; sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &x); }else From 7b0ab210162556a4b19623853635f7b5e68e861e Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 4 Dec 2020 16:25:59 +0000 Subject: [PATCH 023/257] Fix an incorrect datatype no the sqlite3WhereTrace variable in test1.c. FossilOrigin-Name: 4e6dab30f6d6795ecec9d8c4489fa4d210a3002715ad89812d65a1a846c164b9 --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/test1.c | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 4f3892ce96..3a03e90b15 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Eliminate\sthe\ssqlite3_unsupported_selecttrace\sglobal\svariable\sby\screating\na\snew\stest-control\sto\scontrol\sSELECT\stracing.\s\sNote\sthat\sSELECT\stracing\sis\nonly\savailable\son\sdebug\sbuilds. -D 2020-12-04T16:09:27.683 +C Fix\san\sincorrect\sdatatype\sno\sthe\ssqlite3WhereTrace\svariable\sin\stest1.c. +D 2020-12-04T16:25:59.508 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -550,7 +550,7 @@ F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a3 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/tclsqlite.c 986b6391f02cd9b53c1d688be55899f6ffddeb8e8014cd83c1b73ff912579a71 -F src/test1.c 3543dcebd67dbe8eb35114d7ea1d4306e9aa6ac1dcc1f6bd40aa701ae20fc8ee +F src/test1.c 2197966d2f7211ef9eefaa6c3c7dd2c7d786d1f33f2aadef2f08c8c79eceec26 F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644 F src/test4.c 7c4420e01c577b5c4add2cb03119743b1a357543d347773b9e717195ea967159 @@ -1887,8 +1887,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 026a93508ec392ca5cd2578ae9eab64974f58beccda088e10d4cc951f237632f 3a4c98b989964e3e366fe9519e9b5ed935e893d5b69d92bc0388a14c7e7938e6 -R 7e0eae4df77dd74014280bc6a83dc3cd -T +closed 3a4c98b989964e3e366fe9519e9b5ed935e893d5b69d92bc0388a14c7e7938e6 +P fb07c4e3c7ad3493c274cbfcf0dffdedcca18c0d90de04459134511d4e2a5277 +R ec7dd2e987372222def1ec4ae2f714bf U drh -Z f9a73407194c3537b2bea93de0e6ddbd +Z 07f297f45f5db93080b5cfd3b5bf2b1d diff --git a/manifest.uuid b/manifest.uuid index 36773d961d..4d0b7df535 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fb07c4e3c7ad3493c274cbfcf0dffdedcca18c0d90de04459134511d4e2a5277 \ No newline at end of file +4e6dab30f6d6795ecec9d8c4489fa4d210a3002715ad89812d65a1a846c164b9 \ No newline at end of file diff --git a/src/test1.c b/src/test1.c index 039da74ce5..1eb30514bf 100644 --- a/src/test1.c +++ b/src/test1.c @@ -8512,7 +8512,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ extern LONG volatile sqlite3_os_type; #endif #ifdef SQLITE_DEBUG - extern int sqlite3WhereTrace; + extern u32 sqlite3WhereTrace; extern int sqlite3OSTrace; extern int sqlite3WalTrace; #endif From ee8221859b6ecc79fc33f7582f15602498b8daf1 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 4 Dec 2020 16:26:25 +0000 Subject: [PATCH 024/257] Fix a test script problem in walvfs.test. FossilOrigin-Name: 4c5076fbe42cc6447c47bfc202501f945f78bd716cbe8e33599c67b7d0956611 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/walvfs.test | 9 ++++++++- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 3a03e90b15..18fc34100c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sincorrect\sdatatype\sno\sthe\ssqlite3WhereTrace\svariable\sin\stest1.c. -D 2020-12-04T16:25:59.508 +C Fix\sa\stest\sscript\sproblem\sin\swalvfs.test. +D 2020-12-04T16:26:25.602 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1714,7 +1714,7 @@ F test/walsetlk.test 11f7fe792fdce54cf09874dab824e0627f2eedecfb9f7983e325606ec51 F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417 F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747 -F test/walvfs.test a2913001a83b19c1d20220e556cee14d87d47ecb6949b5e0a2e9e2590abecf1e +F test/walvfs.test bccb3e0d235ef85e276f491d34db32c9ada1ea67be8d9f10aabe7b30319ec656 F test/wapp.tcl b440cd8cf57953d3a49e7ee81e6a18f18efdaf113b69f7d8482b0710a64566ec F test/wapptest.tcl 899594e25684861d5b0c0880fb012364def50ef8097041b8ddf74be5ba7fa270 x F test/where.test e713c0c64e3e6b062235e39a2f7e5508c517df16b63d69fd786e26bc7330b1c6 @@ -1887,7 +1887,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 fb07c4e3c7ad3493c274cbfcf0dffdedcca18c0d90de04459134511d4e2a5277 -R ec7dd2e987372222def1ec4ae2f714bf -U drh -Z 07f297f45f5db93080b5cfd3b5bf2b1d +P 4e6dab30f6d6795ecec9d8c4489fa4d210a3002715ad89812d65a1a846c164b9 +R 07161e41d5089cc6ef28f0415edcb9d6 +U dan +Z 7e2ee23c5c662414c726391354dad230 diff --git a/manifest.uuid b/manifest.uuid index 4d0b7df535..761f354c26 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4e6dab30f6d6795ecec9d8c4489fa4d210a3002715ad89812d65a1a846c164b9 \ No newline at end of file +4c5076fbe42cc6447c47bfc202501f945f78bd716cbe8e33599c67b7d0956611 \ No newline at end of file diff --git a/test/walvfs.test b/test/walvfs.test index f21b65e7e9..d6c58656f0 100644 --- a/test/walvfs.test +++ b/test/walvfs.test @@ -146,16 +146,23 @@ proc xWrite {method file args} { incr ::cnt -1 if {$::cnt==0} { sqlite3_memdebug_fail 1 -repeat 0 - catchsql { SELECT 'a big long string!' } + # For this test to pass, the following statement must call malloc() at + # least once. Even if the lookaside is enabled. + set ::xwrite_stmt_res [catchsql { SELECT hex(randomblob(4000)) }] sqlite3_interrupt db } } return SQLITE_OK } +set ::xwrite_stmt_res "" do_catchsql_test 3.2 { PRAGMA wal_checkpoint } {1 {out of memory}} +do_test 3.2.2 { + set ::xwrite_stmt_res +} {1 {out of memory}} +unset ::xwrite_stmt_res #------------------------------------------------------------------------- # From b9ceb833f7b11094365223c1d338cbefc834c437 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 4 Dec 2020 16:49:25 +0000 Subject: [PATCH 025/257] Ensure that fts5 function matchinfo() is registered before running tests that use it in fts5corrupt3.test. FossilOrigin-Name: 932e05e093192991589e70c2cbcc8a57fb3dcc6df1c2673962bfd06ba5cfdd97 --- ext/fts5/test/fts5corrupt3.test | 2 ++ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/ext/fts5/test/fts5corrupt3.test b/ext/fts5/test/fts5corrupt3.test index a63624f3f6..4223d3c240 100644 --- a/ext/fts5/test/fts5corrupt3.test +++ b/ext/fts5/test/fts5corrupt3.test @@ -8346,6 +8346,7 @@ do_catchsql_test 58.1 { #------------------------------------------------------------------------- do_test 59.0 { sqlite3 db {} + sqlite3_fts5_register_matchinfo db db deserialize [decode_hexdb { .open --hexdb | size 32768 pagesize 4096 filename crash-96b136358d01ec.db @@ -8549,6 +8550,7 @@ do_catchsql_test 59.1 { #------------------------------------------------------------------------- do_test 60.0 { sqlite3 db {} + sqlite3_fts5_register_matchinfo db db deserialize [decode_hexdb { .open --hexdb | size 32768 pagesize 4096 filename crash-c77b90b929dc92.db diff --git a/manifest b/manifest index 18fc34100c..9796d20a44 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stest\sscript\sproblem\sin\swalvfs.test. -D 2020-12-04T16:26:25.602 +C Ensure\sthat\sfts5\sfunction\smatchinfo()\sis\sregistered\sbefore\srunning\stests\sthat\suse\sit\sin\sfts5corrupt3.test. +D 2020-12-04T16:49:25.140 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -160,7 +160,7 @@ F ext/fts5/test/fts5connect.test 08030168fc96fc278fa81f28654fb7e90566f33aff269c0 F ext/fts5/test/fts5content.test 213506436fb2c87567b8e31f6d43ab30aab99354cec74ed679f22aad0cdbf283 F ext/fts5/test/fts5corrupt.test 77ae6f41a7eba10620efb921cf7dbe218b0ef232b04519deb43581cb17a57ebe F ext/fts5/test/fts5corrupt2.test 7453752ba12ce91690c469a6449d412561cc604b1dec994e16ab132952e7805f -F ext/fts5/test/fts5corrupt3.test 09225c23d76c5538aab5199e239b1ecd234e8c0dd52f3b18af6d2bafe85015b0 +F ext/fts5/test/fts5corrupt3.test 1c26a651ea7e52fd69d54436fe4f02f6dd1268bc8b48ab851c7e1d374aa242b9 F ext/fts5/test/fts5corrupt4.test f4c08e2182a48d8b70975fd869ee5391855c06d8a0ff87b6a2529e7c5a88a1d3 F ext/fts5/test/fts5delete.test 4a15fb03b6c7eac62ac807a3a32b7f0dc74f0d479c410e3e3568ae96b9469290 F ext/fts5/test/fts5detail.test 31b240dbf6d44ac3507e2f8b65f29fdc12465ffd531212378c7ce1066766f54e @@ -1887,7 +1887,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 4e6dab30f6d6795ecec9d8c4489fa4d210a3002715ad89812d65a1a846c164b9 -R 07161e41d5089cc6ef28f0415edcb9d6 +P 4c5076fbe42cc6447c47bfc202501f945f78bd716cbe8e33599c67b7d0956611 +R 8d18d605e8483c2f8c8d19c49ca4aafe U dan -Z 7e2ee23c5c662414c726391354dad230 +Z 0f37f3e2444904cd3595dc4b87688ea8 diff --git a/manifest.uuid b/manifest.uuid index 761f354c26..10f1bf43c3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4c5076fbe42cc6447c47bfc202501f945f78bd716cbe8e33599c67b7d0956611 \ No newline at end of file +932e05e093192991589e70c2cbcc8a57fb3dcc6df1c2673962bfd06ba5cfdd97 \ No newline at end of file From 0a2fb7960c7b1b9c504016882dd3fcde414fcbe4 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 4 Dec 2020 16:58:20 +0000 Subject: [PATCH 026/257] Fix a bug in the ".eqp" command of the shell that was introduced by the recent sqlite3SelectTrace/SQLITE_TESTCTRL_TRACEFLAGS changes. FossilOrigin-Name: fd02dffceb0e21cd85c99d5481ab8567110d01c30ea701178547f32299944302 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c.in | 5 +++-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 9796d20a44..1c834621f1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sfts5\sfunction\smatchinfo()\sis\sregistered\sbefore\srunning\stests\sthat\suse\sit\sin\sfts5corrupt3.test. -D 2020-12-04T16:49:25.140 +C Fix\sa\sbug\sin\sthe\s".eqp"\scommand\sof\sthe\sshell\sthat\swas\sintroduced\sby\sthe\nrecent\ssqlite3SelectTrace/SQLITE_TESTCTRL_TRACEFLAGS\schanges. +D 2020-12-04T16:58:20.287 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -541,7 +541,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c c9b68506e5d8cc8d0e4b307b97a9800b050ac37dada80ae9c66f680f8fac3e09 -F src/shell.c.in ccc9bd73a510238cfee1c306bae28d22651b70011fa58e6292e04f5f625538b8 +F src/shell.c.in e9f674ee4ec6c345679e8a5b16c869c6c59eb1540dd98ac69e4736ecddce0090 F src/sqlite.h.in 0e2b4259e49a0eda54d9118eb18a04fcd60e0727a2fd2c81aade0bf57520e706 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e @@ -1887,7 +1887,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 4c5076fbe42cc6447c47bfc202501f945f78bd716cbe8e33599c67b7d0956611 -R 8d18d605e8483c2f8c8d19c49ca4aafe -U dan -Z 0f37f3e2444904cd3595dc4b87688ea8 +P 932e05e093192991589e70c2cbcc8a57fb3dcc6df1c2673962bfd06ba5cfdd97 +R 72c47bd3b237b1831a726f9d8517bab8 +U drh +Z 9b9504ab938901a398e00c8416a51c09 diff --git a/manifest.uuid b/manifest.uuid index 10f1bf43c3..16f5007904 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -932e05e093192991589e70c2cbcc8a57fb3dcc6df1c2673962bfd06ba5cfdd97 \ No newline at end of file +fd02dffceb0e21cd85c99d5481ab8567110d01c30ea701178547f32299944302 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 523ee2c96a..dbdba271cd 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -2884,10 +2884,11 @@ static void explain_data_delete(ShellState *p){ static unsigned int savedSelectTrace; static unsigned int savedWhereTrace; static void disable_debug_trace_modes(void){ + unsigned int zero = 0; sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 0, &savedSelectTrace); - sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, 0); + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &zero); sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 2, &savedWhereTrace); - sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, 0); + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &zero); } static void restore_debug_trace_modes(void){ sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &savedSelectTrace); From aeb6bc56280c7961a0c5fe1a1e26a8e51bf8648d Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 4 Dec 2020 17:05:16 +0000 Subject: [PATCH 027/257] Fix harmless compiler warnings associated with the recent FTS5 enhancements. FossilOrigin-Name: 1db7c751912beb57a697ac8e85b9c29e30da7b6c89207e9828bf08e56c58242f --- ext/fts5/fts5_index.c | 11 ++++++----- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 88709f2c35..2daa07c51e 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -4899,8 +4899,9 @@ static void fts5MergeRowidLists( i64 iRowid2 = 0; i64 iOut = 0; Fts5Buffer *p2 = &aBuf[0]; - Fts5Buffer out; + + (void)nBuf; memset(&out, 0, sizeof(out)); assert( nBuf==1 ); sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n); @@ -5090,10 +5091,10 @@ static void fts5MergePrefixLists( pHead = pSave; for(i=0; iiter.aPoslist && pThis->iter.iRowid==iLastRowid ){ - fts5DoclistIterNext(&pThis->iter); - fts5PrefixMergerInsertByRowid(&pHead, pThis); + PrefixMerger *pX = &aMerger[i]; + if( pX->iter.aPoslist && pX->iter.iRowid==iLastRowid ){ + fts5DoclistIterNext(&pX->iter); + fts5PrefixMergerInsertByRowid(&pHead, pX); } } diff --git a/manifest b/manifest index 1c834621f1..5e328f066a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbug\sin\sthe\s".eqp"\scommand\sof\sthe\sshell\sthat\swas\sintroduced\sby\sthe\nrecent\ssqlite3SelectTrace/SQLITE_TESTCTRL_TRACEFLAGS\schanges. -D 2020-12-04T16:58:20.287 +C Fix\sharmless\scompiler\swarnings\sassociated\swith\sthe\srecent\sFTS5\senhancements. +D 2020-12-04T17:05:16.189 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -119,7 +119,7 @@ F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6 F ext/fts5/fts5_config.c be54f44fca491e96c6923a4b9a736f2da2b13811600eb6e38d1bcc91c4ea2e61 F ext/fts5/fts5_expr.c e527e3a7410393075598cec544e3831798a8c88b3e8878e2cfb7cb147113e925 F ext/fts5/fts5_hash.c 1aa93c9b5f461afba66701ee226297dc78402b3bdde81e90a10de5fe3df14959 -F ext/fts5/fts5_index.c 3f00c9889425c6c19a8e5f5b9a0cd67d2e27340567b4c20bbe102b4f624ecf5a +F ext/fts5/fts5_index.c 7be3a7dcf4458a2d58a1c6ae0290921c9df226bff7eb9bc82f14e667b27aeb20 F ext/fts5/fts5_main.c b4e4931c7fcc9acfa0c3b8b5e5e80b5b424b8d9207aae3a22b674bd35ccf149d F ext/fts5/fts5_storage.c 58ba71e6cd3d43a5735815e7956ee167babb4d2cbfe206905174792af4d09d75 F ext/fts5/fts5_tcl.c 39bcbae507f594aad778172fa914cad0f585bf92fd3b078c686e249282db0d95 @@ -1887,7 +1887,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 932e05e093192991589e70c2cbcc8a57fb3dcc6df1c2673962bfd06ba5cfdd97 -R 72c47bd3b237b1831a726f9d8517bab8 +P fd02dffceb0e21cd85c99d5481ab8567110d01c30ea701178547f32299944302 +R d3c2d5d830919ec315662cc1d113703f U drh -Z 9b9504ab938901a398e00c8416a51c09 +Z d16f9ab88139a6919756f891af8788a5 diff --git a/manifest.uuid b/manifest.uuid index 16f5007904..9b7ad54cc9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fd02dffceb0e21cd85c99d5481ab8567110d01c30ea701178547f32299944302 \ No newline at end of file +1db7c751912beb57a697ac8e85b9c29e30da7b6c89207e9828bf08e56c58242f \ No newline at end of file From f6e904bd9243498889ae3e628aeef9f697c728c9 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 7 Dec 2020 17:15:32 +0000 Subject: [PATCH 028/257] Begin adding new SQL functions that depend on -lm: ceil(), ceiling(), floor(), ln(), log(), and log10() so far. More to follow. FossilOrigin-Name: 4db5f2f7875f6df78630a7816fc018141a6eee2e295b44fc7627eb66d07881ea --- Makefile.msc | 3 ++ configure | 104 +++++++++++++++++++++++++++++++++++++++------- configure.ac | 14 +++++++ manifest | 25 +++++------ manifest.uuid | 2 +- src/ctime.c | 3 ++ src/func.c | 78 ++++++++++++++++++++++++++++++++++ src/sqliteInt.h | 6 +++ src/test_config.c | 6 +++ test/func7.test | 35 ++++++++++++++++ 10 files changed, 249 insertions(+), 27 deletions(-) create mode 100644 test/func7.test diff --git a/Makefile.msc b/Makefile.msc index 404e3b2360..af39679a8f 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -380,6 +380,9 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_SESSION=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_PREUPDATE_HOOK=1 !ENDIF +# Always enable math functions on Windows +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_MATH_FUNCTIONS + # Should the rbu extension be enabled? If so, add compilation options # to enable it. # diff --git a/configure b/configure index 90cb4d25e8..5a313189b1 100755 --- a/configure +++ b/configure @@ -1557,6 +1557,7 @@ Optional Features: separately --disable-load-extension Disable loading of external extensions + --disable-math Disable math functions --enable-memsys5 Enable MEMSYS5 --enable-memsys3 Enable MEMSYS3 --enable-all Enable FTS4, FTS5, Geopoly, JSON, RTree, Sessions @@ -3935,13 +3936,13 @@ if ${lt_cv_nm_interface+:} false; then : else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:3938: $ac_compile\"" >&5) + (eval echo "\"\$as_me:3939: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:3941: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:3942: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:3944: output\"" >&5) + (eval echo "\"\$as_me:3945: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -5147,7 +5148,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 5150 "configure"' > conftest.$ac_ext + echo '#line 5151 "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -6672,11 +6673,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6675: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6676: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:6679: \$? = $ac_status" >&5 + echo "$as_me:6680: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7011,11 +7012,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7014: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7015: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7018: \$? = $ac_status" >&5 + echo "$as_me:7019: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7116,11 +7117,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7119: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7120: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7123: \$? = $ac_status" >&5 + echo "$as_me:7124: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -7171,11 +7172,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7174: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7175: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7178: \$? = $ac_status" >&5 + echo "$as_me:7179: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -9551,7 +9552,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9554 "configure" +#line 9555 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -9647,7 +9648,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9650 "configure" +#line 9651 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11411,6 +11412,81 @@ else OPT_FEATURE_FLAGS="-DSQLITE_OMIT_LOAD_EXTENSION=1" fi +########## +# Do we want to support math functions +# +# Check whether --enable-threadsafe was given. +if test "${enable_threadsafe+set}" = set; then : + enableval=$enable_threadsafe; +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support math functions" >&5 +$as_echo_n "checking whether to support math functions... " >&6; } +if test "$enable_math" = "no"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MATH_FUNCTIONS" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing ceil" >&5 +$as_echo_n "checking for library containing ceil... " >&6; } +if ${ac_cv_search_ceil+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ceil (); +int +main () +{ +return ceil (); + ; + return 0; +} +_ACEOF +for ac_lib in '' m; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_ceil=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_ceil+:} false; then : + break +fi +done +if ${ac_cv_search_ceil+:} false; then : + +else + ac_cv_search_ceil=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ceil" >&5 +$as_echo "$ac_cv_search_ceil" >&6; } +ac_res=$ac_cv_search_ceil +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +fi + ########## # Do we want to support memsys3 and/or memsys5 # diff --git a/configure.ac b/configure.ac index bb8f4bd563..5285581eec 100644 --- a/configure.ac +++ b/configure.ac @@ -586,6 +586,20 @@ else OPT_FEATURE_FLAGS="-DSQLITE_OMIT_LOAD_EXTENSION=1" fi +########## +# Do we want to support math functions +# +AC_ARG_ENABLE(threadsafe, +AC_HELP_STRING([--disable-math],[Disable math functions])) +AC_MSG_CHECKING([whether to support math functions]) +if test "$enable_math" = "no"; then + AC_MSG_RESULT([no]) +else + AC_MSG_RESULT([yes]) + OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MATH_FUNCTIONS" + AC_SEARCH_LIBS(ceil, m) +fi + ########## # Do we want to support memsys3 and/or memsys5 # diff --git a/manifest b/manifest index 5e328f066a..9347e389ec 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C Fix\sharmless\scompiler\swarnings\sassociated\swith\sthe\srecent\sFTS5\senhancements. -D 2020-12-04T17:05:16.189 +C Begin\sadding\snew\sSQL\sfunctions\sthat\sdepend\son\s-lm:\s\sceil(),\sceiling(),\nfloor(),\sln(),\slog(),\sand\slog10()\sso\sfar.\s\sMore\sto\sfollow. +D 2020-12-07T17:15:32.150 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F Makefile.in 0e88f5d095213a9ccd45c5bbd871c8ead498f886dff4493471fbf48b1f867f9d F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241 -F Makefile.msc dd10dbf63b2f8ac3e2f0542963a21bc69058976ac4355165f212a31c83d17f44 +F Makefile.msc ad07bbd645132533e1fd7164a03acfa9afecda378b3787c10f62ab4c7c45e6ea F README.md 1514a365ffca3c138e00c5cc839906108a01011a6b082bad19b09781e3aa498a F VERSION 92f3e4c5cdee6f0779aef1eae857dfc21d0eabb1f2af169dc90e63cd76b15bb2 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -34,8 +34,8 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6 F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559 -F configure 73234664de11cb7f1f1b198fe6775d8b0f01d25480d325a7b9f9645675bf6b79 x -F configure.ac 73545c21eebcef9398d85c982c7be260f07708256778221b541f83ae8c6f61eb +F configure 79bcd87c8c18e4e60a9b0282c259b9db912e68c086cb65634628763b3c6b6321 x +F configure.ac b865a0e9724d09b5e510d07340901ecfceab706c8d21f26d55914f2d1be7dc7e F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd F doc/lemon.html c5d8ba85ac1daef7be8c2d389899480eb62451ff5c09b0c28ff8157bb8770746 @@ -487,7 +487,7 @@ F src/btreeInt.h ffd66480520d9d70222171b3a026d78b80833b5cea49c89867949f3e023d5f4 F src/build.c f6449d4e85e998e14d3f537e8ea898dca2fcb83c277db3e60945af9b9177db81 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e -F src/ctime.c e98518d2d3d4029a13c805e07313fb60c877be56db76e90dd5f3af73085d0ce6 +F src/ctime.c 0bcc6a908779a520be534fd985b2185dfd457588b6798d0bcbf37755a044b7c3 F src/date.c dace306a10d9b02ee553d454c8e1cf8d3c9b932e137738a6b15b90253a9bfc10 F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c @@ -495,7 +495,7 @@ F src/delete.c 927cf8f900583e79aca8f1a321979e0a8f053babd9a690b44b38f79de2cc09fe F src/expr.c 0d196ed5a2ebf96be7e8df88add4fabfad0dce16c0fed81a4b8f6a26e259797f F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 83372403298e6a7dd989a47aaacdbaa5b4307b5199dbd56e07d4896066b3de72 -F src/func.c 574f7e5a67e4b7a7855cf3478037717c8f44686c0cd727e1d7f7773414165c03 +F src/func.c d3113a23625daeb54331752421442af772abd851123550459dec96fedbe068e7 F src/global.c ed55af196a9b66e198aaeda3f5454c3aa7d7d050c6c938181fd044b70d180a81 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 @@ -545,7 +545,7 @@ F src/shell.c.in e9f674ee4ec6c345679e8a5b16c869c6c59eb1540dd98ac69e4736ecddce009 F src/sqlite.h.in 0e2b4259e49a0eda54d9118eb18a04fcd60e0727a2fd2c81aade0bf57520e706 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h c897ea47eb7dfc1b337e2c5681dbf00eb43c2a1af2f0045a19adc1052aadc03d +F src/sqliteInt.h 6ab40b33a1f5edbb7d71c78e82e0f9c5291dcff4704df8e4f0ab0d9c1a0c06af F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -565,7 +565,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 5ea19bf0972a9d91728518b4d30e91477acce80496003ecbef3a7fb18d0bd081 +F src/test_config.c 98698f5242be88af75eaac54adde573471d5ed2f6484e0dac034cb1e763a551a F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f F src/test_demovfs.c 86142ba864d4297d54c5b2e972e74f3141ae4b30f05b3a95824184ed2d3d7f91 F src/test_devsym.c aff2255ea290d7718da08af30cdf18e470ff7325a5eff63e0057b1496ed66593 @@ -1026,6 +1026,7 @@ F test/func3.test 2bb0f31ab7baaed690b962a88544d7be6b34fa389364bc36a44e441ed3e3f1 F test/func4.test 2285fb5792d593fef442358763f0fd9de806eda47dbc7a5934df57ffdc484c31 F test/func5.test 863e6d1bd0013d09c17236f8a13ea34008dd857d87d85a13a673960e4c25d82a F test/func6.test 90e42b64c4f9fb6f04f44cb8a1da586c8542502e926b19c76504fe74ff2a9b7c +F test/func7.test 7414f1ffb7aba86b6bcfdf0c3739a4e4717026ff583acd8b43ab21189300bcdc F test/fuzz-oss1.test e58330d01cbbd8215ee636b17a03fe220b37dbfa F test/fuzz.test 96083052bf5765e4518c1ba686ce2bab785670d1 F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1 @@ -1887,7 +1888,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 fd02dffceb0e21cd85c99d5481ab8567110d01c30ea701178547f32299944302 -R d3c2d5d830919ec315662cc1d113703f +P 1db7c751912beb57a697ac8e85b9c29e30da7b6c89207e9828bf08e56c58242f +R 6662031cc76e6cb57f52d5a4ee0696ea U drh -Z d16f9ab88139a6919756f891af8788a5 +Z 99632da1aa8e30b2d9d751e33b863567 diff --git a/manifest.uuid b/manifest.uuid index 9b7ad54cc9..7ffa11f57e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1db7c751912beb57a697ac8e85b9c29e30da7b6c89207e9828bf08e56c58242f \ No newline at end of file +4db5f2f7875f6df78630a7816fc018141a6eee2e295b44fc7627eb66d07881ea \ No newline at end of file diff --git a/src/ctime.c b/src/ctime.c index e3e1e79a95..f0fdccbdc1 100644 --- a/src/ctime.c +++ b/src/ctime.c @@ -259,6 +259,9 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_ENABLE_LOCKING_STYLE "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE), #endif +#if SQLITE_ENABLE_MATH_FUNCTIONS + "ENABLE_MATH_FUNCTIONS" +#endif #if SQLITE_ENABLE_MEMORY_MANAGEMENT "ENABLE_MEMORY_MANAGEMENT", #endif diff --git a/src/func.c b/src/func.c index 5d00c94a92..09e44345dc 100644 --- a/src/func.c +++ b/src/func.c @@ -1904,6 +1904,75 @@ int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){ return 1; } +/* Extra math functions that require linking with -lm +*/ +#ifdef SQLITE_ENABLE_MATH_FUNCTIONS +/* +** Implementation SQL functions: +** +** ceil(X) +** ceiling(X) +** floor(X) +** +** The sqlite3_user_data() pointer is a pointer to the libm implementation +** of the underlying C function. +*/ +static void ceilingFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + assert( argc==1 ); + switch( sqlite3_value_type(argv[0]) ){ + case SQLITE_INTEGER: + sqlite3_result_int64(context, sqlite3_value_int64(argv[0])); + break; + case SQLITE_NULL: + break; + default: { + double (*x)(double) = (double(*)(double))sqlite3_user_data(context); + sqlite3_result_double(context, x(sqlite3_value_double(argv[0]))); + break; + } + } +} + +/* +** Implementation of SQL functions: +** +** ln(X) - natural logarithm +** log(X) - log base 10 +** log10(X) - log base 10 +** log(X,Y) - log base Y +*/ +static void logFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + double x, y, ans; + assert( argc==1 || argc==2 ); + if( sqlite3_value_type(argv[0])==SQLITE_NULL + || (x = sqlite3_value_double(argv[0]))<0.0 + ){ + return; /* Return NULL for a domain error */ + } + ans = log(x); + if( argc==2 ){ + if( sqlite3_value_type(argv[1])==SQLITE_NULL + || (y = sqlite3_value_double(argv[1]))<0.0 + ){ + return; /* Return NULL for a domain error */ + } + ans /= log(y); + }else if( sqlite3_user_data(context)!=0 ){ + /* Convert from natural logarithm to log base 10 */ + ans *= 0.43429448190325178672; + } + sqlite3_result_double(context, ans); +} +#endif /* SQLITE_ENABLE_MATH_FUNCTIONS */ + /* ** All of the FuncDef structures in the aBuiltinFunc[] array above ** to the global function hash table. This occurs at start-time (as @@ -2024,6 +2093,15 @@ void sqlite3RegisterBuiltinFunctions(void){ FUNCTION(coalesce, 0, 0, 0, 0 ), INLINE_FUNC(coalesce, -1, INLINEFUNC_coalesce, 0 ), INLINE_FUNC(iif, 3, INLINEFUNC_iif, 0 ), +#ifdef SQLITE_ENABLE_MATH_FUNCTIONS + MFUNCTION(ceil, 1, ceil, ceilingFunc ), + MFUNCTION(ceiling, 1, ceil, ceilingFunc ), + MFUNCTION(floor, 1, floor, ceilingFunc ), + FUNCTION(ln, 1, 0, 0, logFunc ), + FUNCTION(log, 1, 1, 0, logFunc ), + FUNCTION(log10, 1, 1, 0, logFunc ), + FUNCTION(log, 2, 0, 0, logFunc ), +#endif /* SQLITE_ENABLE_MATH_FUNCTIONS */ }; #ifndef SQLITE_OMIT_ALTERTABLE sqlite3AlterFunctions(); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 1efa621427..438f79c092 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1864,6 +1864,9 @@ struct FuncDestructor { ** a single query. The iArg is ignored. The user-data is always set ** to a NULL pointer. The bNC parameter is not used. ** +** MFUNCTION(zName, nArg, xPtr, xFunc) +** For math-library functions. xPtr is an arbitrary pointer. +** ** PURE_DATE(zName, nArg, iArg, bNC, xFunc) ** Used for "pure" date/time functions, this macro is like DFUNCTION ** except that it does set the SQLITE_FUNC_CONSTANT flags. iArg is @@ -1899,6 +1902,9 @@ struct FuncDestructor { #define SFUNCTION(zName, nArg, iArg, bNC, xFunc) \ {nArg, SQLITE_UTF8|SQLITE_DIRECTONLY|SQLITE_FUNC_UNSAFE, \ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } +#define MFUNCTION(zName, nArg, xPtr, xFunc) \ + {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \ + xPtr, 0, xFunc, 0, 0, 0, #zName, {0} } #define INLINE_FUNC(zName, nArg, iArg, mFlags) \ {nArg, SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \ SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} } diff --git a/src/test_config.c b/src/test_config.c index 362e92aa9a..8c4fba71db 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -154,6 +154,12 @@ static void set_options(Tcl_Interp *interp){ Tcl_SetVar2(interp, "sqlite_options", "deserialize", "0", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_ENABLE_MATH_FUNCTIONS + Tcl_SetVar2(interp, "sqlite_options", "mathlib", "1", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "mathlib", "0", TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_ENABLE_MEMSYS3 Tcl_SetVar2(interp, "sqlite_options", "mem3", "1", TCL_GLOBAL_ONLY); #else diff --git a/test/func7.test b/test/func7.test new file mode 100644 index 0000000000..c7fce79dd6 --- /dev/null +++ b/test/func7.test @@ -0,0 +1,35 @@ +# 2020-12-07 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#************************************************************************* +# +# Test cases for SQL functions based off the standard math library +# +set testdir [file dirname $argv0] +source $testdir/tester.tcl +ifcapable !mathlib { + finish_test + return +} + +do_execsql_test func7-100 { + SELECT ceil(99.9), ceiling(-99.01), floor(17), floor(-17.99); +} {100.0 -99.0 17 -18.0} +do_execsql_test func7-110 { + SELECT quote(ceil(NULL)), ceil('-99.99'); +} {NULL -99.0} +do_execsql_test func7-200 { + SELECT round(ln(5),2), log(100.0), log(100), log('256',2); +} {1.61 2.0 2.0 8.0} +do_execsql_test func7-210 { + SELECT ln(-5), log(100.0,-5); +} {{} {}} + + +finish_test From 63f8f98a63ef23803f663e6b128d9b3fe8ef53b6 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 7 Dec 2020 21:13:06 +0000 Subject: [PATCH 029/257] Many more math functions. Semantics follows PG wherever possible. FossilOrigin-Name: 6b93627b5d9819abf179a3e4a82e7afe17cbcafdabbd5f058de9ed114c9d477f --- manifest | 14 ++-- manifest.uuid | 2 +- src/func.c | 190 ++++++++++++++++++++++++++++++++++++------ test/func7.test | 214 +++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 386 insertions(+), 34 deletions(-) diff --git a/manifest b/manifest index 9347e389ec..dccb95c603 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Begin\sadding\snew\sSQL\sfunctions\sthat\sdepend\son\s-lm:\s\sceil(),\sceiling(),\nfloor(),\sln(),\slog(),\sand\slog10()\sso\sfar.\s\sMore\sto\sfollow. -D 2020-12-07T17:15:32.150 +C Many\smore\smath\sfunctions.\s\sSemantics\sfollows\sPG\swherever\spossible. +D 2020-12-07T21:13:06.475 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -495,7 +495,7 @@ F src/delete.c 927cf8f900583e79aca8f1a321979e0a8f053babd9a690b44b38f79de2cc09fe F src/expr.c 0d196ed5a2ebf96be7e8df88add4fabfad0dce16c0fed81a4b8f6a26e259797f F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 83372403298e6a7dd989a47aaacdbaa5b4307b5199dbd56e07d4896066b3de72 -F src/func.c d3113a23625daeb54331752421442af772abd851123550459dec96fedbe068e7 +F src/func.c 7c3a41213179cce249d46283fc2237bc3424a041343866dbdb31914fed0edddc F src/global.c ed55af196a9b66e198aaeda3f5454c3aa7d7d050c6c938181fd044b70d180a81 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 @@ -1026,7 +1026,7 @@ F test/func3.test 2bb0f31ab7baaed690b962a88544d7be6b34fa389364bc36a44e441ed3e3f1 F test/func4.test 2285fb5792d593fef442358763f0fd9de806eda47dbc7a5934df57ffdc484c31 F test/func5.test 863e6d1bd0013d09c17236f8a13ea34008dd857d87d85a13a673960e4c25d82a F test/func6.test 90e42b64c4f9fb6f04f44cb8a1da586c8542502e926b19c76504fe74ff2a9b7c -F test/func7.test 7414f1ffb7aba86b6bcfdf0c3739a4e4717026ff583acd8b43ab21189300bcdc +F test/func7.test bb05a77daedf0e3f8764f323a49bc3b8d98f280a0bc6a370387117f4596bde05 F test/fuzz-oss1.test e58330d01cbbd8215ee636b17a03fe220b37dbfa F test/fuzz.test 96083052bf5765e4518c1ba686ce2bab785670d1 F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1 @@ -1888,7 +1888,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 1db7c751912beb57a697ac8e85b9c29e30da7b6c89207e9828bf08e56c58242f -R 6662031cc76e6cb57f52d5a4ee0696ea +P 4db5f2f7875f6df78630a7816fc018141a6eee2e295b44fc7627eb66d07881ea +R 5f3694d6742f321a9a8686c5ca8182de U drh -Z 99632da1aa8e30b2d9d751e33b863567 +Z 1fdfc343d2601875f5f91cade0f6a5bf diff --git a/manifest.uuid b/manifest.uuid index 7ffa11f57e..acf82a7c34 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4db5f2f7875f6df78630a7816fc018141a6eee2e295b44fc7627eb66d07881ea \ No newline at end of file +6b93627b5d9819abf179a3e4a82e7afe17cbcafdabbd5f058de9ed114c9d477f \ No newline at end of file diff --git a/src/func.c b/src/func.c index 09e44345dc..7bfd5bd6a7 100644 --- a/src/func.c +++ b/src/func.c @@ -1904,6 +1904,18 @@ int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){ return 1; } +/* Mathematical Constants */ +#ifndef M_PI +# define M_PI 3.141592653589793238462643383279502884 +#endif +#ifndef M_LN10 +# define M_LN10 2.302585092994045684017991454684364208 +#endif +#ifndef M_LN2 +# define M_LN2 0.693147180559945309417232121458176568 +#endif + + /* Extra math functions that require linking with -lm */ #ifdef SQLITE_ENABLE_MATH_FUNCTIONS @@ -1923,17 +1935,19 @@ static void ceilingFunc( sqlite3_value **argv ){ assert( argc==1 ); - switch( sqlite3_value_type(argv[0]) ){ - case SQLITE_INTEGER: + switch( sqlite3_value_numeric_type(argv[0]) ){ + case SQLITE_INTEGER: { sqlite3_result_int64(context, sqlite3_value_int64(argv[0])); break; - case SQLITE_NULL: - break; - default: { + } + case SQLITE_FLOAT: { double (*x)(double) = (double(*)(double))sqlite3_user_data(context); sqlite3_result_double(context, x(sqlite3_value_double(argv[0]))); break; } + default: { + break; + } } } @@ -1941,38 +1955,142 @@ static void ceilingFunc( ** Implementation of SQL functions: ** ** ln(X) - natural logarithm -** log(X) - log base 10 -** log10(X) - log base 10 -** log(X,Y) - log base Y +** log(X) - log X base 10 +** log10(X) - log X base 10 +** log(B,X) - log X base B */ static void logFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ - double x, y, ans; + double x, b, ans; assert( argc==1 || argc==2 ); - if( sqlite3_value_type(argv[0])==SQLITE_NULL - || (x = sqlite3_value_double(argv[0]))<0.0 - ){ - return; /* Return NULL for a domain error */ + switch( sqlite3_value_numeric_type(argv[0]) ){ + case SQLITE_INTEGER: + case SQLITE_FLOAT: + x = sqlite3_value_double(argv[0]); + if( x<0.0 ) return; + break; + default: + return; } - ans = log(x); if( argc==2 ){ - if( sqlite3_value_type(argv[1])==SQLITE_NULL - || (y = sqlite3_value_double(argv[1]))<0.0 - ){ - return; /* Return NULL for a domain error */ + switch( sqlite3_value_numeric_type(argv[0]) ){ + case SQLITE_INTEGER: + case SQLITE_FLOAT: + b = x; + x = sqlite3_value_double(argv[1]); + if( x<0.0 ) return; + break; + default: + return; + } + ans = log(x)/log(b); + }else{ + ans = log(x); + switch( SQLITE_PTR_TO_INT(sqlite3_user_data(context)) ){ + case 1: + /* Convert from natural logarithm to log base 10 */ + ans *= 1.0/M_LN10; + break; + case 2: + /* Convert from natural logarithm to log base 2 */ + ans *= 1.0/M_LN2; + break; + default: + break; } - ans /= log(y); - }else if( sqlite3_user_data(context)!=0 ){ - /* Convert from natural logarithm to log base 10 */ - ans *= 0.43429448190325178672; } sqlite3_result_double(context, ans); } + +/* +** Functions to converts degrees to radians and radians to degrees. +*/ +static double degToRad(double x){ return x*(M_PI/180.0); } +static double radToDeg(double x){ return x*(180.0/M_PI); } + +/* +** Implementation of 1-argument SQL math functions: +** +** exp(X) - Compute e to the X-th power +*/ +static void math1Func( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + assert( argc==2 ); + int type0; + double v0, ans; + double (*x)(double); + type0 = sqlite3_value_numeric_type(argv[0]); + if( type0!=SQLITE_INTEGER && type0!=SQLITE_FLOAT ) return; + v0 = sqlite3_value_double(argv[0]); + x = (double(*)(double))sqlite3_user_data(context); + ans = x(v0); + sqlite3_result_double(context, ans); +} + +/* +** Implementation of 2-argument SQL math functions: +** +** power(X,Y) - Compute X to the Y-th power +*/ +static void math2Func( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + assert( argc==2 ); + int type0, type1; + double v0, v1, ans; + double (*x)(double,double); + type0 = sqlite3_value_numeric_type(argv[0]); + if( type0!=SQLITE_INTEGER && type0!=SQLITE_FLOAT ) return; + type1 = sqlite3_value_numeric_type(argv[1]); + if( type1!=SQLITE_INTEGER && type1!=SQLITE_FLOAT ) return; + v0 = sqlite3_value_double(argv[0]); + v1 = sqlite3_value_double(argv[1]); + x = (double(*)(double,double))sqlite3_user_data(context); + ans = x(v0, v1); + sqlite3_result_double(context, ans); +} + +/* +** Implementation of 2-argument SQL math functions: +** +** power(X,Y) - Compute X to the Y-th power +*/ +static void piFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + assert( argc==0 ); + sqlite3_result_double(context, M_PI); +} + #endif /* SQLITE_ENABLE_MATH_FUNCTIONS */ +/* +** Implementation of sign(X) function. +*/ +static void signFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + assert( argc==1 ); + int type0; + double x; + type0 = sqlite3_value_numeric_type(argv[0]); + if( type0!=SQLITE_INTEGER && type0!=SQLITE_FLOAT ) return; + x = sqlite3_value_double(argv[0]); + sqlite3_result_int(context, x<0.0 ? -1 : x>0.0 ? +1 : 0); +} + /* ** All of the FuncDef structures in the aBuiltinFunc[] array above ** to the global function hash table. This occurs at start-time (as @@ -2091,17 +2209,41 @@ void sqlite3RegisterBuiltinFunctions(void){ #endif FUNCTION(coalesce, 1, 0, 0, 0 ), FUNCTION(coalesce, 0, 0, 0, 0 ), - INLINE_FUNC(coalesce, -1, INLINEFUNC_coalesce, 0 ), - INLINE_FUNC(iif, 3, INLINEFUNC_iif, 0 ), #ifdef SQLITE_ENABLE_MATH_FUNCTIONS MFUNCTION(ceil, 1, ceil, ceilingFunc ), MFUNCTION(ceiling, 1, ceil, ceilingFunc ), MFUNCTION(floor, 1, floor, ceilingFunc ), + MFUNCTION(trunc, 1, trunc, ceilingFunc ), FUNCTION(ln, 1, 0, 0, logFunc ), FUNCTION(log, 1, 1, 0, logFunc ), FUNCTION(log10, 1, 1, 0, logFunc ), + FUNCTION(log2, 1, 2, 0, logFunc ), FUNCTION(log, 2, 0, 0, logFunc ), + MFUNCTION(exp, 1, exp, math1Func ), + MFUNCTION(pow, 2, pow, math2Func ), + MFUNCTION(power, 2, pow, math2Func ), + MFUNCTION(mod, 2, fmod, math2Func ), + MFUNCTION(acos, 1, acos, math1Func ), + MFUNCTION(asin, 1, asin, math1Func ), + MFUNCTION(atan, 1, atan, math1Func ), + MFUNCTION(atan2, 2, atan2, math2Func ), + MFUNCTION(cos, 1, cos, math1Func ), + MFUNCTION(sin, 1, sin, math1Func ), + MFUNCTION(tan, 1, tan, math1Func ), + MFUNCTION(cosh, 1, cosh, math1Func ), + MFUNCTION(sinh, 1, sinh, math1Func ), + MFUNCTION(tanh, 1, tanh, math1Func ), + MFUNCTION(acosh, 1, acosh, math1Func ), + MFUNCTION(asinh, 1, asinh, math1Func ), + MFUNCTION(atanh, 1, atanh, math1Func ), + MFUNCTION(sqrt, 1, sqrt, math1Func ), + MFUNCTION(radians, 1, degToRad, math1Func ), + MFUNCTION(degrees, 1, radToDeg, math1Func ), + FUNCTION(pi, 0, 0, 0, piFunc ), #endif /* SQLITE_ENABLE_MATH_FUNCTIONS */ + FUNCTION(sign, 1, 0, 0, signFunc ), + INLINE_FUNC(coalesce, -1, INLINEFUNC_coalesce, 0 ), + INLINE_FUNC(iif, 3, INLINEFUNC_iif, 0 ), }; #ifndef SQLITE_OMIT_ALTERTABLE sqlite3AlterFunctions(); diff --git a/test/func7.test b/test/func7.test index c7fce79dd6..536f7eb414 100644 --- a/test/func7.test +++ b/test/func7.test @@ -25,11 +25,221 @@ do_execsql_test func7-110 { SELECT quote(ceil(NULL)), ceil('-99.99'); } {NULL -99.0} do_execsql_test func7-200 { - SELECT round(ln(5),2), log(100.0), log(100), log('256',2); + SELECT round(ln(5),2), log(100.0), log(100), log(2,'256'); } {1.61 2.0 2.0 8.0} do_execsql_test func7-210 { - SELECT ln(-5), log(100.0,-5); + SELECT ln(-5), log(-5,100.0); } {{} {}} +# Test cases derived from PostgreSQL documentation +# +do_execsql_test func7-pg-100 { + SELECT abs(-17.4) +} {17.4} +do_execsql_test func7-pg-110 { + SELECT ceil(42.2) +} {43.0} +do_execsql_test func7-pg-120 { + SELECT ceil(-42.2) +} {-42.0} +do_execsql_test func7-pg-130 { + SELECT round(exp(1.0),7) +} {2.7182818} +do_execsql_test func7-pg-140 { + SELECT floor(42.8) +} {42.0} +do_execsql_test func7-pg-150 { + SELECT floor(-42.8) +} {-43.0} +do_execsql_test func7-pg-160 { + SELECT round(ln(2.0),7) +} {0.6931472} +do_execsql_test func7-pg-170 { + SELECT log(100.0) +} {2.0} +do_execsql_test func7-pg-180 { + SELECT log10(1000.0) +} {3.0} +do_execsql_test func7-pg-190 { + SELECT log(2.0, 64.0) +} {6.0} +do_execsql_test func7-pg-200 { + SELECT mod(9,4); +} {1.0} +do_execsql_test func7-pg-210 { + SELECT round(pi(),7); +} {3.1415927} +do_execsql_test func7-pg-220 { + SELECT power(9,3); +} {729.0} +do_execsql_test func7-pg-230 { + SELECT round(radians(45.0),7); +} {0.7853982} +do_execsql_test func7-pg-240 { + SELECT round(42.4); +} {42.0} +do_execsql_test func7-pg-250 { + SELECT round(42.4382,2); +} {42.44} +do_execsql_test func7-pg-260 { + SELECT sign(-8.4); +} {-1} +do_execsql_test func7-pg-270 { + SELECT round( sqrt(2), 7); +} {1.4142136} +do_execsql_test func7-pg-280 { + SELECT trunc(42.8), trunc(-42.8); +} {42.0 -42.0} +do_execsql_test func7-pg-300 { + SELECT acos(1); +} {0.0} +do_execsql_test func7-pg-301 { + SELECT degrees(acos(0.5)); +} {60.0} +do_execsql_test func7-pg-310 { + SELECT round( asin(1), 7); +} {1.5707963} +do_execsql_test func7-pg-311 { + SELECT degrees( asin(0.5) ); +} {30.0} +do_execsql_test func7-pg-320 { + SELECT round( atan(1), 7); +} {0.7853982} +do_execsql_test func7-pg-321 { + SELECT degrees( atan(1) ); +} {45.0} +do_execsql_test func7-pg-330 { + SELECT round( atan2(1,0), 7); +} {1.5707963} +do_execsql_test func7-pg-331 { + SELECT degrees( atan2(1,0) ); +} {90.0} +do_execsql_test func7-pg-400 { + SELECT cos(0); +} {1.0} +do_execsql_test func7-pg-401 { + SELECT cos( radians(60.0) ); +} {0.5} +do_execsql_test func7-pg-400 { + SELECT cos(0); +} {1.0} +do_execsql_test func7-pg-410 { + SELECT round( sin(1), 7); +} {0.841471} +do_execsql_test func7-pg-411 { + SELECT sin( radians(30) ); +} {0.5} +do_execsql_test func7-pg-420 { + SELECT round( tan(1), 7); +} {1.5574077} +do_execsql_test func7-pg-421 { + SELECT tan( radians(45) ); +} {1.0} +do_execsql_test func7-pg-500 { + SELECT round( sinh(1), 7); +} {1.1752012} +do_execsql_test func7-pg-510 { + SELECT round( cosh(0), 7); +} {1.0} +do_execsql_test func7-pg-520 { + SELECT round( tanh(1), 7); +} {0.7615942} +do_execsql_test func7-pg-530 { + SELECT round( asinh(1), 7); +} {0.8813736} +do_execsql_test func7-pg-540 { + SELECT round( acosh(1), 7); +} {0.0} +do_execsql_test func7-pg-550 { + SELECT round( atanh(0.5), 7); +} {0.5493061} + +# Test cases derived from MySQL documentation +# +do_execsql_test func7-mysql-100 { + SELECT acos(1); +} {0.0} +do_execsql_test func7-mysql-110 { + SELECT acos(1.0001); +} {{}} +do_execsql_test func7-mysql-120 { + SELECT round( acos(0.0), 7); +} {1.5707963} +do_execsql_test func7-mysql-130 { + SELECT round( asin(0.2), 7); +} {0.2013579} +do_execsql_test func7-mysql-140 { + SELECT asin('foo'); +} {{}} ;# Note: MySQL returns 0 here, not NULL. + # SQLite deliberately returns NULL. + # SQLServer and Oracle throw an error. +do_execsql_test func7-mysql-150 { + SELECT round( atan(2), 7), round( atan(-2), 7); +} {1.1071487 -1.1071487} +do_execsql_test func7-mysql-160 { + SELECT round( atan2(-2,2), 7), round( atan2(pi(),0), 7); +} {-0.7853982 1.5707963} +do_execsql_test func7-mysql-170 { + SELECT ceiling(1.23), ceiling(-1.23); +} {2.0 -1.0} +do_execsql_test func7-mysql-180 { + SELECT cos(pi()); +} {-1.0} +do_execsql_test func7-mysql-190 { + SELECT degrees(pi()), degrees(pi()/2); +} {180.0 90.0} +do_execsql_test func7-mysql-190 { + SELECT round( exp(2), 7), round( exp(-2), 7), exp(0); +} {7.3890561 0.1353353 1.0} +do_execsql_test func7-mysql-200 { + SELECT floor(1.23), floor(-1.23); +} {1.0 -2.0} +do_execsql_test func7-mysql-210 { + SELECT round(ln(2),7), quote(ln(-2)); +} {0.6931472 NULL} +#do_execsql_test func7-mysql-220 { +# SELECT round(log(2),7), log(-2); +#} {0.6931472 NULL} +# log() means natural logarithm in MySQL +do_execsql_test func7-mysql-230 { + SELECT log(2,65536), log(10,100), quote(log(1,100)); +} {16.0 2.0 Inf} +do_execsql_test func7-mysql-240 { + SELECT log2(65536), quote(log2(-100)); +} {16.0 NULL} +do_execsql_test func7-mysql-250 { + SELECT round(log10(2),7), log10(100), quote(log10(-100)); +} {0.30103 2.0 NULL} +do_execsql_test func7-mysql-260 { + SELECT mod(234,10), 253%7, mod(29,9), 29%9; +} {4.0 1 2.0 2} +do_execsql_test func7-mysql-270 { + SELECT mod(34.5,3); +} {1.5} +do_execsql_test func7-mysql-280 { + SELECT pow(2,2), pow(2,-2); +} {4.0 0.25} +do_execsql_test func7-mysql-281 { + SELECT power(2,2), power(2,-2); +} {4.0 0.25} +do_execsql_test func7-mysql-290 { + SELECT round(radians(90),7); +} {1.5707963} +do_execsql_test func7-mysql-300 { + SELECT sign(-32), sign(0), sign(234); +} {-1 0 1} +do_execsql_test func7-mysql-310 { + SELECT sin(pi()) BETWEEN -1.0e-15 AND 1.0e-15; +} {1} +do_execsql_test func7-mysql-320 { + SELECT sqrt(4), round(sqrt(20),7), quote(sqrt(-16)); +} {2.0 4.472136 NULL} +do_execsql_test func7-mysql-330 { + SELECT tan(pi()) BETWEEN -1.0e-15 AND 1.0e-15; +} {1} +do_execsql_test func7-mysql-331 { + SELECT round(tan(pi()+1),7); +} {1.5574077} + finish_test From e2ce8c446fd3f2ce188af9b5b75584fb52f7839e Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 7 Dec 2020 21:19:17 +0000 Subject: [PATCH 030/257] Fix to the --disable-math option to ./configure. FossilOrigin-Name: 99ff6418492adcbaf2be728737735afa1c2997de5868395e69c53d08fc14491f --- configure | 35 ++++++++++++++++++----------------- configure.ac | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 27 insertions(+), 26 deletions(-) diff --git a/configure b/configure index 5a313189b1..b094ef71ad 100755 --- a/configure +++ b/configure @@ -903,6 +903,7 @@ with_readline_inc enable_debug enable_amalgamation enable_load_extension +enable_math enable_memsys5 enable_memsys3 enable_all @@ -3936,13 +3937,13 @@ if ${lt_cv_nm_interface+:} false; then : else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:3939: $ac_compile\"" >&5) + (eval echo "\"\$as_me:3940: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:3942: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:3943: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:3945: output\"" >&5) + (eval echo "\"\$as_me:3946: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -5148,7 +5149,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 5151 "configure"' > conftest.$ac_ext + echo '#line 5152 "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -6673,11 +6674,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6676: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6677: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:6680: \$? = $ac_status" >&5 + echo "$as_me:6681: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7012,11 +7013,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7015: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7016: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7019: \$? = $ac_status" >&5 + echo "$as_me:7020: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7117,11 +7118,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7120: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7121: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7124: \$? = $ac_status" >&5 + echo "$as_me:7125: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -7172,11 +7173,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7175: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7176: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7179: \$? = $ac_status" >&5 + echo "$as_me:7180: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -9552,7 +9553,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9555 "configure" +#line 9556 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -9648,7 +9649,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9651 "configure" +#line 9652 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11415,9 +11416,9 @@ fi ########## # Do we want to support math functions # -# Check whether --enable-threadsafe was given. -if test "${enable_threadsafe+set}" = set; then : - enableval=$enable_threadsafe; +# Check whether --enable-math was given. +if test "${enable_math+set}" = set; then : + enableval=$enable_math; fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support math functions" >&5 diff --git a/configure.ac b/configure.ac index 5285581eec..ae73a5350e 100644 --- a/configure.ac +++ b/configure.ac @@ -589,7 +589,7 @@ fi ########## # Do we want to support math functions # -AC_ARG_ENABLE(threadsafe, +AC_ARG_ENABLE(math, AC_HELP_STRING([--disable-math],[Disable math functions])) AC_MSG_CHECKING([whether to support math functions]) if test "$enable_math" = "no"; then diff --git a/manifest b/manifest index dccb95c603..9811874330 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Many\smore\smath\sfunctions.\s\sSemantics\sfollows\sPG\swherever\spossible. -D 2020-12-07T21:13:06.475 +C Fix\sto\sthe\s--disable-math\soption\sto\s./configure. +D 2020-12-07T21:19:17.901 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -34,8 +34,8 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6 F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559 -F configure 79bcd87c8c18e4e60a9b0282c259b9db912e68c086cb65634628763b3c6b6321 x -F configure.ac b865a0e9724d09b5e510d07340901ecfceab706c8d21f26d55914f2d1be7dc7e +F configure 7736c168f4fd717c8052e58428a89e645d15cf0e5a3d051e248aad859a3cb140 x +F configure.ac efdb70036084ea637226e378a14f932e70c0df9f1bc846a24a909c0e1613524a F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd F doc/lemon.html c5d8ba85ac1daef7be8c2d389899480eb62451ff5c09b0c28ff8157bb8770746 @@ -1888,7 +1888,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 4db5f2f7875f6df78630a7816fc018141a6eee2e295b44fc7627eb66d07881ea -R 5f3694d6742f321a9a8686c5ca8182de +P 6b93627b5d9819abf179a3e4a82e7afe17cbcafdabbd5f058de9ed114c9d477f +R 344d0bcab916063736a47d8c55992722 U drh -Z 1fdfc343d2601875f5f91cade0f6a5bf +Z c106f4c2e997d379fe9c71e8d1365827 diff --git a/manifest.uuid b/manifest.uuid index acf82a7c34..3b76d9f0d7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6b93627b5d9819abf179a3e4a82e7afe17cbcafdabbd5f058de9ed114c9d477f \ No newline at end of file +99ff6418492adcbaf2be728737735afa1c2997de5868395e69c53d08fc14491f \ No newline at end of file From 0dffe465f76869016bc8b849f160c3d1a40505e8 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 7 Dec 2020 23:14:25 +0000 Subject: [PATCH 031/257] Fix a bad assert() in math1Func(). FossilOrigin-Name: 4b286129138d44e6f8e9b3450289941e01d20fdfb9d0b5d846031425e8ca6b49 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/func.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 9811874330..18c17599b4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sto\sthe\s--disable-math\soption\sto\s./configure. -D 2020-12-07T21:19:17.901 +C Fix\sa\sbad\sassert()\sin\smath1Func(). +D 2020-12-07T23:14:25.210 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -495,7 +495,7 @@ F src/delete.c 927cf8f900583e79aca8f1a321979e0a8f053babd9a690b44b38f79de2cc09fe F src/expr.c 0d196ed5a2ebf96be7e8df88add4fabfad0dce16c0fed81a4b8f6a26e259797f F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 83372403298e6a7dd989a47aaacdbaa5b4307b5199dbd56e07d4896066b3de72 -F src/func.c 7c3a41213179cce249d46283fc2237bc3424a041343866dbdb31914fed0edddc +F src/func.c c65447d69bbf743328e7e4e836475ac5fb4ab80213fe5b189b8b0109e942e7c1 F src/global.c ed55af196a9b66e198aaeda3f5454c3aa7d7d050c6c938181fd044b70d180a81 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 @@ -1888,7 +1888,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 6b93627b5d9819abf179a3e4a82e7afe17cbcafdabbd5f058de9ed114c9d477f -R 344d0bcab916063736a47d8c55992722 +P 99ff6418492adcbaf2be728737735afa1c2997de5868395e69c53d08fc14491f +R 747ed0f69719082482a4ff82786fa288 U drh -Z c106f4c2e997d379fe9c71e8d1365827 +Z ac855459dfaf775bb9ffc51142afdf45 diff --git a/manifest.uuid b/manifest.uuid index 3b76d9f0d7..7e5c04ae26 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -99ff6418492adcbaf2be728737735afa1c2997de5868395e69c53d08fc14491f \ No newline at end of file +4b286129138d44e6f8e9b3450289941e01d20fdfb9d0b5d846031425e8ca6b49 \ No newline at end of file diff --git a/src/func.c b/src/func.c index 7bfd5bd6a7..169f231430 100644 --- a/src/func.c +++ b/src/func.c @@ -2021,7 +2021,7 @@ static void math1Func( int argc, sqlite3_value **argv ){ - assert( argc==2 ); + assert( argc==1 ); int type0; double v0, ans; double (*x)(double); From 2549e4cc2fef9fc969a9efdc723c2bcf1ac69f1f Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 8 Dec 2020 14:29:03 +0000 Subject: [PATCH 032/257] Enhance UPSERT parsing to allow multiple ON CONFLICT clauses. Only the very last clause may omit the conflict target, but the conflict target may now be omitted for the DO UPDATE resolution. FossilOrigin-Name: 2ca62f4c71df6544cb8039bdc80e3701d09697c38800534371f6d44532fcffae --- manifest | 19 +++-- manifest.uuid | 2 +- src/parse.y | 19 ++--- src/sqliteInt.h | 7 +- src/upsert.c | 189 +++++++++++++++++++++++++++--------------------- 5 files changed, 130 insertions(+), 106 deletions(-) diff --git a/manifest b/manifest index 18c17599b4..9471059ac9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbad\sassert()\sin\smath1Func(). -D 2020-12-07T23:14:25.210 +C Enhance\sUPSERT\sparsing\sto\sallow\smultiple\sON\sCONFLICT\sclauses.\s\sOnly\sthe\nvery\slast\sclause\smay\somit\sthe\sconflict\starget,\sbut\sthe\sconflict\starget\smay\nnow\sbe\somitted\sfor\sthe\sDO\sUPDATE\sresolution. +D 2020-12-08T14:29:03.533 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -529,7 +529,7 @@ F src/os_win.c 77d39873836f1831a9b0b91894fec45ab0e9ca8e067dc8c549e1d1eca1566fe9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c c49952ac5e9cc536778eff528091d79d38b3e45cbeeed4695dc05e207dc6547d F src/pager.h 4bf9b3213a4b2bebbced5eaa8b219cf25d4a82f385d093cd64b7e93e5285f66f -F src/parse.y 9ce4dfb772608ed5bd3c32f33e943e021e3b06cfd2c01932d4280888fdd2ebed +F src/parse.y 72b884c73f2b446e7dc4c7169ec7fbb82e0e292eec733fcf554f0fde46f269f6 F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a @@ -545,7 +545,7 @@ F src/shell.c.in e9f674ee4ec6c345679e8a5b16c869c6c59eb1540dd98ac69e4736ecddce009 F src/sqlite.h.in 0e2b4259e49a0eda54d9118eb18a04fcd60e0727a2fd2c81aade0bf57520e706 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h 6ab40b33a1f5edbb7d71c78e82e0f9c5291dcff4704df8e4f0ab0d9c1a0c06af +F src/sqliteInt.h 351d29fad669d5c98066a89ab48259d451379edac3c24773c3c8ac5df66fd8ff F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -608,7 +608,7 @@ F src/tokenize.c 01dba3023659dc6f6b1e054c14b35a0074bd35de10466b99454d33278191d97 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda F src/trigger.c 515e79206d40d1d4149129318582e79a6e9db590a7b74e226fdb5b2a6c7e1b10 F src/update.c 9f126204a6acb96bbe47391ae48e0fc579105d8e76a6d9c4fab3271367476580 -F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78 +F src/upsert.c 25673d007c2408fec47a6326b6d7ac265abd2cbc162d11f3b3c333de27d3c78a F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c c0c7977de7ef9b8cb10f6c85f2d0557889a658f817b0455909a49179ba4c8002 F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286 @@ -1888,7 +1888,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 99ff6418492adcbaf2be728737735afa1c2997de5868395e69c53d08fc14491f -R 747ed0f69719082482a4ff82786fa288 +P 4b286129138d44e6f8e9b3450289941e01d20fdfb9d0b5d846031425e8ca6b49 +R 204aa888c3a8b96c5008bc9a579603f7 +T *branch * generalized-upsert +T *sym-generalized-upsert * +T -sym-trunk * U drh -Z ac855459dfaf775bb9ffc51142afdf45 +Z d13edca14ac31a65fc7ae7d7fdc7eaff diff --git a/manifest.uuid b/manifest.uuid index 7e5c04ae26..0eeaf11f2a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4b286129138d44e6f8e9b3450289941e01d20fdfb9d0b5d846031425e8ca6b49 \ No newline at end of file +2ca62f4c71df6544cb8039bdc80e3701d09697c38800534371f6d44532fcffae \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index d3ec2b3da6..f28bb47414 100644 --- a/src/parse.y +++ b/src/parse.y @@ -952,20 +952,17 @@ cmd ::= with insert_cmd(R) INTO xfullname(X) idlist_opt(F) DEFAULT VALUES. } %type upsert {Upsert*} - -// Because upsert only occurs at the tip end of the INSERT rule for cmd, -// there is never a case where the value of the upsert pointer will not -// be destroyed by the cmd action. So comment-out the destructor to -// avoid unreachable code. -//%destructor upsert {sqlite3UpsertDelete(pParse->db,$$);} +%destructor upsert {sqlite3UpsertDelete(pParse->db,$$);} upsert(A) ::= . { A = 0; } upsert(A) ::= ON CONFLICT LP sortlist(T) RP where_opt(TW) - DO UPDATE SET setlist(Z) where_opt(W). - { A = sqlite3UpsertNew(pParse->db,T,TW,Z,W);} -upsert(A) ::= ON CONFLICT LP sortlist(T) RP where_opt(TW) DO NOTHING. - { A = sqlite3UpsertNew(pParse->db,T,TW,0,0); } + DO UPDATE SET setlist(Z) where_opt(W) upsert(N). + { A = sqlite3UpsertNew(pParse->db,T,TW,Z,W,N);} +upsert(A) ::= ON CONFLICT LP sortlist(T) RP where_opt(TW) DO NOTHING upsert(N). + { A = sqlite3UpsertNew(pParse->db,T,TW,0,0,N); } upsert(A) ::= ON CONFLICT DO NOTHING. - { A = sqlite3UpsertNew(pParse->db,0,0,0,0); } + { A = sqlite3UpsertNew(pParse->db,0,0,0,0,0); } +upsert(A) ::= ON CONFLICT DO UPDATE SET setlist(Z) where_opt(W). + { A = sqlite3UpsertNew(pParse->db,0,0,Z,W,0);} %type insert_cmd {int} insert_cmd(A) ::= INSERT orconf(R). {A = R;} diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 438f79c092..68c8680600 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3071,6 +3071,7 @@ struct Upsert { Expr *pUpsertTargetWhere; /* WHERE clause for partial index targets */ ExprList *pUpsertSet; /* The SET clause from an ON CONFLICT UPDATE */ Expr *pUpsertWhere; /* WHERE clause for the ON CONFLICT UPDATE */ + Upsert *pNextUpsert; /* Next ON CONFLICT clause in the list */ /* The fields above comprise the parse tree for the upsert clause. ** The fields below are used to transfer information from the INSERT ** processing down into the UPDATE processing while generating code. @@ -4824,15 +4825,15 @@ const char *sqlite3JournalModename(int); #define sqlite3WithDelete(x,y) #endif #ifndef SQLITE_OMIT_UPSERT - Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*); + Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*,Upsert*); void sqlite3UpsertDelete(sqlite3*,Upsert*); Upsert *sqlite3UpsertDup(sqlite3*,Upsert*); int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*); void sqlite3UpsertDoUpdate(Parse*,Upsert*,Table*,Index*,int); #else -#define sqlite3UpsertNew(v,w,x,y,z) ((Upsert*)0) +#define sqlite3UpsertNew(u,v,w,x,y,z) ((Upsert*)0) #define sqlite3UpsertDelete(x,y) -#define sqlite3UpsertDup(x,y) ((Upsert*)0) +#define sqlite3UpsertDup(x,y) ((Upsert*)0) #endif diff --git a/src/upsert.c b/src/upsert.c index 9a33f75d0a..ddd7c18428 100644 --- a/src/upsert.c +++ b/src/upsert.c @@ -18,15 +18,21 @@ /* ** Free a list of Upsert objects */ -void sqlite3UpsertDelete(sqlite3 *db, Upsert *p){ - if( p ){ +static void SQLITE_NOINLINE upsertDelete(sqlite3 *db, Upsert *p){ + do{ + Upsert *pNext = p->pNextUpsert; sqlite3ExprListDelete(db, p->pUpsertTarget); sqlite3ExprDelete(db, p->pUpsertTargetWhere); sqlite3ExprListDelete(db, p->pUpsertSet); sqlite3ExprDelete(db, p->pUpsertWhere); sqlite3DbFree(db, p); - } + p = pNext; + }while( p ); } +void sqlite3UpsertDelete(sqlite3 *db, Upsert *p){ + if( p ) upsertDelete(db, p); +} + /* ** Duplicate an Upsert object. @@ -37,7 +43,8 @@ Upsert *sqlite3UpsertDup(sqlite3 *db, Upsert *p){ sqlite3ExprListDup(db, p->pUpsertTarget, 0), sqlite3ExprDup(db, p->pUpsertTargetWhere, 0), sqlite3ExprListDup(db, p->pUpsertSet, 0), - sqlite3ExprDup(db, p->pUpsertWhere, 0) + sqlite3ExprDup(db, p->pUpsertWhere, 0), + sqlite3UpsertDup(db, p->pNextUpsert) ); } @@ -49,7 +56,8 @@ Upsert *sqlite3UpsertNew( ExprList *pTarget, /* Target argument to ON CONFLICT, or NULL */ Expr *pTargetWhere, /* Optional WHERE clause on the target */ ExprList *pSet, /* UPDATE columns, or NULL for a DO NOTHING */ - Expr *pWhere /* WHERE clause for the ON CONFLICT UPDATE */ + Expr *pWhere, /* WHERE clause for the ON CONFLICT UPDATE */ + Upsert *pNext /* Next ON CONFLICT clause in the list */ ){ Upsert *pNew; pNew = sqlite3DbMallocRaw(db, sizeof(Upsert)); @@ -58,6 +66,7 @@ Upsert *sqlite3UpsertNew( sqlite3ExprDelete(db, pTargetWhere); sqlite3ExprListDelete(db, pSet); sqlite3ExprDelete(db, pWhere); + sqlite3UpsertDelete(db, pNext); return 0; }else{ pNew->pUpsertTarget = pTarget; @@ -65,6 +74,7 @@ Upsert *sqlite3UpsertNew( pNew->pUpsertSet = pSet; pNew->pUpsertWhere = pWhere; pNew->pUpsertIdx = 0; + pNew->pNextUpsert = pNext; } return pNew; } @@ -89,6 +99,7 @@ int sqlite3UpsertAnalyzeTarget( Expr *pTerm; /* One term of the conflict-target clause */ NameContext sNC; /* Context for resolving symbolic names */ Expr sCol[2]; /* Index column converted into an Expr */ + int nClause = 0; /* Counter of ON CONFLICT clauses */ assert( pTabList->nSrc==1 ); assert( pTabList->a[0].pTab!=0 ); @@ -102,87 +113,99 @@ int sqlite3UpsertAnalyzeTarget( memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; sNC.pSrcList = pTabList; - rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget); - if( rc ) return rc; - rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere); - if( rc ) return rc; - - /* Check to see if the conflict target matches the rowid. */ - pTab = pTabList->a[0].pTab; - pTarget = pUpsert->pUpsertTarget; - iCursor = pTabList->a[0].iCursor; - if( HasRowid(pTab) - && pTarget->nExpr==1 - && (pTerm = pTarget->a[0].pExpr)->op==TK_COLUMN - && pTerm->iColumn==XN_ROWID - ){ - /* The conflict-target is the rowid of the primary table */ - assert( pUpsert->pUpsertIdx==0 ); - return SQLITE_OK; - } - - /* Initialize sCol[0..1] to be an expression parse tree for a - ** single column of an index. The sCol[0] node will be the TK_COLLATE - ** operator and sCol[1] will be the TK_COLUMN operator. Code below - ** will populate the specific collation and column number values - ** prior to comparing against the conflict-target expression. - */ - memset(sCol, 0, sizeof(sCol)); - sCol[0].op = TK_COLLATE; - sCol[0].pLeft = &sCol[1]; - sCol[1].op = TK_COLUMN; - sCol[1].iTable = pTabList->a[0].iCursor; - - /* Check for matches against other indexes */ - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - int ii, jj, nn; - if( !IsUniqueIndex(pIdx) ) continue; - if( pTarget->nExpr!=pIdx->nKeyCol ) continue; - if( pIdx->pPartIdxWhere ){ - if( pUpsert->pUpsertTargetWhere==0 ) continue; - if( sqlite3ExprCompare(pParse, pUpsert->pUpsertTargetWhere, - pIdx->pPartIdxWhere, iCursor)!=0 ){ - continue; - } - } - nn = pIdx->nKeyCol; - for(ii=0; iiazColl[ii]; - if( pIdx->aiColumn[ii]==XN_EXPR ){ - assert( pIdx->aColExpr!=0 ); - assert( pIdx->aColExpr->nExpr>ii ); - pExpr = pIdx->aColExpr->a[ii].pExpr; - if( pExpr->op!=TK_COLLATE ){ - sCol[0].pLeft = pExpr; - pExpr = &sCol[0]; - } - }else{ - sCol[0].pLeft = &sCol[1]; - sCol[1].iColumn = pIdx->aiColumn[ii]; - pExpr = &sCol[0]; - } - for(jj=0; jja[jj].pExpr, pExpr,iCursor)<2 ){ - break; /* Column ii of the index matches column jj of target */ - } - } - if( jj>=nn ){ - /* The target contains no match for column jj of the index */ - break; - } - } - if( iipUpsertTarget; + pUpsert=pUpsert->pNextUpsert, nClause++){ + rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget); + if( rc ) return rc; + rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere); + if( rc ) return rc; + + /* Check to see if the conflict target matches the rowid. */ + pTab = pTabList->a[0].pTab; + pTarget = pUpsert->pUpsertTarget; + iCursor = pTabList->a[0].iCursor; + if( HasRowid(pTab) + && pTarget->nExpr==1 + && (pTerm = pTarget->a[0].pExpr)->op==TK_COLUMN + && pTerm->iColumn==XN_ROWID + ){ + /* The conflict-target is the rowid of the primary table */ + assert( pUpsert->pUpsertIdx==0 ); continue; } - pUpsert->pUpsertIdx = pIdx; - return SQLITE_OK; + + /* Initialize sCol[0..1] to be an expression parse tree for a + ** single column of an index. The sCol[0] node will be the TK_COLLATE + ** operator and sCol[1] will be the TK_COLUMN operator. Code below + ** will populate the specific collation and column number values + ** prior to comparing against the conflict-target expression. + */ + memset(sCol, 0, sizeof(sCol)); + sCol[0].op = TK_COLLATE; + sCol[0].pLeft = &sCol[1]; + sCol[1].op = TK_COLUMN; + sCol[1].iTable = pTabList->a[0].iCursor; + + /* Check for matches against other indexes */ + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + int ii, jj, nn; + if( !IsUniqueIndex(pIdx) ) continue; + if( pTarget->nExpr!=pIdx->nKeyCol ) continue; + if( pIdx->pPartIdxWhere ){ + if( pUpsert->pUpsertTargetWhere==0 ) continue; + if( sqlite3ExprCompare(pParse, pUpsert->pUpsertTargetWhere, + pIdx->pPartIdxWhere, iCursor)!=0 ){ + continue; + } + } + nn = pIdx->nKeyCol; + for(ii=0; iiazColl[ii]; + if( pIdx->aiColumn[ii]==XN_EXPR ){ + assert( pIdx->aColExpr!=0 ); + assert( pIdx->aColExpr->nExpr>ii ); + pExpr = pIdx->aColExpr->a[ii].pExpr; + if( pExpr->op!=TK_COLLATE ){ + sCol[0].pLeft = pExpr; + pExpr = &sCol[0]; + } + }else{ + sCol[0].pLeft = &sCol[1]; + sCol[1].iColumn = pIdx->aiColumn[ii]; + pExpr = &sCol[0]; + } + for(jj=0; jja[jj].pExpr,pExpr,iCursor)<2 ){ + break; /* Column ii of the index matches column jj of target */ + } + } + if( jj>=nn ){ + /* The target contains no match for column jj of the index */ + break; + } + } + if( iipUpsertIdx = pIdx; + break; + } + if( pUpsert->pUpsertIdx==0 ){ + char zWhich[16]; + if( nClause==0 && pUpsert->pNextUpsert==0 ){ + zWhich[0] = 0; + }else{ + sqlite3_snprintf(sizeof(zWhich),zWhich,"%r ", nClause+1); + } + sqlite3ErrorMsg(pParse, "%sON CONFLICT clause does not match any " + "PRIMARY KEY or UNIQUE constraint", zWhich); + return SQLITE_ERROR; + } } - sqlite3ErrorMsg(pParse, "ON CONFLICT clause does not match any " - "PRIMARY KEY or UNIQUE constraint"); - return SQLITE_ERROR; + return SQLITE_OK; } /* From 036e0675e6a0af385f03592a7ab56ba81e056174 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 8 Dec 2020 20:19:07 +0000 Subject: [PATCH 033/257] Experimental changes to vacuum to avoid loading large records entirely into memory. Currently only works in limited cases only - for rowid tables when the page-size does not change. FossilOrigin-Name: c90e063ca9ddcdd1e9f1a2e25a3f7d6e7ee798373ad8acf65b90536b0a124c0d --- manifest | 23 +++++++------- manifest.uuid | 2 +- src/btree.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/btree.h | 2 ++ src/insert.c | 21 +++++++------ src/vdbe.c | 38 ++++++++++++++++++----- 6 files changed, 142 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index 18c17599b4..6cf3a15c36 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbad\sassert()\sin\smath1Func(). -D 2020-12-07T23:14:25.210 +C Experimental\schanges\sto\svacuum\sto\savoid\sloading\slarge\srecords\sentirely\sinto\smemory.\sCurrently\sonly\sworks\sin\slimited\scases\sonly\s-\sfor\srowid\stables\swhen\sthe\spage-size\sdoes\snot\schange. +D 2020-12-08T20:19:07.385 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -481,8 +481,8 @@ F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c ee14224322b9e4172d01e691e2f289f6c630ae39b7906f84b72dc780b9e42a76 -F src/btree.h dcdff4037d75b3f032a5de0d922fcfaf35d48589417f634fa8627362709315f9 +F src/btree.c 6d5cfd0e411e1db8042c94593a4847d85fc5398fa4860689d6f0d74cefa4e534 +F src/btree.h cff4cd182eb0d97802d82f398e4c8447f01bd2f5e501f70386b1097c910091cb F src/btreeInt.h ffd66480520d9d70222171b3a026d78b80833b5cea49c89867949f3e023d5f43 F src/build.c f6449d4e85e998e14d3f537e8ea898dca2fcb83c277db3e60945af9b9177db81 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c @@ -501,7 +501,7 @@ 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 7e081d33aab4a9d761c39dccf3c3872c35501565d2ed9db66301918d23bc7901 +F src/insert.c a64406fb5ae856fb30be018423eec9984a60a9b46d261447717c502b1fb781d3 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 F src/main.c 97e9f137354bc1f76dc9bb60a0a24f8c45cf73b33e80d3ee4c64155336fb820d @@ -612,7 +612,7 @@ F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c c0c7977de7ef9b8cb10f6c85f2d0557889a658f817b0455909a49179ba4c8002 F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286 -F src/vdbe.c d24a43b6b1ed2dba893636a14f5e56001444ab3fd5465e3bca8ab01799840acd +F src/vdbe.c 77fd09a782f72d5ff6e69363353e80e31d26bedd1d187e8813d781c74ba15770 F src/vdbe.h 83603854bfa5851af601fc0947671eb260f4363e62e960e8a994fb9bbcd2aaa1 F src/vdbeInt.h 3ca5e9fd6e095a8b6cf6bc3587a46fc93499503b2fe48951e1034ba9e2ce2f6e F src/vdbeapi.c c5e7cb2ab89a24d7f723e87b508f21bfb1359a04db5277d8a99fd1e015c12eb9 @@ -1888,7 +1888,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 99ff6418492adcbaf2be728737735afa1c2997de5868395e69c53d08fc14491f -R 747ed0f69719082482a4ff82786fa288 -U drh -Z ac855459dfaf775bb9ffc51142afdf45 +P 4b286129138d44e6f8e9b3450289941e01d20fdfb9d0b5d846031425e8ca6b49 +R ebe894c92d077c4bc1f846403c247ebe +T *branch * vacuum-lomem +T *sym-vacuum-lomem * +T -sym-trunk * +U dan +Z e00eb83dabf2298b62b079f62bce894b diff --git a/manifest.uuid b/manifest.uuid index 7e5c04ae26..ccd89eef6a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4b286129138d44e6f8e9b3450289941e01d20fdfb9d0b5d846031425e8ca6b49 \ No newline at end of file +c90e063ca9ddcdd1e9f1a2e25a3f7d6e7ee798373ad8acf65b90536b0a124c0d \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 4ac283101a..abc28c179a 100644 --- a/src/btree.c +++ b/src/btree.c @@ -6500,6 +6500,10 @@ static int fillInCell( /* Fill in the header. */ nHeader = pPage->childPtrSize; if( pPage->intKey ){ + if( pX->pData==(const void*)pPage->pBt->pTmpSpace ){ + *pnSize = pX->nData; + return SQLITE_OK; + } nPayload = pX->nData + pX->nZero; pSrc = pX->pData; nSrc = pX->nData; @@ -8912,6 +8916,85 @@ end_insert: return rc; } +int sqlite3BtreeTransfer( + BtCursor *pDest, + BtCursor *pSrc, + i64 iKey, + int seekResult +){ + int rc = SQLITE_OK; + BtreePayload x; + + memset(&x, 0, sizeof(x)); + x.nKey = iKey; + getCellInfo(pSrc); + if( pDest->pBt->usableSize!=pSrc->pBt->usableSize ){ + void *pFree = 0; + x.nData = pSrc->info.nPayload; + if( pSrc->info.nLocal==pSrc->info.nPayload ){ + x.pData = pSrc->info.pPayload; + }else{ + x.pData = pFree = sqlite3_malloc(pSrc->info.nPayload); + if( pFree==0 ){ + rc = SQLITE_NOMEM_BKPT; + }else{ + rc = sqlite3BtreePayload(pSrc, 0, x.nData, pFree); + } + } + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeInsert(pDest, &x, OPFLAG_APPEND, seekResult); + } + sqlite3_free(pFree); + }else{ + /* Page sizes match. This means each overflow page (if any) and the + ** cell itself can be copied verbatim. */ + u8 *pCell = pDest->pBt->pTmpSpace; + x.pData = pCell; + x.nData = putVarint32(pCell, pSrc->info.nPayload); + x.nData += putVarint(&pCell[x.nData], iKey); + memcpy(&pCell[x.nData], pSrc->info.pPayload, pSrc->info.nLocal); + x.nData += pSrc->info.nLocal; + assert( pSrc->info.nLocal<=pSrc->info.nPayload ); + if( pSrc->info.nLocalinfo.nPayload ){ + Pager *pSrcPager = pSrc->pBt->pPager; + u8 *pPgno = &pCell[x.nData]; + Pgno ovfl; + x.nData += 4; + ovfl = get4byte(pSrc->info.pPayload + pSrc->info.nLocal); + do{ + MemPage *pNew = 0; + Pgno pgnoNew = 0; + if( rc==SQLITE_OK ){ + rc = allocateBtreePage(pDest->pBt, &pNew, &pgnoNew, 0, 0); + put4byte(pPgno, pgnoNew); + } + if( rc==SQLITE_OK ){ + pPgno = pNew->aData; + rc = sqlite3PagerWrite(pNew->pDbPage); + } + if( rc==SQLITE_OK ){ + DbPage *pOrig = 0; + void *pOrigData; + rc = sqlite3PagerGet(pSrcPager, ovfl, &pOrig, PAGER_GET_READONLY); + if( rc==SQLITE_OK ){ + pOrigData = sqlite3PagerGetData(pOrig); + memcpy(pNew->aData, pOrigData, pDest->pBt->usableSize); + put4byte(pNew->aData, 0); + ovfl = get4byte(pOrigData); + } + sqlite3PagerUnref(pOrig); + } + releasePage(pNew); + }while( rc==SQLITE_OK && ovfl>0 ); + } + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeInsert(pDest, &x, OPFLAG_APPEND, seekResult); + } + } + + return rc; +} + /* ** Delete the entry that the cursor is pointing to. ** diff --git a/src/btree.h b/src/btree.h index 7a9ed2e3c6..abdfc33630 100644 --- a/src/btree.h +++ b/src/btree.h @@ -361,6 +361,8 @@ void sqlite3BtreeCursorList(Btree*); int sqlite3BtreeCheckpoint(Btree*, int, int *, int *); #endif +int sqlite3BtreeTransfer(BtCursor*, BtCursor*, i64, int); + /* ** If we are not using shared cache, then there is no need to ** use mutexes to access the BtShared structures. So make the diff --git a/src/insert.c b/src/insert.c index 393cd528f1..d801b47902 100644 --- a/src/insert.c +++ b/src/insert.c @@ -2783,11 +2783,13 @@ static int xferOptimization( emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v); if( pDest->iPKey>=0 ){ addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid); - sqlite3VdbeVerifyAbortable(v, onError); - addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid); - VdbeCoverage(v); - sqlite3RowidConstraint(pParse, onError, pDest); - sqlite3VdbeJumpHere(v, addr2); + if( (db->mDbFlags & DBFLAG_Vacuum)==0 ){ + sqlite3VdbeVerifyAbortable(v, onError); + addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid); + VdbeCoverage(v); + sqlite3RowidConstraint(pParse, onError, pDest); + sqlite3VdbeJumpHere(v, addr2); + } autoIncStep(pParse, regAutoinc, regRowid); }else if( pDest->pIndex==0 && !(db->mDbFlags & DBFLAG_VacuumInto) ){ addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid); @@ -2798,13 +2800,14 @@ static int xferOptimization( if( db->mDbFlags & DBFLAG_Vacuum ){ sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest); insFlags = OPFLAG_APPEND|OPFLAG_USESEEKRESULT; + sqlite3VdbeAddOp3(v, OP_Transfer, iDest, iSrc, regRowid); }else{ insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND; + sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); + sqlite3VdbeAddOp4(v, OP_Insert, iDest, regData, regRowid, + (char*)pDest, P4_TABLE); + sqlite3VdbeChangeP5(v, insFlags); } - sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); - sqlite3VdbeAddOp4(v, OP_Insert, iDest, regData, regRowid, - (char*)pDest, P4_TABLE); - sqlite3VdbeChangeP5(v, insFlags); sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); sqlite3VdbeAddOp2(v, OP_Close, iDest, 0); diff --git a/src/vdbe.c b/src/vdbe.c index 1507fb3181..ea35e6aa56 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3572,13 +3572,6 @@ case OP_Transaction: { && (iMeta!=pOp->p3 || db->aDb[pOp->p1].pSchema->iGeneration!=pOp->p4.i) ){ - /* - ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema - ** version is checked to ensure that the schema has not changed since the - ** SQL statement was prepared. - */ - sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); /* If the schema-cookie from the database file matches the cookie ** stored with the in-memory representation of the schema, do ** not reload the schema from the database file. @@ -3595,6 +3588,13 @@ case OP_Transaction: { if( db->aDb[pOp->p1].pSchema->schema_cookie!=iMeta ){ sqlite3ResetOneSchema(db, pOp->p1); } + /* + ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema + ** version is checked to ensure that the schema has not changed since the + ** SQL statement was prepared. + */ + sqlite3DbFree(db, p->zErrMsg); + p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); p->expired = 1; rc = SQLITE_SCHEMA; } @@ -5143,6 +5143,30 @@ case OP_Insert: { break; } +/* Opcode: Transfer P1 P2 P3 * * +** Synopsis: intkey=r[P3] +** +** P1 and P2 are both cursors open on either intkey or index btrees. This +** instruction reads the current row from P2 and writes it into the +** table opened by P1. If P1 and P2 are opened on intkey tables, register +** P3 contains the rowid value to use when inserting into P1. +*/ +case OP_Transfer: { + VdbeCursor *pDest; /* Cursor to write to */ + VdbeCursor *pSrc; /* Cursor to read from */ + i64 iKey; /* Rowid value to insert with */ + + pDest = p->apCsr[pOp->p1]; + pSrc = p->apCsr[pOp->p2]; + iKey = aMem[pOp->p3].u.i; + + rc = sqlite3BtreeTransfer( + pDest->uc.pCursor, pSrc->uc.pCursor, iKey, pDest->seekResult + ); + if( rc!=SQLITE_OK ) goto abort_due_to_error; + break; +} + /* Opcode: Delete P1 P2 P3 P4 P5 ** ** Delete the record at which the P1 cursor is currently pointing. From 20b86324a1b3c78b5eee3872d1934ec21c911bfa Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 9 Dec 2020 01:34:48 +0000 Subject: [PATCH 034/257] Initialize all terms in the ON CONFLICT clause stack. FossilOrigin-Name: 5e683fd1cbde53f37cf8a2b1e981191e2b29e3376db554691767f33c37c7547e --- manifest | 15 ++++++--------- manifest.uuid | 2 +- src/insert.c | 19 ++++++++++++------- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 9471059ac9..b6cfaef7fe 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sUPSERT\sparsing\sto\sallow\smultiple\sON\sCONFLICT\sclauses.\s\sOnly\sthe\nvery\slast\sclause\smay\somit\sthe\sconflict\starget,\sbut\sthe\sconflict\starget\smay\nnow\sbe\somitted\sfor\sthe\sDO\sUPDATE\sresolution. -D 2020-12-08T14:29:03.533 +C Initialize\sall\sterms\sin\sthe\sON\sCONFLICT\sclause\sstack. +D 2020-12-09T01:34:48.233 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -501,7 +501,7 @@ 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 7e081d33aab4a9d761c39dccf3c3872c35501565d2ed9db66301918d23bc7901 +F src/insert.c 2fdfd14bf872501f041cb2220632dace2df63342151b9b30ebfb798df3f14632 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 F src/main.c 97e9f137354bc1f76dc9bb60a0a24f8c45cf73b33e80d3ee4c64155336fb820d @@ -1888,10 +1888,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 4b286129138d44e6f8e9b3450289941e01d20fdfb9d0b5d846031425e8ca6b49 -R 204aa888c3a8b96c5008bc9a579603f7 -T *branch * generalized-upsert -T *sym-generalized-upsert * -T -sym-trunk * +P 2ca62f4c71df6544cb8039bdc80e3701d09697c38800534371f6d44532fcffae +R 522b57bc98ce1a3ca7ad7f44cd4944b4 U drh -Z d13edca14ac31a65fc7ae7d7fdc7eaff +Z 6380cbc8ce17e23f96dde835eaec54ed diff --git a/manifest.uuid b/manifest.uuid index 0eeaf11f2a..f0390ac713 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2ca62f4c71df6544cb8039bdc80e3701d09697c38800534371f6d44532fcffae \ No newline at end of file +5e683fd1cbde53f37cf8a2b1e981191e2b29e3376db554691767f33c37c7547e \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 393cd528f1..137590a5e5 100644 --- a/src/insert.c +++ b/src/insert.c @@ -975,6 +975,7 @@ void sqlite3Insert( } #ifndef SQLITE_OMIT_UPSERT if( pUpsert ){ + Upsert *pNx; if( IsVirtual(pTab) ){ sqlite3ErrorMsg(pParse, "UPSERT not implemented for virtual table \"%s\"", pTab->zName); @@ -988,13 +989,17 @@ void sqlite3Insert( goto insert_cleanup; } pTabList->a[0].iCursor = iDataCur; - pUpsert->pUpsertSrc = pTabList; - pUpsert->regData = regData; - pUpsert->iDataCur = iDataCur; - pUpsert->iIdxCur = iIdxCur; - if( pUpsert->pUpsertTarget ){ - sqlite3UpsertAnalyzeTarget(pParse, pTabList, pUpsert); - } + pNx = pUpsert; + do{ + pNx->pUpsertSrc = pTabList; + pNx->regData = regData; + pNx->iDataCur = iDataCur; + pNx->iIdxCur = iIdxCur; + if( pNx->pUpsertTarget ){ + sqlite3UpsertAnalyzeTarget(pParse, pTabList, pNx); + } + pNx = pNx->pNextUpsert; + }while( pNx!=0 ); } #endif From 5602777e8fc872e638c0d9ccc116bebfd66e02e9 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 9 Dec 2020 13:11:02 +0000 Subject: [PATCH 035/257] Improved comments in sqliteInt.h. No changes to code. FossilOrigin-Name: 8ccb8d1d55fa5aaf625c30f0e7c10aa403d79b5574dbdfa3fd0271a4e546f7e3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqliteInt.h | 14 ++++++++++---- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index b6cfaef7fe..ce2af91be7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Initialize\sall\sterms\sin\sthe\sON\sCONFLICT\sclause\sstack. -D 2020-12-09T01:34:48.233 +C Improved\scomments\sin\ssqliteInt.h.\s\sNo\schanges\sto\scode. +D 2020-12-09T13:11:02.579 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -545,7 +545,7 @@ F src/shell.c.in e9f674ee4ec6c345679e8a5b16c869c6c59eb1540dd98ac69e4736ecddce009 F src/sqlite.h.in 0e2b4259e49a0eda54d9118eb18a04fcd60e0727a2fd2c81aade0bf57520e706 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h 351d29fad669d5c98066a89ab48259d451379edac3c24773c3c8ac5df66fd8ff +F src/sqliteInt.h f8e462357ee34e6859f20e7f83adcca0809bbc1033a85a19d9be50a09930717a F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1888,7 +1888,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 2ca62f4c71df6544cb8039bdc80e3701d09697c38800534371f6d44532fcffae -R 522b57bc98ce1a3ca7ad7f44cd4944b4 +P 5e683fd1cbde53f37cf8a2b1e981191e2b29e3376db554691767f33c37c7547e +R f2e8184a51a526d27f353dba2479feca U drh -Z 6380cbc8ce17e23f96dde835eaec54ed +Z 0139a36f3f85012162d949eb364157e1 diff --git a/manifest.uuid b/manifest.uuid index f0390ac713..0de188d914 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5e683fd1cbde53f37cf8a2b1e981191e2b29e3376db554691767f33c37c7547e \ No newline at end of file +8ccb8d1d55fa5aaf625c30f0e7c10aa403d79b5574dbdfa3fd0271a4e546f7e3 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 68c8680600..06ddb3a613 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2304,16 +2304,22 @@ struct FKey { ** is returned. REPLACE means that preexisting database rows that caused ** a UNIQUE constraint violation are removed so that the new insert or ** update can proceed. Processing continues and no error is reported. +** UPDATE applies to insert operations only and means that the insert +** is omitted and the DO UPDATE clause of an upsert is run instead. ** -** RESTRICT, SETNULL, and CASCADE actions apply only to foreign keys. +** RESTRICT, SETNULL, SETDFLT, and CASCADE actions apply only to foreign keys. ** RESTRICT is the same as ABORT for IMMEDIATE foreign keys and the ** same as ROLLBACK for DEFERRED keys. SETNULL means that the foreign -** key is set to NULL. CASCADE means that a DELETE or UPDATE of the +** key is set to NULL. SETDFLT means that the foreign key is set +** to its default value. CASCADE means that a DELETE or UPDATE of the ** referenced table row is propagated into the row that holds the ** foreign key. ** +** The OE_Default value is a place holder that means to use whatever +** conflict resolution algorthm is required from context. +** ** The following symbolic values are used to record which type -** of action to take. +** of conflict resolution action to take. */ #define OE_None 0 /* There is no constraint to check */ #define OE_Rollback 1 /* Fail the operation and rollback the transaction */ @@ -3067,7 +3073,7 @@ struct NameContext { ** WHERE clause is omitted. */ struct Upsert { - ExprList *pUpsertTarget; /* Optional description of conflicting index */ + ExprList *pUpsertTarget; /* Optional description of conflict target */ Expr *pUpsertTargetWhere; /* WHERE clause for partial index targets */ ExprList *pUpsertSet; /* The SET clause from an ON CONFLICT UPDATE */ Expr *pUpsertWhere; /* WHERE clause for the ON CONFLICT UPDATE */ From ebbf36878ce2f1b7210be890eb676caf93c95ab2 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 9 Dec 2020 16:32:11 +0000 Subject: [PATCH 036/257] Avoid loading large intkey rows when VACUUMing, even if the page-size is changing. FossilOrigin-Name: 0d2c3776065dc94119899ae4164995193b82fca7ac31868f3141b729d0b65ab9 --- manifest | 18 +++--- manifest.uuid | 2 +- src/btree.c | 157 ++++++++++++++++++++++++++++------------------ test/vacuum2.test | 2 +- test/vacuum6.test | 94 +++++++++++++++++++++++++++ 5 files changed, 200 insertions(+), 73 deletions(-) create mode 100644 test/vacuum6.test diff --git a/manifest b/manifest index 6cf3a15c36..9e63b89316 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Experimental\schanges\sto\svacuum\sto\savoid\sloading\slarge\srecords\sentirely\sinto\smemory.\sCurrently\sonly\sworks\sin\slimited\scases\sonly\s-\sfor\srowid\stables\swhen\sthe\spage-size\sdoes\snot\schange. -D 2020-12-08T20:19:07.385 +C Avoid\sloading\slarge\sintkey\srows\swhen\sVACUUMing,\seven\sif\sthe\spage-size\sis\schanging. +D 2020-12-09T16:32:11.593 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -481,7 +481,7 @@ F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 6d5cfd0e411e1db8042c94593a4847d85fc5398fa4860689d6f0d74cefa4e534 +F src/btree.c 2dd52a7d6f473ef345ac028f49f3cc14e1207a3596b2d9fd92fe532e57da6328 F src/btree.h cff4cd182eb0d97802d82f398e4c8447f01bd2f5e501f70386b1097c910091cb F src/btreeInt.h ffd66480520d9d70222171b3a026d78b80833b5cea49c89867949f3e023d5f43 F src/build.c f6449d4e85e998e14d3f537e8ea898dca2fcb83c277db3e60945af9b9177db81 @@ -1650,10 +1650,11 @@ F test/userauth01.test e740a2697a7b40d7c5003a7d7edaee16acd349a9 F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae F test/vacuum-into.test 48f4cec354fb6f27c98ef58d2fe49a11b71ff131af0cd9140efacc9858b9f670 F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d -F test/vacuum2.test aa048abee196c16c9ba308465494009057b79f9b +F test/vacuum2.test 9fd45ce6ce29f5614c249e03938d3567c06a9e772d4f155949f8eafe2d8af520 F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d F test/vacuum4.test 7ea76b769fffeb41f925303b04cbcf5a5bbeabe55e4c60ae754ff24eeeb7c010 F test/vacuum5.test 263b144d537e92ad8e9ca8a73cc6e1583f41cfd0dda9432b87f7806174a2f48c +F test/vacuum6.test 7d3aea27ef3c671dafccbad5adc7848205c38ab14ee7a1dabe592e0794e132d7 F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2 F test/varint.test bbce22cda8fc4d135bcc2b589574be8410614e62 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 @@ -1888,10 +1889,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 4b286129138d44e6f8e9b3450289941e01d20fdfb9d0b5d846031425e8ca6b49 -R ebe894c92d077c4bc1f846403c247ebe -T *branch * vacuum-lomem -T *sym-vacuum-lomem * -T -sym-trunk * +P c90e063ca9ddcdd1e9f1a2e25a3f7d6e7ee798373ad8acf65b90536b0a124c0d +R 306b82fcb1780d3a4b54ba51609ce03f U dan -Z e00eb83dabf2298b62b079f62bce894b +Z fc13f09d46076f2b65a2bba6a14de43b diff --git a/manifest.uuid b/manifest.uuid index ccd89eef6a..e9576184e1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c90e063ca9ddcdd1e9f1a2e25a3f7d6e7ee798373ad8acf65b90536b0a124c0d \ No newline at end of file +0d2c3776065dc94119899ae4164995193b82fca7ac31868f3141b729d0b65ab9 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index abc28c179a..96ea9c4a04 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1143,6 +1143,24 @@ static SQLITE_NOINLINE void btreeParseCellAdjustSizeForOverflow( pInfo->nSize = (u16)(&pInfo->pPayload[pInfo->nLocal] - pCell) + 4; } +/* +** Given a record with nPayload bytes of payload stored within btree +** page pPage, return the number of bytes of payload stored locally. +*/ +static int btreePayloadToLocal(MemPage *pPage, int nPayload){ + int maxLocal; /* Maximum amount of payload held locally */ + maxLocal = pPage->maxLocal; + if( nPayload<=maxLocal ){ + return nPayload; + }else{ + int minLocal; /* Minimum amount of payload held locally */ + int surplus; /* Overflow payload available for local storage */ + minLocal = pPage->minLocal; + surplus = minLocal + (nPayload - minLocal)%(pPage->pBt->usableSize-4); + return ( surplus <= maxLocal ) ? surplus : minLocal; + } +} + /* ** The following routines are implementations of the MemPage.xParseCell() ** method. @@ -6500,7 +6518,7 @@ static int fillInCell( /* Fill in the header. */ nHeader = pPage->childPtrSize; if( pPage->intKey ){ - if( pX->pData==(const void*)pPage->pBt->pTmpSpace ){ + if( pX->nZero<0 ){ *pnSize = pX->nData; return SQLITE_OK; } @@ -8924,72 +8942,89 @@ int sqlite3BtreeTransfer( ){ int rc = SQLITE_OK; BtreePayload x; + Pager *pSrcPager = pSrc->pBt->pPager; + u8 *pCell = pDest->pBt->pTmpSpace; + u8 *aOut; /* Pointer to next output buffer */ + int nOut; /* Size of output buffer aOut[] */ + const u8 *aIn; /* Pointer to next input buffer */ + int nIn; /* Size of input buffer aIn[] */ + int nRem; /* Bytes of data still to copy */ + u8 *pPgnoOut = 0; + Pgno ovflIn = 0; + DbPage *pPageIn = 0; + MemPage *pPageOut = 0; memset(&x, 0, sizeof(x)); x.nKey = iKey; getCellInfo(pSrc); - if( pDest->pBt->usableSize!=pSrc->pBt->usableSize ){ - void *pFree = 0; - x.nData = pSrc->info.nPayload; - if( pSrc->info.nLocal==pSrc->info.nPayload ){ - x.pData = pSrc->info.pPayload; - }else{ - x.pData = pFree = sqlite3_malloc(pSrc->info.nPayload); - if( pFree==0 ){ - rc = SQLITE_NOMEM_BKPT; - }else{ - rc = sqlite3BtreePayload(pSrc, 0, x.nData, pFree); + + x.pData = pCell; + x.nData = putVarint32(pCell, pSrc->info.nPayload); + x.nData += putVarint(&pCell[x.nData], iKey); + x.nZero = -1; + + nOut = btreePayloadToLocal(pDest->pPage, pSrc->info.nPayload); + aOut = &pCell[x.nData]; + nIn = pSrc->info.nLocal; + aIn = pSrc->info.pPayload; + nRem = pSrc->info.nPayload; + + x.nData += nOut; + if( nOutinfo.nPayload ){ + pPgnoOut = &pCell[x.nData]; + x.nData += 4; + } + + if( nRem>nIn ){ + ovflIn = get4byte(&pSrc->info.pPayload[nIn]); + } + + do { + nRem -= nOut; + do{ + assert( nOut>0 ); + if( nIn>0 ){ + int nCopy = MIN(nOut, nIn); + memcpy(aOut, aIn, nCopy); + nOut -= nCopy; + nIn -= nCopy; + aOut += nCopy; + aIn += nCopy; + } + if( nOut>0 ){ + sqlite3PagerUnref(pPageIn); + pPageIn = 0; + rc = sqlite3PagerGet(pSrcPager, ovflIn, &pPageIn, PAGER_GET_READONLY); + if( rc==SQLITE_OK ){ + aIn = (const u8*)sqlite3PagerGetData(pPageIn); + ovflIn = get4byte(aIn); + aIn += 4; + nIn = pSrc->pBt->usableSize - 4; + } + } + }while( rc==SQLITE_OK && nOut>0 ); + + if( rc==SQLITE_OK && nRem>0 ){ + Pgno pgnoNew; + MemPage *pNew = 0; + rc = allocateBtreePage(pDest->pBt, &pNew, &pgnoNew, 0, 0); + put4byte(pPgnoOut, pgnoNew); + releasePage(pPageOut); + pPageOut = pNew; + if( pPageOut ){ + pPgnoOut = pPageOut->aData; + put4byte(pPgnoOut, 0); + aOut = &pPgnoOut[4]; + nOut = MIN(pDest->pBt->usableSize - 4, nRem); } } - if( rc==SQLITE_OK ){ - rc = sqlite3BtreeInsert(pDest, &x, OPFLAG_APPEND, seekResult); - } - sqlite3_free(pFree); - }else{ - /* Page sizes match. This means each overflow page (if any) and the - ** cell itself can be copied verbatim. */ - u8 *pCell = pDest->pBt->pTmpSpace; - x.pData = pCell; - x.nData = putVarint32(pCell, pSrc->info.nPayload); - x.nData += putVarint(&pCell[x.nData], iKey); - memcpy(&pCell[x.nData], pSrc->info.pPayload, pSrc->info.nLocal); - x.nData += pSrc->info.nLocal; - assert( pSrc->info.nLocal<=pSrc->info.nPayload ); - if( pSrc->info.nLocalinfo.nPayload ){ - Pager *pSrcPager = pSrc->pBt->pPager; - u8 *pPgno = &pCell[x.nData]; - Pgno ovfl; - x.nData += 4; - ovfl = get4byte(pSrc->info.pPayload + pSrc->info.nLocal); - do{ - MemPage *pNew = 0; - Pgno pgnoNew = 0; - if( rc==SQLITE_OK ){ - rc = allocateBtreePage(pDest->pBt, &pNew, &pgnoNew, 0, 0); - put4byte(pPgno, pgnoNew); - } - if( rc==SQLITE_OK ){ - pPgno = pNew->aData; - rc = sqlite3PagerWrite(pNew->pDbPage); - } - if( rc==SQLITE_OK ){ - DbPage *pOrig = 0; - void *pOrigData; - rc = sqlite3PagerGet(pSrcPager, ovfl, &pOrig, PAGER_GET_READONLY); - if( rc==SQLITE_OK ){ - pOrigData = sqlite3PagerGetData(pOrig); - memcpy(pNew->aData, pOrigData, pDest->pBt->usableSize); - put4byte(pNew->aData, 0); - ovfl = get4byte(pOrigData); - } - sqlite3PagerUnref(pOrig); - } - releasePage(pNew); - }while( rc==SQLITE_OK && ovfl>0 ); - } - if( rc==SQLITE_OK ){ - rc = sqlite3BtreeInsert(pDest, &x, OPFLAG_APPEND, seekResult); - } + }while( nRem>0 && rc==SQLITE_OK ); + + releasePage(pPageOut); + sqlite3PagerUnref(pPageIn); + + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeInsert(pDest, &x, OPFLAG_APPEND, seekResult); } return rc; diff --git a/test/vacuum2.test b/test/vacuum2.test index 0350c8ec42..89fdb506c5 100644 --- a/test/vacuum2.test +++ b/test/vacuum2.test @@ -56,7 +56,7 @@ do_test vacuum2-2.1 { } hexio_get_int [hexio_read test.db 24 4] } [expr {[hexio_get_int [hexio_read test.db 24 4]]+3}] -do_test vacuum2-2.1 { +do_test vacuum2-2.2 { execsql { VACUUM } diff --git a/test/vacuum6.test b/test/vacuum6.test new file mode 100644 index 0000000000..203b3329e2 --- /dev/null +++ b/test/vacuum6.test @@ -0,0 +1,94 @@ +# 2016-08-19 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file implements a test for VACUUM on attached databases. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix vacuum6 + +# If the VACUUM statement is disabled in the current build, skip all +# the tests in this file. +# +ifcapable !vacuum { + finish_test + return +} + + +do_execsql_test 1.0 { + CREATE TABLE t1(x INTEGER PRIMARY KEY, y); + INSERT INTO t1 VALUES(1, 1); +} {} +do_execsql_test 1.1 { + VACUUM +} + +#------------------------------------------------------------------------- +reset_db +foreach {tn sz} {1 400 2 4000 3 9999} { + reset_db + do_execsql_test 2.$tn.1 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100 + ) + INSERT INTO t1 SELECT i, randomblob($sz) FROM s; + } + + do_execsql_test 2.$tn.2 { + vacuum; + } + + do_execsql_test 2.$tn.3 { + PRAGMA integrity_check; + } {ok} +} + +reset_db +do_execsql_test 3.0 { + PRAGMA page_size = 1024; + CREATE TABLE t1(x INTEGER PRIMARY KEY, y); + INSERT INTO t1 VALUES(2, randomblob(1200)); +} {} +do_execsql_test 3.1 { + PRAGMA page_size = 512; + VACUUM; +} +do_execsql_test 3.2 { + PRAGMA integrity_check +} {ok} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 4.0 { + CREATE TABLE tx(a, b); + CREATE INDEX i1 ON tx(b); + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<10000 + ) + INSERT INTO tx SELECT i, randomblob(i) FROM s; +} +foreach {tn pgsz} { + 1 2048 + 2 1024 + 3 65536 + 4 8192 +} { + do_execsql_test 4.1.$tn.1 " + PRAGMA page_size = $pgsz + " + do_execsql_test 4.1.$tn.2 VACUUM + integrity_check 4.1.$tn.3 +} + +finish_test From 1418b9daf66066941d1d2e58b2edc28b29575bb1 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 9 Dec 2020 16:49:28 +0000 Subject: [PATCH 037/257] Add tests for a 'delete' command on a contentless table where values that weren't actually inserted are NULL. FossilOrigin-Name: 818c647cec7063b33b6c5de3e23599a1d61439fa6e9bf6c974b2522a5a9e1b44 --- ext/fts5/test/fts5delete.test | 23 ++++++++++++++++++++++- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/ext/fts5/test/fts5delete.test b/ext/fts5/test/fts5delete.test index 467e2e5707..1214fec4f4 100644 --- a/ext/fts5/test/fts5delete.test +++ b/ext/fts5/test/fts5delete.test @@ -91,6 +91,27 @@ do_catchsql_test 2.4 { SELECT rowid FROM test_idx WHERE test_idx MATCH 'two' ORDER BY rank; } {1 {database disk image is malformed}} - +#------------------------------------------------------------------------- +reset_db +do_execsql_test 3.0 { + CREATE VIRTUAL TABLE tx USING fts5(a, b, c, d, content=); + INSERT INTO tx(rowid, a, c) VALUES(1, 'abc def', 'a b c'); + INSERT INTO tx(rowid, a, c) VALUES(5, 'a b c', 'a b d def'); +} +do_execsql_test 3.1 { + INSERT INTO tx(tx, rowid, a, b, c, d) + VALUES('delete', 5, 'a b c', NULL, 'a b d def', NULL); +} +do_execsql_test 3.2 { + INSERT INTO tx(tx) VALUES('integrity-check'); +} +do_execsql_test 3.3 { + INSERT INTO tx(tx, rowid, a, b, c, d) + VALUES('delete', 1, 'abc def', NULL, 'a b c', NULL); +} +do_execsql_test 3.4 { + INSERT INTO tx(tx) VALUES('integrity-check'); +} finish_test + diff --git a/manifest b/manifest index 18c17599b4..12a9b3e68c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbad\sassert()\sin\smath1Func(). -D 2020-12-07T23:14:25.210 +C Add\stests\sfor\sa\s'delete'\scommand\son\sa\scontentless\stable\swhere\svalues\sthat\sweren't\sactually\sinserted\sare\sNULL. +D 2020-12-09T16:49:28.314 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -162,7 +162,7 @@ F ext/fts5/test/fts5corrupt.test 77ae6f41a7eba10620efb921cf7dbe218b0ef232b04519d F ext/fts5/test/fts5corrupt2.test 7453752ba12ce91690c469a6449d412561cc604b1dec994e16ab132952e7805f F ext/fts5/test/fts5corrupt3.test 1c26a651ea7e52fd69d54436fe4f02f6dd1268bc8b48ab851c7e1d374aa242b9 F ext/fts5/test/fts5corrupt4.test f4c08e2182a48d8b70975fd869ee5391855c06d8a0ff87b6a2529e7c5a88a1d3 -F ext/fts5/test/fts5delete.test 4a15fb03b6c7eac62ac807a3a32b7f0dc74f0d479c410e3e3568ae96b9469290 +F ext/fts5/test/fts5delete.test 619295b20dbc1d840b403ee07c878f52378849c3c02e44f2ee143b3e978a0aa7 F ext/fts5/test/fts5detail.test 31b240dbf6d44ac3507e2f8b65f29fdc12465ffd531212378c7ce1066766f54e F ext/fts5/test/fts5determin.test 1b77879b2ae818b5b71c859e534ee334dac088b7cf3ff3bf76a2c82b1c788d11 F ext/fts5/test/fts5dlidx.test b90852c55881b29dbac6380b274de27beae623ac4b6d567c6c8fb9cdc315a86e @@ -1888,7 +1888,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 99ff6418492adcbaf2be728737735afa1c2997de5868395e69c53d08fc14491f -R 747ed0f69719082482a4ff82786fa288 -U drh -Z ac855459dfaf775bb9ffc51142afdf45 +P 4b286129138d44e6f8e9b3450289941e01d20fdfb9d0b5d846031425e8ca6b49 +R 37fc0afc3fe30eb3e2571a975a076869 +U dan +Z 8a4734d621babbb70002204527e1408c diff --git a/manifest.uuid b/manifest.uuid index 7e5c04ae26..1e6307466a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4b286129138d44e6f8e9b3450289941e01d20fdfb9d0b5d846031425e8ca6b49 \ No newline at end of file +818c647cec7063b33b6c5de3e23599a1d61439fa6e9bf6c974b2522a5a9e1b44 \ No newline at end of file From e84ad92f17b96f1952f27645042bbf83fe6d0da5 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 9 Dec 2020 20:30:47 +0000 Subject: [PATCH 038/257] For upsert, the constraint check code generator uses a copy of the index list for the target table, which can potentially be reordered. FossilOrigin-Name: 3194c00c2c6a32bdfd5acc9fda5b38ae131d20cd3b7aea8512a41b2e76808f6a --- manifest | 19 +++++++++++-------- manifest.uuid | 2 +- src/insert.c | 48 +++++++++++++++++++++++++++++++++++++----------- src/sqliteInt.h | 12 ++++++++---- src/upsert.c | 4 ++-- 5 files changed, 59 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index ce2af91be7..7766814266 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\scomments\sin\ssqliteInt.h.\s\sNo\schanges\sto\scode. -D 2020-12-09T13:11:02.579 +C For\supsert,\sthe\sconstraint\scheck\scode\sgenerator\suses\sa\scopy\sof\sthe\sindex\slist\nfor\sthe\starget\stable,\swhich\scan\spotentially\sbe\sreordered. +D 2020-12-09T20:30:47.480 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -501,7 +501,7 @@ 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 2fdfd14bf872501f041cb2220632dace2df63342151b9b30ebfb798df3f14632 +F src/insert.c df28564b7d79f146266e906549687c74e3a5e9c4d8ba8697ef9c479ad83407e0 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 F src/main.c 97e9f137354bc1f76dc9bb60a0a24f8c45cf73b33e80d3ee4c64155336fb820d @@ -545,7 +545,7 @@ F src/shell.c.in e9f674ee4ec6c345679e8a5b16c869c6c59eb1540dd98ac69e4736ecddce009 F src/sqlite.h.in 0e2b4259e49a0eda54d9118eb18a04fcd60e0727a2fd2c81aade0bf57520e706 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h f8e462357ee34e6859f20e7f83adcca0809bbc1033a85a19d9be50a09930717a +F src/sqliteInt.h f01f37844eed0fab3e1fa8efe72cc327cf8e2ac121688ec94199d610978ecb09 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -608,7 +608,7 @@ F src/tokenize.c 01dba3023659dc6f6b1e054c14b35a0074bd35de10466b99454d33278191d97 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda F src/trigger.c 515e79206d40d1d4149129318582e79a6e9db590a7b74e226fdb5b2a6c7e1b10 F src/update.c 9f126204a6acb96bbe47391ae48e0fc579105d8e76a6d9c4fab3271367476580 -F src/upsert.c 25673d007c2408fec47a6326b6d7ac265abd2cbc162d11f3b3c333de27d3c78a +F src/upsert.c 803c383d493546c71580e9e532d6c7f87fc337316a2ffc202ba1812158dfa8fb F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c c0c7977de7ef9b8cb10f6c85f2d0557889a658f817b0455909a49179ba4c8002 F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286 @@ -1888,7 +1888,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 5e683fd1cbde53f37cf8a2b1e981191e2b29e3376db554691767f33c37c7547e -R f2e8184a51a526d27f353dba2479feca +P 8ccb8d1d55fa5aaf625c30f0e7c10aa403d79b5574dbdfa3fd0271a4e546f7e3 +R cb21a770762087a569cd96190733ebe7 +T *branch * generalized-upsert-ex1 +T *sym-generalized-upsert-ex1 * +T -sym-generalized-upsert * U drh -Z 0139a36f3f85012162d949eb364157e1 +Z d9a35c3fa2c53151f722f0a994f8bfdd diff --git a/manifest.uuid b/manifest.uuid index 0de188d914..ce7066ad55 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8ccb8d1d55fa5aaf625c30f0e7c10aa403d79b5574dbdfa3fd0271a4e546f7e3 \ No newline at end of file +3194c00c2c6a32bdfd5acc9fda5b38ae131d20cd3b7aea8512a41b2e76808f6a \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 137590a5e5..f10587f9f2 100644 --- a/src/insert.c +++ b/src/insert.c @@ -976,6 +976,9 @@ void sqlite3Insert( #ifndef SQLITE_OMIT_UPSERT if( pUpsert ){ Upsert *pNx; + int nIdx; + Index *pIdxList; + int *aReg; if( IsVirtual(pTab) ){ sqlite3ErrorMsg(pParse, "UPSERT not implemented for virtual table \"%s\"", pTab->zName); @@ -1000,6 +1003,26 @@ void sqlite3Insert( } pNx = pNx->pNextUpsert; }while( pNx!=0 ); + for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ + assert( pIdx ); + assert( aRegIdx[nIdx]>0 ); + } + if( nIdx==0 ){ + pUpsert->pIdxList = 0; + }else{ + u64 nByte = sizeof(Index)*nIdx + sizeof(int)*(nIdx+2); + pIdxList = sqlite3DbMallocRaw(db, nByte); + if( pIdxList==0 ) goto insert_cleanup; + aReg = (int*)&pIdxList[nIdx]; + for(i=0, pIdx=pTab->pIndex; ipNext, i++){ + memcpy(&pIdxList[i], pIdx, sizeof(Index)); + pIdxList[i].pNext = 0; + if( i ) pIdxList[i-1].pNext = &pIdxList[i]; + aReg[i] = aRegIdx[i]; + } + aReg[i] = aRegIdx[i]; + pUpsert->pIdxList = pIdxList; + } } #endif @@ -1512,7 +1535,7 @@ void sqlite3GenerateConstraintChecks( ){ Vdbe *v; /* VDBE under constrution */ Index *pIdx; /* Pointer to one of the indices */ - Index *pPk = 0; /* The PRIMARY KEY index */ + Index *pPk = 0; /* The PRIMARY KEY index for WITHOUT ROWID tables */ sqlite3 *db; /* Database connection */ int i; /* loop counter */ int ix; /* Index loop counter */ @@ -1930,7 +1953,8 @@ void sqlite3GenerateConstraintChecks( ** This loop also handles the case of the PRIMARY KEY index for a ** WITHOUT ROWID table. */ - for(ix=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, ix++){ + pIdx = pUpsert ? pUpsert->pIdxList : pTab->pIndex; + for(ix=0; pIdx; pIdx=pIdx->pNext, ix++){ int regIdx; /* Range of registers hold conent for pIdx */ int regR; /* Range of registers holding conflicting PK */ int iThisCur; /* Cursor for this UNIQUE index */ @@ -1938,7 +1962,7 @@ void sqlite3GenerateConstraintChecks( int addrConflictCk; /* First opcode in the conflict check logic */ if( aRegIdx[ix]==0 ) continue; /* Skip indices that do not change */ - if( pUpIdx==pIdx ){ + if( pUpIdx && pUpIdx->zName==pIdx->zName ){ addrUniqueOk = upsertJump+1; upsertBypass = sqlite3VdbeGoto(v, 0); VdbeComment((v, "Skip upsert subroutine")); @@ -1946,7 +1970,7 @@ void sqlite3GenerateConstraintChecks( }else{ addrUniqueOk = sqlite3VdbeMakeLabel(pParse); } - if( bAffinityDone==0 && (pUpIdx==0 || pUpIdx==pIdx) ){ + if( bAffinityDone==0 && (pUpIdx==0 || pUpIdx->zName==pIdx->zName) ){ sqlite3TableAffinity(v, pTab, regNewData+1); bAffinityDone = 1; } @@ -1999,7 +2023,7 @@ void sqlite3GenerateConstraintChecks( ** of a WITHOUT ROWID table and there has been no change the ** primary key, then no collision is possible. The collision detection ** logic below can all be skipped. */ - if( isUpdate && pPk==pIdx && pkChng==0 ){ + if( isUpdate && pPk && pPk->zName==pIdx->zName && pkChng==0 ){ sqlite3VdbeResolveLabel(v, addrUniqueOk); continue; } @@ -2017,7 +2041,7 @@ void sqlite3GenerateConstraintChecks( } /* Figure out if the upsert clause applies to this index */ - if( pUpIdx==pIdx ){ + if( pUpIdx && pUpIdx->zName==pIdx->zName ){ if( pUpsert->pUpsertSet==0 ){ onError = OE_Ignore; /* DO NOTHING is the same as INSERT OR IGNORE */ }else{ @@ -2037,7 +2061,7 @@ void sqlite3GenerateConstraintChecks( ** is invoked. */ #ifndef SQLITE_ENABLE_PREUPDATE_HOOK if( (ix==0 && pIdx->pNext==0) /* Condition 3 */ - && pPk==pIdx /* Condition 2 */ + && pPk && pPk->zName==pIdx->zName /* Condition 2 */ && onError==OE_Replace /* Condition 1 */ && ( 0==(db->flags&SQLITE_RecTriggers) || /* Condition 4 */ 0==sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0)) @@ -2056,7 +2080,8 @@ void sqlite3GenerateConstraintChecks( regIdx, pIdx->nKeyCol); VdbeCoverage(v); /* Generate code to handle collisions */ - regR = (pIdx==pPk) ? regIdx : sqlite3GetTempRange(pParse, nPkField); + regR = (pPk && pIdx->zName==pPk->zName) ? + regIdx : sqlite3GetTempRange(pParse, nPkField); if( isUpdate || onError==OE_Replace ){ if( HasRowid(pTab) ){ sqlite3VdbeAddOp2(v, OP_IdxRowid, iThisCur, regR); @@ -2071,7 +2096,7 @@ void sqlite3GenerateConstraintChecks( int x; /* Extract the PRIMARY KEY from the end of the index entry and ** store it in registers regR..regR+nPk-1 */ - if( pIdx!=pPk ){ + if( pPk && pIdx->zName!=pPk->zName ){ for(i=0; inKeyCol; i++){ assert( pPk->aiColumn[i]>=0 ); x = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[i]); @@ -2152,7 +2177,8 @@ void sqlite3GenerateConstraintChecks( } sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, regR, nPkField, 0, OE_Replace, - (pIdx==pPk ? ONEPASS_SINGLE : ONEPASS_OFF), iThisCur); + (pPk && pIdx->zName==pPk->zName ? ONEPASS_SINGLE : ONEPASS_OFF), + iThisCur); if( pTrigger && isUpdate ){ sqlite3VdbeAddOp1(v, OP_CursorUnlock, iDataCur); } @@ -2208,7 +2234,7 @@ void sqlite3GenerateConstraintChecks( break; } } - if( pUpIdx==pIdx ){ + if( pUpIdx && pUpIdx->zName==pIdx->zName ){ sqlite3VdbeGoto(v, upsertJump+1); sqlite3VdbeJumpHere(v, upsertBypass); }else{ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 06ddb3a613..8661f9058c 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3078,10 +3078,14 @@ struct Upsert { ExprList *pUpsertSet; /* The SET clause from an ON CONFLICT UPDATE */ Expr *pUpsertWhere; /* WHERE clause for the ON CONFLICT UPDATE */ Upsert *pNextUpsert; /* Next ON CONFLICT clause in the list */ - /* The fields above comprise the parse tree for the upsert clause. - ** The fields below are used to transfer information from the INSERT - ** processing down into the UPDATE processing while generating code. - ** Upsert owns the memory allocated above, but not the memory below. */ + /* Above this point is the parse tree for the ON CONFLICT clauses. + ** The next group of fields stores intermediate data. */ + Index *pIdxList; + /* All fields above are owned by the Upsert object and must be freed + ** when the Upsert is destroyed. The fields below are used to transfer + ** information from the INSERT processing down into the UPDATE processing + ** while generating code. The fields below are owned by the INSERT + ** statement and will be freed by INSERT processing. */ Index *pUpsertIdx; /* Constraint that pUpsertTarget identifies */ SrcList *pUpsertSrc; /* Table to be updated */ int regData; /* First register holding array of VALUES */ diff --git a/src/upsert.c b/src/upsert.c index ddd7c18428..0f1f6d8a32 100644 --- a/src/upsert.c +++ b/src/upsert.c @@ -25,6 +25,7 @@ static void SQLITE_NOINLINE upsertDelete(sqlite3 *db, Upsert *p){ sqlite3ExprDelete(db, p->pUpsertTargetWhere); sqlite3ExprListDelete(db, p->pUpsertSet); sqlite3ExprDelete(db, p->pUpsertWhere); + sqlite3DbFree(db, p->pIdxList); sqlite3DbFree(db, p); p = pNext; }while( p ); @@ -60,7 +61,7 @@ Upsert *sqlite3UpsertNew( Upsert *pNext /* Next ON CONFLICT clause in the list */ ){ Upsert *pNew; - pNew = sqlite3DbMallocRaw(db, sizeof(Upsert)); + pNew = sqlite3DbMallocZero(db, sizeof(Upsert)); if( pNew==0 ){ sqlite3ExprListDelete(db, pTarget); sqlite3ExprDelete(db, pTargetWhere); @@ -73,7 +74,6 @@ Upsert *sqlite3UpsertNew( pNew->pUpsertTargetWhere = pTargetWhere; pNew->pUpsertSet = pSet; pNew->pUpsertWhere = pWhere; - pNew->pUpsertIdx = 0; pNew->pNextUpsert = pNext; } return pNew; From cd1b2d0b5431164787d4acad07940191af992c6a Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 9 Dec 2020 20:33:51 +0000 Subject: [PATCH 039/257] Transfer large index or WITHOUT ROWID records between b-trees when vacuuming without loading them into memory. FossilOrigin-Name: dfd4ca6891a893d0e9551689954d3e79114d5565f8a5264f96ad1d64fe1d6280 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/btree.c | 30 +++++++++++++++++------------- src/btree.h | 1 + src/insert.c | 9 ++++++--- src/vdbe.c | 2 +- 6 files changed, 35 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index 9e63b89316..3a5de7a2d6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sloading\slarge\sintkey\srows\swhen\sVACUUMing,\seven\sif\sthe\spage-size\sis\schanging. -D 2020-12-09T16:32:11.593 +C Transfer\slarge\sindex\sor\sWITHOUT\sROWID\srecords\sbetween\sb-trees\swhen\svacuuming\swithout\sloading\sthem\sinto\smemory. +D 2020-12-09T20:33:51.761 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -481,8 +481,8 @@ F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 2dd52a7d6f473ef345ac028f49f3cc14e1207a3596b2d9fd92fe532e57da6328 -F src/btree.h cff4cd182eb0d97802d82f398e4c8447f01bd2f5e501f70386b1097c910091cb +F src/btree.c ce6a27f7d8be22aed5914e3c5bb7293eb6bc8fa43b332c0c2cdd71afcceb81e7 +F src/btree.h 78908bc31dd4cbd54762825346d7a24534773ec4ca42e16faf10a0a164d74ec4 F src/btreeInt.h ffd66480520d9d70222171b3a026d78b80833b5cea49c89867949f3e023d5f43 F src/build.c f6449d4e85e998e14d3f537e8ea898dca2fcb83c277db3e60945af9b9177db81 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c @@ -501,7 +501,7 @@ 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 a64406fb5ae856fb30be018423eec9984a60a9b46d261447717c502b1fb781d3 +F src/insert.c 0c4f619e119dc6201fdc8f7ea4cbde9e71268cf3089b36c064c49c3e2d07077d F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 F src/main.c 97e9f137354bc1f76dc9bb60a0a24f8c45cf73b33e80d3ee4c64155336fb820d @@ -612,7 +612,7 @@ F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c c0c7977de7ef9b8cb10f6c85f2d0557889a658f817b0455909a49179ba4c8002 F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286 -F src/vdbe.c 77fd09a782f72d5ff6e69363353e80e31d26bedd1d187e8813d781c74ba15770 +F src/vdbe.c 334c2626ad478fc85c992856e71a6bdd95dc11bf0d7cfe10856ec915f3d9fbe5 F src/vdbe.h 83603854bfa5851af601fc0947671eb260f4363e62e960e8a994fb9bbcd2aaa1 F src/vdbeInt.h 3ca5e9fd6e095a8b6cf6bc3587a46fc93499503b2fe48951e1034ba9e2ce2f6e F src/vdbeapi.c c5e7cb2ab89a24d7f723e87b508f21bfb1359a04db5277d8a99fd1e015c12eb9 @@ -1889,7 +1889,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 c90e063ca9ddcdd1e9f1a2e25a3f7d6e7ee798373ad8acf65b90536b0a124c0d -R 306b82fcb1780d3a4b54ba51609ce03f +P 0d2c3776065dc94119899ae4164995193b82fca7ac31868f3141b729d0b65ab9 +R 2ada74530286abe77d1ee50368ad4c2c U dan -Z fc13f09d46076f2b65a2bba6a14de43b +Z b452c10135ea2f1997d2fa69cc2163a3 diff --git a/manifest.uuid b/manifest.uuid index e9576184e1..604f1fcaeb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0d2c3776065dc94119899ae4164995193b82fca7ac31868f3141b729d0b65ab9 \ No newline at end of file +dfd4ca6891a893d0e9551689954d3e79114d5565f8a5264f96ad1d64fe1d6280 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 96ea9c4a04..8087d3935b 100644 --- a/src/btree.c +++ b/src/btree.c @@ -6518,10 +6518,6 @@ static int fillInCell( /* Fill in the header. */ nHeader = pPage->childPtrSize; if( pPage->intKey ){ - if( pX->nZero<0 ){ - *pnSize = pX->nData; - return SQLITE_OK; - } nPayload = pX->nData + pX->nZero; pSrc = pX->pData; nSrc = pX->nData; @@ -8682,7 +8678,8 @@ int sqlite3BtreeInsert( unsigned char *oldCell; unsigned char *newCell = 0; - assert( (flags & (BTREE_SAVEPOSITION|BTREE_APPEND))==flags ); + assert( (flags & (BTREE_SAVEPOSITION|BTREE_APPEND|BTREE_PREFORMAT))==flags ); + assert( (flags & BTREE_PREFORMAT)==0 || seekResult ); if( pCur->eState==CURSOR_FAULT ){ assert( pCur->skipNext!=SQLITE_OK ); @@ -8700,7 +8697,7 @@ int sqlite3BtreeInsert( ** keys with no associated data. If the cursor was opened expecting an ** intkey table, the caller should be inserting integer keys with a ** blob of associated data. */ - assert( (pX->pKey==0)==(pCur->pKeyInfo==0) ); + assert( (pX->pKey==0)==(pCur->pKeyInfo==0) || (flags & BTREE_PREFORMAT) ); /* Save the positions of any other cursors open on this table. ** @@ -8810,7 +8807,7 @@ int sqlite3BtreeInsert( || CORRUPT_DB ); pPage = pCur->pPage; - assert( pPage->intKey || pX->nKey>=0 ); + assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) ); assert( pPage->leaf || !pPage->intKey ); if( pPage->nFree<0 ){ if( pCur->eState>CURSOR_INVALID ){ @@ -8827,8 +8824,15 @@ int sqlite3BtreeInsert( assert( pPage->isInit ); newCell = pBt->pTmpSpace; assert( newCell!=0 ); - rc = fillInCell(pPage, newCell, pX, &szNew); - if( rc ) goto end_insert; + if( flags & BTREE_PREFORMAT ){ + assert( pX->pData==pBt->pTmpSpace ); + szNew = pX->nData; + if( szNew<4 ) szNew = 4; + rc = SQLITE_OK; + }else{ + rc = fillInCell(pPage, newCell, pX, &szNew); + if( rc ) goto end_insert; + } assert( szNew==pPage->xCellSize(pPage, newCell) ); assert( szNew <= MX_CELL_SIZE(pBt) ); idx = pCur->ix; @@ -8959,9 +8963,8 @@ int sqlite3BtreeTransfer( getCellInfo(pSrc); x.pData = pCell; - x.nData = putVarint32(pCell, pSrc->info.nPayload); - x.nData += putVarint(&pCell[x.nData], iKey); - x.nZero = -1; + x.nData += putVarint32(pCell, pSrc->info.nPayload); + if( pDest->pKeyInfo==0 ) x.nData += putVarint(&pCell[x.nData], iKey); nOut = btreePayloadToLocal(pDest->pPage, pSrc->info.nPayload); aOut = &pCell[x.nData]; @@ -9024,7 +9027,8 @@ int sqlite3BtreeTransfer( sqlite3PagerUnref(pPageIn); if( rc==SQLITE_OK ){ - rc = sqlite3BtreeInsert(pDest, &x, OPFLAG_APPEND, seekResult); + int flags = BTREE_APPEND|BTREE_PREFORMAT; + rc = sqlite3BtreeInsert(pDest, &x, flags, seekResult); } return rc; diff --git a/src/btree.h b/src/btree.h index abdfc33630..4c2a872bb9 100644 --- a/src/btree.h +++ b/src/btree.h @@ -262,6 +262,7 @@ int sqlite3BtreeDelete(BtCursor*, u8 flags); #define BTREE_SAVEPOSITION 0x02 /* Leave cursor pointing at NEXT or PREV */ #define BTREE_AUXDELETE 0x04 /* not the primary delete operation */ #define BTREE_APPEND 0x08 /* Insert is likely an append */ +#define BTREE_PREFORMAT 0x10 /* Insert is likely an append */ /* An instance of the BtreePayload object describes the content of a single ** entry in either an index or table btree. diff --git a/src/insert.c b/src/insert.c index d801b47902..0af845e887 100644 --- a/src/insert.c +++ b/src/insert.c @@ -2851,13 +2851,16 @@ static int xferOptimization( if( i==pSrcIdx->nColumn ){ idxInsFlags = OPFLAG_USESEEKRESULT; sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest); + sqlite3VdbeAddOp3(v, OP_Transfer, iDest, iSrc, 0); } }else if( !HasRowid(pSrc) && pDestIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){ idxInsFlags |= OPFLAG_NCHANGE; } - sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, regData); - sqlite3VdbeChangeP5(v, idxInsFlags|OPFLAG_APPEND); + if( idxInsFlags!=OPFLAG_USESEEKRESULT ){ + sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); + sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, regData); + sqlite3VdbeChangeP5(v, idxInsFlags|OPFLAG_APPEND); + } sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v); sqlite3VdbeJumpHere(v, addr1); sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); diff --git a/src/vdbe.c b/src/vdbe.c index ea35e6aa56..74fede8562 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5158,7 +5158,7 @@ case OP_Transfer: { pDest = p->apCsr[pOp->p1]; pSrc = p->apCsr[pOp->p2]; - iKey = aMem[pOp->p3].u.i; + iKey = pOp->p3 ? aMem[pOp->p3].u.i : 0; rc = sqlite3BtreeTransfer( pDest->uc.pCursor, pSrc->uc.pCursor, iKey, pDest->seekResult From d97a4c008dd7f58a0bbeabdd3d257b4487a77f92 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 9 Dec 2020 23:35:51 +0000 Subject: [PATCH 040/257] Fix compilation issues with MSVC related to C99. FossilOrigin-Name: c0de6c1fb2c486be1da01e5e4ca8c5634ba37822e418d57f272e018c3e3fc0a2 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/func.c | 10 +++++++--- src/sqliteInt.h | 12 ++++++++++++ 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 12a9b3e68c..617f92a7f3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests\sfor\sa\s'delete'\scommand\son\sa\scontentless\stable\swhere\svalues\sthat\sweren't\sactually\sinserted\sare\sNULL. -D 2020-12-09T16:49:28.314 +C Fix\scompilation\sissues\swith\sMSVC\srelated\sto\sC99. +D 2020-12-09T23:35:51.896 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -495,7 +495,7 @@ F src/delete.c 927cf8f900583e79aca8f1a321979e0a8f053babd9a690b44b38f79de2cc09fe F src/expr.c 0d196ed5a2ebf96be7e8df88add4fabfad0dce16c0fed81a4b8f6a26e259797f F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 83372403298e6a7dd989a47aaacdbaa5b4307b5199dbd56e07d4896066b3de72 -F src/func.c c65447d69bbf743328e7e4e836475ac5fb4ab80213fe5b189b8b0109e942e7c1 +F src/func.c 04b33016df7f4dcda295f71c6c776e2f49bfe0d50b5c5118240dfcd307d4755d F src/global.c ed55af196a9b66e198aaeda3f5454c3aa7d7d050c6c938181fd044b70d180a81 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 @@ -545,7 +545,7 @@ F src/shell.c.in e9f674ee4ec6c345679e8a5b16c869c6c59eb1540dd98ac69e4736ecddce009 F src/sqlite.h.in 0e2b4259e49a0eda54d9118eb18a04fcd60e0727a2fd2c81aade0bf57520e706 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h 6ab40b33a1f5edbb7d71c78e82e0f9c5291dcff4704df8e4f0ab0d9c1a0c06af +F src/sqliteInt.h 6b9e04aff5ae385e8d0957bf64cb3c1c42f4bf5115788c7be76e85ca9875740b F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1888,7 +1888,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 4b286129138d44e6f8e9b3450289941e01d20fdfb9d0b5d846031425e8ca6b49 -R 37fc0afc3fe30eb3e2571a975a076869 -U dan -Z 8a4734d621babbb70002204527e1408c +P 818c647cec7063b33b6c5de3e23599a1d61439fa6e9bf6c974b2522a5a9e1b44 +R f5a4c0e24239e1b152c6955913834244 +U mistachkin +Z ac2c81554df4b37487abc146a7fda901 diff --git a/manifest.uuid b/manifest.uuid index 1e6307466a..402122935f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -818c647cec7063b33b6c5de3e23599a1d61439fa6e9bf6c974b2522a5a9e1b44 \ No newline at end of file +c0de6c1fb2c486be1da01e5e4ca8c5634ba37822e418d57f272e018c3e3fc0a2 \ No newline at end of file diff --git a/src/func.c b/src/func.c index 169f231430..a29088a68d 100644 --- a/src/func.c +++ b/src/func.c @@ -2021,10 +2021,10 @@ static void math1Func( int argc, sqlite3_value **argv ){ - assert( argc==1 ); int type0; double v0, ans; double (*x)(double); + assert( argc==1 ); type0 = sqlite3_value_numeric_type(argv[0]); if( type0!=SQLITE_INTEGER && type0!=SQLITE_FLOAT ) return; v0 = sqlite3_value_double(argv[0]); @@ -2043,10 +2043,10 @@ static void math2Func( int argc, sqlite3_value **argv ){ - assert( argc==2 ); int type0, type1; double v0, v1, ans; double (*x)(double,double); + assert( argc==2 ); type0 = sqlite3_value_numeric_type(argv[0]); if( type0!=SQLITE_INTEGER && type0!=SQLITE_FLOAT ) return; type1 = sqlite3_value_numeric_type(argv[1]); @@ -2082,9 +2082,9 @@ static void signFunc( int argc, sqlite3_value **argv ){ - assert( argc==1 ); int type0; double x; + assert( argc==1 ); type0 = sqlite3_value_numeric_type(argv[0]); if( type0!=SQLITE_INTEGER && type0!=SQLITE_FLOAT ) return; x = sqlite3_value_double(argv[0]); @@ -2213,7 +2213,9 @@ void sqlite3RegisterBuiltinFunctions(void){ MFUNCTION(ceil, 1, ceil, ceilingFunc ), MFUNCTION(ceiling, 1, ceil, ceilingFunc ), MFUNCTION(floor, 1, floor, ceilingFunc ), +#if SQLITE_HAVE_C99_MATH_FUNCS MFUNCTION(trunc, 1, trunc, ceilingFunc ), +#endif FUNCTION(ln, 1, 0, 0, logFunc ), FUNCTION(log, 1, 1, 0, logFunc ), FUNCTION(log10, 1, 1, 0, logFunc ), @@ -2233,9 +2235,11 @@ void sqlite3RegisterBuiltinFunctions(void){ MFUNCTION(cosh, 1, cosh, math1Func ), MFUNCTION(sinh, 1, sinh, math1Func ), MFUNCTION(tanh, 1, tanh, math1Func ), +#if SQLITE_HAVE_C99_MATH_FUNCS MFUNCTION(acosh, 1, acosh, math1Func ), MFUNCTION(asinh, 1, asinh, math1Func ), MFUNCTION(atanh, 1, atanh, math1Func ), +#endif MFUNCTION(sqrt, 1, sqrt, math1Func ), MFUNCTION(radians, 1, degToRad, math1Func ), MFUNCTION(degrees, 1, radToDeg, math1Func ), diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 438f79c092..dd1d7e03ac 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -119,6 +119,18 @@ # define MSVC_VERSION 0 #endif +/* +** Some C99 functions in "math.h" are only present for MSVC when its version +** is associated with Visual Studio 2013 or higher. +*/ +#ifndef SQLITE_HAVE_C99_MATH_FUNCS +# if MSVC_VERSION==0 || MSVC_VERSION>=1800 +# define SQLITE_HAVE_C99_MATH_FUNCS (1) +# else +# define SQLITE_HAVE_C99_MATH_FUNCS (0) +# endif +#endif + /* Needed for various definitions... */ #if defined(__GNUC__) && !defined(_GNU_SOURCE) # define _GNU_SOURCE From 91f2717f22e5a7c3feab8224a16416677ad28e47 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 10 Dec 2020 12:49:26 +0000 Subject: [PATCH 041/257] The DO UPDATE code generator searches for the correct ON CONFLICT clause to use. FossilOrigin-Name: a47e35ee2d901baaa37e7229d190f934e1b0bd3510147cd4a2a49c4a1411416a --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/sqliteInt.h | 3 ++- src/upsert.c | 26 +++++++++++++++++++++----- 4 files changed, 31 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 7766814266..abce3073d7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C For\supsert,\sthe\sconstraint\scheck\scode\sgenerator\suses\sa\scopy\sof\sthe\sindex\slist\nfor\sthe\starget\stable,\swhich\scan\spotentially\sbe\sreordered. -D 2020-12-09T20:30:47.480 +C The\sDO\sUPDATE\scode\sgenerator\ssearches\sfor\sthe\scorrect\sON\sCONFLICT\sclause\sto\nuse. +D 2020-12-10T12:49:26.425 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -545,7 +545,7 @@ F src/shell.c.in e9f674ee4ec6c345679e8a5b16c869c6c59eb1540dd98ac69e4736ecddce009 F src/sqlite.h.in 0e2b4259e49a0eda54d9118eb18a04fcd60e0727a2fd2c81aade0bf57520e706 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h f01f37844eed0fab3e1fa8efe72cc327cf8e2ac121688ec94199d610978ecb09 +F src/sqliteInt.h 0e042bd76044617ae919a294778ceacdb00a405d60de1b94c8ee4d2b81829bdb F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -608,7 +608,7 @@ F src/tokenize.c 01dba3023659dc6f6b1e054c14b35a0074bd35de10466b99454d33278191d97 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda F src/trigger.c 515e79206d40d1d4149129318582e79a6e9db590a7b74e226fdb5b2a6c7e1b10 F src/update.c 9f126204a6acb96bbe47391ae48e0fc579105d8e76a6d9c4fab3271367476580 -F src/upsert.c 803c383d493546c71580e9e532d6c7f87fc337316a2ffc202ba1812158dfa8fb +F src/upsert.c 49170532578f2f30984b35e2c1e2f308b089c6814edf384d32158a53b25fc930 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c c0c7977de7ef9b8cb10f6c85f2d0557889a658f817b0455909a49179ba4c8002 F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286 @@ -1888,10 +1888,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 8ccb8d1d55fa5aaf625c30f0e7c10aa403d79b5574dbdfa3fd0271a4e546f7e3 -R cb21a770762087a569cd96190733ebe7 -T *branch * generalized-upsert-ex1 -T *sym-generalized-upsert-ex1 * -T -sym-generalized-upsert * +P 3194c00c2c6a32bdfd5acc9fda5b38ae131d20cd3b7aea8512a41b2e76808f6a +R 8dc7164868d12444f67e9c3abe760e73 U drh -Z d9a35c3fa2c53151f722f0a994f8bfdd +Z 978ca06206ec1f9d5cc426705017394f diff --git a/manifest.uuid b/manifest.uuid index ce7066ad55..88e882cea1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3194c00c2c6a32bdfd5acc9fda5b38ae131d20cd3b7aea8512a41b2e76808f6a \ No newline at end of file +a47e35ee2d901baaa37e7229d190f934e1b0bd3510147cd4a2a49c4a1411416a \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 8661f9058c..23df9cc710 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3086,11 +3086,12 @@ struct Upsert { ** information from the INSERT processing down into the UPDATE processing ** while generating code. The fields below are owned by the INSERT ** statement and will be freed by INSERT processing. */ - Index *pUpsertIdx; /* Constraint that pUpsertTarget identifies */ + Index *pUpsertIdx; /* UNIQUE constraint specified by pUpsertTarget */ SrcList *pUpsertSrc; /* Table to be updated */ int regData; /* First register holding array of VALUES */ int iDataCur; /* Index of the data cursor */ int iIdxCur; /* Index of the first index cursor */ + int addrGenericUpdate; /* Address of routine for generic DO UPDATE */ }; /* diff --git a/src/upsert.c b/src/upsert.c index 0f1f6d8a32..63b9144419 100644 --- a/src/upsert.c +++ b/src/upsert.c @@ -229,11 +229,27 @@ void sqlite3UpsertDoUpdate( SrcList *pSrc; /* FROM clause for the UPDATE */ int iDataCur; int i; + Upsert *pTop = pUpsert; assert( v!=0 ); assert( pUpsert!=0 ); - VdbeNoopComment((v, "Begin DO UPDATE of UPSERT")); iDataCur = pUpsert->iDataCur; + while( + pUpsert->pUpsertTarget!=0 + && (pUpsert->pUpsertIdx==0 ? pIdx!=0 : + pUpsert->pUpsertIdx->zName!=pIdx->zName) + ){ + assert( pUpsert->pNextUpsert!=0 ); + pUpsert = pUpsert->pNextUpsert; + } + if( pUpsert->addrGenericUpdate>0 ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, pUpsert->addrGenericUpdate); + return; + } + VdbeNoopComment((v, "Begin DO UPDATE of UPSERT")); + if( pUpsert->pUpsertTarget==0 ){ + pUpsert->addrGenericUpdate = sqlite3VdbeCurrentAddr(v); + } if( pIdx && iCur!=iDataCur ){ if( HasRowid(pTab) ){ int regRowid = sqlite3GetTempReg(pParse); @@ -263,13 +279,13 @@ void sqlite3UpsertDoUpdate( sqlite3VdbeJumpHere(v, i); } } - /* pUpsert does not own pUpsertSrc - the outer INSERT statement does. So - ** we have to make a copy before passing it down into sqlite3Update() */ - pSrc = sqlite3SrcListDup(db, pUpsert->pUpsertSrc, 0); + /* pUpsert does not own pTop->pUpsertSrc - the outer INSERT statement does. + ** So we have to make a copy before passing it down into sqlite3Update() */ + pSrc = sqlite3SrcListDup(db, pTop->pUpsertSrc, 0); /* excluded.* columns of type REAL need to be converted to a hard real */ for(i=0; inCol; i++){ if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){ - sqlite3VdbeAddOp1(v, OP_RealAffinity, pUpsert->regData+i); + sqlite3VdbeAddOp1(v, OP_RealAffinity, pTop->regData+i); } } sqlite3Update(pParse, pSrc, pUpsert->pUpsertSet, From 70f3eda5bedef47246d14a03e6ce4ce8a5c2ff50 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 10 Dec 2020 13:49:00 +0000 Subject: [PATCH 042/257] Add an optional function to the chsumvfs extension. When activated by the SQLITE_CKSUMVFS_INIT_FUNCNAME macro, this function will invoke the file-control that sets the number of reserved bytes to 8. This can be used to initialize a cksumvfs database file by programming languages that do not have access to the sqlite3_file_control() interface. FossilOrigin-Name: 01841fb4bf3d6c5fd5bcbc7d1338998c50f69f84ca475fba7cf764d636714678 --- ext/misc/cksumvfs.c | 40 ++++++++++++++++++++++++++++++++++++++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/ext/misc/cksumvfs.c b/ext/misc/cksumvfs.c index a0888c0024..46f3a4f0b5 100644 --- a/ext/misc/cksumvfs.c +++ b/ext/misc/cksumvfs.c @@ -356,6 +356,41 @@ static void cksmVerifyFunc( sqlite3_result_int(context, memcmp(data+nByte-8,cksum,8)==0); } +#ifdef SQLITE_CKSUMVFS_INIT_FUNCNAME +/* +** SQL function: initialize_cksumvfs(SCHEMANAME) +** +** This SQL functions (whose name is actually determined at compile-time +** by the value of the SQLITE_CKSUMVFS_INIT_FUNCNAME macro) invokes: +** +** sqlite3_file_control(db, SCHEMANAME, SQLITE_FCNTL_RESERVE_BYTE, &n); +** +** In order to set the reserve bytes value to 8, so that cksumvfs will +** operation. This feature is provided (if and only if the +** SQLITE_CKSUMVFS_INIT_FUNCNAME compile-time option is set to a string +** which is the name of the SQL function) so as to provide the ability +** to invoke the file-control in programming languages that lack +** direct access to the sqlite3_file_control() interface (ex: Java). +** +** This interface is undocumented, apart from this comment. Usage +** example: +** +** 1. Compile with -DSQLITE_CKSUMVFS_INIT_FUNCNAME="ckvfs_init" +** 2. Run: "SELECT cksum_init('main'); VACUUM;" +*/ +static void cksmInitFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int nByte = 8; + const char *zSchemaName = (const char*)sqlite3_value_text(argv[0]); + sqlite3 *db = sqlite3_context_db_handle(context); + sqlite3_file_control(db, zSchemaName, SQLITE_FCNTL_RESERVE_BYTES, &nByte); + /* Return NULL */ +} +#endif /* SQLITE_CKSUMBFS_INIT_FUNCNAME */ + /* ** Close a cksm-file. */ @@ -746,6 +781,11 @@ static int cksmRegisterFunc( rc = sqlite3_create_function(db, "verify_checksum", 1, SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC, 0, cksmVerifyFunc, 0, 0); +#ifdef SQLITE_CKSUMVFS_INIT_FUNCNAME + (void)sqlite3_create_function(db, SQLITE_CKSUMVFS_INIT_FUNCNAME, 1, + SQLITE_UTF8|SQLITE_DIRECTONLY, + 0, cksmInitFunc, 0, 0); +#endif return rc; } diff --git a/manifest b/manifest index 617f92a7f3..ead9a8fa60 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\scompilation\sissues\swith\sMSVC\srelated\sto\sC99. -D 2020-12-09T23:35:51.896 +C Add\san\soptional\sfunction\sto\sthe\schsumvfs\sextension.\s\sWhen\sactivated\sby\nthe\sSQLITE_CKSUMVFS_INIT_FUNCNAME\smacro,\sthis\sfunction\swill\sinvoke\sthe\nfile-control\sthat\ssets\sthe\snumber\sof\sreserved\sbytes\sto\s8.\s\sThis\scan\sbe\nused\sto\sinitialize\sa\scksumvfs\sdatabase\sfile\sby\sprogramming\slanguages\nthat\sdo\snot\shave\saccess\sto\sthe\ssqlite3_file_control()\sinterface. +D 2020-12-10T13:49:00.833 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -291,7 +291,7 @@ F ext/misc/blobio.c a867c4c4617f6ec223a307ebfe0eabb45e0992f74dd47722b96f3e631c0e F ext/misc/btreeinfo.c d28ce349b40054eaa9473e835837bad7a71deec33ba13e39f963d50933bfa0f9 F ext/misc/carray.c b75a0f207391038bf1540d3372f482a95c3613511c7c474db51ede1196321c7c F ext/misc/carray.h de74ac70b2338f416723f7d538026e8ec0b7f1d388319f8f140c9a4d7677f02e -F ext/misc/cksumvfs.c c4e7ebeae5aa578df98f23bddb63ecbcbe913ee3c32b8b769525af100d752061 +F ext/misc/cksumvfs.c 688a59d6c5dc7e7e0aba09654d8cbeeb7d04bad8cf57902df86aa06c2f723ff4 F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c85c243 F ext/misc/completion.c 6dafd7f4348eecc7be9e920d4b419d1fb2af75d938cd9c59a20cfe8beb2f22b9 F ext/misc/compress.c 3354c77a7c8e86e07d849916000cdac451ed96500bfb5bd83b20eb61eee012c9 @@ -1888,7 +1888,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 818c647cec7063b33b6c5de3e23599a1d61439fa6e9bf6c974b2522a5a9e1b44 -R f5a4c0e24239e1b152c6955913834244 -U mistachkin -Z ac2c81554df4b37487abc146a7fda901 +P c0de6c1fb2c486be1da01e5e4ca8c5634ba37822e418d57f272e018c3e3fc0a2 +R 6c67d7c383f4b37d548756594c8d9b75 +U drh +Z ffe92d1035962188772639969e0a3892 diff --git a/manifest.uuid b/manifest.uuid index 402122935f..782a536fd6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c0de6c1fb2c486be1da01e5e4ca8c5634ba37822e418d57f272e018c3e3fc0a2 \ No newline at end of file +01841fb4bf3d6c5fd5bcbc7d1338998c50f69f84ca475fba7cf764d636714678 \ No newline at end of file From 7aae73588aeb9fd33d26f0d0a654bfbebdccf72c Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 10 Dec 2020 18:06:24 +0000 Subject: [PATCH 043/257] Better integrate the changes on this branch with OP_Insert and OP_IdxInsert. FossilOrigin-Name: 101cef14910d6e865a94bc870aed599321b893188062a9a61d70a9434992cf23 --- manifest | 22 +++---- manifest.uuid | 2 +- src/btree.c | 166 ++++++++++++++++++++++++------------------------ src/btree.h | 4 +- src/btreeInt.h | 1 + src/insert.c | 34 ++++++---- src/sqliteInt.h | 1 + src/vdbe.c | 26 +++----- 8 files changed, 129 insertions(+), 127 deletions(-) diff --git a/manifest b/manifest index 3a5de7a2d6..d9b671f413 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Transfer\slarge\sindex\sor\sWITHOUT\sROWID\srecords\sbetween\sb-trees\swhen\svacuuming\swithout\sloading\sthem\sinto\smemory. -D 2020-12-09T20:33:51.761 +C Better\sintegrate\sthe\schanges\son\sthis\sbranch\swith\sOP_Insert\sand\sOP_IdxInsert. +D 2020-12-10T18:06:24.603 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -481,9 +481,9 @@ F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c ce6a27f7d8be22aed5914e3c5bb7293eb6bc8fa43b332c0c2cdd71afcceb81e7 -F src/btree.h 78908bc31dd4cbd54762825346d7a24534773ec4ca42e16faf10a0a164d74ec4 -F src/btreeInt.h ffd66480520d9d70222171b3a026d78b80833b5cea49c89867949f3e023d5f43 +F src/btree.c b14822d4dd984340d8b1c46bf5d49b12ab3adf6b639c5f3b395fa541153b1ba3 +F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e +F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 F src/build.c f6449d4e85e998e14d3f537e8ea898dca2fcb83c277db3e60945af9b9177db81 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e @@ -501,7 +501,7 @@ 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 0c4f619e119dc6201fdc8f7ea4cbde9e71268cf3089b36c064c49c3e2d07077d +F src/insert.c 153c5b438d44ba0b8ae7ca467f8f6390b18958d14e681a26e5e861a2ac480750 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 F src/main.c 97e9f137354bc1f76dc9bb60a0a24f8c45cf73b33e80d3ee4c64155336fb820d @@ -545,7 +545,7 @@ F src/shell.c.in e9f674ee4ec6c345679e8a5b16c869c6c59eb1540dd98ac69e4736ecddce009 F src/sqlite.h.in 0e2b4259e49a0eda54d9118eb18a04fcd60e0727a2fd2c81aade0bf57520e706 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h 6ab40b33a1f5edbb7d71c78e82e0f9c5291dcff4704df8e4f0ab0d9c1a0c06af +F src/sqliteInt.h 47bc1232d1c68525876c6c2d2b602bf8f614f84e7650de6031301435b535bf30 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -612,7 +612,7 @@ F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c c0c7977de7ef9b8cb10f6c85f2d0557889a658f817b0455909a49179ba4c8002 F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286 -F src/vdbe.c 334c2626ad478fc85c992856e71a6bdd95dc11bf0d7cfe10856ec915f3d9fbe5 +F src/vdbe.c b8ac132f98ab4edb126c7784cfd6f479aa45e476c9e873c13ecd7bd6ffdd8668 F src/vdbe.h 83603854bfa5851af601fc0947671eb260f4363e62e960e8a994fb9bbcd2aaa1 F src/vdbeInt.h 3ca5e9fd6e095a8b6cf6bc3587a46fc93499503b2fe48951e1034ba9e2ce2f6e F src/vdbeapi.c c5e7cb2ab89a24d7f723e87b508f21bfb1359a04db5277d8a99fd1e015c12eb9 @@ -1889,7 +1889,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 0d2c3776065dc94119899ae4164995193b82fca7ac31868f3141b729d0b65ab9 -R 2ada74530286abe77d1ee50368ad4c2c +P dfd4ca6891a893d0e9551689954d3e79114d5565f8a5264f96ad1d64fe1d6280 +R 649db055ff8e87cb8a713e180a0e255a U dan -Z b452c10135ea2f1997d2fa69cc2163a3 +Z 6c3c81094000f4145ba4e14f9b1ea402 diff --git a/manifest.uuid b/manifest.uuid index 604f1fcaeb..36af76a357 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dfd4ca6891a893d0e9551689954d3e79114d5565f8a5264f96ad1d64fe1d6280 \ No newline at end of file +101cef14910d6e865a94bc870aed599321b893188062a9a61d70a9434992cf23 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 8087d3935b..224d533b7c 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8679,7 +8679,7 @@ int sqlite3BtreeInsert( unsigned char *newCell = 0; assert( (flags & (BTREE_SAVEPOSITION|BTREE_APPEND|BTREE_PREFORMAT))==flags ); - assert( (flags & BTREE_PREFORMAT)==0 || seekResult ); + assert( (flags & BTREE_PREFORMAT)==0 || seekResult || pCur->pKeyInfo==0 ); if( pCur->eState==CURSOR_FAULT ){ assert( pCur->skipNext!=SQLITE_OK ); @@ -8825,14 +8825,21 @@ int sqlite3BtreeInsert( newCell = pBt->pTmpSpace; assert( newCell!=0 ); if( flags & BTREE_PREFORMAT ){ - assert( pX->pData==pBt->pTmpSpace ); - szNew = pX->nData; - if( szNew<4 ) szNew = 4; rc = SQLITE_OK; + szNew = pBt->nPreformatSize; + if( szNew<4 ) szNew = 4; + if( ISAUTOVACUUM && szNew>pPage->maxLocal ){ + CellInfo info; + pPage->xParseCell(pPage, newCell, &info); + if( ISAUTOVACUUM && info.nPayload!=info.nLocal ){ + Pgno ovfl = get4byte(&newCell[szNew-4]); + ptrmapPut(pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, &rc); + } + } }else{ rc = fillInCell(pPage, newCell, pX, &szNew); - if( rc ) goto end_insert; } + if( rc ) goto end_insert; assert( szNew==pPage->xCellSize(pPage, newCell) ); assert( szNew <= MX_CELL_SIZE(pBt) ); idx = pCur->ix; @@ -8938,97 +8945,88 @@ end_insert: return rc; } -int sqlite3BtreeTransfer( - BtCursor *pDest, - BtCursor *pSrc, - i64 iKey, - int seekResult -){ +int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 iKey){ int rc = SQLITE_OK; - BtreePayload x; - Pager *pSrcPager = pSrc->pBt->pPager; - u8 *pCell = pDest->pBt->pTmpSpace; - u8 *aOut; /* Pointer to next output buffer */ - int nOut; /* Size of output buffer aOut[] */ + BtShared *pBt = pDest->pBt; + u8 *aOut = pBt->pTmpSpace; /* Pointer to next output buffer */ const u8 *aIn; /* Pointer to next input buffer */ int nIn; /* Size of input buffer aIn[] */ int nRem; /* Bytes of data still to copy */ - u8 *pPgnoOut = 0; - Pgno ovflIn = 0; - DbPage *pPageIn = 0; - MemPage *pPageOut = 0; - memset(&x, 0, sizeof(x)); - x.nKey = iKey; getCellInfo(pSrc); - - x.pData = pCell; - x.nData += putVarint32(pCell, pSrc->info.nPayload); - if( pDest->pKeyInfo==0 ) x.nData += putVarint(&pCell[x.nData], iKey); - - nOut = btreePayloadToLocal(pDest->pPage, pSrc->info.nPayload); - aOut = &pCell[x.nData]; + aOut += putVarint32(aOut, pSrc->info.nPayload); + if( pDest->pKeyInfo==0 ) aOut += putVarint(aOut, iKey); nIn = pSrc->info.nLocal; aIn = pSrc->info.pPayload; nRem = pSrc->info.nPayload; + if( nIn==nRem && nInpPage->maxLocal ){ + memcpy(aOut, aIn, nIn); + pBt->nPreformatSize = nIn + (aOut - pBt->pTmpSpace); + }else{ + Pager *pSrcPager = pSrc->pBt->pPager; + u8 *pPgnoOut = 0; + Pgno ovflIn = 0; + DbPage *pPageIn = 0; + MemPage *pPageOut = 0; + int nOut; /* Size of output buffer aOut[] */ - x.nData += nOut; - if( nOutinfo.nPayload ){ - pPgnoOut = &pCell[x.nData]; - x.nData += 4; - } - - if( nRem>nIn ){ - ovflIn = get4byte(&pSrc->info.pPayload[nIn]); - } - - do { - nRem -= nOut; - do{ - assert( nOut>0 ); - if( nIn>0 ){ - int nCopy = MIN(nOut, nIn); - memcpy(aOut, aIn, nCopy); - nOut -= nCopy; - nIn -= nCopy; - aOut += nCopy; - aIn += nCopy; - } - if( nOut>0 ){ - sqlite3PagerUnref(pPageIn); - pPageIn = 0; - rc = sqlite3PagerGet(pSrcPager, ovflIn, &pPageIn, PAGER_GET_READONLY); - if( rc==SQLITE_OK ){ - aIn = (const u8*)sqlite3PagerGetData(pPageIn); - ovflIn = get4byte(aIn); - aIn += 4; - nIn = pSrc->pBt->usableSize - 4; + nOut = btreePayloadToLocal(pDest->pPage, pSrc->info.nPayload); + pBt->nPreformatSize = nOut + (aOut - pBt->pTmpSpace); + if( nOutinfo.nPayload ){ + pPgnoOut = &aOut[nOut]; + pBt->nPreformatSize += 4; + } + + if( nRem>nIn ){ + ovflIn = get4byte(&pSrc->info.pPayload[nIn]); + } + + do { + nRem -= nOut; + do{ + assert( nOut>0 ); + if( nIn>0 ){ + int nCopy = MIN(nOut, nIn); + memcpy(aOut, aIn, nCopy); + nOut -= nCopy; + nIn -= nCopy; + aOut += nCopy; + aIn += nCopy; + } + if( nOut>0 ){ + sqlite3PagerUnref(pPageIn); + pPageIn = 0; + rc = sqlite3PagerGet(pSrcPager, ovflIn, &pPageIn, PAGER_GET_READONLY); + if( rc==SQLITE_OK ){ + aIn = (const u8*)sqlite3PagerGetData(pPageIn); + ovflIn = get4byte(aIn); + aIn += 4; + nIn = pSrc->pBt->usableSize - 4; + } + } + }while( rc==SQLITE_OK && nOut>0 ); + + if( rc==SQLITE_OK && nRem>0 ){ + Pgno pgnoNew; + MemPage *pNew = 0; + rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0); + put4byte(pPgnoOut, pgnoNew); + if( ISAUTOVACUUM && pPageOut ){ + ptrmapPut(pBt, pgnoNew, PTRMAP_OVERFLOW2, pPageOut->pgno, &rc); + } + releasePage(pPageOut); + pPageOut = pNew; + if( pPageOut ){ + pPgnoOut = pPageOut->aData; + put4byte(pPgnoOut, 0); + aOut = &pPgnoOut[4]; + nOut = MIN(pBt->usableSize - 4, nRem); } } - }while( rc==SQLITE_OK && nOut>0 ); - - if( rc==SQLITE_OK && nRem>0 ){ - Pgno pgnoNew; - MemPage *pNew = 0; - rc = allocateBtreePage(pDest->pBt, &pNew, &pgnoNew, 0, 0); - put4byte(pPgnoOut, pgnoNew); - releasePage(pPageOut); - pPageOut = pNew; - if( pPageOut ){ - pPgnoOut = pPageOut->aData; - put4byte(pPgnoOut, 0); - aOut = &pPgnoOut[4]; - nOut = MIN(pDest->pBt->usableSize - 4, nRem); - } - } - }while( nRem>0 && rc==SQLITE_OK ); - - releasePage(pPageOut); - sqlite3PagerUnref(pPageIn); - - if( rc==SQLITE_OK ){ - int flags = BTREE_APPEND|BTREE_PREFORMAT; - rc = sqlite3BtreeInsert(pDest, &x, flags, seekResult); + }while( nRem>0 && rc==SQLITE_OK ); + + releasePage(pPageOut); + sqlite3PagerUnref(pPageIn); } return rc; diff --git a/src/btree.h b/src/btree.h index 4c2a872bb9..e00c473c93 100644 --- a/src/btree.h +++ b/src/btree.h @@ -262,7 +262,7 @@ int sqlite3BtreeDelete(BtCursor*, u8 flags); #define BTREE_SAVEPOSITION 0x02 /* Leave cursor pointing at NEXT or PREV */ #define BTREE_AUXDELETE 0x04 /* not the primary delete operation */ #define BTREE_APPEND 0x08 /* Insert is likely an append */ -#define BTREE_PREFORMAT 0x10 /* Insert is likely an append */ +#define BTREE_PREFORMAT 0x80 /* Insert is likely an append */ /* An instance of the BtreePayload object describes the content of a single ** entry in either an index or table btree. @@ -362,7 +362,7 @@ void sqlite3BtreeCursorList(Btree*); int sqlite3BtreeCheckpoint(Btree*, int, int *, int *); #endif -int sqlite3BtreeTransfer(BtCursor*, BtCursor*, i64, int); +int sqlite3BtreeTransferRow(BtCursor*, BtCursor*, i64); /* ** If we are not using shared cache, then there is no need to diff --git a/src/btreeInt.h b/src/btreeInt.h index c09699fbb5..851b8e6c1d 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -455,6 +455,7 @@ struct BtShared { Btree *pWriter; /* Btree with currently open write transaction */ #endif u8 *pTmpSpace; /* Temp space sufficient to hold a single cell */ + int nPreformatSize; /* Size of last cell written by TransferRow() */ }; /* diff --git a/src/insert.c b/src/insert.c index 0af845e887..2a40acaa0c 100644 --- a/src/insert.c +++ b/src/insert.c @@ -2748,6 +2748,7 @@ static int xferOptimization( iDest = pParse->nTab++; regAutoinc = autoIncBegin(pParse, iDbDest, pDest); regData = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_Null, 0, regData); regRowid = sqlite3GetTempReg(pParse); sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite); assert( HasRowid(pDest) || destHasUniqueIdx ); @@ -2797,17 +2798,26 @@ static int xferOptimization( addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid); assert( (pDest->tabFlags & TF_Autoincrement)==0 ); } + if( db->mDbFlags & DBFLAG_Vacuum ){ sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest); - insFlags = OPFLAG_APPEND|OPFLAG_USESEEKRESULT; - sqlite3VdbeAddOp3(v, OP_Transfer, iDest, iSrc, regRowid); + insFlags = OPFLAG_APPEND|OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT; }else{ - insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND; - sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); - sqlite3VdbeAddOp4(v, OP_Insert, iDest, regData, regRowid, - (char*)pDest, P4_TABLE); - sqlite3VdbeChangeP5(v, insFlags); + insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND|OPFLAG_PREFORMAT; } +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + if( db->xPreUpdateCallback ){ + sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); + insFlags &= ~OPFLAG_PREFORMAT; + }else +#endif + { + sqlite3VdbeAddOp3(v, OP_RowCell, iDest, iSrc, regRowid); + } + sqlite3VdbeAddOp4(v, OP_Insert, iDest, regData, regRowid, + (char*)pDest, P4_TABLE); + sqlite3VdbeChangeP5(v, insFlags); + sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); sqlite3VdbeAddOp2(v, OP_Close, iDest, 0); @@ -2849,18 +2859,18 @@ static int xferOptimization( if( sqlite3_stricmp(sqlite3StrBINARY, zColl) ) break; } if( i==pSrcIdx->nColumn ){ - idxInsFlags = OPFLAG_USESEEKRESULT; + idxInsFlags = OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT; sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest); - sqlite3VdbeAddOp3(v, OP_Transfer, iDest, iSrc, 0); + sqlite3VdbeAddOp3(v, OP_RowCell, iDest, iSrc, regData); } }else if( !HasRowid(pSrc) && pDestIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){ idxInsFlags |= OPFLAG_NCHANGE; } - if( idxInsFlags!=OPFLAG_USESEEKRESULT ){ + if( idxInsFlags!=(OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT) ){ sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, regData); - sqlite3VdbeChangeP5(v, idxInsFlags|OPFLAG_APPEND); } + sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, regData); + sqlite3VdbeChangeP5(v, idxInsFlags|OPFLAG_APPEND); sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v); sqlite3VdbeJumpHere(v, addr1); sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 438f79c092..fa24bf9ac0 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3517,6 +3517,7 @@ struct AuthContext { #define OPFLAG_SAVEPOSITION 0x02 /* OP_Delete/Insert: save cursor pos */ #define OPFLAG_AUXDELETE 0x04 /* OP_Delete: index in a DELETE op */ #define OPFLAG_NOCHNG_MAGIC 0x6d /* OP_MakeRecord: serialtype 10 is ok */ +#define OPFLAG_PREFORMAT 0x80 /* OP_Insert uses preformatted cell */ /* * Each trigger present in the database schema is stored as an instance of diff --git a/src/vdbe.c b/src/vdbe.c index 74fede8562..e640dedbcd 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5126,7 +5126,8 @@ case OP_Insert: { } x.pKey = 0; rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, - (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION)), seekResult + (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION|OPFLAG_PREFORMAT)), + seekResult ); pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; @@ -5143,29 +5144,20 @@ case OP_Insert: { break; } -/* Opcode: Transfer P1 P2 P3 * * -** Synopsis: intkey=r[P3] -** -** P1 and P2 are both cursors open on either intkey or index btrees. This -** instruction reads the current row from P2 and writes it into the -** table opened by P1. If P1 and P2 are opened on intkey tables, register -** P3 contains the rowid value to use when inserting into P1. +/* Opcode: RowCell P1 P2 P3 * * */ -case OP_Transfer: { +case OP_RowCell: { VdbeCursor *pDest; /* Cursor to write to */ VdbeCursor *pSrc; /* Cursor to read from */ i64 iKey; /* Rowid value to insert with */ - + assert( pOp[1].opcode==OP_Insert || pOp[1].opcode==OP_IdxInsert ); pDest = p->apCsr[pOp->p1]; pSrc = p->apCsr[pOp->p2]; iKey = pOp->p3 ? aMem[pOp->p3].u.i : 0; - - rc = sqlite3BtreeTransfer( - pDest->uc.pCursor, pSrc->uc.pCursor, iKey, pDest->seekResult - ); + rc = sqlite3BtreeTransferRow(pDest->uc.pCursor, pSrc->uc.pCursor, iKey); if( rc!=SQLITE_OK ) goto abort_due_to_error; break; -} +}; /* Opcode: Delete P1 P2 P3 P4 P5 ** @@ -5822,7 +5814,7 @@ case OP_IdxInsert: { /* in2 */ assert( pC!=0 ); assert( !isSorter(pC) ); pIn2 = &aMem[pOp->p2]; - assert( pIn2->flags & MEM_Blob ); + assert( (pIn2->flags & MEM_Blob) || (pOp->p5 & OPFLAG_PREFORMAT) ); if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; assert( pC->eCurType==CURTYPE_BTREE ); assert( pC->isTable==0 ); @@ -5833,7 +5825,7 @@ case OP_IdxInsert: { /* in2 */ x.aMem = aMem + pOp->p3; x.nMem = (u16)pOp->p4.i; rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, - (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION)), + (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION|OPFLAG_PREFORMAT)), ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0) ); assert( pC->deferredMoveto==0 ); From d2ffc9721e0cc7ae5362bd80a0a65c4063eb7e18 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 10 Dec 2020 19:20:15 +0000 Subject: [PATCH 044/257] Fix minor issues with new code on this branch. FossilOrigin-Name: f7fa76d0963e7b34026dc20c920bfbf7961033fe2b99503f6857157595f86823 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/btree.c | 15 +++++++++++++++ src/vdbe.c | 24 +++++++++++++++++------- test/vacuum6.test | 23 +++++++++++++++-------- 5 files changed, 56 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index 95ecdca302..44b269d0ac 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\strunk\schanges\sinto\sthis\sbranch. -D 2020-12-10T18:07:01.742 +C Fix\sminor\sissues\swith\snew\scode\son\sthis\sbranch. +D 2020-12-10T19:20:15.980 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -481,7 +481,7 @@ F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c b14822d4dd984340d8b1c46bf5d49b12ab3adf6b639c5f3b395fa541153b1ba3 +F src/btree.c de8d2a4d8dedf9187cc9019b8f882bc788ab8fe815b7f69042e880fbc11304dc F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 F src/build.c f6449d4e85e998e14d3f537e8ea898dca2fcb83c277db3e60945af9b9177db81 @@ -612,7 +612,7 @@ F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c c0c7977de7ef9b8cb10f6c85f2d0557889a658f817b0455909a49179ba4c8002 F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286 -F src/vdbe.c b8ac132f98ab4edb126c7784cfd6f479aa45e476c9e873c13ecd7bd6ffdd8668 +F src/vdbe.c 808c1503dd183578d7ebcf0e517e636c6005f783daadc9a27305b10597c1142e F src/vdbe.h 83603854bfa5851af601fc0947671eb260f4363e62e960e8a994fb9bbcd2aaa1 F src/vdbeInt.h 3ca5e9fd6e095a8b6cf6bc3587a46fc93499503b2fe48951e1034ba9e2ce2f6e F src/vdbeapi.c c5e7cb2ab89a24d7f723e87b508f21bfb1359a04db5277d8a99fd1e015c12eb9 @@ -1654,7 +1654,7 @@ F test/vacuum2.test 9fd45ce6ce29f5614c249e03938d3567c06a9e772d4f155949f8eafe2d8a F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d F test/vacuum4.test 7ea76b769fffeb41f925303b04cbcf5a5bbeabe55e4c60ae754ff24eeeb7c010 F test/vacuum5.test 263b144d537e92ad8e9ca8a73cc6e1583f41cfd0dda9432b87f7806174a2f48c -F test/vacuum6.test 7d3aea27ef3c671dafccbad5adc7848205c38ab14ee7a1dabe592e0794e132d7 +F test/vacuum6.test e67488fa1341cc8034ba261807d429a8c06f4593ec1bb1651d8497d2d5df92c9 F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2 F test/varint.test bbce22cda8fc4d135bcc2b589574be8410614e62 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 @@ -1889,7 +1889,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 101cef14910d6e865a94bc870aed599321b893188062a9a61d70a9434992cf23 01841fb4bf3d6c5fd5bcbc7d1338998c50f69f84ca475fba7cf764d636714678 -R a5d793c28e830d9302f879f5ab38dd56 +P 7337eed629b4537b8fc2dc87c3c71d0a664128a91fd00f3c5f18843505beee90 +R 4dec8f74318b8721d36ac1bd02f7a778 U dan -Z 2458c10db91ae6ca73e242d0fd66a7be +Z 1308f2122d2b4d2b55d5a48e115dbda3 diff --git a/manifest.uuid b/manifest.uuid index e8cdfeec6b..7aba6f714d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7337eed629b4537b8fc2dc87c3c71d0a664128a91fd00f3c5f18843505beee90 \ No newline at end of file +f7fa76d0963e7b34026dc20c920bfbf7961033fe2b99503f6857157595f86823 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 224d533b7c..7522f01c36 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8945,6 +8945,21 @@ end_insert: return rc; } +/* +** This function is used as part of copying the current row from cursor +** pSrc into cursor pDest. If the cursors are open on intkey tables, then +** parameter iKey is used as the rowid value when the record is copied +** into pDest. Otherwise, the record is copied verbatim. +** +** This function does not actually write the new value to cursor pDest. +** Instead, it creates and populates any required overflow pages and +** writes the data for the new cell into the BtShared.pTmpSpace buffer +** for the destination database. The size of the cell, in bytes, is left +** in BtShared.nPreformatSize. The caller completes the insertion by +** calling sqlite3BtreeInsert() with the BTREE_PREFORMAT flag specified. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +*/ int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 iKey){ int rc = SQLITE_OK; BtShared *pBt = pDest->pBt; diff --git a/src/vdbe.c b/src/vdbe.c index e640dedbcd..904b5e2bc0 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3572,6 +3572,13 @@ case OP_Transaction: { && (iMeta!=pOp->p3 || db->aDb[pOp->p1].pSchema->iGeneration!=pOp->p4.i) ){ + /* + ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema + ** version is checked to ensure that the schema has not changed since the + ** SQL statement was prepared. + */ + sqlite3DbFree(db, p->zErrMsg); + p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); /* If the schema-cookie from the database file matches the cookie ** stored with the in-memory representation of the schema, do ** not reload the schema from the database file. @@ -3588,13 +3595,6 @@ case OP_Transaction: { if( db->aDb[pOp->p1].pSchema->schema_cookie!=iMeta ){ sqlite3ResetOneSchema(db, pOp->p1); } - /* - ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema - ** version is checked to ensure that the schema has not changed since the - ** SQL statement was prepared. - */ - sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); p->expired = 1; rc = SQLITE_SCHEMA; } @@ -5145,12 +5145,22 @@ case OP_Insert: { } /* Opcode: RowCell P1 P2 P3 * * +** +** P1 and P2 are both open cursors. Both must be opened on the same type +** of table - intkey or index. This opcode is used as part of copying +** the current row from P2 into P1. If the cursors are opened on intkey +** tables, register P3 contains the rowid to use with the new record in +** P1. If they are opened on index tables, P3 is not used. +** +** This opcode must be followed by either an Insert or InsertIdx opcode +** with the OPFLAG_PREFORMAT flag set to complete the insert operation. */ case OP_RowCell: { VdbeCursor *pDest; /* Cursor to write to */ VdbeCursor *pSrc; /* Cursor to read from */ i64 iKey; /* Rowid value to insert with */ assert( pOp[1].opcode==OP_Insert || pOp[1].opcode==OP_IdxInsert ); + assert( pOp[1].p5 & OPFLAG_PREFORMAT ); pDest = p->apCsr[pOp->p1]; pSrc = p->apCsr[pOp->p2]; iKey = pOp->p3 ? aMem[pOp->p3].u.i : 0; diff --git a/test/vacuum6.test b/test/vacuum6.test index 203b3329e2..51070fd0c7 100644 --- a/test/vacuum6.test +++ b/test/vacuum6.test @@ -34,6 +34,7 @@ do_execsql_test 1.1 { } #------------------------------------------------------------------------- +# reset_db foreach {tn sz} {1 400 2 4000 3 9999} { reset_db @@ -69,23 +70,29 @@ do_execsql_test 3.2 { } {ok} #------------------------------------------------------------------------- +# reset_db do_execsql_test 4.0 { CREATE TABLE tx(a, b); CREATE INDEX i1 ON tx(b); WITH s(i) AS ( - SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<10000 + SELECT 8000 UNION ALL SELECT i+1 FROM s WHERE i<10000 ) INSERT INTO tx SELECT i, randomblob(i) FROM s; -} -foreach {tn pgsz} { - 1 2048 - 2 1024 - 3 65536 - 4 8192 + + SELECT sum(length(b)) FROM tx; +} {18009000} +foreach {tn pgsz av} { + 1 2048 0 + 2 1024 1 + 3 65536 0 + 4 8192 1 + 5 512 0 + 6 4096 1 } { do_execsql_test 4.1.$tn.1 " - PRAGMA page_size = $pgsz + PRAGMA page_size = $pgsz; + PRAGMA auto_vacuum = $av; " do_execsql_test 4.1.$tn.2 VACUUM integrity_check 4.1.$tn.3 From 9257ddbf87a2c3a8ecf7022f4a25975b89a1be3f Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 10 Dec 2020 19:54:13 +0000 Subject: [PATCH 045/257] Remove a redundant branch added by [56a54258560]. FossilOrigin-Name: b4d6f6d728738710249ad74236c31a1872fdff7dadabd4c4a67d05826eb5df9e --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/btree.c | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 2b7531deb8..a3131d8cd4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Changes\sto\savoid\sloading\slarge\srecords\sinto\smemory\swithin\sVACUUM. -D 2020-12-10T19:51:39.987 +C Remove\sa\sredundant\sbranch\sadded\sby\s[56a54258560]. +D 2020-12-10T19:54:13.413 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -481,7 +481,7 @@ F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c de8d2a4d8dedf9187cc9019b8f882bc788ab8fe815b7f69042e880fbc11304dc +F src/btree.c 91da5fd5d99bc7e7422242419561bd9518e0229c243c48799303be7112ef5601 F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 F src/build.c f6449d4e85e998e14d3f537e8ea898dca2fcb83c277db3e60945af9b9177db81 @@ -1889,8 +1889,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 01841fb4bf3d6c5fd5bcbc7d1338998c50f69f84ca475fba7cf764d636714678 f7fa76d0963e7b34026dc20c920bfbf7961033fe2b99503f6857157595f86823 -R 4dec8f74318b8721d36ac1bd02f7a778 -T +closed f7fa76d0963e7b34026dc20c920bfbf7961033fe2b99503f6857157595f86823 +P 56a54258560fab715b83967634b2bd4c04be43cded112b46e85da9f99ee02f7c +R c82b011ba062cfde3acc0789a727fd1f U dan -Z 3adf74c0105eb40ca1b5c5d7fdb48232 +Z 9746b01cc9973ffd448104549b3bbdff diff --git a/manifest.uuid b/manifest.uuid index c98df885d4..8a864002ee 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -56a54258560fab715b83967634b2bd4c04be43cded112b46e85da9f99ee02f7c \ No newline at end of file +b4d6f6d728738710249ad74236c31a1872fdff7dadabd4c4a67d05826eb5df9e \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 7522f01c36..3ed365c5f7 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8831,7 +8831,7 @@ int sqlite3BtreeInsert( if( ISAUTOVACUUM && szNew>pPage->maxLocal ){ CellInfo info; pPage->xParseCell(pPage, newCell, &info); - if( ISAUTOVACUUM && info.nPayload!=info.nLocal ){ + if( info.nPayload!=info.nLocal ){ Pgno ovfl = get4byte(&newCell[szNew-4]); ptrmapPut(pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, &rc); } From daf2761c62103f7bf126f8029dcf5fb473216f5f Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 10 Dec 2020 20:31:25 +0000 Subject: [PATCH 046/257] Use an iterator for the index loop in sqlite3GenerateConstraintChecks(). The idea is that this iterator can be enhanced to traverse the indexes in any order, as required by multi-index UPSERT. FossilOrigin-Name: 64a4a91ecc5dcde3fa07d3cf038c74b9ede63d36628ecfb35203a9dfbbfe113c --- manifest | 16 ++++----- manifest.uuid | 2 +- src/insert.c | 89 +++++++++++++++++++++++++++++++++++-------------- src/sqliteInt.h | 2 +- src/upsert.c | 2 +- 5 files changed, 75 insertions(+), 36 deletions(-) diff --git a/manifest b/manifest index abce3073d7..293f993ca7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sDO\sUPDATE\scode\sgenerator\ssearches\sfor\sthe\scorrect\sON\sCONFLICT\sclause\sto\nuse. -D 2020-12-10T12:49:26.425 +C Use\san\siterator\sfor\sthe\sindex\sloop\sin\ssqlite3GenerateConstraintChecks().\nThe\sidea\sis\sthat\sthis\siterator\scan\sbe\senhanced\sto\straverse\sthe\sindexes\sin\nany\sorder,\sas\srequired\sby\smulti-index\sUPSERT. +D 2020-12-10T20:31:25.985 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -501,7 +501,7 @@ 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 df28564b7d79f146266e906549687c74e3a5e9c4d8ba8697ef9c479ad83407e0 +F src/insert.c ac236526a7f239d420291fae1bf7ea56c9e54f335598315a0ddf8ebb5a110120 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 F src/main.c 97e9f137354bc1f76dc9bb60a0a24f8c45cf73b33e80d3ee4c64155336fb820d @@ -545,7 +545,7 @@ F src/shell.c.in e9f674ee4ec6c345679e8a5b16c869c6c59eb1540dd98ac69e4736ecddce009 F src/sqlite.h.in 0e2b4259e49a0eda54d9118eb18a04fcd60e0727a2fd2c81aade0bf57520e706 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h 0e042bd76044617ae919a294778ceacdb00a405d60de1b94c8ee4d2b81829bdb +F src/sqliteInt.h 72c7bfc4831f171d25b7b03c9fb152f1a3bbf55f51d5bbcdef313ebfa5873bea F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -608,7 +608,7 @@ F src/tokenize.c 01dba3023659dc6f6b1e054c14b35a0074bd35de10466b99454d33278191d97 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda F src/trigger.c 515e79206d40d1d4149129318582e79a6e9db590a7b74e226fdb5b2a6c7e1b10 F src/update.c 9f126204a6acb96bbe47391ae48e0fc579105d8e76a6d9c4fab3271367476580 -F src/upsert.c 49170532578f2f30984b35e2c1e2f308b089c6814edf384d32158a53b25fc930 +F src/upsert.c 4b960968084a1d2a301ddbc782f625dbb1c02e0e8d0b0d6ad4a1986ecf305729 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c c0c7977de7ef9b8cb10f6c85f2d0557889a658f817b0455909a49179ba4c8002 F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286 @@ -1888,7 +1888,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 3194c00c2c6a32bdfd5acc9fda5b38ae131d20cd3b7aea8512a41b2e76808f6a -R 8dc7164868d12444f67e9c3abe760e73 +P a47e35ee2d901baaa37e7229d190f934e1b0bd3510147cd4a2a49c4a1411416a +R 57e2c4174298e4f52a8ae7fd60045bd5 U drh -Z 978ca06206ec1f9d5cc426705017394f +Z 27b1defd588019eb0041967767579913 diff --git a/manifest.uuid b/manifest.uuid index 88e882cea1..1fd8f4a00d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a47e35ee2d901baaa37e7229d190f934e1b0bd3510147cd4a2a49c4a1411416a \ No newline at end of file +64a4a91ecc5dcde3fa07d3cf038c74b9ede63d36628ecfb35203a9dfbbfe113c \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index f10587f9f2..44cd8a3390 100644 --- a/src/insert.c +++ b/src/insert.c @@ -976,9 +976,6 @@ void sqlite3Insert( #ifndef SQLITE_OMIT_UPSERT if( pUpsert ){ Upsert *pNx; - int nIdx; - Index *pIdxList; - int *aReg; if( IsVirtual(pTab) ){ sqlite3ErrorMsg(pParse, "UPSERT not implemented for virtual table \"%s\"", pTab->zName); @@ -1003,26 +1000,6 @@ void sqlite3Insert( } pNx = pNx->pNextUpsert; }while( pNx!=0 ); - for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ - assert( pIdx ); - assert( aRegIdx[nIdx]>0 ); - } - if( nIdx==0 ){ - pUpsert->pIdxList = 0; - }else{ - u64 nByte = sizeof(Index)*nIdx + sizeof(int)*(nIdx+2); - pIdxList = sqlite3DbMallocRaw(db, nByte); - if( pIdxList==0 ) goto insert_cleanup; - aReg = (int*)&pIdxList[nIdx]; - for(i=0, pIdx=pTab->pIndex; ipNext, i++){ - memcpy(&pIdxList[i], pIdx, sizeof(Index)); - pIdxList[i].pNext = 0; - if( i ) pIdxList[i-1].pNext = &pIdxList[i]; - aReg[i] = aRegIdx[i]; - } - aReg[i] = aRegIdx[i]; - pUpsert->pIdxList = pIdxList; - } } #endif @@ -1427,6 +1404,62 @@ int sqlite3ExprReferencesUpdatedColumn( return w.eCode!=0; } +/* +** The sqlite3GenerateConstraintChecks() routine usually wants to visit +** the indexes of a table in the order provided in the Table->pIndex list. +** However, sometimes (rarely - when there is an upsert) it wants to visit +** the indexes in a different order. The following data structures accomplish +** this. +** +** The IndexIterator object is used to walk through all of the indexes +** of a table in either Index.pNext order, or in some other order established +** by an array of IndexListTerm objects. +*/ +typedef struct IndexListTerm IndexListTerm; +typedef struct IndexIterator IndexIterator; +struct IndexIterator { + int eType; /* 0 for Index.pNext list. 1 for an array of IndexListTerm */ + int i; /* Index of the current item from the list */ + union { + struct { /* Use this object for eType==0: A Index.pNext list */ + Index *pIdx; /* The current Index */ + } lx; + struct { /* Use this object for eType==1; Array of IndexListTerm */ + int nIdx; /* Size of the array */ + IndexListTerm *aIdx; /* Array of IndexListTerms */ + } ax; + } u; +}; + +/* When IndexIterator.eType==1, then each index is an array of instances +** of the following object +*/ +struct IndexListTerm { + Index *p; /* The index */ + int ix; /* Which entry in the original Table.pIndex list is this index*/ +}; + +/* Return the first index on the list */ +static Index *indexIteratorFirst(IndexIterator *pIter, int *pIx){ + int i = pIter->i; + *pIx = i; + return pIter->eType ? pIter->u.ax.aIdx[i].p : pIter->u.lx.pIdx; +} + +/* Return the next index from the list. Return NULL when out of indexes */ +static Index *indexIteratorNext(IndexIterator *pIter, int *pIx){ + int i = ++pIter->i; + if( pIter->eType ){ + if( i>=pIter->u.ax.nIdx ) return 0; + *pIx = pIter->u.ax.aIdx[i].ix; + return pIter->u.ax.aIdx[i].p; + }else{ + *pIx = i; + pIter->u.lx.pIdx = pIter->u.lx.pIdx->pNext; + return pIter->u.lx.pIdx; + } +} + /* ** Generate code to do constraint checks prior to an INSERT or an UPDATE ** on table pTab. @@ -1557,6 +1590,7 @@ void sqlite3GenerateConstraintChecks( int lblRecheckOk = 0; /* Each recheck jumps to this label if it passes */ Trigger *pTrigger; /* List of DELETE triggers on the table pTab */ int nReplaceTrig = 0; /* Number of replace triggers coded */ + IndexIterator ixi; /* Index iterator */ isUpdate = regOldData!=0; db = pParse->db; @@ -1769,6 +1803,9 @@ void sqlite3GenerateConstraintChecks( VdbeComment((v, "UPSERT constraint goes first")); } } + ixi.eType = 0; + ixi.i = 0; + ixi.u.lx.pIdx = pTab->pIndex; /* Determine if it is possible that triggers (either explicitly coded ** triggers or FK resolution actions) might run as a result of deletes @@ -1953,8 +1990,10 @@ void sqlite3GenerateConstraintChecks( ** This loop also handles the case of the PRIMARY KEY index for a ** WITHOUT ROWID table. */ - pIdx = pUpsert ? pUpsert->pIdxList : pTab->pIndex; - for(ix=0; pIdx; pIdx=pIdx->pNext, ix++){ + for(pIdx = indexIteratorFirst(&ixi, &ix); + pIdx; + pIdx = indexIteratorNext(&ixi, &ix) + ){ int regIdx; /* Range of registers hold conent for pIdx */ int regR; /* Range of registers holding conflicting PK */ int iThisCur; /* Cursor for this UNIQUE index */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 23df9cc710..83993f08c5 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3080,7 +3080,7 @@ struct Upsert { Upsert *pNextUpsert; /* Next ON CONFLICT clause in the list */ /* Above this point is the parse tree for the ON CONFLICT clauses. ** The next group of fields stores intermediate data. */ - Index *pIdxList; + void *pToFree; /* Free memory when deleting the Upsert object */ /* All fields above are owned by the Upsert object and must be freed ** when the Upsert is destroyed. The fields below are used to transfer ** information from the INSERT processing down into the UPDATE processing diff --git a/src/upsert.c b/src/upsert.c index 63b9144419..6b9bff6851 100644 --- a/src/upsert.c +++ b/src/upsert.c @@ -25,7 +25,7 @@ static void SQLITE_NOINLINE upsertDelete(sqlite3 *db, Upsert *p){ sqlite3ExprDelete(db, p->pUpsertTargetWhere); sqlite3ExprListDelete(db, p->pUpsertSet); sqlite3ExprDelete(db, p->pUpsertWhere); - sqlite3DbFree(db, p->pIdxList); + sqlite3DbFree(db, p->pToFree); sqlite3DbFree(db, p); p = pNext; }while( p ); From 61e280ad8a3ce9d14c65948265cd8732825e18dd Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 11 Dec 2020 01:17:06 +0000 Subject: [PATCH 047/257] Logic is in place to handle multiple ON CONFLICT clauses, but it does not work. Any use of ON CONFLICT will likely lead to memory faults. This is an incremental check-in to save my place. FossilOrigin-Name: 155142314feb007d526f8f67723636fd50dc52d1cd4d3a67dd93b105c9d5c2be --- manifest | 16 +++--- manifest.uuid | 2 +- src/insert.c | 140 +++++++++++++++++++++++++++++++++--------------- src/sqliteInt.h | 4 ++ src/upsert.c | 41 +++++++++++--- 5 files changed, 142 insertions(+), 61 deletions(-) diff --git a/manifest b/manifest index 293f993ca7..5bb77216d5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\san\siterator\sfor\sthe\sindex\sloop\sin\ssqlite3GenerateConstraintChecks().\nThe\sidea\sis\sthat\sthis\siterator\scan\sbe\senhanced\sto\straverse\sthe\sindexes\sin\nany\sorder,\sas\srequired\sby\smulti-index\sUPSERT. -D 2020-12-10T20:31:25.985 +C Logic\sis\sin\splace\sto\shandle\smultiple\sON\sCONFLICT\sclauses,\sbut\sit\sdoes\snot\swork.\nAny\suse\sof\sON\sCONFLICT\swill\slikely\slead\sto\smemory\sfaults.\s\sThis\sis\san\nincremental\scheck-in\sto\ssave\smy\splace. +D 2020-12-11T01:17:06.489 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -501,7 +501,7 @@ 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 ac236526a7f239d420291fae1bf7ea56c9e54f335598315a0ddf8ebb5a110120 +F src/insert.c c8d4bc0dcde4d9d42a1761e919a6a99668000e16840814f8bb643e161894b27f F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 F src/main.c 97e9f137354bc1f76dc9bb60a0a24f8c45cf73b33e80d3ee4c64155336fb820d @@ -545,7 +545,7 @@ F src/shell.c.in e9f674ee4ec6c345679e8a5b16c869c6c59eb1540dd98ac69e4736ecddce009 F src/sqlite.h.in 0e2b4259e49a0eda54d9118eb18a04fcd60e0727a2fd2c81aade0bf57520e706 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h 72c7bfc4831f171d25b7b03c9fb152f1a3bbf55f51d5bbcdef313ebfa5873bea +F src/sqliteInt.h aff99a1938b53530971fcfa7a6a5e6b47f986ddd673660bafb41f1c559747b72 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -608,7 +608,7 @@ F src/tokenize.c 01dba3023659dc6f6b1e054c14b35a0074bd35de10466b99454d33278191d97 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda F src/trigger.c 515e79206d40d1d4149129318582e79a6e9db590a7b74e226fdb5b2a6c7e1b10 F src/update.c 9f126204a6acb96bbe47391ae48e0fc579105d8e76a6d9c4fab3271367476580 -F src/upsert.c 4b960968084a1d2a301ddbc782f625dbb1c02e0e8d0b0d6ad4a1986ecf305729 +F src/upsert.c 6471d9e0e5e05547f8a00d7d686714ac08fe89526de133abcf8e1c7a35f2cb82 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c c0c7977de7ef9b8cb10f6c85f2d0557889a658f817b0455909a49179ba4c8002 F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286 @@ -1888,7 +1888,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 a47e35ee2d901baaa37e7229d190f934e1b0bd3510147cd4a2a49c4a1411416a -R 57e2c4174298e4f52a8ae7fd60045bd5 +P 64a4a91ecc5dcde3fa07d3cf038c74b9ede63d36628ecfb35203a9dfbbfe113c +R 750cd21a590114aba81487b95892f11b U drh -Z 27b1defd588019eb0041967767579913 +Z dd643da8c0e77547922105a9f9bf1ab2 diff --git a/manifest.uuid b/manifest.uuid index 1fd8f4a00d..7a1e0b0cb8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -64a4a91ecc5dcde3fa07d3cf038c74b9ede63d36628ecfb35203a9dfbbfe113c \ No newline at end of file +155142314feb007d526f8f67723636fd50dc52d1cd4d3a67dd93b105c9d5c2be \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 44cd8a3390..5e59221278 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1450,7 +1450,10 @@ static Index *indexIteratorFirst(IndexIterator *pIter, int *pIx){ static Index *indexIteratorNext(IndexIterator *pIter, int *pIx){ int i = ++pIter->i; if( pIter->eType ){ - if( i>=pIter->u.ax.nIdx ) return 0; + if( i>=pIter->u.ax.nIdx ){ + *pIx = i; + return 0; + } *pIx = pIter->u.ax.aIdx[i].ix; return pIter->u.ax.aIdx[i].p; }else{ @@ -1576,11 +1579,11 @@ void sqlite3GenerateConstraintChecks( int onError; /* Conflict resolution strategy */ int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */ int nPkField; /* Number of fields in PRIMARY KEY. 1 for ROWID tables */ - Index *pUpIdx = 0; /* Index to which to apply the upsert */ - u8 isUpdate; /* True if this is an UPDATE operation */ + Upsert *pUpsertClause = 0; /* The specific ON CONFLICT clause for pIdx */ + u8 isUpdate; /* True if this is an UPDATE operation */ u8 bAffinityDone = 0; /* True if the OP_Affinity operation has been run */ - int upsertBypass = 0; /* Address of Goto to bypass upsert subroutine */ - int upsertJump = 0; /* Address of Goto that jumps into upsert subroutine */ + int upsertIpkReturn = 0; /* Address of Goto at end of IPK uniqueness check */ + int upsertIpkDelay = 0; /* Address of Goto to bypass initial IPK check */ int ipkTop = 0; /* Top of the IPK uniqueness check */ int ipkBottom = 0; /* OP_Goto at the end of the IPK uniqueness check */ /* Variables associated with retesting uniqueness constraints after @@ -1590,7 +1593,7 @@ void sqlite3GenerateConstraintChecks( int lblRecheckOk = 0; /* Each recheck jumps to this label if it passes */ Trigger *pTrigger; /* List of DELETE triggers on the table pTab */ int nReplaceTrig = 0; /* Number of replace triggers coded */ - IndexIterator ixi; /* Index iterator */ + IndexIterator sIdxIter; /* Index iterator */ isUpdate = regOldData!=0; db = pParse->db; @@ -1788,24 +1791,64 @@ void sqlite3GenerateConstraintChecks( ** list of indexes attached to a table puts all OE_Replace indexes last ** in the list. See sqlite3CreateIndex() for where that happens. */ - + sIdxIter.eType = 0; + sIdxIter.i = 0; + sIdxIter.u.lx.pIdx = pTab->pIndex; if( pUpsert ){ if( pUpsert->pUpsertTarget==0 ){ - /* An ON CONFLICT DO NOTHING clause, without a constraint-target. - ** Make all unique constraint resolution be OE_Ignore */ - assert( pUpsert->pUpsertSet==0 ); - overrideError = OE_Ignore; - pUpsert = 0; - }else if( (pUpIdx = pUpsert->pUpsertIdx)!=0 ){ - /* If the constraint-target uniqueness check must be run first. - ** Jump to that uniqueness check now */ - upsertJump = sqlite3VdbeAddOp0(v, OP_Goto); - VdbeComment((v, "UPSERT constraint goes first")); + /* There is just on ON CONFLICT clause and it has no constraint-target */ + assert( pUpsert->pNextUpsert==0 ); + if( pUpsert->pUpsertSet==0 ){ + /* A single ON CONFLICT DO NOTHING clause, without a constraint-target. + ** Make all unique constraint resolution be OE_Ignore */ + overrideError = OE_Ignore; + pUpsert = 0; + }else{ + /* A single ON CONFLICT DO UPDATE. Make all resolutions OE_Update */ + overrideError = OE_Update; + } + }else if( pTab->pIndex!=0 ){ + /* Otherwise, we'll need to run the IndexListTerm array version of the + ** iterator to ensure that all of the ON CONFLICT conditions are + ** checked first and in order. */ + int nIdx, jj; + u64 nByte; + Upsert *pTerm; + u8 *bUsed; + for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ + assert( aRegIdx[nIdx]>0 ); + } + sIdxIter.eType = 1; + sIdxIter.u.ax.nIdx = nIdx; + nByte = (sizeof(IndexListTerm)+1)*nIdx + nIdx; + sIdxIter.u.ax.aIdx = sqlite3DbMallocZero(db, nByte); + if( sIdxIter.u.ax.aIdx==0 ) return; /* OOM */ + bUsed = (u8*)&sIdxIter.u.ax.aIdx[nIdx]; + pUpsert->pToFree = sIdxIter.u.ax.aIdx; + for(i=0, pTerm=pUpsert; pTerm; pTerm=pTerm->pNextUpsert){ + if( pTerm->pUpsertTarget==0 ) break; + if( pTerm->pUpsertIdx==0 ) continue; /* Skip ON CONFLICT for the IPK */ + jj = 0; + pIdx = pTab->pIndex; + while( ALWAYS(pIdx!=0) && pIdx!=pTerm->pUpsertIdx ){ + pIdx = pIdx->pNext; + jj++; + } + if( bUsed[jj] ) continue; /* Duplicate ON CONFLICT clause ignored */ + bUsed[jj] = 1; + sIdxIter.u.ax.aIdx[i].p = pIdx; + sIdxIter.u.ax.aIdx[i].ix = jj; + i++; + } + for(jj=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, jj++){ + if( bUsed[jj] ) continue; + sIdxIter.u.ax.aIdx[i].p = pIdx; + sIdxIter.u.ax.aIdx[i].ix = jj; + i++; + } + assert( i==nIdx ); } } - ixi.eType = 0; - ixi.i = 0; - ixi.u.lx.pIdx = pTab->pIndex; /* Determine if it is possible that triggers (either explicitly coded ** triggers or FK resolution actions) might run as a result of deletes @@ -1866,11 +1909,20 @@ void sqlite3GenerateConstraintChecks( } /* figure out whether or not upsert applies in this case */ - if( pUpsert && pUpsert->pUpsertIdx==0 ){ - if( pUpsert->pUpsertSet==0 ){ - onError = OE_Ignore; /* DO NOTHING is the same as INSERT OR IGNORE */ - }else{ - onError = OE_Update; /* DO UPDATE */ + if( pUpsert ){ + pUpsertClause = sqlite3UpsertOfIndex(pUpsert,0); + if( pUpsertClause!=0 ){ + if( pUpsertClause->pUpsertSet==0 ){ + onError = OE_Ignore; /* DO NOTHING is the same as INSERT OR IGNORE */ + }else{ + onError = OE_Update; /* DO UPDATE */ + } + } + if( pUpsertClause!=pUpsert ){ + /* The first ON CONFLICT clause has a conflict target other than + ** the IPK. We have to jump ahead to that first ON CONFLICT clause + ** and then come back here and deal with the IPK afterwards */ + upsertIpkDelay = sqlite3VdbeAddOp0(v, OP_Goto); } } @@ -1977,7 +2029,9 @@ void sqlite3GenerateConstraintChecks( } } sqlite3VdbeResolveLabel(v, addrRowidOk); - if( ipkTop ){ + if( pUpsert && pUpsertClause!=pUpsert ){ + upsertIpkReturn = sqlite3VdbeAddOp0(v, OP_Goto); + }else if( ipkTop ){ ipkBottom = sqlite3VdbeAddOp0(v, OP_Goto); sqlite3VdbeJumpHere(v, ipkTop-1); } @@ -1990,9 +2044,9 @@ void sqlite3GenerateConstraintChecks( ** This loop also handles the case of the PRIMARY KEY index for a ** WITHOUT ROWID table. */ - for(pIdx = indexIteratorFirst(&ixi, &ix); + for(pIdx = indexIteratorFirst(&sIdxIter, &ix); pIdx; - pIdx = indexIteratorNext(&ixi, &ix) + pIdx = indexIteratorNext(&sIdxIter, &ix) ){ int regIdx; /* Range of registers hold conent for pIdx */ int regR; /* Range of registers holding conflicting PK */ @@ -2001,15 +2055,14 @@ void sqlite3GenerateConstraintChecks( int addrConflictCk; /* First opcode in the conflict check logic */ if( aRegIdx[ix]==0 ) continue; /* Skip indices that do not change */ - if( pUpIdx && pUpIdx->zName==pIdx->zName ){ - addrUniqueOk = upsertJump+1; - upsertBypass = sqlite3VdbeGoto(v, 0); - VdbeComment((v, "Skip upsert subroutine")); - sqlite3VdbeJumpHere(v, upsertJump); - }else{ - addrUniqueOk = sqlite3VdbeMakeLabel(pParse); + if( pUpsert ){ + pUpsertClause = sqlite3UpsertOfIndex(pUpsert, pIdx); + if( upsertIpkDelay && pUpsertClause==pUpsert ){ + sqlite3VdbeJumpHere(v, upsertIpkDelay); + } } - if( bAffinityDone==0 && (pUpIdx==0 || pUpIdx->zName==pIdx->zName) ){ + addrUniqueOk = sqlite3VdbeMakeLabel(pParse); + if( bAffinityDone==0 ){ sqlite3TableAffinity(v, pTab, regNewData+1); bAffinityDone = 1; } @@ -2080,8 +2133,8 @@ void sqlite3GenerateConstraintChecks( } /* Figure out if the upsert clause applies to this index */ - if( pUpIdx && pUpIdx->zName==pIdx->zName ){ - if( pUpsert->pUpsertSet==0 ){ + if( pUpsertClause ){ + if( pUpsertClause->pUpsertSet==0 ){ onError = OE_Ignore; /* DO NOTHING is the same as INSERT OR IGNORE */ }else{ onError = OE_Update; /* DO UPDATE */ @@ -2273,13 +2326,12 @@ void sqlite3GenerateConstraintChecks( break; } } - if( pUpIdx && pUpIdx->zName==pIdx->zName ){ - sqlite3VdbeGoto(v, upsertJump+1); - sqlite3VdbeJumpHere(v, upsertBypass); - }else{ - sqlite3VdbeResolveLabel(v, addrUniqueOk); - } + sqlite3VdbeResolveLabel(v, addrUniqueOk); if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField); + if( pUpsertClause && sqlite3UpsertNextIsIPK(pUpsertClause) ){ + sqlite3VdbeGoto(v, upsertIpkDelay+1); + sqlite3VdbeJumpHere(v, upsertIpkReturn); + } } /* If the IPK constraint is a REPLACE, run it last */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 83993f08c5..403f31326d 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4841,10 +4841,14 @@ const char *sqlite3JournalModename(int); Upsert *sqlite3UpsertDup(sqlite3*,Upsert*); int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*); void sqlite3UpsertDoUpdate(Parse*,Upsert*,Table*,Index*,int); + Upsert *sqlite3UpsertOfIndex(Upsert*,Index*); + int sqlite3UpsertNextIsIPK(Upsert*); #else #define sqlite3UpsertNew(u,v,w,x,y,z) ((Upsert*)0) #define sqlite3UpsertDelete(x,y) #define sqlite3UpsertDup(x,y) ((Upsert*)0) +#define sqlite3UpsertOfIndex(x,y) ((Upsert*)0) +#define sqlite3UpsertNextIsIPK(x) 0 #endif diff --git a/src/upsert.c b/src/upsert.c index 6b9bff6851..0a9b67dbdb 100644 --- a/src/upsert.c +++ b/src/upsert.c @@ -208,6 +208,38 @@ int sqlite3UpsertAnalyzeTarget( return SQLITE_OK; } +/* +** Return true if pUpsert is the last ON CONFLICT clause with a +** conflict target, or if pUpsert is followed by another ON CONFLICT +** clause that targets the INTEGER PRIMARY KEY. +*/ +int sqlite3UpsertNextIsIPK(Upsert *pUpsert){ + Upsert *pNext; + if( pUpsert==0 ) return 0; + pNext = pUpsert->pNextUpsert; + if( pNext==0 ) return 1; + if( pNext->pUpsertTarget==0 ) return 1; + if( pNext->pUpsertIdx==0 ) return 1; + return 0; +} + +/* +** Given the list of ON CONFLICT clauses described by pUpsert, and +** a particular index pIdx, return a pointer to the particular ON CONFLICT +** clause that applies to the index. Or, if the index is not subject to +** any ON CONFLICT clause, return NULL. +*/ +Upsert *sqlite3UpsertOfIndex(Upsert *pUpsert, Index *pIdx){ + while( + pUpsert + && pUpsert->pUpsertTarget!=0 + && pUpsert->pUpsertIdx!=pIdx + ){ + pUpsert = pUpsert->pNextUpsert; + } + return pUpsert; +} + /* ** Generate bytecode that does an UPDATE as part of an upsert. ** @@ -234,14 +266,7 @@ void sqlite3UpsertDoUpdate( assert( v!=0 ); assert( pUpsert!=0 ); iDataCur = pUpsert->iDataCur; - while( - pUpsert->pUpsertTarget!=0 - && (pUpsert->pUpsertIdx==0 ? pIdx!=0 : - pUpsert->pUpsertIdx->zName!=pIdx->zName) - ){ - assert( pUpsert->pNextUpsert!=0 ); - pUpsert = pUpsert->pNextUpsert; - } + pUpsert = sqlite3UpsertOfIndex(pTop, pIdx); if( pUpsert->addrGenericUpdate>0 ){ sqlite3VdbeAddOp2(v, OP_Goto, 0, pUpsert->addrGenericUpdate); return; From 69871baa1589e6dc486fbbf82a6e90b1d98419dd Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 11 Dec 2020 14:22:44 +0000 Subject: [PATCH 048/257] Fix the expert extension so that it handles generated columns correctly. FossilOrigin-Name: c2ae7ba6f8f4b10bd734051a0cfa8ed9675bd58c82ede4e9eadfd7cbcc03b82d --- ext/expert/expert1.test | 26 +++++++++++++++++++++++++- ext/expert/sqlite3expert.c | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/ext/expert/expert1.test b/ext/expert/expert1.test index f49f1f5e5c..0e6fc82604 100644 --- a/ext/expert/expert1.test +++ b/ext/expert/expert1.test @@ -28,6 +28,7 @@ if {[info commands sqlite3_expert_new]==""} { return } + set CLI [test_binary_name sqlite3] set CMD [test_binary_name sqlite3_expert] @@ -367,6 +368,29 @@ do_setup_rec_test $tn.17.5 { SEARCH TABLE example USING INDEX example_idx_0000cb3f (B=? AND A>?) } +do_setup_rec_test $tn.18.0 { + CREATE TABLE SomeObject ( + a INTEGER PRIMARY KEY, + x TEXT GENERATED ALWAYS AS(HEX(a)) VIRTUAL + ); +} { + SELECT x FROM SomeObject; +} { + (no new indexes) + SCAN TABLE SomeObject +} +do_setup_rec_test $tn.18.1 { + CREATE TABLE SomeObject ( + a INTEGER PRIMARY KEY, + x TEXT GENERATED ALWAYS AS(HEX(a)) VIRTUAL + ); +} { + SELECT * FROM SomeObject WHERE x=?; +} { + CREATE INDEX SomeObject_idx_00000078 ON SomeObject(x); + SEARCH TABLE SomeObject USING COVERING INDEX SomeObject_idx_00000078 (x=?) +} + } proc do_candidates_test {tn sql res} { @@ -430,5 +454,5 @@ do_execsql_test 5.3 { t2 t2_idx_0001295b {100 20 5} } - finish_test + diff --git a/ext/expert/sqlite3expert.c b/ext/expert/sqlite3expert.c index 5c13423204..863c6a3409 100644 --- a/ext/expert/sqlite3expert.c +++ b/ext/expert/sqlite3expert.c @@ -687,7 +687,7 @@ static int idxGetTableInfo( char *pCsr = 0; int nPk = 0; - rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_info=%Q", zTab); + rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_xinfo=%Q", zTab); while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){ const char *zCol = (const char*)sqlite3_column_text(p1, 1); nByte += 1 + STRLEN(zCol); diff --git a/manifest b/manifest index a3131d8cd4..ff78950e97 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\sredundant\sbranch\sadded\sby\s[56a54258560]. -D 2020-12-10T19:54:13.413 +C Fix\sthe\sexpert\sextension\sso\sthat\sit\shandles\sgenerated\scolumns\scorrectly. +D 2020-12-11T14:22:44.596 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -50,8 +50,8 @@ F ext/async/sqlite3async.c 6f247666b495c477628dd19364d279c78ea48cd90c72d9f9b98ad F ext/async/sqlite3async.h 46b47c79357b97ad85d20d2795942c0020dc20c532114a49808287f04aa5309a F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3 F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4 -F ext/expert/expert1.test dba6e752cc701621771f925f3872b183fa688f7b4a9f4822631fc02bdbffc45a -F ext/expert/sqlite3expert.c 216e250acc54b8aaa9ff5c1e1b2256788abc3994dd1d757626102718122e6a91 +F ext/expert/expert1.test 63d778d964e55ef2d1a723043d91c59e7dc6ef1649d91c78c0bef00f9c6f1427 +F ext/expert/sqlite3expert.c de51b187c629a4c4264d5de0b77862641e11426f7a963a92abf2d4077085fc8c F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72 F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e @@ -1889,7 +1889,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 56a54258560fab715b83967634b2bd4c04be43cded112b46e85da9f99ee02f7c -R c82b011ba062cfde3acc0789a727fd1f +P b4d6f6d728738710249ad74236c31a1872fdff7dadabd4c4a67d05826eb5df9e +R fb55f5147e16371ec8e31fd2331cfcf7 U dan -Z 9746b01cc9973ffd448104549b3bbdff +Z 166ee843647c304936c75f8093a2d2ca diff --git a/manifest.uuid b/manifest.uuid index 8a864002ee..3fc850b622 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b4d6f6d728738710249ad74236c31a1872fdff7dadabd4c4a67d05826eb5df9e \ No newline at end of file +c2ae7ba6f8f4b10bd734051a0cfa8ed9675bd58c82ede4e9eadfd7cbcc03b82d \ No newline at end of file From d0a0538229a2a263163d320ac7ba36f3e133452c Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 11 Dec 2020 14:34:58 +0000 Subject: [PATCH 049/257] Fix the configure script on the autoconf distribution so that the --disable-threadsafe option works. See [https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=244459|FreeBSD bug 244459]. FossilOrigin-Name: e64ff2cce3c03ba27c3bf410948ece1424113e727870015eb3806b75d0d21f94 --- autoconf/configure.ac | 4 +++- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/autoconf/configure.ac b/autoconf/configure.ac index 167626d59e..a86bd2ca39 100644 --- a/autoconf/configure.ac +++ b/autoconf/configure.ac @@ -87,7 +87,9 @@ AC_SUBST(READLINE_LIBS) AC_ARG_ENABLE(threadsafe, [AS_HELP_STRING( [--enable-threadsafe], [build a thread-safe library [default=yes]])], [], [enable_threadsafe=yes]) -if test x"$enable_threadsafe" != "xno"; then +if test x"$enable_threadsafe" == "xno"; then + BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_THREADSAFE=0" +else BUILD_CFLAGS="$BUILD_CFLAGS -D_REENTRANT=1 -DSQLITE_THREADSAFE=1" AC_SEARCH_LIBS(pthread_create, pthread) AC_SEARCH_LIBS(pthread_mutexattr_init, pthread) diff --git a/manifest b/manifest index ff78950e97..f303725351 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sexpert\sextension\sso\sthat\sit\shandles\sgenerated\scolumns\scorrectly. -D 2020-12-11T14:22:44.596 +C Fix\sthe\sconfigure\sscript\son\sthe\sautoconf\sdistribution\sso\sthat\sthe\n--disable-threadsafe\soption\sworks.\s\sSee\n[https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=244459|FreeBSD\sbug\s244459]. +D 2020-12-11T14:34:58.941 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -18,7 +18,7 @@ F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a F autoconf/Makefile.msc e0f1dafc48d000fd6ddfdb01815271528db55cbc7299ca888df5b93367f0d5a4 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1 -F autoconf/configure.ac 3cd933b959fe514eebd1ca1717dfddbf2c9b825b6bc2c5f744deaf5d63af9288 +F autoconf/configure.ac 55be6fc04a5b030b367fe317b72dc8c0eafc4713991fe6182cf647b02fb782cb F autoconf/tea/Makefile.in b438a7020446c8a8156e8d97c8914a04833da6fd F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873 F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43 @@ -1889,7 +1889,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 b4d6f6d728738710249ad74236c31a1872fdff7dadabd4c4a67d05826eb5df9e -R fb55f5147e16371ec8e31fd2331cfcf7 -U dan -Z 166ee843647c304936c75f8093a2d2ca +P c2ae7ba6f8f4b10bd734051a0cfa8ed9675bd58c82ede4e9eadfd7cbcc03b82d +R 081acf382e9d875924b95569479a3f66 +U drh +Z 18dbb49cec21f6cfe4518d963fb09370 diff --git a/manifest.uuid b/manifest.uuid index 3fc850b622..84bb652ffb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c2ae7ba6f8f4b10bd734051a0cfa8ed9675bd58c82ede4e9eadfd7cbcc03b82d \ No newline at end of file +e64ff2cce3c03ba27c3bf410948ece1424113e727870015eb3806b75d0d21f94 \ No newline at end of file From 771087833330bbb5f4081f61e67fb22da608ff75 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 11 Dec 2020 16:03:19 +0000 Subject: [PATCH 050/257] Add an "#ifndef SQLITE_AMALGAMATION" block around the typedef for u64 in shathree.c. FossilOrigin-Name: b411f29e1a6415f4a241777c45591b8389e746cd8b40d9b225e073bcb0a3bdbf --- ext/misc/shathree.c | 3 +++ manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/ext/misc/shathree.c b/ext/misc/shathree.c index 56eba564ce..75065e97c1 100644 --- a/ext/misc/shathree.c +++ b/ext/misc/shathree.c @@ -31,7 +31,10 @@ SQLITE_EXTENSION_INIT1 #include #include #include + +#ifndef SQLITE_AMALGAMATION typedef sqlite3_uint64 u64; +#endif /* SQLITE_AMALGAMATION */ /****************************************************************************** ** The Hash Engine diff --git a/manifest b/manifest index f303725351..274f153437 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sconfigure\sscript\son\sthe\sautoconf\sdistribution\sso\sthat\sthe\n--disable-threadsafe\soption\sworks.\s\sSee\n[https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=244459|FreeBSD\sbug\s244459]. -D 2020-12-11T14:34:58.941 +C Add\san\s"#ifndef\sSQLITE_AMALGAMATION"\sblock\saround\sthe\stypedef\sfor\su64\sin\sshathree.c. +D 2020-12-11T16:03:19.055 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -321,7 +321,7 @@ F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d385 F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946 F ext/misc/series.c c6bd5d249e5199a1b55aeee4d0e6576ff3a68702fc475dbd64503a32903516c7 F ext/misc/sha1.c c8f2253c8792ffab9517695ea7d88c079f0395a5505eefef5c8198fe184ed5ac -F ext/misc/shathree.c 135b7c145db4a09b1650c3e7aff9cb538763a9a361e834c015dd1aaf8d5c9a00 +F ext/misc/shathree.c 5398f945a30b4792c757ab16b03cf54ce3b542fe933bbd43e2d6d40c5443b12e F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c 94df9bbfa514a563c1484f684a2df3d128a2f7209a84ca3ca100c68a0163e29f F ext/misc/sqlar.c 0ace5d3c10fe736dc584bf1159a36b8e2e60fab309d310cd8a0eecd9036621b6 @@ -1889,7 +1889,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 c2ae7ba6f8f4b10bd734051a0cfa8ed9675bd58c82ede4e9eadfd7cbcc03b82d -R 081acf382e9d875924b95569479a3f66 -U drh -Z 18dbb49cec21f6cfe4518d963fb09370 +P e64ff2cce3c03ba27c3bf410948ece1424113e727870015eb3806b75d0d21f94 +R 718f3d689418739102dd17603d779863 +U dan +Z ab9d6df0eec0ce68bf9b160e6deb9056 diff --git a/manifest.uuid b/manifest.uuid index 84bb652ffb..b066f6a7f4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e64ff2cce3c03ba27c3bf410948ece1424113e727870015eb3806b75d0d21f94 \ No newline at end of file +b411f29e1a6415f4a241777c45591b8389e746cd8b40d9b225e073bcb0a3bdbf \ No newline at end of file From ed4c54699df2c2a0494e96dacaf21d279ca0adf2 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 11 Dec 2020 16:49:51 +0000 Subject: [PATCH 051/257] Bug fixes so that legacy tests pass. New tests for new functionality have not yet been added. FossilOrigin-Name: aa76790e58cea9a2b707f5912fd66c76545e7417442553fc13c87f773a2fe1dd --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/insert.c | 16 ++++++++++++---- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 5bb77216d5..09d7eda057 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Logic\sis\sin\splace\sto\shandle\smultiple\sON\sCONFLICT\sclauses,\sbut\sit\sdoes\snot\swork.\nAny\suse\sof\sON\sCONFLICT\swill\slikely\slead\sto\smemory\sfaults.\s\sThis\sis\san\nincremental\scheck-in\sto\ssave\smy\splace. -D 2020-12-11T01:17:06.489 +C Bug\sfixes\sso\sthat\slegacy\stests\spass.\s\sNew\stests\sfor\snew\sfunctionality\shave\nnot\syet\sbeen\sadded. +D 2020-12-11T16:49:51.732 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -501,7 +501,7 @@ 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 c8d4bc0dcde4d9d42a1761e919a6a99668000e16840814f8bb643e161894b27f +F src/insert.c 3f90efe0afbbf4a64f7fe37cb061527a86445f0a1b85a78038ae406b41fbf806 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 F src/main.c 97e9f137354bc1f76dc9bb60a0a24f8c45cf73b33e80d3ee4c64155336fb820d @@ -1888,7 +1888,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 64a4a91ecc5dcde3fa07d3cf038c74b9ede63d36628ecfb35203a9dfbbfe113c -R 750cd21a590114aba81487b95892f11b +P 155142314feb007d526f8f67723636fd50dc52d1cd4d3a67dd93b105c9d5c2be +R 63e742ce65925663b08e2a758de8f6e2 U drh -Z dd643da8c0e77547922105a9f9bf1ab2 +Z 0aa452b6f5f81d99a0b8c06fa6b89e8a diff --git a/manifest.uuid b/manifest.uuid index 7a1e0b0cb8..13c5d7b5a1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -155142314feb007d526f8f67723636fd50dc52d1cd4d3a67dd93b105c9d5c2be \ No newline at end of file +aa76790e58cea9a2b707f5912fd66c76545e7417442553fc13c87f773a2fe1dd \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 5e59221278..41503224ec 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1441,9 +1441,14 @@ struct IndexListTerm { /* Return the first index on the list */ static Index *indexIteratorFirst(IndexIterator *pIter, int *pIx){ - int i = pIter->i; - *pIx = i; - return pIter->eType ? pIter->u.ax.aIdx[i].p : pIter->u.lx.pIdx; + assert( pIter->i==0 ); + if( pIter->eType ){ + *pIx = pIter->u.ax.aIdx[0].ix; + return pIter->u.ax.aIdx[0].p; + }else{ + *pIx = 0; + return pIter->u.lx.pIdx; + } } /* Return the next index from the list. Return NULL when out of indexes */ @@ -2328,7 +2333,10 @@ void sqlite3GenerateConstraintChecks( } sqlite3VdbeResolveLabel(v, addrUniqueOk); if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField); - if( pUpsertClause && sqlite3UpsertNextIsIPK(pUpsertClause) ){ + if( pUpsertClause + && upsertIpkReturn + && sqlite3UpsertNextIsIPK(pUpsertClause) + ){ sqlite3VdbeGoto(v, upsertIpkDelay+1); sqlite3VdbeJumpHere(v, upsertIpkReturn); } From d3e21a1098ea6b5002417514ba2c984c4d1871ff Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 11 Dec 2020 17:11:56 +0000 Subject: [PATCH 052/257] Small performance tweaks. FossilOrigin-Name: 5321d60c575ef8f888d1b315df02cf9ed96a3ffc61babbc1429aa73b2a61a190 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/insert.c | 17 ++++++++--------- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 09d7eda057..953046263d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Bug\sfixes\sso\sthat\slegacy\stests\spass.\s\sNew\stests\sfor\snew\sfunctionality\shave\nnot\syet\sbeen\sadded. -D 2020-12-11T16:49:51.732 +C Small\sperformance\stweaks. +D 2020-12-11T17:11:56.302 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -501,7 +501,7 @@ 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 3f90efe0afbbf4a64f7fe37cb061527a86445f0a1b85a78038ae406b41fbf806 +F src/insert.c 2b9b6a9cae187bf6c1d4220726511459a23d6089dd4025c4cb00657195c81ba8 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 F src/main.c 97e9f137354bc1f76dc9bb60a0a24f8c45cf73b33e80d3ee4c64155336fb820d @@ -1888,7 +1888,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 155142314feb007d526f8f67723636fd50dc52d1cd4d3a67dd93b105c9d5c2be -R 63e742ce65925663b08e2a758de8f6e2 +P aa76790e58cea9a2b707f5912fd66c76545e7417442553fc13c87f773a2fe1dd +R facb33fc25631aa36550b455921f2f42 U drh -Z 0aa452b6f5f81d99a0b8c06fa6b89e8a +Z 1d9f47d8176ed5a99b3ef4efb5d1d2d4 diff --git a/manifest.uuid b/manifest.uuid index 13c5d7b5a1..529b505cd2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aa76790e58cea9a2b707f5912fd66c76545e7417442553fc13c87f773a2fe1dd \ No newline at end of file +5321d60c575ef8f888d1b315df02cf9ed96a3ffc61babbc1429aa73b2a61a190 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 41503224ec..8306c602bc 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1453,8 +1453,8 @@ static Index *indexIteratorFirst(IndexIterator *pIter, int *pIx){ /* Return the next index from the list. Return NULL when out of indexes */ static Index *indexIteratorNext(IndexIterator *pIter, int *pIx){ - int i = ++pIter->i; if( pIter->eType ){ + int i = ++pIter->i; if( i>=pIter->u.ax.nIdx ){ *pIx = i; return 0; @@ -1462,7 +1462,7 @@ static Index *indexIteratorNext(IndexIterator *pIter, int *pIx){ *pIx = pIter->u.ax.aIdx[i].ix; return pIter->u.ax.aIdx[i].p; }else{ - *pIx = i; + ++(*pIx); pIter->u.lx.pIdx = pIter->u.lx.pIdx->pNext; return pIter->u.lx.pIdx; } @@ -1798,6 +1798,7 @@ void sqlite3GenerateConstraintChecks( */ sIdxIter.eType = 0; sIdxIter.i = 0; + sIdxIter.u.ax.aIdx = 0; /* Silence harmless compiler warning */ sIdxIter.u.lx.pIdx = pTab->pIndex; if( pUpsert ){ if( pUpsert->pUpsertTarget==0 ){ @@ -2120,7 +2121,7 @@ void sqlite3GenerateConstraintChecks( ** of a WITHOUT ROWID table and there has been no change the ** primary key, then no collision is possible. The collision detection ** logic below can all be skipped. */ - if( isUpdate && pPk && pPk->zName==pIdx->zName && pkChng==0 ){ + if( isUpdate && pPk==pIdx && pkChng==0 ){ sqlite3VdbeResolveLabel(v, addrUniqueOk); continue; } @@ -2158,7 +2159,7 @@ void sqlite3GenerateConstraintChecks( ** is invoked. */ #ifndef SQLITE_ENABLE_PREUPDATE_HOOK if( (ix==0 && pIdx->pNext==0) /* Condition 3 */ - && pPk && pPk->zName==pIdx->zName /* Condition 2 */ + && pPk==pIdx /* Condition 2 */ && onError==OE_Replace /* Condition 1 */ && ( 0==(db->flags&SQLITE_RecTriggers) || /* Condition 4 */ 0==sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0)) @@ -2177,8 +2178,7 @@ void sqlite3GenerateConstraintChecks( regIdx, pIdx->nKeyCol); VdbeCoverage(v); /* Generate code to handle collisions */ - regR = (pPk && pIdx->zName==pPk->zName) ? - regIdx : sqlite3GetTempRange(pParse, nPkField); + regR = pIdx==pPk ? regIdx : sqlite3GetTempRange(pParse, nPkField); if( isUpdate || onError==OE_Replace ){ if( HasRowid(pTab) ){ sqlite3VdbeAddOp2(v, OP_IdxRowid, iThisCur, regR); @@ -2193,7 +2193,7 @@ void sqlite3GenerateConstraintChecks( int x; /* Extract the PRIMARY KEY from the end of the index entry and ** store it in registers regR..regR+nPk-1 */ - if( pPk && pIdx->zName!=pPk->zName ){ + if( pIdx!=pPk ){ for(i=0; inKeyCol; i++){ assert( pPk->aiColumn[i]>=0 ); x = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[i]); @@ -2274,8 +2274,7 @@ void sqlite3GenerateConstraintChecks( } sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, regR, nPkField, 0, OE_Replace, - (pPk && pIdx->zName==pPk->zName ? ONEPASS_SINGLE : ONEPASS_OFF), - iThisCur); + (pIdx==pPk ? ONEPASS_SINGLE : ONEPASS_OFF), iThisCur); if( pTrigger && isUpdate ){ sqlite3VdbeAddOp1(v, OP_CursorUnlock, iDataCur); } From 855aed19e224ebb5328b9fbffbf69cb8161630e8 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 11 Dec 2020 19:01:24 +0000 Subject: [PATCH 053/257] Fix an assert() broken by recent changes to vacuum. FossilOrigin-Name: dd058da85ca54ae70e26cb0bdc75ff42998d4a8b29a5e2dcac44ee0e45776a85 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 2 +- test/vacuum6.test | 11 +++++++++++ 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 274f153437..c5e7ec8dc9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\san\s"#ifndef\sSQLITE_AMALGAMATION"\sblock\saround\sthe\stypedef\sfor\su64\sin\sshathree.c. -D 2020-12-11T16:03:19.055 +C Fix\san\sassert()\sbroken\sby\srecent\schanges\sto\svacuum. +D 2020-12-11T19:01:24.454 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -481,7 +481,7 @@ F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 91da5fd5d99bc7e7422242419561bd9518e0229c243c48799303be7112ef5601 +F src/btree.c ea5e8bfe904d4818d97cae4eee229d7ce21a0a090ef5402ebac68840dc16713f F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 F src/build.c f6449d4e85e998e14d3f537e8ea898dca2fcb83c277db3e60945af9b9177db81 @@ -1654,7 +1654,7 @@ F test/vacuum2.test 9fd45ce6ce29f5614c249e03938d3567c06a9e772d4f155949f8eafe2d8a F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d F test/vacuum4.test 7ea76b769fffeb41f925303b04cbcf5a5bbeabe55e4c60ae754ff24eeeb7c010 F test/vacuum5.test 263b144d537e92ad8e9ca8a73cc6e1583f41cfd0dda9432b87f7806174a2f48c -F test/vacuum6.test e67488fa1341cc8034ba261807d429a8c06f4593ec1bb1651d8497d2d5df92c9 +F test/vacuum6.test d3173a54edc81d13d99e4cf4972232b3cbb52f1d56ed48c3a939ef4e751c1ee8 F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2 F test/varint.test bbce22cda8fc4d135bcc2b589574be8410614e62 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 @@ -1889,7 +1889,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 e64ff2cce3c03ba27c3bf410948ece1424113e727870015eb3806b75d0d21f94 -R 718f3d689418739102dd17603d779863 +P b411f29e1a6415f4a241777c45591b8389e746cd8b40d9b225e073bcb0a3bdbf +R 5f1281ebbbf31df2eed9d78849a16b43 U dan -Z ab9d6df0eec0ce68bf9b160e6deb9056 +Z 63f7dff9f8374ff08b8e0cc7e378c500 diff --git a/manifest.uuid b/manifest.uuid index b066f6a7f4..e819bc2a41 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b411f29e1a6415f4a241777c45591b8389e746cd8b40d9b225e073bcb0a3bdbf \ No newline at end of file +dd058da85ca54ae70e26cb0bdc75ff42998d4a8b29a5e2dcac44ee0e45776a85 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 3ed365c5f7..1a151fe4ef 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8697,7 +8697,7 @@ int sqlite3BtreeInsert( ** keys with no associated data. If the cursor was opened expecting an ** intkey table, the caller should be inserting integer keys with a ** blob of associated data. */ - assert( (pX->pKey==0)==(pCur->pKeyInfo==0) || (flags & BTREE_PREFORMAT) ); + assert( (flags & BTREE_PREFORMAT) || (pX->pKey==0)==(pCur->pKeyInfo==0) ); /* Save the positions of any other cursors open on this table. ** diff --git a/test/vacuum6.test b/test/vacuum6.test index 51070fd0c7..e9a1542f25 100644 --- a/test/vacuum6.test +++ b/test/vacuum6.test @@ -29,10 +29,21 @@ do_execsql_test 1.0 { CREATE TABLE t1(x INTEGER PRIMARY KEY, y); INSERT INTO t1 VALUES(1, 1); } {} + do_execsql_test 1.1 { VACUUM } +reset_db +do_execsql_test 1.2 { + CREATE TABLE t1(x,b); + CREATE INDEX x1 ON t1(x); + CREATE INDEX x2 ON t1(x); + CREATE INDEX x3 ON t1(x); + INSERT INTO t1 SELECT 2,''; + VACUUM; +} + #------------------------------------------------------------------------- # reset_db From 58b18a47df0ec28487bf7be3bf517b7f0f801686 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 11 Dec 2020 19:36:19 +0000 Subject: [PATCH 054/257] Begin adding test cases. Fix one bug found so far. More are pending. FossilOrigin-Name: aadd67ddf2a191629b5356395f75e4556aac904a6e2f6b83742fa4f26e4253a4 --- manifest | 13 +-- manifest.uuid | 2 +- src/insert.c | 1 + test/upsert5.test | 242 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 251 insertions(+), 7 deletions(-) create mode 100644 test/upsert5.test diff --git a/manifest b/manifest index 953046263d..728e086000 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\sperformance\stweaks. -D 2020-12-11T17:11:56.302 +C Begin\sadding\stest\scases.\s\sFix\sone\sbug\sfound\sso\sfar.\s\sMore\sare\spending. +D 2020-12-11T19:36:19.206 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -501,7 +501,7 @@ 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 2b9b6a9cae187bf6c1d4220726511459a23d6089dd4025c4cb00657195c81ba8 +F src/insert.c 7bb29b8acdd49917fe12cc14e164b9c49fc98f5f2725e5311a03b30349ca3880 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 F src/main.c 97e9f137354bc1f76dc9bb60a0a24f8c45cf73b33e80d3ee4c64155336fb820d @@ -1643,6 +1643,7 @@ F test/upsert1.test 88f9e258c6a0eeeb85937b08831e8daad440ba41f125af48439e9d33f266 F test/upsert2.test 9c3cdbb1a890227f6504ce4b0e3de68f4cdfa16bb21d8641208a9239896c5a09 F test/upsert3.test 88d7d590a1948a9cb6eac1b54b0642f67a9f35a1fc0f19b200e97d5d39e3179c F test/upsert4.test 25d2a1da92f149331ae0c51ca6e3eee78189577585eab92de149900d62994fa5 +F test/upsert5.test 82acbe52e9a7d74b9eeb93dc219558f44dccd07ef5e07e74fec9eca7173e4bfe F test/upsertfault.test f21ca47740841fdb4d61acfa7b17646d773e67724fe8c185b71c018db8a94b35 F test/uri.test 3481026f00ade6dfe8adb7acb6e1e47b04369568 F test/uri2.test 9d3ba7a53ee167572d53a298ee4a5d38ec4a8fb7 @@ -1888,7 +1889,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 aa76790e58cea9a2b707f5912fd66c76545e7417442553fc13c87f773a2fe1dd -R facb33fc25631aa36550b455921f2f42 +P 5321d60c575ef8f888d1b315df02cf9ed96a3ffc61babbc1429aa73b2a61a190 +R 8ec7743a66623a70c1f2fd83cc9cbf09 U drh -Z 1d9f47d8176ed5a99b3ef4efb5d1d2d4 +Z d9c45c2e1447fdcad46c943d9137f6df diff --git a/manifest.uuid b/manifest.uuid index 529b505cd2..87fe70a5b0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5321d60c575ef8f888d1b315df02cf9ed96a3ffc61babbc1429aa73b2a61a190 \ No newline at end of file +aadd67ddf2a191629b5356395f75e4556aac904a6e2f6b83742fa4f26e4253a4 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 8306c602bc..4fa337a2f2 100644 --- a/src/insert.c +++ b/src/insert.c @@ -2338,6 +2338,7 @@ void sqlite3GenerateConstraintChecks( ){ sqlite3VdbeGoto(v, upsertIpkDelay+1); sqlite3VdbeJumpHere(v, upsertIpkReturn); + upsertIpkReturn = 0; } } diff --git a/test/upsert5.test b/test/upsert5.test new file mode 100644 index 0000000000..e3840a9b32 --- /dev/null +++ b/test/upsert5.test @@ -0,0 +1,242 @@ +# 2020-12-11 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# Test cases for generalized UPSERT + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix upsert5 + +foreach {tn sql} { + 1 { CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c UNIQUE, d UNIQUE, e UNIQUE) } + 2 { CREATE TABLE t1(a INT PRIMARY KEY, b, c UNIQUE, d UNIQUE, e UNIQUE) } + 3 { CREATE TABLE t1(a INT PRIMARY KEY, b, c UNIQUE, d UNIQUE, e UNIQUE) WITHOUT ROWID} + 4 { CREATE TABLE t1(e UNIQUE, d UNIQUE, c UNIQUE, a INTEGER PRIMARY KEY, b) } + 5 { CREATE TABLE t1(e UNIQUE, d UNIQUE, c UNIQUE, a INT PRIMARY KEY, b) } + 6 { CREATE TABLE t1(e UNIQUE, d UNIQUE, c UNIQUE, a INT PRIMARY KEY, b) WITHOUT ROWID} +} { + reset_db + execsql $sql + + do_execsql_test 1.$tn.100 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,3,4,5) + ON CONFLICT(a) DO UPDATE SET b='a' + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT(e) DO UPDATE SET b='e'; + SELECT a,b,c,d,e FROM t1; + } {1 a 3 4 5} + do_execsql_test 1.$tn.101 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,3,4,5) + ON CONFLICT(a) DO UPDATE SET b='a' + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT(e) DO UPDATE SET b='e'; + SELECT a,b,c,d,e FROM t1; + } {1 c 3 4 5} + do_execsql_test 1.$tn.102 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,4,5) + ON CONFLICT(a) DO UPDATE SET b='a' + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT(e) DO UPDATE SET b='e'; + SELECT a,b,c,d,e FROM t1; + } {1 d 3 4 5} + do_execsql_test 1.$tn.103 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,94,5) + ON CONFLICT(a) DO UPDATE SET b='a' + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT(e) DO UPDATE SET b='e'; + SELECT a,b,c,d,e FROM t1; + } {1 e 3 4 5} + do_execsql_test 1.$tn.200 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95) + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(a) DO UPDATE SET b='a' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT(e) DO UPDATE SET b='e'; + SELECT a,b,c,d,e FROM t1; + } {1 a 3 4 5} + do_execsql_test 1.$tn.201 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,3,94,95) + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(a) DO UPDATE SET b='a' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT(e) DO UPDATE SET b='e'; + SELECT a,b,c,d,e FROM t1; + } {1 c 3 4 5} + do_execsql_test 1.$tn.202 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,3,4,5) + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(a) DO UPDATE SET b='a' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT(e) DO UPDATE SET b='e'; + SELECT a,b,c,d,e FROM t1; + } {1 c 3 4 5} + do_execsql_test 1.$tn.203 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,5) + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(a) DO UPDATE SET b='a' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT(e) DO UPDATE SET b='e'; + SELECT a,b,c,d,e FROM t1; + } {1 a 3 4 5} + do_execsql_test 1.$tn.204 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,4,95) + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(a) DO UPDATE SET b='a' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT(e) DO UPDATE SET b='e'; + SELECT a,b,c,d,e FROM t1; + } {1 a 3 4 5} + do_execsql_test 1.$tn.210 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95) + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT(a) DO UPDATE SET b='a' + ON CONFLICT(e) DO UPDATE SET b='e'; + SELECT a,b,c,d,e FROM t1; + } {1 a 3 4 5} + do_execsql_test 1.$tn.211 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,4,95) + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT(a) DO UPDATE SET b='a' + ON CONFLICT(e) DO UPDATE SET b='e'; + SELECT a,b,c,d,e FROM t1; + } {1 d 3 4 5} + do_execsql_test 1.$tn.212 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,5) + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT(a) DO UPDATE SET b='a' + ON CONFLICT(e) DO UPDATE SET b='e'; + SELECT a,b,c,d,e FROM t1; + } {1 a 3 4 5} + do_execsql_test 1.$tn.213 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,94,5) + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT(a) DO UPDATE SET b='a' + ON CONFLICT(e) DO UPDATE SET b='e'; + SELECT a,b,c,d,e FROM t1; + } {1 e 3 4 5} + do_execsql_test 1.$tn.214 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,94,5) + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT(e) DO UPDATE SET b='e' + ON CONFLICT(a) DO UPDATE SET b='a'; + SELECT a,b,c,d,e FROM t1; + } {1 e 3 4 5} + do_execsql_test 1.$tn.215 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,5) + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT(e) DO UPDATE SET b='e' + ON CONFLICT(a) DO UPDATE SET b='a'; + SELECT a,b,c,d,e FROM t1; + } {1 e 3 4 5} + do_execsql_test 1.$tn.216 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95) + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT(e) DO UPDATE SET b='e' + ON CONFLICT(a) DO UPDATE SET b='a'; + SELECT a,b,c,d,e FROM t1; + } {1 a 3 4 5} + + do_execsql_test 1.$tn.300 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95) + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT(a) DO UPDATE SET b='a1' + ON CONFLICT(a) DO UPDATE SET b='a2' + ON CONFLICT(a) DO UPDATE SET b='a3' + ON CONFLICT(a) DO UPDATE SET b='a4' + ON CONFLICT(a) DO UPDATE SET b='a5' + ON CONFLICT(e) DO UPDATE SET b='e'; + SELECT a,b,c,d,e FROM t1; + } {1 a1 3 4 5} + do_execsql_test 1.$tn.301 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,94,5) + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT(a) DO UPDATE SET b='a1' + ON CONFLICT(a) DO UPDATE SET b='a2' + ON CONFLICT(a) DO UPDATE SET b='a3' + ON CONFLICT(a) DO UPDATE SET b='a4' + ON CONFLICT(a) DO UPDATE SET b='a5' + ON CONFLICT(e) DO UPDATE SET b='e'; + SELECT a,b,c,d,e FROM t1; + } {1 e 3 4 5} + +if {0} { + do_execsql_test 1.$tn.400 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95) + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT DO UPDATE set b='x'; + SELECT a,b,c,d,e FROM t1; + } {1 x 3 4 5} + do_execsql_test 1.$tn.401 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,94,5) + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT DO UPDATE set b='x'; + SELECT a,b,c,d,e FROM t1; + } {1 x 3 4 5} +} + +} + +finish_test From 255c1c159b1082c712995436862e4dd4cfa20761 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 12 Dec 2020 00:28:15 +0000 Subject: [PATCH 055/257] New test cases with corresponding bug fixes. FossilOrigin-Name: f22c21a94ca4cad0217f91c1a5a275bc348cb6ba0f3a54c927533bc8d8c96a90 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/insert.c | 6 +++--- src/sqliteInt.h | 2 +- src/upsert.c | 14 +++----------- test/upsert5.test | 38 ++++++++++++++++++++++++++++++++++++-- 6 files changed, 53 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index 728e086000..43fe5d0f2c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Begin\sadding\stest\scases.\s\sFix\sone\sbug\sfound\sso\sfar.\s\sMore\sare\spending. -D 2020-12-11T19:36:19.206 +C New\stest\scases\swith\scorresponding\sbug\sfixes. +D 2020-12-12T00:28:15.628 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -501,7 +501,7 @@ 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 7bb29b8acdd49917fe12cc14e164b9c49fc98f5f2725e5311a03b30349ca3880 +F src/insert.c ec68f3a8b9af7c6e127735af8f61633bc0a2c9cd24a961fb21331ac95c7df251 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 F src/main.c 97e9f137354bc1f76dc9bb60a0a24f8c45cf73b33e80d3ee4c64155336fb820d @@ -545,7 +545,7 @@ F src/shell.c.in e9f674ee4ec6c345679e8a5b16c869c6c59eb1540dd98ac69e4736ecddce009 F src/sqlite.h.in 0e2b4259e49a0eda54d9118eb18a04fcd60e0727a2fd2c81aade0bf57520e706 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h aff99a1938b53530971fcfa7a6a5e6b47f986ddd673660bafb41f1c559747b72 +F src/sqliteInt.h 31492bf5f9d7ccc4835d5e0a88758737812b0ee4c35c0b961840373dbd18bbb0 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -608,7 +608,7 @@ F src/tokenize.c 01dba3023659dc6f6b1e054c14b35a0074bd35de10466b99454d33278191d97 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda F src/trigger.c 515e79206d40d1d4149129318582e79a6e9db590a7b74e226fdb5b2a6c7e1b10 F src/update.c 9f126204a6acb96bbe47391ae48e0fc579105d8e76a6d9c4fab3271367476580 -F src/upsert.c 6471d9e0e5e05547f8a00d7d686714ac08fe89526de133abcf8e1c7a35f2cb82 +F src/upsert.c 5ebb702817ee157badae0548098ea216cc1636e98eda63554e346968565c64c4 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c c0c7977de7ef9b8cb10f6c85f2d0557889a658f817b0455909a49179ba4c8002 F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286 @@ -1643,7 +1643,7 @@ F test/upsert1.test 88f9e258c6a0eeeb85937b08831e8daad440ba41f125af48439e9d33f266 F test/upsert2.test 9c3cdbb1a890227f6504ce4b0e3de68f4cdfa16bb21d8641208a9239896c5a09 F test/upsert3.test 88d7d590a1948a9cb6eac1b54b0642f67a9f35a1fc0f19b200e97d5d39e3179c F test/upsert4.test 25d2a1da92f149331ae0c51ca6e3eee78189577585eab92de149900d62994fa5 -F test/upsert5.test 82acbe52e9a7d74b9eeb93dc219558f44dccd07ef5e07e74fec9eca7173e4bfe +F test/upsert5.test 32ff55ed7e3dcfe62a8e54897c20e074d4629ddf72297092e79997f82ccf06b5 F test/upsertfault.test f21ca47740841fdb4d61acfa7b17646d773e67724fe8c185b71c018db8a94b35 F test/uri.test 3481026f00ade6dfe8adb7acb6e1e47b04369568 F test/uri2.test 9d3ba7a53ee167572d53a298ee4a5d38ec4a8fb7 @@ -1889,7 +1889,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 5321d60c575ef8f888d1b315df02cf9ed96a3ffc61babbc1429aa73b2a61a190 -R 8ec7743a66623a70c1f2fd83cc9cbf09 +P aadd67ddf2a191629b5356395f75e4556aac904a6e2f6b83742fa4f26e4253a4 +R ebc93beb1a5a9905106ef56cc676e95d U drh -Z d9c45c2e1447fdcad46c943d9137f6df +Z 4e2db7f4f46c9338f10a1365883b3835 diff --git a/manifest.uuid b/manifest.uuid index 87fe70a5b0..73f4c884b4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aadd67ddf2a191629b5356395f75e4556aac904a6e2f6b83742fa4f26e4253a4 \ No newline at end of file +f22c21a94ca4cad0217f91c1a5a275bc348cb6ba0f3a54c927533bc8d8c96a90 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 4fa337a2f2..d0f82dccfe 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1804,7 +1804,7 @@ void sqlite3GenerateConstraintChecks( if( pUpsert->pUpsertTarget==0 ){ /* There is just on ON CONFLICT clause and it has no constraint-target */ assert( pUpsert->pNextUpsert==0 ); - if( pUpsert->pUpsertSet==0 ){ + if( pUpsert->isDoUpdate==0 ){ /* A single ON CONFLICT DO NOTHING clause, without a constraint-target. ** Make all unique constraint resolution be OE_Ignore */ overrideError = OE_Ignore; @@ -1918,7 +1918,7 @@ void sqlite3GenerateConstraintChecks( if( pUpsert ){ pUpsertClause = sqlite3UpsertOfIndex(pUpsert,0); if( pUpsertClause!=0 ){ - if( pUpsertClause->pUpsertSet==0 ){ + if( pUpsertClause->isDoUpdate==0 ){ onError = OE_Ignore; /* DO NOTHING is the same as INSERT OR IGNORE */ }else{ onError = OE_Update; /* DO UPDATE */ @@ -2140,7 +2140,7 @@ void sqlite3GenerateConstraintChecks( /* Figure out if the upsert clause applies to this index */ if( pUpsertClause ){ - if( pUpsertClause->pUpsertSet==0 ){ + if( pUpsertClause->isDoUpdate==0 ){ onError = OE_Ignore; /* DO NOTHING is the same as INSERT OR IGNORE */ }else{ onError = OE_Update; /* DO UPDATE */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 403f31326d..3c88c07806 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3078,6 +3078,7 @@ struct Upsert { ExprList *pUpsertSet; /* The SET clause from an ON CONFLICT UPDATE */ Expr *pUpsertWhere; /* WHERE clause for the ON CONFLICT UPDATE */ Upsert *pNextUpsert; /* Next ON CONFLICT clause in the list */ + u8 isDoUpdate; /* True for DO UPDATE. False for DO NOTHING */ /* Above this point is the parse tree for the ON CONFLICT clauses. ** The next group of fields stores intermediate data. */ void *pToFree; /* Free memory when deleting the Upsert object */ @@ -3091,7 +3092,6 @@ struct Upsert { int regData; /* First register holding array of VALUES */ int iDataCur; /* Index of the data cursor */ int iIdxCur; /* Index of the first index cursor */ - int addrGenericUpdate; /* Address of routine for generic DO UPDATE */ }; /* diff --git a/src/upsert.c b/src/upsert.c index 0a9b67dbdb..cb173aa53f 100644 --- a/src/upsert.c +++ b/src/upsert.c @@ -74,6 +74,7 @@ Upsert *sqlite3UpsertNew( pNew->pUpsertTargetWhere = pTargetWhere; pNew->pUpsertSet = pSet; pNew->pUpsertWhere = pWhere; + pNew->isDoUpdate = pSet!=0; pNew->pNextUpsert = pNext; } return pNew; @@ -267,14 +268,7 @@ void sqlite3UpsertDoUpdate( assert( pUpsert!=0 ); iDataCur = pUpsert->iDataCur; pUpsert = sqlite3UpsertOfIndex(pTop, pIdx); - if( pUpsert->addrGenericUpdate>0 ){ - sqlite3VdbeAddOp2(v, OP_Goto, 0, pUpsert->addrGenericUpdate); - return; - } VdbeNoopComment((v, "Begin DO UPDATE of UPSERT")); - if( pUpsert->pUpsertTarget==0 ){ - pUpsert->addrGenericUpdate = sqlite3VdbeCurrentAddr(v); - } if( pIdx && iCur!=iDataCur ){ if( HasRowid(pTab) ){ int regRowid = sqlite3GetTempReg(pParse); @@ -313,10 +307,8 @@ void sqlite3UpsertDoUpdate( sqlite3VdbeAddOp1(v, OP_RealAffinity, pTop->regData+i); } } - sqlite3Update(pParse, pSrc, pUpsert->pUpsertSet, - pUpsert->pUpsertWhere, OE_Abort, 0, 0, pUpsert); - pUpsert->pUpsertSet = 0; /* Will have been deleted by sqlite3Update() */ - pUpsert->pUpsertWhere = 0; /* Will have been deleted by sqlite3Update() */ + sqlite3Update(pParse, pSrc, sqlite3ExprListDup(db,pUpsert->pUpsertSet,0), + sqlite3ExprDup(db,pUpsert->pUpsertWhere,0), OE_Abort, 0, 0, pUpsert); VdbeNoopComment((v, "End DO UPDATE of UPSERT")); } diff --git a/test/upsert5.test b/test/upsert5.test index e3840a9b32..fe748f5f00 100644 --- a/test/upsert5.test +++ b/test/upsert5.test @@ -216,7 +216,6 @@ foreach {tn sql} { SELECT a,b,c,d,e FROM t1; } {1 e 3 4 5} -if {0} { do_execsql_test 1.$tn.400 { DELETE FROM t1; INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); @@ -235,7 +234,42 @@ if {0} { ON CONFLICT DO UPDATE set b='x'; SELECT a,b,c,d,e FROM t1; } {1 x 3 4 5} -} + do_execsql_test 1.$tn.402 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95) + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT DO UPDATE set b='x'; + SELECT a,b,c,d,e FROM t1; + } {1 x 3 4 5} + do_execsql_test 1.$tn.403 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,3,94,95) + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT DO UPDATE set b='x'; + SELECT a,b,c,d,e FROM t1; + } {1 c 3 4 5} + do_execsql_test 1.$tn.404 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,3,4,95) + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT DO UPDATE set b='x'; + SELECT a,b,c,d,e FROM t1; + } {1 c 3 4 5} + do_execsql_test 1.$tn.405 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,4,5) + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT DO UPDATE set b='x'; + SELECT a,b,c,d,e FROM t1; + } {1 d 3 4 5} } From 250af6e0fb8c9fab2aab73651e39b5832eccd331 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 12 Dec 2020 00:43:52 +0000 Subject: [PATCH 056/257] More test cases. No new problems discovered. FossilOrigin-Name: f34dd67e2d0dfc9e3b5d49148fb0162853119c097cbc3fe961878875ba98d8e3 --- manifest | 12 ++--- manifest.uuid | 2 +- test/upsert5.test | 121 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 43fe5d0f2c..3410b246b8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\stest\scases\swith\scorresponding\sbug\sfixes. -D 2020-12-12T00:28:15.628 +C More\stest\scases.\s\sNo\snew\sproblems\sdiscovered. +D 2020-12-12T00:43:52.775 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1643,7 +1643,7 @@ F test/upsert1.test 88f9e258c6a0eeeb85937b08831e8daad440ba41f125af48439e9d33f266 F test/upsert2.test 9c3cdbb1a890227f6504ce4b0e3de68f4cdfa16bb21d8641208a9239896c5a09 F test/upsert3.test 88d7d590a1948a9cb6eac1b54b0642f67a9f35a1fc0f19b200e97d5d39e3179c F test/upsert4.test 25d2a1da92f149331ae0c51ca6e3eee78189577585eab92de149900d62994fa5 -F test/upsert5.test 32ff55ed7e3dcfe62a8e54897c20e074d4629ddf72297092e79997f82ccf06b5 +F test/upsert5.test f49faf5f15b5c3641c6f5d7c7cc531ef5ac997567b2b6bb7bc96f7c88753ca0b F test/upsertfault.test f21ca47740841fdb4d61acfa7b17646d773e67724fe8c185b71c018db8a94b35 F test/uri.test 3481026f00ade6dfe8adb7acb6e1e47b04369568 F test/uri2.test 9d3ba7a53ee167572d53a298ee4a5d38ec4a8fb7 @@ -1889,7 +1889,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 aadd67ddf2a191629b5356395f75e4556aac904a6e2f6b83742fa4f26e4253a4 -R ebc93beb1a5a9905106ef56cc676e95d +P f22c21a94ca4cad0217f91c1a5a275bc348cb6ba0f3a54c927533bc8d8c96a90 +R 5a5b9a84e82bccc93a94b5f0a9cd7326 U drh -Z 4e2db7f4f46c9338f10a1365883b3835 +Z 16b3f3b436b8a24d4c2a8d5d463d0b17 diff --git a/manifest.uuid b/manifest.uuid index 73f4c884b4..bf1f11ba9a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f22c21a94ca4cad0217f91c1a5a275bc348cb6ba0f3a54c927533bc8d8c96a90 \ No newline at end of file +f34dd67e2d0dfc9e3b5d49148fb0162853119c097cbc3fe961878875ba98d8e3 \ No newline at end of file diff --git a/test/upsert5.test b/test/upsert5.test index fe748f5f00..c4747ddf18 100644 --- a/test/upsert5.test +++ b/test/upsert5.test @@ -271,6 +271,127 @@ foreach {tn sql} { SELECT a,b,c,d,e FROM t1; } {1 d 3 4 5} + do_execsql_test 1.$tn.410 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95) + ON CONFLICT DO UPDATE set b='x'; + SELECT a,b,c,d,e FROM t1; + } {1 x 3 4 5} + do_execsql_test 1.$tn.411 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,94,5) + ON CONFLICT DO UPDATE set b='x'; + SELECT a,b,c,d,e FROM t1; + } {1 x 3 4 5} + do_execsql_test 1.$tn.412 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,4,95) + ON CONFLICT DO UPDATE set b='x'; + SELECT a,b,c,d,e FROM t1; + } {1 x 3 4 5} + do_execsql_test 1.$tn.413 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,3,94,95) + ON CONFLICT DO UPDATE set b='x'; + SELECT a,b,c,d,e FROM t1; + } {1 x 3 4 5} + + do_execsql_test 1.$tn.420 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95) + ON CONFLICT(c) DO NOTHING + ON CONFLICT(d) DO NOTHING + ON CONFLICT DO UPDATE set b='x'; + SELECT a,b,c,d,e FROM t1; + } {1 x 3 4 5} + do_execsql_test 1.$tn.421 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,94,5) + ON CONFLICT(c) DO NOTHING + ON CONFLICT(d) DO NOTHING + ON CONFLICT DO UPDATE set b='x'; + SELECT a,b,c,d,e FROM t1; + } {1 x 3 4 5} + do_execsql_test 1.$tn.422 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,4,95) + ON CONFLICT(c) DO NOTHING + ON CONFLICT(d) DO NOTHING + ON CONFLICT DO UPDATE set b='x'; + SELECT a,b,c,d,e FROM t1; + } {1 2 3 4 5} + do_execsql_test 1.$tn.423 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,3,94,95) + ON CONFLICT(c) DO NOTHING + ON CONFLICT(d) DO NOTHING + ON CONFLICT DO UPDATE set b='x'; + SELECT a,b,c,d,e FROM t1; + } {1 2 3 4 5} + + do_execsql_test 1.$tn.500 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95) + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT DO NOTHING; + SELECT a,b,c,d,e FROM t1; + } {1 2 3 4 5} + do_execsql_test 1.$tn.501 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,94,5) + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT DO NOTHING; + SELECT a,b,c,d,e FROM t1; + } {1 2 3 4 5} + do_execsql_test 1.$tn.502 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95) + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT DO NOTHING; + SELECT a,b,c,d,e FROM t1; + } {1 2 3 4 5} + do_execsql_test 1.$tn.503 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,3,94,95) + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT DO NOTHING; + SELECT a,b,c,d,e FROM t1; + } {1 c 3 4 5} + do_execsql_test 1.$tn.504 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,3,4,95) + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT DO NOTHING; + SELECT a,b,c,d,e FROM t1; + } {1 c 3 4 5} + do_execsql_test 1.$tn.505 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,4,5) + ON CONFLICT(c) DO UPDATE SET b='c' + ON CONFLICT(d) DO UPDATE SET b='d' + ON CONFLICT DO NOTHING; + SELECT a,b,c,d,e FROM t1; + } {1 d 3 4 5} + } finish_test From 1c19848386babe4056e0e825433fcbe4b4ef1a5d Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 14 Dec 2020 13:52:03 +0000 Subject: [PATCH 057/257] Minor changes for test coverage. FossilOrigin-Name: e5a8fa50f4e5e5c24664452eda4af80904f75e5123b8f84353347dbd505d416d --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/parse.y | 7 ++++++- src/upsert.c | 2 +- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 3410b246b8..d18f0d5c73 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\stest\scases.\s\sNo\snew\sproblems\sdiscovered. -D 2020-12-12T00:43:52.775 +C Minor\schanges\sfor\stest\scoverage. +D 2020-12-14T13:52:03.476 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -529,7 +529,7 @@ F src/os_win.c 77d39873836f1831a9b0b91894fec45ab0e9ca8e067dc8c549e1d1eca1566fe9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c c49952ac5e9cc536778eff528091d79d38b3e45cbeeed4695dc05e207dc6547d F src/pager.h 4bf9b3213a4b2bebbced5eaa8b219cf25d4a82f385d093cd64b7e93e5285f66f -F src/parse.y 72b884c73f2b446e7dc4c7169ec7fbb82e0e292eec733fcf554f0fde46f269f6 +F src/parse.y 6c8aa09a7fa6e0867c3a3d67ef61b911aa392c9b084a61dc632cd93732aef8ad F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a @@ -608,7 +608,7 @@ F src/tokenize.c 01dba3023659dc6f6b1e054c14b35a0074bd35de10466b99454d33278191d97 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda F src/trigger.c 515e79206d40d1d4149129318582e79a6e9db590a7b74e226fdb5b2a6c7e1b10 F src/update.c 9f126204a6acb96bbe47391ae48e0fc579105d8e76a6d9c4fab3271367476580 -F src/upsert.c 5ebb702817ee157badae0548098ea216cc1636e98eda63554e346968565c64c4 +F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c c0c7977de7ef9b8cb10f6c85f2d0557889a658f817b0455909a49179ba4c8002 F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286 @@ -1889,7 +1889,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 f22c21a94ca4cad0217f91c1a5a275bc348cb6ba0f3a54c927533bc8d8c96a90 -R 5a5b9a84e82bccc93a94b5f0a9cd7326 +P f34dd67e2d0dfc9e3b5d49148fb0162853119c097cbc3fe961878875ba98d8e3 +R e4ba77cafc1a5ebe11440b61ff8c6ede U drh -Z 16b3f3b436b8a24d4c2a8d5d463d0b17 +Z 22668862baa080d495b808bc49582152 diff --git a/manifest.uuid b/manifest.uuid index bf1f11ba9a..22965be8e2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f34dd67e2d0dfc9e3b5d49148fb0162853119c097cbc3fe961878875ba98d8e3 \ No newline at end of file +e5a8fa50f4e5e5c24664452eda4af80904f75e5123b8f84353347dbd505d416d \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index f28bb47414..faec4b5cf5 100644 --- a/src/parse.y +++ b/src/parse.y @@ -952,7 +952,12 @@ cmd ::= with insert_cmd(R) INTO xfullname(X) idlist_opt(F) DEFAULT VALUES. } %type upsert {Upsert*} -%destructor upsert {sqlite3UpsertDelete(pParse->db,$$);} + +// Because upsert only occurs at the tip end of the INSERT rule for cmd, +// there is never a case where the value of the upsert pointer will not +// be destroyed by the cmd action. So comment-out the destructor to +// avoid unreachable code. +//%destructor upsert {sqlite3UpsertDelete(pParse->db,$$);} upsert(A) ::= . { A = 0; } upsert(A) ::= ON CONFLICT LP sortlist(T) RP where_opt(TW) DO UPDATE SET setlist(Z) where_opt(W) upsert(N). diff --git a/src/upsert.c b/src/upsert.c index cb173aa53f..982dc7dbc1 100644 --- a/src/upsert.c +++ b/src/upsert.c @@ -216,7 +216,7 @@ int sqlite3UpsertAnalyzeTarget( */ int sqlite3UpsertNextIsIPK(Upsert *pUpsert){ Upsert *pNext; - if( pUpsert==0 ) return 0; + if( NEVER(pUpsert==0) ) return 0; pNext = pUpsert->pNextUpsert; if( pNext==0 ) return 1; if( pNext->pUpsertTarget==0 ) return 1; From 59964b40103d530aa1e84ca873ecc146dc13fc80 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 14 Dec 2020 15:25:14 +0000 Subject: [PATCH 058/257] Fix an integer overflow problem in new VACUUM code. FossilOrigin-Name: 59b4367fd852ba1bfefdff99a27b11657495a3f114ed6f85fdcf6c532f4a19fa --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index c5e7ec8dc9..cb0f550f9e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sassert()\sbroken\sby\srecent\schanges\sto\svacuum. -D 2020-12-11T19:01:24.454 +C Fix\san\sinteger\soverflow\sproblem\sin\snew\sVACUUM\scode. +D 2020-12-14T15:25:14.417 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -481,7 +481,7 @@ F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c ea5e8bfe904d4818d97cae4eee229d7ce21a0a090ef5402ebac68840dc16713f +F src/btree.c f8cdad7e00eedad4e4f5183aee8db354dd3622604a27bd2223811eeb182236fb F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 F src/build.c f6449d4e85e998e14d3f537e8ea898dca2fcb83c277db3e60945af9b9177db81 @@ -1889,7 +1889,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 b411f29e1a6415f4a241777c45591b8389e746cd8b40d9b225e073bcb0a3bdbf -R 5f1281ebbbf31df2eed9d78849a16b43 +P dd058da85ca54ae70e26cb0bdc75ff42998d4a8b29a5e2dcac44ee0e45776a85 +R 0d937f0ec9f044837ba6918ca3838d82 U dan -Z 63f7dff9f8374ff08b8e0cc7e378c500 +Z 57f4f0625729074fba29cd7d21629db2 diff --git a/manifest.uuid b/manifest.uuid index e819bc2a41..c8f28578db 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dd058da85ca54ae70e26cb0bdc75ff42998d4a8b29a5e2dcac44ee0e45776a85 \ No newline at end of file +59b4367fd852ba1bfefdff99a27b11657495a3f114ed6f85fdcf6c532f4a19fa \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 1a151fe4ef..a3cf388ff9 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1147,7 +1147,7 @@ static SQLITE_NOINLINE void btreeParseCellAdjustSizeForOverflow( ** Given a record with nPayload bytes of payload stored within btree ** page pPage, return the number of bytes of payload stored locally. */ -static int btreePayloadToLocal(MemPage *pPage, int nPayload){ +static int btreePayloadToLocal(MemPage *pPage, i64 nPayload){ int maxLocal; /* Maximum amount of payload held locally */ maxLocal = pPage->maxLocal; if( nPayload<=maxLocal ){ From 84b168ffa7b04a7d5fca80c0e98f7022673af119 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 15 Dec 2020 13:55:38 +0000 Subject: [PATCH 059/257] Change an fts5 assert() that can be triggered by a corrupt database to an if() condition. FossilOrigin-Name: ea0a7f103a6f6a9e57d7377140ff9f372bf2b156f86f148291fb05a7030f2b36 --- ext/fts5/fts5_expr.c | 4 +- ext/fts5/test/fts5corrupt3.test | 128 ++++++++++++++++++++++++++++++++ manifest | 17 ++--- manifest.uuid | 2 +- 4 files changed, 139 insertions(+), 12 deletions(-) diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index 392dde3ab4..088d8b8cae 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -1500,8 +1500,8 @@ int sqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, i64 iFirst, int bDesc){ } /* If the iterator is not at a real match, skip forward until it is. */ - while( pRoot->bNomatch ){ - assert( pRoot->bEof==0 && rc==SQLITE_OK ); + while( pRoot->bNomatch && rc==SQLITE_OK ){ + assert( pRoot->bEof==0 ); rc = fts5ExprNodeNext(p, pRoot, 0, 0); } return rc; diff --git a/ext/fts5/test/fts5corrupt3.test b/ext/fts5/test/fts5corrupt3.test index 4223d3c240..4554abbcfb 100644 --- a/ext/fts5/test/fts5corrupt3.test +++ b/ext/fts5/test/fts5corrupt3.test @@ -10509,6 +10509,134 @@ do_catchsql_test 71.2 { INSERT INTO t1(t1) VALUES('integrity-check'); } {1 {database disk image is malformed}} +#------------------------------------------------------------------------- +reset_db +do_test 72.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +.open --hexdb +| size 24576 pagesize 4096 filename crash-77b86d070d0ac6.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 06 .....@ ........ +| 32: 00 00 00 00 00 00 00 00 00 00 00 06 00 00 00 04 ................ +| 96: 00 00 00 00 0d 00 00 00 06 0d e2 00 0f c4 0f 6a ...............j +| 112: 0e fc 0e 9d 0e 3d 0d e2 00 00 00 00 00 00 00 00 .....=.......... +| 3552: 00 00 59 06 06 17 21 21 01 7f 74 61 62 6c 65 74 ..Y...!!..tablet +| 3568: 74 74 5f 63 6f 6e 66 69 67 74 74 74 5f 63 6f 6e tt_configttt_con +| 3584: 66 69 67 06 43 52 45 41 54 45 20 54 41 42 4c 45 fig.CREATE TABLE +| 3600: 20 27 74 74 74 5f 63 6f 6e 66 69 67 27 28 6b 20 'ttt_config'(k +| 3616: 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 PRIMARY KEY, v) +| 3632: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5e 05 07 WITHOUT ROWID^.. +| 3648: 17 23 23 01 81 03 74 61 62 6c 65 74 74 74 5f 64 .##...tablettt_d +| 3664: 6f 63 73 69 7a 65 74 74 74 5f 64 6f 63 73 69 7a ocsizettt_docsiz +| 3680: 65 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 e.CREATE TABLE ' +| 3696: 74 74 74 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 ttt_docsize'(id +| 3712: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 INTEGER PRIMARY +| 3728: 4b 45 59 2c 20 73 7a 20 42 4c 4f 42 29 5d 04 07 KEY, sz BLOB)].. +| 3744: 17 23 23 01 81 01 74 61 62 6c 65 74 74 74 5f 63 .##...tablettt_c +| 3760: 6f 6e 74 65 6e 74 74 74 74 5f 63 6f 6e 74 65 6e ontentttt_conten +| 3776: 74 04 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 t.CREATE TABLE ' +| 3792: 74 74 74 5f 63 6f 6e 74 65 6e 74 27 28 69 64 20 ttt_content'(id +| 3808: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 INTEGER PRIMARY +| 3824: 4b 45 59 2c 20 63 30 2c 20 63 31 29 6c 03 07 17 KEY, c0, c1)l... +| 3840: 1b 1b 01 81 2f 74 61 62 6c 65 74 74 74 5f 69 64 ..../tablettt_id +| 3856: 78 74 74 74 5f 69 64 78 03 43 52 45 41 54 45 20 xttt_idx.CREATE +| 3872: 54 41 42 4c 45 20 27 74 74 74 5f 69 64 78 27 28 TABLE 'ttt_idx'( +| 3888: 73 65 67 69 64 2c 20 74 65 72 6d 2c 20 70 67 6e segid, term, pgn +| 3904: 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45 59 28 73 o, PRIMARY KEY(s +| 3920: 65 67 69 64 2c 20 74 65 72 6d 29 29 20 57 49 54 egid, term)) WIT +| 3936: 48 4f 55 54 20 52 4f 57 49 44 58 02 07 17 1d 1d HOUT ROWIDX..... +| 3952: 01 81 03 74 61 62 6c 65 74 74 74 5f 64 61 74 61 ...tablettt_data +| 3968: 74 74 74 5f 64 61 74 61 02 43 52 45 41 54 45 20 ttt_data.CREATE +| 3984: 54 41 42 4c 45 20 27 74 74 74 5f 64 61 74 61 27 TABLE 'ttt_data' +| 4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d (id INTEGER PRIM +| 4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 ARY KEY, block B +| 4032: 4c 4f 42 29 3a 01 06 17 13 13 08 5f 74 61 62 6c LOB):......_tabl +| 4048: 65 74 74 74 74 74 74 43 52 45 41 54 45 20 56 49 ettttttCREATE VI +| 4064: 52 54 55 41 4c 20 54 41 42 4c 45 20 74 74 74 20 RTUAL TABLE ttt +| 4080: 55 53 49 4e 47 20 66 74 73 35 28 61 2c 20 62 29 USING fts5(a, b) +| page 2 offset 4096 +| 0: 0d 0f 44 00 05 0e 81 00 0f e7 0e 81 0f af 0f 58 ..D............X +| 16: 0e 98 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 3712: 00 15 0a 03 00 30 00 00 00 00 01 03 03 00 03 01 .....0.......... +| 3728: 01 01 02 01 01 03 01 01 81 24 8c 80 80 80 80 01 .........$...... +| 3744: 04 00 82 4c 00 00 00 9b 02 30 65 03 1a 02 05 05 ...L.....0e..... +| 3760: 07 05 01 01 04 03 03 08 03 03 01 2e 02 05 05 07 ................ +| 3776: 05 07 05 07 05 01 01 04 03 03 08 03 03 08 03 03 ................ +| 3792: 08 03 03 02 01 65 03 1e 03 05 05 04 05 05 01 01 .....e.......... +| 3808: 03 06 04 04 06 04 03 01 36 03 05 05 04 05 05 04 ........6....... +| 3824: 05 05 04 05 05 01 01 03 06 04 04 06 04 04 06 04 ................ +| 3840: 04 06 04 03 03 01 65 03 14 04 05 07 05 05 01 01 ......e......... +| 3856: 02 08 0a 01 20 04 05 07 05 07 05 07 05 05 01 01 .... ........... +| 3872: 02 08 0a 09 fa 04 01 65 03 02 0a 01 06 0a 1a 0a .......e........ +| 3888: 05 01 65 03 06 01 01 0a 01 0a 01 01 0a 0a 0a 04 ..e............. +| 3904: 2b 31 21 0b 0f ef 00 14 2a 00 00 00 00 01 02 02 +1!.....*....... +| 3920: 00 02 01 01 01 02 01 01 50 88 80 80 80 80 01 04 ........P....... +| 3936: 00 81 24 00 00 00 47 02 30 65 02 1a 02 05 05 07 ..$...G.0e...... +| 3952: 05 01 01 04 03 03 08 03 03 02 01 65 02 1e 03 05 ...........e.... +| 3968: 05 04 05 05 01 01 03 06 04 04 06 04 03 03 01 65 ...............e +| 3984: 02 14 04 05 07 05 05 01 01 02 08 0a 04 01 65 02 ..............e. +| 4000: 02 0a 05 01 65 02 06 01 01 0a 04 12 14 0f 06 31 ....e..........1 +| 4016: 84 80 80 80 80 01 03 00 68 00 00 00 2b 02 30 65 ........h...+.0e +| 4032: 01 10 02 05 05 01 01 04 03 9f 02 01 65 01 12 03 ............e... +| 4048: 05 05 01 01 03 06 04 03 03 01 65 01 0e 14 05 05 ..........e..... +| 4064: 01 01 02 08 04 0d 0e 06 01 03 00 12 04 4c 4c 00 .............LL. +| 4080: 00 00 11 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............ +| page 3 offset 8192 +| 0: 0a 00 00 00 03 0f 00 00 00 00 00 00 00 00 00 00 ................ +| 4064: 00 00 00 00 00 00 00 00 00 00 00 00 06 04 01 0c ................ +| 4080: 01 03 02 06 04 01 0c 01 02 02 05 04 09 0c 01 02 ................ +| page 4 offset 12288 +| 0: 0d 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 ................ +| 3600: 00 00 00 00 00 00 00 00 00 00 81 52 04 06 00 81 ...........R.... +| 3616: 5d 81 55 65 20 65 65 20 65 65 65 20 65 20 65 65 ].Ue ee eee e ee +| 3632: 20 65 65 65 20 65 20 65 65 20 65 65 65 65 20 65 eee e ee eeee e +| 3648: 65 20 65 65 65 20 65 20 65 65 20 65 65 65 20 65 e eee e ee eee e +| 3664: 20 65 65 20 65 65 55 65 20 65 65 20 65 65 65 20 ee eeUe ee eee +| 3680: 65 20 65 65 20 65 65 65 20 65 20 65 65 20 65 65 e ee eee e ee ee +| 3696: 65 65 20 65 65 20 65 65 65 20 65 20 65 65 20 65 ee ee eee e ee e +| 3712: 65 65 20 65 20 65 65 20 65 65 65 65 65 65 20 65 ee e ee eeeeee e +| 3728: 65 20 65 20 65 20 65 20 65 65 20 65 85 65 20 65 e e e e ee e.e e +| 3744: 65 20 65 65 65 65 65 20 65 65 20 65 20 65 20 65 e eeeee ee e e e +| 3760: 20 65 65 20 65 65 65 20 65 65 20 65 65 65 65 65 ee eee ee eeeee +| 3776: 20 65 65 20 65 20 65 20 65 20 65 65 20 65 65 65 ee e e e ee eee +| 3792: 20 65 65 20 65 65 65 65 65 20 65 65 20 65 20 65 ee eeeee ee e e +| 3808: 20 65 20 65 65 20 65 65 65 20 65 65 20 65 65 6a e ee eee ee eej +| 3824: 03 04 00 75 71 65 20 65 65 20 65 65 65 20 65 20 ...uqe ee eee e +| 3840: 65 65 20 65 65 65 20 65 20 65 65 20 65 65 65 65 ee eee e ee eeee +| 3856: 20 65 65 20 65 65 65 20 65 20 65 65 20 65 65 65 ee eee e ee eee +| 3872: 20 65 20 65 65 20 65 65 65 65 65 65 20 65 65 20 e ee eeeeee ee +| 3888: 65 20 65 20 65 20 65 64 20 65 65 65 20 65 65 20 e e e ed eee ee +| 3904: 65 65 65 65 65 20 65 65 20 65 20 65 20 65 10 65 eeeee ee e e e.e +| 3920: 65 20 65 65 65 10 65 65 20 65 65 6a 02 04 00 75 e eee.ee eej...u +| 3936: 71 65 20 65 65 20 65 65 65 20 65 20 65 65 20 65 qe ee eee e ee e +| 3952: 65 65 20 65 20 65 65 20 65 65 65 65 20 65 65 20 ee e ee eeee ee +| 3968: 65 65 65 20 65 20 65 65 20 65 65 65 20 65 20 65 eee e ee eee e e +| 3984: 65 20 65 65 65 66 65 65 20 65 65 20 65 20 65 20 e eeefee ee e e +| 4000: 65 88 65 65 20 65 65 65 30 65 65 20 65 65 65 65 e.ee eee0ee eeee +| 4016: 65 20 65 65 20 65 20 65 20 65 20 65 65 20 65 65 e ee e e e ee ee +| 4032: 65 20 65 65 20 65 65 37 01 04 00 41 3f 65 20 65 e ee ee7...A?e e +| 4048: 65 20 65 65 65 20 65 20 65 65 20 65 65 65 20 65 e eee e ee eee e +| 4064: 20 65 65 20 65 65 65 65 65 65 20 65 65 20 65 20 ee eeeeee ee e +| 4080: 65 20 65 20 65 65 20 65 65 65 20 65 65 20 65 65 e e ee eee ee ee +| page 5 offset 16384 +| 0: 0d 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 ................ +| 4064: 00 00 00 00 05 04 03 00 10 21 21 05 03 03 00 10 .........!!..... +| 4080: 11 11 05 02 03 00 10 11 11 05 01 03 00 10 09 09 ................ +| page 6 offset 20480 +| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................ +| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version. +| end crash-77b86d070d0ac6.db +}]} {} + +do_catchsql_test 72.1 { + INSERT INTO ttt(ttt) VALUES('integrity-check'); +} {1 {database disk image is malformed}} + +do_catchsql_test 72.1 { + SELECT 1 FROM ttt('e* NOT ee*'); +} {1 {database disk image is malformed}} sqlite3_fts5_may_be_corrupt 0 finish_test diff --git a/manifest b/manifest index 00e5a96cef..71aaea204e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sUPSERT\sso\sthat\sit\sallows\smultiple\sON\sCONFLICT\sclauses\sand\sdoes\nnot\srequire\sa\sconflict\starget\sfor\sDO\sUPDATE. -D 2020-12-14T15:39:12.267 +C Change\san\sfts5\sassert()\sthat\scan\sbe\striggered\sby\sa\scorrupt\sdatabase\sto\san\sif()\scondition. +D 2020-12-15T13:55:38.138 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -117,7 +117,7 @@ F ext/fts5/fts5Int.h 26c74dd5776f798436fbf604a0bf0e8de263b35b5060b05c15f9085845d F ext/fts5/fts5_aux.c f558e1fb9f0f86a4f7489e258c162e1f947de5ff2709087fbb465fddb7092f98 F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6dc8aaca70 F ext/fts5/fts5_config.c be54f44fca491e96c6923a4b9a736f2da2b13811600eb6e38d1bcc91c4ea2e61 -F ext/fts5/fts5_expr.c e527e3a7410393075598cec544e3831798a8c88b3e8878e2cfb7cb147113e925 +F ext/fts5/fts5_expr.c 016bd06030679bd31b0f07ef87d62c42031e5da25cb3174a84e5b0f6ef4b47b0 F ext/fts5/fts5_hash.c 1aa93c9b5f461afba66701ee226297dc78402b3bdde81e90a10de5fe3df14959 F ext/fts5/fts5_index.c 7be3a7dcf4458a2d58a1c6ae0290921c9df226bff7eb9bc82f14e667b27aeb20 F ext/fts5/fts5_main.c b4e4931c7fcc9acfa0c3b8b5e5e80b5b424b8d9207aae3a22b674bd35ccf149d @@ -160,7 +160,7 @@ F ext/fts5/test/fts5connect.test 08030168fc96fc278fa81f28654fb7e90566f33aff269c0 F ext/fts5/test/fts5content.test 213506436fb2c87567b8e31f6d43ab30aab99354cec74ed679f22aad0cdbf283 F ext/fts5/test/fts5corrupt.test 77ae6f41a7eba10620efb921cf7dbe218b0ef232b04519deb43581cb17a57ebe F ext/fts5/test/fts5corrupt2.test 7453752ba12ce91690c469a6449d412561cc604b1dec994e16ab132952e7805f -F ext/fts5/test/fts5corrupt3.test 1c26a651ea7e52fd69d54436fe4f02f6dd1268bc8b48ab851c7e1d374aa242b9 +F ext/fts5/test/fts5corrupt3.test 6de9f4f73fec1d996460d2f65576590e1e7074f9c28b8db9c19287c588c6f552 F ext/fts5/test/fts5corrupt4.test f4c08e2182a48d8b70975fd869ee5391855c06d8a0ff87b6a2529e7c5a88a1d3 F ext/fts5/test/fts5delete.test 619295b20dbc1d840b403ee07c878f52378849c3c02e44f2ee143b3e978a0aa7 F ext/fts5/test/fts5detail.test 31b240dbf6d44ac3507e2f8b65f29fdc12465ffd531212378c7ce1066766f54e @@ -1890,8 +1890,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 59b4367fd852ba1bfefdff99a27b11657495a3f114ed6f85fdcf6c532f4a19fa e5a8fa50f4e5e5c24664452eda4af80904f75e5123b8f84353347dbd505d416d -R 5965c0546552f5972781a0c11e3dea88 -T +closed e5a8fa50f4e5e5c24664452eda4af80904f75e5123b8f84353347dbd505d416d -U drh -Z 3b5c01b64f44977242fcbbbded19a49d +P 6b01a24daab1e5bcb0768ebf994368d941b1dfc217bf6b661211d900331e68cf +R a02cdc0a688d372d47b00b934b62e2f2 +U dan +Z 2a130663522021cad08d2a2db075511b diff --git a/manifest.uuid b/manifest.uuid index 8c7df83e8d..ab262d65eb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6b01a24daab1e5bcb0768ebf994368d941b1dfc217bf6b661211d900331e68cf \ No newline at end of file +ea0a7f103a6f6a9e57d7377140ff9f372bf2b156f86f148291fb05a7030f2b36 \ No newline at end of file From 0bf333467ca7abd3467f005863f652343fc38d8f Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 15 Dec 2020 16:28:07 +0000 Subject: [PATCH 060/257] When the -statstep option is passed to the "rbu" executable, print out memory stats right before exiting, as well as every -statstep steps. FossilOrigin-Name: 94f81b51176566409b7d16b30d861f48ad15bb43a145df6e02e0880f7c348109 --- ext/rbu/rbu.c | 7 +++++++ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/ext/rbu/rbu.c b/ext/rbu/rbu.c index 02822c4a42..91773409cf 100644 --- a/ext/rbu/rbu.c +++ b/ext/rbu/rbu.c @@ -183,6 +183,13 @@ int main(int argc, char **argv){ break; } + if( nStatStep>0 ){ + sqlite3_int64 nUsed; + sqlite3_int64 nHighwater; + sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &nUsed, &nHighwater, 0); + fprintf(stdout, "memory used=%lld highwater=%lld\n", nUsed, nHighwater); + } + sqlite3_free(zErrmsg); return (rc==SQLITE_OK || rc==SQLITE_DONE) ? 0 : 1; } diff --git a/manifest b/manifest index 71aaea204e..82f8be63a6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\san\sfts5\sassert()\sthat\scan\sbe\striggered\sby\sa\scorrupt\sdatabase\sto\san\sif()\scondition. -D 2020-12-15T13:55:38.138 +C When\sthe\s-statstep\soption\sis\spassed\sto\sthe\s"rbu"\sexecutable,\sprint\sout\smemory\sstats\sright\sbefore\sexiting,\sas\swell\sas\severy\s-statstep\ssteps. +D 2020-12-15T16:28:07.633 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -339,7 +339,7 @@ F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd F ext/misc/wholenumber.c 520f34c3099e5b7d546f13708607dc2fa173c46b68952eecf0d19cd675fec85e F ext/misc/zipfile.c e35e035bc2765b1ccdcb15f9815c2112843fcbc8f36aa071f0e5935df7072228 F ext/misc/zorder.c b0ff58fa643afa1d846786d51ea8d5c4b6b35aa0254ab5a82617db92f3adda64 -F ext/rbu/rbu.c 8681f6157db6adc82c34af24b14ea8a3be0146ad2a3b6c1d5da6cb8a5796c8ce +F ext/rbu/rbu.c b880ca5cb857d6d6f52e72eb7397813058ef48c78c5402cd04ff2b6b5437f622 F ext/rbu/rbu1.test 221d9c18a5e600ac9ac6b1810d99d9f99163a7909ba61597876ab6e4d4beb3d6 F ext/rbu/rbu10.test 0a201c32202143f23c81c0144503da339786fc20acb7a2fda11601b65659f314 F ext/rbu/rbu11.test 5c834cf491086b45e071eabf71f708febc143e86a384a92de69e0b1a4cace144 @@ -1890,7 +1890,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 6b01a24daab1e5bcb0768ebf994368d941b1dfc217bf6b661211d900331e68cf -R a02cdc0a688d372d47b00b934b62e2f2 +P ea0a7f103a6f6a9e57d7377140ff9f372bf2b156f86f148291fb05a7030f2b36 +R a2929ff08e32fd95eef1d5a44bce177d U dan -Z 2a130663522021cad08d2a2db075511b +Z 7d2f5d8183adfe209996b488d97e46d6 diff --git a/manifest.uuid b/manifest.uuid index ab262d65eb..c48b781edb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ea0a7f103a6f6a9e57d7377140ff9f372bf2b156f86f148291fb05a7030f2b36 \ No newline at end of file +94f81b51176566409b7d16b30d861f48ad15bb43a145df6e02e0880f7c348109 \ No newline at end of file From 7f607066911c7957e93f9fb5c5f4d8bad17f04ba Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 15 Dec 2020 19:27:20 +0000 Subject: [PATCH 061/257] Fix another integer overflow triggered by a corrupt database in recently modified vacuum code. FossilOrigin-Name: 4e2dd2a53364f1fed48b995fd5d2642472585f6da5e4735e9da193ba7ff45514 --- manifest | 13 +++--- manifest.uuid | 2 +- src/btree.c | 2 +- test/corruptN.test | 106 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 115 insertions(+), 8 deletions(-) create mode 100644 test/corruptN.test diff --git a/manifest b/manifest index 82f8be63a6..097c1231bf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sthe\s-statstep\soption\sis\spassed\sto\sthe\s"rbu"\sexecutable,\sprint\sout\smemory\sstats\sright\sbefore\sexiting,\sas\swell\sas\severy\s-statstep\ssteps. -D 2020-12-15T16:28:07.633 +C Fix\sanother\sinteger\soverflow\striggered\sby\sa\scorrupt\sdatabase\sin\srecently\smodified\svacuum\scode. +D 2020-12-15T19:27:20.474 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -481,7 +481,7 @@ F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c f8cdad7e00eedad4e4f5183aee8db354dd3622604a27bd2223811eeb182236fb +F src/btree.c b995dfb6a2d79e2be51ce65a6f54a52f2c327507c35f3f8558d0def711d59298 F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 F src/build.c f6449d4e85e998e14d3f537e8ea898dca2fcb83c277db3e60945af9b9177db81 @@ -791,6 +791,7 @@ F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4 F test/corruptK.test 5b4212fe346699831c5ad559a62c54e11c0611bdde1ea8423a091f9c01aa32af F test/corruptL.test 22589f503602cc5984e80f27f46c4de2134f24f1515ba2440513c377cb692258 F test/corruptM.test 7d574320e08c1b36caa3e47262061f186367d593a7e305d35f15289cc2c3e067 +F test/corruptN.test 781c5f26a2d8918f03d45ac4968a738031eeb113a4b153c7588756d9b09c7b04 F test/cost.test 1d156ce9858780a966c062694687afe0343a0ed12d081d071fb57027e726bafc F test/count.test e0699a15712bc2a4679d60e408921c2cce7f6365a30340e790c98e0f334a9c77 F test/countofview.test e17d6e6688cf74f22783c9ec6e788c0790ee4fbbaee713affd00b1ac0bb39b86 @@ -1890,7 +1891,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 ea0a7f103a6f6a9e57d7377140ff9f372bf2b156f86f148291fb05a7030f2b36 -R a2929ff08e32fd95eef1d5a44bce177d +P 94f81b51176566409b7d16b30d861f48ad15bb43a145df6e02e0880f7c348109 +R f70af48afc53d25055f1c1dd84b7bed4 U dan -Z 7d2f5d8183adfe209996b488d97e46d6 +Z 726142031de41291f3ae18db2fa43170 diff --git a/manifest.uuid b/manifest.uuid index c48b781edb..4aa36b8a6b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -94f81b51176566409b7d16b30d861f48ad15bb43a145df6e02e0880f7c348109 \ No newline at end of file +4e2dd2a53364f1fed48b995fd5d2642472585f6da5e4735e9da193ba7ff45514 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index a3cf388ff9..0f4b5aaa4d 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8966,7 +8966,7 @@ int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 iKey){ u8 *aOut = pBt->pTmpSpace; /* Pointer to next output buffer */ const u8 *aIn; /* Pointer to next input buffer */ int nIn; /* Size of input buffer aIn[] */ - int nRem; /* Bytes of data still to copy */ + u32 nRem; /* Bytes of data still to copy */ getCellInfo(pSrc); aOut += putVarint32(aOut, pSrc->info.nPayload); diff --git a/test/corruptN.test b/test/corruptN.test new file mode 100644 index 0000000000..4f7667ce1e --- /dev/null +++ b/test/corruptN.test @@ -0,0 +1,106 @@ +# 2020-12-16 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix corruptN + +# These tests deal with corrupt database files +# +database_may_be_corrupt + +reset_db +do_test 1.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +.open --hexdb +| size 4096 pagesize 512 filename sql024239.txt.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 02 00 01 01 00 40 20 20 00 00 00 0c 00 00 00 07 .....@ ........ +| 32: 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 04 ................ +| 48: 00 00 00 00 89 00 00 04 00 10 00 01 0a 00 00 01 ................ +| 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0c ................ +| 96: 00 2e 2c 50 0d 00 00 00 06 01 06 00 01 da 01 b0 ..,P............ +| 112: 01 56 01 86 01 2a 01 06 00 00 00 00 00 00 00 00 .V...*.......... +| 256: 00 00 00 00 00 00 22 07 06 17 11 11 01 31 74 61 .............1ta +| 272: 62 6c 65 74 34 74 34 07 43 52 45 41 54 45 20 54 blet4t4.CREATE T +| 288: 41 42 4c 45 20 74 34 28 78 29 2a 06 06 17 13 11 ABLE t4(x)*..... +| 304: 01 3f 69 6e 64 65 78 74 33 78 74 33 05 43 52 45 .?indext3xt3.CRE +| 320: 41 54 45 20 49 4e 44 45 58 20 74 33 78 20 4f 4e ATE INDEX t3x ON +| 336: 20 74 33 28 78 29 2e 04 06 17 15 11 01 45 69 6e t3(x).......Ein +| 352: 64 65 78 74 32 63 64 74 32 05 43 52 45 41 54 45 dext2cdt2.CREATE +| 368: 20 49 4e 44 45 58 20 74 32 63 64 20 4f 4e 20 74 INDEX t2cd ON t +| 384: 32 28 63 2c 64 29 28 05 06 17 11 11 01 3d 74 61 2(c,d)(......=ta +| 400: 62 6c 65 74 33 74 33 07 43 52 45 41 54 45 20 54 blet3t3.CREATE T +| 416: 41 42 4c 45 20 74 33 28 63 2c 78 2c 65 2c 66 29 ABLE t3(c,x,e,f) +| 432: 28 02 06 17 11 11 01 3d 74 61 62 6c 65 74 32 74 (......=tablet2t +| 448: 32 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 2.CREATE TABLE t +| 464: 32 28 63 2c 64 2c 65 2c 66 29 24 01 06 17 11 11 2(c,d,e,f)$..... +| 480: 01 35 74 61 62 6c 65 74 31 74 31 02 43 52 45 41 .5tablet1t1.CREA +| 496: 54 45 20 54 41 42 4c 45 20 74 31 28 61 2c 62 29 TE TABLE t1(a,b) +| page 2 offset 512 +| 0: 0d 00 00 00 04 01 41 00 01 fa 01 f3 01 de 01 cf ......A......... +| 160: 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 .. ............. +| 448: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0d ................ +| 464: 04 03 17 17 73 65 76 65 6e 65 69 67 68 74 13 03 ....seveneight.. +| 480: 03 07 07 40 14 00 00 00 00 00 00 40 18 00 00 00 ...@.......@.... +| 496: 00 00 00 05 02 03 01 01 03 04 04 01 03 09 01 02 ................ +| page 3 offset 1024 +| 0: 0d 00 00 00 08 01 54 00 01 f7 01 ec 01 c5 01 aa ......T......... +| 16: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 112: 00 00 dd 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 336: 00 00 00 00 19 08 05 17 17 17 17 65 69 67 68 74 ...........eight +| 352: 65 69 67 68 74 73 65 76 65 6e 73 65 76 65 6e 25 eightsevenseven% +| 368: 07 05 07 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 432: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 ................ +| 480: 00 00 0f 04 17 17 01 65 69 67 68 74 65 69 67 68 .......eighteigh +| 496: 74 08 15 04 07 07 01 40 18 00 00 00 00 00 00 40 t......@.......@ +| page 4 offset 1536 +| 0: 18 00 00 00 00 00 00 07 07 04 01 01 01 04 04 06 ................ +| 16: 07 04 01 01 01 02 02 05 0f 04 17 17 01 73 6d 76 .............smv +| 32: 65 6e 65 69 67 68 74 04 15 04 07 07 01 40 14 00 eneight......@.. +| page 5 offset 2048 +| 0: 0a 00 00 00 08 01 96 00 01 fa 01 c4 01 f2 01 bc ................ +| 16: 01 dc 01 e1 01 96 01 cc 00 00 00 00 00 00 00 00 ................ +| 160: 00 00 00 00 00 00 32 00 00 00 00 00 00 00 00 00 ......2......... +| 368: 00 00 00 08 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 400: 00 00 00 00 00 00 0f 04 17 17 01 85 69 67 68 74 ............ight +| 416: 65 69 67 68 74 08 15 04 07 07 01 40 18 00 00 00 eight......@.... +| 432: 00 00 00 40 18 00 00 00 00 00 00 07 07 04 01 01 ...@............ +| 448: 01 04 04 06 07 04 01 01 01 02 02 05 0f 04 17 17 ................ +| 464: 01 73 6d 76 65 6e 65 69 67 68 74 04 15 04 07 07 .smveneight..... +| 480: 01 40 14 00 00 00 00 00 00 40 18 00 00 00 00 00 .@.......@...... +| 496: 00 03 07 04 01 01 01 03 04 02 05 04 03 01 09 02 ................ +| page 6 offset 2560 +| 0: 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 16: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00 ................ +| 304: 00 00 00 26 00 00 00 00 00 00 00 00 00 00 00 00 ...&............ +| page 7 offset 3072 +| 0: 0d 00 00 00 08 01 c2 00 01 fb 01 f6 01 f1 01 ec ................ +| 16: 01 e0 01 d4 01 cb 01 c2 00 00 00 00 00 00 00 00 ................ +| 128: 00 00 00 00 00 00 00 00 00 00 00 00 00 20 00 04 ............. .. +| 384: 00 00 00 00 00 00 00 00 00 07 08 02 17 65 69 fc .............ei. +| 400: 68 74 07 07 02 17 65 69 67 68 74 0a fb fd f8 bf ht....eight..... +| 416: e7 ff ff ff 00 00 00 0a 05 02 07 40 18 00 00 00 ...........@.... +| 432: 00 00 00 03 04 02 01 04 03 03 02 01 04 03 02 01 ................ +| 448: ff ff ff ff ff ff 00 00 00 00 00 00 00 00 00 00 ................ +| end sql024239.txt.db +}]} {} + +do_catchsql_test 1.1 { + VACUUM; +} {1 {database disk image is malformed}} + + +finish_test From 9463d793531c893859c5756741246b0cc5f3e412 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 16 Dec 2020 13:17:32 +0000 Subject: [PATCH 062/257] Fix a typo in the sqlite3_free_filename() documentation. FossilOrigin-Name: 48301edc90fe5811df0394b106edce7726d0ea86ac562c9f4db511b812a76433 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 097c1231bf..fe92f0c21e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sanother\sinteger\soverflow\striggered\sby\sa\scorrupt\sdatabase\sin\srecently\smodified\svacuum\scode. -D 2020-12-15T19:27:20.474 +C Fix\sa\stypo\sin\sthe\ssqlite3_free_filename()\sdocumentation. +D 2020-12-16T13:17:32.129 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -542,7 +542,7 @@ F src/resolve.c 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c c9b68506e5d8cc8d0e4b307b97a9800b050ac37dada80ae9c66f680f8fac3e09 F src/shell.c.in e9f674ee4ec6c345679e8a5b16c869c6c59eb1540dd98ac69e4736ecddce0090 -F src/sqlite.h.in 0e2b4259e49a0eda54d9118eb18a04fcd60e0727a2fd2c81aade0bf57520e706 +F src/sqlite.h.in 5b7593bb0f3658e682a9fcd1cd8fcedf244ec45ca93d645055a53172f55eb783 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e F src/sqliteInt.h ef8b4b3992d9460c9676c4695416f4141d5c5db4d3d78f89d20662361d6e21f1 @@ -1891,7 +1891,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 94f81b51176566409b7d16b30d861f48ad15bb43a145df6e02e0880f7c348109 -R f70af48afc53d25055f1c1dd84b7bed4 -U dan -Z 726142031de41291f3ae18db2fa43170 +P 4e2dd2a53364f1fed48b995fd5d2642472585f6da5e4735e9da193ba7ff45514 +R 3372ddf7c965d76aff4a452b717f27a6 +U drh +Z 51799b847b8818e6198c5e71c210a358 diff --git a/manifest.uuid b/manifest.uuid index 4aa36b8a6b..56b34a6d6e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4e2dd2a53364f1fed48b995fd5d2642472585f6da5e4735e9da193ba7ff45514 \ No newline at end of file +48301edc90fe5811df0394b106edce7726d0ea86ac562c9f4db511b812a76433 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index c975b23351..79eecb4b08 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -3697,7 +3697,7 @@ sqlite3_file *sqlite3_database_file_object(const char*); ** If the Y parameter to sqlite3_free_filename(Y) is anything other ** than a NULL pointer or a pointer previously acquired from ** sqlite3_create_filename(), then bad things such as heap -** corruption or segfaults may occur. The value Y should be +** corruption or segfaults may occur. The value Y should not be ** used again after sqlite3_free_filename(Y) has been called. This means ** that if the [sqlite3_vfs.xOpen()] method of a VFS has been called using Y, ** then the corresponding [sqlite3_module.xClose() method should also be From e5baf5c28351cfaa8daa605e7f066894eac9eef6 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 16 Dec 2020 14:20:45 +0000 Subject: [PATCH 063/257] Remove an unnecessary and incorrect #ifdef. Fix harmless compiler warnings. FossilOrigin-Name: 31cd1bbfa5b06723288d99d1cb423f88353bdef770b82e9103f71a796d66f660 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/btree.c | 4 ++-- src/func.c | 1 + src/sqliteInt.h | 4 +--- 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index fe92f0c21e..89395f093a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sin\sthe\ssqlite3_free_filename()\sdocumentation. -D 2020-12-16T13:17:32.129 +C Remove\san\sunnecessary\sand\sincorrect\s#ifdef.\s\sFix\sharmless\scompiler\swarnings. +D 2020-12-16T14:20:45.731 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -481,7 +481,7 @@ F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c b995dfb6a2d79e2be51ce65a6f54a52f2c327507c35f3f8558d0def711d59298 +F src/btree.c fae82794638b41f4fdd0e49d5196ceaa7848e6666dbbf412eb173c58c4fbf48c F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 F src/build.c f6449d4e85e998e14d3f537e8ea898dca2fcb83c277db3e60945af9b9177db81 @@ -495,7 +495,7 @@ F src/delete.c 927cf8f900583e79aca8f1a321979e0a8f053babd9a690b44b38f79de2cc09fe F src/expr.c 0d196ed5a2ebf96be7e8df88add4fabfad0dce16c0fed81a4b8f6a26e259797f F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 83372403298e6a7dd989a47aaacdbaa5b4307b5199dbd56e07d4896066b3de72 -F src/func.c 04b33016df7f4dcda295f71c6c776e2f49bfe0d50b5c5118240dfcd307d4755d +F src/func.c 2163afb2cfabb71768f9254b95dbab3b7d4cd94394f6cffb86704e0b7e6ccabe F src/global.c ed55af196a9b66e198aaeda3f5454c3aa7d7d050c6c938181fd044b70d180a81 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 @@ -545,7 +545,7 @@ F src/shell.c.in e9f674ee4ec6c345679e8a5b16c869c6c59eb1540dd98ac69e4736ecddce009 F src/sqlite.h.in 5b7593bb0f3658e682a9fcd1cd8fcedf244ec45ca93d645055a53172f55eb783 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h ef8b4b3992d9460c9676c4695416f4141d5c5db4d3d78f89d20662361d6e21f1 +F src/sqliteInt.h 6d8363d245354e360b5efa5f1dc4a7658f252dc80b1c9010264d64dfe77fdf1b F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1891,7 +1891,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 4e2dd2a53364f1fed48b995fd5d2642472585f6da5e4735e9da193ba7ff45514 -R 3372ddf7c965d76aff4a452b717f27a6 +P 48301edc90fe5811df0394b106edce7726d0ea86ac562c9f4db511b812a76433 +R bc270d52af99cca590351162eea6886b U drh -Z 51799b847b8818e6198c5e71c210a358 +Z 53bb33e2ab1210ebb52c38429ca9bfe7 diff --git a/manifest.uuid b/manifest.uuid index 56b34a6d6e..1abcf7fc42 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -48301edc90fe5811df0394b106edce7726d0ea86ac562c9f4db511b812a76433 \ No newline at end of file +31cd1bbfa5b06723288d99d1cb423f88353bdef770b82e9103f71a796d66f660 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 0f4b5aaa4d..9b8005037e 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8965,7 +8965,7 @@ int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 iKey){ BtShared *pBt = pDest->pBt; u8 *aOut = pBt->pTmpSpace; /* Pointer to next output buffer */ const u8 *aIn; /* Pointer to next input buffer */ - int nIn; /* Size of input buffer aIn[] */ + u32 nIn; /* Size of input buffer aIn[] */ u32 nRem; /* Bytes of data still to copy */ getCellInfo(pSrc); @@ -8983,7 +8983,7 @@ int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 iKey){ Pgno ovflIn = 0; DbPage *pPageIn = 0; MemPage *pPageOut = 0; - int nOut; /* Size of output buffer aOut[] */ + u32 nOut; /* Size of output buffer aOut[] */ nOut = btreePayloadToLocal(pDest->pPage, pSrc->info.nPayload); pBt->nPreformatSize = nOut + (aOut - pBt->pTmpSpace); diff --git a/src/func.c b/src/func.c index a29088a68d..e91fc256cb 100644 --- a/src/func.c +++ b/src/func.c @@ -2084,6 +2084,7 @@ static void signFunc( ){ int type0; double x; + UNUSED_PARAMETER(argc); assert( argc==1 ); type0 = sqlite3_value_numeric_type(argv[0]); if( type0!=SQLITE_INTEGER && type0!=SQLITE_FLOAT ) return; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index d91ba49d95..a0e05570e7 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1014,11 +1014,9 @@ extern u32 sqlite3SelectTrace; /* ** Macros for "wheretrace" */ -#if !defined(SQLITE_AMAGAMATION) -extern u32 sqlite3WhereTrace; -#endif #if defined(SQLITE_DEBUG) \ && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE)) +extern u32 sqlite3WhereTrace; # define WHERETRACE(K,X) if(sqlite3WhereTrace&(K)) sqlite3DebugPrintf X # define WHERETRACE_ENABLED 1 #else From de9ed6293de53e89b7c37e7de9a8697d86d7f619 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 16 Dec 2020 20:00:46 +0000 Subject: [PATCH 064/257] Allow sub-queries that use UNION ALL to be flattened, even if the parent query is a join. Still some problems on this branch. FossilOrigin-Name: 00e4bf74d3dfb87666a2266905f7d1a2afc6eb088d22cfd4f38f048733d6b936 --- manifest | 23 +++++++++------ manifest.uuid | 2 +- src/select.c | 64 +++++++++++++++++------------------------ test/selectC.test | 6 ++-- test/unionall.test | 58 +++++++++++++++++++++++++++++++++++++ test/unionallfault.test | 36 +++++++++++++++++++++++ test/whereL.test | 15 +++++----- 7 files changed, 146 insertions(+), 58 deletions(-) create mode 100644 test/unionall.test create mode 100644 test/unionallfault.test diff --git a/manifest b/manifest index 89395f093a..08b4c06499 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\sand\sincorrect\s#ifdef.\s\sFix\sharmless\scompiler\swarnings. -D 2020-12-16T14:20:45.731 +C Allow\ssub-queries\sthat\suse\sUNION\sALL\sto\sbe\sflattened,\seven\sif\sthe\sparent\squery\sis\sa\sjoin.\sStill\ssome\sproblems\son\sthis\sbranch. +D 2020-12-16T20:00:46.479 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -540,7 +540,7 @@ F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c c9b68506e5d8cc8d0e4b307b97a9800b050ac37dada80ae9c66f680f8fac3e09 +F src/select.c 85f02c7d6bcc81c369da37e3c5decf45e326d8a4988b44f7111a06352d9c8830 F src/shell.c.in e9f674ee4ec6c345679e8a5b16c869c6c59eb1540dd98ac69e4736ecddce0090 F src/sqlite.h.in 5b7593bb0f3658e682a9fcd1cd8fcedf244ec45ca93d645055a53172f55eb783 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1331,7 +1331,7 @@ F test/select8.test 8c8f5ae43894c891efc5755ed905467d1d67ad5d F test/select9.test aebc2bb0c3bc44606125033cbcaac2c8d1f33a95 F test/selectA.test 68de52409e45a3313d00b8461b48bef4fb729faf36ade9067a994eae55cc86f4 F test/selectB.test 954e4e49cf1f896d61794e440669e03a27ceea25 -F test/selectC.test e25243f8ca503e06f252eb0218976d07cfeceac3 +F test/selectC.test fec14c9015ed4ec941508bbc144f30b42e40ac34a4bb33001450369865dd0b75 F test/selectD.test fc20452847a01775710090383cfb4423275d2f745fed61f34fbf37573ac0d214 F test/selectE.test a8730ca330fcf40ace158f134f4fe0eb00c7edbf F test/selectF.test 21c94e6438f76537b72532fa9fd4710cdd455fc3 @@ -1627,6 +1627,8 @@ F test/tt3_vacuum.c 1753f45917699c9c1f66b64c717a717c9379f776 F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff F test/types2.test 1aeb81976841a91eef292723649b5c4fe3bc3cac F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a +F test/unionall.test 52a4324f59c70df2525188298a0593d650d983ccbfa9441a8a411ac99e1d6644 +F test/unionallfault.test 8dcc3f680ace498d8d3110ddcfdaa6a3d8aa1843bc7c266b990f13815ee6d7fe F test/unionvtab.test e1704ab1b4c1bb3ffc9da4681f8e85a0b909fd80b937984fc94b27415ac8e5a4 F test/unionvtabfault.test e8759f3d14fb938ce9657e2342db34aeac0fb9bc1692b0d1ebb0069630151d06 F test/unique.test 93f8b2ef5ea51b9495f8d6493429b1fd0f465264 @@ -1741,7 +1743,7 @@ F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2 F test/whereI.test a2874062140ed4aba9ffae76e6190a3df6fc73d1373fdfa8fd632945082a5364 F test/whereJ.test 88287550f6ee604422403b053455b1ad894eeaa5c35d348532dfa1439286cb9a F test/whereK.test f8e3cf26a8513ecc7f514f54df9f0572c046c42b -F test/whereL.test e05cedc9389c6f09ad55bd5999a3fddccebec90672fb989433c145dcdaf26996 +F test/whereL.test 1afe47227f093dc0547236491fb37529b7be9724b8575925a321001b80e6a23a F test/wherefault.test 1374c3aa198388925246475f84ad4cd5f9528864 F test/wherelfault.test 9012e4ef5259058b771606616bd007af5d154e64cc25fa9fd4170f6411db44e3 F test/wherelimit.test 592081800806d297dd7449b1030c863d2883d6d42901837ccd2e5a9bd962edb0 @@ -1891,7 +1893,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 48301edc90fe5811df0394b106edce7726d0ea86ac562c9f4db511b812a76433 -R bc270d52af99cca590351162eea6886b -U drh -Z 53bb33e2ab1210ebb52c38429ca9bfe7 +P 31cd1bbfa5b06723288d99d1cb423f88353bdef770b82e9103f71a796d66f660 +R 1855283db3260c0b82311305192dc3a1 +T *branch * union-all-flattener +T *sym-union-all-flattener * +T -sym-trunk * +U dan +Z cdcd89c0fb8db082c205bd2de653ec39 diff --git a/manifest.uuid b/manifest.uuid index 1abcf7fc42..7304546311 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -31cd1bbfa5b06723288d99d1cb423f88353bdef770b82e9103f71a796d66f660 \ No newline at end of file +00e4bf74d3dfb87666a2266905f7d1a2afc6eb088d22cfd4f38f048733d6b936 \ No newline at end of file diff --git a/src/select.c b/src/select.c index c1eba438f9..24236e6a36 100644 --- a/src/select.c +++ b/src/select.c @@ -3920,7 +3920,7 @@ static int flattenSubquery( if( pSub->pOrderBy ){ return 0; /* Restriction (20) */ } - if( isAgg || (p->selFlags & SF_Distinct)!=0 || pSrc->nSrc!=1 ){ + if( isAgg || (p->selFlags & SF_Distinct)!=0 || isLeftJoin>0 ){ return 0; /* (17d1), (17d2), or (17d3) */ } for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){ @@ -3947,15 +3947,10 @@ static int flattenSubquery( if( p->pOrderBy->a[ii].u.x.iOrderByCol==0 ) return 0; } } - } - /* Ex-restriction (23): - ** The only way that the recursive part of a CTE can contain a compound - ** subquery is for the subquery to be one term of a join. But if the - ** subquery is a join, then the flattening has already been stopped by - ** restriction (17d3) - */ - assert( (p->selFlags & SF_Recursive)==0 || pSub->pPrior==0 ); + /* Restriction (23) */ + if( (p->selFlags & SF_Recursive) ) return 0; + } /***** If we reach this point, flattening is permitted. *****/ SELECTTRACE(1,pParse,p,("flatten %u.%p from term %d\n", @@ -3967,6 +3962,17 @@ static int flattenSubquery( testcase( i==SQLITE_DENY ); pParse->zAuthContext = zSavedAuthContext; + /* Delete the transient structures associated with thesubquery */ + pSub1 = pSubitem->pSelect; + sqlite3DbFree(db, pSubitem->zDatabase); + sqlite3DbFree(db, pSubitem->zName); + sqlite3DbFree(db, pSubitem->zAlias); + pSubitem->zDatabase = 0; + pSubitem->zName = 0; + pSubitem->zAlias = 0; + pSubitem->pSelect = 0; + assert( pSubitem->pOn==0 ); + /* If the sub-query is a compound SELECT statement, then (by restrictions ** 17 and 18 above) it must be a UNION ALL and the parent query must ** be of the form: @@ -4005,15 +4011,16 @@ static int flattenSubquery( ExprList *pOrderBy = p->pOrderBy; Expr *pLimit = p->pLimit; Select *pPrior = p->pPrior; + Table *pItemTab = pSubitem->pTab; + pSubitem->pTab = 0; p->pOrderBy = 0; - p->pSrc = 0; p->pPrior = 0; p->pLimit = 0; pNew = sqlite3SelectDup(db, p, 0); p->pLimit = pLimit; p->pOrderBy = pOrderBy; - p->pSrc = pSrc; p->op = TK_ALL; + pSubitem->pTab = pItemTab; if( pNew==0 ){ p->pPrior = pPrior; }else{ @@ -4024,25 +4031,13 @@ static int flattenSubquery( SELECTTRACE(2,pParse,p,("compound-subquery flattener" " creates %u as peer\n",pNew->selId)); } - if( db->mallocFailed ) return 1; + assert( pSubitem->pSelect==0 ); + if( db->mallocFailed ){ + pSubitem->pSelect = pSub1; + return 1; + } } - /* Begin flattening the iFrom-th entry of the FROM clause - ** in the outer query. - */ - pSub = pSub1 = pSubitem->pSelect; - - /* Delete the transient table structure associated with the - ** subquery - */ - sqlite3DbFree(db, pSubitem->zDatabase); - sqlite3DbFree(db, pSubitem->zName); - sqlite3DbFree(db, pSubitem->zAlias); - pSubitem->zDatabase = 0; - pSubitem->zName = 0; - pSubitem->zAlias = 0; - pSubitem->pSelect = 0; - /* Defer deleting the Table object associated with the ** subquery until code generation is ** complete, since there may still exist Expr.pTab entries that @@ -4075,6 +4070,7 @@ static int flattenSubquery( ** those references with expressions that resolve to the subquery FROM ** elements we are now copying in. */ + pSub = pSub1; for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){ int nSubSrc; u8 jointype = 0; @@ -4083,16 +4079,10 @@ static int flattenSubquery( nSubSrc = pSubSrc->nSrc; /* Number of terms in subquery FROM clause */ pSrc = pParent->pSrc; /* FROM clause of the outer query */ - if( pSrc ){ - assert( pParent==p ); /* First time through the loop */ - jointype = pSubitem->fg.jointype; - }else{ - assert( pParent!=p ); /* 2nd and subsequent times through the loop */ - pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); - if( pSrc==0 ) break; - pParent->pSrc = pSrc; + if( pParent==p ){ + jointype = pSubitem->fg.jointype; /* First time through the loop */ } - + /* The subquery uses a single slot of the FROM clause of the outer ** query. If the subquery has more than one element in its FROM clause, ** then expand the outer query to make space for it to hold all elements diff --git a/test/selectC.test b/test/selectC.test index 4d79963007..63851ca5d7 100644 --- a/test/selectC.test +++ b/test/selectC.test @@ -261,10 +261,10 @@ do_execsql_test 5.2 { } do_execsql_test 5.3 { - SELECT * FROM x1, (SELECT b FROM vvv UNION ALL SELECT c from x3); + SELECT * FROM x1, (SELECT b FROM vvv UNION ALL SELECT c from x3) ORDER BY 1,2; } { - a 21 a 22 a 23 a 24 a 25 a 302 a 303 a 301 - b 21 b 22 b 23 b 24 b 25 b 302 b 303 b 301 + a 21 a 22 a 23 a 24 a 25 a 301 a 302 a 303 + b 21 b 22 b 23 b 24 b 25 b 301 b 302 b 303 } finish_test diff --git a/test/unionall.test b/test/unionall.test new file mode 100644 index 0000000000..d8dc4c2414 --- /dev/null +++ b/test/unionall.test @@ -0,0 +1,58 @@ +# 2020-12-16 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this file is flattening UNION ALL sub-queries. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix unionall + +do_execsql_test 1.0 { + CREATE TABLE t1_a(a INTEGER PRIMARY KEY, b TEXT); + CREATE TABLE t1_b(c INTEGER PRIMARY KEY, d TEXT); + CREATE TABLE t1_c(e INTEGER PRIMARY KEY, f TEXT); + + INSERT INTO t1_a VALUES(1, 'one'), (4, 'four'); + INSERT INTO t1_b VALUES(2, 'two'), (5, 'five'); + INSERT INTO t1_c VALUES(3, 'three'), (6, 'six'); + + CREATE VIEW t1 AS + SELECT a, b FROM t1_a UNION ALL + SELECT c, d FROM t1_b UNION ALL + SELECT e, f FROM t1_c; + + CREATE TABLE i1(x); + INSERT INTO i1 VALUES(2), (5), (6), (1); +} + +do_execsql_test 1.1 { + SELECT a, b FROM ( + SELECT a, b FROM t1_a UNION ALL + SELECT c, d FROM t1_b UNION ALL + SELECT e, f FROM t1_c + ) ORDER BY a +} { + 1 one 2 two 3 three 4 four 5 five 6 six +} + +do_execsql_test 1.2 { + SELECT a, b FROM t1 ORDER BY a +} { + 1 one 2 two 3 three 4 four 5 five 6 six +} + +do_execsql_test 1.3 { + SELECT a, b FROM i1, t1 WHERE a=x ORDER BY a +} {1 one 2 two 5 five 6 six} + + +finish_test diff --git a/test/unionallfault.test b/test/unionallfault.test new file mode 100644 index 0000000000..f9cde26636 --- /dev/null +++ b/test/unionallfault.test @@ -0,0 +1,36 @@ +# 2020-12-16 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix unionallfault + +do_execsql_test 1.0 { + CREATE TABLE t1(x,y,z); + CREATE TABLE t3(x,y,z); +} +faultsim_save_and_close + + +do_faultsim_test 1 -faults oom-t* -prep { + faultsim_restore_and_reopen +} -body { + execsql { + SELECT * FROM ( + SELECT x FROM t1 UNION ALL SELECT y FROM t1 + ) + } +} -test { + faultsim_test_result {0 {}} +} + +finish_test diff --git a/test/whereL.test b/test/whereL.test index fbb424e919..c78ae160b3 100644 --- a/test/whereL.test +++ b/test/whereL.test @@ -26,14 +26,13 @@ do_eqp_test 110 { SELECT * FROM t1, v4 WHERE t1.a=?1 AND v4.a=t1.a; } { QUERY PLAN - |--MATERIALIZE xxxxxx - | `--COMPOUND QUERY - | |--LEFT-MOST SUBQUERY - | | `--SEARCH TABLE t2 USING INDEX sqlite_autoindex_t2_1 (a=?) - | `--UNION ALL - | `--SEARCH TABLE t3 USING INDEX sqlite_autoindex_t3_1 (a=?) - |--SCAN SUBQUERY xxxxxx - `--SEARCH TABLE t1 USING INDEX sqlite_autoindex_t1_1 (a=?) + `--COMPOUND QUERY + |--LEFT-MOST SUBQUERY + | |--SEARCH TABLE t2 USING INDEX sqlite_autoindex_t2_1 (a=?) + | `--SEARCH TABLE t1 USING INDEX sqlite_autoindex_t1_1 (a=?) + `--UNION ALL + |--SEARCH TABLE t3 USING INDEX sqlite_autoindex_t3_1 (a=?) + `--SEARCH TABLE t1 USING INDEX sqlite_autoindex_t1_1 (a=?) } # The scan of the t1 table goes first since that enables the ORDER BY From 0a8b6a9f8f5a1b446cb4217efa37529bcc37bc1d Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 16 Dec 2020 21:09:45 +0000 Subject: [PATCH 065/257] Enhance the sqlite3BtreeTransferRow() routine so that it does more careful checks for corrupt database pages. FossilOrigin-Name: 85952e71175dae73c4e587a3b80783825d91fe8567a819e072da651c1ff4131b --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 6 ++++++ test/fuzzdata8.db | Bin 1616896 -> 1619968 bytes 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 89395f093a..efa169e37a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\sand\sincorrect\s#ifdef.\s\sFix\sharmless\scompiler\swarnings. -D 2020-12-16T14:20:45.731 +C Enhance\sthe\ssqlite3BtreeTransferRow()\sroutine\sso\sthat\sit\sdoes\smore\scareful\nchecks\sfor\scorrupt\sdatabase\spages. +D 2020-12-16T21:09:45.084 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -481,7 +481,7 @@ F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c fae82794638b41f4fdd0e49d5196ceaa7848e6666dbbf412eb173c58c4fbf48c +F src/btree.c 0f9cb686871ae668817673f0823b55d1bcadbc86ea28bd22c590b064a8322d5a F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 F src/build.c f6449d4e85e998e14d3f537e8ea898dca2fcb83c277db3e60945af9b9177db81 @@ -1043,7 +1043,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 f8451a1fd38efbea8c1a7cdf5d02259c4702446a9fabf566becd306b64a50236 +F test/fuzzdata8.db 7f6c5443d67ba040f760b4d28da54cc9f68174fa212ae34ccb86c645de761ec4 F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 @@ -1891,7 +1891,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 48301edc90fe5811df0394b106edce7726d0ea86ac562c9f4db511b812a76433 -R bc270d52af99cca590351162eea6886b +P 31cd1bbfa5b06723288d99d1cb423f88353bdef770b82e9103f71a796d66f660 +R be1e2d0f672e56f934d1c99d7dc679ec U drh -Z 53bb33e2ab1210ebb52c38429ca9bfe7 +Z e48ee7782ade3dd763b30b3828175795 diff --git a/manifest.uuid b/manifest.uuid index 1abcf7fc42..d23f02d0c0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -31cd1bbfa5b06723288d99d1cb423f88353bdef770b82e9103f71a796d66f660 \ No newline at end of file +85952e71175dae73c4e587a3b80783825d91fe8567a819e072da651c1ff4131b \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 9b8005037e..a587332ce2 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8973,6 +8973,9 @@ int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 iKey){ if( pDest->pKeyInfo==0 ) aOut += putVarint(aOut, iKey); nIn = pSrc->info.nLocal; aIn = pSrc->info.pPayload; + if( aIn+nIn>pSrc->pPage->aDataEnd ){ + return SQLITE_CORRUPT_BKPT; + } nRem = pSrc->info.nPayload; if( nIn==nRem && nInpPage->maxLocal ){ memcpy(aOut, aIn, nIn); @@ -8993,6 +8996,9 @@ int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 iKey){ } if( nRem>nIn ){ + if( aIn+nIn+4>pSrc->pPage->aDataEnd ){ + return SQLITE_CORRUPT_BKPT; + } ovflIn = get4byte(&pSrc->info.pPayload[nIn]); } diff --git a/test/fuzzdata8.db b/test/fuzzdata8.db index 39191fc8b1f03935f6b661eab5af1e2e2fba7285..47d0d5a165f0d64501d44be2fe3902b232d67776 100644 GIT binary patch delta 25797 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 E-@|?Jw*UYD delta 23001 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 From 13dd0228d318e98346adc1b4021d44dfd8869a7a Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 17 Dec 2020 11:24:26 +0000 Subject: [PATCH 066/257] Fix a problem with sqlite3_expanded_sql() that could occur with statements that use both numbered (e.g. "?1") and unnumbered (i.e. "?") parameters. FossilOrigin-Name: 2a6cd6833e44dd6a2ac388815f43be6508f6fa6db5e451e964276a6c87e6c5ae --- manifest | 16 +++++----- manifest.uuid | 2 +- src/vdbetrace.c | 2 +- test/trace3.test | 79 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index efa169e37a..d48de5b388 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\ssqlite3BtreeTransferRow()\sroutine\sso\sthat\sit\sdoes\smore\scareful\nchecks\sfor\scorrupt\sdatabase\spages. -D 2020-12-16T21:09:45.084 +C Fix\sa\sproblem\swith\ssqlite3_expanded_sql()\sthat\scould\soccur\swith\sstatements\sthat\suse\sboth\snumbered\s(e.g.\s"?1")\sand\sunnumbered\s(i.e.\s"?")\sparameters. +D 2020-12-17T11:24:26.721 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -620,7 +620,7 @@ F src/vdbeaux.c c76b7e96e189f5056d1de914d33d07bd03d3b88741f75375c8e18c9b11ffd379 F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1 F src/vdbemem.c 947f2a65910edb4014dc981d33e414a68c51f169f9df8c4c493a0ba840b6eb1f F src/vdbesort.c f5b5e473a7cee44e47a94817b042fd7172cf3aa2c0a7928a8339d612bcfdec5a -F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0 +F src/vdbetrace.c 666c6fd9f1b62be6999e072a45b913e3c2c3518bc60dfd4d54fe304130acb724 F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c F src/vtab.c 5f5fc793092f53bbdfde296c50f563fb7bda58cf48e9cf6a8bdfbc5abd409845 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 @@ -1595,7 +1595,7 @@ F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7 F test/tpch01.test 7c4eb8cdd79c568f46d344b3e789c9fdb8a766d112871352704861f3fca32a2a F test/trace.test a659a9862957f4789e37a92b3bf6d2caf5c86b02cdeefc41e850ae53acf6992a F test/trace2.test f5cb67ad3bc09e0c58e8cca78dfd0b5639259983 -F test/trace3.test 1dff966888773ff1bfea01c080caf15417892b3f998408fe920c4791f7337144 +F test/trace3.test ae2004df24b585fed9046cc0bae4601762bc6fc4aa321d475f1350bba5047f31 F test/trans.test 45f6f9ab6f66a7b5744f1caac06b558f95da62501916906cf55586a896f9f439 F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76 F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94 @@ -1891,7 +1891,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 31cd1bbfa5b06723288d99d1cb423f88353bdef770b82e9103f71a796d66f660 -R be1e2d0f672e56f934d1c99d7dc679ec -U drh -Z e48ee7782ade3dd763b30b3828175795 +P 85952e71175dae73c4e587a3b80783825d91fe8567a819e072da651c1ff4131b +R 8413851e616b40793979ba3b0b321ea0 +U dan +Z a9095f79474677b3701cc55eacd5797f diff --git a/manifest.uuid b/manifest.uuid index d23f02d0c0..550b66bf87 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -85952e71175dae73c4e587a3b80783825d91fe8567a819e072da651c1ff4131b \ No newline at end of file +2a6cd6833e44dd6a2ac388815f43be6508f6fa6db5e451e964276a6c87e6c5ae \ No newline at end of file diff --git a/src/vdbetrace.c b/src/vdbetrace.c index 32c66af228..1095e7f589 100644 --- a/src/vdbetrace.c +++ b/src/vdbetrace.c @@ -125,7 +125,7 @@ char *sqlite3VdbeExpandSql( assert( idx>0 ); } zRawSql += nToken; - nextIndex = idx + 1; + nextIndex = MAX(idx + 1, nextIndex); assert( idx>0 && idx<=p->nVar ); pVar = &p->aVar[idx-1]; if( pVar->flags & MEM_Null ){ diff --git a/test/trace3.test b/test/trace3.test index 538dcd0942..e9935acfb8 100644 --- a/test/trace3.test +++ b/test/trace3.test @@ -251,4 +251,83 @@ do_test trace3-11.2 { set ::stmtlist(record) } {/^-?\d+$/} +#------------------------------------------------------------------------- +reset_db +do_test 12.1.0 { + set ::STMT [sqlite3_prepare_v2 $DB \ + "SELECT ?1 || ?1 || ?1 || ?2 || ?3 || ?4 || ? || ?1 || ?" -1 TAIL + ] + sqlite3_bind_parameter_count $::STMT +} {6} + +do_test 12.1.1 { + sqlite3_bind_text $STMT 1 "A" 1 + sqlite3_bind_text $STMT 2 "B" 1 + sqlite3_bind_text $STMT 3 "C" 1 + sqlite3_bind_text $STMT 4 "D" 1 + sqlite3_bind_text $STMT 5 "E" 1 + sqlite3_bind_text $STMT 6 "F" 1 + sqlite3_expanded_sql $STMT +} {SELECT 'A' || 'A' || 'A' || 'B' || 'C' || 'D' || 'E' || 'A' || 'F'} + +do_test 12.1.2 { + sqlite3_step $STMT + sqlite3_column_text $STMT 0 +} {AAABCDEAF} + +do_test 12.1.3 { + sqlite3_finalize $STMT +} {SQLITE_OK} + +do_test 12.2.0 { + execsql { + CREATE TABLE nameFtsFuzzySearchTable( + word, distance, langid, score, top, scope + ); + } + set ::STMT [sqlite3_prepare_v2 $DB { + SELECT + substr(word,1,length(?1)-1) AS term, + distance, + langid, + score + FROM + nameFtsFuzzySearchTable + WHERE + word MATCH (?1) AND abs(?1) = abs(term) + AND top = ?2 AND distance > ?3 AND scope = ?4 AND langid = ? + GROUP BY term, langid + HAVING (1.0 - ((distance / 100.0) / CAST( length(?1) - 1 AS REAL ))) >= ? + } -1 TAIL] + sqlite3_bind_parameter_count $::STMT +} {6} + +do_test 12.1.1 { + sqlite3_bind_text $STMT 1 "A" 1 + sqlite3_bind_text $STMT 2 "B" 1 + sqlite3_bind_text $STMT 3 "C" 1 + sqlite3_bind_text $STMT 4 "D" 1 + sqlite3_bind_text $STMT 5 "E" 1 + sqlite3_bind_text $STMT 6 "F" 1 + sqlite3_expanded_sql $STMT +} { + SELECT + substr(word,1,length('A')-1) AS term, + distance, + langid, + score + FROM + nameFtsFuzzySearchTable + WHERE + word MATCH ('A') AND abs('A') = abs(term) + AND top = 'B' AND distance > 'C' AND scope = 'D' AND langid = 'E' + GROUP BY term, langid + HAVING (1.0 - ((distance / 100.0) / CAST( length('A') - 1 AS REAL ))) >= 'F' + } + +do_test 12.1.2 { + sqlite3_finalize $STMT +} {SQLITE_OK} + + finish_test From 18a4bbdf63e11c30acec5419ac6f69ea08fa127b Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 17 Dec 2020 15:17:42 +0000 Subject: [PATCH 067/257] In the CLI, add the ".filectrl data_version" command. And put the various ".filectrl" subcommands in alphabetical order. FossilOrigin-Name: 3434452148eef39ba3ba2f40a6fedb6ec4f5157cbc2763b3ec90ec7f2b126382 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c.in | 14 ++++++++------ 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index d48de5b388..1e99f333c3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\ssqlite3_expanded_sql()\sthat\scould\soccur\swith\sstatements\sthat\suse\sboth\snumbered\s(e.g.\s"?1")\sand\sunnumbered\s(i.e.\s"?")\sparameters. -D 2020-12-17T11:24:26.721 +C In\sthe\sCLI,\sadd\sthe\s".filectrl\sdata_version"\scommand.\s\sAnd\sput\sthe\svarious\n".filectrl"\ssubcommands\sin\salphabetical\sorder. +D 2020-12-17T15:17:42.367 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -541,7 +541,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c c9b68506e5d8cc8d0e4b307b97a9800b050ac37dada80ae9c66f680f8fac3e09 -F src/shell.c.in e9f674ee4ec6c345679e8a5b16c869c6c59eb1540dd98ac69e4736ecddce0090 +F src/shell.c.in 6dd0d9260220f807d6d1b8e57dd6e163fe55bd0e97fa416c8c139162e3416134 F src/sqlite.h.in 5b7593bb0f3658e682a9fcd1cd8fcedf244ec45ca93d645055a53172f55eb783 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e @@ -1891,7 +1891,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 85952e71175dae73c4e587a3b80783825d91fe8567a819e072da651c1ff4131b -R 8413851e616b40793979ba3b0b321ea0 -U dan -Z a9095f79474677b3701cc55eacd5797f +P 2a6cd6833e44dd6a2ac388815f43be6508f6fa6db5e451e964276a6c87e6c5ae +R 8fec60d5d4f6323f9e214e52e3dfbcc8 +U drh +Z 8df200953f9823684b5ad2b1a02406fd diff --git a/manifest.uuid b/manifest.uuid index 550b66bf87..c23f193a3e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2a6cd6833e44dd6a2ac388815f43be6508f6fa6db5e451e964276a6c87e6c5ae \ No newline at end of file +3434452148eef39ba3ba2f40a6fedb6ec4f5157cbc2763b3ec90ec7f2b126382 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index dbdba271cd..80bc261fcc 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -7863,16 +7863,17 @@ static int do_meta_command(char *zLine, ShellState *p){ int ctrlCode; /* Integer code for that option */ const char *zUsage; /* Usage notes */ } aCtrl[] = { - { "size_limit", SQLITE_FCNTL_SIZE_LIMIT, "[LIMIT]" }, { "chunk_size", SQLITE_FCNTL_CHUNK_SIZE, "SIZE" }, - /* { "win32_av_retry", SQLITE_FCNTL_WIN32_AV_RETRY, "COUNT DELAY" },*/ - { "persist_wal", SQLITE_FCNTL_PERSIST_WAL, "[BOOLEAN]" }, - { "psow", SQLITE_FCNTL_POWERSAFE_OVERWRITE, "[BOOLEAN]" }, - /* { "pragma", SQLITE_FCNTL_PRAGMA, "NAME ARG" },*/ - { "tempfilename", SQLITE_FCNTL_TEMPFILENAME, "" }, + { "data_version", SQLITE_FCNTL_DATA_VERSION, "" }, { "has_moved", SQLITE_FCNTL_HAS_MOVED, "" }, { "lock_timeout", SQLITE_FCNTL_LOCK_TIMEOUT, "MILLISEC" }, + { "persist_wal", SQLITE_FCNTL_PERSIST_WAL, "[BOOLEAN]" }, + /* { "pragma", SQLITE_FCNTL_PRAGMA, "NAME ARG" },*/ + { "psow", SQLITE_FCNTL_POWERSAFE_OVERWRITE, "[BOOLEAN]" }, { "reserve_bytes", SQLITE_FCNTL_RESERVE_BYTES, "[N]" }, + { "size_limit", SQLITE_FCNTL_SIZE_LIMIT, "[LIMIT]" }, + { "tempfilename", SQLITE_FCNTL_TEMPFILENAME, "" }, + /* { "win32_av_retry", SQLITE_FCNTL_WIN32_AV_RETRY, "COUNT DELAY" },*/ }; int filectrl = -1; int iCtrl = -1; @@ -7959,6 +7960,7 @@ static int do_meta_command(char *zLine, ShellState *p){ isOk = 1; break; } + case SQLITE_FCNTL_DATA_VERSION: case SQLITE_FCNTL_HAS_MOVED: { int x; if( nArg!=2 ) break; From 8daf5ae2eda2260b17a5ff3df445b29ad1be90e8 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 17 Dec 2020 16:48:04 +0000 Subject: [PATCH 068/257] Add test cases and minor fixes to this branch. FossilOrigin-Name: 5d6dc29d5f81738b07e4fee652fb2343fc409c2545f2f4667e8ee82d1a75f721 --- manifest | 17 +++---- manifest.uuid | 2 +- src/select.c | 14 +++--- test/unionall.test | 112 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 127 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 08b4c06499..5e496dbf03 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\ssub-queries\sthat\suse\sUNION\sALL\sto\sbe\sflattened,\seven\sif\sthe\sparent\squery\sis\sa\sjoin.\sStill\ssome\sproblems\son\sthis\sbranch. -D 2020-12-16T20:00:46.479 +C Add\stest\scases\sand\sminor\sfixes\sto\sthis\sbranch. +D 2020-12-17T16:48:04.003 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -540,7 +540,7 @@ F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 85f02c7d6bcc81c369da37e3c5decf45e326d8a4988b44f7111a06352d9c8830 +F src/select.c f80a2081645e3e841417f2d280ba7badfe44cee2537376035bf3dfb5f2fbdf73 F src/shell.c.in e9f674ee4ec6c345679e8a5b16c869c6c59eb1540dd98ac69e4736ecddce0090 F src/sqlite.h.in 5b7593bb0f3658e682a9fcd1cd8fcedf244ec45ca93d645055a53172f55eb783 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1627,7 +1627,7 @@ F test/tt3_vacuum.c 1753f45917699c9c1f66b64c717a717c9379f776 F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff F test/types2.test 1aeb81976841a91eef292723649b5c4fe3bc3cac F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a -F test/unionall.test 52a4324f59c70df2525188298a0593d650d983ccbfa9441a8a411ac99e1d6644 +F test/unionall.test d2a6956fa3f01e0566b2cb81b2eea6e10be67c54ca1b1623685c6dbff8bd465b F test/unionallfault.test 8dcc3f680ace498d8d3110ddcfdaa6a3d8aa1843bc7c266b990f13815ee6d7fe F test/unionvtab.test e1704ab1b4c1bb3ffc9da4681f8e85a0b909fd80b937984fc94b27415ac8e5a4 F test/unionvtabfault.test e8759f3d14fb938ce9657e2342db34aeac0fb9bc1692b0d1ebb0069630151d06 @@ -1893,10 +1893,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 31cd1bbfa5b06723288d99d1cb423f88353bdef770b82e9103f71a796d66f660 -R 1855283db3260c0b82311305192dc3a1 -T *branch * union-all-flattener -T *sym-union-all-flattener * -T -sym-trunk * +P 00e4bf74d3dfb87666a2266905f7d1a2afc6eb088d22cfd4f38f048733d6b936 +R 4cf81f06ce809058bd00b1e229a42929 U dan -Z cdcd89c0fb8db082c205bd2de653ec39 +Z 4e0770b4a8bae0abb40b2b1a928fba76 diff --git a/manifest.uuid b/manifest.uuid index 7304546311..03481edead 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -00e4bf74d3dfb87666a2266905f7d1a2afc6eb088d22cfd4f38f048733d6b936 \ No newline at end of file +5d6dc29d5f81738b07e4fee652fb2343fc409c2545f2f4667e8ee82d1a75f721 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 24236e6a36..81db65167e 100644 --- a/src/select.c +++ b/src/select.c @@ -3743,9 +3743,9 @@ static void recomputeColumnsUsed( ** (17c) every term within the subquery compound must have a FROM clause ** (17d) the outer query may not be ** (17d1) aggregate, or -** (17d2) DISTINCT, or -** (17d3) a join. -** (17e) the subquery may not contain window functions +** (17d2) DISTINCT +** (17e) the subquery may not contain window functions, and +** (17f) the subquery must not be the RHS of a LEFT JOIN. ** ** The parent and sub-query may contain WHERE clauses. Subject to ** rules (11), (13) and (14), they may also contain ORDER BY, @@ -3778,9 +3778,8 @@ static void recomputeColumnsUsed( ** ** (22) The subquery may not be a recursive CTE. ** -** (**) Subsumed into restriction (17d3). Was: If the outer query is -** a recursive CTE, then the sub-query may not be a compound query. -** This restriction is because transforming the +** (23) If the outer query is a recursive CTE, then the sub-query may not be +** a compound query. This restriction is because transforming the ** parent to a compound query confuses the code that handles ** recursive queries in multiSelect(). ** @@ -3921,12 +3920,13 @@ static int flattenSubquery( return 0; /* Restriction (20) */ } if( isAgg || (p->selFlags & SF_Distinct)!=0 || isLeftJoin>0 ){ - return 0; /* (17d1), (17d2), or (17d3) */ + return 0; /* (17d1), (17d2), or (17f) */ } for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){ testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct ); testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate ); assert( pSub->pSrc!=0 ); + assert( (pSub->selFlags & SF_Recursive)==0 ); assert( pSub->pEList->nExpr==pSub1->pEList->nExpr ); if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0 /* (17b) */ || (pSub1->pPrior && pSub1->op!=TK_ALL) /* (17a) */ diff --git a/test/unionall.test b/test/unionall.test index d8dc4c2414..43b24a455f 100644 --- a/test/unionall.test +++ b/test/unionall.test @@ -55,4 +55,116 @@ do_execsql_test 1.3 { } {1 one 2 two 5 five 6 six} +#------------------------------------------------------------------------- +reset_db + +do_execsql_test 2.1.0 { + CREATE TABLE t1(x, y); + INSERT INTO t1 VALUES(1, 'one'); + INSERT INTO t1 VALUES(1, 'ONE'); + INSERT INTO t1 VALUES(2, 'two'); + INSERT INTO t1 VALUES(2, 'TWO'); + INSERT INTO t1 VALUES(3, 'three'); + INSERT INTO t1 VALUES(3, 'THREE'); +} + +do_execsql_test 2.1.1 { + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<3 + ) + SELECT * FROM ( + SELECT 0 AS i UNION ALL SELECT i FROM s UNION ALL SELECT 0 + ), t1 WHERE x=i; +} { + 1 1 one 1 1 ONE 2 2 two 2 2 TWO 3 3 three 3 3 THREE +} + +do_catchsql_test 2.1.2 { + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<3 UNION ALL SELECT 4 + ) + SELECT * FROM s, t1 WHERE x=i; +} {1 {circular reference: s}} + +do_execsql_test 2.2.0 { + CREATE TABLE t2_a(k INTEGER PRIMARY KEY, v TEXT); + CREATE TABLE t2_b(k INTEGER PRIMARY KEY, v TEXT); + + CREATE VIEW t2 AS + SELECT * FROM t2_a + UNION ALL + SELECT * FROM t2_b; + + CREATE TRIGGER t2_insert INSTEAD OF INSERT ON t2 BEGIN + INSERT INTO t2_a SELECT new.k, new.v WHERE (new.k%2)==0; + INSERT INTO t2_b SELECT new.k, new.v WHERE (new.k%2)==1; + END; + + INSERT INTO t2 VALUES(5, 'v'), (4, 'iv'), (3, 'iii'), (2, 'ii'); +} + +do_execsql_test 2.2.1 { + SELECT * FROM t1, t2 WHERE x=k; +} { + 2 two 2 ii 2 TWO 2 ii 3 three 3 iii 3 THREE 3 iii +} + +do_execsql_test 2.2.2 { + SELECT * FROM t1 LEFT JOIN t2 ON (x=k); +} { + 1 one {} {} + 1 ONE {} {} + 2 two 2 ii 2 TWO 2 ii 3 three 3 iii 3 THREE 3 iii +} + +do_execsql_test 2.2.3 { + SELECT x1.*, x2.* FROM t2 AS x1, t2 AS x2 WHERE x1.k=x2.k+1 +} { + 4 iv 3 iii + 3 iii 2 ii + 5 v 4 iv +} + +do_execsql_test 2.2.4 { + SELECT * FROM t1, t2 WHERE x=k ORDER BY y; +} { + 3 THREE 3 iii + 2 TWO 2 ii + 3 three 3 iii + 2 two 2 ii +} +do_execsql_test 2.2.5 { + SELECT * FROM t1, t2 WHERE x=k ORDER BY y||''; +} { + 3 THREE 3 iii + 2 TWO 2 ii + 3 three 3 iii + 2 two 2 ii +} +do_execsql_test 2.2.6 { + SELECT * FROM t1, t2 WHERE x=k ORDER BY v +} { + 2 two 2 ii + 2 TWO 2 ii + 3 three 3 iii + 3 THREE 3 iii +} +do_execsql_test 2.2.7 { + SELECT * FROM t1, t2 WHERE x=k ORDER BY v||'' +} { + 2 two 2 ii + 2 TWO 2 ii + 3 three 3 iii + 3 THREE 3 iii +} +do_execsql_test 2.2.8 { + SELECT * FROM t1, t2 WHERE x=k ORDER BY k,v||'' +} { + 2 two 2 ii + 2 TWO 2 ii + 3 three 3 iii + 3 THREE 3 iii +} + + finish_test From 9353beaff1f236487f07378892c440a8245470aa Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 17 Dec 2020 17:17:12 +0000 Subject: [PATCH 069/257] Fix a part of the header comment for flattenSubquery(). FossilOrigin-Name: dc0937ce9d5569e3409b2b036a9f15b896125f4eb2eec30e3f0bbe4a92bcd0ad --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 5e496dbf03..8381f8dd8d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\scases\sand\sminor\sfixes\sto\sthis\sbranch. -D 2020-12-17T16:48:04.003 +C Fix\sa\spart\sof\sthe\sheader\scomment\sfor\sflattenSubquery(). +D 2020-12-17T17:17:12.113 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -540,7 +540,7 @@ F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c f80a2081645e3e841417f2d280ba7badfe44cee2537376035bf3dfb5f2fbdf73 +F src/select.c a9c7607d8fe60e17df2b8839abad2e333b306e40e0b20e53747b3dcf600832ec F src/shell.c.in e9f674ee4ec6c345679e8a5b16c869c6c59eb1540dd98ac69e4736ecddce0090 F src/sqlite.h.in 5b7593bb0f3658e682a9fcd1cd8fcedf244ec45ca93d645055a53172f55eb783 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1893,7 +1893,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 00e4bf74d3dfb87666a2266905f7d1a2afc6eb088d22cfd4f38f048733d6b936 -R 4cf81f06ce809058bd00b1e229a42929 +P 5d6dc29d5f81738b07e4fee652fb2343fc409c2545f2f4667e8ee82d1a75f721 +R 856c8700228bcdbf610d5cdb34881db9 U dan -Z 4e0770b4a8bae0abb40b2b1a928fba76 +Z d0c22076b1f40da6b64269c66f6c133c diff --git a/manifest.uuid b/manifest.uuid index 03481edead..3ab5a1e229 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5d6dc29d5f81738b07e4fee652fb2343fc409c2545f2f4667e8ee82d1a75f721 \ No newline at end of file +dc0937ce9d5569e3409b2b036a9f15b896125f4eb2eec30e3f0bbe4a92bcd0ad \ No newline at end of file diff --git a/src/select.c b/src/select.c index 81db65167e..d6cd724ae0 100644 --- a/src/select.c +++ b/src/select.c @@ -3761,8 +3761,8 @@ static void recomputeColumnsUsed( ** syntax error and return a detailed message. ** ** (18) If the sub-query is a compound select, then all terms of the -** ORDER BY clause of the parent must be simple references to -** columns of the sub-query. +** ORDER BY clause of the parent must be copies of a term returned +** by the parent query. ** ** (19) If the subquery uses LIMIT then the outer query may not ** have a WHERE clause. From 964fa26e0c81e999950ce1f9b95e0547e93fdf5d Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 18 Dec 2020 16:13:39 +0000 Subject: [PATCH 070/257] When flattening UNION ALL subqueries into a join query, ensure that separate cursor numbers are used for each segment of the newly flattened query. FossilOrigin-Name: c510377b0b052e400f2ee4f20220b61cdf74ee44b9bb9e6490787c88dd4c55aa --- manifest | 16 +++---- manifest.uuid | 2 +- src/select.c | 97 +++++++++++++++++++++++++++++++++++++++-- test/unionall.test | 31 +++++++++++++ test/unionallfault.test | 4 +- 5 files changed, 135 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 8381f8dd8d..be6d22c043 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\spart\sof\sthe\sheader\scomment\sfor\sflattenSubquery(). -D 2020-12-17T17:17:12.113 +C When\sflattening\sUNION\sALL\ssubqueries\sinto\sa\sjoin\squery,\sensure\sthat\sseparate\scursor\snumbers\sare\sused\sfor\seach\ssegment\sof\sthe\snewly\sflattened\squery. +D 2020-12-18T16:13:39.603 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -540,7 +540,7 @@ F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c a9c7607d8fe60e17df2b8839abad2e333b306e40e0b20e53747b3dcf600832ec +F src/select.c 7282b1a0fc81ce3c61c988b228b63b45a5521254033370d1ad6bf3366b5c2788 F src/shell.c.in e9f674ee4ec6c345679e8a5b16c869c6c59eb1540dd98ac69e4736ecddce0090 F src/sqlite.h.in 5b7593bb0f3658e682a9fcd1cd8fcedf244ec45ca93d645055a53172f55eb783 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1627,8 +1627,8 @@ F test/tt3_vacuum.c 1753f45917699c9c1f66b64c717a717c9379f776 F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff F test/types2.test 1aeb81976841a91eef292723649b5c4fe3bc3cac F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a -F test/unionall.test d2a6956fa3f01e0566b2cb81b2eea6e10be67c54ca1b1623685c6dbff8bd465b -F test/unionallfault.test 8dcc3f680ace498d8d3110ddcfdaa6a3d8aa1843bc7c266b990f13815ee6d7fe +F test/unionall.test 6676ff915eced719e7010149d758ba85665c0aef6a782e693b6fb5e83fb4e4e1 +F test/unionallfault.test 652bfbb630e6c43135965dc1e8f0a9a791da83aec885d626a632fe1909c56f73 F test/unionvtab.test e1704ab1b4c1bb3ffc9da4681f8e85a0b909fd80b937984fc94b27415ac8e5a4 F test/unionvtabfault.test e8759f3d14fb938ce9657e2342db34aeac0fb9bc1692b0d1ebb0069630151d06 F test/unique.test 93f8b2ef5ea51b9495f8d6493429b1fd0f465264 @@ -1893,7 +1893,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 5d6dc29d5f81738b07e4fee652fb2343fc409c2545f2f4667e8ee82d1a75f721 -R 856c8700228bcdbf610d5cdb34881db9 +P dc0937ce9d5569e3409b2b036a9f15b896125f4eb2eec30e3f0bbe4a92bcd0ad +R d7f9897a9bbc548d53ddd8cd562a8b6a U dan -Z d0c22076b1f40da6b64269c66f6c133c +Z aa626afff11dd6191a903497d2bb6cf2 diff --git a/manifest.uuid b/manifest.uuid index 3ab5a1e229..dcf4a244f3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dc0937ce9d5569e3409b2b036a9f15b896125f4eb2eec30e3f0bbe4a92bcd0ad \ No newline at end of file +c510377b0b052e400f2ee4f20220b61cdf74ee44b9bb9e6490787c88dd4c55aa \ No newline at end of file diff --git a/src/select.c b/src/select.c index d6cd724ae0..bc5f17ecb2 100644 --- a/src/select.c +++ b/src/select.c @@ -3649,6 +3649,86 @@ static void recomputeColumnsUsed( } #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) +/* +** Assign new cursor numbers to each of the items in pSrc. For each +** new cursor number assigned, set an entry in the aCsrMap[] array +** to map the old cursor number to the new: +** +** aCsrMap[iOld] = iNew; +** +** The array is guaranteed by the caller to be large enough for all +** existing cursor numbers in pSrc. +** +** If pSrc contains any sub-selects, call this routine recursively +** on the FROM clause of each such sub-select, with iExcept set to -1. +*/ +static void srclistRenumberCursors( + Parse *pParse, /* Parse context */ + int *aCsrMap, /* Array to store cursor mappings in */ + SrcList *pSrc, /* FROM clause to renumber */ + int iExcept /* FROM clause item to skip */ +){ + int i; + struct SrcList_item *pItem; + for(i=0, pItem=pSrc->a; inSrc; i++, pItem++){ + if( i!=iExcept ){ + int iNew = pParse->nTab++; + aCsrMap[pItem->iCursor] = iNew; + pItem->iCursor = iNew; + if( pItem->pSelect ){ + srclistRenumberCursors(pParse, aCsrMap, pItem->pSelect->pSrc, -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; + if( pExpr->op==TK_COLUMN && aCsrMap[pExpr->iTable] ){ + pExpr->iTable = aCsrMap[pExpr->iTable]; + } + return WRC_Continue; +} + +/* +** Assign a new cursor number to each cursor in the FROM clause (Select.pSrc) +** of the SELECT statement passed as the second argument, and to each +** cursor in the FROM clause of any FROM clause sub-selects, recursively. +** Except, do not assign a new cursor number to the iExcept'th element in +** the FROM clause of (*p). Update all expressions and other references +** to refer to the new cursor numbers. +** +** Argument aCsrMap is an array that may be used for temporary working +** space. Two guarantees are made by the caller: +** +** * the array is larger than the largest cursor number used within the +** select statement passed as an argument, and +** +** * the array entries for all cursor numbers that do *not* appear in +** FROM clauses of the select statement as described above are +** initialized to zero. +*/ +static void renumberCursors( + Parse *pParse, /* Parse context */ + Select *p, /* Select to renumber cursors within */ + int iExcept, /* FROM clause item to skip */ + int *aCsrMap /* Working space */ +){ + Walker w; + srclistRenumberCursors(pParse, aCsrMap, p->pSrc, iExcept); + memset(&w, 0, sizeof(w)); + w.u.aiCol = aCsrMap; + w.xExprCallback = renumberCursorsCb; + w.xSelectCallback = sqlite3SelectWalkNoop; + sqlite3WalkSelect(&w, p); +} +#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ + #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) /* ** This routine attempts to flatten subqueries as a performance optimization. @@ -3824,6 +3904,7 @@ static int flattenSubquery( struct SrcList_item *pSubitem; /* The subquery */ sqlite3 *db = pParse->db; Walker w; /* Walker to persist agginfo data */ + int *aCsrMap = 0; /* Check to see if flattening is permitted. Return 0 if not. */ @@ -3950,6 +4031,10 @@ static int flattenSubquery( /* Restriction (23) */ if( (p->selFlags & SF_Recursive) ) return 0; + + if( pSrc->nSrc>1 ){ + aCsrMap = sqlite3DbMallocZero(db, pParse->nTab*sizeof(int)); + } } /***** If we reach this point, flattening is permitted. *****/ @@ -4024,6 +4109,9 @@ static int flattenSubquery( if( pNew==0 ){ p->pPrior = pPrior; }else{ + if( aCsrMap && db->mallocFailed==0 ){ + renumberCursors(pParse, pNew, iFrom, aCsrMap); + } pNew->pPrior = pPrior; if( pPrior ) pPrior->pNext = pNew; pNew->pNext = p; @@ -4032,10 +4120,11 @@ static int flattenSubquery( " creates %u as peer\n",pNew->selId)); } assert( pSubitem->pSelect==0 ); - if( db->mallocFailed ){ - pSubitem->pSelect = pSub1; - return 1; - } + } + sqlite3DbFree(db, aCsrMap); + if( db->mallocFailed ){ + pSubitem->pSelect = pSub1; + return 1; } /* Defer deleting the Table object associated with the diff --git a/test/unionall.test b/test/unionall.test index 43b24a455f..0098cf15a4 100644 --- a/test/unionall.test +++ b/test/unionall.test @@ -165,6 +165,37 @@ do_execsql_test 2.2.8 { 3 three 3 iii 3 THREE 3 iii } +do_execsql_test 2.2.9a { + SELECT * FROM t1, t2 ORDER BY +k +} { + 1 one 2 ii 1 ONE 2 ii 2 two 2 ii + 2 TWO 2 ii 3 three 2 ii 3 THREE 2 ii + + 1 one 3 iii 1 ONE 3 iii 2 two 3 iii + 2 TWO 3 iii 3 three 3 iii 3 THREE 3 iii + + 1 one 4 iv 1 ONE 4 iv 2 two 4 iv + 2 TWO 4 iv 3 three 4 iv 3 THREE 4 iv + + 1 one 5 v 1 ONE 5 v 2 two 5 v + 2 TWO 5 v 3 three 5 v 3 THREE 5 v +} + +do_execsql_test 2.2.9b { + SELECT * FROM t1, t2 ORDER BY k +} { + 1 one 2 ii 1 ONE 2 ii 2 two 2 ii + 2 TWO 2 ii 3 three 2 ii 3 THREE 2 ii + + 1 one 3 iii 1 ONE 3 iii 2 two 3 iii + 2 TWO 3 iii 3 three 3 iii 3 THREE 3 iii + + 1 one 4 iv 1 ONE 4 iv 2 two 4 iv + 2 TWO 4 iv 3 three 4 iv 3 THREE 4 iv + + 1 one 5 v 1 ONE 5 v 2 two 5 v + 2 TWO 5 v 3 three 5 v 3 THREE 5 v +} finish_test diff --git a/test/unionallfault.test b/test/unionallfault.test index f9cde26636..c78abe548c 100644 --- a/test/unionallfault.test +++ b/test/unionallfault.test @@ -25,9 +25,9 @@ do_faultsim_test 1 -faults oom-t* -prep { faultsim_restore_and_reopen } -body { execsql { - SELECT * FROM ( + SELECT * FROM t1, ( SELECT x FROM t1 UNION ALL SELECT y FROM t1 - ) + ), t3 } } -test { faultsim_test_result {0 {}} From d131b51cbd820f9ac3fbdb23e1f0e58c5d831bca Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 18 Dec 2020 18:04:44 +0000 Subject: [PATCH 071/257] Fix for the previous fix in the case where a UNION ALL sub-query is joined against some other compound query. FossilOrigin-Name: 63c5cfb9ae8f4598a523bed2a60c0e69172179952961a573113fcf756c06551d --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 9 ++++----- test/unionall.test | 47 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index be6d22c043..5b84a2befe 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sflattening\sUNION\sALL\ssubqueries\sinto\sa\sjoin\squery,\sensure\sthat\sseparate\scursor\snumbers\sare\sused\sfor\seach\ssegment\sof\sthe\snewly\sflattened\squery. -D 2020-12-18T16:13:39.603 +C Fix\sfor\sthe\sprevious\sfix\sin\sthe\scase\swhere\sa\sUNION\sALL\ssub-query\sis\sjoined\sagainst\ssome\sother\scompound\squery. +D 2020-12-18T18:04:44.749 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -540,7 +540,7 @@ F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 7282b1a0fc81ce3c61c988b228b63b45a5521254033370d1ad6bf3366b5c2788 +F src/select.c deeed19d210db99369cb66d6804c889426851d541484fcc35ad554a19859ae8d F src/shell.c.in e9f674ee4ec6c345679e8a5b16c869c6c59eb1540dd98ac69e4736ecddce0090 F src/sqlite.h.in 5b7593bb0f3658e682a9fcd1cd8fcedf244ec45ca93d645055a53172f55eb783 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1627,7 +1627,7 @@ F test/tt3_vacuum.c 1753f45917699c9c1f66b64c717a717c9379f776 F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff F test/types2.test 1aeb81976841a91eef292723649b5c4fe3bc3cac F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a -F test/unionall.test 6676ff915eced719e7010149d758ba85665c0aef6a782e693b6fb5e83fb4e4e1 +F test/unionall.test 9dcc5faefe8caa4e2e4084fd4f45ad783abb7cfb86fcb87a3b74204e03f86014 F test/unionallfault.test 652bfbb630e6c43135965dc1e8f0a9a791da83aec885d626a632fe1909c56f73 F test/unionvtab.test e1704ab1b4c1bb3ffc9da4681f8e85a0b909fd80b937984fc94b27415ac8e5a4 F test/unionvtabfault.test e8759f3d14fb938ce9657e2342db34aeac0fb9bc1692b0d1ebb0069630151d06 @@ -1893,7 +1893,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 dc0937ce9d5569e3409b2b036a9f15b896125f4eb2eec30e3f0bbe4a92bcd0ad -R d7f9897a9bbc548d53ddd8cd562a8b6a +P c510377b0b052e400f2ee4f20220b61cdf74ee44b9bb9e6490787c88dd4c55aa +R 2a24a93078ef04ec108f14575de16445 U dan -Z aa626afff11dd6191a903497d2bb6cf2 +Z c9e8c301310f3fe94971f95dfbdc7685 diff --git a/manifest.uuid b/manifest.uuid index dcf4a244f3..844ee23275 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c510377b0b052e400f2ee4f20220b61cdf74ee44b9bb9e6490787c88dd4c55aa \ No newline at end of file +63c5cfb9ae8f4598a523bed2a60c0e69172179952961a573113fcf756c06551d \ No newline at end of file diff --git a/src/select.c b/src/select.c index bc5f17ecb2..64ed913cf8 100644 --- a/src/select.c +++ b/src/select.c @@ -3673,11 +3673,10 @@ static void srclistRenumberCursors( struct SrcList_item *pItem; for(i=0, pItem=pSrc->a; inSrc; i++, pItem++){ if( i!=iExcept ){ - int iNew = pParse->nTab++; - aCsrMap[pItem->iCursor] = iNew; - pItem->iCursor = iNew; - if( pItem->pSelect ){ - srclistRenumberCursors(pParse, aCsrMap, pItem->pSelect->pSrc, -1); + Select *p; + pItem->iCursor = aCsrMap[pItem->iCursor] = pParse->nTab++; + for(p=pItem->pSelect; p; p=p->pPrior){ + srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1); } } } diff --git a/test/unionall.test b/test/unionall.test index 0098cf15a4..430cd62e09 100644 --- a/test/unionall.test +++ b/test/unionall.test @@ -197,5 +197,52 @@ do_execsql_test 2.2.9b { 2 TWO 5 v 3 three 5 v 3 THREE 5 v } +#------------------------------------------------------------------------- +reset_db +do_execsql_test 3.0 { + CREATE TABLE t1(c INTEGER PRIMARY KEY, d TEXT); + INSERT INTO t1 VALUES(1,2); + CREATE TABLE t3_a(k INTEGER PRIMARY KEY, v TEXT); + INSERT INTO t3_a VALUES(2,'ii'); + CREATE TABLE t3_b(k INTEGER PRIMARY KEY, v TEXT); + CREATE VIEW t3 AS + SELECT * FROM t3_a + UNION ALL + SELECT * FROM t3_b; +} {} + +do_execsql_test 3.1 { + SELECT * FROM t1, t3 ORDER BY k; +} {1 2 2 ii} + +reset_db +do_execsql_test 4.0 { + + CREATE TABLE t1_a(a INTEGER PRIMARY KEY, b TEXT); + INSERT INTO t1_a VALUES(123, 't1_a'); + CREATE TABLE t1_b(c INTEGER PRIMARY KEY, d TEXT); + + CREATE VIEW t1 AS + SELECT a, b FROM t1_a + UNION ALL + SELECT c, d FROM t1_b; + + CREATE TABLE t3_a(k INTEGER PRIMARY KEY, v TEXT); + INSERT INTO t3_a VALUES(456, 't3_a'); + CREATE TABLE t3_b(k INTEGER PRIMARY KEY, v TEXT); + + CREATE VIEW t3 AS + SELECT * FROM t3_a + UNION ALL + SELECT * FROM t3_b; +} + +do_execsql_test 4.1 { + SELECT * FROM t1, t3 ORDER BY k; +} {123 t1_a 456 t3_a} + +do_execsql_test 4.2 { + SELECT * FROM (SELECT * FROM t1, t3) ORDER BY k; +} {123 t1_a 456 t3_a} finish_test From 5763f3d582bd87159667246a62dfef890d684df0 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 19 Dec 2020 15:39:10 +0000 Subject: [PATCH 072/257] Fix a broken assert() in fts5 that could be triggered by corrupt database records. FossilOrigin-Name: b79f59f9ad897d5bd4b9d17e6219bc765b02450bfe14dc020485f221ba6b02cb --- ext/fts5/fts5_index.c | 8 +- ext/fts5/test/fts5corrupt3.test | 126 ++++++++++++++++++++++++++++++++ manifest | 17 ++--- manifest.uuid | 2 +- 4 files changed, 137 insertions(+), 16 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 2daa07c51e..c01d5d9de6 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -2070,14 +2070,10 @@ static void fts5SegIterNext( }else{ /* The following could be done by calling fts5SegIterLoadNPos(). But ** this block is particularly performance critical, so equivalent - ** code is inlined. - ** - ** Later: Switched back to fts5SegIterLoadNPos() because it supports - ** detail=none mode. Not ideal. - */ + ** code is inlined. */ int nSz; assert( p->rc==SQLITE_OK ); - assert( pIter->iLeafOffset<=pIter->pLeaf->nn ); + assert_nc( pIter->iLeafOffset<=pIter->pLeaf->nn ); fts5FastGetVarint32(pIter->pLeaf->p, pIter->iLeafOffset, nSz); pIter->bDel = (nSz & 0x0001); pIter->nPos = nSz>>1; diff --git a/ext/fts5/test/fts5corrupt3.test b/ext/fts5/test/fts5corrupt3.test index 4554abbcfb..6fae40ecb9 100644 --- a/ext/fts5/test/fts5corrupt3.test +++ b/ext/fts5/test/fts5corrupt3.test @@ -10638,6 +10638,132 @@ do_catchsql_test 72.1 { SELECT 1 FROM ttt('e* NOT ee*'); } {1 {database disk image is malformed}} +#------------------------------------------------------------------------- +reset_db +do_test 73.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +.open --hexdb +| size 24576 pagesize 4096 filename crash-b02ca2cc4d7dda.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 06 .....@ ........ +| 32: 00 00 00 00 00 00 00 00 00 00 00 06 00 00 00 04 ................ +| 96: 00 00 00 00 0d 00 00 00 06 0d e2 00 0f c4 0f 6a ...............j +| 112: 0e fc 0e 9d 0e 3d 0d e2 00 00 00 00 00 00 00 00 .....=.......... +| 3552: 00 00 59 06 06 17 21 21 01 7f 74 61 62 6c 65 74 ..Y...!!..tablet +| 3568: 74 74 5f 63 6f 6e 66 69 67 74 74 74 5f 63 6f 6e tt_configttt_con +| 3584: 66 69 67 06 43 52 45 41 54 45 20 54 41 42 4c 45 fig.CREATE TABLE +| 3600: 20 27 74 74 74 5f 63 6f 6e 66 69 67 27 28 6b 20 'ttt_config'(k +| 3616: 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 PRIMARY KEY, v) +| 3632: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5e 05 07 WITHOUT ROWID^.. +| 3648: 17 23 23 01 81 03 74 61 62 6c 65 74 74 74 5f 64 .##...tablettt_d +| 3664: 6f 63 73 69 7a 65 74 74 74 5f 64 6f 63 73 69 7a ocsizettt_docsiz +| 3680: 65 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 e.CREATE TABLE ' +| 3696: 74 74 74 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 ttt_docsize'(id +| 3712: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 INTEGER PRIMARY +| 3728: 4b 45 59 2c 20 73 7a 20 42 4c 4f 42 29 5d 04 07 KEY, sz BLOB)].. +| 3744: 17 23 23 01 81 01 74 61 62 6c 65 74 74 74 5f 63 .##...tablettt_c +| 3760: 6f 6e 74 65 6e 74 74 74 74 5f 63 6f 6e 74 65 6e ontentttt_conten +| 3776: 74 04 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 t.CREATE TABLE ' +| 3792: 74 74 74 5f 63 6f 6e 74 65 6e 74 27 28 69 64 20 ttt_content'(id +| 3808: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 INTEGER PRIMARY +| 3824: 4b 45 59 2c 20 63 30 2c 20 63 31 29 6c 03 07 17 KEY, c0, c1)l... +| 3840: 1b 1b 01 81 2f 74 61 62 6c 65 74 74 74 5f 69 64 ..../tablettt_id +| 3856: 78 74 74 74 5f 69 64 78 03 43 52 45 41 54 45 20 xttt_idx.CREATE +| 3872: 54 41 42 4c 45 20 27 74 74 74 5f 69 64 78 27 28 TABLE 'ttt_idx'( +| 3888: 73 65 67 69 64 2c 20 74 65 72 6d 2c 20 70 67 6e segid, term, pgn +| 3904: 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45 59 28 73 o, PRIMARY KEY(s +| 3920: 65 67 69 64 2c 20 74 65 72 6d 29 29 20 57 49 54 egid, term)) WIT +| 3936: 48 4f 55 54 20 52 4f 57 49 44 58 02 07 17 1d 1d HOUT ROWIDX..... +| 3952: 01 81 03 74 61 62 6c 65 74 74 74 5f 64 61 74 61 ...tablettt_data +| 3968: 74 74 74 5f 64 61 74 61 02 43 52 45 41 54 45 20 ttt_data.CREATE +| 3984: 54 41 42 4c 45 20 27 74 74 74 5f 64 61 74 61 27 TABLE 'ttt_data' +| 4000: 28 69 65 20 49 4e 54 45 47 45 52 20 50 52 49 4d (ie INTEGER PRIM +| 4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 ARY KEY, block B +| 4032: 4c 4f 42 29 3a 01 06 17 13 13 08 5f 74 61 62 6c LOB):......_tabl +| 4048: 65 74 74 74 74 74 74 43 52 45 41 54 45 20 56 49 ettttttCREATE VI +| 4064: 52 54 55 41 4c 20 54 41 42 4c 45 20 74 74 74 20 RTUAL TABLE ttt +| 4080: 55 53 49 4e 47 20 66 74 73 35 28 61 2c 20 62 29 USING fts5(a, b) +| page 2 offset 4096 +| 0: 0d 0f 44 00 05 0e 81 00 0f e7 0e 81 0f af 0f 58 ..D............X +| 16: 0e 98 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 3712: 00 15 0a 03 00 30 00 00 00 00 01 03 03 00 03 01 .....0.......... +| 3728: 01 01 02 01 01 03 01 01 81 24 8c 80 80 80 80 01 .........$...... +| 3744: 04 00 82 4c 00 00 00 9b 02 30 65 03 1a 02 05 05 ...L.....0e..... +| 3760: 07 05 01 01 04 03 03 08 03 03 01 2e 02 05 05 07 ................ +| 3776: 05 07 05 07 05 01 01 04 03 03 08 03 03 08 03 03 ................ +| 3792: 08 03 03 02 01 65 03 1e 03 05 05 04 05 05 01 01 .....e.......... +| 3808: 03 06 04 04 06 04 03 01 36 03 05 05 04 05 05 04 ........6....... +| 3824: 05 04 f4 04 05 01 01 03 06 04 04 06 04 04 06 04 ................ +| 3840: 04 06 04 db 03 01 65 03 14 04 05 07 05 05 01 01 ......e......... +| 3856: 02 08 0a 01 20 04 05 07 05 07 05 07 05 05 01 01 .... ........... +| 3872: 02 08 0a 0a 0a 04 01 65 03 02 0a 01 06 0a 0a 0a .......e........ +| 3888: 05 01 65 03 06 01 01 0a 01 0a 01 01 0a 0a 0a 04 ..e............. +| 3904: 2b 31 21 0b 0f ef 00 14 2a 00 00 00 00 01 02 02 +1!.....*....... +| 3920: 00 02 01 01 01 02 01 01 50 88 80 80 80 80 01 04 ........P....... +| 3936: 00 81 24 00 00 00 47 02 30 65 02 1a 02 05 05 07 ..$...G.0e...... +| 3952: 05 01 01 04 03 03 08 03 03 02 01 65 02 1e 03 05 ...........e.... +| 3968: 05 04 05 05 01 01 03 06 09 14 06 04 03 03 01 65 ...............e +| 3984: 02 14 04 05 07 05 05 01 01 02 08 ed 04 01 65 02 ..............e. +| 4000: 02 0a 05 01 65 02 06 01 01 0a 04 12 14 0f 06 31 ....e..........1 +| 4016: 84 80 80 80 80 01 03 00 68 00 00 00 2b 02 30 65 ........h...+.0e +| 4032: 01 10 02 05 05 01 01 04 03 03 02 01 55 01 12 03 ............U... +| 4048: 05 05 01 01 03 06 05 03 03 01 65 01 0e 04 05 05 ..........e..... +| 4064: 01 01 02 08 04 0d 0e 06 01 03 00 12 04 4c 4c 00 .............LL. +| 4080: 00 00 11 24 00 00 00 00 01 0f c1 00 01 01 01 01 ...$............ +| page 3 offset 8192 +| 0: 0a 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................ +| 4064: 00 00 00 00 00 00 00 00 00 00 00 00 06 04 01 0c ................ +| 4080: 01 03 02 06 04 01 0c 01 02 02 05 04 09 0c 01 02 ................ +| page 4 offset 12288 +| 0: 0d 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 ................ +| 3600: 00 00 00 00 00 00 00 00 00 00 81 52 04 06 00 81 ...........R.... +| 3616: 5d 81 55 65 20 65 65 20 65 65 65 20 65 20 65 65 ].Ue ee eee e ee +| 3632: 20 65 65 65 20 65 20 65 65 20 65 65 65 65 20 65 eee e ee eeee e +| 3648: 65 20 65 65 65 20 65 20 65 65 20 65 65 65 20 65 e eee e ee eee e +| 3664: 20 65 65 20 65 65 65 65 20 65 65 20 65 65 65 20 ee eeee ee eee +| 3680: 65 20 65 65 20 65 65 65 20 65 20 65 65 20 65 65 e ee eee e ee ee +| 3696: 65 65 20 65 65 20 65 65 65 20 65 20 65 65 20 65 ee ee eee e ee e +| 3712: 65 65 20 65 20 65 65 20 65 65 65 65 65 65 20 65 ee e ee eeeeee e +| 3728: 65 20 65 20 65 20 65 20 65 65 20 65 65 65 20 65 e e e e ee eee e +| 3744: 65 20 65 65 65 65 65 20 65 65 20 65 20 65 20 65 e eeeee ee e e e +| 3760: 20 65 65 20 65 62 d5 20 65 65 20 65 65 65 65 65 ee eb. ee eeeee +| 3776: 20 65 65 20 65 20 65 20 65 20 65 65 20 65 65 65 ee e e e ee eee +| 3792: 20 65 65 20 65 65 65 65 65 20 65 65 20 65 21 65 ee eeeee ee e!e +| 3808: 20 65 20 65 65 20 65 65 65 20 65 65 20 65 65 6a e ee eee ee eej +| 3824: 03 04 00 75 71 65 20 65 65 10 65 65 65 20 65 20 ...uqe ee.eee e +| 3840: 65 65 20 65 65 65 20 65 20 65 65 20 65 65 65 65 ee eee e ee eeee +| 3856: 20 65 65 20 65 65 65 20 65 20 65 65 20 65 65 65 ee eee e ee eee +| 3872: 20 65 20 65 65 20 65 65 65 65 65 65 20 65 65 20 e ee eeeeee ee +| 3888: 65 20 65 20 65 20 65 65 20 65 65 65 20 62 55 20 e e e ee eee bU +| 3904: 65 65 65 65 65 20 65 65 20 65 20 65 20 65 20 65 eeeee ee e e e e +| 3920: 65 20 65 65 65 20 55 65 20 65 65 6a 02 04 00 75 e eee Ue eej...u +| 3936: 71 65 20 65 65 20 65 65 65 20 65 10 65 65 20 65 qe ee eee e.ee e +| 3952: 65 65 20 65 20 65 65 20 65 65 65 65 20 65 65 20 ee e ee eeee ee +| 3968: 65 65 65 20 65 20 65 65 20 65 65 65 20 65 20 65 eee e ee eee e e +| 3984: 65 20 65 65 65 65 65 65 20 65 65 20 65 20 65 20 e eeeeee ee e e +| 4000: 65 20 65 65 20 65 65 65 20 65 65 20 65 65 65 65 e ee eee ee eeee +| 4016: 65 20 65 65 20 65 20 65 20 65 20 65 65 20 65 65 e ee e e e ee ee +| 4032: 65 20 65 65 21 65 65 37 0a 04 00 41 3f 65 20 65 e ee!ee7...A?e e +| 4048: 65 20 65 65 65 20 65 20 65 65 20 65 65 65 20 65 e eee e ee eee e +| 4064: 20 65 65 20 65 65 65 65 65 65 20 65 65 20 65 20 ee eeeeee ee e +| 4080: 65 20 65 20 65 65 20 65 65 65 20 65 65 20 65 65 e e ee eee ee ee +| page 5 offset 16384 +| 0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 4064: 00 00 00 00 05 04 03 00 10 21 21 05 13 03 00 10 .........!!..... +| 4080: 11 11 05 02 03 00 10 11 11 05 01 03 00 10 09 09 ................ +| page 6 offset 20480 +| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................ +| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version. +| end crash-b02ca2cc4d7dda.db +}]} {} + +do_catchsql_test 73.1 { + SELECT snippet(ttt,ttt, NOT 54 ), + * FROM ttt('e* NOT ee*e* NOT ee* NOT ee*e* NOT e*') ; +} {1 {database disk image is malformed}} + sqlite3_fts5_may_be_corrupt 0 finish_test diff --git a/manifest b/manifest index c174113104..c68355c8dd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sUNION\sALL\ssub-queriesto\sbe\sflattened\seven\sif\sthe\sparent\squery\sis\sa\sjoin. -D 2020-12-19T13:58:06.688 +C Fix\sa\sbroken\sassert()\sin\sfts5\sthat\scould\sbe\striggered\sby\scorrupt\sdatabase\srecords. +D 2020-12-19T15:39:10.157 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -119,7 +119,7 @@ F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6 F ext/fts5/fts5_config.c be54f44fca491e96c6923a4b9a736f2da2b13811600eb6e38d1bcc91c4ea2e61 F ext/fts5/fts5_expr.c 016bd06030679bd31b0f07ef87d62c42031e5da25cb3174a84e5b0f6ef4b47b0 F ext/fts5/fts5_hash.c 1aa93c9b5f461afba66701ee226297dc78402b3bdde81e90a10de5fe3df14959 -F ext/fts5/fts5_index.c 7be3a7dcf4458a2d58a1c6ae0290921c9df226bff7eb9bc82f14e667b27aeb20 +F ext/fts5/fts5_index.c acbe3ccd36f5a7373009dfff02a11c4a817af73bc3ef8c340f2105d7d073f8b4 F ext/fts5/fts5_main.c b4e4931c7fcc9acfa0c3b8b5e5e80b5b424b8d9207aae3a22b674bd35ccf149d F ext/fts5/fts5_storage.c 58ba71e6cd3d43a5735815e7956ee167babb4d2cbfe206905174792af4d09d75 F ext/fts5/fts5_tcl.c 39bcbae507f594aad778172fa914cad0f585bf92fd3b078c686e249282db0d95 @@ -160,7 +160,7 @@ F ext/fts5/test/fts5connect.test 08030168fc96fc278fa81f28654fb7e90566f33aff269c0 F ext/fts5/test/fts5content.test 213506436fb2c87567b8e31f6d43ab30aab99354cec74ed679f22aad0cdbf283 F ext/fts5/test/fts5corrupt.test 77ae6f41a7eba10620efb921cf7dbe218b0ef232b04519deb43581cb17a57ebe F ext/fts5/test/fts5corrupt2.test 7453752ba12ce91690c469a6449d412561cc604b1dec994e16ab132952e7805f -F ext/fts5/test/fts5corrupt3.test 6de9f4f73fec1d996460d2f65576590e1e7074f9c28b8db9c19287c588c6f552 +F ext/fts5/test/fts5corrupt3.test 5df97f353102f0078d0bb418d620652d03460ee1cceb2992a3b5ee6fb619b24e F ext/fts5/test/fts5corrupt4.test f4c08e2182a48d8b70975fd869ee5391855c06d8a0ff87b6a2529e7c5a88a1d3 F ext/fts5/test/fts5delete.test 619295b20dbc1d840b403ee07c878f52378849c3c02e44f2ee143b3e978a0aa7 F ext/fts5/test/fts5detail.test 31b240dbf6d44ac3507e2f8b65f29fdc12465ffd531212378c7ce1066766f54e @@ -1893,8 +1893,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 3434452148eef39ba3ba2f40a6fedb6ec4f5157cbc2763b3ec90ec7f2b126382 63c5cfb9ae8f4598a523bed2a60c0e69172179952961a573113fcf756c06551d -R 01abc47468d8209e3de01dce0ca29125 -T +closed 63c5cfb9ae8f4598a523bed2a60c0e69172179952961a573113fcf756c06551d -U drh -Z 9a839de521f6f5591d18cd2ba96a1b41 +P df1d6482f9e92dafdca1948e96eef52d8646eef9c356394afabe431d6357dd34 +R f1d4aca5ede0c75d21614cee261645e8 +U dan +Z 700032770407797204dd07cf99586f0c diff --git a/manifest.uuid b/manifest.uuid index 516cbc030e..afc009e436 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -df1d6482f9e92dafdca1948e96eef52d8646eef9c356394afabe431d6357dd34 \ No newline at end of file +b79f59f9ad897d5bd4b9d17e6219bc765b02450bfe14dc020485f221ba6b02cb \ No newline at end of file From 8e2b9c2a8903f3a408429d0b3749549973b83ca5 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 20 Dec 2020 14:51:17 +0000 Subject: [PATCH 073/257] Always declare the sqlite3WhereTrace variable, even for non-debug builds. FossilOrigin-Name: 88d93ee380b6fd87474545f20ade874ba05c784c787ce9c45ebfcffed3795308 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqliteInt.h | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index c68355c8dd..a355d7e3c6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbroken\sassert()\sin\sfts5\sthat\scould\sbe\striggered\sby\scorrupt\sdatabase\srecords. -D 2020-12-19T15:39:10.157 +C Always\sdeclare\sthe\ssqlite3WhereTrace\svariable,\seven\sfor\snon-debug\sbuilds. +D 2020-12-20T14:51:17.806 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -545,7 +545,7 @@ F src/shell.c.in 6dd0d9260220f807d6d1b8e57dd6e163fe55bd0e97fa416c8c139162e341613 F src/sqlite.h.in 5b7593bb0f3658e682a9fcd1cd8fcedf244ec45ca93d645055a53172f55eb783 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h 6d8363d245354e360b5efa5f1dc4a7658f252dc80b1c9010264d64dfe77fdf1b +F src/sqliteInt.h 830d395a43449bd9980fa227d60ca20396e7035e5e8ab54be26214fb5379f531 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1893,7 +1893,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 df1d6482f9e92dafdca1948e96eef52d8646eef9c356394afabe431d6357dd34 -R f1d4aca5ede0c75d21614cee261645e8 -U dan -Z 700032770407797204dd07cf99586f0c +P b79f59f9ad897d5bd4b9d17e6219bc765b02450bfe14dc020485f221ba6b02cb +R 44577f8a1c7518c34582de96a91b2e8b +U drh +Z 174bdbab8294579fbf084a8c0c09510f diff --git a/manifest.uuid b/manifest.uuid index afc009e436..a92964c8e9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b79f59f9ad897d5bd4b9d17e6219bc765b02450bfe14dc020485f221ba6b02cb \ No newline at end of file +88d93ee380b6fd87474545f20ade874ba05c784c787ce9c45ebfcffed3795308 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index a0e05570e7..9da6231882 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1014,9 +1014,9 @@ extern u32 sqlite3SelectTrace; /* ** Macros for "wheretrace" */ +extern u32 sqlite3WhereTrace; #if defined(SQLITE_DEBUG) \ && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE)) -extern u32 sqlite3WhereTrace; # define WHERETRACE(K,X) if(sqlite3WhereTrace&(K)) sqlite3DebugPrintf X # define WHERETRACE_ENABLED 1 #else From 237f41ab8d1120786c17fe0a79277fcd626ad0d2 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 21 Dec 2020 12:14:59 +0000 Subject: [PATCH 074/257] Add the --timer option to fuzzcheck. Get the --timeout option working in fuzzcheck when running dbsql tests. FossilOrigin-Name: 3b0c9b41a877c7344ef3b7c5b6981436005716e25b41b1a1ffc145520243abd3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/fuzzcheck.c | 34 +++++++++++++++++++++++++++------- 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index a355d7e3c6..d01d5241ed 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Always\sdeclare\sthe\ssqlite3WhereTrace\svariable,\seven\sfor\snon-debug\sbuilds. -D 2020-12-20T14:51:17.806 +C Add\sthe\s--timer\soption\sto\sfuzzcheck.\s\sGet\sthe\s--timeout\soption\sworking\sin\nfuzzcheck\swhen\srunning\sdbsql\stests. +D 2020-12-21T12:14:59.759 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1035,7 +1035,7 @@ F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634 F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830 F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2 -F test/fuzzcheck.c 5f81f2cc65f13068620245f2e2c6059657d3b26be476df379ae2da539f17676d +F test/fuzzcheck.c 95427205d6cedb8fdb95bf7738e95785c790febf782d9c1e6067baaa1adc871d F test/fuzzdata1.db d36e88741b4f23bcbaaf55b006290669d03c6c891cf13c7b3a53bc1b097b693f F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba @@ -1893,7 +1893,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 b79f59f9ad897d5bd4b9d17e6219bc765b02450bfe14dc020485f221ba6b02cb -R 44577f8a1c7518c34582de96a91b2e8b +P 88d93ee380b6fd87474545f20ade874ba05c784c787ce9c45ebfcffed3795308 +R 27ec1c9c08574b257c1035ec83dd9754 U drh -Z 174bdbab8294579fbf084a8c0c09510f +Z b0ca2a90328c04cad0677f000624e900 diff --git a/manifest.uuid b/manifest.uuid index a92964c8e9..8e9af402eb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -88d93ee380b6fd87474545f20ade874ba05c784c787ce9c45ebfcffed3795308 \ No newline at end of file +3b0c9b41a877c7344ef3b7c5b6981436005716e25b41b1a1ffc145520243abd3 \ No newline at end of file diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c index cf49956b47..c6ad4cd5c3 100644 --- a/test/fuzzcheck.c +++ b/test/fuzzcheck.c @@ -455,7 +455,12 @@ static void blobListFree(Blob *p){ } } -/* Return the current wall-clock time */ +/* Return the current wall-clock time +** +** The number of milliseconds since the julian epoch. +** 1907-01-01 00:00:00 -> 210866716800000 +** 2021-01-01 00:00:00 -> 212476176000000 +*/ static sqlite3_int64 timeOfDay(void){ static sqlite3_vfs *clockVfs = 0; sqlite3_int64 t; @@ -713,6 +718,7 @@ static int progress_handler(void *pClientData) { sqlite3_int64 iNow = timeOfDay(); int rc = iNow>=p->iCutoffTime; sqlite3_int64 iDiff = iNow - p->iLastCb; + /* printf("time-remaining: %lld\n", p->iCutoffTime - iNow); */ if( iDiff > p->mxInterval ) p->mxInterval = iDiff; p->nCb++; if( rc==0 && p->mxCb>0 && p->mxCb<=p->nCb ) rc = 1; @@ -835,7 +841,7 @@ static int runDbSql(sqlite3 *db, const char *zSql){ } /* Invoke this routine to run a single test case */ -int runCombinedDbSqlInput(const uint8_t *aData, size_t nByte){ +int runCombinedDbSqlInput(const uint8_t *aData, size_t nByte, int iTimeout){ int rc; /* SQLite API return value */ int iSql; /* Index in aData[] of start of SQL */ unsigned char *aDb = 0; /* Decoded database content */ @@ -882,7 +888,7 @@ int runCombinedDbSqlInput(const uint8_t *aData, size_t nByte){ ** elapsed since the start of the test. */ cx.iLastCb = timeOfDay(); - cx.iCutoffTime = cx.iLastCb + giTimeout; /* Now + giTimeout seconds */ + cx.iCutoffTime = cx.iLastCb + (iTimeout=argc-1 ) fatalError("missing arguments on %s", argv[i]); onlySqlid = integerValue(argv[++i]); @@ -1894,6 +1905,7 @@ int main(int argc, char **argv){ */ if( !verboseFlag && !quietFlag && !bSpinner ) printf("%s:", zDbName); for(pSql=g.pFirstSql; pSql; pSql=pSql->pNext){ + tmStart = timeOfDay(); if( isDbSql(pSql->a, pSql->sz) ){ sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "sqlid=%d",pSql->id); if( bSpinner ){ @@ -1917,9 +1929,13 @@ int main(int argc, char **argv){ if( nSkip>0 ){ nSkip--; }else{ - runCombinedDbSqlInput(pSql->a, pSql->sz); + runCombinedDbSqlInput(pSql->a, pSql->sz, iTimeout); } nTest++; + if( bTimer ){ + sqlite3_int64 tmEnd = timeOfDay(); + printf("%lld %s\n", tmEnd - tmStart, g.zTestName); + } g.zTestName[0] = 0; disableOom(); continue; @@ -1972,7 +1988,7 @@ int main(int argc, char **argv){ sqlite3_limit(db, SQLITE_LIMIT_LENGTH, 100000000); sqlite3_limit(db, SQLITE_LIMIT_LIKE_PATTERN_LENGTH, 50); if( cellSzCkFlag ) runSql(db, "PRAGMA cell_size_check=ON", runFlags); - setAlarm(iTimeout); + setAlarm((iTimeout+999)/1000); #ifndef SQLITE_OMIT_PROGRESS_CALLBACK if( sqlFuzz || vdbeLimitFlag ){ sqlite3_progress_handler(db, 100000, progressHandler, @@ -1998,6 +2014,10 @@ int main(int argc, char **argv){ } reformatVfs(); nTest++; + if( bTimer ){ + sqlite3_int64 tmEnd = timeOfDay(); + printf("%lld %s\n", tmEnd - tmStart, g.zTestName); + } g.zTestName[0] = 0; /* Simulate an error if the TEST_FAILURE environment variable is "5". From 6d5f928d22e61bb9e12d7ba5ea01da42bacd63dd Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 21 Dec 2020 14:51:33 +0000 Subject: [PATCH 075/257] Enhance documentation to show that "ro" is the correct way to say "readonly" in the mode= query parameter. FossilOrigin-Name: 788b96851d9ced84757c48dc3e0414cab27ee7e50e9730dab30b2e42a7762397 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index d01d5241ed..af20ffa076 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s--timer\soption\sto\sfuzzcheck.\s\sGet\sthe\s--timeout\soption\sworking\sin\nfuzzcheck\swhen\srunning\sdbsql\stests. -D 2020-12-21T12:14:59.759 +C Enhance\sdocumentation\sto\sshow\sthat\s"ro"\sis\sthe\scorrect\sway\sto\ssay\s"readonly"\nin\sthe\smode=\squery\sparameter. +D 2020-12-21T14:51:33.242 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -542,7 +542,7 @@ F src/resolve.c 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c deeed19d210db99369cb66d6804c889426851d541484fcc35ad554a19859ae8d F src/shell.c.in 6dd0d9260220f807d6d1b8e57dd6e163fe55bd0e97fa416c8c139162e3416134 -F src/sqlite.h.in 5b7593bb0f3658e682a9fcd1cd8fcedf244ec45ca93d645055a53172f55eb783 +F src/sqlite.h.in 0af968a1fa3c717261e1df0ed105fa7bddb4d82de7e0adb3eab49e6aa81b4de7 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e F src/sqliteInt.h 830d395a43449bd9980fa227d60ca20396e7035e5e8ab54be26214fb5379f531 @@ -1893,7 +1893,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 88d93ee380b6fd87474545f20ade874ba05c784c787ce9c45ebfcffed3795308 -R 27ec1c9c08574b257c1035ec83dd9754 +P 3b0c9b41a877c7344ef3b7c5b6981436005716e25b41b1a1ffc145520243abd3 +R b74c560d3085cb3bea733f18ec03ab77 U drh -Z b0ca2a90328c04cad0677f000624e900 +Z 76c875139f02e2b74c2635d603850742 diff --git a/manifest.uuid b/manifest.uuid index 8e9af402eb..52e405b2a6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3b0c9b41a877c7344ef3b7c5b6981436005716e25b41b1a1ffc145520243abd3 \ No newline at end of file +788b96851d9ced84757c48dc3e0414cab27ee7e50e9730dab30b2e42a7762397 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 79eecb4b08..c17d012002 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -3499,6 +3499,7 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** that uses dot-files in place of posix advisory locking. ** file:data.db?mode=readonly ** An error. "readonly" is not a valid option for the "mode" parameter. +** Use "ro" instead: "file:data.db?mode=ro". ** ** ** ^URI hexadecimal escape sequences (%HH) are supported within the path and From a3d33ebe4ab767f976ea24ef1488fe1d0be82deb Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 21 Dec 2020 18:39:58 +0000 Subject: [PATCH 076/257] Fix a problem when flattening joins between a UNION ALL sub-query and another sub-query that uses more than one window function. FossilOrigin-Name: ef9733fe1c6b31849a5da1037d21915f82e0e4ab42d1a23ead8a121012f1bace --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/walker.c | 7 ++++--- test/unionall.test | 30 ++++++++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index af20ffa076..3d9ea67193 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sdocumentation\sto\sshow\sthat\s"ro"\sis\sthe\scorrect\sway\sto\ssay\s"readonly"\nin\sthe\smode=\squery\sparameter. -D 2020-12-21T14:51:33.242 +C Fix\sa\sproblem\swhen\sflattening\sjoins\sbetween\sa\sUNION\sALL\ssub-query\sand\sanother\ssub-query\sthat\suses\smore\sthan\sone\swindow\sfunction. +D 2020-12-21T18:39:58.008 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -626,7 +626,7 @@ F src/vtab.c 5f5fc793092f53bbdfde296c50f563fb7bda58cf48e9cf6a8bdfbc5abd409845 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 69e770e96fd56cc21608992bf2c6f1f3dc5cf2572d0495c6a643b06c3a679f14 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a -F src/walker.c 3df26a33dc4f54e8771600fb7fdebe1ece0896c2ad68c30ab40b017aa4395049 +F src/walker.c d9c4e454ebb9499e908aa62d55b8994c375cf5355ac78f60d45af17f7890701c F src/where.c 2d593bfc6fa24e53dfe7c99bd327af687f8502e5f0e0299dd2c0f503b133f0bb F src/whereInt.h 9a3f577619f07700d16d89eeb2f3d94d6b7ed7f109c2dacf0ce8844921549506 F src/wherecode.c a3a1aff30fe99a818d8e7c607980f033f40c68d890e03ed25838b9dbb7908bee @@ -1627,7 +1627,7 @@ F test/tt3_vacuum.c 1753f45917699c9c1f66b64c717a717c9379f776 F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff F test/types2.test 1aeb81976841a91eef292723649b5c4fe3bc3cac F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a -F test/unionall.test 9dcc5faefe8caa4e2e4084fd4f45ad783abb7cfb86fcb87a3b74204e03f86014 +F test/unionall.test 70d6ec7bce279cf63edc11589b0541ddf289ef6efe51c24cbf4efaceeb4ce5b8 F test/unionallfault.test 652bfbb630e6c43135965dc1e8f0a9a791da83aec885d626a632fe1909c56f73 F test/unionvtab.test e1704ab1b4c1bb3ffc9da4681f8e85a0b909fd80b937984fc94b27415ac8e5a4 F test/unionvtabfault.test e8759f3d14fb938ce9657e2342db34aeac0fb9bc1692b0d1ebb0069630151d06 @@ -1893,7 +1893,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 3b0c9b41a877c7344ef3b7c5b6981436005716e25b41b1a1ffc145520243abd3 -R b74c560d3085cb3bea733f18ec03ab77 -U drh -Z 76c875139f02e2b74c2635d603850742 +P 788b96851d9ced84757c48dc3e0414cab27ee7e50e9730dab30b2e42a7762397 +R 8f0537d0e7a9b2ba57d49d118851dfa2 +U dan +Z 750efdd05db1f99dfea3008ae72af1b9 diff --git a/manifest.uuid b/manifest.uuid index 52e405b2a6..f60e210e25 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -788b96851d9ced84757c48dc3e0414cab27ee7e50e9730dab30b2e42a7762397 \ No newline at end of file +ef9733fe1c6b31849a5da1037d21915f82e0e4ab42d1a23ead8a121012f1bace \ No newline at end of file diff --git a/src/walker.c b/src/walker.c index 7649036f56..d047ccc039 100644 --- a/src/walker.c +++ b/src/walker.c @@ -22,7 +22,7 @@ ** Walk all expressions linked into the list of Window objects passed ** as the second argument. */ -static int walkWindowList(Walker *pWalker, Window *pList){ +static int walkWindowList(Walker *pWalker, Window *pList, int bOneOnly){ Window *pWin; for(pWin=pList; pWin; pWin=pWin->pNextWin){ int rc; @@ -41,6 +41,7 @@ static int walkWindowList(Walker *pWalker, Window *pList){ if( NEVER(rc) ) return WRC_Abort; rc = sqlite3WalkExpr(pWalker, pWin->pEnd); if( NEVER(rc) ) return WRC_Abort; + if( bOneOnly ) break; } return WRC_Continue; } @@ -88,7 +89,7 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){ } #ifndef SQLITE_OMIT_WINDOWFUNC if( ExprHasProperty(pExpr, EP_WinFunc) ){ - if( walkWindowList(pWalker, pExpr->y.pWin) ) return WRC_Abort; + if( walkWindowList(pWalker, pExpr->y.pWin, 1) ) return WRC_Abort; } #endif } @@ -135,7 +136,7 @@ int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){ if( pParse && IN_RENAME_OBJECT ){ /* The following may return WRC_Abort if there are unresolvable ** symbols (e.g. a table that does not exist) in a window definition. */ - int rc = walkWindowList(pWalker, p->pWinDefn); + int rc = walkWindowList(pWalker, p->pWinDefn, 0); return rc; } } diff --git a/test/unionall.test b/test/unionall.test index 430cd62e09..7688ce8b36 100644 --- a/test/unionall.test +++ b/test/unionall.test @@ -245,4 +245,34 @@ do_execsql_test 4.2 { SELECT * FROM (SELECT * FROM t1, t3) ORDER BY k; } {123 t1_a 456 t3_a} +do_execsql_test 4.3 { + SELECT * FROM (SELECT * FROM t1, t3), ( + SELECT max(a) OVER () FROM t1 + UNION ALL + SELECT min(a) OVER () FROM t1 + ) + ORDER BY k; +} { + 123 t1_a 456 t3_a 123 + 123 t1_a 456 t3_a 123 +} + +do_execsql_test 4.3 { + SELECT * FROM (SELECT * FROM t1, t3), ( + SELECT group_concat(a) OVER (ORDER BY a), + group_concat(a) OVER (ORDER BY a), + group_concat(a) OVER (ORDER BY a), + group_concat(a) OVER (ORDER BY a), + group_concat(a) OVER (ORDER BY a), + group_concat(a) OVER (ORDER BY a), + group_concat(a) OVER (ORDER BY a), + group_concat(a) OVER (ORDER BY a), + group_concat(a) OVER (ORDER BY a) + FROM t1 + ) + ORDER BY k; +} { + 123 t1_a 456 t3_a 123 123 123 123 123 123 123 123 123 +} + finish_test From 961a72601bfb981f347d4860e65515e7ab5b7eba Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 21 Dec 2020 19:50:10 +0000 Subject: [PATCH 077/257] Fix problems with joining UNION ALL sub-queries against other sub-queries that contain LEFT JOIN. FossilOrigin-Name: d554f710a5abbe64022f47a14ef67227c861a8f0991d85d240434e9a709cf8b8 --- manifest | 17 +++++++++-------- manifest.uuid | 2 +- src/select.c | 7 +++++-- src/sqliteInt.h | 2 +- test/unionall.test | 8 ++++++++ test/unionall2.test | 39 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 63 insertions(+), 12 deletions(-) create mode 100644 test/unionall2.test diff --git a/manifest b/manifest index 3d9ea67193..44b381ddc0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swhen\sflattening\sjoins\sbetween\sa\sUNION\sALL\ssub-query\sand\sanother\ssub-query\sthat\suses\smore\sthan\sone\swindow\sfunction. -D 2020-12-21T18:39:58.008 +C Fix\sproblems\swith\sjoining\sUNION\sALL\ssub-queries\sagainst\sother\ssub-queries\sthat\scontain\sLEFT\sJOIN. +D 2020-12-21T19:50:10.786 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -540,12 +540,12 @@ F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c deeed19d210db99369cb66d6804c889426851d541484fcc35ad554a19859ae8d +F src/select.c 610ca9552475310eb73d0f815c8558279910f3bbf5c5391476853c33400e302f F src/shell.c.in 6dd0d9260220f807d6d1b8e57dd6e163fe55bd0e97fa416c8c139162e3416134 F src/sqlite.h.in 0af968a1fa3c717261e1df0ed105fa7bddb4d82de7e0adb3eab49e6aa81b4de7 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h 830d395a43449bd9980fa227d60ca20396e7035e5e8ab54be26214fb5379f531 +F src/sqliteInt.h 53c440c2e62844aede29ce692ead431c8c7edd858ed6030f72829bc4bbe5a362 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1627,7 +1627,8 @@ F test/tt3_vacuum.c 1753f45917699c9c1f66b64c717a717c9379f776 F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff F test/types2.test 1aeb81976841a91eef292723649b5c4fe3bc3cac F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a -F test/unionall.test 70d6ec7bce279cf63edc11589b0541ddf289ef6efe51c24cbf4efaceeb4ce5b8 +F test/unionall.test 25fe866e51b6b590f59117d713ee5e88f5ad8d1fea136a0c4b0c597904e07887 +F test/unionall2.test c9a62db63350bcbce3a7bec50dd8c5410f08be33f8af435473756286d4657215 F test/unionallfault.test 652bfbb630e6c43135965dc1e8f0a9a791da83aec885d626a632fe1909c56f73 F test/unionvtab.test e1704ab1b4c1bb3ffc9da4681f8e85a0b909fd80b937984fc94b27415ac8e5a4 F test/unionvtabfault.test e8759f3d14fb938ce9657e2342db34aeac0fb9bc1692b0d1ebb0069630151d06 @@ -1893,7 +1894,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 788b96851d9ced84757c48dc3e0414cab27ee7e50e9730dab30b2e42a7762397 -R 8f0537d0e7a9b2ba57d49d118851dfa2 +P ef9733fe1c6b31849a5da1037d21915f82e0e4ab42d1a23ead8a121012f1bace +R 080e6ee530ae0ca63a2553bcffc20a5b U dan -Z 750efdd05db1f99dfea3008ae72af1b9 +Z a4fa2089cbf5bf716d3ea10acbb07023 diff --git a/manifest.uuid b/manifest.uuid index f60e210e25..0372897b34 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ef9733fe1c6b31849a5da1037d21915f82e0e4ab42d1a23ead8a121012f1bace \ No newline at end of file +d554f710a5abbe64022f47a14ef67227c861a8f0991d85d240434e9a709cf8b8 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 64ed913cf8..82174a02c8 100644 --- a/src/select.c +++ b/src/select.c @@ -347,7 +347,7 @@ static void addWhereTerm( ExprSetProperty(pEq, EP_FromJoin); assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) ); ExprSetVVAProperty(pEq, EP_NoReduce); - pEq->iRightJoinTable = (i16)pE2->iTable; + pEq->iRightJoinTable = pE2->iTable; } *ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq); } @@ -383,7 +383,7 @@ void sqlite3SetJoinExpr(Expr *p, int iTable){ ExprSetProperty(p, EP_FromJoin); assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); ExprSetVVAProperty(p, EP_NoReduce); - p->iRightJoinTable = (i16)iTable; + p->iRightJoinTable = iTable; if( p->op==TK_FUNCTION && p->x.pList ){ int i; for(i=0; ix.pList->nExpr; i++){ @@ -3691,6 +3691,9 @@ static int renumberCursorsCb(Walker *pWalker, Expr *pExpr){ if( pExpr->op==TK_COLUMN && aCsrMap[pExpr->iTable] ){ pExpr->iTable = aCsrMap[pExpr->iTable]; } + if( ExprHasProperty(pExpr, EP_FromJoin) && aCsrMap[pExpr->iRightJoinTable] ){ + pExpr->iRightJoinTable = aCsrMap[pExpr->iRightJoinTable]; + } return WRC_Continue; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 9da6231882..70cc68a2f1 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2715,7 +2715,7 @@ struct Expr { ** TK_VARIABLE: variable number (always >= 1). ** TK_SELECT_COLUMN: column of the result vector */ i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */ - i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */ + int iRightJoinTable; /* If EP_FromJoin, the right table of the join */ AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ union { Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL diff --git a/test/unionall.test b/test/unionall.test index 7688ce8b36..5dfac42e13 100644 --- a/test/unionall.test +++ b/test/unionall.test @@ -275,4 +275,12 @@ do_execsql_test 4.3 { 123 t1_a 456 t3_a 123 123 123 123 123 123 123 123 123 } +do_execsql_test 4.3 { + SELECT * FROM (SELECT * FROM t1, t3) AS o, ( + SELECT * FROM t1 LEFT JOIN t3 ON a=k + ); +} { + 123 t1_a 456 t3_a 123 t1_a {} {} +} + finish_test diff --git a/test/unionall2.test b/test/unionall2.test new file mode 100644 index 0000000000..265804291b --- /dev/null +++ b/test/unionall2.test @@ -0,0 +1,39 @@ +# 2020-12-22 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this file is flattening UNION ALL sub-queries. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix unionall2 + +do_execsql_test 1.0 { + CREATE TABLE t1(a, b); + CREATE TABLE t2(c, d); + + CREATE VIEW v1 AS SELECT * FROM t1, t2; + CREATE VIEW v2 AS SELECT * FROM t1, t2; + + CREATE VIEW vA AS + SELECT * FROM v1, ( + SELECT * FROM t1 LEFT JOIN t2 ON (a=c) + ) + UNION ALL + SELECT * FROM v1, v2 +} + +do_execsql_test 1.1 { + SELECT 1 FROM vA, vA, vA, vA, vA, vA, vA, vA, vA, vA +} + + +finish_test From 06ddb08f3f526a0fe018b04f3c0884a618ca5b2f Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 22 Dec 2020 14:54:20 +0000 Subject: [PATCH 078/257] Simplification to the aggregate-function analysis error detection logic at the end of sqlite3Select(). FossilOrigin-Name: 82884438e30ad8241f8249927fe92e0856d78b64d7ade38f3d5bb1c931d958d0 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 6 ++---- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 44b381ddc0..23328371fb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sproblems\swith\sjoining\sUNION\sALL\ssub-queries\sagainst\sother\ssub-queries\sthat\scontain\sLEFT\sJOIN. -D 2020-12-21T19:50:10.786 +C Simplification\sto\sthe\saggregate-function\sanalysis\serror\sdetection\slogic\sat\nthe\send\sof\ssqlite3Select(). +D 2020-12-22T14:54:20.628 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -540,7 +540,7 @@ F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 610ca9552475310eb73d0f815c8558279910f3bbf5c5391476853c33400e302f +F src/select.c 8626f34077f95d39a3a1b87bf19a3f107508dc075f946b8f44bf95360c9817bc F src/shell.c.in 6dd0d9260220f807d6d1b8e57dd6e163fe55bd0e97fa416c8c139162e3416134 F src/sqlite.h.in 0af968a1fa3c717261e1df0ed105fa7bddb4d82de7e0adb3eab49e6aa81b4de7 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1894,7 +1894,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 ef9733fe1c6b31849a5da1037d21915f82e0e4ab42d1a23ead8a121012f1bace -R 080e6ee530ae0ca63a2553bcffc20a5b -U dan -Z a4fa2089cbf5bf716d3ea10acbb07023 +P d554f710a5abbe64022f47a14ef67227c861a8f0991d85d240434e9a709cf8b8 +R c76471a509e5f704181ef32470d9334a +U drh +Z 75d6a966e9bdbb44ee6e2e92dddb1757 diff --git a/manifest.uuid b/manifest.uuid index 0372897b34..54fca24a6d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d554f710a5abbe64022f47a14ef67227c861a8f0991d85d240434e9a709cf8b8 \ No newline at end of file +82884438e30ad8241f8249927fe92e0856d78b64d7ade38f3d5bb1c931d958d0 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 82174a02c8..46dd0739ba 100644 --- a/src/select.c +++ b/src/select.c @@ -6970,15 +6970,13 @@ select_end: if( pAggInfo && !db->mallocFailed ){ for(i=0; inColumn; i++){ Expr *pExpr = pAggInfo->aCol[i].pCExpr; - assert( pExpr!=0 || db->mallocFailed ); - if( pExpr==0 ) continue; + assert( pExpr!=0 ); assert( pExpr->pAggInfo==pAggInfo ); assert( pExpr->iAgg==i ); } for(i=0; inFunc; i++){ Expr *pExpr = pAggInfo->aFunc[i].pFExpr; - assert( pExpr!=0 || db->mallocFailed ); - if( pExpr==0 ) continue; + assert( pExpr!=0 ); assert( pExpr->pAggInfo==pAggInfo ); assert( pExpr->iAgg==i ); } From f39168e468af3b1d6b6d37efdcb081eced6724b2 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 22 Dec 2020 16:23:29 +0000 Subject: [PATCH 079/257] Fix a problem handling sub-queries with both a correlated WHERE clause and a "HAVING 0" clause where the parent query is itself an aggregate. FossilOrigin-Name: f62f983b56623f0ec34f9a54ce1c21b013a20399162f5ee6ee43b23f10c2ecd5 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/select.c | 4 +++- test/having.test | 24 ++++++++++++++++++++++-- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 23328371fb..3b65f9b378 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplification\sto\sthe\saggregate-function\sanalysis\serror\sdetection\slogic\sat\nthe\send\sof\ssqlite3Select(). -D 2020-12-22T14:54:20.628 +C Fix\sa\sproblem\shandling\ssub-queries\swith\sboth\sa\scorrelated\sWHERE\sclause\sand\sa\s"HAVING\s0"\sclause\swhere\sthe\sparent\squery\sis\sitself\san\saggregate. +D 2020-12-22T16:23:29.675 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -540,7 +540,7 @@ F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 8626f34077f95d39a3a1b87bf19a3f107508dc075f946b8f44bf95360c9817bc +F src/select.c 85c7cec9a4a983416d4bd023b2c4fbbeb608ae8dfb069781f80c8ed08b0c7a7c F src/shell.c.in 6dd0d9260220f807d6d1b8e57dd6e163fe55bd0e97fa416c8c139162e3416134 F src/sqlite.h.in 0af968a1fa3c717261e1df0ed105fa7bddb4d82de7e0adb3eab49e6aa81b4de7 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1050,7 +1050,7 @@ F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 F test/gcfault.test dd28c228a38976d6336a3fc42d7e5f1ad060cb8c F test/gencol1.test b05e6c5edb9b10d48efb634ed07342441bddc89d225043e17095c36e567521a0 F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 -F test/having.test e4098a4b8962f9596035c3b87a8928a10648acc509f1bb8d6f96413bbf79a1b3 +F test/having.test ea5cb01cdf3d90fd1b516ef36b1fbde518dbbd61c50141f5eb830d8101844040 F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751 F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711 F test/hook.test e97382e68e4379838e888756d653afd159f5f14780315ff97b70360d3d8485bc @@ -1894,7 +1894,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 d554f710a5abbe64022f47a14ef67227c861a8f0991d85d240434e9a709cf8b8 -R c76471a509e5f704181ef32470d9334a -U drh -Z 75d6a966e9bdbb44ee6e2e92dddb1757 +P 82884438e30ad8241f8249927fe92e0856d78b64d7ade38f3d5bb1c931d958d0 +R 5b9b1eafbef4593babef1f4d206a30c6 +U dan +Z a856915eaf20f0d711508df4b26bec16 diff --git a/manifest.uuid b/manifest.uuid index 54fca24a6d..f2c6e3ef47 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -82884438e30ad8241f8249927fe92e0856d78b64d7ade38f3d5bb1c931d958d0 \ No newline at end of file +f62f983b56623f0ec34f9a54ce1c21b013a20399162f5ee6ee43b23f10c2ecd5 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 46dd0739ba..407a6a4b2e 100644 --- a/src/select.c +++ b/src/select.c @@ -5696,7 +5696,9 @@ static void explainSimpleCount( static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){ if( pExpr->op!=TK_AND ){ Select *pS = pWalker->u.pSelect; - if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, pS->pGroupBy) ){ + if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, pS->pGroupBy) + && ExprAlwaysFalse(pExpr)==0 + ){ sqlite3 *db = pWalker->pParse->db; Expr *pNew = sqlite3Expr(db, TK_INTEGER, "1"); if( pNew ){ diff --git a/test/having.test b/test/having.test index a3882552d3..71a44637b9 100644 --- a/test/having.test +++ b/test/having.test @@ -65,8 +65,8 @@ foreach {tn sql1 sql2} { 3 "SELECT a, sum(b) FROM t1 GROUP BY a COLLATE binary HAVING a=2" "SELECT a, sum(b) FROM t1 WHERE a=2 GROUP BY a COLLATE binary" - 5 "SELECT a, sum(b) FROM t1 GROUP BY a COLLATE binary HAVING 0" - "SELECT a, sum(b) FROM t1 WHERE 0 GROUP BY a COLLATE binary" + 5 "SELECT a, sum(b) FROM t1 GROUP BY a COLLATE binary HAVING 1" + "SELECT a, sum(b) FROM t1 WHERE 1 GROUP BY a COLLATE binary" 6 "SELECT count(*) FROM t1,t2 WHERE a=c GROUP BY b, d HAVING b=d" "SELECT count(*) FROM t1,t2 WHERE a=c AND b=d GROUP BY b, d" @@ -154,5 +154,25 @@ do_execsql_test 4.3 { SELECT a, sum(b) FROM t3 WHERE nondeter(a) GROUP BY a } {1 4 2 2} +#------------------------------------------------------------------------- +reset_db +do_execsql_test 5.0 { + CREATE TABLE t1(a, b); + CREATE TABLE t2(x, y); + INSERT INTO t1 VALUES('a', 'b'); +} + +# The WHERE clause (a=2), uses an aggregate column from the outer query. +# If the HAVING term (0) is moved into the WHERE clause in this case, +# SQLite would at one point optimize (a=2 AND 0) to simply (0). Which +# is logically correct, but happened to cause problems in aggregate +# processing for the outer query. This test case verifies that those +# problems are no longer present. +do_execsql_test 5.1 { + SELECT min(b), ( + SELECT x FROM t2 WHERE a=2 GROUP BY y HAVING 0 + ) FROM t1; +} {b {}} + finish_test From 9a60e716f7092c9b52adfcb4ef03d76fd1aa8d03 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 22 Dec 2020 19:57:53 +0000 Subject: [PATCH 080/257] Fix a couple spelling typos in comments. FossilOrigin-Name: 907ddf86766ebdbe39bdc89543c1a7bbd65c710c9f3a3a4d796845b2c02b711b --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/insert.c | 2 +- src/where.c | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 3b65f9b378..de036f04b7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\shandling\ssub-queries\swith\sboth\sa\scorrelated\sWHERE\sclause\sand\sa\s"HAVING\s0"\sclause\swhere\sthe\sparent\squery\sis\sitself\san\saggregate. -D 2020-12-22T16:23:29.675 +C Fix\sa\scouple\sspelling\stypos\sin\scomments. +D 2020-12-22T19:57:53.468 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -501,7 +501,7 @@ 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 7300982986b0aae32382ce57438998b92efa64e9a7169378e83c1c5d0e2ecdb3 +F src/insert.c 74d8c23c9a94d0ebe46084e9b29c3c242485ccbad6c646f3829f73111d0758c2 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 F src/main.c 97e9f137354bc1f76dc9bb60a0a24f8c45cf73b33e80d3ee4c64155336fb820d @@ -627,7 +627,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 69e770e96fd56cc21608992bf2c6f1f3dc5cf2572d0495c6a643b06c3a679f14 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c d9c4e454ebb9499e908aa62d55b8994c375cf5355ac78f60d45af17f7890701c -F src/where.c 2d593bfc6fa24e53dfe7c99bd327af687f8502e5f0e0299dd2c0f503b133f0bb +F src/where.c 3d31871d03906312d7d71a9c0b28c97bcbaead7606dfc15f9b3d080b18702385 F src/whereInt.h 9a3f577619f07700d16d89eeb2f3d94d6b7ed7f109c2dacf0ce8844921549506 F src/wherecode.c a3a1aff30fe99a818d8e7c607980f033f40c68d890e03ed25838b9dbb7908bee F src/whereexpr.c 3a463e156ea388083c501502229c2c7f4f5c6b5330ea59bdf40d6eb6e155a25f @@ -1894,7 +1894,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 82884438e30ad8241f8249927fe92e0856d78b64d7ade38f3d5bb1c931d958d0 -R 5b9b1eafbef4593babef1f4d206a30c6 -U dan -Z a856915eaf20f0d711508df4b26bec16 +P f62f983b56623f0ec34f9a54ce1c21b013a20399162f5ee6ee43b23f10c2ecd5 +R 5cb77512797b3ddd065c48a0657933eb +U mistachkin +Z ce0438cd19d68cbd0a8441516b190bfc diff --git a/manifest.uuid b/manifest.uuid index f2c6e3ef47..fdb22f23c6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f62f983b56623f0ec34f9a54ce1c21b013a20399162f5ee6ee43b23f10c2ecd5 \ No newline at end of file +907ddf86766ebdbe39bdc89543c1a7bbd65c710c9f3a3a4d796845b2c02b711b \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 9913136db7..bc8a7f5b25 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1938,7 +1938,7 @@ void sqlite3GenerateConstraintChecks( ** the UNIQUE constraints have run. */ if( onError==OE_Replace /* IPK rule is REPLACE */ - && onError!=overrideError /* Rules for other contraints are different */ + && onError!=overrideError /* Rules for other constraints are different */ && pTab->pIndex /* There exist other constraints */ ){ ipkTop = sqlite3VdbeAddOp0(v, OP_Goto)+1; diff --git a/src/where.c b/src/where.c index e2f8cbca21..0f219d4391 100644 --- a/src/where.c +++ b/src/where.c @@ -2605,7 +2605,7 @@ static int whereLoopAddBtreeIndex( pBtm = pTerm; pTop = 0; if( pTerm->wtFlags & TERM_LIKEOPT ){ - /* Range contraints that come from the LIKE optimization are + /* Range constraints that come from the LIKE optimization are ** always used in pairs. */ pTop = &pTerm[1]; assert( (pTop-(pTerm->pWC->a))pWC->nTerm ); From 7225bfef164bced949c0ba98436b1fa104546493 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 22 Dec 2020 20:35:22 +0000 Subject: [PATCH 081/257] Fix SQLITE_OMIT_WINDOWFUNC builds by moving declaration of sqlite3ExpandSubquery out of "ifndef SQLITE_OMIT_WINDOWFUNC" block. FossilOrigin-Name: 9587fa8b29fc2f91d751a71b909f574014656f24d276b4974f47fcc18dbadcb8 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqliteInt.h | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index de036f04b7..45336da30c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scouple\sspelling\stypos\sin\scomments. -D 2020-12-22T19:57:53.468 +C Fix\sSQLITE_OMIT_WINDOWFUNC\sbuilds\sby\smoving\sdeclaration\sof\ssqlite3ExpandSubquery\sout\sof\s"ifndef\sSQLITE_OMIT_WINDOWFUNC"\sblock. +D 2020-12-22T20:35:22.397 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -545,7 +545,7 @@ F src/shell.c.in 6dd0d9260220f807d6d1b8e57dd6e163fe55bd0e97fa416c8c139162e341613 F src/sqlite.h.in 0af968a1fa3c717261e1df0ed105fa7bddb4d82de7e0adb3eab49e6aa81b4de7 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h 53c440c2e62844aede29ce692ead431c8c7edd858ed6030f72829bc4bbe5a362 +F src/sqliteInt.h bd9c97bbf54ed566be46fe55b5c5d9506b66e627f483c7d4791fcdd26b639418 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1894,7 +1894,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 f62f983b56623f0ec34f9a54ce1c21b013a20399162f5ee6ee43b23f10c2ecd5 -R 5cb77512797b3ddd065c48a0657933eb -U mistachkin -Z ce0438cd19d68cbd0a8441516b190bfc +P 907ddf86766ebdbe39bdc89543c1a7bbd65c710c9f3a3a4d796845b2c02b711b +R dd30694e4f91ee91b88bcc802eb6d9cd +U dan +Z c8215834a8a499c013c16379be6fc471 diff --git a/manifest.uuid b/manifest.uuid index fdb22f23c6..b931e07ba6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -907ddf86766ebdbe39bdc89543c1a7bbd65c710c9f3a3a4d796845b2c02b711b \ No newline at end of file +9587fa8b29fc2f91d751a71b909f574014656f24d276b4974f47fcc18dbadcb8 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 70cc68a2f1..37df2911a6 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3918,7 +3918,6 @@ int sqlite3WindowCompare(Parse*, Window*, Window*, int); void sqlite3WindowCodeInit(Parse*, Select*); void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int); int sqlite3WindowRewrite(Parse*, Select*); -int sqlite3ExpandSubquery(Parse*, struct SrcList_item*); void sqlite3WindowUpdate(Parse*, Window*, Window*, FuncDef*); Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p); Window *sqlite3WindowListDup(sqlite3 *db, Window *p); @@ -4655,6 +4654,7 @@ void sqlite3ExpirePreparedStatements(sqlite3*, int); void sqlite3CodeRhsOfIN(Parse*, Expr*, int); int sqlite3CodeSubselect(Parse*, Expr*); void sqlite3SelectPrep(Parse*, Select*, NameContext*); +int sqlite3ExpandSubquery(Parse*, struct SrcList_item*); void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p); int sqlite3MatchEName( const struct ExprList_item*, From 0cb735b9fbc76f8f14798f48c166f1b31ab8a9dd Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 23 Dec 2020 16:46:39 +0000 Subject: [PATCH 082/257] Add the sqlite3session_memory_used() API to the sessions module. For querying the amount of heap memory currently being used by a session object. FossilOrigin-Name: 823f75c2e448b649cbe9e174be21524ae3f580beedced65701ad49a2dcc5ee19 --- ext/session/sqlite3session.c | 82 ++++++++++++++++++++++++++---------- ext/session/sqlite3session.h | 8 ++++ ext/session/test_session.c | 7 +++ manifest | 16 +++---- manifest.uuid | 2 +- 5 files changed, 84 insertions(+), 31 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index dae2604719..2ee6b427e2 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -48,6 +48,7 @@ struct sqlite3_session { int rc; /* Non-zero if an error has occurred */ void *pFilterCtx; /* First argument to pass to xTableFilter */ int (*xTableFilter)(void *pCtx, const char *zTab); + i64 nMalloc; /* Number of bytes of data allocated */ sqlite3_value *pZeroBlob; /* Value containing X'' */ sqlite3_session *pNext; /* Next session object on same db. */ SessionTable *pTable; /* List of attached tables */ @@ -431,6 +432,26 @@ static int sessionSerializeValue( return SQLITE_OK; } +/* +** Allocate and return a pointer to a buffer nByte bytes in size. If +** pSession is not NULL, increase the sqlite3_session.nMalloc variable +** by the number of bytes allocated. +*/ +static void *sessionMalloc64(sqlite3_session *pSession, i64 nByte){ + void *pRet = sqlite3_malloc64(nByte); + if( pSession ) pSession->nMalloc += sqlite3_msize(pRet); + return pRet; +} + +/* +** Free buffer pFree, which must have been allocated by an earlier +** call to sessionMalloc64(). If pSession is not NULL, decrease the +** sqlite3_session.nMalloc counter by the number of bytes freed. +*/ +static void sessionFree(sqlite3_session *pSession, void *pFree){ + if( pSession ) pSession->nMalloc -= sqlite3_msize(pFree); + sqlite3_free(pFree); +} /* ** This macro is used to calculate hash key values for data structures. In @@ -898,13 +919,19 @@ static int sessionPreupdateEqual( ** Growing the hash table in this case is a performance optimization only, ** it is not required for correct operation. */ -static int sessionGrowHash(int bPatchset, SessionTable *pTab){ +static int sessionGrowHash( + sqlite3_session *pSession, /* For memory accounting. May be NULL */ + int bPatchset, + SessionTable *pTab +){ if( pTab->nChange==0 || pTab->nEntry>=(pTab->nChange/2) ){ int i; SessionChange **apNew; sqlite3_int64 nNew = 2*(sqlite3_int64)(pTab->nChange ? pTab->nChange : 128); - apNew = (SessionChange **)sqlite3_malloc64(sizeof(SessionChange *) * nNew); + apNew = (SessionChange**)sessionMalloc64( + pSession, sizeof(SessionChange*) * nNew + ); if( apNew==0 ){ if( pTab->nChange==0 ){ return SQLITE_ERROR; @@ -925,7 +952,7 @@ static int sessionGrowHash(int bPatchset, SessionTable *pTab){ } } - sqlite3_free(pTab->apChange); + sessionFree(pSession, pTab->apChange); pTab->nChange = nNew; pTab->apChange = apNew; } @@ -959,6 +986,7 @@ static int sessionGrowHash(int bPatchset, SessionTable *pTab){ ** be freed using sqlite3_free() by the caller */ static int sessionTableInfo( + sqlite3_session *pSession, /* For memory accounting. May be NULL */ sqlite3 *db, /* Database connection */ const char *zDb, /* Name of attached database (e.g. "main") */ const char *zThis, /* Table name */ @@ -1013,7 +1041,7 @@ static int sessionTableInfo( if( rc==SQLITE_OK ){ nByte += nDbCol * (sizeof(const char *) + sizeof(u8) + 1); - pAlloc = sqlite3_malloc64(nByte); + pAlloc = sessionMalloc64(pSession, nByte); if( pAlloc==0 ){ rc = SQLITE_NOMEM; } @@ -1056,7 +1084,7 @@ static int sessionTableInfo( *pabPK = 0; *pnCol = 0; if( pzTab ) *pzTab = 0; - sqlite3_free(azCol); + sessionFree(pSession, azCol); } sqlite3_finalize(pStmt); return rc; @@ -1078,7 +1106,7 @@ static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){ if( pTab->nCol==0 ){ u8 *abPK; assert( pTab->azCol==0 || pTab->abPK==0 ); - pSession->rc = sessionTableInfo(pSession->db, pSession->zDb, + pSession->rc = sessionTableInfo(pSession, pSession->db, pSession->zDb, pTab->zName, &pTab->nCol, 0, &pTab->azCol, &abPK ); if( pSession->rc==SQLITE_OK ){ @@ -1169,7 +1197,7 @@ static void sessionPreupdateOneChange( } /* Grow the hash table if required */ - if( sessionGrowHash(0, pTab) ){ + if( sessionGrowHash(pSession, 0, pTab) ){ pSession->rc = SQLITE_NOMEM; return; } @@ -1236,7 +1264,7 @@ static void sessionPreupdateOneChange( } /* Allocate the change object */ - pChange = (SessionChange *)sqlite3_malloc64(nByte); + pChange = (SessionChange *)sessionMalloc64(pSession, nByte); if( !pChange ){ rc = SQLITE_NOMEM; goto error_out; @@ -1609,7 +1637,7 @@ int sqlite3session_diff( int nCol; /* Columns in zFrom.zTbl */ u8 *abPK; const char **azCol = 0; - rc = sessionTableInfo(db, zFrom, zTbl, &nCol, 0, &azCol, &abPK); + rc = sessionTableInfo(0, db, zFrom, zTbl, &nCol, 0, &azCol, &abPK); if( rc==SQLITE_OK ){ if( pTo->nCol!=nCol ){ bMismatch = 1; @@ -1707,7 +1735,7 @@ int sqlite3session_create( ** Free the list of table objects passed as the first argument. The contents ** of the changed-rows hash tables are also deleted. */ -static void sessionDeleteTable(SessionTable *pList){ +static void sessionDeleteTable(sqlite3_session *pSession, SessionTable *pList){ SessionTable *pNext; SessionTable *pTab; @@ -1719,12 +1747,12 @@ static void sessionDeleteTable(SessionTable *pList){ SessionChange *pNextChange; for(p=pTab->apChange[i]; p; p=pNextChange){ pNextChange = p->pNext; - sqlite3_free(p); + sessionFree(pSession, p); } } - sqlite3_free((char*)pTab->azCol); /* cast works around VC++ bug */ - sqlite3_free(pTab->apChange); - sqlite3_free(pTab); + sessionFree(pSession, (char*)pTab->azCol); /* cast works around VC++ bug */ + sessionFree(pSession, pTab->apChange); + sessionFree(pSession, pTab); } } @@ -1752,9 +1780,11 @@ void sqlite3session_delete(sqlite3_session *pSession){ /* Delete all attached table objects. And the contents of their ** associated hash-tables. */ - sessionDeleteTable(pSession->pTable); + sessionDeleteTable(pSession, pSession->pTable); - /* Free the session object itself. */ + /* Assert that all allocations have been freed and then free the + ** session object itself. */ + assert( pSession->nMalloc==0 ); sqlite3_free(pSession); } @@ -1801,7 +1831,8 @@ int sqlite3session_attach( if( !pTab ){ /* Allocate new SessionTable object. */ - pTab = (SessionTable *)sqlite3_malloc64(sizeof(SessionTable) + nName + 1); + int nByte = sizeof(SessionTable) + nName + 1; + pTab = (SessionTable*)sessionMalloc64(pSession, nByte); if( !pTab ){ rc = SQLITE_NOMEM; }else{ @@ -2398,7 +2429,7 @@ static int sessionGenerateChangeset( int nNoop; /* Size of buffer after writing tbl header */ /* Check the table schema is still Ok. */ - rc = sessionTableInfo(db, pSession->zDb, zName, &nCol, 0, &azCol, &abPK); + rc = sessionTableInfo(0, db, pSession->zDb, zName, &nCol, 0,&azCol,&abPK); if( !rc && (pTab->nCol!=nCol || memcmp(abPK, pTab->abPK, nCol)) ){ rc = SQLITE_SCHEMA; } @@ -2573,6 +2604,13 @@ int sqlite3session_isempty(sqlite3_session *pSession){ return (ret==0); } +/* +** Return the amount of heap memory in use. +*/ +sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession){ + return pSession->nMalloc; +} + /* ** Do the work for either sqlite3changeset_start() or start_strm(). */ @@ -4384,7 +4422,7 @@ static int sessionChangesetApply( int i; sqlite3changeset_pk(pIter, &abPK, 0); - rc = sessionTableInfo( + rc = sessionTableInfo(0, db, "main", zNew, &sApply.nCol, &zTab, &sApply.azCol, &sApply.abPK ); if( rc!=SQLITE_OK ) break; @@ -4863,7 +4901,7 @@ static int sessionChangesetToHash( } } - if( sessionGrowHash(pIter->bPatchset, pTab) ){ + if( sessionGrowHash(0, pIter->bPatchset, pTab) ){ rc = SQLITE_NOMEM; break; } @@ -5049,7 +5087,7 @@ int sqlite3changegroup_output_strm( */ void sqlite3changegroup_delete(sqlite3_changegroup *pGrp){ if( pGrp ){ - sessionDeleteTable(pGrp->pList); + sessionDeleteTable(0, pGrp->pList); sqlite3_free(pGrp); } } @@ -5450,7 +5488,7 @@ int sqlite3rebaser_rebase_strm( */ void sqlite3rebaser_delete(sqlite3_rebaser *p){ if( p ){ - sessionDeleteTable(p->grp.pList); + sessionDeleteTable(0, p->grp.pList); sqlite3_free(p); } } diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 1ed3b550f4..3785a77240 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -440,6 +440,14 @@ int sqlite3session_patchset( */ int sqlite3session_isempty(sqlite3_session *pSession); +/* +** CAPI3REF: Query for the amount of heap memory used by a session object. +** +** This API returns the total amount of heap memory in bytes currently +** used by the session object passed as the only argument. +*/ +sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession); + /* ** CAPI3REF: Create An Iterator To Traverse A Changeset ** CONSTRUCTOR: sqlite3_changeset_iter diff --git a/ext/session/test_session.c b/ext/session/test_session.c index 82f30979f5..7f6cd0eb97 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -242,6 +242,7 @@ static int SQLITE_TCLAPI test_session_cmd( { "table_filter", 1, "SCRIPT", }, /* 6 */ { "patchset", 0, "", }, /* 7 */ { "diff", 2, "FROMDB TBL", }, /* 8 */ + { "memory_used", 0, "", }, /* 9 */ { 0 } }; int iSub; @@ -347,6 +348,12 @@ static int SQLITE_TCLAPI test_session_cmd( } break; } + + case 9: { /* memory_used */ + sqlite3_int64 nMalloc = sqlite3session_memory_used(pSession); + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(nMalloc)); + break; + } } return TCL_OK; diff --git a/manifest b/manifest index 45336da30c..fddff0b8a5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sSQLITE_OMIT_WINDOWFUNC\sbuilds\sby\smoving\sdeclaration\sof\ssqlite3ExpandSubquery\sout\sof\s"ifndef\sSQLITE_OMIT_WINDOWFUNC"\sblock. -D 2020-12-22T20:35:22.397 +C Add\sthe\ssqlite3session_memory_used()\sAPI\sto\sthe\ssessions\smodule.\sFor\squerying\sthe\samount\sof\sheap\smemory\scurrently\sbeing\sused\sby\sa\ssession\sobject. +D 2020-12-23T16:46:39.915 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -453,9 +453,9 @@ F ext/session/sessioninvert.test 04075517a9497a80d39c495ba6b44f3982c7371129b89e2 F ext/session/sessionrebase.test ccfa716b23bd1d3b03217ee58cfd90c78d4b99f53e6a9a2f05e82363b9142810 F ext/session/sessionstat1.test 218d351cf9fcd6648f125a26b607b140310160184723c2666091b54450a68fb5 F ext/session/sessionwor.test 67b5ab91d4f93ce65ff1f58240ac5ddf73f8670facc1ffa49cef56293d52818d -F ext/session/sqlite3session.c 2c76b8c3a5d6dab736686f8a48833b8bdac0871ecc6f447f9839d28bd4a63d6c -F ext/session/sqlite3session.h a2db5b72b938d12c727b4b4ec632254ca493670a9c0de597af3271a7f774fc57 -F ext/session/test_session.c 24286d958dc6f4ca4d7e710f09bc0fa9d50956a40dd99fd8223e7488024c71fe +F ext/session/sqlite3session.c d2aaaf05241ac7d23a1b1eaa8b1f165c90f7ff0fe57ff1932a87c6b89b886117 +F ext/session/sqlite3session.h f53c99731882bf59c7362855cdeba176ce1fe8eeba089e38a8cce0172f8473aa +F ext/session/test_session.c 93ca965112d2b4d9d669c9c0be6b1e52942a268796050a145612df1eee175ce0 F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb @@ -1894,7 +1894,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 907ddf86766ebdbe39bdc89543c1a7bbd65c710c9f3a3a4d796845b2c02b711b -R dd30694e4f91ee91b88bcc802eb6d9cd +P 9587fa8b29fc2f91d751a71b909f574014656f24d276b4974f47fcc18dbadcb8 +R 8a19a9976fc51c3ed2ff74d48489d86a U dan -Z c8215834a8a499c013c16379be6fc471 +Z bb9f93711cbcff6309bc973aaedad8c7 diff --git a/manifest.uuid b/manifest.uuid index b931e07ba6..541e80f318 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9587fa8b29fc2f91d751a71b909f574014656f24d276b4974f47fcc18dbadcb8 \ No newline at end of file +823f75c2e448b649cbe9e174be21524ae3f580beedced65701ad49a2dcc5ee19 \ No newline at end of file From 277a30d9ce5ea64a36b2b970c3e39c275e6999b8 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 28 Dec 2020 21:42:38 +0000 Subject: [PATCH 083/257] Fix missing comma in ctime.c that would cause the ENABLE_MATH_FUNCTIONS output rw to merge with whatever row followed. Problem reported in [forum:/forumpost/aacac97680|forum post aacac97680]. FossilOrigin-Name: 328bc4a01dd67096be49c8b5a656109ad2839a7959d1b00c02a96bfbcb44ec18 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/ctime.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index fddff0b8a5..28ec51ccf2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite3session_memory_used()\sAPI\sto\sthe\ssessions\smodule.\sFor\squerying\sthe\samount\sof\sheap\smemory\scurrently\sbeing\sused\sby\sa\ssession\sobject. -D 2020-12-23T16:46:39.915 +C Fix\smissing\scomma\sin\sctime.c\sthat\swould\scause\sthe\sENABLE_MATH_FUNCTIONS\noutput\srw\sto\smerge\swith\swhatever\srow\sfollowed.\s\sProblem\sreported\sin\n[forum:/forumpost/aacac97680|forum\spost\saacac97680]. +D 2020-12-28T21:42:38.075 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -487,7 +487,7 @@ F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b7532975733 F src/build.c f6449d4e85e998e14d3f537e8ea898dca2fcb83c277db3e60945af9b9177db81 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e -F src/ctime.c 0bcc6a908779a520be534fd985b2185dfd457588b6798d0bcbf37755a044b7c3 +F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 F src/date.c dace306a10d9b02ee553d454c8e1cf8d3c9b932e137738a6b15b90253a9bfc10 F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c @@ -1894,7 +1894,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 9587fa8b29fc2f91d751a71b909f574014656f24d276b4974f47fcc18dbadcb8 -R 8a19a9976fc51c3ed2ff74d48489d86a -U dan -Z bb9f93711cbcff6309bc973aaedad8c7 +P 823f75c2e448b649cbe9e174be21524ae3f580beedced65701ad49a2dcc5ee19 +R 4cea6028a24f1360fba1c7d5e36beba8 +U drh +Z 164f7b84f32a08eccc89b53be84f4226 diff --git a/manifest.uuid b/manifest.uuid index 541e80f318..09aa60792c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -823f75c2e448b649cbe9e174be21524ae3f580beedced65701ad49a2dcc5ee19 \ No newline at end of file +328bc4a01dd67096be49c8b5a656109ad2839a7959d1b00c02a96bfbcb44ec18 \ No newline at end of file diff --git a/src/ctime.c b/src/ctime.c index f0fdccbdc1..7982f23aeb 100644 --- a/src/ctime.c +++ b/src/ctime.c @@ -260,7 +260,7 @@ static const char * const sqlite3azCompileOpt[] = { "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE), #endif #if SQLITE_ENABLE_MATH_FUNCTIONS - "ENABLE_MATH_FUNCTIONS" + "ENABLE_MATH_FUNCTIONS", #endif #if SQLITE_ENABLE_MEMORY_MANAGEMENT "ENABLE_MEMORY_MANAGEMENT", From a06eafc8fc70b8d6eaef429e75f603518aba7948 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 29 Dec 2020 15:06:26 +0000 Subject: [PATCH 084/257] Do not set the P3 parameter on OP_RowCell when copying an index btree, as P3 is not used in that case. FossilOrigin-Name: eef070a4aadf02a845d0ed00767be049d3b76e811e24797a116776fa836d1b03 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/insert.c | 2 +- src/vdbe.c | 2 ++ 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 28ec51ccf2..8a1fc0f31f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\smissing\scomma\sin\sctime.c\sthat\swould\scause\sthe\sENABLE_MATH_FUNCTIONS\noutput\srw\sto\smerge\swith\swhatever\srow\sfollowed.\s\sProblem\sreported\sin\n[forum:/forumpost/aacac97680|forum\spost\saacac97680]. -D 2020-12-28T21:42:38.075 +C Do\snot\sset\sthe\sP3\sparameter\son\sOP_RowCell\swhen\scopying\san\sindex\sbtree,\sas\nP3\sis\snot\sused\sin\sthat\scase. +D 2020-12-29T15:06:26.440 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -501,7 +501,7 @@ 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 74d8c23c9a94d0ebe46084e9b29c3c242485ccbad6c646f3829f73111d0758c2 +F src/insert.c 81b7ee72cd754b5d0018659d5593355f2d61b3d80f07f200167c4826846e907d F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 F src/main.c 97e9f137354bc1f76dc9bb60a0a24f8c45cf73b33e80d3ee4c64155336fb820d @@ -612,7 +612,7 @@ F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c c0c7977de7ef9b8cb10f6c85f2d0557889a658f817b0455909a49179ba4c8002 F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286 -F src/vdbe.c 808c1503dd183578d7ebcf0e517e636c6005f783daadc9a27305b10597c1142e +F src/vdbe.c 67de20067fa3a2ee8566342c751e941a2fe3fd88940fd9886ca5115f04165cce F src/vdbe.h 83603854bfa5851af601fc0947671eb260f4363e62e960e8a994fb9bbcd2aaa1 F src/vdbeInt.h 3ca5e9fd6e095a8b6cf6bc3587a46fc93499503b2fe48951e1034ba9e2ce2f6e F src/vdbeapi.c c5e7cb2ab89a24d7f723e87b508f21bfb1359a04db5277d8a99fd1e015c12eb9 @@ -1894,7 +1894,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 823f75c2e448b649cbe9e174be21524ae3f580beedced65701ad49a2dcc5ee19 -R 4cea6028a24f1360fba1c7d5e36beba8 +P 328bc4a01dd67096be49c8b5a656109ad2839a7959d1b00c02a96bfbcb44ec18 +R 781b48b7ecdc86b8a50d5d0b6180469c U drh -Z 164f7b84f32a08eccc89b53be84f4226 +Z 7a280581b61c05a6f5da0fb16cf85e09 diff --git a/manifest.uuid b/manifest.uuid index 09aa60792c..7aff062ebd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -328bc4a01dd67096be49c8b5a656109ad2839a7959d1b00c02a96bfbcb44ec18 \ No newline at end of file +eef070a4aadf02a845d0ed00767be049d3b76e811e24797a116776fa836d1b03 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index bc8a7f5b25..0e52ee7a00 100644 --- a/src/insert.c +++ b/src/insert.c @@ -2991,7 +2991,7 @@ static int xferOptimization( if( i==pSrcIdx->nColumn ){ idxInsFlags = OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT; sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest); - sqlite3VdbeAddOp3(v, OP_RowCell, iDest, iSrc, regData); + sqlite3VdbeAddOp2(v, OP_RowCell, iDest, iSrc); } }else if( !HasRowid(pSrc) && pDestIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){ idxInsFlags |= OPFLAG_NCHANGE; diff --git a/src/vdbe.c b/src/vdbe.c index 904b5e2bc0..8e107a8a56 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5160,6 +5160,8 @@ case OP_RowCell: { VdbeCursor *pSrc; /* Cursor to read from */ i64 iKey; /* Rowid value to insert with */ assert( pOp[1].opcode==OP_Insert || pOp[1].opcode==OP_IdxInsert ); + assert( pOp[1].opcode==OP_Insert || pOp->p3==0 ); + assert( pOp[1].opcode==OP_IdxInsert || pOp->p3>0 ); assert( pOp[1].p5 & OPFLAG_PREFORMAT ); pDest = p->apCsr[pOp->p1]; pSrc = p->apCsr[pOp->p2]; From c4403ca61afe74ed1ad7af6b1ebe646c89205026 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 30 Dec 2020 13:10:57 +0000 Subject: [PATCH 085/257] New test cases for cursor renumbering in the UNION ALL query flattener. FossilOrigin-Name: 270babf259750f3d6c490a08df608a101b24b3c06b9e8a938a0e09a854af6a20 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/unionall.test | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 8a1fc0f31f..14cf559ebc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sset\sthe\sP3\sparameter\son\sOP_RowCell\swhen\scopying\san\sindex\sbtree,\sas\nP3\sis\snot\sused\sin\sthat\scase. -D 2020-12-29T15:06:26.440 +C New\stest\scases\sfor\scursor\srenumbering\sin\sthe\sUNION\sALL\squery\sflattener. +D 2020-12-30T13:10:57.397 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1627,7 +1627,7 @@ F test/tt3_vacuum.c 1753f45917699c9c1f66b64c717a717c9379f776 F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff F test/types2.test 1aeb81976841a91eef292723649b5c4fe3bc3cac F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a -F test/unionall.test 25fe866e51b6b590f59117d713ee5e88f5ad8d1fea136a0c4b0c597904e07887 +F test/unionall.test ca6f612930c79e30f41f804dff4cce949b61347930847642e333ecd5d79f5964 F test/unionall2.test c9a62db63350bcbce3a7bec50dd8c5410f08be33f8af435473756286d4657215 F test/unionallfault.test 652bfbb630e6c43135965dc1e8f0a9a791da83aec885d626a632fe1909c56f73 F test/unionvtab.test e1704ab1b4c1bb3ffc9da4681f8e85a0b909fd80b937984fc94b27415ac8e5a4 @@ -1894,7 +1894,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 328bc4a01dd67096be49c8b5a656109ad2839a7959d1b00c02a96bfbcb44ec18 -R 781b48b7ecdc86b8a50d5d0b6180469c +P eef070a4aadf02a845d0ed00767be049d3b76e811e24797a116776fa836d1b03 +R 9df7a36b340e01b8e6a68b556d08634a U drh -Z 7a280581b61c05a6f5da0fb16cf85e09 +Z 1966d3d59e34224433c9949aacd8ed2d diff --git a/manifest.uuid b/manifest.uuid index 7aff062ebd..edc513b421 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eef070a4aadf02a845d0ed00767be049d3b76e811e24797a116776fa836d1b03 \ No newline at end of file +270babf259750f3d6c490a08df608a101b24b3c06b9e8a938a0e09a854af6a20 \ No newline at end of file diff --git a/test/unionall.test b/test/unionall.test index 5dfac42e13..5cefa64a82 100644 --- a/test/unionall.test +++ b/test/unionall.test @@ -283,4 +283,47 @@ do_execsql_test 4.3 { 123 t1_a 456 t3_a 123 t1_a {} {} } +# 2020-12-30: dbsqlfuzz find +reset_db +do_execsql_test 5.1 { + CREATE TABLE t1_a(a INTEGER PRIMARY KEY, b TEXT); + INSERT INTO t1_a VALUES(1,'one'); + INSERT INTO t1_a VALUES(0,NULL); + CREATE TABLE t1_b(c INTEGER PRIMARY KEY, d TEXT); + INSERT INTO t1_b VALUES(2,'two'); + INSERT INTO t1_b VALUES(5,'five'); + CREATE TABLE t1_c(e INTEGER PRIMARY KEY, f TEXT); + INSERT INTO t1_c VALUES(3,'three'); + INSERT INTO t1_c VALUES(6,'six'); + CREATE TABLE t2(k,v); + INSERT INTO t2 VALUES(5,'v'); + INSERT INTO t2 VALUES(4,'iv'); + INSERT INTO t2 VALUES(3,'iii'); + INSERT INTO t2 VALUES(2,'ii'); + CREATE TABLE t3_a(k INTEGER PRIMARY KEY, v TEXT); + INSERT INTO t3_a VALUES(2,'ii'); + INSERT INTO t3_a VALUES(4,'iv'); + CREATE TABLE t3_b(k INTEG5R PRIMARY KEY, v TEXT); + INSERT INTO t3_b VALUES(NULL,'iii'); + INSERT INTO t3_b VALUES(NULL,'v'); + CREATE VIEW t1 AS + SELECT a, b FROM t1_a UNION ALL + SELECT c, d FROM t1_b UNION ALL + SELECT e, f FROM t1_c; + CREATE VIEW t3 AS + SELECT * FROM t3_a + UNION ALL + SELECT * FROM t3_b; + CREATE TRIGGER t3_insert INSTEAD OF INSERT ON t3 BEGIN + INSERT INTO t3_a SELECT new.k, new.v WHERE (new.k%2)==0; + INSERT INTO t3_b SELECT new.k, new.v WHERE (new.k%2)==1; + END; +} {} +do_execsql_test 5.10 { + SELECT *, '+' FROM t1 LEFT JOIN t2 ON (a NOT IN(SELECT v FROM t1, t3 WHERE a=k)=NOT EXISTS(SELECT 1 FROM t1 LEFT JOIN t3 ON (a=k))); +} {0 {} {} {} + 1 one {} {} + 2 two {} {} + 5 five {} {} + 3 three {} {} + 6 six {} {} +} +do_execsql_test 5.20 { + SELECT *, '+' FROM t1 LEFT JOIN t3 ON (a NOT IN(SELECT v FROM t1 LEFT JOIN t2 ON (a=k))=k); +} {0 {} {} {} + 1 one {} {} + 2 two {} {} + 5 five {} {} + 3 three {} {} + 6 six {} {} +} + finish_test From 85d31b9f3757016e4dc1b6e5f74fa14ad834aa96 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 30 Dec 2020 13:20:27 +0000 Subject: [PATCH 086/257] New test case for the HAVING fix of check-in [f62f983b56623f0e]. FossilOrigin-Name: 45f46317ab8bd92dcd346bf00ba3a33b0cfd030b790c04e19ef33cff124d8d7f --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/having.test | 13 +++++++++++++ 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 14cf559ebc..66d111cbad 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\stest\scases\sfor\scursor\srenumbering\sin\sthe\sUNION\sALL\squery\sflattener. -D 2020-12-30T13:10:57.397 +C New\stest\scase\sfor\sthe\sHAVING\sfix\sof\scheck-in\s[f62f983b56623f0e]. +D 2020-12-30T13:20:27.167 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1050,7 +1050,7 @@ F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 F test/gcfault.test dd28c228a38976d6336a3fc42d7e5f1ad060cb8c F test/gencol1.test b05e6c5edb9b10d48efb634ed07342441bddc89d225043e17095c36e567521a0 F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 -F test/having.test ea5cb01cdf3d90fd1b516ef36b1fbde518dbbd61c50141f5eb830d8101844040 +F test/having.test a89236dd8d55aa50c4805f82ac9daf64d477a44d712d8209c118978d0ca21ec9 F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751 F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711 F test/hook.test e97382e68e4379838e888756d653afd159f5f14780315ff97b70360d3d8485bc @@ -1894,7 +1894,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 eef070a4aadf02a845d0ed00767be049d3b76e811e24797a116776fa836d1b03 -R 9df7a36b340e01b8e6a68b556d08634a +P 270babf259750f3d6c490a08df608a101b24b3c06b9e8a938a0e09a854af6a20 +R 09227fec8aad1c60b1b910c5f099b057 U drh -Z 1966d3d59e34224433c9949aacd8ed2d +Z 6d7124961a0c65e002372f290392ee57 diff --git a/manifest.uuid b/manifest.uuid index edc513b421..512affabbc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -270babf259750f3d6c490a08df608a101b24b3c06b9e8a938a0e09a854af6a20 \ No newline at end of file +45f46317ab8bd92dcd346bf00ba3a33b0cfd030b790c04e19ef33cff124d8d7f \ No newline at end of file diff --git a/test/having.test b/test/having.test index 71a44637b9..3bfa8120a1 100644 --- a/test/having.test +++ b/test/having.test @@ -174,5 +174,18 @@ do_execsql_test 5.1 { ) FROM t1; } {b {}} +# From chromium +# https://bugs.chromium.org/p/chromium/issues/detail?id=1161869 +# +do_execsql_test 5.2 { + SELECT EXISTS ( + SELECT * FROM ( + SELECT * FROM ( + SELECT 1 + ) WHERE Col0 = 1 GROUP BY 1 + ) WHERE 0 + ) + FROM (SELECT 1 Col0) GROUP BY 1 +} {0} finish_test From 4fd4a7a1e91b6fca1aa7546cd537001c736f655f Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 1 Jan 2021 01:44:06 +0000 Subject: [PATCH 087/257] Do not attempt to take a pointer to the ceil() and floor() functions as those routines are intrinsics on some versions of MSVC. FossilOrigin-Name: e5d7209e118a84537a85c0c9cd2b7ca4cd6ccf04181dc840b19339b4c93840cd --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/func.c | 14 +++++++++++--- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 66d111cbad..fabd0298b1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\stest\scase\sfor\sthe\sHAVING\sfix\sof\scheck-in\s[f62f983b56623f0e]. -D 2020-12-30T13:20:27.167 +C Do\snot\sattempt\sto\stake\sa\spointer\sto\sthe\sceil()\sand\sfloor()\sfunctions\sas\nthose\sroutines\sare\sintrinsics\son\ssome\sversions\sof\sMSVC. +D 2021-01-01T01:44:06.406 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -495,7 +495,7 @@ F src/delete.c 927cf8f900583e79aca8f1a321979e0a8f053babd9a690b44b38f79de2cc09fe F src/expr.c 0d196ed5a2ebf96be7e8df88add4fabfad0dce16c0fed81a4b8f6a26e259797f F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 83372403298e6a7dd989a47aaacdbaa5b4307b5199dbd56e07d4896066b3de72 -F src/func.c 2163afb2cfabb71768f9254b95dbab3b7d4cd94394f6cffb86704e0b7e6ccabe +F src/func.c 6fb20c0bd604af514fa77456446e6f7725e6818dbc21f560fce4616320a06f28 F src/global.c ed55af196a9b66e198aaeda3f5454c3aa7d7d050c6c938181fd044b70d180a81 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 @@ -1894,7 +1894,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 270babf259750f3d6c490a08df608a101b24b3c06b9e8a938a0e09a854af6a20 -R 09227fec8aad1c60b1b910c5f099b057 +P 45f46317ab8bd92dcd346bf00ba3a33b0cfd030b790c04e19ef33cff124d8d7f +R 7df46009733971e381ace45b945cc6c1 U drh -Z 6d7124961a0c65e002372f290392ee57 +Z 8b481f25827e97ba1d6b3da4a1f709c6 diff --git a/manifest.uuid b/manifest.uuid index 512affabbc..731787e87f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -45f46317ab8bd92dcd346bf00ba3a33b0cfd030b790c04e19ef33cff124d8d7f \ No newline at end of file +e5d7209e118a84537a85c0c9cd2b7ca4cd6ccf04181dc840b19339b4c93840cd \ No newline at end of file diff --git a/src/func.c b/src/func.c index e91fc256cb..6cd9fdce66 100644 --- a/src/func.c +++ b/src/func.c @@ -1951,6 +1951,14 @@ static void ceilingFunc( } } +/* +** On some systems, ceil() and floor() are intrinsic function. You are +** unable to take a pointer to this functions. Hence, we here wrap them +** in our own actual functions. +*/ +static double xCeil(double x){ return ceil(x); } +static double xFloor(double x){ return floor(x); } + /* ** Implementation of SQL functions: ** @@ -2211,9 +2219,9 @@ void sqlite3RegisterBuiltinFunctions(void){ FUNCTION(coalesce, 1, 0, 0, 0 ), FUNCTION(coalesce, 0, 0, 0, 0 ), #ifdef SQLITE_ENABLE_MATH_FUNCTIONS - MFUNCTION(ceil, 1, ceil, ceilingFunc ), - MFUNCTION(ceiling, 1, ceil, ceilingFunc ), - MFUNCTION(floor, 1, floor, ceilingFunc ), + MFUNCTION(ceil, 1, xCeil, ceilingFunc ), + MFUNCTION(ceiling, 1, xCeil, ceilingFunc ), + MFUNCTION(floor, 1, xFloor, ceilingFunc ), #if SQLITE_HAVE_C99_MATH_FUNCS MFUNCTION(trunc, 1, trunc, ceilingFunc ), #endif From 33e1ec224ecc953eb2f24f1b5cf4cbe35f99a44e Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 1 Jan 2021 15:13:17 +0000 Subject: [PATCH 088/257] Add the "startup" test program designed to measure startup performance, and in particular schema parsing time. FossilOrigin-Name: 7b3b31efb0047c5a461f487905cffba2b0ddb1518a6e757ca092eb40e1e2cd49 --- Makefile.in | 3 + manifest | 13 +- manifest.uuid | 2 +- test/startup.c | 628 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 639 insertions(+), 7 deletions(-) create mode 100644 test/startup.c diff --git a/Makefile.in b/Makefile.in index 6ab49dbe9a..3fb531256b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1378,6 +1378,9 @@ wordcount$(TEXE): $(TOP)/test/wordcount.c sqlite3.lo speedtest1$(TEXE): $(TOP)/test/speedtest1.c sqlite3.c $(LTLINK) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c $(TLIBS) +startup$(TEXE): $(TOP)/test/startup.c sqlite3.c + $(LTLINK) $(ST_OPT) -o $@ $(TOP)/test/startup.c sqlite3.c $(TLIBS) + KV_OPT += -DSQLITE_DIRECT_OVERFLOW_READ kvtest$(TEXE): $(TOP)/test/kvtest.c sqlite3.c diff --git a/manifest b/manifest index fabd0298b1..706d825b29 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Do\snot\sattempt\sto\stake\sa\spointer\sto\sthe\sceil()\sand\sfloor()\sfunctions\sas\nthose\sroutines\sare\sintrinsics\son\ssome\sversions\sof\sMSVC. -D 2021-01-01T01:44:06.406 +C Add\sthe\s"startup"\stest\sprogram\sdesigned\sto\smeasure\sstartup\sperformance,\nand\sin\sparticular\sschema\sparsing\stime. +D 2021-01-01T15:13:17.551 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 0e88f5d095213a9ccd45c5bbd871c8ead498f886dff4493471fbf48b1f867f9d +F Makefile.in 2e13f6830ef6ee26bdc72dd50536cbd4f5599834185213b50ee5648a393db82d F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241 F Makefile.msc ad07bbd645132533e1fd7164a03acfa9afecda378b3787c10f62ab4c7c45e6ea F README.md 1514a365ffca3c138e00c5cc839906108a01011a6b082bad19b09781e3aa498a @@ -1401,6 +1401,7 @@ F test/spellfix4.test 51c7c26514ade169855c66bcf130bd5acfb4d7fd090cc624645ab275ae F test/sqldiff1.test 28cd737cf1b0078b1ec1bbf425e674c47785835e F test/sqllimits1.test 264f4b0f941800ba139d25e33ee919c5d95fea06dfbe8ac291d6811a30984ca5 F test/sqllog.test 6af6cb0b09f4e44e1917e06ce85be7670302517a +F test/startup.c 1beb5ca66fcc0fce95c3444db9d1674f90fc605499a574ae2434dcfc10d22805 F test/stat.test 15a3106eddedfc882f64bc09f237b4169be4b92dd57c93031b8ff8b13af3e7c5 F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1 F test/stmt.test 54ed2cc0764bf3e48a058331813c3dbd19fc1d0827c3d8369914a5d8f564ec75 @@ -1894,7 +1895,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 45f46317ab8bd92dcd346bf00ba3a33b0cfd030b790c04e19ef33cff124d8d7f -R 7df46009733971e381ace45b945cc6c1 +P e5d7209e118a84537a85c0c9cd2b7ca4cd6ccf04181dc840b19339b4c93840cd +R 4199bcdca03d0dfcf22a616708200b54 U drh -Z 8b481f25827e97ba1d6b3da4a1f709c6 +Z 0a6e287c5f9af8cda46993666a938c17 diff --git a/manifest.uuid b/manifest.uuid index 731787e87f..41fb89a951 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e5d7209e118a84537a85c0c9cd2b7ca4cd6ccf04181dc840b19339b4c93840cd \ No newline at end of file +7b3b31efb0047c5a461f487905cffba2b0ddb1518a6e757ca092eb40e1e2cd49 \ No newline at end of file diff --git a/test/startup.c b/test/startup.c new file mode 100644 index 0000000000..7262189229 --- /dev/null +++ b/test/startup.c @@ -0,0 +1,628 @@ +/* +** 2021-01-01 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file implements a program used to measure the start-up performance +** of SQLite. +** +** To use: +** +** ./startup init +** valgrind --tool=cachegrind ./startup run +** +** +** The "./startup init" command creates the test database file named +** "startup.db". The performance test is run by the "./startup run" +** command. That command does nothing but open the database file and +** parse the entire schema. +*/ +#include +#include +#include +#include +#include +#include "sqlite3.h" + +static const char zHelp[] = + "Usage: %s COMMAND\n" + "Commands:\n" + " init Initialized the startup.db database file\n" + " run Run the startup performance test\n" + "Options:\n" + " --dbname NAME Set the name of the test database file\n" + " --heap SZ MIN Memory allocator uses SZ bytes & min allocation MIN\n" + " --stats Show statistics at the end\n" +/* TBD + " --journal M Set the journal_mode to M\n" + " --lookaside N SZ Configure lookaside for N slots of SZ bytes each\n" + " --mmap SZ MMAP the first SZ bytes of the database file\n" + " --multithread Set multithreaded mode\n" + " --nomemstat Disable memory statistics\n" + " --pagesize N Set the page size to N\n" + " --pcache N SZ Configure N pages of pagecache each of size SZ bytes\n" + " --serialized Set serialized threading mode\n" + " --singlethread Set single-threaded mode - disables all mutexing\n" + " --utf16be Set text encoding to UTF-16BE\n" + " --utf16le Set text encoding to UTF-16LE\n" + " --utf8 Set text encoding to UTF-8\n" +*/ +; + +static void usage(const char *argv0){ + printf(zHelp, argv0); + exit(1); +} + +/* +** The test schema is derived from the Fossil repository for SQLite itself. +** The schema covers the repository, the local checkout database, and +** the global configuration database. +*/ +static const char zTestSchema[] = + "CREATE TABLE repo_blob(\n" + " rid INTEGER PRIMARY KEY,\n" + " rcvid INTEGER,\n" + " size INTEGER,\n" + " uuid TEXT UNIQUE NOT NULL,\n" + " content BLOB,\n" + " CHECK( length(uuid)>=40 AND rid>0 )\n" + ");\n" + "CREATE TABLE repo_delta(\n" + " rid INTEGER PRIMARY KEY,\n" + " srcid INTEGER NOT NULL REFERENCES blob\n" + ");\n" + "CREATE TABLE repo_rcvfrom(\n" + " rcvid INTEGER PRIMARY KEY,\n" + " uid INTEGER REFERENCES user,\n" + " mtime DATETIME,\n" + " nonce TEXT UNIQUE,\n" + " ipaddr TEXT\n" + ");\n" + "CREATE TABLE repo_private(rid INTEGER PRIMARY KEY);\n" + "CREATE TABLE repo_accesslog(\n" + " uname TEXT,\n" + " ipaddr TEXT,\n" + " success BOOLEAN,\n" + " mtime TIMESTAMP);\n" + "CREATE TABLE repo_user(\n" + " uid INTEGER PRIMARY KEY,\n" + " login TEXT UNIQUE,\n" + " pw TEXT,\n" + " cap TEXT,\n" + " cookie TEXT,\n" + " ipaddr TEXT,\n" + " cexpire DATETIME,\n" + " info TEXT,\n" + " mtime DATE,\n" + " photo BLOB\n" + ");\n" + "CREATE TABLE repo_reportfmt(\n" + " rn INTEGER PRIMARY KEY,\n" + " owner TEXT,\n" + " title TEXT UNIQUE,\n" + " mtime INTEGER,\n" + " cols TEXT,\n" + " sqlcode TEXT\n" + ");\n" + "CREATE TABLE repo_sqlite_stat2(tbl,idx,sampleno,sample);\n" + "CREATE TABLE repo_sqlite_stat1(tbl,idx,stat);\n" + "CREATE TABLE repo_sqlite_stat3(tbl,idx,neq,nlt,ndlt,sample);\n" + "CREATE TABLE repo_config(\n" + " name TEXT PRIMARY KEY NOT NULL,\n" + " value CLOB, mtime INTEGER,\n" + " CHECK( typeof(name)='text' AND length(name)>=1 )\n" + ") WITHOUT ROWID;\n" + "CREATE TABLE repo_shun(uuid PRIMARY KEY,\n" + " mtime INTEGER,\n" + " scom TEXT) WITHOUT ROWID;\n" + "CREATE TABLE repo_concealed(\n" + " hash TEXT PRIMARY KEY,\n" + " content TEXT\n" + ", mtime INTEGER) WITHOUT ROWID;\n" + "CREATE TABLE repo_admin_log(\n" + " id INTEGER PRIMARY KEY,\n" + " time INTEGER, -- Seconds since 1970\n" + " page TEXT, -- path of page\n" + " who TEXT, -- User who made the change\n" + " what TEXT -- What changed\n" + ");\n" + "CREATE TABLE repo_unversioned(\n" + " name TEXT PRIMARY KEY,\n" + " rcvid INTEGER,\n" + " mtime DATETIME,\n" + " hash TEXT,\n" + " sz INTEGER,\n" + " encoding INT,\n" + " content BLOB\n" + ") WITHOUT ROWID;\n" + "CREATE TABLE repo_subscriber(\n" + " subscriberId INTEGER PRIMARY KEY,\n" + " subscriberCode BLOB DEFAULT (randomblob(32)) UNIQUE,\n" + " semail TEXT UNIQUE COLLATE nocase,\n" + " suname TEXT,\n" + " sverified BOOLEAN DEFAULT true,\n" + " sdonotcall BOOLEAN,\n" + " sdigest BOOLEAN,\n" + " ssub TEXT,\n" + " sctime INTDATE,\n" + " mtime INTDATE,\n" + " smip TEXT\n" + ");\n" + "CREATE TABLE repo_pending_alert(\n" + " eventid TEXT PRIMARY KEY,\n" + " sentSep BOOLEAN DEFAULT false,\n" + " sentDigest BOOLEAN DEFAULT false\n" + ", sentMod BOOLEAN DEFAULT false) WITHOUT ROWID;\n" + "CREATE INDEX repo_delta_i1 ON repo_delta(srcid);\n" + "CREATE INDEX repo_blob_rcvid ON repo_blob(rcvid);\n" + "CREATE INDEX repo_subscriberUname\n" + " ON repo_subscriber(suname) WHERE suname IS NOT NULL;\n" + "CREATE VIEW repo_artifact(rid,rcvid,size,atype,srcid,hash,content) AS\n" + " SELECT blob.rid,rcvid,size,1,srcid,uuid,content\n" + " FROM repo_blob LEFT JOIN repo_delta ON (blob.rid=delta.rid);\n" + "CREATE TABLE repo_filename(\n" + " fnid INTEGER PRIMARY KEY,\n" + " name TEXT UNIQUE\n" + ");\n" + "CREATE TABLE repo_mlink(\n" + " mid INTEGER,\n" + " fid INTEGER,\n" + " pmid INTEGER,\n" + " pid INTEGER,\n" + " fnid INTEGER REFERENCES filename,\n" + " pfnid INTEGER,\n" + " mperm INTEGER,\n" + " isaux BOOLEAN DEFAULT 0\n" + ");\n" + "CREATE INDEX repo_mlink_i1 ON repo_mlink(mid);\n" + "CREATE INDEX repo_mlink_i2 ON repo_mlink(fnid);\n" + "CREATE INDEX repo_mlink_i3 ON repo_mlink(fid);\n" + "CREATE INDEX repo_mlink_i4 ON repo_mlink(pid);\n" + "CREATE TABLE repo_plink(\n" + " pid INTEGER REFERENCES blob,\n" + " cid INTEGER REFERENCES blob,\n" + " isprim BOOLEAN,\n" + " mtime DATETIME,\n" + " baseid INTEGER REFERENCES blob,\n" + " UNIQUE(pid, cid)\n" + ");\n" + "CREATE INDEX repo_plink_i2 ON repo_plink(cid,pid);\n" + "CREATE TABLE repo_leaf(rid INTEGER PRIMARY KEY);\n" + "CREATE TABLE repo_event(\n" + " type TEXT,\n" + " mtime DATETIME,\n" + " objid INTEGER PRIMARY KEY,\n" + " tagid INTEGER,\n" + " uid INTEGER REFERENCES user,\n" + " bgcolor TEXT,\n" + " euser TEXT,\n" + " user TEXT,\n" + " ecomment TEXT,\n" + " comment TEXT,\n" + " brief TEXT,\n" + " omtime DATETIME\n" + ");\n" + "CREATE INDEX repo_event_i1 ON repo_event(mtime);\n" + "CREATE TABLE repo_phantom(\n" + " rid INTEGER PRIMARY KEY\n" + ");\n" + "CREATE TABLE repo_orphan(\n" + " rid INTEGER PRIMARY KEY,\n" + " baseline INTEGER\n" + ");\n" + "CREATE INDEX repo_orphan_baseline ON repo_orphan(baseline);\n" + "CREATE TABLE repo_unclustered(\n" + " rid INTEGER PRIMARY KEY\n" + ");\n" + "CREATE TABLE repo_unsent(\n" + " rid INTEGER PRIMARY KEY\n" + ");\n" + "CREATE TABLE repo_tag(\n" + " tagid INTEGER PRIMARY KEY,\n" + " tagname TEXT UNIQUE\n" + ");\n" + "CREATE TABLE repo_tagxref(\n" + " tagid INTEGER REFERENCES tag,\n" + " tagtype INTEGER,\n" + " srcid INTEGER REFERENCES blob,\n" + " origid INTEGER REFERENCES blob,\n" + " value TEXT,\n" + " mtime TIMESTAMP,\n" + " rid INTEGER REFERENCE blob,\n" + " UNIQUE(rid, tagid)\n" + ");\n" + "CREATE INDEX repo_tagxref_i1 ON repo_tagxref(tagid, mtime);\n" + "CREATE TABLE repo_backlink(\n" + " target TEXT,\n" + " srctype INT,\n" + " srcid INT,\n" + " mtime TIMESTAMP,\n" + " UNIQUE(target, srctype, srcid)\n" + ");\n" + "CREATE INDEX repo_backlink_src ON repo_backlink(srcid, srctype);\n" + "CREATE TABLE repo_attachment(\n" + " attachid INTEGER PRIMARY KEY,\n" + " isLatest BOOLEAN DEFAULT 0,\n" + " mtime TIMESTAMP,\n" + " src TEXT,\n" + " target TEXT,\n" + " filename TEXT,\n" + " comment TEXT,\n" + " user TEXT\n" + ");\n" + "CREATE INDEX repo_attachment_idx1\n" + " ON repo_attachment(target, filename, mtime);\n" + "CREATE INDEX repo_attachment_idx2 ON repo_attachment(src);\n" + "CREATE TABLE repo_cherrypick(\n" + " parentid INT,\n" + " childid INT,\n" + " isExclude BOOLEAN DEFAULT false,\n" + " PRIMARY KEY(parentid, childid)\n" + ") WITHOUT ROWID;\n" + "CREATE INDEX repo_cherrypick_cid ON repo_cherrypick(childid);\n" + "CREATE TABLE repo_ticket(\n" + " -- Do not change any column that begins with tkt_\n" + " tkt_id INTEGER PRIMARY KEY,\n" + " tkt_uuid TEXT UNIQUE,\n" + " tkt_mtime DATE,\n" + " tkt_ctime DATE,\n" + " -- Add as many fields as required below this line\n" + " type TEXT,\n" + " status TEXT,\n" + " subsystem TEXT,\n" + " priority TEXT,\n" + " severity TEXT,\n" + " foundin TEXT,\n" + " private_contact TEXT,\n" + " resolution TEXT,\n" + " title TEXT,\n" + " comment TEXT\n" + ");\n" + "CREATE TABLE repo_ticketchng(\n" + " -- Do not change any column that begins with tkt_\n" + " tkt_id INTEGER REFERENCES ticket,\n" + " tkt_rid INTEGER REFERENCES blob,\n" + " tkt_mtime DATE,\n" + " -- Add as many fields as required below this line\n" + " login TEXT,\n" + " username TEXT,\n" + " mimetype TEXT,\n" + " icomment TEXT\n" + ");\n" + "CREATE INDEX repo_ticketchng_idx1 ON repo_ticketchng(tkt_id, tkt_mtime);\n" + "CREATE TRIGGER repo_alert_trigger1\n" + "AFTER INSERT ON repo_event BEGIN\n" + " INSERT INTO repo_pending_alert(eventid)\n" + " SELECT printf('%.1c%d',new.type,new.objid) WHERE true\n" + " ON CONFLICT(eventId) DO NOTHING;\n" + "END;\n" + "CREATE TABLE repo_vcache(\n" + " vid INTEGER, -- check-in ID\n" + " fname TEXT, -- filename\n" + " rid INTEGER, -- artifact ID\n" + " PRIMARY KEY(vid,fname)\n" + ") WITHOUT ROWID;\n" + "CREATE TABLE localdb_vvar(\n" + " name TEXT PRIMARY KEY NOT NULL,\n" + " value CLOB,\n" + " CHECK( typeof(name)='text' AND length(name)>=1 )\n" + ");\n" + "CREATE TABLE localdb_vfile(\n" + " id INTEGER PRIMARY KEY,\n" + " vid INTEGER REFERENCES blob,\n" + " chnged INT DEFAULT 0,\n" + " deleted BOOLEAN DEFAULT 0,\n" + " isexe BOOLEAN,\n" + " islink BOOLEAN,\n" + " rid INTEGER,\n" + " mrid INTEGER,\n" + " mtime INTEGER,\n" + " pathname TEXT,\n" + " origname TEXT, mhash,\n" + " UNIQUE(pathname,vid)\n" + ");\n" + "CREATE TABLE localdb_sqlite_stat1(tbl,idx,stat);\n" + "CREATE TABLE localdb_vcache(\n" + " vid INTEGER, -- check-in ID\n" + " fname TEXT, -- filename\n" + " rid INTEGER, -- artifact ID\n" + " PRIMARY KEY(vid,fname)\n" + ") WITHOUT ROWID;\n" + "CREATE TABLE localdb_stash(\n" + " stashid INTEGER PRIMARY KEY,\n" + " vid INTEGER,\n" + " hash TEXT,\n" + " comment TEXT,\n" + " ctime TIMESTAMP\n" + ");\n" + "CREATE TABLE localdb_stashfile(\n" + " stashid INTEGER REFERENCES stash,\n" + " isAdded BOOLEAN,\n" + " isRemoved BOOLEAN,\n" + " isExec BOOLEAN,\n" + " isLink BOOLEAN,\n" + " rid INTEGER,\n" + " hash TEXT,\n" + " origname TEXT,\n" + " newname TEXT,\n" + " delta BLOB,\n" + " PRIMARY KEY(newname, stashid)\n" + ");\n" + "CREATE TABLE localdb_vmerge(\n" + " id INTEGER REFERENCES vfile,\n" + " merge INTEGER,\n" + " mhash TEXT\n" + ");\n" + "CREATE UNIQUE INDEX localdb_vmergex1 ON localdb_vmerge(id,mhash);\n" + "CREATE TRIGGER localdb_vmerge_ck1 AFTER INSERT ON localdb_vmerge\n" + "WHEN new.mhash IS NULL BEGIN\n" + " SELECT raise(FAIL,\n" + " 'trying to update a newer checkout with an older version of Fossil');\n" + "END;\n" + "CREATE TABLE configdb_global_config(\n" + " name TEXT PRIMARY KEY,\n" + " value TEXT\n" + ");\n" + "CREATE TABLE configdb_sqlite_stat1(tbl,idx,stat);\n" +; + +#ifdef __linux__ +#include +#include + +/* +** Attempt to display I/O stats on Linux using /proc/PID/io +*/ +static void displayLinuxIoStats(FILE *out){ + FILE *in; + char z[200]; + sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid()); + in = fopen(z, "rb"); + if( in==0 ) return; + while( fgets(z, sizeof(z), in)!=0 ){ + static const struct { + const char *zPattern; + const char *zDesc; + } aTrans[] = { + { "rchar: ", "Bytes received by read():" }, + { "wchar: ", "Bytes sent to write():" }, + { "syscr: ", "Read() system calls:" }, + { "syscw: ", "Write() system calls:" }, + { "read_bytes: ", "Bytes rcvd from storage:" }, + { "write_bytes: ", "Bytes sent to storage:" }, + { "cancelled_write_bytes: ", "Cancelled write bytes:" }, + }; + int i; + for(i=0; i='0' && c<='9' ) return c - '0'; + if( c>='a' && c<='f' ) return c - 'a' + 10; + if( c>='A' && c<='F' ) return c - 'A' + 10; + return -1; +} + +/* +** Interpret zArg as an integer value, possibly with suffixes. +*/ +static int integerValue(const char *zArg){ + sqlite3_int64 v = 0; + static const struct { char *zSuffix; int iMult; } aMult[] = { + { "KiB", 1024 }, + { "MiB", 1024*1024 }, + { "GiB", 1024*1024*1024 }, + { "KB", 1000 }, + { "MB", 1000000 }, + { "GB", 1000000000 }, + { "K", 1000 }, + { "M", 1000000 }, + { "G", 1000000000 }, + }; + int i; + int isNeg = 0; + if( zArg[0]=='-' ){ + isNeg = 1; + zArg++; + }else if( zArg[0]=='+' ){ + zArg++; + } + if( zArg[0]=='0' && zArg[1]=='x' ){ + int x; + zArg += 2; + while( (x = hexDigitValue(zArg[0]))>=0 ){ + v = (v<<4) + x; + zArg++; + } + }else{ + while( isdigit(zArg[0]) ){ + v = v*10 + zArg[0] - '0'; + zArg++; + } + } + for(i=0; i0x7fffffff ){ + printf("ERROR: parameter too large - max 2147483648\n"); + exit(1); + } + return (int)(isNeg? -v : v); +} + + +int main(int argc, char **argv){ + const char *zCmd = 0; + int i; + int bAutovac = 0; + int showStats = 0; + const char *zDbName = "./startup.db"; + int nHeap = 0; + int mnHeap = 0; + + for(i=1; i=argc-2 ){ + printf("ERROR: missing arguments on %s\n", argv[i]); + exit(1); + } + nHeap = integerValue(argv[i+1]); + mnHeap = integerValue(argv[i+2]); + i += 2; + }else + if( strcmp(z,"-stats")==0 ){ + showStats = 1; + }else + { + printf("ERROR: unknown option \"%s\"\n", argv[i]); + usage(argv[0]); + } + } + if( zCmd==0 ){ + printf("ERROR: no COMMAND specified\n"); + usage(argv[0]); + } + if( strcmp(zCmd, "run")==0 ){ + sqlite3 *db; + int rc; + char *zErr = 0; + void *pHeap = 0; + if( nHeap>0 ){ + pHeap = malloc( nHeap ); + if( pHeap==0 ){ + printf("ERROR: cannot allocate %d-byte heap\n", nHeap); + exit(1); + } + rc = sqlite3_config(SQLITE_CONFIG_HEAP, pHeap, nHeap, mnHeap); + if( rc ){ + printf("ERROR: heap configuration failed: %d\n", rc); + exit(1); + } + } + rc = sqlite3_open(zDbName, &db); + if( rc ){ + printf("SQLite error: %s\n", sqlite3_errmsg(db)); + }else{ + sqlite3_exec(db, "PRAGMA synchronous", 0, 0, &zErr); + } + if( zErr ){ + printf("ERROR: %s\n", zErr); + sqlite3_free(zErr); + } + if( showStats ){ + int iCur, iHi; + sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHi, 0); + printf("-- Lookaside Slots Used: %d (max %d)\n", iCur,iHi); + sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHi, 0); + printf("-- Successful lookasides: %d\n", iHi); + sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur,&iHi,0); + printf("-- Lookaside size faults: %d\n", iHi); + sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur,&iHi,0); + printf("-- Lookaside OOM faults: %d\n", iHi); + sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHi, 0); + printf("-- Pager Heap Usage: %d bytes\n", iCur); + sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHi, 1); + printf("-- Page cache hits: %d\n", iCur); + sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHi, 1); + printf("-- Page cache misses: %d\n", iCur); + sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHi, 1); + printf("-- Page cache writes: %d\n", iCur); + sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHi, 0); + printf("-- Schema Heap Usage: %d bytes\n", iCur); + sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHi, 0); + printf("-- Statement Heap Usage: %d bytes\n", iCur); + } + sqlite3_close(db); + free(pHeap); + /* Global memory usage statistics printed after the database connection + ** has closed. Memory usage should be zero at this point. */ + if( showStats ){ + int iCur, iHi; + sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHi, 0); + printf("-- Memory Used (bytes): %d (max %d)\n", iCur,iHi); + sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHi, 0); + printf("-- Outstanding Allocations: %d (max %d)\n", iCur,iHi); + sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHi, 0); + printf("-- Pcache Overflow Bytes: %d (max %d)\n", iCur,iHi); + sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHi, 0); + printf("-- Largest Allocation: %d bytes\n",iHi); + sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHi, 0); + printf("-- Largest Pcache Allocation: %d bytes\n",iHi); +#ifdef __linux__ + displayLinuxIoStats(stdout); +#endif + } + return 0; + } + if( strcmp(zCmd, "init")==0 ){ + sqlite3 *db; + char *zAux; + char *zErr = 0; + int rc; + unlink(zDbName); + zAux = sqlite3_mprintf("%s-journal", zDbName); + unlink(zAux); + sqlite3_free(zAux); + zAux = sqlite3_mprintf("%s-wal", zDbName); + unlink(zAux); + sqlite3_free(zAux); + rc = sqlite3_open(zDbName, &db); + if( rc ){ + printf("SQLite error: %s\n", sqlite3_errmsg(db)); + }else{ + sqlite3_exec(db, "BEGIN", 0, 0, 0); + sqlite3_exec(db, zTestSchema, 0, 0, &zErr); + sqlite3_exec(db, "COMMIT", 0, 0, 0); + } + if( zErr ){ + printf("ERROR: %s\n", zErr); + sqlite3_free(zErr); + } + sqlite3_close(db); + return 0; + + } +} From 69e856ae66f867f3c67f5d88bc5e134ced43fd69 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 1 Jan 2021 16:43:26 +0000 Subject: [PATCH 089/257] Streamline processing of the authenticator callback for the common case when there is no callback. FossilOrigin-Name: d3196685d958bf22b5c362e96bbf8e1df58cc09cc3abc4bfa94bb33bc28c61aa --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/auth.c | 6 +----- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 706d825b29..1213d3bf93 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s"startup"\stest\sprogram\sdesigned\sto\smeasure\sstartup\sperformance,\nand\sin\sparticular\sschema\sparsing\stime. -D 2021-01-01T15:13:17.551 +C Streamline\sprocessing\sof\sthe\sauthenticator\scallback\sfor\sthe\scommon\scase\nwhen\sthere\sis\sno\scallback. +D 2021-01-01T16:43:26.044 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -477,7 +477,7 @@ F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c b6de60d59419e34f5b48ff2b21fe0f9bb66fc714e5545a6ac790ac7a0c46548c F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c F src/attach.c 0f497c15c4cfe3bdcb214f0dbdbbb6c5ed7e8a9308ac445c7959f5e5780437a9 -F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 +F src/auth.c 8d1df0e2ef8bafbedd4f1fe4baff03eb27507da4bf6e449df3613d383c4018b2 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 @@ -1895,7 +1895,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 e5d7209e118a84537a85c0c9cd2b7ca4cd6ccf04181dc840b19339b4c93840cd -R 4199bcdca03d0dfcf22a616708200b54 +P 7b3b31efb0047c5a461f487905cffba2b0ddb1518a6e757ca092eb40e1e2cd49 +R 489f030d394b5dc73ee4610f953c57c4 U drh -Z 0a6e287c5f9af8cda46993666a938c17 +Z b8fcdd693d25c5b93d4d26cc00dbdbe9 diff --git a/manifest.uuid b/manifest.uuid index 41fb89a951..2b851a19d1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7b3b31efb0047c5a461f487905cffba2b0ddb1518a6e757ca092eb40e1e2cd49 \ No newline at end of file +d3196685d958bf22b5c362e96bbf8e1df58cc09cc3abc4bfa94bb33bc28c61aa \ No newline at end of file diff --git a/src/auth.c b/src/auth.c index 40673d5ea4..83451c29a9 100644 --- a/src/auth.c +++ b/src/auth.c @@ -209,11 +209,7 @@ int sqlite3AuthCheck( ** or if the parser is being invoked from within sqlite3_declare_vtab. */ assert( !IN_RENAME_OBJECT || db->xAuth==0 ); - if( db->init.busy || IN_SPECIAL_PARSE ){ - return SQLITE_OK; - } - - if( db->xAuth==0 ){ + if( db->xAuth==0 || db->init.busy || IN_SPECIAL_PARSE ){ return SQLITE_OK; } From e2b0a12d58752dc5b7fb21bac8caa7b2838bf1d1 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 1 Jan 2021 17:01:33 +0000 Subject: [PATCH 090/257] Small size reduction and performance improvement in sqlite3VdbeMakeReady() by linking the new prepared statement into the prepared statement list sooner rather than later. FossilOrigin-Name: 2996e800a02967f9d0e27c816cf0b7b581a25634f94abcf167f27b019e1515e5 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 1213d3bf93..27455ef2ac 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Streamline\sprocessing\sof\sthe\sauthenticator\scallback\sfor\sthe\scommon\scase\nwhen\sthere\sis\sno\scallback. -D 2021-01-01T16:43:26.044 +C Small\ssize\sreduction\sand\sperformance\simprovement\sin\ssqlite3VdbeMakeReady()\nby\slinking\sthe\snew\sprepared\sstatement\sinto\sthe\sprepared\sstatement\slist\ssooner\nrather\sthan\slater. +D 2021-01-01T17:01:33.478 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -616,7 +616,7 @@ F src/vdbe.c 67de20067fa3a2ee8566342c751e941a2fe3fd88940fd9886ca5115f04165cce F src/vdbe.h 83603854bfa5851af601fc0947671eb260f4363e62e960e8a994fb9bbcd2aaa1 F src/vdbeInt.h 3ca5e9fd6e095a8b6cf6bc3587a46fc93499503b2fe48951e1034ba9e2ce2f6e F src/vdbeapi.c c5e7cb2ab89a24d7f723e87b508f21bfb1359a04db5277d8a99fd1e015c12eb9 -F src/vdbeaux.c c76b7e96e189f5056d1de914d33d07bd03d3b88741f75375c8e18c9b11ffd379 +F src/vdbeaux.c e91d74e24babcf61969279b193e228cf4f8bc724a9cc59ed287db064326876f8 F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1 F src/vdbemem.c 947f2a65910edb4014dc981d33e414a68c51f169f9df8c4c493a0ba840b6eb1f F src/vdbesort.c f5b5e473a7cee44e47a94817b042fd7172cf3aa2c0a7928a8339d612bcfdec5a @@ -1895,7 +1895,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 7b3b31efb0047c5a461f487905cffba2b0ddb1518a6e757ca092eb40e1e2cd49 -R 489f030d394b5dc73ee4610f953c57c4 +P d3196685d958bf22b5c362e96bbf8e1df58cc09cc3abc4bfa94bb33bc28c61aa +R bad67f6d73ac47ab0047b97a3d4436f2 U drh -Z b8fcdd693d25c5b93d4d26cc00dbdbe9 +Z 8e16a28d94f61b89d64b2b5c78bce681 diff --git a/manifest.uuid b/manifest.uuid index 2b851a19d1..d5d2a4a3f1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d3196685d958bf22b5c362e96bbf8e1df58cc09cc3abc4bfa94bb33bc28c61aa \ No newline at end of file +2996e800a02967f9d0e27c816cf0b7b581a25634f94abcf167f27b019e1515e5 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index dfd259d718..7b9b792054 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2358,6 +2358,8 @@ void sqlite3VdbeMakeReady( assert( pParse!=0 ); assert( p->magic==VDBE_MAGIC_INIT ); assert( pParse==p->pParse ); + p->pVList = pParse->pVList; + pParse->pVList = 0; db = p->db; assert( db->mallocFailed==0 ); nVar = pParse->nVar; @@ -2442,8 +2444,6 @@ void sqlite3VdbeMakeReady( } } - p->pVList = pParse->pVList; - pParse->pVList = 0; if( db->mallocFailed ){ p->nVar = 0; p->nCursor = 0; From 88efc796c2928960977f49ad15af899c929ed433 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 1 Jan 2021 18:23:56 +0000 Subject: [PATCH 091/257] Size reduction and performance increase in sqlite3Prepare(). FossilOrigin-Name: 41f45c8e894f48049325ccfef12cec0887b636bfad5d531a47628eb9e8612924 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/prepare.c | 34 ++++++++++++++++++---------------- src/sqliteInt.h | 1 + src/util.c | 10 ++++++++++ 5 files changed, 38 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index 27455ef2ac..98a89950b9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\ssize\sreduction\sand\sperformance\simprovement\sin\ssqlite3VdbeMakeReady()\nby\slinking\sthe\snew\sprepared\sstatement\sinto\sthe\sprepared\sstatement\slist\ssooner\nrather\sthan\slater. -D 2021-01-01T17:01:33.478 +C Size\sreduction\sand\sperformance\sincrease\sin\ssqlite3Prepare(). +D 2021-01-01T18:23:56.767 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -535,7 +535,7 @@ F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a F src/pragma.c 6daaaecc26a4b09481d21722525b079ce756751a43a79cc1d8f122d686806193 F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf -F src/prepare.c 270170a239c0f66bd3c228f373afe24447c2614a6829ae22080babc64f241931 +F src/prepare.c 7acf95d1f84853d3b1152909497002f1333c3b2ee26bc7fe8e43a167ab5fb003 F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c @@ -545,7 +545,7 @@ F src/shell.c.in 6dd0d9260220f807d6d1b8e57dd6e163fe55bd0e97fa416c8c139162e341613 F src/sqlite.h.in 0af968a1fa3c717261e1df0ed105fa7bddb4d82de7e0adb3eab49e6aa81b4de7 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h bd9c97bbf54ed566be46fe55b5c5d9506b66e627f483c7d4791fcdd26b639418 +F src/sqliteInt.h 1ae150649f0a5752e6b83f65089c05301966969df2b2beac7286c351581ac6ee F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -610,7 +610,7 @@ F src/trigger.c 515e79206d40d1d4149129318582e79a6e9db590a7b74e226fdb5b2a6c7e1b10 F src/update.c 9f126204a6acb96bbe47391ae48e0fc579105d8e76a6d9c4fab3271367476580 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 -F src/util.c c0c7977de7ef9b8cb10f6c85f2d0557889a658f817b0455909a49179ba4c8002 +F src/util.c 41c7a72da1df47864faa378a1c720b38adb288c6838cb6be5594511b6287a048 F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286 F src/vdbe.c 67de20067fa3a2ee8566342c751e941a2fe3fd88940fd9886ca5115f04165cce F src/vdbe.h 83603854bfa5851af601fc0947671eb260f4363e62e960e8a994fb9bbcd2aaa1 @@ -1895,7 +1895,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 d3196685d958bf22b5c362e96bbf8e1df58cc09cc3abc4bfa94bb33bc28c61aa -R bad67f6d73ac47ab0047b97a3d4436f2 +P 2996e800a02967f9d0e27c816cf0b7b581a25634f94abcf167f27b019e1515e5 +R 0506b8b55e2eb63eafe4c191c8e24ddc U drh -Z 8e16a28d94f61b89d64b2b5c78bce681 +Z 7bb1e47525328d1390b6713294a18b77 diff --git a/manifest.uuid b/manifest.uuid index d5d2a4a3f1..9db5417678 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2996e800a02967f9d0e27c816cf0b7b581a25634f94abcf167f27b019e1515e5 \ No newline at end of file +41f45c8e894f48049325ccfef12cec0887b636bfad5d531a47628eb9e8612924 \ No newline at end of file diff --git a/src/prepare.c b/src/prepare.c index 13fd1d33b2..09fdbd78bc 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -671,12 +671,6 @@ static int sqlite3Prepare( } assert( 0==sParse.nQueryLoop ); - if( sParse.rc==SQLITE_DONE ){ - sParse.rc = SQLITE_OK; - } - if( sParse.checkSchema ){ - schemaIsValid(&sParse); - } if( pzTail ){ *pzTail = sParse.zTail; } @@ -687,20 +681,28 @@ static int sqlite3Prepare( if( db->mallocFailed ){ sParse.rc = SQLITE_NOMEM_BKPT; } - rc = sParse.rc; - if( rc!=SQLITE_OK ){ - if( sParse.pVdbe ) sqlite3VdbeFinalize(sParse.pVdbe); - assert(!(*ppStmt)); + if( sParse.rc!=SQLITE_OK && sParse.rc!=SQLITE_DONE ){ + if( sParse.checkSchema ){ + schemaIsValid(&sParse); + } + if( sParse.pVdbe ){ + sqlite3VdbeFinalize(sParse.pVdbe); + } + assert( 0==(*ppStmt) ); + rc = sParse.rc; + if( zErrMsg ){ + sqlite3ErrorWithMsg(db, rc, "%s", zErrMsg); + sqlite3DbFree(db, zErrMsg); + }else{ + sqlite3Error(db, rc); + } }else{ + assert( zErrMsg==0 ); *ppStmt = (sqlite3_stmt*)sParse.pVdbe; + rc = SQLITE_OK; + sqlite3ErrorClear(db); } - if( zErrMsg ){ - sqlite3ErrorWithMsg(db, rc, "%s", zErrMsg); - sqlite3DbFree(db, zErrMsg); - }else{ - sqlite3Error(db, rc); - } /* Delete any TriggerPrg structures allocated while parsing this statement. */ while( sParse.pTriggerPrg ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 37df2911a6..f20fd70676 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4573,6 +4573,7 @@ int sqlite3Atoi64(const char*, i64*, int, u8); int sqlite3DecOrHexToI64(const char*, i64*); void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...); void sqlite3Error(sqlite3*,int); +void sqlite3ErrorClear(sqlite3*); void sqlite3SystemError(sqlite3*,int); void *sqlite3HexToBlob(sqlite3*, const char *z, int n); u8 sqlite3HexToInt(int h); diff --git a/src/util.c b/src/util.c index fb86d7d118..fc0c2042bd 100644 --- a/src/util.c +++ b/src/util.c @@ -114,6 +114,16 @@ void sqlite3Error(sqlite3 *db, int err_code){ if( err_code || db->pErr ) sqlite3ErrorFinish(db, err_code); } +/* +** The equivalent of sqlite3Error(db, SQLITE_OK). Clear the error state +** and error message. +*/ +void sqlite3ErrorClear(sqlite3 *db){ + assert( db!=0 ); + db->errCode = SQLITE_OK; + if( db->pErr ) sqlite3ValueSetNull(db->pErr); +} + /* ** Load the sqlite3.iSysErrno field if that is an appropriate thing ** to do based on the SQLite error code in rc. From 266f0f4585cd7692bd4187ac8bbe279e4783111b Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 1 Jan 2021 18:32:15 +0000 Subject: [PATCH 092/257] Modify the makefile rule for "startup" so that it always builds with -Os and -DSQLITE_THREADSAFE=0 and no other options, for consistency of performance. FossilOrigin-Name: 5ac939e0adc923378173297e934c3664254a4fefbcddcc842bf4cc42dbaacf4f --- Makefile.in | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Makefile.in b/Makefile.in index 3fb531256b..875bba4c04 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1379,7 +1379,7 @@ speedtest1$(TEXE): $(TOP)/test/speedtest1.c sqlite3.c $(LTLINK) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c $(TLIBS) startup$(TEXE): $(TOP)/test/startup.c sqlite3.c - $(LTLINK) $(ST_OPT) -o $@ $(TOP)/test/startup.c sqlite3.c $(TLIBS) + $(CC) -Os -g -DSQLITE_THREADSAFE=0 -o $@ $(TOP)/test/startup.c sqlite3.c $(TLIBS) KV_OPT += -DSQLITE_DIRECT_OVERFLOW_READ diff --git a/manifest b/manifest index 98a89950b9..022d55e936 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Size\sreduction\sand\sperformance\sincrease\sin\ssqlite3Prepare(). -D 2021-01-01T18:23:56.767 +C Modify\sthe\smakefile\srule\sfor\s"startup"\sso\sthat\sit\salways\sbuilds\swith\n-Os\sand\s-DSQLITE_THREADSAFE=0\sand\sno\sother\soptions,\sfor\sconsistency\sof\nperformance. +D 2021-01-01T18:32:15.639 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 2e13f6830ef6ee26bdc72dd50536cbd4f5599834185213b50ee5648a393db82d +F Makefile.in 9cae1bffe5cb811216bf7425395e7fc0594daa2ce31f625835a9d0c3fb25315f F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241 F Makefile.msc ad07bbd645132533e1fd7164a03acfa9afecda378b3787c10f62ab4c7c45e6ea F README.md 1514a365ffca3c138e00c5cc839906108a01011a6b082bad19b09781e3aa498a @@ -1895,7 +1895,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 2996e800a02967f9d0e27c816cf0b7b581a25634f94abcf167f27b019e1515e5 -R 0506b8b55e2eb63eafe4c191c8e24ddc +P 41f45c8e894f48049325ccfef12cec0887b636bfad5d531a47628eb9e8612924 +R c6a646e99c7a838404fe08a2f6524679 U drh -Z 7bb1e47525328d1390b6713294a18b77 +Z f3be154d8c50c2d6e064126a71c3cb12 diff --git a/manifest.uuid b/manifest.uuid index 9db5417678..0f871a741e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -41f45c8e894f48049325ccfef12cec0887b636bfad5d531a47628eb9e8612924 \ No newline at end of file +5ac939e0adc923378173297e934c3664254a4fefbcddcc842bf4cc42dbaacf4f \ No newline at end of file From 3e992d1ab72ba48c4896d18b6ea29b4f184bb7d3 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 1 Jan 2021 19:17:01 +0000 Subject: [PATCH 093/257] Use the column name hash to improve performance of column name collision detection while parsing CREATE TABLE statements. FossilOrigin-Name: d02820f03575e4633a7917427f11c19f99bd7b92f37d0ffe6fdc2418ad729813 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 7 +++++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 022d55e936..1aca84feb2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Modify\sthe\smakefile\srule\sfor\s"startup"\sso\sthat\sit\salways\sbuilds\swith\n-Os\sand\s-DSQLITE_THREADSAFE=0\sand\sno\sother\soptions,\sfor\sconsistency\sof\nperformance. -D 2021-01-01T18:32:15.639 +C Use\sthe\scolumn\sname\shash\sto\simprove\sperformance\sof\scolumn\sname\scollision\ndetection\swhile\sparsing\sCREATE\sTABLE\sstatements. +D 2021-01-01T19:17:01.346 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -484,7 +484,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 0f9cb686871ae668817673f0823b55d1bcadbc86ea28bd22c590b064a8322d5a F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 -F src/build.c f6449d4e85e998e14d3f537e8ea898dca2fcb83c277db3e60945af9b9177db81 +F src/build.c f5610708b09e6e2aed20e9f87e41abc9cb7d9c524b2af473b6b8f979185fcc3c F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 @@ -1895,7 +1895,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 41f45c8e894f48049325ccfef12cec0887b636bfad5d531a47628eb9e8612924 -R c6a646e99c7a838404fe08a2f6524679 +P 5ac939e0adc923378173297e934c3664254a4fefbcddcc842bf4cc42dbaacf4f +R 76ed3eb5d9ad1369259443b69c6d4eb4 U drh -Z f3be154d8c50c2d6e064126a71c3cb12 +Z 392a8d945c1dcd1bc8026b48aa7097cf diff --git a/manifest.uuid b/manifest.uuid index 0f871a741e..7ce76aea34 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5ac939e0adc923378173297e934c3664254a4fefbcddcc842bf4cc42dbaacf4f \ No newline at end of file +d02820f03575e4633a7917427f11c19f99bd7b92f37d0ffe6fdc2418ad729813 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 9779e93732..3a35530400 100644 --- a/src/build.c +++ b/src/build.c @@ -1255,6 +1255,8 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ char *zType; Column *pCol; sqlite3 *db = pParse->db; + u8 hName; + if( (p = pParse->pNewTable)==0 ) return; if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){ sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName); @@ -1266,8 +1268,9 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ memcpy(z, pName->z, pName->n); z[pName->n] = 0; sqlite3Dequote(z); + hName = sqlite3StrIHash(z); for(i=0; inCol; i++){ - if( sqlite3_stricmp(z, p->aCol[i].zName)==0 ){ + if( p->aCol[i].hName==hName && sqlite3StrICmp(z, p->aCol[i].zName)==0 ){ sqlite3ErrorMsg(pParse, "duplicate column name: %s", z); sqlite3DbFree(db, z); return; @@ -1285,7 +1288,7 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ pCol = &p->aCol[p->nCol]; memset(pCol, 0, sizeof(p->aCol[0])); pCol->zName = z; - pCol->hName = sqlite3StrIHash(z); + pCol->hName = hName; sqlite3ColumnPropertiesFromName(p, pCol); if( pType->n==0 ){ From 37114fbfcc3b7e03ca9d4aa6c23d36e3df0ce553 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 1 Jan 2021 20:04:34 +0000 Subject: [PATCH 094/257] Change the unions of the Table.addColOffset field from characters to bytes. This makes the query that implements ALTER TABLE ADD COLUMN more complex and slightly slower, but also makes CREATE TABLE statement parsing faster by avoiding a call to sqlite3UtfCharLen(). Since, CREATE TABLE parsing is far more common than ALTER TABLE, this is a net win for performance. FossilOrigin-Name: 6f25f2529f1495a26129d7d407979906e4962b2de351f901d41cb037d05ba780 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/alter.c | 7 +++++-- src/build.c | 2 +- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 1aca84feb2..7ea3b257e6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\sthe\scolumn\sname\shash\sto\simprove\sperformance\sof\scolumn\sname\scollision\ndetection\swhile\sparsing\sCREATE\sTABLE\sstatements. -D 2021-01-01T19:17:01.346 +C Change\sthe\sunions\sof\sthe\sTable.addColOffset\sfield\sfrom\scharacters\sto\sbytes.\nThis\smakes\sthe\squery\sthat\simplements\sALTER\sTABLE\sADD\sCOLUMN\smore\scomplex\sand\nslightly\sslower,\sbut\salso\smakes\sCREATE\sTABLE\sstatement\sparsing\sfaster\sby\navoiding\sa\scall\sto\ssqlite3UtfCharLen().\s\sSince,\sCREATE\sTABLE\sparsing\sis\sfar\nmore\scommon\sthan\sALTER\sTABLE,\sthis\sis\sa\snet\swin\sfor\sperformance. +D 2021-01-01T20:04:34.680 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -474,7 +474,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c b6de60d59419e34f5b48ff2b21fe0f9bb66fc714e5545a6ac790ac7a0c46548c +F src/alter.c 36cae0d6e3e91a1996e1a472f8c7242c31a4e38ba4295e3056da198c04fd2a87 F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c F src/attach.c 0f497c15c4cfe3bdcb214f0dbdbbb6c5ed7e8a9308ac445c7959f5e5780437a9 F src/auth.c 8d1df0e2ef8bafbedd4f1fe4baff03eb27507da4bf6e449df3613d383c4018b2 @@ -484,7 +484,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 0f9cb686871ae668817673f0823b55d1bcadbc86ea28bd22c590b064a8322d5a F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 -F src/build.c f5610708b09e6e2aed20e9f87e41abc9cb7d9c524b2af473b6b8f979185fcc3c +F src/build.c 7a9983015d707482329820eb0ab6bc014554cbd89f8f0312e88ee47ca924257d F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 @@ -1895,7 +1895,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 5ac939e0adc923378173297e934c3664254a4fefbcddcc842bf4cc42dbaacf4f -R 76ed3eb5d9ad1369259443b69c6d4eb4 +P d02820f03575e4633a7917427f11c19f99bd7b92f37d0ffe6fdc2418ad729813 +R d65e8365f48ba6717e932860e31b53aa U drh -Z 392a8d945c1dcd1bc8026b48aa7097cf +Z 862f00eca17b025046c1fc8e371a884b diff --git a/manifest.uuid b/manifest.uuid index 7ce76aea34..377d6e125d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d02820f03575e4633a7917427f11c19f99bd7b92f37d0ffe6fdc2418ad729813 \ No newline at end of file +6f25f2529f1495a26129d7d407979906e4962b2de351f901d41cb037d05ba780 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index f4098863dd..e0beb8f3ed 100644 --- a/src/alter.c +++ b/src/alter.c @@ -381,11 +381,14 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ *zEnd-- = '\0'; } db->mDbFlags |= DBFLAG_PreferBuiltin; + /* substr() operations on characters, but addColOffset is in bytes. So we + ** have to use printf() to translate between these units: */ sqlite3NestedParse(pParse, "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET " - "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) " + "sql = printf('%%.%ds, ',sql) || %Q" + " || substr(sql,1+length(printf('%%.%ds',sql))) " "WHERE type = 'table' AND name = %Q", - zDb, pNew->addColOffset, zCol, pNew->addColOffset+1, + zDb, pNew->addColOffset, zCol, pNew->addColOffset, zTab ); sqlite3DbFree(db, zCol); diff --git a/src/build.c b/src/build.c index 3a35530400..c9877951c6 100644 --- a/src/build.c +++ b/src/build.c @@ -2564,7 +2564,7 @@ void sqlite3EndTable( pCons = pEnd; } nName = (int)((const char *)pCons->z - zName); - p->addColOffset = 13 + sqlite3Utf8CharLen(zName, nName); + p->addColOffset = 13 + nName; } #endif } From 630fc34c1aa99dc3c3fae030bcb3de5741c4e34b Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 1 Jan 2021 21:02:37 +0000 Subject: [PATCH 095/257] Faster and smaller test to ensure that the sqlite_schema.sql field is always a CREATE statement of some kind. FossilOrigin-Name: 76de2bb04b1c02a6c0300cd61d9b3d2477d845aa0d1cdb9dbe4f354b9fedd923 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/prepare.c | 9 ++++++++- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 7ea3b257e6..a6d72ee472 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sunions\sof\sthe\sTable.addColOffset\sfield\sfrom\scharacters\sto\sbytes.\nThis\smakes\sthe\squery\sthat\simplements\sALTER\sTABLE\sADD\sCOLUMN\smore\scomplex\sand\nslightly\sslower,\sbut\salso\smakes\sCREATE\sTABLE\sstatement\sparsing\sfaster\sby\navoiding\sa\scall\sto\ssqlite3UtfCharLen().\s\sSince,\sCREATE\sTABLE\sparsing\sis\sfar\nmore\scommon\sthan\sALTER\sTABLE,\sthis\sis\sa\snet\swin\sfor\sperformance. -D 2021-01-01T20:04:34.680 +C Faster\sand\ssmaller\stest\sto\sensure\sthat\sthe\ssqlite_schema.sql\sfield\sis\salways\na\sCREATE\sstatement\sof\ssome\skind. +D 2021-01-01T21:02:37.996 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -535,7 +535,7 @@ F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a F src/pragma.c 6daaaecc26a4b09481d21722525b079ce756751a43a79cc1d8f122d686806193 F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf -F src/prepare.c 7acf95d1f84853d3b1152909497002f1333c3b2ee26bc7fe8e43a167ab5fb003 +F src/prepare.c a6bac9100b5f171189f6bb7ee12dfeeda7f3a8fd0c89be4a7958f14df13fa746 F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c @@ -1895,7 +1895,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 d02820f03575e4633a7917427f11c19f99bd7b92f37d0ffe6fdc2418ad729813 -R d65e8365f48ba6717e932860e31b53aa +P 6f25f2529f1495a26129d7d407979906e4962b2de351f901d41cb037d05ba780 +R b56645f386266a2944ab2c45a4a49580 U drh -Z 862f00eca17b025046c1fc8e371a884b +Z 5ad0d6addcb4bd606a3544d738c2cf50 diff --git a/manifest.uuid b/manifest.uuid index 377d6e125d..1f0e61ce42 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6f25f2529f1495a26129d7d407979906e4962b2de351f901d41cb037d05ba780 \ No newline at end of file +76de2bb04b1c02a6c0300cd61d9b3d2477d845aa0d1cdb9dbe4f354b9fedd923 \ No newline at end of file diff --git a/src/prepare.c b/src/prepare.c index 09fdbd78bc..3a2943f103 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -102,11 +102,18 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */ if( argv[3]==0 ){ corruptSchema(pData, argv[1], 0); - }else if( sqlite3_strnicmp(argv[4],"create ",7)==0 ){ + }else if( argv[4] + && 'c'==sqlite3UpperToLower[(unsigned char)argv[4][0]] + && 'r'==sqlite3UpperToLower[(unsigned char)argv[4][1]] ){ /* Call the parser to process a CREATE TABLE, INDEX or VIEW. ** But because db->init.busy is set to 1, no VDBE code is generated ** or executed. All the parser does is build the internal data ** structures that describe the table, index, or view. + ** + ** No other valid SQL statement, other than the variable CREATE statements, + ** can begin with the letters "C" and "R". Thus, it is not possible run + ** any other kind of statement while parsing the schema, even a corrupt + ** schema. */ int rc; u8 saved_iDb = db->init.iDb; From c8af879e5f501595d5bc59e15621ce25ab76d566 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 1 Jan 2021 22:06:17 +0000 Subject: [PATCH 096/257] Avoid allocating space to hold the prepared statements for CREATE statements when parsing the schema of an existing database, since those prepared statements are never used.. This helps to make startup faster, FossilOrigin-Name: d01e9f2d00dc439c529cd8885a219fcddbaad73b9f471b020e2a0c18e2add69b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 4 ++++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index a6d72ee472..62f5f649c1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Faster\sand\ssmaller\stest\sto\sensure\sthat\sthe\ssqlite_schema.sql\sfield\sis\salways\na\sCREATE\sstatement\sof\ssome\skind. -D 2021-01-01T21:02:37.996 +C Avoid\sallocating\sspace\sto\shold\sthe\sprepared\sstatements\sfor\sCREATE\sstatements\nwhen\sparsing\sthe\sschema\sof\san\sexisting\sdatabase,\ssince\sthose\sprepared\nstatements\sare\snever\sused..\s\sThis\shelps\sto\smake\sstartup\sfaster, +D 2021-01-01T22:06:17.152 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -484,7 +484,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 0f9cb686871ae668817673f0823b55d1bcadbc86ea28bd22c590b064a8322d5a F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 -F src/build.c 7a9983015d707482329820eb0ab6bc014554cbd89f8f0312e88ee47ca924257d +F src/build.c d4c06261b0e532523ede58dc511381a7a9c155132e4b65a6bb2ff76fe657793a F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 @@ -1895,7 +1895,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 6f25f2529f1495a26129d7d407979906e4962b2de351f901d41cb037d05ba780 -R b56645f386266a2944ab2c45a4a49580 +P 76de2bb04b1c02a6c0300cd61d9b3d2477d845aa0d1cdb9dbe4f354b9fedd923 +R df14a0f8e3c8c0f24b4bc5fa275286c3 U drh -Z 5ad0d6addcb4bd606a3544d738c2cf50 +Z f56f3715fca7ebd8ed5abb62c2ed9411 diff --git a/manifest.uuid b/manifest.uuid index 1f0e61ce42..be0c633268 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -76de2bb04b1c02a6c0300cd61d9b3d2477d845aa0d1cdb9dbe4f354b9fedd923 \ No newline at end of file +d01e9f2d00dc439c529cd8885a219fcddbaad73b9f471b020e2a0c18e2add69b \ No newline at end of file diff --git a/src/build.c b/src/build.c index c9877951c6..50289c6a1d 100644 --- a/src/build.c +++ b/src/build.c @@ -143,6 +143,10 @@ void sqlite3FinishCoding(Parse *pParse){ /* Begin by generating some termination code at the end of the ** vdbe program */ + if( pParse->pVdbe==0 && db->init.busy ){ + pParse->rc = SQLITE_DONE; + return; + } v = sqlite3GetVdbe(pParse); assert( !pParse->isMultiWrite || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort)); From e81f879f517b2c947d691332f2820a854e05056d Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 2 Jan 2021 23:56:37 +0000 Subject: [PATCH 097/257] In Lemon, factor the parser stack overflow detection logic out of the yy_reduce() subroutine and into the main parser routine, so that when overflow is detected, it can exit immediately. This saves a single conditional in the main loop of the parser. FossilOrigin-Name: 203c049c662380411522d0c7c493201331bbb2792a7c5b12684f04f532a0695d --- manifest | 12 +++--- manifest.uuid | 2 +- tool/lempar.c | 101 ++++++++++++++++++++++++-------------------------- 3 files changed, 55 insertions(+), 60 deletions(-) diff --git a/manifest b/manifest index 62f5f649c1..92e502e71e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sallocating\sspace\sto\shold\sthe\sprepared\sstatements\sfor\sCREATE\sstatements\nwhen\sparsing\sthe\sschema\sof\san\sexisting\sdatabase,\ssince\sthose\sprepared\nstatements\sare\snever\sused..\s\sThis\shelps\sto\smake\sstartup\sfaster, -D 2021-01-01T22:06:17.152 +C In\sLemon,\sfactor\sthe\sparser\sstack\soverflow\sdetection\slogic\sout\sof\sthe\nyy_reduce()\ssubroutine\sand\sinto\sthe\smain\sparser\sroutine,\sso\sthat\swhen\soverflow\nis\sdetected,\sit\scan\sexit\simmediately.\s\sThis\ssaves\sa\ssingle\sconditional\sin\nthe\smain\sloop\sof\sthe\sparser. +D 2021-01-02T23:56:37.261 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1815,7 +1815,7 @@ F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/index_usage.c f62a0c701b2c7ff2f3e21d206f093c123f222dbf07136a10ffd1ca15a5c706c5 F tool/kvtest-speed.sh 4761a9c4b3530907562314d7757995787f7aef8f F tool/lemon.c 70eedc31614a58fe31a71025c17ebd1502a6ce9cfef0ed5e33acb0b5b737b291 -F tool/lempar.c 0e1d5eeb9736108d3dba782a9dd56f4e7cb69006b6ee181308b7ebfb15313a12 +F tool/lempar.c 1d3d075da18681c67ecc66c1f171e7094e18cd2cfba6a8a1bd4f3f639d6656e1 F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca @@ -1895,7 +1895,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 76de2bb04b1c02a6c0300cd61d9b3d2477d845aa0d1cdb9dbe4f354b9fedd923 -R df14a0f8e3c8c0f24b4bc5fa275286c3 +P d01e9f2d00dc439c529cd8885a219fcddbaad73b9f471b020e2a0c18e2add69b +R 30317f78042211a4eaf8fdf4d0539bb2 U drh -Z f56f3715fca7ebd8ed5abb62c2ed9411 +Z 16a40d4bd4688bf574b37b863bb32871 diff --git a/manifest.uuid b/manifest.uuid index be0c633268..076424831b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d01e9f2d00dc439c529cd8885a219fcddbaad73b9f471b020e2a0c18e2add69b \ No newline at end of file +203c049c662380411522d0c7c493201331bbb2792a7c5b12684f04f532a0695d \ No newline at end of file diff --git a/tool/lempar.c b/tool/lempar.c index 71a51cf448..35c3768bb9 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -718,55 +718,6 @@ static YYACTIONTYPE yy_reduce( (void)yyLookahead; (void)yyLookaheadToken; yymsp = yypParser->yytos; - assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ); -#ifndef NDEBUG - if( yyTraceFILE ){ - yysize = yyRuleInfoNRhs[yyruleno]; - if( yysize ){ - fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", - yyTracePrompt, - yyruleno, yyRuleName[yyruleno], - yyrulenoyytos - yypParser->yystack)>yypParser->yyhwm ){ - yypParser->yyhwm++; - assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack)); - } -#endif -#if YYSTACKDEPTH>0 - if( yypParser->yytos>=yypParser->yystackEnd ){ - yyStackOverflow(yypParser); - /* The call to yyStackOverflow() above pops the stack until it is - ** empty, causing the main parser loop to exit. So the return value - ** is never used and does not matter. */ - return 0; - } -#else - if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ - if( yyGrowStack(yypParser) ){ - yyStackOverflow(yypParser); - /* The call to yyStackOverflow() above pops the stack until it is - ** empty, causing the main parser loop to exit. So the return value - ** is never used and does not matter. */ - return 0; - } - yymsp = yypParser->yytos; - } -#endif - } switch( yyruleno ){ /* Beginning here are the reduction cases. A typical example @@ -925,12 +876,56 @@ void Parse( } #endif - do{ + while(1){ /* Exit by "break" */ + assert( yypParser->yytos>=yypParser->yystack ); assert( yyact==yypParser->yytos->stateno ); yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact); if( yyact >= YY_MIN_REDUCE ){ - yyact = yy_reduce(yypParser,yyact-YY_MIN_REDUCE,yymajor, - yyminor ParseCTX_PARAM); + unsigned int yyruleno = yyact - YY_MIN_REDUCE; /* Reduce by this rule */ + assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ); +#ifndef NDEBUG + if( yyTraceFILE ){ + int yysize = yyRuleInfoNRhs[yyruleno]; + if( yysize ){ + fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", + yyTracePrompt, + yyruleno, yyRuleName[yyruleno], + yyrulenoyytos[yysize].stateno); + }else{ + fprintf(yyTraceFILE, "%sReduce %d [%s]%s.\n", + yyTracePrompt, yyruleno, yyRuleName[yyruleno], + yyrulenoyytos - yypParser->yystack)>yypParser->yyhwm ){ + yypParser->yyhwm++; + assert( yypParser->yyhwm == + (int)(yypParser->yytos - yypParser->yystack)); + } +#endif +#if YYSTACKDEPTH>0 + if( yypParser->yytos>=yypParser->yystackEnd ){ + yyStackOverflow(yypParser); + break; + } +#else + if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ + if( yyGrowStack(yypParser) ){ + yyStackOverflow(yypParser); + break; + } + } +#endif + } + yyact = yy_reduce(yypParser,yyruleno,yymajor,yyminor ParseCTX_PARAM); }else if( yyact <= YY_MAX_SHIFTREDUCE ){ yy_shift(yypParser,yyact,(YYCODETYPE)yymajor,yyminor); #ifndef YYNOERRORRECOVERY @@ -1043,7 +1038,7 @@ void Parse( break; #endif } - }while( yypParser->yytos>yypParser->yystack ); + } #ifndef NDEBUG if( yyTraceFILE ){ yyStackEntry *i; From 31afee93726e5a438fac58e9d921ec0584798004 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 4 Jan 2021 18:28:29 +0000 Subject: [PATCH 098/257] Add extra test for handling of embedded nul characters in the fts4 unicode61 tokenizer. FossilOrigin-Name: c2c2c7e945f5d5700d91b8e779117e70e388ffc613912a434885ae27f5fe4e22 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/fts4unicode.test | 18 ++++++++++++++++++ 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 92e502e71e..eee9dbcaa6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sLemon,\sfactor\sthe\sparser\sstack\soverflow\sdetection\slogic\sout\sof\sthe\nyy_reduce()\ssubroutine\sand\sinto\sthe\smain\sparser\sroutine,\sso\sthat\swhen\soverflow\nis\sdetected,\sit\scan\sexit\simmediately.\s\sThis\ssaves\sa\ssingle\sconditional\sin\nthe\smain\sloop\sof\sthe\sparser. -D 2021-01-02T23:56:37.261 +C Add\sextra\stest\sfor\shandling\sof\sembedded\snul\scharacters\sin\sthe\sfts4\sunicode61\stokenizer. +D 2021-01-04T18:28:29.171 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1018,7 +1018,7 @@ F test/fts4opt.test 0fd0cc84000743ff2a883b9b84b4a5be07249f0ba790c8848a757164cdd4 F test/fts4record.test a48508f69a84c9287c8019d3a1ae712f5730d8335ffaf8e2101e691d078950bb F test/fts4rename.test 15fd9985c2bce6dea20da2245b22029ec89bd4710ed317c4c53abbe3cfd0c880 F test/fts4umlaut.test fcaca4471de7e78c9d1f7e8976e3e8704d7d8ad979d57a739d00f3f757380429 -F test/fts4unicode.test ceca76422abc251818cb25dabe33d3c3970da5f7c90e1540f190824e6b3a7c95 +F test/fts4unicode.test 82a9c16b68ba2f358a856226bb2ee02f81583797bc4744061c54401bf1a0f4c9 F test/fts4upfrom.test 8df5acb6e10ad73f393d1add082b042ab1db72567888847d098152121e507b34 F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d F test/func.test f673822636fb8ed618dd2b80230d16e495d19c8f2e2e7d6c22e93e2b3de097ad @@ -1895,7 +1895,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 d01e9f2d00dc439c529cd8885a219fcddbaad73b9f471b020e2a0c18e2add69b -R 30317f78042211a4eaf8fdf4d0539bb2 -U drh -Z 16a40d4bd4688bf574b37b863bb32871 +P 203c049c662380411522d0c7c493201331bbb2792a7c5b12684f04f532a0695d +R 13e46d62ad91a9f054084b2f8c17f303 +U dan +Z 21909ae0d43a0fafde3bfee513c0e7b6 diff --git a/manifest.uuid b/manifest.uuid index 076424831b..b74500a2da 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -203c049c662380411522d0c7c493201331bbb2792a7c5b12684f04f532a0695d \ No newline at end of file +c2c2c7e945f5d5700d91b8e779117e70e388ffc613912a434885ae27f5fe4e22 \ No newline at end of file diff --git a/test/fts4unicode.test b/test/fts4unicode.test index f4d1a33486..facf2bf9c4 100644 --- a/test/fts4unicode.test +++ b/test/fts4unicode.test @@ -567,4 +567,22 @@ do_execsql_test 11.1 { berlin@street sydney.road } +# Test for embedded nul characters in fts4 unicode index. +# +do_execsql_test 12.0 { + CREATE VIRTUAL TABLE t12 USING fts4(tokenize=unicode61); + INSERT INTO t12 VALUES('abc' || char(0) || 'def'); + SELECT hex(CAST(content AS blob)) FROM t12; +} {61626300646566} +do_execsql_test 12.1 { + INSERT INTO t12(t12) VALUES('integrity-check'); +} {} +do_execsql_test 12.2 { + CREATE VIRTUAL TABLE t12aux USING fts4aux(t12); + SELECT * FROM t12aux; +} {abc * 1 1 abc 0 1 1} +do_execsql_test 12.3 { + SELECT hex(CAST(content AS blob)) FROM t12 WHERE t12 MATCH 'abc' +} {61626300646566} + finish_test From c2dbf35f49af1587154597e33dffe72ffa2a47af Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 7 Jan 2021 16:10:14 +0000 Subject: [PATCH 099/257] Fix harmless typos in comments per [forum:/forumpost/7849e58dd5|forum post 7849e58dd5] FossilOrigin-Name: d1e22e2f76cce7eb9f9029646176daef2d9e41c7bb1d3e1da182fbdd0096605c --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/func.c | 2 +- tool/lemon.c | 12 ++++++------ 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index eee9dbcaa6..f453d948f2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sextra\stest\sfor\shandling\sof\sembedded\snul\scharacters\sin\sthe\sfts4\sunicode61\stokenizer. -D 2021-01-04T18:28:29.171 +C Fix\sharmless\stypos\sin\scomments\sper\s\n[forum:/forumpost/7849e58dd5|forum\spost\s7849e58dd5] +D 2021-01-07T16:10:14.503 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -495,7 +495,7 @@ F src/delete.c 927cf8f900583e79aca8f1a321979e0a8f053babd9a690b44b38f79de2cc09fe F src/expr.c 0d196ed5a2ebf96be7e8df88add4fabfad0dce16c0fed81a4b8f6a26e259797f F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 83372403298e6a7dd989a47aaacdbaa5b4307b5199dbd56e07d4896066b3de72 -F src/func.c 6fb20c0bd604af514fa77456446e6f7725e6818dbc21f560fce4616320a06f28 +F src/func.c 251b5953cecd0ce3e282213c5e623134415793d3569d7804d13460559d7e45ff F src/global.c ed55af196a9b66e198aaeda3f5454c3aa7d7d050c6c938181fd044b70d180a81 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 @@ -1814,7 +1814,7 @@ F tool/genfkey.test b6afd7b825d797a1e1274f519ab5695373552ecad5cd373530c63533638a F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/index_usage.c f62a0c701b2c7ff2f3e21d206f093c123f222dbf07136a10ffd1ca15a5c706c5 F tool/kvtest-speed.sh 4761a9c4b3530907562314d7757995787f7aef8f -F tool/lemon.c 70eedc31614a58fe31a71025c17ebd1502a6ce9cfef0ed5e33acb0b5b737b291 +F tool/lemon.c d44ba4f03427c9bd34b601f315fe77c2b6d4bd215801a0259aeedbcc4c94a95c F tool/lempar.c 1d3d075da18681c67ecc66c1f171e7094e18cd2cfba6a8a1bd4f3f639d6656e1 F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 @@ -1895,7 +1895,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 203c049c662380411522d0c7c493201331bbb2792a7c5b12684f04f532a0695d -R 13e46d62ad91a9f054084b2f8c17f303 -U dan -Z 21909ae0d43a0fafde3bfee513c0e7b6 +P c2c2c7e945f5d5700d91b8e779117e70e388ffc613912a434885ae27f5fe4e22 +R 001c230a08957ce4d5a03839716e575b +U drh +Z 3adc05f7c3c6f4fad03349029fbaefe8 diff --git a/manifest.uuid b/manifest.uuid index b74500a2da..547c4aa0ea 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c2c2c7e945f5d5700d91b8e779117e70e388ffc613912a434885ae27f5fe4e22 \ No newline at end of file +d1e22e2f76cce7eb9f9029646176daef2d9e41c7bb1d3e1da182fbdd0096605c \ No newline at end of file diff --git a/src/func.c b/src/func.c index 6cd9fdce66..dcf5e6cf2d 100644 --- a/src/func.c +++ b/src/func.c @@ -1953,7 +1953,7 @@ static void ceilingFunc( /* ** On some systems, ceil() and floor() are intrinsic function. You are -** unable to take a pointer to this functions. Hence, we here wrap them +** unable to take a pointer to these functions. Hence, we here wrap them ** in our own actual functions. */ static double xCeil(double x){ return ceil(x); } diff --git a/tool/lemon.c b/tool/lemon.c index 54c8946a0d..06ba1be2bd 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -401,7 +401,7 @@ struct lemon { struct symbol *errsym; /* The error symbol */ struct symbol *wildcard; /* Token that matches anything */ char *name; /* Name of the generated parser */ - char *arg; /* Declaration of the 3th argument to parser */ + char *arg; /* Declaration of the 3rd argument to parser */ char *ctx; /* Declaration of 2nd argument to constructor */ char *tokentype; /* Type of terminal symbols in the parser stack */ char *vartype; /* The default type of non-terminal symbols */ @@ -1027,7 +1027,7 @@ PRIVATE void buildshifts(struct lemon *lemp, struct state *stp) struct symbol *bsp; /* Symbol following the dot in configuration "bcfp" */ struct state *newstp; /* A pointer to a successor state */ - /* Each configuration becomes complete after it contibutes to a successor + /* Each configuration becomes complete after it contributes to a successor ** state. Initially, all configurations are incomplete */ for(cfp=stp->cfp; cfp; cfp=cfp->next) cfp->status = INCOMPLETE; @@ -1887,7 +1887,7 @@ static char *merge( ** ** Return Value: ** A pointer to the head of a sorted list containing the elements -** orginally in list. +** originally in list. ** ** Side effects: ** The "next" pointers for elements in list are changed. @@ -3513,7 +3513,7 @@ void ReportOutput(struct lemon *lemp) } /* Search for the file "name" which is in the same directory as -** the exacutable */ +** the executable */ PRIVATE char *pathsearch(char *argv0, char *name, int modemask) { const char *pathlist; @@ -3868,7 +3868,7 @@ PRIVATE int translate_code(struct lemon *lemp, struct rule *rp){ lhsdirect = 1; }else if( rp->rhsalias[0]==0 ){ /* The left-most RHS symbol has no value. LHS direct is ok. But - ** we have to call the distructor on the RHS symbol first. */ + ** we have to call the destructor on the RHS symbol first. */ lhsdirect = 1; if( has_destructor(rp->rhs[0],lemp) ){ append_str(0,0,0,0); @@ -4849,7 +4849,7 @@ void ReportTable( ** yyRuleInfoNRhs[]. ** ** Note: This code depends on the fact that rules are number - ** sequentually beginning with 0. + ** sequentially beginning with 0. */ for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){ fprintf(out," %4d, /* (%d) ", rp->lhs->index, i); From 5cb960b7afd53cdfe877f4069ab1be2440bca6f2 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 7 Jan 2021 16:29:34 +0000 Subject: [PATCH 100/257] Fix problems with some "crashsql" tests. FossilOrigin-Name: 0c8e2ede5c325aa7fef8e8587057ec8c865fc7cf3e974a2733066fbac640b983 --- manifest | 16 ++++++------ manifest.uuid | 2 +- test/crash5.test | 67 ++++++++++++++++++++++++++++-------------------- test/tester.tcl | 5 +++- 4 files changed, 52 insertions(+), 38 deletions(-) diff --git a/manifest b/manifest index f453d948f2..2e2be77dba 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\stypos\sin\scomments\sper\s\n[forum:/forumpost/7849e58dd5|forum\spost\s7849e58dd5] -D 2021-01-07T16:10:14.503 +C Fix\sproblems\swith\ssome\s"crashsql"\stests. +D 2021-01-07T16:29:34.204 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -800,7 +800,7 @@ F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f F test/crash2.test 5b14d4eb58b880e231361d3b609b216acda86651 F test/crash3.test 8f5de9d32ab9ab95475a9efe7f47a940aa889418 F test/crash4.test fe2821baf37168dc59dd733dcf7dba2a401487bc -F test/crash5.test f14ff37eddc41991be4eb63568f86caa306fd9962a0ae3750db8836777bb7aae +F test/crash5.test 98f77ad22bceaea9043bf87088d5b61d004a1f40bb7c9dc3b6a7c70bd502c0bb F test/crash6.test 4c56f1e40d0291e1110790a99807aa875b1647ba F test/crash7.test 1a194c4900a255258cf94b7fcbfd29536db572df F test/crash8.test 64366e459c28dd62edfb7ad87253a409c7533b92d16fcc479a6a8131bdcc3100 @@ -1435,7 +1435,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 754521f0db534d51ab504b2d14fe0bdca1f1c15de731ceb8ee5bfd78372a2a5f +F test/tester.tcl 56c059c88c5b96a624f1193ba48b0bac034190b79cd9c75cb4acbfe84baf7ec5 F test/thread001.test b61a29dd87cf669f5f6ac96124a7c97d71b0c80d9012746072055877055cf9ef F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1895,7 +1895,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 c2c2c7e945f5d5700d91b8e779117e70e388ffc613912a434885ae27f5fe4e22 -R 001c230a08957ce4d5a03839716e575b -U drh -Z 3adc05f7c3c6f4fad03349029fbaefe8 +P d1e22e2f76cce7eb9f9029646176daef2d9e41c7bb1d3e1da182fbdd0096605c +R f2a08ccfa9bd07e6fe085165034f514e +U dan +Z ff87a608ac05b1370695f464c3f563ec diff --git a/manifest.uuid b/manifest.uuid index 547c4aa0ea..3c3c05d554 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d1e22e2f76cce7eb9f9029646176daef2d9e41c7bb1d3e1da182fbdd0096605c \ No newline at end of file +0c8e2ede5c325aa7fef8e8587057ec8c865fc7cf3e974a2733066fbac640b983 \ No newline at end of file diff --git a/test/crash5.test b/test/crash5.test index b80b15137f..5c8e04c137 100644 --- a/test/crash5.test +++ b/test/crash5.test @@ -29,7 +29,7 @@ ifcapable !crashtest||!memorymanage { db close for {set ii 0} {$ii < 10} {incr ii} { - for {set jj 50} {$jj < 100} {incr jj} { + for {set jj 1} {$jj < 100} {incr jj} { # Set up the database so that it is an auto-vacuum database # containing a single table (root page 3) with a single row. @@ -47,6 +47,14 @@ for {set ii 0} {$ii < 10} {incr ii} { do_test crash5-$ii.$jj.1 { crashsql -delay 1 -file test.db-journal -seed $ii -tclbody [join [list \ [list set iFail $jj] { + proc get_pwd {} { + if {$::tcl_platform(platform) eq "windows"} { + return [string map [list \\ /] \ + [string trim [exec -- $::env(ComSpec) /c echo %CD%]]] + } else { + return [pwd] + } + } sqlite3_crashparams 0 [file join [get_pwd] test.db-journal] # Begin a transaction and evaluate a "CREATE INDEX" statement @@ -61,36 +69,39 @@ for {set ii 0} {$ii < 10} {incr ii} { # db eval BEGIN sqlite3_memdebug_fail $iFail -repeat 0 - catch {db eval { CREATE UNIQUE INDEX i1 ON t1(a); }} msg - # puts "$n $msg ac=[sqlite3_get_autocommit db]" + set rc [catch {db eval { CREATE UNIQUE INDEX i1 ON t1(a); }} msg] +# puts "$msg ac=[sqlite3_get_autocommit db] iFail=$iFail" +# puts "fail=[sqlite3_memdebug_fail -1]" - # If the transaction is still active (it may not be if the malloc() - # failure occurred in the OS layer), write to the database. Make sure - # page 4 is among those written. - # - if {![sqlite3_get_autocommit db]} { - db eval { - DELETE FROM t1; -- This will put page 4 on the free list. - INSERT INTO t1 VALUES('111111111', '2222222222', '33333333'); - INSERT INTO t1 SELECT * FROM t1; -- 2 - INSERT INTO t1 SELECT * FROM t1; -- 4 - INSERT INTO t1 SELECT * FROM t1; -- 8 - INSERT INTO t1 SELECT * FROM t1; -- 16 - INSERT INTO t1 SELECT * FROM t1; -- 32 - INSERT INTO t1 SELECT * FROM t1 WHERE rowid%2; -- 48 + if {$rc} { + # If the transaction is still active (it may not be if the malloc() + # failure occurred in the OS layer), write to the database. Make sure + # page 4 is among those written. + # + if {![sqlite3_get_autocommit db]} { + db eval { + DELETE FROM t1; -- This will put page 4 on the free list. + INSERT INTO t1 VALUES('111111111', '2222222222', '33333333'); + INSERT INTO t1 SELECT * FROM t1; -- 2 + INSERT INTO t1 SELECT * FROM t1; -- 4 + INSERT INTO t1 SELECT * FROM t1; -- 8 + INSERT INTO t1 SELECT * FROM t1; -- 16 + INSERT INTO t1 SELECT * FROM t1; -- 32 + INSERT INTO t1 SELECT * FROM t1 WHERE rowid%2; -- 48 + } } + + # If the right malloc() failed during the 'CREATE INDEX' above and + # the transaction was not rolled back, then the sqlite cache now + # has a dirty page 4 that it incorrectly believes is already safely + # in the synced part of the journal file. When + # sqlite3_release_memory() is called sqlite tries to free memory + # by writing page 4 out to the db file. If it crashes later on, + # before syncing the journal... Corruption! + # + sqlite3_crashparams 1 [file join [get_pwd] test.db-journal] + sqlite3_release_memory 8092 } - - # If the right malloc() failed during the 'CREATE INDEX' above and - # the transaction was not rolled back, then the sqlite cache now - # has a dirty page 4 that it incorrectly believes is already safely - # in the synced part of the journal file. When - # sqlite3_release_memory() is called sqlite tries to free memory - # by writing page 4 out to the db file. If it crashes later on, - # before syncing the journal... Corruption! - # - sqlite3_crashparams 1 [file join [get_pwd] test.db-journal] - sqlite3_release_memory 8092 }]] {} expr 1 } {1} diff --git a/test/tester.tcl b/test/tester.tcl index 3b91ff46cb..7ef059571a 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -1689,9 +1689,12 @@ proc crashsql {args} { set cfile [string map {\\ \\\\} [file nativename [file join [get_pwd] $crashfile]]] set f [open crash.tcl w] + puts $f "sqlite3_initialize ; sqlite3_shutdown" + puts $f "catch { install_malloc_faultsim 1 }" puts $f "sqlite3_crash_enable 1 $dfltvfs" puts $f "sqlite3_crashparams $blocksize $dc $crashdelay $cfile" puts $f "sqlite3_test_control_pending_byte $::sqlite_pending_byte" + puts $f "autoinstall_test_functions" # This block sets the cache size of the main database to 10 # pages. This is done in case the build is configured to omit @@ -1719,7 +1722,7 @@ proc crashsql {args} { } close $f set r [catch { - exec [info nameofexec] crash.tcl >@stdout + exec [info nameofexec] crash.tcl >@stdout 2>@stdout } msg] # Windows/ActiveState TCL returns a slightly different From 3a5e9759478a0e048857ce574c1a7c1a67d68851 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 7 Jan 2021 16:59:35 +0000 Subject: [PATCH 101/257] Update cksumvfs to check that the xCurrentTimeGetInt64 method of the underlying VFS is not NULL before invoking it. FossilOrigin-Name: c71f6cadcc8c2172ad4113bbe4026aac4ebb8a91485454e8a14de32d197a93aa --- ext/misc/cksumvfs.c | 12 +++++++++++- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/ext/misc/cksumvfs.c b/ext/misc/cksumvfs.c index 46f3a4f0b5..0f6b00f436 100644 --- a/ext/misc/cksumvfs.c +++ b/ext/misc/cksumvfs.c @@ -750,7 +750,17 @@ static int cksmGetLastError(sqlite3_vfs *pVfs, int a, char *b){ return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b); } static int cksmCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){ - return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p); + sqlite3_vfs *pOrig = ORIGVFS(pVfs); + int rc; + assert( pOrig->iVersion>=2 ); + if( pOrig->xCurrentTimeInt64 ){ + rc = pOrig->xCurrentTimeInt64(pOrig, p); + }else{ + double r; + rc = pOrig->xCurrentTime(pOrig, &r); + *p = (sqlite3_int64)(r*86400000.0); + } + return rc; } static int cksmSetSystemCall( sqlite3_vfs *pVfs, diff --git a/manifest b/manifest index 2e2be77dba..8d841b8124 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sproblems\swith\ssome\s"crashsql"\stests. -D 2021-01-07T16:29:34.204 +C Update\scksumvfs\sto\scheck\sthat\sthe\sxCurrentTimeGetInt64\smethod\sof\sthe\sunderlying\sVFS\sis\snot\sNULL\sbefore\sinvoking\sit. +D 2021-01-07T16:59:35.102 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -291,7 +291,7 @@ F ext/misc/blobio.c a867c4c4617f6ec223a307ebfe0eabb45e0992f74dd47722b96f3e631c0e F ext/misc/btreeinfo.c d28ce349b40054eaa9473e835837bad7a71deec33ba13e39f963d50933bfa0f9 F ext/misc/carray.c b75a0f207391038bf1540d3372f482a95c3613511c7c474db51ede1196321c7c F ext/misc/carray.h de74ac70b2338f416723f7d538026e8ec0b7f1d388319f8f140c9a4d7677f02e -F ext/misc/cksumvfs.c 688a59d6c5dc7e7e0aba09654d8cbeeb7d04bad8cf57902df86aa06c2f723ff4 +F ext/misc/cksumvfs.c 8dc4e1b718e374bed3a9b5c0a08da2922438002e33267311697768e06217b983 F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c85c243 F ext/misc/completion.c 6dafd7f4348eecc7be9e920d4b419d1fb2af75d938cd9c59a20cfe8beb2f22b9 F ext/misc/compress.c 3354c77a7c8e86e07d849916000cdac451ed96500bfb5bd83b20eb61eee012c9 @@ -1895,7 +1895,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 d1e22e2f76cce7eb9f9029646176daef2d9e41c7bb1d3e1da182fbdd0096605c -R f2a08ccfa9bd07e6fe085165034f514e +P 0c8e2ede5c325aa7fef8e8587057ec8c865fc7cf3e974a2733066fbac640b983 +R 1a3bee667f65d0e32bb0f436f092ae42 U dan -Z ff87a608ac05b1370695f464c3f563ec +Z 9608ffa77e14ed1f71d5ad4aa271555e diff --git a/manifest.uuid b/manifest.uuid index 3c3c05d554..40bf37ae0e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0c8e2ede5c325aa7fef8e8587057ec8c865fc7cf3e974a2733066fbac640b983 \ No newline at end of file +c71f6cadcc8c2172ad4113bbe4026aac4ebb8a91485454e8a14de32d197a93aa \ No newline at end of file From 1242c0ccf4b16ca70e877aca1c36df02dc94de12 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 8 Jan 2021 19:53:18 +0000 Subject: [PATCH 102/257] Fix an issue with sha3_query() when the first argument contains blank SQL statements. FossilOrigin-Name: 24baab9a9faab50c26d7167821031cd66aaf784baefbc0f92354ae54ac43a714 --- ext/misc/shathree.c | 8 +++++--- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/ext/misc/shathree.c b/ext/misc/shathree.c index 75065e97c1..ef25cb56c6 100644 --- a/ext/misc/shathree.c +++ b/ext/misc/shathree.c @@ -624,9 +624,11 @@ static void sha3QueryFunc( } nCol = sqlite3_column_count(pStmt); z = sqlite3_sql(pStmt); - n = (int)strlen(z); - hash_step_vformat(&cx,"S%d:",n); - SHA3Update(&cx,(unsigned char*)z,n); + if( z ){ + n = (int)strlen(z); + hash_step_vformat(&cx,"S%d:",n); + SHA3Update(&cx,(unsigned char*)z,n); + } /* Compute a hash over the result of the query */ while( SQLITE_ROW==sqlite3_step(pStmt) ){ diff --git a/manifest b/manifest index 8d841b8124..8d1da076b7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\scksumvfs\sto\scheck\sthat\sthe\sxCurrentTimeGetInt64\smethod\sof\sthe\sunderlying\sVFS\sis\snot\sNULL\sbefore\sinvoking\sit. -D 2021-01-07T16:59:35.102 +C Fix\san\sissue\swith\ssha3_query()\swhen\sthe\sfirst\sargument\scontains\sblank\nSQL\sstatements. +D 2021-01-08T19:53:18.684 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -321,7 +321,7 @@ F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d385 F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946 F ext/misc/series.c c6bd5d249e5199a1b55aeee4d0e6576ff3a68702fc475dbd64503a32903516c7 F ext/misc/sha1.c c8f2253c8792ffab9517695ea7d88c079f0395a5505eefef5c8198fe184ed5ac -F ext/misc/shathree.c 5398f945a30b4792c757ab16b03cf54ce3b542fe933bbd43e2d6d40c5443b12e +F ext/misc/shathree.c e984f31731de4cf302a0386be5fe664580f63d8204c47b9b41cc4b997745f9ec F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c 94df9bbfa514a563c1484f684a2df3d128a2f7209a84ca3ca100c68a0163e29f F ext/misc/sqlar.c 0ace5d3c10fe736dc584bf1159a36b8e2e60fab309d310cd8a0eecd9036621b6 @@ -1895,7 +1895,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 0c8e2ede5c325aa7fef8e8587057ec8c865fc7cf3e974a2733066fbac640b983 -R 1a3bee667f65d0e32bb0f436f092ae42 -U dan -Z 9608ffa77e14ed1f71d5ad4aa271555e +P c71f6cadcc8c2172ad4113bbe4026aac4ebb8a91485454e8a14de32d197a93aa +R cc767b37e9c2c0feee110e02581211ee +U drh +Z 1c7fa074713d00a24e24cef3301f23ad diff --git a/manifest.uuid b/manifest.uuid index 40bf37ae0e..1d312194a8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c71f6cadcc8c2172ad4113bbe4026aac4ebb8a91485454e8a14de32d197a93aa \ No newline at end of file +24baab9a9faab50c26d7167821031cd66aaf784baefbc0f92354ae54ac43a714 \ No newline at end of file From 4ee492f176e963341b1d75a803663697e95ea00a Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 9 Jan 2021 18:24:33 +0000 Subject: [PATCH 103/257] More detailed compile-time testing before attempting to use atomic load intrinsics. See [forum:/forumpost/fc0237a39b30ac0a|forum post fc0237a39b30ac0a]. FossilOrigin-Name: 5204c2c4a7b73a64764b0d2d1d7c53709bb64e0d2685a829c7bf31af13bab5e7 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqliteInt.h | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 8d1da076b7..77d8b29c82 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sissue\swith\ssha3_query()\swhen\sthe\sfirst\sargument\scontains\sblank\nSQL\sstatements. -D 2021-01-08T19:53:18.684 +C More\sdetailed\scompile-time\stesting\sbefore\sattempting\sto\suse\satomic\sload\nintrinsics.\s\sSee\n[forum:/forumpost/fc0237a39b30ac0a|forum\spost\sfc0237a39b30ac0a]. +D 2021-01-09T18:24:33.207 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -545,7 +545,7 @@ F src/shell.c.in 6dd0d9260220f807d6d1b8e57dd6e163fe55bd0e97fa416c8c139162e341613 F src/sqlite.h.in 0af968a1fa3c717261e1df0ed105fa7bddb4d82de7e0adb3eab49e6aa81b4de7 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h 1ae150649f0a5752e6b83f65089c05301966969df2b2beac7286c351581ac6ee +F src/sqliteInt.h 0eb4c251a6df26fb97fcd0c285c5dd442f90f0d0305c14f2a9d0cfc006a0e1da F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1895,7 +1895,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 c71f6cadcc8c2172ad4113bbe4026aac4ebb8a91485454e8a14de32d197a93aa -R cc767b37e9c2c0feee110e02581211ee +P 24baab9a9faab50c26d7167821031cd66aaf784baefbc0f92354ae54ac43a714 +R f436034378e7ad8864e7bea1bcf5d189 U drh -Z 1c7fa074713d00a24e24cef3301f23ad +Z fd75732825704368b80a067191a5a63f diff --git a/manifest.uuid b/manifest.uuid index 1d312194a8..32386517ea 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -24baab9a9faab50c26d7167821031cd66aaf784baefbc0f92354ae54ac43a714 \ No newline at end of file +5204c2c4a7b73a64764b0d2d1d7c53709bb64e0d2685a829c7bf31af13bab5e7 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index f20fd70676..980ae6d580 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -214,7 +214,8 @@ #ifndef __has_extension # define __has_extension(x) 0 /* compatibility with non-clang compilers */ #endif -#if GCC_VERSION>=4007000 || __has_extension(c_atomic) +#if GCC_VERSION>=4007000 || \ + (__has_extension(c_atomic) && __has_extension(c_atomic_store_n)) # define AtomicLoad(PTR) __atomic_load_n((PTR),__ATOMIC_RELAXED) # define AtomicStore(PTR,VAL) __atomic_store_n((PTR),(VAL),__ATOMIC_RELAXED) #else From a6e6cf2c8f2f3a272b4cb5f592906c7a53be59d6 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 9 Jan 2021 19:10:04 +0000 Subject: [PATCH 104/257] New CLI command: ".stats vmstep" enables the display of the virtual-machine step count only, after each command. Useful for optimization problems. FossilOrigin-Name: 49dfce469e6a17111b349e53578479daf783064200bf0eec5bf8a91d3553b19f --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/shell.c.in | 37 +++++++++++++++++++++++++++++++------ test/shell1.test | 4 ++-- test/shell4.test | 2 +- 5 files changed, 43 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 77d8b29c82..5c6ea5e56e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\sdetailed\scompile-time\stesting\sbefore\sattempting\sto\suse\satomic\sload\nintrinsics.\s\sSee\n[forum:/forumpost/fc0237a39b30ac0a|forum\spost\sfc0237a39b30ac0a]. -D 2021-01-09T18:24:33.207 +C New\sCLI\scommand:\s\s".stats\svmstep"\senables\sthe\sdisplay\sof\sthe\svirtual-machine\nstep\scount\sonly,\safter\seach\scommand.\s\sUseful\sfor\soptimization\sproblems. +D 2021-01-09T19:10:04.989 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -541,7 +541,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 85c7cec9a4a983416d4bd023b2c4fbbeb608ae8dfb069781f80c8ed08b0c7a7c -F src/shell.c.in 6dd0d9260220f807d6d1b8e57dd6e163fe55bd0e97fa416c8c139162e3416134 +F src/shell.c.in 79bceb990e4bac23a09bb8dd65783ea4867b8bfca9242b5a82b884043e65109a F src/sqlite.h.in 0af968a1fa3c717261e1df0ed105fa7bddb4d82de7e0adb3eab49e6aa81b4de7 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e @@ -1352,10 +1352,10 @@ F test/sharedA.test 49d87ec54ab640fbbc3786ee3c01de94aaa482a3a9f834ad3fe92770eb69 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test 0ba53c72545de142e1b76fa793ee33293134aa02abb9b50b35398670481ea661 +F test/shell1.test 56a7358a2a05e850e9e4aa24629db9c8975e8038dbe8debd2d95be22a5f03612 F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b F test/shell3.test ac8c2b744014c3e9a0e26bfd829ab65f00923dc1a91ffd044863e9423cc91494 -F test/shell4.test 1c6aef11daaa2d6830acaba3ac9cbec93fbc1c3d5530743a637f39b3987d08ce +F test/shell4.test 3ed6c4b42fd695efcbc25d69ef759dbb15855ca8e52ba6c5ee076f8b435f48be F test/shell5.test 84a30b55722a95a5b72989e691c469a999ca7591e7aa00b7fabc783ea5c9a6fe F test/shell6.test 1ceb51b2678c472ba6cf1e5da96679ce8347889fe2c3bf93a0e0fa73f00b00d3 F test/shell7.test 115132f66d0463417f408562cc2cf534f6bbc6d83a6d50f0072a9eb171bae97f @@ -1895,7 +1895,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 24baab9a9faab50c26d7167821031cd66aaf784baefbc0f92354ae54ac43a714 -R f436034378e7ad8864e7bea1bcf5d189 +P 5204c2c4a7b73a64764b0d2d1d7c53709bb64e0d2685a829c7bf31af13bab5e7 +R 08e016b91a617b99baf0add20ffab4d1 U drh -Z fd75732825704368b80a067191a5a63f +Z 8b24dd36b9adf4430f5fd36c021c9d5f diff --git a/manifest.uuid b/manifest.uuid index 32386517ea..ad74ba7a76 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5204c2c4a7b73a64764b0d2d1d7c53709bb64e0d2685a829c7bf31af13bab5e7 \ No newline at end of file +49dfce469e6a17111b349e53578479daf783064200bf0eec5bf8a91d3553b19f \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 80bc261fcc..806ca2102b 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -1085,12 +1085,12 @@ struct ShellState { u8 autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */ u8 autoEQPtest; /* autoEQP is in test mode */ u8 autoEQPtrace; /* autoEQP is in trace mode */ - u8 statsOn; /* True to display memory stats before each finalize */ u8 scanstatsOn; /* True to display scan stats before each finalize */ u8 openMode; /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */ u8 doXdgOpen; /* Invoke start/open/xdg-open in output_reset() */ u8 nEqpLevel; /* Depth of the EQP output graph */ u8 eTraceType; /* SHELL_TRACE_* value for type of trace */ + unsigned statsOn; /* True to display memory stats before each finalize */ unsigned mEqpLines; /* Mask of veritical lines in the EQP output graph */ int outCount; /* Revert to stdout when reaching zero */ int cnt; /* Number of records displayed so far */ @@ -2591,7 +2591,7 @@ static int display_stats( if( pArg==0 || pArg->out==0 ) return 0; out = pArg->out; - if( pArg->pStmt && (pArg->statsOn & 2) ){ + if( pArg->pStmt && pArg->statsOn==2 ){ int nCol, i, x; sqlite3_stmt *pStmt = pArg->pStmt; char z[100]; @@ -2615,6 +2615,14 @@ static int display_stats( } } + if( pArg->statsOn==3 ){ + if( pArg->pStmt ){ + iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset); + raw_printf(pArg->out, "VM-steps: %d\n", iCur); + } + return 0; + } + displayStatLine(pArg, "Memory Used:", "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset); displayStatLine(pArg, "Number of Outstanding Allocations:", @@ -4047,7 +4055,11 @@ static const char *(azHelp[]) = { ".shell CMD ARGS... Run CMD ARGS... in a system shell", #endif ".show Show the current values for various settings", - ".stats ?on|off? Show stats or turn stats on or off", + ".stats ?ARG? Show stats or turn stats on or off", + " off Turn off automatic stat display", + " on Turn on automatic stat display", + " stmt Show statement stats", + " vmstep Show the virtual machine step count only", #ifndef SQLITE_NOHAVE_SYSTEM ".system CMD ARGS... Run CMD ARGS... in a system shell", #endif @@ -9724,6 +9736,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='s' && strncmp(azArg[0], "show", n)==0 ){ static const char *azBool[] = { "off", "on", "trigger", "full"}; + const char *zOut; int i; if( nArg!=1 ){ raw_printf(stderr, "Usage: .show\n"); @@ -9748,7 +9761,13 @@ static int do_meta_command(char *zLine, ShellState *p){ utf8_printf(p->out,"%12.12s: ", "rowseparator"); output_c_string(p->out, p->rowSeparator); raw_printf(p->out, "\n"); - utf8_printf(p->out, "%12.12s: %s\n","stats", azBool[p->statsOn!=0]); + switch( p->statsOn ){ + case 0: zOut = "off"; break; + default: zOut = "on"; break; + case 2: zOut = "stmt"; break; + case 3: zOut = "vmstep"; break; + } + utf8_printf(p->out, "%12.12s: %s\n","stats", zOut); utf8_printf(p->out, "%12.12s: ", "width"); for (i=0;inWidth;i++) { raw_printf(p->out, "%d ", p->colWidth[i]); @@ -9760,11 +9779,17 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){ if( nArg==2 ){ - p->statsOn = (u8)booleanValue(azArg[1]); + if( strcmp(azArg[1],"stmt")==0 ){ + p->statsOn = 2; + }else if( strcmp(azArg[1],"vmstep")==0 ){ + p->statsOn = 3; + }else{ + p->statsOn = (u8)booleanValue(azArg[1]); + } }else if( nArg==1 ){ display_stats(p->db, p, 0); }else{ - raw_printf(stderr, "Usage: .stats ?on|off?\n"); + raw_printf(stderr, "Usage: .stats ?on|off|stmt|vmstep?\n"); rc = 1; } }else diff --git a/test/shell1.test b/test/shell1.test index a62b0d1a80..330276120d 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -642,7 +642,7 @@ do_test shell1-3.23.2 { # .stats ON|OFF Turn stats on or off #do_test shell1-3.23b.1 { # catchcmd "test.db" ".stats" -#} {1 {Usage: .stats on|off}} +#} {1 {Usage: .stats on|off|stmt|vmstep}} do_test shell1-3.23b.2 { catchcmd "test.db" ".stats ON" } {0 {}} @@ -652,7 +652,7 @@ do_test shell1-3.23b.3 { do_test shell1-3.23b.4 { # too many arguments catchcmd "test.db" ".stats OFF BAD" -} {1 {Usage: .stats ?on|off?}} +} {1 {Usage: .stats ?on|off|stmt|vmstep?}} # Ticket 7be932dfa60a8a6b3b26bcf7623ec46e0a403ddb 2018-06-07 # Adverse interaction between .stats and .eqp diff --git a/test/shell4.test b/test/shell4.test index 386e51f6c7..9e3c58fbec 100644 --- a/test/shell4.test +++ b/test/shell4.test @@ -66,7 +66,7 @@ do_test shell4-1.3.3 { do_test shell4-1.3.4 { # too many arguments catchcmd "test.db" ".stats OFF BAD" -} {1 {Usage: .stats ?on|off?}} +} {1 {Usage: .stats ?on|off|stmt|vmstep?}} # NB. whitespace is important do_test shell4-1.4.1 { From cf3c078f9326ac990fc4e1bfb4748e0b9f467069 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 11 Jan 2021 20:37:02 +0000 Subject: [PATCH 105/257] Add a linked list of ParseCleanup objects to the end of a Parse object and use that list as a place to put other sub-objects that need to be deallocated. Have a single such list for infrequently used sub-objects is more efficient than doing an a separate check for each kind of sub-object. FossilOrigin-Name: affa2b7b316941b8a6c4d0d1ff212c81a593faf1d05d129e14d2b70d73a25c59 --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/insert.c | 1 + src/prepare.c | 38 +++++++++++++++++++++++++++++++++++++- src/select.c | 12 ++++++++---- src/sqliteInt.h | 17 ++++++++++++++--- src/tokenize.c | 12 ------------ src/trigger.c | 1 - 8 files changed, 72 insertions(+), 33 deletions(-) diff --git a/manifest b/manifest index 5c6ea5e56e..fdfe62597e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\sCLI\scommand:\s\s".stats\svmstep"\senables\sthe\sdisplay\sof\sthe\svirtual-machine\nstep\scount\sonly,\safter\seach\scommand.\s\sUseful\sfor\soptimization\sproblems. -D 2021-01-09T19:10:04.989 +C Add\sa\slinked\slist\sof\sParseCleanup\sobjects\sto\sthe\send\sof\sa\sParse\sobject\sand\nuse\sthat\slist\sas\sa\splace\sto\sput\sother\ssub-objects\sthat\sneed\sto\sbe\sdeallocated.\nHave\sa\ssingle\ssuch\slist\sfor\sinfrequently\sused\ssub-objects\sis\smore\sefficient\nthan\sdoing\san\sa\sseparate\scheck\sfor\seach\skind\sof\ssub-object. +D 2021-01-11T20:37:02.868 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -501,7 +501,7 @@ 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 81b7ee72cd754b5d0018659d5593355f2d61b3d80f07f200167c4826846e907d +F src/insert.c 9ced988440d29531568bfe4f48c7b69035b100f6833ca1080abb710b7c415111 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 F src/main.c 97e9f137354bc1f76dc9bb60a0a24f8c45cf73b33e80d3ee4c64155336fb820d @@ -535,17 +535,17 @@ F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a F src/pragma.c 6daaaecc26a4b09481d21722525b079ce756751a43a79cc1d8f122d686806193 F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf -F src/prepare.c a6bac9100b5f171189f6bb7ee12dfeeda7f3a8fd0c89be4a7958f14df13fa746 +F src/prepare.c 1f8bb4f20d83024194780f28920c6af9cfe52adc772ded8f33b4ee2b66f46f66 F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 85c7cec9a4a983416d4bd023b2c4fbbeb608ae8dfb069781f80c8ed08b0c7a7c +F src/select.c b7281a798ee02cb356d2d8b7381939cb513646a91210478587ed6f7f33c357a8 F src/shell.c.in 79bceb990e4bac23a09bb8dd65783ea4867b8bfca9242b5a82b884043e65109a F src/sqlite.h.in 0af968a1fa3c717261e1df0ed105fa7bddb4d82de7e0adb3eab49e6aa81b4de7 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h 0eb4c251a6df26fb97fcd0c285c5dd442f90f0d0305c14f2a9d0cfc006a0e1da +F src/sqliteInt.h e484ffb8ce2182ecd745b2e0af0caa12996e848b0f91748c742d1d135d31770c F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -604,9 +604,9 @@ F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a9 F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394ba3f F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c -F src/tokenize.c 01dba3023659dc6f6b1e054c14b35a0074bd35de10466b99454d33278191d97f +F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda -F src/trigger.c 515e79206d40d1d4149129318582e79a6e9db590a7b74e226fdb5b2a6c7e1b10 +F src/trigger.c 29680c54c1aa088fa1b4d50137d75669a40d5ef814394e321fab1e547868e3d3 F src/update.c 9f126204a6acb96bbe47391ae48e0fc579105d8e76a6d9c4fab3271367476580 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 @@ -1895,7 +1895,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 5204c2c4a7b73a64764b0d2d1d7c53709bb64e0d2685a829c7bf31af13bab5e7 -R 08e016b91a617b99baf0add20ffab4d1 +P 49dfce469e6a17111b349e53578479daf783064200bf0eec5bf8a91d3553b19f +R f1889156a8e996b56aa3e8cdd75a199d U drh -Z 8b24dd36b9adf4430f5fd36c021c9d5f +Z 2f77ed20cd8529f3498738d09cff4442 diff --git a/manifest.uuid b/manifest.uuid index ad74ba7a76..6b51da5c3c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -49dfce469e6a17111b349e53578479daf783064200bf0eec5bf8a91d3553b19f \ No newline at end of file +affa2b7b316941b8a6c4d0d1ff212c81a593faf1d05d129e14d2b70d73a25c59 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 0e52ee7a00..ae55868961 100644 --- a/src/insert.c +++ b/src/insert.c @@ -371,6 +371,7 @@ static int autoIncBegin( if( pInfo==0 ){ pInfo = sqlite3DbMallocRawNN(pParse->db, sizeof(*pInfo)); if( pInfo==0 ) return 0; + sqlite3ParserAddCleanup(pToplevel, sqlite3DbFreeNN, pInfo); pInfo->pNext = pToplevel->pAinc; pToplevel->pAinc = pInfo; pInfo->pTab = pTab; diff --git a/src/prepare.c b/src/prepare.c index 3a2943f103..980785c341 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -570,8 +570,16 @@ void sqlite3ParserReset(Parse *pParse){ agginfoFree(db, pThis); pThis = pNext; } + while( pParse->pCleanup ){ + ParseCleanup *pThis = pParse->pCleanup; + pParse->pCleanup = pThis->pNext; + pThis->xCleanup(db, pThis->pPtr); + sqlite3DbFree(db, pThis); + } sqlite3DbFree(db, pParse->aLabel); - sqlite3ExprListDelete(db, pParse->pConstExpr); + if( pParse->pConstExpr ){ + sqlite3ExprListDelete(db, pParse->pConstExpr); + } if( db ){ assert( db->lookaside.bDisable >= pParse->disableLookaside ); db->lookaside.bDisable -= pParse->disableLookaside; @@ -580,6 +588,34 @@ void sqlite3ParserReset(Parse *pParse){ pParse->disableLookaside = 0; } +/* +** Add a new cleanup operation to a Parser. The cleanup should happen when +** the parser object is destroyed. +** +** Use this mechanism for uncommon cleanups. There is a higher setup +** cost, so this should not be used for common cleanups. But for less +** common cleanups, we save a single NULL-pointer comparison in +** sqlite3ParserReset(), which makes a surprising difference in total +** performance. +** +** If a memory allocation error occurs, then the cleanup happens immediately. +*/ +void sqlite3ParserAddCleanup( + Parse *pParse, + void (*xCleanup)(sqlite3*,void*), + void *pPtr +){ + ParseCleanup *pCleanup = sqlite3DbMallocRaw(pParse->db, sizeof(*pCleanup)); + if( pCleanup ){ + pCleanup->pNext = pParse->pCleanup; + pParse->pCleanup = pCleanup; + pCleanup->pPtr = pPtr; + pCleanup->xCleanup = xCleanup; + }else{ + xCleanup(pParse->db, pPtr); + } +} + /* ** Compile the UTF-8 encoded SQL statement zSql into a statement handle. */ diff --git a/src/select.c b/src/select.c index 407a6a4b2e..fc853210fa 100644 --- a/src/select.c +++ b/src/select.c @@ -4140,8 +4140,9 @@ static int flattenSubquery( Table *pTabToDel = pSubitem->pTab; if( pTabToDel->nTabRef==1 ){ Parse *pToplevel = sqlite3ParseToplevel(pParse); - pTabToDel->pNextZombie = pToplevel->pZombieTab; - pToplevel->pZombieTab = pTabToDel; + sqlite3ParserAddCleanup(pToplevel, + (void(*)(sqlite3*,void*))sqlite3DeleteTable, + pTabToDel); }else{ pTabToDel->nTabRef--; } @@ -4856,12 +4857,15 @@ static struct Cte *searchWith( ** statement with which it is associated. */ void sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){ - assert( bFree==0 || (pParse->pWith==0 && pParse->pWithToFree==0) ); if( pWith ){ assert( pParse->pWith!=pWith ); pWith->pOuter = pParse->pWith; pParse->pWith = pWith; - if( bFree ) pParse->pWithToFree = pWith; + if( bFree ){ + sqlite3ParserAddCleanup(pParse, + (void(*)(sqlite3*,void*))sqlite3WithDelete, + pWith); + } } } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 980ae6d580..484d63c5b8 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1154,6 +1154,7 @@ typedef struct LookasideSlot LookasideSlot; typedef struct Module Module; typedef struct NameContext NameContext; typedef struct Parse Parse; +typedef struct ParseCleanup ParseCleanup; typedef struct PreUpdate PreUpdate; typedef struct PrintfArguments PrintfArguments; typedef struct RenameToken RenameToken; @@ -2186,7 +2187,6 @@ struct Table { #endif Trigger *pTrigger; /* List of triggers stored in pSchema */ Schema *pSchema; /* Schema that contains this table */ - Table *pNextZombie; /* Next on the Parse.pZombieTab list */ }; /* @@ -3348,6 +3348,17 @@ struct TriggerPrg { # define DbMaskNonZero(M) (M)!=0 #endif +/* +** An instance of the ParseCleanup object specifies an operation that +** should be performed after parsing to deallocation resources obtained +** during the parse and which are no longer needed. +*/ +struct ParseCleanup { + ParseCleanup *pNext; /* Next cleanup task */ + void *pPtr; /* Pointer to object to deallocate */ + void (*xCleanup)(sqlite3*,void*); /* Deallocation routine */ +}; + /* ** An SQL parser context. A copy of this structure is passed through ** the parser and down into all the parser action routine in order to @@ -3457,10 +3468,9 @@ struct Parse { Token sArg; /* Complete text of a module argument */ Table **apVtabLock; /* Pointer to virtual tables needing locking */ #endif - Table *pZombieTab; /* List of Table objects to delete after code gen */ TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */ With *pWith; /* Current WITH clause, or NULL */ - With *pWithToFree; /* Free this WITH object at the end of the parse */ + ParseCleanup *pCleanup; /* List of cleanup operations to run after parse */ #ifndef SQLITE_OMIT_ALTERTABLE RenameToken *pRename; /* Tokens subject to renaming by ALTER TABLE */ #endif @@ -4827,6 +4837,7 @@ sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*); int sqlite3VdbeParameterIndex(Vdbe*, const char*, int); int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); void sqlite3ParserReset(Parse*); +void sqlite3ParserAddCleanup(Parse*,void(*)(sqlite3*,void*),void*); #ifdef SQLITE_ENABLE_NORMALIZE char *sqlite3Normalize(Vdbe*, const char*); #endif diff --git a/src/tokenize.c b/src/tokenize.c index bafda0322b..712447c4ca 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -713,19 +713,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ if( !IN_RENAME_OBJECT ){ sqlite3DeleteTrigger(db, pParse->pNewTrigger); } - - if( pParse->pWithToFree ) sqlite3WithDelete(db, pParse->pWithToFree); sqlite3DbFree(db, pParse->pVList); - while( pParse->pAinc ){ - AutoincInfo *p = pParse->pAinc; - pParse->pAinc = p->pNext; - sqlite3DbFreeNN(db, p); - } - while( pParse->pZombieTab ){ - Table *p = pParse->pZombieTab; - pParse->pZombieTab = p->pNextZombie; - sqlite3DeleteTable(db, p); - } db->pParse = pParse->pParentParse; pParse->pParentParse = 0; assert( nErr==0 || pParse->rc!=SQLITE_OK ); diff --git a/src/trigger.c b/src/trigger.c index dd4ed8c2e8..0c8cf5334f 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -1000,7 +1000,6 @@ static TriggerPrg *codeRowTrigger( sqlite3VdbeDelete(v); } - assert( !pSubParse->pAinc && !pSubParse->pZombieTab ); assert( !pSubParse->pTriggerPrg && !pSubParse->nMaxArg ); sqlite3ParserReset(pSubParse); sqlite3StackFree(db, pSubParse); From ef36ccd1a4dafa6c2bd6b8478264b305e96d13a1 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 12 Jan 2021 14:19:12 +0000 Subject: [PATCH 106/257] Fix for the top-level configure script so that it works with tcl 8.7. FossilOrigin-Name: 4810f814ff13db31b95b471d53e9654ecde286c23d10984e3cc8788d79ee79ee --- configure.ac | 6 ++++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/configure.ac b/configure.ac index ae73a5350e..8a58d3dd33 100644 --- a/configure.ac +++ b/configure.ac @@ -134,8 +134,10 @@ AC_ARG_VAR([TCLLIBDIR], [Where to install tcl plugin]) if test "x${TCLLIBDIR+set}" != "xset" ; then TCLLIBDIR='$(libdir)' for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}` ; do - TCLLIBDIR=$i - break + if test -d $i ; then + TCLLIBDIR=$i + break + fi done TCLLIBDIR="${TCLLIBDIR}/sqlite3" fi diff --git a/manifest b/manifest index 5c6ea5e56e..ee93d18c82 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\sCLI\scommand:\s\s".stats\svmstep"\senables\sthe\sdisplay\sof\sthe\svirtual-machine\nstep\scount\sonly,\safter\seach\scommand.\s\sUseful\sfor\soptimization\sproblems. -D 2021-01-09T19:10:04.989 +C Fix\sfor\sthe\stop-level\sconfigure\sscript\sso\sthat\sit\sworks\swith\stcl\s8.7. +D 2021-01-12T14:19:12.264 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -35,7 +35,7 @@ F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6 F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559 F configure 7736c168f4fd717c8052e58428a89e645d15cf0e5a3d051e248aad859a3cb140 x -F configure.ac efdb70036084ea637226e378a14f932e70c0df9f1bc846a24a909c0e1613524a +F configure.ac 412b65c6107e41c098ad7f5f2e6a3f74ac02ffc6e92b9a6264b9f1060c235a04 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd F doc/lemon.html c5d8ba85ac1daef7be8c2d389899480eb62451ff5c09b0c28ff8157bb8770746 @@ -1895,7 +1895,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 5204c2c4a7b73a64764b0d2d1d7c53709bb64e0d2685a829c7bf31af13bab5e7 -R 08e016b91a617b99baf0add20ffab4d1 -U drh -Z 8b24dd36b9adf4430f5fd36c021c9d5f +P 49dfce469e6a17111b349e53578479daf783064200bf0eec5bf8a91d3553b19f +R 444f6513d1cb519041d3beb5c2993e55 +U dan +Z a232385ce33879f0868385b077fff5a0 diff --git a/manifest.uuid b/manifest.uuid index ad74ba7a76..e050439767 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -49dfce469e6a17111b349e53578479daf783064200bf0eec5bf8a91d3553b19f \ No newline at end of file +4810f814ff13db31b95b471d53e9654ecde286c23d10984e3cc8788d79ee79ee \ No newline at end of file From d9cc532a1e06a6cbef17f0b47e1626827de97102 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 12 Jan 2021 14:23:03 +0000 Subject: [PATCH 107/257] Rerun autoconf. FossilOrigin-Name: 8f3ab5da4c8906b63e2c1a0021a3ba4f60e7199e8640518060f998876a002663 --- configure | 6 ++++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/configure b/configure index b094ef71ad..1dbef10575 100755 --- a/configure +++ b/configure @@ -10366,8 +10366,10 @@ fi if test "x${TCLLIBDIR+set}" != "xset" ; then TCLLIBDIR='$(libdir)' for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}` ; do - TCLLIBDIR=$i - break + if test -d $i ; then + TCLLIBDIR=$i + break + fi done TCLLIBDIR="${TCLLIBDIR}/sqlite3" fi diff --git a/manifest b/manifest index ee93d18c82..5be196cbe6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sfor\sthe\stop-level\sconfigure\sscript\sso\sthat\sit\sworks\swith\stcl\s8.7. -D 2021-01-12T14:19:12.264 +C Rerun\sautoconf. +D 2021-01-12T14:23:03.305 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 7736c168f4fd717c8052e58428a89e645d15cf0e5a3d051e248aad859a3cb140 x +F configure 91893a81f698778dda4d8fb24bfca606ded31ef02bcfbc2ab072d30fb67138d6 x F configure.ac 412b65c6107e41c098ad7f5f2e6a3f74ac02ffc6e92b9a6264b9f1060c235a04 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd @@ -1895,7 +1895,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 49dfce469e6a17111b349e53578479daf783064200bf0eec5bf8a91d3553b19f -R 444f6513d1cb519041d3beb5c2993e55 -U dan -Z a232385ce33879f0868385b077fff5a0 +P 4810f814ff13db31b95b471d53e9654ecde286c23d10984e3cc8788d79ee79ee +R 1b500ed31de7c59874719d84948d5eac +U drh +Z ac02a7ef9cea69c8c8e6df42e63203a3 diff --git a/manifest.uuid b/manifest.uuid index e050439767..f482c2e886 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4810f814ff13db31b95b471d53e9654ecde286c23d10984e3cc8788d79ee79ee \ No newline at end of file +8f3ab5da4c8906b63e2c1a0021a3ba4f60e7199e8640518060f998876a002663 \ No newline at end of file From 21d4f5b53a4d758a1a164201fe25c32b20b9c08a Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 12 Jan 2021 15:30:01 +0000 Subject: [PATCH 108/257] Fix a potential use-after-free following an OOM in sqlite3ParserAddCleanup() and add a mechanism to detect situations where this might occur in the future. FossilOrigin-Name: 38ef8ab9830e12acd2c710e113939b1f8dced02612c6933c37a3c948a4030d0a --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/insert.c | 5 +++-- src/prepare.c | 25 ++++++++++++++++++------- src/select.c | 2 ++ src/sqliteInt.h | 3 +++ 6 files changed, 36 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index fdfe62597e..cfee239768 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\slinked\slist\sof\sParseCleanup\sobjects\sto\sthe\send\sof\sa\sParse\sobject\sand\nuse\sthat\slist\sas\sa\splace\sto\sput\sother\ssub-objects\sthat\sneed\sto\sbe\sdeallocated.\nHave\sa\ssingle\ssuch\slist\sfor\sinfrequently\sused\ssub-objects\sis\smore\sefficient\nthan\sdoing\san\sa\sseparate\scheck\sfor\seach\skind\sof\ssub-object. -D 2021-01-11T20:37:02.868 +C Fix\sa\spotential\suse-after-free\sfollowing\san\sOOM\sin\ssqlite3ParserAddCleanup()\nand\sadd\sa\smechanism\sto\sdetect\ssituations\swhere\sthis\smight\soccur\sin\sthe\nfuture. +D 2021-01-12T15:30:01.102 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -501,7 +501,7 @@ 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 9ced988440d29531568bfe4f48c7b69035b100f6833ca1080abb710b7c415111 +F src/insert.c c5e0c25cfb9960d9b7d49043de6adc12748853bc6dea76f5adef059e366f2f70 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 F src/main.c 97e9f137354bc1f76dc9bb60a0a24f8c45cf73b33e80d3ee4c64155336fb820d @@ -535,17 +535,17 @@ F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a F src/pragma.c 6daaaecc26a4b09481d21722525b079ce756751a43a79cc1d8f122d686806193 F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf -F src/prepare.c 1f8bb4f20d83024194780f28920c6af9cfe52adc772ded8f33b4ee2b66f46f66 +F src/prepare.c cfe5a0ec9fd612c89b4d50acfd4b796bd5fe850441cab0d866d72fa3aa982c45 F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c b7281a798ee02cb356d2d8b7381939cb513646a91210478587ed6f7f33c357a8 +F src/select.c a9c38abfbaaf1230fa9079b4d1d43694cac335a85efa39684bd4969a5c877a19 F src/shell.c.in 79bceb990e4bac23a09bb8dd65783ea4867b8bfca9242b5a82b884043e65109a F src/sqlite.h.in 0af968a1fa3c717261e1df0ed105fa7bddb4d82de7e0adb3eab49e6aa81b4de7 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h e484ffb8ce2182ecd745b2e0af0caa12996e848b0f91748c742d1d135d31770c +F src/sqliteInt.h c7c7e0e79769885a1c7fa519299bdb222e83e2d7d4843ed6ca1cd9a585016386 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1895,7 +1895,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 49dfce469e6a17111b349e53578479daf783064200bf0eec5bf8a91d3553b19f -R f1889156a8e996b56aa3e8cdd75a199d +P affa2b7b316941b8a6c4d0d1ff212c81a593faf1d05d129e14d2b70d73a25c59 +R f95fa7a0a6ecfccf053d41ca6f333d8f U drh -Z 2f77ed20cd8529f3498738d09cff4442 +Z 25b7965ccc91991627419c27b1a54eed diff --git a/manifest.uuid b/manifest.uuid index 6b51da5c3c..0e810795ba 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -affa2b7b316941b8a6c4d0d1ff212c81a593faf1d05d129e14d2b70d73a25c59 \ No newline at end of file +38ef8ab9830e12acd2c710e113939b1f8dced02612c6933c37a3c948a4030d0a \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index ae55868961..c0ab0cf37a 100644 --- a/src/insert.c +++ b/src/insert.c @@ -370,8 +370,9 @@ static int autoIncBegin( while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; } if( pInfo==0 ){ pInfo = sqlite3DbMallocRawNN(pParse->db, sizeof(*pInfo)); - if( pInfo==0 ) return 0; - sqlite3ParserAddCleanup(pToplevel, sqlite3DbFreeNN, pInfo); + sqlite3ParserAddCleanup(pToplevel, sqlite3DbFree, pInfo); + testcase( pParse->earlyCleanup ); + if( pParse->db->mallocFailed ) return 0; pInfo->pNext = pToplevel->pAinc; pToplevel->pAinc = pInfo; pInfo->pTab = pTab; diff --git a/src/prepare.c b/src/prepare.c index 980785c341..f93a6f07ad 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -590,20 +590,28 @@ void sqlite3ParserReset(Parse *pParse){ /* ** Add a new cleanup operation to a Parser. The cleanup should happen when -** the parser object is destroyed. +** the parser object is destroyed. But, beware: the cleanup might happen +** immediately. ** ** Use this mechanism for uncommon cleanups. There is a higher setup -** cost, so this should not be used for common cleanups. But for less +** cost for this mechansim (an extra malloc), so it should not be used +** for common cleanups that happen on most calls. But for less ** common cleanups, we save a single NULL-pointer comparison in -** sqlite3ParserReset(), which makes a surprising difference in total -** performance. +** sqlite3ParserReset(), which reduces the total CPU cycle count. ** ** If a memory allocation error occurs, then the cleanup happens immediately. +** When eithr SQLITE_DEBUG or SQLITE_COVERAGE_TEST are defined, the +** pParse->earlyCleanup flag is set in that case. Calling code show verify +** that test cases exist for which this happens, to guard against possible +** use-after-free errors following an OOM. The preferred way to do this is +** to immediately follow the call to this routine with: +** +** testcase( pParse->earlyCleanup ); */ void sqlite3ParserAddCleanup( - Parse *pParse, - void (*xCleanup)(sqlite3*,void*), - void *pPtr + Parse *pParse, /* Destroy when this Parser finishes */ + void (*xCleanup)(sqlite3*,void*), /* The cleanup routine */ + void *pPtr /* Pointer to object to be cleaned up */ ){ ParseCleanup *pCleanup = sqlite3DbMallocRaw(pParse->db, sizeof(*pCleanup)); if( pCleanup ){ @@ -613,6 +621,9 @@ void sqlite3ParserAddCleanup( pCleanup->xCleanup = xCleanup; }else{ xCleanup(pParse->db, pPtr); +#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) + pParse->earlyCleanup = 1; +#endif } } diff --git a/src/select.c b/src/select.c index fc853210fa..c4d17810e3 100644 --- a/src/select.c +++ b/src/select.c @@ -4143,6 +4143,7 @@ static int flattenSubquery( sqlite3ParserAddCleanup(pToplevel, (void(*)(sqlite3*,void*))sqlite3DeleteTable, pTabToDel); + testcase( pToplevel->earlyCleanup ); }else{ pTabToDel->nTabRef--; } @@ -4865,6 +4866,7 @@ void sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){ sqlite3ParserAddCleanup(pParse, (void(*)(sqlite3*,void*))sqlite3WithDelete, pWith); + testcase( pParse->earlyCleanup ); } } } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 484d63c5b8..6d1e598d94 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3390,6 +3390,9 @@ struct Parse { u8 okConstFactor; /* OK to factor out constants */ u8 disableLookaside; /* Number of times lookaside has been disabled */ u8 disableVtab; /* Disable all virtual tables for this parse */ +#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) + u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */ +#endif int nRangeReg; /* Size of the temporary register block */ int iRangeReg; /* First register in temporary register block */ int nErr; /* Number of errors seen */ From 2053f313bfc498262f13c04793b93867f58544ba Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 12 Jan 2021 20:16:31 +0000 Subject: [PATCH 109/257] Lexer and grammar rules for a RETURNING clause on DELETE/INSERT/UPDATE. Actually making this work, though, will involve a lot more code which will likely slow down processing for the common case where there is no RETURNING clause. Furthermore, RETURNING seems to be of limited usefulness and it is not standard SQL. So we abandon it here. These experimental changes are parked in a branch as an historical reference. If circumstances changes, we might take up the cause again some day. FossilOrigin-Name: abf8da815646055df5b871d54b99994c1470182dee7952fc5fd627e4379406cb --- manifest | 22 ++++++++++++---------- manifest.uuid | 2 +- src/build.c | 8 ++++++++ src/parse.y | 22 +++++++++++++++++----- src/sqliteInt.h | 2 ++ tool/mkkeywordhash.c | 11 +++++++++-- 6 files changed, 49 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 018db97054..9c330a0aad 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\sParseCleanup\senhancement\sto\strunk. -D 2021-01-12T16:26:36.110 +C Lexer\sand\sgrammar\srules\sfor\sa\sRETURNING\sclause\son\sDELETE/INSERT/UPDATE.\nActually\smaking\sthis\swork,\sthough,\swill\sinvolve\sa\slot\smore\scode\swhich\swill\nlikely\sslow\sdown\sprocessing\sfor\sthe\scommon\scase\swhere\sthere\sis\sno\nRETURNING\sclause.\s\sFurthermore,\sRETURNING\sseems\sto\sbe\sof\slimited\susefulness\nand\sit\sis\snot\sstandard\sSQL.\s\sSo\swe\sabandon\sit\shere.\s\sThese\sexperimental\nchanges\sare\sparked\sin\sa\sbranch\sas\san\shistorical\sreference.\s\sIf\scircumstances\nchanges,\swe\smight\stake\sup\sthe\scause\sagain\ssome\sday. +D 2021-01-12T20:16:31.150 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -484,7 +484,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 0f9cb686871ae668817673f0823b55d1bcadbc86ea28bd22c590b064a8322d5a F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 -F src/build.c d4c06261b0e532523ede58dc511381a7a9c155132e4b65a6bb2ff76fe657793a +F src/build.c ba8af18891c07501a185ecd02a2bc13a593de9bfd59dbffa5d126780c0c9fb8e F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 @@ -529,7 +529,7 @@ F src/os_win.c 77d39873836f1831a9b0b91894fec45ab0e9ca8e067dc8c549e1d1eca1566fe9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c c49952ac5e9cc536778eff528091d79d38b3e45cbeeed4695dc05e207dc6547d F src/pager.h 4bf9b3213a4b2bebbced5eaa8b219cf25d4a82f385d093cd64b7e93e5285f66f -F src/parse.y 6c8aa09a7fa6e0867c3a3d67ef61b911aa392c9b084a61dc632cd93732aef8ad +F src/parse.y 6b462c25bae7e0c53f2935f9157f82abeba07754905ef8835c978742c5473ff3 F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a @@ -545,7 +545,7 @@ F src/shell.c.in 79bceb990e4bac23a09bb8dd65783ea4867b8bfca9242b5a82b884043e65109 F src/sqlite.h.in 0af968a1fa3c717261e1df0ed105fa7bddb4d82de7e0adb3eab49e6aa81b4de7 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h c7c7e0e79769885a1c7fa519299bdb222e83e2d7d4843ed6ca1cd9a585016386 +F src/sqliteInt.h de0ba6b4f9bcddd665b4aa8feead3108e737536f061bad85992ffbad8050239f F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1823,7 +1823,7 @@ F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439 F tool/mkautoconfamal.sh f62353eb6c06ab264da027fd4507d09914433dbdcab9cb011cdc18016f1ab3b8 F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe x F tool/mkctimec.tcl dd183b73ae1c28249669741c250525f0407e579a70482371668fd5f130d9feb3 -F tool/mkkeywordhash.c 24e4396ae665d985fed9e040e8b748129c1a12d77eeeae7ad4609821c41ba7bf +F tool/mkkeywordhash.c 750f25aef0e23f8e3367af6d824fbf5ed7d3e285f27cea91aa2dd72c367630eb F tool/mkmsvcmin.tcl 6ecab9fe22c2c8de4d82d4c46797bda3d2deac8e763885f5a38d0c44a895ab33 F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl 352a4319c0ad869eb26442bf7c3b015aa15594c21f1cce5a6420dbe999367c21 @@ -1895,8 +1895,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 8f3ab5da4c8906b63e2c1a0021a3ba4f60e7199e8640518060f998876a002663 38ef8ab9830e12acd2c710e113939b1f8dced02612c6933c37a3c948a4030d0a -R a2b97b3e175b432108521b3e9366ef42 -T +closed 38ef8ab9830e12acd2c710e113939b1f8dced02612c6933c37a3c948a4030d0a +P 35824c1bcbd89ae4a94acfbe511bfbd888c418b981819e72bc9a991fc82d136c +R f88ede067372ddc1781e1314bfb966d4 +T *branch * returning +T *sym-returning * +T -sym-trunk * U drh -Z 9c0d514193cce7631d3a6adc01edb18c +Z a56a87fefbb361b1248407b671a1766d diff --git a/manifest.uuid b/manifest.uuid index 730c7d084c..1bce0b6baa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -35824c1bcbd89ae4a94acfbe511bfbd888c418b981819e72bc9a991fc82d136c \ No newline at end of file +abf8da815646055df5b871d54b99994c1470182dee7952fc5fd627e4379406cb \ No newline at end of file diff --git a/src/build.c b/src/build.c index 50289c6a1d..5b4bbe499b 100644 --- a/src/build.c +++ b/src/build.c @@ -1243,6 +1243,14 @@ void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){ } #endif +/* +** Add the RETURNING clause to the parser currently underway. +*/ +void sqlite3AddReturning(Parse *pParse, ExprList *pList){ + sqlite3ParserAddCleanup(pParse, + (void(*)(sqlite3*,void*))sqlite3ExprListDelete, pList); + pParse->pReturning = pList; +} /* ** Add a new column to the table currently being constructed. diff --git a/src/parse.y b/src/parse.y index faec4b5cf5..4c79d4a87a 100644 --- a/src/parse.y +++ b/src/parse.y @@ -868,7 +868,7 @@ limit_opt(A) ::= LIMIT expr(X) COMMA expr(Y). /////////////////////////// The DELETE statement ///////////////////////////// // %if SQLITE_ENABLE_UPDATE_DELETE_LIMIT || SQLITE_UDL_CAPABLE_PARSER -cmd ::= with DELETE FROM xfullname(X) indexed_opt(I) where_opt(W) +cmd ::= with DELETE FROM xfullname(X) indexed_opt(I) where_opt_ret(W) orderby_opt(O) limit_opt(L). { sqlite3SrcListIndexedBy(pParse, X, &I); #ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT @@ -881,7 +881,7 @@ cmd ::= with DELETE FROM xfullname(X) indexed_opt(I) where_opt(W) sqlite3DeleteFrom(pParse,X,W,O,L); } %else -cmd ::= with DELETE FROM xfullname(X) indexed_opt(I) where_opt(W). { +cmd ::= with DELETE FROM xfullname(X) indexed_opt(I) where_opt_ret(W). { sqlite3SrcListIndexedBy(pParse, X, &I); sqlite3DeleteFrom(pParse,X,W,0,0); } @@ -889,9 +889,17 @@ cmd ::= with DELETE FROM xfullname(X) indexed_opt(I) where_opt(W). { %type where_opt {Expr*} %destructor where_opt {sqlite3ExprDelete(pParse->db, $$);} +%type where_opt_ret {Expr*} +%destructor where_opt_ret {sqlite3ExprDelete(pParse->db, $$);} where_opt(A) ::= . {A = 0;} where_opt(A) ::= WHERE expr(X). {A = X;} +where_opt_ret(A) ::= . {A = 0;} +where_opt_ret(A) ::= WHERE expr(X). {A = X;} +where_opt_ret(A) ::= RETURNING selcollist(X). + {sqlite3AddReturning(pParse,X); A = 0;} +where_opt_ret(A) ::= WHERE expr(X) RETURNING selcollist(Y). + {sqlite3AddReturning(pParse,Y); A = X;} ////////////////////////// The UPDATE command //////////////////////////////// // @@ -946,7 +954,7 @@ cmd ::= with insert_cmd(R) INTO xfullname(X) idlist_opt(F) select(S) upsert(U). { sqlite3Insert(pParse, X, S, F, R, U); } -cmd ::= with insert_cmd(R) INTO xfullname(X) idlist_opt(F) DEFAULT VALUES. +cmd ::= with insert_cmd(R) INTO xfullname(X) idlist_opt(F) DEFAULT VALUES returning. { sqlite3Insert(pParse, X, 0, F, R, 0); } @@ -959,16 +967,20 @@ cmd ::= with insert_cmd(R) INTO xfullname(X) idlist_opt(F) DEFAULT VALUES. // avoid unreachable code. //%destructor upsert {sqlite3UpsertDelete(pParse->db,$$);} upsert(A) ::= . { A = 0; } +upsert(A) ::= RETURNING selcollist(X). { A = 0; sqlite3AddReturning(pParse,X); } upsert(A) ::= ON CONFLICT LP sortlist(T) RP where_opt(TW) DO UPDATE SET setlist(Z) where_opt(W) upsert(N). { A = sqlite3UpsertNew(pParse->db,T,TW,Z,W,N);} upsert(A) ::= ON CONFLICT LP sortlist(T) RP where_opt(TW) DO NOTHING upsert(N). { A = sqlite3UpsertNew(pParse->db,T,TW,0,0,N); } -upsert(A) ::= ON CONFLICT DO NOTHING. +upsert(A) ::= ON CONFLICT DO NOTHING returning. { A = sqlite3UpsertNew(pParse->db,0,0,0,0,0); } -upsert(A) ::= ON CONFLICT DO UPDATE SET setlist(Z) where_opt(W). +upsert(A) ::= ON CONFLICT DO UPDATE SET setlist(Z) where_opt(W) returning. { A = sqlite3UpsertNew(pParse->db,0,0,Z,W,0);} +returning ::= RETURNING selcollist(X). {sqlite3AddReturning(pParse,X);} +returning ::= . + %type insert_cmd {int} insert_cmd(A) ::= INSERT orconf(R). {A = R;} insert_cmd(A) ::= REPLACE. {A = OE_Replace;} diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 6d1e598d94..c7dd11862f 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3405,6 +3405,7 @@ struct Parse { int nLabelAlloc; /* Number of slots in aLabel */ int *aLabel; /* Space to hold the labels */ ExprList *pConstExpr;/* Constant expressions */ + ExprList *pReturning;/* The RETURNING clause, if any */ Token constraintName;/* Name of the constraint currently being parsed */ yDbMask writeMask; /* Start a write transaction on these databases */ yDbMask cookieMask; /* Bitmask of schema verified databases */ @@ -4248,6 +4249,7 @@ void sqlite3AddDefaultValue(Parse*,Expr*,const char*,const char*); void sqlite3AddCollateType(Parse*, Token*); void sqlite3AddGenerated(Parse*,Expr*,Token*); void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*); +void sqlite3AddReturning(Parse*,ExprList*); int sqlite3ParseUri(const char*,const char*,unsigned int*, sqlite3_vfs**,char**,char **); #define sqlite3CodecQueryParameters(A,B,C) 0 diff --git a/tool/mkkeywordhash.c b/tool/mkkeywordhash.c index f8537a85bd..ea3763fd19 100644 --- a/tool/mkkeywordhash.c +++ b/tool/mkkeywordhash.c @@ -155,10 +155,16 @@ struct Keyword { # define WINDOWFUNC 0x00100000 #endif #ifdef SQLITE_OMIT_GENERATED_COLUMNS -# define GENCOL 0 +# define GENCOL 0 #else -# define GENCOL 0x00200000 +# define GENCOL 0x00200000 #endif +#ifdef SQLITE_OMIT_RETURNING +# define RETURNING 0 +#else +# define RETURNING 0x00400000 +#endif + /* ** These are the keywords @@ -280,6 +286,7 @@ static Keyword aKeywordTable[] = { { "RENAME", "TK_RENAME", ALTER, 1 }, { "REPLACE", "TK_REPLACE", CONFLICT, 10 }, { "RESTRICT", "TK_RESTRICT", FKEY, 1 }, + { "RETURNING", "TK_RETURNING", RETURNING, 10 }, { "RIGHT", "TK_JOIN_KW", ALWAYS, 0 }, { "ROLLBACK", "TK_ROLLBACK", ALWAYS, 1 }, { "ROW", "TK_ROW", TRIGGER, 1 }, From b9366f8e3250eae8417a46396cefd082c2ab7a59 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 13 Jan 2021 11:44:51 +0000 Subject: [PATCH 110/257] In the .selecttrace output, show the ORDER BY clause added by the Min/Max optimization. FossilOrigin-Name: db0ecfe66433f8915b6eb16d3735a4a0d0f8e0bbc395bc9c1364387506fc4657 --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/select.c | 4 ++++ 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 018db97054..24a5971adf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\sParseCleanup\senhancement\sto\strunk. -D 2021-01-12T16:26:36.110 +C In\sthe\s.selecttrace\soutput,\sshow\sthe\sORDER\sBY\sclause\sadded\sby\sthe\sMin/Max\noptimization. +D 2021-01-13T11:44:51.022 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -540,7 +540,7 @@ F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c a9c38abfbaaf1230fa9079b4d1d43694cac335a85efa39684bd4969a5c877a19 +F src/select.c 74655feb1ba3767f0f376029acdf1e488942e6b02aa0e65679a75181c2fbe88f F src/shell.c.in 79bceb990e4bac23a09bb8dd65783ea4867b8bfca9242b5a82b884043e65109a F src/sqlite.h.in 0af968a1fa3c717261e1df0ed105fa7bddb4d82de7e0adb3eab49e6aa81b4de7 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1895,8 +1895,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 8f3ab5da4c8906b63e2c1a0021a3ba4f60e7199e8640518060f998876a002663 38ef8ab9830e12acd2c710e113939b1f8dced02612c6933c37a3c948a4030d0a -R a2b97b3e175b432108521b3e9366ef42 -T +closed 38ef8ab9830e12acd2c710e113939b1f8dced02612c6933c37a3c948a4030d0a +P 35824c1bcbd89ae4a94acfbe511bfbd888c418b981819e72bc9a991fc82d136c +R 61cf4ac944232eaafcf9775988abf565 U drh -Z 9c0d514193cce7631d3a6adc01edb18c +Z 998402e9038a172631ad95c2c70da3a5 diff --git a/manifest.uuid b/manifest.uuid index 730c7d084c..5458f1df8c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -35824c1bcbd89ae4a94acfbe511bfbd888c418b981819e72bc9a991fc82d136c \ No newline at end of file +db0ecfe66433f8915b6eb16d3735a4a0d0f8e0bbc395bc9c1364387506fc4657 \ No newline at end of file diff --git a/src/select.c b/src/select.c index c4d17810e3..f00a3acd8d 100644 --- a/src/select.c +++ b/src/select.c @@ -6580,6 +6580,10 @@ int sqlite3Select( int ii; SELECTTRACE(0x400,pParse,p,("After aggregate analysis %p:\n", pAggInfo)); sqlite3TreeViewSelect(0, p, 0); + if( minMaxFlag ){ + sqlite3DebugPrintf("MIN/MAX Optimization (0x%02x) adds:\n", minMaxFlag); + sqlite3TreeViewExprList(0, pMinMaxOrderBy, 0, "ORDERBY"); + } for(ii=0; iinColumn; ii++){ sqlite3DebugPrintf("agg-column[%d] iMem=%d\n", ii, pAggInfo->aCol[ii].iMem); From aa556b0fa7ae3f96df773f20d86c51186be25f52 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 13 Jan 2021 12:59:20 +0000 Subject: [PATCH 111/257] cli: Omit surplus whitespace at the end of lines in .explain output. FossilOrigin-Name: 11e4eb095746602961a178044809a68a77ba7b367596997bef726e54062423d9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 24a5971adf..b050b37ce0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\s.selecttrace\soutput,\sshow\sthe\sORDER\sBY\sclause\sadded\sby\sthe\sMin/Max\noptimization. -D 2021-01-13T11:44:51.022 +C cli:\sOmit\ssurplus\swhitespace\sat\sthe\send\sof\slines\sin\s.explain\soutput. +D 2021-01-13T12:59:20.834 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -541,7 +541,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 74655feb1ba3767f0f376029acdf1e488942e6b02aa0e65679a75181c2fbe88f -F src/shell.c.in 79bceb990e4bac23a09bb8dd65783ea4867b8bfca9242b5a82b884043e65109a +F src/shell.c.in 8331e564cd73e1784dd034d88ce626d2867531e9cc38ece980b256b09eb548b3 F src/sqlite.h.in 0af968a1fa3c717261e1df0ed105fa7bddb4d82de7e0adb3eab49e6aa81b4de7 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e @@ -1895,7 +1895,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 35824c1bcbd89ae4a94acfbe511bfbd888c418b981819e72bc9a991fc82d136c -R 61cf4ac944232eaafcf9775988abf565 +P db0ecfe66433f8915b6eb16d3735a4a0d0f8e0bbc395bc9c1364387506fc4657 +R 2ad612629a79dbad03e8b7f173945d59 U drh -Z 998402e9038a172631ad95c2c70da3a5 +Z f407a95e341e109313c0922f7d2a229b diff --git a/manifest.uuid b/manifest.uuid index 5458f1df8c..ccaf3daab6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -db0ecfe66433f8915b6eb16d3735a4a0d0f8e0bbc395bc9c1364387506fc4657 \ No newline at end of file +11e4eb095746602961a178044809a68a77ba7b367596997bef726e54062423d9 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 806ca2102b..734a54546e 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -2027,6 +2027,7 @@ static int shell_callback( if( azArg==0 ) break; for(i=0; iw ){ w = strlenChar(azArg[i]); } From d193057ad147fe038d0f85c68cd914fa9d91c40c Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 13 Jan 2021 15:23:17 +0000 Subject: [PATCH 112/257] Further enhancements to the min/max optimization of [/info/b8ba2f17f938c035|check-in b8ba2f17f938c035] to fix the performance regression identified by [forum:/forumpost/623f571482|forum post 623f571482]. FossilOrigin-Name: 188772a1dbaf066fbddd39c718fdd87478b19a920622f4640bcb79d4ef065331 --- manifest | 19 +++++++++++-------- manifest.uuid | 2 +- src/select.c | 8 +++----- src/sqliteInt.h | 1 + src/where.c | 23 +++++++++++++++++++++++ 5 files changed, 39 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index b050b37ce0..d0beeb67d4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C cli:\sOmit\ssurplus\swhitespace\sat\sthe\send\sof\slines\sin\s.explain\soutput. -D 2021-01-13T12:59:20.834 +C Further\senhancements\sto\sthe\smin/max\soptimization\sof\n[/info/b8ba2f17f938c035|check-in\sb8ba2f17f938c035]\sto\sfix\sthe\sperformance\nregression\sidentified\sby\n[forum:/forumpost/623f571482|forum\spost\s623f571482]. +D 2021-01-13T15:23:17.568 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -540,12 +540,12 @@ F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 74655feb1ba3767f0f376029acdf1e488942e6b02aa0e65679a75181c2fbe88f +F src/select.c 083c9bcc6b2ec80f172d414f8129679dddfb25e1ad57364cf3677bb504d62158 F src/shell.c.in 8331e564cd73e1784dd034d88ce626d2867531e9cc38ece980b256b09eb548b3 F src/sqlite.h.in 0af968a1fa3c717261e1df0ed105fa7bddb4d82de7e0adb3eab49e6aa81b4de7 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h c7c7e0e79769885a1c7fa519299bdb222e83e2d7d4843ed6ca1cd9a585016386 +F src/sqliteInt.h cecaa4eea2af66d36e4b1453d08da83b4d9ad2de2510d58d518ebd51fbd2692b F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -627,7 +627,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 69e770e96fd56cc21608992bf2c6f1f3dc5cf2572d0495c6a643b06c3a679f14 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c d9c4e454ebb9499e908aa62d55b8994c375cf5355ac78f60d45af17f7890701c -F src/where.c 3d31871d03906312d7d71a9c0b28c97bcbaead7606dfc15f9b3d080b18702385 +F src/where.c dee929890fe399993d4e78a5a89d4b289f7ab015446e157d2e4c25477fdfa060 F src/whereInt.h 9a3f577619f07700d16d89eeb2f3d94d6b7ed7f109c2dacf0ce8844921549506 F src/wherecode.c a3a1aff30fe99a818d8e7c607980f033f40c68d890e03ed25838b9dbb7908bee F src/whereexpr.c 3a463e156ea388083c501502229c2c7f4f5c6b5330ea59bdf40d6eb6e155a25f @@ -1895,7 +1895,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 db0ecfe66433f8915b6eb16d3735a4a0d0f8e0bbc395bc9c1364387506fc4657 -R 2ad612629a79dbad03e8b7f173945d59 +P 11e4eb095746602961a178044809a68a77ba7b367596997bef726e54062423d9 +R 14dcd4c79aadaa323e7c1244a63358d2 +T *branch * minmax-opt-exp +T *sym-minmax-opt-exp * +T -sym-trunk * U drh -Z f407a95e341e109313c0922f7d2a229b +Z 525d6c9785240d33b80adadc935f19d6 diff --git a/manifest.uuid b/manifest.uuid index ccaf3daab6..a15faf20cd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -11e4eb095746602961a178044809a68a77ba7b367596997bef726e54062423d9 \ No newline at end of file +188772a1dbaf066fbddd39c718fdd87478b19a920622f4640bcb79d4ef065331 \ No newline at end of file diff --git a/src/select.c b/src/select.c index f00a3acd8d..76806b66ea 100644 --- a/src/select.c +++ b/src/select.c @@ -6773,7 +6773,7 @@ int sqlite3Select( /* End of the loop */ if( groupBySort ){ - sqlite3VdbeAddOp2(v, OP_SorterNext, pAggInfo->sortingIdx, addrTopOfLoop); + sqlite3VdbeAddOp2(v, OP_SorterNext, pAggInfo->sortingIdx,addrTopOfLoop); VdbeCoverage(v); }else{ sqlite3WhereEnd(pWInfo); @@ -6885,7 +6885,6 @@ int sqlite3Select( explainSimpleCount(pParse, pTab, pBest); }else{ int regAcc = 0; /* "populate accumulators" flag */ - int addrSkip; /* If there are accumulator registers but no min() or max() functions ** without FILTER clauses, allocate register regAcc. Register regAcc @@ -6934,9 +6933,8 @@ int sqlite3Select( } updateAccumulator(pParse, regAcc, pAggInfo); if( regAcc ) sqlite3VdbeAddOp2(v, OP_Integer, 1, regAcc); - addrSkip = sqlite3WhereOrderByLimitOptLabel(pWInfo); - if( addrSkip!=sqlite3WhereContinueLabel(pWInfo) ){ - sqlite3VdbeGoto(v, addrSkip); + if( minMaxFlag ){ + sqlite3WhereMinMaxOptEarlyOut(v, pWInfo); } sqlite3WhereEnd(pWInfo); finalizeAggFunctions(pParse, pAggInfo); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 6d1e598d94..8432fe20cd 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4341,6 +4341,7 @@ LogEst sqlite3WhereOutputRowCount(WhereInfo*); int sqlite3WhereIsDistinct(WhereInfo*); int sqlite3WhereIsOrdered(WhereInfo*); int sqlite3WhereOrderByLimitOptLabel(WhereInfo*); +void sqlite3WhereMinMaxOptEarlyOut(Vdbe*,WhereInfo*); int sqlite3WhereIsSorted(WhereInfo*); int sqlite3WhereContinueLabel(WhereInfo*); int sqlite3WhereBreakLabel(WhereInfo*); diff --git a/src/where.c b/src/where.c index 0f219d4391..adc688b4ba 100644 --- a/src/where.c +++ b/src/where.c @@ -99,6 +99,29 @@ int sqlite3WhereOrderByLimitOptLabel(WhereInfo *pWInfo){ return pInner->addrNxt; } +/* +** While generating code for the min/max optimization, after handling +** the aggregate-step call to min() or max(), check to see if any +** additional looping is required. If the output order is such that +** we are certain that the correct answer has already been found, then +** code an OP_Goto to by pass subsequent processing. +** +** Any extra OP_Goto that is coded here is an optimization. The +** correct answer should be obtained regardless. This OP_Goto just +** makes the answer appear faster. +*/ +void sqlite3WhereMinMaxOptEarlyOut(Vdbe *v, WhereInfo *pWInfo){ + WhereLevel *pInner; + if( !pWInfo->bOrderedInnerLoop ) return; + if( pWInfo->nOBSat==0 ) return; + pInner = &pWInfo->a[pWInfo->nLevel-1]; + if( (pInner->pWLoop->wsFlags & WHERE_COLUMN_IN)==0 ){ + sqlite3VdbeGoto(v, pWInfo->iBreak); + }else if( pInner->addrNxt!=pWInfo->iContinue ){ + sqlite3VdbeGoto(v, pInner->addrNxt); + } +} + /* ** Return the VDBE address or label to jump to in order to continue ** immediately with the next row of a WHERE clause. From af7b76534b3680d712fadf5d5a038c75d4b99a90 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 13 Jan 2021 19:28:17 +0000 Subject: [PATCH 113/257] Expand the number of optimization-disable bits from 16 to 32. Use one of the new bits to disable the min/max optimization, so that we can more easily verify that we get the same answer both with and within that optimization. FossilOrigin-Name: fd0c9a123b58b7b134ed67f26dbb4196b61e56227f078422cc7e9a3497054c2d --- manifest | 21 +++++++++------------ manifest.uuid | 2 +- src/main.c | 2 +- src/select.c | 6 +++++- src/shell.c.in | 2 +- src/sqliteInt.h | 39 ++++++++++++++++++++------------------- 6 files changed, 37 insertions(+), 35 deletions(-) diff --git a/manifest b/manifest index d0beeb67d4..761cd8ddc4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\senhancements\sto\sthe\smin/max\soptimization\sof\n[/info/b8ba2f17f938c035|check-in\sb8ba2f17f938c035]\sto\sfix\sthe\sperformance\nregression\sidentified\sby\n[forum:/forumpost/623f571482|forum\spost\s623f571482]. -D 2021-01-13T15:23:17.568 +C Expand\sthe\snumber\sof\soptimization-disable\sbits\sfrom\s16\sto\s32.\s\sUse\sone\sof\nthe\snew\sbits\sto\sdisable\sthe\smin/max\soptimization,\sso\sthat\swe\scan\smore\seasily\nverify\sthat\swe\sget\sthe\ssame\sanswer\sboth\swith\sand\swithin\sthat\soptimization. +D 2021-01-13T19:28:17.446 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -504,7 +504,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c c5e0c25cfb9960d9b7d49043de6adc12748853bc6dea76f5adef059e366f2f70 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 -F src/main.c 97e9f137354bc1f76dc9bb60a0a24f8c45cf73b33e80d3ee4c64155336fb820d +F src/main.c 1c5de7b3fabcdf05f4fe563aab5d81d175b89c67a8678a12ba86629356afa356 F src/malloc.c c1af4ac5a463648cd2953fd4ac679b3ba9022ce5ec794a60806150ad69dfd33a F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -540,12 +540,12 @@ F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 083c9bcc6b2ec80f172d414f8129679dddfb25e1ad57364cf3677bb504d62158 -F src/shell.c.in 8331e564cd73e1784dd034d88ce626d2867531e9cc38ece980b256b09eb548b3 +F src/select.c 738cb746189f721f59972993c13085fa2975c4cbfd04ba26445f3b42c81237dc +F src/shell.c.in 9ebc74e4f05cfbd0f4a36060fdaeff1da4e9af4458358722bc08c5a1ab9a0879 F src/sqlite.h.in 0af968a1fa3c717261e1df0ed105fa7bddb4d82de7e0adb3eab49e6aa81b4de7 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h cecaa4eea2af66d36e4b1453d08da83b4d9ad2de2510d58d518ebd51fbd2692b +F src/sqliteInt.h 6aad58a5ae1374e18ea53d0c3ea71f047b67313426767783bd7fa14ee786725a F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1895,10 +1895,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 11e4eb095746602961a178044809a68a77ba7b367596997bef726e54062423d9 -R 14dcd4c79aadaa323e7c1244a63358d2 -T *branch * minmax-opt-exp -T *sym-minmax-opt-exp * -T -sym-trunk * +P 188772a1dbaf066fbddd39c718fdd87478b19a920622f4640bcb79d4ef065331 +R fee2bff3fc3f4ab0866b8b2d20b15a63 U drh -Z 525d6c9785240d33b80adadc935f19d6 +Z b04c23448445719d4a662625f97c5411 diff --git a/manifest.uuid b/manifest.uuid index a15faf20cd..834b730385 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -188772a1dbaf066fbddd39c718fdd87478b19a920622f4640bcb79d4ef065331 \ No newline at end of file +fd0c9a123b58b7b134ed67f26dbb4196b61e56227f078422cc7e9a3497054c2d \ No newline at end of file diff --git a/src/main.c b/src/main.c index bbf81e778e..0f3989d9df 100644 --- a/src/main.c +++ b/src/main.c @@ -4080,7 +4080,7 @@ int sqlite3_test_control(int op, ...){ */ case SQLITE_TESTCTRL_OPTIMIZATIONS: { sqlite3 *db = va_arg(ap, sqlite3*); - db->dbOptFlags = (u16)(va_arg(ap, int) & 0xffff); + db->dbOptFlags = va_arg(ap, u32); break; } diff --git a/src/select.c b/src/select.c index 76806b66ea..7c3019890c 100644 --- a/src/select.c +++ b/src/select.c @@ -4640,7 +4640,11 @@ static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){ assert( *ppMinMax==0 ); assert( pFunc->op==TK_AGG_FUNCTION ); assert( !IsWindowFunc(pFunc) ); - if( pEList==0 || pEList->nExpr!=1 || ExprHasProperty(pFunc, EP_WinFunc) ){ + if( pEList==0 + || pEList->nExpr!=1 + || ExprHasProperty(pFunc, EP_WinFunc) + || OptimizationDisabled(db, SQLITE_MinMaxOpt) + ){ return eRet; } zFunc = pFunc->u.zToken; diff --git a/src/shell.c.in b/src/shell.c.in index 734a54546e..bfb9648128 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -9995,7 +9995,7 @@ static int do_meta_command(char *zLine, ShellState *p){ /* sqlite3_test_control(int, db, int) */ case SQLITE_TESTCTRL_OPTIMIZATIONS: if( nArg==3 ){ - int opt = (int)strtol(azArg[2], 0, 0); + unsigned int opt = (unsigned int)strtol(azArg[2], 0, 0); rc2 = sqlite3_test_control(testctrl, p->db, opt); isOk = 3; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 8432fe20cd..0581e907da 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1496,7 +1496,7 @@ struct sqlite3 { int errCode; /* Most recent error code (SQLITE_*) */ int errMask; /* & result codes with this before returning */ int iSysErrno; /* Errno value from last system error */ - u16 dbOptFlags; /* Flags to enable/disable optimizations */ + u32 dbOptFlags; /* Flags to enable/disable optimizations */ u8 enc; /* Text encoding */ u8 autoCommit; /* The auto-commit flag. */ u8 temp_store; /* 1: file 2: memory 0: default */ @@ -1703,24 +1703,25 @@ struct sqlite3 { ** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to ** selectively disable various optimizations. */ -#define SQLITE_QueryFlattener 0x0001 /* Query flattening */ -#define SQLITE_WindowFunc 0x0002 /* Use xInverse for window functions */ -#define SQLITE_GroupByOrder 0x0004 /* GROUPBY cover of ORDERBY */ -#define SQLITE_FactorOutConst 0x0008 /* Constant factoring */ -#define SQLITE_DistinctOpt 0x0010 /* DISTINCT using indexes */ -#define SQLITE_CoverIdxScan 0x0020 /* Covering index scans */ -#define SQLITE_OrderByIdxJoin 0x0040 /* ORDER BY of joins via index */ -#define SQLITE_Transitive 0x0080 /* Transitive constraints */ -#define SQLITE_OmitNoopJoin 0x0100 /* Omit unused tables in joins */ -#define SQLITE_CountOfView 0x0200 /* The count-of-view optimization */ -#define SQLITE_CursorHints 0x0400 /* Add OP_CursorHint opcodes */ -#define SQLITE_Stat4 0x0800 /* Use STAT4 data */ - /* TH3 expects the Stat4 ^^^^^^ value to be 0x0800. Don't change it */ -#define SQLITE_PushDown 0x1000 /* The push-down optimization */ -#define SQLITE_SimplifyJoin 0x2000 /* Convert LEFT JOIN to JOIN */ -#define SQLITE_SkipScan 0x4000 /* Skip-scans */ -#define SQLITE_PropagateConst 0x8000 /* The constant propagation opt */ -#define SQLITE_AllOpts 0xffff /* All optimizations */ +#define SQLITE_QueryFlattener 0x00000001 /* Query flattening */ +#define SQLITE_WindowFunc 0x00000002 /* Use xInverse for window functions */ +#define SQLITE_GroupByOrder 0x00000004 /* GROUPBY cover of ORDERBY */ +#define SQLITE_FactorOutConst 0x00000008 /* Constant factoring */ +#define SQLITE_DistinctOpt 0x00000010 /* DISTINCT using indexes */ +#define SQLITE_CoverIdxScan 0x00000020 /* Covering index scans */ +#define SQLITE_OrderByIdxJoin 0x00000040 /* ORDER BY of joins via index */ +#define SQLITE_Transitive 0x00000080 /* Transitive constraints */ +#define SQLITE_OmitNoopJoin 0x00000100 /* Omit unused tables in joins */ +#define SQLITE_CountOfView 0x00000200 /* The count-of-view optimization */ +#define SQLITE_CursorHints 0x00000400 /* Add OP_CursorHint opcodes */ +#define SQLITE_Stat4 0x00000800 /* Use STAT4 data */ + /* TH3 expects this value ^^^^^^^^^^ to be 0x0000800. Don't change it */ +#define SQLITE_PushDown 0x00001000 /* The push-down optimization */ +#define SQLITE_SimplifyJoin 0x00002000 /* Convert LEFT JOIN to JOIN */ +#define SQLITE_SkipScan 0x00004000 /* Skip-scans */ +#define SQLITE_PropagateConst 0x00008000 /* The constant propagation opt */ +#define SQLITE_MinMaxOpt 0x00010000 /* The min/max optimization */ +#define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* ** Macros for testing whether or not optimizations are enabled or disabled. From 5e5683ae466667c61aa4cd5127850f080508eab9 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 13 Jan 2021 21:05:07 +0000 Subject: [PATCH 114/257] Fix a harmless compiler warning. FossilOrigin-Name: 83ec01e38cbd22147ba544e15eae32c72e0523a55b54851e483dc2effc64f206 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/prepare.c | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 761cd8ddc4..f632558422 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Expand\sthe\snumber\sof\soptimization-disable\sbits\sfrom\s16\sto\s32.\s\sUse\sone\sof\nthe\snew\sbits\sto\sdisable\sthe\smin/max\soptimization,\sso\sthat\swe\scan\smore\seasily\nverify\sthat\swe\sget\sthe\ssame\sanswer\sboth\swith\sand\swithin\sthat\soptimization. -D 2021-01-13T19:28:17.446 +C Fix\sa\sharmless\scompiler\swarning. +D 2021-01-13T21:05:07.314 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -535,7 +535,7 @@ F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a F src/pragma.c 6daaaecc26a4b09481d21722525b079ce756751a43a79cc1d8f122d686806193 F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf -F src/prepare.c cfe5a0ec9fd612c89b4d50acfd4b796bd5fe850441cab0d866d72fa3aa982c45 +F src/prepare.c f288cbc35f79eb32e162de7e80a63ebe00d80e639dcfac071bee11570cbdb16f F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c @@ -1895,7 +1895,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 188772a1dbaf066fbddd39c718fdd87478b19a920622f4640bcb79d4ef065331 -R fee2bff3fc3f4ab0866b8b2d20b15a63 +P fd0c9a123b58b7b134ed67f26dbb4196b61e56227f078422cc7e9a3497054c2d +R 066b14d85f5f9812b58b6c0444ced87b U drh -Z b04c23448445719d4a662625f97c5411 +Z 1cdf44f5345d423ffb8022710ae292a6 diff --git a/manifest.uuid b/manifest.uuid index 834b730385..72d1bbda5b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fd0c9a123b58b7b134ed67f26dbb4196b61e56227f078422cc7e9a3497054c2d \ No newline at end of file +83ec01e38cbd22147ba544e15eae32c72e0523a55b54851e483dc2effc64f206 \ No newline at end of file diff --git a/src/prepare.c b/src/prepare.c index f93a6f07ad..87c1ab9368 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -571,10 +571,10 @@ void sqlite3ParserReset(Parse *pParse){ pThis = pNext; } while( pParse->pCleanup ){ - ParseCleanup *pThis = pParse->pCleanup; - pParse->pCleanup = pThis->pNext; - pThis->xCleanup(db, pThis->pPtr); - sqlite3DbFree(db, pThis); + ParseCleanup *pCleanup = pParse->pCleanup; + pParse->pCleanup = pCleanup->pNext; + pCleanup->xCleanup(db, pCleanup->pPtr); + sqlite3DbFree(db, pCleanup); } sqlite3DbFree(db, pParse->aLabel); if( pParse->pConstExpr ){ From 5870dc80f906c5e841d330db095ec2dae6db4ce9 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 14 Jan 2021 00:53:14 +0000 Subject: [PATCH 115/257] The early-out of the inner loop on the min/max optimization was overly aggressive for the cases where there is a join and outer loops contain IN operators. Fix this. Test case in TH3. FossilOrigin-Name: ccd3bae14b6b47bb0f9622700c04db989f76ce65e10e0709964cfd0675eca762 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 13 ++++++++----- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index f632558422..a0e67a5b46 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sharmless\scompiler\swarning. -D 2021-01-13T21:05:07.314 +C The\searly-out\sof\sthe\sinner\sloop\son\sthe\smin/max\soptimization\swas\soverly\naggressive\sfor\sthe\scases\swhere\sthere\sis\sa\sjoin\sand\souter\sloops\scontain\nIN\soperators.\s\sFix\sthis.\s\sTest\scase\sin\sTH3. +D 2021-01-14T00:53:14.879 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -627,7 +627,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 69e770e96fd56cc21608992bf2c6f1f3dc5cf2572d0495c6a643b06c3a679f14 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c d9c4e454ebb9499e908aa62d55b8994c375cf5355ac78f60d45af17f7890701c -F src/where.c dee929890fe399993d4e78a5a89d4b289f7ab015446e157d2e4c25477fdfa060 +F src/where.c 0e6abb22a2323fec80b450825593c26a2ad8f4815d1ee3af9969d8f6144bf681 F src/whereInt.h 9a3f577619f07700d16d89eeb2f3d94d6b7ed7f109c2dacf0ce8844921549506 F src/wherecode.c a3a1aff30fe99a818d8e7c607980f033f40c68d890e03ed25838b9dbb7908bee F src/whereexpr.c 3a463e156ea388083c501502229c2c7f4f5c6b5330ea59bdf40d6eb6e155a25f @@ -1895,7 +1895,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 fd0c9a123b58b7b134ed67f26dbb4196b61e56227f078422cc7e9a3497054c2d -R 066b14d85f5f9812b58b6c0444ced87b +P 83ec01e38cbd22147ba544e15eae32c72e0523a55b54851e483dc2effc64f206 +R 3dc0d948d76c5e90d01be3a954f85921 U drh -Z 1cdf44f5345d423ffb8022710ae292a6 +Z 4b60af58a6a03c91f6ab835dbd142db0 diff --git a/manifest.uuid b/manifest.uuid index 72d1bbda5b..7f27c3343a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -83ec01e38cbd22147ba544e15eae32c72e0523a55b54851e483dc2effc64f206 \ No newline at end of file +ccd3bae14b6b47bb0f9622700c04db989f76ce65e10e0709964cfd0675eca762 \ No newline at end of file diff --git a/src/where.c b/src/where.c index adc688b4ba..8128c2ed0b 100644 --- a/src/where.c +++ b/src/where.c @@ -112,14 +112,17 @@ int sqlite3WhereOrderByLimitOptLabel(WhereInfo *pWInfo){ */ void sqlite3WhereMinMaxOptEarlyOut(Vdbe *v, WhereInfo *pWInfo){ WhereLevel *pInner; + int i; if( !pWInfo->bOrderedInnerLoop ) return; if( pWInfo->nOBSat==0 ) return; - pInner = &pWInfo->a[pWInfo->nLevel-1]; - if( (pInner->pWLoop->wsFlags & WHERE_COLUMN_IN)==0 ){ - sqlite3VdbeGoto(v, pWInfo->iBreak); - }else if( pInner->addrNxt!=pWInfo->iContinue ){ - sqlite3VdbeGoto(v, pInner->addrNxt); + for(i=pWInfo->nLevel-1; i>=0; i--){ + pInner = &pWInfo->a[i]; + if( (pInner->pWLoop->wsFlags & WHERE_COLUMN_IN)!=0 ){ + sqlite3VdbeGoto(v, pInner->addrNxt); + return; + } } + sqlite3VdbeGoto(v, pWInfo->iBreak); } /* From 6bfc167a67586d465ed995ae6dd3216967fc83c6 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 14 Jan 2021 20:50:40 +0000 Subject: [PATCH 116/257] Allow the planner to convert an EXISTS(SELECT...) expression in a WHERE clause to the equivalent IN(...) expression in situations where this is possible and advantageous. FossilOrigin-Name: 9f90a88221d0694951c353e58efce342eb0b868b8ca6a4469c8205e5c7855b24 --- manifest | 17 ++-- manifest.uuid | 2 +- src/whereexpr.c | 200 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 211 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index b050b37ce0..a99b42e9cc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C cli:\sOmit\ssurplus\swhitespace\sat\sthe\send\sof\slines\sin\s.explain\soutput. -D 2021-01-13T12:59:20.834 +C Allow\sthe\splanner\sto\sconvert\san\sEXISTS(SELECT...)\sexpression\sin\sa\sWHERE\sclause\sto\sthe\sequivalent\sIN(...)\sexpression\sin\ssituations\swhere\sthis\sis\spossible\sand\sadvantageous. +D 2021-01-14T20:50:40.571 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -630,7 +630,7 @@ F src/walker.c d9c4e454ebb9499e908aa62d55b8994c375cf5355ac78f60d45af17f7890701c F src/where.c 3d31871d03906312d7d71a9c0b28c97bcbaead7606dfc15f9b3d080b18702385 F src/whereInt.h 9a3f577619f07700d16d89eeb2f3d94d6b7ed7f109c2dacf0ce8844921549506 F src/wherecode.c a3a1aff30fe99a818d8e7c607980f033f40c68d890e03ed25838b9dbb7908bee -F src/whereexpr.c 3a463e156ea388083c501502229c2c7f4f5c6b5330ea59bdf40d6eb6e155a25f +F src/whereexpr.c e48e3edea45b4afabbf6f6ece9647734c828a20c49a8cc780ff4d69b42f55fa4 F src/window.c edd6f5e25a1e8f2b6f5305b7f5f7da7bb35f07f0d432b255b1d4c2fcab4205aa F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -1895,7 +1895,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 db0ecfe66433f8915b6eb16d3735a4a0d0f8e0bbc395bc9c1364387506fc4657 -R 2ad612629a79dbad03e8b7f173945d59 -U drh -Z f407a95e341e109313c0922f7d2a229b +P 11e4eb095746602961a178044809a68a77ba7b367596997bef726e54062423d9 +R 1a9ea60bc9bb7dab69ccea9e0b8c40d8 +T *branch * exists-to-in +T *sym-exists-to-in * +T -sym-trunk * +U dan +Z d4d95c9878f460cd53a2ce8ada6afd2a diff --git a/manifest.uuid b/manifest.uuid index ccaf3daab6..e8520659ef 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -11e4eb095746602961a178044809a68a77ba7b367596997bef726e54062423d9 \ No newline at end of file +9f90a88221d0694951c353e58efce342eb0b868b8ca6a4469c8205e5c7855b24 \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index a77eb36106..9326a57fcb 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1007,6 +1007,202 @@ static int exprMightBeIndexed( return exprMightBeIndexed2(pFrom,mPrereq,aiCurCol,pExpr); } +/* +** Expression callback for exprUsesSrclist(). +*/ +static int exprUsesSrclistCb(Walker *p, Expr *pExpr){ + if( pExpr->op==TK_COLUMN ){ + SrcList *pSrc = p->u.pSrcList; + int iCsr = pExpr->iTable; + int ii; + for(ii=0; iinSrc; ii++){ + if( pSrc->a[ii].iCursor==iCsr ){ + return p->eCode ? WRC_Abort : WRC_Continue; + } + } + return p->eCode ? WRC_Continue : WRC_Abort; + } + return WRC_Continue; +} + +/* +** Select callback for exprUsesSrclist(). +*/ +static int exprUsesSrclistSelectCb(Walker *p, Select *pSelect){ + return WRC_Abort; +} + +/* +** This function always returns true if expression pExpr contains +** a sub-select. +** +** If there is no sub-select and bUses is 1, then true is returned +** if the expression contains at least one TK_COLUMN node that refers +** to a table in pSrc. +** +** Or, if there is no sub-select and bUses is 0, then true is returned +** if the expression contains at least one TK_COLUMN node that refers +** to a table that is not in pSrc. +*/ +static int exprUsesSrclist(SrcList *pSrc, Expr *pExpr, int bUses){ + Walker sWalker; + memset(&sWalker, 0, sizeof(Walker)); + sWalker.eCode = bUses; + sWalker.u.pSrcList = pSrc; + sWalker.xExprCallback = exprUsesSrclistCb; + sWalker.xSelectCallback = exprUsesSrclistSelectCb; + return (sqlite3WalkExpr(&sWalker, pExpr)==WRC_Abort); +} + +struct ExistsToInCtx { + SrcList *pSrc; + Expr *pInLhs; + Expr *pEq; + Expr **ppAnd; + Expr **ppParent; +}; + +static int exprExistsToInIter( + struct ExistsToInCtx *p, + Expr *pExpr, + Expr **ppExpr +){ + assert( ppExpr==0 || *ppExpr==pExpr ); + switch( pExpr->op ){ + case TK_AND: + p->ppParent = ppExpr; + if( exprExistsToInIter(p, pExpr->pLeft, &pExpr->pLeft) ) return 1; + p->ppParent = ppExpr; + if( exprExistsToInIter(p, pExpr->pRight, &pExpr->pRight) ) return 1; + break; + case TK_EQ: { + int bLeft = exprUsesSrclist(p->pSrc, pExpr->pLeft, 0); + int bRight = exprUsesSrclist(p->pSrc, pExpr->pRight, 0); + if( bLeft || bRight ){ + if( (bLeft && bRight) || p->pInLhs ) return 1; + p->pInLhs = bLeft ? pExpr->pLeft : pExpr->pRight; + p->pEq = pExpr; + p->ppAnd = p->ppParent; + if( exprUsesSrclist(p->pSrc, p->pInLhs, 1) ) return 1; + } + break; + } + default: + if( exprUsesSrclist(p->pSrc, pExpr, 0) ){ + return 1; + } + break; + } + + return 0; +} + +static Expr *exprAnalyzeExistsFindEq( + SrcList *pSrc, + Expr *pWhere, /* WHERE clause to traverse */ + Expr **ppEq, /* OUT: == node from WHERE clause */ + Expr ***pppAnd /* OUT: Pointer to parent of ==, if any */ +){ + struct ExistsToInCtx ctx; + memset(&ctx, 0, sizeof(ctx)); + ctx.pSrc = pSrc; + if( exprExistsToInIter(&ctx, pWhere, 0) ){ + return 0; + } + if( ppEq ) *ppEq = ctx.pEq; + if( pppAnd ) *pppAnd = ctx.ppAnd; + return ctx.pInLhs; +} + +/* +** Term idxTerm of the WHERE clause passed as the second argument is an +** EXISTS expression with a correlated SELECT statement on the RHS. +** This function analyzes the SELECT statement, and if possible adds an +** equivalent "? IN(SELECT...)" virtual term to the WHERE clause. +** +** For an EXISTS term such as the following: +** +** EXISTS (SELECT ... FROM WHERE = AND ) +** +** The virtual IN() term added is: +** +** IN (SELECT FROM WHERE ) +** +** The virtual term is only added if the following conditions are met: +** +** 1. The sub-select must not be an aggregate or use window functions, +** +** 2. The sub-select must not be a compound SELECT, +** +** 3. Expression must refer to at least one column from the outer +** query, and must not refer to any column from the inner query +** (i.e. from ). +** +** 4. and must not refer to any values from the outer query. +** In other words, once has been removed, the inner query +** must not be correlated. +** +*/ +static void exprAnalyzeExists( + SrcList *pSrc, /* the FROM clause */ + WhereClause *pWC, /* the WHERE clause */ + int idxTerm /* Index of the term to be analyzed */ +){ + Parse *pParse = pWC->pWInfo->pParse; + WhereTerm *pTerm = &pWC->a[idxTerm]; + Expr *pExpr = pTerm->pExpr; + Select *pSel = pExpr->x.pSelect; + Expr *pDup = 0; + Expr *pEq = 0; + Expr *pRet = 0; + Expr *pInLhs = 0; + Expr **ppAnd = 0; + int idxNew; + + assert( pExpr->op==TK_EXISTS ); + assert( (pExpr->flags & EP_VarSelect) && (pExpr->flags & EP_xIsSelect) ); + + if( (pSel->selFlags & SF_Aggregate) || pSel->pWin ) return; + if( pSel->pPrior ) return; + if( pSel->pWhere==0 ) return; + if( 0==exprAnalyzeExistsFindEq(pSel->pSrc, pSel->pWhere, 0, 0) ) return; + + pDup = sqlite3ExprDup(pParse->db, pExpr, 0); + if( pDup==0 ) return; + pSel = pDup->x.pSelect; + sqlite3ExprListDelete(pParse->db, pSel->pEList); + pSel->pEList = 0; + + pInLhs = exprAnalyzeExistsFindEq(pSel->pSrc, pSel->pWhere, &pEq, &ppAnd); + + assert( pDup->pLeft==0 ); + pDup->op = TK_IN; + pDup->pLeft = pInLhs; + pDup->flags &= ~EP_VarSelect; + pRet = (pInLhs==pEq->pLeft) ? pEq->pRight : pEq->pLeft; + pSel->pEList = sqlite3ExprListAppend(pParse, 0, pRet); + pEq->pLeft = 0; + pEq->pRight = 0; + if( ppAnd ){ + Expr *pAnd = *ppAnd; + Expr *pOther = (pAnd->pLeft==pEq) ? pAnd->pRight : pAnd->pLeft; + pAnd->pLeft = pAnd->pRight = 0; + sqlite3ExprDelete(pParse->db, pAnd); + *ppAnd = pOther; + }else{ + assert( pSel->pWhere==pEq ); + pSel->pWhere = 0; + } + sqlite3ExprDelete(pParse->db, pEq); + + idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC); + if( idxNew ){ + exprAnalyze(pSrc, pWC, idxNew); + markTermAsChild(pWC, idxNew, idxTerm); + pWC->a[idxTerm].wtFlags |= TERM_COPIED; + } +} + /* ** The input to this routine is an WhereTerm structure with only the ** "pExpr" field filled in. The job of this routine is to analyze the @@ -1418,6 +1614,10 @@ static void exprAnalyze( } #endif /* SQLITE_ENABLE_STAT4 */ + if( pExpr->op==TK_EXISTS && (pExpr->flags & EP_VarSelect) ){ + exprAnalyzeExists(pSrc, pWC, idxTerm); + } + /* Prevent ON clause terms of a LEFT JOIN from being used to drive ** an index for tables to the left of the join. */ From 76cac6ef0663c097c9ba5195556963567cece3b5 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 15 Jan 2021 11:39:46 +0000 Subject: [PATCH 117/257] Add simple tests (and a fix) for the change on this branch. FossilOrigin-Name: 897f3f40267dc922f0fda287484435e1fd8709bade3e87c3829e2f945bb5e4aa --- manifest | 16 ++++----- manifest.uuid | 2 +- src/whereexpr.c | 27 +++++++-------- test/exists2.test | 87 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 107 insertions(+), 25 deletions(-) create mode 100644 test/exists2.test diff --git a/manifest b/manifest index a99b42e9cc..93a625e98a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sthe\splanner\sto\sconvert\san\sEXISTS(SELECT...)\sexpression\sin\sa\sWHERE\sclause\sto\sthe\sequivalent\sIN(...)\sexpression\sin\ssituations\swhere\sthis\sis\spossible\sand\sadvantageous. -D 2021-01-14T20:50:40.571 +C Add\ssimple\stests\s(and\sa\sfix)\sfor\sthe\schange\son\sthis\sbranch. +D 2021-01-15T11:39:46.131 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -630,7 +630,7 @@ F src/walker.c d9c4e454ebb9499e908aa62d55b8994c375cf5355ac78f60d45af17f7890701c F src/where.c 3d31871d03906312d7d71a9c0b28c97bcbaead7606dfc15f9b3d080b18702385 F src/whereInt.h 9a3f577619f07700d16d89eeb2f3d94d6b7ed7f109c2dacf0ce8844921549506 F src/wherecode.c a3a1aff30fe99a818d8e7c607980f033f40c68d890e03ed25838b9dbb7908bee -F src/whereexpr.c e48e3edea45b4afabbf6f6ece9647734c828a20c49a8cc780ff4d69b42f55fa4 +F src/whereexpr.c 1f4fac8ea8eac6facb9e80107c659094a56a8ad0b35108717ac99ea57bbc71bc F src/window.c edd6f5e25a1e8f2b6f5305b7f5f7da7bb35f07f0d432b255b1d4c2fcab4205aa F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -874,6 +874,7 @@ F test/exclusive.test 7ff63be7503990921838d5c9f77f6e33e68e48ed1a9d48cd28745bf650 F test/exclusive2.test 984090e8e9d1b331d2e8111daf6e5d61dda0bef7 F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7 F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac +F test/exists2.test 44e18a6aaadefa8e1c68a8453fb22a57a0270a673d9b256790d142ea257459e3 F test/expr.test 26cd01e8485bc48c8aa6a1add598e9ce1e706b4eb4f3f554e0b0223022e8c2cf F test/expr2.test c27327ae9c017a7ff6280123f67aff496f912da74d78c888926d68b46ec75fd8 F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9 @@ -1895,10 +1896,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 11e4eb095746602961a178044809a68a77ba7b367596997bef726e54062423d9 -R 1a9ea60bc9bb7dab69ccea9e0b8c40d8 -T *branch * exists-to-in -T *sym-exists-to-in * -T -sym-trunk * +P 9f90a88221d0694951c353e58efce342eb0b868b8ca6a4469c8205e5c7855b24 +R 9984162db1d3035db01dde79c4fce484 U dan -Z d4d95c9878f460cd53a2ce8ada6afd2a +Z 278fef5940bb689562d7ebf0ab17cbb2 diff --git a/manifest.uuid b/manifest.uuid index e8520659ef..ace34aaabc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9f90a88221d0694951c353e58efce342eb0b868b8ca6a4469c8205e5c7855b24 \ No newline at end of file +897f3f40267dc922f0fda287484435e1fd8709bade3e87c3829e2f945bb5e4aa \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index 9326a57fcb..e5e566bbfe 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1062,18 +1062,14 @@ struct ExistsToInCtx { Expr **ppParent; }; -static int exprExistsToInIter( - struct ExistsToInCtx *p, - Expr *pExpr, - Expr **ppExpr -){ - assert( ppExpr==0 || *ppExpr==pExpr ); +static int exprExistsToInIter(struct ExistsToInCtx *p, Expr **ppExpr){ + Expr *pExpr = *ppExpr; switch( pExpr->op ){ case TK_AND: p->ppParent = ppExpr; - if( exprExistsToInIter(p, pExpr->pLeft, &pExpr->pLeft) ) return 1; + if( exprExistsToInIter(p, &pExpr->pLeft) ) return 1; p->ppParent = ppExpr; - if( exprExistsToInIter(p, pExpr->pRight, &pExpr->pRight) ) return 1; + if( exprExistsToInIter(p, &pExpr->pRight) ) return 1; break; case TK_EQ: { int bLeft = exprUsesSrclist(p->pSrc, pExpr->pLeft, 0); @@ -1081,9 +1077,9 @@ static int exprExistsToInIter( if( bLeft || bRight ){ if( (bLeft && bRight) || p->pInLhs ) return 1; p->pInLhs = bLeft ? pExpr->pLeft : pExpr->pRight; + if( exprUsesSrclist(p->pSrc, p->pInLhs, 1) ) return 1; p->pEq = pExpr; p->ppAnd = p->ppParent; - if( exprUsesSrclist(p->pSrc, p->pInLhs, 1) ) return 1; } break; } @@ -1098,15 +1094,14 @@ static int exprExistsToInIter( } static Expr *exprAnalyzeExistsFindEq( - SrcList *pSrc, - Expr *pWhere, /* WHERE clause to traverse */ + Select *pSel, Expr **ppEq, /* OUT: == node from WHERE clause */ Expr ***pppAnd /* OUT: Pointer to parent of ==, if any */ ){ struct ExistsToInCtx ctx; memset(&ctx, 0, sizeof(ctx)); - ctx.pSrc = pSrc; - if( exprExistsToInIter(&ctx, pWhere, 0) ){ + ctx.pSrc = pSel->pSrc; + if( exprExistsToInIter(&ctx, &pSel->pWhere) ){ return 0; } if( ppEq ) *ppEq = ctx.pEq; @@ -1165,7 +1160,7 @@ static void exprAnalyzeExists( if( (pSel->selFlags & SF_Aggregate) || pSel->pWin ) return; if( pSel->pPrior ) return; if( pSel->pWhere==0 ) return; - if( 0==exprAnalyzeExistsFindEq(pSel->pSrc, pSel->pWhere, 0, 0) ) return; + if( 0==exprAnalyzeExistsFindEq(pSel, 0, 0) ) return; pDup = sqlite3ExprDup(pParse->db, pExpr, 0); if( pDup==0 ) return; @@ -1173,7 +1168,9 @@ static void exprAnalyzeExists( sqlite3ExprListDelete(pParse->db, pSel->pEList); pSel->pEList = 0; - pInLhs = exprAnalyzeExistsFindEq(pSel->pSrc, pSel->pWhere, &pEq, &ppAnd); + pInLhs = exprAnalyzeExistsFindEq(pSel, &pEq, &ppAnd); + assert( pInLhs && pEq ); + assert( pEq==pSel->pWhere || ppAnd ); assert( pDup->pLeft==0 ); pDup->op = TK_IN; diff --git a/test/exists2.test b/test/exists2.test new file mode 100644 index 0000000000..55369f8f2f --- /dev/null +++ b/test/exists2.test @@ -0,0 +1,87 @@ +# 2021 January 15 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this file is testing cases where EXISTS expressions are +# transformed to IN() expressions by where.c +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix exists2 + +do_execsql_test 1.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); + INSERT INTO t1 VALUES(1, 'one'); + INSERT INTO t1 VALUES(2, 'two'); + INSERT INTO t1 VALUES(3, 'three'); + INSERT INTO t1 VALUES(4, 'four'); + INSERT INTO t1 VALUES(5, 'five'); + INSERT INTO t1 VALUES(6, 'six'); + INSERT INTO t1 VALUES(7, 'seven'); + + CREATE TABLE t2(c INTEGER, d INTEGER); + INSERT INTO t2 VALUES(1, 1); + INSERT INTO t2 VALUES(3, 2); + INSERT INTO t2 VALUES(5, 3); + INSERT INTO t2 VALUES(7, 4); +} + +proc do_execsql_eqp_test {tn sql eqp res} { + uplevel [list do_eqp_test $tn.1 $sql [string trim $eqp]] + uplevel [list do_execsql_test $tn.2 $sql $res] +} + +do_execsql_eqp_test 1.1 { + SELECT t1.* FROM t1 WHERE EXISTS(SELECT * FROM t2 WHERE t1.a=t2.c); +} { + USING INTEGER PRIMARY KEY +} { + 1 one 3 three 5 five 7 seven +} + +do_execsql_eqp_test 1.2 { + SELECT t1.* FROM t1 WHERE EXISTS(SELECT * FROM t2 WHERE t2.c=t1.a); +} { + SEARCH TABLE t1 USING INTEGER PRIMARY KEY +} { + 1 one 3 three 5 five 7 seven +} + +do_execsql_eqp_test 1.3 { + SELECT t1.* FROM t1 WHERE EXISTS(SELECT * FROM t2 WHERE t2.c+1=t1.a); +} { + SEARCH TABLE t1 USING INTEGER PRIMARY KEY +} { + 2 two 4 four 6 six +} + +do_execsql_eqp_test 1.4 { + SELECT t1.* FROM t1 WHERE EXISTS(SELECT * FROM t2 WHERE t2.c+1=t1.a+1); +} { + SCAN TABLE t1 +} { + 1 one 3 three 5 five 7 seven +} + +breakpoint +do_execsql_eqp_test 1.5 { + SELECT t1.* FROM t1 WHERE EXISTS( + SELECT * FROM t2 WHERE t1.a=t2.c AND d IN (1, 2, 3) + ); +} { + SEARCH TABLE t1 USING INTEGER PRIMARY KEY +} { + 1 one 3 three 5 five +} + + + +finish_test From 10c9ef65fa7d453bfd8b1d82f434f29938d39342 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 15 Jan 2021 14:25:06 +0000 Subject: [PATCH 118/257] Small performance improvement in the EXISTS-to-IN translator for the common case where the EXISTS operator is not found in the WHERE clause. FossilOrigin-Name: dcb7772d7695ddbc0fe89e06c07ff4a6ae4fa05de914e2ec10b5cc07a62ed49f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/whereexpr.c | 12 ++++++++---- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index afcc0dca9c..c7f52277ae 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\slatest\strunk\senhancements\sinto\sthe\sexists-to-in\sbranch. -D 2021-01-15T14:15:31.281 +C Small\sperformance\simprovement\sin\sthe\sEXISTS-to-IN\stranslator\sfor\sthe\ncommon\scase\swhere\sthe\sEXISTS\soperator\sis\snot\sfound\sin\sthe\sWHERE\sclause. +D 2021-01-15T14:25:06.079 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -630,7 +630,7 @@ F src/walker.c d9c4e454ebb9499e908aa62d55b8994c375cf5355ac78f60d45af17f7890701c F src/where.c 0e6abb22a2323fec80b450825593c26a2ad8f4815d1ee3af9969d8f6144bf681 F src/whereInt.h 9a3f577619f07700d16d89eeb2f3d94d6b7ed7f109c2dacf0ce8844921549506 F src/wherecode.c a3a1aff30fe99a818d8e7c607980f033f40c68d890e03ed25838b9dbb7908bee -F src/whereexpr.c 1f4fac8ea8eac6facb9e80107c659094a56a8ad0b35108717ac99ea57bbc71bc +F src/whereexpr.c 0ba5c743ee34255658051179441a13297dc2d6b21ef3c41120659ae3dd896ae8 F src/window.c edd6f5e25a1e8f2b6f5305b7f5f7da7bb35f07f0d432b255b1d4c2fcab4205aa F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -1896,7 +1896,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 897f3f40267dc922f0fda287484435e1fd8709bade3e87c3829e2f945bb5e4aa 249a71cc6822d6bdd5bb9e727aac81c6549693b418e9c0987b96850ee332c940 -R 6fb3b1c5ffde39ec234334a7c5ffcb56 +P 13c4c9088cc8a2426e30a2ad1e9b9969407249281c6ed16653d43a0e6852a2e4 +R c79f76fc898939a9f2cc931eb9a2c482 U drh -Z 90ae5651a54d924d6159985985e1584c +Z e1fe560394403461c8187fdaaf345432 diff --git a/manifest.uuid b/manifest.uuid index 88f1bf8bca..13001fa395 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -13c4c9088cc8a2426e30a2ad1e9b9969407249281c6ed16653d43a0e6852a2e4 \ No newline at end of file +dcb7772d7695ddbc0fe89e06c07ff4a6ae4fa05de914e2ec10b5cc07a62ed49f \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index e5e566bbfe..e360001931 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1385,6 +1385,14 @@ static void exprAnalyze( } #endif /* SQLITE_OMIT_OR_OPTIMIZATION */ + else if( pExpr->op==TK_EXISTS ){ + /* Perhaps treat an EXISTS operator as an IN operator */ + if( (pExpr->flags & EP_VarSelect)!=0 ){ + exprAnalyzeExists(pSrc, pWC, idxTerm); + } + } + + #ifndef SQLITE_OMIT_LIKE_OPTIMIZATION /* Add constraints to reduce the search space on a LIKE or GLOB ** operator. @@ -1611,10 +1619,6 @@ static void exprAnalyze( } #endif /* SQLITE_ENABLE_STAT4 */ - if( pExpr->op==TK_EXISTS && (pExpr->flags & EP_VarSelect) ){ - exprAnalyzeExists(pSrc, pWC, idxTerm); - } - /* Prevent ON clause terms of a LEFT JOIN from being used to drive ** an index for tables to the left of the join. */ From 19ef211d85972c998ce8baa834efe0797f1ab492 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 15 Jan 2021 15:17:14 +0000 Subject: [PATCH 119/257] Add a new optimizer disabling bit to close off the exists-to-in optimization, for testing purposes. FossilOrigin-Name: a80c9a076d31729282004ca372913c9fdbfb6e74711fbb8c5dc12ee0ecba2b87 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqliteInt.h | 1 + src/whereexpr.c | 4 +++- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index c7f52277ae..0e289c8966 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\sperformance\simprovement\sin\sthe\sEXISTS-to-IN\stranslator\sfor\sthe\ncommon\scase\swhere\sthe\sEXISTS\soperator\sis\snot\sfound\sin\sthe\sWHERE\sclause. -D 2021-01-15T14:25:06.079 +C Add\sa\snew\soptimizer\sdisabling\sbit\sto\sclose\soff\sthe\sexists-to-in\soptimization,\nfor\stesting\spurposes. +D 2021-01-15T15:17:14.152 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -545,7 +545,7 @@ F src/shell.c.in 9ebc74e4f05cfbd0f4a36060fdaeff1da4e9af4458358722bc08c5a1ab9a087 F src/sqlite.h.in 0af968a1fa3c717261e1df0ed105fa7bddb4d82de7e0adb3eab49e6aa81b4de7 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h 6aad58a5ae1374e18ea53d0c3ea71f047b67313426767783bd7fa14ee786725a +F src/sqliteInt.h d921214bba203960de10ea7a9183735ec362a5def5910d468282a8f82e8b4c26 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -630,7 +630,7 @@ F src/walker.c d9c4e454ebb9499e908aa62d55b8994c375cf5355ac78f60d45af17f7890701c F src/where.c 0e6abb22a2323fec80b450825593c26a2ad8f4815d1ee3af9969d8f6144bf681 F src/whereInt.h 9a3f577619f07700d16d89eeb2f3d94d6b7ed7f109c2dacf0ce8844921549506 F src/wherecode.c a3a1aff30fe99a818d8e7c607980f033f40c68d890e03ed25838b9dbb7908bee -F src/whereexpr.c 0ba5c743ee34255658051179441a13297dc2d6b21ef3c41120659ae3dd896ae8 +F src/whereexpr.c 2d42217961cf8da8280779df88bcfb7cb3ee719369cafb44ac2b376fdecf9db7 F src/window.c edd6f5e25a1e8f2b6f5305b7f5f7da7bb35f07f0d432b255b1d4c2fcab4205aa F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -1896,7 +1896,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 13c4c9088cc8a2426e30a2ad1e9b9969407249281c6ed16653d43a0e6852a2e4 -R c79f76fc898939a9f2cc931eb9a2c482 +P dcb7772d7695ddbc0fe89e06c07ff4a6ae4fa05de914e2ec10b5cc07a62ed49f +R 6fb63e2f60db07c2af9d4dfa7cc52f88 U drh -Z e1fe560394403461c8187fdaaf345432 +Z 5ba57a27c0ec24c2bc90f07584644072 diff --git a/manifest.uuid b/manifest.uuid index 13001fa395..1f56d238fa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dcb7772d7695ddbc0fe89e06c07ff4a6ae4fa05de914e2ec10b5cc07a62ed49f \ No newline at end of file +a80c9a076d31729282004ca372913c9fdbfb6e74711fbb8c5dc12ee0ecba2b87 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 0581e907da..e1e0707bf3 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1721,6 +1721,7 @@ struct sqlite3 { #define SQLITE_SkipScan 0x00004000 /* Skip-scans */ #define SQLITE_PropagateConst 0x00008000 /* The constant propagation opt */ #define SQLITE_MinMaxOpt 0x00010000 /* The min/max optimization */ +#define SQLITE_ExistsToIN 0x00020000 /* The EXISTS-to-IN optimization */ #define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* diff --git a/src/whereexpr.c b/src/whereexpr.c index e360001931..4de5af1730 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1387,7 +1387,9 @@ static void exprAnalyze( else if( pExpr->op==TK_EXISTS ){ /* Perhaps treat an EXISTS operator as an IN operator */ - if( (pExpr->flags & EP_VarSelect)!=0 ){ + if( (pExpr->flags & EP_VarSelect)!=0 + && OptimizationEnabled(db, SQLITE_ExistsToIN) + ){ exprAnalyzeExists(pSrc, pWC, idxTerm); } } From 9d326d67937b23217718cc64e67d214351691a2a Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 15 Jan 2021 15:21:27 +0000 Subject: [PATCH 120/257] Fix a potential NULL pointer dereference following OOM. FossilOrigin-Name: 8ce3cb90965771530c0021173d98720fc4c76bb99e69f7a879f80471dea0aace --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/whereexpr.c | 14 +++++++++----- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 0e289c8966..235abe4634 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\snew\soptimizer\sdisabling\sbit\sto\sclose\soff\sthe\sexists-to-in\soptimization,\nfor\stesting\spurposes. -D 2021-01-15T15:17:14.152 +C Fix\sa\spotential\sNULL\spointer\sdereference\sfollowing\sOOM. +D 2021-01-15T15:21:27.437 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -630,7 +630,7 @@ F src/walker.c d9c4e454ebb9499e908aa62d55b8994c375cf5355ac78f60d45af17f7890701c F src/where.c 0e6abb22a2323fec80b450825593c26a2ad8f4815d1ee3af9969d8f6144bf681 F src/whereInt.h 9a3f577619f07700d16d89eeb2f3d94d6b7ed7f109c2dacf0ce8844921549506 F src/wherecode.c a3a1aff30fe99a818d8e7c607980f033f40c68d890e03ed25838b9dbb7908bee -F src/whereexpr.c 2d42217961cf8da8280779df88bcfb7cb3ee719369cafb44ac2b376fdecf9db7 +F src/whereexpr.c 8ea4f6cd1332fdfbfbe832dc8a9f5194990684870931e7a07c2cafbc544588e7 F src/window.c edd6f5e25a1e8f2b6f5305b7f5f7da7bb35f07f0d432b255b1d4c2fcab4205aa F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -1896,7 +1896,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 dcb7772d7695ddbc0fe89e06c07ff4a6ae4fa05de914e2ec10b5cc07a62ed49f -R 6fb63e2f60db07c2af9d4dfa7cc52f88 +P a80c9a076d31729282004ca372913c9fdbfb6e74711fbb8c5dc12ee0ecba2b87 +R 31b39e7a643244cb65bba0cd39985e5a U drh -Z 5ba57a27c0ec24c2bc90f07584644072 +Z 96ac907b935dc11fb79e0a38f40aef27 diff --git a/manifest.uuid b/manifest.uuid index 1f56d238fa..b72b9116a2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a80c9a076d31729282004ca372913c9fdbfb6e74711fbb8c5dc12ee0ecba2b87 \ No newline at end of file +8ce3cb90965771530c0021173d98720fc4c76bb99e69f7a879f80471dea0aace \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index 4de5af1730..0359babc50 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1153,6 +1153,7 @@ static void exprAnalyzeExists( Expr *pInLhs = 0; Expr **ppAnd = 0; int idxNew; + sqlite3 *db = pParse->db; assert( pExpr->op==TK_EXISTS ); assert( (pExpr->flags & EP_VarSelect) && (pExpr->flags & EP_xIsSelect) ); @@ -1162,10 +1163,13 @@ static void exprAnalyzeExists( if( pSel->pWhere==0 ) return; if( 0==exprAnalyzeExistsFindEq(pSel, 0, 0) ) return; - pDup = sqlite3ExprDup(pParse->db, pExpr, 0); - if( pDup==0 ) return; + pDup = sqlite3ExprDup(db, pExpr, 0); + if( db->mallocFailed ){ + sqlite3ExprDelete(db, pDup); + return; + } pSel = pDup->x.pSelect; - sqlite3ExprListDelete(pParse->db, pSel->pEList); + sqlite3ExprListDelete(db, pSel->pEList); pSel->pEList = 0; pInLhs = exprAnalyzeExistsFindEq(pSel, &pEq, &ppAnd); @@ -1184,13 +1188,13 @@ static void exprAnalyzeExists( Expr *pAnd = *ppAnd; Expr *pOther = (pAnd->pLeft==pEq) ? pAnd->pRight : pAnd->pLeft; pAnd->pLeft = pAnd->pRight = 0; - sqlite3ExprDelete(pParse->db, pAnd); + sqlite3ExprDelete(db, pAnd); *ppAnd = pOther; }else{ assert( pSel->pWhere==pEq ); pSel->pWhere = 0; } - sqlite3ExprDelete(pParse->db, pEq); + sqlite3ExprDelete(db, pEq); idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC); if( idxNew ){ From e8f7fcf6f4a3655334251ad638db47bcdde37a9c Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 15 Jan 2021 15:32:09 +0000 Subject: [PATCH 121/257] Ensure the EXISTS->IN transformation preserves the collation sequence of the comparison operation. FossilOrigin-Name: a373baae12c914e48fd84de77998e301fdd3da43b06b9d64ac24a14418ed48cd --- manifest | 16 +++++----- manifest.uuid | 2 +- src/whereexpr.c | 8 ++++- test/exists2.test | 78 ++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 93 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 235abe4634..1523531c03 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\spotential\sNULL\spointer\sdereference\sfollowing\sOOM. -D 2021-01-15T15:21:27.437 +C Ensure\sthe\sEXISTS->IN\stransformation\spreserves\sthe\scollation\ssequence\sof\sthe\scomparison\soperation. +D 2021-01-15T15:32:09.587 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -630,7 +630,7 @@ F src/walker.c d9c4e454ebb9499e908aa62d55b8994c375cf5355ac78f60d45af17f7890701c F src/where.c 0e6abb22a2323fec80b450825593c26a2ad8f4815d1ee3af9969d8f6144bf681 F src/whereInt.h 9a3f577619f07700d16d89eeb2f3d94d6b7ed7f109c2dacf0ce8844921549506 F src/wherecode.c a3a1aff30fe99a818d8e7c607980f033f40c68d890e03ed25838b9dbb7908bee -F src/whereexpr.c 8ea4f6cd1332fdfbfbe832dc8a9f5194990684870931e7a07c2cafbc544588e7 +F src/whereexpr.c d63dcb44253f7ad67449759bca6da63cac1c352aba7bea46ba3210154ad21e22 F src/window.c edd6f5e25a1e8f2b6f5305b7f5f7da7bb35f07f0d432b255b1d4c2fcab4205aa F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -874,7 +874,7 @@ F test/exclusive.test 7ff63be7503990921838d5c9f77f6e33e68e48ed1a9d48cd28745bf650 F test/exclusive2.test 984090e8e9d1b331d2e8111daf6e5d61dda0bef7 F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7 F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac -F test/exists2.test 44e18a6aaadefa8e1c68a8453fb22a57a0270a673d9b256790d142ea257459e3 +F test/exists2.test 1022fe1c85ee162ae55efda6c00497b29d1f61ecb21e7d5f1c014eb46245c70a F test/expr.test 26cd01e8485bc48c8aa6a1add598e9ce1e706b4eb4f3f554e0b0223022e8c2cf F test/expr2.test c27327ae9c017a7ff6280123f67aff496f912da74d78c888926d68b46ec75fd8 F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9 @@ -1896,7 +1896,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 a80c9a076d31729282004ca372913c9fdbfb6e74711fbb8c5dc12ee0ecba2b87 -R 31b39e7a643244cb65bba0cd39985e5a -U drh -Z 96ac907b935dc11fb79e0a38f40aef27 +P 8ce3cb90965771530c0021173d98720fc4c76bb99e69f7a879f80471dea0aace +R bc5d3e0052171a4a3fcfe5fb2a3891b3 +U dan +Z 4e48cccd8bd31a2f422fbd932b326f93 diff --git a/manifest.uuid b/manifest.uuid index b72b9116a2..58184acaa4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8ce3cb90965771530c0021173d98720fc4c76bb99e69f7a879f80471dea0aace \ No newline at end of file +a373baae12c914e48fd84de77998e301fdd3da43b06b9d64ac24a14418ed48cd \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index 0359babc50..82a9759f39 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1175,12 +1175,18 @@ static void exprAnalyzeExists( pInLhs = exprAnalyzeExistsFindEq(pSel, &pEq, &ppAnd); assert( pInLhs && pEq ); assert( pEq==pSel->pWhere || ppAnd ); + if( pInLhs==pEq->pLeft ){ + pRet = pEq->pRight; + }else{ + CollSeq *p = sqlite3ExprCompareCollSeq(pParse, pEq); + pInLhs = sqlite3ExprAddCollateString(pParse, pInLhs, p?p->zName:"BINARY"); + pRet = pEq->pLeft; + } assert( pDup->pLeft==0 ); pDup->op = TK_IN; pDup->pLeft = pInLhs; pDup->flags &= ~EP_VarSelect; - pRet = (pInLhs==pEq->pLeft) ? pEq->pRight : pEq->pLeft; pSel->pEList = sqlite3ExprListAppend(pParse, 0, pRet); pEq->pLeft = 0; pEq->pRight = 0; diff --git a/test/exists2.test b/test/exists2.test index 55369f8f2f..3472751a21 100644 --- a/test/exists2.test +++ b/test/exists2.test @@ -71,7 +71,6 @@ do_execsql_eqp_test 1.4 { 1 one 3 three 5 five 7 seven } -breakpoint do_execsql_eqp_test 1.5 { SELECT t1.* FROM t1 WHERE EXISTS( SELECT * FROM t2 WHERE t1.a=t2.c AND d IN (1, 2, 3) @@ -82,6 +81,83 @@ do_execsql_eqp_test 1.5 { 1 one 3 three 5 five } +do_execsql_eqp_test 1.6 { + SELECT t1.* FROM t1 WHERE EXISTS( + SELECT * FROM t2 WHERE d IN (1, 2, 3)AND t1.a=t2.c + ); +} { + SEARCH TABLE t1 USING INTEGER PRIMARY KEY +} { + 1 one 3 three 5 five +} + +do_execsql_eqp_test 1.7 { + SELECT t1.* FROM t1 WHERE EXISTS( + SELECT * FROM t2 WHERE d IN (1, 2, 3)AND t1.a=t2.c + ); +} { + SEARCH TABLE t1 USING INTEGER PRIMARY KEY +} { + 1 one 3 three 5 five +} + +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 2.0 { + CREATE TABLE t3(a TEXT PRIMARY KEY, b TEXT) WITHOUT ROWID; + CREATE TABLE t4(c TEXT COLLATE nocase); + + INSERT INTO t3 VALUES('one', 'i'); + INSERT INTO t3 VALUES('two', 'ii'); + INSERT INTO t3 VALUES('three', 'iii'); + INSERT INTO t3 VALUES('four', 'iv'); + INSERT INTO t3 VALUES('five', 'v'); + + INSERT INTO t4 VALUES('FIVE'), ('four'), ('TWO'), ('one'); +} + +do_execsql_test 2.1 { SELECT a FROM t3, t4 WHERE a=c } {four one} +do_execsql_test 2.2 { SELECT a FROM t3, t4 WHERE c=a } {five four one two} + +do_execsql_eqp_test 2.3 { + SELECT a FROM t3 WHERE EXISTS (SELECT 1 FROM t4 WHERE a=c) +} { + SEARCH TABLE t3 USING PRIMARY KEY +} { + four one +} + +do_execsql_eqp_test 2.4 { + SELECT a FROM t3 WHERE EXISTS (SELECT 1 FROM t4 WHERE c=a) +} { + SCAN TABLE t3 +} { + five four one two +} + +do_execsql_test 2.5 { + CREATE INDEX t3anc ON t3(a COLLATE nocase); +} + +do_execsql_eqp_test 2.6 { + SELECT a FROM t3 WHERE EXISTS (SELECT 1 FROM t4 WHERE c=a) +} { + SEARCH TABLE t3 USING COVERING INDEX t3anc +} { + five four one two +} + +do_execsql_eqp_test 2.7 { + SELECT a FROM t3 WHERE EXISTS (SELECT 1 FROM t4 WHERE a=c) +} { + SEARCH TABLE t3 USING PRIMARY KEY +} { + four one +} + + finish_test + From a828d565b6b1b0fa6f97175f3d7934100a69b505 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 15 Jan 2021 16:37:32 +0000 Subject: [PATCH 122/257] Update header comments for routines added by this branch. FossilOrigin-Name: 950030d679933f9ccd2b86ee650a4a78d338278a3629f0d289cca720a43e686b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/whereexpr.c | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 1523531c03..7005bdf9f6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthe\sEXISTS->IN\stransformation\spreserves\sthe\scollation\ssequence\sof\sthe\scomparison\soperation. -D 2021-01-15T15:32:09.587 +C Update\sheader\scomments\sfor\sroutines\sadded\sby\sthis\sbranch. +D 2021-01-15T16:37:32.495 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -630,7 +630,7 @@ F src/walker.c d9c4e454ebb9499e908aa62d55b8994c375cf5355ac78f60d45af17f7890701c F src/where.c 0e6abb22a2323fec80b450825593c26a2ad8f4815d1ee3af9969d8f6144bf681 F src/whereInt.h 9a3f577619f07700d16d89eeb2f3d94d6b7ed7f109c2dacf0ce8844921549506 F src/wherecode.c a3a1aff30fe99a818d8e7c607980f033f40c68d890e03ed25838b9dbb7908bee -F src/whereexpr.c d63dcb44253f7ad67449759bca6da63cac1c352aba7bea46ba3210154ad21e22 +F src/whereexpr.c 0462a66ccabeea05c2d41a1e650a9c4db5bc696b9a3b42b48a43a89a2ba81474 F src/window.c edd6f5e25a1e8f2b6f5305b7f5f7da7bb35f07f0d432b255b1d4c2fcab4205aa F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -1896,7 +1896,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 8ce3cb90965771530c0021173d98720fc4c76bb99e69f7a879f80471dea0aace -R bc5d3e0052171a4a3fcfe5fb2a3891b3 +P a373baae12c914e48fd84de77998e301fdd3da43b06b9d64ac24a14418ed48cd +R e59675eaf8d9cef929f4570c41e8d7b0 U dan -Z 4e48cccd8bd31a2f422fbd932b326f93 +Z 99df7f39e80917b2e7ef225da7aeef0d diff --git a/manifest.uuid b/manifest.uuid index 58184acaa4..a3d3997a3a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a373baae12c914e48fd84de77998e301fdd3da43b06b9d64ac24a14418ed48cd \ No newline at end of file +950030d679933f9ccd2b86ee650a4a78d338278a3629f0d289cca720a43e686b \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index 82a9759f39..cdaaa7e894 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1054,6 +1054,10 @@ static int exprUsesSrclist(SrcList *pSrc, Expr *pExpr, int bUses){ return (sqlite3WalkExpr(&sWalker, pExpr)==WRC_Abort); } +/* +** Context object used by exprExistsToInIter() as it iterates through an +** expression tree. +*/ struct ExistsToInCtx { SrcList *pSrc; Expr *pInLhs; @@ -1062,6 +1066,15 @@ struct ExistsToInCtx { Expr **ppParent; }; +/* +** Iterate through all AND connected nodes in the expression tree +** headed by (*ppExpr), populating the structure passed as the first +** argument with the values required by exprAnalyzeExistsFindEq(). +** +** This function returns non-zero if the expression tree does not meet +** the two conditions described by the header comment for +** exprAnalyzeExistsFindEq(), or zero if it does. +*/ static int exprExistsToInIter(struct ExistsToInCtx *p, Expr **ppExpr){ Expr *pExpr = *ppExpr; switch( pExpr->op ){ @@ -1093,6 +1106,30 @@ static int exprExistsToInIter(struct ExistsToInCtx *p, Expr **ppExpr){ return 0; } +/* +** This function is by exprAnalyzeExists() when creating virtual IN(...) +** terms equivalent to user-supplied EXIST(...) clauses. It splits the WHERE +** clause of the Select object passed as the first argument into one or more +** expressions joined by AND operators, and then tests if the following are +** true: +** +** 1. Exactly one of the AND separated terms refers to the outer +** query, and it is an == (TK_EQ) expression. +** +** 2. Only one side of the == expression refers to the outer query, and +** it does not refer to any columns from the inner query. +** +** If both these conditions are true, then a pointer to the side of the == +** expression that refers to the outer query is returned. The caller will +** use this expression as the LHS of the IN(...) virtual term. Or, if one +** or both of the above conditions are not true, NULL is returned. +** +** If non-NULL is returned and ppEq is non-NULL, *ppEq is set to point +** to the == expression node before returning. If pppAnd is non-NULL and +** the == node is not the root of the WHERE clause, then *pppAnd is set +** to point to the pointer to the AND node that is the parent of the == +** node within the WHERE expression tree. +*/ static Expr *exprAnalyzeExistsFindEq( Select *pSel, Expr **ppEq, /* OUT: == node from WHERE clause */ From f7588d4072453c050169f549ce06ac3cc6b259ff Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 15 Jan 2021 17:51:56 +0000 Subject: [PATCH 123/257] Add OOM injection tests for new code on this branch. FossilOrigin-Name: 9a181dbaedcc2117e670e679ca94ed6d1fabd90c835671dee36424dd0646c4e5 --- manifest | 11 ++++----- manifest.uuid | 2 +- test/existsfault.test | 52 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 test/existsfault.test diff --git a/manifest b/manifest index 7005bdf9f6..a50135c18f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sheader\scomments\sfor\sroutines\sadded\sby\sthis\sbranch. -D 2021-01-15T16:37:32.495 +C Add\sOOM\sinjection\stests\sfor\snew\scode\son\sthis\sbranch. +D 2021-01-15T17:51:56.060 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -875,6 +875,7 @@ F test/exclusive2.test 984090e8e9d1b331d2e8111daf6e5d61dda0bef7 F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7 F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac F test/exists2.test 1022fe1c85ee162ae55efda6c00497b29d1f61ecb21e7d5f1c014eb46245c70a +F test/existsfault.test 74f7edc713f5a335e7ff47adf503067bf05c6f8630f88b2a19c24f0fa5486ab8 F test/expr.test 26cd01e8485bc48c8aa6a1add598e9ce1e706b4eb4f3f554e0b0223022e8c2cf F test/expr2.test c27327ae9c017a7ff6280123f67aff496f912da74d78c888926d68b46ec75fd8 F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9 @@ -1896,7 +1897,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 a373baae12c914e48fd84de77998e301fdd3da43b06b9d64ac24a14418ed48cd -R e59675eaf8d9cef929f4570c41e8d7b0 +P 950030d679933f9ccd2b86ee650a4a78d338278a3629f0d289cca720a43e686b +R 9a769128390cc86c331540163e8fa29c U dan -Z 99df7f39e80917b2e7ef225da7aeef0d +Z a3f9abfbc145e44a2a1bba02d43a960d diff --git a/manifest.uuid b/manifest.uuid index a3d3997a3a..7877c79580 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -950030d679933f9ccd2b86ee650a4a78d338278a3629f0d289cca720a43e686b \ No newline at end of file +9a181dbaedcc2117e670e679ca94ed6d1fabd90c835671dee36424dd0646c4e5 \ No newline at end of file diff --git a/test/existsfault.test b/test/existsfault.test new file mode 100644 index 0000000000..24e44a7b58 --- /dev/null +++ b/test/existsfault.test @@ -0,0 +1,52 @@ +# 2021 January 15 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this file is testing cases where EXISTS expressions are +# transformed to IN() expressions by where.c +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix existsfault + +do_execsql_test 1 { + CREATE TABLE t1(a PRIMARY KEY, b); + INSERT INTO t1 VALUES(1, 'one'); + INSERT INTO t1 VALUES(2, 'two'); + INSERT INTO t1 VALUES(3, 'three'); + INSERT INTO t1 VALUES(4, 'four'); + INSERT INTO t1 VALUES(5, 'five'); + INSERT INTO t1 VALUES(6, 'six'); + INSERT INTO t1 VALUES(7, 'seven'); + + CREATE TABLE t2(c INTEGER, d INTEGER); + INSERT INTO t2 VALUES(1, 1); + INSERT INTO t2 VALUES(3, 2); + INSERT INTO t2 VALUES(5, 3); + INSERT INTO t2 VALUES(7, 4); +} +faultsim_save_and_close + +do_faultsim_test 1 -prep { + faultsim_restore_and_reopen +} -body { + execsql { + SELECT t1.* FROM t1 WHERE EXISTS( + SELECT * FROM t2 WHERE t2.c=t1.a AND d IN (1, 2, 3) + ) + } +} -test { + faultsim_test_result {0 {1 one 3 three 5 five}} +} + + +finish_test + From 1e2896ec6e47c6f5a3bf3920c241014e6c47fcab Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 16 Jan 2021 12:15:41 +0000 Subject: [PATCH 124/257] Fix a hyperlink in the Lemon documentation. FossilOrigin-Name: 2ffb2ffa0ea147edd88632d2bbe29cc1d66d0911ce8e1068c406c81dd5a20242 --- doc/lemon.html | 4 ++-- manifest | 13 ++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/doc/lemon.html b/doc/lemon.html index bd078c8ec7..457004627e 100644 --- a/doc/lemon.html +++ b/doc/lemon.html @@ -1077,7 +1077,7 @@ can choose a different start symbol using the

4.4.19 The %syntax_error directive

-

See Error Processing.

+

See Error Processing.

4.4.20 The %token_class directive

@@ -1176,7 +1176,7 @@ match any input token.

the wildcard token and some other token, the other token is always used. The wildcard token is only matched if there are no alternatives.

- +

5.0 Error Processing

After extensive experimentation over several years, it has been diff --git a/manifest b/manifest index c00d0af4e9..1bbd748b03 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sthe\smin/max\soptimization.\s\sFix\sfor\sa\sperformance\nregression\sintroduced\sat\s[b8ba2f17f938c035]\sreported\sby\n[forum:/forumpost/4050026ab8|forum\spost\s4050026ab8] -D 2021-01-14T20:57:47.228 +C Fix\sa\shyperlink\sin\sthe\sLemon\sdocumentation. +D 2021-01-16T12:15:41.192 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -38,7 +38,7 @@ F configure 91893a81f698778dda4d8fb24bfca606ded31ef02bcfbc2ab072d30fb67138d6 x F configure.ac 412b65c6107e41c098ad7f5f2e6a3f74ac02ffc6e92b9a6264b9f1060c235a04 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd -F doc/lemon.html c5d8ba85ac1daef7be8c2d389899480eb62451ff5c09b0c28ff8157bb8770746 +F doc/lemon.html 1bb72ece6271df0d901d233551dd985f2c6ba30d09382cf2d321ed951ab57491 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a F doc/vdbesort-memory.md 4da2639c14cd24a31e0af694b1a8dd37eaf277aff3867e9a8cc14046bc49df56 @@ -1895,8 +1895,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 11e4eb095746602961a178044809a68a77ba7b367596997bef726e54062423d9 ccd3bae14b6b47bb0f9622700c04db989f76ce65e10e0709964cfd0675eca762 -R 3dc0d948d76c5e90d01be3a954f85921 -T +closed ccd3bae14b6b47bb0f9622700c04db989f76ce65e10e0709964cfd0675eca762 +P 249a71cc6822d6bdd5bb9e727aac81c6549693b418e9c0987b96850ee332c940 +R 0d3b2c6d616a91b857e305e5fa92f92c U drh -Z 8ad13e36552647d99e513fed14d21def +Z 3e8f8636c650d40fd45e0f7dddeb2d81 diff --git a/manifest.uuid b/manifest.uuid index 6ee0559a9e..ffa68fe850 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -249a71cc6822d6bdd5bb9e727aac81c6549693b418e9c0987b96850ee332c940 \ No newline at end of file +2ffb2ffa0ea147edd88632d2bbe29cc1d66d0911ce8e1068c406c81dd5a20242 \ No newline at end of file From 2a3be742caf8c35330038ce839f9a735e847045e Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 16 Jan 2021 18:22:10 +0000 Subject: [PATCH 125/257] Add debugging output about the EXISTS-to-IN optimization when the ".wheretrace" flag has the 0x20 bit set. FossilOrigin-Name: 0dad5ce34ad8a59200b013453c9334f8898e07f2c0107c8c734ecc34b67de572 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/whereexpr.c | 10 +++++++++- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index a50135c18f..f5d05c712c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sOOM\sinjection\stests\sfor\snew\scode\son\sthis\sbranch. -D 2021-01-15T17:51:56.060 +C Add\sdebugging\soutput\sabout\sthe\sEXISTS-to-IN\soptimization\swhen\nthe\s".wheretrace"\sflag\shas\sthe\s0x20\sbit\sset. +D 2021-01-16T18:22:10.163 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -630,7 +630,7 @@ F src/walker.c d9c4e454ebb9499e908aa62d55b8994c375cf5355ac78f60d45af17f7890701c F src/where.c 0e6abb22a2323fec80b450825593c26a2ad8f4815d1ee3af9969d8f6144bf681 F src/whereInt.h 9a3f577619f07700d16d89eeb2f3d94d6b7ed7f109c2dacf0ce8844921549506 F src/wherecode.c a3a1aff30fe99a818d8e7c607980f033f40c68d890e03ed25838b9dbb7908bee -F src/whereexpr.c 0462a66ccabeea05c2d41a1e650a9c4db5bc696b9a3b42b48a43a89a2ba81474 +F src/whereexpr.c 10ed78eb09474c4f4d2ad61c3047900897d48ce969f2fa7ef48ffd28b6d934a6 F src/window.c edd6f5e25a1e8f2b6f5305b7f5f7da7bb35f07f0d432b255b1d4c2fcab4205aa F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -1897,7 +1897,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 950030d679933f9ccd2b86ee650a4a78d338278a3629f0d289cca720a43e686b -R 9a769128390cc86c331540163e8fa29c -U dan -Z a3f9abfbc145e44a2a1bba02d43a960d +P 9a181dbaedcc2117e670e679ca94ed6d1fabd90c835671dee36424dd0646c4e5 +R 37544a92998410ad6bf700343ed335b0 +U drh +Z b455d8286b10f237c30679d2b4a9d690 diff --git a/manifest.uuid b/manifest.uuid index 7877c79580..c0bab29af4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9a181dbaedcc2117e670e679ca94ed6d1fabd90c835671dee36424dd0646c4e5 \ No newline at end of file +0dad5ce34ad8a59200b013453c9334f8898e07f2c0107c8c734ecc34b67de572 \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index cdaaa7e894..1772aa7486 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1107,7 +1107,7 @@ static int exprExistsToInIter(struct ExistsToInCtx *p, Expr **ppExpr){ } /* -** This function is by exprAnalyzeExists() when creating virtual IN(...) +** This function is used by exprAnalyzeExists() when creating virtual IN(...) ** terms equivalent to user-supplied EXIST(...) clauses. It splits the WHERE ** clause of the Select object passed as the first argument into one or more ** expressions joined by AND operators, and then tests if the following are @@ -1239,6 +1239,14 @@ static void exprAnalyzeExists( } sqlite3ExprDelete(db, pEq); +#ifdef WHERETRACE_ENABLED /* 0x20 */ + if( sqlite3WhereTrace & 0x20 ){ + sqlite3DebugPrintf("Convert EXISTS:\n"); + sqlite3TreeViewExpr(0, pExpr, 0); + sqlite3DebugPrintf("into IN:\n"); + sqlite3TreeViewExpr(0, pDup, 0); + } +#endif idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC); if( idxNew ){ exprAnalyze(pSrc, pWC, idxNew); From 4be8bdccd453440e653f04bb6da4dcecf4bdfa68 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 16 Jan 2021 18:55:10 +0000 Subject: [PATCH 126/257] Give the EXISTS-to-IN optimization the ability to handle some cases that involve vector comparisons, instead of throwing a mysterious error in those cases. FossilOrigin-Name: 87e78a19bb3ae1caf57aeeae53a5ab4efdccb57265f25d5c19b62eae53747aff --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/whereexpr.c | 14 +++++++++++--- test/exists2.test | 19 ++++++++++++++++++- 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index f5d05c712c..995f5e28d2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sdebugging\soutput\sabout\sthe\sEXISTS-to-IN\soptimization\swhen\nthe\s".wheretrace"\sflag\shas\sthe\s0x20\sbit\sset. -D 2021-01-16T18:22:10.163 +C Give\sthe\sEXISTS-to-IN\soptimization\sthe\sability\sto\shandle\ssome\scases\sthat\ninvolve\svector\scomparisons,\sinstead\sof\sthrowing\sa\smysterious\serror\sin\sthose\ncases. +D 2021-01-16T18:55:10.186 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -630,7 +630,7 @@ F src/walker.c d9c4e454ebb9499e908aa62d55b8994c375cf5355ac78f60d45af17f7890701c F src/where.c 0e6abb22a2323fec80b450825593c26a2ad8f4815d1ee3af9969d8f6144bf681 F src/whereInt.h 9a3f577619f07700d16d89eeb2f3d94d6b7ed7f109c2dacf0ce8844921549506 F src/wherecode.c a3a1aff30fe99a818d8e7c607980f033f40c68d890e03ed25838b9dbb7908bee -F src/whereexpr.c 10ed78eb09474c4f4d2ad61c3047900897d48ce969f2fa7ef48ffd28b6d934a6 +F src/whereexpr.c 0a3fd3667cb78d5ced831d103a9769e9429b69cc06336a557f7436a36298a08d F src/window.c edd6f5e25a1e8f2b6f5305b7f5f7da7bb35f07f0d432b255b1d4c2fcab4205aa F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -874,7 +874,7 @@ F test/exclusive.test 7ff63be7503990921838d5c9f77f6e33e68e48ed1a9d48cd28745bf650 F test/exclusive2.test 984090e8e9d1b331d2e8111daf6e5d61dda0bef7 F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7 F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac -F test/exists2.test 1022fe1c85ee162ae55efda6c00497b29d1f61ecb21e7d5f1c014eb46245c70a +F test/exists2.test 3e6741849880410a438e1e016878aee518e82fc14c9df7bb8b975414e822960a F test/existsfault.test 74f7edc713f5a335e7ff47adf503067bf05c6f8630f88b2a19c24f0fa5486ab8 F test/expr.test 26cd01e8485bc48c8aa6a1add598e9ce1e706b4eb4f3f554e0b0223022e8c2cf F test/expr2.test c27327ae9c017a7ff6280123f67aff496f912da74d78c888926d68b46ec75fd8 @@ -1897,7 +1897,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 9a181dbaedcc2117e670e679ca94ed6d1fabd90c835671dee36424dd0646c4e5 -R 37544a92998410ad6bf700343ed335b0 +P 0dad5ce34ad8a59200b013453c9334f8898e07f2c0107c8c734ecc34b67de572 +R dac9991b639e128a44072e06099f9d5a U drh -Z b455d8286b10f237c30679d2b4a9d690 +Z 4c2faa19ecfc2a7e1d7bc30b27d619e2 diff --git a/manifest.uuid b/manifest.uuid index c0bab29af4..b027e9f246 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0dad5ce34ad8a59200b013453c9334f8898e07f2c0107c8c734ecc34b67de572 \ No newline at end of file +87e78a19bb3ae1caf57aeeae53a5ab4efdccb57265f25d5c19b62eae53747aff \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index 1772aa7486..e3c02deacd 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1215,16 +1215,24 @@ static void exprAnalyzeExists( if( pInLhs==pEq->pLeft ){ pRet = pEq->pRight; }else{ - CollSeq *p = sqlite3ExprCompareCollSeq(pParse, pEq); - pInLhs = sqlite3ExprAddCollateString(pParse, pInLhs, p?p->zName:"BINARY"); pRet = pEq->pLeft; + if( pRet->op!=TK_VECTOR ){ + CollSeq *p = sqlite3ExprCompareCollSeq(pParse, pEq); + pInLhs = sqlite3ExprAddCollateString(pParse, pInLhs, p?p->zName:"BINARY"); + } } assert( pDup->pLeft==0 ); pDup->op = TK_IN; pDup->pLeft = pInLhs; pDup->flags &= ~EP_VarSelect; - pSel->pEList = sqlite3ExprListAppend(pParse, 0, pRet); + if( pRet->op==TK_VECTOR ){ + pSel->pEList = pRet->x.pList; + pRet->x.pList = 0; + sqlite3ExprDelete(db, pRet); + }else{ + pSel->pEList = sqlite3ExprListAppend(pParse, 0, pRet); + } pEq->pLeft = 0; pEq->pRight = 0; if( ppAnd ){ diff --git a/test/exists2.test b/test/exists2.test index 3472751a21..a28e5daaef 100644 --- a/test/exists2.test +++ b/test/exists2.test @@ -156,8 +156,25 @@ do_execsql_eqp_test 2.7 { four one } +# EXISTS clauses using vector expressions in the WHERE clause. +# +reset_db +do_execsql_test 3.0 { + CREATE TABLE t1(a,b); + INSERT INTO t1(a,b) VALUES(1,111),(2,222),(8,888); + CREATE TABLE t2(x INTEGER PRIMARY KEY, y); + INSERT INTO t2(x,y) VALUES(2,222),(3,333),(7,333); + SELECT y FROM t2 WHERE EXISTS(SELECT 1 FROM t1 WHERE (x,y)=(a,b)); +} {222} +do_execsql_test 3.1 { + SELECT y FROM t2 WHERE EXISTS(SELECT 1 FROM t1 WHERE (a,b)=(x,y)); +} {222} +do_execsql_test 3.2 { + SELECT y FROM t2 WHERE EXISTS(SELECT 1 FROM t1 WHERE (x,b)=(a,y)); +} {222} + + finish_test - From 9ffa258a01ff64cce868f452164a001e702561b5 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 16 Jan 2021 20:22:11 +0000 Subject: [PATCH 127/257] Improved handling of vector equalities in the EXISTS-to-IN translator. FossilOrigin-Name: ef49ee4a3766146963bfb6b013472f9836afb9c5b0d21a8533871cf961139e38 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 13 ++++++++++++- src/whereexpr.c | 6 ++---- test/exists2.test | 26 +++++++++++++++++--------- 5 files changed, 40 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index 995f5e28d2..2755d47c82 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Give\sthe\sEXISTS-to-IN\soptimization\sthe\sability\sto\shandle\ssome\scases\sthat\ninvolve\svector\scomparisons,\sinstead\sof\sthrowing\sa\smysterious\serror\sin\sthose\ncases. -D 2021-01-16T18:55:10.186 +C Improved\shandling\sof\svector\sequalities\sin\sthe\sEXISTS-to-IN\stranslator. +D 2021-01-16T20:22:11.928 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -492,7 +492,7 @@ F src/date.c dace306a10d9b02ee553d454c8e1cf8d3c9b932e137738a6b15b90253a9bfc10 F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c F src/delete.c 927cf8f900583e79aca8f1a321979e0a8f053babd9a690b44b38f79de2cc09fe -F src/expr.c 0d196ed5a2ebf96be7e8df88add4fabfad0dce16c0fed81a4b8f6a26e259797f +F src/expr.c 47c85263e6d179424e6b09e2c79db5704ab5b8cbc2fae2ee3285faa2566f2e74 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 83372403298e6a7dd989a47aaacdbaa5b4307b5199dbd56e07d4896066b3de72 F src/func.c 251b5953cecd0ce3e282213c5e623134415793d3569d7804d13460559d7e45ff @@ -630,7 +630,7 @@ F src/walker.c d9c4e454ebb9499e908aa62d55b8994c375cf5355ac78f60d45af17f7890701c F src/where.c 0e6abb22a2323fec80b450825593c26a2ad8f4815d1ee3af9969d8f6144bf681 F src/whereInt.h 9a3f577619f07700d16d89eeb2f3d94d6b7ed7f109c2dacf0ce8844921549506 F src/wherecode.c a3a1aff30fe99a818d8e7c607980f033f40c68d890e03ed25838b9dbb7908bee -F src/whereexpr.c 0a3fd3667cb78d5ced831d103a9769e9429b69cc06336a557f7436a36298a08d +F src/whereexpr.c 9fdbed19035077e41ca993ab469114e9b6b0746c18ea4e7675a850713b35fc72 F src/window.c edd6f5e25a1e8f2b6f5305b7f5f7da7bb35f07f0d432b255b1d4c2fcab4205aa F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -874,7 +874,7 @@ F test/exclusive.test 7ff63be7503990921838d5c9f77f6e33e68e48ed1a9d48cd28745bf650 F test/exclusive2.test 984090e8e9d1b331d2e8111daf6e5d61dda0bef7 F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7 F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac -F test/exists2.test 3e6741849880410a438e1e016878aee518e82fc14c9df7bb8b975414e822960a +F test/exists2.test 3e5726d6a67ebd4bd3466db58be424c09156c1f276c7594abb260cbf6ad494d3 F test/existsfault.test 74f7edc713f5a335e7ff47adf503067bf05c6f8630f88b2a19c24f0fa5486ab8 F test/expr.test 26cd01e8485bc48c8aa6a1add598e9ce1e706b4eb4f3f554e0b0223022e8c2cf F test/expr2.test c27327ae9c017a7ff6280123f67aff496f912da74d78c888926d68b46ec75fd8 @@ -1897,7 +1897,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 0dad5ce34ad8a59200b013453c9334f8898e07f2c0107c8c734ecc34b67de572 -R dac9991b639e128a44072e06099f9d5a +P 87e78a19bb3ae1caf57aeeae53a5ab4efdccb57265f25d5c19b62eae53747aff +R 9040bb485a8bcb3beab221382ed76aaa U drh -Z 4c2faa19ecfc2a7e1d7bc30b27d619e2 +Z 15d0a474b0220437a1e81a3ea0fc01b3 diff --git a/manifest.uuid b/manifest.uuid index b027e9f246..773b82c6ef 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -87e78a19bb3ae1caf57aeeae53a5ab4efdccb57265f25d5c19b62eae53747aff \ No newline at end of file +ef49ee4a3766146963bfb6b013472f9836afb9c5b0d21a8533871cf961139e38 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 685f041752..f225b59bce 100644 --- a/src/expr.c +++ b/src/expr.c @@ -95,7 +95,18 @@ Expr *sqlite3ExprAddCollateToken( const Token *pCollName, /* Name of collating sequence */ int dequote /* True to dequote pCollName */ ){ - if( pCollName->n>0 ){ + assert( pExpr!=0 || pParse->db->mallocFailed ); + if( pExpr==0 ) return 0; + if( pExpr->op==TK_VECTOR ){ + ExprList *pList = pExpr->x.pList; + if( ALWAYS(pList!=0) ){ + int i; + for(i=0; inExpr; i++){ + pList->a[i].pExpr = sqlite3ExprAddCollateToken(pParse,pList->a[i].pExpr, + pCollName, dequote); + } + } + }else if( pCollName->n>0 ){ Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote); if( pNew ){ pNew->pLeft = pExpr; diff --git a/src/whereexpr.c b/src/whereexpr.c index e3c02deacd..9029ff1810 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1215,11 +1215,9 @@ static void exprAnalyzeExists( if( pInLhs==pEq->pLeft ){ pRet = pEq->pRight; }else{ + CollSeq *p = sqlite3ExprCompareCollSeq(pParse, pEq); + pInLhs = sqlite3ExprAddCollateString(pParse, pInLhs, p?p->zName:"BINARY"); pRet = pEq->pLeft; - if( pRet->op!=TK_VECTOR ){ - CollSeq *p = sqlite3ExprCompareCollSeq(pParse, pEq); - pInLhs = sqlite3ExprAddCollateString(pParse, pInLhs, p?p->zName:"BINARY"); - } } assert( pDup->pLeft==0 ); diff --git a/test/exists2.test b/test/exists2.test index a28e5daaef..c4fc9dc373 100644 --- a/test/exists2.test +++ b/test/exists2.test @@ -105,16 +105,16 @@ do_execsql_eqp_test 1.7 { # reset_db do_execsql_test 2.0 { - CREATE TABLE t3(a TEXT PRIMARY KEY, b TEXT) WITHOUT ROWID; - CREATE TABLE t4(c TEXT COLLATE nocase); + CREATE TABLE t3(a TEXT PRIMARY KEY, b TEXT, x INT) WITHOUT ROWID; + CREATE TABLE t4(c TEXT COLLATE nocase, y INT); - INSERT INTO t3 VALUES('one', 'i'); - INSERT INTO t3 VALUES('two', 'ii'); - INSERT INTO t3 VALUES('three', 'iii'); - INSERT INTO t3 VALUES('four', 'iv'); - INSERT INTO t3 VALUES('five', 'v'); + INSERT INTO t3 VALUES('one', 'i', 1); + INSERT INTO t3 VALUES('two', 'ii', 2); + INSERT INTO t3 VALUES('three', 'iii', 3); + INSERT INTO t3 VALUES('four', 'iv', 4); + INSERT INTO t3 VALUES('five', 'v', 5); - INSERT INTO t4 VALUES('FIVE'), ('four'), ('TWO'), ('one'); + INSERT INTO t4 VALUES('FIVE',5), ('four',4), ('TWO',2), ('one',1); } do_execsql_test 2.1 { SELECT a FROM t3, t4 WHERE a=c } {four one} @@ -137,7 +137,7 @@ do_execsql_eqp_test 2.4 { } do_execsql_test 2.5 { - CREATE INDEX t3anc ON t3(a COLLATE nocase); + CREATE INDEX t3anc ON t3(a COLLATE nocase, x); } do_execsql_eqp_test 2.6 { @@ -147,6 +147,9 @@ do_execsql_eqp_test 2.6 { } { five four one two } +do_execsql_test 2.6a { + SELECT a FROM t3 WHERE EXISTS (SELECT 1 FROM t4 WHERE (c,y)=(a,x)) +} {five four one two} do_execsql_eqp_test 2.7 { SELECT a FROM t3 WHERE EXISTS (SELECT 1 FROM t4 WHERE a=c) @@ -155,6 +158,11 @@ do_execsql_eqp_test 2.7 { } { four one } +do_execsql_test 2.7a { + SELECT a FROM t3 WHERE EXISTS (SELECT 1 FROM t4 WHERE (a,x)=(c,y)) +} { + four one +} # EXISTS clauses using vector expressions in the WHERE clause. # From 9fcc8c69bbf0af6da7f3e767ddadd1aa7bf28bbe Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 17 Jan 2021 00:13:12 +0000 Subject: [PATCH 128/257] Minor simplification of the EXISTS-to-IN logic. FossilOrigin-Name: cac90a9f4ab0a8f3ff77ee1f8549213c2f97169fc3469e55d57caa564079ce2a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/whereexpr.c | 8 +++----- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 2755d47c82..51ebfdca8d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\shandling\sof\svector\sequalities\sin\sthe\sEXISTS-to-IN\stranslator. -D 2021-01-16T20:22:11.928 +C Minor\ssimplification\sof\sthe\sEXISTS-to-IN\slogic. +D 2021-01-17T00:13:12.097 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -630,7 +630,7 @@ F src/walker.c d9c4e454ebb9499e908aa62d55b8994c375cf5355ac78f60d45af17f7890701c F src/where.c 0e6abb22a2323fec80b450825593c26a2ad8f4815d1ee3af9969d8f6144bf681 F src/whereInt.h 9a3f577619f07700d16d89eeb2f3d94d6b7ed7f109c2dacf0ce8844921549506 F src/wherecode.c a3a1aff30fe99a818d8e7c607980f033f40c68d890e03ed25838b9dbb7908bee -F src/whereexpr.c 9fdbed19035077e41ca993ab469114e9b6b0746c18ea4e7675a850713b35fc72 +F src/whereexpr.c 9886a16b52af66e01ded9e69e3e2913f25d8e34bdeaa5e583d7c8c9a1ffe71d2 F src/window.c edd6f5e25a1e8f2b6f5305b7f5f7da7bb35f07f0d432b255b1d4c2fcab4205aa F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -1897,7 +1897,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 87e78a19bb3ae1caf57aeeae53a5ab4efdccb57265f25d5c19b62eae53747aff -R 9040bb485a8bcb3beab221382ed76aaa +P ef49ee4a3766146963bfb6b013472f9836afb9c5b0d21a8533871cf961139e38 +R ed5d5749a7ed1103ef3bdb4ce2a908bc U drh -Z 15d0a474b0220437a1e81a3ea0fc01b3 +Z beb39ea924321eafaa423b5e3b964772 diff --git a/manifest.uuid b/manifest.uuid index 773b82c6ef..7186b19c6e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ef49ee4a3766146963bfb6b013472f9836afb9c5b0d21a8533871cf961139e38 \ No newline at end of file +cac90a9f4ab0a8f3ff77ee1f8549213c2f97169fc3469e55d57caa564079ce2a \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index 9029ff1810..584d2d35f5 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1254,11 +1254,9 @@ static void exprAnalyzeExists( } #endif idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC); - if( idxNew ){ - exprAnalyze(pSrc, pWC, idxNew); - markTermAsChild(pWC, idxNew, idxTerm); - pWC->a[idxTerm].wtFlags |= TERM_COPIED; - } + exprAnalyze(pSrc, pWC, idxNew); + markTermAsChild(pWC, idxNew, idxTerm); + pWC->a[idxTerm].wtFlags |= TERM_COPIED; } /* From 06afa291cfc887c7a5592542c770184db6732814 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 18 Jan 2021 00:11:20 +0000 Subject: [PATCH 129/257] More comments on the EXISTS-to-IN optimization logic. FossilOrigin-Name: 92cc29099f796f5f244dd80ee431c48d36d01eaece6f150119ead5ecd14eaae1 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/whereexpr.c | 37 +++++++++++++++++++++++++------------ 3 files changed, 32 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 51ebfdca8d..c51fc6703b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\ssimplification\sof\sthe\sEXISTS-to-IN\slogic. -D 2021-01-17T00:13:12.097 +C More\scomments\son\sthe\sEXISTS-to-IN\soptimization\slogic. +D 2021-01-18T00:11:20.813 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -630,7 +630,7 @@ F src/walker.c d9c4e454ebb9499e908aa62d55b8994c375cf5355ac78f60d45af17f7890701c F src/where.c 0e6abb22a2323fec80b450825593c26a2ad8f4815d1ee3af9969d8f6144bf681 F src/whereInt.h 9a3f577619f07700d16d89eeb2f3d94d6b7ed7f109c2dacf0ce8844921549506 F src/wherecode.c a3a1aff30fe99a818d8e7c607980f033f40c68d890e03ed25838b9dbb7908bee -F src/whereexpr.c 9886a16b52af66e01ded9e69e3e2913f25d8e34bdeaa5e583d7c8c9a1ffe71d2 +F src/whereexpr.c a022b4f447c0fb0674e172a9a303537ea5055df60d579f99cec7ead18e8c453f F src/window.c edd6f5e25a1e8f2b6f5305b7f5f7da7bb35f07f0d432b255b1d4c2fcab4205aa F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -1897,7 +1897,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 ef49ee4a3766146963bfb6b013472f9836afb9c5b0d21a8533871cf961139e38 -R ed5d5749a7ed1103ef3bdb4ce2a908bc +P cac90a9f4ab0a8f3ff77ee1f8549213c2f97169fc3469e55d57caa564079ce2a +R f533358ab2d88dffa58abcd3bcdbe4bd U drh -Z beb39ea924321eafaa423b5e3b964772 +Z 7271ac9ea9a27eaec7cf5d0a637bfec4 diff --git a/manifest.uuid b/manifest.uuid index 7186b19c6e..689f037d90 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cac90a9f4ab0a8f3ff77ee1f8549213c2f97169fc3469e55d57caa564079ce2a \ No newline at end of file +92cc29099f796f5f244dd80ee431c48d36d01eaece6f150119ead5ecd14eaae1 \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index 584d2d35f5..5cfdad67c1 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1036,13 +1036,26 @@ static int exprUsesSrclistSelectCb(Walker *p, Select *pSelect){ ** This function always returns true if expression pExpr contains ** a sub-select. ** -** If there is no sub-select and bUses is 1, then true is returned -** if the expression contains at least one TK_COLUMN node that refers -** to a table in pSrc. +** If there is no sub-select in pExpr, then return true if pExpr +** contains a TK_COLUMN node for a table that is (bUses==1) +** or is not (bUses==0) in pSrc. ** -** Or, if there is no sub-select and bUses is 0, then true is returned -** if the expression contains at least one TK_COLUMN node that refers -** to a table that is not in pSrc. +** Said another way: +** +** bUses Return Meaning +** -------- ------ ------------------------------------------------ +** +** bUses==1 true pExpr contains either a sub-select or a +** TK_COLUMN referencing pSrc. +** +** bUses==1 false pExpr contains no sub-selects and all TK_COLUMN +** nodes reference tables not found in pSrc +** +** bUses==0 true pExpr contains either a sub-select or a TK_COLUMN +** that references a table not in pSrc. +** +** bUses==0 false pExpr contains no sub-selects and all TK_COLUMN +** nodes reference pSrc */ static int exprUsesSrclist(SrcList *pSrc, Expr *pExpr, int bUses){ Walker sWalker; @@ -1059,11 +1072,11 @@ static int exprUsesSrclist(SrcList *pSrc, Expr *pExpr, int bUses){ ** expression tree. */ struct ExistsToInCtx { - SrcList *pSrc; - Expr *pInLhs; - Expr *pEq; - Expr **ppAnd; - Expr **ppParent; + SrcList *pSrc; /* The tables in an EXISTS(SELECT ... FROM ...) */ + Expr *pInLhs; /* OUT: Use this as the LHS of the IN operator */ + Expr *pEq; /* OUT: The == term that include pInLhs */ + Expr **ppAnd; /* OUT: The AND operator that includes pEq as a child */ + Expr **ppParent; /* The AND operator currently being examined */ }; /* @@ -1131,7 +1144,7 @@ static int exprExistsToInIter(struct ExistsToInCtx *p, Expr **ppExpr){ ** node within the WHERE expression tree. */ static Expr *exprAnalyzeExistsFindEq( - Select *pSel, + Select *pSel, /* The SELECT of the EXISTS */ Expr **ppEq, /* OUT: == node from WHERE clause */ Expr ***pppAnd /* OUT: Pointer to parent of ==, if any */ ){ From f3ebea8114feb2798ffd2f12dd1b9a2a1b0d418f Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 18 Jan 2021 19:27:56 +0000 Subject: [PATCH 130/257] Update test helper procedure 'get_pwd' to handle the ComSpec environment variable being absent. FossilOrigin-Name: fe1979552f43e0526f16481457e01981f29707401f77079f9854a8d91b35b5a4 --- manifest | 17 ++++++++--------- manifest.uuid | 2 +- test/crash5.test | 10 ++++++++-- test/tester.tcl | 8 +++++++- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 36270a6a17..03ea998b51 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\squery\splanner\sso\sthat\sit\sis\sable\sto\scode\sEXISTS\soperators\sin\nthe\sWHERE\sclause\sas\sif\sthey\swere\sIN\soperators,\swhen\sappropriate. -D 2021-01-18T12:35:16.581 +C Update\stest\shelper\sprocedure\s'get_pwd'\sto\shandle\sthe\sComSpec\senvironment\svariable\sbeing\sabsent. +D 2021-01-18T19:27:56.252 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -800,7 +800,7 @@ F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f F test/crash2.test 5b14d4eb58b880e231361d3b609b216acda86651 F test/crash3.test 8f5de9d32ab9ab95475a9efe7f47a940aa889418 F test/crash4.test fe2821baf37168dc59dd733dcf7dba2a401487bc -F test/crash5.test 98f77ad22bceaea9043bf87088d5b61d004a1f40bb7c9dc3b6a7c70bd502c0bb +F test/crash5.test 4aa55e7ac3c4bc511873e457aa65d2827d52da9b51e061511899dadcfe22b1e8 F test/crash6.test 4c56f1e40d0291e1110790a99807aa875b1647ba F test/crash7.test 1a194c4900a255258cf94b7fcbfd29536db572df F test/crash8.test 64366e459c28dd62edfb7ad87253a409c7533b92d16fcc479a6a8131bdcc3100 @@ -1437,7 +1437,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 56c059c88c5b96a624f1193ba48b0bac034190b79cd9c75cb4acbfe84baf7ec5 +F test/tester.tcl e5e4f5707fbf791ff8e06438fd0d4d71fe4c1d48753b7dd415efe72e853ef877 F test/thread001.test b61a29dd87cf669f5f6ac96124a7c97d71b0c80d9012746072055877055cf9ef F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1897,8 +1897,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 2ffb2ffa0ea147edd88632d2bbe29cc1d66d0911ce8e1068c406c81dd5a20242 92cc29099f796f5f244dd80ee431c48d36d01eaece6f150119ead5ecd14eaae1 -R e9622ae2cc2f8f16e772e641d8b24f1c -T +closed 92cc29099f796f5f244dd80ee431c48d36d01eaece6f150119ead5ecd14eaae1 -U drh -Z f5a7eb36d087a773f1b509e693ef42b1 +P c1862abb44873f06ec0d772469d8a2d128ae4670b1e98c2d97b0e2da18df9a04 +R 3b894a27798e4da33503e4ea0791a039 +U mistachkin +Z 4d9421bedbee9a79d4853a9ab24d8edd diff --git a/manifest.uuid b/manifest.uuid index c22949f1d4..13ef47c004 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c1862abb44873f06ec0d772469d8a2d128ae4670b1e98c2d97b0e2da18df9a04 \ No newline at end of file +fe1979552f43e0526f16481457e01981f29707401f77079f9854a8d91b35b5a4 \ No newline at end of file diff --git a/test/crash5.test b/test/crash5.test index 5c8e04c137..fc078b3504 100644 --- a/test/crash5.test +++ b/test/crash5.test @@ -21,7 +21,7 @@ source $testdir/tester.tcl # Only run these tests if memory debugging is turned on. # ifcapable !crashtest||!memorymanage { - puts "Skipping crash5 tests: not compiled with -DSQLITE_MEMDEBUG..." + puts "Skipping crash5 tests: not compiled with -DSQLITE_ENABLE_MEMORY_MANAGEMENT..." finish_test return } @@ -49,8 +49,14 @@ for {set ii 0} {$ii < 10} {incr ii} { [list set iFail $jj] { proc get_pwd {} { if {$::tcl_platform(platform) eq "windows"} { + if {[info exists ::env(ComSpec)]} { + set comSpec $::env(ComSpec) + } else { + # NOTE: Hard-code the typical default value. + set comSpec {C:\Windows\system32\cmd.exe} + } return [string map [list \\ /] \ - [string trim [exec -- $::env(ComSpec) /c echo %CD%]]] + [string trim [exec -- $comSpec /c echo %CD%]]] } else { return [pwd] } diff --git a/test/tester.tcl b/test/tester.tcl index 7ef059571a..5c72dccbb7 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -174,8 +174,14 @@ proc get_pwd {} { # case of the result to what Tcl considers canonical, which would # defeat the purpose of this procedure. # + if {[info exists ::env(ComSpec)]} { + set comSpec $::env(ComSpec) + } else { + # NOTE: Hard-code the typical default value. + set comSpec {C:\Windows\system32\cmd.exe} + } return [string map [list \\ /] \ - [string trim [exec -- $::env(ComSpec) /c echo %CD%]]] + [string trim [exec -- $comSpec /c echo %CD%]]] } else { return [pwd] } From d6665c51e2ed677aab53b2dc6504f1ea2270a951 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 18 Jan 2021 19:28:56 +0000 Subject: [PATCH 131/257] Fix harmless compiler warnings seen with MSVC. FossilOrigin-Name: dc7938d2d715301595dee2fac6880af3716c4b3d1cbe7c3578d7fd30ba146a23 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/insert.c | 2 ++ src/vdbe.c | 2 ++ 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 03ea998b51..a604568c21 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\stest\shelper\sprocedure\s'get_pwd'\sto\shandle\sthe\sComSpec\senvironment\svariable\sbeing\sabsent. -D 2021-01-18T19:27:56.252 +C Fix\sharmless\scompiler\swarnings\sseen\swith\sMSVC. +D 2021-01-18T19:28:56.733 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -501,7 +501,7 @@ 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 c5e0c25cfb9960d9b7d49043de6adc12748853bc6dea76f5adef059e366f2f70 +F src/insert.c 9b970eff058a858fbd9f2db71425ef195942c2610855daa66ae23024432d52f5 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 F src/main.c 1c5de7b3fabcdf05f4fe563aab5d81d175b89c67a8678a12ba86629356afa356 @@ -612,7 +612,7 @@ F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 41c7a72da1df47864faa378a1c720b38adb288c6838cb6be5594511b6287a048 F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286 -F src/vdbe.c 67de20067fa3a2ee8566342c751e941a2fe3fd88940fd9886ca5115f04165cce +F src/vdbe.c fd3ae827dea9da118d22c172ad183888120070d4c709bd0a5a97af7749246783 F src/vdbe.h 83603854bfa5851af601fc0947671eb260f4363e62e960e8a994fb9bbcd2aaa1 F src/vdbeInt.h 3ca5e9fd6e095a8b6cf6bc3587a46fc93499503b2fe48951e1034ba9e2ce2f6e F src/vdbeapi.c c5e7cb2ab89a24d7f723e87b508f21bfb1359a04db5277d8a99fd1e015c12eb9 @@ -1897,7 +1897,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 c1862abb44873f06ec0d772469d8a2d128ae4670b1e98c2d97b0e2da18df9a04 -R 3b894a27798e4da33503e4ea0791a039 +P fe1979552f43e0526f16481457e01981f29707401f77079f9854a8d91b35b5a4 +R dc7be2ccd019ce776f5c5401443272a0 U mistachkin -Z 4d9421bedbee9a79d4853a9ab24d8edd +Z dce87543665f3b6eb6e012303a5399fb diff --git a/manifest.uuid b/manifest.uuid index 13ef47c004..f83d261629 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fe1979552f43e0526f16481457e01981f29707401f77079f9854a8d91b35b5a4 \ No newline at end of file +dc7938d2d715301595dee2fac6880af3716c4b3d1cbe7c3578d7fd30ba146a23 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index c0ab0cf37a..6047969c07 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1301,7 +1301,9 @@ void sqlite3Insert( sqlite3VdbeJumpHere(v, addrInsTop); } +#ifndef SQLITE_OMIT_XFER_OPT insert_end: +#endif /* SQLITE_OMIT_XFER_OPT */ /* Update the sqlite_sequence table by storing the content of the ** maximum rowid counter values recorded while inserting into ** autoincrement tables. diff --git a/src/vdbe.c b/src/vdbe.c index 8e107a8a56..bcfc5df8d9 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4909,8 +4909,10 @@ case OP_NewRowid: { /* out2 */ VdbeCursor *pC; /* Cursor of table to get the new rowid */ int res; /* Result of an sqlite3BtreeLast() */ int cnt; /* Counter to limit the number of searches */ +#ifndef SQLITE_OMIT_AUTOINCREMENT Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ VdbeFrame *pFrame; /* Root frame of VDBE */ +#endif v = 0; res = 0; From a2560ce934ddef0ebebfea7702e2ad361b2df654 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 20 Jan 2021 10:59:47 +0000 Subject: [PATCH 132/257] Add tests for sqlite3session_memory_used() interface. FossilOrigin-Name: 5596611f96f3401262b9dadc591bf7e3411d2c4a6f5be5cfe524e203d9820fd1 --- ext/session/sessionmem.test | 57 +++++++++++++++++++++++++++++++++++++ manifest | 13 +++++---- manifest.uuid | 2 +- 3 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 ext/session/sessionmem.test diff --git a/ext/session/sessionmem.test b/ext/session/sessionmem.test new file mode 100644 index 0000000000..75b48623d0 --- /dev/null +++ b/ext/session/sessionmem.test @@ -0,0 +1,57 @@ +# 2020 December 23 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for the SQLite sessions module +# Specifically, for the sqlite3session_memory_used() API. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} + +set testprefix sessionmem + +do_execsql_test 1.0 { + CREATE TABLE t1(i INTEGER PRIMARY KEY, x, y); + CREATE TABLE t2(i INTEGER, x, y, PRIMARY KEY(x, y)); +} + +do_test 1.1 { + sqlite3session S db main + S attach * +} {} + +foreach {tn sql eRes} { + 1 { INSERT INTO t1 VALUES(1, 2, 3) } 1 + 2 { UPDATE t1 SET x=5 } 0 + 3 { UPDATE t1 SET i=5 } 1 + 4 { DELETE FROM t1 } 0 + 5 { INSERT INTO t1 VALUES(1, 2, 3) } 0 + 6 { INSERT INTO t1 VALUES(5, 2, 3) } 0 + 7 { INSERT INTO t2 VALUES('a', 'b', 'c') } 1 + 8 { INSERT INTO t2 VALUES('d', 'e', 'f') } 1 + 9 { UPDATE t2 SET i='e' } 0 +} { + set mem1 [S memory_used] + do_test 1.2.$tn.(mu=$mem1) { + execsql $sql + set mem2 [S memory_used] + expr {$mem2 > $mem1} + } $eRes +} + +do_test 1.3 { + S delete +} {} + +finish_test diff --git a/manifest b/manifest index a604568c21..1f0fed3243 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sseen\swith\sMSVC. -D 2021-01-18T19:28:56.733 +C Add\stests\sfor\ssqlite3session_memory_used()\sinterface. +D 2021-01-20T10:59:47.320 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -450,6 +450,7 @@ F ext/session/sessiondiff.test ad13dd65664bae26744e1f18eb3cbd5588349b7e9118851d8 F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7 F ext/session/sessionfault2.test dd593f80b6b4786f7adfe83c5939620bc505559770cc181332da26f29cddd7bb F ext/session/sessioninvert.test 04075517a9497a80d39c495ba6b44f3982c7371129b89e2c52219819bc105a25 +F ext/session/sessionmem.test f2a735db84a3e9e19f571033b725b0b2daf847f3f28b1da55a0c1a4e74f1de09 F ext/session/sessionrebase.test ccfa716b23bd1d3b03217ee58cfd90c78d4b99f53e6a9a2f05e82363b9142810 F ext/session/sessionstat1.test 218d351cf9fcd6648f125a26b607b140310160184723c2666091b54450a68fb5 F ext/session/sessionwor.test 67b5ab91d4f93ce65ff1f58240ac5ddf73f8670facc1ffa49cef56293d52818d @@ -1897,7 +1898,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 fe1979552f43e0526f16481457e01981f29707401f77079f9854a8d91b35b5a4 -R dc7be2ccd019ce776f5c5401443272a0 -U mistachkin -Z dce87543665f3b6eb6e012303a5399fb +P dc7938d2d715301595dee2fac6880af3716c4b3d1cbe7c3578d7fd30ba146a23 +R 2a7f82e5717f1cb1207576a8070164d7 +U dan +Z 837106ab8ad362dbfd49cfef88809376 diff --git a/manifest.uuid b/manifest.uuid index f83d261629..92afa750c7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dc7938d2d715301595dee2fac6880af3716c4b3d1cbe7c3578d7fd30ba146a23 \ No newline at end of file +5596611f96f3401262b9dadc591bf7e3411d2c4a6f5be5cfe524e203d9820fd1 \ No newline at end of file From 7b88f5491487424bd88ad0ebdd22d81ac92690bf Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 20 Jan 2021 23:01:31 +0000 Subject: [PATCH 133/257] Improvements to the auxiliary "main.mk" makefile so that it works better with multi-threaded builds. FossilOrigin-Name: d1873054d8e1006a370ea7891dbb9a62e7d36ce98cb92b58dcb0daf271265de3 --- main.mk | 12 ++++++------ manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/main.mk b/main.mk index e47e85fdfb..dfaf7db15e 100644 --- a/main.mk +++ b/main.mk @@ -550,13 +550,13 @@ ST_OPT = -DSQLITE_THREADSAFE=0 # This is the default Makefile target. The objects listed here # are what get build when you type just "make" with no arguments. # -all: sqlite3.h libsqlite3.a sqlite3$(EXE) +all: sqlite3.h sqlite3ext.h libsqlite3.a sqlite3$(EXE) -libsqlite3.a: $(LIBOBJ) +libsqlite3.a: sqlite3.h $(LIBOBJ) $(AR) libsqlite3.a $(LIBOBJ) $(RANLIB) libsqlite3.a -sqlite3$(EXE): shell.c libsqlite3.a sqlite3.h +sqlite3$(EXE): sqlite3.h libsqlite3.a shell.c $(TCCX) $(READLINE_FLAGS) -o sqlite3$(EXE) $(SHELL_OPT) \ shell.c libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB) @@ -824,13 +824,13 @@ fts3_unicode2.o: $(TOP)/ext/fts3/fts3_unicode2.c $(HDR) $(EXTHDR) fts3_write.o: $(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR) $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_write.c -fts5.o: fts5.c +fts5.o: fts5.c sqlite3ext.h sqlite3.h $(TCCX) -DSQLITE_CORE -c fts5.c -json1.o: $(TOP)/ext/misc/json1.c +json1.o: $(TOP)/ext/misc/json1.c sqlite3ext.h sqlite3.h $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/misc/json1.c -stmt.o: $(TOP)/ext/misc/stmt.c +stmt.o: $(TOP)/ext/misc/stmt.c sqlite3ext.h sqlite3.h $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/misc/stmt.c rtree.o: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR) diff --git a/manifest b/manifest index 1f0fed3243..df9622f9fc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests\sfor\ssqlite3session_memory_used()\sinterface. -D 2021-01-20T10:59:47.320 +C Improvements\sto\sthe\sauxiliary\s"main.mk"\smakefile\sso\sthat\sit\sworks\sbetter\swith\nmulti-threaded\sbuilds. +D 2021-01-20T23:01:31.158 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -463,7 +463,7 @@ F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 57451ea5b3d5cd86e9c5324b10c9de184b12e8dcccc31c65d24fbcb55ccd9c53 +F main.mk 443a4ec1ca89ad267cbde45dadc68861154b99c7bd26e7b7dc74303a664002b8 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -1898,7 +1898,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 dc7938d2d715301595dee2fac6880af3716c4b3d1cbe7c3578d7fd30ba146a23 -R 2a7f82e5717f1cb1207576a8070164d7 -U dan -Z 837106ab8ad362dbfd49cfef88809376 +P 5596611f96f3401262b9dadc591bf7e3411d2c4a6f5be5cfe524e203d9820fd1 +R e4325fbe06f6c9247629eb04294fa661 +U drh +Z 1b9b0d992b3d4f78ff264eba5ac968ed diff --git a/manifest.uuid b/manifest.uuid index 92afa750c7..7e5a82c2e6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5596611f96f3401262b9dadc591bf7e3411d2c4a6f5be5cfe524e203d9820fd1 \ No newline at end of file +d1873054d8e1006a370ea7891dbb9a62e7d36ce98cb92b58dcb0daf271265de3 \ No newline at end of file From f380c3f13c2b7da8a9f95768c6062d56b0f81d66 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 21 Jan 2021 15:40:52 +0000 Subject: [PATCH 134/257] Fix a problem caused by using an SQL variable in an OVER clause within a trigger program. FossilOrigin-Name: 4f676466e60ee2a420b7b2deace76f3a733ce1af278347428285715d9c67f022 --- manifest | 23 ++--- manifest.uuid | 2 +- src/attach.c | 198 +++++++++++++++++++------------------------- src/sqliteInt.h | 33 ++++---- test/altertab3.test | 2 +- test/triggerE.test | 2 + 6 files changed, 118 insertions(+), 142 deletions(-) diff --git a/manifest b/manifest index df9622f9fc..c88831d299 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sthe\sauxiliary\s"main.mk"\smakefile\sso\sthat\sit\sworks\sbetter\swith\nmulti-threaded\sbuilds. -D 2021-01-20T23:01:31.158 +C Fix\sa\sproblem\scaused\sby\susing\san\sSQL\svariable\sin\san\sOVER\sclause\swithin\sa\strigger\sprogram. +D 2021-01-21T15:40:52.172 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -477,7 +477,7 @@ F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 36cae0d6e3e91a1996e1a472f8c7242c31a4e38ba4295e3056da198c04fd2a87 F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c -F src/attach.c 0f497c15c4cfe3bdcb214f0dbdbbb6c5ed7e8a9308ac445c7959f5e5780437a9 +F src/attach.c 87102aba5ddac8ef3a8a033ab657e4cae9cc8e846efe93b14029cfffaaf8831e F src/auth.c 8d1df0e2ef8bafbedd4f1fe4baff03eb27507da4bf6e449df3613d383c4018b2 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 @@ -546,7 +546,7 @@ F src/shell.c.in 9ebc74e4f05cfbd0f4a36060fdaeff1da4e9af4458358722bc08c5a1ab9a087 F src/sqlite.h.in 0af968a1fa3c717261e1df0ed105fa7bddb4d82de7e0adb3eab49e6aa81b4de7 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h d921214bba203960de10ea7a9183735ec362a5def5910d468282a8f82e8b4c26 +F src/sqliteInt.h 3e5bc0446611e272b93754265e3265f36249d0458da25e32991fce241d69dbcf F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -652,7 +652,7 @@ F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74 F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b F test/altertab.test 6d7bbac2c4a6ef71b775094a3298fa3a92274d95034ee23157ffba92768e47e6 F test/altertab2.test b0d62f323ca5dab42b0bc028c52e310ebdd13e655e8fac070fe622bad7852c2b -F test/altertab3.test 1db384eb85b4a30b0b332842f5c596b0dc0126f7c61959be3f85ae8b1c271d9a +F test/altertab3.test 2b82fa2236a3a91553d53ae5555d8e723c7eec174c41f1fa62ff497355398479 F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f F test/analyze.test 547bb700f903107b38611b014ca645d6b5bb819f5210d7bf39c40802aafeb7d7 F test/analyze3.test fca2a9de0017becfdcc201647f03b1cfd5ba0e7b5b5c852936e4ec62780cde49 @@ -1617,7 +1617,7 @@ F test/triggerA.test 837be862d8721f903dba3f3ceff05b32e0bee5214cf6ea3da5fadf12d36 F test/triggerB.test 56780c031b454abac2340dbb3b71ac5c56c3d7fe F test/triggerC.test 29f5a28d0fe39e6e2c01f6e1f53f08c0955170ae10a63ad023e33cb0a1682a51 F test/triggerD.test 8e7f3921a92a5797d472732108109e44575fa650 -F test/triggerE.test ede2e4bce4ba802337bd69d39447fa04a938e06d84a8bfc53c76850fc36ed86d +F test/triggerE.test 612969cb57a4ef792059ad6d01af0117e1ae862c283753ffcc9a6428642b22ee F test/triggerF.test 5d76f0a8c428ff87a4d5ed52da06f6096a2c787a1e21b846111dfac4123de3ad F test/triggerG.test 2b816093c91ba73c733cfa8aedcc210ad819d72a98b1da30768a3c56505233e9 F test/triggerupfrom.test d25961fa70a99b6736193da7b49a36d8c1d28d56188f0be6406d4366315cd6e4 @@ -1898,7 +1898,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 5596611f96f3401262b9dadc591bf7e3411d2c4a6f5be5cfe524e203d9820fd1 -R e4325fbe06f6c9247629eb04294fa661 -U drh -Z 1b9b0d992b3d4f78ff264eba5ac968ed +P d1873054d8e1006a370ea7891dbb9a62e7d36ce98cb92b58dcb0daf271265de3 +R 56f323b51c91a7109bc328027a56f7a2 +T *branch * fix-over-trigger +T *sym-fix-over-trigger * +T -sym-trunk * +U dan +Z c7d4efd5b6b0d32bc23a7887ed998edc diff --git a/manifest.uuid b/manifest.uuid index 7e5a82c2e6..faba828e79 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d1873054d8e1006a370ea7891dbb9a62e7d36ce98cb92b58dcb0daf271265de3 \ No newline at end of file +4f676466e60ee2a420b7b2deace76f3a733ce1af278347428285715d9c67f022 \ No newline at end of file diff --git a/src/attach.c b/src/attach.c index 3b5c57f0cc..04274c6a7a 100644 --- a/src/attach.c +++ b/src/attach.c @@ -433,6 +433,63 @@ void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){ } #endif /* SQLITE_OMIT_ATTACH */ +/* +** Expression callback used by sqlite3FixAAAA() routines. +*/ +static int fixExprCb(Walker *p, Expr *pExpr){ + DbFixer *pFix = p->u.pFix; + if( !pFix->bTemp ) ExprSetProperty(pExpr, EP_FromDDL); + if( pExpr->op==TK_VARIABLE ){ + if( pFix->pParse->db->init.busy ){ + pExpr->op = TK_NULL; + }else{ + sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType); + return WRC_Abort; + } + } + return WRC_Continue; +} + +/* +** Select callback used by sqlite3FixAAAA() routines. +*/ +static int fixSelectCb(Walker *p, Select *pSelect){ + DbFixer *pFix = p->u.pFix; + int i; + struct SrcList_item *pItem; + sqlite3 *db = pFix->pParse->db; + int iDb = sqlite3FindDbName(db, pFix->zDb); + SrcList *pList = pSelect->pSrc; + + if( NEVER(pList==0) ) return WRC_Continue; + for(i=0, pItem=pList->a; inSrc; i++, pItem++){ + if( pFix->bTemp==0 ){ + if( pItem->zDatabase && iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){ + sqlite3ErrorMsg(pFix->pParse, + "%s %T cannot reference objects in database %s", + pFix->zType, pFix->pName, pItem->zDatabase); + return WRC_Abort; + } + sqlite3DbFree(db, pItem->zDatabase); + pItem->zDatabase = 0; + pItem->pSchema = pFix->pSchema; + pItem->fg.fromDDL = 1; + } +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) + if( sqlite3WalkExpr(&pFix->w, pList->a[i].pOn) ) return WRC_Abort; +#endif + } + if( pSelect->pWith ){ + int i; + for(i=0; ipWith->nCte; i++){ + if( sqlite3WalkSelect(p, pSelect->pWith->a[i].pSelect) ){ + return WRC_Abort; + } + } + } + return WRC_Continue; +} + /* ** Initialize a DbFixer structure. This routine must be called prior ** to passing the structure to one of the sqliteFixAAAA() routines below. @@ -444,9 +501,7 @@ void sqlite3FixInit( const char *zType, /* "view", "trigger", or "index" */ const Token *pName /* Name of the view, trigger, or index */ ){ - sqlite3 *db; - - db = pParse->db; + sqlite3 *db = pParse->db; assert( db->nDb>iDb ); pFix->pParse = pParse; pFix->zDb = db->aDb[iDb].zDbSName; @@ -454,6 +509,13 @@ void sqlite3FixInit( pFix->zType = zType; pFix->pName = pName; pFix->bTemp = (iDb==1); + pFix->w.pParse = pParse; + pFix->w.xExprCallback = fixExprCb; + pFix->w.xSelectCallback = fixSelectCb; + pFix->w.xSelectCallback2 = 0; + pFix->w.walkerDepth = 0; + pFix->w.eCode = 0; + pFix->w.u.pFix = pFix; } /* @@ -474,115 +536,27 @@ int sqlite3FixSrcList( DbFixer *pFix, /* Context of the fixation */ SrcList *pList /* The Source list to check and modify */ ){ - int i; - struct SrcList_item *pItem; - sqlite3 *db = pFix->pParse->db; - int iDb = sqlite3FindDbName(db, pFix->zDb); - - if( NEVER(pList==0) ) return 0; - - for(i=0, pItem=pList->a; inSrc; i++, pItem++){ - if( pFix->bTemp==0 ){ - if( pItem->zDatabase && iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){ - sqlite3ErrorMsg(pFix->pParse, - "%s %T cannot reference objects in database %s", - pFix->zType, pFix->pName, pItem->zDatabase); - return 1; - } - sqlite3DbFree(db, pItem->zDatabase); - pItem->zDatabase = 0; - pItem->pSchema = pFix->pSchema; - pItem->fg.fromDDL = 1; - } -#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) - if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1; - if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1; -#endif - if( pItem->fg.isTabFunc && sqlite3FixExprList(pFix, pItem->u1.pFuncArg) ){ - return 1; - } + int res = 0; + if( pList ){ + Select s; + memset(&s, 0, sizeof(s)); + s.pSrc = pList; + res = sqlite3WalkSelect(&pFix->w, &s); } - return 0; + return res; } #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) int sqlite3FixSelect( DbFixer *pFix, /* Context of the fixation */ Select *pSelect /* The SELECT statement to be fixed to one database */ ){ - while( pSelect ){ - if( sqlite3FixExprList(pFix, pSelect->pEList) ){ - return 1; - } - if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){ - return 1; - } - if( sqlite3FixExpr(pFix, pSelect->pWhere) ){ - return 1; - } - if( sqlite3FixExprList(pFix, pSelect->pGroupBy) ){ - return 1; - } - if( sqlite3FixExpr(pFix, pSelect->pHaving) ){ - return 1; - } - if( sqlite3FixExprList(pFix, pSelect->pOrderBy) ){ - return 1; - } - if( sqlite3FixExpr(pFix, pSelect->pLimit) ){ - return 1; - } - if( pSelect->pWith ){ - int i; - for(i=0; ipWith->nCte; i++){ - if( sqlite3FixSelect(pFix, pSelect->pWith->a[i].pSelect) ){ - return 1; - } - } - } - pSelect = pSelect->pPrior; - } - return 0; + return sqlite3WalkSelect(&pFix->w, pSelect); } int sqlite3FixExpr( DbFixer *pFix, /* Context of the fixation */ Expr *pExpr /* The expression to be fixed to one database */ ){ - while( pExpr ){ - if( !pFix->bTemp ) ExprSetProperty(pExpr, EP_FromDDL); - if( pExpr->op==TK_VARIABLE ){ - if( pFix->pParse->db->init.busy ){ - pExpr->op = TK_NULL; - }else{ - sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType); - return 1; - } - } - if( ExprHasProperty(pExpr, EP_TokenOnly|EP_Leaf) ) break; - if( ExprHasProperty(pExpr, EP_xIsSelect) ){ - if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1; - }else{ - if( sqlite3FixExprList(pFix, pExpr->x.pList) ) return 1; - } - if( sqlite3FixExpr(pFix, pExpr->pRight) ){ - return 1; - } - pExpr = pExpr->pLeft; - } - return 0; -} -int sqlite3FixExprList( - DbFixer *pFix, /* Context of the fixation */ - ExprList *pList /* The expression to be fixed to one database */ -){ - int i; - struct ExprList_item *pItem; - if( pList==0 ) return 0; - for(i=0, pItem=pList->a; inExpr; i++, pItem++){ - if( sqlite3FixExpr(pFix, pItem->pExpr) ){ - return 1; - } - } - return 0; + return sqlite3WalkExpr(&pFix->w, pExpr); } #endif @@ -592,25 +566,20 @@ int sqlite3FixTriggerStep( TriggerStep *pStep /* The trigger step be fixed to one database */ ){ while( pStep ){ - if( sqlite3FixSelect(pFix, pStep->pSelect) ){ - return 1; - } - if( sqlite3FixExpr(pFix, pStep->pWhere) ){ - return 1; - } - if( sqlite3FixExprList(pFix, pStep->pExprList) ){ - return 1; - } - if( pStep->pFrom && sqlite3FixSrcList(pFix, pStep->pFrom) ){ + if( sqlite3WalkSelect(&pFix->w, pStep->pSelect) + || sqlite3WalkExpr(&pFix->w, pStep->pWhere) + || sqlite3WalkExprList(&pFix->w, pStep->pExprList) + || sqlite3FixSrcList(pFix, pStep->pFrom) + ){ return 1; } #ifndef SQLITE_OMIT_UPSERT if( pStep->pUpsert ){ Upsert *pUp = pStep->pUpsert; - if( sqlite3FixExprList(pFix, pUp->pUpsertTarget) - || sqlite3FixExpr(pFix, pUp->pUpsertTargetWhere) - || sqlite3FixExprList(pFix, pUp->pUpsertSet) - || sqlite3FixExpr(pFix, pUp->pUpsertWhere) + if( sqlite3WalkExprList(&pFix->w, pUp->pUpsertTarget) + || sqlite3WalkExpr(&pFix->w, pUp->pUpsertTargetWhere) + || sqlite3WalkExprList(&pFix->w, pUp->pUpsertSet) + || sqlite3WalkExpr(&pFix->w, pUp->pUpsertWhere) ){ return 1; } @@ -618,6 +587,7 @@ int sqlite3FixTriggerStep( #endif pStep = pStep->pNext; } + return 0; } #endif diff --git a/src/sqliteInt.h b/src/sqliteInt.h index e1e0707bf3..510aab1ca5 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1137,6 +1137,7 @@ typedef struct Bitvec Bitvec; typedef struct CollSeq CollSeq; typedef struct Column Column; typedef struct Db Db; +typedef struct DbFixer DbFixer; typedef struct Schema Schema; typedef struct Expr Expr; typedef struct ExprList ExprList; @@ -3650,21 +3651,6 @@ struct TriggerStep { TriggerStep *pLast; /* Last element in link-list. Valid for 1st elem only */ }; -/* -** The following structure contains information used by the sqliteFix... -** routines as they walk the parse tree to make database references -** explicit. -*/ -typedef struct DbFixer DbFixer; -struct DbFixer { - Parse *pParse; /* The parsing context. Error messages written here */ - Schema *pSchema; /* Fix items to this schema */ - u8 bTemp; /* True for TEMP schema entries */ - const char *zDb; /* Make sure all objects are contained in this database */ - const char *zType; /* Type of the container - used for error messages */ - const Token *pName; /* Name of the container - used for error messages */ -}; - /* ** An objected used to accumulate the text of a string where we ** do not necessarily know how big the string will be in the end. @@ -3815,9 +3801,25 @@ struct Walker { struct RenameCtx *pRename; /* RENAME COLUMN context */ struct Table *pTab; /* Table of generated column */ struct SrcList_item *pSrcItem; /* A single FROM clause item */ + DbFixer *pFix; } u; }; +/* +** The following structure contains information used by the sqliteFix... +** routines as they walk the parse tree to make database references +** explicit. +*/ +struct DbFixer { + Parse *pParse; /* The parsing context. Error messages written here */ + Walker w; /* Walker object */ + Schema *pSchema; /* Fix items to this schema */ + u8 bTemp; /* True for TEMP schema entries */ + const char *zDb; /* Make sure all objects are contained in this database */ + const char *zType; /* Type of the container - used for error messages */ + const Token *pName; /* Name of the container - used for error messages */ +}; + /* Forward declarations */ int sqlite3WalkExpr(Walker*, Expr*); int sqlite3WalkExprList(Walker*, ExprList*); @@ -4527,7 +4529,6 @@ void sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*); int sqlite3FixSrcList(DbFixer*, SrcList*); int sqlite3FixSelect(DbFixer*, Select*); int sqlite3FixExpr(DbFixer*, Expr*); -int sqlite3FixExprList(DbFixer*, ExprList*); int sqlite3FixTriggerStep(DbFixer*, TriggerStep*); int sqlite3RealSameAsInt(double,sqlite3_int64); void sqlite3Int64ToText(i64,char*); diff --git a/test/altertab3.test b/test/altertab3.test index 10d9ef32e3..1823b21edf 100644 --- a/test/altertab3.test +++ b/test/altertab3.test @@ -253,7 +253,7 @@ do_execsql_test 11.1 { do_catchsql_test 11.2 { ALTER TABLE t1 RENAME TO t1x; -} {1 {error in trigger b: no such table: abc}} +} {1 {error in trigger b: no such table: main.abc}} do_execsql_test 11.3 { DROP TRIGGER b; diff --git a/test/triggerE.test b/test/triggerE.test index 9db7035325..de4b068582 100644 --- a/test/triggerE.test +++ b/test/triggerE.test @@ -58,6 +58,8 @@ foreach {tn defn} { 8 { BEFORE UPDATE ON t1 BEGIN UPDATE t2 SET c = ?; END; } 9 { BEFORE UPDATE ON t1 BEGIN UPDATE t2 SET c = 1 WHERE d = ?; END; } 10 { AFTER INSERT ON t1 BEGIN SELECT * FROM pragma_stats(?); END; } + 11 { BEFORE INSERT ON t1 BEGIN + INSERT INTO t1 SELECT max(b) OVER(ORDER BY $1) FROM t1; END } } { catchsql {drop trigger tr1} do_catchsql_test 1.1.$tn "CREATE TRIGGER tr1 $defn" [list 1 $errmsg] From 6cca0aa9df3d4e18fd7eed0b9867120e6cc1e482 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 21 Jan 2021 17:54:41 +0000 Subject: [PATCH 135/257] Always enable the IS NOT NULL optimization, even if STAT4 is not enabled. FossilOrigin-Name: fc98218cf69e63bdb9e5f154521a341508502cd8cfe04cb870cabee2d99e0cb3 --- manifest | 20 +++++++------ manifest.uuid | 2 +- src/whereInt.h | 6 +--- src/whereexpr.c | 78 ++++++++++++++++++++++++------------------------- 4 files changed, 51 insertions(+), 55 deletions(-) diff --git a/manifest b/manifest index c2ea1b0e81..008fa8c252 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\scaused\sby\susing\san\sSQL\svariable\sin\san\sOVER\sclause\swithin\sa\strigger\sprogram. -D 2021-01-21T16:02:14.840 +C Always\senable\sthe\sIS\sNOT\sNULL\soptimization,\seven\sif\sSTAT4\sis\snot\senabled. +D 2021-01-21T17:54:41.795 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -629,9 +629,9 @@ F src/wal.c 69e770e96fd56cc21608992bf2c6f1f3dc5cf2572d0495c6a643b06c3a679f14 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c d9c4e454ebb9499e908aa62d55b8994c375cf5355ac78f60d45af17f7890701c F src/where.c 0e6abb22a2323fec80b450825593c26a2ad8f4815d1ee3af9969d8f6144bf681 -F src/whereInt.h 9a3f577619f07700d16d89eeb2f3d94d6b7ed7f109c2dacf0ce8844921549506 +F src/whereInt.h ae03b5e3a4cca9bd9cb1b7d3c63faf8f1f177200fc8cecc87d3d0cab6ca338e6 F src/wherecode.c a3a1aff30fe99a818d8e7c607980f033f40c68d890e03ed25838b9dbb7908bee -F src/whereexpr.c a022b4f447c0fb0674e172a9a303537ea5055df60d579f99cec7ead18e8c453f +F src/whereexpr.c 1f11bdd204ad021f5935df6e7726b4f1dbdd3157a4f31d0dafc9c457e5e545a8 F src/window.c edd6f5e25a1e8f2b6f5305b7f5f7da7bb35f07f0d432b255b1d4c2fcab4205aa F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -1898,8 +1898,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 d1873054d8e1006a370ea7891dbb9a62e7d36ce98cb92b58dcb0daf271265de3 4f676466e60ee2a420b7b2deace76f3a733ce1af278347428285715d9c67f022 -R 56f323b51c91a7109bc328027a56f7a2 -T +closed 4f676466e60ee2a420b7b2deace76f3a733ce1af278347428285715d9c67f022 -U dan -Z af485d37bfb17e22d383f2711ee5f268 +P 02264ab6a02d6cc95cf865920bcbaf4307d034640e6e4f3371b009ae9818540e +R 8df6cd517dfa239c965fc40092a79782 +T *branch * isnotnull-opt +T *sym-isnotnull-opt * +T -sym-trunk * +U drh +Z d06e074a8f142c72ee8a673bfd500f4d diff --git a/manifest.uuid b/manifest.uuid index 57afc8f5ef..1e251fa4a5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -02264ab6a02d6cc95cf865920bcbaf4307d034640e6e4f3371b009ae9818540e \ No newline at end of file +fc98218cf69e63bdb9e5f154521a341508502cd8cfe04cb870cabee2d99e0cb3 \ No newline at end of file diff --git a/src/whereInt.h b/src/whereInt.h index f8509996fa..89a463dc38 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -270,11 +270,7 @@ struct WhereTerm { #define TERM_ORINFO 0x0010 /* Need to free the WhereTerm.u.pOrInfo object */ #define TERM_ANDINFO 0x0020 /* Need to free the WhereTerm.u.pAndInfo obj */ #define TERM_OR_OK 0x0040 /* Used during OR-clause processing */ -#ifdef SQLITE_ENABLE_STAT4 -# define TERM_VNULL 0x0080 /* Manufactured x>NULL or x<=NULL term */ -#else -# define TERM_VNULL 0x0000 /* Disabled if not using stat4 */ -#endif +#define TERM_VNULL 0x0080 /* Manufactured x>NULL or x<=NULL term */ #define TERM_LIKEOPT 0x0100 /* Virtual terms from the LIKE optimization */ #define TERM_LIKECOND 0x0200 /* Conditionally this LIKE operator term */ #define TERM_LIKE 0x0400 /* The original LIKE operator */ diff --git a/src/whereexpr.c b/src/whereexpr.c index 5cfdad67c1..0dc56ea8a3 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1466,6 +1466,41 @@ static void exprAnalyze( } } + /* The form "x IS NOT NULL" can sometimes be evaluated more efficiently + ** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a + ** virtual term of that form. + ** + ** The virtual term must be tagged with TERM_VNULL. + */ + else if( pExpr->op==TK_NOTNULL ){ + if( pExpr->pLeft->op==TK_COLUMN + && pExpr->pLeft->iColumn>=0 + && !ExprHasProperty(pExpr, EP_FromJoin) + ){ + Expr *pNewExpr; + Expr *pLeft = pExpr->pLeft; + int idxNew; + WhereTerm *pNewTerm; + + pNewExpr = sqlite3PExpr(pParse, TK_GT, + sqlite3ExprDup(db, pLeft, 0), + sqlite3ExprAlloc(db, TK_NULL, 0, 0)); + + idxNew = whereClauseInsert(pWC, pNewExpr, + TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL); + if( idxNew ){ + pNewTerm = &pWC->a[idxNew]; + pNewTerm->prereqRight = 0; + pNewTerm->leftCursor = pLeft->iTable; + pNewTerm->u.x.leftColumn = pLeft->iColumn; + pNewTerm->eOperator = WO_GT; + markTermAsChild(pWC, idxNew, idxTerm); + pTerm = &pWC->a[idxTerm]; + pTerm->wtFlags |= TERM_COPIED; + pNewTerm->prereqAll = pTerm->prereqAll; + } + } + } #ifndef SQLITE_OMIT_LIKE_OPTIMIZATION /* Add constraints to reduce the search space on a LIKE or GLOB @@ -1637,7 +1672,9 @@ static void exprAnalyze( ** This only works if the RHS is a simple SELECT (not a compound) that does ** not use window functions. */ - if( pWC->op==TK_AND && pExpr->op==TK_IN && pTerm->u.x.iField==0 + if( pWC->op==TK_AND + && pExpr->op==TK_IN + && pTerm->u.x.iField==0 && pExpr->pLeft->op==TK_VECTOR && pExpr->x.pSelect->pPrior==0 #ifndef SQLITE_OMIT_WINDOWFUNC @@ -1654,45 +1691,6 @@ static void exprAnalyze( } } -#ifdef SQLITE_ENABLE_STAT4 - /* When sqlite_stat4 histogram data is available an operator of the - ** form "x IS NOT NULL" can sometimes be evaluated more efficiently - ** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a - ** virtual term of that form. - ** - ** Note that the virtual term must be tagged with TERM_VNULL. - */ - if( pExpr->op==TK_NOTNULL - && pExpr->pLeft->op==TK_COLUMN - && pExpr->pLeft->iColumn>=0 - && !ExprHasProperty(pExpr, EP_FromJoin) - && OptimizationEnabled(db, SQLITE_Stat4) - ){ - Expr *pNewExpr; - Expr *pLeft = pExpr->pLeft; - int idxNew; - WhereTerm *pNewTerm; - - pNewExpr = sqlite3PExpr(pParse, TK_GT, - sqlite3ExprDup(db, pLeft, 0), - sqlite3ExprAlloc(db, TK_NULL, 0, 0)); - - idxNew = whereClauseInsert(pWC, pNewExpr, - TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL); - if( idxNew ){ - pNewTerm = &pWC->a[idxNew]; - pNewTerm->prereqRight = 0; - pNewTerm->leftCursor = pLeft->iTable; - pNewTerm->u.x.leftColumn = pLeft->iColumn; - pNewTerm->eOperator = WO_GT; - markTermAsChild(pWC, idxNew, idxTerm); - pTerm = &pWC->a[idxTerm]; - pTerm->wtFlags |= TERM_COPIED; - pNewTerm->prereqAll = pTerm->prereqAll; - } - } -#endif /* SQLITE_ENABLE_STAT4 */ - /* Prevent ON clause terms of a LEFT JOIN from being used to drive ** an index for tables to the left of the join. */ From 71aff85503b826122aa22db1e341b87c29a5b305 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 21 Jan 2021 20:42:36 +0000 Subject: [PATCH 136/257] Performance optimizations in exprAnalyze() FossilOrigin-Name: 6d60cf540b8cc231448175f1e16e1f4f7a0aee26898570a5b8a09c89fae53c02 --- manifest | 15 +++--- manifest.uuid | 2 +- src/whereexpr.c | 124 ++++++++++++++++++++++++------------------------ 3 files changed, 70 insertions(+), 71 deletions(-) diff --git a/manifest b/manifest index 008fa8c252..a19e4809b7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Always\senable\sthe\sIS\sNOT\sNULL\soptimization,\seven\sif\sSTAT4\sis\snot\senabled. -D 2021-01-21T17:54:41.795 +C Performance\soptimizations\sin\sexprAnalyze() +D 2021-01-21T20:42:36.445 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -631,7 +631,7 @@ F src/walker.c d9c4e454ebb9499e908aa62d55b8994c375cf5355ac78f60d45af17f7890701c F src/where.c 0e6abb22a2323fec80b450825593c26a2ad8f4815d1ee3af9969d8f6144bf681 F src/whereInt.h ae03b5e3a4cca9bd9cb1b7d3c63faf8f1f177200fc8cecc87d3d0cab6ca338e6 F src/wherecode.c a3a1aff30fe99a818d8e7c607980f033f40c68d890e03ed25838b9dbb7908bee -F src/whereexpr.c 1f11bdd204ad021f5935df6e7726b4f1dbdd3157a4f31d0dafc9c457e5e545a8 +F src/whereexpr.c a182038cf7d10aa9a95a96b8563a34f34990323cf307dee6559e995961966d43 F src/window.c edd6f5e25a1e8f2b6f5305b7f5f7da7bb35f07f0d432b255b1d4c2fcab4205aa F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -1898,10 +1898,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 02264ab6a02d6cc95cf865920bcbaf4307d034640e6e4f3371b009ae9818540e -R 8df6cd517dfa239c965fc40092a79782 -T *branch * isnotnull-opt -T *sym-isnotnull-opt * -T -sym-trunk * +P fc98218cf69e63bdb9e5f154521a341508502cd8cfe04cb870cabee2d99e0cb3 +R f46bf0fe436bc977a841647e6a3e3ebc U drh -Z d06e074a8f142c72ee8a673bfd500f4d +Z 4d2704e467917a55449d9cd09c1bd5e8 diff --git a/manifest.uuid b/manifest.uuid index 1e251fa4a5..3639833e1d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fc98218cf69e63bdb9e5f154521a341508502cd8cfe04cb870cabee2d99e0cb3 \ No newline at end of file +6d60cf540b8cc231448175f1e16e1f4f7a0aee26898570a5b8a09c89fae53c02 \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index 0dc56ea8a3..f69210975c 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1502,6 +1502,7 @@ static void exprAnalyze( } } + #ifndef SQLITE_OMIT_LIKE_OPTIMIZATION /* Add constraints to reduce the search space on a LIKE or GLOB ** operator. @@ -1516,7 +1517,8 @@ static void exprAnalyze( ** bound is made all lowercase so that the bounds also work when comparing ** BLOBs. */ - if( pWC->op==TK_AND + else if( pExpr->op==TK_FUNCTION + && pWC->op==TK_AND && isLikeOrGlob(pParse, pExpr, &pStr1, &isComplete, &noCase) ){ Expr *pLeft; /* LHS of LIKE/GLOB operator */ @@ -1586,6 +1588,65 @@ static void exprAnalyze( } #endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */ + /* If there is a vector == or IS term - e.g. "(a, b) == (?, ?)" - create + ** new terms for each component comparison - "a = ?" and "b = ?". The + ** new terms completely replace the original vector comparison, which is + ** no longer used. + ** + ** This is only required if at least one side of the comparison operation + ** is not a sub-select. */ + if( (pExpr->op==TK_EQ || pExpr->op==TK_IS) + && (nLeft = sqlite3ExprVectorSize(pExpr->pLeft))>1 + && sqlite3ExprVectorSize(pExpr->pRight)==nLeft + && ( (pExpr->pLeft->flags & EP_xIsSelect)==0 + || (pExpr->pRight->flags & EP_xIsSelect)==0) + && pWC->op==TK_AND + ){ + int i; + for(i=0; ipLeft, i); + Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i); + + pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight); + transferJoinMarkings(pNew, pExpr); + idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC); + exprAnalyze(pSrc, pWC, idxNew); + } + pTerm = &pWC->a[idxTerm]; + pTerm->wtFlags |= TERM_CODED|TERM_VIRTUAL; /* Disable the original */ + pTerm->eOperator = 0; + } + + /* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create + ** a virtual term for each vector component. The expression object + ** used by each such virtual term is pExpr (the full vector IN(...) + ** expression). The WhereTerm.u.x.iField variable identifies the index within + ** the vector on the LHS that the virtual term represents. + ** + ** This only works if the RHS is a simple SELECT (not a compound) that does + ** not use window functions. + */ + else if( pExpr->op==TK_IN + && pTerm->u.x.iField==0 + && pExpr->pLeft->op==TK_VECTOR + && pExpr->x.pSelect->pPrior==0 +#ifndef SQLITE_OMIT_WINDOWFUNC + && pExpr->x.pSelect->pWin==0 +#endif + && pWC->op==TK_AND + ){ + int i; + for(i=0; ipLeft); i++){ + int idxNew; + idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL); + pWC->a[idxNew].u.x.iField = i+1; + exprAnalyze(pSrc, pWC, idxNew); + markTermAsChild(pWC, idxNew, idxTerm); + } + } + #ifndef SQLITE_OMIT_VIRTUALTABLE /* Add a WO_AUX auxiliary term to the constraint set if the ** current expression is of the form "column OP expr" where OP @@ -1596,7 +1657,7 @@ static void exprAnalyze( ** virtual tables. The native query optimizer does not attempt ** to do anything with MATCH functions. */ - if( pWC->op==TK_AND ){ + else if( pWC->op==TK_AND ){ Expr *pRight = 0, *pLeft = 0; int res = isAuxiliaryVtabOperator(db, pExpr, &eOp2, &pLeft, &pRight); while( res-- > 0 ){ @@ -1632,65 +1693,6 @@ static void exprAnalyze( } #endif /* SQLITE_OMIT_VIRTUALTABLE */ - /* If there is a vector == or IS term - e.g. "(a, b) == (?, ?)" - create - ** new terms for each component comparison - "a = ?" and "b = ?". The - ** new terms completely replace the original vector comparison, which is - ** no longer used. - ** - ** This is only required if at least one side of the comparison operation - ** is not a sub-select. */ - if( pWC->op==TK_AND - && (pExpr->op==TK_EQ || pExpr->op==TK_IS) - && (nLeft = sqlite3ExprVectorSize(pExpr->pLeft))>1 - && sqlite3ExprVectorSize(pExpr->pRight)==nLeft - && ( (pExpr->pLeft->flags & EP_xIsSelect)==0 - || (pExpr->pRight->flags & EP_xIsSelect)==0) - ){ - int i; - for(i=0; ipLeft, i); - Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i); - - pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight); - transferJoinMarkings(pNew, pExpr); - idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC); - exprAnalyze(pSrc, pWC, idxNew); - } - pTerm = &pWC->a[idxTerm]; - pTerm->wtFlags |= TERM_CODED|TERM_VIRTUAL; /* Disable the original */ - pTerm->eOperator = 0; - } - - /* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create - ** a virtual term for each vector component. The expression object - ** used by each such virtual term is pExpr (the full vector IN(...) - ** expression). The WhereTerm.u.x.iField variable identifies the index within - ** the vector on the LHS that the virtual term represents. - ** - ** This only works if the RHS is a simple SELECT (not a compound) that does - ** not use window functions. - */ - if( pWC->op==TK_AND - && pExpr->op==TK_IN - && pTerm->u.x.iField==0 - && pExpr->pLeft->op==TK_VECTOR - && pExpr->x.pSelect->pPrior==0 -#ifndef SQLITE_OMIT_WINDOWFUNC - && pExpr->x.pSelect->pWin==0 -#endif - ){ - int i; - for(i=0; ipLeft); i++){ - int idxNew; - idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL); - pWC->a[idxNew].u.x.iField = i+1; - exprAnalyze(pSrc, pWC, idxNew); - markTermAsChild(pWC, idxNew, idxTerm); - } - } - /* Prevent ON clause terms of a LEFT JOIN from being used to drive ** an index for tables to the left of the join. */ From 906602ac3f04fd329e83ccb4567543276721e843 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 21 Jan 2021 21:36:25 +0000 Subject: [PATCH 137/257] Do not allow VACUUM to resize the page_size to 512 if the reserve_byte value is 31 or greater. [forum:/forumpost/e807885dc5|forum post e807885dc5]. FossilOrigin-Name: d5ea75a09d4bf61262cead2604e35d8331b727c504807592d09f5d9e01ce794a --- manifest | 15 +++++++-------- manifest.uuid | 2 +- src/btree.c | 1 + 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index c2ea1b0e81..0cc6359996 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\scaused\sby\susing\san\sSQL\svariable\sin\san\sOVER\sclause\swithin\sa\strigger\sprogram. -D 2021-01-21T16:02:14.840 +C Do\snot\sallow\sVACUUM\sto\sresize\sthe\spage_size\sto\s512\sif\sthe\sreserve_byte\svalue\nis\s31\sor\sgreater.\s[forum:/forumpost/e807885dc5|forum\spost\se807885dc5]. +D 2021-01-21T21:36:25.588 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -482,7 +482,7 @@ F src/auth.c 8d1df0e2ef8bafbedd4f1fe4baff03eb27507da4bf6e449df3613d383c4018b2 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 0f9cb686871ae668817673f0823b55d1bcadbc86ea28bd22c590b064a8322d5a +F src/btree.c 47d9fe97d5c0d74506154e3597f8a23b81a00080751dc4d11fec91ee22796f4c F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 F src/build.c d4c06261b0e532523ede58dc511381a7a9c155132e4b65a6bb2ff76fe657793a @@ -1898,8 +1898,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 d1873054d8e1006a370ea7891dbb9a62e7d36ce98cb92b58dcb0daf271265de3 4f676466e60ee2a420b7b2deace76f3a733ce1af278347428285715d9c67f022 -R 56f323b51c91a7109bc328027a56f7a2 -T +closed 4f676466e60ee2a420b7b2deace76f3a733ce1af278347428285715d9c67f022 -U dan -Z af485d37bfb17e22d383f2711ee5f268 +P 02264ab6a02d6cc95cf865920bcbaf4307d034640e6e4f3371b009ae9818540e +R 48ee8ca426c1edea6b9f06bdf29c3bdc +U drh +Z cbe3ac807720d5b866771e6277e15b90 diff --git a/manifest.uuid b/manifest.uuid index 57afc8f5ef..949cc47910 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -02264ab6a02d6cc95cf865920bcbaf4307d034640e6e4f3371b009ae9818540e \ No newline at end of file +d5ea75a09d4bf61262cead2604e35d8331b727c504807592d09f5d9e01ce794a \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index a587332ce2..a3fbfef043 100644 --- a/src/btree.c +++ b/src/btree.c @@ -2901,6 +2901,7 @@ int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){ ((pageSize-1)&pageSize)==0 ){ assert( (pageSize & 7)==0 ); assert( !pBt->pCursor ); + if( nReserve>32 && pageSize==512 ) pageSize = 1024; pBt->pageSize = (u32)pageSize; freeTempSpace(pBt); } From e5ceaac446d11372cd4b20cd5d9033a8e868c66a Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 25 Jan 2021 21:24:14 +0000 Subject: [PATCH 138/257] Add an extra log message in the case of an SQLITE_CORRUPT_INDEX error. FossilOrigin-Name: 0571c24177d77ac966bcf42cb8ab00fdf541ce84af1468c8ef0b60c48c45a22f --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/vdbe.c | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 192c496e18..e0a9937e58 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\squery\splanner\sto\senable\sit\sto\suse\san\sindex\sfor\sIS\sNOT\sNULL\nconstraints,\seven\sif\sSTAT4\sis\snot\senabled. -D 2021-01-22T21:23:12.101 +C Add\san\sextra\slog\smessage\sin\sthe\scase\sof\san\sSQLITE_CORRUPT_INDEX\serror. +D 2021-01-25T21:24:14.510 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -613,7 +613,7 @@ F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 41c7a72da1df47864faa378a1c720b38adb288c6838cb6be5594511b6287a048 F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286 -F src/vdbe.c fd3ae827dea9da118d22c172ad183888120070d4c709bd0a5a97af7749246783 +F src/vdbe.c 102d21260bddbb43c845603c3a2d6b4f3762e72f836ccda12991f291485d2539 F src/vdbe.h 83603854bfa5851af601fc0947671eb260f4363e62e960e8a994fb9bbcd2aaa1 F src/vdbeInt.h 3ca5e9fd6e095a8b6cf6bc3587a46fc93499503b2fe48951e1034ba9e2ce2f6e F src/vdbeapi.c c5e7cb2ab89a24d7f723e87b508f21bfb1359a04db5277d8a99fd1e015c12eb9 @@ -1898,8 +1898,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 d5ea75a09d4bf61262cead2604e35d8331b727c504807592d09f5d9e01ce794a 0b42f9eb5dd710991af3cf4b16464b22db9539361d618e50eaa4d43c811577b4 -R dd365517921749a64a3732b6a8560730 -T +closed 0b42f9eb5dd710991af3cf4b16464b22db9539361d618e50eaa4d43c811577b4 +P 7b2a7c7314d2239992dc1d707280f3b75ba75bb074ba1e77b55cad01ca7fd51b +R c809d928cb746073aedc3f5cce34c965 U drh -Z 6ed219298d2cd360981b4aacc96226a6 +Z 375659ad9a05c828e459b8457d7233ea diff --git a/manifest.uuid b/manifest.uuid index bdab433263..93a9669da3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7b2a7c7314d2239992dc1d707280f3b75ba75bb074ba1e77b55cad01ca7fd51b \ No newline at end of file +0571c24177d77ac966bcf42cb8ab00fdf541ce84af1468c8ef0b60c48c45a22f \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index bcfc5df8d9..3a00515e57 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5912,7 +5912,7 @@ case OP_IdxDelete: { rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE); if( rc ) goto abort_due_to_error; }else if( pOp->p5 ){ - rc = SQLITE_CORRUPT_INDEX; + rc = sqlite3ReportError(SQLITE_CORRUPT_INDEX, __LINE__, "index corruption"); goto abort_due_to_error; } assert( pC->deferredMoveto==0 ); From df1b52e72795ad08fc1b80027f3d4fbe6be408c4 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 27 Jan 2021 17:15:06 +0000 Subject: [PATCH 139/257] Ensure a cursor used by the SeekScan operator does not point to a valid row on the first iteration of the loop. Possible fix for [2d6e8400]. FossilOrigin-Name: 390cf60a286b13f454429f4652a133f95a7891a75c1ec6d16cd39990590fd3fb --- manifest | 19 +++++++++++-------- manifest.uuid | 2 +- src/wherecode.c | 6 ++++++ test/in4.test | 28 ++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index e0a9937e58..00a745920f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\san\sextra\slog\smessage\sin\sthe\scase\sof\san\sSQLITE_CORRUPT_INDEX\serror. -D 2021-01-25T21:24:14.510 +C Ensure\sa\scursor\sused\sby\sthe\sSeekScan\soperator\sdoes\snot\spoint\sto\sa\svalid\srow\son\sthe\sfirst\siteration\sof\sthe\sloop.\sPossible\sfix\sfor\s[2d6e8400]. +D 2021-01-27T17:15:06.938 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -630,7 +630,7 @@ F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c d9c4e454ebb9499e908aa62d55b8994c375cf5355ac78f60d45af17f7890701c F src/where.c 0e6abb22a2323fec80b450825593c26a2ad8f4815d1ee3af9969d8f6144bf681 F src/whereInt.h ae03b5e3a4cca9bd9cb1b7d3c63faf8f1f177200fc8cecc87d3d0cab6ca338e6 -F src/wherecode.c a3a1aff30fe99a818d8e7c607980f033f40c68d890e03ed25838b9dbb7908bee +F src/wherecode.c 43a63441f8662ddf86b15975683a502ec33f08167e9636f4d19e38e265e95fd9 F src/whereexpr.c a182038cf7d10aa9a95a96b8563a34f34990323cf307dee6559e995961966d43 F src/window.c edd6f5e25a1e8f2b6f5305b7f5f7da7bb35f07f0d432b255b1d4c2fcab4205aa F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1064,7 +1064,7 @@ F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8 F test/in.test 688ed2011d922d83141a45af431601738674a4c0bdde34b6351f688b82a169b3 F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0 -F test/in4.test 65460600d48933adba4283c6ebd089aae173d16136ab9d01f74c89089090c5a5 +F test/in4.test 64ac9c767ac5af562f066a40163d4202f8fa3be05d264ec65d6258e74606b30c F test/in5.test b32ce7f4a93f44c5dee94af16886d922cc16ebe33c8e1765c73d4049d0f4b40f F test/in6.test 8562d0945195cab3cc4ab3794e9118e72cb44c43f785c2b04d48a9d06ca6b4ec F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822 @@ -1898,7 +1898,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 7b2a7c7314d2239992dc1d707280f3b75ba75bb074ba1e77b55cad01ca7fd51b -R c809d928cb746073aedc3f5cce34c965 -U drh -Z 375659ad9a05c828e459b8457d7233ea +P 0571c24177d77ac966bcf42cb8ab00fdf541ce84af1468c8ef0b60c48c45a22f +R 4574041b82ab28e377188abbe28af4d5 +T *branch * fix-2d6e8400 +T *sym-fix-2d6e8400 * +T -sym-trunk * +U dan +Z e3d30b9ac2ed7bc4de1a15a8bab650b5 diff --git a/manifest.uuid b/manifest.uuid index 93a9669da3..8fc9323ad9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0571c24177d77ac966bcf42cb8ab00fdf541ce84af1468c8ef0b60c48c45a22f \ No newline at end of file +390cf60a286b13f454429f4652a133f95a7891a75c1ec6d16cd39990590fd3fb \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 4afe0ac9c9..17dc36152d 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1743,6 +1743,12 @@ Bitmask sqlite3WhereCodeOneLoopStart( SWAP(u8, nBtm, nTop); } + if( iLevel>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)!=0 ){ + /* In case OP_SeekScan is used, ensure that the index cursor does not + ** point to a valid row for the first iteration of this loop. */ + sqlite3VdbeAddOp1(v, OP_NullRow, iIdxCur); + } + /* Generate code to evaluate all constraint terms using == or IN ** and store the values of those terms in an array of registers ** starting at regBase. diff --git a/test/in4.test b/test/in4.test index 37eafdebec..bbb32d8a7a 100644 --- a/test/in4.test +++ b/test/in4.test @@ -365,4 +365,32 @@ ifcapable rtree { } {{} 1 {} {} {}} } +#------------------------------------------------------------------------- +reset_db +do_execsql_test 8.0 { + CREATE TABLE t1(x INTEGER PRIMARY KEY, y); + CREATE UNIQUE INDEX t1y ON t1(y); + INSERT INTO t1 VALUES(111, 'AAA'),(222, 'BBB'),(333, 'CCC'); + CREATE TABLE t2(z); + INSERT INTO t2 VALUES('BBB'),('AAA'); + ANALYZE sqlite_schema; + INSERT INTO sqlite_stat1 VALUES('t1', 't1y','100 1'); +} + +db close +sqlite3 db test.db + +do_execsql_test 8.1 { + SELECT t1.x FROM t2 CROSS JOIN t1 WHERE t2.z = t1.y; +} {222 111} + +do_execsql_test 8.2 { + SELECT t1.x FROM t2 CROSS JOIN t1 WHERE t2.z = t1.y AND +t1.x IN (111, 222); +} {222 111} + +do_execsql_test 8.3 { + SELECT t1.x FROM t2 CROSS JOIN t1 WHERE t2.z = t1.y AND t1.x IN (111, 222); +} {222 111} + + finish_test From f54a80fe5c4afa61f17ec3380a4201b1fda630d7 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 29 Jan 2021 13:47:36 +0000 Subject: [PATCH 140/257] Performance optimization (and size reduction) in sqlite3TriggerList() for the common case where there are no TEMP triggers. FossilOrigin-Name: 0defaf730bdc82212a5d3feeb2e16f16423b1691b0aaa7da1787eb82ea39ae9e --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/trigger.c | 22 +++++++++++++--------- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index df58f37956..7045fd7798 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sissue\swith\sIN\soperator\soptimization\sintroduced\sby\ncheck-in\s[4a43430fd23f8835]\sand\sdescribed\sby\sticket\s[ee51301f316c09e9]. -D 2021-01-27T19:15:06.983 +C Performance\soptimization\s(and\ssize\sreduction)\sin\ssqlite3TriggerList()\sfor\sthe\ncommon\scase\swhere\sthere\sare\sno\sTEMP\striggers. +D 2021-01-29T13:47:36.426 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -607,7 +607,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda -F src/trigger.c 29680c54c1aa088fa1b4d50137d75669a40d5ef814394e321fab1e547868e3d3 +F src/trigger.c 731ea5ed6b308574b7dc2a5d2a9187ef5510a3692cc1ea06a34608a084b8f376 F src/update.c 9f126204a6acb96bbe47391ae48e0fc579105d8e76a6d9c4fab3271367476580 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 @@ -1898,8 +1898,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 0571c24177d77ac966bcf42cb8ab00fdf541ce84af1468c8ef0b60c48c45a22f 390cf60a286b13f454429f4652a133f95a7891a75c1ec6d16cd39990590fd3fb -R 4574041b82ab28e377188abbe28af4d5 -T +closed 390cf60a286b13f454429f4652a133f95a7891a75c1ec6d16cd39990590fd3fb +P 9dc7fc9f04d5c14fc436e5ff5b4c06c1969ddde5857ebeb5dccd59b7c748c339 +R 0b7a0544b0d15fb4a458f0ab87fbb410 U drh -Z 071fbdee3969843efb30cf74f43578ee +Z 6a477571c6e856bdd183f551e55df63b diff --git a/manifest.uuid b/manifest.uuid index 29b10f4d3b..6f87f82bcf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9dc7fc9f04d5c14fc436e5ff5b4c06c1969ddde5857ebeb5dccd59b7c748c339 \ No newline at end of file +0defaf730bdc82212a5d3feeb2e16f16423b1691b0aaa7da1787eb82ea39ae9e \ No newline at end of file diff --git a/src/trigger.c b/src/trigger.c index 0c8cf5334f..a9378fd3a3 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -48,28 +48,32 @@ void sqlite3DeleteTriggerStep(sqlite3 *db, TriggerStep *pTriggerStep){ ** pTab as well as the triggers lised in pTab->pTrigger. */ Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){ - Schema * const pTmpSchema = pParse->db->aDb[1].pSchema; - Trigger *pList = 0; /* List of triggers to return */ + Schema *pTmpSchema; /* Schema of the pTab table */ + Trigger *pList; /* List of triggers to return */ + HashElem *p; /* Loop variable for TEMP triggers */ if( pParse->disableTriggers ){ return 0; } - + pTmpSchema = pParse->db->aDb[1].pSchema; + p = sqliteHashFirst(&pTmpSchema->trigHash); + if( p==0 ){ + return pTab->pTrigger; + } + pList = pTab->pTrigger; if( pTmpSchema!=pTab->pSchema ){ - HashElem *p; - assert( sqlite3SchemaMutexHeld(pParse->db, 0, pTmpSchema) ); - for(p=sqliteHashFirst(&pTmpSchema->trigHash); p; p=sqliteHashNext(p)){ + while( p ){ Trigger *pTrig = (Trigger *)sqliteHashData(p); if( pTrig->pTabSchema==pTab->pSchema && 0==sqlite3StrICmp(pTrig->table, pTab->zName) ){ - pTrig->pNext = (pList ? pList : pTab->pTrigger); + pTrig->pNext = pList; pList = pTrig; } + p = sqliteHashNext(p); } } - - return (pList ? pList : pTab->pTrigger); + return pList; } /* From 02d6f9b295827d5d545801f5babcc572389f8d5a Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 29 Jan 2021 16:20:16 +0000 Subject: [PATCH 141/257] Fix possible division-by-zero in the new log() SQL functions. Problemm discovered by OSSFuzz. FossilOrigin-Name: 1ffd321a33b778e87614a26a91a8407ec7b9dec4f0f847b16b1dac4f3b910604 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/func.c | 9 +++++---- test/func7.test | 8 ++++---- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 7045fd7798..95498bd054 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimization\s(and\ssize\sreduction)\sin\ssqlite3TriggerList()\sfor\sthe\ncommon\scase\swhere\sthere\sare\sno\sTEMP\striggers. -D 2021-01-29T13:47:36.426 +C Fix\spossible\sdivision-by-zero\sin\sthe\snew\slog()\sSQL\sfunctions.\nProblemm\sdiscovered\sby\sOSSFuzz. +D 2021-01-29T16:20:16.527 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -496,7 +496,7 @@ F src/delete.c 927cf8f900583e79aca8f1a321979e0a8f053babd9a690b44b38f79de2cc09fe F src/expr.c 47c85263e6d179424e6b09e2c79db5704ab5b8cbc2fae2ee3285faa2566f2e74 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 83372403298e6a7dd989a47aaacdbaa5b4307b5199dbd56e07d4896066b3de72 -F src/func.c 796a7a4a0ff5eee82a04ee3c8265c5ebf9c6a9f5625621c5f97ed94f6224d7d9 +F src/func.c 2ea99e9e0531b7f020d5e8e167d25344d618afc718ddc94dd91fa8fef1c85a91 F src/global.c ed55af196a9b66e198aaeda3f5454c3aa7d7d050c6c938181fd044b70d180a81 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 @@ -1030,7 +1030,7 @@ F test/func3.test 2bb0f31ab7baaed690b962a88544d7be6b34fa389364bc36a44e441ed3e3f1 F test/func4.test 2285fb5792d593fef442358763f0fd9de806eda47dbc7a5934df57ffdc484c31 F test/func5.test 863e6d1bd0013d09c17236f8a13ea34008dd857d87d85a13a673960e4c25d82a F test/func6.test 90e42b64c4f9fb6f04f44cb8a1da586c8542502e926b19c76504fe74ff2a9b7c -F test/func7.test bb05a77daedf0e3f8764f323a49bc3b8d98f280a0bc6a370387117f4596bde05 +F test/func7.test b9e2a1a30a8562b00841b4a21a5d2d81754fa3ab99275fd71fd5279287b44b1c F test/fuzz-oss1.test e58330d01cbbd8215ee636b17a03fe220b37dbfa F test/fuzz.test 96083052bf5765e4518c1ba686ce2bab785670d1 F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1 @@ -1898,7 +1898,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 9dc7fc9f04d5c14fc436e5ff5b4c06c1969ddde5857ebeb5dccd59b7c748c339 -R 0b7a0544b0d15fb4a458f0ab87fbb410 +P 0defaf730bdc82212a5d3feeb2e16f16423b1691b0aaa7da1787eb82ea39ae9e +R 818a051c7c4bf2ae05824d55152903eb U drh -Z 6a477571c6e856bdd183f551e55df63b +Z b6b8cd840ef34d4d25e074519b6e4b42 diff --git a/manifest.uuid b/manifest.uuid index 6f87f82bcf..dc726d75c2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0defaf730bdc82212a5d3feeb2e16f16423b1691b0aaa7da1787eb82ea39ae9e \ No newline at end of file +1ffd321a33b778e87614a26a91a8407ec7b9dec4f0f847b16b1dac4f3b910604 \ No newline at end of file diff --git a/src/func.c b/src/func.c index e6f293ef06..6d7a77fdb6 100644 --- a/src/func.c +++ b/src/func.c @@ -1980,7 +1980,7 @@ static void logFunc( case SQLITE_INTEGER: case SQLITE_FLOAT: x = sqlite3_value_double(argv[0]); - if( x<0.0 ) return; + if( x<=0.0 ) return; break; default: return; @@ -1989,14 +1989,15 @@ static void logFunc( switch( sqlite3_value_numeric_type(argv[0]) ){ case SQLITE_INTEGER: case SQLITE_FLOAT: - b = x; + b = log(x); + if( b<=0.0 ) return; x = sqlite3_value_double(argv[1]); - if( x<0.0 ) return; + if( x<=0.0 ) return; break; default: return; } - ans = log(x)/log(b); + ans = log(x)/b; }else{ ans = log(x); switch( SQLITE_PTR_TO_INT(sqlite3_user_data(context)) ){ diff --git a/test/func7.test b/test/func7.test index 536f7eb414..c8ae2931e1 100644 --- a/test/func7.test +++ b/test/func7.test @@ -202,11 +202,11 @@ do_execsql_test func7-mysql-210 { #} {0.6931472 NULL} # log() means natural logarithm in MySQL do_execsql_test func7-mysql-230 { - SELECT log(2,65536), log(10,100), quote(log(1,100)); -} {16.0 2.0 Inf} + SELECT log(2,65536), log(10,100), quote(log(1,100)), quote(log(0,100)); +} {16.0 2.0 NULL NULL} do_execsql_test func7-mysql-240 { - SELECT log2(65536), quote(log2(-100)); -} {16.0 NULL} + SELECT log2(65536), quote(log2(-100)), quote(log2(0)); +} {16.0 NULL NULL} do_execsql_test func7-mysql-250 { SELECT round(log10(2),7), log10(100), quote(log10(-100)); } {0.30103 2.0 NULL} From b83524795427e9ad8131fe9827e397f973b37932 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 29 Jan 2021 19:32:17 +0000 Subject: [PATCH 142/257] Working prototype. FossilOrigin-Name: b7ef4dc21f187ff4ff679e823782535188c3814aa6ce720b3a01c6d3ba4ef9f5 --- manifest | 26 +++++++++++++------------- manifest.uuid | 2 +- src/build.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- src/fkey.c | 3 ++- src/parse.y | 4 ++-- src/resolve.c | 11 +++++++---- src/sqliteInt.h | 17 ++++++++++++++++- src/trigger.c | 20 +++++++++++++++++--- src/vdbe.h | 1 + src/vdbeaux.c | 14 ++++++++++++++ 10 files changed, 117 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index d18146bacc..4720b86680 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Incorporate\sthe\ssqlite3TriggerList()\soptimization\sfrom\strunk.\s\sAnd\smove\nthe\spReturning\sfield\sto\sthe\suninitialized\sarea\sin\sthe\sParse\sobject,\sto\nsave\smemset()\stime. -D 2021-01-29T14:22:56.875 +C Working\sprototype. +D 2021-01-29T19:32:17.139 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -485,7 +485,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 47d9fe97d5c0d74506154e3597f8a23b81a00080751dc4d11fec91ee22796f4c F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 -F src/build.c ba8af18891c07501a185ecd02a2bc13a593de9bfd59dbffa5d126780c0c9fb8e +F src/build.c 2aded84176695b0f885eec582f3afbe667737998a14fb39b3eb6623626a8f2b5 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 @@ -495,7 +495,7 @@ F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c F src/delete.c 927cf8f900583e79aca8f1a321979e0a8f053babd9a690b44b38f79de2cc09fe F src/expr.c 47c85263e6d179424e6b09e2c79db5704ab5b8cbc2fae2ee3285faa2566f2e74 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 -F src/fkey.c 83372403298e6a7dd989a47aaacdbaa5b4307b5199dbd56e07d4896066b3de72 +F src/fkey.c df06098e66c95bb5169e2e79eb59583efe00794e6345e196e776dd6f4b1ea33b F src/func.c 796a7a4a0ff5eee82a04ee3c8265c5ebf9c6a9f5625621c5f97ed94f6224d7d9 F src/global.c ed55af196a9b66e198aaeda3f5454c3aa7d7d050c6c938181fd044b70d180a81 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 @@ -530,7 +530,7 @@ F src/os_win.c 77d39873836f1831a9b0b91894fec45ab0e9ca8e067dc8c549e1d1eca1566fe9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c c49952ac5e9cc536778eff528091d79d38b3e45cbeeed4695dc05e207dc6547d F src/pager.h 4bf9b3213a4b2bebbced5eaa8b219cf25d4a82f385d093cd64b7e93e5285f66f -F src/parse.y 6b462c25bae7e0c53f2935f9157f82abeba07754905ef8835c978742c5473ff3 +F src/parse.y 67ba503780de64b967ae195b7e14c33531329228e1bc0b83d63324beb733680b F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a @@ -539,14 +539,14 @@ F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf F src/prepare.c f288cbc35f79eb32e162de7e80a63ebe00d80e639dcfac071bee11570cbdb16f F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c +F src/resolve.c b714e6f9f3cdfb6ba287bb5ef76888ec8cd9e15c98a608c82bc3300b99a245d7 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 738cb746189f721f59972993c13085fa2975c4cbfd04ba26445f3b42c81237dc F src/shell.c.in 9ebc74e4f05cfbd0f4a36060fdaeff1da4e9af4458358722bc08c5a1ab9a0879 F src/sqlite.h.in 0af968a1fa3c717261e1df0ed105fa7bddb4d82de7e0adb3eab49e6aa81b4de7 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h aebfa715feaf134b5d0cf6a2dccb4a4d0172d7915658c69abd5b3a0cb3b794d3 +F src/sqliteInt.h e3ad4cc28df195a9676d9f108d2cd1d41da6b505950797dc069094d90fd9f197 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -607,17 +607,17 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda -F src/trigger.c 731ea5ed6b308574b7dc2a5d2a9187ef5510a3692cc1ea06a34608a084b8f376 +F src/trigger.c 39ac8d708d6c929817c230fba0cf1ef5bd7ac52ce883df8ab49bcdc28817a787 F src/update.c 9f126204a6acb96bbe47391ae48e0fc579105d8e76a6d9c4fab3271367476580 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 41c7a72da1df47864faa378a1c720b38adb288c6838cb6be5594511b6287a048 F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286 F src/vdbe.c 102d21260bddbb43c845603c3a2d6b4f3762e72f836ccda12991f291485d2539 -F src/vdbe.h 83603854bfa5851af601fc0947671eb260f4363e62e960e8a994fb9bbcd2aaa1 +F src/vdbe.h a71bf43572d3de57923d1928ac01ae8d355cd67e94462ba4f7462265cedbef9a F src/vdbeInt.h 3ca5e9fd6e095a8b6cf6bc3587a46fc93499503b2fe48951e1034ba9e2ce2f6e F src/vdbeapi.c c5e7cb2ab89a24d7f723e87b508f21bfb1359a04db5277d8a99fd1e015c12eb9 -F src/vdbeaux.c e91d74e24babcf61969279b193e228cf4f8bc724a9cc59ed287db064326876f8 +F src/vdbeaux.c 7ae7b2d7d97250d7100065eca7f04324f331b16b8165775f1724af10c7240d11 F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1 F src/vdbemem.c 947f2a65910edb4014dc981d33e414a68c51f169f9df8c4c493a0ba840b6eb1f F src/vdbesort.c f5b5e473a7cee44e47a94817b042fd7172cf3aa2c0a7928a8339d612bcfdec5a @@ -1898,7 +1898,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 5fbcb208d24d45169fc53ad8738dd3545d9bbd26b7434e31afc7f6419cd4e958 0defaf730bdc82212a5d3feeb2e16f16423b1691b0aaa7da1787eb82ea39ae9e -R c5cf37660ce1737a23c63b9fdc43eb3e +P 29fbaf0e3eabda08500f350bc32e9f339e5732a65bfa62822eefb692a2ff0243 +R 0f4eeb3bbbe288c435a7916147e604d5 U drh -Z c6d2a25c829d2b926a3cb0974507f1ba +Z cf32b347d108b527d7c22e05c5929805 diff --git a/manifest.uuid b/manifest.uuid index 64051cb566..9c5f6afd5b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -29fbaf0e3eabda08500f350bc32e9f339e5732a65bfa62822eefb692a2ff0243 \ No newline at end of file +b7ef4dc21f187ff4ff679e823782535188c3814aa6ce720b3a01c6d3ba4ef9f5 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 5b4bbe499b..99ecad4d63 100644 --- a/src/build.c +++ b/src/build.c @@ -1243,13 +1243,55 @@ void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){ } #endif +/* +** Name of the magic TEMP trigger used to implement RETURNING +*/ +#define RETURNING_TRIGGER "sqlite_returning" + +/* +** Delete the data structures associated with the RETURNING clause. +*/ +static void sqlite3DeleteReturning(sqlite3 *db, Returning *pRet){ + Hash *pHash; + pHash = &(db->aDb[1].pSchema->trigHash); + assert( sqlite3HashFind(pHash, RETURNING_TRIGGER)==&pRet->retTrig ); + sqlite3HashInsert(pHash, RETURNING_TRIGGER, 0); + sqlite3ExprListDelete(db, pRet->pReturnEL); + sqlite3DbFree(db, pRet); +} + /* ** Add the RETURNING clause to the parser currently underway. */ void sqlite3AddReturning(Parse *pParse, ExprList *pList){ + Returning *pRet; + Hash *pHash; + sqlite3 *db = pParse->db; + pRet = sqlite3DbMallocZero(db, sizeof(*pRet)); + if( pRet==0 ){ + sqlite3ExprListDelete(db, pList); + return; + } + pRet->pParse = pParse; + pRet->pReturnEL = pList; sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3ExprListDelete, pList); - pParse->pReturning = pList; + (void(*)(sqlite3*,void*))sqlite3DeleteReturning, pRet); + pRet->retTrig.zName = "sqlite_returning"; + pRet->retTrig.op = TK_RETURNING; + pRet->retTrig.tr_tm = TRIGGER_AFTER; + pRet->retTrig.bReturning = 1; + pRet->retTrig.pSchema = db->aDb[1].pSchema; + pRet->retTrig.step_list = &pRet->retTStep; + pRet->retTStep.op = TK_SELECT; + pRet->retTStep.eTrigDest = SRT_Output; + pRet->retTStep.pTrig = &pRet->retTrig; + pRet->retTStep.pSelect = &pRet->retSel; + pRet->retSel.op = TK_ALL; + pRet->retSel.pEList = pList; + pRet->retSel.pSrc = (SrcList*)&pRet->retSrcList; + pHash = &(db->aDb[1].pSchema->trigHash); + assert( sqlite3HashFind(pHash, RETURNING_TRIGGER)==0 ); + sqlite3HashInsert(pHash, "sqlite_returning", &pRet->retTrig); } /* diff --git a/src/fkey.c b/src/fkey.c index 959e994d17..4cb92e2915 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -1352,7 +1352,8 @@ static Trigger *fkActionTrigger( switch( action ){ case OE_Restrict: - pStep->op = TK_SELECT; + pStep->op = TK_SELECT; + pStep->eTrigDest = SRT_Discard; break; case OE_Cascade: if( !pChanges ){ diff --git a/src/parse.y b/src/parse.y index 4c79d4a87a..591cde3b9d 100644 --- a/src/parse.y +++ b/src/parse.y @@ -905,7 +905,7 @@ where_opt_ret(A) ::= WHERE expr(X) RETURNING selcollist(Y). // %if SQLITE_ENABLE_UPDATE_DELETE_LIMIT || SQLITE_UDL_CAPABLE_PARSER cmd ::= with UPDATE orconf(R) xfullname(X) indexed_opt(I) SET setlist(Y) from(F) - where_opt(W) orderby_opt(O) limit_opt(L). { + where_opt_ret(W) orderby_opt(O) limit_opt(L). { sqlite3SrcListIndexedBy(pParse, X, &I); X = sqlite3SrcListAppendList(pParse, X, F); sqlite3ExprListCheckLength(pParse,Y,"set list"); @@ -920,7 +920,7 @@ cmd ::= with UPDATE orconf(R) xfullname(X) indexed_opt(I) SET setlist(Y) from(F) } %else cmd ::= with UPDATE orconf(R) xfullname(X) indexed_opt(I) SET setlist(Y) from(F) - where_opt(W). { + where_opt_ret(W). { sqlite3SrcListIndexedBy(pParse, X, &I); sqlite3ExprListCheckLength(pParse,Y,"set list"); X = sqlite3SrcListAppendList(pParse, X, F); diff --git a/src/resolve.c b/src/resolve.c index b55bdc4187..fa46954da8 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -371,23 +371,26 @@ static int lookupName( ** it is a new.* or old.* trigger argument reference. Or ** maybe it is an excluded.* from an upsert. */ - if( zDb==0 && zTab!=0 && cntTab==0 ){ + if( zDb==0 && cntTab==0 ){ pTab = 0; #ifndef SQLITE_OMIT_TRIGGER if( pParse->pTriggerTab!=0 ){ int op = pParse->eTriggerOp; assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT ); - if( op!=TK_DELETE && sqlite3StrICmp("new",zTab) == 0 ){ + if( op!=TK_DELETE && zTab && sqlite3StrICmp("new",zTab) == 0 ){ pExpr->iTable = 1; pTab = pParse->pTriggerTab; - }else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){ + }else if( op!=TK_INSERT && zTab && sqlite3StrICmp("old",zTab)==0 ){ pExpr->iTable = 0; pTab = pParse->pTriggerTab; + }else if( pParse->bReturning ){ + pExpr->iTable = op!=TK_DELETE; + pTab = pParse->pTriggerTab; } } #endif /* SQLITE_OMIT_TRIGGER */ #ifndef SQLITE_OMIT_UPSERT - if( (pNC->ncFlags & NC_UUpsert)!=0 ){ + if( (pNC->ncFlags & NC_UUpsert)!=0 && zTab ){ Upsert *pUpsert = pNC->uNC.pUpsert; if( pUpsert && sqlite3StrICmp("excluded",zTab)==0 ){ pTab = pUpsert->pUpsertSrc->a[0].pTab; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index c66b44290c..231ead5062 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1159,6 +1159,7 @@ typedef struct ParseCleanup ParseCleanup; typedef struct PreUpdate PreUpdate; typedef struct PrintfArguments PrintfArguments; typedef struct RenameToken RenameToken; +typedef struct Returning Returning; typedef struct RowSet RowSet; typedef struct Savepoint Savepoint; typedef struct Select Select; @@ -3429,6 +3430,7 @@ struct Parse { u32 oldmask; /* Mask of old.* columns referenced */ u32 newmask; /* Mask of new.* columns referenced */ u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */ + u8 bReturning; /* Coding a RETURNING trigger */ u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ u8 disableTriggers; /* True to disable triggers */ @@ -3441,7 +3443,6 @@ struct Parse { int aTempReg[8]; /* Holding area for temporary registers */ Token sNameToken; /* Token with unqualified schema object name */ - ExprList *pReturning; /* The RETURNING clause, if any */ /************************************************************************ ** Above is constant between recursions. Below is reset before and after @@ -3579,6 +3580,7 @@ struct Trigger { char *table; /* The table or view to which the trigger applies */ u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT */ u8 tr_tm; /* One of TRIGGER_BEFORE, TRIGGER_AFTER */ + u8 bReturning; /* This trigger implements a RETURNING clause */ Expr *pWhen; /* The WHEN clause of the expression (may be NULL) */ IdList *pColumns; /* If this is an UPDATE OF trigger, the is stored here */ @@ -3639,6 +3641,7 @@ struct Trigger { struct TriggerStep { u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */ u8 orconf; /* OE_Rollback etc. */ + u8 eTrigDest; /* SRT_ destination value for SELECT */ Trigger *pTrig; /* The trigger that this step is a part of */ Select *pSelect; /* SELECT statement or RHS of INSERT INTO SELECT ... */ char *zTarget; /* Target table for DELETE, UPDATE, INSERT */ @@ -3652,6 +3655,18 @@ struct TriggerStep { TriggerStep *pLast; /* Last element in link-list. Valid for 1st elem only */ }; +/* +** Information about a RETURNING clause +*/ +struct Returning { + Parse *pParse; /* The parse that includes the RETURNING clause */ + ExprList *pReturnEL; /* List of expressions to return */ + Trigger retTrig; /* The transient trigger that implements RETURNING */ + TriggerStep retTStep; /* The trigger step */ + Select retSel; /* The SELECT statement that implements RETURNING */ + u64 retSrcList; /* The empty FROM clause of the SELECT */ +}; + /* ** An objected used to accumulate the text of a string where we ** do not necessarily know how big the string will be in the end. diff --git a/src/trigger.c b/src/trigger.c index a9378fd3a3..5508e4d151 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -65,11 +65,16 @@ Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){ while( p ){ Trigger *pTrig = (Trigger *)sqliteHashData(p); if( pTrig->pTabSchema==pTab->pSchema - && 0==sqlite3StrICmp(pTrig->table, pTab->zName) + && 0==sqlite3StrICmp(pTrig->table, pTab->zName) ){ pTrig->pNext = pList; pList = pTrig; - } + }else if( pTrig->op==TK_RETURNING ){ + pTrig->table = pTab->zName; + pTrig->pTabSchema = pTab->pSchema; + pTrig->pNext = pList; + pList = pTrig; + } p = sqliteHashNext(p); } } @@ -405,6 +410,7 @@ TriggerStep *sqlite3TriggerSelectStep( return 0; } pTriggerStep->op = TK_SELECT; + pTriggerStep->eTrigDest = SRT_Discard; pTriggerStep->pSelect = pSelect; pTriggerStep->orconf = OE_Default; pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd); @@ -563,6 +569,7 @@ TriggerStep *sqlite3TriggerDeleteStep( */ void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){ if( pTrigger==0 ) return; + assert( !pTrigger->bReturning ); sqlite3DeleteTriggerStep(db, pTrigger->step_list); sqlite3DbFree(db, pTrigger->zName); sqlite3DbFree(db, pTrigger->table); @@ -734,6 +741,9 @@ Trigger *sqlite3TriggersExist( for(p=pList; p; p=p->pNext){ if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){ mask |= p->tr_tm; + }else if( p->op==TK_RETURNING ){ + p->op = op; + mask |= TRIGGER_AFTER; } } if( pMask ){ @@ -849,7 +859,7 @@ static int codeTriggerProgram( default: assert( pStep->op==TK_SELECT ); { SelectDest sDest; Select *pSelect = sqlite3SelectDup(db, pStep->pSelect, 0); - sqlite3SelectDestInit(&sDest, SRT_Discard, 0); + sqlite3SelectDestInit(&sDest, pStep->eTrigDest, 0); sqlite3Select(pParse, pSelect, &sDest); sqlite3SelectDelete(db, pSelect); break; @@ -947,6 +957,7 @@ static TriggerPrg *codeRowTrigger( pSubParse->pToplevel = pTop; pSubParse->zAuthContext = pTrigger->zName; pSubParse->eTriggerOp = pTrigger->op; + pSubParse->bReturning = pTrigger->bReturning; pSubParse->nQueryLoop = pParse->nQueryLoop; pSubParse->disableVtab = pParse->disableVtab; @@ -996,6 +1007,9 @@ static TriggerPrg *codeRowTrigger( if( db->mallocFailed==0 && pParse->nErr==0 ){ pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg); } + if( pTrigger->bReturning ){ + sqlite3VdbeColumnInfoXfer(pParse->pVdbe, v); + } pProgram->nMem = pSubParse->nMem; pProgram->nCsr = pSubParse->nTab; pProgram->token = (void *)pTrigger; diff --git a/src/vdbe.h b/src/vdbe.h index 17f11fdd77..48be53df7f 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -259,6 +259,7 @@ void sqlite3VdbeResetStepResult(Vdbe*); void sqlite3VdbeRewind(Vdbe*); int sqlite3VdbeReset(Vdbe*); void sqlite3VdbeSetNumCols(Vdbe*,int); +void sqlite3VdbeColumnInfoXfer(Vdbe*,Vdbe*); int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*)); void sqlite3VdbeCountChanges(Vdbe*); sqlite3 *sqlite3VdbeDb(Vdbe*); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 7b9b792054..9ea20628fe 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2595,6 +2595,20 @@ void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){ initMemArray(p->aColName, n, db, MEM_Null); } +/* +** Transfer the column count and name information from one Vdbe to +** another. +*/ +void sqlite3VdbeColumnInfoXfer(Vdbe *pTo, Vdbe *pFrom){ + sqlite3 *db = pTo->db; + assert( db==pFrom->db ); + sqlite3DbFree(db, pTo->aColName); + pTo->aColName = pFrom->aColName; + pFrom->aColName = 0; + pTo->nResColumn = pFrom->nResColumn; + pFrom->nResColumn = 0; +} + /* ** Set the name of the idx'th column to be returned by the SQL statement. ** zName must be a pointer to a nul terminated string. From dac9a5f7df0e65f35d6f9de423a90cb7eb52c8b6 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 29 Jan 2021 21:18:46 +0000 Subject: [PATCH 143/257] Allow "*" wildcards in the RETURNING clause. FossilOrigin-Name: b0e3ae303db2a035583a05848ab7977e612d7e40c77e31ea9e0166de443c901f --- manifest | 18 +++++++------- manifest.uuid | 2 +- src/build.c | 3 +-- src/fkey.c | 1 - src/sqliteInt.h | 4 ++-- src/trigger.c | 63 ++++++++++++++++++++++++++++++++++++++++++++----- 6 files changed, 70 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 4720b86680..562358c6c0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Working\sprototype. -D 2021-01-29T19:32:17.139 +C Allow\s"*"\swildcards\sin\sthe\sRETURNING\sclause. +D 2021-01-29T21:18:46.467 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -485,7 +485,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 47d9fe97d5c0d74506154e3597f8a23b81a00080751dc4d11fec91ee22796f4c F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 -F src/build.c 2aded84176695b0f885eec582f3afbe667737998a14fb39b3eb6623626a8f2b5 +F src/build.c 2da961ffeb6253117a859ddfc682b20969ff7ebd0ec8c9f88636ea16cdc512b4 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 @@ -495,7 +495,7 @@ F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c F src/delete.c 927cf8f900583e79aca8f1a321979e0a8f053babd9a690b44b38f79de2cc09fe F src/expr.c 47c85263e6d179424e6b09e2c79db5704ab5b8cbc2fae2ee3285faa2566f2e74 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 -F src/fkey.c df06098e66c95bb5169e2e79eb59583efe00794e6345e196e776dd6f4b1ea33b +F src/fkey.c 02e4a3311885cd2b31eb17fd58dc2fc738cd2c823d0d39e4dd5595169c6f8bc3 F src/func.c 796a7a4a0ff5eee82a04ee3c8265c5ebf9c6a9f5625621c5f97ed94f6224d7d9 F src/global.c ed55af196a9b66e198aaeda3f5454c3aa7d7d050c6c938181fd044b70d180a81 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 @@ -546,7 +546,7 @@ F src/shell.c.in 9ebc74e4f05cfbd0f4a36060fdaeff1da4e9af4458358722bc08c5a1ab9a087 F src/sqlite.h.in 0af968a1fa3c717261e1df0ed105fa7bddb4d82de7e0adb3eab49e6aa81b4de7 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h e3ad4cc28df195a9676d9f108d2cd1d41da6b505950797dc069094d90fd9f197 +F src/sqliteInt.h 0fda3b2c05b1559135aa2c4ecb8e75bd2085ba4433310bbb5427d97c2d81315d F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -607,7 +607,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda -F src/trigger.c 39ac8d708d6c929817c230fba0cf1ef5bd7ac52ce883df8ab49bcdc28817a787 +F src/trigger.c 47629a1e3fd483347d6cf468d7d397ab50f3ead4286d837ad7054de418767e38 F src/update.c 9f126204a6acb96bbe47391ae48e0fc579105d8e76a6d9c4fab3271367476580 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 @@ -1898,7 +1898,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 29fbaf0e3eabda08500f350bc32e9f339e5732a65bfa62822eefb692a2ff0243 -R 0f4eeb3bbbe288c435a7916147e604d5 +P b7ef4dc21f187ff4ff679e823782535188c3814aa6ce720b3a01c6d3ba4ef9f5 +R 4fd580e848a9786e2403b5294c0c89d9 U drh -Z cf32b347d108b527d7c22e05c5929805 +Z d7647504631490a0d91f2ce3b7260d98 diff --git a/manifest.uuid b/manifest.uuid index 9c5f6afd5b..e387b3e2f7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b7ef4dc21f187ff4ff679e823782535188c3814aa6ce720b3a01c6d3ba4ef9f5 \ No newline at end of file +b0e3ae303db2a035583a05848ab7977e612d7e40c77e31ea9e0166de443c901f \ No newline at end of file diff --git a/src/build.c b/src/build.c index 99ecad4d63..a25c9c6d80 100644 --- a/src/build.c +++ b/src/build.c @@ -1282,8 +1282,7 @@ void sqlite3AddReturning(Parse *pParse, ExprList *pList){ pRet->retTrig.bReturning = 1; pRet->retTrig.pSchema = db->aDb[1].pSchema; pRet->retTrig.step_list = &pRet->retTStep; - pRet->retTStep.op = TK_SELECT; - pRet->retTStep.eTrigDest = SRT_Output; + pRet->retTStep.op = TK_RETURNING; pRet->retTStep.pTrig = &pRet->retTrig; pRet->retTStep.pSelect = &pRet->retSel; pRet->retSel.op = TK_ALL; diff --git a/src/fkey.c b/src/fkey.c index 4cb92e2915..59e12b5fa8 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -1353,7 +1353,6 @@ static Trigger *fkActionTrigger( switch( action ){ case OE_Restrict: pStep->op = TK_SELECT; - pStep->eTrigDest = SRT_Discard; break; case OE_Cascade: if( !pChanges ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 231ead5062..3cadb7f53a 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3639,9 +3639,9 @@ struct Trigger { * */ struct TriggerStep { - u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */ + u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT, + ** or TK_RETURNING */ u8 orconf; /* OE_Rollback etc. */ - u8 eTrigDest; /* SRT_ destination value for SELECT */ Trigger *pTrig; /* The trigger that this step is a part of */ Select *pSelect; /* SELECT statement or RHS of INSERT INTO SELECT ... */ char *zTarget; /* Target table for DELETE, UPDATE, INSERT */ diff --git a/src/trigger.c b/src/trigger.c index 5508e4d151..a20c14197b 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -410,7 +410,6 @@ TriggerStep *sqlite3TriggerSelectStep( return 0; } pTriggerStep->op = TK_SELECT; - pTriggerStep->eTrigDest = SRT_Discard; pTriggerStep->pSelect = pSelect; pTriggerStep->orconf = OE_Default; pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd); @@ -788,6 +787,46 @@ SrcList *sqlite3TriggerStepSrc( return pSrc; } +/* The input list pList is the list of result set terms from a RETURNING +** clause. The table that we are returning from is pTab. +** +** This routine makes a copy of the pList, and at the same time expands +** any "*" wildcards to be the complete set of columns from pTab. +*/ +static ExprList *sqlite3ExpandReturning( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* The arguments to RETURNING */ + Table *pTab /* The table being updated */ +){ + ExprList *pNew = 0; + sqlite3 *db = pParse->db; + int i; + for(i=0; inExpr; i++){ + Expr *pOldExpr = pList->a[i].pExpr; + if( ALWAYS(pOldExpr!=0) && pOldExpr->op==TK_ASTERISK ){ + int j; + for(j=0; jnCol; j++){ + Expr *pNewExpr = sqlite3Expr(db, TK_ID, pTab->aCol[j].zName); + pNew = sqlite3ExprListAppend(pParse, pNew, pNewExpr); + if( !db->mallocFailed ){ + struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1]; + pItem->zEName = sqlite3DbStrDup(db, pTab->aCol[j].zName); + pItem->eEName = ENAME_NAME; + } + } + }else{ + Expr *pNewExpr = sqlite3ExprDup(db, pOldExpr, 0); + pNew = sqlite3ExprListAppend(pParse, pNew, pNewExpr); + if( pList->a[i].zEName!=0 && !db->mallocFailed ){ + struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1]; + pItem->zEName = sqlite3DbStrDup(db, pList->a[i].zEName); + pItem->eEName = pList->a[i].eEName; + } + } + } + return pNew; +} + /* ** Generate VDBE code for the statements inside the body of a single ** trigger. @@ -837,6 +876,7 @@ static int codeTriggerProgram( sqlite3ExprDup(db, pStep->pWhere, 0), pParse->eOrconf, 0, 0, 0 ); + sqlite3VdbeAddOp0(v, OP_ResetCount); break; } case TK_INSERT: { @@ -847,6 +887,7 @@ static int codeTriggerProgram( pParse->eOrconf, sqlite3UpsertDup(db, pStep->pUpsert) ); + sqlite3VdbeAddOp0(v, OP_ResetCount); break; } case TK_DELETE: { @@ -854,20 +895,30 @@ static int codeTriggerProgram( sqlite3TriggerStepSrc(pParse, pStep), sqlite3ExprDup(db, pStep->pWhere, 0), 0, 0 ); + sqlite3VdbeAddOp0(v, OP_ResetCount); break; } - default: assert( pStep->op==TK_SELECT ); { + case TK_SELECT: { SelectDest sDest; Select *pSelect = sqlite3SelectDup(db, pStep->pSelect, 0); - sqlite3SelectDestInit(&sDest, pStep->eTrigDest, 0); + sqlite3SelectDestInit(&sDest, SRT_Discard, 0); sqlite3Select(pParse, pSelect, &sDest); sqlite3SelectDelete(db, pSelect); break; } + default: assert( pStep->op==TK_RETURNING ); { + Select *pSelect = pStep->pSelect; + ExprList *pList = pSelect->pEList; + SelectDest sDest; + pSelect->pEList = + sqlite3ExpandReturning(pParse, pList, pParse->pTriggerTab); + sqlite3SelectDestInit(&sDest, SRT_Output, 0); + sqlite3Select(pParse, pSelect, &sDest); + sqlite3ExprListDelete(db, pSelect->pEList); + pSelect->pEList = pList; + break; + } } - if( pStep->op!=TK_SELECT ){ - sqlite3VdbeAddOp0(v, OP_ResetCount); - } } return 0; From d086aa0a480f6fabf0bb4f0952ae84d79d4295f4 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 29 Jan 2021 21:31:59 +0000 Subject: [PATCH 144/257] RETURNING works even if "PRAGMA count_changes=ON" is set. FossilOrigin-Name: a9122d97577b239704cdee1a90a3b0dbff8bdf9dea2324d7315bd47238dcc8eb --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/build.c | 2 ++ src/delete.c | 1 + src/insert.c | 1 + src/update.c | 1 + 6 files changed, 15 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 562358c6c0..65a114c0e4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\s"*"\swildcards\sin\sthe\sRETURNING\sclause. -D 2021-01-29T21:18:46.467 +C RETURNING\sworks\seven\sif\s"PRAGMA\scount_changes=ON"\sis\sset. +D 2021-01-29T21:31:59.474 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -485,14 +485,14 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 47d9fe97d5c0d74506154e3597f8a23b81a00080751dc4d11fec91ee22796f4c F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 -F src/build.c 2da961ffeb6253117a859ddfc682b20969ff7ebd0ec8c9f88636ea16cdc512b4 +F src/build.c 0453da1ba48d8bf17855bb3d7dfaadbaf5fd0871f249f2e5b98a7231aeac7ae1 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 F src/date.c dace306a10d9b02ee553d454c8e1cf8d3c9b932e137738a6b15b90253a9bfc10 F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c -F src/delete.c 927cf8f900583e79aca8f1a321979e0a8f053babd9a690b44b38f79de2cc09fe +F src/delete.c a4b3a6db02d2e705edf41bdb378d4c53c106f305fd8e7b441713fe87f69ea624 F src/expr.c 47c85263e6d179424e6b09e2c79db5704ab5b8cbc2fae2ee3285faa2566f2e74 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 02e4a3311885cd2b31eb17fd58dc2fc738cd2c823d0d39e4dd5595169c6f8bc3 @@ -502,7 +502,7 @@ 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 9b970eff058a858fbd9f2db71425ef195942c2610855daa66ae23024432d52f5 +F src/insert.c 8f725611e5c5943cfd40461a8fa518538d8be666ef09097a29f7272ccd3ab0a0 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 F src/main.c 1c5de7b3fabcdf05f4fe563aab5d81d175b89c67a8678a12ba86629356afa356 @@ -608,7 +608,7 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda F src/trigger.c 47629a1e3fd483347d6cf468d7d397ab50f3ead4286d837ad7054de418767e38 -F src/update.c 9f126204a6acb96bbe47391ae48e0fc579105d8e76a6d9c4fab3271367476580 +F src/update.c 3dbc7189ffcf361c2149f1b1d0841a8a9689d27f15c5e72e6f14ebc447e6b0c0 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 41c7a72da1df47864faa378a1c720b38adb288c6838cb6be5594511b6287a048 @@ -1898,7 +1898,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 b7ef4dc21f187ff4ff679e823782535188c3814aa6ce720b3a01c6d3ba4ef9f5 -R 4fd580e848a9786e2403b5294c0c89d9 +P b0e3ae303db2a035583a05848ab7977e612d7e40c77e31ea9e0166de443c901f +R 0b4d4b086e5a69193a34b592f53c4e83 U drh -Z d7647504631490a0d91f2ce3b7260d98 +Z 1de82168e812ff82dbf4f00b9d1c7aff diff --git a/manifest.uuid b/manifest.uuid index e387b3e2f7..672cce1dac 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b0e3ae303db2a035583a05848ab7977e612d7e40c77e31ea9e0166de443c901f \ No newline at end of file +a9122d97577b239704cdee1a90a3b0dbff8bdf9dea2324d7315bd47238dcc8eb \ No newline at end of file diff --git a/src/build.c b/src/build.c index a25c9c6d80..74c5319caa 100644 --- a/src/build.c +++ b/src/build.c @@ -1267,6 +1267,8 @@ void sqlite3AddReturning(Parse *pParse, ExprList *pList){ Returning *pRet; Hash *pHash; sqlite3 *db = pParse->db; + assert( !pParse->bReturning ); + pParse->bReturning = 1; pRet = sqlite3DbMallocZero(db, sizeof(*pRet)); if( pRet==0 ){ sqlite3ExprListDelete(db, pList); diff --git a/src/delete.c b/src/delete.c index 064ae7325a..e9b092b245 100644 --- a/src/delete.c +++ b/src/delete.c @@ -387,6 +387,7 @@ void sqlite3DeleteFrom( if( (db->flags & SQLITE_CountRows)!=0 && !pParse->nested && !pParse->pTriggerTab + && !pParse->bReturning ){ memCnt = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt); diff --git a/src/insert.c b/src/insert.c index 6047969c07..4f549f3523 100644 --- a/src/insert.c +++ b/src/insert.c @@ -954,6 +954,7 @@ void sqlite3Insert( if( (db->flags & SQLITE_CountRows)!=0 && !pParse->nested && !pParse->pTriggerTab + && !pParse->bReturning ){ regRowCount = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount); diff --git a/src/update.c b/src/update.c index f8cb2afedb..82a6eb6356 100644 --- a/src/update.c +++ b/src/update.c @@ -643,6 +643,7 @@ void sqlite3Update( if( (db->flags&SQLITE_CountRows)!=0 && !pParse->pTriggerTab && !pParse->nested + && !pParse->bReturning && pUpsert==0 ){ regRowCount = ++pParse->nMem; From 8f4e2e25c4b5bff5e43bca2f9f166ff48311d6a3 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 29 Jan 2021 22:33:05 +0000 Subject: [PATCH 145/257] Better handling of errors in RETURNING due to corrupt database files. FossilOrigin-Name: 6aa2a058d136d0b24d94c5cbe1ce447eb435c1a1c7cdce5e435f1548bb3f05e7 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/build.c | 1 - src/trigger.c | 3 +-- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 65a114c0e4..0499237a61 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C RETURNING\sworks\seven\sif\s"PRAGMA\scount_changes=ON"\sis\sset. -D 2021-01-29T21:31:59.474 +C Better\shandling\sof\serrors\sin\sRETURNING\sdue\sto\scorrupt\sdatabase\sfiles. +D 2021-01-29T22:33:05.109 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -485,7 +485,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 47d9fe97d5c0d74506154e3597f8a23b81a00080751dc4d11fec91ee22796f4c F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 -F src/build.c 0453da1ba48d8bf17855bb3d7dfaadbaf5fd0871f249f2e5b98a7231aeac7ae1 +F src/build.c 451f832bfcbcb3004b09909608c452f1488863111167378355f95782c95bb358 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 @@ -607,7 +607,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda -F src/trigger.c 47629a1e3fd483347d6cf468d7d397ab50f3ead4286d837ad7054de418767e38 +F src/trigger.c 7d9f9ba8723a84aed98f9446b30144acb539674b433ca7584145128791a60050 F src/update.c 3dbc7189ffcf361c2149f1b1d0841a8a9689d27f15c5e72e6f14ebc447e6b0c0 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 @@ -1898,7 +1898,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 b0e3ae303db2a035583a05848ab7977e612d7e40c77e31ea9e0166de443c901f -R 0b4d4b086e5a69193a34b592f53c4e83 +P a9122d97577b239704cdee1a90a3b0dbff8bdf9dea2324d7315bd47238dcc8eb +R fb4fe290c70a72991d2bf3bb937da403 U drh -Z 1de82168e812ff82dbf4f00b9d1c7aff +Z ed1108ccda3615e26a51d20c5efe4e6c diff --git a/manifest.uuid b/manifest.uuid index 672cce1dac..4c38766895 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a9122d97577b239704cdee1a90a3b0dbff8bdf9dea2324d7315bd47238dcc8eb \ No newline at end of file +6aa2a058d136d0b24d94c5cbe1ce447eb435c1a1c7cdce5e435f1548bb3f05e7 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 74c5319caa..4143221c39 100644 --- a/src/build.c +++ b/src/build.c @@ -1254,7 +1254,6 @@ void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){ static void sqlite3DeleteReturning(sqlite3 *db, Returning *pRet){ Hash *pHash; pHash = &(db->aDb[1].pSchema->trigHash); - assert( sqlite3HashFind(pHash, RETURNING_TRIGGER)==&pRet->retTrig ); sqlite3HashInsert(pHash, RETURNING_TRIGGER, 0); sqlite3ExprListDelete(db, pRet->pReturnEL); sqlite3DbFree(db, pRet); diff --git a/src/trigger.c b/src/trigger.c index a20c14197b..4520059442 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -567,8 +567,7 @@ TriggerStep *sqlite3TriggerDeleteStep( ** Recursively delete a Trigger structure */ void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){ - if( pTrigger==0 ) return; - assert( !pTrigger->bReturning ); + if( pTrigger==0 || pTrigger->bReturning ) return; sqlite3DeleteTriggerStep(db, pTrigger->step_list); sqlite3DbFree(db, pTrigger->zName); sqlite3DbFree(db, pTrigger->table); From ba71a8a01bf2559eefe526e3b44f07e9ff2da5b8 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 30 Jan 2021 01:30:26 +0000 Subject: [PATCH 146/257] Test cases added. RETURNING works with UPSERT as does PG. FossilOrigin-Name: f5698f96e27c9b8669ec6016bb9920ef7580c4146eb61d628a0f62be5135ce94 --- manifest | 15 ++++---- manifest.uuid | 2 +- src/trigger.c | 8 ++-- src/vdbeaux.c | 5 ++- test/returning1.test | 87 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 105 insertions(+), 12 deletions(-) create mode 100644 test/returning1.test diff --git a/manifest b/manifest index 0499237a61..97aab3c71b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Better\shandling\sof\serrors\sin\sRETURNING\sdue\sto\scorrupt\sdatabase\sfiles. -D 2021-01-29T22:33:05.109 +C Test\scases\sadded.\s\sRETURNING\sworks\swith\sUPSERT\sas\sdoes\sPG. +D 2021-01-30T01:30:26.496 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -607,7 +607,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda -F src/trigger.c 7d9f9ba8723a84aed98f9446b30144acb539674b433ca7584145128791a60050 +F src/trigger.c 88f616cbd1aa538f3d6bebc4e9b9fb95b566771b45c0690f21223de0317ace54 F src/update.c 3dbc7189ffcf361c2149f1b1d0841a8a9689d27f15c5e72e6f14ebc447e6b0c0 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 @@ -617,7 +617,7 @@ F src/vdbe.c 102d21260bddbb43c845603c3a2d6b4f3762e72f836ccda12991f291485d2539 F src/vdbe.h a71bf43572d3de57923d1928ac01ae8d355cd67e94462ba4f7462265cedbef9a F src/vdbeInt.h 3ca5e9fd6e095a8b6cf6bc3587a46fc93499503b2fe48951e1034ba9e2ce2f6e F src/vdbeapi.c c5e7cb2ab89a24d7f723e87b508f21bfb1359a04db5277d8a99fd1e015c12eb9 -F src/vdbeaux.c 7ae7b2d7d97250d7100065eca7f04324f331b16b8165775f1724af10c7240d11 +F src/vdbeaux.c 2be30e4918126122fa358ef8303206cad0feffe17d320077c77ff5c2a34f3626 F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1 F src/vdbemem.c 947f2a65910edb4014dc981d33e414a68c51f169f9df8c4c493a0ba840b6eb1f F src/vdbesort.c f5b5e473a7cee44e47a94817b042fd7172cf3aa2c0a7928a8339d612bcfdec5a @@ -1286,6 +1286,7 @@ F test/releasetest.tcl fb76d8fcc95ac29d6356cd9e52b726ab9e43a24082897618dfbcb7c2b F test/releasetest_data.tcl b9cb30360759b80d92d4ea86b84ebfd8035b97f9078a482deb3cf9d0b2442655 F test/resetdb.test 8062cf10a09d8c048f8de7711e94571c38b38168db0e5877ba7561789e5eeb2b F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb +F test/returning1.test 684e1c73d961422a7376c932fcdd6dacf02bad21d12f749cfe8c19991ef379f6 F test/rollback.test 06680159bc6746d0f26276e339e3ae2f951c64812468308838e0a3362d911eaa F test/rollback2.test bc868d57899dc6972e2b4483faae0e03365a0556941474eec487ae21d8d38bb6 F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a @@ -1898,7 +1899,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 a9122d97577b239704cdee1a90a3b0dbff8bdf9dea2324d7315bd47238dcc8eb -R fb4fe290c70a72991d2bf3bb937da403 +P 6aa2a058d136d0b24d94c5cbe1ce447eb435c1a1c7cdce5e435f1548bb3f05e7 +R c5d28b15f2cd5974ae8ec5b186394cb6 U drh -Z ed1108ccda3615e26a51d20c5efe4e6c +Z 4324b62b15638b065ad3c0261246302c diff --git a/manifest.uuid b/manifest.uuid index 4c38766895..b8ff6b9b92 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6aa2a058d136d0b24d94c5cbe1ce447eb435c1a1c7cdce5e435f1548bb3f05e7 \ No newline at end of file +f5698f96e27c9b8669ec6016bb9920ef7580c4146eb61d628a0f62be5135ce94 \ No newline at end of file diff --git a/src/trigger.c b/src/trigger.c index 4520059442..baf78eb8c2 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -567,7 +567,8 @@ TriggerStep *sqlite3TriggerDeleteStep( ** Recursively delete a Trigger structure */ void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){ - if( pTrigger==0 || pTrigger->bReturning ) return; + if( pTrigger==0 ) return; + assert( !pTrigger->bReturning ); sqlite3DeleteTriggerStep(db, pTrigger->step_list); sqlite3DbFree(db, pTrigger->zName); sqlite3DbFree(db, pTrigger->table); @@ -739,7 +740,7 @@ Trigger *sqlite3TriggersExist( for(p=pList; p; p=p->pNext){ if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){ mask |= p->tr_tm; - }else if( p->op==TK_RETURNING ){ + }else if( p->bReturning ){ p->op = op; mask |= TRIGGER_AFTER; } @@ -912,6 +913,7 @@ static int codeTriggerProgram( pSelect->pEList = sqlite3ExpandReturning(pParse, pList, pParse->pTriggerTab); sqlite3SelectDestInit(&sDest, SRT_Output, 0); + pSelect->selFlags = 0; sqlite3Select(pParse, pSelect, &sDest); sqlite3ExprListDelete(db, pSelect->pEList); pSelect->pEList = pList; @@ -1215,7 +1217,7 @@ void sqlite3CodeRowTrigger( || p->pSchema==pParse->db->aDb[1].pSchema ); /* Determine whether we should code this trigger */ - if( p->op==op + if( (p->op==op || p->bReturning) && p->tr_tm==tr_tm && checkColumnOverlap(p->pColumns, pChanges) ){ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 9ea20628fe..c7c2125751 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2602,7 +2602,10 @@ void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){ void sqlite3VdbeColumnInfoXfer(Vdbe *pTo, Vdbe *pFrom){ sqlite3 *db = pTo->db; assert( db==pFrom->db ); - sqlite3DbFree(db, pTo->aColName); + if( pTo->nResColumn ){ + releaseMemArray(pTo->aColName, pTo->nResColumn*COLNAME_N); + sqlite3DbFree(db, pTo->aColName); + } pTo->aColName = pFrom->aColName; pFrom->aColName = 0; pTo->nResColumn = pFrom->nResColumn; diff --git a/test/returning1.test b/test/returning1.test new file mode 100644 index 0000000000..52fb8812a6 --- /dev/null +++ b/test/returning1.test @@ -0,0 +1,87 @@ +# 2021-01-28 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this file is the new RETURNING clause +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix returning1 + +do_execsql_test 1.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY,b,c DEFAULT 'pax'); + INSERT INTO t1(b) VALUES(10),('happy'),(NULL) RETURNING a,b,c; +} {1 10 pax 2 happy pax 3 {} pax} +do_execsql_test 1.1 { + SELECT * FROM t1; +} {1 10 pax 2 happy pax 3 {} pax} +do_execsql_test 1.2 { + INSERT INTO t1(b,c) VALUES(5,99) RETURNING b,c,a,rowid; +} {5 99 4 4} +do_execsql_test 1.3 { + SELECT * FROM t1; +} {1 10 pax 2 happy pax 3 {} pax 4 5 99} +do_execsql_test 1.4 { + INSERT INTO t1 DEFAULT VALUES RETURNING *; +} {5 {} pax} +do_execsql_test 1.5 { + SELECT * FROM t1; +} {1 10 pax 2 happy pax 3 {} pax 4 5 99 5 {} pax} +do_execsql_test 1.6 { + CREATE TABLE t2(x,y,z); + INSERT INTO t2 VALUES(11,12,13),(21,'b','c'),(31,'b-value',4.75); +} +do_execsql_test 1.7 { + INSERT INTO t1 SELECT * FROM t2 RETURNING *; +} {11 12 13 21 b c 31 b-value 4.75} +do_execsql_test 1.8 { + SELECT *, '|' FROM t1; +} {1 10 pax | 2 happy pax | 3 {} pax | 4 5 99 | 5 {} pax | 11 12 13 | 21 b c | 31 b-value 4.75 |} + +do_execsql_test 2.1 { + UPDATE t1 SET c='bellum' WHERE c='pax' RETURNING rowid, b, '|'; +} {1 10 | 2 happy | 3 {} | 5 {} |} +do_execsql_test 2.2 { + SELECT *, '|' FROM t1; +} {1 10 bellum | 2 happy bellum | 3 {} bellum | 4 5 99 | 5 {} bellum | 11 12 13 | 21 b c | 31 b-value 4.75 |} + +do_execsql_test 3.1 { + DELETE FROM t1 WHERE c='bellum' RETURNING rowid, *, '|'; +} {1 1 10 bellum | 2 2 happy bellum | 3 3 {} bellum | 5 5 {} bellum |} +do_execsql_test 3.2 { + SELECT *, '|' FROM t1; +} {4 5 99 | 11 12 13 | 21 b c | 31 b-value 4.75 |} + +do_execsql_test 4.1 { + CREATE TABLE t4(a INT, b INT DEFAULT 1234, c INT DEFAULT -16); + CREATE UNIQUE INDEX t4a ON t4(a); + INSERT INTO t4(a,b,c) VALUES(1,2,3); +} {} +do_execsql_test 4.2 { + INSERT INTO t4(a,b,c) VALUES(1,22,33) + ON CONFLICT(a) DO UPDATE SET b=44 + RETURNING *; +} {1 44 3} +do_execsql_test 4.3 { + SELECT * FROM t4; +} {1 44 3} +do_execsql_test 4.4 { + DELETE FROM t4; + INSERT INTO t4 VALUES(1,2,3),(4,5,6),(7,8,9); +} {} +do_execsql_test 4.5 { + INSERT INTO t4(a,b,c) VALUES(2,3,4),(4,5,6),(5,6,7) + ON CONFLICT(a) DO UPDATE SET b=100 + RETURNING *, '|'; +} {2 3 4 | 4 100 6 | 5 6 7 |} + + +finish_test From 16d861ffc27142a17e4e888d8ff57280e3ac754c Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 30 Jan 2021 02:22:38 +0000 Subject: [PATCH 147/257] When running the RETURNING trigger, if it is tagged as a DELETE trigger, do not use it as INSERT or UPDATE. FossilOrigin-Name: 3c7a6e04ddde34961d8e9d0443913e572a80853cf14a8263cec19523c39ca744 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/trigger.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 97aab3c71b..332c29a24d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Test\scases\sadded.\s\sRETURNING\sworks\swith\sUPSERT\sas\sdoes\sPG. -D 2021-01-30T01:30:26.496 +C When\srunning\sthe\sRETURNING\strigger,\sif\sit\sis\stagged\sas\sa\sDELETE\strigger,\ndo\snot\suse\sit\sas\sINSERT\sor\sUPDATE. +D 2021-01-30T02:22:38.436 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -607,7 +607,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda -F src/trigger.c 88f616cbd1aa538f3d6bebc4e9b9fb95b566771b45c0690f21223de0317ace54 +F src/trigger.c 0b683379a7855f50bfd114cc7590bc1a10d4c8008dcc23e335e307459a36daba F src/update.c 3dbc7189ffcf361c2149f1b1d0841a8a9689d27f15c5e72e6f14ebc447e6b0c0 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 @@ -1899,7 +1899,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 6aa2a058d136d0b24d94c5cbe1ce447eb435c1a1c7cdce5e435f1548bb3f05e7 -R c5d28b15f2cd5974ae8ec5b186394cb6 +P f5698f96e27c9b8669ec6016bb9920ef7580c4146eb61d628a0f62be5135ce94 +R c9a80a1d4c54684acda1e51b55904277 U drh -Z 4324b62b15638b065ad3c0261246302c +Z 993208c24ec6d120a7fb4e41ada97fae diff --git a/manifest.uuid b/manifest.uuid index b8ff6b9b92..0fa6e547a7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f5698f96e27c9b8669ec6016bb9920ef7580c4146eb61d628a0f62be5135ce94 \ No newline at end of file +3c7a6e04ddde34961d8e9d0443913e572a80853cf14a8263cec19523c39ca744 \ No newline at end of file diff --git a/src/trigger.c b/src/trigger.c index baf78eb8c2..6a3498c457 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -740,7 +740,7 @@ Trigger *sqlite3TriggersExist( for(p=pList; p; p=p->pNext){ if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){ mask |= p->tr_tm; - }else if( p->bReturning ){ + }else if( p->bReturning && (p->op==TK_RETURNING || p->op!=TK_DELETE) ){ p->op = op; mask |= TRIGGER_AFTER; } @@ -1217,7 +1217,7 @@ void sqlite3CodeRowTrigger( || p->pSchema==pParse->db->aDb[1].pSchema ); /* Determine whether we should code this trigger */ - if( (p->op==op || p->bReturning) + if( (p->op==op || (p->bReturning && p->op!=TK_DELETE)) && p->tr_tm==tr_tm && checkColumnOverlap(p->pColumns, pChanges) ){ From 343256b9b0b4cc05b978f087c39518c01dee6eca Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 30 Jan 2021 02:34:47 +0000 Subject: [PATCH 148/257] Another attempt to get trigger selection correct for RETURNING triggers. FossilOrigin-Name: 1b8ed52275a54800df90682d694b482f55f26c6c4a420659f9a3b7bfc61e8abe --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/trigger.c | 4 +++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 332c29a24d..00cf98647f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\srunning\sthe\sRETURNING\strigger,\sif\sit\sis\stagged\sas\sa\sDELETE\strigger,\ndo\snot\suse\sit\sas\sINSERT\sor\sUPDATE. -D 2021-01-30T02:22:38.436 +C Another\sattempt\sto\sget\strigger\sselection\scorrect\sfor\sRETURNING\striggers. +D 2021-01-30T02:34:47.012 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -607,7 +607,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda -F src/trigger.c 0b683379a7855f50bfd114cc7590bc1a10d4c8008dcc23e335e307459a36daba +F src/trigger.c 6b312904df04c5e8bac6d801448736b5170d7902ea62d87615845938cf466836 F src/update.c 3dbc7189ffcf361c2149f1b1d0841a8a9689d27f15c5e72e6f14ebc447e6b0c0 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 @@ -1899,7 +1899,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 f5698f96e27c9b8669ec6016bb9920ef7580c4146eb61d628a0f62be5135ce94 -R c9a80a1d4c54684acda1e51b55904277 +P 3c7a6e04ddde34961d8e9d0443913e572a80853cf14a8263cec19523c39ca744 +R 62218e74d94127b5c670903aeb07216b U drh -Z 993208c24ec6d120a7fb4e41ada97fae +Z 08397caac37c2d39eeda13ae69545f62 diff --git a/manifest.uuid b/manifest.uuid index 0fa6e547a7..6e7cdb23a9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3c7a6e04ddde34961d8e9d0443913e572a80853cf14a8263cec19523c39ca744 \ No newline at end of file +1b8ed52275a54800df90682d694b482f55f26c6c4a420659f9a3b7bfc61e8abe \ No newline at end of file diff --git a/src/trigger.c b/src/trigger.c index 6a3498c457..e22439cf47 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -740,7 +740,8 @@ Trigger *sqlite3TriggersExist( for(p=pList; p; p=p->pNext){ if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){ mask |= p->tr_tm; - }else if( p->bReturning && (p->op==TK_RETURNING || p->op!=TK_DELETE) ){ + }else if( p->bReturning + && (p->op==TK_RETURNING || (p->op!=TK_DELETE && op!=TK_DELETE)) ){ p->op = op; mask |= TRIGGER_AFTER; } @@ -1221,6 +1222,7 @@ void sqlite3CodeRowTrigger( && p->tr_tm==tr_tm && checkColumnOverlap(p->pColumns, pChanges) ){ + p->op = op; sqlite3CodeRowTriggerDirect(pParse, p, pTab, reg, orconf, ignoreJump); } } From 658f0a36796bc6508bbc01379bb1725775e9a9b7 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 30 Jan 2021 02:43:26 +0000 Subject: [PATCH 149/257] Fix a memory deallocation problem that comes up when doing a RETURNING query on a corrupt database. I think I fixed this before, but it got unfixed with stale editor content. FossilOrigin-Name: 02b1415efb7d9849499afe4e9dbf7e470484bf144d6ca3d28fdc38fc0ac10afa --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/trigger.c | 3 +-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 00cf98647f..1654f29a1a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Another\sattempt\sto\sget\strigger\sselection\scorrect\sfor\sRETURNING\striggers. -D 2021-01-30T02:34:47.012 +C Fix\sa\smemory\sdeallocation\sproblem\sthat\scomes\sup\swhen\sdoing\sa\sRETURNING\squery\non\sa\scorrupt\sdatabase.\s\sI\sthink\sI\sfixed\sthis\sbefore,\sbut\sit\sgot\sunfixed\swith\nstale\seditor\scontent. +D 2021-01-30T02:43:26.023 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -607,7 +607,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda -F src/trigger.c 6b312904df04c5e8bac6d801448736b5170d7902ea62d87615845938cf466836 +F src/trigger.c ec5ba098328dccba9b5c2e5e9946df4dab1d551ae8b7d1b0bdaec65914bf2bfa F src/update.c 3dbc7189ffcf361c2149f1b1d0841a8a9689d27f15c5e72e6f14ebc447e6b0c0 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 @@ -1899,7 +1899,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 3c7a6e04ddde34961d8e9d0443913e572a80853cf14a8263cec19523c39ca744 -R 62218e74d94127b5c670903aeb07216b +P 1b8ed52275a54800df90682d694b482f55f26c6c4a420659f9a3b7bfc61e8abe +R cf21e41910dc0faee5037ce4e11838eb U drh -Z 08397caac37c2d39eeda13ae69545f62 +Z 8a2777d3702d0168b2e6293ee5f1e515 diff --git a/manifest.uuid b/manifest.uuid index 6e7cdb23a9..828d783ff4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1b8ed52275a54800df90682d694b482f55f26c6c4a420659f9a3b7bfc61e8abe \ No newline at end of file +02b1415efb7d9849499afe4e9dbf7e470484bf144d6ca3d28fdc38fc0ac10afa \ No newline at end of file diff --git a/src/trigger.c b/src/trigger.c index e22439cf47..805b960364 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -567,8 +567,7 @@ TriggerStep *sqlite3TriggerDeleteStep( ** Recursively delete a Trigger structure */ void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){ - if( pTrigger==0 ) return; - assert( !pTrigger->bReturning ); + if( pTrigger==0 || pTrigger->bReturning ) return; sqlite3DeleteTriggerStep(db, pTrigger->step_list); sqlite3DbFree(db, pTrigger->zName); sqlite3DbFree(db, pTrigger->table); From cf4108bbc687170edaeaed2548524bec3b63b5eb Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 30 Jan 2021 03:06:19 +0000 Subject: [PATCH 150/257] Fix handling of an OOM condition in sqlite3AddReturning(). FossilOrigin-Name: 52204cd768f115d13249ff0e3a252b716620f7ad16a6962e1192a09137a78596 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 1654f29a1a..5b308e9abc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\smemory\sdeallocation\sproblem\sthat\scomes\sup\swhen\sdoing\sa\sRETURNING\squery\non\sa\scorrupt\sdatabase.\s\sI\sthink\sI\sfixed\sthis\sbefore,\sbut\sit\sgot\sunfixed\swith\nstale\seditor\scontent. -D 2021-01-30T02:43:26.023 +C Fix\shandling\sof\san\sOOM\scondition\sin\ssqlite3AddReturning(). +D 2021-01-30T03:06:19.421 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -485,7 +485,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 47d9fe97d5c0d74506154e3597f8a23b81a00080751dc4d11fec91ee22796f4c F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 -F src/build.c 451f832bfcbcb3004b09909608c452f1488863111167378355f95782c95bb358 +F src/build.c d708731a10a780723f7f6d996c1a7ff827ce2153bb4b6e964a59176fc373a6a3 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 @@ -1899,7 +1899,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 1b8ed52275a54800df90682d694b482f55f26c6c4a420659f9a3b7bfc61e8abe -R cf21e41910dc0faee5037ce4e11838eb +P 02b1415efb7d9849499afe4e9dbf7e470484bf144d6ca3d28fdc38fc0ac10afa +R 0f2932eca63747c13c7de64fbcf0f21a U drh -Z 8a2777d3702d0168b2e6293ee5f1e515 +Z 484e428235115814320582a3c935b7db diff --git a/manifest.uuid b/manifest.uuid index 828d783ff4..6b582d77da 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -02b1415efb7d9849499afe4e9dbf7e470484bf144d6ca3d28fdc38fc0ac10afa \ No newline at end of file +52204cd768f115d13249ff0e3a252b716620f7ad16a6962e1192a09137a78596 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 4143221c39..e9e35333c4 100644 --- a/src/build.c +++ b/src/build.c @@ -1277,6 +1277,7 @@ void sqlite3AddReturning(Parse *pParse, ExprList *pList){ pRet->pReturnEL = pList; sqlite3ParserAddCleanup(pParse, (void(*)(sqlite3*,void*))sqlite3DeleteReturning, pRet); + if( db->mallocFailed ) return; pRet->retTrig.zName = "sqlite_returning"; pRet->retTrig.op = TK_RETURNING; pRet->retTrig.tr_tm = TRIGGER_AFTER; From 0166df0bdad64754cb72f205a823575dae7b45ea Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 30 Jan 2021 12:07:32 +0000 Subject: [PATCH 151/257] Fix a obsolete assert() in the bytecode engine. Improved OOM detection in sqlite3AddReturning(). FossilOrigin-Name: 138b10d54a83e1e7d5b3cdbe593a5073b05e632d1823e1b74d85835435b9ee3d --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/build.c | 5 ++++- src/vdbe.c | 9 +++++---- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 5b308e9abc..9eb9587464 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\shandling\sof\san\sOOM\scondition\sin\ssqlite3AddReturning(). -D 2021-01-30T03:06:19.421 +C Fix\sa\sobsolete\sassert()\sin\sthe\sbytecode\sengine.\s\sImproved\sOOM\sdetection\nin\ssqlite3AddReturning(). +D 2021-01-30T12:07:32.582 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -485,7 +485,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 47d9fe97d5c0d74506154e3597f8a23b81a00080751dc4d11fec91ee22796f4c F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 -F src/build.c d708731a10a780723f7f6d996c1a7ff827ce2153bb4b6e964a59176fc373a6a3 +F src/build.c ff2cdab3c86156c3c1808e282daaf04d298e532ef11478844964107496898cf9 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 @@ -613,7 +613,7 @@ F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 41c7a72da1df47864faa378a1c720b38adb288c6838cb6be5594511b6287a048 F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286 -F src/vdbe.c 102d21260bddbb43c845603c3a2d6b4f3762e72f836ccda12991f291485d2539 +F src/vdbe.c 5761ca995715f12825faba7a465c6aa1c92cf88f3199fc221d312268edfde6f5 F src/vdbe.h a71bf43572d3de57923d1928ac01ae8d355cd67e94462ba4f7462265cedbef9a F src/vdbeInt.h 3ca5e9fd6e095a8b6cf6bc3587a46fc93499503b2fe48951e1034ba9e2ce2f6e F src/vdbeapi.c c5e7cb2ab89a24d7f723e87b508f21bfb1359a04db5277d8a99fd1e015c12eb9 @@ -1899,7 +1899,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 02b1415efb7d9849499afe4e9dbf7e470484bf144d6ca3d28fdc38fc0ac10afa -R 0f2932eca63747c13c7de64fbcf0f21a +P 52204cd768f115d13249ff0e3a252b716620f7ad16a6962e1192a09137a78596 +R 2383351840f532b10fd8d9e8187ff10e U drh -Z 484e428235115814320582a3c935b7db +Z 835a3a4123d883b7f5aa3b3a2eaef96a diff --git a/manifest.uuid b/manifest.uuid index 6b582d77da..37afd6a33a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -52204cd768f115d13249ff0e3a252b716620f7ad16a6962e1192a09137a78596 \ No newline at end of file +138b10d54a83e1e7d5b3cdbe593a5073b05e632d1823e1b74d85835435b9ee3d \ No newline at end of file diff --git a/src/build.c b/src/build.c index e9e35333c4..b0dac9965d 100644 --- a/src/build.c +++ b/src/build.c @@ -1292,7 +1292,10 @@ void sqlite3AddReturning(Parse *pParse, ExprList *pList){ pRet->retSel.pSrc = (SrcList*)&pRet->retSrcList; pHash = &(db->aDb[1].pSchema->trigHash); assert( sqlite3HashFind(pHash, RETURNING_TRIGGER)==0 ); - sqlite3HashInsert(pHash, "sqlite_returning", &pRet->retTrig); + if( sqlite3HashInsert(pHash, "sqlite_returning", &pRet->retTrig) + ==&pRet->retTrig ){ + sqlite3OomFault(db); + } } /* diff --git a/src/vdbe.c b/src/vdbe.c index 3a00515e57..d38d9a0689 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1470,9 +1470,10 @@ case OP_ResultRow: { goto abort_due_to_error; } - /* If the SQLITE_CountRows flag is set in sqlite3.flags mask, then - ** DML statements invoke this opcode to return the number of rows - ** modified to the user. This is the only way that a VM that + /* DML statements can invoke this opcode to return the number of rows + ** modified to the user if the "PRAGMA count_changes=ON" pragma has been + ** run. DML statement triggers can invoke this satement to implement + ** the RETURNING clause. Thess are the only ways that a VM that ** opens a statement transaction may invoke this opcode. ** ** In case this is such a statement, close any statement transaction @@ -1485,7 +1486,7 @@ case OP_ResultRow: { ** The statement transaction is never a top-level transaction. Hence ** the RELEASE call below can never fail. */ - assert( p->iStatement==0 || db->flags&SQLITE_CountRows ); + assert( p->iStatement==0 || db->flags&SQLITE_CountRows || p->pFrame ); rc = sqlite3VdbeCloseStatement(p, SAVEPOINT_RELEASE); assert( rc==SQLITE_OK ); From a8a64a078ff8e44f175f1985d75cb91c25f8f5e3 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 30 Jan 2021 14:17:18 +0000 Subject: [PATCH 152/257] Chagne the OP_ResultRow opcode so that it does not cancel pending statement transactions. FossilOrigin-Name: fea91e3a511b14dafcc4da92c59188f927ec60ed91441335183da6b4e7866c1b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 20 -------------------- 3 files changed, 7 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index 9eb9587464..fabb001c84 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sobsolete\sassert()\sin\sthe\sbytecode\sengine.\s\sImproved\sOOM\sdetection\nin\ssqlite3AddReturning(). -D 2021-01-30T12:07:32.582 +C Chagne\sthe\sOP_ResultRow\sopcode\sso\sthat\sit\sdoes\snot\scancel\npending\sstatement\stransactions. +D 2021-01-30T14:17:18.189 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -613,7 +613,7 @@ F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 41c7a72da1df47864faa378a1c720b38adb288c6838cb6be5594511b6287a048 F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286 -F src/vdbe.c 5761ca995715f12825faba7a465c6aa1c92cf88f3199fc221d312268edfde6f5 +F src/vdbe.c d715b1eeb37168afec92185bcf3dc6da175abafd247821af200ac7eeab68a706 F src/vdbe.h a71bf43572d3de57923d1928ac01ae8d355cd67e94462ba4f7462265cedbef9a F src/vdbeInt.h 3ca5e9fd6e095a8b6cf6bc3587a46fc93499503b2fe48951e1034ba9e2ce2f6e F src/vdbeapi.c c5e7cb2ab89a24d7f723e87b508f21bfb1359a04db5277d8a99fd1e015c12eb9 @@ -1899,7 +1899,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 52204cd768f115d13249ff0e3a252b716620f7ad16a6962e1192a09137a78596 -R 2383351840f532b10fd8d9e8187ff10e +P 138b10d54a83e1e7d5b3cdbe593a5073b05e632d1823e1b74d85835435b9ee3d +R 570c84bd891a98ecddec602b36250bc2 U drh -Z 835a3a4123d883b7f5aa3b3a2eaef96a +Z 60be8821ffce46f579893c6cfdf10955 diff --git a/manifest.uuid b/manifest.uuid index 37afd6a33a..23a12179ec 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -138b10d54a83e1e7d5b3cdbe593a5073b05e632d1823e1b74d85835435b9ee3d \ No newline at end of file +fea91e3a511b14dafcc4da92c59188f927ec60ed91441335183da6b4e7866c1b \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index d38d9a0689..6547b41553 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1470,26 +1470,6 @@ case OP_ResultRow: { goto abort_due_to_error; } - /* DML statements can invoke this opcode to return the number of rows - ** modified to the user if the "PRAGMA count_changes=ON" pragma has been - ** run. DML statement triggers can invoke this satement to implement - ** the RETURNING clause. Thess are the only ways that a VM that - ** opens a statement transaction may invoke this opcode. - ** - ** In case this is such a statement, close any statement transaction - ** opened by this VM before returning control to the user. This is to - ** ensure that statement-transactions are always nested, not overlapping. - ** If the open statement-transaction is not closed here, then the user - ** may step another VM that opens its own statement transaction. This - ** may lead to overlapping statement transactions. - ** - ** The statement transaction is never a top-level transaction. Hence - ** the RELEASE call below can never fail. - */ - assert( p->iStatement==0 || db->flags&SQLITE_CountRows || p->pFrame ); - rc = sqlite3VdbeCloseStatement(p, SAVEPOINT_RELEASE); - assert( rc==SQLITE_OK ); - /* Invalidate all ephemeral cursor row caches */ p->cacheCtr = (p->cacheCtr + 2)|1; From 1832f2921dcfee91d4ab68b6612acd75d54d4f43 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 30 Jan 2021 16:16:42 +0000 Subject: [PATCH 153/257] Add an ALWAYS() to an unreachable branch. FossilOrigin-Name: 6bb6de42b62acd35ade6c95a11bb4c9b35e7e9a24620731ae36364c4d5c3bc31 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/resolve.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index fabb001c84..80f6d36869 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Chagne\sthe\sOP_ResultRow\sopcode\sso\sthat\sit\sdoes\snot\scancel\npending\sstatement\stransactions. -D 2021-01-30T14:17:18.189 +C Add\san\sALWAYS()\sto\san\sunreachable\sbranch. +D 2021-01-30T16:16:42.507 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -539,7 +539,7 @@ F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf F src/prepare.c f288cbc35f79eb32e162de7e80a63ebe00d80e639dcfac071bee11570cbdb16f F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c b714e6f9f3cdfb6ba287bb5ef76888ec8cd9e15c98a608c82bc3300b99a245d7 +F src/resolve.c f6761473ea4b51190fc52f8f2121498b78717266e106e7bff12849ea2d52165f F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 738cb746189f721f59972993c13085fa2975c4cbfd04ba26445f3b42c81237dc F src/shell.c.in 9ebc74e4f05cfbd0f4a36060fdaeff1da4e9af4458358722bc08c5a1ab9a0879 @@ -1899,7 +1899,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 138b10d54a83e1e7d5b3cdbe593a5073b05e632d1823e1b74d85835435b9ee3d -R 570c84bd891a98ecddec602b36250bc2 +P fea91e3a511b14dafcc4da92c59188f927ec60ed91441335183da6b4e7866c1b +R 8cd82e0fb3b2559278f1acef6be93a28 U drh -Z 60be8821ffce46f579893c6cfdf10955 +Z 32c0d1eece5071f19ef4a6007df09364 diff --git a/manifest.uuid b/manifest.uuid index 23a12179ec..c7413ce5bb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fea91e3a511b14dafcc4da92c59188f927ec60ed91441335183da6b4e7866c1b \ No newline at end of file +6bb6de42b62acd35ade6c95a11bb4c9b35e7e9a24620731ae36364c4d5c3bc31 \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index fa46954da8..5074a28812 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -390,7 +390,7 @@ static int lookupName( } #endif /* SQLITE_OMIT_TRIGGER */ #ifndef SQLITE_OMIT_UPSERT - if( (pNC->ncFlags & NC_UUpsert)!=0 && zTab ){ + if( (pNC->ncFlags & NC_UUpsert)!=0 && ALWAYS(zTab) ){ Upsert *pUpsert = pNC->uNC.pUpsert; if( pUpsert && sqlite3StrICmp("excluded",zTab)==0 ){ pTab = pUpsert->pUpsertSrc->a[0].pTab; From 28828c550fe957516ca2d49cd485ae3cb209ea4a Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 30 Jan 2021 21:55:38 +0000 Subject: [PATCH 154/257] Improved comments on the new code. FossilOrigin-Name: a38f0c1d7c1d7635732ac370d8fbc7e6a2005378e4621da7bc4f51a2f99912d1 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/build.c | 31 +++++++++++++++++++++++-------- src/trigger.c | 18 ++++++++++++++---- 4 files changed, 45 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 80f6d36869..33c213e5b0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\san\sALWAYS()\sto\san\sunreachable\sbranch. -D 2021-01-30T16:16:42.507 +C Improved\scomments\son\sthe\snew\scode. +D 2021-01-30T21:55:38.166 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -485,7 +485,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 47d9fe97d5c0d74506154e3597f8a23b81a00080751dc4d11fec91ee22796f4c F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 -F src/build.c ff2cdab3c86156c3c1808e282daaf04d298e532ef11478844964107496898cf9 +F src/build.c 118e1076282415229420d04f9cc25bb148a2c412d82ea3c319136d2122c842e5 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 @@ -607,7 +607,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda -F src/trigger.c ec5ba098328dccba9b5c2e5e9946df4dab1d551ae8b7d1b0bdaec65914bf2bfa +F src/trigger.c 207168409c59f346df3a8b4556f0f35fdf721cd35e06fb3c75ea76b7ce95ed35 F src/update.c 3dbc7189ffcf361c2149f1b1d0841a8a9689d27f15c5e72e6f14ebc447e6b0c0 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 @@ -1899,7 +1899,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 fea91e3a511b14dafcc4da92c59188f927ec60ed91441335183da6b4e7866c1b -R 8cd82e0fb3b2559278f1acef6be93a28 +P 6bb6de42b62acd35ade6c95a11bb4c9b35e7e9a24620731ae36364c4d5c3bc31 +R 9e0cb8b9c72d2bfe4a3d882f4b872a05 U drh -Z 32c0d1eece5071f19ef4a6007df09364 +Z 296f4bf266bf4139fc832ba9efb3047c diff --git a/manifest.uuid b/manifest.uuid index c7413ce5bb..32aff6c58f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6bb6de42b62acd35ade6c95a11bb4c9b35e7e9a24620731ae36364c4d5c3bc31 \ No newline at end of file +a38f0c1d7c1d7635732ac370d8fbc7e6a2005378e4621da7bc4f51a2f99912d1 \ No newline at end of file diff --git a/src/build.c b/src/build.c index b0dac9965d..25f61e8156 100644 --- a/src/build.c +++ b/src/build.c @@ -1244,23 +1244,38 @@ void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){ #endif /* -** Name of the magic TEMP trigger used to implement RETURNING +** Name of the special TEMP trigger used to implement RETURNING. The +** name begins with "sqlite_" so that it is guaranteed not to collide +** with any application-generated triggers. */ -#define RETURNING_TRIGGER "sqlite_returning" +#define RETURNING_TRIGGER_NAME "sqlite_returning" /* -** Delete the data structures associated with the RETURNING clause. +** Clean up the data structures associated with the RETURNING clause. */ static void sqlite3DeleteReturning(sqlite3 *db, Returning *pRet){ Hash *pHash; pHash = &(db->aDb[1].pSchema->trigHash); - sqlite3HashInsert(pHash, RETURNING_TRIGGER, 0); + sqlite3HashInsert(pHash, RETURNING_TRIGGER_NAME, 0); sqlite3ExprListDelete(db, pRet->pReturnEL); sqlite3DbFree(db, pRet); } /* -** Add the RETURNING clause to the parser currently underway. +** Add the RETURNING clause to the parse currently underway. +** +** This routine creates a special TEMP trigger that will fire for each row +** of the DML statement. That TEMP trigger contains a single SELECT +** statement with a result set that is the argument of the RETURNING clause. +** The trigger has the Trigger.bReturning flag and an opcode of +** TK_RETURNING instead of TK_SELECT, so that the trigger code generator +** knows to handle it specially. The TEMP trigger is automatically +** removed at the end of the parse. +** +** When this routine is called, we do not yet know if the RETURNING clause +** is attached to a DELETE, INSERT, or UPDATE, so construct it as a +** RETURNING trigger instead. It will then be converted into the appropriate +** type on the first call to sqlite3TriggersExist(). */ void sqlite3AddReturning(Parse *pParse, ExprList *pList){ Returning *pRet; @@ -1278,7 +1293,7 @@ void sqlite3AddReturning(Parse *pParse, ExprList *pList){ sqlite3ParserAddCleanup(pParse, (void(*)(sqlite3*,void*))sqlite3DeleteReturning, pRet); if( db->mallocFailed ) return; - pRet->retTrig.zName = "sqlite_returning"; + pRet->retTrig.zName = RETURNING_TRIGGER_NAME; pRet->retTrig.op = TK_RETURNING; pRet->retTrig.tr_tm = TRIGGER_AFTER; pRet->retTrig.bReturning = 1; @@ -1291,8 +1306,8 @@ void sqlite3AddReturning(Parse *pParse, ExprList *pList){ pRet->retSel.pEList = pList; pRet->retSel.pSrc = (SrcList*)&pRet->retSrcList; pHash = &(db->aDb[1].pSchema->trigHash); - assert( sqlite3HashFind(pHash, RETURNING_TRIGGER)==0 ); - if( sqlite3HashInsert(pHash, "sqlite_returning", &pRet->retTrig) + assert( sqlite3HashFind(pHash, RETURNING_TRIGGER_NAME)==0 ); + if( sqlite3HashInsert(pHash, RETURNING_TRIGGER_NAME, &pRet->retTrig) ==&pRet->retTrig ){ sqlite3OomFault(db); } diff --git a/src/trigger.c b/src/trigger.c index 805b960364..5463d2dd0f 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -739,10 +739,14 @@ Trigger *sqlite3TriggersExist( for(p=pList; p; p=p->pNext){ if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){ mask |= p->tr_tm; - }else if( p->bReturning - && (p->op==TK_RETURNING || (p->op!=TK_DELETE && op!=TK_DELETE)) ){ + }else if( p->op==TK_RETURNING ){ + /* The first time a RETURNING trigger is seen, the "op" value tells + ** us what time of trigger it should be. */ p->op = op; mask |= TRIGGER_AFTER; + }else if( p->bReturning && p->op==TK_INSERT && op==TK_UPDATE ){ + /* Also fire a RETURNING trigger for INSERT on the UPDATE of an UPSERT */ + mask |= TRIGGER_AFTER; } } if( pMask ){ @@ -1216,13 +1220,19 @@ void sqlite3CodeRowTrigger( assert( p->pSchema==p->pTabSchema || p->pSchema==pParse->db->aDb[1].pSchema ); - /* Determine whether we should code this trigger */ - if( (p->op==op || (p->bReturning && p->op!=TK_DELETE)) + /* Determine whether we should code this trigger. One of two choices: + ** 1. The trigger is an exact match to the current DML statement + ** 2. This is a RETURNING trigger for INSERT but we are currently + ** doing the UPDATE part of an UPSERT. + */ + if( (p->op==op || (p->bReturning && p->op==TK_INSERT && op==TK_UPDATE)) && p->tr_tm==tr_tm && checkColumnOverlap(p->pColumns, pChanges) ){ + u8 origOp = p->op; p->op = op; sqlite3CodeRowTriggerDirect(pParse, p, pTab, reg, orconf, ignoreJump); + p->op = origOp; } } } From 662fe7964744f40f5e75e71a5c2f50cbc3817a72 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 31 Jan 2021 12:41:20 +0000 Subject: [PATCH 155/257] When setting the number of result columns in a RETURNING trigger, be sure to set that value in the top-level bytecode program, not in the immediate caller of the trigger. FossilOrigin-Name: 1f1ce7ceb9807d22efea496f33908040ee196a31cd192f27ec0fb3e23afb729c --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/trigger.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 33c213e5b0..0955fb3250 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\scomments\son\sthe\snew\scode. -D 2021-01-30T21:55:38.166 +C When\ssetting\sthe\snumber\sof\sresult\scolumns\sin\sa\sRETURNING\strigger,\sbe\ssure\nto\sset\sthat\svalue\sin\sthe\stop-level\sbytecode\sprogram,\snot\sin\sthe\simmediate\ncaller\sof\sthe\strigger. +D 2021-01-31T12:41:20.387 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -607,7 +607,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda -F src/trigger.c 207168409c59f346df3a8b4556f0f35fdf721cd35e06fb3c75ea76b7ce95ed35 +F src/trigger.c 424f81a5631a06dda99d70c6bfa3e7e6ead74ab9eb757b77f75a14a18ef7d419 F src/update.c 3dbc7189ffcf361c2149f1b1d0841a8a9689d27f15c5e72e6f14ebc447e6b0c0 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 @@ -1899,7 +1899,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 6bb6de42b62acd35ade6c95a11bb4c9b35e7e9a24620731ae36364c4d5c3bc31 -R 9e0cb8b9c72d2bfe4a3d882f4b872a05 +P a38f0c1d7c1d7635732ac370d8fbc7e6a2005378e4621da7bc4f51a2f99912d1 +R 34ba0ebdbec7699355883290972263ed U drh -Z 296f4bf266bf4139fc832ba9efb3047c +Z 1a944974e641f069223aa2fcb2319010 diff --git a/manifest.uuid b/manifest.uuid index 32aff6c58f..ca1e4d426c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a38f0c1d7c1d7635732ac370d8fbc7e6a2005378e4621da7bc4f51a2f99912d1 \ No newline at end of file +1f1ce7ceb9807d22efea496f33908040ee196a31cd192f27ec0fb3e23afb729c \ No newline at end of file diff --git a/src/trigger.c b/src/trigger.c index 5463d2dd0f..ae86c7c9af 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -1064,7 +1064,7 @@ static TriggerPrg *codeRowTrigger( pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg); } if( pTrigger->bReturning ){ - sqlite3VdbeColumnInfoXfer(pParse->pVdbe, v); + sqlite3VdbeColumnInfoXfer(sqlite3ParseToplevel(pParse)->pVdbe, v); } pProgram->nMem = pSubParse->nMem; pProgram->nCsr = pSubParse->nTab; From 18e5607211405d3852bbc61e39794ebb32574ebc Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 31 Jan 2021 15:50:36 +0000 Subject: [PATCH 156/257] New opcode OP_ChngCntRow used to output the result of PRAGMA change_count. Only this new opcode, and not OP_ResultRow, checks for foreign key errors. Faster performance, and now also works with RETURNING. FossilOrigin-Name: 154fc2b15465c7c92a1af0a93851421aec42a81bab54840a9701f2c78068e14e --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/delete.c | 2 +- src/insert.c | 2 +- src/update.c | 2 +- src/vdbe.c | 29 ++++++++++++++++++++--------- 6 files changed, 33 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 0955fb3250..a461a2acbd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\ssetting\sthe\snumber\sof\sresult\scolumns\sin\sa\sRETURNING\strigger,\sbe\ssure\nto\sset\sthat\svalue\sin\sthe\stop-level\sbytecode\sprogram,\snot\sin\sthe\simmediate\ncaller\sof\sthe\strigger. -D 2021-01-31T12:41:20.387 +C New\sopcode\sOP_ChngCntRow\sused\sto\soutput\sthe\sresult\sof\sPRAGMA\schange_count.\nOnly\sthis\snew\sopcode,\sand\snot\sOP_ResultRow,\schecks\sfor\sforeign\skey\serrors.\nFaster\sperformance,\sand\snow\salso\sworks\swith\sRETURNING. +D 2021-01-31T15:50:36.442 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -492,7 +492,7 @@ F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 F src/date.c dace306a10d9b02ee553d454c8e1cf8d3c9b932e137738a6b15b90253a9bfc10 F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c -F src/delete.c a4b3a6db02d2e705edf41bdb378d4c53c106f305fd8e7b441713fe87f69ea624 +F src/delete.c 352ea931218c45a3daf17472d4141b9c7fc026d85da3f1ade404ea5bb6d67f77 F src/expr.c 47c85263e6d179424e6b09e2c79db5704ab5b8cbc2fae2ee3285faa2566f2e74 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 02e4a3311885cd2b31eb17fd58dc2fc738cd2c823d0d39e4dd5595169c6f8bc3 @@ -502,7 +502,7 @@ 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 8f725611e5c5943cfd40461a8fa518538d8be666ef09097a29f7272ccd3ab0a0 +F src/insert.c 97be36c52c667a64aacbba76398544d224268d62444b67d011a077c486e375bb F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 F src/main.c 1c5de7b3fabcdf05f4fe563aab5d81d175b89c67a8678a12ba86629356afa356 @@ -608,12 +608,12 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda F src/trigger.c 424f81a5631a06dda99d70c6bfa3e7e6ead74ab9eb757b77f75a14a18ef7d419 -F src/update.c 3dbc7189ffcf361c2149f1b1d0841a8a9689d27f15c5e72e6f14ebc447e6b0c0 +F src/update.c 0f5a61f0787199983530a33f6fffe4f52742f35fcdf6ccfad1078b1a8bc17723 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 41c7a72da1df47864faa378a1c720b38adb288c6838cb6be5594511b6287a048 F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286 -F src/vdbe.c d715b1eeb37168afec92185bcf3dc6da175abafd247821af200ac7eeab68a706 +F src/vdbe.c 9b9a714318e49b59a282b4e175080dc53a07b8099895fa21613e6b80fbad3727 F src/vdbe.h a71bf43572d3de57923d1928ac01ae8d355cd67e94462ba4f7462265cedbef9a F src/vdbeInt.h 3ca5e9fd6e095a8b6cf6bc3587a46fc93499503b2fe48951e1034ba9e2ce2f6e F src/vdbeapi.c c5e7cb2ab89a24d7f723e87b508f21bfb1359a04db5277d8a99fd1e015c12eb9 @@ -1899,7 +1899,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 a38f0c1d7c1d7635732ac370d8fbc7e6a2005378e4621da7bc4f51a2f99912d1 -R 34ba0ebdbec7699355883290972263ed +P 1f1ce7ceb9807d22efea496f33908040ee196a31cd192f27ec0fb3e23afb729c +R ed51f62c70425c1aaf20f4ecddc8579f U drh -Z 1a944974e641f069223aa2fcb2319010 +Z 39d7fe9d2d8727b4a3ee19f9ebc8e8e1 diff --git a/manifest.uuid b/manifest.uuid index ca1e4d426c..7749366dc6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1f1ce7ceb9807d22efea496f33908040ee196a31cd192f27ec0fb3e23afb729c \ No newline at end of file +154fc2b15465c7c92a1af0a93851421aec42a81bab54840a9701f2c78068e14e \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index e9b092b245..b2edaa9ab9 100644 --- a/src/delete.c +++ b/src/delete.c @@ -609,7 +609,7 @@ void sqlite3DeleteFrom( ** invoke the callback function. */ if( memCnt ){ - sqlite3VdbeAddOp2(v, OP_ResultRow, memCnt, 1); + sqlite3VdbeAddOp2(v, OP_ChngCntRow, memCnt, 1); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC); } diff --git a/src/insert.c b/src/insert.c index 4f549f3523..2f22121f7d 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1319,7 +1319,7 @@ insert_end: ** invoke the callback function. */ if( regRowCount ){ - sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1); + sqlite3VdbeAddOp2(v, OP_ChngCntRow, regRowCount, 1); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC); } diff --git a/src/update.c b/src/update.c index 82a6eb6356..b360766b68 100644 --- a/src/update.c +++ b/src/update.c @@ -1107,7 +1107,7 @@ void sqlite3Update( ** that information. */ if( regRowCount ){ - sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1); + sqlite3VdbeAddOp2(v, OP_ChngCntRow, regRowCount, 1); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC); } diff --git a/src/vdbe.c b/src/vdbe.c index 6547b41553..bb18277891 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1445,6 +1445,26 @@ case OP_IntCopy: { /* out2 */ break; } +/* Opcode: ChngCntRow P1 P2 * * * +** Synopsis: output=r[P1] +** +** Output value in register P1 as the chance count for a DML statement, +** due to the "PRAGMA count_changes=ON" setting. Or, if there was a +** foreign key error in the statement, trigger the error now. +** +** This opcode is a variant of OP_ResultRow that checks the foreign key +** immediate constraint count and throws an error if the count is +** non-zero. The P2 opcode must be 1. +*/ +case OP_ChngCntRow: { + assert( pOp->p2==1 ); + if( (rc = sqlite3VdbeCheckFk(p,0))!=SQLITE_OK ){ + goto abort_due_to_error; + } + /* Fall through to the next case, OP_String */ + /* no break */ deliberate_fall_through +} + /* Opcode: ResultRow P1 P2 * * * ** Synopsis: output=r[P1@P2] ** @@ -1461,15 +1481,6 @@ case OP_ResultRow: { assert( pOp->p1>0 ); assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 ); - /* If this statement has violated immediate foreign key constraints, do - ** not return the number of rows modified. And do not RELEASE the statement - ** transaction. It needs to be rolled back. */ - if( SQLITE_OK!=(rc = sqlite3VdbeCheckFk(p, 0)) ){ - assert( db->flags&SQLITE_CountRows ); - assert( p->usesStmtJournal ); - goto abort_due_to_error; - } - /* Invalidate all ephemeral cursor row caches */ p->cacheCtr = (p->cacheCtr + 2)|1; From 9407b6ef29d676da3184ccd456a46049c5b3c448 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 31 Jan 2021 16:45:10 +0000 Subject: [PATCH 157/257] Mark an unreachable branch as ALWAYS(). FossilOrigin-Name: cb8b797a64f65fca01c5faaeb30cbe4a53b56b81e696d1b62a90362d7ef8f924 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/trigger.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index a461a2acbd..b7675c721e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\sopcode\sOP_ChngCntRow\sused\sto\soutput\sthe\sresult\sof\sPRAGMA\schange_count.\nOnly\sthis\snew\sopcode,\sand\snot\sOP_ResultRow,\schecks\sfor\sforeign\skey\serrors.\nFaster\sperformance,\sand\snow\salso\sworks\swith\sRETURNING. -D 2021-01-31T15:50:36.442 +C Mark\san\sunreachable\sbranch\sas\sALWAYS(). +D 2021-01-31T16:45:10.780 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -607,7 +607,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda -F src/trigger.c 424f81a5631a06dda99d70c6bfa3e7e6ead74ab9eb757b77f75a14a18ef7d419 +F src/trigger.c b380259579a6d9dc3fa50d49b1b18ebfe42c10f12d3c5b3d0e2f7c3b35c45574 F src/update.c 0f5a61f0787199983530a33f6fffe4f52742f35fcdf6ccfad1078b1a8bc17723 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 @@ -1899,7 +1899,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 1f1ce7ceb9807d22efea496f33908040ee196a31cd192f27ec0fb3e23afb729c -R ed51f62c70425c1aaf20f4ecddc8579f +P 154fc2b15465c7c92a1af0a93851421aec42a81bab54840a9701f2c78068e14e +R cea5f0df7552de24bb2dee28a7a1e3f6 U drh -Z 39d7fe9d2d8727b4a3ee19f9ebc8e8e1 +Z fb166b95a911fcb55830f05a31923ad0 diff --git a/manifest.uuid b/manifest.uuid index 7749366dc6..3f622440c0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -154fc2b15465c7c92a1af0a93851421aec42a81bab54840a9701f2c78068e14e \ No newline at end of file +cb8b797a64f65fca01c5faaeb30cbe4a53b56b81e696d1b62a90362d7ef8f924 \ No newline at end of file diff --git a/src/trigger.c b/src/trigger.c index ae86c7c9af..de926f305d 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -821,7 +821,7 @@ static ExprList *sqlite3ExpandReturning( }else{ Expr *pNewExpr = sqlite3ExprDup(db, pOldExpr, 0); pNew = sqlite3ExprListAppend(pParse, pNew, pNewExpr); - if( pList->a[i].zEName!=0 && !db->mallocFailed ){ + if( !db->mallocFailed && ALWAYS(pList->a[i].zEName!=0) ){ struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1]; pItem->zEName = sqlite3DbStrDup(db, pList->a[i].zEName); pItem->eEName = pList->a[i].eEName; From 7baf3d411b6dc45c4478741958e383bab5fc666a Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 1 Feb 2021 01:57:55 +0000 Subject: [PATCH 158/257] Modify RETURNING so that it does not return changes implemented by cascading foreign keys or by triggers. FossilOrigin-Name: 6e62470a737cbde7f3fdcd027b98eb0b3dd11d063c63501d3c18448e93f5959f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/trigger.c | 5 ++++- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index b7675c721e..98f33922b5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Mark\san\sunreachable\sbranch\sas\sALWAYS(). -D 2021-01-31T16:45:10.780 +C Modify\sRETURNING\sso\sthat\sit\sdoes\snot\sreturn\schanges\simplemented\sby\ncascading\sforeign\skeys\sor\sby\striggers. +D 2021-02-01T01:57:55.870 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -607,7 +607,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda -F src/trigger.c b380259579a6d9dc3fa50d49b1b18ebfe42c10f12d3c5b3d0e2f7c3b35c45574 +F src/trigger.c 30cb8be5ef144f5c9036cf45faa007aeb8cfebe3bc766fc58072730416d6bc57 F src/update.c 0f5a61f0787199983530a33f6fffe4f52742f35fcdf6ccfad1078b1a8bc17723 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 @@ -1899,7 +1899,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 154fc2b15465c7c92a1af0a93851421aec42a81bab54840a9701f2c78068e14e -R cea5f0df7552de24bb2dee28a7a1e3f6 +P cb8b797a64f65fca01c5faaeb30cbe4a53b56b81e696d1b62a90362d7ef8f924 +R 199f69fc6dd65199d262c6cd91e2535c U drh -Z fb166b95a911fcb55830f05a31923ad0 +Z 013370d4bb9ad0b56cd61fbf8918d3d1 diff --git a/manifest.uuid b/manifest.uuid index 3f622440c0..d10e387699 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cb8b797a64f65fca01c5faaeb30cbe4a53b56b81e696d1b62a90362d7ef8f924 \ No newline at end of file +6e62470a737cbde7f3fdcd027b98eb0b3dd11d063c63501d3c18448e93f5959f \ No newline at end of file diff --git a/src/trigger.c b/src/trigger.c index de926f305d..ca9033b2d6 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -742,9 +742,11 @@ Trigger *sqlite3TriggersExist( }else if( p->op==TK_RETURNING ){ /* The first time a RETURNING trigger is seen, the "op" value tells ** us what time of trigger it should be. */ + assert( sqlite3IsToplevel(pParse) ); p->op = op; mask |= TRIGGER_AFTER; - }else if( p->bReturning && p->op==TK_INSERT && op==TK_UPDATE ){ + }else if( p->bReturning && p->op==TK_INSERT && op==TK_UPDATE + && sqlite3IsToplevel(pParse) ){ /* Also fire a RETURNING trigger for INSERT on the UPDATE of an UPSERT */ mask |= TRIGGER_AFTER; } @@ -1228,6 +1230,7 @@ void sqlite3CodeRowTrigger( if( (p->op==op || (p->bReturning && p->op==TK_INSERT && op==TK_UPDATE)) && p->tr_tm==tr_tm && checkColumnOverlap(p->pColumns, pChanges) + && (sqlite3IsToplevel(pParse) || !p->bReturning) ){ u8 origOp = p->op; p->op = op; From 9e673ace5bcbda881f153d2fe987f2414ac85f42 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 1 Feb 2021 12:39:50 +0000 Subject: [PATCH 159/257] Improved corrupt database detection in balance_nonroot(). FossilOrigin-Name: 5d54d9fd406381383afdf10612bfd590afc4142215d9bca09e227e3aa5baa102 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 3 +++ test/fuzzdata8.db | Bin 1619968 -> 1626112 bytes 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 95498bd054..7cded2c472 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\spossible\sdivision-by-zero\sin\sthe\snew\slog()\sSQL\sfunctions.\nProblemm\sdiscovered\sby\sOSSFuzz. -D 2021-01-29T16:20:16.527 +C Improved\scorrupt\sdatabase\sdetection\sin\sbalance_nonroot(). +D 2021-02-01T12:39:50.859 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -482,7 +482,7 @@ F src/auth.c 8d1df0e2ef8bafbedd4f1fe4baff03eb27507da4bf6e449df3613d383c4018b2 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 47d9fe97d5c0d74506154e3597f8a23b81a00080751dc4d11fec91ee22796f4c +F src/btree.c 4da25694985ac8f5f714bfa58a6cd453f9161d7da9394a95605aaa4db2752757 F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 F src/build.c d4c06261b0e532523ede58dc511381a7a9c155132e4b65a6bb2ff76fe657793a @@ -1046,7 +1046,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 7f6c5443d67ba040f760b4d28da54cc9f68174fa212ae34ccb86c645de761ec4 +F test/fuzzdata8.db 977cb95f4a5d828056dea804a6de416debe3fa0182c77f47fe19a0554aaf4db0 F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 @@ -1898,7 +1898,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 0defaf730bdc82212a5d3feeb2e16f16423b1691b0aaa7da1787eb82ea39ae9e -R 818a051c7c4bf2ae05824d55152903eb +P 1ffd321a33b778e87614a26a91a8407ec7b9dec4f0f847b16b1dac4f3b910604 +R b8a4f4fec4116f58162d1c62be0cf1fb U drh -Z b6b8cd840ef34d4d25e074519b6e4b42 +Z 4a762bd4c15e78835f4802843c46cdfa diff --git a/manifest.uuid b/manifest.uuid index dc726d75c2..11f8da895e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1ffd321a33b778e87614a26a91a8407ec7b9dec4f0f847b16b1dac4f3b910604 \ No newline at end of file +5d54d9fd406381383afdf10612bfd590afc4142215d9bca09e227e3aa5baa102 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index a3fbfef043..0f71b0479e 100644 --- a/src/btree.c +++ b/src/btree.c @@ -7975,6 +7975,9 @@ static int balance_nonroot( apOld[i] = 0; rc = sqlite3PagerWrite(pNew->pDbPage); nNew++; + if( sqlite3PagerPageRefcount(pNew->pDbPage)!=1+(i==(iParentIdx-nxDiv)) ){ + rc = SQLITE_CORRUPT_BKPT; + } if( rc ) goto balance_cleanup; }else{ assert( i>0 ); diff --git a/test/fuzzdata8.db b/test/fuzzdata8.db index 47d0d5a165f0d64501d44be2fe3902b232d67776..eb5b897ec024c77226996266cbe6719a1ef173e5 100644 GIT binary patch delta 24576 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 delta 23567 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 From d33d3a2ba729a11fd901ffda566fc22e87bcf5ad Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 1 Feb 2021 21:26:09 +0000 Subject: [PATCH 160/257] Add a few test cases for RETURNING together with UPDATE/DELETE LIMIT. FossilOrigin-Name: 7611c77d6baa84086ff18cbd045127fd682c6d5c434af5404e34fbe631fedfe1 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/wherelimit.test | 22 +++++++++++++++++----- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 98f33922b5..6d658d3ecb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Modify\sRETURNING\sso\sthat\sit\sdoes\snot\sreturn\schanges\simplemented\sby\ncascading\sforeign\skeys\sor\sby\striggers. -D 2021-02-01T01:57:55.870 +C Add\sa\sfew\stest\scases\sfor\sRETURNING\stogether\swith\sUPDATE/DELETE\sLIMIT. +D 2021-02-01T21:26:09.061 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1752,7 +1752,7 @@ F test/whereK.test f8e3cf26a8513ecc7f514f54df9f0572c046c42b F test/whereL.test 1afe47227f093dc0547236491fb37529b7be9724b8575925a321001b80e6a23a F test/wherefault.test 1374c3aa198388925246475f84ad4cd5f9528864 F test/wherelfault.test 9012e4ef5259058b771606616bd007af5d154e64cc25fa9fd4170f6411db44e3 -F test/wherelimit.test 592081800806d297dd7449b1030c863d2883d6d42901837ccd2e5a9bd962edb0 +F test/wherelimit.test daa0fd9122c5745cc459ec40b8d3c16ce13ce8382b5b847e7cfff4b871260cbf F test/wherelimit2.test 657a3f24aadee62d058c5091ea682dc4af4b95ffe32f137155be49799a58e721 F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2aeee74 F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972 @@ -1899,7 +1899,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 cb8b797a64f65fca01c5faaeb30cbe4a53b56b81e696d1b62a90362d7ef8f924 -R 199f69fc6dd65199d262c6cd91e2535c +P 6e62470a737cbde7f3fdcd027b98eb0b3dd11d063c63501d3c18448e93f5959f +R ebbe9120e496309466d7b572d1580227 U drh -Z 013370d4bb9ad0b56cd61fbf8918d3d1 +Z 59e7c95767d01f130d57c6f24563b271 diff --git a/manifest.uuid b/manifest.uuid index d10e387699..f40ec8c986 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6e62470a737cbde7f3fdcd027b98eb0b3dd11d063c63501d3c18448e93f5959f \ No newline at end of file +7611c77d6baa84086ff18cbd045127fd682c6d5c434af5404e34fbe631fedfe1 \ No newline at end of file diff --git a/test/wherelimit.test b/test/wherelimit.test index 8db7a0cc28..aeadc6f39b 100644 --- a/test/wherelimit.test +++ b/test/wherelimit.test @@ -94,21 +94,31 @@ ifcapable {update_delete_limit} { execsql {DELETE FROM t1 ORDER BY x LIMIT 5} execsql {SELECT count(*) FROM t1} } {15} + create_test_data 4 + do_test wherelimit-1.3b { + # limit 5 + execsql {DELETE FROM t1 RETURNING x, y, '|' ORDER BY x, y LIMIT 5} + } {1 1 | 1 2 | 1 3 | 1 4 | 2 1 |} + do_test wherelimit-1.3c { + execsql {SELECT count(*) FROM t1} + } {11} do_test wherelimit-1.4 { # limit 5, offset 2 - execsql {DELETE FROM t1 ORDER BY x LIMIT 5 OFFSET 2} + execsql {DELETE FROM t1 RETURNING x, y, '|' ORDER BY x LIMIT 5 OFFSET 2} + } {2 4 | 3 1 | 3 2 | 3 3 | 3 4 |} + do_test wherelimit-1.4cnt { execsql {SELECT count(*) FROM t1} - } {10} + } {6} do_test wherelimit-1.5 { # limit 5, offset -2 execsql {DELETE FROM t1 ORDER BY x LIMIT 5 OFFSET -2} execsql {SELECT count(*) FROM t1} - } {5} + } {1} do_test wherelimit-1.6 { # limit -5 (no limit), offset 2 execsql {DELETE FROM t1 ORDER BY x LIMIT 2, -5} execsql {SELECT count(*) FROM t1} - } {2} + } {1} do_test wherelimit-1.7 { # limit 5, offset -2 (no offset) execsql {DELETE FROM t1 ORDER BY x LIMIT -2, 5} @@ -227,7 +237,9 @@ ifcapable {update_delete_limit} { } {11} create_test_data 6 do_test wherelimit-3.2 { - execsql {UPDATE t1 SET y=1 WHERE x=1 LIMIT 5} + execsql {UPDATE t1 SET y=1 WHERE x=1 RETURNING x, old.y, '|' LIMIT 5} + } {1 1 | 1 2 | 1 3 | 1 4 | 1 5 |} + do_test wherelimit-3.2cnt { execsql {SELECT count(*) FROM t1 WHERE y=1} } {10} do_test wherelimit-3.3 { From c9be8630982cf8c797a0773da67958d9786bc2f3 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 2 Feb 2021 00:16:15 +0000 Subject: [PATCH 161/257] Allow the RETURNING trigger to exist for virtual tables. FossilOrigin-Name: 2f244ab4a2ba2bdb608cf44ef02e00738ad58c10a76d9e4222dc843a17103d92 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/trigger.c | 12 +++++++----- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 6d658d3ecb..65556f2f8c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\sfew\stest\scases\sfor\sRETURNING\stogether\swith\sUPDATE/DELETE\sLIMIT. -D 2021-02-01T21:26:09.061 +C Allow\sthe\sRETURNING\strigger\sto\sexist\sfor\svirtual\stables. +D 2021-02-02T00:16:15.269 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -607,7 +607,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda -F src/trigger.c 30cb8be5ef144f5c9036cf45faa007aeb8cfebe3bc766fc58072730416d6bc57 +F src/trigger.c 80c38e0d22bf062b2076a348885f40450dea5a0f5a4335916b71201653962e61 F src/update.c 0f5a61f0787199983530a33f6fffe4f52742f35fcdf6ccfad1078b1a8bc17723 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 @@ -1899,7 +1899,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 6e62470a737cbde7f3fdcd027b98eb0b3dd11d063c63501d3c18448e93f5959f -R ebbe9120e496309466d7b572d1580227 +P 7611c77d6baa84086ff18cbd045127fd682c6d5c434af5404e34fbe631fedfe1 +R 037a63c21faae44932a1c96611422080 U drh -Z 59e7c95767d01f130d57c6f24563b271 +Z 602a59ff4156534125d9199fea478bc0 diff --git a/manifest.uuid b/manifest.uuid index f40ec8c986..5ddb54f697 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7611c77d6baa84086ff18cbd045127fd682c6d5c434af5404e34fbe631fedfe1 \ No newline at end of file +2f244ab4a2ba2bdb608cf44ef02e00738ad58c10a76d9e4222dc843a17103d92 \ No newline at end of file diff --git a/src/trigger.c b/src/trigger.c index ca9033b2d6..efc10bb837 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -735,7 +735,8 @@ Trigger *sqlite3TriggersExist( if( (pParse->db->flags & SQLITE_EnableTrigger)!=0 ){ pList = sqlite3TriggerList(pParse, pTab); } - assert( pList==0 || IsVirtual(pTab)==0 ); + assert( pList==0 || IsVirtual(pTab)==0 + || (pList->bReturning && pList->pNext==0) ); for(p=pList; p; p=p->pNext){ if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){ mask |= p->tr_tm; @@ -810,13 +811,14 @@ static ExprList *sqlite3ExpandReturning( for(i=0; inExpr; i++){ Expr *pOldExpr = pList->a[i].pExpr; if( ALWAYS(pOldExpr!=0) && pOldExpr->op==TK_ASTERISK ){ - int j; - for(j=0; jnCol; j++){ - Expr *pNewExpr = sqlite3Expr(db, TK_ID, pTab->aCol[j].zName); + int jj; + for(jj=0; jjnCol; jj++){ + if( IsHiddenColumn(pTab->aCol+jj) ) continue; + Expr *pNewExpr = sqlite3Expr(db, TK_ID, pTab->aCol[jj].zName); pNew = sqlite3ExprListAppend(pParse, pNew, pNewExpr); if( !db->mallocFailed ){ struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1]; - pItem->zEName = sqlite3DbStrDup(db, pTab->aCol[j].zName); + pItem->zEName = sqlite3DbStrDup(db, pTab->aCol[jj].zName); pItem->eEName = ENAME_NAME; } } From 709dd13927c9ecc9f53aff461124d97e6b273f6a Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 2 Feb 2021 12:01:22 +0000 Subject: [PATCH 162/257] Report an error if RETURNING is used for DELETE or UPDATE of a virtual table. FossilOrigin-Name: bd5dee8425327fde0429043ce325b910f1b7951988d9a448a8eeeb713a46bc81 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/trigger.c | 5 +++++ 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 65556f2f8c..502b6f6d4c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sthe\sRETURNING\strigger\sto\sexist\sfor\svirtual\stables. -D 2021-02-02T00:16:15.269 +C Report\san\serror\sif\sRETURNING\sis\sused\sfor\sDELETE\sor\sUPDATE\sof\sa\svirtual\stable. +D 2021-02-02T12:01:22.075 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -607,7 +607,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda -F src/trigger.c 80c38e0d22bf062b2076a348885f40450dea5a0f5a4335916b71201653962e61 +F src/trigger.c 0e8d33e9ba2c9ce2a3ded92b6d81afd56bac39dc0faf18455b3b49f71a451195 F src/update.c 0f5a61f0787199983530a33f6fffe4f52742f35fcdf6ccfad1078b1a8bc17723 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 @@ -1899,7 +1899,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 7611c77d6baa84086ff18cbd045127fd682c6d5c434af5404e34fbe631fedfe1 -R 037a63c21faae44932a1c96611422080 +P 2f244ab4a2ba2bdb608cf44ef02e00738ad58c10a76d9e4222dc843a17103d92 +R a875c66b94135d7bf08c2474b75d1d9b U drh -Z 602a59ff4156534125d9199fea478bc0 +Z 7903baa82d2a34245eb14a08b0ad275c diff --git a/manifest.uuid b/manifest.uuid index 5ddb54f697..9fd2b15429 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2f244ab4a2ba2bdb608cf44ef02e00738ad58c10a76d9e4222dc843a17103d92 \ No newline at end of file +bd5dee8425327fde0429043ce325b910f1b7951988d9a448a8eeeb713a46bc81 \ No newline at end of file diff --git a/src/trigger.c b/src/trigger.c index efc10bb837..dd645324d3 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -746,6 +746,11 @@ Trigger *sqlite3TriggersExist( assert( sqlite3IsToplevel(pParse) ); p->op = op; mask |= TRIGGER_AFTER; + if( IsVirtual(pTab) && op!=TK_INSERT ){ + sqlite3ErrorMsg(pParse, + "%s RETURNING is not available on virtual tables", + op==TK_DELETE ? "DELETE" : "UPDATE"); + } }else if( p->bReturning && p->op==TK_INSERT && op==TK_UPDATE && sqlite3IsToplevel(pParse) ){ /* Also fire a RETURNING trigger for INSERT on the UPDATE of an UPSERT */ From e0d2096afa8af30299d9638e6760bbc58b6edca6 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 2 Feb 2021 20:41:13 +0000 Subject: [PATCH 163/257] Modify the sessions extension to use more efficient SQL when applying a changeset or patchset. FossilOrigin-Name: e4ccfac09b6fe8cc3aec29d10f4e4c83097964f29882343db52ed91f6f0dde1c --- ext/session/session2.test | 58 ++++++- ext/session/sqlite3session.c | 315 +++++++++++++++++++++-------------- manifest | 16 +- manifest.uuid | 2 +- 4 files changed, 249 insertions(+), 142 deletions(-) diff --git a/ext/session/session2.test b/ext/session/session2.test index cd8c2869e7..806687745e 100644 --- a/ext/session/session2.test +++ b/ext/session/session2.test @@ -35,7 +35,7 @@ proc test_reset {} { test_reset do_execsql_test 1.0 { - CREATE TABLE t1(a PRIMARY KEY, b); + CREATE TABLE t1(a INT PRIMARY KEY, b); INSERT INTO t1 VALUES('i', 'one'); } do_iterator_test 1.1 t1 { @@ -184,7 +184,7 @@ set set_of_tests { test_reset do_common_sql { - CREATE TABLE t1(a PRIMARY KEY, b); + CREATE TABLE t1(a int PRIMARY KEY, b); CREATE TABLE t2(a, b INTEGER PRIMARY KEY); CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b)); CREATE TABLE t4(a, b, PRIMARY KEY(b, a)); @@ -206,17 +206,17 @@ sqlite3 db3 test.db3 do_test 3.0 { execsql { ATTACH 'test.db3' AS 'aux'; - CREATE TABLE t1(a, b PRIMARY KEY); + CREATE TABLE t1(a int, b PRIMARY KEY); CREATE TABLE t2(x, y, z); CREATE TABLE t3(a); - CREATE TABLE aux.t1(a PRIMARY KEY, b); + CREATE TABLE aux.t1(a int PRIMARY KEY, b); CREATE TABLE aux.t2(a, b INTEGER PRIMARY KEY); CREATE TABLE aux.t3(a, b, c, PRIMARY KEY(a, b)); CREATE TABLE aux.t4(a, b, PRIMARY KEY(b, a)); } execsql { - CREATE TABLE t1(a PRIMARY KEY, b); + CREATE TABLE t1(a int PRIMARY KEY, b); CREATE TABLE t2(a, b INTEGER PRIMARY KEY); CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b)); CREATE TABLE t4(a, b, PRIMARY KEY(b, a)); @@ -588,4 +588,52 @@ do_execsql_test 10.2 { } {0 0 1 1} S delete +#------------------------------------------------------------------------- +test_reset +do_common_sql { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d, e, f); + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<32 + ) + INSERT INTO t1 SELECT NULL, 0, 0, 0, 0, 0 FROM s +} + +do_then_apply_sql { + UPDATE t1 SET f=f+1 WHERE a=1; + UPDATE t1 SET e=e+1 WHERE a=2; + UPDATE t1 SET e=e+1, f=f+1 WHERE a=3; + UPDATE t1 SET d=d+1 WHERE a=4; + UPDATE t1 SET d=d+1, f=f+1 WHERE a=5; + UPDATE t1 SET d=d+1, e=e+1 WHERE a=6; + UPDATE t1 SET d=d+1, e=e+1, f=f+1 WHERE a=7; + UPDATE t1 SET c=c+1 WHERE a=8; + UPDATE t1 SET c=c+1, f=f+1 WHERE a=9; + UPDATE t1 SET c=c+1, e=e+1 WHERE a=10; + UPDATE t1 SET c=c+1, e=e+1, f=f+1 WHERE a=11; + UPDATE t1 SET c=c+1, d=d+1 WHERE a=12; + UPDATE t1 SET c=c+1, d=d+1, f=f+1 WHERE a=13; + UPDATE t1 SET c=c+1, d=d+1, e=e+1 WHERE a=14; + UPDATE t1 SET c=c+1, d=d+1, e=e+1, f=f+1 WHERE a=15; + UPDATE t1 SET d=d+1 WHERE a=16; + UPDATE t1 SET d=d+1, f=f+1 WHERE a=17; + UPDATE t1 SET d=d+1, e=e+1 WHERE a=18; + UPDATE t1 SET d=d+1, e=e+1, f=f+1 WHERE a=19; + UPDATE t1 SET d=d+1, d=d+1 WHERE a=20; + UPDATE t1 SET d=d+1, d=d+1, f=f+1 WHERE a=21; + UPDATE t1 SET d=d+1, d=d+1, e=e+1 WHERE a=22; + UPDATE t1 SET d=d+1, d=d+1, e=e+1, f=f+1 WHERE a=23; + UPDATE t1 SET d=d+1, c=c+1 WHERE a=24; + UPDATE t1 SET d=d+1, c=c+1, f=f+1 WHERE a=25; + UPDATE t1 SET d=d+1, c=c+1, e=e+1 WHERE a=26; + UPDATE t1 SET d=d+1, c=c+1, e=e+1, f=f+1 WHERE a=27; + UPDATE t1 SET d=d+1, c=c+1, d=d+1 WHERE a=28; + UPDATE t1 SET d=d+1, c=c+1, d=d+1, f=f+1 WHERE a=29; + UPDATE t1 SET d=d+1, c=c+1, d=d+1, e=e+1 WHERE a=30; + UPDATE t1 SET d=d+1, c=c+1, d=d+1, e=e+1, f=f+1 WHERE a=31; +} + +do_test 11.0 { + compare_db db db2 +} {} + finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 2ee6b427e2..cafa5b29b7 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -3510,16 +3510,25 @@ int sqlite3changeset_invert_strm( return rc; } + +typedef struct SessionUpdate SessionUpdate; +struct SessionUpdate { + sqlite3_stmt *pStmt; + u32 *aMask; + SessionUpdate *pNext; +}; + typedef struct SessionApplyCtx SessionApplyCtx; struct SessionApplyCtx { sqlite3 *db; sqlite3_stmt *pDelete; /* DELETE statement */ - sqlite3_stmt *pUpdate; /* UPDATE statement */ sqlite3_stmt *pInsert; /* INSERT statement */ sqlite3_stmt *pSelect; /* SELECT statement */ int nCol; /* Size of azCol[] and abPK[] arrays */ const char **azCol; /* Array of column names */ u8 *abPK; /* Boolean array - true if column is in PK */ + u32 *aUpdateMask; /* Used by sessionUpdateFind */ + SessionUpdate *pUp; int bStat1; /* True if table is sqlite_stat1 */ int bDeferConstraints; /* True to defer constraints */ int bInvertConstraints; /* Invert when iterating constraints buffer */ @@ -3529,6 +3538,167 @@ struct SessionApplyCtx { u8 bRebase; /* True to collect rebase information */ }; +/* Number of prepared UPDATE statements to cache. */ +#define SESSION_UPDATE_CACHE_SZ 12 + +/* +** Find a prepared UPDATE statement suitable for the UPDATE step currently +** being visited by the iterator. The UPDATE is of the form: +** +** UPDATE tbl SET col = ?, col2 = ? WHERE pk1 IS ? AND pk2 IS ? +*/ +static int sessionUpdateFind( + sqlite3_changeset_iter *pIter, + SessionApplyCtx *p, + int bPatchset, + sqlite3_stmt **ppStmt +){ + int rc = SQLITE_OK; + SessionUpdate *pUp = 0; + int nCol = pIter->nCol; + int nU32 = (pIter->nCol+33)/32; + int ii; + + if( p->aUpdateMask==0 ){ + p->aUpdateMask = sqlite3_malloc(nU32*sizeof(u32)); + if( p->aUpdateMask==0 ){ + rc = SQLITE_NOMEM; + } + } + + if( rc==SQLITE_OK ){ + memset(p->aUpdateMask, 0, nU32*sizeof(u32)); + rc = SQLITE_CORRUPT; + for(ii=0; iinCol; ii++){ + if( sessionChangesetNew(pIter, ii) ){ + p->aUpdateMask[ii/32] |= (1<<(ii%32)); + rc = SQLITE_OK; + } + } + } + + if( rc==SQLITE_OK ){ + if( bPatchset ) p->aUpdateMask[nCol/32] |= (1<<(nCol%32)); + + if( p->pUp ){ + int nUp = 0; + SessionUpdate **pp = &p->pUp; + while( 1 ){ + nUp++; + if( 0==memcmp(p->aUpdateMask, (*pp)->aMask, nU32*sizeof(u32)) ){ + pUp = *pp; + *pp = pUp->pNext; + pUp->pNext = p->pUp; + p->pUp = pUp; + break; + } + + if( (*pp)->pNext ){ + pp = &(*pp)->pNext; + }else{ + if( nUp>=SESSION_UPDATE_CACHE_SZ ){ + sqlite3_finalize((*pp)->pStmt); + sqlite3_free(*pp); + *pp = 0; + } + break; + } + } + } + + if( pUp==0 ){ + int nByte = sizeof(SessionUpdate) * nU32*sizeof(u32); + int bStat1 = (sqlite3_stricmp(pIter->zTab, "sqlite_stat1")==0); + pUp = (SessionUpdate*)sqlite3_malloc(nByte); + if( pUp==0 ){ + rc = SQLITE_NOMEM; + }else{ + const char *zSep = ""; + SessionBuffer buf; + + memset(&buf, 0, sizeof(buf)); + pUp->aMask = (u32*)&pUp[1]; + memcpy(pUp->aMask, p->aUpdateMask, nU32*sizeof(u32)); + + sessionAppendStr(&buf, "UPDATE main.", &rc); + sessionAppendIdent(&buf, pIter->zTab, &rc); + sessionAppendStr(&buf, " SET ", &rc); + + /* Create the assignments part of the UPDATE */ + for(ii=0; iinCol; ii++){ + if( p->abPK[ii]==0 && sessionChangesetNew(pIter, ii) ){ + sessionAppendStr(&buf, zSep, &rc); + sessionAppendIdent(&buf, p->azCol[ii], &rc); + sessionAppendStr(&buf, " = ?", &rc); + sessionAppendInteger(&buf, ii*2+1, &rc); + zSep = ", "; + } + } + + /* Create the WHERE clause part of the UPDATE */ + zSep = ""; + sessionAppendStr(&buf, " WHERE ", &rc); + for(ii=0; iinCol; ii++){ + if( p->abPK[ii] || (bPatchset==0 && sessionChangesetOld(pIter, ii)) ){ + sessionAppendStr(&buf, zSep, &rc); + if( bStat1 && ii==1 ){ + assert( sqlite3_stricmp(p->azCol[ii], "idx")==0 ); + sessionAppendStr(&buf, + "idx IS CASE " + "WHEN length(?4)=0 AND typeof(?4)='blob' THEN NULL " + "ELSE ?4 END ", &rc + ); + }else{ + sessionAppendIdent(&buf, p->azCol[ii], &rc); + sessionAppendStr(&buf, " IS ?", &rc); + sessionAppendInteger(&buf, ii*2+2, &rc); + } + zSep = " AND "; + } + } + + if( rc==SQLITE_OK ){ + char *zSql = (char*)buf.aBuf; + rc = sqlite3_prepare_v2(p->db, zSql, buf.nBuf, &pUp->pStmt, 0); + } + + if( rc!=SQLITE_OK ){ + sqlite3_free(pUp); + pUp = 0; + }else{ + pUp->pNext = p->pUp; + p->pUp = pUp; + } + sqlite3_free(buf.aBuf); + } + } + } + + assert( (rc==SQLITE_OK)==(pUp!=0) ); + if( pUp ){ + *ppStmt = pUp->pStmt; + }else{ + *ppStmt = 0; + } + return rc; +} + +/* +** Free all cached UPDATE statements. +*/ +static void sessionUpdateFree(SessionApplyCtx *p){ + SessionUpdate *pUp; + SessionUpdate *pNext; + for(pUp=p->pUp; pUp; pUp=pNext){ + pNext = pUp->pNext; + sqlite3_finalize(pUp->pStmt); + sqlite3_free(pUp); + } + p->pUp = 0; + sqlite3_free(p->aUpdateMask); + p->aUpdateMask = 0; +} + /* ** Formulate a statement to DELETE a row from database db. Assuming a table ** structure like this: @@ -3598,103 +3768,6 @@ static int sessionDeleteRow( return rc; } -/* -** Formulate and prepare a statement to UPDATE a row from database db. -** Assuming a table structure like this: -** -** CREATE TABLE x(a, b, c, d, PRIMARY KEY(a, c)); -** -** The UPDATE statement looks like this: -** -** UPDATE x SET -** a = CASE WHEN ?2 THEN ?3 ELSE a END, -** b = CASE WHEN ?5 THEN ?6 ELSE b END, -** c = CASE WHEN ?8 THEN ?9 ELSE c END, -** d = CASE WHEN ?11 THEN ?12 ELSE d END -** WHERE a = ?1 AND c = ?7 AND (?13 OR -** (?5==0 OR b IS ?4) AND (?11==0 OR d IS ?10) AND -** ) -** -** For each column in the table, there are three variables to bind: -** -** ?(i*3+1) The old.* value of the column, if any. -** ?(i*3+2) A boolean flag indicating that the value is being modified. -** ?(i*3+3) The new.* value of the column, if any. -** -** Also, a boolean flag that, if set to true, causes the statement to update -** a row even if the non-PK values do not match. This is required if the -** conflict-handler is invoked with CHANGESET_DATA and returns -** CHANGESET_REPLACE. This is variable "?(nCol*3+1)". -** -** If successful, SQLITE_OK is returned and SessionApplyCtx.pUpdate is left -** pointing to the prepared version of the SQL statement. -*/ -static int sessionUpdateRow( - sqlite3 *db, /* Database handle */ - const char *zTab, /* Table name */ - SessionApplyCtx *p /* Session changeset-apply context */ -){ - int rc = SQLITE_OK; - int i; - const char *zSep = ""; - SessionBuffer buf = {0, 0, 0}; - - /* Append "UPDATE tbl SET " */ - sessionAppendStr(&buf, "UPDATE main.", &rc); - sessionAppendIdent(&buf, zTab, &rc); - sessionAppendStr(&buf, " SET ", &rc); - - /* Append the assignments */ - for(i=0; inCol; i++){ - sessionAppendStr(&buf, zSep, &rc); - sessionAppendIdent(&buf, p->azCol[i], &rc); - sessionAppendStr(&buf, " = CASE WHEN ?", &rc); - sessionAppendInteger(&buf, i*3+2, &rc); - sessionAppendStr(&buf, " THEN ?", &rc); - sessionAppendInteger(&buf, i*3+3, &rc); - sessionAppendStr(&buf, " ELSE ", &rc); - sessionAppendIdent(&buf, p->azCol[i], &rc); - sessionAppendStr(&buf, " END", &rc); - zSep = ", "; - } - - /* Append the PK part of the WHERE clause */ - sessionAppendStr(&buf, " WHERE ", &rc); - for(i=0; inCol; i++){ - if( p->abPK[i] ){ - sessionAppendIdent(&buf, p->azCol[i], &rc); - sessionAppendStr(&buf, " = ?", &rc); - sessionAppendInteger(&buf, i*3+1, &rc); - sessionAppendStr(&buf, " AND ", &rc); - } - } - - /* Append the non-PK part of the WHERE clause */ - sessionAppendStr(&buf, " (?", &rc); - sessionAppendInteger(&buf, p->nCol*3+1, &rc); - sessionAppendStr(&buf, " OR 1", &rc); - for(i=0; inCol; i++){ - if( !p->abPK[i] ){ - sessionAppendStr(&buf, " AND (?", &rc); - sessionAppendInteger(&buf, i*3+2, &rc); - sessionAppendStr(&buf, "=0 OR ", &rc); - sessionAppendIdent(&buf, p->azCol[i], &rc); - sessionAppendStr(&buf, " IS ?", &rc); - sessionAppendInteger(&buf, i*3+1, &rc); - sessionAppendStr(&buf, ")", &rc); - } - } - sessionAppendStr(&buf, ")", &rc); - - if( rc==SQLITE_OK ){ - rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pUpdate, 0); - } - sqlite3_free(buf.aBuf); - - return rc; -} - - /* ** Formulate and prepare an SQL statement to query table zTab by primary ** key. Assuming the following table structure: @@ -3775,17 +3848,6 @@ static int sessionStat1Sql(sqlite3 *db, SessionApplyCtx *p){ "?3)" ); } - if( rc==SQLITE_OK ){ - rc = sessionPrepare(db, &p->pUpdate, - "UPDATE main.sqlite_stat1 SET " - "tbl = CASE WHEN ?2 THEN ?3 ELSE tbl END, " - "idx = CASE WHEN ?5 THEN ?6 ELSE idx END, " - "stat = CASE WHEN ?8 THEN ?9 ELSE stat END " - "WHERE tbl=?1 AND idx IS " - "CASE WHEN length(?4)=0 AND typeof(?4)='blob' THEN NULL ELSE ?4 END " - "AND (?10 OR ?8=0 OR stat IS ?7)" - ); - } if( rc==SQLITE_OK ){ rc = sessionPrepare(db, &p->pDelete, "DELETE FROM main.sqlite_stat1 WHERE tbl=?1 AND idx IS " @@ -4102,7 +4164,7 @@ static int sessionApplyOneOp( int nCol; int rc = SQLITE_OK; - assert( p->pDelete && p->pUpdate && p->pInsert && p->pSelect ); + assert( p->pDelete && p->pInsert && p->pSelect ); assert( p->azCol && p->abPK ); assert( !pbReplace || *pbReplace==0 ); @@ -4142,29 +4204,28 @@ static int sessionApplyOneOp( }else if( op==SQLITE_UPDATE ){ int i; + sqlite3_stmt *pUp = 0; + int bPatchset = (pbRetry==0 || pIter->bPatchset); + + rc = sessionUpdateFind(pIter, p, bPatchset, &pUp); /* Bind values to the UPDATE statement. */ for(i=0; rc==SQLITE_OK && ipUpdate, i*3+2, !!pNew); - if( pOld ){ - rc = sessionBindValue(p->pUpdate, i*3+1, pOld); + if( p->abPK[i] || (bPatchset==0 && pOld) ){ + rc = sessionBindValue(pUp, i*2+2, pOld); } if( rc==SQLITE_OK && pNew ){ - rc = sessionBindValue(p->pUpdate, i*3+3, pNew); + rc = sessionBindValue(pUp, i*2+1, pNew); } } - if( rc==SQLITE_OK ){ - sqlite3_bind_int(p->pUpdate, nCol*3+1, pbRetry==0 || pIter->bPatchset); - } if( rc!=SQLITE_OK ) return rc; /* Attempt the UPDATE. In the case of a NOTFOUND or DATA conflict, ** the result will be SQLITE_OK with 0 rows modified. */ - sqlite3_step(p->pUpdate); - rc = sqlite3_reset(p->pUpdate); + sqlite3_step(pUp); + rc = sqlite3_reset(pUp); if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 ){ /* A NOTFOUND or DATA error. Search the table to see if it contains @@ -4387,14 +4448,13 @@ static int sessionChangesetApply( ); if( rc!=SQLITE_OK ) break; + sessionUpdateFree(&sApply); sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */ sqlite3_finalize(sApply.pDelete); - sqlite3_finalize(sApply.pUpdate); sqlite3_finalize(sApply.pInsert); sqlite3_finalize(sApply.pSelect); sApply.db = db; sApply.pDelete = 0; - sApply.pUpdate = 0; sApply.pInsert = 0; sApply.pSelect = 0; sApply.nCol = 0; @@ -4458,11 +4518,10 @@ static int sessionChangesetApply( } sApply.bStat1 = 1; }else{ - if((rc = sessionSelectRow(db, zTab, &sApply)) - || (rc = sessionUpdateRow(db, zTab, &sApply)) - || (rc = sessionDeleteRow(db, zTab, &sApply)) - || (rc = sessionInsertRow(db, zTab, &sApply)) - ){ + if( (rc = sessionSelectRow(db, zTab, &sApply)) + || (rc = sessionDeleteRow(db, zTab, &sApply)) + || (rc = sessionInsertRow(db, zTab, &sApply)) + ){ break; } sApply.bStat1 = 0; @@ -4521,9 +4580,9 @@ static int sessionChangesetApply( *pnRebase = sApply.rebase.nBuf; sApply.rebase.aBuf = 0; } + sessionUpdateFree(&sApply); sqlite3_finalize(sApply.pInsert); sqlite3_finalize(sApply.pDelete); - sqlite3_finalize(sApply.pUpdate); sqlite3_finalize(sApply.pSelect); sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */ sqlite3_free((char*)sApply.constraints.aBuf); diff --git a/manifest b/manifest index 7cded2c472..5463576ba6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\scorrupt\sdatabase\sdetection\sin\sbalance_nonroot(). -D 2021-02-01T12:39:50.859 +C Modify\sthe\ssessions\sextension\sto\suse\smore\sefficient\sSQL\swhen\sapplying\sa\schangeset\sor\spatchset. +D 2021-02-02T20:41:13.378 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -428,7 +428,7 @@ F ext/session/changeset.c 7a1e6a14c7e92d36ca177e92e88b5281acd709f3b726298dc34ec0 F ext/session/changesetfuzz.c 227076ab0ae4447d742c01ee88a564da6478bbf26b65108bf8fac9cd8b0b24aa F ext/session/changesetfuzz1.test 2e1b90d888fbf0eea5e1bd2f1e527a48cc85f8e0ff75df1ec4e320b21f580b3a F ext/session/session1.test 0b2f88995832ea040ae8e83a1ad4afa99c00b85c779d213da73a95ea4113233e -F ext/session/session2.test 284de45abae4cc1082bc52012ee81521d5ac58e0 +F ext/session/session2.test 7f53d755d921e0baf815c4258348e0ed460dfd8a772351bca5ad3ccbb1dc786e F ext/session/session3.test ce9ce3dfa489473987f899e9f6a0f2db9bde3479 F ext/session/session4.test 6778997065b44d99c51ff9cece047ff9244a32856b328735ae27ddef68979c40 F ext/session/session5.test 716bc6fafd625ce60dfa62ae128971628c1a1169 @@ -454,7 +454,7 @@ F ext/session/sessionmem.test f2a735db84a3e9e19f571033b725b0b2daf847f3f28b1da55a F ext/session/sessionrebase.test ccfa716b23bd1d3b03217ee58cfd90c78d4b99f53e6a9a2f05e82363b9142810 F ext/session/sessionstat1.test 218d351cf9fcd6648f125a26b607b140310160184723c2666091b54450a68fb5 F ext/session/sessionwor.test 67b5ab91d4f93ce65ff1f58240ac5ddf73f8670facc1ffa49cef56293d52818d -F ext/session/sqlite3session.c d2aaaf05241ac7d23a1b1eaa8b1f165c90f7ff0fe57ff1932a87c6b89b886117 +F ext/session/sqlite3session.c 1d0553077b55ffcfa69963c354e9bad3bace6ce79bbe7368e650c6ae1e106314 F ext/session/sqlite3session.h f53c99731882bf59c7362855cdeba176ce1fe8eeba089e38a8cce0172f8473aa F ext/session/test_session.c 93ca965112d2b4d9d669c9c0be6b1e52942a268796050a145612df1eee175ce0 F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3 @@ -1898,7 +1898,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 1ffd321a33b778e87614a26a91a8407ec7b9dec4f0f847b16b1dac4f3b910604 -R b8a4f4fec4116f58162d1c62be0cf1fb -U drh -Z 4a762bd4c15e78835f4802843c46cdfa +P 5d54d9fd406381383afdf10612bfd590afc4142215d9bca09e227e3aa5baa102 +R d44cc6b5db574b719ae909c431a63549 +U dan +Z 32b2c74d653dfa71fce784320ccf15ed diff --git a/manifest.uuid b/manifest.uuid index 11f8da895e..2cd9cb7572 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5d54d9fd406381383afdf10612bfd590afc4142215d9bca09e227e3aa5baa102 \ No newline at end of file +e4ccfac09b6fe8cc3aec29d10f4e4c83097964f29882343db52ed91f6f0dde1c \ No newline at end of file From cb83dc9e957fe5e21d8ee560e1e25838fdc1c342 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 2 Feb 2021 20:46:11 +0000 Subject: [PATCH 164/257] Do not allow aggregates in a RETURNING clause. Fix a memory leak that occurs when window functions are used in a RETURNING clause. FossilOrigin-Name: 2e9bd94b9ad37c7e4123b7324f2fe42d3609a65af449eb8a0064057647709a73 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/trigger.c | 13 ++++++++++--- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 502b6f6d4c..81bc47332a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Report\san\serror\sif\sRETURNING\sis\sused\sfor\sDELETE\sor\sUPDATE\sof\sa\svirtual\stable. -D 2021-02-02T12:01:22.075 +C Do\snot\sallow\saggregates\sin\sa\sRETURNING\sclause.\s\sFix\sa\smemory\sleak\sthat\noccurs\swhen\swindow\sfunctions\sare\sused\sin\sa\sRETURNING\sclause. +D 2021-02-02T20:46:11.972 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -607,7 +607,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda -F src/trigger.c 0e8d33e9ba2c9ce2a3ded92b6d81afd56bac39dc0faf18455b3b49f71a451195 +F src/trigger.c a9357898b5965f579c6384b6538aa7297e3d38a132e87e1fc0e1e5b276a4cf21 F src/update.c 0f5a61f0787199983530a33f6fffe4f52742f35fcdf6ccfad1078b1a8bc17723 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 @@ -1899,7 +1899,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 2f244ab4a2ba2bdb608cf44ef02e00738ad58c10a76d9e4222dc843a17103d92 -R a875c66b94135d7bf08c2474b75d1d9b +P bd5dee8425327fde0429043ce325b910f1b7951988d9a448a8eeeb713a46bc81 +R cd87aa40fae996ae8358e0b84594bda6 U drh -Z 7903baa82d2a34245eb14a08b0ad275c +Z 25e8d0af3fd413c8e6c9d01783338232 diff --git a/manifest.uuid b/manifest.uuid index 9fd2b15429..fec5166aaa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bd5dee8425327fde0429043ce325b910f1b7951988d9a448a8eeeb713a46bc81 \ No newline at end of file +2e9bd94b9ad37c7e4123b7324f2fe42d3609a65af449eb8a0064057647709a73 \ No newline at end of file diff --git a/src/trigger.c b/src/trigger.c index dd645324d3..52811617ee 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -923,13 +923,20 @@ static int codeTriggerProgram( Select *pSelect = pStep->pSelect; ExprList *pList = pSelect->pEList; SelectDest sDest; + Select *pNew; pSelect->pEList = sqlite3ExpandReturning(pParse, pList, pParse->pTriggerTab); sqlite3SelectDestInit(&sDest, SRT_Output, 0); - pSelect->selFlags = 0; - sqlite3Select(pParse, pSelect, &sDest); + pNew = sqlite3SelectDup(db, pSelect, 0); + if( pNew ){ + sqlite3Select(pParse, pNew, &sDest); + if( pNew->selFlags & (SF_Aggregate|SF_HasAgg|SF_WinRewrite) ){ + sqlite3ErrorMsg(pParse, "aggregates not allowed in RETURNING"); + } + sqlite3SelectDelete(db, pNew); + } sqlite3ExprListDelete(db, pSelect->pEList); - pSelect->pEList = pList; + pStep->pSelect->pEList = pList; break; } } From 2aa41c82dab03eedefe393ee87a0b179285bf447 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 3 Feb 2021 00:55:34 +0000 Subject: [PATCH 165/257] Modify the SQLITE_DBCONFIG_ENABLE_TRIGGER setting so that it only disables main-schema triggers and allows TEMP trigger to continue operating. This is safe, since only the application (not an attacker) can add TEMP triggers. It will also all us to disengage SQLITE_DBCONFIG_ENABLE_TRIGGER on Fossil databases since Fossil has no main-schema triggers but does use TEMP triggers. FossilOrigin-Name: a10c5a2503ff2998f6ee40f721aab8c9579052e535dc141bd57d10551eaea387 --- manifest | 14 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 8 ++++++- src/trigger.c | 57 ++++++++++++++++++++++++++++++++----------------- 4 files changed, 52 insertions(+), 29 deletions(-) diff --git a/manifest b/manifest index 8baca9a552..8950ada11e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Load\senhancements\sfrom\strunk\sinto\sthe\sreturning\sbranch. -D 2021-02-03T00:05:57.450 +C Modify\sthe\sSQLITE_DBCONFIG_ENABLE_TRIGGER\ssetting\sso\sthat\sit\sonly\sdisables\nmain-schema\striggers\sand\sallows\sTEMP\strigger\sto\scontinue\soperating.\s\sThis\sis\nsafe,\ssince\sonly\sthe\sapplication\s(not\san\sattacker)\scan\sadd\sTEMP\striggers.\nIt\swill\salso\sall\sus\sto\sdisengage\sSQLITE_DBCONFIG_ENABLE_TRIGGER\son\sFossil\ndatabases\ssince\sFossil\shas\sno\smain-schema\striggers\sbut\sdoes\suse\sTEMP\striggers. +D 2021-02-03T00:55:34.680 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -543,7 +543,7 @@ F src/resolve.c f6761473ea4b51190fc52f8f2121498b78717266e106e7bff12849ea2d52165f F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 738cb746189f721f59972993c13085fa2975c4cbfd04ba26445f3b42c81237dc F src/shell.c.in 9ebc74e4f05cfbd0f4a36060fdaeff1da4e9af4458358722bc08c5a1ab9a0879 -F src/sqlite.h.in 0af968a1fa3c717261e1df0ed105fa7bddb4d82de7e0adb3eab49e6aa81b4de7 +F src/sqlite.h.in 8855a19f37ade8dad189a9e48233a2ebe1b46faf469c7eb0906a654e252dcc57 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e F src/sqliteInt.h 0fda3b2c05b1559135aa2c4ecb8e75bd2085ba4433310bbb5427d97c2d81315d @@ -607,7 +607,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda -F src/trigger.c a9357898b5965f579c6384b6538aa7297e3d38a132e87e1fc0e1e5b276a4cf21 +F src/trigger.c 0a242d65dd9b9822d4e990653eb4ece3557dcda01374934aa3cc1f9718d8dee3 F src/update.c 0f5a61f0787199983530a33f6fffe4f52742f35fcdf6ccfad1078b1a8bc17723 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 @@ -1899,7 +1899,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 2e9bd94b9ad37c7e4123b7324f2fe42d3609a65af449eb8a0064057647709a73 e4ccfac09b6fe8cc3aec29d10f4e4c83097964f29882343db52ed91f6f0dde1c -R 189e18b39cf3d0cb3ef657405a5431b5 +P b84c7f60c2e1e7debf9f50622087f87d60c6870061d61e14e59cc1ba0775ee92 +R 02daf4bf169cb22bac4b88e2c2565d05 U drh -Z 8f661fe5807957ca703992c48d933956 +Z cfd272038413f78f81e2c24e00e99d6f diff --git a/manifest.uuid b/manifest.uuid index 53886e64e3..e1651727c4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b84c7f60c2e1e7debf9f50622087f87d60c6870061d61e14e59cc1ba0775ee92 \ No newline at end of file +a10c5a2503ff2998f6ee40f721aab8c9579052e535dc141bd57d10551eaea387 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index c17d012002..8a9470f01b 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2115,7 +2115,13 @@ struct sqlite3_mem_methods { ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether triggers are disabled or enabled ** following this call. The second parameter may be a NULL pointer, in -** which case the trigger setting is not reported back. +** which case the trigger setting is not reported back. +** +**

Originally this option disabled all triggers. ^(However, since +** SQLite version 3.35.0, TEMP triggers are still allowed even if +** this option is off. So, in other words, this option now only disables +** triggers in the main database schema or in the schemas of ATTACH-ed +** databases.)^ ** ** [[SQLITE_DBCONFIG_ENABLE_VIEW]] **

SQLITE_DBCONFIG_ENABLE_VIEW
diff --git a/src/trigger.c b/src/trigger.c index 52811617ee..ef0a90b24f 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -732,31 +732,48 @@ Trigger *sqlite3TriggersExist( Trigger *pList = 0; Trigger *p; - if( (pParse->db->flags & SQLITE_EnableTrigger)!=0 ){ - pList = sqlite3TriggerList(pParse, pTab); - } + pList = sqlite3TriggerList(pParse, pTab); assert( pList==0 || IsVirtual(pTab)==0 || (pList->bReturning && pList->pNext==0) ); - for(p=pList; p; p=p->pNext){ - if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){ - mask |= p->tr_tm; - }else if( p->op==TK_RETURNING ){ - /* The first time a RETURNING trigger is seen, the "op" value tells - ** us what time of trigger it should be. */ - assert( sqlite3IsToplevel(pParse) ); - p->op = op; - mask |= TRIGGER_AFTER; - if( IsVirtual(pTab) && op!=TK_INSERT ){ - sqlite3ErrorMsg(pParse, - "%s RETURNING is not available on virtual tables", - op==TK_DELETE ? "DELETE" : "UPDATE"); + if( pList!=0 ){ + p = pList; + if( (pParse->db->flags & SQLITE_EnableTrigger)==0 + && pTab->pTrigger!=0 + ){ + /* The SQLITE_DBCONFIG_ENABLE_TRIGGER setting is off. That means that + ** only TEMP triggers are allowed. Truncate the pList so that it + ** includes only TEMP triggers */ + if( pList==pTab->pTrigger ){ + pList = 0; + goto exit_triggers_exist; } - }else if( p->bReturning && p->op==TK_INSERT && op==TK_UPDATE - && sqlite3IsToplevel(pParse) ){ - /* Also fire a RETURNING trigger for INSERT on the UPDATE of an UPSERT */ - mask |= TRIGGER_AFTER; + while( ALWAYS(p->pNext) && p->pNext!=pTab->pTrigger ) p = p->pNext; + p->pNext = 0; + p = pList; } + do{ + if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){ + mask |= p->tr_tm; + }else if( p->op==TK_RETURNING ){ + /* The first time a RETURNING trigger is seen, the "op" value tells + ** us what time of trigger it should be. */ + assert( sqlite3IsToplevel(pParse) ); + p->op = op; + mask |= TRIGGER_AFTER; + if( IsVirtual(pTab) && op!=TK_INSERT ){ + sqlite3ErrorMsg(pParse, + "%s RETURNING is not available on virtual tables", + op==TK_DELETE ? "DELETE" : "UPDATE"); + } + }else if( p->bReturning && p->op==TK_INSERT && op==TK_UPDATE + && sqlite3IsToplevel(pParse) ){ + /* Also fire a RETURNING trigger for an UPSERT */ + mask |= TRIGGER_AFTER; + } + p = p->pNext; + }while( p ); } +exit_triggers_exist: if( pMask ){ *pMask = mask; } From 78197e0f8b748f35ba579163df2ba5548d90ed2a Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 3 Feb 2021 12:35:51 +0000 Subject: [PATCH 166/257] Fix an assert() that might be off-by-one in the case of a prior errors in the parse. FossilOrigin-Name: 06b15b17be38c804dd2641d8616a2a7bd396d2eb9901a0fbf94edd8bd508cf9c --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/where.c | 2 +- test/rowvalue.test | 13 +++++++++++++ 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 5463576ba6..397bdd9678 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Modify\sthe\ssessions\sextension\sto\suse\smore\sefficient\sSQL\swhen\sapplying\sa\schangeset\sor\spatchset. -D 2021-02-02T20:41:13.378 +C Fix\san\sassert()\sthat\smight\sbe\soff-by-one\sin\sthe\scase\sof\sa\sprior\nerrors\sin\sthe\sparse. +D 2021-02-03T12:35:51.366 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -628,7 +628,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 69e770e96fd56cc21608992bf2c6f1f3dc5cf2572d0495c6a643b06c3a679f14 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c d9c4e454ebb9499e908aa62d55b8994c375cf5355ac78f60d45af17f7890701c -F src/where.c 0e6abb22a2323fec80b450825593c26a2ad8f4815d1ee3af9969d8f6144bf681 +F src/where.c 6efc4a10bfe0ec908c4f3c9112afb7675c952204b4b0b255672f488860141fec F src/whereInt.h ae03b5e3a4cca9bd9cb1b7d3c63faf8f1f177200fc8cecc87d3d0cab6ca338e6 F src/wherecode.c 43a63441f8662ddf86b15975683a502ec33f08167e9636f4d19e38e265e95fd9 F src/whereexpr.c a182038cf7d10aa9a95a96b8563a34f34990323cf307dee6559e995961966d43 @@ -1293,7 +1293,7 @@ F test/round1.test 768018b04522ca420b1aba8a24bd76091d269f3bce3902af3ec6ebcee41ab F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test bfbd7b97d9267660be3c8f28507c4ed7f205196b8877c0db42df347c2e8845e3 -F test/rowvalue.test 8964f95b253d3b5cc8dc1cfd0cdb7529bce3ecc6b6259e23c5f829f80f4d51cd +F test/rowvalue.test b5436c767394a3f8fa5e7e474b2114ba430fdab34a5c8573c1b6256756534565 F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b F test/rowvalue3.test 3068f508753af69884b12125995f023da0dbb256 F test/rowvalue4.test 02e35f7762371c2f57ebd856aa056eac56cb27ef7715a0bb31eac1895a745356 @@ -1898,7 +1898,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 5d54d9fd406381383afdf10612bfd590afc4142215d9bca09e227e3aa5baa102 -R d44cc6b5db574b719ae909c431a63549 -U dan -Z 32b2c74d653dfa71fce784320ccf15ed +P e4ccfac09b6fe8cc3aec29d10f4e4c83097964f29882343db52ed91f6f0dde1c +R 30096bbeccf9e03a69ea838444df44cb +U drh +Z 17a66c8e0166569653feae3b32e8dbae diff --git a/manifest.uuid b/manifest.uuid index 2cd9cb7572..7cec0847e3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e4ccfac09b6fe8cc3aec29d10f4e4c83097964f29882343db52ed91f6f0dde1c \ No newline at end of file +06b15b17be38c804dd2641d8616a2a7bd396d2eb9901a0fbf94edd8bd508cf9c \ No newline at end of file diff --git a/src/where.c b/src/where.c index 8128c2ed0b..971c223730 100644 --- a/src/where.c +++ b/src/where.c @@ -5565,7 +5565,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ #endif pOp = sqlite3VdbeGetOp(v, k); pLastOp = pOp + (last - k); - assert( pOpnErr>0 && pOp==pLastOp) ); do{ if( pOp->p1!=pLevel->iTabCur ){ /* no-op */ diff --git a/test/rowvalue.test b/test/rowvalue.test index e3b66a1096..91a59e71c3 100644 --- a/test/rowvalue.test +++ b/test/rowvalue.test @@ -644,4 +644,17 @@ do_catchsql_test 27.10 { INSERT INTO t0(c0) VALUES(0) ON CONFLICT(c0) DO UPDATE SET c0 = 3; } {1 {ON CONFLICT clause does not match any PRIMARY KEY or UNIQUE constraint}} +# 2021-02-03 +# https://bugs.chromium.org/p/chromium/issues/detail?id=1173511 +# Faulty assert() statement. +# +reset_db +do_catchsql_test 28.10 { + CREATE TABLE t0(c0 PRIMARY KEY, c1); + CREATE TRIGGER trigger0 BEFORE DELETE ON t0 BEGIN + SELECT (SELECT c0,c1 FROM t0) FROM t0; + END ; + DELETE FROM t0; +} {1 {sub-select returns 2 columns - expected 1}} + finish_test From c5eb176a09ef6dc7d8d19a4d85c0bc7dcb856848 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 3 Feb 2021 13:20:12 +0000 Subject: [PATCH 167/257] Fix a harmless compiler warning. FossilOrigin-Name: 1eb69c64ed4a11601698000573c507684bc4b0366336ba0748ebd661644d0902 --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/attach.c | 1 - 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index b8b3e0e883..22730f26d0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssupport\sfor\sthe\sRETURNING\sclause\sfollowing\sPostgreSQL\ssyntax. -D 2021-02-03T13:08:09.152 +C Fix\sa\sharmless\scompiler\swarning. +D 2021-02-03T13:20:12.253 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -477,7 +477,7 @@ F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 36cae0d6e3e91a1996e1a472f8c7242c31a4e38ba4295e3056da198c04fd2a87 F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c -F src/attach.c 87102aba5ddac8ef3a8a033ab657e4cae9cc8e846efe93b14029cfffaaf8831e +F src/attach.c e80162a47411f296bea550ed8fafd730481f4aa71e89ece23ba9c957eed15d4a F src/auth.c 8d1df0e2ef8bafbedd4f1fe4baff03eb27507da4bf6e449df3613d383c4018b2 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 @@ -1899,8 +1899,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 06b15b17be38c804dd2641d8616a2a7bd396d2eb9901a0fbf94edd8bd508cf9c a10c5a2503ff2998f6ee40f721aab8c9579052e535dc141bd57d10551eaea387 -R 10c9b96c07db17433ca188cab65447b4 -T +closed a10c5a2503ff2998f6ee40f721aab8c9579052e535dc141bd57d10551eaea387 +P 416c898bfb8ff9639ffbaefcfb47fce3782763af1fc67969fa91c5f01a336676 +R 22f5f05df54d41491893560077891588 U drh -Z 40f463993ad19f6f3483715fa2a6abfe +Z c0e52194d9465bf18726b8f5537bde36 diff --git a/manifest.uuid b/manifest.uuid index d25c8a1544..62827798f1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -416c898bfb8ff9639ffbaefcfb47fce3782763af1fc67969fa91c5f01a336676 \ No newline at end of file +1eb69c64ed4a11601698000573c507684bc4b0366336ba0748ebd661644d0902 \ No newline at end of file diff --git a/src/attach.c b/src/attach.c index 04274c6a7a..638929b26e 100644 --- a/src/attach.c +++ b/src/attach.c @@ -480,7 +480,6 @@ static int fixSelectCb(Walker *p, Select *pSelect){ #endif } if( pSelect->pWith ){ - int i; for(i=0; ipWith->nCte; i++){ if( sqlite3WalkSelect(p, pSelect->pWith->a[i].pSelect) ){ return WRC_Abort; From 7937f632203b9102d7093c13d98ab1db92f78603 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 3 Feb 2021 14:20:56 +0000 Subject: [PATCH 168/257] Avoid doing any foreign-key constraint related processing for an UPDATE statement that does not modify any columns that are part of FK constraints, even if the table has a self-referencing FK. FossilOrigin-Name: 7f3b036e730153ac22933b03a52d4ec3978c9ecab1399d8cc79fe533893321e3 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/fkey.c | 17 ++++++++++------- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 22730f26d0..dccbf6d97b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sharmless\scompiler\swarning. -D 2021-02-03T13:20:12.253 +C Avoid\sdoing\sany\sforeign-key\sconstraint\srelated\sprocessing\sfor\san\sUPDATE\sstatement\sthat\sdoes\snot\smodify\sany\scolumns\sthat\sare\spart\sof\sFK\sconstraints,\seven\sif\sthe\stable\shas\sa\sself-referencing\sFK. +D 2021-02-03T14:20:56.465 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -495,7 +495,7 @@ F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c F src/delete.c 352ea931218c45a3daf17472d4141b9c7fc026d85da3f1ade404ea5bb6d67f77 F src/expr.c 47c85263e6d179424e6b09e2c79db5704ab5b8cbc2fae2ee3285faa2566f2e74 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 -F src/fkey.c 02e4a3311885cd2b31eb17fd58dc2fc738cd2c823d0d39e4dd5595169c6f8bc3 +F src/fkey.c 73adaca988d0dd517d373b432dc9dfa2cd7fa3108b114260132a80832de19037 F src/func.c 2ea99e9e0531b7f020d5e8e167d25344d618afc718ddc94dd91fa8fef1c85a91 F src/global.c ed55af196a9b66e198aaeda3f5454c3aa7d7d050c6c938181fd044b70d180a81 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 @@ -1899,7 +1899,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 416c898bfb8ff9639ffbaefcfb47fce3782763af1fc67969fa91c5f01a336676 -R 22f5f05df54d41491893560077891588 -U drh -Z c0e52194d9465bf18726b8f5537bde36 +P 1eb69c64ed4a11601698000573c507684bc4b0366336ba0748ebd661644d0902 +R beb98a80dee252f5d30d5bb137b97d58 +U dan +Z 08ea3f42cb5505c3408631e0be2e285f diff --git a/manifest.uuid b/manifest.uuid index 62827798f1..ba705bf27e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1eb69c64ed4a11601698000573c507684bc4b0366336ba0748ebd661644d0902 \ No newline at end of file +7f3b036e730153ac22933b03a52d4ec3978c9ecab1399d8cc79fe533893321e3 \ No newline at end of file diff --git a/src/fkey.c b/src/fkey.c index 59e12b5fa8..abfc7d9a43 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -1112,7 +1112,9 @@ u32 sqlite3FkOldmask( ** ** For an UPDATE, this function returns 2 if: ** -** * There are any FKs for which pTab is the child and the parent table, or +** * There are any FKs for which pTab is the child and the parent table +** and any FK processing at all is required (even of a different FK), or +** ** * the UPDATE modifies one or more parent keys for which the action is ** not "NO ACTION" (i.e. is CASCADE, SET DEFAULT or SET NULL). ** @@ -1124,13 +1126,14 @@ int sqlite3FkRequired( int *aChange, /* Non-NULL for UPDATE operations */ int chngRowid /* True for UPDATE that affects rowid */ ){ - int eRet = 0; + 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( !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. */ - eRet = (sqlite3FkReferences(pTab) || pTab->pFKey); + bHaveFK = (sqlite3FkReferences(pTab) || pTab->pFKey); }else{ /* This is an UPDATE. Foreign key processing is only required if the ** operation modifies one or more child or parent key columns. */ @@ -1138,9 +1141,9 @@ int sqlite3FkRequired( /* Check if any child key columns are being modified. */ for(p=pTab->pFKey; p; p=p->pNextFrom){ - if( 0==sqlite3_stricmp(pTab->zName, p->zTo) ) return 2; if( fkChildIsModified(pTab, p, aChange, chngRowid) ){ - eRet = 1; + if( 0==sqlite3_stricmp(pTab->zName, p->zTo) ) eRet = 2; + bHaveFK = 1; } } @@ -1148,12 +1151,12 @@ int sqlite3FkRequired( for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ if( fkParentIsModified(pTab, p, aChange, chngRowid) ){ if( p->aAction[1]!=OE_None ) return 2; - eRet = 1; + bHaveFK = 1; } } } } - return eRet; + return bHaveFK ? eRet : 0; } /* From 17b74817c09709c0dece04b65a6bfa888a4007b5 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 3 Feb 2021 18:32:25 +0000 Subject: [PATCH 169/257] Change the name of Vdbe.magic to Vdbe.iVdbeMagic to disambiguate with sqlite3.magic. FossilOrigin-Name: 6b29e549bb34933bfd0758e31085e65dcc0f75446c478fc775d96cf01c22cf43 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/vdbe.c | 2 +- src/vdbeInt.h | 2 +- src/vdbeapi.c | 6 +++--- src/vdbeaux.c | 34 +++++++++++++++++----------------- 6 files changed, 33 insertions(+), 33 deletions(-) diff --git a/manifest b/manifest index dccbf6d97b..02d9db9c6b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sdoing\sany\sforeign-key\sconstraint\srelated\sprocessing\sfor\san\sUPDATE\sstatement\sthat\sdoes\snot\smodify\sany\scolumns\sthat\sare\spart\sof\sFK\sconstraints,\seven\sif\sthe\stable\shas\sa\sself-referencing\sFK. -D 2021-02-03T14:20:56.465 +C Change\sthe\sname\sof\sVdbe.magic\sto\sVdbe.iVdbeMagic\sto\sdisambiguate\swith\nsqlite3.magic. +D 2021-02-03T18:32:25.893 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -613,11 +613,11 @@ F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 41c7a72da1df47864faa378a1c720b38adb288c6838cb6be5594511b6287a048 F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286 -F src/vdbe.c 9b9a714318e49b59a282b4e175080dc53a07b8099895fa21613e6b80fbad3727 +F src/vdbe.c b3c9a3f9d546d4848a2a8c88a3c40875cd6ba3d248d9b99d01b1eeb38b29c171 F src/vdbe.h a71bf43572d3de57923d1928ac01ae8d355cd67e94462ba4f7462265cedbef9a -F src/vdbeInt.h 3ca5e9fd6e095a8b6cf6bc3587a46fc93499503b2fe48951e1034ba9e2ce2f6e -F src/vdbeapi.c c5e7cb2ab89a24d7f723e87b508f21bfb1359a04db5277d8a99fd1e015c12eb9 -F src/vdbeaux.c 2be30e4918126122fa358ef8303206cad0feffe17d320077c77ff5c2a34f3626 +F src/vdbeInt.h 3df118924e1711f1bbc8e30c46260d0ab6c3b029b32dd411f789111f76434f3c +F src/vdbeapi.c 4a43e303ec3354c785f453e881521969378e85628278ab74ba4a9df790c0d93b +F src/vdbeaux.c 34994221fbde303e362cf11c7d97fe9b115055cfdf716260ca0140811de94aab F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1 F src/vdbemem.c 947f2a65910edb4014dc981d33e414a68c51f169f9df8c4c493a0ba840b6eb1f F src/vdbesort.c f5b5e473a7cee44e47a94817b042fd7172cf3aa2c0a7928a8339d612bcfdec5a @@ -1899,7 +1899,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 1eb69c64ed4a11601698000573c507684bc4b0366336ba0748ebd661644d0902 -R beb98a80dee252f5d30d5bb137b97d58 -U dan -Z 08ea3f42cb5505c3408631e0be2e285f +P 7f3b036e730153ac22933b03a52d4ec3978c9ecab1399d8cc79fe533893321e3 +R da1e9977e016fead3ba113e856c385ff +U drh +Z f627ee51e8367fe2ca61dde2a77a6558 diff --git a/manifest.uuid b/manifest.uuid index ba705bf27e..7ab2b2f097 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7f3b036e730153ac22933b03a52d4ec3978c9ecab1399d8cc79fe533893321e3 \ No newline at end of file +6b29e549bb34933bfd0758e31085e65dcc0f75446c478fc775d96cf01c22cf43 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index bb18277891..97cd696de3 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -685,7 +685,7 @@ int sqlite3VdbeExec( #endif /*** INSERT STACK UNION HERE ***/ - assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */ + assert( p->iVdbeMagic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */ sqlite3VdbeEnter(p); #ifndef SQLITE_OMIT_PROGRESS_CALLBACK if( db->xProgress ){ diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 7d22cb8093..4f8a2edf37 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -381,7 +381,7 @@ struct Vdbe { Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */ Parse *pParse; /* Parsing context used to create this Vdbe */ ynVar nVar; /* Number of entries in aVar[] */ - u32 magic; /* Magic number for sanity checking */ + u32 iVdbeMagic; /* Magic number defining state of the SQL statement */ int nMem; /* Number of memory locations currently allocated */ int nCursor; /* Number of slots in apCsr[] */ u32 cacheCtr; /* VdbeCursor row cache generation counter */ diff --git a/src/vdbeapi.c b/src/vdbeapi.c index a9cbf92fc3..ba3bdf6a5f 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -617,7 +617,7 @@ static int sqlite3Step(Vdbe *p){ int rc; assert(p); - if( p->magic!=VDBE_MAGIC_RUN ){ + if( p->iVdbeMagic!=VDBE_MAGIC_RUN ){ /* We used to require that sqlite3_reset() be called before retrying ** sqlite3_step() after any error or after SQLITE_DONE. But beginning ** with version 3.7.0, we changed this so that sqlite3_reset() would @@ -1333,7 +1333,7 @@ static int vdbeUnbind(Vdbe *p, int i){ return SQLITE_MISUSE_BKPT; } sqlite3_mutex_enter(p->db->mutex); - if( p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){ + if( p->iVdbeMagic!=VDBE_MAGIC_RUN || p->pc>=0 ){ sqlite3Error(p->db, SQLITE_MISUSE); sqlite3_mutex_leave(p->db->mutex); sqlite3_log(SQLITE_MISUSE, @@ -1687,7 +1687,7 @@ int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt){ */ int sqlite3_stmt_busy(sqlite3_stmt *pStmt){ Vdbe *v = (Vdbe*)pStmt; - return v!=0 && v->magic==VDBE_MAGIC_RUN && v->pc>=0; + return v!=0 && v->iVdbeMagic==VDBE_MAGIC_RUN && v->pc>=0; } /* diff --git a/src/vdbeaux.c b/src/vdbeaux.c index c7c2125751..1c77b2ce94 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -35,7 +35,7 @@ Vdbe *sqlite3VdbeCreate(Parse *pParse){ p->pNext = db->pVdbe; p->pPrev = 0; db->pVdbe = p; - p->magic = VDBE_MAGIC_INIT; + p->iVdbeMagic = VDBE_MAGIC_INIT; p->pParse = pParse; pParse->pVdbe = p; assert( pParse->aLabel==0 ); @@ -236,7 +236,7 @@ int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ VdbeOp *pOp; i = p->nOp; - assert( p->magic==VDBE_MAGIC_INIT ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); assert( op>=0 && op<0xff ); if( p->nOpAlloc<=i ){ return growOp3(p, op, p1, p2, p3); @@ -565,7 +565,7 @@ static SQLITE_NOINLINE void resizeResolveLabel(Parse *p, Vdbe *v, int j){ void sqlite3VdbeResolveLabel(Vdbe *v, int x){ Parse *p = v->pParse; int j = ADDR(x); - assert( v->magic==VDBE_MAGIC_INIT ); + assert( v->iVdbeMagic==VDBE_MAGIC_INIT ); assert( j<-p->nLabel ); assert( j>=0 ); #ifdef SQLITE_DEBUG @@ -890,7 +890,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ ** Return the address of the next instruction to be inserted. */ int sqlite3VdbeCurrentAddr(Vdbe *p){ - assert( p->magic==VDBE_MAGIC_INIT ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); return p->nOp; } @@ -975,7 +975,7 @@ VdbeOp *sqlite3VdbeAddOpList( int i; VdbeOp *pOut, *pFirst; assert( nOp>0 ); - assert( p->magic==VDBE_MAGIC_INIT ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); if( p->nOp + nOp > p->nOpAlloc && growOpArray(p, nOp) ){ return 0; } @@ -1299,7 +1299,7 @@ void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){ sqlite3 *db; assert( p!=0 ); db = p->db; - assert( p->magic==VDBE_MAGIC_INIT ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); assert( p->aOp!=0 || db->mallocFailed ); if( db->mallocFailed ){ if( n!=P4_VTAB ) freeP4(db, n, (void*)*(char**)&zP4); @@ -1428,7 +1428,7 @@ VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){ /* C89 specifies that the constant "dummy" will be initialized to all ** zeros, which is correct. MSVC generates a warning, nevertheless. */ static VdbeOp dummy; /* Ignore the MSVC warning about no initializer */ - assert( p->magic==VDBE_MAGIC_INIT ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); if( addr<0 ){ addr = p->nOp - 1; } @@ -2113,7 +2113,7 @@ int sqlite3VdbeList( Op *pOp; /* Current opcode */ assert( p->explain ); - assert( p->magic==VDBE_MAGIC_RUN ); + assert( p->iVdbeMagic==VDBE_MAGIC_RUN ); assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM ); /* Even though this opcode does not use dynamic strings for @@ -2293,14 +2293,14 @@ void sqlite3VdbeRewind(Vdbe *p){ int i; #endif assert( p!=0 ); - assert( p->magic==VDBE_MAGIC_INIT || p->magic==VDBE_MAGIC_RESET ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT || p->iVdbeMagic==VDBE_MAGIC_RESET ); /* There should be at least one opcode. */ assert( p->nOp>0 ); /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */ - p->magic = VDBE_MAGIC_RUN; + p->iVdbeMagic = VDBE_MAGIC_RUN; #ifdef SQLITE_DEBUG for(i=0; inMem; i++){ @@ -2356,7 +2356,7 @@ void sqlite3VdbeMakeReady( assert( p!=0 ); assert( p->nOp>0 ); assert( pParse!=0 ); - assert( p->magic==VDBE_MAGIC_INIT ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); assert( pParse==p->pParse ); p->pVList = pParse->pVList; pParse->pVList = 0; @@ -3058,7 +3058,7 @@ int sqlite3VdbeHalt(Vdbe *p){ ** one, or the complete transaction if there is no statement transaction. */ - if( p->magic!=VDBE_MAGIC_RUN ){ + if( p->iVdbeMagic!=VDBE_MAGIC_RUN ){ return SQLITE_OK; } if( db->mallocFailed ){ @@ -3216,7 +3216,7 @@ int sqlite3VdbeHalt(Vdbe *p){ assert( db->nVdbeRead>=db->nVdbeWrite ); assert( db->nVdbeWrite>=0 ); } - p->magic = VDBE_MAGIC_HALT; + p->iVdbeMagic = VDBE_MAGIC_HALT; checkActiveVdbeCnt(db); if( db->mallocFailed ){ p->rc = SQLITE_NOMEM_BKPT; @@ -3389,7 +3389,7 @@ int sqlite3VdbeReset(Vdbe *p){ } } #endif - p->magic = VDBE_MAGIC_RESET; + p->iVdbeMagic = VDBE_MAGIC_RESET; return p->rc & db->errMask; } @@ -3399,7 +3399,7 @@ int sqlite3VdbeReset(Vdbe *p){ */ int sqlite3VdbeFinalize(Vdbe *p){ int rc = SQLITE_OK; - if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){ + if( p->iVdbeMagic==VDBE_MAGIC_RUN || p->iVdbeMagic==VDBE_MAGIC_HALT ){ rc = sqlite3VdbeReset(p); assert( (rc & p->db->errMask)==rc ); } @@ -3460,7 +3460,7 @@ void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ vdbeFreeOpArray(db, pSub->aOp, pSub->nOp); sqlite3DbFree(db, pSub); } - if( p->magic!=VDBE_MAGIC_INIT ){ + if( p->iVdbeMagic!=VDBE_MAGIC_INIT ){ releaseMemArray(p->aVar, p->nVar); sqlite3DbFree(db, p->pVList); sqlite3DbFree(db, p->pFree); @@ -3508,7 +3508,7 @@ void sqlite3VdbeDelete(Vdbe *p){ if( p->pNext ){ p->pNext->pPrev = p->pPrev; } - p->magic = VDBE_MAGIC_DEAD; + p->iVdbeMagic = VDBE_MAGIC_DEAD; p->db = 0; sqlite3DbFreeNN(db, p); } From 8c333cfc0d9076223a8156380820d702947b80fc Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 3 Feb 2021 19:38:40 +0000 Subject: [PATCH 170/257] Corrections to the 'filepath_normalize' test suite helper procedure. FossilOrigin-Name: 32f4d04470bf953b08eea285543f16e03de13d5448c1ebccbba1578ca3b5363e --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/tester.tcl | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 02d9db9c6b..512110c1e4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sname\sof\sVdbe.magic\sto\sVdbe.iVdbeMagic\sto\sdisambiguate\swith\nsqlite3.magic. -D 2021-02-03T18:32:25.893 +C Corrections\sto\sthe\s'filepath_normalize'\stest\ssuite\shelper\sprocedure. +D 2021-02-03T19:38:40.978 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1439,7 +1439,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 e5e4f5707fbf791ff8e06438fd0d4d71fe4c1d48753b7dd415efe72e853ef877 +F test/tester.tcl 19d2a19a6dd55a2b4e2b943963959a05a2c088495dd5f5274b04e0494ce86d66 F test/thread001.test b61a29dd87cf669f5f6ac96124a7c97d71b0c80d9012746072055877055cf9ef F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1899,7 +1899,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 7f3b036e730153ac22933b03a52d4ec3978c9ecab1399d8cc79fe533893321e3 -R da1e9977e016fead3ba113e856c385ff -U drh -Z f627ee51e8367fe2ca61dde2a77a6558 +P 6b29e549bb34933bfd0758e31085e65dcc0f75446c478fc775d96cf01c22cf43 +R 85ac248a64299c59878f72d774654f84 +U mistachkin +Z cd094eb04790b0c848908f94f1895107 diff --git a/manifest.uuid b/manifest.uuid index 7ab2b2f097..a3ab0cdd0d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6b29e549bb34933bfd0758e31085e65dcc0f75446c478fc775d96cf01c22cf43 \ No newline at end of file +32f4d04470bf953b08eea285543f16e03de13d5448c1ebccbba1578ca3b5363e \ No newline at end of file diff --git a/test/tester.tcl b/test/tester.tcl index 5c72dccbb7..304808b6bc 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -908,8 +908,8 @@ proc catchcmdex {db {cmd ""}} { proc filepath_normalize {p} { # test cases should be written to assume "unix"-like file paths if {$::tcl_platform(platform)!="unix"} { - # lreverse*2 as a hack to remove any unneeded {} after the string map - lreverse [lreverse [string map {\\ /} [regsub -nocase -all {[a-z]:[/\\]+} $p {/}]]] + string map [list \\ / \{/ / .db\} .db] \ + [regsub -nocase -all {[a-z]:[/\\]+} $p {/}] } { set p } From 02c4aa39e7c731e3ff9cec3bb456f006ba8af7fa Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 4 Feb 2021 13:44:42 +0000 Subject: [PATCH 171/257] Performance optimization in sqlite3FinishCoding(). FossilOrigin-Name: 0f34f241d37cc4f31dc657a6fc33815fa5e24298487121cb27c29118524b8ee7 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/build.c | 13 ++++++++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 512110c1e4..72a3bd8f37 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Corrections\sto\sthe\s'filepath_normalize'\stest\ssuite\shelper\sprocedure. -D 2021-02-03T19:38:40.978 +C Performance\soptimization\sin\ssqlite3FinishCoding(). +D 2021-02-04T13:44:42.342 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -485,7 +485,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 4da25694985ac8f5f714bfa58a6cd453f9161d7da9394a95605aaa4db2752757 F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 -F src/build.c 118e1076282415229420d04f9cc25bb148a2c412d82ea3c319136d2122c842e5 +F src/build.c 4a70f3ce393dba6963e7d74f72fab0108da6c87e43f1d8afe3fdb31034e190f6 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 @@ -1899,7 +1899,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 6b29e549bb34933bfd0758e31085e65dcc0f75446c478fc775d96cf01c22cf43 -R 85ac248a64299c59878f72d774654f84 -U mistachkin -Z cd094eb04790b0c848908f94f1895107 +P 32f4d04470bf953b08eea285543f16e03de13d5448c1ebccbba1578ca3b5363e +R cafbcf0e593374a18560abb41780f369 +U drh +Z bc6fff01a90b824647bf326788fdbb3d diff --git a/manifest.uuid b/manifest.uuid index a3ab0cdd0d..0db27cffdf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -32f4d04470bf953b08eea285543f16e03de13d5448c1ebccbba1578ca3b5363e \ No newline at end of file +0f34f241d37cc4f31dc657a6fc33815fa5e24298487121cb27c29118524b8ee7 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 25f61e8156..d592827792 100644 --- a/src/build.c +++ b/src/build.c @@ -143,11 +143,15 @@ void sqlite3FinishCoding(Parse *pParse){ /* Begin by generating some termination code at the end of the ** vdbe program */ - if( pParse->pVdbe==0 && db->init.busy ){ - pParse->rc = SQLITE_DONE; - return; + v = pParse->pVdbe; + if( v==0 ){ + if( db->init.busy ){ + pParse->rc = SQLITE_DONE; + return; + } + v = sqlite3GetVdbe(pParse); + if( v==0 ) pParse->rc = SQLITE_ERROR; } - v = sqlite3GetVdbe(pParse); assert( !pParse->isMultiWrite || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort)); if( v ){ @@ -233,7 +237,6 @@ void sqlite3FinishCoding(Parse *pParse){ } } - /* Get the VDBE program ready for execution */ if( v && pParse->nErr==0 && !db->mallocFailed ){ From 8ab79d6135b33523a5d7f5c988b080a63fb15db3 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 4 Feb 2021 13:52:34 +0000 Subject: [PATCH 172/257] Add NEVER() to a branch that check-in [5d54d9fd40638138] apparently made unreachable. FossilOrigin-Name: 5c8e6296aa9f69a092364524b716ba894f113f7f1e6024b9a2eaa01c239e65c1 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 72a3bd8f37..cb5c4da361 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimization\sin\ssqlite3FinishCoding(). -D 2021-02-04T13:44:42.342 +C Add\sNEVER()\sto\sa\sbranch\sthat\scheck-in\s[5d54d9fd40638138]\sapparently\smade\nunreachable. +D 2021-02-04T13:52:34.346 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -482,7 +482,7 @@ F src/auth.c 8d1df0e2ef8bafbedd4f1fe4baff03eb27507da4bf6e449df3613d383c4018b2 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 4da25694985ac8f5f714bfa58a6cd453f9161d7da9394a95605aaa4db2752757 +F src/btree.c 694020ad8a3af3d79b09f74c8f1421272a419cdea42a13401e3b0f7dea6e9c3e F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 F src/build.c 4a70f3ce393dba6963e7d74f72fab0108da6c87e43f1d8afe3fdb31034e190f6 @@ -1899,7 +1899,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 32f4d04470bf953b08eea285543f16e03de13d5448c1ebccbba1578ca3b5363e -R cafbcf0e593374a18560abb41780f369 +P 0f34f241d37cc4f31dc657a6fc33815fa5e24298487121cb27c29118524b8ee7 +R cff545e4a39efc504a1ff4bec6444fd1 U drh -Z bc6fff01a90b824647bf326788fdbb3d +Z e8f529c01cdfd85106db62be4d9db740 diff --git a/manifest.uuid b/manifest.uuid index 0db27cffdf..0cefd72434 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0f34f241d37cc4f31dc657a6fc33815fa5e24298487121cb27c29118524b8ee7 \ No newline at end of file +5c8e6296aa9f69a092364524b716ba894f113f7f1e6024b9a2eaa01c239e65c1 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 0f71b0479e..d0e51b82dc 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8014,7 +8014,7 @@ static int balance_nonroot( aPgOrder[i] = aPgno[i] = apNew[i]->pgno; aPgFlags[i] = apNew[i]->pDbPage->flags; for(j=0; j Date: Thu, 4 Feb 2021 17:29:04 +0000 Subject: [PATCH 173/257] Preliminary changes for a new implementation of RETURNING that captures all results in a buffer and plays them all back after the DML statement completes. This avoids problems with interleaved DML statements. This particular check-in is a non-functional work in progress. FossilOrigin-Name: 04b77d63216ce11b4e797946953bcde504fc005807c7a5ac757fbf47d78698dc --- manifest | 19 +++++---- manifest.uuid | 2 +- src/build.c | 37 ++++++++++++++---- src/sqliteInt.h | 11 ++++-- src/trigger.c | 100 ++++++++++++++++++++++++++++++++---------------- 5 files changed, 117 insertions(+), 52 deletions(-) diff --git a/manifest b/manifest index cb5c4da361..50a026f7a0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sNEVER()\sto\sa\sbranch\sthat\scheck-in\s[5d54d9fd40638138]\sapparently\smade\nunreachable. -D 2021-02-04T13:52:34.346 +C Preliminary\schanges\sfor\sa\snew\simplementation\sof\sRETURNING\sthat\scaptures\sall\nresults\sin\sa\sbuffer\sand\splays\sthem\sall\sback\safter\sthe\sDML\sstatement\ncompletes.\s\sThis\savoids\sproblems\swith\sinterleaved\sDML\sstatements.\nThis\sparticular\scheck-in\sis\sa\snon-functional\swork\sin\sprogress. +D 2021-02-04T17:29:04.659 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -485,7 +485,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 694020ad8a3af3d79b09f74c8f1421272a419cdea42a13401e3b0f7dea6e9c3e F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 -F src/build.c 4a70f3ce393dba6963e7d74f72fab0108da6c87e43f1d8afe3fdb31034e190f6 +F src/build.c 5285b8d1e4cf21dd9e12619fe0a6067bcb036ee7f7ad5cd31a39a05c5823e2a2 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 @@ -546,7 +546,7 @@ F src/shell.c.in 9ebc74e4f05cfbd0f4a36060fdaeff1da4e9af4458358722bc08c5a1ab9a087 F src/sqlite.h.in 8855a19f37ade8dad189a9e48233a2ebe1b46faf469c7eb0906a654e252dcc57 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h 0fda3b2c05b1559135aa2c4ecb8e75bd2085ba4433310bbb5427d97c2d81315d +F src/sqliteInt.h 596729ed0c2509a32cb17cecc7baf2a3499299064c03dbe79f8daca08d4daf7c F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -607,7 +607,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda -F src/trigger.c 0a242d65dd9b9822d4e990653eb4ece3557dcda01374934aa3cc1f9718d8dee3 +F src/trigger.c 803db1f98d84a86b31a13e8a42715936bc760d0192bc4264d57a96f362c2a591 F src/update.c 0f5a61f0787199983530a33f6fffe4f52742f35fcdf6ccfad1078b1a8bc17723 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 @@ -1899,7 +1899,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 0f34f241d37cc4f31dc657a6fc33815fa5e24298487121cb27c29118524b8ee7 -R cff545e4a39efc504a1ff4bec6444fd1 +P 5c8e6296aa9f69a092364524b716ba894f113f7f1e6024b9a2eaa01c239e65c1 +R 9ba8b89a255b185f318ef97355eff6b3 +T *branch * returning-manifested +T *sym-returning-manifested * +T -sym-trunk * U drh -Z e8f529c01cdfd85106db62be4d9db740 +Z 04ce06a70e76b82a776d153a576955fb diff --git a/manifest.uuid b/manifest.uuid index 0cefd72434..be203d8902 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5c8e6296aa9f69a092364524b716ba894f113f7f1e6024b9a2eaa01c239e65c1 \ No newline at end of file +04b77d63216ce11b4e797946953bcde504fc005807c7a5ac757fbf47d78698dc \ No newline at end of file diff --git a/src/build.c b/src/build.c index d592827792..48607bfe81 100644 --- a/src/build.c +++ b/src/build.c @@ -155,6 +155,24 @@ void sqlite3FinishCoding(Parse *pParse){ assert( !pParse->isMultiWrite || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort)); if( v ){ + if( pParse->bReturning ){ + Returning *pReturning = pParse->u1.pReturning; + int addrRewind; + int i; + int reg; + + sqlite3VdbeAddOp0(v, OP_Noop); VdbeComment((v, "TODO: Commit changes")); + addrRewind = + sqlite3VdbeAddOp1(v, OP_Rewind, pReturning->iRetCur); + reg = pParse->nMem+1; + pParse->nMem += pReturning->nRetCol; + for(i=0; inRetCol; i++){ + sqlite3VdbeAddOp3(v, OP_Column, pReturning->iRetCur, i, reg+i); + } + sqlite3VdbeAddOp2(v, OP_ResultRow, reg, i); + sqlite3VdbeAddOp2(v, OP_Next, pReturning->iRetCur, addrRewind+1); + sqlite3VdbeJumpHere(v, addrRewind); + } sqlite3VdbeAddOp0(v, OP_Halt); #if SQLITE_USER_AUTHENTICATION @@ -232,6 +250,11 @@ void sqlite3FinishCoding(Parse *pParse){ } } + if( pParse->bReturning ){ + Returning *pRet = pParse->u1.pReturning; + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRet->iRetCur, pRet->nRetCol); + } + /* Finally, jump back to the beginning of the executable code. */ sqlite3VdbeGoto(v, 1); } @@ -1213,7 +1236,8 @@ void sqlite3StartTable( }else #endif { - pParse->addrCrTab = + assert( !pParse->bReturning ); + pParse->u1.addrCrTab = sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, reg2, BTREE_INTKEY); } sqlite3OpenSchemaTable(pParse, iDb); @@ -1291,6 +1315,7 @@ void sqlite3AddReturning(Parse *pParse, ExprList *pList){ sqlite3ExprListDelete(db, pList); return; } + pParse->u1.pReturning = pRet; pRet->pParse = pParse; pRet->pReturnEL = pList; sqlite3ParserAddCleanup(pParse, @@ -1304,10 +1329,7 @@ void sqlite3AddReturning(Parse *pParse, ExprList *pList){ pRet->retTrig.step_list = &pRet->retTStep; pRet->retTStep.op = TK_RETURNING; pRet->retTStep.pTrig = &pRet->retTrig; - pRet->retTStep.pSelect = &pRet->retSel; - pRet->retSel.op = TK_ALL; - pRet->retSel.pEList = pList; - pRet->retSel.pSrc = (SrcList*)&pRet->retSrcList; + pRet->retTStep.pExprList = pList; pHash = &(db->aDb[1].pSchema->trigHash); assert( sqlite3HashFind(pHash, RETURNING_TRIGGER_NAME)==0 ); if( sqlite3HashInsert(pHash, RETURNING_TRIGGER_NAME, &pRet->retTrig) @@ -2147,9 +2169,10 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ /* Convert the P3 operand of the OP_CreateBtree opcode from BTREE_INTKEY ** into BTREE_BLOBKEY. */ - if( pParse->addrCrTab ){ + assert( !pParse->bReturning ); + if( pParse->u1.addrCrTab ){ assert( v ); - sqlite3VdbeChangeP3(v, pParse->addrCrTab, BTREE_BLOBKEY); + sqlite3VdbeChangeP3(v, pParse->u1.addrCrTab, BTREE_BLOBKEY); } /* Locate the PRIMARY KEY index. Or, if this table was originally diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 3cadb7f53a..528c908ca6 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3425,7 +3425,10 @@ struct Parse { Table *pTriggerTab; /* Table triggers are being coded for */ Parse *pParentParse; /* Parent parser if this parser is nested */ AggInfo *pAggList; /* List of all AggInfo objects */ - int addrCrTab; /* Address of OP_CreateBtree opcode on CREATE TABLE */ + union { + int addrCrTab; /* Address of OP_CreateBtree on CREATE TABLE */ + Returning *pReturning; /* The RETURNING clause */ + } u1; u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */ u32 oldmask; /* Mask of old.* columns referenced */ u32 newmask; /* Mask of new.* columns referenced */ @@ -3647,7 +3650,7 @@ struct TriggerStep { char *zTarget; /* Target table for DELETE, UPDATE, INSERT */ SrcList *pFrom; /* FROM clause for UPDATE statement (if any) */ Expr *pWhere; /* The WHERE clause for DELETE or UPDATE steps */ - ExprList *pExprList; /* SET clause for UPDATE */ + ExprList *pExprList; /* SET clause for UPDATE, or RETURNING clause */ IdList *pIdList; /* Column names for INSERT */ Upsert *pUpsert; /* Upsert clauses on an INSERT */ char *zSpan; /* Original SQL text of this command */ @@ -3663,8 +3666,8 @@ struct Returning { ExprList *pReturnEL; /* List of expressions to return */ Trigger retTrig; /* The transient trigger that implements RETURNING */ TriggerStep retTStep; /* The trigger step */ - Select retSel; /* The SELECT statement that implements RETURNING */ - u64 retSrcList; /* The empty FROM clause of the SELECT */ + int iRetCur; /* Transient table holding RETURNING results */ + int nRetCol; /* Number of in pReturnEL after expansion */ }; /* diff --git a/src/trigger.c b/src/trigger.c index ef0a90b24f..fc7e64e51e 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -70,6 +70,8 @@ Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){ pTrig->pNext = pList; pList = pTrig; }else if( pTrig->op==TK_RETURNING ){ + assert( pParse->bReturning ); + assert( &(pParse->u1.pReturning->retTrig) == pTrig ); pTrig->table = pTab->zName; pTrig->pTabSchema = pTab->pSchema; pTrig->pNext = pList; @@ -857,6 +859,55 @@ static ExprList *sqlite3ExpandReturning( return pNew; } +/* +** Generate code for the RETURNING trigger. Unlike other triggers +** that invoke a subprogram in the bytecode, the code for RETURNING +** is generated in-line. +*/ +static void codeReturningTrigger( + Parse *pParse, /* Parse context */ + Trigger *pTrigger, /* The trigger step that defines the RETURNING */ + Table *pTab, /* The table to code triggers from */ + int reg /* The first in an array of registers */ +){ + Vdbe *v = pParse->pVdbe; + ExprList *pNew; + Returning *pReturning; + + assert( v!=0 ); + assert( pParse->bReturning ); + pReturning = pParse->u1.pReturning; + assert( pTrigger == &(pReturning->retTrig) ); + sqlite3VdbeAddOp0(v, OP_Noop); + VdbeComment((v, "RETURNING trigger goes here")); + pNew = sqlite3ExpandReturning(pParse, pReturning->pReturnEL, pTab); + if( pNew ){ + pReturning->nRetCol = pNew->nExpr; + pReturning->iRetCur = pParse->nTab++; + sqlite3ExprListDelete(pParse->db, pNew); + } + +#if 0 + pSelect->pEList = + sqlite3ExpandReturning(pParse, pList, pParse->pTriggerTab); + sqlite3SelectDestInit(&sDest, SRT_Output, 0); + pNew = sqlite3SelectDup(db, pSelect, 0); + if( pNew ){ + sqlite3Select(pParse, pNew, &sDest); + if( pNew->selFlags & (SF_Aggregate|SF_HasAgg|SF_WinRewrite) ){ + sqlite3ErrorMsg(pParse, "aggregates not allowed in RETURNING"); + } + sqlite3SelectDelete(db, pNew); + } + sqlite3ExprListDelete(db, pSelect->pEList); + pStep->pSelect->pEList = pList; + break; + } +#endif +} + + + /* ** Generate VDBE code for the statements inside the body of a single ** trigger. @@ -928,7 +979,7 @@ static int codeTriggerProgram( sqlite3VdbeAddOp0(v, OP_ResetCount); break; } - case TK_SELECT: { + default: assert( pStep->op==TK_SELECT ); { SelectDest sDest; Select *pSelect = sqlite3SelectDup(db, pStep->pSelect, 0); sqlite3SelectDestInit(&sDest, SRT_Discard, 0); @@ -936,26 +987,6 @@ static int codeTriggerProgram( sqlite3SelectDelete(db, pSelect); break; } - default: assert( pStep->op==TK_RETURNING ); { - Select *pSelect = pStep->pSelect; - ExprList *pList = pSelect->pEList; - SelectDest sDest; - Select *pNew; - pSelect->pEList = - sqlite3ExpandReturning(pParse, pList, pParse->pTriggerTab); - sqlite3SelectDestInit(&sDest, SRT_Output, 0); - pNew = sqlite3SelectDup(db, pSelect, 0); - if( pNew ){ - sqlite3Select(pParse, pNew, &sDest); - if( pNew->selFlags & (SF_Aggregate|SF_HasAgg|SF_WinRewrite) ){ - sqlite3ErrorMsg(pParse, "aggregates not allowed in RETURNING"); - } - sqlite3SelectDelete(db, pNew); - } - sqlite3ExprListDelete(db, pSelect->pEList); - pStep->pSelect->pEList = pList; - break; - } } } @@ -1208,7 +1239,7 @@ void sqlite3CodeRowTriggerDirect( ** ... ... ** reg+N OLD.* value of right-most column of pTab ** reg+N+1 NEW.rowid -** reg+N+2 OLD.* value of left-most column of pTab +** reg+N+2 NEW.* value of left-most column of pTab ** ... ... ** reg+N+N+1 NEW.* value of right-most column of pTab ** @@ -1261,12 +1292,12 @@ void sqlite3CodeRowTrigger( if( (p->op==op || (p->bReturning && p->op==TK_INSERT && op==TK_UPDATE)) && p->tr_tm==tr_tm && checkColumnOverlap(p->pColumns, pChanges) - && (sqlite3IsToplevel(pParse) || !p->bReturning) ){ - u8 origOp = p->op; - p->op = op; - sqlite3CodeRowTriggerDirect(pParse, p, pTab, reg, orconf, ignoreJump); - p->op = origOp; + if( !p->bReturning ){ + sqlite3CodeRowTriggerDirect(pParse, p, pTab, reg, orconf, ignoreJump); + }else if( sqlite3IsToplevel(pParse) ){ + codeReturningTrigger(pParse, p, pTab, reg); + } } } } @@ -1311,13 +1342,18 @@ u32 sqlite3TriggerColmask( assert( isNew==1 || isNew==0 ); for(p=pTrigger; p; p=p->pNext){ - if( p->op==op && (tr_tm&p->tr_tm) + if( p->op==op + && (tr_tm&p->tr_tm) && checkColumnOverlap(p->pColumns,pChanges) ){ - TriggerPrg *pPrg; - pPrg = getRowTrigger(pParse, p, pTab, orconf); - if( pPrg ){ - mask |= pPrg->aColmask[isNew]; + if( p->bReturning ){ + mask = 0xffffffff; + }else{ + TriggerPrg *pPrg; + pPrg = getRowTrigger(pParse, p, pTab, orconf); + if( pPrg ){ + mask |= pPrg->aColmask[isNew]; + } } } } From 552562c48feb6659f7fb72311c66d7a62154d523 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 4 Feb 2021 20:52:20 +0000 Subject: [PATCH 174/257] Snapshot. New design appears to work on a simple test case. FossilOrigin-Name: 8a65fbeecf3597e30853c5f0ccd9b8b46c508854fa521e58e0db279deebca7d4 --- manifest | 21 +++++++++---------- manifest.uuid | 2 +- src/build.c | 3 +-- src/resolve.c | 40 +++++++++++++++++++++--------------- src/sqliteInt.h | 3 +++ src/trigger.c | 54 +++++++++++++++++++++++++++++++------------------ 6 files changed, 72 insertions(+), 51 deletions(-) diff --git a/manifest b/manifest index 50a026f7a0..75c0cabd1e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Preliminary\schanges\sfor\sa\snew\simplementation\sof\sRETURNING\sthat\scaptures\sall\nresults\sin\sa\sbuffer\sand\splays\sthem\sall\sback\safter\sthe\sDML\sstatement\ncompletes.\s\sThis\savoids\sproblems\swith\sinterleaved\sDML\sstatements.\nThis\sparticular\scheck-in\sis\sa\snon-functional\swork\sin\sprogress. -D 2021-02-04T17:29:04.659 +C Snapshot.\s\sNew\sdesign\sappears\sto\swork\son\sa\ssimple\stest\scase. +D 2021-02-04T20:52:20.449 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -485,7 +485,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 694020ad8a3af3d79b09f74c8f1421272a419cdea42a13401e3b0f7dea6e9c3e F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 -F src/build.c 5285b8d1e4cf21dd9e12619fe0a6067bcb036ee7f7ad5cd31a39a05c5823e2a2 +F src/build.c 1b8d3d59dcd52c5d74847a56174e6819713012cd370809352375422d0907c8bf F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 @@ -539,14 +539,14 @@ F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf F src/prepare.c f288cbc35f79eb32e162de7e80a63ebe00d80e639dcfac071bee11570cbdb16f F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c f6761473ea4b51190fc52f8f2121498b78717266e106e7bff12849ea2d52165f +F src/resolve.c 397c3e889fea46fc7aa0bbe98ffd91046b7b44ade2cdab6b2357a4b7ddd10b13 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 738cb746189f721f59972993c13085fa2975c4cbfd04ba26445f3b42c81237dc F src/shell.c.in 9ebc74e4f05cfbd0f4a36060fdaeff1da4e9af4458358722bc08c5a1ab9a0879 F src/sqlite.h.in 8855a19f37ade8dad189a9e48233a2ebe1b46faf469c7eb0906a654e252dcc57 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h 596729ed0c2509a32cb17cecc7baf2a3499299064c03dbe79f8daca08d4daf7c +F src/sqliteInt.h c51a21569e193f377f6d70a2fed0031fd88f141e112a5902cb9e31c1f79f5194 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -607,7 +607,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda -F src/trigger.c 803db1f98d84a86b31a13e8a42715936bc760d0192bc4264d57a96f362c2a591 +F src/trigger.c 5da6ba6d4067b5dcdd11a6da37ce3cb56586df75a7be685efb534c46d5c773c8 F src/update.c 0f5a61f0787199983530a33f6fffe4f52742f35fcdf6ccfad1078b1a8bc17723 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 @@ -1899,10 +1899,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 5c8e6296aa9f69a092364524b716ba894f113f7f1e6024b9a2eaa01c239e65c1 -R 9ba8b89a255b185f318ef97355eff6b3 -T *branch * returning-manifested -T *sym-returning-manifested * -T -sym-trunk * +P 04b77d63216ce11b4e797946953bcde504fc005807c7a5ac757fbf47d78698dc +R 3969643abefe6509994dc8b8c75efd08 U drh -Z 04ce06a70e76b82a776d153a576955fb +Z b4647d4c6645877bc3632b5ebc38eb6e diff --git a/manifest.uuid b/manifest.uuid index be203d8902..6756c35314 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -04b77d63216ce11b4e797946953bcde504fc005807c7a5ac757fbf47d78698dc \ No newline at end of file +8a65fbeecf3597e30853c5f0ccd9b8b46c508854fa521e58e0db279deebca7d4 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 48607bfe81..a219d2b23c 100644 --- a/src/build.c +++ b/src/build.c @@ -164,8 +164,7 @@ void sqlite3FinishCoding(Parse *pParse){ sqlite3VdbeAddOp0(v, OP_Noop); VdbeComment((v, "TODO: Commit changes")); addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, pReturning->iRetCur); - reg = pParse->nMem+1; - pParse->nMem += pReturning->nRetCol; + reg = pReturning->iRetReg; for(i=0; inRetCol; i++){ sqlite3VdbeAddOp3(v, OP_Column, pReturning->iRetCur, i, reg+i); } diff --git a/src/resolve.c b/src/resolve.c index 5074a28812..84ba82a11c 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -371,7 +371,7 @@ static int lookupName( ** it is a new.* or old.* trigger argument reference. Or ** maybe it is an excluded.* from an upsert. */ - if( zDb==0 && cntTab==0 ){ + if( cntTab==0 && zDb==0 ){ pTab = 0; #ifndef SQLITE_OMIT_TRIGGER if( pParse->pTriggerTab!=0 ){ @@ -434,22 +434,27 @@ static int lookupName( }else #endif /* SQLITE_OMIT_UPSERT */ { -#ifndef SQLITE_OMIT_TRIGGER - if( iCol<0 ){ - pExpr->affExpr = SQLITE_AFF_INTEGER; - }else if( pExpr->iTable==0 ){ - testcase( iCol==31 ); - testcase( iCol==32 ); - pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<y.pTab = pTab; - pExpr->iColumn = (i16)iCol; - eNewExprOp = TK_TRIGGER; + if( iCol<0 ) pExpr->affExpr = SQLITE_AFF_INTEGER; + if( pParse->bReturning ){ + eNewExprOp = TK_REGISTER; + pExpr->iTable = pNC->uNC.iBaseReg + (pTab->nCol+1)*pExpr->iTable + + iCol + 1; + }else{ + pExpr->iColumn = (i16)iCol; + eNewExprOp = TK_TRIGGER; +#ifndef SQLITE_OMIT_TRIGGER + if( pExpr->iTable==0 ){ + testcase( iCol==31 ); + testcase( iCol==32 ); + pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<db->xAuth + && !ExprHasProperty(pExpr, EP_Alias) + && pExpr->op!=TK_REGISTER + ){ sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList); } /* Increment the nRef value on all name contexts from TopNC up to diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 528c908ca6..7b22b6b3b2 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3037,6 +3037,7 @@ struct NameContext { ExprList *pEList; /* Optional list of result-set columns */ AggInfo *pAggInfo; /* Information about aggregates at this level */ Upsert *pUpsert; /* ON CONFLICT clause information from an upsert */ + int iBaseReg; /* For TK_REGISTER when parsing RETURNING */ } uNC; NameContext *pNext; /* Next outer name context. NULL for outermost */ int nRef; /* Number of names resolved by this context */ @@ -3065,6 +3066,7 @@ struct NameContext { #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 */ @@ -3668,6 +3670,7 @@ struct Returning { TriggerStep retTStep; /* The trigger step */ int iRetCur; /* Transient table holding RETURNING results */ int nRetCol; /* Number of in pReturnEL after expansion */ + int iRetReg; /* Register array for holding a row of RETURNING */ }; /* diff --git a/src/trigger.c b/src/trigger.c index fc7e64e51e..5b24ed021b 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -832,6 +832,7 @@ static ExprList *sqlite3ExpandReturning( ExprList *pNew = 0; sqlite3 *db = pParse->db; int i; + for(i=0; inExpr; i++){ Expr *pOldExpr = pList->a[i].pExpr; if( ALWAYS(pOldExpr!=0) && pOldExpr->op==TK_ASTERISK ){ @@ -856,6 +857,15 @@ static ExprList *sqlite3ExpandReturning( } } } + if( !db->mallocFailed ){ + Vdbe *v = pParse->pVdbe; + assert( v!=0 ); + sqlite3VdbeSetNumCols(v, pNew->nExpr); + for(i=0; inExpr; i++){ + sqlite3VdbeSetColName(v, i, COLNAME_NAME, pNew->a[i].zEName, + SQLITE_TRANSIENT); + } + } return pNew; } @@ -868,7 +878,7 @@ static void codeReturningTrigger( Parse *pParse, /* Parse context */ Trigger *pTrigger, /* The trigger step that defines the RETURNING */ Table *pTab, /* The table to code triggers from */ - int reg /* The first in an array of registers */ + int regIn /* The first in an array of registers */ ){ Vdbe *v = pParse->pVdbe; ExprList *pNew; @@ -882,28 +892,32 @@ static void codeReturningTrigger( VdbeComment((v, "RETURNING trigger goes here")); pNew = sqlite3ExpandReturning(pParse, pReturning->pReturnEL, pTab); if( pNew ){ + NameContext sNC; + memset(&sNC, 0, sizeof(sNC)); pReturning->nRetCol = pNew->nExpr; pReturning->iRetCur = pParse->nTab++; - sqlite3ExprListDelete(pParse->db, pNew); - } - -#if 0 - pSelect->pEList = - sqlite3ExpandReturning(pParse, pList, pParse->pTriggerTab); - sqlite3SelectDestInit(&sDest, SRT_Output, 0); - pNew = sqlite3SelectDup(db, pSelect, 0); - if( pNew ){ - sqlite3Select(pParse, pNew, &sDest); - if( pNew->selFlags & (SF_Aggregate|SF_HasAgg|SF_WinRewrite) ){ - sqlite3ErrorMsg(pParse, "aggregates not allowed in RETURNING"); - } - sqlite3SelectDelete(db, pNew); - } - sqlite3ExprListDelete(db, pSelect->pEList); - pStep->pSelect->pEList = pList; - break; + sNC.pParse = pParse; + sNC.uNC.iBaseReg = regIn; + sNC.ncFlags = NC_UBaseReg; + pParse->eTriggerOp = pTrigger->op; + pParse->pTriggerTab = pTab; + if( sqlite3ResolveExprListNames(&sNC, pNew)==SQLITE_OK ){ + int i; + int nCol = pNew->nExpr; + int reg = pParse->nMem+1; + pParse->nMem += nCol+2; + pReturning->iRetReg = reg; + for(i=0; ia[i].pExpr, reg+i); } -#endif + sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, i, reg+i); + sqlite3VdbeAddOp2(v, OP_NewRowid, pReturning->iRetCur, reg+i+1); + sqlite3VdbeAddOp3(v, OP_Insert, pReturning->iRetCur, reg+i, reg+i+1); + } + sqlite3ExprListDelete(pParse->db, pNew); + pParse->eTriggerOp = 0; + pParse->pTriggerTab = 0; + } } From e1db9343d524391e50a8dd69220b3f38c18b1f0f Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 4 Feb 2021 21:17:12 +0000 Subject: [PATCH 175/257] Fix an issue with RETURNING from UPSERT. FossilOrigin-Name: 757b74ba0fd64634a365bd73955181191767ad8816a33a362e32ece250299a51 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/trigger.c | 10 +++++----- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 75c0cabd1e..d0547d1351 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Snapshot.\s\sNew\sdesign\sappears\sto\swork\son\sa\ssimple\stest\scase. -D 2021-02-04T20:52:20.449 +C Fix\san\sissue\swith\sRETURNING\sfrom\sUPSERT. +D 2021-02-04T21:17:12.237 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -607,7 +607,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda -F src/trigger.c 5da6ba6d4067b5dcdd11a6da37ce3cb56586df75a7be685efb534c46d5c773c8 +F src/trigger.c f7c383d955433ecb8b4e1469578e559585b08c846cfeb7c1e9a3fa54d6872c0e F src/update.c 0f5a61f0787199983530a33f6fffe4f52742f35fcdf6ccfad1078b1a8bc17723 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 @@ -1899,7 +1899,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 04b77d63216ce11b4e797946953bcde504fc005807c7a5ac757fbf47d78698dc -R 3969643abefe6509994dc8b8c75efd08 +P 8a65fbeecf3597e30853c5f0ccd9b8b46c508854fa521e58e0db279deebca7d4 +R d02a9b42befb5b25aa3638c6334cc03d U drh -Z b4647d4c6645877bc3632b5ebc38eb6e +Z fef4d4b17488be8894b2080187642bf5 diff --git a/manifest.uuid b/manifest.uuid index 6756c35314..a390300e32 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8a65fbeecf3597e30853c5f0ccd9b8b46c508854fa521e58e0db279deebca7d4 \ No newline at end of file +757b74ba0fd64634a365bd73955181191767ad8816a33a362e32ece250299a51 \ No newline at end of file diff --git a/src/trigger.c b/src/trigger.c index 5b24ed021b..87d507395c 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -857,7 +857,7 @@ static ExprList *sqlite3ExpandReturning( } } } - if( !db->mallocFailed ){ + if( !db->mallocFailed && !pParse->colNamesSet ){ Vdbe *v = pParse->pVdbe; assert( v!=0 ); sqlite3VdbeSetNumCols(v, pNew->nExpr); @@ -888,14 +888,14 @@ static void codeReturningTrigger( assert( pParse->bReturning ); pReturning = pParse->u1.pReturning; assert( pTrigger == &(pReturning->retTrig) ); - sqlite3VdbeAddOp0(v, OP_Noop); - VdbeComment((v, "RETURNING trigger goes here")); pNew = sqlite3ExpandReturning(pParse, pReturning->pReturnEL, pTab); if( pNew ){ NameContext sNC; memset(&sNC, 0, sizeof(sNC)); - pReturning->nRetCol = pNew->nExpr; - pReturning->iRetCur = pParse->nTab++; + if( pReturning->nRetCol==0 ){ + pReturning->nRetCol = pNew->nExpr; + pReturning->iRetCur = pParse->nTab++; + } sNC.pParse = pParse; sNC.uNC.iBaseReg = regIn; sNC.ncFlags = NC_UBaseReg; From 7dec804d4210cf928820693735135f4307fef050 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 4 Feb 2021 22:59:19 +0000 Subject: [PATCH 176/257] Remove dead code. Fix RETURNING for INSERT into a virtual table. FossilOrigin-Name: dbfa38699c87ab4bf390666e411dda8d375c7b53b9b4fb131adacbf575867a72 --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/build.c | 1 - src/insert.c | 5 ----- src/trigger.c | 21 +++++++++++---------- src/vdbe.h | 1 - src/vdbeaux.c | 17 ----------------- src/vtab.c | 2 +- 8 files changed, 24 insertions(+), 47 deletions(-) diff --git a/manifest b/manifest index d0547d1351..a65876b333 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sissue\swith\sRETURNING\sfrom\sUPSERT. -D 2021-02-04T21:17:12.237 +C Remove\sdead\scode.\s\sFix\sRETURNING\sfor\sINSERT\sinto\sa\svirtual\stable. +D 2021-02-04T22:59:19.826 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -485,7 +485,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 694020ad8a3af3d79b09f74c8f1421272a419cdea42a13401e3b0f7dea6e9c3e F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 -F src/build.c 1b8d3d59dcd52c5d74847a56174e6819713012cd370809352375422d0907c8bf +F src/build.c e6f5ed03c843fcb016b085835e40108a8625fb296716d3babb15cd81b8bb8c57 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 @@ -502,7 +502,7 @@ 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 97be36c52c667a64aacbba76398544d224268d62444b67d011a077c486e375bb +F src/insert.c 3d17e465c4cdb7e02e4b2a9d0a6cee08d23c478a01bd7eb5c5d4024fc70c5e5c F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 F src/main.c 1c5de7b3fabcdf05f4fe563aab5d81d175b89c67a8678a12ba86629356afa356 @@ -607,23 +607,23 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda -F src/trigger.c f7c383d955433ecb8b4e1469578e559585b08c846cfeb7c1e9a3fa54d6872c0e +F src/trigger.c a018d5bd5f1d429572fd08ebdf3ca8c1d11891cf73abf6013c3919aec45756c8 F src/update.c 0f5a61f0787199983530a33f6fffe4f52742f35fcdf6ccfad1078b1a8bc17723 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 41c7a72da1df47864faa378a1c720b38adb288c6838cb6be5594511b6287a048 F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286 F src/vdbe.c b3c9a3f9d546d4848a2a8c88a3c40875cd6ba3d248d9b99d01b1eeb38b29c171 -F src/vdbe.h a71bf43572d3de57923d1928ac01ae8d355cd67e94462ba4f7462265cedbef9a +F src/vdbe.h 83603854bfa5851af601fc0947671eb260f4363e62e960e8a994fb9bbcd2aaa1 F src/vdbeInt.h 3df118924e1711f1bbc8e30c46260d0ab6c3b029b32dd411f789111f76434f3c F src/vdbeapi.c 4a43e303ec3354c785f453e881521969378e85628278ab74ba4a9df790c0d93b -F src/vdbeaux.c 34994221fbde303e362cf11c7d97fe9b115055cfdf716260ca0140811de94aab +F src/vdbeaux.c c8e96fb57ee6f7150845325ffb8d7fd4e340ff4f73aa527a6f26a485db8b9955 F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1 F src/vdbemem.c 947f2a65910edb4014dc981d33e414a68c51f169f9df8c4c493a0ba840b6eb1f F src/vdbesort.c f5b5e473a7cee44e47a94817b042fd7172cf3aa2c0a7928a8339d612bcfdec5a F src/vdbetrace.c 666c6fd9f1b62be6999e072a45b913e3c2c3518bc60dfd4d54fe304130acb724 F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c -F src/vtab.c 5f5fc793092f53bbdfde296c50f563fb7bda58cf48e9cf6a8bdfbc5abd409845 +F src/vtab.c 81e1a336ba47eccc5cadb80de15f03afabd83c55ff9648e3a98d8988d4c264aa F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 69e770e96fd56cc21608992bf2c6f1f3dc5cf2572d0495c6a643b06c3a679f14 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a @@ -1899,7 +1899,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 8a65fbeecf3597e30853c5f0ccd9b8b46c508854fa521e58e0db279deebca7d4 -R d02a9b42befb5b25aa3638c6334cc03d +P 757b74ba0fd64634a365bd73955181191767ad8816a33a362e32ece250299a51 +R 88d822e5d89f75ce7408ba510079f31a U drh -Z fef4d4b17488be8894b2080187642bf5 +Z c8bf85f0968e78afc9da5bd08d2fe521 diff --git a/manifest.uuid b/manifest.uuid index a390300e32..8d669b7bff 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -757b74ba0fd64634a365bd73955181191767ad8816a33a362e32ece250299a51 \ No newline at end of file +dbfa38699c87ab4bf390666e411dda8d375c7b53b9b4fb131adacbf575867a72 \ No newline at end of file diff --git a/src/build.c b/src/build.c index a219d2b23c..ce96a71dc9 100644 --- a/src/build.c +++ b/src/build.c @@ -161,7 +161,6 @@ void sqlite3FinishCoding(Parse *pParse){ int i; int reg; - sqlite3VdbeAddOp0(v, OP_Noop); VdbeComment((v, "TODO: Commit changes")); addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, pReturning->iRetCur); reg = pReturning->iRetReg; diff --git a/src/insert.c b/src/insert.c index 2f22121f7d..7522a72697 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1143,11 +1143,6 @@ void sqlite3Insert( sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols); VdbeCoverage(v); } - /* Cannot have triggers on a virtual table. If it were possible, - ** this block would have to account for hidden column. - */ - assert( !IsVirtual(pTab) ); - /* Copy the new data already generated. */ assert( pTab->nNVCol>0 ); sqlite3VdbeAddOp3(v, OP_Copy, regRowid+1, regCols+1, pTab->nNVCol-1); diff --git a/src/trigger.c b/src/trigger.c index 87d507395c..0893f790d3 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -761,16 +761,21 @@ Trigger *sqlite3TriggersExist( ** us what time of trigger it should be. */ assert( sqlite3IsToplevel(pParse) ); p->op = op; - mask |= TRIGGER_AFTER; - if( IsVirtual(pTab) && op!=TK_INSERT ){ - sqlite3ErrorMsg(pParse, - "%s RETURNING is not available on virtual tables", - op==TK_DELETE ? "DELETE" : "UPDATE"); + if( IsVirtual(pTab) ){ + if( op!=TK_INSERT ){ + sqlite3ErrorMsg(pParse, + "%s RETURNING is not available on virtual tables", + op==TK_DELETE ? "DELETE" : "UPDATE"); + } + p->tr_tm = TRIGGER_BEFORE; + }else{ + p->tr_tm = TRIGGER_AFTER; } + mask |= p->tr_tm; }else if( p->bReturning && p->op==TK_INSERT && op==TK_UPDATE && sqlite3IsToplevel(pParse) ){ /* Also fire a RETURNING trigger for an UPSERT */ - mask |= TRIGGER_AFTER; + mask |= p->tr_tm; } p = p->pNext; }while( p ); @@ -1091,7 +1096,6 @@ static TriggerPrg *codeRowTrigger( pSubParse->pToplevel = pTop; pSubParse->zAuthContext = pTrigger->zName; pSubParse->eTriggerOp = pTrigger->op; - pSubParse->bReturning = pTrigger->bReturning; pSubParse->nQueryLoop = pParse->nQueryLoop; pSubParse->disableVtab = pParse->disableVtab; @@ -1141,9 +1145,6 @@ static TriggerPrg *codeRowTrigger( if( db->mallocFailed==0 && pParse->nErr==0 ){ pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg); } - if( pTrigger->bReturning ){ - sqlite3VdbeColumnInfoXfer(sqlite3ParseToplevel(pParse)->pVdbe, v); - } pProgram->nMem = pSubParse->nMem; pProgram->nCsr = pSubParse->nTab; pProgram->token = (void *)pTrigger; diff --git a/src/vdbe.h b/src/vdbe.h index 48be53df7f..17f11fdd77 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -259,7 +259,6 @@ void sqlite3VdbeResetStepResult(Vdbe*); void sqlite3VdbeRewind(Vdbe*); int sqlite3VdbeReset(Vdbe*); void sqlite3VdbeSetNumCols(Vdbe*,int); -void sqlite3VdbeColumnInfoXfer(Vdbe*,Vdbe*); int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*)); void sqlite3VdbeCountChanges(Vdbe*); sqlite3 *sqlite3VdbeDb(Vdbe*); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 1c77b2ce94..7ee4f629e0 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2595,23 +2595,6 @@ void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){ initMemArray(p->aColName, n, db, MEM_Null); } -/* -** Transfer the column count and name information from one Vdbe to -** another. -*/ -void sqlite3VdbeColumnInfoXfer(Vdbe *pTo, Vdbe *pFrom){ - sqlite3 *db = pTo->db; - assert( db==pFrom->db ); - if( pTo->nResColumn ){ - releaseMemArray(pTo->aColName, pTo->nResColumn*COLNAME_N); - sqlite3DbFree(db, pTo->aColName); - } - pTo->aColName = pFrom->aColName; - pFrom->aColName = 0; - pTo->nResColumn = pFrom->nResColumn; - pFrom->nResColumn = 0; -} - /* ** Set the name of the idx'th column to be returned by the SQL statement. ** zName must be a pointer to a nul terminated string. diff --git a/src/vtab.c b/src/vtab.c index b2c01f2fad..400ae40968 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -828,7 +828,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ Table *pNew = sParse.pNewTable; Index *pIdx; pTab->aCol = pNew->aCol; - pTab->nCol = pNew->nCol; + pTab->nNVCol = pTab->nCol = pNew->nCol; pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid); pNew->nCol = 0; pNew->aCol = 0; From 29f6a365ccd09fdf922125f324d13d2cac34d3e4 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 5 Feb 2021 17:34:47 +0000 Subject: [PATCH 177/257] Remove unreachable code. Fix a shift UB problem introduced yesterday and discovered by OSSFuzz. FossilOrigin-Name: 078dbff04a95a001bbd8690ab08038fbb5506899df8290991b53fd1122a4c30c --- manifest | 19 +++++++++---------- manifest.uuid | 2 +- src/auth.c | 7 +++---- src/resolve.c | 5 +---- src/sqliteInt.h | 2 +- src/trigger.c | 2 +- 6 files changed, 16 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 6a7da7c071..8027ff49d7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sRETURNING\salgorithm\sso\sthat\soutputs\saccumulate\sin\san\sephemeral\ntable\suntil\sall\smodifications\shave\sbeen\scompleted,\sand\sonly\sthen\sdo\sresults\nstart\sbeing\sreturned.\s\sThis\sshould\shelp\sprevent\sproblems\swith\sinterleaved\nsqlite3_step()\scalls\son\stwo\sseparate\sDML\sstatements.\s\sIt\salso\sseems\sto\sbe\ncloser\sto\show\sPostgreSQL\sworks,\swhich\smight\sprevent\scompatibility\sproblems. -D 2021-02-04T23:20:13.904 +C Remove\sunreachable\scode.\s\sFix\sa\sshift\sUB\sproblem\sintroduced\syesterday\nand\sdiscovered\sby\sOSSFuzz. +D 2021-02-05T17:34:47.616 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -478,7 +478,7 @@ F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 36cae0d6e3e91a1996e1a472f8c7242c31a4e38ba4295e3056da198c04fd2a87 F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c F src/attach.c e80162a47411f296bea550ed8fafd730481f4aa71e89ece23ba9c957eed15d4a -F src/auth.c 8d1df0e2ef8bafbedd4f1fe4baff03eb27507da4bf6e449df3613d383c4018b2 +F src/auth.c 807c65bbe66806cd0a4b1cf2dbda12023002093b2c572e94a783f48b60e64441 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 @@ -539,14 +539,14 @@ F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf F src/prepare.c f288cbc35f79eb32e162de7e80a63ebe00d80e639dcfac071bee11570cbdb16f F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c 397c3e889fea46fc7aa0bbe98ffd91046b7b44ade2cdab6b2357a4b7ddd10b13 +F src/resolve.c d94f65ad822a8a4ea1eec1d192093855c097c913be617c15de5afea35449bb5e F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 738cb746189f721f59972993c13085fa2975c4cbfd04ba26445f3b42c81237dc F src/shell.c.in 9ebc74e4f05cfbd0f4a36060fdaeff1da4e9af4458358722bc08c5a1ab9a0879 F src/sqlite.h.in 8855a19f37ade8dad189a9e48233a2ebe1b46faf469c7eb0906a654e252dcc57 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h c51a21569e193f377f6d70a2fed0031fd88f141e112a5902cb9e31c1f79f5194 +F src/sqliteInt.h fc56cfde306778a431c133803676fdd1c962ee3e75b5f2483c20fa069cb056e4 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -607,7 +607,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda -F src/trigger.c a018d5bd5f1d429572fd08ebdf3ca8c1d11891cf73abf6013c3919aec45756c8 +F src/trigger.c f5b6d20b53f6ced4ce5f8c5b526a1ab9d0a4d07f680cb6abf5c685eee2e1f9a7 F src/update.c 0f5a61f0787199983530a33f6fffe4f52742f35fcdf6ccfad1078b1a8bc17723 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 @@ -1899,8 +1899,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 5c8e6296aa9f69a092364524b716ba894f113f7f1e6024b9a2eaa01c239e65c1 dbfa38699c87ab4bf390666e411dda8d375c7b53b9b4fb131adacbf575867a72 -R 88d822e5d89f75ce7408ba510079f31a -T +closed dbfa38699c87ab4bf390666e411dda8d375c7b53b9b4fb131adacbf575867a72 +P c4615eb28c3dd2d473daf104f32e60d02799f3158d9d275a899c39129cc71401 +R ff024c949e3f9255ec1e795290e75e4c U drh -Z a2b37659b7969f20723dc948c328e70a +Z 12f6db35869c69dae1575bf57bae19b1 diff --git a/manifest.uuid b/manifest.uuid index abc996f2a3..526131027c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c4615eb28c3dd2d473daf104f32e60d02799f3158d9d275a899c39129cc71401 \ No newline at end of file +078dbff04a95a001bbd8690ab08038fbb5506899df8290991b53fd1122a4c30c \ No newline at end of file diff --git a/src/auth.c b/src/auth.c index 83451c29a9..48b1c42beb 100644 --- a/src/auth.c +++ b/src/auth.c @@ -143,7 +143,6 @@ void sqlite3AuthRead( Schema *pSchema, /* The schema of the expression */ SrcList *pTabList /* All table that pExpr might refer to */ ){ - sqlite3 *db = pParse->db; Table *pTab = 0; /* The table being read */ const char *zCol; /* Name of the column of the table */ int iSrc; /* Index in pTabList->a[] of table being read */ @@ -151,8 +150,8 @@ void sqlite3AuthRead( int iCol; /* Index of column in table */ assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER ); - assert( !IN_RENAME_OBJECT || db->xAuth==0 ); - if( db->xAuth==0 ) return; + assert( !IN_RENAME_OBJECT ); + assert( pParse->db->xAuth!=0 ); iDb = sqlite3SchemaToIndex(pParse->db, pSchema); if( iDb<0 ){ /* An attempt to read a column out of a subquery or other @@ -183,7 +182,7 @@ void sqlite3AuthRead( }else{ zCol = "ROWID"; } - assert( iDb>=0 && iDbnDb ); + assert( iDb>=0 && iDbdb->nDb ); if( SQLITE_IGNORE==sqlite3AuthReadCol(pParse, pTab->zName, zCol, iDb) ){ pExpr->op = TK_NULL; } diff --git a/src/resolve.c b/src/resolve.c index 84ba82a11c..720fdb760a 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -112,7 +112,6 @@ static void resolveAlias( } sqlite3DbFree(db, pDup); } - ExprSetProperty(pExpr, EP_Alias); } @@ -429,7 +428,6 @@ static int lookupName( pExpr->iTable = pNC->uNC.pUpsert->regData + sqlite3TableColumnToStorage(pTab, iCol); eNewExprOp = TK_REGISTER; - ExprSetProperty(pExpr, EP_Alias); } }else #endif /* SQLITE_OMIT_UPSERT */ @@ -636,8 +634,7 @@ lookupname_end: if( cnt==1 ){ assert( pNC!=0 ); if( pParse->db->xAuth - && !ExprHasProperty(pExpr, EP_Alias) - && pExpr->op!=TK_REGISTER + && (pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER) ){ sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7b22b6b3b2..093ce76210 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2762,7 +2762,7 @@ struct Expr { #define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */ #define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */ #define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */ -#define EP_Alias 0x400000 /* Is an alias for a result set column */ + /* 0x400000 // Available */ #define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */ #define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */ #define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */ diff --git a/src/trigger.c b/src/trigger.c index 0893f790d3..4f4bf9a978 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -862,7 +862,7 @@ static ExprList *sqlite3ExpandReturning( } } } - if( !db->mallocFailed && !pParse->colNamesSet ){ + if( !db->mallocFailed ){ Vdbe *v = pParse->pVdbe; assert( v!=0 ); sqlite3VdbeSetNumCols(v, pNew->nExpr); From 8873aea390d47e070171bf7cc081d406d396bdea Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 6 Feb 2021 14:37:36 +0000 Subject: [PATCH 178/257] Fix the OSSFuzz-discovered shift problem from two days ago. This patch was omitted from [078dbff04a95a001] apparently because I made the edit to "sqlite3.c" rather than "resolve.c" where it belongs. FossilOrigin-Name: 864772ffec4e91d8d73f9b97e6e1d7bd4e0537de19d11d30aed7eedd5b7d394a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/resolve.c | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 8027ff49d7..fb1bc22542 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sunreachable\scode.\s\sFix\sa\sshift\sUB\sproblem\sintroduced\syesterday\nand\sdiscovered\sby\sOSSFuzz. -D 2021-02-05T17:34:47.616 +C Fix\sthe\sOSSFuzz-discovered\sshift\sproblem\sfrom\stwo\sdays\sago.\s\sThis\spatch\swas\nomitted\sfrom\s[078dbff04a95a001]\sapparently\sbecause\sI\smade\sthe\sedit\sto\n"sqlite3.c"\srather\sthan\s"resolve.c"\swhere\sit\sbelongs. +D 2021-02-06T14:37:36.326 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -539,7 +539,7 @@ F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf F src/prepare.c f288cbc35f79eb32e162de7e80a63ebe00d80e639dcfac071bee11570cbdb16f F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c d94f65ad822a8a4ea1eec1d192093855c097c913be617c15de5afea35449bb5e +F src/resolve.c d0a77f10614c80e0e4a1127391370ab512d78af32e87f12906673c485d5ff118 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 738cb746189f721f59972993c13085fa2975c4cbfd04ba26445f3b42c81237dc F src/shell.c.in 9ebc74e4f05cfbd0f4a36060fdaeff1da4e9af4458358722bc08c5a1ab9a0879 @@ -1899,7 +1899,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 c4615eb28c3dd2d473daf104f32e60d02799f3158d9d275a899c39129cc71401 -R ff024c949e3f9255ec1e795290e75e4c +P 078dbff04a95a001bbd8690ab08038fbb5506899df8290991b53fd1122a4c30c +R e6748b9d1b630db8f8b3410473bbf7b2 U drh -Z 12f6db35869c69dae1575bf57bae19b1 +Z 80bacc1d0dff416297cd42e4085d2a09 diff --git a/manifest.uuid b/manifest.uuid index 526131027c..aae9390c7c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -078dbff04a95a001bbd8690ab08038fbb5506899df8290991b53fd1122a4c30c \ No newline at end of file +864772ffec4e91d8d73f9b97e6e1d7bd4e0537de19d11d30aed7eedd5b7d394a \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index 720fdb760a..24ec7bb46c 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -433,7 +433,6 @@ static int lookupName( #endif /* SQLITE_OMIT_UPSERT */ { pExpr->y.pTab = pTab; - if( iCol<0 ) pExpr->affExpr = SQLITE_AFF_INTEGER; if( pParse->bReturning ){ eNewExprOp = TK_REGISTER; pExpr->iTable = pNC->uNC.iBaseReg + (pTab->nCol+1)*pExpr->iTable @@ -442,7 +441,9 @@ static int lookupName( pExpr->iColumn = (i16)iCol; eNewExprOp = TK_TRIGGER; #ifndef SQLITE_OMIT_TRIGGER - if( pExpr->iTable==0 ){ + if( iCol<0 ){ + pExpr->affExpr = SQLITE_AFF_INTEGER; + }else if( pExpr->iTable==0 ){ testcase( iCol==31 ); testcase( iCol==32 ); pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)< Date: Sat, 6 Feb 2021 14:56:30 +0000 Subject: [PATCH 179/257] Remove an ALWAYS() and NEVER() in the authorizer that become reachable as of [078dbff04a95a001]. Test case for coverage in TH3. FossilOrigin-Name: b469327e2949352325d3db815bd4782f9734239c378f08afd2f00ffa54bef924 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/auth.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index fb1bc22542..8f740e87d1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sOSSFuzz-discovered\sshift\sproblem\sfrom\stwo\sdays\sago.\s\sThis\spatch\swas\nomitted\sfrom\s[078dbff04a95a001]\sapparently\sbecause\sI\smade\sthe\sedit\sto\n"sqlite3.c"\srather\sthan\s"resolve.c"\swhere\sit\sbelongs. -D 2021-02-06T14:37:36.326 +C Remove\san\sALWAYS()\sand\sNEVER()\sin\sthe\sauthorizer\sthat\sbecome\sreachable\nas\sof\s[078dbff04a95a001].\s\sTest\scase\sfor\scoverage\sin\sTH3. +D 2021-02-06T14:56:30.179 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -478,7 +478,7 @@ F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 36cae0d6e3e91a1996e1a472f8c7242c31a4e38ba4295e3056da198c04fd2a87 F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c F src/attach.c e80162a47411f296bea550ed8fafd730481f4aa71e89ece23ba9c957eed15d4a -F src/auth.c 807c65bbe66806cd0a4b1cf2dbda12023002093b2c572e94a783f48b60e64441 +F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 @@ -1899,7 +1899,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 078dbff04a95a001bbd8690ab08038fbb5506899df8290991b53fd1122a4c30c -R e6748b9d1b630db8f8b3410473bbf7b2 +P 864772ffec4e91d8d73f9b97e6e1d7bd4e0537de19d11d30aed7eedd5b7d394a +R b1f31e46f151931adb314ae288cc333a U drh -Z 80bacc1d0dff416297cd42e4085d2a09 +Z 9c38539633f74e19146c1878e4331de3 diff --git a/manifest.uuid b/manifest.uuid index aae9390c7c..556d728f41 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -864772ffec4e91d8d73f9b97e6e1d7bd4e0537de19d11d30aed7eedd5b7d394a \ No newline at end of file +b469327e2949352325d3db815bd4782f9734239c378f08afd2f00ffa54bef924 \ No newline at end of file diff --git a/src/auth.c b/src/auth.c index 48b1c42beb..33420f5839 100644 --- a/src/auth.c +++ b/src/auth.c @@ -163,7 +163,7 @@ void sqlite3AuthRead( pTab = pParse->pTriggerTab; }else{ assert( pTabList ); - for(iSrc=0; ALWAYS(iSrcnSrc); iSrc++){ + for(iSrc=0; iSrcnSrc; iSrc++){ if( pExpr->iTable==pTabList->a[iSrc].iCursor ){ pTab = pTabList->a[iSrc].pTab; break; @@ -171,7 +171,7 @@ void sqlite3AuthRead( } } iCol = pExpr->iColumn; - if( NEVER(pTab==0) ) return; + if( pTab==0 ) return; if( iCol>=0 ){ assert( iColnCol ); From 8729642112076f1103837ed02b23db8424c0bdef Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 7 Feb 2021 12:59:43 +0000 Subject: [PATCH 180/257] Fix harmless compiler warnings. FossilOrigin-Name: 5f8bf99579e6663fc701cdc94f685584a86398c4687e25e7e241de755398f17d --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/trigger.c | 3 ++- src/whereexpr.c | 4 +++- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 8f740e87d1..f93eb07911 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sALWAYS()\sand\sNEVER()\sin\sthe\sauthorizer\sthat\sbecome\sreachable\nas\sof\s[078dbff04a95a001].\s\sTest\scase\sfor\scoverage\sin\sTH3. -D 2021-02-06T14:56:30.179 +C Fix\sharmless\scompiler\swarnings. +D 2021-02-07T12:59:43.373 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -607,7 +607,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda -F src/trigger.c f5b6d20b53f6ced4ce5f8c5b526a1ab9d0a4d07f680cb6abf5c685eee2e1f9a7 +F src/trigger.c 983c7c8464c46840dac1ffe0461a6c447ac12c965746975c108eb5f4283e8801 F src/update.c 0f5a61f0787199983530a33f6fffe4f52742f35fcdf6ccfad1078b1a8bc17723 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 @@ -631,7 +631,7 @@ F src/walker.c d9c4e454ebb9499e908aa62d55b8994c375cf5355ac78f60d45af17f7890701c F src/where.c 6efc4a10bfe0ec908c4f3c9112afb7675c952204b4b0b255672f488860141fec F src/whereInt.h ae03b5e3a4cca9bd9cb1b7d3c63faf8f1f177200fc8cecc87d3d0cab6ca338e6 F src/wherecode.c 43a63441f8662ddf86b15975683a502ec33f08167e9636f4d19e38e265e95fd9 -F src/whereexpr.c a182038cf7d10aa9a95a96b8563a34f34990323cf307dee6559e995961966d43 +F src/whereexpr.c f7b5469e83db3c3b9eb14e4ba44559a2e125523761d12e5ac8d8fb88301af393 F src/window.c edd6f5e25a1e8f2b6f5305b7f5f7da7bb35f07f0d432b255b1d4c2fcab4205aa F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -1899,7 +1899,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 864772ffec4e91d8d73f9b97e6e1d7bd4e0537de19d11d30aed7eedd5b7d394a -R b1f31e46f151931adb314ae288cc333a +P b469327e2949352325d3db815bd4782f9734239c378f08afd2f00ffa54bef924 +R e1ce577f863fec71881e8440ed5dbc05 U drh -Z 9c38539633f74e19146c1878e4331de3 +Z 17b4317a1f1bb914fafc7a0f7a28c210 diff --git a/manifest.uuid b/manifest.uuid index 556d728f41..66158c1636 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b469327e2949352325d3db815bd4782f9734239c378f08afd2f00ffa54bef924 \ No newline at end of file +5f8bf99579e6663fc701cdc94f685584a86398c4687e25e7e241de755398f17d \ No newline at end of file diff --git a/src/trigger.c b/src/trigger.c index 4f4bf9a978..1d4c2790c3 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -843,8 +843,9 @@ static ExprList *sqlite3ExpandReturning( if( ALWAYS(pOldExpr!=0) && pOldExpr->op==TK_ASTERISK ){ int jj; for(jj=0; jjnCol; jj++){ + Expr *pNewExpr; if( IsHiddenColumn(pTab->aCol+jj) ) continue; - Expr *pNewExpr = sqlite3Expr(db, TK_ID, pTab->aCol[jj].zName); + pNewExpr = sqlite3Expr(db, TK_ID, pTab->aCol[jj].zName); pNew = sqlite3ExprListAppend(pParse, pNew, pNewExpr); if( !db->mallocFailed ){ struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1]; diff --git a/src/whereexpr.c b/src/whereexpr.c index f69210975c..1c8987d847 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1028,7 +1028,9 @@ static int exprUsesSrclistCb(Walker *p, Expr *pExpr){ /* ** Select callback for exprUsesSrclist(). */ -static int exprUsesSrclistSelectCb(Walker *p, Select *pSelect){ +static int exprUsesSrclistSelectCb(Walker *NotUsed1, Select *NotUsed2){ + UNUSED_PARAMETER(NotUsed1); + UNUSED_PARAMETER(NotUsed2); return WRC_Abort; } From e1c9a4ebf9c234942ccf6f2f23731b9c89a71895 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 7 Feb 2021 23:28:20 +0000 Subject: [PATCH 181/257] Do not allow RETURNING in the DML statements of a trigger. FossilOrigin-Name: 7a8fe6463a9728bc4e34465688a059afb74f3c373cde8fdf570d5d148fdde04d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 8 ++++++-- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index f93eb07911..5c9f07663b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings. -D 2021-02-07T12:59:43.373 +C Do\snot\sallow\sRETURNING\sin\sthe\sDML\sstatements\sof\sa\strigger. +D 2021-02-07T23:28:20.174 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -485,7 +485,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 694020ad8a3af3d79b09f74c8f1421272a419cdea42a13401e3b0f7dea6e9c3e F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 -F src/build.c e6f5ed03c843fcb016b085835e40108a8625fb296716d3babb15cd81b8bb8c57 +F src/build.c 1bae5588bfdf21bdf41e634f0a053d633fb1ae3a2896117b4eea76412b76c2e0 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 @@ -1899,7 +1899,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 b469327e2949352325d3db815bd4782f9734239c378f08afd2f00ffa54bef924 -R e1ce577f863fec71881e8440ed5dbc05 +P 5f8bf99579e6663fc701cdc94f685584a86398c4687e25e7e241de755398f17d +R a856103465991ee8605c1021fc58e7ff U drh -Z 17b4317a1f1bb914fafc7a0f7a28c210 +Z ce7bda39131bfdba5d6961a4ae1bd760 diff --git a/manifest.uuid b/manifest.uuid index 66158c1636..8f82f8d4bd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5f8bf99579e6663fc701cdc94f685584a86398c4687e25e7e241de755398f17d \ No newline at end of file +7a8fe6463a9728bc4e34465688a059afb74f3c373cde8fdf570d5d148fdde04d \ No newline at end of file diff --git a/src/build.c b/src/build.c index ce96a71dc9..f5c796fac3 100644 --- a/src/build.c +++ b/src/build.c @@ -1306,7 +1306,11 @@ void sqlite3AddReturning(Parse *pParse, ExprList *pList){ Returning *pRet; Hash *pHash; sqlite3 *db = pParse->db; - assert( !pParse->bReturning ); + if( pParse->pNewTrigger ){ + sqlite3ErrorMsg(pParse, "cannot use RETURNING in a trigger"); + }else{ + assert( pParse->bReturning==0 ); + } pParse->bReturning = 1; pRet = sqlite3DbMallocZero(db, sizeof(*pRet)); if( pRet==0 ){ @@ -1329,7 +1333,7 @@ void sqlite3AddReturning(Parse *pParse, ExprList *pList){ pRet->retTStep.pTrig = &pRet->retTrig; pRet->retTStep.pExprList = pList; pHash = &(db->aDb[1].pSchema->trigHash); - assert( sqlite3HashFind(pHash, RETURNING_TRIGGER_NAME)==0 ); + assert( sqlite3HashFind(pHash, RETURNING_TRIGGER_NAME)==0 || pParse->nErr ); if( sqlite3HashInsert(pHash, RETURNING_TRIGGER_NAME, &pRet->retTrig) ==&pRet->retTrig ){ sqlite3OomFault(db); From d5101972763c64fce051b477ef046b2476f18392 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 8 Feb 2021 13:41:17 +0000 Subject: [PATCH 182/257] Improved name resolution for references to a table begin modified from within a subquery in the RETURNING clause. FossilOrigin-Name: 799d205bfa7945ee4a92dfec5fbf90a00b9a535e3171aab2ec46404f7efb0f78 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/resolve.c | 16 +++++++++++----- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 5c9f07663b..906f43411a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sallow\sRETURNING\sin\sthe\sDML\sstatements\sof\sa\strigger. -D 2021-02-07T23:28:20.174 +C Improved\sname\sresolution\sfor\sreferences\sto\sa\stable\sbegin\smodified\sfrom\nwithin\sa\ssubquery\sin\sthe\sRETURNING\sclause. +D 2021-02-08T13:41:17.019 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -539,7 +539,7 @@ F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf F src/prepare.c f288cbc35f79eb32e162de7e80a63ebe00d80e639dcfac071bee11570cbdb16f F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c d0a77f10614c80e0e4a1127391370ab512d78af32e87f12906673c485d5ff118 +F src/resolve.c 3d77986c0b3b4254c6480844ecc21466251dedeb9dafe1c914581ef6e6683c76 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 738cb746189f721f59972993c13085fa2975c4cbfd04ba26445f3b42c81237dc F src/shell.c.in 9ebc74e4f05cfbd0f4a36060fdaeff1da4e9af4458358722bc08c5a1ab9a0879 @@ -1899,7 +1899,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 5f8bf99579e6663fc701cdc94f685584a86398c4687e25e7e241de755398f17d -R a856103465991ee8605c1021fc58e7ff +P 7a8fe6463a9728bc4e34465688a059afb74f3c373cde8fdf570d5d148fdde04d +R 961443c7bac5377cba010ae78e1611b5 U drh -Z ce7bda39131bfdba5d6961a4ae1bd760 +Z d9624b59094cb9e104494bd0199a6b01 diff --git a/manifest.uuid b/manifest.uuid index 8f82f8d4bd..cb3269e118 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7a8fe6463a9728bc4e34465688a059afb74f3c373cde8fdf570d5d148fdde04d \ No newline at end of file +799d205bfa7945ee4a92dfec5fbf90a00b9a535e3171aab2ec46404f7efb0f78 \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index 24ec7bb46c..8642dffac9 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -368,9 +368,10 @@ static int lookupName( #if !defined(SQLITE_OMIT_TRIGGER) || !defined(SQLITE_OMIT_UPSERT) /* If we have not already resolved the name, then maybe ** it is a new.* or old.* trigger argument reference. Or - ** maybe it is an excluded.* from an upsert. + ** maybe it is an excluded.* from an upsert. Or maybe it is + ** a reference in the RETURNING clause to a table being modified. */ - if( cntTab==0 && zDb==0 ){ + if( cnt==0 && zDb==0 ){ pTab = 0; #ifndef SQLITE_OMIT_TRIGGER if( pParse->pTriggerTab!=0 ){ @@ -389,7 +390,7 @@ static int lookupName( } #endif /* SQLITE_OMIT_TRIGGER */ #ifndef SQLITE_OMIT_UPSERT - if( (pNC->ncFlags & NC_UUpsert)!=0 && ALWAYS(zTab) ){ + if( (pNC->ncFlags & NC_UUpsert)!=0 && zTab!=0 ){ Upsert *pUpsert = pNC->uNC.pUpsert; if( pUpsert && sqlite3StrICmp("excluded",zTab)==0 ){ pTab = pUpsert->pUpsertSrc->a[0].pTab; @@ -434,8 +435,13 @@ static int lookupName( { pExpr->y.pTab = pTab; if( pParse->bReturning ){ + NameContext *pUp = pNC; + while( (pUp->ncFlags & NC_UBaseReg)==0 && ALWAYS(pUp->pNext) ){ + pUp = pUp->pNext; + } + assert( pUp->ncFlags & NC_UBaseReg ); eNewExprOp = TK_REGISTER; - pExpr->iTable = pNC->uNC.iBaseReg + (pTab->nCol+1)*pExpr->iTable + pExpr->iTable = pUp->uNC.iBaseReg + (pTab->nCol+1)*pExpr->iTable + iCol + 1; }else{ pExpr->iColumn = (i16)iCol; @@ -1648,7 +1654,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ ** Minor point: If this is the case, then the expression will be ** re-evaluated for each reference to it. */ - assert( (sNC.ncFlags & (NC_UAggInfo|NC_UUpsert))==0 ); + assert( (sNC.ncFlags & (NC_UAggInfo|NC_UUpsert|NC_UBaseReg))==0 ); sNC.uNC.pEList = p->pEList; sNC.ncFlags |= NC_UEList; if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort; From 82ab4f6b1a68147d63b7887873a96ebf33082040 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 8 Feb 2021 15:56:01 +0000 Subject: [PATCH 183/257] Correctly detect correlated subqueries when resolving names in RETURNING clauses. FossilOrigin-Name: b43cfa04922a401442b9d1708e3e4a88d3cfa2c591f9a6b253d99ba83f4b280a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/resolve.c | 11 +++-------- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 906f43411a..c6adae91d0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\sname\sresolution\sfor\sreferences\sto\sa\stable\sbegin\smodified\sfrom\nwithin\sa\ssubquery\sin\sthe\sRETURNING\sclause. -D 2021-02-08T13:41:17.019 +C Correctly\sdetect\scorrelated\ssubqueries\swhen\sresolving\snames\sin\sRETURNING\nclauses. +D 2021-02-08T15:56:01.736 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -539,7 +539,7 @@ F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf F src/prepare.c f288cbc35f79eb32e162de7e80a63ebe00d80e639dcfac071bee11570cbdb16f F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c 3d77986c0b3b4254c6480844ecc21466251dedeb9dafe1c914581ef6e6683c76 +F src/resolve.c 89e4faf6171e179edf279905e8e45c4f9dd108777dc60716396729fbd7cb045e F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 738cb746189f721f59972993c13085fa2975c4cbfd04ba26445f3b42c81237dc F src/shell.c.in 9ebc74e4f05cfbd0f4a36060fdaeff1da4e9af4458358722bc08c5a1ab9a0879 @@ -1899,7 +1899,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 7a8fe6463a9728bc4e34465688a059afb74f3c373cde8fdf570d5d148fdde04d -R 961443c7bac5377cba010ae78e1611b5 +P 799d205bfa7945ee4a92dfec5fbf90a00b9a535e3171aab2ec46404f7efb0f78 +R 678a6afb8f9086ca3bbf2ce851a61869 U drh -Z d9624b59094cb9e104494bd0199a6b01 +Z 31510d8bd4a0645324a2097023f1e72e diff --git a/manifest.uuid b/manifest.uuid index cb3269e118..9aefd705d4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -799d205bfa7945ee4a92dfec5fbf90a00b9a535e3171aab2ec46404f7efb0f78 \ No newline at end of file +b43cfa04922a401442b9d1708e3e4a88d3cfa2c591f9a6b253d99ba83f4b280a \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index 8642dffac9..57ba75f30e 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -383,7 +383,7 @@ static int lookupName( }else if( op!=TK_INSERT && zTab && sqlite3StrICmp("old",zTab)==0 ){ pExpr->iTable = 0; pTab = pParse->pTriggerTab; - }else if( pParse->bReturning ){ + }else if( pParse->bReturning && (pNC->ncFlags & NC_UBaseReg)!=0 ){ pExpr->iTable = op!=TK_DELETE; pTab = pParse->pTriggerTab; } @@ -435,14 +435,9 @@ static int lookupName( { pExpr->y.pTab = pTab; if( pParse->bReturning ){ - NameContext *pUp = pNC; - while( (pUp->ncFlags & NC_UBaseReg)==0 && ALWAYS(pUp->pNext) ){ - pUp = pUp->pNext; - } - assert( pUp->ncFlags & NC_UBaseReg ); eNewExprOp = TK_REGISTER; - pExpr->iTable = pUp->uNC.iBaseReg + (pTab->nCol+1)*pExpr->iTable - + iCol + 1; + pExpr->iTable = pNC->uNC.iBaseReg + (pTab->nCol+1)*pExpr->iTable + + iCol + 1; }else{ pExpr->iColumn = (i16)iCol; eNewExprOp = TK_TRIGGER; From 8737d46ea153e51192e93be9a1fc75cf47cfe16f Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 10 Feb 2021 17:31:50 +0000 Subject: [PATCH 184/257] In RBU, avoid passing VFS xShmLock calls through to the underlying VFS in cases where xShmMap calls may not be. This fixes a bad interaction with ZipVFS. FossilOrigin-Name: bd1e9e0a4c0e07901ef59fe3b7e6f7b9cc66ccfcd5192f576e1620820891de99 --- ext/rbu/sqlite3rbu.c | 13 ++++++++----- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 12a0a46603..a402174461 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -4828,11 +4828,14 @@ static int rbuVfsShmLock(sqlite3_file *pFile, int ofst, int n, int flags){ #endif assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) ); - if( pRbu && (pRbu->eStage==RBU_STAGE_OAL || pRbu->eStage==RBU_STAGE_MOVE) ){ - /* Magic number 1 is the WAL_CKPT_LOCK lock. Preventing SQLite from - ** taking this lock also prevents any checkpoints from occurring. - ** todo: really, it's not clear why this might occur, as - ** wal_autocheckpoint ought to be turned off. */ + if( pRbu && ( + pRbu->eStage==RBU_STAGE_OAL + || pRbu->eStage==RBU_STAGE_MOVE + || pRbu->eStage==RBU_STAGE_DONE + )){ + /* Prevent SQLite from taking a shm-lock on the target file when it + ** is supplying heap memory to the upper layer in place of *-shm + ** segments. */ if( ofst==WAL_LOCK_CKPT && n==1 ) rc = SQLITE_BUSY; }else{ int bCapture = 0; diff --git a/manifest b/manifest index c6adae91d0..0ea0396e02 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Correctly\sdetect\scorrelated\ssubqueries\swhen\sresolving\snames\sin\sRETURNING\nclauses. -D 2021-02-08T15:56:01.736 +C In\sRBU,\savoid\spassing\sVFS\sxShmLock\scalls\sthrough\sto\sthe\sunderlying\sVFS\sin\scases\swhere\sxShmMap\scalls\smay\snot\sbe.\sThis\sfixes\sa\sbad\sinteraction\swith\sZipVFS. +D 2021-02-10T17:31:50.767 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -379,7 +379,7 @@ F ext/rbu/rbuvacuum.test 55e101e90168c2b31df6c9638fe73dc7f7cc666b6142266d1563697 F ext/rbu/rbuvacuum2.test b8e5b51dc8b2c0153373d024c0936be3f66f9234acbd6d0baab0869d56b14e6b F ext/rbu/rbuvacuum3.test 8addd82e4b83b4c93fa47428eae4fd0dbf410f8512c186f38e348feb49ba03dc F ext/rbu/rbuvacuum4.test a78898e438a44803eb2bc897ba3323373c9f277418e2d6d76e90f2f1dbccfd10 -F ext/rbu/sqlite3rbu.c 05c457c27e9340c944f34e850871a915a6b5ee1d823f7a0bb2b482ac6b1e1464 +F ext/rbu/sqlite3rbu.c faf05a0eb4a7ca08781c6df818387657df7a77f4b1b52dbcad920594a7ac978e F ext/rbu/sqlite3rbu.h 1dc88ab7bd32d0f15890ea08d23476c4198d3da3056985403991f8c9cd389812 F ext/rbu/test_rbu.c 03f6f177096a5f822d68d8e4069ad8907fe572c62ff2d19b141f59742821828a F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15 @@ -1899,7 +1899,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 799d205bfa7945ee4a92dfec5fbf90a00b9a535e3171aab2ec46404f7efb0f78 -R 678a6afb8f9086ca3bbf2ce851a61869 -U drh -Z 31510d8bd4a0645324a2097023f1e72e +P b43cfa04922a401442b9d1708e3e4a88d3cfa2c591f9a6b253d99ba83f4b280a +R a6fc5ec0146d48de2a325dbfaebfd9dc +U dan +Z 6adabe12ed5563ac984baebbb7742b7f diff --git a/manifest.uuid b/manifest.uuid index 9aefd705d4..9ab1cf3ad2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b43cfa04922a401442b9d1708e3e4a88d3cfa2c591f9a6b253d99ba83f4b280a \ No newline at end of file +bd1e9e0a4c0e07901ef59fe3b7e6f7b9cc66ccfcd5192f576e1620820891de99 \ No newline at end of file From 513c9a1ff3600b5be3b2fcbb6081c8f88293b7fe Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 10 Feb 2021 19:40:47 +0000 Subject: [PATCH 185/257] Fix a longstanding problem causing an RBU vacuum to omit releasing some locks before finishing. FossilOrigin-Name: cb5bdf82fe0f90922dc34202be9d0aa34d899afff4200456623765da2877ca41 --- ext/rbu/sqlite3rbu.c | 3 +-- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os_unix.c | 1 + 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index a402174461..c5f809848d 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -4842,11 +4842,10 @@ static int rbuVfsShmLock(sqlite3_file *pFile, int ofst, int n, int flags){ if( pRbu && pRbu->eStage==RBU_STAGE_CAPTURE ){ bCapture = 1; } - if( bCapture==0 || 0==(flags & SQLITE_SHM_UNLOCK) ){ rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags); if( bCapture && rc==SQLITE_OK ){ - pRbu->mLock |= (1 << ofst); + pRbu->mLock |= ((1<pShmNode; + assert( p->exclMask==0 && p->sharedMask==0 ); assert( pShmNode==pDbFd->pInode->pShmNode ); assert( pShmNode->pInode==pDbFd->pInode ); From b9edded0fdaf7f0359b33cba5d993b4392e27875 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 10 Feb 2021 19:49:35 +0000 Subject: [PATCH 186/257] Remove an assert() added by the previous commit that is sometimes false. FossilOrigin-Name: fb36ac4dc60ccc6c5fba3f23e13fcab985f27ebef0527c929806cda5f9d3660c --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 5bede417d1..c7125d8713 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\slongstanding\sproblem\scausing\san\sRBU\svacuum\sto\somit\sreleasing\ssome\slocks\sbefore\sfinishing. -D 2021-02-10T19:40:47.797 +C Remove\san\sassert()\sadded\sby\sthe\sprevious\scommit\sthat\sis\ssometimes\sfalse. +D 2021-02-10T19:49:35.745 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -525,7 +525,7 @@ F src/os.c 2d6e646370b1aa78942c68d7edf124e518963adf4a90bce87f365a5a5495529a F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 -F src/os_unix.c 0e712a25b35921fa8b8bbda141c70ba2bde3871dd43d0efe79107327c9058589 +F src/os_unix.c adbbcea4c63d3b400d405f60a5da4c01433753ec4a12e2dc695beb2bbd671fe9 F src/os_win.c 77d39873836f1831a9b0b91894fec45ab0e9ca8e067dc8c549e1d1eca1566fe9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c c49952ac5e9cc536778eff528091d79d38b3e45cbeeed4695dc05e207dc6547d @@ -1899,7 +1899,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 bd1e9e0a4c0e07901ef59fe3b7e6f7b9cc66ccfcd5192f576e1620820891de99 -R 2559369e2b744524005199c4dee97027 +P cb5bdf82fe0f90922dc34202be9d0aa34d899afff4200456623765da2877ca41 +R f4fc3fdf82de1da25700d7b06c4d78f5 U dan -Z 5291d693cac6649082a01a89198a422f +Z a1b0598c229f8a1f298b7df3e89aeb78 diff --git a/manifest.uuid b/manifest.uuid index 1b88ab91e2..8aeb0855ce 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cb5bdf82fe0f90922dc34202be9d0aa34d899afff4200456623765da2877ca41 \ No newline at end of file +fb36ac4dc60ccc6c5fba3f23e13fcab985f27ebef0527c929806cda5f9d3660c \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 7156b2aeac..a688ed2706 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -5022,7 +5022,6 @@ static int unixShmUnmap( if( p==0 ) return SQLITE_OK; pShmNode = p->pShmNode; - assert( p->exclMask==0 && p->sharedMask==0 ); assert( pShmNode==pDbFd->pInode->pShmNode ); assert( pShmNode->pInode==pDbFd->pInode ); From 23ed8109b67b55db4b30ed7e82ede7e676582884 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 12 Feb 2021 11:37:13 +0000 Subject: [PATCH 187/257] Ensure RBU tests are run as part of release testing. FossilOrigin-Name: a18dc08bafefd849e640086b18c41e06361d2e09d7dd2e9af4a394dc543e598b --- manifest | 13 ++++++------- manifest.uuid | 2 +- test/releasetest_data.tcl | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index b1b2a3bcbd..b7380e82b2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\slongstanding\sproblem\scausing\san\sRBU\svacuum\sto\somit\sreleasing\ssome\slocks\sbefore\sfinishing. -D 2021-02-10T20:00:40.512 +C Ensure\sRBU\stests\sare\srun\sas\spart\sof\srelease\stesting. +D 2021-02-12T11:37:13.786 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1283,7 +1283,7 @@ F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8 F test/regexp2.test 40e894223b3d6672655481493f1be12012f2b33c F test/reindex.test cd9d6021729910ece82267b4f5e1b5ac2911a7566c43b43c176a6a4732e2118d F test/releasetest.tcl fb76d8fcc95ac29d6356cd9e52b726ab9e43a24082897618dfbcb7c2b0049153 x -F test/releasetest_data.tcl b9cb30360759b80d92d4ea86b84ebfd8035b97f9078a482deb3cf9d0b2442655 +F test/releasetest_data.tcl 756514dabf6d19531a173a07853426543a2f3a6026863c1b5ef00cbcbd86ff30 F test/resetdb.test 8062cf10a09d8c048f8de7711e94571c38b38168db0e5877ba7561789e5eeb2b F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb F test/returning1.test 684e1c73d961422a7376c932fcdd6dacf02bad21d12f749cfe8c19991ef379f6 @@ -1899,8 +1899,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 bd1e9e0a4c0e07901ef59fe3b7e6f7b9cc66ccfcd5192f576e1620820891de99 fb36ac4dc60ccc6c5fba3f23e13fcab985f27ebef0527c929806cda5f9d3660c -R f4fc3fdf82de1da25700d7b06c4d78f5 -T +closed fb36ac4dc60ccc6c5fba3f23e13fcab985f27ebef0527c929806cda5f9d3660c +P 66c07a07b21e46529780eec3c82a84c494d586f8b7ed80b78d358e23b80458c7 +R 9b461eb226a7d68884e4035e774a75a3 U dan -Z e97f611a0a7197a91080c2d49e7edf82 +Z d41690f6a24f168371741e4cbc675a70 diff --git a/manifest.uuid b/manifest.uuid index 8ca0b46774..69cc053376 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -66c07a07b21e46529780eec3c82a84c494d586f8b7ed80b78d358e23b80458c7 \ No newline at end of file +a18dc08bafefd849e640086b18c41e06361d2e09d7dd2e9af4a394dc543e598b \ No newline at end of file diff --git a/test/releasetest_data.tcl b/test/releasetest_data.tcl index 9692cf47fc..921ca29fad 100644 --- a/test/releasetest_data.tcl +++ b/test/releasetest_data.tcl @@ -289,7 +289,7 @@ if {$tcl_platform(os)=="Darwin"} { array set ::Platforms [strip_comments { Linux-x86_64 { "Check-Symbols*" checksymbols - "Fast-One" "fuzztest test" + "Fast-One" "QUICKTEST_INCLUDE=rbu.test fuzztest test" "Debug-One" "mptest test" "Debug-Two" "test" "Have-Not" test From 8b7e93adbce69298fb80c69dbeae5db167f5d7a9 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 12 Feb 2021 21:22:01 +0000 Subject: [PATCH 188/257] Fix a test case to account for the fact that different versions of OpenBSD behave differently when a program tries to read() from a file-descriptor open on a directory. FossilOrigin-Name: ecd712032f56a20d7df2bcf89b0d3b8d91dc72c552e27f0a4b23980bd49747b0 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/backup2.test | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index b7380e82b2..40173b5a69 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sRBU\stests\sare\srun\sas\spart\sof\srelease\stesting. -D 2021-02-12T11:37:13.786 +C Fix\sa\stest\scase\sto\saccount\sfor\sthe\sfact\sthat\sdifferent\sversions\sof\sOpenBSD\sbehave\sdifferently\swhen\sa\sprogram\stries\sto\sread()\sfrom\sa\sfile-descriptor\sopen\son\sa\sdirectory. +D 2021-02-12T21:22:01.411 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -697,7 +697,7 @@ F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4 F test/avtrans.test b7dc25459ecbd86c6fa9c606ee3068f59d81e225118617dcf2bbb6ded2ade89e F test/backcompat.test 3e64cedda754c778ef6bbe417b6e7a295e662a4d F test/backup.test dd4a5ff756e3df3931dacb1791db0584d4bad989 -F test/backup2.test 1fd1ad8c5b3d2d5b9c0cce4143a4fc610d51ddc6ae16a7a122973d43e6b50bbd +F test/backup2.test f52e3b87f39d1b826d4f622eafe5d30260ae5bdb05764843ff7c83057b05ed49 F test/backup4.test 8f6fd48e0dfde77b9a3bb26dc471ede3e101df32 F test/backup5.test ee5da6d7fe5082f5b9b0bbfa31d016f52412a2e4 F test/backup_ioerr.test 4c3c7147cee85b024ecf6e150e090c32fdbb5135 @@ -1899,7 +1899,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 66c07a07b21e46529780eec3c82a84c494d586f8b7ed80b78d358e23b80458c7 -R 9b461eb226a7d68884e4035e774a75a3 +P a18dc08bafefd849e640086b18c41e06361d2e09d7dd2e9af4a394dc543e598b +R 75ef21488d6a3f284e4e31927f38030c U dan -Z d41690f6a24f168371741e4cbc675a70 +Z 408da0e65feec11d579f305d93e52369 diff --git a/manifest.uuid b/manifest.uuid index 69cc053376..56987518bf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a18dc08bafefd849e640086b18c41e06361d2e09d7dd2e9af4a394dc543e598b \ No newline at end of file +ecd712032f56a20d7df2bcf89b0d3b8d91dc72c552e27f0a4b23980bd49747b0 \ No newline at end of file diff --git a/test/backup2.test b/test/backup2.test index b58c6a3cd3..8b9cb8731a 100644 --- a/test/backup2.test +++ b/test/backup2.test @@ -144,7 +144,7 @@ do_test backup2-9 { if {$tcl_platform(platform)=="windows"} { set msg {cannot open source database: unable to open database file} } elseif {[string match *BSD $tcl_platform(os)]} { - set msg {restore failed: file is not a database} + set msg {} } else { set msg {cannot open source database: disk I/O error} } @@ -152,7 +152,8 @@ do_test backup2-10 { forcedelete bu3.db file mkdir bu3.db set rc [catch {db restore temp bu3.db} res] - lappend rc $res + if {0==[string match *BSD $tcl_platform(os)]} { lappend rc $res } + set rc } [list 1 $msg] # Try to restore from something that is not a database file. From e8f1490f555ad3c1033fe6ec822394d125312f46 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 13 Feb 2021 14:26:25 +0000 Subject: [PATCH 189/257] Fix a problem in the unreleased union-all flattening code. FossilOrigin-Name: e4f8a79fd8b3be9bf8add5f5e1c66bc2fe78da4e50ea500ab0b8370d30e31ba5 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 3 ++- test/unionall.test | 29 +++++++++++++++++++++++++++++ 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 40173b5a69..3be9abba78 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stest\scase\sto\saccount\sfor\sthe\sfact\sthat\sdifferent\sversions\sof\sOpenBSD\sbehave\sdifferently\swhen\sa\sprogram\stries\sto\sread()\sfrom\sa\sfile-descriptor\sopen\son\sa\sdirectory. -D 2021-02-12T21:22:01.411 +C Fix\sa\sproblem\sin\sthe\sunreleased\sunion-all\sflattening\scode. +D 2021-02-13T14:26:25.041 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -541,7 +541,7 @@ F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 89e4faf6171e179edf279905e8e45c4f9dd108777dc60716396729fbd7cb045e F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 738cb746189f721f59972993c13085fa2975c4cbfd04ba26445f3b42c81237dc +F src/select.c e0668a378b8728f7bd8e43014fad070b546f9063ac7b4d55ce784a78c03975b9 F src/shell.c.in 9ebc74e4f05cfbd0f4a36060fdaeff1da4e9af4458358722bc08c5a1ab9a0879 F src/sqlite.h.in 8855a19f37ade8dad189a9e48233a2ebe1b46faf469c7eb0906a654e252dcc57 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1632,7 +1632,7 @@ F test/tt3_vacuum.c 1753f45917699c9c1f66b64c717a717c9379f776 F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff F test/types2.test 1aeb81976841a91eef292723649b5c4fe3bc3cac F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a -F test/unionall.test ca6f612930c79e30f41f804dff4cce949b61347930847642e333ecd5d79f5964 +F test/unionall.test 369dac51f4e7b94442b054d3d7f2e6755cd6994274718228878e3bd47c425f6d F test/unionall2.test c9a62db63350bcbce3a7bec50dd8c5410f08be33f8af435473756286d4657215 F test/unionallfault.test 652bfbb630e6c43135965dc1e8f0a9a791da83aec885d626a632fe1909c56f73 F test/unionvtab.test e1704ab1b4c1bb3ffc9da4681f8e85a0b909fd80b937984fc94b27415ac8e5a4 @@ -1899,7 +1899,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 a18dc08bafefd849e640086b18c41e06361d2e09d7dd2e9af4a394dc543e598b -R 75ef21488d6a3f284e4e31927f38030c +P ecd712032f56a20d7df2bcf89b0d3b8d91dc72c552e27f0a4b23980bd49747b0 +R fe5286a527183faa5a61a85cfa611b1e U dan -Z 408da0e65feec11d579f305d93e52369 +Z fdafd1b43ce985516188a52cad4557fd diff --git a/manifest.uuid b/manifest.uuid index 56987518bf..a8ecb8c741 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ecd712032f56a20d7df2bcf89b0d3b8d91dc72c552e27f0a4b23980bd49747b0 \ No newline at end of file +e4f8a79fd8b3be9bf8add5f5e1c66bc2fe78da4e50ea500ab0b8370d30e31ba5 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 7c3019890c..0976a0a006 100644 --- a/src/select.c +++ b/src/select.c @@ -3688,7 +3688,8 @@ static void srclistRenumberCursors( */ static int renumberCursorsCb(Walker *pWalker, Expr *pExpr){ int *aCsrMap = pWalker->u.aiCol; - if( pExpr->op==TK_COLUMN && aCsrMap[pExpr->iTable] ){ + int op = pExpr->op; + if( (op==TK_COLUMN || op==TK_IF_NULL_ROW) && aCsrMap[pExpr->iTable] ){ pExpr->iTable = aCsrMap[pExpr->iTable]; } if( ExprHasProperty(pExpr, EP_FromJoin) && aCsrMap[pExpr->iRightJoinTable] ){ diff --git a/test/unionall.test b/test/unionall.test index 5cefa64a82..2f8027ccb7 100644 --- a/test/unionall.test +++ b/test/unionall.test @@ -326,4 +326,33 @@ do_execsql_test 5.20 { SELECT *, '+' FROM t1 LEFT JOIN t3 ON (a NOT IN(SELECT v FROM t1 LEFT JOIN t2 ON (a=k))=k); } {0 {} {} {} + 1 one {} {} + 2 two {} {} + 5 five {} {} + 3 three {} {} + 6 six {} {} +} +reset_db +do_execsql_test 6.0 { + CREATE TABLE t1(a,b); + INSERT INTO t1 VALUES(1,2); + CREATE TABLE t2(a,b); + INSERT INTO t2 VALUES(3,4); + + CREATE TABLE t3(a,b); + INSERT INTO t3 VALUES(5,6); + CREATE TABLE t4(a,b); + INSERT INTO t4 VALUES(7,8); + + CREATE TABLE t5(a,b); + INSERT INTO t5 VALUES(9,10); +} + +do_execsql_test 6.1 { + WITH x(c) AS ( + SELECT 1000 FROM t1 UNION ALL SELECT 800 FROM t2 + ), + y(d) AS ( + SELECT 100 FROM t3 UNION ALL SELECT 400 FROM t4 + ) + SELECT * FROM t5, x, y; +} { + 9 10 1000 100 9 10 1000 400 + 9 10 800 100 9 10 800 400 +} + finish_test From 8794c68a3566c50173c77d30a1126389ee434a36 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 13 Feb 2021 16:39:24 +0000 Subject: [PATCH 190/257] Avoid manifesting a CTE (or other view) multiple times when it is possible to reuse the first manifestation. FossilOrigin-Name: 9692f510803c9b9725abb687d7c10fbc0d5ed784479ec6f3fcc55925a87fe16d --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/select.c | 8 +++++--- src/sqliteInt.h | 1 + test/with3.test | 29 +++++++++++++++++++++++++++++ 5 files changed, 45 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 3be9abba78..23d8ed89b9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sin\sthe\sunreleased\sunion-all\sflattening\scode. -D 2021-02-13T14:26:25.041 +C Avoid\smanifesting\sa\sCTE\s(or\sother\sview)\smultiple\stimes\swhen\sit\sis\spossible\sto\nreuse\sthe\sfirst\smanifestation. +D 2021-02-13T16:39:24.888 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -541,12 +541,12 @@ F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 89e4faf6171e179edf279905e8e45c4f9dd108777dc60716396729fbd7cb045e F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c e0668a378b8728f7bd8e43014fad070b546f9063ac7b4d55ce784a78c03975b9 +F src/select.c 9b4c84fd2703ee3c8b5d4b189387482a84c26acf2c38ca4835db5b48c68a09d4 F src/shell.c.in 9ebc74e4f05cfbd0f4a36060fdaeff1da4e9af4458358722bc08c5a1ab9a0879 F src/sqlite.h.in 8855a19f37ade8dad189a9e48233a2ebe1b46faf469c7eb0906a654e252dcc57 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h fc56cfde306778a431c133803676fdd1c962ee3e75b5f2483c20fa069cb056e4 +F src/sqliteInt.h 4cb469678a0dbf814e4efbde4488a0161a5398e9a63141830d9f676b4e9fb0cc F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1779,7 +1779,7 @@ F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3c F test/windowfault.test 72375ae71031eabf96bc88d0af128c8628a091ddc99b5a394e848b3df5fc17ad F test/with1.test 780be387f01e290e768bdfd1827280f9e37ba37223eb4736aba386864fac5a94 F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1ab -F test/with3.test a261f0ea225c4af0ce6447f1157bb603959b2a665f14a03951c2883d2ef1c0f0 +F test/with3.test 85e059bf4c2ef5626411ee59f399b4bb4b4a0f009bcb7db86f254e570ed11831 F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205 F test/with5.test 6248213c41fab36290b5b73aa3f937309dfba337004d9d8434c3fabc8c7d4be8 F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64 @@ -1899,7 +1899,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 ecd712032f56a20d7df2bcf89b0d3b8d91dc72c552e27f0a4b23980bd49747b0 -R fe5286a527183faa5a61a85cfa611b1e -U dan -Z fdafd1b43ce985516188a52cad4557fd +P e4f8a79fd8b3be9bf8add5f5e1c66bc2fe78da4e50ea500ab0b8370d30e31ba5 +R fcb006f6d71d2e850d377aff55f1cc80 +U drh +Z 1875864fd8db78218d6a73a66447730a diff --git a/manifest.uuid b/manifest.uuid index a8ecb8c741..c88100c366 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e4f8a79fd8b3be9bf8add5f5e1c66bc2fe78da4e50ea500ab0b8370d30e31ba5 \ No newline at end of file +9692f510803c9b9725abb687d7c10fbc0d5ed784479ec6f3fcc55925a87fe16d \ No newline at end of file diff --git a/src/select.c b/src/select.c index 0976a0a006..1ab2ec367e 100644 --- a/src/select.c +++ b/src/select.c @@ -4593,6 +4593,7 @@ static int pushDownWhereTerms( } if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){ nChng++; + pSubq->selFlags |= SF_PushDown; while( pSubq ){ SubstContext x; pNew = sqlite3ExprDup(pParse->db, pWhere, 0); @@ -5765,6 +5766,8 @@ static struct SrcList_item *isSelfJoinView( struct SrcList_item *pThis /* Search for prior reference to this subquery */ ){ struct SrcList_item *pItem; + assert( pThis->pSelect!=0 ); + if( pThis->pSelect->selFlags & SF_PushDown ) return 0; for(pItem = pTabList->a; pItempSelect==0 ) continue; @@ -5780,9 +5783,7 @@ static struct SrcList_item *isSelfJoinView( ** names in the same FROM clause. */ continue; } - if( sqlite3ExprCompare(0, pThis->pSelect->pWhere, pS1->pWhere, -1) - || sqlite3ExprCompare(0, pThis->pSelect->pHaving, pS1->pHaving, -1) - ){ + if( pItem->pSelect->selFlags & SF_PushDown ){ /* The view was modified by some other optimization such as ** pushDownWhereTerms() */ continue; @@ -6203,6 +6204,7 @@ int sqlite3Select( sqlite3TreeViewSelect(0, p, 0); } #endif + assert( pItem->pSelect && (pItem->pSelect->selFlags & SF_PushDown)!=0 ); }else{ SELECTTRACE(0x100,pParse,p,("Push-down not possible\n")); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 093ce76210..17b1cb415d 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3184,6 +3184,7 @@ struct Select { #define SF_View 0x0200000 /* SELECT statement is a view */ #define SF_NoopOrderBy 0x0400000 /* ORDER BY is ignored for this query */ #define SF_UpdateFrom 0x0800000 /* Statement is an UPDATE...FROM */ +#define SF_PushDown 0x1000000 /* SELECT has be modified by push-down opt */ /* ** The results of a SELECT can be distributed in several ways, as defined diff --git a/test/with3.test b/test/with3.test index a574263b89..3325ecc93f 100644 --- a/test/with3.test +++ b/test/with3.test @@ -198,4 +198,33 @@ do_execsql_test 4.2 { GROUP BY 1; } {elvis} +# 2021-02-13 +# Avoid manifesting the same CTE multiple times. +# +do_eqp_test 5.1 { + WITH RECURSIVE c(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM c WHERE x<1) + SELECT x1.x||x2.x||x3.x||x4.x FROM c AS x1, c AS x2, c AS x3, c AS x4 + ORDER BY 1; +} { + QUERY PLAN + |--MATERIALIZE xxxxxx + | |--SETUP + | | `--SCAN CONSTANT ROW + | `--RECURSIVE STEP + | `--SCAN TABLE c + |--SCAN SUBQUERY xxxxxx AS x1 + |--SCAN SUBQUERY xxxxxx AS x2 + |--SCAN SUBQUERY xxxxxx AS x3 + |--SCAN SUBQUERY xxxxxx AS x4 + `--USE TEMP B-TREE FOR ORDER BY +} +do_execsql_test 5.2 { + WITH RECURSIVE c(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM c WHERE x<1) + SELECT x1.x||x2.x||x3.x||x4.x FROM c AS x1, c AS x2, c AS x3, c AS x4 + ORDER BY 1; +} {0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111} + + + + finish_test From 329eaaf0b3a857d67f99da45564d398a615d1c78 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 13 Feb 2021 18:14:15 +0000 Subject: [PATCH 191/257] Fix incorrect test name labels in the select1.test script. FossilOrigin-Name: 179c79ea0deb0f5adaa8d369cfcad06d959a9cc18a8a41e01ef013b2d90acd61 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/select1.test | 12 ++++++------ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 23d8ed89b9..81d46eaf6d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\smanifesting\sa\sCTE\s(or\sother\sview)\smultiple\stimes\swhen\sit\sis\spossible\sto\nreuse\sthe\sfirst\smanifestation. -D 2021-02-13T16:39:24.888 +C Fix\sincorrect\stest\sname\slabels\sin\sthe\sselect1.test\sscript. +D 2021-02-13T18:14:15.205 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1324,7 +1324,7 @@ F test/schema6.test e4bd1f23d368695eb9e7b51ef6e02ca0642ea2ab4a52579959826b5e7dce F test/schemafault.test 1936bceca55ac82c5efbcc9fc91a1933e45c8d1e1d106b9a7e56c972a5a2a51e F test/securedel.test 2f70b2449186a1921bd01ec9da407fbfa98c3a7a5521854c300c194b2ff09384 F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5 -F test/select1.test 0ed936740777f52858b6607f39ffac4b2b63b8fc7edf3ab2ebad3c3553ceecee +F test/select1.test 3d23f66bf9ba77570acfe2ca5f1540ece17037cc64ab1a00efec9758ac29c268 F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56 F test/select3.test c49fbb758903f3718e2de5aa4655eda4838131cbea24a86db908f8b6889aa68c F test/select4.test e8a2502e3623f3058871030599a48abb35789d2244d5b380ecf3696873fdd4a4 @@ -1899,7 +1899,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 e4f8a79fd8b3be9bf8add5f5e1c66bc2fe78da4e50ea500ab0b8370d30e31ba5 -R fcb006f6d71d2e850d377aff55f1cc80 +P 9692f510803c9b9725abb687d7c10fbc0d5ed784479ec6f3fcc55925a87fe16d +R 0c64c86089d6aa467750f9eba3dbafff U drh -Z 1875864fd8db78218d6a73a66447730a +Z bef3ac59ff66799b655a50d5e67ecd31 diff --git a/manifest.uuid b/manifest.uuid index c88100c366..16c0579a8f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9692f510803c9b9725abb687d7c10fbc0d5ed784479ec6f3fcc55925a87fe16d \ No newline at end of file +179c79ea0deb0f5adaa8d369cfcad06d959a9cc18a8a41e01ef013b2d90acd61 \ No newline at end of file diff --git a/test/select1.test b/test/select1.test index 82e6ab55c8..e22907da1e 100644 --- a/test/select1.test +++ b/test/select1.test @@ -1167,17 +1167,17 @@ do_execsql_test select1-18.4 { # 2019-12-17 gramfuzz find # -do_execsql_test select-19.10 { +do_execsql_test select1-19.10 { DROP TABLE IF EXISTS t1; CREATE TABLE t1(x); } {} -do_catchsql_test select-19.20 { +do_catchsql_test select1-19.20 { INSERT INTO t1 SELECT 1,2,3,4,5,6,7 UNION ALL SELECT 1,2,3,4,5,6,7 ORDER BY 1; } {1 {table t1 has 1 columns but 7 values were supplied}} -do_catchsql_test select-19.21 { +do_catchsql_test select1-19.21 { INSERT INTO t1 SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 UNION ALL SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 @@ -1187,7 +1187,7 @@ do_catchsql_test select-19.21 { # 2020-01-01 Found by Yongheng's fuzzer # reset_db -do_execsql_test select-20.10 { +do_execsql_test select1-20.10 { CREATE TABLE t1 ( a INTEGER PRIMARY KEY, b AS('Y') UNIQUE @@ -1197,13 +1197,13 @@ do_execsql_test select-20.10 { WHERE ((SELECT t1.a FROM t1 AS x GROUP BY b) AND b=0) OR a = 10; } {10 Y} -do_execsql_test select-20.20 { +do_execsql_test select1-20.20 { SELECT ifnull(a, max((SELECT 123))), count(a) FROM t1 ; } {10 1} # 2020-10-02 dbsqlfuzz find reset_db -do_execsql_test select-21.1 { +do_execsql_test select1-21.1 { CREATE TABLE t1(a IMTEGES PRIMARY KEY,R); CREATE TABLE t2(x UNIQUE); CREATE VIEW v1a(z,y) AS SELECT x IS NULL, x FROM t2; From 863fd4905c99bdfa1cf28f12a399bb8506271263 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 15 Feb 2021 11:14:53 +0000 Subject: [PATCH 192/257] Fix an error in the test case fix in [ecd71203]. FossilOrigin-Name: 5411bfa41ea9a492ca1f567327d8e0a1b3db047292fec1753bfef8a157cf8c1d --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/backup2.test | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 81d46eaf6d..a96e2a9ce5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sincorrect\stest\sname\slabels\sin\sthe\sselect1.test\sscript. -D 2021-02-13T18:14:15.205 +C Fix\san\serror\sin\sthe\stest\scase\sfix\sin\s[ecd71203]. +D 2021-02-15T11:14:53.674 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -697,7 +697,7 @@ F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4 F test/avtrans.test b7dc25459ecbd86c6fa9c606ee3068f59d81e225118617dcf2bbb6ded2ade89e F test/backcompat.test 3e64cedda754c778ef6bbe417b6e7a295e662a4d F test/backup.test dd4a5ff756e3df3931dacb1791db0584d4bad989 -F test/backup2.test f52e3b87f39d1b826d4f622eafe5d30260ae5bdb05764843ff7c83057b05ed49 +F test/backup2.test 8facb54df1388419d34b362ab1f7e233310ff3a3af64e8ad5ec47ba3c2bbe5cf F test/backup4.test 8f6fd48e0dfde77b9a3bb26dc471ede3e101df32 F test/backup5.test ee5da6d7fe5082f5b9b0bbfa31d016f52412a2e4 F test/backup_ioerr.test 4c3c7147cee85b024ecf6e150e090c32fdbb5135 @@ -1899,7 +1899,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 9692f510803c9b9725abb687d7c10fbc0d5ed784479ec6f3fcc55925a87fe16d -R 0c64c86089d6aa467750f9eba3dbafff -U drh -Z bef3ac59ff66799b655a50d5e67ecd31 +P 179c79ea0deb0f5adaa8d369cfcad06d959a9cc18a8a41e01ef013b2d90acd61 +R 5f0aad5d7f182c557891a16fbaaa8cc0 +U dan +Z ba1469c6a8636da747e8ff0251d05f6d diff --git a/manifest.uuid b/manifest.uuid index 16c0579a8f..4b00764d71 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -179c79ea0deb0f5adaa8d369cfcad06d959a9cc18a8a41e01ef013b2d90acd61 \ No newline at end of file +5411bfa41ea9a492ca1f567327d8e0a1b3db047292fec1753bfef8a157cf8c1d \ No newline at end of file diff --git a/test/backup2.test b/test/backup2.test index 8b9cb8731a..1822e2dbf0 100644 --- a/test/backup2.test +++ b/test/backup2.test @@ -152,8 +152,8 @@ do_test backup2-10 { forcedelete bu3.db file mkdir bu3.db set rc [catch {db restore temp bu3.db} res] - if {0==[string match *BSD $tcl_platform(os)]} { lappend rc $res } - set rc + if {[string match *BSD $tcl_platform(os)]} { set res "" } + list $rc $res } [list 1 $msg] # Try to restore from something that is not a database file. From 351ae772a3ad1096fbd57867fb1058df9dab4265 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 15 Feb 2021 13:17:19 +0000 Subject: [PATCH 193/257] Ensure that the ALTER TABLE statements return 0 for sqlite3_column_count(). FossilOrigin-Name: 29c1932a47cd46c2585ebbf937c03544a8a355014776129662789e15db9ed4de --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/alter.c | 1 + 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index a96e2a9ce5..69fdb0bdad 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\serror\sin\sthe\stest\scase\sfix\sin\s[ecd71203]. -D 2021-02-15T11:14:53.674 +C Ensure\sthat\sthe\sALTER\sTABLE\sstatements\sreturn\s0\sfor\nsqlite3_column_count(). +D 2021-02-15T13:17:19.534 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 36cae0d6e3e91a1996e1a472f8c7242c31a4e38ba4295e3056da198c04fd2a87 +F src/alter.c c4a973d7fc68f81fbc5d1d028a88ddb2cb212faef8c6f63433175b8d5ecd83dc F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c F src/attach.c e80162a47411f296bea550ed8fafd730481f4aa71e89ece23ba9c957eed15d4a F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 @@ -1899,7 +1899,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 179c79ea0deb0f5adaa8d369cfcad06d959a9cc18a8a41e01ef013b2d90acd61 -R 5f0aad5d7f182c557891a16fbaaa8cc0 -U dan -Z ba1469c6a8636da747e8ff0251d05f6d +P 5411bfa41ea9a492ca1f567327d8e0a1b3db047292fec1753bfef8a157cf8c1d +R 26a1b41fc224209a7df396ceab19e9c5 +U drh +Z 636bc50c9ef75b6ac02dee0a656e0aee diff --git a/manifest.uuid b/manifest.uuid index 4b00764d71..7c0f2a322e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5411bfa41ea9a492ca1f567327d8e0a1b3db047292fec1753bfef8a157cf8c1d \ No newline at end of file +29c1932a47cd46c2585ebbf937c03544a8a355014776129662789e15db9ed4de \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index e0beb8f3ed..0f50f195e7 100644 --- a/src/alter.c +++ b/src/alter.c @@ -50,6 +50,7 @@ static int isAlterableTable(Parse *pParse, Table *pTab){ ** objects unusable. */ static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){ + pParse->colNamesSet = 1; sqlite3NestedParse(pParse, "SELECT 1 " "FROM \"%w\"." DFLT_SCHEMA_TABLE " " From f2b32e8915384bbfe4783de481280b8bdb1b367f Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 15 Feb 2021 14:32:05 +0000 Subject: [PATCH 194/257] Add tests for sqlite3_column_count(). FossilOrigin-Name: 7cc65ae57183b3c16f1102fca5603a36acda432e5d45e22a2996e5ebe069fc6a --- manifest | 13 +++++----- manifest.uuid | 2 +- test/columncount.test | 57 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 test/columncount.test diff --git a/manifest b/manifest index 69fdb0bdad..9d684a6c24 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sthe\sALTER\sTABLE\sstatements\sreturn\s0\sfor\nsqlite3_column_count(). -D 2021-02-15T13:17:19.534 +C Add\stests\sfor\ssqlite3_column_count(). +D 2021-02-15T14:32:05.655 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -766,6 +766,7 @@ F test/collateA.test b8218ab90d1fa5c59dcf156efabb1b2599c580d6 F test/collateB.test 1e68906951b846570f29f20102ed91d29e634854ee47454d725f2151ecac0b95 F test/colmeta.test 2c765ea61ee37bc43bbe6d6047f89004e6508eb1 F test/colname.test 87ad5458bb8709312dac0d6755fd30e8e4ca83298d0a9ef6e5c24277a3c3390e +F test/columncount.test eff33d402a7b0fde0a52a1920d238af200ca573327021e0ce3b7e5688de41449 F test/conflict.test ac0667090f66130ac77d5fb764655558ca6600dd6d88f670ca9123b61c448337 F test/conflict2.test 5557909ce683b1073982f5d1b61dfb1d41e369533bfdaf003180c5bc87282dd1 F test/conflict3.test 81865d9599609aca394fb3b9cd5f561d4729ea5b176bece3644f6ecb540f88ac @@ -1899,7 +1900,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 5411bfa41ea9a492ca1f567327d8e0a1b3db047292fec1753bfef8a157cf8c1d -R 26a1b41fc224209a7df396ceab19e9c5 -U drh -Z 636bc50c9ef75b6ac02dee0a656e0aee +P 29c1932a47cd46c2585ebbf937c03544a8a355014776129662789e15db9ed4de +R f9be004d695acd30974fbbc52a7a4370 +U dan +Z 4ef0a84d25d02d84a3a2cc2fe061f3e4 diff --git a/manifest.uuid b/manifest.uuid index 7c0f2a322e..5f39af6f20 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -29c1932a47cd46c2585ebbf937c03544a8a355014776129662789e15db9ed4de \ No newline at end of file +7cc65ae57183b3c16f1102fca5603a36acda432e5d45e22a2996e5ebe069fc6a \ No newline at end of file diff --git a/test/columncount.test b/test/columncount.test new file mode 100644 index 0000000000..3ecc1f8d8a --- /dev/null +++ b/test/columncount.test @@ -0,0 +1,57 @@ +# 2021 February 15 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this file is testing the sqlite3_column_count() API. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix columncount + +proc do_ccsql_test {tn sql res} { + + uplevel [list do_test $tn [subst -nocommands { + set stmt [sqlite3_prepare_v2 db {$sql} -1 dummy] + set res [sqlite3_column_count [set stmt]] + while {[sqlite3_step [set stmt]]=="SQLITE_ROW"} { + for {set i 0} {[set i] < [sqlite3_data_count [set stmt]]} {incr i} { + lappend res [sqlite3_column_text [set stmt] [set i]] + } + } + + set rc [sqlite3_finalize [set stmt]] + if {[set rc]!="SQLITE_OK"} { + error [sqlite3_errmsg db] + } + + set res + }] [list {*}$res]] + +} + +do_execsql_test 1.0 { + CREATE TABLE t1(x, y, z); + INSERT INTO t1 VALUES('a', 'b', 'c'); +} + +do_ccsql_test 1.1 { SELECT * FROM t1 } {3 a b c} +do_ccsql_test 1.2 { CREATE TABLE t2(a, b) } {0} + +do_ccsql_test 1.3 { ALTER TABLE t2 RENAME TO t3 } {0} +do_ccsql_test 1.4 { ALTER TABLE t3 RENAME b TO ccc } {0} +do_ccsql_test 1.5 { ALTER TABLE t3 ADD COLUMN d } {0} + +do_ccsql_test 1.6 { DROP TABLE t3 } {0} + + + +finish_test + From 33941691a526dfc19c3f5a4de39864800a3a9cd9 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 15 Feb 2021 17:02:01 +0000 Subject: [PATCH 195/257] Fix an issue with the LIKE operator when it includes the "ESCAPE '_'" clause. Ticket [c0aeea67d58ae0fd]. FossilOrigin-Name: 27d4117980d125975b5e70eeea58a6ab07bcf066e71b5fcb81b822e05afdbab0 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/func.c | 3 ++- test/like.test | 7 +++++++ 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 9d684a6c24..3ceb441cfb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests\sfor\ssqlite3_column_count(). -D 2021-02-15T14:32:05.655 +C Fix\san\sissue\swith\sthe\sLIKE\soperator\swhen\sit\sincludes\sthe\s"ESCAPE\s'_'"\sclause.\nTicket\s[c0aeea67d58ae0fd]. +D 2021-02-15T17:02:01.949 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -496,7 +496,7 @@ F src/delete.c 352ea931218c45a3daf17472d4141b9c7fc026d85da3f1ade404ea5bb6d67f77 F src/expr.c 47c85263e6d179424e6b09e2c79db5704ab5b8cbc2fae2ee3285faa2566f2e74 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 73adaca988d0dd517d373b432dc9dfa2cd7fa3108b114260132a80832de19037 -F src/func.c 2ea99e9e0531b7f020d5e8e167d25344d618afc718ddc94dd91fa8fef1c85a91 +F src/func.c 479f6929be027eb0210cbdde9d3529c012facf082d64a6b854a9415940761e5e F src/global.c ed55af196a9b66e198aaeda3f5454c3aa7d7d050c6c938181fd044b70d180a81 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 @@ -1136,7 +1136,7 @@ F test/kvtest.c feb4358fb022da8ebd098c45811f2f6507688bb6c43aa72b3e840df19026317b F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/lemon-test01.y 58b764610fd934e189ffbb0bbfa33d171b9cb06019b55bdc04d090d6767e11d7 -F test/like.test 47b81d5de2ff19d996d49a65d50ec9754246aacbe0e950b48d186d9d8171eaf0 +F test/like.test 0b7b4765ca59d95a1f92dfab9e4d810c9fb8280b5edd6332a01340a20db9e0ed F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da F test/like3.test 03d1bdf848483b78d2cfd1db283d75c4ec2e37c8b8eccc006813f3978d78fbbd F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e @@ -1900,7 +1900,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 29c1932a47cd46c2585ebbf937c03544a8a355014776129662789e15db9ed4de -R f9be004d695acd30974fbbc52a7a4370 -U dan -Z 4ef0a84d25d02d84a3a2cc2fe061f3e4 +P 7cc65ae57183b3c16f1102fca5603a36acda432e5d45e22a2996e5ebe069fc6a +R 3ed1929e1ca13bbf9ff7ef7c6dc85f4d +U drh +Z b9fb1ccb5459387ee6a14bca5dee2b45 diff --git a/manifest.uuid b/manifest.uuid index 5f39af6f20..1137531a24 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7cc65ae57183b3c16f1102fca5603a36acda432e5d45e22a2996e5ebe069fc6a \ No newline at end of file +27d4117980d125975b5e70eeea58a6ab07bcf066e71b5fcb81b822e05afdbab0 \ No newline at end of file diff --git a/src/func.c b/src/func.c index 6d7a77fdb6..aedbda6f36 100644 --- a/src/func.c +++ b/src/func.c @@ -694,7 +694,8 @@ static int patternCompare( /* Skip over multiple "*" characters in the pattern. If there ** are also "?" characters, skip those as well, but consume a ** single character of the input string for each "?" skipped */ - while( (c=Utf8Read(zPattern)) == matchAll || c == matchOne ){ + while( (c=Utf8Read(zPattern)) == matchAll + || (c == matchOne && matchOne!=0) ){ if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){ return SQLITE_NOWILDCARDMATCH; } diff --git a/test/like.test b/test/like.test index c29ebb2676..8ea7cff782 100644 --- a/test/like.test +++ b/test/like.test @@ -1131,4 +1131,11 @@ do_execsql_test 17.1 { SELECT id FROM t1 WHERE x LIKE 'abc__' ESCAPE '_'; } {2} +# 2021-02-15 ticket c0aeea67d58ae0fd +# +do_execsql_test 17.1 { + SELECT 'x' LIKE '%' ESCAPE '_'; +} {1} + + finish_test From 13162ef9755a4677cce7d3e29f66d8c1dfbea221 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 16 Feb 2021 20:01:08 +0000 Subject: [PATCH 196/257] New SELECTTRACE macros more clearly deliniate when the query planner is invoked in the middle of PRAGMA vdbe_addoptrace output. FossilOrigin-Name: 7c03ce49b74f72b63dd75c3a02625e671bfd771f71b24e808994322b00d97677 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 7 +++++++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 3ceb441cfb..e921ebcca4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sissue\swith\sthe\sLIKE\soperator\swhen\sit\sincludes\sthe\s"ESCAPE\s'_'"\sclause.\nTicket\s[c0aeea67d58ae0fd]. -D 2021-02-15T17:02:01.949 +C New\sSELECTTRACE\smacros\smore\sclearly\sdeliniate\swhen\sthe\squery\splanner\sis\ninvoked\sin\sthe\smiddle\sof\sPRAGMA\svdbe_addoptrace\soutput. +D 2021-02-16T20:01:08.164 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -541,7 +541,7 @@ F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 89e4faf6171e179edf279905e8e45c4f9dd108777dc60716396729fbd7cb045e F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 9b4c84fd2703ee3c8b5d4b189387482a84c26acf2c38ca4835db5b48c68a09d4 +F src/select.c d009aafcd9304b8406809fc808ce8c2cd55471552d242b98bd3006d0ad55cd12 F src/shell.c.in 9ebc74e4f05cfbd0f4a36060fdaeff1da4e9af4458358722bc08c5a1ab9a0879 F src/sqlite.h.in 8855a19f37ade8dad189a9e48233a2ebe1b46faf469c7eb0906a654e252dcc57 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1900,7 +1900,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 7cc65ae57183b3c16f1102fca5603a36acda432e5d45e22a2996e5ebe069fc6a -R 3ed1929e1ca13bbf9ff7ef7c6dc85f4d +P 27d4117980d125975b5e70eeea58a6ab07bcf066e71b5fcb81b822e05afdbab0 +R d43052c777aaa14629da9c7e3bc44da1 U drh -Z b9fb1ccb5459387ee6a14bca5dee2b45 +Z eeb77f51dc50205cf2215ff7ac94a3a0 diff --git a/manifest.uuid b/manifest.uuid index 1137531a24..6d6ed811ef 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -27d4117980d125975b5e70eeea58a6ab07bcf066e71b5fcb81b822e05afdbab0 \ No newline at end of file +7c03ce49b74f72b63dd75c3a02625e671bfd771f71b24e808994322b00d97677 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 1ab2ec367e..49a36875fe 100644 --- a/src/select.c +++ b/src/select.c @@ -6427,6 +6427,7 @@ int sqlite3Select( sSort.pOrderBy = 0; } } + SELECTTRACE(1,pParse,p,("WhereBegin returns\n")); /* If sorting index that was created by a prior OP_OpenEphemeral ** instruction ended up not being needed, then change the OP_OpenEphemeral @@ -6465,6 +6466,7 @@ int sqlite3Select( /* End the database scan loop. */ + SELECTTRACE(1,pParse,p,("WhereEnd\n")); sqlite3WhereEnd(pWInfo); } }else{ @@ -6658,6 +6660,7 @@ int sqlite3Select( WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0), 0 ); if( pWInfo==0 ) goto select_end; + SELECTTRACE(1,pParse,p,("WhereBegin returns\n")); if( sqlite3WhereIsOrdered(pWInfo)==pGroupBy->nExpr ){ /* The optimizer is able to deliver rows in group by order so ** we do not have to sort. The OP_OpenEphemeral table will be @@ -6706,6 +6709,7 @@ int sqlite3Select( sqlite3VdbeAddOp2(v, OP_SorterInsert, pAggInfo->sortingIdx, regRecord); sqlite3ReleaseTempReg(pParse, regRecord); sqlite3ReleaseTempRange(pParse, regBase, nCol); + SELECTTRACE(1,pParse,p,("WhereEnd\n")); sqlite3WhereEnd(pWInfo); pAggInfo->sortingIdxPTab = sortPTab = pParse->nTab++; sortOut = sqlite3GetTempReg(pParse); @@ -6783,6 +6787,7 @@ int sqlite3Select( sqlite3VdbeAddOp2(v, OP_SorterNext, pAggInfo->sortingIdx,addrTopOfLoop); VdbeCoverage(v); }else{ + SELECTTRACE(1,pParse,p,("WhereEnd\n")); sqlite3WhereEnd(pWInfo); sqlite3VdbeChangeToNoop(v, addrSortingIdx); } @@ -6938,11 +6943,13 @@ int sqlite3Select( if( pWInfo==0 ){ goto select_end; } + SELECTTRACE(1,pParse,p,("WhereBegin returns\n")); updateAccumulator(pParse, regAcc, pAggInfo); if( regAcc ) sqlite3VdbeAddOp2(v, OP_Integer, 1, regAcc); if( minMaxFlag ){ sqlite3WhereMinMaxOptEarlyOut(v, pWInfo); } + SELECTTRACE(1,pParse,p,("WhereEnd\n")); sqlite3WhereEnd(pWInfo); finalizeAggFunctions(pParse, pAggInfo); } From 6b37b762ed85f83d4b78d60fdd97b36c40de887f Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 16 Feb 2021 20:32:17 +0000 Subject: [PATCH 197/257] Simplification to the resolveAlias() routine. FossilOrigin-Name: 00bead3931135af80475c22f08cbb26c914518e8f2c7e73c2b8be1cee4ac4d5e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/resolve.c | 8 +++----- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index e921ebcca4..931f661935 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\sSELECTTRACE\smacros\smore\sclearly\sdeliniate\swhen\sthe\squery\splanner\sis\ninvoked\sin\sthe\smiddle\sof\sPRAGMA\svdbe_addoptrace\soutput. -D 2021-02-16T20:01:08.164 +C Simplification\sto\sthe\sresolveAlias()\sroutine. +D 2021-02-16T20:32:17.668 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -539,7 +539,7 @@ F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf F src/prepare.c f288cbc35f79eb32e162de7e80a63ebe00d80e639dcfac071bee11570cbdb16f F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c 89e4faf6171e179edf279905e8e45c4f9dd108777dc60716396729fbd7cb045e +F src/resolve.c 172d0f27c021b1d572e73b6f04f3e2695f2932233d3f5e675bd85b028fa2fb75 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c d009aafcd9304b8406809fc808ce8c2cd55471552d242b98bd3006d0ad55cd12 F src/shell.c.in 9ebc74e4f05cfbd0f4a36060fdaeff1da4e9af4458358722bc08c5a1ab9a0879 @@ -1900,7 +1900,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 27d4117980d125975b5e70eeea58a6ab07bcf066e71b5fcb81b822e05afdbab0 -R d43052c777aaa14629da9c7e3bc44da1 +P 7c03ce49b74f72b63dd75c3a02625e671bfd771f71b24e808994322b00d97677 +R 1b54c7cb4db039e6ced5272704b39604 U drh -Z eeb77f51dc50205cf2215ff7ac94a3a0 +Z 6cadfbe2d2e5d960db064c83d646ea7d diff --git a/manifest.uuid b/manifest.uuid index 6d6ed811ef..10192cda7d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7c03ce49b74f72b63dd75c3a02625e671bfd771f71b24e808994322b00d97677 \ No newline at end of file +00bead3931135af80475c22f08cbb26c914518e8f2c7e73c2b8be1cee4ac4d5e \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index 57ba75f30e..4848e3cfa7 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -70,7 +70,6 @@ static void resolveAlias( ExprList *pEList, /* A result set */ int iCol, /* A column in the result set. 0..pEList->nExpr-1 */ Expr *pExpr, /* Transform this into an alias to the result set */ - const char *zType, /* "GROUP" or "ORDER" or "" */ int nSubquery /* Number of subqueries that the label is moving */ ){ Expr *pOrig; /* The iCol-th column of the result set */ @@ -83,7 +82,7 @@ static void resolveAlias( db = pParse->db; pDup = sqlite3ExprDup(db, pOrig, 0); if( pDup!=0 ){ - if( zType[0]!='G' ) incrAggFunctionDepth(pDup, nSubquery); + if( nSubquery ) incrAggFunctionDepth(pDup, nSubquery); if( pExpr->op==TK_COLLATE ){ pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); } @@ -524,7 +523,7 @@ static int lookupName( sqlite3ErrorMsg(pParse, "row value misused"); return WRC_Abort; } - resolveAlias(pParse, pEList, j, pExpr, "", nSubquery); + resolveAlias(pParse, pEList, j, pExpr, nSubquery); cnt = 1; pMatch = 0; assert( zTab==0 && zDb==0 ); @@ -1401,8 +1400,7 @@ int sqlite3ResolveOrderGroupBy( resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr); return 1; } - resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr, - zType,0); + resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr,0); } } return 0; From 6e6d9833ccf422b90f5b1875c948c11544f32ce6 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 16 Feb 2021 20:43:36 +0000 Subject: [PATCH 198/257] Add experimental implementation of ALTER TABLE DROP COLUMN. Only some cases work so far. FossilOrigin-Name: f0217937d7306fb595727e61e871e8b03d8c881d339a0865bfd0117d90d42e4e --- manifest | 24 +++-- manifest.uuid | 2 +- src/alter.c | 207 ++++++++++++++++++++++++++++++++++++++--- src/parse.y | 4 + src/select.c | 6 +- src/sqliteInt.h | 2 + test/alterdropcol.test | 113 ++++++++++++++++++++++ 7 files changed, 332 insertions(+), 26 deletions(-) create mode 100644 test/alterdropcol.test diff --git a/manifest b/manifest index 3ceb441cfb..2350dad5e2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sissue\swith\sthe\sLIKE\soperator\swhen\sit\sincludes\sthe\s"ESCAPE\s'_'"\sclause.\nTicket\s[c0aeea67d58ae0fd]. -D 2021-02-15T17:02:01.949 +C Add\sexperimental\simplementation\sof\sALTER\sTABLE\sDROP\sCOLUMN.\sOnly\ssome\scases\swork\sso\sfar. +D 2021-02-16T20:43:36.239 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c c4a973d7fc68f81fbc5d1d028a88ddb2cb212faef8c6f63433175b8d5ecd83dc +F src/alter.c e912280eed81e2df936cc03af00a59abfcbfc24a27c3e5db8e8bd96022e2bf79 F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c F src/attach.c e80162a47411f296bea550ed8fafd730481f4aa71e89ece23ba9c957eed15d4a F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 @@ -530,7 +530,7 @@ F src/os_win.c 77d39873836f1831a9b0b91894fec45ab0e9ca8e067dc8c549e1d1eca1566fe9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c c49952ac5e9cc536778eff528091d79d38b3e45cbeeed4695dc05e207dc6547d F src/pager.h 4bf9b3213a4b2bebbced5eaa8b219cf25d4a82f385d093cd64b7e93e5285f66f -F src/parse.y 67ba503780de64b967ae195b7e14c33531329228e1bc0b83d63324beb733680b +F src/parse.y 8170885f22f4815c2adba3430ac7c990a39b60e04a0bcc4d02cce54e33475975 F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a @@ -541,12 +541,12 @@ F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 89e4faf6171e179edf279905e8e45c4f9dd108777dc60716396729fbd7cb045e F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 9b4c84fd2703ee3c8b5d4b189387482a84c26acf2c38ca4835db5b48c68a09d4 +F src/select.c 4bd3b7d21d0d58dfdb4134f71d0330915e962a036ae1e1c8cde2f7f8b45de7e9 F src/shell.c.in 9ebc74e4f05cfbd0f4a36060fdaeff1da4e9af4458358722bc08c5a1ab9a0879 F src/sqlite.h.in 8855a19f37ade8dad189a9e48233a2ebe1b46faf469c7eb0906a654e252dcc57 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h 4cb469678a0dbf814e4efbde4488a0161a5398e9a63141830d9f676b4e9fb0cc +F src/sqliteInt.h 514b41619e2c6b49188571df50249db2600ec33e4bfd1a6efb21f7e1c352f400 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -647,6 +647,7 @@ F test/alter4.test dfd6086faf461b27ca2d2999848dcd207edf23352fc1592d0005c0844f3f0 F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959 F test/alterauth2.test c0a1ddf5b93d93cb0d15ba7acaf0c5c6fb515bbe861ede75b2d3fabad33b6499 F test/altercol.test 1d6a6fe698b81e626baea4881f5717f9bc53d7d07f1cd23ee7ad1b931f117ddf +F test/alterdropcol.test 77539861deb0f1a04fb938f33984d7ccac8618337492611ac41dffea4b316863 F test/alterlegacy.test 82022721ce0de29cedc9a7af63bc9fcc078b0ee000f8283b4b6ea9c3eab2f44b F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9 F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b @@ -1900,7 +1901,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 7cc65ae57183b3c16f1102fca5603a36acda432e5d45e22a2996e5ebe069fc6a -R 3ed1929e1ca13bbf9ff7ef7c6dc85f4d -U drh -Z b9fb1ccb5459387ee6a14bca5dee2b45 +P 27d4117980d125975b5e70eeea58a6ab07bcf066e71b5fcb81b822e05afdbab0 +R af9ecd1afb3809621548f4fa239dc0d6 +T *branch * alter-table-drop-column +T *sym-alter-table-drop-column * +T -sym-trunk * +U dan +Z e426edd9d98bb43cdac675b225a7f76a diff --git a/manifest.uuid b/manifest.uuid index 1137531a24..031aa0ca61 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -27d4117980d125975b5e70eeea58a6ab07bcf066e71b5fcb81b822e05afdbab0 \ No newline at end of file +f0217937d7306fb595727e61e871e8b03d8c881d339a0865bfd0117d90d42e4e \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 0f50f195e7..4b00d4c386 100644 --- a/src/alter.c +++ b/src/alter.c @@ -870,23 +870,33 @@ static void renameTokenFree(sqlite3 *db, RenameToken *pToken){ /* ** Search the Parse object passed as the first argument for a RenameToken -** object associated with parse tree element pPtr. If found, remove it -** from the Parse object and add it to the list maintained by the -** RenameCtx object passed as the second argument. +** object associated with parse tree element pPtr. If found, return a pointer +** to it. Otherwise, return NULL. +** +** If the second argument passed to this function is not NULL and a matching +** RenameToken object is found, remove it from the Parse object and add it to +** the list maintained by the RenameCtx object. */ -static void renameTokenFind(Parse *pParse, struct RenameCtx *pCtx, void *pPtr){ +static RenameToken *renameTokenFind( + Parse *pParse, + struct RenameCtx *pCtx, + void *pPtr +){ RenameToken **pp; assert( pPtr!=0 ); for(pp=&pParse->pRename; (*pp); pp=&(*pp)->pNext){ if( (*pp)->p==pPtr ){ RenameToken *pToken = *pp; - *pp = pToken->pNext; - pToken->pNext = pCtx->pList; - pCtx->pList = pToken; - pCtx->nList++; - break; + if( pCtx ){ + *pp = pToken->pNext; + pToken->pNext = pCtx->pList; + pCtx->pList = pToken; + pCtx->nList++; + } + return pToken; } } + return 0; } /* @@ -1751,14 +1761,187 @@ static void renameTableTest( #endif } +/* +** Arguments: +** +** argv[0]: An integer - the index of the schema containing the table +** argv[1]: CREATE TABLE statement to modify. +** argv[2]: An integer - the index of the column to remove. +** argv[3]: Byte offset of first byte after last column definition in argv[1] +*/ +static void dropColumnFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + int iSchema = sqlite3_value_int(argv[0]); + const char *zSql = (const char*)sqlite3_value_text(argv[1]); + int iCol = sqlite3_value_int(argv[2]); + int iAddColOffset = sqlite3_value_int(argv[3]); + const char *zDb = db->aDb[iSchema].zDbSName; + int rc; + Parse sParse; + RenameToken *pCol; + Table *pTab; + const char *zEnd; + char *zNew = 0; + + rc = renameParseSql(&sParse, zDb, db, zSql, iSchema==1); + if( rc!=SQLITE_OK ) goto drop_column_done; + pTab = sParse.pNewTable; + + pCol = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol].zName); + if( iColnCol-1 ){ + RenameToken *pEnd; + pEnd = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol+1].zName); + zEnd = (const char*)pEnd->t.z; + }else{ + zEnd = (const char*)&zSql[iAddColOffset]; + while( pCol->t.z[0]!=',' && pCol->t.z[1]!='(' ) pCol->t.z--; + } + + zNew = sqlite3_mprintf("%.*s%s", pCol->t.z-zSql, zSql, zEnd); + sqlite3_result_text(context, zNew, -1, SQLITE_TRANSIENT); + sqlite3_free(zNew); + +drop_column_done: + renameParseCleanup(&sParse); +} + +void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, Token *pName){ + Table *pTab; + int i; + int iSchema = 0; + const char *zDb = 0; + sqlite3 *db = pParse->db; + char *zCol = 0; + int iCol = 0; + Vdbe *v; + int iCur; + int addr; + int reg; + int regRec; + Index *pIdx; + Index *pPk = 0; + + /* Look up the table being altered. */ + assert( pParse->pNewTable==0 ); + assert( sqlite3BtreeHoldsAllMutexes(db) ); + if( db->mallocFailed ) goto exit_drop_column; + pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); + if( !pTab ) goto exit_drop_column; + + /* Which schema holds the table to be altered */ + iSchema = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iSchema>=0 ); + zDb = db->aDb[iSchema].zDbSName; + +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + sqlite3ErrorMsg(pParse, "virtual tables may not be altered"); + goto exit_drop_column; + } +#endif + + /* Make sure this is not an attempt to ALTER a view. */ + if( pTab->pSelect ){ + sqlite3ErrorMsg(pParse, "cannot drop a column from a view"); + goto exit_drop_column; + } + if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){ + goto exit_drop_column; + } + + /* Find the index of the column being dropped. */ + zCol = sqlite3NameFromToken(db, pName); + if( zCol==0 ){ + assert( db->mallocFailed ); + goto exit_drop_column; + } + iCol = sqlite3ColumnIndex(pTab, zCol); + if( iCol<0 ){ + sqlite3ErrorMsg(pParse, "no such column: \"%s\"", zCol); + goto exit_drop_column; + } + + /* Do not allow the user to drop a PRIMARY KEY column or a column + ** constrained by a UNIQUE constraint. */ + if( pTab->iPKey==iCol ){ + sqlite3ErrorMsg(pParse, "cannot drop PRIMARY KEY column: \"%s\"", zCol); + goto exit_drop_column; + } + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + int ii; + for(ii=0; iinKeyCol; ii++){ + if( iCol==pIdx->aiColumn[ii] + && sqlite3_strnicmp("sqlite_", pIdx->zName, 7)==0 + ){ + sqlite3ErrorMsg(pParse, "cannot drop %s column: \"%s\"", + pIdx->idxType==2 ? "PRIMARY KEY" : "UNIQUE", zCol + ); + goto exit_drop_column; + } + } + } + + sqlite3NestedParse(pParse, + "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET " + "sql = sqlite_drop_column(%d, sql, %d, %d) " + "WHERE (type=='table' AND tbl_name=%Q COLLATE nocase)" + , zDb, iSchema, iCol, pTab->addColOffset, pTab->zName + ); + + /* Drop and reload the database schema. */ + renameReloadSchema(pParse, iSchema); + renameTestSchema(pParse, zDb, iSchema==1); + + /* Edit rows of table on disk */ + v = sqlite3GetVdbe(pParse); + iCur = pParse->nTab++; + sqlite3OpenTable(pParse, iCur, iSchema, pTab, OP_OpenWrite); + addr = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); + reg = ++pParse->nMem; + pParse->nMem += pTab->nCol; + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp2(v, OP_Rowid, iCur, reg); + }else{ + pPk = sqlite3PrimaryKeyIndex(pTab); + } + for(i=0; inCol; i++){ + if( i!=iCol ){ + int iPos = (pPk ? sqlite3TableColumnToIndex(pPk, i) : i); + int iColPos = (pPk ? sqlite3TableColumnToIndex(pPk, iCol) : iCol); + int regOut = reg+1+iPos-(iPos>iColPos); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, i, regOut); + } + } + regRec = reg + pTab->nCol; + sqlite3VdbeAddOp3(v, OP_MakeRecord, reg+1, pTab->nCol-1, regRec); + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp3(v, OP_Insert, iCur, regRec, reg); + }else{ + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iCur, regRec, reg+1, pPk->nKeyCol); + } + + sqlite3VdbeAddOp2(v, OP_Next, iCur, addr+1); + sqlite3VdbeJumpHere(v, addr); + +exit_drop_column: + sqlite3DbFree(db, zCol); + sqlite3SrcListDelete(db, pSrc); + return; +} + /* ** Register built-in functions used to help implement ALTER TABLE */ void sqlite3AlterFunctions(void){ static FuncDef aAlterTableFuncs[] = { - INTERNAL_FUNCTION(sqlite_rename_column, 9, renameColumnFunc), - INTERNAL_FUNCTION(sqlite_rename_table, 7, renameTableFunc), - INTERNAL_FUNCTION(sqlite_rename_test, 5, renameTableTest), + INTERNAL_FUNCTION(sqlite_rename_column, 9, renameColumnFunc), + INTERNAL_FUNCTION(sqlite_rename_table, 7, renameTableFunc), + INTERNAL_FUNCTION(sqlite_rename_test, 5, renameTableTest), + INTERNAL_FUNCTION(sqlite_drop_column, 4, dropColumnFunc), }; sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs)); } diff --git a/src/parse.y b/src/parse.y index 591cde3b9d..92626f2c17 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1621,6 +1621,10 @@ cmd ::= ALTER TABLE add_column_fullname Y.n = (int)(pParse->sLastToken.z-Y.z) + pParse->sLastToken.n; sqlite3AlterFinishAddColumn(pParse, &Y); } +cmd ::= ALTER TABLE fullname(X) DROP COLUMNKW nm(Y). { + sqlite3AlterDropColumn(pParse, X, &Y); +} + add_column_fullname ::= fullname(X). { disableLookaside(pParse); sqlite3AlterBeginAddColumn(pParse, X); diff --git a/src/select.c b/src/select.c index 1ab2ec367e..04c29e6d2a 100644 --- a/src/select.c +++ b/src/select.c @@ -262,7 +262,7 @@ int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){ ** Return the index of a column in a table. Return -1 if the column ** is not contained in the table. */ -static int columnIndex(Table *pTab, const char *zCol){ +int sqlite3ColumnIndex(Table *pTab, const char *zCol){ int i; u8 h = sqlite3StrIHash(zCol); Column *pCol; @@ -294,7 +294,7 @@ static int tableAndColumnIndex( assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */ for(i=0; ia[i].pTab, zCol); + iCol = sqlite3ColumnIndex(pSrc->a[i].pTab, zCol); if( iCol>=0 && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pTab->aCol[iCol])==0) ){ @@ -504,7 +504,7 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ int iRightCol; /* Column number of matching column on the right */ zName = pList->a[j].zName; - iRightCol = columnIndex(pRightTab, zName); + iRightCol = sqlite3ColumnIndex(pRightTab, zName); if( iRightCol<0 || !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, 0) ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 17b1cb415d..9c09b24aca 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4531,6 +4531,7 @@ void sqlite3MaterializeView(Parse*, Table*, Expr*, ExprList*,Expr*,int); #endif int sqlite3JoinType(Parse*, Token*, Token*, Token*); +int sqlite3ColumnIndex(Table *pTab, const char *zCol); void sqlite3SetJoinExpr(Expr*,int); void sqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int); void sqlite3DeferForeignKey(Parse*, int); @@ -4715,6 +4716,7 @@ int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*); void sqlite3ColumnDefault(Vdbe *, Table *, int, int); void sqlite3AlterFinishAddColumn(Parse *, Token *); void sqlite3AlterBeginAddColumn(Parse *, SrcList *); +void sqlite3AlterDropColumn(Parse*, SrcList*, Token*); void *sqlite3RenameTokenMap(Parse*, void*, Token*); void sqlite3RenameTokenRemap(Parse*, void *pTo, void *pFrom); void sqlite3RenameExprUnmap(Parse*, Expr*); diff --git a/test/alterdropcol.test b/test/alterdropcol.test new file mode 100644 index 0000000000..7bb5977054 --- /dev/null +++ b/test/alterdropcol.test @@ -0,0 +1,113 @@ +# 2021 February 16 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#************************************************************************* +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix alterdropcol + +# If SQLITE_OMIT_ALTERTABLE is defined, omit this file. +ifcapable !altertable { + finish_test + return +} + +do_execsql_test 1.0 { + CREATE TABLE t1(a, b, c); + CREATE VIEW v1 AS SELECT * FROM t1; + + CREATE TABLE t2(x INTEGER PRIMARY KEY, y, z UNIQUE); + CREATE INDEX t2y ON t2(y); +} + +do_catchsql_test 1.1 { + ALTER TABLE nosuch DROP COLUMN z; +} {1 {no such table: nosuch}} + +do_catchsql_test 1.2 { + ALTER TABLE v1 DROP COLUMN c; +} {1 {cannot drop a column from a view}} + +ifcapable fts5 { + do_execsql_test 1.3.1 { + CREATE VIRTUAL TABLE ft1 USING fts5(one, two); + } + do_catchsql_test 1.3.2 { + ALTER TABLE ft1 DROP COLUMN two; + } {1 {virtual tables may not be altered}} +} + +do_catchsql_test 1.4 { + ALTER TABLE sqlite_schema DROP COLUMN sql; +} {1 {table sqlite_master may not be altered}} + +do_catchsql_test 1.5 { + ALTER TABLE t1 DROP COLUMN d; +} {1 {no such column: "d"}} + +do_execsql_test 1.6.1 { + ALTER TABLE t1 DROP COLUMN b; +} +do_execsql_test 1.6.2 { + SELECT sql FROM sqlite_schema WHERE name = 't1' +} {{CREATE TABLE t1(a, c)}} + +do_execsql_test 1.7.1 { + ALTER TABLE t1 DROP COLUMN c; +} +do_execsql_test 1.7.2 { + SELECT sql FROM sqlite_schema WHERE name = 't1' +} {{CREATE TABLE t1(a)}} + + +do_catchsql_test 1.8 { + ALTER TABLE t2 DROP COLUMN z +} {1 {cannot drop UNIQUE column: "z"}} + +do_catchsql_test 1.9 { + ALTER TABLE t2 DROP COLUMN x +} {1 {cannot drop PRIMARY KEY column: "x"}} + +do_catchsql_test 1.10 { + ALTER TABLE t2 DROP COLUMN y +} {1 {cannot drop indexed column: "y"}} + +#------------------------------------------------------------------------- + +foreach {tn wo} { + 1 {} + 2 {WITHOUT ROWID} +} { eval [string map [list %TN% $tn %WO% $wo] { + + reset_db + do_execsql_test 2.%TN%.0 { + CREATE TABLE t1(x, y INTEGER PRIMARY KEY, z) %WO% ; + INSERT INTO t1 VALUES(1, 2, 3); + INSERT INTO t1 VALUES(4, 5, 6); + INSERT INTO t1 VALUES(7, 8, 9); + } + + do_execsql_test 2.%TN%.1 { + ALTER TABLE t1 DROP COLUMN x; + SELECT * FROM t1; + } { + 2 3 5 6 8 9 + } + do_execsql_test 2.%TN%.2 { + ALTER TABLE t1 DROP COLUMN z; + SELECT * FROM t1; + } { + 2 5 8 + } +}]} + +finish_test + From 4b0229ae1ff30df9cf1d33e7c1df27cb01c5ecfe Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 17 Feb 2021 13:19:22 +0000 Subject: [PATCH 199/257] Enhance the ".once" and ".output" commands in the CLI so that if the filename argument begins with "|" the name becomes the concatenation of all subsequent arguments. Hence, commands like ".once | open -f" become possible without the need for quotes. FossilOrigin-Name: c46a94a624c2cc6c49ac916a206a913081e1628c24805987cabc75c9057ea36b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 17 ++++++++++++----- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 931f661935..e7f230bfd2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplification\sto\sthe\sresolveAlias()\sroutine. -D 2021-02-16T20:32:17.668 +C Enhance\sthe\s".once"\sand\s".output"\scommands\sin\sthe\sCLI\sso\sthat\sif\sthe\nfilename\sargument\sbegins\swith\s"|"\sthe\sname\sbecomes\sthe\sconcatenation\nof\sall\ssubsequent\sarguments.\s\sHence,\scommands\slike\s".once\s|\sopen\s-f"\sbecome\npossible\swithout\sthe\sneed\sfor\squotes. +D 2021-02-17T13:19:22.550 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -542,7 +542,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 172d0f27c021b1d572e73b6f04f3e2695f2932233d3f5e675bd85b028fa2fb75 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c d009aafcd9304b8406809fc808ce8c2cd55471552d242b98bd3006d0ad55cd12 -F src/shell.c.in 9ebc74e4f05cfbd0f4a36060fdaeff1da4e9af4458358722bc08c5a1ab9a0879 +F src/shell.c.in 844417f84df1f6c4fce1c815629a888cfdcf219e86513e9c332bbcc38832f477 F src/sqlite.h.in 8855a19f37ade8dad189a9e48233a2ebe1b46faf469c7eb0906a654e252dcc57 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e @@ -1900,7 +1900,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 7c03ce49b74f72b63dd75c3a02625e671bfd771f71b24e808994322b00d97677 -R 1b54c7cb4db039e6ced5272704b39604 +P 00bead3931135af80475c22f08cbb26c914518e8f2c7e73c2b8be1cee4ac4d5e +R c958a1f70e224efabdacd339f843bfe0 U drh -Z 6cadfbe2d2e5d960db064c83d646ea7d +Z 21b3dfef27853d212520b4c1b1451b1a diff --git a/manifest.uuid b/manifest.uuid index 10192cda7d..323618e653 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -00bead3931135af80475c22f08cbb26c914518e8f2c7e73c2b8be1cee4ac4d5e \ No newline at end of file +c46a94a624c2cc6c49ac916a206a913081e1628c24805987cabc75c9057ea36b \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index bfb9648128..03c4fd319e 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -8753,7 +8753,7 @@ static int do_meta_command(char *zLine, ShellState *p){ && (strncmp(azArg[0], "output", n)==0||strncmp(azArg[0], "once", n)==0)) || (c=='e' && n==5 && strcmp(azArg[0],"excel")==0) ){ - const char *zFile = 0; + char *zFile = 0; int bTxtMode = 0; int i; int eMode = 0; @@ -8783,17 +8783,22 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = 1; goto meta_command_exit; } - }else if( zFile==0 ){ - zFile = z; + }else if( zFile==0 && eMode!='e' && eMode!='x' ){ + zFile = sqlite3_mprintf("%s", z); + if( zFile[0]=='|' ){ + while( i+1out,"ERROR: extra parameter: \"%s\". Usage:\n", azArg[i]); showHelp(p->out, azArg[0]); rc = 1; + sqlite3_free(zFile); goto meta_command_exit; } } - if( zFile==0 ) zFile = "stdout"; + if( zFile==0 ) zFile = sqlite3_mprintf("stdout"); if( bOnce ){ p->outCount = 2; }else{ @@ -8816,7 +8821,8 @@ static int do_meta_command(char *zLine, ShellState *p){ newTempFile(p, "txt"); bTxtMode = 1; } - zFile = p->zTempFile; + sqlite3_free(zFile); + zFile = sqlite3_mprintf("%s", p->zTempFile); } #endif /* SQLITE_NOHAVE_SYSTEM */ if( zFile[0]=='|' ){ @@ -8848,6 +8854,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); } } + sqlite3_free(zFile); }else if( c=='p' && n>=3 && strncmp(azArg[0], "parameter", n)==0 ){ From 6a5a13df978cb9371bca8e1721037eef78da66ae Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 17 Feb 2021 20:08:22 +0000 Subject: [PATCH 200/257] Fix various issues with the changes on this branch. Add test cases for the same. FossilOrigin-Name: 10538ec6fc1642dfc2ca6cef06ce6cb9e124847b421ccf01f5842064fad379ab --- manifest | 35 ++++---- manifest.uuid | 2 +- src/alter.c | 179 ++++++++++++++++++++--------------------- src/build.c | 4 +- src/prepare.c | 26 +++--- src/sqliteInt.h | 3 +- src/trigger.c | 2 +- src/vdbe.c | 2 +- src/vdbe.h | 2 +- src/vdbeaux.c | 3 +- src/vtab.c | 2 +- test/alterdropcol.test | 107 +++++++++++++++++++++++- test/alterlegacy.test | 4 +- 13 files changed, 237 insertions(+), 134 deletions(-) diff --git a/manifest b/manifest index 2350dad5e2..586bf12bbf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sexperimental\simplementation\sof\sALTER\sTABLE\sDROP\sCOLUMN.\sOnly\ssome\scases\swork\sso\sfar. -D 2021-02-16T20:43:36.239 +C Fix\svarious\sissues\swith\sthe\schanges\son\sthis\sbranch.\sAdd\stest\scases\sfor\sthe\ssame. +D 2021-02-17T20:08:22.323 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c e912280eed81e2df936cc03af00a59abfcbfc24a27c3e5db8e8bd96022e2bf79 +F src/alter.c e4bb151562fb0de03dc89964c55d89ef06da4f1cbd6521ed166bd4ec7eaa66f8 F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c F src/attach.c e80162a47411f296bea550ed8fafd730481f4aa71e89ece23ba9c957eed15d4a F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 @@ -485,7 +485,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 694020ad8a3af3d79b09f74c8f1421272a419cdea42a13401e3b0f7dea6e9c3e F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 -F src/build.c 1bae5588bfdf21bdf41e634f0a053d633fb1ae3a2896117b4eea76412b76c2e0 +F src/build.c 50c70715bd4e958f8354410e78a676b30f9e2eaba107eaff8a54c465733628df F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 @@ -536,7 +536,7 @@ F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a F src/pragma.c 6daaaecc26a4b09481d21722525b079ce756751a43a79cc1d8f122d686806193 F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf -F src/prepare.c f288cbc35f79eb32e162de7e80a63ebe00d80e639dcfac071bee11570cbdb16f +F src/prepare.c 77c7410c0c5c95278f6eb5e0d4cb82fdff3cb3e51434a7ab9f2b64b501a86974 F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 89e4faf6171e179edf279905e8e45c4f9dd108777dc60716396729fbd7cb045e @@ -546,7 +546,7 @@ F src/shell.c.in 9ebc74e4f05cfbd0f4a36060fdaeff1da4e9af4458358722bc08c5a1ab9a087 F src/sqlite.h.in 8855a19f37ade8dad189a9e48233a2ebe1b46faf469c7eb0906a654e252dcc57 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h 514b41619e2c6b49188571df50249db2600ec33e4bfd1a6efb21f7e1c352f400 +F src/sqliteInt.h d701e738731988caef0c6d12c531a2df6a34cb10528ba8dfe442138b977e2045 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -607,23 +607,23 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda -F src/trigger.c 983c7c8464c46840dac1ffe0461a6c447ac12c965746975c108eb5f4283e8801 +F src/trigger.c 861c3ec2c5b0fc830bdf82470454a9324fad70cbaa96d2e208fb54577c9e8d28 F src/update.c 0f5a61f0787199983530a33f6fffe4f52742f35fcdf6ccfad1078b1a8bc17723 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 41c7a72da1df47864faa378a1c720b38adb288c6838cb6be5594511b6287a048 F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286 -F src/vdbe.c b3c9a3f9d546d4848a2a8c88a3c40875cd6ba3d248d9b99d01b1eeb38b29c171 -F src/vdbe.h 83603854bfa5851af601fc0947671eb260f4363e62e960e8a994fb9bbcd2aaa1 +F src/vdbe.c 9766281c0febf25f30a043d98b2417011acc7b04f287d3c671c3e59f656fc208 +F src/vdbe.h 25dabb25c7e157b84e59260cfb5b466c3ac103ede9f36f4db371332c47601abe F src/vdbeInt.h 3df118924e1711f1bbc8e30c46260d0ab6c3b029b32dd411f789111f76434f3c F src/vdbeapi.c 4a43e303ec3354c785f453e881521969378e85628278ab74ba4a9df790c0d93b -F src/vdbeaux.c c8e96fb57ee6f7150845325ffb8d7fd4e340ff4f73aa527a6f26a485db8b9955 +F src/vdbeaux.c fb51483c2bcaf45c5de63c26cce8649ef37f1332e8e035867033d21ef5e7fc2c F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1 F src/vdbemem.c 947f2a65910edb4014dc981d33e414a68c51f169f9df8c4c493a0ba840b6eb1f F src/vdbesort.c f5b5e473a7cee44e47a94817b042fd7172cf3aa2c0a7928a8339d612bcfdec5a F src/vdbetrace.c 666c6fd9f1b62be6999e072a45b913e3c2c3518bc60dfd4d54fe304130acb724 F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c -F src/vtab.c 81e1a336ba47eccc5cadb80de15f03afabd83c55ff9648e3a98d8988d4c264aa +F src/vtab.c 88bd6d3f0207d5d71842faf984bebff7f7ed96746234bfd6c917d8f4ff93c654 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 69e770e96fd56cc21608992bf2c6f1f3dc5cf2572d0495c6a643b06c3a679f14 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a @@ -647,8 +647,8 @@ F test/alter4.test dfd6086faf461b27ca2d2999848dcd207edf23352fc1592d0005c0844f3f0 F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959 F test/alterauth2.test c0a1ddf5b93d93cb0d15ba7acaf0c5c6fb515bbe861ede75b2d3fabad33b6499 F test/altercol.test 1d6a6fe698b81e626baea4881f5717f9bc53d7d07f1cd23ee7ad1b931f117ddf -F test/alterdropcol.test 77539861deb0f1a04fb938f33984d7ccac8618337492611ac41dffea4b316863 -F test/alterlegacy.test 82022721ce0de29cedc9a7af63bc9fcc078b0ee000f8283b4b6ea9c3eab2f44b +F test/alterdropcol.test 1d9577320aa1b501ebc44de02b7c101789bca9fb6fbbb393c99d24351f15d11e +F test/alterlegacy.test f38c6d06cda39e1f7b955bbce57f2e3ef5b7cb566d3d1234502093e228c15811 F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9 F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b F test/altertab.test 6d7bbac2c4a6ef71b775094a3298fa3a92274d95034ee23157ffba92768e47e6 @@ -1901,10 +1901,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 27d4117980d125975b5e70eeea58a6ab07bcf066e71b5fcb81b822e05afdbab0 -R af9ecd1afb3809621548f4fa239dc0d6 -T *branch * alter-table-drop-column -T *sym-alter-table-drop-column * -T -sym-trunk * +P f0217937d7306fb595727e61e871e8b03d8c881d339a0865bfd0117d90d42e4e +R 35acba48cd575f61e2691128781d8577 U dan -Z e426edd9d98bb43cdac675b225a7f76a +Z 437b0700aa4a252237abb9f1d982595f diff --git a/manifest.uuid b/manifest.uuid index 031aa0ca61..f8588015c3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f0217937d7306fb595727e61e871e8b03d8c881d339a0865bfd0117d90d42e4e \ No newline at end of file +10538ec6fc1642dfc2ca6cef06ce6cb9e124847b421ccf01f5842064fad379ab \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 4b00d4c386..4fc2d1f7f3 100644 --- a/src/alter.c +++ b/src/alter.c @@ -77,12 +77,12 @@ static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){ ** Generate code to reload the schema for database iDb. And, if iDb!=1, for ** the temp database as well. */ -static void renameReloadSchema(Parse *pParse, int iDb){ +static void renameReloadSchema(Parse *pParse, int iDb, u16 p5){ Vdbe *v = pParse->pVdbe; if( v ){ sqlite3ChangeCookie(pParse, iDb); - sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, iDb, 0); - if( iDb!=1 ) sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, 1, 0); + sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, iDb, 0, p5); + if( iDb!=1 ) sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, 1, 0, p5); } } @@ -250,7 +250,7 @@ void sqlite3AlterRenameTable( } #endif - renameReloadSchema(pParse, iDb); + renameReloadSchema(pParse, iDb, INITFLAG_AlterRename); renameTestSchema(pParse, zDb, iDb==1); exit_rename_table: @@ -413,7 +413,7 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ } /* Reload the table definition */ - renameReloadSchema(pParse, iDb); + renameReloadSchema(pParse, iDb, INITFLAG_AlterRename); } /* @@ -513,7 +513,7 @@ exit_begin_add_column: ** Or, if pTab is not a view or virtual table, zero is returned. */ #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) -static int isRealTable(Parse *pParse, Table *pTab){ +static int isRealTable(Parse *pParse, Table *pTab, int bDrop){ const char *zType = 0; #ifndef SQLITE_OMIT_VIEW if( pTab->pSelect ){ @@ -526,15 +526,16 @@ static int isRealTable(Parse *pParse, Table *pTab){ } #endif if( zType ){ - sqlite3ErrorMsg( - pParse, "cannot rename columns of %s \"%s\"", zType, pTab->zName + sqlite3ErrorMsg(pParse, "cannot %s %s \"%s\"", + (bDrop ? "drop column from" : "rename columns of"), + zType, pTab->zName ); return 1; } return 0; } #else /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */ -# define isRealTable(x,y) (0) +# define isRealTable(x,y,z) (0) #endif /* @@ -563,7 +564,7 @@ void sqlite3AlterRenameColumn( /* Cannot alter a system table */ if( SQLITE_OK!=isAlterableTable(pParse, pTab) ) goto exit_rename_column; - if( SQLITE_OK!=isRealTable(pParse, pTab) ) goto exit_rename_column; + if( SQLITE_OK!=isRealTable(pParse, pTab, 0) ) goto exit_rename_column; /* Which schema holds the table to be altered */ iSchema = sqlite3SchemaToIndex(db, pTab->pSchema); @@ -617,7 +618,7 @@ void sqlite3AlterRenameColumn( ); /* Drop and reload the database schema. */ - renameReloadSchema(pParse, iSchema); + renameReloadSchema(pParse, iSchema, INITFLAG_AlterRename); renameTestSchema(pParse, zDb, iSchema==1); exit_rename_column: @@ -1762,12 +1763,17 @@ static void renameTableTest( } /* +** The implementation of internal UDF sqlite_drop_column(). +** ** Arguments: ** ** argv[0]: An integer - the index of the schema containing the table ** argv[1]: CREATE TABLE statement to modify. ** argv[2]: An integer - the index of the column to remove. ** argv[3]: Byte offset of first byte after last column definition in argv[1] +** +** The value returned is a string containing the CREATE TABLE statement +** with column argv[2] removed. */ static void dropColumnFunc( sqlite3_context *context, @@ -1809,21 +1815,21 @@ drop_column_done: renameParseCleanup(&sParse); } +/* +** This function is called by the parser upon parsing an +** +** ALTER TABLE pSrc DROP COLUMN pName +** +** statement. Argument pSrc contains the possibly qualified name of the +** table being edited, and token pName the name of the column to drop. +*/ void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, Token *pName){ - Table *pTab; - int i; - int iSchema = 0; - const char *zDb = 0; - sqlite3 *db = pParse->db; - char *zCol = 0; - int iCol = 0; - Vdbe *v; - int iCur; - int addr; - int reg; - int regRec; - Index *pIdx; - Index *pPk = 0; + sqlite3 *db = pParse->db; /* Database handle */ + Table *pTab; /* Table to modify */ + int iDb; /* Index of db containing pTab in aDb[] */ + const char *zDb; /* Database containing pTab ("main" etc.) */ + char *zCol = 0; /* Name of column to drop */ + int iCol; /* Index of column zCol in pTab->aCol[] */ /* Look up the table being altered. */ assert( pParse->pNewTable==0 ); @@ -1832,26 +1838,10 @@ void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, Token *pName){ pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); if( !pTab ) goto exit_drop_column; - /* Which schema holds the table to be altered */ - iSchema = sqlite3SchemaToIndex(db, pTab->pSchema); - assert( iSchema>=0 ); - zDb = db->aDb[iSchema].zDbSName; - -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( IsVirtual(pTab) ){ - sqlite3ErrorMsg(pParse, "virtual tables may not be altered"); - goto exit_drop_column; - } -#endif - - /* Make sure this is not an attempt to ALTER a view. */ - if( pTab->pSelect ){ - sqlite3ErrorMsg(pParse, "cannot drop a column from a view"); - goto exit_drop_column; - } - if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){ - goto exit_drop_column; - } + /* Make sure this is not an attempt to ALTER a view, virtual table or + ** system table. */ + if( SQLITE_OK!=isAlterableTable(pParse, pTab) ) goto exit_drop_column; + if( SQLITE_OK!=isRealTable(pParse, pTab, 1) ) goto exit_drop_column; /* Find the index of the column being dropped. */ zCol = sqlite3NameFromToken(db, pName); @@ -1867,65 +1857,74 @@ void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, Token *pName){ /* Do not allow the user to drop a PRIMARY KEY column or a column ** constrained by a UNIQUE constraint. */ - if( pTab->iPKey==iCol ){ - sqlite3ErrorMsg(pParse, "cannot drop PRIMARY KEY column: \"%s\"", zCol); + if( pTab->aCol[iCol].colFlags & (COLFLAG_PRIMKEY|COLFLAG_UNIQUE) ){ + sqlite3ErrorMsg(pParse, "cannot drop %s column: \"%s\"", + (pTab->aCol[iCol].colFlags&COLFLAG_PRIMKEY) ? "PRIMARY KEY" : "UNIQUE", + zCol + ); goto exit_drop_column; } - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - int ii; - for(ii=0; iinKeyCol; ii++){ - if( iCol==pIdx->aiColumn[ii] - && sqlite3_strnicmp("sqlite_", pIdx->zName, 7)==0 - ){ - sqlite3ErrorMsg(pParse, "cannot drop %s column: \"%s\"", - pIdx->idxType==2 ? "PRIMARY KEY" : "UNIQUE", zCol - ); - goto exit_drop_column; - } - } - } + /* Edit the sqlite_schema table */ + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iDb>=0 ); + zDb = db->aDb[iDb].zDbSName; sqlite3NestedParse(pParse, "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET " "sql = sqlite_drop_column(%d, sql, %d, %d) " "WHERE (type=='table' AND tbl_name=%Q COLLATE nocase)" - , zDb, iSchema, iCol, pTab->addColOffset, pTab->zName + , zDb, iDb, iCol, pTab->addColOffset, pTab->zName ); /* Drop and reload the database schema. */ - renameReloadSchema(pParse, iSchema); - renameTestSchema(pParse, zDb, iSchema==1); + renameReloadSchema(pParse, iDb, INITFLAG_AlterDrop); + renameTestSchema(pParse, zDb, iDb==1); /* Edit rows of table on disk */ - v = sqlite3GetVdbe(pParse); - iCur = pParse->nTab++; - sqlite3OpenTable(pParse, iCur, iSchema, pTab, OP_OpenWrite); - addr = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); - reg = ++pParse->nMem; - pParse->nMem += pTab->nCol; - if( HasRowid(pTab) ){ - sqlite3VdbeAddOp2(v, OP_Rowid, iCur, reg); - }else{ - pPk = sqlite3PrimaryKeyIndex(pTab); - } - for(i=0; inCol; i++){ - if( i!=iCol ){ - int iPos = (pPk ? sqlite3TableColumnToIndex(pPk, i) : i); - int iColPos = (pPk ? sqlite3TableColumnToIndex(pPk, iCol) : iCol); - int regOut = reg+1+iPos-(iPos>iColPos); - sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, i, regOut); + if( (pTab->aCol[iCol].colFlags & COLFLAG_VIRTUAL)==0 ){ + int i; + int addr; + int reg; + int regRec; + Index *pPk = 0; + int nField = 0; /* Number of non-virtual columns after drop */ + int iCur; + Vdbe *v = sqlite3GetVdbe(pParse); + iCur = pParse->nTab++; + sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenWrite); + addr = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); + reg = ++pParse->nMem; + pParse->nMem += pTab->nCol; + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp2(v, OP_Rowid, iCur, reg); + }else{ + pPk = sqlite3PrimaryKeyIndex(pTab); + } + for(i=0; inCol; i++){ + if( i!=iCol && (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){ + int regOut; + if( pPk ){ + int iPos = sqlite3TableColumnToIndex(pPk, i); + int iColPos = sqlite3TableColumnToIndex(pPk, iCol); + regOut = reg+1+iPos-(iPos>iColPos); + }else{ + regOut = reg+1+nField; + } + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, i, regOut); + nField++; + } + } + regRec = reg + pTab->nCol; + sqlite3VdbeAddOp3(v, OP_MakeRecord, reg+1, nField, regRec); + if( pPk ){ + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iCur, regRec, reg+1, pPk->nKeyCol); + }else{ + sqlite3VdbeAddOp3(v, OP_Insert, iCur, regRec, reg); } - } - regRec = reg + pTab->nCol; - sqlite3VdbeAddOp3(v, OP_MakeRecord, reg+1, pTab->nCol-1, regRec); - if( HasRowid(pTab) ){ - sqlite3VdbeAddOp3(v, OP_Insert, iCur, regRec, reg); - }else{ - sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iCur, regRec, reg+1, pPk->nKeyCol); - } - sqlite3VdbeAddOp2(v, OP_Next, iCur, addr+1); - sqlite3VdbeJumpHere(v, addr); + sqlite3VdbeAddOp2(v, OP_Next, iCur, addr+1); + sqlite3VdbeJumpHere(v, addr); + } exit_drop_column: sqlite3DbFree(db, zCol); diff --git a/src/build.c b/src/build.c index f5c796fac3..065b50c082 100644 --- a/src/build.c +++ b/src/build.c @@ -2638,7 +2638,7 @@ void sqlite3EndTable( /* Reparse everything to update our internal data structures */ sqlite3VdbeAddParseSchemaOp(v, iDb, - sqlite3MPrintf(db, "tbl_name='%q' AND type!='trigger'", p->zName)); + sqlite3MPrintf(db, "tbl_name='%q' AND type!='trigger'", p->zName),0); } /* Add the table to the in-memory representation of the database. @@ -4126,7 +4126,7 @@ void sqlite3CreateIndex( sqlite3RefillIndex(pParse, pIndex, iMem); sqlite3ChangeCookie(pParse, iDb); sqlite3VdbeAddParseSchemaOp(v, iDb, - sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName)); + sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName), 0); sqlite3VdbeAddOp2(v, OP_Expire, 0, 1); } diff --git a/src/prepare.c b/src/prepare.c index 87c1ab9368..4888744a89 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -21,7 +21,7 @@ */ static void corruptSchema( InitData *pData, /* Initialization context */ - const char *zObj, /* Object being parsed at the point of error */ + char **azObj, /* Type and name of object being parsed */ const char *zExtra /* Error information */ ){ sqlite3 *db = pData->db; @@ -29,14 +29,18 @@ static void corruptSchema( pData->rc = SQLITE_NOMEM_BKPT; }else if( pData->pzErrMsg[0]!=0 ){ /* A error message has already been generated. Do not overwrite it */ - }else if( pData->mInitFlags & INITFLAG_AlterTable ){ - *pData->pzErrMsg = sqlite3DbStrDup(db, zExtra); + }else if( pData->mInitFlags & (INITFLAG_AlterRename|INITFLAG_AlterDrop) ){ + *pData->pzErrMsg = sqlite3MPrintf(db, + "error in %s %s after %s: %s", azObj[0], azObj[1], + (pData->mInitFlags & INITFLAG_AlterRename) ? "rename" : "drop column", + zExtra + ); pData->rc = SQLITE_ERROR; }else if( db->flags & SQLITE_WriteSchema ){ pData->rc = SQLITE_CORRUPT_BKPT; }else{ char *z; - if( zObj==0 ) zObj = "?"; + const char *zObj = azObj[1] ? azObj[1] : "?"; z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj); if( zExtra && zExtra[0] ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra); *pData->pzErrMsg = z; @@ -94,14 +98,14 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ db->mDbFlags |= DBFLAG_EncodingFixed; pData->nInitRow++; if( db->mallocFailed ){ - corruptSchema(pData, argv[1], 0); + corruptSchema(pData, argv, 0); return 1; } assert( iDb>=0 && iDbnDb ); if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */ if( argv[3]==0 ){ - corruptSchema(pData, argv[1], 0); + corruptSchema(pData, argv, 0); }else if( argv[4] && 'c'==sqlite3UpperToLower[(unsigned char)argv[4][0]] && 'r'==sqlite3UpperToLower[(unsigned char)argv[4][1]] ){ @@ -126,7 +130,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ || (db->init.newTnum>pData->mxPage && pData->mxPage>0) ){ if( sqlite3Config.bExtraSchemaChecks ){ - corruptSchema(pData, argv[1], "invalid rootpage"); + corruptSchema(pData, argv, "invalid rootpage"); } } db->init.orphanTrigger = 0; @@ -145,13 +149,13 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ if( rc==SQLITE_NOMEM ){ sqlite3OomFault(db); }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){ - corruptSchema(pData, argv[1], sqlite3_errmsg(db)); + corruptSchema(pData, argv, sqlite3_errmsg(db)); } } } sqlite3_finalize(pStmt); }else if( argv[1]==0 || (argv[4]!=0 && argv[4][0]!=0) ){ - corruptSchema(pData, argv[1], 0); + corruptSchema(pData, argv, 0); }else{ /* If the SQL column is blank it means this is an index that ** was created to be the PRIMARY KEY or to fulfill a UNIQUE @@ -162,7 +166,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ Index *pIndex; pIndex = sqlite3FindIndex(db, argv[1], db->aDb[iDb].zDbSName); if( pIndex==0 ){ - corruptSchema(pData, argv[1], "orphan index"); + corruptSchema(pData, argv, "orphan index"); }else if( sqlite3GetUInt32(argv[3],&pIndex->tnum)==0 || pIndex->tnum<2 @@ -170,7 +174,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ || sqlite3IndexHasDuplicateRootPage(pIndex) ){ if( sqlite3Config.bExtraSchemaChecks ){ - corruptSchema(pData, argv[1], "invalid rootpage"); + corruptSchema(pData, argv, "invalid rootpage"); } } } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 9c09b24aca..850396ced3 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3711,7 +3711,8 @@ typedef struct { /* ** Allowed values for mInitFlags */ -#define INITFLAG_AlterTable 0x0001 /* This is a reparse after ALTER TABLE */ +#define INITFLAG_AlterRename 0x0001 /* Reparse after a RENAME */ +#define INITFLAG_AlterDrop 0x0002 /* Reparse after a DROP COLUMN */ /* ** Structure containing global configuration data for the SQLite library. diff --git a/src/trigger.c b/src/trigger.c index 1d4c2790c3..689c7c741e 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -356,7 +356,7 @@ void sqlite3FinishTrigger( sqlite3DbFree(db, z); sqlite3ChangeCookie(pParse, iDb); sqlite3VdbeAddParseSchemaOp(v, iDb, - sqlite3MPrintf(db, "type='trigger' AND name='%q'", zName)); + sqlite3MPrintf(db, "type='trigger' AND name='%q'", zName), 0); } if( db->init.busy ){ diff --git a/src/vdbe.c b/src/vdbe.c index 97cd696de3..153ed40b75 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6330,7 +6330,7 @@ case OP_ParseSchema: { if( pOp->p4.z==0 ){ sqlite3SchemaClear(db->aDb[iDb].pSchema); db->mDbFlags &= ~DBFLAG_SchemaKnownOk; - rc = sqlite3InitOne(db, iDb, &p->zErrMsg, INITFLAG_AlterTable); + rc = sqlite3InitOne(db, iDb, &p->zErrMsg, pOp->p5); db->mDbFlags |= DBFLAG_SchemaChange; p->expired = 0; }else diff --git a/src/vdbe.h b/src/vdbe.h index 17f11fdd77..3257ff68a1 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -223,7 +223,7 @@ VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp,int iLineno); #else # define sqlite3ExplainBreakpoint(A,B) /*no-op*/ #endif -void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*); +void sqlite3VdbeAddParseSchemaOp(Vdbe*, int, char*, u16); void sqlite3VdbeChangeOpcode(Vdbe*, int addr, u8); void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1); void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 7ee4f629e0..ede652dfac 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -471,9 +471,10 @@ void sqlite3VdbeExplainPop(Parse *pParse){ ** The zWhere string must have been obtained from sqlite3_malloc(). ** This routine will take ownership of the allocated memory. */ -void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere){ +void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere, u16 p5){ int j; sqlite3VdbeAddOp4(p, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC); + sqlite3VdbeChangeP5(p, p5); for(j=0; jdb->nDb; j++) sqlite3VdbeUsesBtree(p, j); sqlite3MayAbort(p->pParse); } diff --git a/src/vtab.c b/src/vtab.c index 400ae40968..0da5518b15 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -489,7 +489,7 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ sqlite3VdbeAddOp0(v, OP_Expire); zWhere = sqlite3MPrintf(db, "name=%Q AND sql=%Q", pTab->zName, zStmt); - sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere); + sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere, 0); sqlite3DbFree(db, zStmt); iReg = ++pParse->nMem; diff --git a/test/alterdropcol.test b/test/alterdropcol.test index 7bb5977054..ef3e97dea7 100644 --- a/test/alterdropcol.test +++ b/test/alterdropcol.test @@ -26,6 +26,9 @@ do_execsql_test 1.0 { CREATE TABLE t2(x INTEGER PRIMARY KEY, y, z UNIQUE); CREATE INDEX t2y ON t2(y); + + CREATE TABLE t3(q, r, s); + CREATE INDEX t3rs ON t3(r+s); } do_catchsql_test 1.1 { @@ -34,7 +37,7 @@ do_catchsql_test 1.1 { do_catchsql_test 1.2 { ALTER TABLE v1 DROP COLUMN c; -} {1 {cannot drop a column from a view}} +} {1 {cannot drop column from view "v1"}} ifcapable fts5 { do_execsql_test 1.3.1 { @@ -42,7 +45,7 @@ ifcapable fts5 { } do_catchsql_test 1.3.2 { ALTER TABLE ft1 DROP COLUMN two; - } {1 {virtual tables may not be altered}} + } {1 {cannot drop column from virtual table "ft1"}} } do_catchsql_test 1.4 { @@ -67,6 +70,10 @@ do_execsql_test 1.7.2 { SELECT sql FROM sqlite_schema WHERE name = 't1' } {{CREATE TABLE t1(a)}} +do_catchsql_test 1.7.3 { + ALTER TABLE t1 DROP COLUMN a; +} {1 {error in table t1 after drop column: near ")": syntax error}} + do_catchsql_test 1.8 { ALTER TABLE t2 DROP COLUMN z @@ -78,7 +85,11 @@ do_catchsql_test 1.9 { do_catchsql_test 1.10 { ALTER TABLE t2 DROP COLUMN y -} {1 {cannot drop indexed column: "y"}} +} {1 {error in index t2y after drop column: no such column: y}} + +do_catchsql_test 1.11 { + ALTER TABLE t3 DROP COLUMN s +} {1 {error in index t3rs after drop column: no such column: s}} #------------------------------------------------------------------------- @@ -109,5 +120,95 @@ foreach {tn wo} { } }]} +#------------------------------------------------------------------------- +reset_db + +do_execsql_test 3.0 { + CREATE TABLE t12(a, b, c, CHECK(c>10)); + CREATE TABLE t13(a, b, c CHECK(c>10)); +} +do_catchsql_test 3.1 { + ALTER TABLE t12 DROP COLUMN c; +} {1 {error in table t12 after drop column: no such column: c}} + +do_catchsql_test 3.2 { + ALTER TABLE t13 DROP COLUMN c; +} {0 {}} + +#------------------------------------------------------------------------- +# Test that generated columns can be dropped. And that other columns from +# tables that contain generated columns can be dropped. +# +foreach {tn wo vs} { + 1 "" "" + 2 "" VIRTUAL + 3 "" STORED + 4 "WITHOUT ROWID" STORED + 5 "WITHOUT ROWID" VIRTUAL +} { + reset_db + + do_execsql_test 4.$tn.0 " + CREATE TABLE 'my table'(a, b PRIMARY KEY, c AS (a+b) $vs, d) $wo + " + do_execsql_test 4.$tn.1 { + INSERT INTO "my table"(a, b, d) VALUES(1, 2, 'hello'); + INSERT INTO "my table"(a, b, d) VALUES(3, 4, 'world'); + + SELECT * FROM "my table" + } { + 1 2 3 hello + 3 4 7 world + } + + do_execsql_test 4.$tn.2 { + ALTER TABLE "my table" DROP COLUMN c; + } + do_execsql_test 4.$tn.3 { + SELECT * FROM "my table" + } { + 1 2 hello + 3 4 world + } + + do_execsql_test 4.$tn.4 " + CREATE TABLE x1(a, b, c PRIMARY KEY, d AS (b+c) $vs, e) $wo + " + do_execsql_test 4.$tn.5 { + INSERT INTO x1(a, b, c, e) VALUES(1, 2, 3, 4); + INSERT INTO x1(a, b, c, e) VALUES(5, 6, 7, 8); + INSERT INTO x1(a, b, c, e) VALUES(9, 10, 11, 12); + SELECT * FROM x1; + } { + 1 2 3 5 4 + 5 6 7 13 8 + 9 10 11 21 12 + } + + do_execsql_test 4.$tn.6 { + ALTER TABLE x1 DROP COLUMN a + } + do_execsql_test 4.$tn.7 { + SELECT * FROM x1 + } { + 2 3 5 4 + 6 7 13 8 + 10 11 21 12 + } + do_execsql_test 4.$tn.8 { + ALTER TABLE x1 DROP COLUMN e + } + do_execsql_test 4.$tn.9 { + SELECT * FROM x1 + } { + 2 3 5 + 6 7 13 + 10 11 21 + } +} + + + finish_test + diff --git a/test/alterlegacy.test b/test/alterlegacy.test index 47d8bcfba9..dfa1716467 100644 --- a/test/alterlegacy.test +++ b/test/alterlegacy.test @@ -40,7 +40,7 @@ do_execsql_test 1.1 { # slightly different - it rejects the change and rolls back the transaction. do_catchsql_test 1.2 { ALTER TABLE t1 RENAME TO t1new; -} {1 {no such column: t1.a}} +} {1 {error in table t1new after rename: no such column: t1.a}} do_execsql_test 1.3 { CREATE TABLE t3(c, d); @@ -59,7 +59,7 @@ do_execsql_test 1.4 { do_catchsql_test 1.3 { ALTER TABLE t2 RENAME TO t2new; -} {1 {no such column: t2.b}} +} {1 {error in index t2expr after rename: no such column: t2.b}} do_execsql_test 1.4 { SELECT sql FROM sqlite_master } { From c2a878ed0ad5e22d84848af61b45cb8293450fd6 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 17 Feb 2021 20:46:44 +0000 Subject: [PATCH 201/257] Fix a problem with OOM error handling in the new code on this branch. FossilOrigin-Name: ea999c9db59e4193b306a2e1b15fc94f8f04cb05e852bb0d068b7d5243a0849b --- manifest | 13 +++++++------ manifest.uuid | 2 +- src/alter.c | 4 ++-- test/altermalloc3.test | 40 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 9 deletions(-) create mode 100644 test/altermalloc3.test diff --git a/manifest b/manifest index 3b9c2a45cf..86e0edd9a2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\strunk\schanges\sinto\sthis\sbranch. -D 2021-02-17T20:19:13.331 +C Fix\sa\sproblem\swith\sOOM\serror\shandling\sin\sthe\snew\scode\son\sthis\sbranch. +D 2021-02-17T20:46:44.173 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c e4bb151562fb0de03dc89964c55d89ef06da4f1cbd6521ed166bd4ec7eaa66f8 +F src/alter.c d56ceae00c743ef991e5ab1e9be2095a441dcee085bccf8795eba3da71b4d85f F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c F src/attach.c e80162a47411f296bea550ed8fafd730481f4aa71e89ece23ba9c957eed15d4a F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 @@ -651,6 +651,7 @@ F test/alterdropcol.test 1d9577320aa1b501ebc44de02b7c101789bca9fb6fbbb393c99d243 F test/alterlegacy.test f38c6d06cda39e1f7b955bbce57f2e3ef5b7cb566d3d1234502093e228c15811 F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9 F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b +F test/altermalloc3.test 2c7bbd8cf3e9c4a91e28675bb62bcc2ef70f227967fa74349f03d9f4642f0615 F test/altertab.test 6d7bbac2c4a6ef71b775094a3298fa3a92274d95034ee23157ffba92768e47e6 F test/altertab2.test b0d62f323ca5dab42b0bc028c52e310ebdd13e655e8fac070fe622bad7852c2b F test/altertab3.test 2b82fa2236a3a91553d53ae5555d8e723c7eec174c41f1fa62ff497355398479 @@ -1901,7 +1902,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 10538ec6fc1642dfc2ca6cef06ce6cb9e124847b421ccf01f5842064fad379ab c46a94a624c2cc6c49ac916a206a913081e1628c24805987cabc75c9057ea36b -R cd9a0e3d809cc9e7ce63f07940cfcccd +P 0cd5e2f9ce181f2c940ffca6fe69fda84f452613e66463d0d7c7413fc11b9772 +R e80f4b5b5082fe2df5d466ff5786649a U dan -Z a10b1b1ec1f77c18dc4beea8a7cf3e36 +Z a20fda248d094f1d6381bdbf1b68230b diff --git a/manifest.uuid b/manifest.uuid index 057bbf38ad..96da958def 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0cd5e2f9ce181f2c940ffca6fe69fda84f452613e66463d0d7c7413fc11b9772 \ No newline at end of file +ea999c9db59e4193b306a2e1b15fc94f8f04cb05e852bb0d068b7d5243a0849b \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 4fc2d1f7f3..d48b5ec919 100644 --- a/src/alter.c +++ b/src/alter.c @@ -1807,7 +1807,7 @@ static void dropColumnFunc( while( pCol->t.z[0]!=',' && pCol->t.z[1]!='(' ) pCol->t.z--; } - zNew = sqlite3_mprintf("%.*s%s", pCol->t.z-zSql, zSql, zEnd); + zNew = sqlite3MPrintf(db, "%.*s%s", pCol->t.z-zSql, zSql, zEnd); sqlite3_result_text(context, zNew, -1, SQLITE_TRANSIENT); sqlite3_free(zNew); @@ -1881,7 +1881,7 @@ void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, Token *pName){ renameTestSchema(pParse, zDb, iDb==1); /* Edit rows of table on disk */ - if( (pTab->aCol[iCol].colFlags & COLFLAG_VIRTUAL)==0 ){ + if( pParse->nErr==0 && (pTab->aCol[iCol].colFlags & COLFLAG_VIRTUAL)==0 ){ int i; int addr; int reg; diff --git a/test/altermalloc3.test b/test/altermalloc3.test new file mode 100644 index 0000000000..d84f6bbc94 --- /dev/null +++ b/test/altermalloc3.test @@ -0,0 +1,40 @@ +# 2021 February 18 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#************************************************************************* +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/malloc_common.tcl +set testprefix altermalloc3 + +# If SQLITE_OMIT_ALTERTABLE is defined, omit this file. +ifcapable !altertable { + finish_test + return +} + +do_execsql_test 1.0 { + CREATE TABLE t1(a, b, c, d, PRIMARY KEY(d, b)) WITHOUT ROWID; + INSERT INTO t1 VALUES(1, 2, 3, 4); +} +faultsim_save_and_close + +do_faultsim_test 1 -prep { + faultsim_restore_and_reopen +} -body { + execsql { ALTER TABLE t1 DROP COLUMN c } +} -test { + faultsim_test_result {0 {}} +} + + +finish_test + From c54246ffdf51ae0af4d9e39c653571e6e6586cc6 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 17 Feb 2021 21:13:14 +0000 Subject: [PATCH 202/257] Use the sqlite3ParserAddCleanup() mechanism to ensure that the AggInfo structure associated with an aggregate query is deallocated, for a performance increase and size reduction. FossilOrigin-Name: 7a1399671fa10c64d5358cc4d364d24c643fe9dd8da923356462267ee7962f61 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/prepare.c | 17 +---------------- src/select.c | 17 ++++++++++++++--- src/sqliteInt.h | 2 -- 5 files changed, 24 insertions(+), 30 deletions(-) diff --git a/manifest b/manifest index e7f230bfd2..e3cf8afbaf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\s".once"\sand\s".output"\scommands\sin\sthe\sCLI\sso\sthat\sif\sthe\nfilename\sargument\sbegins\swith\s"|"\sthe\sname\sbecomes\sthe\sconcatenation\nof\sall\ssubsequent\sarguments.\s\sHence,\scommands\slike\s".once\s|\sopen\s-f"\sbecome\npossible\swithout\sthe\sneed\sfor\squotes. -D 2021-02-17T13:19:22.550 +C Use\sthe\ssqlite3ParserAddCleanup()\smechanism\sto\sensure\sthat\sthe\sAggInfo\nstructure\sassociated\swith\san\saggregate\squery\sis\sdeallocated,\sfor\sa\sperformance\nincrease\sand\ssize\sreduction. +D 2021-02-17T21:13:14.431 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -536,17 +536,17 @@ F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a F src/pragma.c 6daaaecc26a4b09481d21722525b079ce756751a43a79cc1d8f122d686806193 F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf -F src/prepare.c f288cbc35f79eb32e162de7e80a63ebe00d80e639dcfac071bee11570cbdb16f +F src/prepare.c a25c7df3a71be19c31231d59d0694e950183837fc54b1828549c5a766538fcf7 F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 172d0f27c021b1d572e73b6f04f3e2695f2932233d3f5e675bd85b028fa2fb75 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c d009aafcd9304b8406809fc808ce8c2cd55471552d242b98bd3006d0ad55cd12 +F src/select.c 8acabad7dd5f2843b834d59a268aa186c987e469c13a777b6c62be35f2f17fad F src/shell.c.in 844417f84df1f6c4fce1c815629a888cfdcf219e86513e9c332bbcc38832f477 F src/sqlite.h.in 8855a19f37ade8dad189a9e48233a2ebe1b46faf469c7eb0906a654e252dcc57 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h 4cb469678a0dbf814e4efbde4488a0161a5398e9a63141830d9f676b4e9fb0cc +F src/sqliteInt.h 2b9857cce5da2ca42496cbe1f82c8565543e293c69a284659b9aebbd47652dfc F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1900,7 +1900,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 00bead3931135af80475c22f08cbb26c914518e8f2c7e73c2b8be1cee4ac4d5e -R c958a1f70e224efabdacd339f843bfe0 +P c46a94a624c2cc6c49ac916a206a913081e1628c24805987cabc75c9057ea36b +R 7e862b26b0bc3ecb89f295cd752077f2 U drh -Z 21b3dfef27853d212520b4c1b1451b1a +Z 8efe4ae08dfd69f1aac139f8c3069d98 diff --git a/manifest.uuid b/manifest.uuid index 323618e653..0ab3df8614 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c46a94a624c2cc6c49ac916a206a913081e1628c24805987cabc75c9057ea36b \ No newline at end of file +7a1399671fa10c64d5358cc4d364d24c643fe9dd8da923356462267ee7962f61 \ No newline at end of file diff --git a/src/prepare.c b/src/prepare.c index 87c1ab9368..a990350223 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -550,31 +550,16 @@ int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){ return i; } -/* -** Deallocate a single AggInfo object -*/ -static void agginfoFree(sqlite3 *db, AggInfo *p){ - sqlite3DbFree(db, p->aCol); - sqlite3DbFree(db, p->aFunc); - sqlite3DbFree(db, p); -} - /* ** Free all memory allocations in the pParse object */ void sqlite3ParserReset(Parse *pParse){ sqlite3 *db = pParse->db; - AggInfo *pThis = pParse->pAggList; - while( pThis ){ - AggInfo *pNext = pThis->pNext; - agginfoFree(db, pThis); - pThis = pNext; - } while( pParse->pCleanup ){ ParseCleanup *pCleanup = pParse->pCleanup; pParse->pCleanup = pCleanup->pNext; pCleanup->xCleanup(db, pCleanup->pPtr); - sqlite3DbFree(db, pCleanup); + sqlite3DbFreeNN(db, pCleanup); } sqlite3DbFree(db, pParse->aLabel); if( pParse->pConstExpr ){ diff --git a/src/select.c b/src/select.c index 49a36875fe..4a969caf2f 100644 --- a/src/select.c +++ b/src/select.c @@ -5793,6 +5793,15 @@ static struct SrcList_item *isSelfJoinView( return 0; } +/* +** Deallocate a single AggInfo object +*/ +static void agginfoFree(sqlite3 *db, AggInfo *p){ + sqlite3DbFree(db, p->aCol); + sqlite3DbFree(db, p->aFunc); + sqlite3DbFreeNN(db, p); +} + #ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION /* ** Attempt to transform a query of the form @@ -6537,11 +6546,13 @@ int sqlite3Select( ** SELECT statement. */ pAggInfo = sqlite3DbMallocZero(db, sizeof(*pAggInfo) ); - if( pAggInfo==0 ){ + if( pAggInfo ){ + sqlite3ParserAddCleanup(pParse, + (void(*)(sqlite3*,void*))agginfoFree, pAggInfo); + } + if( db->mallocFailed ){ goto select_end; } - pAggInfo->pNext = pParse->pAggList; - pParse->pAggList = pAggInfo; pAggInfo->selId = p->selId; memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 17b1cb415d..b1d9bab492 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2591,7 +2591,6 @@ struct AggInfo { } *aFunc; int nFunc; /* Number of entries in aFunc[] */ u32 selId; /* Select to which this AggInfo belongs */ - AggInfo *pNext; /* Next in list of them all */ }; /* @@ -3427,7 +3426,6 @@ struct Parse { Parse *pToplevel; /* Parse structure for main program (or NULL) */ Table *pTriggerTab; /* Table triggers are being coded for */ Parse *pParentParse; /* Parent parser if this parser is nested */ - AggInfo *pAggList; /* List of all AggInfo objects */ union { int addrCrTab; /* Address of OP_CreateBtree on CREATE TABLE */ Returning *pReturning; /* The RETURNING clause */ From c7e93f58d500971f531215ea96ed99a92144acdf Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 18 Feb 2021 00:26:11 +0000 Subject: [PATCH 203/257] Performance optimization in the code generator for INSERT for the common case where the target table has neither generated nor hidden columns. Also fix a redundant (and thus unreachable) branch in the resolver. FossilOrigin-Name: 16ac213c57196361a9d14df4c0d1ccc6f67ac522365b345ea364d1aec61fa3f2 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/insert.c | 26 ++++++++++++++------------ src/resolve.c | 2 +- 4 files changed, 23 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index e3cf8afbaf..b519cd383c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\sthe\ssqlite3ParserAddCleanup()\smechanism\sto\sensure\sthat\sthe\sAggInfo\nstructure\sassociated\swith\san\saggregate\squery\sis\sdeallocated,\sfor\sa\sperformance\nincrease\sand\ssize\sreduction. -D 2021-02-17T21:13:14.431 +C Performance\soptimization\sin\sthe\scode\sgenerator\sfor\sINSERT\sfor\sthe\scommon\ncase\swhere\sthe\starget\stable\shas\sneither\sgenerated\snor\shidden\scolumns.\nAlso\sfix\sa\sredundant\s(and\sthus\sunreachable)\sbranch\sin\sthe\sresolver. +D 2021-02-18T00:26:11.149 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -502,7 +502,7 @@ 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 3d17e465c4cdb7e02e4b2a9d0a6cee08d23c478a01bd7eb5c5d4024fc70c5e5c +F src/insert.c aad00bdc7946606ddef5377b28f25b455d9953ca320881c95498dee42efae8f5 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 F src/main.c 1c5de7b3fabcdf05f4fe563aab5d81d175b89c67a8678a12ba86629356afa356 @@ -539,7 +539,7 @@ F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf F src/prepare.c a25c7df3a71be19c31231d59d0694e950183837fc54b1828549c5a766538fcf7 F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c 172d0f27c021b1d572e73b6f04f3e2695f2932233d3f5e675bd85b028fa2fb75 +F src/resolve.c 065d8ab56a0c6fcd70462d487527c45820ff45e5b7abc3f600f79ebfd0f890cd F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 8acabad7dd5f2843b834d59a268aa186c987e469c13a777b6c62be35f2f17fad F src/shell.c.in 844417f84df1f6c4fce1c815629a888cfdcf219e86513e9c332bbcc38832f477 @@ -1900,7 +1900,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 c46a94a624c2cc6c49ac916a206a913081e1628c24805987cabc75c9057ea36b -R 7e862b26b0bc3ecb89f295cd752077f2 +P 7a1399671fa10c64d5358cc4d364d24c643fe9dd8da923356462267ee7962f61 +R 2a75ab3203514692b6cbe52f335b0341 U drh -Z 8efe4ae08dfd69f1aac139f8c3069d98 +Z 1b7be3c7e4ab1fb3c1aac42d1ac5aa16 diff --git a/manifest.uuid b/manifest.uuid index 0ab3df8614..87ece08ade 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7a1399671fa10c64d5358cc4d364d24c643fe9dd8da923356462267ee7962f61 \ No newline at end of file +16ac213c57196361a9d14df4c0d1ccc6f67ac522365b345ea364d1aec61fa3f2 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 7522a72697..3469ee1ea0 100644 --- a/src/insert.c +++ b/src/insert.c @@ -930,19 +930,21 @@ void sqlite3Insert( } } #endif - } - /* Make sure the number of columns in the source data matches the number - ** of columns to be inserted into the table. - */ - for(i=0; inCol; i++){ - if( pTab->aCol[i].colFlags & COLFLAG_NOINSERT ) nHidden++; - } - if( pColumn==0 && nColumn && nColumn!=(pTab->nCol-nHidden) ){ - sqlite3ErrorMsg(pParse, - "table %S has %d columns but %d values were supplied", - pTabList, 0, pTab->nCol-nHidden, nColumn); - goto insert_cleanup; + /* Make sure the number of columns in the source data matches the number + ** of columns to be inserted into the table. + */ + if( IsVirtual(pTab) || (pTab->tabFlags & TF_HasGenerated)!=0 ){ + for(i=0; inCol; i++){ + if( pTab->aCol[i].colFlags & COLFLAG_NOINSERT ) nHidden++; + } + } + if( nColumn!=(pTab->nCol-nHidden) ){ + sqlite3ErrorMsg(pParse, + "table %S has %d columns but %d values were supplied", + pTabList, 0, pTab->nCol-nHidden, nColumn); + goto insert_cleanup; + } } if( pColumn!=0 && nColumn!=pColumn->nId ){ sqlite3ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId); diff --git a/src/resolve.c b/src/resolve.c index 4848e3cfa7..afb73664f8 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -82,7 +82,7 @@ static void resolveAlias( db = pParse->db; pDup = sqlite3ExprDup(db, pOrig, 0); if( pDup!=0 ){ - if( nSubquery ) incrAggFunctionDepth(pDup, nSubquery); + incrAggFunctionDepth(pDup, nSubquery); if( pExpr->op==TK_COLLATE ){ pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); } From 7b7a9cf263fa6f4c75d4468077a3d6ed7e8a6c42 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 18 Feb 2021 00:59:16 +0000 Subject: [PATCH 204/257] Performance optimization in the resolver. FossilOrigin-Name: 1aafb94d4e3f28a8322e5e43be737d84b1a09f0063408f4a466a6071fa95b39b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/resolve.c | 10 ++++++---- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index b519cd383c..9993f3d7c6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimization\sin\sthe\scode\sgenerator\sfor\sINSERT\sfor\sthe\scommon\ncase\swhere\sthe\starget\stable\shas\sneither\sgenerated\snor\shidden\scolumns.\nAlso\sfix\sa\sredundant\s(and\sthus\sunreachable)\sbranch\sin\sthe\sresolver. -D 2021-02-18T00:26:11.149 +C Performance\soptimization\sin\sthe\sresolver. +D 2021-02-18T00:59:16.830 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -539,7 +539,7 @@ F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf F src/prepare.c a25c7df3a71be19c31231d59d0694e950183837fc54b1828549c5a766538fcf7 F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c 065d8ab56a0c6fcd70462d487527c45820ff45e5b7abc3f600f79ebfd0f890cd +F src/resolve.c 52f81603cc40f78449f5b6aed96dbea9484b194771ecb1937e8c0f6547c186a0 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 8acabad7dd5f2843b834d59a268aa186c987e469c13a777b6c62be35f2f17fad F src/shell.c.in 844417f84df1f6c4fce1c815629a888cfdcf219e86513e9c332bbcc38832f477 @@ -1900,7 +1900,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 7a1399671fa10c64d5358cc4d364d24c643fe9dd8da923356462267ee7962f61 -R 2a75ab3203514692b6cbe52f335b0341 +P 16ac213c57196361a9d14df4c0d1ccc6f67ac522365b345ea364d1aec61fa3f2 +R 88777051eb54ed65a5d815fe0ac16f7f U drh -Z 1b7be3c7e4ab1fb3c1aac42d1ac5aa16 +Z 74868408efd584dc66181e50a9627e38 diff --git a/manifest.uuid b/manifest.uuid index 87ece08ade..29e0a2baca 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -16ac213c57196361a9d14df4c0d1ccc6f67ac522365b345ea364d1aec61fa3f2 \ No newline at end of file +1aafb94d4e3f28a8322e5e43be737d84b1a09f0063408f4a466a6071fa95b39b \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index afb73664f8..c1cabab75d 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -625,10 +625,12 @@ static int lookupName( /* Clean up and return */ - sqlite3ExprDelete(db, pExpr->pLeft); - pExpr->pLeft = 0; - sqlite3ExprDelete(db, pExpr->pRight); - pExpr->pRight = 0; + if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ + sqlite3ExprDelete(db, pExpr->pLeft); + pExpr->pLeft = 0; + sqlite3ExprDelete(db, pExpr->pRight); + pExpr->pRight = 0; + } pExpr->op = eNewExprOp; ExprSetProperty(pExpr, EP_Leaf); lookupname_end: From 6859d3245a4c628bc30ee22cfa2deb4bc80eef32 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 18 Feb 2021 01:02:03 +0000 Subject: [PATCH 205/257] Add missing VdbeCoverage() macros to some of the new RETURNING code. FossilOrigin-Name: 53a5390909822b3aef8c5f522144bc2e86cc31318b2d3e310a064ae7202b4a15 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 2 ++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 9993f3d7c6..fddc6b6c5f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimization\sin\sthe\sresolver. -D 2021-02-18T00:59:16.830 +C Add\smissing\sVdbeCoverage()\smacros\sto\ssome\sof\sthe\snew\sRETURNING\scode. +D 2021-02-18T01:02:03.701 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -485,7 +485,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 694020ad8a3af3d79b09f74c8f1421272a419cdea42a13401e3b0f7dea6e9c3e F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 -F src/build.c 1bae5588bfdf21bdf41e634f0a053d633fb1ae3a2896117b4eea76412b76c2e0 +F src/build.c c5f94b2a879f2a827accfe3f66facdb70558eafefa22d3614d5b72546c716667 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 @@ -1900,7 +1900,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 16ac213c57196361a9d14df4c0d1ccc6f67ac522365b345ea364d1aec61fa3f2 -R 88777051eb54ed65a5d815fe0ac16f7f +P 1aafb94d4e3f28a8322e5e43be737d84b1a09f0063408f4a466a6071fa95b39b +R 014c63d56957b1a4cbfecbd6b659f75e U drh -Z 74868408efd584dc66181e50a9627e38 +Z 0284a99401abab438415cb1d9101e226 diff --git a/manifest.uuid b/manifest.uuid index 29e0a2baca..02782b2eb6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1aafb94d4e3f28a8322e5e43be737d84b1a09f0063408f4a466a6071fa95b39b \ No newline at end of file +53a5390909822b3aef8c5f522144bc2e86cc31318b2d3e310a064ae7202b4a15 \ No newline at end of file diff --git a/src/build.c b/src/build.c index f5c796fac3..e3deb80c0f 100644 --- a/src/build.c +++ b/src/build.c @@ -163,12 +163,14 @@ void sqlite3FinishCoding(Parse *pParse){ addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, pReturning->iRetCur); + VdbeCoverage(v); reg = pReturning->iRetReg; for(i=0; inRetCol; i++){ sqlite3VdbeAddOp3(v, OP_Column, pReturning->iRetCur, i, reg+i); } sqlite3VdbeAddOp2(v, OP_ResultRow, reg, i); sqlite3VdbeAddOp2(v, OP_Next, pReturning->iRetCur, addrRewind+1); + VdbeCoverage(v); sqlite3VdbeJumpHere(v, addrRewind); } sqlite3VdbeAddOp0(v, OP_Halt); From fadc0e34beb88868dab7109a833f9c1552597662 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 18 Feb 2021 12:18:10 +0000 Subject: [PATCH 206/257] Ensure that the pre-update hook is invoked for INSERT operations on WITHOUT ROWID tables that use the xfer optimization. FossilOrigin-Name: 66bbad239b4527ac8ae8b487a0c71d88b1861a8dfe1edc25109600dc447c60c4 --- ext/session/sessionwor.test | 25 ++++++++++++- manifest | 18 +++++----- manifest.uuid | 2 +- src/insert.c | 70 ++++++++++++++++++++++++------------- test/hook.test | 42 ++++++++++++++++++++++ 5 files changed, 122 insertions(+), 35 deletions(-) diff --git a/ext/session/sessionwor.test b/ext/session/sessionwor.test index 0f0b429d7b..7d9e5c6a89 100644 --- a/ext/session/sessionwor.test +++ b/ext/session/sessionwor.test @@ -69,7 +69,9 @@ foreach {tn wo} { } { reset_db - do_execsql_test 2.$tn.0 "CREATE TABLE t1(a INTEGER PRIMARY KEY, b) $wo ;" + do_execsql_test 2.$tn.0.1 "CREATE TABLE t1(a INTEGER PRIMARY KEY, b) $wo ;" + do_execsql_test 2.$tn.0.2 "CREATE TABLE t2(a INTEGER PRIMARY KEY, b) $wo ;" + do_execsql_test 2.$tn.0.3 "CREATE TABLE t3(a INTEGER PRIMARY KEY, b) $wo ;" do_iterator_test 1.1 t1 { INSERT INTO t1 VALUES(1, 'two'); @@ -94,6 +96,27 @@ foreach {tn wo} { } { {DELETE t1 0 X. {i 1 t four} {}} } + + do_execsql_test 2.$tn.5 { + INSERT INTO t1 VALUES(1, 'one'); + INSERT INTO t1 VALUES(2, 'two'); + INSERT INTO t1 VALUES(3, 'three'); + } + + do_iterator_test 2.$tn.6 t2 { + INSERT INTO t2 SELECT a, b FROM t1 + } { + {INSERT t2 0 X. {} {i 1 t one}} + {INSERT t2 0 X. {} {i 2 t two}} + {INSERT t2 0 X. {} {i 3 t three}} + } + do_iterator_test 2.$tn.7 t3 { + INSERT INTO t3 SELECT * FROM t1 + } { + {INSERT t3 0 X. {} {i 1 t one}} + {INSERT t3 0 X. {} {i 2 t two}} + {INSERT t3 0 X. {} {i 3 t three}} + } } finish_test diff --git a/manifest b/manifest index fddc6b6c5f..9ccc0b72ac 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\smissing\sVdbeCoverage()\smacros\sto\ssome\sof\sthe\snew\sRETURNING\scode. -D 2021-02-18T01:02:03.701 +C Ensure\sthat\sthe\spre-update\shook\sis\sinvoked\sfor\sINSERT\soperations\son\sWITHOUT\sROWID\stables\sthat\suse\sthe\sxfer\soptimization. +D 2021-02-18T12:18:10.995 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -453,7 +453,7 @@ F ext/session/sessioninvert.test 04075517a9497a80d39c495ba6b44f3982c7371129b89e2 F ext/session/sessionmem.test f2a735db84a3e9e19f571033b725b0b2daf847f3f28b1da55a0c1a4e74f1de09 F ext/session/sessionrebase.test ccfa716b23bd1d3b03217ee58cfd90c78d4b99f53e6a9a2f05e82363b9142810 F ext/session/sessionstat1.test 218d351cf9fcd6648f125a26b607b140310160184723c2666091b54450a68fb5 -F ext/session/sessionwor.test 67b5ab91d4f93ce65ff1f58240ac5ddf73f8670facc1ffa49cef56293d52818d +F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc F ext/session/sqlite3session.c 1d0553077b55ffcfa69963c354e9bad3bace6ce79bbe7368e650c6ae1e106314 F ext/session/sqlite3session.h f53c99731882bf59c7362855cdeba176ce1fe8eeba089e38a8cce0172f8473aa F ext/session/test_session.c 93ca965112d2b4d9d669c9c0be6b1e52942a268796050a145612df1eee175ce0 @@ -502,7 +502,7 @@ 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 aad00bdc7946606ddef5377b28f25b455d9953ca320881c95498dee42efae8f5 +F src/insert.c 225c8776218d56f63d218579d753b528347f2138d828438de88cbde976da6d5e F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 F src/main.c 1c5de7b3fabcdf05f4fe563aab5d81d175b89c67a8678a12ba86629356afa356 @@ -1057,7 +1057,7 @@ F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 F test/having.test a89236dd8d55aa50c4805f82ac9daf64d477a44d712d8209c118978d0ca21ec9 F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751 F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711 -F test/hook.test e97382e68e4379838e888756d653afd159f5f14780315ff97b70360d3d8485bc +F test/hook.test bd7ea2e35951291705106295324a91b3bb455081c783e0f681ff4bc68468b8d2 F test/hook2.test b9ff3b8c6519fb67f33192f1afe86e7782ee4ac8 F test/icu.test 716a6b89fbabe5cc63e0cd4c260befb08fd7b9d761f04d43669233292f0753b1 F test/ieee754.test b0945d12be7d255f3dfa18e2511b17ca37e0edd2b803231c52d05b86c04ab26e @@ -1900,7 +1900,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 1aafb94d4e3f28a8322e5e43be737d84b1a09f0063408f4a466a6071fa95b39b -R 014c63d56957b1a4cbfecbd6b659f75e -U drh -Z 0284a99401abab438415cb1d9101e226 +P 53a5390909822b3aef8c5f522144bc2e86cc31318b2d3e310a064ae7202b4a15 +R 781eea4e5f846e02b7fa70a51cb3a0ee +U dan +Z 800c1b7cf896beb329dcd482f50ca3c5 diff --git a/manifest.uuid b/manifest.uuid index 02782b2eb6..7e8eb74db1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -53a5390909822b3aef8c5f522144bc2e86cc31318b2d3e310a064ae7202b4a15 \ No newline at end of file +66bbad239b4527ac8ae8b487a0c71d88b1861a8dfe1edc25109600dc447c60c4 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 3469ee1ea0..c7db81a4d4 100644 --- a/src/insert.c +++ b/src/insert.c @@ -2407,6 +2407,31 @@ void sqlite3SetMakeRecordP5(Vdbe *v, Table *pTab){ } #endif +/* +** Table pTab is a WITHOUT ROWID table that is being written to. The cursor +** number is iCur, and register regData contains the new record for the +** PK index. This function adds code to invoke the pre-update hook, +** if one is registered. +*/ +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK +static void codeWithoutRowidPreupdate( + Parse *pParse, /* Parse context */ + Table *pTab, /* Table being updated */ + int iCur, /* Cursor number for table */ + int regData /* Data containing new record */ +){ + Vdbe *v = pParse->pVdbe; + int r = sqlite3GetTempReg(pParse); + assert( !HasRowid(pTab) ); + sqlite3VdbeAddOp2(v, OP_Integer, 0, r); + sqlite3VdbeAddOp4(v, OP_Insert, iCur, regData, r, (char*)pTab, P4_TABLE); + sqlite3VdbeChangeP5(v, OPFLAG_ISNOOP); + sqlite3ReleaseTempReg(pParse, r); +} +#else +# define codeWithoutRowidPreupdate(a,b,c,d) +#endif + /* ** This routine generates code to finish the INSERT or UPDATE operation ** that was started by a prior call to sqlite3GenerateConstraintChecks. @@ -2455,17 +2480,9 @@ void sqlite3CompleteInsertion( assert( pParse->nested==0 ); pik_flags |= OPFLAG_NCHANGE; pik_flags |= (update_flags & OPFLAG_SAVEPOSITION); -#ifdef SQLITE_ENABLE_PREUPDATE_HOOK if( update_flags==0 ){ - int r = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp2(v, OP_Integer, 0, r); - sqlite3VdbeAddOp4(v, OP_Insert, - iIdxCur+i, aRegIdx[i], r, (char*)pTab, P4_TABLE - ); - sqlite3VdbeChangeP5(v, OPFLAG_ISNOOP); - sqlite3ReleaseTempReg(pParse, r); + codeWithoutRowidPreupdate(pParse, pTab, iIdxCur+i, aRegIdx[i]); } -#endif } sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i], aRegIdx[i]+1, @@ -2938,14 +2955,11 @@ static int xferOptimization( insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND|OPFLAG_PREFORMAT; } #ifdef SQLITE_ENABLE_PREUPDATE_HOOK - if( db->xPreUpdateCallback ){ - sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); - insFlags &= ~OPFLAG_PREFORMAT; - }else + sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); + insFlags &= ~OPFLAG_PREFORMAT; +#else + sqlite3VdbeAddOp3(v, OP_RowCell, iDest, iSrc, regRowid); #endif - { - sqlite3VdbeAddOp3(v, OP_RowCell, iDest, iSrc, regRowid); - } sqlite3VdbeAddOp4(v, OP_Insert, iDest, regData, regRowid, (char*)pDest, P4_TABLE); sqlite3VdbeChangeP5(v, insFlags); @@ -2986,20 +3000,28 @@ static int xferOptimization( ** might change the definition of a collation sequence and then run ** a VACUUM command. In that case keys may not be written in strictly ** sorted order. */ - for(i=0; inColumn; i++){ - const char *zColl = pSrcIdx->azColl[i]; - if( sqlite3_stricmp(sqlite3StrBINARY, zColl) ) break; - } - if( i==pSrcIdx->nColumn ){ - idxInsFlags = OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT; - sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest); - sqlite3VdbeAddOp2(v, OP_RowCell, iDest, iSrc); +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + if( (HasRowid(pDest) || !IsPrimaryKeyIndex(pDestIdx)) ) +#endif + { + for(i=0; inColumn; i++){ + const char *zColl = pSrcIdx->azColl[i]; + if( sqlite3_stricmp(sqlite3StrBINARY, zColl) ) break; + } + if( i==pSrcIdx->nColumn ){ + idxInsFlags = OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT; + sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest); + sqlite3VdbeAddOp2(v, OP_RowCell, iDest, iSrc); + } } }else if( !HasRowid(pSrc) && pDestIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){ idxInsFlags |= OPFLAG_NCHANGE; } if( idxInsFlags!=(OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT) ){ sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); + if( !HasRowid(pDest) && IsPrimaryKeyIndex(pDestIdx) ){ + codeWithoutRowidPreupdate(pParse, pDest, iDest, regData); + } } sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, regData); sqlite3VdbeChangeP5(v, idxInsFlags|OPFLAG_APPEND); diff --git a/test/hook.test b/test/hook.test index d137e9056f..5d6a354572 100644 --- a/test/hook.test +++ b/test/hook.test @@ -956,5 +956,47 @@ ifcapable analyze { }] } +#------------------------------------------------------------------------- +# Test that the pre-update hook is fired for INSERT statements that use +# the xfer optimization on without rowid tables. +# +reset_db +do_execsql_test 12.1 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); + CREATE TABLE t2(a INTEGER PRIMARY KEY, b) WITHOUT ROWID; + + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(3, 4); + INSERT INTO t2 VALUES(5, 6); + INSERT INTO t2 VALUES(7, 8); + + CREATE TABLE t3 (a INTEGER PRIMARY KEY, b) WITHOUT ROWID; +} + +db preupdate hook preupdate_cb +db update_hook update_cb + +proc preupdate_cb {args} { lappend ::res "preupdate" $args } +proc update_cb {args} { lappend ::res "update" $args } + +#set ::res [list] +#do_test 11.2 { +# execsql VACUUM +# set ::res +#} {} + +do_test 11.3 { + set ::res [list] + execsql { INSERT INTO t3 SELECT a, b FROM t2 } + set ::res +} {preupdate {INSERT main t3 0 0} preupdate {INSERT main t3 0 0}} + +do_test 11.4 { + execsql { DELETE FROM t3 } + set ::res [list] + execsql { INSERT INTO t3 SELECT * FROM t2 } + set ::res +} {preupdate {INSERT main t3 0 0} preupdate {INSERT main t3 0 0}} finish_test + From 39065807dd997113d2d88df1dd36a40da1e698d0 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 18 Feb 2021 14:27:43 +0000 Subject: [PATCH 207/257] Disable the optimization of [16ac213c57196361] when the SQLITE_ENABLE_HIDDEN_COLUMN compile-time option is used, as the optimization does not work in that case. FossilOrigin-Name: 5168b06bcf283ef64cb9fd76330a743baf8bb0cd747c14eae23e607e0491cbce --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/insert.c | 5 ++++- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 9ccc0b72ac..741a27dc2b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sthe\spre-update\shook\sis\sinvoked\sfor\sINSERT\soperations\son\sWITHOUT\sROWID\stables\sthat\suse\sthe\sxfer\soptimization. -D 2021-02-18T12:18:10.995 +C Disable\sthe\soptimization\sof\s[16ac213c57196361]\swhen\sthe\nSQLITE_ENABLE_HIDDEN_COLUMN\scompile-time\soption\sis\sused,\sas\sthe\soptimization\ndoes\snot\swork\sin\sthat\scase. +D 2021-02-18T14:27:43.194 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -502,7 +502,7 @@ 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 225c8776218d56f63d218579d753b528347f2138d828438de88cbde976da6d5e +F src/insert.c fdcd29544946ed7597471aaac3b50fea0836db91f49948e01390f8be48cdbd33 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 F src/main.c 1c5de7b3fabcdf05f4fe563aab5d81d175b89c67a8678a12ba86629356afa356 @@ -1900,7 +1900,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 53a5390909822b3aef8c5f522144bc2e86cc31318b2d3e310a064ae7202b4a15 -R 781eea4e5f846e02b7fa70a51cb3a0ee -U dan -Z 800c1b7cf896beb329dcd482f50ca3c5 +P 66bbad239b4527ac8ae8b487a0c71d88b1861a8dfe1edc25109600dc447c60c4 +R b3dd5e522fd45ccbd523cfd6d2ce1f5b +U drh +Z 4838bf50459457dc91014b363c54c8bb diff --git a/manifest.uuid b/manifest.uuid index 7e8eb74db1..5651beece7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -66bbad239b4527ac8ae8b487a0c71d88b1861a8dfe1edc25109600dc447c60c4 \ No newline at end of file +5168b06bcf283ef64cb9fd76330a743baf8bb0cd747c14eae23e607e0491cbce \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index c7db81a4d4..9746cef481 100644 --- a/src/insert.c +++ b/src/insert.c @@ -934,7 +934,10 @@ void sqlite3Insert( /* Make sure the number of columns in the source data matches the number ** of columns to be inserted into the table. */ - if( IsVirtual(pTab) || (pTab->tabFlags & TF_HasGenerated)!=0 ){ +#ifndef SQLITE_ENABLE_HIDDEN_COLUMNS + if( IsVirtual(pTab) || (pTab->tabFlags & TF_HasGenerated)!=0 ) +#endif + { for(i=0; inCol; i++){ if( pTab->aCol[i].colFlags & COLFLAG_NOINSERT ) nHidden++; } From 6f6e60ddb1a7311bba7b5dd5f060365bf50225ae Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 18 Feb 2021 15:45:34 +0000 Subject: [PATCH 208/257] Improvement to the INSERT optimization of check-in [16ac213c57196361] so that it works with SQLITE_ENABLE_HIDDEN_COLUMN but is also easier to maintain and a little faster as well. FossilOrigin-Name: f985a78ecc0c6d9ff671c730a109d97dc781b06e47a0ab03f441cea5d021a4c3 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/build.c | 1 + src/insert.c | 8 ++++---- src/select.c | 1 + src/sqliteInt.h | 15 +++++++++++---- src/vtab.c | 1 + 7 files changed, 29 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 741a27dc2b..d2cea81cb0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\sthe\soptimization\sof\s[16ac213c57196361]\swhen\sthe\nSQLITE_ENABLE_HIDDEN_COLUMN\scompile-time\soption\sis\sused,\sas\sthe\soptimization\ndoes\snot\swork\sin\sthat\scase. -D 2021-02-18T14:27:43.194 +C Improvement\sto\sthe\sINSERT\soptimization\sof\scheck-in\s[16ac213c57196361]\sso\nthat\sit\sworks\swith\sSQLITE_ENABLE_HIDDEN_COLUMN\sbut\sis\salso\seasier\sto\smaintain\nand\sa\slittle\sfaster\sas\swell. +D 2021-02-18T15:45:34.839 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -485,7 +485,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 694020ad8a3af3d79b09f74c8f1421272a419cdea42a13401e3b0f7dea6e9c3e F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 -F src/build.c c5f94b2a879f2a827accfe3f66facdb70558eafefa22d3614d5b72546c716667 +F src/build.c e50a6d7132b051b7d00c59a896e4889128a55c0f55f81c664da1906fbad51d1c F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 @@ -502,7 +502,7 @@ 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 fdcd29544946ed7597471aaac3b50fea0836db91f49948e01390f8be48cdbd33 +F src/insert.c c801ce88caadea239f890fdb744628f2da02a945aca600ccfde6988f7e2cd558 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 F src/main.c 1c5de7b3fabcdf05f4fe563aab5d81d175b89c67a8678a12ba86629356afa356 @@ -541,12 +541,12 @@ F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 52f81603cc40f78449f5b6aed96dbea9484b194771ecb1937e8c0f6547c186a0 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 8acabad7dd5f2843b834d59a268aa186c987e469c13a777b6c62be35f2f17fad +F src/select.c aa04743edeac1142f0a698ca4a3188795b826bd5ef46ea61f06897a4f71ad6b2 F src/shell.c.in 844417f84df1f6c4fce1c815629a888cfdcf219e86513e9c332bbcc38832f477 F src/sqlite.h.in 8855a19f37ade8dad189a9e48233a2ebe1b46faf469c7eb0906a654e252dcc57 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h 2b9857cce5da2ca42496cbe1f82c8565543e293c69a284659b9aebbd47652dfc +F src/sqliteInt.h 4d57a17d4697a6e7f992008f36a35852c2a6c3064992fbedf3f56b7bad9df027 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -623,7 +623,7 @@ F src/vdbemem.c 947f2a65910edb4014dc981d33e414a68c51f169f9df8c4c493a0ba840b6eb1f F src/vdbesort.c f5b5e473a7cee44e47a94817b042fd7172cf3aa2c0a7928a8339d612bcfdec5a F src/vdbetrace.c 666c6fd9f1b62be6999e072a45b913e3c2c3518bc60dfd4d54fe304130acb724 F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c -F src/vtab.c 81e1a336ba47eccc5cadb80de15f03afabd83c55ff9648e3a98d8988d4c264aa +F src/vtab.c b7773ffbde8d2b134fde8f7349c8d0a0503b308f77561acda7db975d3114d6a1 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 69e770e96fd56cc21608992bf2c6f1f3dc5cf2572d0495c6a643b06c3a679f14 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a @@ -1900,7 +1900,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 66bbad239b4527ac8ae8b487a0c71d88b1861a8dfe1edc25109600dc447c60c4 -R b3dd5e522fd45ccbd523cfd6d2ce1f5b +P 5168b06bcf283ef64cb9fd76330a743baf8bb0cd747c14eae23e607e0491cbce +R e1b8540e4a303e92cccaf5fd2962de4f U drh -Z 4838bf50459457dc91014b363c54c8bb +Z c7f2d82d7568a9beb226b994480e85d8 diff --git a/manifest.uuid b/manifest.uuid index 5651beece7..f2c6960a06 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5168b06bcf283ef64cb9fd76330a743baf8bb0cd747c14eae23e607e0491cbce \ No newline at end of file +f985a78ecc0c6d9ff671c730a109d97dc781b06e47a0ab03f441cea5d021a4c3 \ No newline at end of file diff --git a/src/build.c b/src/build.c index e3deb80c0f..3bb084cbf4 100644 --- a/src/build.c +++ b/src/build.c @@ -1264,6 +1264,7 @@ begin_table_error: void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){ if( sqlite3_strnicmp(pCol->zName, "__hidden__", 10)==0 ){ pCol->colFlags |= COLFLAG_HIDDEN; + if( pTab ) pTab->tabFlags |= TF_HasHidden; }else if( pTab && pCol!=pTab->aCol && (pCol[-1].colFlags & COLFLAG_HIDDEN) ){ pTab->tabFlags |= TF_OOOHidden; } diff --git a/src/insert.c b/src/insert.c index 9746cef481..a78150df39 100644 --- a/src/insert.c +++ b/src/insert.c @@ -934,10 +934,10 @@ void sqlite3Insert( /* Make sure the number of columns in the source data matches the number ** of columns to be inserted into the table. */ -#ifndef SQLITE_ENABLE_HIDDEN_COLUMNS - if( IsVirtual(pTab) || (pTab->tabFlags & TF_HasGenerated)!=0 ) -#endif - { + assert( TF_HasHidden==COLFLAG_HIDDEN ); + assert( TF_HasGenerated==COLFLAG_GENERATED ); + assert( COLFLAG_NOINSERT==(COLFLAG_GENERATED|COLFLAG_HIDDEN) ); + if( (pTab->tabFlags & (TF_HasGenerated|TF_HasHidden))!=0 ){ for(i=0; inCol; i++){ if( pTab->aCol[i].colFlags & COLFLAG_NOINSERT ) nHidden++; } diff --git a/src/select.c b/src/select.c index 4a969caf2f..9e275db712 100644 --- a/src/select.c +++ b/src/select.c @@ -2086,6 +2086,7 @@ void sqlite3SelectAddColumnTypeAndCollation( for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){ const char *zType; int n, m; + pTab->tabFlags |= (pCol->colFlags & COLFLAG_NOINSERT); p = a[i].pExpr; zType = columnType(&sNC, p, 0, 0, 0); /* pCol->szEst = ... // Column size est for SELECT tables never used */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index b1d9bab492..811b9665e7 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2015,7 +2015,12 @@ struct Column { u16 colFlags; /* Boolean properties. See COLFLAG_ defines below */ }; -/* Allowed values for Column.colFlags: +/* Allowed values for Column.colFlags. +** +** Constraints: +** TF_HasVirtual == COLFLAG_VIRTUAL +** TF_HasStored == COLFLAG_STORED +** TF_HasHidden == COLFLAG_HIDDEN */ #define COLFLAG_PRIMKEY 0x0001 /* Column is part of the primary key */ #define COLFLAG_HIDDEN 0x0002 /* A hidden column in a virtual table */ @@ -2204,11 +2209,12 @@ struct Table { ** ** Constraints: ** -** TF_HasVirtual == COLFLAG_Virtual -** TF_HasStored == COLFLAG_Stored +** TF_HasVirtual == COLFLAG_VIRTUAL +** TF_HasStored == COLFLAG_STORED +** TF_HasHidden == COLFLAG_HIDDEN */ #define TF_Readonly 0x0001 /* Read-only system table */ -#define TF_Ephemeral 0x0002 /* An ephemeral 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 */ @@ -2223,6 +2229,7 @@ struct Table { #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 */ /* ** Test to see whether or not a table is a virtual table. This is diff --git a/src/vtab.c b/src/vtab.c index 400ae40968..24144902fe 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -660,6 +660,7 @@ static int vtabCallConstructor( zType[i-1] = '\0'; } pTab->aCol[iCol].colFlags |= COLFLAG_HIDDEN; + pTab->tabFlags |= TF_HasHidden; oooHidden = TF_OOOHidden; }else{ pTab->tabFlags |= oooHidden; From a55a839ab327630511f37098ed25d5df71b558d3 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 18 Feb 2021 15:59:37 +0000 Subject: [PATCH 209/257] Avoid invoking the update or pre-update hooks during VACUUM operations. FossilOrigin-Name: 3c25cb4ab8885a50e2a485fe76f5ffd5dd8ebe1306aca8c0989e0b7fd7dd18d2 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/insert.c | 44 ++++++++++++++++++++++++-------------------- test/hook.test | 30 +++++++++++++++++++++++------- 4 files changed, 56 insertions(+), 36 deletions(-) diff --git a/manifest b/manifest index d2cea81cb0..a595639ccc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvement\sto\sthe\sINSERT\soptimization\sof\scheck-in\s[16ac213c57196361]\sso\nthat\sit\sworks\swith\sSQLITE_ENABLE_HIDDEN_COLUMN\sbut\sis\salso\seasier\sto\smaintain\nand\sa\slittle\sfaster\sas\swell. -D 2021-02-18T15:45:34.839 +C Avoid\sinvoking\sthe\supdate\sor\spre-update\shooks\sduring\sVACUUM\soperations. +D 2021-02-18T15:59:37.490 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -502,7 +502,7 @@ 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 c801ce88caadea239f890fdb744628f2da02a945aca600ccfde6988f7e2cd558 +F src/insert.c 3959a2e8a6c1e688e7390ef242472817653f4ae9a42bb78b293eaa98645f1a07 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 F src/main.c 1c5de7b3fabcdf05f4fe563aab5d81d175b89c67a8678a12ba86629356afa356 @@ -1057,7 +1057,7 @@ F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 F test/having.test a89236dd8d55aa50c4805f82ac9daf64d477a44d712d8209c118978d0ca21ec9 F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751 F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711 -F test/hook.test bd7ea2e35951291705106295324a91b3bb455081c783e0f681ff4bc68468b8d2 +F test/hook.test fa54fa8afc842ae375f10c1f9fc0014fa59789052fc30c9eae19811fa3afa009 F test/hook2.test b9ff3b8c6519fb67f33192f1afe86e7782ee4ac8 F test/icu.test 716a6b89fbabe5cc63e0cd4c260befb08fd7b9d761f04d43669233292f0753b1 F test/ieee754.test b0945d12be7d255f3dfa18e2511b17ca37e0edd2b803231c52d05b86c04ab26e @@ -1900,7 +1900,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 5168b06bcf283ef64cb9fd76330a743baf8bb0cd747c14eae23e607e0491cbce -R e1b8540e4a303e92cccaf5fd2962de4f -U drh -Z c7f2d82d7568a9beb226b994480e85d8 +P f985a78ecc0c6d9ff671c730a109d97dc781b06e47a0ab03f441cea5d021a4c3 +R 887c3ab5f5432ba4ea084453147dc94e +U dan +Z 858d0f25e386aba1accc2e325cd1540d diff --git a/manifest.uuid b/manifest.uuid index f2c6960a06..81f136ebf3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f985a78ecc0c6d9ff671c730a109d97dc781b06e47a0ab03f441cea5d021a4c3 \ No newline at end of file +3c25cb4ab8885a50e2a485fe76f5ffd5dd8ebe1306aca8c0989e0b7fd7dd18d2 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index a78150df39..646864ee60 100644 --- a/src/insert.c +++ b/src/insert.c @@ -2426,6 +2426,7 @@ static void codeWithoutRowidPreupdate( Vdbe *v = pParse->pVdbe; int r = sqlite3GetTempReg(pParse); assert( !HasRowid(pTab) ); + assert( 0==(pParse->db->mDbFlags & DBFLAG_Vacuum) ); sqlite3VdbeAddOp2(v, OP_Integer, 0, r); sqlite3VdbeAddOp4(v, OP_Insert, iCur, regData, r, (char*)pTab, P4_TABLE); sqlite3VdbeChangeP5(v, OPFLAG_ISNOOP); @@ -2958,13 +2959,18 @@ static int xferOptimization( insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND|OPFLAG_PREFORMAT; } #ifdef SQLITE_ENABLE_PREUPDATE_HOOK - sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); - insFlags &= ~OPFLAG_PREFORMAT; -#else - sqlite3VdbeAddOp3(v, OP_RowCell, iDest, iSrc, regRowid); + if( (db->mDbFlags & DBFLAG_Vacuum)==0 ){ + sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); + insFlags &= ~OPFLAG_PREFORMAT; + }else #endif - sqlite3VdbeAddOp4(v, OP_Insert, iDest, regData, regRowid, - (char*)pDest, P4_TABLE); + { + sqlite3VdbeAddOp3(v, OP_RowCell, iDest, iSrc, regRowid); + } + sqlite3VdbeAddOp3(v, OP_Insert, iDest, regData, regRowid); + if( (db->mDbFlags & DBFLAG_Vacuum)==0 ){ + sqlite3VdbeChangeP4(v, -1, (char*)pDest, P4_TABLE); + } sqlite3VdbeChangeP5(v, insFlags); sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); VdbeCoverage(v); @@ -3003,26 +3009,24 @@ static int xferOptimization( ** might change the definition of a collation sequence and then run ** a VACUUM command. In that case keys may not be written in strictly ** sorted order. */ -#ifdef SQLITE_ENABLE_PREUPDATE_HOOK - if( (HasRowid(pDest) || !IsPrimaryKeyIndex(pDestIdx)) ) -#endif - { - for(i=0; inColumn; i++){ - const char *zColl = pSrcIdx->azColl[i]; - if( sqlite3_stricmp(sqlite3StrBINARY, zColl) ) break; - } - if( i==pSrcIdx->nColumn ){ - idxInsFlags = OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT; - sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest); - sqlite3VdbeAddOp2(v, OP_RowCell, iDest, iSrc); - } + for(i=0; inColumn; i++){ + const char *zColl = pSrcIdx->azColl[i]; + if( sqlite3_stricmp(sqlite3StrBINARY, zColl) ) break; + } + if( i==pSrcIdx->nColumn ){ + idxInsFlags = OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT; + sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest); + sqlite3VdbeAddOp2(v, OP_RowCell, iDest, iSrc); } }else if( !HasRowid(pSrc) && pDestIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){ idxInsFlags |= OPFLAG_NCHANGE; } if( idxInsFlags!=(OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT) ){ sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); - if( !HasRowid(pDest) && IsPrimaryKeyIndex(pDestIdx) ){ + if( (db->mDbFlags & DBFLAG_Vacuum)==0 + && !HasRowid(pDest) + && IsPrimaryKeyIndex(pDestIdx) + ){ codeWithoutRowidPreupdate(pParse, pDest, iDest, regData); } } diff --git a/test/hook.test b/test/hook.test index 5d6a354572..0b72b2dcff 100644 --- a/test/hook.test +++ b/test/hook.test @@ -979,24 +979,40 @@ db update_hook update_cb proc preupdate_cb {args} { lappend ::res "preupdate" $args } proc update_cb {args} { lappend ::res "update" $args } -#set ::res [list] -#do_test 11.2 { -# execsql VACUUM -# set ::res -#} {} +set ::res [list] +do_test 12.2 { + execsql VACUUM + set ::res +} {} -do_test 11.3 { +do_test 12.3 { set ::res [list] execsql { INSERT INTO t3 SELECT a, b FROM t2 } set ::res } {preupdate {INSERT main t3 0 0} preupdate {INSERT main t3 0 0}} -do_test 11.4 { +do_test 12.4 { execsql { DELETE FROM t3 } set ::res [list] execsql { INSERT INTO t3 SELECT * FROM t2 } set ::res } {preupdate {INSERT main t3 0 0} preupdate {INSERT main t3 0 0}} +do_execsql_test 12.5 { + CREATE TABLE t4(a COLLATE nocase PRIMARY KEY, b) WITHOUT ROWID; + INSERT INTO t4 VALUES('abc', 1); + INSERT INTO t4 VALUES('DEF', 2); +} + +set ::res [list] +do_test 12.6 { + execsql VACUUM + set ::res +} {} + +do_catchsql_test 12.6 { + INSERT INTO t4 VALUES('def', 3); +} {1 {UNIQUE constraint failed: t4.a}} + finish_test From 30cdb992dda520e78374776eac16dff4eff93908 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 18 Feb 2021 17:48:36 +0000 Subject: [PATCH 210/257] Add test cases for ALTER TABLE DROP COLUMN. FossilOrigin-Name: 204ee5e28210738fb624a9cf85dc6f9b59de0d7eb4fddd46c8babe9beddd4944 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/alterdropcol.test | 15 +++++++++++++++ 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 86e0edd9a2..12294215e9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\sOOM\serror\shandling\sin\sthe\snew\scode\son\sthis\sbranch. -D 2021-02-17T20:46:44.173 +C Add\stest\scases\sfor\sALTER\sTABLE\sDROP\sCOLUMN. +D 2021-02-18T17:48:36.327 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -647,7 +647,7 @@ F test/alter4.test dfd6086faf461b27ca2d2999848dcd207edf23352fc1592d0005c0844f3f0 F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959 F test/alterauth2.test c0a1ddf5b93d93cb0d15ba7acaf0c5c6fb515bbe861ede75b2d3fabad33b6499 F test/altercol.test 1d6a6fe698b81e626baea4881f5717f9bc53d7d07f1cd23ee7ad1b931f117ddf -F test/alterdropcol.test 1d9577320aa1b501ebc44de02b7c101789bca9fb6fbbb393c99d24351f15d11e +F test/alterdropcol.test e75893837c5a9b6422c646c36cb9b50b6ff5a526e6c827bd96a9cea7112ca9ad F test/alterlegacy.test f38c6d06cda39e1f7b955bbce57f2e3ef5b7cb566d3d1234502093e228c15811 F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9 F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b @@ -1902,7 +1902,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 0cd5e2f9ce181f2c940ffca6fe69fda84f452613e66463d0d7c7413fc11b9772 -R e80f4b5b5082fe2df5d466ff5786649a +P ea999c9db59e4193b306a2e1b15fc94f8f04cb05e852bb0d068b7d5243a0849b +R e87cb22a663d50f61a2888642ea17223 U dan -Z a20fda248d094f1d6381bdbf1b68230b +Z a5aedcb976c3c92cd79e2c941a67f828 diff --git a/manifest.uuid b/manifest.uuid index 96da958def..6ed839059c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ea999c9db59e4193b306a2e1b15fc94f8f04cb05e852bb0d068b7d5243a0849b \ No newline at end of file +204ee5e28210738fb624a9cf85dc6f9b59de0d7eb4fddd46c8babe9beddd4944 \ No newline at end of file diff --git a/test/alterdropcol.test b/test/alterdropcol.test index ef3e97dea7..fecd9e121a 100644 --- a/test/alterdropcol.test +++ b/test/alterdropcol.test @@ -207,6 +207,21 @@ foreach {tn wo vs} { } } +#------------------------------------------------------------------------- +reset_db +do_execsql_test 5.0 { + CREATE TABLE p1(a PRIMARY KEY, b UNIQUE); + CREATE TABLE c1(x, y, z REFERENCES p1(c)); + CREATE TABLE c2(x, y, z, w REFERENCES p1(b)); +} +do_execsql_test 5.1 { + ALTER TABLE c1 DROP COLUMN z; + ALTER TABLE c2 DROP COLUMN z; + SELECT sql FROM sqlite_schema WHERE name IN ('c1', 'c2'); +} { + {CREATE TABLE c1(x, y)} + {CREATE TABLE c2(x, y, w REFERENCES p1(b))} +} finish_test From 16953469a64ed8f8b5c7434f7200ebd49c5ac983 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 18 Feb 2021 19:25:44 +0000 Subject: [PATCH 211/257] Fix a problem with schema error detection when processing ALTER TABLE DROP COLUMN commands. FossilOrigin-Name: 565a6fd0c95b438fea7bf84913b38de1718117e16e0d685534a8650e1dc8421b --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/alter.c | 42 +++++++++++++++++++++++++----------------- test/alterdropcol.test | 31 +++++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index 12294215e9..bc2e3dbf4b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\scases\sfor\sALTER\sTABLE\sDROP\sCOLUMN. -D 2021-02-18T17:48:36.327 +C Fix\sa\sproblem\swith\sschema\serror\sdetection\swhen\sprocessing\sALTER\sTABLE\sDROP\sCOLUMN\scommands. +D 2021-02-18T19:25:44.637 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c d56ceae00c743ef991e5ab1e9be2095a441dcee085bccf8795eba3da71b4d85f +F src/alter.c 2e5a29206228e57739e644dab71f268a5d95348e29fc498aa2c31ccc33229fcc F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c F src/attach.c e80162a47411f296bea550ed8fafd730481f4aa71e89ece23ba9c957eed15d4a F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 @@ -647,7 +647,7 @@ F test/alter4.test dfd6086faf461b27ca2d2999848dcd207edf23352fc1592d0005c0844f3f0 F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959 F test/alterauth2.test c0a1ddf5b93d93cb0d15ba7acaf0c5c6fb515bbe861ede75b2d3fabad33b6499 F test/altercol.test 1d6a6fe698b81e626baea4881f5717f9bc53d7d07f1cd23ee7ad1b931f117ddf -F test/alterdropcol.test e75893837c5a9b6422c646c36cb9b50b6ff5a526e6c827bd96a9cea7112ca9ad +F test/alterdropcol.test f4fb3a02a7274740769506f2af2eb8cc60aac26a148b71564b79fe3a19acae3b F test/alterlegacy.test f38c6d06cda39e1f7b955bbce57f2e3ef5b7cb566d3d1234502093e228c15811 F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9 F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b @@ -1902,7 +1902,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 ea999c9db59e4193b306a2e1b15fc94f8f04cb05e852bb0d068b7d5243a0849b -R e87cb22a663d50f61a2888642ea17223 +P 204ee5e28210738fb624a9cf85dc6f9b59de0d7eb4fddd46c8babe9beddd4944 +R 845ed6581bddfe7c8da85d38a6d123ff U dan -Z a5aedcb976c3c92cd79e2c941a67f828 +Z f3602657c19c9bc4f7de01775efae4db diff --git a/manifest.uuid b/manifest.uuid index 6ed839059c..70e8900803 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -204ee5e28210738fb624a9cf85dc6f9b59de0d7eb4fddd46c8babe9beddd4944 \ No newline at end of file +565a6fd0c95b438fea7bf84913b38de1718117e16e0d685534a8650e1dc8421b \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index d48b5ec919..36cc9f3213 100644 --- a/src/alter.c +++ b/src/alter.c @@ -49,16 +49,21 @@ static int isAlterableTable(Parse *pParse, Table *pTab){ ** statement to ensure that the operation has not rendered any schema ** objects unusable. */ -static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){ +static void renameTestSchema( + Parse *pParse, /* Parse context */ + const char *zDb, /* Name of db to verify schema of */ + int bTemp, /* True if this is the temp db */ + const char *zWhen /* "when" part of error message */ +){ pParse->colNamesSet = 1; sqlite3NestedParse(pParse, "SELECT 1 " "FROM \"%w\"." DFLT_SCHEMA_TABLE " " "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" " AND sql NOT LIKE 'create virtual%%'" - " AND sqlite_rename_test(%Q, sql, type, name, %d)=NULL ", + " AND sqlite_rename_test(%Q, sql, type, name, %d, %Q)=NULL ", zDb, - zDb, bTemp + zDb, bTemp, zWhen ); if( bTemp==0 ){ @@ -67,8 +72,8 @@ static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){ "FROM temp." DFLT_SCHEMA_TABLE " " "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" " AND sql NOT LIKE 'create virtual%%'" - " AND sqlite_rename_test(%Q, sql, type, name, 1)=NULL ", - zDb + " AND sqlite_rename_test(%Q, sql, type, name, 1, %Q)=NULL ", + zDb, zWhen ); } } @@ -231,7 +236,7 @@ void sqlite3AlterRenameTable( "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, 1), " "tbl_name = " "CASE WHEN tbl_name=%Q COLLATE nocase AND " - " sqlite_rename_test(%Q, sql, type, name, 1) " + " sqlite_rename_test(%Q, sql, type, name, 1, 'after rename') " "THEN %Q ELSE tbl_name END " "WHERE type IN ('view', 'trigger')" , zDb, zTabName, zName, zTabName, zDb, zName); @@ -251,7 +256,7 @@ void sqlite3AlterRenameTable( #endif renameReloadSchema(pParse, iDb, INITFLAG_AlterRename); - renameTestSchema(pParse, zDb, iDb==1); + renameTestSchema(pParse, zDb, iDb==1, "after rename"); exit_rename_table: sqlite3SrcListDelete(db, pSrc); @@ -619,7 +624,7 @@ void sqlite3AlterRenameColumn( /* Drop and reload the database schema. */ renameReloadSchema(pParse, iSchema, INITFLAG_AlterRename); - renameTestSchema(pParse, zDb, iSchema==1); + renameTestSchema(pParse, zDb, iSchema==1, "after rename"); exit_rename_column: sqlite3SrcListDelete(db, pSrc); @@ -968,7 +973,7 @@ static RenameToken *renameColumnTokenNext(RenameCtx *pCtx){ */ static void renameColumnParseError( sqlite3_context *pCtx, - int bPost, + const char *zWhen, sqlite3_value *pType, sqlite3_value *pObject, Parse *pParse @@ -977,8 +982,8 @@ static void renameColumnParseError( const char *zN = (const char*)sqlite3_value_text(pObject); char *zErr; - zErr = sqlite3_mprintf("error in %s %s%s: %s", - zT, zN, (bPost ? " after rename" : ""), + zErr = sqlite3_mprintf("error in %s %s%s%s: %s", + zT, zN, (zWhen[0] ? " " : ""), zWhen, pParse->zErrMsg ); sqlite3_result_error(pCtx, zErr, -1); @@ -1484,7 +1489,7 @@ static void renameColumnFunc( renameColumnFunc_done: if( rc!=SQLITE_OK ){ if( sParse.zErrMsg ){ - renameColumnParseError(context, 0, argv[1], argv[2], &sParse); + renameColumnParseError(context, "", argv[1], argv[2], &sParse); }else{ sqlite3_result_error_code(context, rc); } @@ -1673,7 +1678,7 @@ static void renameTableFunc( } if( rc!=SQLITE_OK ){ if( sParse.zErrMsg ){ - renameColumnParseError(context, 0, argv[1], argv[2], &sParse); + renameColumnParseError(context, "", argv[1], argv[2], &sParse); }else{ sqlite3_result_error_code(context, rc); } @@ -1702,6 +1707,7 @@ static void renameTableFunc( ** 2: Object type ("view", "table", "trigger" or "index"). ** 3: Object name. ** 4: True if object is from temp schema. +** 5: "when" part of error message. ** ** Unless it finds an error, this function normally returns NULL. However, it ** returns integer value 1 if: @@ -1719,6 +1725,7 @@ static void renameTableTest( char const *zInput = (const char*)sqlite3_value_text(argv[1]); int bTemp = sqlite3_value_int(argv[4]); int isLegacy = (db->flags & SQLITE_LegacyAlter); + char const *zWhen = (const char*)sqlite3_value_text(argv[5]); #ifndef SQLITE_OMIT_AUTHORIZATION sqlite3_xauth xAuth = db->xAuth; @@ -1751,8 +1758,8 @@ static void renameTableTest( } } - if( rc!=SQLITE_OK ){ - renameColumnParseError(context, 1, argv[2], argv[3], &sParse); + if( rc!=SQLITE_OK && zWhen ){ + renameColumnParseError(context, zWhen, argv[2], argv[3],&sParse); } renameParseCleanup(&sParse); } @@ -1869,6 +1876,7 @@ void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, Token *pName){ iDb = sqlite3SchemaToIndex(db, pTab->pSchema); assert( iDb>=0 ); zDb = db->aDb[iDb].zDbSName; + renameTestSchema(pParse, zDb, iDb==1, ""); sqlite3NestedParse(pParse, "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET " "sql = sqlite_drop_column(%d, sql, %d, %d) " @@ -1878,7 +1886,7 @@ void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, Token *pName){ /* Drop and reload the database schema. */ renameReloadSchema(pParse, iDb, INITFLAG_AlterDrop); - renameTestSchema(pParse, zDb, iDb==1); + renameTestSchema(pParse, zDb, iDb==1, "after drop column"); /* Edit rows of table on disk */ if( pParse->nErr==0 && (pTab->aCol[iCol].colFlags & COLFLAG_VIRTUAL)==0 ){ @@ -1939,7 +1947,7 @@ void sqlite3AlterFunctions(void){ static FuncDef aAlterTableFuncs[] = { INTERNAL_FUNCTION(sqlite_rename_column, 9, renameColumnFunc), INTERNAL_FUNCTION(sqlite_rename_table, 7, renameTableFunc), - INTERNAL_FUNCTION(sqlite_rename_test, 5, renameTableTest), + INTERNAL_FUNCTION(sqlite_rename_test, 6, renameTableTest), INTERNAL_FUNCTION(sqlite_drop_column, 4, dropColumnFunc), }; sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs)); diff --git a/test/alterdropcol.test b/test/alterdropcol.test index fecd9e121a..7edb05f4b9 100644 --- a/test/alterdropcol.test +++ b/test/alterdropcol.test @@ -223,6 +223,37 @@ do_execsql_test 5.1 { {CREATE TABLE c2(x, y, w REFERENCES p1(b))} } +do_execsql_test 5.2.1 { + CREATE VIEW v1 AS SELECT d, e FROM p1 +} +do_catchsql_test 5.2.2 { + ALTER TABLE c1 DROP COLUMN x +} {1 {error in view v1: no such column: d}} +do_execsql_test 5.3.1 { + DROP VIEW v1; + CREATE VIEW v1 AS SELECT x, y FROM c1; +} +do_catchsql_test 5.3.2 { + ALTER TABLE c1 DROP COLUMN x +} {1 {error in view v1 after drop column: no such column: x}} + +do_execsql_test 5.4.1 { + CREATE TRIGGER tr AFTER INSERT ON c1 BEGIN + INSERT INTO p1 VALUES(new.y, new.xyz); + END; +} +do_catchsql_test 5.4.2 { + ALTER TABLE c1 DROP COLUMN y +} {1 {error in trigger tr: no such column: new.xyz}} +do_execsql_test 5.5.1 { + DROP TRIGGER tr; + CREATE TRIGGER tr AFTER INSERT ON c1 BEGIN + INSERT INTO p1 VALUES(new.y, new.z); + END; +} +do_catchsql_test 5.5.2 { + ALTER TABLE c1 DROP COLUMN y +} {1 {error in trigger tr: no such column: new.z}} finish_test From 678f3b33cc057f8253444343575d24ab093d8ddf Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 18 Feb 2021 20:27:46 +0000 Subject: [PATCH 212/257] Fix DROP COLUMN so that it works even if the user has registered an authorizer callback. FossilOrigin-Name: e5f144182bbb3ba10c77151cf63c8bddf86374049fb6866387f85e335df298cb --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/alter.c | 9 ++++++++- test/alterauth2.test | 17 +++++++++++++++++ 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index bc2e3dbf4b..d852fefe4b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\sschema\serror\sdetection\swhen\sprocessing\sALTER\sTABLE\sDROP\sCOLUMN\scommands. -D 2021-02-18T19:25:44.637 +C Fix\sDROP\sCOLUMN\sso\sthat\sit\sworks\seven\sif\sthe\suser\shas\sregistered\san\sauthorizer\scallback. +D 2021-02-18T20:27:46.953 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 2e5a29206228e57739e644dab71f268a5d95348e29fc498aa2c31ccc33229fcc +F src/alter.c c2d554c43d0e4c3d264f5d9130bc51ebc581ad04c86f998707006ab9b34c25d8 F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c F src/attach.c e80162a47411f296bea550ed8fafd730481f4aa71e89ece23ba9c957eed15d4a F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 @@ -645,7 +645,7 @@ F test/alter2.test a966ccfcddf9ce0a4e0e6ff1aca9e6e7948e0e242cd7e43fc091948521807 F test/alter3.test e487958dec7932453e0b83baf21d6b1e71d5e7d9a55bc20eadfa62a51ddffc29 F test/alter4.test dfd6086faf461b27ca2d2999848dcd207edf23352fc1592d0005c0844f3f08cf F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959 -F test/alterauth2.test c0a1ddf5b93d93cb0d15ba7acaf0c5c6fb515bbe861ede75b2d3fabad33b6499 +F test/alterauth2.test 794ac5cef251819fe364b4fe20f12f86e9c5d68070513c7fd26c17cb244c89af F test/altercol.test 1d6a6fe698b81e626baea4881f5717f9bc53d7d07f1cd23ee7ad1b931f117ddf F test/alterdropcol.test f4fb3a02a7274740769506f2af2eb8cc60aac26a148b71564b79fe3a19acae3b F test/alterlegacy.test f38c6d06cda39e1f7b955bbce57f2e3ef5b7cb566d3d1234502093e228c15811 @@ -1902,7 +1902,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 204ee5e28210738fb624a9cf85dc6f9b59de0d7eb4fddd46c8babe9beddd4944 -R 845ed6581bddfe7c8da85d38a6d123ff +P 565a6fd0c95b438fea7bf84913b38de1718117e16e0d685534a8650e1dc8421b +R 68a986e7be36e9399d403bc01ee6e384 U dan -Z f3602657c19c9bc4f7de01775efae4db +Z 3cbcbd274cebad95d2a18c7496f951e1 diff --git a/manifest.uuid b/manifest.uuid index 70e8900803..c10a6b2426 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -565a6fd0c95b438fea7bf84913b38de1718117e16e0d685534a8650e1dc8421b \ No newline at end of file +e5f144182bbb3ba10c77151cf63c8bddf86374049fb6866387f85e335df298cb \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 36cc9f3213..e34a592be0 100644 --- a/src/alter.c +++ b/src/alter.c @@ -1800,6 +1800,11 @@ static void dropColumnFunc( const char *zEnd; char *zNew = 0; +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth = db->xAuth; + db->xAuth = 0; +#endif + rc = renameParseSql(&sParse, zDb, db, zSql, iSchema==1); if( rc!=SQLITE_OK ) goto drop_column_done; pTab = sParse.pNewTable; @@ -1820,6 +1825,9 @@ static void dropColumnFunc( drop_column_done: renameParseCleanup(&sParse); +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; +#endif } /* @@ -1937,7 +1945,6 @@ void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, Token *pName){ exit_drop_column: sqlite3DbFree(db, zCol); sqlite3SrcListDelete(db, pSrc); - return; } /* diff --git a/test/alterauth2.test b/test/alterauth2.test index bd589cda1d..a411408b58 100644 --- a/test/alterauth2.test +++ b/test/alterauth2.test @@ -95,4 +95,21 @@ do_auth_test 1.2 { {SQLITE_UPDATE sqlite_temp_master sql temp {}} } +do_auth_test 1.3 { + ALTER TABLE t2 DROP COLUMN c; +} { + {SQLITE_FUNCTION {} like {} {}} + {SQLITE_FUNCTION {} sqlite_drop_column {} {}} + {SQLITE_FUNCTION {} sqlite_rename_test {} {}} + {SQLITE_READ sqlite_master name main {}} + {SQLITE_READ sqlite_master sql main {}} + {SQLITE_READ sqlite_master tbl_name main {}} + {SQLITE_READ sqlite_master type main {}} + {SQLITE_READ sqlite_temp_master name temp {}} + {SQLITE_READ sqlite_temp_master sql temp {}} + {SQLITE_READ sqlite_temp_master type temp {}} + {SQLITE_SELECT {} {} {} {}} + {SQLITE_UPDATE sqlite_master sql main {}} +} + finish_test From dcc29e0d1dfa79fcc03c664c3e897689d5225ee7 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 18 Feb 2021 23:03:50 +0000 Subject: [PATCH 213/257] Enhance renameParseSql() to better handle OOMs. FossilOrigin-Name: 68bcde7ab57b2d4bdcfb2f6c7134a0b01a504b2e7cdf6ee5bf0df70fb4a517b0 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/alter.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index c7e6117f2e..814d0fb5c6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\schanges\sfrom\strunk\sinto\sthe\salter-table-drop-column\sbranch. -D 2021-02-18T22:47:34.981 +C Enhance\srenameParseSql()\sto\sbetter\shandle\sOOMs. +D 2021-02-18T23:03:50.874 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c c2d554c43d0e4c3d264f5d9130bc51ebc581ad04c86f998707006ab9b34c25d8 +F src/alter.c fedd5c9e8d2b11564e3973cf8703c2fb2302e5a214e5c4c48da6b1438c9145ef F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c F src/attach.c e80162a47411f296bea550ed8fafd730481f4aa71e89ece23ba9c957eed15d4a F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 @@ -1902,7 +1902,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 e5f144182bbb3ba10c77151cf63c8bddf86374049fb6866387f85e335df298cb 3c25cb4ab8885a50e2a485fe76f5ffd5dd8ebe1306aca8c0989e0b7fd7dd18d2 -R 7a26bb4b78580fad399e64abb8851442 +P 9ea640073f8809dfe2612ae1ea384a938b433f884c54d9e5aa3712de79397ac1 +R 527e6c9ac23803f3ec7175bf228774c2 U drh -Z dbdaa6bf28df7e70f0af3298f4e6f0bf +Z 50f2afee92ce107a5465565f794dcaa9 diff --git a/manifest.uuid b/manifest.uuid index 31dc178056..2e5910cb01 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9ea640073f8809dfe2612ae1ea384a938b433f884c54d9e5aa3712de79397ac1 \ No newline at end of file +68bcde7ab57b2d4bdcfb2f6c7134a0b01a504b2e7cdf6ee5bf0df70fb4a517b0 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index e34a592be0..c630f0ded2 100644 --- a/src/alter.c +++ b/src/alter.c @@ -1062,7 +1062,7 @@ static int renameParseSql( p->eParseMode = PARSE_MODE_RENAME; p->db = db; p->nQueryLoop = 1; - rc = sqlite3RunParser(p, zSql, &zErr); + rc = zSql ? sqlite3RunParser(p, zSql, &zErr) : SQLITE_NOMEM; assert( p->zErrMsg==0 ); assert( rc!=SQLITE_OK || zErr==0 ); p->zErrMsg = zErr; From 0336140cd9913671601dd184072cd14361d53bb0 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 18 Feb 2021 23:53:47 +0000 Subject: [PATCH 214/257] Add missing VdbeCoverage() macros. FossilOrigin-Name: 9bb720e6590482bc9c2fbb273738808209e9651710dbee7572b0348cadf87e68 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/alter.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 814d0fb5c6..0cecf6429f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\srenameParseSql()\sto\sbetter\shandle\sOOMs. -D 2021-02-18T23:03:50.874 +C Add\smissing\sVdbeCoverage()\smacros. +D 2021-02-18T23:53:47.042 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c fedd5c9e8d2b11564e3973cf8703c2fb2302e5a214e5c4c48da6b1438c9145ef +F src/alter.c 7f9453d11a53808eececd397fc98bfa0431a47838322f944a5026861582503cf F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c F src/attach.c e80162a47411f296bea550ed8fafd730481f4aa71e89ece23ba9c957eed15d4a F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 @@ -1902,7 +1902,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 9ea640073f8809dfe2612ae1ea384a938b433f884c54d9e5aa3712de79397ac1 -R 527e6c9ac23803f3ec7175bf228774c2 +P 68bcde7ab57b2d4bdcfb2f6c7134a0b01a504b2e7cdf6ee5bf0df70fb4a517b0 +R 152516a53a5f57ac32212c9aee0d7991 U drh -Z 50f2afee92ce107a5465565f794dcaa9 +Z d661d689a5e017081615544903b6cdf3 diff --git a/manifest.uuid b/manifest.uuid index 2e5910cb01..31b116895f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -68bcde7ab57b2d4bdcfb2f6c7134a0b01a504b2e7cdf6ee5bf0df70fb4a517b0 \ No newline at end of file +9bb720e6590482bc9c2fbb273738808209e9651710dbee7572b0348cadf87e68 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index c630f0ded2..8f432b38c9 100644 --- a/src/alter.c +++ b/src/alter.c @@ -1908,7 +1908,7 @@ void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, Token *pName){ Vdbe *v = sqlite3GetVdbe(pParse); iCur = pParse->nTab++; sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenWrite); - addr = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); + addr = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v); reg = ++pParse->nMem; pParse->nMem += pTab->nCol; if( HasRowid(pTab) ){ @@ -1938,7 +1938,7 @@ void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, Token *pName){ sqlite3VdbeAddOp3(v, OP_Insert, iCur, regRec, reg); } - sqlite3VdbeAddOp2(v, OP_Next, iCur, addr+1); + sqlite3VdbeAddOp2(v, OP_Next, iCur, addr+1); VdbeCoverage(v); sqlite3VdbeJumpHere(v, addr); } From c90fa01dbfc9b94a9f07583d254ce785ee232fb9 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 19 Feb 2021 02:30:02 +0000 Subject: [PATCH 215/257] Add a NEVER() to an unreachable branch in the DROP COLUMN logic. FossilOrigin-Name: 963f498ae64cf7530fb7a405fa476c411ad66523f62f5eefa5a16596cd19a481 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/alter.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 0cecf6429f..adef7e5a09 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\smissing\sVdbeCoverage()\smacros. -D 2021-02-18T23:53:47.042 +C Add\sa\sNEVER()\sto\san\sunreachable\sbranch\sin\sthe\sDROP\sCOLUMN\slogic. +D 2021-02-19T02:30:02.782 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 7f9453d11a53808eececd397fc98bfa0431a47838322f944a5026861582503cf +F src/alter.c b2a3c89c5bcf5251cfb786e608381ef506d71a9f1c375e277124cc924e4546f9 F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c F src/attach.c e80162a47411f296bea550ed8fafd730481f4aa71e89ece23ba9c957eed15d4a F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 @@ -1902,7 +1902,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 68bcde7ab57b2d4bdcfb2f6c7134a0b01a504b2e7cdf6ee5bf0df70fb4a517b0 -R 152516a53a5f57ac32212c9aee0d7991 +P 9bb720e6590482bc9c2fbb273738808209e9651710dbee7572b0348cadf87e68 +R c0fbd4f44b1d4f87e911757503e8d30c U drh -Z d661d689a5e017081615544903b6cdf3 +Z 525012fbf3fca5430284eed456ca18e8 diff --git a/manifest.uuid b/manifest.uuid index 31b116895f..870b42977f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9bb720e6590482bc9c2fbb273738808209e9651710dbee7572b0348cadf87e68 \ No newline at end of file +963f498ae64cf7530fb7a405fa476c411ad66523f62f5eefa5a16596cd19a481 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 8f432b38c9..a4caf71598 100644 --- a/src/alter.c +++ b/src/alter.c @@ -1849,7 +1849,7 @@ void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, Token *pName){ /* Look up the table being altered. */ assert( pParse->pNewTable==0 ); assert( sqlite3BtreeHoldsAllMutexes(db) ); - if( db->mallocFailed ) goto exit_drop_column; + if( NEVER(db->mallocFailed) ) goto exit_drop_column; pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); if( !pTab ) goto exit_drop_column; From 239c84fc620d76e98547a8387e1aaa6d7d995b79 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 19 Feb 2021 09:09:07 +0000 Subject: [PATCH 216/257] Give a better error message on DROP COLUMN when attempting to drop the last column of a table. FossilOrigin-Name: 5e1f362bc3e53c60f9e6f771346d10c6e6a6cb3ff1eec5608101f9c5d6d2a5a4 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/alter.c | 6 ++++++ test/alterdropcol.test | 4 +--- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index adef7e5a09..646161d8d2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\sNEVER()\sto\san\sunreachable\sbranch\sin\sthe\sDROP\sCOLUMN\slogic. -D 2021-02-19T02:30:02.782 +C Give\sa\sbetter\serror\smessage\son\sDROP\sCOLUMN\swhen\sattempting\sto\sdrop\nthe\slast\scolumn\sof\sa\stable. +D 2021-02-19T09:09:07.189 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c b2a3c89c5bcf5251cfb786e608381ef506d71a9f1c375e277124cc924e4546f9 +F src/alter.c ae5ff195830c9fb15869067340ab3e619fb41332907c75f0fd0c8756e4a3826d F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c F src/attach.c e80162a47411f296bea550ed8fafd730481f4aa71e89ece23ba9c957eed15d4a F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 @@ -647,7 +647,7 @@ F test/alter4.test dfd6086faf461b27ca2d2999848dcd207edf23352fc1592d0005c0844f3f0 F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959 F test/alterauth2.test 794ac5cef251819fe364b4fe20f12f86e9c5d68070513c7fd26c17cb244c89af F test/altercol.test 1d6a6fe698b81e626baea4881f5717f9bc53d7d07f1cd23ee7ad1b931f117ddf -F test/alterdropcol.test f4fb3a02a7274740769506f2af2eb8cc60aac26a148b71564b79fe3a19acae3b +F test/alterdropcol.test baad37ff9b07078ea02dcc33dbfb82bde655f3eee5c453e218f69501c36f02ba F test/alterlegacy.test f38c6d06cda39e1f7b955bbce57f2e3ef5b7cb566d3d1234502093e228c15811 F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9 F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b @@ -1902,7 +1902,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 9bb720e6590482bc9c2fbb273738808209e9651710dbee7572b0348cadf87e68 -R c0fbd4f44b1d4f87e911757503e8d30c +P 963f498ae64cf7530fb7a405fa476c411ad66523f62f5eefa5a16596cd19a481 +R aa22eacb2d5994361fbd57544a6b9a8f U drh -Z 525012fbf3fca5430284eed456ca18e8 +Z 3143b8a85ae4a74a1f1f600bf54bbab2 diff --git a/manifest.uuid b/manifest.uuid index 870b42977f..bde579b620 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -963f498ae64cf7530fb7a405fa476c411ad66523f62f5eefa5a16596cd19a481 \ No newline at end of file +5e1f362bc3e53c60f9e6f771346d10c6e6a6cb3ff1eec5608101f9c5d6d2a5a4 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index a4caf71598..cb25f98078 100644 --- a/src/alter.c +++ b/src/alter.c @@ -1880,6 +1880,12 @@ void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, Token *pName){ goto exit_drop_column; } + /* Do not allow the number of columns to go to zero */ + if( pTab->nCol<=1 ){ + sqlite3ErrorMsg(pParse, "cannot drop column \"%s\": no other columns exist",zCol); + goto exit_drop_column; + } + /* Edit the sqlite_schema table */ iDb = sqlite3SchemaToIndex(db, pTab->pSchema); assert( iDb>=0 ); diff --git a/test/alterdropcol.test b/test/alterdropcol.test index 7edb05f4b9..1087f66328 100644 --- a/test/alterdropcol.test +++ b/test/alterdropcol.test @@ -72,7 +72,7 @@ do_execsql_test 1.7.2 { do_catchsql_test 1.7.3 { ALTER TABLE t1 DROP COLUMN a; -} {1 {error in table t1 after drop column: near ")": syntax error}} +} {1 {cannot drop column "a": no other columns exist}} do_catchsql_test 1.8 { @@ -256,5 +256,3 @@ do_catchsql_test 5.5.2 { } {1 {error in trigger tr: no such column: new.z}} finish_test - - From 329cb9eb8872390468d0b42a52a1764b70e664a8 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 19 Feb 2021 09:36:50 +0000 Subject: [PATCH 217/257] The COLUMN keyword in ALTER TABLE DROP COLUMN is optional. FossilOrigin-Name: a22f87fb6c43dd6217691c8dd1cdcd7880068024fb779ca8a5def068d72c3e6b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/parse.y | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 646161d8d2..d9a4b3b6a4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Give\sa\sbetter\serror\smessage\son\sDROP\sCOLUMN\swhen\sattempting\sto\sdrop\nthe\slast\scolumn\sof\sa\stable. -D 2021-02-19T09:09:07.189 +C The\sCOLUMN\skeyword\sin\sALTER\sTABLE\sDROP\sCOLUMN\sis\soptional. +D 2021-02-19T09:36:50.687 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -530,7 +530,7 @@ F src/os_win.c 77d39873836f1831a9b0b91894fec45ab0e9ca8e067dc8c549e1d1eca1566fe9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c c49952ac5e9cc536778eff528091d79d38b3e45cbeeed4695dc05e207dc6547d F src/pager.h 4bf9b3213a4b2bebbced5eaa8b219cf25d4a82f385d093cd64b7e93e5285f66f -F src/parse.y 8170885f22f4815c2adba3430ac7c990a39b60e04a0bcc4d02cce54e33475975 +F src/parse.y cdc4e5efaf1618d82f6b241a30f1a586188bf37e9c55f967258ed15fe24c51a2 F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a @@ -1902,7 +1902,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 963f498ae64cf7530fb7a405fa476c411ad66523f62f5eefa5a16596cd19a481 -R aa22eacb2d5994361fbd57544a6b9a8f +P 5e1f362bc3e53c60f9e6f771346d10c6e6a6cb3ff1eec5608101f9c5d6d2a5a4 +R d4c9013c313cab1e0a7971c4b14f44ef U drh -Z 3143b8a85ae4a74a1f1f600bf54bbab2 +Z f136680b9ca40f702c72664ef013c51c diff --git a/manifest.uuid b/manifest.uuid index bde579b620..40e46f4821 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5e1f362bc3e53c60f9e6f771346d10c6e6a6cb3ff1eec5608101f9c5d6d2a5a4 \ No newline at end of file +a22f87fb6c43dd6217691c8dd1cdcd7880068024fb779ca8a5def068d72c3e6b \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index 92626f2c17..82f760ede5 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1621,7 +1621,7 @@ cmd ::= ALTER TABLE add_column_fullname Y.n = (int)(pParse->sLastToken.z-Y.z) + pParse->sLastToken.n; sqlite3AlterFinishAddColumn(pParse, &Y); } -cmd ::= ALTER TABLE fullname(X) DROP COLUMNKW nm(Y). { +cmd ::= ALTER TABLE fullname(X) DROP kwcolumn_opt nm(Y). { sqlite3AlterDropColumn(pParse, X, &Y); } From 60fe2352f5f16e9d0c4602e2f71bd095b961c2a0 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 19 Feb 2021 09:46:52 +0000 Subject: [PATCH 218/257] Omit an branch made unreachable by the improved error message from dropping the last column of a table. FossilOrigin-Name: c5719fc5aa04c50bb01533f1cedb73dc80c4bf5315ff6a7206c8a10504afca8b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/alter.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index d9a4b3b6a4..fefd385742 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sCOLUMN\skeyword\sin\sALTER\sTABLE\sDROP\sCOLUMN\sis\soptional. -D 2021-02-19T09:36:50.687 +C Omit\san\sbranch\smade\sunreachable\sby\sthe\simproved\serror\smessage\sfrom\sdropping\nthe\slast\scolumn\sof\sa\stable. +D 2021-02-19T09:46:52.358 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c ae5ff195830c9fb15869067340ab3e619fb41332907c75f0fd0c8756e4a3826d +F src/alter.c 4dc2c97b49c555e624783caaa50ae27c23be9933c64e26e4a033366ab60c30f2 F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c F src/attach.c e80162a47411f296bea550ed8fafd730481f4aa71e89ece23ba9c957eed15d4a F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 @@ -1902,7 +1902,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 5e1f362bc3e53c60f9e6f771346d10c6e6a6cb3ff1eec5608101f9c5d6d2a5a4 -R d4c9013c313cab1e0a7971c4b14f44ef +P a22f87fb6c43dd6217691c8dd1cdcd7880068024fb779ca8a5def068d72c3e6b +R 8fe145aa3933b8b7851e138e048197cd U drh -Z f136680b9ca40f702c72664ef013c51c +Z 50b646c8c422b4be2f6044aaaf70a38b diff --git a/manifest.uuid b/manifest.uuid index 40e46f4821..708f49a650 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a22f87fb6c43dd6217691c8dd1cdcd7880068024fb779ca8a5def068d72c3e6b \ No newline at end of file +c5719fc5aa04c50bb01533f1cedb73dc80c4bf5315ff6a7206c8a10504afca8b \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index cb25f98078..f93e0ecb7e 100644 --- a/src/alter.c +++ b/src/alter.c @@ -1816,7 +1816,7 @@ static void dropColumnFunc( zEnd = (const char*)pEnd->t.z; }else{ zEnd = (const char*)&zSql[iAddColOffset]; - while( pCol->t.z[0]!=',' && pCol->t.z[1]!='(' ) pCol->t.z--; + while( ALWAYS(pCol->t.z[0]!=0) && pCol->t.z[0]!=',' ) pCol->t.z--; } zNew = sqlite3MPrintf(db, "%.*s%s", pCol->t.z-zSql, zSql, zEnd); From f4a72788a42f476a84fd2f318cd6d9773c3921c2 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 19 Feb 2021 14:13:40 +0000 Subject: [PATCH 219/257] Fix a crash that could occur in ALTER TABLE DROP COLUMN if the sqlite_schema table was corrupt. FossilOrigin-Name: 126ee1ec4f3565c0cccca98885fa3665a641ea3df251511de16eed2a1c396124 --- manifest | 15 ++++--- manifest.uuid | 2 +- src/alter.c | 8 ++++ test/altercorrupt.test | 100 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 117 insertions(+), 8 deletions(-) create mode 100644 test/altercorrupt.test diff --git a/manifest b/manifest index fefd385742..ef19b71a40 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Omit\san\sbranch\smade\sunreachable\sby\sthe\simproved\serror\smessage\sfrom\sdropping\nthe\slast\scolumn\sof\sa\stable. -D 2021-02-19T09:46:52.358 +C Fix\sa\scrash\sthat\scould\soccur\sin\sALTER\sTABLE\sDROP\sCOLUMN\sif\sthe\ssqlite_schema\stable\swas\scorrupt. +D 2021-02-19T14:13:40.890 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 4dc2c97b49c555e624783caaa50ae27c23be9933c64e26e4a033366ab60c30f2 +F src/alter.c 1addd06a7aae343497ebede71ec355c2011f175075943007341693ebf7daa47d F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c F src/attach.c e80162a47411f296bea550ed8fafd730481f4aa71e89ece23ba9c957eed15d4a F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 @@ -647,6 +647,7 @@ F test/alter4.test dfd6086faf461b27ca2d2999848dcd207edf23352fc1592d0005c0844f3f0 F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959 F test/alterauth2.test 794ac5cef251819fe364b4fe20f12f86e9c5d68070513c7fd26c17cb244c89af F test/altercol.test 1d6a6fe698b81e626baea4881f5717f9bc53d7d07f1cd23ee7ad1b931f117ddf +F test/altercorrupt.test cb17a81f655a0d71bc1e48e44741a5e0905a3b3efbbe485b0b6c7648f2af3eed F test/alterdropcol.test baad37ff9b07078ea02dcc33dbfb82bde655f3eee5c453e218f69501c36f02ba F test/alterlegacy.test f38c6d06cda39e1f7b955bbce57f2e3ef5b7cb566d3d1234502093e228c15811 F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9 @@ -1902,7 +1903,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 a22f87fb6c43dd6217691c8dd1cdcd7880068024fb779ca8a5def068d72c3e6b -R 8fe145aa3933b8b7851e138e048197cd -U drh -Z 50b646c8c422b4be2f6044aaaf70a38b +P c5719fc5aa04c50bb01533f1cedb73dc80c4bf5315ff6a7206c8a10504afca8b +R a9f6b9c36a39e6908ea00fd7298f0619 +U dan +Z 77e2ec90698c4f83ecd6e0d769d5b14d diff --git a/manifest.uuid b/manifest.uuid index 708f49a650..d35260df63 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c5719fc5aa04c50bb01533f1cedb73dc80c4bf5315ff6a7206c8a10504afca8b \ No newline at end of file +126ee1ec4f3565c0cccca98885fa3665a641ea3df251511de16eed2a1c396124 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index f93e0ecb7e..e2af2beb8b 100644 --- a/src/alter.c +++ b/src/alter.c @@ -1808,6 +1808,11 @@ static void dropColumnFunc( rc = renameParseSql(&sParse, zDb, db, zSql, iSchema==1); if( rc!=SQLITE_OK ) goto drop_column_done; pTab = sParse.pNewTable; + if( iCol>=pTab->nCol ){ + /* This can happen if the sqlite_schema table is corrupt */ + rc = SQLITE_CORRUPT_BKPT; + goto drop_column_done; + } pCol = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol].zName); if( iColnCol-1 ){ @@ -1828,6 +1833,9 @@ drop_column_done: #ifndef SQLITE_OMIT_AUTHORIZATION db->xAuth = xAuth; #endif + if( rc!=SQLITE_OK ){ + sqlite3_result_error_code(context, rc); + } } /* diff --git a/test/altercorrupt.test b/test/altercorrupt.test new file mode 100644 index 0000000000..84a67e281c --- /dev/null +++ b/test/altercorrupt.test @@ -0,0 +1,100 @@ +# 2019-01-11 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix altercorrupt + +database_may_be_corrupt + +#-------------------------------------------------------------------------- +reset_db +do_test 1.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +.open --hexdb +| size 24576 pagesize 4096 filename crash-685346d89b5e5f.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 06 .....@ ........ +| 32: 00 00 63 00 00 05 f0 00 00 00 00 04 10 00 00 04 ..c............. +| 48: 00 00 00 00 00 00 0f f0 00 00 00 01 00 00 00 00 ................ +| 64: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 96: 00 00 00 00 0d 0f f8 00 05 0e cf 00 0f 79 0f d3 .............y.. +| 112: 0f 2e 0e f3 0e cf 00 00 00 00 00 00 00 00 00 00 ................ +| 3776: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 22 ................ +| 3792: 05 06 17 11 11 01 31 74 61 62 6c 65 74 34 74 34 ......1tablet4t4 +| 3808: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 34 .CREATE TABLE t4 +| 3824: 28 7a 29 39 04 06 17 11 11 01 5f 74 61 62 6c 65 (z)9......_table +| 3840: 74 33 74 33 05 43 52 45 41 54 45 20 54 41 42 4c t3t3.CREATE TABL +| 3856: 45 20 74 33 28 78 20 49 4e 54 45 47 45 52 20 50 E t3(x INTEGER P +| 3872: 52 49 4d 41 52 59 20 4b 45 59 2c 20 79 29 49 03 RIMARY KEY, y)I. +| 3888: 06 17 11 11 01 7f 74 61 62 6c 65 74 32 74 32 04 ......tablet2t2. +| 3904: 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 32 28 CREATE TABLE t2( +| 3920: 61 2c 62 2c 63 20 50 52 49 4d 41 52 59 20 4b 45 a,b,c PRIMARY KE +| 3936: 59 2c 20 64 2c 20 65 2c 20 66 29 20 57 49 54 48 Y, d, e, f) WITH +| 3952: 4f 55 54 20 52 4f 57 49 44 58 03 07 17 11 11 01 OUT ROWIDX...... +| 3968: 81 1b 74 61 62 6c 65 74 31 74 31 02 43 52 45 41 ..tablet1t1.CREA +| 3984: 54 45 20 54 41 42 4c 45 20 74 31 28 61 2c 62 2c TE TABLE t1(a,b, +| 4000: 63 20 41 53 20 28 2d 62 29 20 56 49 52 54 55 41 c AS (-b) VIRTUA +| 4016: 4c 2c 64 20 43 48 45 43 4b 28 64 3e 35 29 2c 65 L,d CHECK(d>5),e +| 4032: 20 55 4e 49 51 55 45 2c 20 66 20 41 53 20 28 2b UNIQUE, f AS (+ +| 4048: 62 29 29 23 02 06 17 37 11 01 00 69 6e 64 65 78 b))#...7...index +| 4064: 73 71 6c 69 74 65 5f 61 75 74 6f 69 6e 64 65 78 sqlite_autoindex +| 4080: 5f 74 31 5f 31 74 31 03 00 00 00 08 00 00 00 00 _t1_1t1......... +| page 2 offset 4096 +| 0: 0d 00 00 00 0a 0f 93 00 0f f6 0f eb 0f e0 0f d5 ................ +| 16: 0f ca 0f 8f 0f b4 0f a9 0f 9e 0f 93 00 00 00 00 ................ +| 3984: 00 00 00 09 0a 05 01 01 01 01 0a 64 6e 14 09 09 ...........dn... +| 4000: 05 01 01 01 01 09 5a 6d 12 09 08 05 01 01 01 01 ......Zm........ +| 4016: 08 50 6c 10 09 07 05 01 01 01 01 07 46 6b 0e 09 .Pl.........Fk.. +| 4032: 06 05 01 01 01 01 06 3c 6a 0c 09 05 05 01 01 01 ....... Date: Fri, 19 Feb 2021 15:34:16 +0000 Subject: [PATCH 220/257] Add tests for ALTER TABLE DROP COLUMN commands. FossilOrigin-Name: 05dbea9b26bdcb096194dc531816333f3784eca50b133fe3efede6ab0d233472 --- manifest | 12 +-- manifest.uuid | 2 +- test/alterdropcol2.test | 214 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 221 insertions(+), 7 deletions(-) create mode 100644 test/alterdropcol2.test diff --git a/manifest b/manifest index 7d02d42122..87b1469a9c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssupport\sfor\s"ALTER\sTABLE\s...\sDROP\sCOLUMN\s..."\scommands. -D 2021-02-19T14:32:58.535 +C Add\stests\sfor\sALTER\sTABLE\sDROP\sCOLUMN\scommands. +D 2021-02-19T15:34:16.257 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -649,6 +649,7 @@ F test/alterauth2.test 794ac5cef251819fe364b4fe20f12f86e9c5d68070513c7fd26c17cb2 F test/altercol.test 1d6a6fe698b81e626baea4881f5717f9bc53d7d07f1cd23ee7ad1b931f117ddf F test/altercorrupt.test cb17a81f655a0d71bc1e48e44741a5e0905a3b3efbbe485b0b6c7648f2af3eed F test/alterdropcol.test baad37ff9b07078ea02dcc33dbfb82bde655f3eee5c453e218f69501c36f02ba +F test/alterdropcol2.test 3948c805ca52f4621051b35968c18c09d107eb117e2b656c78cee3b2870650c0 F test/alterlegacy.test f38c6d06cda39e1f7b955bbce57f2e3ef5b7cb566d3d1234502093e228c15811 F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9 F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b @@ -1903,8 +1904,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 3c25cb4ab8885a50e2a485fe76f5ffd5dd8ebe1306aca8c0989e0b7fd7dd18d2 126ee1ec4f3565c0cccca98885fa3665a641ea3df251511de16eed2a1c396124 -R a9f6b9c36a39e6908ea00fd7298f0619 -T +closed 126ee1ec4f3565c0cccca98885fa3665a641ea3df251511de16eed2a1c396124 +P c844a331e78949850fde8ed95058cb34f863566944bc9e92e3ae042768f130e1 +R bd5254ae46e1e31d2902be2dbd124020 U dan -Z c1e3973235fcf41f620261cabeb4df13 +Z 3710b56eea4906fb9c766789f57cac08 diff --git a/manifest.uuid b/manifest.uuid index a03f87c63b..8d0357d6fb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c844a331e78949850fde8ed95058cb34f863566944bc9e92e3ae042768f130e1 \ No newline at end of file +05dbea9b26bdcb096194dc531816333f3784eca50b133fe3efede6ab0d233472 \ No newline at end of file diff --git a/test/alterdropcol2.test b/test/alterdropcol2.test new file mode 100644 index 0000000000..8af3677d32 --- /dev/null +++ b/test/alterdropcol2.test @@ -0,0 +1,214 @@ +# 2021 February 19 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#************************************************************************* +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix alterdropcol2 + +# If SQLITE_OMIT_ALTERTABLE is defined, omit this file. +ifcapable !altertable { + finish_test + return +} + +# EVIDENCE-OF: R-58318-35349 The DROP COLUMN syntax is used to remove an +# existing column from a table. +do_execsql_test 1.0 { + CREATE TABLE t1(c, b, a, PRIMARY KEY(b, a)) WITHOUT ROWID; + INSERT INTO t1 VALUES(1, 2, 3), (4, 5, 6); +} +do_execsql_test 1.1 { + ALTER TABLE t1 DROP c; +} + +# EVIDENCE-OF: The DROP COLUMN command removes the named column from the table, +# and also rewrites the entire table to purge the data associated with that +# column. +do_execsql_test 1.2.1 { + SELECT * FROM t1; +} {2 3 5 6} + +do_execsql_test 1.2.2 { + SELECT sql FROM sqlite_schema; +} { + {CREATE TABLE t1(b, a, PRIMARY KEY(b, a)) WITHOUT ROWID} +} + +proc do_atdc_error_test {tn schema atdc error} { + reset_db + execsql $schema + uplevel [list do_catchsql_test $tn $atdc [list 1 [string trim $error]]] +} + +#------------------------------------------------------------------------- +# Test cases 2.* attempt to verify the following: +# +# EVIDENCE-OF: R-24098-10282 The DROP COLUMN command only works if the column +# is not referenced by any other parts of the schema and is not a PRIMARY KEY +# and does not have a UNIQUE constraint. +# + +# EVIDENCE-OF: R-05184-13006 The column is a PRIMARY KEY. +# +do_atdc_error_test 2.1.1 { + CREATE TABLE x1(a PRIMARY KEY, b, c); +} { + ALTER TABLE x1 DROP COLUMN a +} { + cannot drop PRIMARY KEY column: "a" +} + +# EVIDENCE-OF: R-43412-16016 The column has a UNIQUE constraint. +# +do_atdc_error_test 2.2.1 { + CREATE TABLE x1(a PRIMARY KEY, b, c UNIQUE); +} { + ALTER TABLE x1 DROP COLUMN c +} { + cannot drop UNIQUE column: "c" +} +do_atdc_error_test 2.2.2 { + CREATE TABLE x1(a PRIMARY KEY, b, c, UNIQUE(b, c)); +} { + ALTER TABLE x1 DROP COLUMN c +} { + error in table x1 after drop column: no such column: c +} + +# EVIDENCE-OF: R-46731-08965: The column is indexed. +# +do_atdc_error_test 2.3.1 { + CREATE TABLE 'one two'('x y', 'z 1', 'a b'); + CREATE INDEX idx ON 'one two'('z 1'); +} { + ALTER TABLE 'one two' DROP COLUMN 'z 1' +} { + error in index idx after drop column: no such column: z 1 +} +do_atdc_error_test 2.3.2 { + CREATE TABLE x1(a, b, c); + CREATE INDEX idx ON x1(a); +} { + ALTER TABLE x1 DROP COLUMN a; +} { + error in index idx after drop column: no such column: a +} + +# EVIDENCE-OF: R-46731-08965: The column is indexed. +# +do_atdc_error_test 2.4.1 { + CREATE TABLE x1234(a, b, c PRIMARY KEY) WITHOUT ROWID; + CREATE INDEX i1 ON x1234(b) WHERE ((a+5) % 10)==0; +} { + ALTER TABLE x1234 DROP a +} { + error in index i1 after drop column: no such column: a +} + +# EVIDENCE-OF: R-18825-17786 The column appears in a table CHECK constraint. +# +do_atdc_error_test 2.5.1 { + CREATE TABLE x1234(a, b, c PRIMARY KEY, CHECK(((a+5)%10)!=0)) WITHOUT ROWID; +} { + ALTER TABLE x1234 DROP a +} { + error in table x1234 after drop column: no such column: a +} + +# EVIDENCE-OF: R-55640-01652 The column is used in a foreign key constraint. +# +do_atdc_error_test 2.6.1 { + CREATE TABLE p1(x, y UNIQUE); + CREATE TABLE c1(u, v, FOREIGN KEY (v) REFERENCES p1(y)) +} { + ALTER TABLE c1 DROP v +} { + error in table c1 after drop column: unknown column "v" in foreign key definition +} + +# EVIDENCE-OF: R-20795-39479 The column is used in the expression of a +# generated column. +do_atdc_error_test 2.7.1 { + CREATE TABLE c1(u, v, w AS (u+v)); +} { + ALTER TABLE c1 DROP v +} { + error in table c1 after drop column: no such column: v +} +do_atdc_error_test 2.7.2 { + CREATE TABLE c1(u, v, w AS (u+v) STORED); +} { + ALTER TABLE c1 DROP u +} { + error in table c1 after drop column: no such column: u +} + +# EVIDENCE-OF: R-01515-49025 The column appears in a trigger or view. +# +do_atdc_error_test 2.8.1 { + CREATE TABLE log(l); + CREATE TABLE c1(u, v, w); + CREATE TRIGGER tr1 AFTER INSERT ON c1 BEGIN + INSERT INTO log VALUES(new.w); + END; +} { + ALTER TABLE c1 DROP w +} { + error in trigger tr1 after drop column: no such column: new.w +} +do_atdc_error_test 2.8.2 { + CREATE TABLE c1(u, v, w); + CREATE VIEW v1 AS SELECT u, v, w FROM c1; +} { + ALTER TABLE c1 DROP w +} { + error in view v1 after drop column: no such column: w +} +do_atdc_error_test 2.8.3 { + CREATE TABLE c1(u, v, w); + CREATE VIEW v1 AS SELECT * FROM c1 WHERE w IS NOT NULL; +} { + ALTER TABLE c1 DROP w +} { + error in view v1 after drop column: no such column: w +} + +#------------------------------------------------------------------------- +# Verify that a column that is part of a CHECK constraint may be dropped +# if the CHECK constraint was specified as part of the column definition. +# + +# EVIDENCE-OF: R-60924-11170 However, the column being deleted can be used in a +# column CHECK constraint because the column CHECK constraint is dropped +# together with the column itself. +do_execsql_test 3.0 { + CREATE TABLE yyy(q, w, e CHECK (e > 0), r); + INSERT INTO yyy VALUES(1,1,1,1), (2,2,2,2); + + CREATE TABLE zzz(q, w, e, r, CHECK (e > 0)); + INSERT INTO zzz VALUES(1,1,1,1), (2,2,2,2); +} +do_catchsql_test 3.1.1 { + INSERT INTO yyy VALUES(0,0,0,0); +} {1 {CHECK constraint failed: e > 0}} +do_catchsql_test 3.1.2 { + INSERT INTO yyy VALUES(0,0,0,0); +} {1 {CHECK constraint failed: e > 0}} + +do_execsql_test 3.2.1 { + ALTER TABLE yyy DROP e; +} +do_catchsql_test 3.2.2 { + ALTER TABLE zzz DROP e; +} {1 {error in table zzz after drop column: no such column: e}} + +finish_test From 578277c25749e183e677217ad88799352749d854 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 19 Feb 2021 18:39:32 +0000 Subject: [PATCH 221/257] Fix another problem handling corrupt database files in the ALTER TABLE DROP COLUMN code. FossilOrigin-Name: 9edf2ddc4799c8830c4b7b91d7aacee50029a4b9db329fd4c5674fbedea33034 --- manifest | 16 ++++----- manifest.uuid | 2 +- src/alter.c | 12 +++---- src/build.c | 17 ++++------ test/altercorrupt.test | 77 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 98 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index 87b1469a9c..b3cbdb5100 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests\sfor\sALTER\sTABLE\sDROP\sCOLUMN\scommands. -D 2021-02-19T15:34:16.257 +C Fix\sanother\sproblem\shandling\scorrupt\sdatabase\sfiles\sin\sthe\sALTER\sTABLE\sDROP\sCOLUMN\scode. +D 2021-02-19T18:39:32.279 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 1addd06a7aae343497ebede71ec355c2011f175075943007341693ebf7daa47d +F src/alter.c 19b49c98a094f9dfc72998dc48f8e720e5ae98576f2316fc0f496aa5d3db9fb1 F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c F src/attach.c e80162a47411f296bea550ed8fafd730481f4aa71e89ece23ba9c957eed15d4a F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 @@ -485,7 +485,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 694020ad8a3af3d79b09f74c8f1421272a419cdea42a13401e3b0f7dea6e9c3e F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 -F src/build.c 72b868d9c8a0d56aef4237825b0fad38898a2d9310669940383accf20429c5ca +F src/build.c 3e1e1df6807c91c17b0e0cdf24d0e85176d7e006d9783ab3eb1afb154aa26822 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 @@ -647,7 +647,7 @@ F test/alter4.test dfd6086faf461b27ca2d2999848dcd207edf23352fc1592d0005c0844f3f0 F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959 F test/alterauth2.test 794ac5cef251819fe364b4fe20f12f86e9c5d68070513c7fd26c17cb244c89af F test/altercol.test 1d6a6fe698b81e626baea4881f5717f9bc53d7d07f1cd23ee7ad1b931f117ddf -F test/altercorrupt.test cb17a81f655a0d71bc1e48e44741a5e0905a3b3efbbe485b0b6c7648f2af3eed +F test/altercorrupt.test 36e71e0ff3042682c9137cdd40e19ccdcd6808f31ed9ba8a29fece356736a3ef F test/alterdropcol.test baad37ff9b07078ea02dcc33dbfb82bde655f3eee5c453e218f69501c36f02ba F test/alterdropcol2.test 3948c805ca52f4621051b35968c18c09d107eb117e2b656c78cee3b2870650c0 F test/alterlegacy.test f38c6d06cda39e1f7b955bbce57f2e3ef5b7cb566d3d1234502093e228c15811 @@ -1904,7 +1904,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 c844a331e78949850fde8ed95058cb34f863566944bc9e92e3ae042768f130e1 -R bd5254ae46e1e31d2902be2dbd124020 +P 05dbea9b26bdcb096194dc531816333f3784eca50b133fe3efede6ab0d233472 +R 654376f36a79c8c3f0a8b98f1eb136d6 U dan -Z 3710b56eea4906fb9c766789f57cac08 +Z 6b0bcca992d79748743aedfd1336dec2 diff --git a/manifest.uuid b/manifest.uuid index 8d0357d6fb..735950980f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -05dbea9b26bdcb096194dc531816333f3784eca50b133fe3efede6ab0d233472 \ No newline at end of file +9edf2ddc4799c8830c4b7b91d7aacee50029a4b9db329fd4c5674fbedea33034 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index e2af2beb8b..de710cda88 100644 --- a/src/alter.c +++ b/src/alter.c @@ -1777,7 +1777,6 @@ static void renameTableTest( ** argv[0]: An integer - the index of the schema containing the table ** argv[1]: CREATE TABLE statement to modify. ** argv[2]: An integer - the index of the column to remove. -** argv[3]: Byte offset of first byte after last column definition in argv[1] ** ** The value returned is a string containing the CREATE TABLE statement ** with column argv[2] removed. @@ -1791,7 +1790,6 @@ static void dropColumnFunc( int iSchema = sqlite3_value_int(argv[0]); const char *zSql = (const char*)sqlite3_value_text(argv[1]); int iCol = sqlite3_value_int(argv[2]); - int iAddColOffset = sqlite3_value_int(argv[3]); const char *zDb = db->aDb[iSchema].zDbSName; int rc; Parse sParse; @@ -1808,7 +1806,7 @@ static void dropColumnFunc( rc = renameParseSql(&sParse, zDb, db, zSql, iSchema==1); if( rc!=SQLITE_OK ) goto drop_column_done; pTab = sParse.pNewTable; - if( iCol>=pTab->nCol ){ + if( pTab->nCol==1 || iCol>=pTab->nCol ){ /* This can happen if the sqlite_schema table is corrupt */ rc = SQLITE_CORRUPT_BKPT; goto drop_column_done; @@ -1820,7 +1818,7 @@ static void dropColumnFunc( pEnd = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol+1].zName); zEnd = (const char*)pEnd->t.z; }else{ - zEnd = (const char*)&zSql[iAddColOffset]; + zEnd = (const char*)&zSql[pTab->addColOffset]; while( ALWAYS(pCol->t.z[0]!=0) && pCol->t.z[0]!=',' ) pCol->t.z--; } @@ -1901,9 +1899,9 @@ void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, Token *pName){ renameTestSchema(pParse, zDb, iDb==1, ""); sqlite3NestedParse(pParse, "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET " - "sql = sqlite_drop_column(%d, sql, %d, %d) " + "sql = sqlite_drop_column(%d, sql, %d) " "WHERE (type=='table' AND tbl_name=%Q COLLATE nocase)" - , zDb, iDb, iCol, pTab->addColOffset, pTab->zName + , zDb, iDb, iCol, pTab->zName ); /* Drop and reload the database schema. */ @@ -1969,7 +1967,7 @@ void sqlite3AlterFunctions(void){ INTERNAL_FUNCTION(sqlite_rename_column, 9, renameColumnFunc), INTERNAL_FUNCTION(sqlite_rename_table, 7, renameTableFunc), INTERNAL_FUNCTION(sqlite_rename_test, 6, renameTableTest), - INTERNAL_FUNCTION(sqlite_drop_column, 4, dropColumnFunc), + INTERNAL_FUNCTION(sqlite_drop_column, 3, dropColumnFunc), }; sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs)); } diff --git a/src/build.c b/src/build.c index bb6610f100..ed8a68fcf5 100644 --- a/src/build.c +++ b/src/build.c @@ -2658,20 +2658,17 @@ void sqlite3EndTable( } pParse->pNewTable = 0; db->mDbFlags |= DBFLAG_SchemaChange; + } #ifndef SQLITE_OMIT_ALTERTABLE - if( !p->pSelect ){ - const char *zName = (const char *)pParse->sNameToken.z; - int nName; - assert( !pSelect && pCons && pEnd ); - if( pCons->z==0 ){ - pCons = pEnd; - } - nName = (int)((const char *)pCons->z - zName); - p->addColOffset = 13 + nName; + if( !pSelect && !p->pSelect ){ + assert( pCons && pEnd ); + if( pCons->z==0 ){ + pCons = pEnd; } -#endif + p->addColOffset = 13 + (int)(pCons->z - pParse->sNameToken.z); } +#endif } #ifndef SQLITE_OMIT_VIEW diff --git a/test/altercorrupt.test b/test/altercorrupt.test index 84a67e281c..612e8d72d5 100644 --- a/test/altercorrupt.test +++ b/test/altercorrupt.test @@ -97,4 +97,81 @@ do_catchsql_test 1.2 { ALTER TABLE t1 DROP COLUMN f; } {1 {database disk image is malformed}} + +#-------------------------------------------------------------------------- +reset_db +do_test 2.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +.open --hexdb +| size 24576 pagesize 4096 filename crash-0572db8f391431.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 06 .....@ ........ +| 32: 00 00 63 00 10 05 f0 00 00 00 00 04 10 00 00 04 ..c............. +| 48: 00 00 00 00 00 00 0f f0 00 00 00 00 00 00 00 00 ................ +| 96: 00 00 00 00 0d 0f f8 00 05 0e cf 00 0f 79 0f d3 .............y.. +| 112: 0f 2e 0e f3 0e cf 00 00 00 00 00 00 00 00 00 00 ................ +| 3776: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 22 ................ +| 3792: 05 06 17 11 11 01 31 74 61 62 6c 65 74 34 74 34 ......1tablet4t4 +| 3808: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 34 .CREATE TABLE t4 +| 3824: 28 7a 29 39 04 06 17 11 11 01 5f 74 61 62 6c 65 (z)9......_table +| 3840: 74 33 74 33 05 43 52 45 41 54 45 20 54 41 42 4c t3t3.CREATE TABL +| 3856: 45 20 74 33 28 78 20 49 4e 54 55 47 45 52 20 50 E t3(x INTUGER P +| 3872: 52 49 4d 41 52 59 20 4b 45 59 2c 20 79 29 49 03 RIMARY KEY, y)I. +| 3888: 06 17 11 11 01 7f 74 61 62 6c 65 74 32 74 32 04 ......tablet2t2. +| 3904: 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 32 28 CREATE TABLE t2( +| 3920: 61 2c 62 2c 63 20 50 52 49 4d 41 52 59 20 4b 45 a,b,c PRIMARY KE +| 3936: 59 2c 20 64 2c 20 65 2c 20 66 29 20 57 49 54 48 Y, d, e, f) WITH +| 3952: 4f 55 54 20 52 4f 57 49 44 58 05 07 17 11 11 01 OUT ROWIDX...... +| 3968: 81 1b 74 61 62 6c 65 74 31 74 31 02 43 52 45 41 ..tablet1t1.CREA +| 3984: 54 45 20 54 41 42 4c 45 20 74 31 28 61 2c 62 2c TE TABLE t1(a,b, +| 4000: 63 20 41 53 20 28 2d 62 29 20 56 49 52 54 55 41 c AS (-b) VIRTUA +| 4016: 4c 2c 64 20 43 48 45 43 4b 28 64 3e 35 29 2c 65 L,d CHECK(d>5),e +| 4032: 20 55 4e 49 51 55 45 2c 20 66 20 41 53 20 28 2b UNIQUE, f AS (+ +| 4048: 62 29 29 23 02 06 17 37 11 01 00 69 6e 64 65 78 b))#...7...index +| 4064: 73 71 6c 69 74 65 5f 61 75 74 6f 69 6e 64 65 78 sqlite_autoindex +| 4080: 5f 74 31 5f 31 84 31 03 01 00 00 08 00 00 00 00 _t1_1.1......... +| page 2 offset 4096 +| 0: 0d 00 00 00 0a 0f 93 00 0f f6 0f eb 0f e0 0f d5 ................ +| 16: 0f ca 0f 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 3984: 00 00 00 09 0a 05 01 01 01 01 0a 64 6e 14 09 09 ...........dn... +| 4000: 05 01 01 01 01 09 5a 6d 12 09 08 05 01 00 f1 01 ......Zm........ +| 4016: 08 50 6c 10 09 07 05 01 01 01 01 07 46 6b 0e 09 .Pl.........Fk.. +| 4032: 06 05 01 00 f1 01 06 3c 6a 0c 09 05 05 01 01 01 ....... Date: Sat, 20 Feb 2021 13:36:14 +0000 Subject: [PATCH 222/257] Simplification to where.c manually cherrypicked from the as-materialize branch. FossilOrigin-Name: 03805a6117c813a33f9bca68bf4d9912997d6abd88ac9b3cb844c5d93ec68049 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index b3cbdb5100..da6ca42046 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sanother\sproblem\shandling\scorrupt\sdatabase\sfiles\sin\sthe\sALTER\sTABLE\sDROP\sCOLUMN\scode. -D 2021-02-19T18:39:32.279 +C Simplification\sto\swhere.c\smanually\scherrypicked\sfrom\sthe\sas-materialize\nbranch. +D 2021-02-20T13:36:14.978 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -628,7 +628,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 69e770e96fd56cc21608992bf2c6f1f3dc5cf2572d0495c6a643b06c3a679f14 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c d9c4e454ebb9499e908aa62d55b8994c375cf5355ac78f60d45af17f7890701c -F src/where.c 6efc4a10bfe0ec908c4f3c9112afb7675c952204b4b0b255672f488860141fec +F src/where.c 5737a9bd24115e7b3a9e6f637eba462d98e61272170618dd1cd9ac3baa854ed7 F src/whereInt.h ae03b5e3a4cca9bd9cb1b7d3c63faf8f1f177200fc8cecc87d3d0cab6ca338e6 F src/wherecode.c 43a63441f8662ddf86b15975683a502ec33f08167e9636f4d19e38e265e95fd9 F src/whereexpr.c f7b5469e83db3c3b9eb14e4ba44559a2e125523761d12e5ac8d8fb88301af393 @@ -1904,7 +1904,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 05dbea9b26bdcb096194dc531816333f3784eca50b133fe3efede6ab0d233472 -R 654376f36a79c8c3f0a8b98f1eb136d6 -U dan -Z 6b0bcca992d79748743aedfd1336dec2 +P 9edf2ddc4799c8830c4b7b91d7aacee50029a4b9db329fd4c5674fbedea33034 +R b70134b2efeeef7df7d7ac293b45ba53 +U drh +Z c54216abf02d6bbe69ae719b87b3ac9c diff --git a/manifest.uuid b/manifest.uuid index 735950980f..629d76186d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9edf2ddc4799c8830c4b7b91d7aacee50029a4b9db329fd4c5674fbedea33034 \ No newline at end of file +03805a6117c813a33f9bca68bf4d9912997d6abd88ac9b3cb844c5d93ec68049 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 971c223730..c95a9db68e 100644 --- a/src/where.c +++ b/src/where.c @@ -2954,7 +2954,7 @@ static int whereLoopAddBtree( pWC = pBuilder->pWC; assert( !IsVirtual(pSrc->pTab) ); - if( pSrc->pIBIndex ){ + if( pSrc->fg.isIndexedBy ){ /* An INDEXED BY clause specifies a particular index to use */ pProbe = pSrc->pIBIndex; }else if( !HasRowid(pTab) ){ @@ -2992,7 +2992,7 @@ static int whereLoopAddBtree( if( !pBuilder->pOrSet /* Not part of an OR optimization */ && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0 - && pSrc->pIBIndex==0 /* Has no INDEXED BY clause */ + && !pSrc->fg.isIndexedBy /* Has no INDEXED BY clause */ && !pSrc->fg.notIndexed /* Has no NOT INDEXED clause */ && HasRowid(pTab) /* Not WITHOUT ROWID table. (FIXME: Why not?) */ && !pSrc->fg.isCorrelated /* Not a correlated subquery */ @@ -3042,7 +3042,7 @@ static int whereLoopAddBtree( /* Loop over all indices. If there was an INDEXED BY clause, then only ** consider index pProbe. */ for(; rc==SQLITE_OK && pProbe; - pProbe=(pSrc->pIBIndex ? 0 : pProbe->pNext), iSortIdx++ + pProbe=(pSrc->fg.isIndexedBy ? 0 : pProbe->pNext), iSortIdx++ ){ int isLeft = (pSrc->fg.jointype & JT_OUTER)!=0; if( pProbe->pPartIdxWhere!=0 From f824b41e6431aa645c29a65c23743e0978a9dd3d Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 20 Feb 2021 14:57:16 +0000 Subject: [PATCH 223/257] Break out the Cte object from the With object. This will make it simpler to add new kinds of Cte objects (ex: DML statements) and/or MATERIALIZED keywords in the future. It brings trunk into closer alignment with the experimental as-materialize branch. FossilOrigin-Name: f03efe905d7b40fb25f9f78b874bb56c6d6ccacb60f86b3b199d430d5eade8d2 --- manifest | 16 +++++------ manifest.uuid | 2 +- src/build.c | 76 ++++++++++++++++++++++++++++++++++++++----------- src/parse.y | 49 +++++++++++++++---------------- src/sqliteInt.h | 37 +++++++++++++++--------- 5 files changed, 117 insertions(+), 63 deletions(-) diff --git a/manifest b/manifest index da6ca42046..f6ba8bff30 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplification\sto\swhere.c\smanually\scherrypicked\sfrom\sthe\sas-materialize\nbranch. -D 2021-02-20T13:36:14.978 +C Break\sout\sthe\sCte\sobject\sfrom\sthe\sWith\sobject.\s\sThis\swill\smake\sit\ssimpler\nto\sadd\snew\skinds\sof\sCte\sobjects\s(ex:\sDML\sstatements)\sand/or\sMATERIALIZED\nkeywords\sin\sthe\sfuture.\s\sIt\sbrings\strunk\sinto\scloser\salignment\swith\sthe\nexperimental\sas-materialize\sbranch. +D 2021-02-20T14:57:16.222 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -485,7 +485,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 694020ad8a3af3d79b09f74c8f1421272a419cdea42a13401e3b0f7dea6e9c3e F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 -F src/build.c 3e1e1df6807c91c17b0e0cdf24d0e85176d7e006d9783ab3eb1afb154aa26822 +F src/build.c 2cf3d07bcf26884f7ab090041960c3daa7436f9afe3f6a29c3d60fb046b3cdcf F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 @@ -530,7 +530,7 @@ F src/os_win.c 77d39873836f1831a9b0b91894fec45ab0e9ca8e067dc8c549e1d1eca1566fe9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c c49952ac5e9cc536778eff528091d79d38b3e45cbeeed4695dc05e207dc6547d F src/pager.h 4bf9b3213a4b2bebbced5eaa8b219cf25d4a82f385d093cd64b7e93e5285f66f -F src/parse.y cdc4e5efaf1618d82f6b241a30f1a586188bf37e9c55f967258ed15fe24c51a2 +F src/parse.y 81e6d07be0420419964c5e71c4445278776c6789b2606aad7b535986f68fe2b4 F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a @@ -546,7 +546,7 @@ F src/shell.c.in 844417f84df1f6c4fce1c815629a888cfdcf219e86513e9c332bbcc38832f47 F src/sqlite.h.in 8855a19f37ade8dad189a9e48233a2ebe1b46faf469c7eb0906a654e252dcc57 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h 4bd449478df0444ccb9f6a8e6f210b2ceacdd59562f52630edb0bb2d8cc25094 +F src/sqliteInt.h 180c58de36f96959aebdbd4f4aa373b1805c3815659aa1e1a5255739a21929fe F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1904,7 +1904,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 9edf2ddc4799c8830c4b7b91d7aacee50029a4b9db329fd4c5674fbedea33034 -R b70134b2efeeef7df7d7ac293b45ba53 +P 03805a6117c813a33f9bca68bf4d9912997d6abd88ac9b3cb844c5d93ec68049 +R a0c1971a7f0c50b4334b5a0eaa224033 U drh -Z c54216abf02d6bbe69ae719b87b3ac9c +Z 4aeed9ebd4e584b2ba4b31a4e09673dd diff --git a/manifest.uuid b/manifest.uuid index 629d76186d..5ec135f568 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -03805a6117c813a33f9bca68bf4d9912997d6abd88ac9b3cb844c5d93ec68049 \ No newline at end of file +f03efe905d7b40fb25f9f78b874bb56c6d6ccacb60f86b3b199d430d5eade8d2 \ No newline at end of file diff --git a/src/build.c b/src/build.c index ed8a68fcf5..37ea46708b 100644 --- a/src/build.c +++ b/src/build.c @@ -5204,24 +5204,74 @@ KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ } #ifndef SQLITE_OMIT_CTE +/* +** Create a new CTE object +*/ +Cte *sqlite3CteNew( + Parse *pParse, /* Parsing context */ + Token *pName, /* Name of the common-table */ + ExprList *pArglist, /* Optional column name list for the table */ + Select *pQuery /* Query used to initialize the table */ +){ + Cte *pNew; + sqlite3 *db = pParse->db; + + pNew = sqlite3DbMallocZero(db, sizeof(*pNew)); + assert( pNew!=0 || db->mallocFailed ); + + if( db->mallocFailed ){ + sqlite3ExprListDelete(db, pArglist); + sqlite3SelectDelete(db, pQuery); + }else{ + pNew->pSelect = pQuery; + pNew->pCols = pArglist; + pNew->zName = sqlite3NameFromToken(pParse->db, pName); + } + return pNew; +} + +/* +** Clear information from a Cte object, but do not deallocate storage +** for the object itself. +*/ +static void cteClear(sqlite3 *db, Cte *pCte){ + assert( pCte!=0 ); + sqlite3ExprListDelete(db, pCte->pCols); + sqlite3SelectDelete(db, pCte->pSelect); + sqlite3DbFree(db, pCte->zName); +} + +/* +** Free the contents of the CTE object passed as the second argument. +*/ +void sqlite3CteDelete(sqlite3 *db, Cte *pCte){ + assert( pCte!=0 ); + cteClear(db, pCte); + sqlite3DbFree(db, pCte); +} + /* ** This routine is invoked once per CTE by the parser while parsing a -** WITH clause. +** WITH clause. The CTE described by teh third argument is added to +** the WITH clause of the second argument. If the second argument is +** NULL, then a new WITH argument is created. */ With *sqlite3WithAdd( Parse *pParse, /* Parsing context */ With *pWith, /* Existing WITH clause, or NULL */ - Token *pName, /* Name of the common-table */ - ExprList *pArglist, /* Optional column name list for the table */ - Select *pQuery /* Query used to initialize the table */ + Cte *pCte /* CTE to add to the WITH clause */ ){ sqlite3 *db = pParse->db; With *pNew; char *zName; + if( pCte==0 ){ + return pWith; + } + /* Check that the CTE name is unique within this WITH clause. If ** not, store an error in the Parse structure. */ - zName = sqlite3NameFromToken(pParse->db, pName); + zName = pCte->zName; if( zName && pWith ){ int i; for(i=0; inCte; i++){ @@ -5240,16 +5290,11 @@ With *sqlite3WithAdd( assert( (pNew!=0 && zName!=0) || db->mallocFailed ); if( db->mallocFailed ){ - sqlite3ExprListDelete(db, pArglist); - sqlite3SelectDelete(db, pQuery); - sqlite3DbFree(db, zName); + sqlite3CteDelete(db, pCte); pNew = pWith; }else{ - pNew->a[pNew->nCte].pSelect = pQuery; - pNew->a[pNew->nCte].pCols = pArglist; - pNew->a[pNew->nCte].zName = zName; - pNew->a[pNew->nCte].zCteErr = 0; - pNew->nCte++; + pNew->a[pNew->nCte++] = *pCte; + sqlite3DbFree(db, pCte); } return pNew; @@ -5262,10 +5307,7 @@ void sqlite3WithDelete(sqlite3 *db, With *pWith){ if( pWith ){ int i; for(i=0; inCte; i++){ - struct Cte *pCte = &pWith->a[i]; - sqlite3ExprListDelete(db, pCte->pCols); - sqlite3SelectDelete(db, pCte->pSelect); - sqlite3DbFree(db, pCte->zName); + cteClear(db, &pWith->a[i]); } sqlite3DbFree(db, pWith); } diff --git a/src/parse.y b/src/parse.y index 82f760ede5..97a0ffd934 100644 --- a/src/parse.y +++ b/src/parse.y @@ -510,29 +510,25 @@ cmd ::= select(X). { } } } + + /* Attach a With object describing the WITH clause to a Select + ** object describing the query for which the WITH clause is a prefix. + */ + static Select *attachWithToSelect(Parse *pParse, Select *pSelect, With *pWith){ + if( pSelect ){ + pSelect->pWith = pWith; + parserDoubleLinkSelect(pParse, pSelect); + }else{ + sqlite3WithDelete(pParse->db, pWith); + } + return pSelect; + } } %ifndef SQLITE_OMIT_CTE -select(A) ::= WITH wqlist(W) selectnowith(X). { - Select *p = X; - if( p ){ - p->pWith = W; - parserDoubleLinkSelect(pParse, p); - }else{ - sqlite3WithDelete(pParse->db, W); - } - A = p; -} -select(A) ::= WITH RECURSIVE wqlist(W) selectnowith(X). { - Select *p = X; - if( p ){ - p->pWith = W; - parserDoubleLinkSelect(pParse, p); - }else{ - sqlite3WithDelete(pParse->db, W); - } - A = p; -} +select(A) ::= WITH wqlist(W) selectnowith(X). {A = attachWithToSelect(pParse,X,W);} +select(A) ::= WITH RECURSIVE wqlist(W) selectnowith(X). + {A = attachWithToSelect(pParse,X,W);} %endif /* SQLITE_OMIT_CTE */ select(A) ::= selectnowith(X). { Select *p = X; @@ -1662,17 +1658,22 @@ anylist ::= anylist ANY. //////////////////////// COMMON TABLE EXPRESSIONS //////////////////////////// %type wqlist {With*} %destructor wqlist {sqlite3WithDelete(pParse->db, $$);} +%type wqitem {Cte*} +// %destructor wqitem {sqlite3CteDelete(pParse->db, $$);} // not reachable with ::= . %ifndef SQLITE_OMIT_CTE with ::= WITH wqlist(W). { sqlite3WithPush(pParse, W, 1); } with ::= WITH RECURSIVE wqlist(W). { sqlite3WithPush(pParse, W, 1); } -wqlist(A) ::= nm(X) eidlist_opt(Y) AS LP select(Z) RP. { - A = sqlite3WithAdd(pParse, 0, &X, Y, Z); /*A-overwrites-X*/ +wqitem(A) ::= nm(X) eidlist_opt(Y) AS LP select(Z) RP. { + A = sqlite3CteNew(pParse, &X, Y, Z); /*A-overwrites-X*/ } -wqlist(A) ::= wqlist(A) COMMA nm(X) eidlist_opt(Y) AS LP select(Z) RP. { - A = sqlite3WithAdd(pParse, A, &X, Y, Z); +wqlist(A) ::= wqitem(X). { + A = sqlite3WithAdd(pParse, 0, X); /*A-overwrites-X*/ +} +wqlist(A) ::= wqlist(A) COMMA wqitem(X). { + A = sqlite3WithAdd(pParse, A, X); } %endif SQLITE_OMIT_CTE diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 961a6ed86f..78bb048fab 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1136,6 +1136,7 @@ typedef struct AutoincInfo AutoincInfo; typedef struct Bitvec Bitvec; typedef struct CollSeq CollSeq; typedef struct Column Column; +typedef struct Cte Cte; typedef struct Db Db; typedef struct DbFixer DbFixer; typedef struct Schema Schema; @@ -3874,18 +3875,23 @@ void sqlite3SelectWalkAssert2(Walker*, Select*); #define WRC_Abort 2 /* Abandon the tree walk */ /* -** An instance of this structure represents a set of one or more CTEs -** (common table expressions) created by a single WITH clause. +** A single common table expression +*/ +struct Cte { + char *zName; /* Name of this CTE */ + ExprList *pCols; /* List of explicit column names, or NULL */ + Select *pSelect; /* The definition of this CTE */ + const char *zCteErr; /* Error message for circular references */ +}; + +/* +** An instance of the With object represents a WITH clause containing +** one or more CTEs (common table expressions). */ struct With { - int nCte; /* Number of CTEs in the WITH clause */ - With *pOuter; /* Containing WITH clause, or NULL */ - struct Cte { /* For each CTE in the WITH clause.... */ - char *zName; /* Name of this CTE */ - ExprList *pCols; /* List of explicit column names, or NULL */ - Select *pSelect; /* The definition of this CTE */ - const char *zCteErr; /* Error message for circular references */ - } a[1]; + int nCte; /* Number of CTEs in the WITH clause */ + With *pOuter; /* Containing WITH clause, or NULL */ + Cte a[1]; /* For each CTE in the WITH clause.... */ }; #ifdef SQLITE_DEBUG @@ -4891,12 +4897,17 @@ const char *sqlite3JournalModename(int); int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int); #endif #ifndef SQLITE_OMIT_CTE - With *sqlite3WithAdd(Parse*,With*,Token*,ExprList*,Select*); + Cte *sqlite3CteNew(Parse*,Token*,ExprList*,Select*); + void sqlite3CteDelete(sqlite3*,Cte*); + With *sqlite3WithAdd(Parse*,With*,Cte*); void sqlite3WithDelete(sqlite3*,With*); void sqlite3WithPush(Parse*, With*, u8); #else -#define sqlite3WithPush(x,y,z) -#define sqlite3WithDelete(x,y) +# define sqlite3CteNew(P,T,E,S) ((void*)0) +# define sqlite3CteDelete(D,C) +# define sqlite3CteWithAdd(P,W,C) ((void*)0) +# define sqlite3WithDelete(x,y) +# define sqlite3WithPush(x,y,z) #endif #ifndef SQLITE_OMIT_UPSERT Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*,Upsert*); From 1e25d20cca3ee566f38557e339c6d199772f5c96 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 20 Feb 2021 18:02:37 +0000 Subject: [PATCH 224/257] Update sqlite3changeset_apply_v2() so that it handles no-op UPDATE changes (UPDATE changes that modify no columns). This fixes a regression introduced by [e4ccfac09b]. Also modify sqlite3rebaser_rebase() so that it does not output changesets containing such UPDATEs. FossilOrigin-Name: 0288a8013e00594e716a5fb0d9f684dcfeb03e877650630e2736565fa6261290 --- ext/session/sessionnoop.test | 187 +++++++++++++++++++++++++++++++++++ ext/session/sqlite3session.c | 92 +++++++++++------ manifest | 15 +-- manifest.uuid | 2 +- 4 files changed, 259 insertions(+), 37 deletions(-) create mode 100644 ext/session/sessionnoop.test diff --git a/ext/session/sessionnoop.test b/ext/session/sessionnoop.test new file mode 100644 index 0000000000..16c60b7abf --- /dev/null +++ b/ext/session/sessionnoop.test @@ -0,0 +1,187 @@ +# 2021 Februar 20 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} + +set testprefix sessionnoop + +#------------------------------------------------------------------------- +# Test plan: +# +# 1.*: Test that concatenating changesets cannot produce a noop UPDATE. +# 2.*: Test that rebasing changesets cannot produce a noop UPDATE. +# 3.*: Test that sqlite3changeset_apply() ignores noop UPDATE changes. +# + +do_execsql_test 1.0 { + CREATE TABLE t1(a PRIMARY KEY, b, c, d); + INSERT INTO t1 VALUES(1, 1, 1, 1); + INSERT INTO t1 VALUES(2, 2, 2, 2); + INSERT INTO t1 VALUES(3, 3, 3, 3); +} + +proc do_concat_test {tn sql1 sql2 res} { + uplevel [list do_test $tn [subst -nocommands { + set C1 [changeset_from_sql {$sql1}] + set C2 [changeset_from_sql {$sql2}] + set C3 [sqlite3changeset_concat [set C1] [set C2]] + set got [list] + sqlite3session_foreach elem [set C3] { lappend got [set elem] } + set got + }] [list {*}$res]] +} + +do_concat_test 1.1 { + UPDATE t1 SET c=c+1; +} { + UPDATE t1 SET c=c-1; +} { +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 2.0 { + CREATE TABLE t1(a PRIMARY KEY, b, c); + INSERT INTO t1 VALUES(1, 1, 1); + INSERT INTO t1 VALUES(2, 2, 2); + INSERT INTO t1 VALUES(3, 3, 3); +} + +proc do_rebase_test {tn sql_local sql_remote conflict_res expected} { + proc xConflict {args} [list return $conflict_res] + + uplevel [list \ + do_test $tn [subst -nocommands { + execsql BEGIN + set c_remote [changeset_from_sql {$sql_remote}] + execsql ROLLBACK + + execsql BEGIN + set c_local [changeset_from_sql {$sql_local}] + set base [sqlite3changeset_apply_v2 db [set c_remote] xConflict] + execsql ROLLBACK + + sqlite3rebaser_create R + R config [set base] + set res [list] + sqlite3session_foreach elem [R rebase [set c_local]] { + lappend res [set elem] + } + R delete + set res + }] [list {*}$expected] + ] +} + +do_rebase_test 2.1 { + UPDATE t1 SET c=2 WHERE a=1; -- local +} { + UPDATE t1 SET c=3 WHERE a=1; -- remote +} OMIT { + {UPDATE t1 0 X.. {i 1 {} {} i 3} {{} {} {} {} i 2}} +} + +do_rebase_test 2.2 { + UPDATE t1 SET c=2 WHERE a=1; -- local +} { + UPDATE t1 SET c=3 WHERE a=1; -- remote +} REPLACE { +} + +do_rebase_test 2.3.1 { + UPDATE t1 SET c=4 WHERE a=1; -- local +} { + UPDATE t1 SET c=4 WHERE a=1 -- remote +} OMIT { + {UPDATE t1 0 X.. {i 1 {} {} i 4} {{} {} {} {} i 4}} +} + +do_rebase_test 2.3.2 { + UPDATE t1 SET c=5 WHERE a=1; -- local +} { + UPDATE t1 SET c=5 WHERE a=1 -- remote +} REPLACE { +} + +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 3.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); + INSERT INTO t1 VALUES(1, 1, 1); + INSERT INTO t1 VALUES(2, 2, 2); + INSERT INTO t1 VALUES(3, 3, 3); + INSERT INTO t1 VALUES(4, 4, 4); +} + +# Arg $pkstr contains one character for each column in the table. An +# "X" for PK column, or a "." for a non-PK. +# +proc mk_tbl_header {name pkstr} { + set ret [binary format H2c 54 [string length $pkstr]] + foreach i [split $pkstr {}] { + if {$i=="X"} { + append ret [binary format H2 01] + } else { + if {$i!="."} {error "bad pkstr: $pkstr ($i)"} + append ret [binary format H2 00] + } + } + append ret $name + append ret [binary format H2 00] + set ret +} + +proc mk_update_change {args} { + set ret [binary format H2H2 17 00] + foreach a $args { + if {$a==""} { + append ret [binary format H2 00] + } else { + append ret [binary format H2W 01 $a] + } + } + set ret +} + +proc xConflict {args} { return "ABORT" } +do_test 3.1 { + set C [mk_tbl_header t1 X..] + append C [mk_update_change 1 {} 1 {} {} 500] + append C [mk_update_change 2 {} {} {} {} {}] + append C [mk_update_change 3 3 {} {} 600 {}] + append C [mk_update_change 4 {} {} {} {} {}] + + sqlite3changeset_apply_v2 db $C xConflict +} {} +do_execsql_test 3.2 { + SELECT * FROM t1 +} { + 1 1 500 + 2 2 2 + 3 600 3 + 4 4 4 +} + + + + + + +finish_test + diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index cafa5b29b7..8210056a89 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -91,6 +91,7 @@ struct sqlite3_changeset_iter { SessionBuffer tblhdr; /* Buffer to hold apValue/zTab/abPK/ */ int bPatchset; /* True if this is a patchset */ int bInvert; /* True to invert changeset */ + int bSkipEmpty; /* Skip noop UPDATE changes */ int rc; /* Iterator error code */ sqlite3_stmt *pConflict; /* Points to conflicting row, if any */ char *zTab; /* Current table */ @@ -2620,7 +2621,8 @@ static int sessionChangesetStart( void *pIn, int nChangeset, /* Size of buffer pChangeset in bytes */ void *pChangeset, /* Pointer to buffer containing changeset */ - int bInvert /* True to invert changeset */ + int bInvert, /* True to invert changeset */ + int bSkipEmpty /* True to skip empty UPDATE changes */ ){ sqlite3_changeset_iter *pRet; /* Iterator to return */ int nByte; /* Number of bytes to allocate for iterator */ @@ -2641,6 +2643,7 @@ static int sessionChangesetStart( pRet->in.pIn = pIn; pRet->in.bEof = (xInput ? 0 : 1); pRet->bInvert = bInvert; + pRet->bSkipEmpty = bSkipEmpty; /* Populate the output variable and return success. */ *pp = pRet; @@ -2655,7 +2658,7 @@ int sqlite3changeset_start( int nChangeset, /* Size of buffer pChangeset in bytes */ void *pChangeset /* Pointer to buffer containing changeset */ ){ - return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, 0); + return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, 0, 0); } int sqlite3changeset_start_v2( sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */ @@ -2664,7 +2667,7 @@ int sqlite3changeset_start_v2( int flags ){ int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT); - return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, bInvert); + return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, bInvert, 0); } /* @@ -2675,7 +2678,7 @@ int sqlite3changeset_start_strm( int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn ){ - return sessionChangesetStart(pp, xInput, pIn, 0, 0, 0); + return sessionChangesetStart(pp, xInput, pIn, 0, 0, 0, 0); } int sqlite3changeset_start_v2_strm( sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */ @@ -2684,7 +2687,7 @@ int sqlite3changeset_start_v2_strm( int flags ){ int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT); - return sessionChangesetStart(pp, xInput, pIn, 0, 0, bInvert); + return sessionChangesetStart(pp, xInput, pIn, 0, 0, bInvert, 0); } /* @@ -2810,11 +2813,14 @@ static int sessionReadRecord( SessionInput *pIn, /* Input data */ int nCol, /* Number of values in record */ u8 *abPK, /* Array of primary key flags, or NULL */ - sqlite3_value **apOut /* Write values to this array */ + sqlite3_value **apOut, /* Write values to this array */ + int *pbEmpty ){ int i; /* Used to iterate through columns */ int rc = SQLITE_OK; + assert( pbEmpty==0 || *pbEmpty==0 ); + if( pbEmpty ) *pbEmpty = 1; for(i=0; iaData[pIn->iNext++]; assert( apOut[i]==0 ); if( eType ){ + if( pbEmpty ) *pbEmpty = 0; apOut[i] = sqlite3ValueNew(0); if( !apOut[i] ) rc = SQLITE_NOMEM; } @@ -3005,31 +3012,27 @@ static int sessionChangesetReadTblhdr(sqlite3_changeset_iter *p){ } /* -** Advance the changeset iterator to the next change. +** Advance the changeset iterator to the next change. The differences between +** this function and sessionChangesetNext() are that ** -** If both paRec and pnRec are NULL, then this function works like the public -** API sqlite3changeset_next(). If SQLITE_ROW is returned, then the -** sqlite3changeset_new() and old() APIs may be used to query for values. +** * If pbEmpty is not NULL and the change is a no-op UPDATE (an UPDATE +** that modifies no columns), this function sets (*pbEmpty) to 1. ** -** Otherwise, if paRec and pnRec are not NULL, then a pointer to the change -** record is written to *paRec before returning and the number of bytes in -** the record to *pnRec. -** -** Either way, this function returns SQLITE_ROW if the iterator is -** successfully advanced to the next change in the changeset, an SQLite -** error code if an error occurs, or SQLITE_DONE if there are no further -** changes in the changeset. +** * If the iterator is configured to skip no-op UPDATEs, +** sessionChangesetNext() does that. This function does not. */ -static int sessionChangesetNext( +static int sessionChangesetNextOne( sqlite3_changeset_iter *p, /* Changeset iterator */ u8 **paRec, /* If non-NULL, store record pointer here */ int *pnRec, /* If non-NULL, store size of record here */ - int *pbNew /* If non-NULL, true if new table */ + int *pbNew, /* If non-NULL, true if new table */ + int *pbEmpty ){ int i; u8 op; assert( (paRec==0 && pnRec==0) || (paRec && pnRec) ); + assert( pbEmpty==0 || *pbEmpty==0 ); /* If the iterator is in the error-state, return immediately. */ if( p->rc!=SQLITE_OK ) return p->rc; @@ -3102,13 +3105,13 @@ static int sessionChangesetNext( /* If this is an UPDATE or DELETE, read the old.* record. */ if( p->op!=SQLITE_INSERT && (p->bPatchset==0 || p->op==SQLITE_DELETE) ){ u8 *abPK = p->bPatchset ? p->abPK : 0; - p->rc = sessionReadRecord(&p->in, p->nCol, abPK, apOld); + p->rc = sessionReadRecord(&p->in, p->nCol, abPK, apOld, 0); if( p->rc!=SQLITE_OK ) return p->rc; } /* If this is an INSERT or UPDATE, read the new.* record. */ if( p->op!=SQLITE_DELETE ){ - p->rc = sessionReadRecord(&p->in, p->nCol, 0, apNew); + p->rc = sessionReadRecord(&p->in, p->nCol, 0, apNew, pbEmpty); if( p->rc!=SQLITE_OK ) return p->rc; } @@ -3135,6 +3138,37 @@ static int sessionChangesetNext( return SQLITE_ROW; } +/* +** Advance the changeset iterator to the next change. +** +** If both paRec and pnRec are NULL, then this function works like the public +** API sqlite3changeset_next(). If SQLITE_ROW is returned, then the +** sqlite3changeset_new() and old() APIs may be used to query for values. +** +** Otherwise, if paRec and pnRec are not NULL, then a pointer to the change +** record is written to *paRec before returning and the number of bytes in +** the record to *pnRec. +** +** Either way, this function returns SQLITE_ROW if the iterator is +** successfully advanced to the next change in the changeset, an SQLite +** error code if an error occurs, or SQLITE_DONE if there are no further +** changes in the changeset. +*/ +static int sessionChangesetNext( + sqlite3_changeset_iter *p, /* Changeset iterator */ + u8 **paRec, /* If non-NULL, store record pointer here */ + int *pnRec, /* If non-NULL, store size of record here */ + int *pbNew /* If non-NULL, true if new table */ +){ + int bEmpty; + int rc; + do { + bEmpty = 0; + rc = sessionChangesetNextOne(p, paRec, pnRec, pbNew, &bEmpty); + }while( rc==SQLITE_ROW && p->bSkipEmpty && bEmpty); + return rc; +} + /* ** Advance an iterator created by sqlite3changeset_start() to the next ** change in the changeset. This function may return SQLITE_ROW, SQLITE_DONE @@ -3407,9 +3441,9 @@ static int sessionChangesetInvert( /* Read the old.* and new.* records for the update change. */ pInput->iNext += 2; - rc = sessionReadRecord(pInput, nCol, 0, &apVal[0]); + rc = sessionReadRecord(pInput, nCol, 0, &apVal[0], 0); if( rc==SQLITE_OK ){ - rc = sessionReadRecord(pInput, nCol, 0, &apVal[nCol]); + rc = sessionReadRecord(pInput, nCol, 0, &apVal[nCol], 0); } /* Write the new old.* record. Consists of the PK columns from the @@ -4357,7 +4391,7 @@ static int sessionRetryConstraints( memset(&pApply->constraints, 0, sizeof(SessionBuffer)); rc = sessionChangesetStart( - &pIter2, 0, 0, cons.nBuf, cons.aBuf, pApply->bInvertConstraints + &pIter2, 0, 0, cons.nBuf, cons.aBuf, pApply->bInvertConstraints, 1 ); if( rc==SQLITE_OK ){ size_t nByte = 2*pApply->nCol*sizeof(sqlite3_value*); @@ -4613,8 +4647,8 @@ int sqlite3changeset_apply_v2( int flags ){ sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ - int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); - int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset,bInverse); + int bInv = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); + int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset, bInv, 1); if( rc==SQLITE_OK ){ rc = sessionChangesetApply( db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags @@ -4672,7 +4706,7 @@ int sqlite3changeset_apply_v2_strm( ){ sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); - int rc = sessionChangesetStart(&pIter, xInput, pIn, 0, 0, bInverse); + int rc = sessionChangesetStart(&pIter, xInput, pIn, 0, 0, bInverse, 1); if( rc==SQLITE_OK ){ rc = sessionChangesetApply( db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags @@ -5292,7 +5326,7 @@ static void sessionAppendPartialUpdate( int n1 = sessionSerialLen(a1); int n2 = sessionSerialLen(a2); if( pIter->abPK[i] || a2[0]==0 ){ - if( !pIter->abPK[i] ) bData = 1; + if( !pIter->abPK[i] && a1[0] ) bData = 1; memcpy(pOut, a1, n1); pOut += n1; }else if( a2[0]!=0xFF ){ diff --git a/manifest b/manifest index f6ba8bff30..2a87f6682f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Break\sout\sthe\sCte\sobject\sfrom\sthe\sWith\sobject.\s\sThis\swill\smake\sit\ssimpler\nto\sadd\snew\skinds\sof\sCte\sobjects\s(ex:\sDML\sstatements)\sand/or\sMATERIALIZED\nkeywords\sin\sthe\sfuture.\s\sIt\sbrings\strunk\sinto\scloser\salignment\swith\sthe\nexperimental\sas-materialize\sbranch. -D 2021-02-20T14:57:16.222 +C Update\ssqlite3changeset_apply_v2()\sso\sthat\sit\shandles\sno-op\sUPDATE\schanges\s(UPDATE\schanges\sthat\smodify\sno\scolumns).\sThis\sfixes\sa\sregression\sintroduced\sby\s[e4ccfac09b].\sAlso\smodify\ssqlite3rebaser_rebase()\sso\sthat\sit\sdoes\snot\soutput\schangesets\scontaining\ssuch\sUPDATEs. +D 2021-02-20T18:02:37.933 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -451,10 +451,11 @@ F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7 F ext/session/sessionfault2.test dd593f80b6b4786f7adfe83c5939620bc505559770cc181332da26f29cddd7bb F ext/session/sessioninvert.test 04075517a9497a80d39c495ba6b44f3982c7371129b89e2c52219819bc105a25 F ext/session/sessionmem.test f2a735db84a3e9e19f571033b725b0b2daf847f3f28b1da55a0c1a4e74f1de09 +F ext/session/sessionnoop.test a9366a36a95ef85f8a3687856ebef46983df399541174cb1ede2ee53b8011bc7 F ext/session/sessionrebase.test ccfa716b23bd1d3b03217ee58cfd90c78d4b99f53e6a9a2f05e82363b9142810 F ext/session/sessionstat1.test 218d351cf9fcd6648f125a26b607b140310160184723c2666091b54450a68fb5 F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc -F ext/session/sqlite3session.c 1d0553077b55ffcfa69963c354e9bad3bace6ce79bbe7368e650c6ae1e106314 +F ext/session/sqlite3session.c a7c5ac1acfe21d94b37921b29b0458d64d022a66b282338eee4aafa9c018cb1c F ext/session/sqlite3session.h f53c99731882bf59c7362855cdeba176ce1fe8eeba089e38a8cce0172f8473aa F ext/session/test_session.c 93ca965112d2b4d9d669c9c0be6b1e52942a268796050a145612df1eee175ce0 F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3 @@ -1904,7 +1905,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 03805a6117c813a33f9bca68bf4d9912997d6abd88ac9b3cb844c5d93ec68049 -R a0c1971a7f0c50b4334b5a0eaa224033 -U drh -Z 4aeed9ebd4e584b2ba4b31a4e09673dd +P f03efe905d7b40fb25f9f78b874bb56c6d6ccacb60f86b3b199d430d5eade8d2 +R abe6f39b4d6e21d7c13ff311c0c06b1f +U dan +Z af5325b22c1dec3dd9459f9acd3cf21e diff --git a/manifest.uuid b/manifest.uuid index 5ec135f568..110e522406 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f03efe905d7b40fb25f9f78b874bb56c6d6ccacb60f86b3b199d430d5eade8d2 \ No newline at end of file +0288a8013e00594e716a5fb0d9f684dcfeb03e877650630e2736565fa6261290 \ No newline at end of file From 1e0cfd7184285d4b4592055b5214cab04165eae5 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 20 Feb 2021 19:22:32 +0000 Subject: [PATCH 225/257] Fix a case where FTS3/4 could pass a NULL pointer to memcpy() when handling a corrupt db. FossilOrigin-Name: 68bb541a39833d7d4bf41aa91cb6cd9c98757d1fc8236299d09db7e9b14d8ec9 --- ext/fts3/fts3_write.c | 36 +++++++++-------- manifest | 14 +++---- manifest.uuid | 2 +- test/fts3corrupt4.test | 88 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 116 insertions(+), 24 deletions(-) diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c index 092cad9ac5..f7ab6432b6 100644 --- a/ext/fts3/fts3_write.c +++ b/ext/fts3/fts3_write.c @@ -4335,23 +4335,27 @@ static int fts3IncrmergeLoad( while( reader.aNode && rc==SQLITE_OK ) rc = nodeReaderNext(&reader); blobGrowBuffer(&pNode->key, reader.term.n, &rc); if( rc==SQLITE_OK ){ - memcpy(pNode->key.a, reader.term.a, reader.term.n); - pNode->key.n = reader.term.n; - if( i>0 ){ - char *aBlock = 0; - int nBlock = 0; - pNode = &pWriter->aNodeWriter[i-1]; - pNode->iBlock = reader.iChild; - rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock, 0); - blobGrowBuffer(&pNode->block, - MAX(nBlock, p->nNodeSize)+FTS3_NODE_PADDING, &rc - ); - if( rc==SQLITE_OK ){ - memcpy(pNode->block.a, aBlock, nBlock); - pNode->block.n = nBlock; - memset(&pNode->block.a[nBlock], 0, FTS3_NODE_PADDING); + if( reader.term.n<=0 ){ + rc = FTS_CORRUPT_VTAB; + }else{ + memcpy(pNode->key.a, reader.term.a, reader.term.n); + pNode->key.n = reader.term.n; + if( i>0 ){ + char *aBlock = 0; + int nBlock = 0; + pNode = &pWriter->aNodeWriter[i-1]; + pNode->iBlock = reader.iChild; + rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock,0); + blobGrowBuffer(&pNode->block, + MAX(nBlock, p->nNodeSize)+FTS3_NODE_PADDING, &rc + ); + if( rc==SQLITE_OK ){ + memcpy(pNode->block.a, aBlock, nBlock); + pNode->block.n = nBlock; + memset(&pNode->block.a[nBlock], 0, FTS3_NODE_PADDING); + } + sqlite3_free(aBlock); } - sqlite3_free(aBlock); } } } diff --git a/manifest b/manifest index 2a87f6682f..a8a07cff8b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\ssqlite3changeset_apply_v2()\sso\sthat\sit\shandles\sno-op\sUPDATE\schanges\s(UPDATE\schanges\sthat\smodify\sno\scolumns).\sThis\sfixes\sa\sregression\sintroduced\sby\s[e4ccfac09b].\sAlso\smodify\ssqlite3rebaser_rebase()\sso\sthat\sit\sdoes\snot\soutput\schangesets\scontaining\ssuch\sUPDATEs. -D 2021-02-20T18:02:37.933 +C Fix\sa\scase\swhere\sFTS3/4\scould\spass\sa\sNULL\spointer\sto\smemcpy()\swhen\shandling\sa\scorrupt\sdb. +D 2021-02-20T19:22:32.180 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -102,7 +102,7 @@ F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3 F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004 F ext/fts3/fts3_unicode.c 4b9af6151c29b35ed09574937083cece7c31e911f69615e168a39677569b684d F ext/fts3/fts3_unicode2.c 416eb7e1e81142703520d284b768ca2751d40e31fa912cae24ba74860532bf0f -F ext/fts3/fts3_write.c 723ed1b11ed46ad1b3a23c0d69fa39e77986783a82d5711bf87a5ce29e0a3b52 +F ext/fts3/fts3_write.c 3b5df74d6563df46f90103a84630613a9fdb782ed93161470df2186e8e906d8c F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100 F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73 @@ -968,7 +968,7 @@ F test/fts3conf.test c84bbaec81281c1788aa545ac6e78a6bd6cde2bdbbce2da261690e3659f F test/fts3corrupt.test 79a32ffdcd5254e2f7fa121d9656e61949ad049c3c6554229911b7ceac37c9c6 F test/fts3corrupt2.test e318f0676e5e78d5a4b702637e2bb25265954c08a1b1e4aaf93c7880bb0c67d0 F test/fts3corrupt3.test 0d5b69a0998b4adf868cc301fc78f3d0707745f1d984ce044c205cdb764b491f -F test/fts3corrupt4.test e4662d37f02248301d8b58778eac380663e09a17a38dd5d6bb5ea4c927b9a575 +F test/fts3corrupt4.test b71512ec391d39da96d60d01959e4e9f20d4237a964a94abcf5f5a2ad28378c1 F test/fts3corrupt5.test 0549f85ec4bd22e992f645f13c59b99d652f2f5e643dac75568bfd23a6db7ed5 F test/fts3corrupt6.test b6c55218b704b0cef224b284c756f9c55d0afd0b3c3837618bffeaa8c31e0d8e F test/fts3cov.test 7eacdbefd756cfa4dc2241974e3db2834e9b372ca215880e00032222f32194cf @@ -1905,7 +1905,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 f03efe905d7b40fb25f9f78b874bb56c6d6ccacb60f86b3b199d430d5eade8d2 -R abe6f39b4d6e21d7c13ff311c0c06b1f +P 0288a8013e00594e716a5fb0d9f684dcfeb03e877650630e2736565fa6261290 +R d444093c909052ae4578b7954edb269e U dan -Z af5325b22c1dec3dd9459f9acd3cf21e +Z 66cf8c59efba0e2d47b96d42e8888972 diff --git a/manifest.uuid b/manifest.uuid index 110e522406..05d7c7fd0c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0288a8013e00594e716a5fb0d9f684dcfeb03e877650630e2736565fa6261290 \ No newline at end of file +68bb541a39833d7d4bf41aa91cb6cd9c98757d1fc8236299d09db7e9b14d8ec9 \ No newline at end of file diff --git a/test/fts3corrupt4.test b/test/fts3corrupt4.test index bddcc9f5de..851119a2fe 100644 --- a/test/fts3corrupt4.test +++ b/test/fts3corrupt4.test @@ -6298,4 +6298,92 @@ do_catchsql_test 47.3 { SELECT matchinfo(t1) FROM t1 WHERE t1 MATCH '"json1 enable"'; } {1 {database disk image is malformed}} +#------------------------------------------------------------------------- +# +reset_db +do_test 48.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +.open --hexdb +| size 20480 pagesize 4096 filename sql038051.txt.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........ +| 96: 00 00 00 00 0d 0e fc 00 05 0e 13 00 0f ca 0f 6c ...............l +| 112: 0f 04 0e 13 0e c9 00 00 00 00 00 00 00 00 00 00 ................ +| 3600: 00 00 00 81 33 04 07 17 1f 1f 01 82 35 74 61 62 ....3.......5tab +| 3616: 6c 65 78 31 5f 73 65 67 64 69 72 78 31 5f 73 65 lex1_segdirx1_se +| 3632: 67 64 69 72 04 43 52 45 41 54 45 20 54 41 42 4c gdir.CREATE TABL +| 3648: 45 20 27 78 31 5f 73 65 67 64 69 72 27 28 6c 65 E 'x1_segdir'(le +| 3664: 76 65 6c 20 49 4e 54 45 47 45 52 2c 69 64 78 20 vel INTEGER,idx +| 3680: 49 4e 54 45 47 45 52 2c 73 74 61 72 74 5f 62 6c INTEGER,start_bl +| 3696: 6f 63 6b 20 49 4e 54 45 47 45 52 2c 6c 65 61 76 ock INTEGER,leav +| 3712: 65 73 5f 65 6e 64 5f 62 6c 6f 63 6b 20 49 4e 54 es_end_block INT +| 3728: 45 47 45 52 2c 65 6e 64 5f 62 6c 6f 63 6b 20 49 EGER,end_block I +| 3744: 4e 54 45 47 45 52 2c 72 6f 6f 74 20 42 4c 4f 42 NTEGER,root BLOB +| 3760: 2c 50 52 49 4d 41 52 59 20 4b 45 59 28 6c 65 76 ,PRIMARY KEY(lev +| 3776: 65 6c 2c 20 69 64 78 29 29 31 05 06 17 45 1f 01 el, idx))1...E.. +| 3792: 00 69 6e 64 65 78 73 71 6c 69 74 65 5f 61 75 74 .indexsqlite_aut +| 3808: 6f 69 6e 64 65 78 5f 78 31 5f 73 65 67 64 69 72 oindex_x1_segdir +| 3824: 5f 31 78 31 5f 73 65 67 64 69 72 05 00 00 00 08 _1x1_segdir..... +| 3840: 00 00 00 00 66 03 07 17 23 23 01 81 13 74 61 62 ....f...##...tab +| 3856: 6c 65 78 31 5f 73 65 67 6d 65 6e 74 73 78 31 5f lex1_segmentsx1_ +| 3872: 73 65 67 6d 65 6e 74 73 03 43 52 45 41 54 45 20 segments.CREATE +| 3888: 54 41 42 4c 45 20 27 78 31 5f 73 65 67 6d 65 6e TABLE 'x1_segmen +| 3904: 74 73 27 28 62 6c 6f 63 6b 69 64 20 49 4e 54 45 ts'(blockid INTE +| 3920: 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c GER PRIMARY KEY, +| 3936: 20 62 6c 6f 63 6b 20 42 4c 4f 42 29 5c 02 07 17 block BLOB).... +| 3952: 21 21 01 81 03 74 61 62 6c 65 78 31 5f 63 6f 6e !!...tablex1_con +| 3968: 74 65 6e 74 78 31 5f 63 6f 6e 74 65 6e 74 02 43 tentx1_content.C +| 3984: 52 45 41 54 45 20 54 41 42 4c 45 20 27 78 31 5f REATE TABLE 'x1_ +| 4000: 63 6f 6e 74 65 6e 74 27 28 64 6f 63 69 64 20 49 content'(docid I +| 4016: 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b NTEGER PRIMARY K +| 4032: 45 59 2c 20 27 63 30 78 27 29 34 01 06 17 11 11 EY, 'c0x')4..... +| 4048: 08 57 74 61 62 6c 65 78 31 78 31 43 52 45 41 54 .Wtablex1x1CREAT +| 4064: 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c 45 20 E VIRTUAL TABLE +| 4080: 78 31 20 55 53 49 4e 47 20 66 74 73 33 28 78 29 x1 USING fts3(x) +| page 2 offset 4096 +| 0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 3920: 00 00 00 2e 04 03 00 63 62 72 61 69 6e 73 74 65 .......cbrainste +| 3936: 6d 20 62 72 61 69 6e 73 74 65 6d 73 20 62 72 61 m brainstems bra +| 3952: 69 6e 73 74 6f 72 6d 20 62 72 61 69 6e 73 74 6f instorm brainsto +| 3968: 72 6d 73 2b 03 03 00 5d 62 72 61 69 6e 20 62 72 rms+...]brain br +| 3984: 61 69 6e 63 68 69 6c 64 20 62 72 61 69 6e 65 64 ainchild brained +| 4000: 20 62 72 61 69 6e 69 6e 67 20 62 72 61 69 6e 73 braining brains +| 4016: 26 02 03 00 53 62 72 61 67 73 20 62 72 61 69 64 &...Sbrags braid +| 4032: 20 62 72 61 69 64 65 64 20 62 72 61 69 64 69 6e braided braidin +| 4048: 67 20 62 72 61 69 64 73 26 01 03 00 53 62 72 61 g braids&...Sbra +| 4064: 65 73 20 62 72 61 67 20 62 72 61 67 67 65 64 20 es brag bragged +| 4080: 62 72 61 c3 67 65 72 20 62 72 61 67 67 69 6e 67 bra.ger bragging +| page 3 offset 8192 +| 0: 0d 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 ................ +| page 4 offset 12288 +| 0: 0d 00 00 00 04 0f 20 00 0f c8 0f 90 0f 54 0f 20 ...... ......T. +| 3872: 32 04 07 08 01 08 08 15 58 03 30 20 33 38 00 09 2.......X.0 38.. +| 3888: 62 72 61 69 6e 73 74 65 6d 03 04 02 00 09 01 73 brainstem......s +| 3904: 03 04 03 00 07 03 6f 72 6d 03 04 04 00 0a 01 73 ......orm......s +| 3920: 03 04 05 00 3a 03 07 08 01 08 08 15 68 02 30 20 ....:.......h.0 +| 3936: 34 36 00 05 62 72 61 69 6e 03 03 02 00 05 05 63 46..brain......c +| 3952: 68 69 6c 64 03 03 03 00 05 02 65 64 03 03 04 00 hild......ed.... +| 3968: 05 03 69 6e 67 03 03 05 00 05 01 73 03 03 06 00 ..ing......s.... +| 3984: 36 02 07 08 09 08 08 15 62 30 20 34 33 00 05 62 6.......b0 43..b +| 4000: 72 61 67 73 03 02 02 00 03 02 69 64 03 02 03 00 rags......id.... +| 4016: 05 02 65 64 03 02 04 00 05 03 69 6e 67 03 02 05 ..ed......ing... +| 4032: 00 05 01 73 03 02 06 00 36 01 07 08 08 08 08 15 ...s....6....... +| 4048: 62 30 20 34 33 00 05 62 72 61 65 73 03 01 02 00 b0 43..braes.... +| 4064: 03 01 68 03 01 03 00 04 03 67 65 74 03 01 04 00 ..h......get.... +| 4080: 06 01 72 03 01 05 00 05 03 69 6e 67 03 01 06 00 ..r......ing.... +| page 5 offset 16384 +| 0: 0a 00 00 00 04 0f e7 00 0f fb 0f f5 0f ee 0f e7 ................ +| 4064: 00 00 00 00 00 00 00 06 04 08 01 01 03 04 06 04 ................ +| 4080: 08 01 01 02 03 05 04 08 09 01 02 04 04 08 08 09 ................ +| end sql038051.txt.db +}]} {} + +do_catchsql_test 48.1 { + INSERT INTO x1(x1) VALUES('nodesize=24'),('merge=3,4'); + INSERT INTO x1(x1) VALUES( 'merge=3,4' ),('merge=3,4'); +} {1 {database disk image is malformed}} + + finish_test From 1862271f7cd2666596808e9d1ef7ba8472353ed7 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 20 Feb 2021 21:20:54 +0000 Subject: [PATCH 226/257] Performance improvement in resolving the INDEXED BY index name for the common case where there is no INDEXED BY clause. FossilOrigin-Name: 554b286ac208168bde91c6c6034cc7087410def76fce650b519661b2ee2c61b7 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/delete.c | 6 +++--- src/select.c | 32 +++++++++++++++++--------------- 4 files changed, 29 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index a8a07cff8b..cda9544d1a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scase\swhere\sFTS3/4\scould\spass\sa\sNULL\spointer\sto\smemcpy()\swhen\shandling\sa\scorrupt\sdb. -D 2021-02-20T19:22:32.180 +C Performance\simprovement\sin\sresolving\sthe\sINDEXED\sBY\sindex\sname\sfor\sthe\scommon\ncase\swhere\sthere\sis\sno\sINDEXED\sBY\sclause. +D 2021-02-20T21:20:54.553 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -493,7 +493,7 @@ F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 F src/date.c dace306a10d9b02ee553d454c8e1cf8d3c9b932e137738a6b15b90253a9bfc10 F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c -F src/delete.c 352ea931218c45a3daf17472d4141b9c7fc026d85da3f1ade404ea5bb6d67f77 +F src/delete.c 720c5d56c8b305db709296a1071db1159b2077b003df167435ad50816f56e12b F src/expr.c 47c85263e6d179424e6b09e2c79db5704ab5b8cbc2fae2ee3285faa2566f2e74 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 73adaca988d0dd517d373b432dc9dfa2cd7fa3108b114260132a80832de19037 @@ -542,7 +542,7 @@ F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 52f81603cc40f78449f5b6aed96dbea9484b194771ecb1937e8c0f6547c186a0 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 371a5c95d47d4e969337548ed9bd344788f15518a1c75921507355bd93815205 +F src/select.c fc2ed90b5e99399ad5cd040d1ccc969127c332275bbb82726b66e5eadf4cb4c0 F src/shell.c.in 844417f84df1f6c4fce1c815629a888cfdcf219e86513e9c332bbcc38832f477 F src/sqlite.h.in 8855a19f37ade8dad189a9e48233a2ebe1b46faf469c7eb0906a654e252dcc57 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1905,7 +1905,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 0288a8013e00594e716a5fb0d9f684dcfeb03e877650630e2736565fa6261290 -R d444093c909052ae4578b7954edb269e -U dan -Z 66cf8c59efba0e2d47b96d42e8888972 +P 68bb541a39833d7d4bf41aa91cb6cd9c98757d1fc8236299d09db7e9b14d8ec9 +R 5e60a181334dd40bb8d4205e0cb8c33a +U drh +Z 063342d2568b33a8aa12ee70783f45a5 diff --git a/manifest.uuid b/manifest.uuid index 05d7c7fd0c..7ef7ce891c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -68bb541a39833d7d4bf41aa91cb6cd9c98757d1fc8236299d09db7e9b14d8ec9 \ No newline at end of file +554b286ac208168bde91c6c6034cc7087410def76fce650b519661b2ee2c61b7 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index b2edaa9ab9..11db5372ea 100644 --- a/src/delete.c +++ b/src/delete.c @@ -37,9 +37,9 @@ Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ pItem->pTab = pTab; if( pTab ){ pTab->nTabRef++; - } - if( sqlite3IndexedByLookup(pParse, pItem) ){ - pTab = 0; + if( pItem->fg.isIndexedBy && sqlite3IndexedByLookup(pParse, pItem) ){ + pTab = 0; + } } return pTab; } diff --git a/src/select.c b/src/select.c index 6d5f049f33..4a37a1acb5 100644 --- a/src/select.c +++ b/src/select.c @@ -4711,23 +4711,25 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){ ** pFrom->pIndex and return SQLITE_OK. */ int sqlite3IndexedByLookup(Parse *pParse, struct SrcList_item *pFrom){ - if( pFrom->pTab && pFrom->fg.isIndexedBy ){ - Table *pTab = pFrom->pTab; - char *zIndexedBy = pFrom->u1.zIndexedBy; - Index *pIdx; - for(pIdx=pTab->pIndex; - pIdx && sqlite3StrICmp(pIdx->zName, zIndexedBy); - pIdx=pIdx->pNext - ); - if( !pIdx ){ - sqlite3ErrorMsg(pParse, "no such index: %s", zIndexedBy, 0); - pParse->checkSchema = 1; - return SQLITE_ERROR; - } - pFrom->pIBIndex = pIdx; + Table *pTab = pFrom->pTab; + char *zIndexedBy = pFrom->u1.zIndexedBy; + Index *pIdx; + assert( pTab!=0 ); + assert( pFrom->fg.isIndexedBy!=0 ); + + for(pIdx=pTab->pIndex; + pIdx && sqlite3StrICmp(pIdx->zName, zIndexedBy); + pIdx=pIdx->pNext + ); + if( !pIdx ){ + sqlite3ErrorMsg(pParse, "no such index: %s", zIndexedBy, 0); + pParse->checkSchema = 1; + return SQLITE_ERROR; } + pFrom->pIBIndex = pIdx; return SQLITE_OK; } + /* ** Detect compound SELECT statements that use an ORDER BY clause with ** an alternative collating sequence. @@ -5195,7 +5197,7 @@ static int selectExpander(Walker *pWalker, Select *p){ } /* Locate the index named by the INDEXED BY clause, if any. */ - if( sqlite3IndexedByLookup(pParse, pFrom) ){ + if( pFrom->fg.isIndexedBy && sqlite3IndexedByLookup(pParse, pFrom) ){ return WRC_Abort; } } From 5abe1d3d536f36dcb0964ff468a229382ce9858a Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 21 Feb 2021 01:19:42 +0000 Subject: [PATCH 227/257] Simplified resolution of CTE names. Slightly faster and about 100 bytes of code smaller. FossilOrigin-Name: 0d2c992f3622a6272ca4a3caff6b21f619fe976b8df8b34eff066086f8df2202 --- manifest | 12 +++---- manifest.uuid | 2 +- src/select.c | 92 +++++++++++++++++++++++++++------------------------ 3 files changed, 56 insertions(+), 50 deletions(-) diff --git a/manifest b/manifest index cda9544d1a..38048c8596 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\simprovement\sin\sresolving\sthe\sINDEXED\sBY\sindex\sname\sfor\sthe\scommon\ncase\swhere\sthere\sis\sno\sINDEXED\sBY\sclause. -D 2021-02-20T21:20:54.553 +C Simplified\sresolution\sof\sCTE\snames.\s\sSlightly\sfaster\sand\sabout\s100\sbytes\nof\scode\ssmaller. +D 2021-02-21T01:19:42.925 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -542,7 +542,7 @@ F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 52f81603cc40f78449f5b6aed96dbea9484b194771ecb1937e8c0f6547c186a0 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c fc2ed90b5e99399ad5cd040d1ccc969127c332275bbb82726b66e5eadf4cb4c0 +F src/select.c 94031cbbcae233326b90ce6a598494987ec4838a88c08ce57ffdcdab465dc3ca F src/shell.c.in 844417f84df1f6c4fce1c815629a888cfdcf219e86513e9c332bbcc38832f477 F src/sqlite.h.in 8855a19f37ade8dad189a9e48233a2ebe1b46faf469c7eb0906a654e252dcc57 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1905,7 +1905,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 68bb541a39833d7d4bf41aa91cb6cd9c98757d1fc8236299d09db7e9b14d8ec9 -R 5e60a181334dd40bb8d4205e0cb8c33a +P 554b286ac208168bde91c6c6034cc7087410def76fce650b519661b2ee2c61b7 +R e20e20e562861619a6969efc4756acf8 U drh -Z 063342d2568b33a8aa12ee70783f45a5 +Z 4bcb1bbda8b09f531893d946c969ef3a diff --git a/manifest.uuid b/manifest.uuid index 7ef7ce891c..6dc6e832cb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -554b286ac208168bde91c6c6034cc7087410def76fce650b519661b2ee2c61b7 \ No newline at end of file +0d2c992f3622a6272ca4a3caff6b21f619fe976b8df8b34eff066086f8df2202 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 4a37a1acb5..2176a6285d 100644 --- a/src/select.c +++ b/src/select.c @@ -4840,16 +4840,16 @@ static struct Cte *searchWith( struct SrcList_item *pItem, /* FROM clause element to resolve */ With **ppContext /* OUT: WITH clause return value belongs to */ ){ - const char *zName; - if( pItem->zDatabase==0 && (zName = pItem->zName)!=0 ){ - With *p; - for(p=pWith; p; p=p->pOuter){ - int i; - for(i=0; inCte; i++){ - if( sqlite3StrICmp(zName, p->a[i].zName)==0 ){ - *ppContext = p; - return &p->a[i]; - } + const char *zName = pItem->zName; + With *p; + assert( pItem->zDatabase==0 ); + assert( zName!=0 ); + for(p=pWith; p; p=p->pOuter){ + int i; + for(i=0; inCte; i++){ + if( sqlite3StrICmp(zName, p->a[i].zName)==0 ){ + *ppContext = p; + return &p->a[i]; } } } @@ -4882,35 +4882,39 @@ void sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){ /* ** This function checks if argument pFrom refers to a CTE declared by -** a WITH clause on the stack currently maintained by the parser. And, -** if currently processing a CTE expression, if it is a recursive -** reference to the current CTE. +** a WITH clause on the stack currently maintained by the parser (on the +** pParse->pWith linked list). And if currently processing a CTE +** CTE expression, through routine checks to see if the reference is +** a recursive reference to the CTE. ** -** If pFrom falls into either of the two categories above, pFrom->pTab -** and other fields are populated accordingly. The caller should check -** (pFrom->pTab!=0) to determine whether or not a successful match -** was found. +** If pFrom matches a CTE according to either of these two above, pFrom->pTab +** and other fields are populated accordingly. ** -** Whether or not a match is found, SQLITE_OK is returned if no error -** occurs. If an error does occur, an error message is stored in the -** parser and some error code other than SQLITE_OK returned. +** Return 0 if no match is found. +** Return 1 if a match is found. +** Return 2 if an error condition is detected. */ -static int withExpand( - Walker *pWalker, - struct SrcList_item *pFrom +static int resolveFromTermToCte( + Parse *pParse, /* The parsing context */ + Walker *pWalker, /* Current tree walker */ + struct SrcList_item *pFrom /* The FROM clause term to check */ ){ - Parse *pParse = pWalker->pParse; - sqlite3 *db = pParse->db; - struct Cte *pCte; /* Matched CTE (or NULL if no match) */ - With *pWith; /* WITH clause that pCte belongs to */ + Cte *pCte; /* Matched CTE (or NULL if no match) */ + With *pWith; /* The matching WITH */ assert( pFrom->pTab==0 ); - if( pParse->nErr ){ - return SQLITE_ERROR; + if( pParse->pWith==0 ){ + /* There are no WITH clauses in the stack. No match is possible */ + return 0; + } + if( pFrom->zDatabase!=0 ){ + /* The FROM term contains a schema qualifier (ex: main.t1) and so + ** it cannot possibly be a CTE reference. */ + return 0; } - pCte = searchWith(pParse->pWith, pFrom, &pWith); if( pCte ){ + sqlite3 *db = pParse->db; Table *pTab; ExprList *pEList; Select *pSel; @@ -4926,20 +4930,20 @@ static int withExpand( ** In this case, proceed. */ if( pCte->zCteErr ){ sqlite3ErrorMsg(pParse, pCte->zCteErr, pCte->zName); - return SQLITE_ERROR; + return 2; } - if( cannotBeFunction(pParse, pFrom) ) return SQLITE_ERROR; + if( cannotBeFunction(pParse, pFrom) ) return 2; assert( pFrom->pTab==0 ); pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); - if( pTab==0 ) return WRC_Abort; + if( pTab==0 ) return 2; pTab->nTabRef = 1; pTab->zName = sqlite3DbStrDup(db, pCte->zName); pTab->iPKey = -1; pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid; pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0); - if( db->mallocFailed ) return SQLITE_NOMEM_BKPT; + if( db->mallocFailed ) return 2; assert( pFrom->pSelect ); /* Check if this is a recursive CTE. */ @@ -4962,7 +4966,7 @@ static int withExpand( sqlite3ErrorMsg(pParse, "multiple references to recursive table: %s", pCte->zName ); - return SQLITE_ERROR; + return 2; } pRecTerm->selFlags |= SF_Recursive; if( iRecTab<0 ) iRecTab = pParse->nTab++; @@ -4998,7 +5002,7 @@ static int withExpand( pCte->zName, pEList->nExpr, pCte->pCols->nExpr ); pParse->pWith = pSavedWith; - return SQLITE_ERROR; + return 2; } pEList = pCte->pCols; } @@ -5014,9 +5018,9 @@ static int withExpand( } pCte->zCteErr = 0; pParse->pWith = pSavedWith; + return 1; /* Success */ } - - return SQLITE_OK; + return 0; /* No match */ } #endif @@ -5098,7 +5102,7 @@ int sqlite3ExpandSubquery(Parse *pParse, struct SrcList_item *pFrom){ */ static int selectExpander(Walker *pWalker, Select *p){ Parse *pParse = pWalker->pParse; - int i, j, k; + int i, j, k, rc; SrcList *pTabList; ExprList *pEList; struct SrcList_item *pFrom; @@ -5137,10 +5141,6 @@ static int selectExpander(Walker *pWalker, Select *p){ assert( pFrom->fg.isRecursive==0 || pFrom->pTab!=0 ); if( pFrom->pTab ) continue; assert( pFrom->fg.isRecursive==0 ); -#ifndef SQLITE_OMIT_CTE - if( withExpand(pWalker, pFrom) ) return WRC_Abort; - if( pFrom->pTab ) {} else -#endif if( pFrom->zName==0 ){ #ifndef SQLITE_OMIT_SUBQUERY Select *pSel = pFrom->pSelect; @@ -5149,6 +5149,12 @@ static int selectExpander(Walker *pWalker, Select *p){ assert( pFrom->pTab==0 ); if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort; if( sqlite3ExpandSubquery(pParse, pFrom) ) return WRC_Abort; +#endif +#ifndef SQLITE_OMIT_CTE + }else if( (rc = resolveFromTermToCte(pParse, pWalker, pFrom))!=0 ){ + if( rc>1 ) return WRC_Abort; + pTab = pFrom->pTab; + assert( pTab!=0 ); #endif }else{ /* An ordinary table or view name in the FROM clause */ From 7601294ad3fe9f7e0db8eb2478dec0de293b8bb6 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 21 Feb 2021 21:04:54 +0000 Subject: [PATCH 228/257] Rename the "struct SrcList_item" object to the more succinct "SrcItem". This is a symbolic change only. The logic is unmodified. FossilOrigin-Name: bfd5bf2c73110fcb36db9ba2a949ff516131fbd3e89325f88fe9f5c2b4ed87b2 --- manifest | 46 +++++++++++++++--------------- manifest.uuid | 2 +- src/alter.c | 4 +-- src/attach.c | 2 +- src/build.c | 16 +++++------ src/delete.c | 2 +- src/expr.c | 6 ++-- src/fkey.c | 2 +- src/insert.c | 2 +- src/parse.y | 4 +-- src/printf.c | 2 +- src/resolve.c | 12 ++++---- src/select.c | 46 +++++++++++++++--------------- src/sqliteInt.h | 75 +++++++++++++++++++++++++++---------------------- src/treeview.c | 2 +- src/walker.c | 2 +- src/where.c | 34 +++++++++++----------- src/whereInt.h | 2 +- src/wherecode.c | 8 +++--- src/whereexpr.c | 2 +- 20 files changed, 139 insertions(+), 132 deletions(-) diff --git a/manifest b/manifest index 38048c8596..59fa169b0a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplified\sresolution\sof\sCTE\snames.\s\sSlightly\sfaster\sand\sabout\s100\sbytes\nof\scode\ssmaller. -D 2021-02-21T01:19:42.925 +C Rename\sthe\s"struct\sSrcList_item"\sobject\sto\sthe\smore\ssuccinct\s"SrcItem".\nThis\sis\sa\ssymbolic\schange\sonly.\s\sThe\slogic\sis\sunmodified. +D 2021-02-21T21:04:54.414 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -476,9 +476,9 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 19b49c98a094f9dfc72998dc48f8e720e5ae98576f2316fc0f496aa5d3db9fb1 +F src/alter.c d5fd529509880eade9ea59ddb24a56e9fe0579ee7f2e9e18bac62b7bd05b3a10 F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c -F src/attach.c e80162a47411f296bea550ed8fafd730481f4aa71e89ece23ba9c957eed15d4a +F src/attach.c 9cbe761e464025694df8e6f6ee4d9f41432c3a255ca9443ccbb4130eeb87cf72 F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 @@ -486,24 +486,24 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 694020ad8a3af3d79b09f74c8f1421272a419cdea42a13401e3b0f7dea6e9c3e F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 -F src/build.c 2cf3d07bcf26884f7ab090041960c3daa7436f9afe3f6a29c3d60fb046b3cdcf +F src/build.c 072e3e22d1431262ac7e49d833dd778416f640407daa6115092aa5ec834a2106 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 F src/date.c dace306a10d9b02ee553d454c8e1cf8d3c9b932e137738a6b15b90253a9bfc10 F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c -F src/delete.c 720c5d56c8b305db709296a1071db1159b2077b003df167435ad50816f56e12b -F src/expr.c 47c85263e6d179424e6b09e2c79db5704ab5b8cbc2fae2ee3285faa2566f2e74 +F src/delete.c 8097c2c8feade9c46a1828dbdc98e1f52f4934fbff38233a2e7b98729528d244 +F src/expr.c 3a756aae0435178ddaed3b4e99ed7c6006f94d380881a249b7cf9d3fca8a405e F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 -F src/fkey.c 73adaca988d0dd517d373b432dc9dfa2cd7fa3108b114260132a80832de19037 +F src/fkey.c e9063648396c58778f77583a678342fe4a9bc82436bf23c5f9f444f2df0fdaa4 F src/func.c 479f6929be027eb0210cbdde9d3529c012facf082d64a6b854a9415940761e5e F src/global.c ed55af196a9b66e198aaeda3f5454c3aa7d7d050c6c938181fd044b70d180a81 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 3959a2e8a6c1e688e7390ef242472817653f4ae9a42bb78b293eaa98645f1a07 +F src/insert.c 8942baede303a54ba3b6d06200d5b74c9bc25ababec8a55823e06309748cd4a3 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 F src/main.c 1c5de7b3fabcdf05f4fe563aab5d81d175b89c67a8678a12ba86629356afa356 @@ -531,23 +531,23 @@ F src/os_win.c 77d39873836f1831a9b0b91894fec45ab0e9ca8e067dc8c549e1d1eca1566fe9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c c49952ac5e9cc536778eff528091d79d38b3e45cbeeed4695dc05e207dc6547d F src/pager.h 4bf9b3213a4b2bebbced5eaa8b219cf25d4a82f385d093cd64b7e93e5285f66f -F src/parse.y 81e6d07be0420419964c5e71c4445278776c6789b2606aad7b535986f68fe2b4 +F src/parse.y e6019e934cbbb4108ed3b9a6a225ee388d9a93fd12877ed5ba72c1dd16ebdd3c F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a F src/pragma.c 6daaaecc26a4b09481d21722525b079ce756751a43a79cc1d8f122d686806193 F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf F src/prepare.c 7a534d100c556f45f10aee131f2e4244cb52547b7cf17e1c393f55d8abb62e97 -F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed +F src/printf.c 10e61ec79dd9d41fdc77afee4e0df04fbb427f309c043118fe0b26a7d7db488a F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c 52f81603cc40f78449f5b6aed96dbea9484b194771ecb1937e8c0f6547c186a0 +F src/resolve.c c263fa5b255a03314c2418f936386e903d01c3e7cbec25a363a586ef3f10b249 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 94031cbbcae233326b90ce6a598494987ec4838a88c08ce57ffdcdab465dc3ca +F src/select.c b3277dc42ab20367b023c78d998119915403aa98c4e7230567dd9884ca38d7fd F src/shell.c.in 844417f84df1f6c4fce1c815629a888cfdcf219e86513e9c332bbcc38832f477 F src/sqlite.h.in 8855a19f37ade8dad189a9e48233a2ebe1b46faf469c7eb0906a654e252dcc57 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h 180c58de36f96959aebdbd4f4aa373b1805c3815659aa1e1a5255739a21929fe +F src/sqliteInt.h dbe0a5541c6eaabd3535ca6fd9838452bef7d25430267ac6701ef4d0c2cce46a F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -607,7 +607,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 -F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda +F src/treeview.c 04bf47d19b9f6f0b636cf42fec6e676b140d781bae792f52a8a014867e838e3e F src/trigger.c 861c3ec2c5b0fc830bdf82470454a9324fad70cbaa96d2e208fb54577c9e8d28 F src/update.c 0f5a61f0787199983530a33f6fffe4f52742f35fcdf6ccfad1078b1a8bc17723 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 @@ -628,11 +628,11 @@ F src/vtab.c 032a0165c147fda16927e6a3230e90c068d4af93f887ce94e26f678fe48e5e4c F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 69e770e96fd56cc21608992bf2c6f1f3dc5cf2572d0495c6a643b06c3a679f14 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a -F src/walker.c d9c4e454ebb9499e908aa62d55b8994c375cf5355ac78f60d45af17f7890701c -F src/where.c 5737a9bd24115e7b3a9e6f637eba462d98e61272170618dd1cd9ac3baa854ed7 -F src/whereInt.h ae03b5e3a4cca9bd9cb1b7d3c63faf8f1f177200fc8cecc87d3d0cab6ca338e6 -F src/wherecode.c 43a63441f8662ddf86b15975683a502ec33f08167e9636f4d19e38e265e95fd9 -F src/whereexpr.c f7b5469e83db3c3b9eb14e4ba44559a2e125523761d12e5ac8d8fb88301af393 +F src/walker.c d42d6c80ea363ef689a462e65eefcfe87deab924c50de5baa37ecb6af7d7ddaa +F src/where.c 40735d2b96b9b071a510fd3f090a195f48a09beb0c97ae0a11fd49e7c9396af9 +F src/whereInt.h 446e5e8018f83358ef917cf32d8e6a86dc8430113d0b17e720f1839d3faa44c4 +F src/wherecode.c e57a8690311a75d06e723e8d379f9831de04aba300e07174d236e32a7f9c7a13 +F src/whereexpr.c 2dc51263e1fb8d8723e97a077a9a137ab0534e59e4cb88b3195f65edbe43cc32 F src/window.c edd6f5e25a1e8f2b6f5305b7f5f7da7bb35f07f0d432b255b1d4c2fcab4205aa F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -1905,7 +1905,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 554b286ac208168bde91c6c6034cc7087410def76fce650b519661b2ee2c61b7 -R e20e20e562861619a6969efc4756acf8 +P 0d2c992f3622a6272ca4a3caff6b21f619fe976b8df8b34eff066086f8df2202 +R 3144ef024c1b147facc59f065688290b U drh -Z 4bcb1bbda8b09f531893d946c969ef3a +Z 9a2772a6abeb20b71009a7863f85f821 diff --git a/manifest.uuid b/manifest.uuid index 6dc6e832cb..08a79a0dbf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0d2c992f3622a6272ca4a3caff6b21f619fe976b8df8b34eff066086f8df2202 \ No newline at end of file +bfd5bf2c73110fcb36db9ba2a949ff516131fbd3e89325f88fe9f5c2b4ed87b2 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index de710cda88..5409de594f 100644 --- a/src/alter.c +++ b/src/alter.c @@ -1215,7 +1215,7 @@ static int renameResolveTrigger(Parse *pParse){ if( pSrc ){ int i; for(i=0; inSrc && rc==SQLITE_OK; i++){ - struct SrcList_item *p = &pSrc->a[i]; + SrcItem *p = &pSrc->a[i]; p->iCursor = pParse->nTab++; if( p->pSelect ){ sqlite3SelectPrep(pParse, p->pSelect, 0); @@ -1527,7 +1527,7 @@ static int renameTableSelectCb(Walker *pWalker, Select *pSelect){ return WRC_Abort; } for(i=0; inSrc; i++){ - struct SrcList_item *pItem = &pSrc->a[i]; + SrcItem *pItem = &pSrc->a[i]; if( pItem->pTab==p->pTab ){ renameTokenFind(pWalker->pParse, p, pItem->zName); } diff --git a/src/attach.c b/src/attach.c index 638929b26e..8eb4486e58 100644 --- a/src/attach.c +++ b/src/attach.c @@ -456,7 +456,7 @@ static int fixExprCb(Walker *p, Expr *pExpr){ static int fixSelectCb(Walker *p, Select *pSelect){ DbFixer *pFix = p->u.pFix; int i; - struct SrcList_item *pItem; + SrcItem *pItem; sqlite3 *db = pFix->pParse->db; int iDb = sqlite3FindDbName(db, pFix->zDb); SrcList *pList = pSelect->pSrc; diff --git a/src/build.c b/src/build.c index 37ea46708b..fad9a8bb8a 100644 --- a/src/build.c +++ b/src/build.c @@ -478,7 +478,7 @@ Table *sqlite3LocateTable( Table *sqlite3LocateTableItem( Parse *pParse, u32 flags, - struct SrcList_item *p + SrcItem *p ){ const char *zDb; assert( p->pSchema==0 || p->zDatabase==0 ); @@ -4519,7 +4519,7 @@ SrcList *sqlite3SrcListAppend( Token *pTable, /* Table to append */ Token *pDatabase /* Database of the table */ ){ - struct SrcList_item *pItem; + SrcItem *pItem; sqlite3 *db; assert( pDatabase==0 || pTable!=0 ); /* Cannot have C without B */ assert( pParse!=0 ); @@ -4560,7 +4560,7 @@ SrcList *sqlite3SrcListAppend( */ void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ int i; - struct SrcList_item *pItem; + SrcItem *pItem; assert(pList || pParse->db->mallocFailed ); if( pList ){ for(i=0, pItem=pList->a; inSrc; i++, pItem++){ @@ -4578,7 +4578,7 @@ void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ */ void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ int i; - struct SrcList_item *pItem; + SrcItem *pItem; if( pList==0 ) return; for(pItem=pList->a, i=0; inSrc; i++, pItem++){ if( pItem->zDatabase ) sqlite3DbFreeNN(db, pItem->zDatabase); @@ -4620,7 +4620,7 @@ SrcList *sqlite3SrcListAppendFromTerm( Expr *pOn, /* The ON clause of a join */ IdList *pUsing /* The USING clause of a join */ ){ - struct SrcList_item *pItem; + SrcItem *pItem; sqlite3 *db = pParse->db; if( !p && (pOn || pUsing) ){ sqlite3ErrorMsg(pParse, "a JOIN clause is required before %s", @@ -4664,7 +4664,7 @@ SrcList *sqlite3SrcListAppendFromTerm( void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){ assert( pIndexedBy!=0 ); if( p && pIndexedBy->n>0 ){ - struct SrcList_item *pItem; + SrcItem *pItem; assert( p->nSrc>0 ); pItem = &p->a[p->nSrc-1]; assert( pItem->fg.notIndexed==0 ); @@ -4694,7 +4694,7 @@ SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2){ sqlite3SrcListDelete(pParse->db, p2); }else{ p1 = pNew; - memcpy(&p1->a[1], p2->a, p2->nSrc*sizeof(struct SrcList_item)); + memcpy(&p1->a[1], p2->a, p2->nSrc*sizeof(SrcItem)); sqlite3DbFree(pParse->db, p2); } } @@ -4707,7 +4707,7 @@ SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2){ */ void sqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList *pList){ if( p ){ - struct SrcList_item *pItem = &p->a[p->nSrc-1]; + SrcItem *pItem = &p->a[p->nSrc-1]; assert( pItem->fg.notIndexed==0 ); assert( pItem->fg.isIndexedBy==0 ); assert( pItem->fg.isTabFunc==0 ); diff --git a/src/delete.c b/src/delete.c index 11db5372ea..860a2739ad 100644 --- a/src/delete.c +++ b/src/delete.c @@ -29,7 +29,7 @@ ** */ Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ - struct SrcList_item *pItem = pSrc->a; + SrcItem *pItem = pSrc->a; Table *pTab; assert( pItem && pSrc->nSrc>=1 ); pTab = sqlite3LocateTableItem(pParse, 0, pItem); diff --git a/src/expr.c b/src/expr.c index f225b59bce..cf9a213f4e 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1530,8 +1530,8 @@ SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){ if( pNew==0 ) return 0; pNew->nSrc = pNew->nAlloc = p->nSrc; for(i=0; inSrc; i++){ - struct SrcList_item *pNewItem = &pNew->a[i]; - struct SrcList_item *pOldItem = &p->a[i]; + SrcItem *pNewItem = &pNew->a[i]; + SrcItem *pOldItem = &p->a[i]; Table *pTab; pNewItem->pSchema = pOldItem->pSchema; pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase); @@ -5861,7 +5861,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ /* Check to see if the column is in one of the tables in the FROM ** clause of the aggregate query */ if( ALWAYS(pSrcList!=0) ){ - struct SrcList_item *pItem = pSrcList->a; + SrcItem *pItem = pSrcList->a; for(i=0; inSrc; i++, pItem++){ struct AggInfo_col *pCol; assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); diff --git a/src/fkey.c b/src/fkey.c index abfc7d9a43..9f622f40c6 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -1024,7 +1024,7 @@ void sqlite3FkCheck( ** child table as a SrcList for sqlite3WhereBegin() */ pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); if( pSrc ){ - struct SrcList_item *pItem = pSrc->a; + SrcItem *pItem = pSrc->a; pItem->pTab = pFKey->pFrom; pItem->zName = pFKey->pFrom->zName; pItem->pTab->nTabRef++; diff --git a/src/insert.c b/src/insert.c index 646864ee60..f0b93ae376 100644 --- a/src/insert.c +++ b/src/insert.c @@ -2684,7 +2684,7 @@ static int xferOptimization( ExprList *pEList; /* The result set of the SELECT */ Table *pSrc; /* The table in the FROM clause of SELECT */ Index *pSrcIdx, *pDestIdx; /* Source and destination indices */ - struct SrcList_item *pItem; /* An element of pSelect->pSrc */ + SrcItem *pItem; /* An element of pSelect->pSrc */ int i; /* Loop counter */ int iDbSrc; /* The database of pSrc */ int iSrc, iDest; /* Cursors from source and destination */ diff --git a/src/parse.y b/src/parse.y index 97a0ffd934..c84631846d 100644 --- a/src/parse.y +++ b/src/parse.y @@ -695,8 +695,8 @@ seltablist(A) ::= stl_prefix(A) nm(Y) dbnm(D) LP exprlist(E) RP as(Z) }else if( F->nSrc==1 ){ A = sqlite3SrcListAppendFromTerm(pParse,A,0,0,&Z,0,N,U); if( A ){ - struct SrcList_item *pNew = &A->a[A->nSrc-1]; - struct SrcList_item *pOld = F->a; + SrcItem *pNew = &A->a[A->nSrc-1]; + SrcItem *pOld = F->a; pNew->zName = pOld->zName; pNew->zDatabase = pOld->zDatabase; pNew->pSelect = pOld->pSelect; diff --git a/src/printf.c b/src/printf.c index f78d3bbb17..476d13e789 100644 --- a/src/printf.c +++ b/src/printf.c @@ -856,7 +856,7 @@ void sqlite3_str_vappendf( case etSRCLIST: { SrcList *pSrc; int k; - struct SrcList_item *pItem; + SrcItem *pItem; if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return; pSrc = va_arg(ap, SrcList*); k = va_arg(ap, int); diff --git a/src/resolve.c b/src/resolve.c index c1cabab75d..a478c7d10e 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -245,8 +245,8 @@ static int lookupName( int cntTab = 0; /* Number of matching table names */ int nSubquery = 0; /* How many levels of subquery */ sqlite3 *db = pParse->db; /* The database connection */ - struct SrcList_item *pItem; /* Use for looping over pSrcList items */ - struct SrcList_item *pMatch = 0; /* The matching pSrcList item */ + SrcItem *pItem; /* Use for looping over pSrcList items */ + SrcItem *pMatch = 0; /* The matching pSrcList item */ NameContext *pTopNC = pNC; /* First namecontext in the list */ Schema *pSchema = 0; /* Schema of the expression */ int eNewExprOp = TK_COLUMN; /* New value for pExpr->op on success */ @@ -662,7 +662,7 @@ lookupname_end: Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){ Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0); if( p ){ - struct SrcList_item *pItem = &pSrc->a[iSrc]; + SrcItem *pItem = &pSrc->a[iSrc]; Table *pTab = p->y.pTab = pItem->pTab; p->iTable = pItem->iCursor; if( p->y.pTab->iPKey==iCol ){ @@ -774,7 +774,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ */ case TK_ROW: { SrcList *pSrcList = pNC->pSrcList; - struct SrcList_item *pItem; + SrcItem *pItem; assert( pSrcList && pSrcList->nSrc>=1 ); pItem = pSrcList->a; pExpr->op = TK_COLUMN; @@ -1587,7 +1587,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ /* Recursively resolve names in all subqueries */ for(i=0; ipSrc->nSrc; i++){ - struct SrcList_item *pItem = &p->pSrc->a[i]; + SrcItem *pItem = &p->pSrc->a[i]; if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){ NameContext *pNC; /* Used to iterate name contexts */ int nRef = 0; /* Refcount for pOuterNC and outer contexts */ @@ -1657,7 +1657,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ /* Resolve names in table-valued-function arguments */ for(i=0; ipSrc->nSrc; i++){ - struct SrcList_item *pItem = &p->pSrc->a[i]; + SrcItem *pItem = &p->pSrc->a[i]; if( pItem->fg.isTabFunc && sqlite3ResolveExprListNames(&sNC, pItem->u1.pFuncArg) ){ diff --git a/src/select.c b/src/select.c index 2176a6285d..a9d0eb1530 100644 --- a/src/select.c +++ b/src/select.c @@ -435,8 +435,8 @@ static void unsetJoinExpr(Expr *p, int iTable){ static int sqliteProcessJoin(Parse *pParse, Select *p){ SrcList *pSrc; /* All tables in the FROM clause */ int i, j; /* Loop counters */ - struct SrcList_item *pLeft; /* Left table being joined */ - struct SrcList_item *pRight; /* Right table being joined */ + SrcItem *pLeft; /* Left table being joined */ + SrcItem *pRight; /* Right table being joined */ pSrc = p->pSrc; pLeft = &pSrc->a[0]; @@ -3597,7 +3597,7 @@ static void substSelect( int doPrior /* Do substitutes on p->pPrior too */ ){ SrcList *pSrc; - struct SrcList_item *pItem; + SrcItem *pItem; int i; if( !p ) return; do{ @@ -3627,7 +3627,7 @@ static void substSelect( ** pSrcItem->colUsed mask. */ static int recomputeColumnsUsedExpr(Walker *pWalker, Expr *pExpr){ - struct SrcList_item *pItem; + SrcItem *pItem; if( pExpr->op!=TK_COLUMN ) return WRC_Continue; pItem = pWalker->u.pSrcItem; if( pItem->iCursor!=pExpr->iTable ) return WRC_Continue; @@ -3637,7 +3637,7 @@ static int recomputeColumnsUsedExpr(Walker *pWalker, Expr *pExpr){ } static void recomputeColumnsUsed( Select *pSelect, /* The complete SELECT statement */ - struct SrcList_item *pSrcItem /* Which FROM clause item to recompute */ + SrcItem *pSrcItem /* Which FROM clause item to recompute */ ){ Walker w; if( NEVER(pSrcItem->pTab==0) ) return; @@ -3671,7 +3671,7 @@ static void srclistRenumberCursors( int iExcept /* FROM clause item to skip */ ){ int i; - struct SrcList_item *pItem; + SrcItem *pItem; for(i=0, pItem=pSrc->a; inSrc; i++, pItem++){ if( i!=iExcept ){ Select *p; @@ -3905,7 +3905,7 @@ static int flattenSubquery( int isLeftJoin = 0; /* True if pSub is the right side of a LEFT JOIN */ int i; /* Loop counter */ Expr *pWhere; /* The WHERE clause */ - struct SrcList_item *pSubitem; /* The subquery */ + SrcItem *pSubitem; /* The subquery */ sqlite3 *db = pParse->db; Walker w; /* Walker to persist agginfo data */ int *aCsrMap = 0; @@ -4710,7 +4710,7 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){ ** SQLITE_ERROR and leave an error in pParse. Otherwise, populate ** pFrom->pIndex and return SQLITE_OK. */ -int sqlite3IndexedByLookup(Parse *pParse, struct SrcList_item *pFrom){ +int sqlite3IndexedByLookup(Parse *pParse, SrcItem *pFrom){ Table *pTab = pFrom->pTab; char *zIndexedBy = pFrom->u1.zIndexedBy; Index *pIdx; @@ -4816,7 +4816,7 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ ** arguments. If it does, leave an error message in pParse and return ** non-zero, since pFrom is not allowed to be a table-valued function. */ -static int cannotBeFunction(Parse *pParse, struct SrcList_item *pFrom){ +static int cannotBeFunction(Parse *pParse, SrcItem *pFrom){ if( pFrom->fg.isTabFunc ){ sqlite3ErrorMsg(pParse, "'%s' is not a function", pFrom->zName); return 1; @@ -4837,7 +4837,7 @@ static int cannotBeFunction(Parse *pParse, struct SrcList_item *pFrom){ */ static struct Cte *searchWith( With *pWith, /* Current innermost WITH clause */ - struct SrcList_item *pItem, /* FROM clause element to resolve */ + SrcItem *pItem, /* FROM clause element to resolve */ With **ppContext /* OUT: WITH clause return value belongs to */ ){ const char *zName = pItem->zName; @@ -4897,7 +4897,7 @@ void sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){ static int resolveFromTermToCte( Parse *pParse, /* The parsing context */ Walker *pWalker, /* Current tree walker */ - struct SrcList_item *pFrom /* The FROM clause term to check */ + SrcItem *pFrom /* The FROM clause term to check */ ){ Cte *pCte; /* Matched CTE (or NULL if no match) */ With *pWith; /* The matching WITH */ @@ -4954,7 +4954,7 @@ static int resolveFromTermToCte( SrcList *pSrc = pRecTerm->pSrc; assert( pRecTerm->pPrior!=0 ); for(i=0; inSrc; i++){ - struct SrcList_item *pItem = &pSrc->a[i]; + SrcItem *pItem = &pSrc->a[i]; if( pItem->zDatabase==0 && pItem->zName!=0 && 0==sqlite3StrICmp(pItem->zName, pCte->zName) @@ -5054,7 +5054,7 @@ static void selectPopWith(Walker *pWalker, Select *p){ ** SQLITE_OK is returned. Otherwise, if an OOM error is encountered, ** SQLITE_NOMEM. */ -int sqlite3ExpandSubquery(Parse *pParse, struct SrcList_item *pFrom){ +int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){ Select *pSel = pFrom->pSelect; Table *pTab; @@ -5105,7 +5105,7 @@ static int selectExpander(Walker *pWalker, Select *p){ int i, j, k, rc; SrcList *pTabList; ExprList *pEList; - struct SrcList_item *pFrom; + SrcItem *pFrom; sqlite3 *db = pParse->db; Expr *pE, *pRight, *pExpr; u16 selFlags = p->selFlags; @@ -5446,7 +5446,7 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ Parse *pParse; int i; SrcList *pTabList; - struct SrcList_item *pFrom; + SrcItem *pFrom; assert( p->selFlags & SF_Resolved ); if( p->selFlags & SF_HasTypeInfo ) return; @@ -5770,11 +5770,11 @@ static void havingToWhere(Parse *pParse, Select *p){ ** If it is, then return the SrcList_item for the prior view. If it is not, ** then return 0. */ -static struct SrcList_item *isSelfJoinView( +static SrcItem *isSelfJoinView( SrcList *pTabList, /* Search for self-joins in this FROM clause */ - struct SrcList_item *pThis /* Search for prior reference to this subquery */ + SrcItem *pThis /* Search for prior reference to this subquery */ ){ - struct SrcList_item *pItem; + SrcItem *pItem; assert( pThis->pSelect!=0 ); if( pThis->pSelect->selFlags & SF_PushDown ) return 0; for(pItem = pTabList->a; pItema[0]) name ** or alias is duplicated within FROM clause (pSrc->a[1..n]). */ if( p->selFlags & SF_UpdateFrom ){ - struct SrcList_item *p0 = &p->pSrc->a[0]; + SrcItem *p0 = &p->pSrc->a[0]; for(i=1; ipSrc->nSrc; i++){ - struct SrcList_item *p1 = &p->pSrc->a[i]; + SrcItem *p1 = &p->pSrc->a[i]; if( p0->pTab==p1->pTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){ sqlite3ErrorMsg(pParse, "target object/alias may not appear in FROM clause: %s", @@ -6018,7 +6018,7 @@ int sqlite3Select( */ #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) for(i=0; !p->pPrior && inSrc; i++){ - struct SrcList_item *pItem = &pTabList->a[i]; + SrcItem *pItem = &pTabList->a[i]; Select *pSub = pItem->pSelect; Table *pTab = pItem->pTab; @@ -6152,7 +6152,7 @@ int sqlite3Select( ** (2) Generate code for all sub-queries */ for(i=0; inSrc; i++){ - struct SrcList_item *pItem = &pTabList->a[i]; + SrcItem *pItem = &pTabList->a[i]; SelectDest dest; Select *pSub; #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) @@ -6270,7 +6270,7 @@ int sqlite3Select( int topAddr; int onceAddr = 0; int retAddr; - struct SrcList_item *pPrior; + SrcItem *pPrior; testcase( pItem->addrFillSub==0 ); /* Ticket c52b09c7f38903b1311 */ pItem->regReturn = ++pParse->nMem; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 78bb048fab..7fd71a86bf 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1166,6 +1166,7 @@ typedef struct Savepoint Savepoint; typedef struct Select Select; typedef struct SQLiteThread SQLiteThread; typedef struct SelectDest SelectDest; +typedef struct SrcItem SrcItem; typedef struct SrcList SrcList; typedef struct sqlite3_str StrAccum; /* Internal alias for sqlite3_str */ typedef struct Table Table; @@ -2917,6 +2918,41 @@ struct IdList { int nId; /* Number of identifiers on the list */ }; +/* +** The SrcItem object represents a single term in the FROM clause of a query. +** The SrcList object is mostly an array of SrcItems. +*/ +struct SrcItem { + Schema *pSchema; /* Schema to which this item is fixed */ + char *zDatabase; /* Name of database holding this table */ + char *zName; /* Name of the table */ + char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */ + Table *pTab; /* An SQL table corresponding to zName */ + Select *pSelect; /* A SELECT statement used in place of a table name */ + int addrFillSub; /* Address of subroutine to manifest a subquery */ + int regReturn; /* Register holding return address of addrFillSub */ + int regResult; /* Registers holding results of a co-routine */ + struct { + u8 jointype; /* Type of join between this table and the previous */ + unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */ + unsigned isIndexedBy :1; /* True if there is an INDEXED BY clause */ + unsigned isTabFunc :1; /* True if table-valued-function syntax */ + unsigned isCorrelated :1; /* True if sub-query is correlated */ + unsigned viaCoroutine :1; /* Implemented as a co-routine */ + unsigned isRecursive :1; /* True for recursive reference in WITH */ + unsigned fromDDL :1; /* Comes from sqlite_schema */ + } fg; + int iCursor; /* The VDBE cursor number used to access this table */ + Expr *pOn; /* The ON clause of a join */ + IdList *pUsing; /* The USING clause of a join */ + Bitmask colUsed; /* Bit N (1<" clause */ + ExprList *pFuncArg; /* Arguments to table-valued-function */ + } u1; + Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */ +}; + /* ** The following structure describes the FROM clause of a SELECT statement. ** Each table or subquery in the FROM clause is a separate element of @@ -2939,36 +2975,7 @@ struct IdList { struct SrcList { int nSrc; /* Number of tables or subqueries in the FROM clause */ u32 nAlloc; /* Number of entries allocated in a[] below */ - struct SrcList_item { - Schema *pSchema; /* Schema to which this item is fixed */ - char *zDatabase; /* Name of database holding this table */ - char *zName; /* Name of the table */ - char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */ - Table *pTab; /* An SQL table corresponding to zName */ - Select *pSelect; /* A SELECT statement used in place of a table name */ - int addrFillSub; /* Address of subroutine to manifest a subquery */ - int regReturn; /* Register holding return address of addrFillSub */ - int regResult; /* Registers holding results of a co-routine */ - struct { - u8 jointype; /* Type of join between this table and the previous */ - unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */ - unsigned isIndexedBy :1; /* True if there is an INDEXED BY clause */ - unsigned isTabFunc :1; /* True if table-valued-function syntax */ - unsigned isCorrelated :1; /* True if sub-query is correlated */ - unsigned viaCoroutine :1; /* Implemented as a co-routine */ - unsigned isRecursive :1; /* True for recursive reference in WITH */ - unsigned fromDDL :1; /* Comes from sqlite_schema */ - } fg; - int iCursor; /* The VDBE cursor number used to access this table */ - Expr *pOn; /* The ON clause of a join */ - IdList *pUsing; /* The USING clause of a join */ - Bitmask colUsed; /* Bit N (1<" clause */ - ExprList *pFuncArg; /* Arguments to table-valued-function */ - } u1; - Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */ - } a[1]; /* One entry for each identifier on the list */ + SrcItem a[1]; /* One entry for each identifier on the list */ }; /* @@ -3830,7 +3837,7 @@ struct Walker { struct WhereConst *pConst; /* WHERE clause constants */ struct RenameCtx *pRename; /* RENAME COLUMN context */ struct Table *pTab; /* Table of generated column */ - struct SrcList_item *pSrcItem; /* A single FROM clause item */ + SrcItem *pSrcItem; /* A single FROM clause item */ DbFixer *pFix; } u; }; @@ -4353,7 +4360,7 @@ SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*, Token*, Select*, Expr*, IdList*); void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *); void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*); -int sqlite3IndexedByLookup(Parse *, struct SrcList_item *); +int sqlite3IndexedByLookup(Parse *, SrcItem *); void sqlite3SrcListShiftJoinType(SrcList*); void sqlite3SrcListAssignCursors(Parse*, SrcList*); void sqlite3IdListDelete(sqlite3*, IdList*); @@ -4415,7 +4422,7 @@ Table *sqlite3FindTable(sqlite3*,const char*, const char*); #define LOCATE_VIEW 0x01 #define LOCATE_NOERR 0x02 Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*); -Table *sqlite3LocateTableItem(Parse*,u32 flags,struct SrcList_item *); +Table *sqlite3LocateTableItem(Parse*,u32 flags,SrcItem *); Index *sqlite3FindIndex(sqlite3*,const char*, const char*); void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*); void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*); @@ -4710,7 +4717,7 @@ void sqlite3ExpirePreparedStatements(sqlite3*, int); void sqlite3CodeRhsOfIN(Parse*, Expr*, int); int sqlite3CodeSubselect(Parse*, Expr*); void sqlite3SelectPrep(Parse*, Select*, NameContext*); -int sqlite3ExpandSubquery(Parse*, struct SrcList_item*); +int sqlite3ExpandSubquery(Parse*, SrcItem*); void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p); int sqlite3MatchEName( const struct ExprList_item*, diff --git a/src/treeview.c b/src/treeview.c index 187f1a07d1..e0fa4971e2 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -127,7 +127,7 @@ void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){ void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ int i; for(i=0; inSrc; i++){ - const struct SrcList_item *pItem = &pSrc->a[i]; + const SrcItem *pItem = &pSrc->a[i]; StrAccum x; char zLine[100]; sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); diff --git a/src/walker.c b/src/walker.c index d047ccc039..927f7e52d7 100644 --- a/src/walker.c +++ b/src/walker.c @@ -154,7 +154,7 @@ int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){ int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){ SrcList *pSrc; int i; - struct SrcList_item *pItem; + SrcItem *pItem; pSrc = p->pSrc; if( pSrc ){ diff --git a/src/where.c b/src/where.c index c95a9db68e..63aba17c71 100644 --- a/src/where.c +++ b/src/where.c @@ -694,7 +694,7 @@ static void whereTraceIndexInfoOutputs(sqlite3_index_info *p){ */ static int termCanDriveIndex( WhereTerm *pTerm, /* WHERE clause term to check */ - struct SrcList_item *pSrc, /* Table we are trying to access */ + SrcItem *pSrc, /* Table we are trying to access */ Bitmask notReady /* Tables in outer loops of the join */ ){ char aff; @@ -728,7 +728,7 @@ static int termCanDriveIndex( static void constructAutomaticIndex( Parse *pParse, /* The parsing context */ WhereClause *pWC, /* The WHERE clause */ - struct SrcList_item *pSrc, /* The FROM clause term to get the next index */ + SrcItem *pSrc, /* The FROM clause term to get the next index */ Bitmask notReady, /* Mask of cursors that are not available */ WhereLevel *pLevel /* Write new index here */ ){ @@ -752,7 +752,7 @@ static void constructAutomaticIndex( u8 sentWarning = 0; /* True if a warnning has been issued */ Expr *pPartial = 0; /* Partial Index Expression */ int iContinue = 0; /* Jump here to skip excluded rows */ - struct SrcList_item *pTabItem; /* FROM clause term being indexed */ + SrcItem *pTabItem; /* FROM clause term being indexed */ int addrCounter = 0; /* Address where integer counter is initialized */ int regBase; /* Array of registers where record is assembled */ @@ -936,7 +936,7 @@ static sqlite3_index_info *allocateIndexInfo( Parse *pParse, /* The parsing context */ WhereClause *pWC, /* The WHERE clause being analyzed */ Bitmask mUnusable, /* Ignore terms with these prereqs */ - struct SrcList_item *pSrc, /* The FROM clause term that is the vtab */ + SrcItem *pSrc, /* The FROM clause term that is the vtab */ ExprList *pOrderBy, /* The ORDER BY clause */ u16 *pmNoOmit /* Mask of terms not to omit */ ){ @@ -1834,7 +1834,7 @@ void sqlite3WhereClausePrint(WhereClause *pWC){ void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC){ WhereInfo *pWInfo = pWC->pWInfo; int nb = 1+(pWInfo->pTabList->nSrc+3)/4; - struct SrcList_item *pItem = pWInfo->pTabList->a + p->iTab; + SrcItem *pItem = pWInfo->pTabList->a + p->iTab; Table *pTab = pItem->pTab; Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1; sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId, @@ -2445,7 +2445,7 @@ static int whereRangeVectorLen( */ static int whereLoopAddBtreeIndex( WhereLoopBuilder *pBuilder, /* The WhereLoop factory */ - struct SrcList_item *pSrc, /* FROM clause term being analyzed */ + SrcItem *pSrc, /* FROM clause term being analyzed */ Index *pProbe, /* An index on pSrc */ LogEst nInMul /* log(Number of iterations due to IN) */ ){ @@ -2936,7 +2936,7 @@ static int whereLoopAddBtree( LogEst aiRowEstPk[2]; /* The aiRowLogEst[] value for the sPk index */ i16 aiColumnPk = -1; /* The aColumn[] value for the sPk index */ SrcList *pTabList; /* The FROM clause */ - struct SrcList_item *pSrc; /* The FROM clause btree term to add */ + SrcItem *pSrc; /* The FROM clause btree term to add */ WhereLoop *pNew; /* Template WhereLoop object */ int rc = SQLITE_OK; /* Return code */ int iSortIdx = 1; /* Index number */ @@ -3217,7 +3217,7 @@ static int whereLoopAddVirtualOne( int rc = SQLITE_OK; WhereLoop *pNew = pBuilder->pNew; Parse *pParse = pBuilder->pWInfo->pParse; - struct SrcList_item *pSrc = &pBuilder->pWInfo->pTabList->a[pNew->iTab]; + SrcItem *pSrc = &pBuilder->pWInfo->pTabList->a[pNew->iTab]; int nConstraint = pIdxInfo->nConstraint; assert( (mUsable & mPrereq)==mPrereq ); @@ -3409,7 +3409,7 @@ static int whereLoopAddVirtual( WhereInfo *pWInfo; /* WHERE analysis context */ Parse *pParse; /* The parsing context */ WhereClause *pWC; /* The WHERE clause */ - struct SrcList_item *pSrc; /* The FROM clause term to search */ + SrcItem *pSrc; /* The FROM clause term to search */ sqlite3_index_info *p; /* Object to pass to xBestIndex() */ int nConstraint; /* Number of constraints in p */ int bIn; /* True if plan uses IN(...) operator */ @@ -3537,7 +3537,7 @@ static int whereLoopAddOr( WhereClause tempWC; WhereLoopBuilder sSubBuild; WhereOrSet sSum, sCur; - struct SrcList_item *pItem; + SrcItem *pItem; pWC = pBuilder->pWC; pWCEnd = pWC->a + pWC->nTerm; @@ -3653,8 +3653,8 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ Bitmask mPrior = 0; int iTab; SrcList *pTabList = pWInfo->pTabList; - struct SrcList_item *pItem; - struct SrcList_item *pEnd = &pTabList->a[pWInfo->nLevel]; + SrcItem *pItem; + SrcItem *pEnd = &pTabList->a[pWInfo->nLevel]; sqlite3 *db = pWInfo->pParse->db; int rc = SQLITE_OK; WhereLoop *pNew; @@ -3677,7 +3677,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ } #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pItem->pTab) ){ - struct SrcList_item *p; + SrcItem *p; for(p=&pItem[1]; pfg.jointype & (JT_LEFT|JT_CROSS)) ){ mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor); @@ -4532,7 +4532,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ */ static int whereShortCut(WhereLoopBuilder *pBuilder){ WhereInfo *pWInfo; - struct SrcList_item *pItem; + SrcItem *pItem; WhereClause *pWC; WhereTerm *pTerm; WhereLoop *pLoop; @@ -5062,7 +5062,7 @@ WhereInfo *sqlite3WhereBegin( } for(i=pWInfo->nLevel-1; i>=1; i--){ WhereTerm *pTerm, *pEnd; - struct SrcList_item *pItem; + SrcItem *pItem; pLoop = pWInfo->a[i].pWLoop; pItem = &pWInfo->pTabList->a[pLoop->iTab]; if( (pItem->fg.jointype & JT_LEFT)==0 ) continue; @@ -5152,7 +5152,7 @@ WhereInfo *sqlite3WhereBegin( for(ii=0, pLevel=pWInfo->a; iia[pLevel->iFrom]; pTab = pTabItem->pTab; @@ -5489,7 +5489,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ int k, last; VdbeOp *pOp, *pLastOp; Index *pIdx = 0; - struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom]; + SrcItem *pTabItem = &pTabList->a[pLevel->iFrom]; Table *pTab = pTabItem->pTab; assert( pTab!=0 ); pLoop = pLevel->pWLoop; diff --git a/src/whereInt.h b/src/whereInt.h index 89a463dc38..8896da0271 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -540,7 +540,7 @@ Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*); Bitmask sqlite3WhereExprUsageNN(WhereMaskSet*, Expr*); Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*); void sqlite3WhereExprAnalyze(SrcList*, WhereClause*); -void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*); +void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*); diff --git a/src/wherecode.c b/src/wherecode.c index 17dc36152d..a7a76fb704 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -129,7 +129,7 @@ int sqlite3WhereExplainOneScan( if( sqlite3ParseToplevel(pParse)->explain==2 ) #endif { - struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom]; + SrcItem *pItem = &pTabList->a[pLevel->iFrom]; Vdbe *v = pParse->pVdbe; /* VM being constructed */ sqlite3 *db = pParse->db; /* Database handle */ int isSearch; /* True for a SEARCH. False for SCAN. */ @@ -922,7 +922,7 @@ static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){ ** Insert an OP_CursorHint instruction if it is appropriate to do so. */ static void codeCursorHint( - struct SrcList_item *pTabItem, /* FROM clause item */ + SrcItem *pTabItem, /* FROM clause item */ WhereInfo *pWInfo, /* The where clause */ WhereLevel *pLevel, /* Which loop to provide hints for */ WhereTerm *pEndRange /* Hint this end-of-scan boundary term if not NULL */ @@ -1297,7 +1297,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( WhereClause *pWC; /* Decomposition of the entire WHERE clause */ WhereTerm *pTerm; /* A WHERE clause term */ sqlite3 *db; /* Database connection */ - struct SrcList_item *pTabItem; /* FROM clause term being coded */ + SrcItem *pTabItem; /* FROM clause term being coded */ int addrBrk; /* Jump here to break out of the loop */ int addrHalt; /* addrBrk for the outermost loop */ int addrCont; /* Jump here to continue with next cycle */ @@ -2085,7 +2085,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( */ if( pWInfo->nLevel>1 ){ int nNotReady; /* The number of notReady tables */ - struct SrcList_item *origSrc; /* Original list of tables */ + SrcItem *origSrc; /* Original list of tables */ nNotReady = pWInfo->nLevel - iLevel - 1; pOrTab = sqlite3StackAllocRaw(db, sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0])); diff --git a/src/whereexpr.c b/src/whereexpr.c index 1c8987d847..09ed7f6c37 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1853,7 +1853,7 @@ void sqlite3WhereExprAnalyze( */ void sqlite3WhereTabFuncArgs( Parse *pParse, /* Parsing context */ - struct SrcList_item *pItem, /* The FROM clause term to process */ + SrcItem *pItem, /* The FROM clause term to process */ WhereClause *pWC /* Xfer function arguments to here */ ){ Table *pTab; From a79e2a2d28eab71b7434a77ada3af5c2855d9bef Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 21 Feb 2021 23:44:14 +0000 Subject: [PATCH 229/257] Materialize any CTE that is used more than once. FossilOrigin-Name: ba59159fbe6b83fb6d79fbfee22d983768b0ebbaac7e99d2ac66c810e5e04100 --- manifest | 27 ++++++++++-------- manifest.uuid | 2 +- src/delete.c | 6 +++- src/expr.c | 5 +++- src/prepare.c | 4 ++- src/select.c | 75 ++++++++++++++++++++++++++++++++++--------------- src/sqliteInt.h | 30 ++++++++++++++++++-- src/treeview.c | 8 +++++- src/where.c | 2 +- 9 files changed, 117 insertions(+), 42 deletions(-) diff --git a/manifest b/manifest index 59fa169b0a..fe6d151c8a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rename\sthe\s"struct\sSrcList_item"\sobject\sto\sthe\smore\ssuccinct\s"SrcItem".\nThis\sis\sa\ssymbolic\schange\sonly.\s\sThe\slogic\sis\sunmodified. -D 2021-02-21T21:04:54.414 +C Materialize\sany\sCTE\sthat\sis\sused\smore\sthan\sonce. +D 2021-02-21T23:44:14.598 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -493,8 +493,8 @@ F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 F src/date.c dace306a10d9b02ee553d454c8e1cf8d3c9b932e137738a6b15b90253a9bfc10 F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c -F src/delete.c 8097c2c8feade9c46a1828dbdc98e1f52f4934fbff38233a2e7b98729528d244 -F src/expr.c 3a756aae0435178ddaed3b4e99ed7c6006f94d380881a249b7cf9d3fca8a405e +F src/delete.c 83dbb8d8c136a100b7a15da38c374b88d82460b3b14f036c169c2d5810223112 +F src/expr.c 6793c836aff149b14011ad546ae1648a18573779ee78f5a7d375f2a3047e8c8e F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c e9063648396c58778f77583a678342fe4a9bc82436bf23c5f9f444f2df0fdaa4 F src/func.c 479f6929be027eb0210cbdde9d3529c012facf082d64a6b854a9415940761e5e @@ -537,17 +537,17 @@ F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a F src/pragma.c 6daaaecc26a4b09481d21722525b079ce756751a43a79cc1d8f122d686806193 F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf -F src/prepare.c 7a534d100c556f45f10aee131f2e4244cb52547b7cf17e1c393f55d8abb62e97 +F src/prepare.c f634a9e799a6b1c136d8ee12479cffa22862bfb807d307b1db406aa0cdb042a5 F src/printf.c 10e61ec79dd9d41fdc77afee4e0df04fbb427f309c043118fe0b26a7d7db488a F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c c263fa5b255a03314c2418f936386e903d01c3e7cbec25a363a586ef3f10b249 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c b3277dc42ab20367b023c78d998119915403aa98c4e7230567dd9884ca38d7fd +F src/select.c cc8df79d5838f7c1d0bdbcf3e78b3d2efb781a09a39c4e5146fe7a669a621e82 F src/shell.c.in 844417f84df1f6c4fce1c815629a888cfdcf219e86513e9c332bbcc38832f477 F src/sqlite.h.in 8855a19f37ade8dad189a9e48233a2ebe1b46faf469c7eb0906a654e252dcc57 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h dbe0a5541c6eaabd3535ca6fd9838452bef7d25430267ac6701ef4d0c2cce46a +F src/sqliteInt.h 4e6c2c06e0234ef5e3049e1d0fc551c45db202bee9d90e2397862ec1ae9ca2cf F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -607,7 +607,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 -F src/treeview.c 04bf47d19b9f6f0b636cf42fec6e676b140d781bae792f52a8a014867e838e3e +F src/treeview.c c6260e1fa5f41c361b2409edc9b0050bcaef5bc4d6abc467fbc45f0d7ccf3d84 F src/trigger.c 861c3ec2c5b0fc830bdf82470454a9324fad70cbaa96d2e208fb54577c9e8d28 F src/update.c 0f5a61f0787199983530a33f6fffe4f52742f35fcdf6ccfad1078b1a8bc17723 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 @@ -629,7 +629,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 69e770e96fd56cc21608992bf2c6f1f3dc5cf2572d0495c6a643b06c3a679f14 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c d42d6c80ea363ef689a462e65eefcfe87deab924c50de5baa37ecb6af7d7ddaa -F src/where.c 40735d2b96b9b071a510fd3f090a195f48a09beb0c97ae0a11fd49e7c9396af9 +F src/where.c a02138440d7230493b5e508664d629f3e1e7615737a5d83aac3a2955d3a654ff F src/whereInt.h 446e5e8018f83358ef917cf32d8e6a86dc8430113d0b17e720f1839d3faa44c4 F src/wherecode.c e57a8690311a75d06e723e8d379f9831de04aba300e07174d236e32a7f9c7a13 F src/whereexpr.c 2dc51263e1fb8d8723e97a077a9a137ab0534e59e4cb88b3195f65edbe43cc32 @@ -1905,7 +1905,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 0d2c992f3622a6272ca4a3caff6b21f619fe976b8df8b34eff066086f8df2202 -R 3144ef024c1b147facc59f065688290b +P bfd5bf2c73110fcb36db9ba2a949ff516131fbd3e89325f88fe9f5c2b4ed87b2 +R aea18ad89757e208224db76c6eac01bc +T *branch * as-materialize-redux +T *sym-as-materialize-redux * +T -sym-trunk * U drh -Z 9a2772a6abeb20b71009a7863f85f821 +Z aa337b23bcebfb9b048b70a9fb74f61a diff --git a/manifest.uuid b/manifest.uuid index 08a79a0dbf..24a494e999 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bfd5bf2c73110fcb36db9ba2a949ff516131fbd3e89325f88fe9f5c2b4ed87b2 \ No newline at end of file +ba59159fbe6b83fb6d79fbfee22d983768b0ebbaac7e99d2ac66c810e5e04100 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 860a2739ad..117347ef96 100644 --- a/src/delete.c +++ b/src/delete.c @@ -209,7 +209,11 @@ Expr *sqlite3LimitWhere( pSrc->a[0].pTab = 0; pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0); pSrc->a[0].pTab = pTab; - pSrc->a[0].pIBIndex = 0; + if( pSrc->a[0].fg.isIndexedBy ){ + pSrc->a[0].u2.pIBIndex = 0; + }else if( pSrc->a[0].fg.isCte ){ + pSrc->a[0].u2.pCteUse->nUse++; + } /* generate the SELECT expression tree. */ pSelect = sqlite3SelectNew(pParse, pEList, pSelectSrc, pWhere, 0 ,0, diff --git a/src/expr.c b/src/expr.c index cf9a213f4e..b66556b039 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1544,7 +1544,10 @@ SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){ if( pNewItem->fg.isIndexedBy ){ pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy); } - pNewItem->pIBIndex = pOldItem->pIBIndex; + pNewItem->u2 = pOldItem->u2; + if( pNewItem->fg.isCte ){ + pNewItem->u2.pCteUse->nUse++; + } if( pNewItem->fg.isTabFunc ){ pNewItem->u1.pFuncArg = sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags); diff --git a/src/prepare.c b/src/prepare.c index dfa20e2b5d..d79495d2c6 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -597,7 +597,7 @@ void sqlite3ParserReset(Parse *pParse){ ** ** testcase( pParse->earlyCleanup ); */ -void sqlite3ParserAddCleanup( +void *sqlite3ParserAddCleanup( Parse *pParse, /* Destroy when this Parser finishes */ void (*xCleanup)(sqlite3*,void*), /* The cleanup routine */ void *pPtr /* Pointer to object to be cleaned up */ @@ -610,10 +610,12 @@ void sqlite3ParserAddCleanup( pCleanup->xCleanup = xCleanup; }else{ xCleanup(pParse->db, pPtr); + pPtr = 0; #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) pParse->earlyCleanup = 1; #endif } + return pPtr; } /* diff --git a/src/select.c b/src/select.c index a9d0eb1530..3da69943f7 100644 --- a/src/select.c +++ b/src/select.c @@ -4726,7 +4726,7 @@ int sqlite3IndexedByLookup(Parse *pParse, SrcItem *pFrom){ pParse->checkSchema = 1; return SQLITE_ERROR; } - pFrom->pIBIndex = pIdx; + pFrom->u2.pIBIndex = pIdx; return SQLITE_OK; } @@ -4935,8 +4935,18 @@ static int resolveFromTermToCte( if( cannotBeFunction(pParse, pFrom) ) return 2; assert( pFrom->pTab==0 ); - pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); + pTab = sqlite3DbMallocZero(db, sizeof(Table)); if( pTab==0 ) return 2; + if( pCte->pUse==0 ){ + pCte->pUse = sqlite3DbMallocZero(db, sizeof(pCte->pUse[0])); + if( pCte->pUse==0 + || sqlite3ParserAddCleanup(pParse,sqlite3DbFree,pCte->pUse)==0 + ){ + sqlite3DbFree(db, pTab); + return 2; + } + } + pFrom->pTab = pTab; pTab->nTabRef = 1; pTab->zName = sqlite3DbStrDup(db, pCte->zName); pTab->iPKey = -1; @@ -4945,6 +4955,9 @@ static int resolveFromTermToCte( pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0); if( db->mallocFailed ) return 2; assert( pFrom->pSelect ); + pFrom->fg.isCte = 1; + pFrom->u2.pCteUse = pCte->pUse; + pCte->pUse->nUse++; /* Check if this is a recursive CTE. */ pRecTerm = pSel = pFrom->pSelect; @@ -6153,6 +6166,7 @@ int sqlite3Select( */ for(i=0; inSrc; i++){ SrcItem *pItem = &pTabList->a[i]; + SrcItem *pPrior; SelectDest dest; Select *pSub; #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) @@ -6212,6 +6226,7 @@ int sqlite3Select( ** inside the subquery. This can help the subquery to run more efficiently. */ if( OptimizationEnabled(db, SQLITE_PushDown) + && (pItem->fg.isCte==0 || pItem->u2.pCteUse->nUse<=1) && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor, (pItem->fg.jointype & JT_OUTER)!=0) ){ @@ -6232,16 +6247,18 @@ int sqlite3Select( /* Generate code to implement the subquery ** - ** The subquery is implemented as a co-routine if the subquery is - ** guaranteed to be the outer loop (so that it does not need to be - ** computed more than once) + ** The subquery is implemented as a co-routine if: + ** (1) the subquery is guaranteed to be the outer loop (so that + ** it does not need to be computed more than once), and + ** (2) the subquery is not a CTE that is used more then once. ** - ** TODO: Are there other reasons beside (1) to use a co-routine + ** TODO: Are there other reasons beside (1) and (2) to use a co-routine ** implementation? */ if( i==0 && (pTabList->nSrc==1 || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0) /* (1) */ + && (pItem->fg.isCte==0 || pItem->u2.pCteUse->nUse<2) /* (2) */ ){ /* Implement a co-routine that will return a single row of the result ** set on each invocation. @@ -6261,16 +6278,30 @@ int sqlite3Select( sqlite3VdbeEndCoroutine(v, pItem->regReturn); sqlite3VdbeJumpHere(v, addrTop-1); sqlite3ClearTempRegCache(pParse); + }else if( pItem->fg.isCte && pItem->u2.pCteUse->addrM9e>0 ){ + /* This is a CTE for which materialization code has already been + ** generated. Invoke the subroutine to compute the materialization, + ** the make the pItem->iCursor be a copy of the ephemerial table that + ** holds the result of the materialization. */ + CteUse *pCteUse = pItem->u2.pCteUse; + sqlite3VdbeAddOp2(v, OP_Gosub, pCteUse->regRtn, pCteUse->addrM9e); + if( pItem->iCursor!=pCteUse->iCur ){ + sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pCteUse->iCur); + } + pSub->nSelectRow = pCteUse->nRowEst; + }else if( (pPrior = isSelfJoinView(pTabList, pItem))!=0 ){ + /* This view has already been materialized by a prior entry in + ** this same FROM clause. Reuse it. */ + if( pPrior->addrFillSub ){ + sqlite3VdbeAddOp2(v, OP_Gosub, pPrior->regReturn, pPrior->addrFillSub); + } + sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor); + pSub->nSelectRow = pPrior->pSelect->nSelectRow; }else{ - /* Generate a subroutine that will fill an ephemeral table with - ** the content of this subquery. pItem->addrFillSub will point - ** to the address of the generated subroutine. pItem->regReturn - ** is a register allocated to hold the subroutine return address - */ + /* Generate a subroutine that will materialize the view. */ int topAddr; int onceAddr = 0; int retAddr; - SrcItem *pPrior; testcase( pItem->addrFillSub==0 ); /* Ticket c52b09c7f38903b1311 */ pItem->regReturn = ++pParse->nMem; @@ -6285,22 +6316,22 @@ int sqlite3Select( }else{ VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName)); } - pPrior = isSelfJoinView(pTabList, pItem); - if( pPrior ){ - sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor); - assert( pPrior->pSelect!=0 ); - pSub->nSelectRow = pPrior->pSelect->nSelectRow; - }else{ - sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); - ExplainQueryPlan((pParse, 1, "MATERIALIZE %u", pSub->selId)); - sqlite3Select(pParse, pSub, &dest); - } + sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); + ExplainQueryPlan((pParse, 1, "MATERIALIZE %u", pSub->selId)); + sqlite3Select(pParse, pSub, &dest); pItem->pTab->nRowLogEst = pSub->nSelectRow; if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr); retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn); VdbeComment((v, "end %s", pItem->pTab->zName)); sqlite3VdbeChangeP1(v, topAddr, retAddr); sqlite3ClearTempRegCache(pParse); + if( pItem->fg.isCte ){ + CteUse *pCteUse = pItem->u2.pCteUse; + pCteUse->addrM9e = pItem->addrFillSub; + pCteUse->regRtn = pItem->regReturn; + pCteUse->iCur = pItem->iCursor; + pCteUse->nRowEst = pSub->nSelectRow; + } } if( db->mallocFailed ) goto select_end; pParse->nHeight -= sqlite3SelectExprHeight(p); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7fd71a86bf..ea6ff13815 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1137,6 +1137,7 @@ typedef struct Bitvec Bitvec; typedef struct CollSeq CollSeq; typedef struct Column Column; typedef struct Cte Cte; +typedef struct CteUse CteUse; typedef struct Db Db; typedef struct DbFixer DbFixer; typedef struct Schema Schema; @@ -2941,6 +2942,7 @@ struct SrcItem { unsigned viaCoroutine :1; /* Implemented as a co-routine */ unsigned isRecursive :1; /* True for recursive reference in WITH */ unsigned fromDDL :1; /* Comes from sqlite_schema */ + unsigned isCte :1; /* This is a CTE */ } fg; int iCursor; /* The VDBE cursor number used to access this table */ Expr *pOn; /* The ON clause of a join */ @@ -2950,7 +2952,10 @@ struct SrcItem { char *zIndexedBy; /* Identifier from "INDEXED BY " clause */ ExprList *pFuncArg; /* Arguments to table-valued-function */ } u1; - Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */ + union { + Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */ + CteUse *pCteUse; /* CTE Usage info info fg.isCte is true */ + } u2; }; /* @@ -3889,6 +3894,7 @@ struct Cte { ExprList *pCols; /* List of explicit column names, or NULL */ Select *pSelect; /* The definition of this CTE */ const char *zCteErr; /* Error message for circular references */ + CteUse *pUse; /* Usage information for this CTE */ }; /* @@ -3901,6 +3907,26 @@ struct With { Cte a[1]; /* For each CTE in the WITH clause.... */ }; +/* +** The Cte object is not guaranteed to persist for the entire duration +** of code generation. (The query flattener or other parser tree +** edits might delete it.) The following object records information +** about each Common Table Expression that must be preserved for the +** duration of the parse. +** +** The CteUse objects are freed using sqlite3ParserAddCleanup() rather +** than sqlite3SelectDelete(), which is what enables them to persist +** until the end of code generation. +*/ +struct CteUse { + int nUse; /* Number of users of this CTE */ + int addrM9e; /* Start of subroutine to compute materialization */ + int regRtn; /* Return address register for addrM9e subroutine */ + int iCur; /* Ephemeral table holding the materialization */ + LogEst nRowEst; /* Estimated number of rows in the table */ +}; + + #ifdef SQLITE_DEBUG /* ** An instance of the TreeView object is used for printing the content of @@ -4889,7 +4915,7 @@ sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*); int sqlite3VdbeParameterIndex(Vdbe*, const char*, int); int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); void sqlite3ParserReset(Parse*); -void sqlite3ParserAddCleanup(Parse*,void(*)(sqlite3*,void*),void*); +void *sqlite3ParserAddCleanup(Parse*,void(*)(sqlite3*,void*),void*); #ifdef SQLITE_ENABLE_NORMALIZE char *sqlite3Normalize(Vdbe*, const char*); #endif diff --git a/src/treeview.c b/src/treeview.c index e0fa4971e2..b696d764e0 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -111,7 +111,10 @@ void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){ } sqlite3_str_appendf(&x, ")"); } - sqlite3_str_appendf(&x, " AS"); + if( pCte->pUse ){ + sqlite3_str_appendf(&x, " (pUse=0x%p, nUse=%d)", pCte->pUse, + pCte->pUse->nUse); + } sqlite3StrAccumFinish(&x); sqlite3TreeViewItem(pView, zLine, inCte-1); sqlite3TreeViewSelect(pView, pCte->pSelect, 0); @@ -150,6 +153,9 @@ void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ if( pItem->fg.fromDDL ){ sqlite3_str_appendf(&x, " DDL"); } + if( pItem->fg.isCte ){ + sqlite3_str_appendf(&x, " CteUse=0x%p", pItem->u2.pCteUse); + } sqlite3StrAccumFinish(&x); sqlite3TreeViewItem(pView, zLine, inSrc-1); if( pItem->pSelect ){ diff --git a/src/where.c b/src/where.c index 63aba17c71..d7aa812849 100644 --- a/src/where.c +++ b/src/where.c @@ -2956,7 +2956,7 @@ static int whereLoopAddBtree( if( pSrc->fg.isIndexedBy ){ /* An INDEXED BY clause specifies a particular index to use */ - pProbe = pSrc->pIBIndex; + pProbe = pSrc->u2.pIBIndex; }else if( !HasRowid(pTab) ){ pProbe = pTab->pIndex; }else{ From 745912efac43f53e9508db41c38987a47f3939e0 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 22 Feb 2021 03:04:25 +0000 Subject: [PATCH 230/257] Add the AS MATERIALIZED and AS NOT MATERIALIZED syntax that works like it does in PostgreSQL. FossilOrigin-Name: a6bb272ec0c758ab069bfc07443624e0ea7910b1f23224ee078d050fa3ccf068 --- manifest | 23 ++++++++++------------- manifest.uuid | 2 +- src/build.c | 4 +++- src/parse.y | 9 +++++++-- src/select.c | 28 +++++++++++++++++++--------- src/sqliteInt.h | 11 ++++++++++- tool/mkkeywordhash.c | 3 ++- 7 files changed, 52 insertions(+), 28 deletions(-) diff --git a/manifest b/manifest index fe6d151c8a..5432275675 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Materialize\sany\sCTE\sthat\sis\sused\smore\sthan\sonce. -D 2021-02-21T23:44:14.598 +C Add\sthe\sAS\sMATERIALIZED\sand\sAS\sNOT\sMATERIALIZED\ssyntax\sthat\sworks\slike\sit\ndoes\sin\sPostgreSQL. +D 2021-02-22T03:04:25.485 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -486,7 +486,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 694020ad8a3af3d79b09f74c8f1421272a419cdea42a13401e3b0f7dea6e9c3e F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 -F src/build.c 072e3e22d1431262ac7e49d833dd778416f640407daa6115092aa5ec834a2106 +F src/build.c 30e069b646bbc94593c46e1b1ebe1822de271bf0a3791dff7b3d0af26e71fe9f F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 @@ -531,7 +531,7 @@ F src/os_win.c 77d39873836f1831a9b0b91894fec45ab0e9ca8e067dc8c549e1d1eca1566fe9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c c49952ac5e9cc536778eff528091d79d38b3e45cbeeed4695dc05e207dc6547d F src/pager.h 4bf9b3213a4b2bebbced5eaa8b219cf25d4a82f385d093cd64b7e93e5285f66f -F src/parse.y e6019e934cbbb4108ed3b9a6a225ee388d9a93fd12877ed5ba72c1dd16ebdd3c +F src/parse.y f3e8d7978c10495850c0bb502fe2669b55cf2841c4670b1f7261782e82069471 F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a @@ -542,12 +542,12 @@ F src/printf.c 10e61ec79dd9d41fdc77afee4e0df04fbb427f309c043118fe0b26a7d7db488a F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c c263fa5b255a03314c2418f936386e903d01c3e7cbec25a363a586ef3f10b249 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c cc8df79d5838f7c1d0bdbcf3e78b3d2efb781a09a39c4e5146fe7a669a621e82 +F src/select.c be6b8ee55be7c87ea7bed39dc880940868620011eae549ea77fa6ea3f28f10b9 F src/shell.c.in 844417f84df1f6c4fce1c815629a888cfdcf219e86513e9c332bbcc38832f477 F src/sqlite.h.in 8855a19f37ade8dad189a9e48233a2ebe1b46faf469c7eb0906a654e252dcc57 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h 4e6c2c06e0234ef5e3049e1d0fc551c45db202bee9d90e2397862ec1ae9ca2cf +F src/sqliteInt.h d7982229bd90ad5646e9250729125fb2f8a429de965c8825a8e378400e9d3c32 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1833,7 +1833,7 @@ F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439 F tool/mkautoconfamal.sh f62353eb6c06ab264da027fd4507d09914433dbdcab9cb011cdc18016f1ab3b8 F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe x F tool/mkctimec.tcl dd183b73ae1c28249669741c250525f0407e579a70482371668fd5f130d9feb3 -F tool/mkkeywordhash.c 750f25aef0e23f8e3367af6d824fbf5ed7d3e285f27cea91aa2dd72c367630eb +F tool/mkkeywordhash.c 08b6e4d7a482a7f37a9a0032e7ba968e26624a027b6b2e9ba589be6f5e3d8c2c F tool/mkmsvcmin.tcl 6ecab9fe22c2c8de4d82d4c46797bda3d2deac8e763885f5a38d0c44a895ab33 F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl 352a4319c0ad869eb26442bf7c3b015aa15594c21f1cce5a6420dbe999367c21 @@ -1905,10 +1905,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 bfd5bf2c73110fcb36db9ba2a949ff516131fbd3e89325f88fe9f5c2b4ed87b2 -R aea18ad89757e208224db76c6eac01bc -T *branch * as-materialize-redux -T *sym-as-materialize-redux * -T -sym-trunk * +P ba59159fbe6b83fb6d79fbfee22d983768b0ebbaac7e99d2ac66c810e5e04100 +R 03d676d4ba542b6ee47b63d9756152cc U drh -Z aa337b23bcebfb9b048b70a9fb74f61a +Z 02dd76bc8630787a973103223b94fcef diff --git a/manifest.uuid b/manifest.uuid index 24a494e999..b88aa0d5b9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ba59159fbe6b83fb6d79fbfee22d983768b0ebbaac7e99d2ac66c810e5e04100 \ No newline at end of file +a6bb272ec0c758ab069bfc07443624e0ea7910b1f23224ee078d050fa3ccf068 \ No newline at end of file diff --git a/src/build.c b/src/build.c index fad9a8bb8a..4068c54da2 100644 --- a/src/build.c +++ b/src/build.c @@ -5211,7 +5211,8 @@ Cte *sqlite3CteNew( Parse *pParse, /* Parsing context */ Token *pName, /* Name of the common-table */ ExprList *pArglist, /* Optional column name list for the table */ - Select *pQuery /* Query used to initialize the table */ + Select *pQuery, /* Query used to initialize the table */ + u8 eM10d /* The MATERIALIZED flag */ ){ Cte *pNew; sqlite3 *db = pParse->db; @@ -5226,6 +5227,7 @@ Cte *sqlite3CteNew( pNew->pSelect = pQuery; pNew->pCols = pArglist; pNew->zName = sqlite3NameFromToken(pParse->db, pName); + pNew->eM10d = eM10d; } return pNew; } diff --git a/src/parse.y b/src/parse.y index c84631846d..825b67ed30 100644 --- a/src/parse.y +++ b/src/parse.y @@ -250,6 +250,7 @@ columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);} %ifndef SQLITE_OMIT_GENERATED_COLUMNS GENERATED ALWAYS %endif + MATERIALIZED REINDEX RENAME CTIME_KW IF . %wildcard ANY. @@ -1666,8 +1667,12 @@ with ::= . with ::= WITH wqlist(W). { sqlite3WithPush(pParse, W, 1); } with ::= WITH RECURSIVE wqlist(W). { sqlite3WithPush(pParse, W, 1); } -wqitem(A) ::= nm(X) eidlist_opt(Y) AS LP select(Z) RP. { - A = sqlite3CteNew(pParse, &X, Y, Z); /*A-overwrites-X*/ +%type wqas {u8} +wqas(A) ::= AS. {A = M10d_Any;} +wqas(A) ::= AS MATERIALIZED. {A = M10d_Yes;} +wqas(A) ::= AS NOT MATERIALIZED. {A = M10d_No;} +wqitem(A) ::= nm(X) eidlist_opt(Y) wqas(M) LP select(Z) RP. { + A = sqlite3CteNew(pParse, &X, Y, Z, M); /*A-overwrites-X*/ } wqlist(A) ::= wqitem(X). { A = sqlite3WithAdd(pParse, 0, X); /*A-overwrites-X*/ diff --git a/src/select.c b/src/select.c index 3da69943f7..a13abe375c 100644 --- a/src/select.c +++ b/src/select.c @@ -4540,6 +4540,10 @@ static int propagateConstants( ** changes to the WHERE clause of the inner query could change the ** window over which window functions are calculated). ** +** (7) The inner query is a Common Table Expression (CTE) that should +** be materialized. (This restriction is implemented in the calling +** routine.) +** ** Return 0 if no changes are made and non-zero if one or more WHERE clause ** terms are duplicated into the subquery. */ @@ -4923,6 +4927,7 @@ static int resolveFromTermToCte( int bMayRecursive; /* True if compound joined by UNION [ALL] */ With *pSavedWith; /* Initial value of pParse->pWith */ int iRecTab = -1; /* Cursor for recursive table */ + CteUse *pCteUse; /* If pCte->zCteErr is non-NULL at this point, then this is an illegal ** recursive reference to CTE pCte. Leave an error in pParse and return @@ -4937,14 +4942,16 @@ static int resolveFromTermToCte( assert( pFrom->pTab==0 ); pTab = sqlite3DbMallocZero(db, sizeof(Table)); if( pTab==0 ) return 2; - if( pCte->pUse==0 ){ - pCte->pUse = sqlite3DbMallocZero(db, sizeof(pCte->pUse[0])); - if( pCte->pUse==0 - || sqlite3ParserAddCleanup(pParse,sqlite3DbFree,pCte->pUse)==0 + pCteUse = pCte->pUse; + if( pCteUse==0 ){ + pCte->pUse = pCteUse = sqlite3DbMallocZero(db, sizeof(pCteUse[0])); + if( pCteUse==0 + || sqlite3ParserAddCleanup(pParse,sqlite3DbFree,pCteUse)==0 ){ sqlite3DbFree(db, pTab); return 2; } + pCteUse->eM10d = pCte->eM10d; } pFrom->pTab = pTab; pTab->nTabRef = 1; @@ -4956,8 +4963,11 @@ static int resolveFromTermToCte( if( db->mallocFailed ) return 2; assert( pFrom->pSelect ); pFrom->fg.isCte = 1; - pFrom->u2.pCteUse = pCte->pUse; - pCte->pUse->nUse++; + pFrom->u2.pCteUse = pCteUse; + pCteUse->nUse++; + if( pCteUse->nUse>=2 && pCteUse->eM10d==M10d_Any ){ + pCteUse->eM10d = M10d_Yes; + } /* Check if this is a recursive CTE. */ pRecTerm = pSel = pFrom->pSelect; @@ -6226,7 +6236,7 @@ int sqlite3Select( ** inside the subquery. This can help the subquery to run more efficiently. */ if( OptimizationEnabled(db, SQLITE_PushDown) - && (pItem->fg.isCte==0 || pItem->u2.pCteUse->nUse<=1) + && (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d==M10d_Yes) && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor, (pItem->fg.jointype & JT_OUTER)!=0) ){ @@ -6250,7 +6260,7 @@ int sqlite3Select( ** The subquery is implemented as a co-routine if: ** (1) the subquery is guaranteed to be the outer loop (so that ** it does not need to be computed more than once), and - ** (2) the subquery is not a CTE that is used more then once. + ** (2) the subquery is not a CTE that should be materialized ** ** TODO: Are there other reasons beside (1) and (2) to use a co-routine ** implementation? @@ -6258,7 +6268,7 @@ int sqlite3Select( if( i==0 && (pTabList->nSrc==1 || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0) /* (1) */ - && (pItem->fg.isCte==0 || pItem->u2.pCteUse->nUse<2) /* (2) */ + && (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d!=M10d_Yes) /* (2) */ ){ /* Implement a co-routine that will return a single row of the result ** set on each invocation. diff --git a/src/sqliteInt.h b/src/sqliteInt.h index ea6ff13815..c2db0f8b6e 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3895,8 +3895,16 @@ struct Cte { Select *pSelect; /* The definition of this CTE */ const char *zCteErr; /* Error message for circular references */ CteUse *pUse; /* Usage information for this CTE */ + u8 eM10d; /* The MATERIALIZED flag */ }; +/* +** Allowed values for the materialized flag (eM10d): +*/ +#define M10d_Yes 0 /* AS MATERIALIZED */ +#define M10d_Any 1 /* Not specified. Query planner's choice */ +#define M10d_No 2 /* AS NOT MATERIALIZED */ + /* ** An instance of the With object represents a WITH clause containing ** one or more CTEs (common table expressions). @@ -3924,6 +3932,7 @@ struct CteUse { int regRtn; /* Return address register for addrM9e subroutine */ int iCur; /* Ephemeral table holding the materialization */ LogEst nRowEst; /* Estimated number of rows in the table */ + u8 eM10d; /* The MATERIALIZED flag */ }; @@ -4930,7 +4939,7 @@ const char *sqlite3JournalModename(int); int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int); #endif #ifndef SQLITE_OMIT_CTE - Cte *sqlite3CteNew(Parse*,Token*,ExprList*,Select*); + Cte *sqlite3CteNew(Parse*,Token*,ExprList*,Select*,u8); void sqlite3CteDelete(sqlite3*,Cte*); With *sqlite3WithAdd(Parse*,With*,Cte*); void sqlite3WithDelete(sqlite3*,With*); diff --git a/tool/mkkeywordhash.c b/tool/mkkeywordhash.c index ea3763fd19..bbb0ccf293 100644 --- a/tool/mkkeywordhash.c +++ b/tool/mkkeywordhash.c @@ -229,7 +229,7 @@ static Keyword aKeywordTable[] = { { "FOREIGN", "TK_FOREIGN", FKEY, 1 }, { "FROM", "TK_FROM", ALWAYS, 10 }, { "FULL", "TK_JOIN_KW", ALWAYS, 3 }, - { "GENERATED", "TK_GENERATED", GENCOL, 1 }, + { "GENERATED", "TK_GENERATED", ALWAYS, 1 }, { "GLOB", "TK_LIKE_KW", ALWAYS, 3 }, { "GROUP", "TK_GROUP", ALWAYS, 5 }, { "GROUPS", "TK_GROUPS", WINDOWFUNC, 2 }, @@ -255,6 +255,7 @@ static Keyword aKeywordTable[] = { { "LIKE", "TK_LIKE_KW", ALWAYS, 5 }, { "LIMIT", "TK_LIMIT", ALWAYS, 3 }, { "MATCH", "TK_MATCH", ALWAYS, 2 }, + { "MATERIALIZED", "TK_MATERIALIZED", CTE, 12 }, { "NATURAL", "TK_JOIN_KW", ALWAYS, 3 }, { "NO", "TK_NO", FKEY|WINDOWFUNC, 2 }, { "NOT", "TK_NOT", ALWAYS, 10 }, From 17267fe3934f73d1cca3954c3c028f4b6420ac2e Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 22 Feb 2021 11:07:25 +0000 Subject: [PATCH 231/257] Fix inverted logic regarding the materialization hint on the push-down optimization. FossilOrigin-Name: b66a49570852cf118a372a6ac44be3070cf9b4254696f16315b7c79a614e6c35 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 5432275675..380baacb02 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sAS\sMATERIALIZED\sand\sAS\sNOT\sMATERIALIZED\ssyntax\sthat\sworks\slike\sit\ndoes\sin\sPostgreSQL. -D 2021-02-22T03:04:25.485 +C Fix\sinverted\slogic\sregarding\sthe\smaterialization\shint\son\sthe\spush-down\noptimization. +D 2021-02-22T11:07:25.045 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -542,7 +542,7 @@ F src/printf.c 10e61ec79dd9d41fdc77afee4e0df04fbb427f309c043118fe0b26a7d7db488a F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c c263fa5b255a03314c2418f936386e903d01c3e7cbec25a363a586ef3f10b249 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c be6b8ee55be7c87ea7bed39dc880940868620011eae549ea77fa6ea3f28f10b9 +F src/select.c 09f15067366d8276c7444badc82863cae782e241ab1636c4bea8137dc61451e4 F src/shell.c.in 844417f84df1f6c4fce1c815629a888cfdcf219e86513e9c332bbcc38832f477 F src/sqlite.h.in 8855a19f37ade8dad189a9e48233a2ebe1b46faf469c7eb0906a654e252dcc57 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1905,7 +1905,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 ba59159fbe6b83fb6d79fbfee22d983768b0ebbaac7e99d2ac66c810e5e04100 -R 03d676d4ba542b6ee47b63d9756152cc +P a6bb272ec0c758ab069bfc07443624e0ea7910b1f23224ee078d050fa3ccf068 +R b8b4e3face4849b33a986c73cf6dafe8 U drh -Z 02dd76bc8630787a973103223b94fcef +Z b61abdd611c185be39fb533ed32c975a diff --git a/manifest.uuid b/manifest.uuid index b88aa0d5b9..6baaa5d223 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a6bb272ec0c758ab069bfc07443624e0ea7910b1f23224ee078d050fa3ccf068 \ No newline at end of file +b66a49570852cf118a372a6ac44be3070cf9b4254696f16315b7c79a614e6c35 \ No newline at end of file diff --git a/src/select.c b/src/select.c index a13abe375c..82e47a5840 100644 --- a/src/select.c +++ b/src/select.c @@ -6236,7 +6236,7 @@ int sqlite3Select( ** inside the subquery. This can help the subquery to run more efficiently. */ if( OptimizationEnabled(db, SQLITE_PushDown) - && (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d==M10d_Yes) + && (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d!=M10d_Yes) && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor, (pItem->fg.jointype & JT_OUTER)!=0) ){ From 606411bf915587861ca2aefabcea2f5657d7b29d Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 22 Feb 2021 14:25:40 +0000 Subject: [PATCH 232/257] Add an ALWAYS() on a branch that is now unreachable. FossilOrigin-Name: ace54c5bd50176db7c60b7e3cf9293a86d9ecf2fea897467044020b9684c0af3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 380baacb02..f5608b1d0a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sinverted\slogic\sregarding\sthe\smaterialization\shint\son\sthe\spush-down\noptimization. -D 2021-02-22T11:07:25.045 +C Add\san\sALWAYS()\son\sa\sbranch\sthat\sis\snow\sunreachable. +D 2021-02-22T14:25:40.130 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -614,7 +614,7 @@ F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 41c7a72da1df47864faa378a1c720b38adb288c6838cb6be5594511b6287a048 F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286 -F src/vdbe.c 9766281c0febf25f30a043d98b2417011acc7b04f287d3c671c3e59f656fc208 +F src/vdbe.c d8d2f2a1247bada7db7acf1f4ae65088bc09f020f4acf15810ef67f4aabe1ce9 F src/vdbe.h 25dabb25c7e157b84e59260cfb5b466c3ac103ede9f36f4db371332c47601abe F src/vdbeInt.h 3df118924e1711f1bbc8e30c46260d0ab6c3b029b32dd411f789111f76434f3c F src/vdbeapi.c 4a43e303ec3354c785f453e881521969378e85628278ab74ba4a9df790c0d93b @@ -1905,7 +1905,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 a6bb272ec0c758ab069bfc07443624e0ea7910b1f23224ee078d050fa3ccf068 -R b8b4e3face4849b33a986c73cf6dafe8 +P b66a49570852cf118a372a6ac44be3070cf9b4254696f16315b7c79a614e6c35 +R 35005ad1dc5275fcaf2f3b302048786b U drh -Z b61abdd611c185be39fb533ed32c975a +Z 9982ff2e051fdcf6655f0be4d2ebfac0 diff --git a/manifest.uuid b/manifest.uuid index 6baaa5d223..222b39c6f4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b66a49570852cf118a372a6ac44be3070cf9b4254696f16315b7c79a614e6c35 \ No newline at end of file +ace54c5bd50176db7c60b7e3cf9293a86d9ecf2fea897467044020b9684c0af3 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 153ed40b75..0be31b95b7 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3949,7 +3949,7 @@ case OP_OpenEphemeral: { aMem[pOp->p3].z = ""; } pCx = p->apCsr[pOp->p1]; - if( pCx && pCx->pBtx ){ + if( pCx && ALWAYS(pCx->pBtx) ){ /* If the ephermeral table is already open, erase all existing content ** so that the table is empty again, rather than creating a new table. */ assert( pCx->isEphemeral ); From f43fef29bb78dd5194cf39c12e74552f411cd4d0 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 22 Feb 2021 15:44:45 +0000 Subject: [PATCH 233/257] When a sub-transaction is released, if no pages required by containing sub-transactions were journaled, truncate the statement journal. This might prevent out-of-control statement journal growth in some cases. FossilOrigin-Name: e36327fb22db08763a82fb517407ff5ab0dbc053953098033e7e50796a777810 --- manifest | 19 +++++++++++-------- manifest.uuid | 2 +- src/memjournal.c | 43 ++++++++++++++++++++++++------------------- src/pager.c | 13 ++++++++++--- 4 files changed, 46 insertions(+), 31 deletions(-) diff --git a/manifest b/manifest index 59fa169b0a..8a3fcf5859 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rename\sthe\s"struct\sSrcList_item"\sobject\sto\sthe\smore\ssuccinct\s"SrcItem".\nThis\sis\sa\ssymbolic\schange\sonly.\s\sThe\slogic\sis\sunmodified. -D 2021-02-21T21:04:54.414 +C When\sa\ssub-transaction\sis\sreleased,\sif\sno\spages\srequired\sby\scontaining\ssub-transactions\swere\sjournaled,\struncate\sthe\sstatement\sjournal.\sThis\smight\sprevent\sout-of-control\sstatement\sjournal\sgrowth\sin\ssome\scases. +D 2021-02-22T15:44:45.441 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -514,7 +514,7 @@ F src/mem2.c b93b8762ab999a29ae7751532dadf0a1ac78040308a5fb1d17fcc365171d67eb F src/mem3.c 30301196cace2a085cbedee1326a49f4b26deff0af68774ca82c1f7c06fda4f6 F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944 F src/memdb.c ab0632d42407e866d2b616bd19d4211ac0ad1b430f04c4e187d60005b8700b98 -F src/memjournal.c 90b2ca7e2f465d57c16b69d15a9f3e3294af61088eb4938f2f7664d5ac50f813 +F src/memjournal.c bb0533253ad4a9657c29742d8504b6813c8367ccf135c0fb553d786850a55ea9 F src/msvc.h 3a15918220367a8876be3fa4f2abe423a861491e84b864fb2b7426bf022a28f8 F src/mutex.c 5e3409715552348732e97b9194abe92fdfcd934cfb681df4ba0ab87ac6c18d25 F src/mutex.h a7b2293c48db5f27007c3bdb21d438873637d12658f5a0bf8ad025bb96803c4a @@ -529,7 +529,7 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c adbbcea4c63d3b400d405f60a5da4c01433753ec4a12e2dc695beb2bbd671fe9 F src/os_win.c 77d39873836f1831a9b0b91894fec45ab0e9ca8e067dc8c549e1d1eca1566fe9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c c49952ac5e9cc536778eff528091d79d38b3e45cbeeed4695dc05e207dc6547d +F src/pager.c 970691daea03f9f15e34de671bd8675c1e136232b529e21bfd36d4dba6d41753 F src/pager.h 4bf9b3213a4b2bebbced5eaa8b219cf25d4a82f385d093cd64b7e93e5285f66f F src/parse.y e6019e934cbbb4108ed3b9a6a225ee388d9a93fd12877ed5ba72c1dd16ebdd3c F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 @@ -1905,7 +1905,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 0d2c992f3622a6272ca4a3caff6b21f619fe976b8df8b34eff066086f8df2202 -R 3144ef024c1b147facc59f065688290b -U drh -Z 9a2772a6abeb20b71009a7863f85f821 +P bfd5bf2c73110fcb36db9ba2a949ff516131fbd3e89325f88fe9f5c2b4ed87b2 +R 54537f477ff92d6f9883b3b55586620b +T *branch * stmt-jrnl-truncate +T *sym-stmt-jrnl-truncate * +T -sym-trunk * +U dan +Z 89681e18982564f6dc1e76e8bd67344b diff --git a/manifest.uuid b/manifest.uuid index 08a79a0dbf..48c77f3bcd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bfd5bf2c73110fcb36db9ba2a949ff516131fbd3e89325f88fe9f5c2b4ed87b2 \ No newline at end of file +e36327fb22db08763a82fb517407ff5ab0dbc053953098033e7e50796a777810 \ No newline at end of file diff --git a/src/memjournal.c b/src/memjournal.c index 4811f2d8d4..77cd6db7f3 100644 --- a/src/memjournal.c +++ b/src/memjournal.c @@ -70,7 +70,6 @@ struct MemJournal { int nChunkSize; /* In-memory chunk-size */ int nSpill; /* Bytes of data before flushing */ - int nSize; /* Bytes of data currently in memory */ FileChunk *pFirst; /* Head of in-memory chunk-list */ FilePoint endpoint; /* Pointer to the end of the file */ FilePoint readpoint; /* Pointer to the end of the last xRead() */ @@ -131,14 +130,13 @@ static int memjrnlRead( /* ** Free the list of FileChunk structures headed at MemJournal.pFirst. */ -static void memjrnlFreeChunks(MemJournal *p){ +static void memjrnlFreeChunks(FileChunk *pFirst){ FileChunk *pIter; FileChunk *pNext; - for(pIter=p->pFirst; pIter; pIter=pNext){ + for(pIter=pFirst; pIter; pIter=pNext){ pNext = pIter->pNext; sqlite3_free(pIter); } - p->pFirst = 0; } /* @@ -165,7 +163,7 @@ static int memjrnlCreateFile(MemJournal *p){ } if( rc==SQLITE_OK ){ /* No error has occurred. Free the in-memory buffers. */ - memjrnlFreeChunks(©); + memjrnlFreeChunks(copy.pFirst); } } if( rc!=SQLITE_OK ){ @@ -248,7 +246,6 @@ static int memjrnlWrite( nWrite -= iSpace; p->endpoint.iOffset += iSpace; } - p->nSize = iAmt + iOfst; } } @@ -256,22 +253,30 @@ static int memjrnlWrite( } /* -** Truncate the file. -** -** If the journal file is already on disk, truncate it there. Or, if it -** is still in main memory but is being truncated to zero bytes in size, -** ignore +** Truncate the in-memory file. */ static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){ MemJournal *p = (MemJournal *)pJfd; - if( ALWAYS(size==0) ){ - memjrnlFreeChunks(p); - p->nSize = 0; - p->endpoint.pChunk = 0; - p->endpoint.iOffset = 0; - p->readpoint.pChunk = 0; - p->readpoint.iOffset = 0; + FileChunk *pIter = 0; + + if( size==0 ){ + memjrnlFreeChunks(p->pFirst); + p->pFirst = 0; + }else{ + i64 iOff = p->nChunkSize; + for(pIter=p->pFirst; ALWAYS(pIter) && iOff<=size; pIter=pIter->pNext){ + iOff += p->nChunkSize; + } + if( pIter ){ + memjrnlFreeChunks(pIter->pNext); + pIter->pNext = 0; + } } + + p->endpoint.pChunk = pIter; + p->endpoint.iOffset = size; + p->readpoint.pChunk = 0; + p->readpoint.iOffset = 0; return SQLITE_OK; } @@ -280,7 +285,7 @@ static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){ */ static int memjrnlClose(sqlite3_file *pJfd){ MemJournal *p = (MemJournal *)pJfd; - memjrnlFreeChunks(p); + memjrnlFreeChunks(p->pFirst); return SQLITE_OK; } diff --git a/src/pager.c b/src/pager.c index a5510e7eb8..cd9096ed1c 100644 --- a/src/pager.c +++ b/src/pager.c @@ -435,6 +435,7 @@ struct PagerSavepoint { Bitvec *pInSavepoint; /* Set of pages in this savepoint */ Pgno nOrig; /* Original number of pages in file */ Pgno iSubRec; /* Index of first record in sub-journal */ + int bTruncateOnRelease; /* If stmt journal may be truncated on RELEASE */ #ifndef SQLITE_OMIT_WAL u32 aWalData[WAL_SAVEPOINT_NDATA]; /* WAL savepoint context */ #endif @@ -1070,6 +1071,9 @@ static int subjRequiresPage(PgHdr *pPg){ for(i=0; inSavepoint; i++){ p = &pPager->aSavepoint[i]; if( p->nOrig>=pgno && 0==sqlite3BitvecTestNotNull(p->pInSavepoint, pgno) ){ + for(i=i+1; inSavepoint; i++){ + pPager->aSavepoint[i].bTruncateOnRelease = 0; + } return 1; } } @@ -6848,6 +6852,7 @@ static SQLITE_NOINLINE int pagerOpenSavepoint(Pager *pPager, int nSavepoint){ } aNew[ii].iSubRec = pPager->nSubRec; aNew[ii].pInSavepoint = sqlite3BitvecCreate(pPager->dbSize); + aNew[ii].bTruncateOnRelease = 1; if( !aNew[ii].pInSavepoint ){ return SQLITE_NOMEM_BKPT; } @@ -6929,13 +6934,15 @@ int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){ /* If this is a release of the outermost savepoint, truncate ** the sub-journal to zero bytes in size. */ if( op==SAVEPOINT_RELEASE ){ - if( nNew==0 && isOpen(pPager->sjfd) ){ + PagerSavepoint *pRel = &pPager->aSavepoint[nNew]; + if( pRel->bTruncateOnRelease && isOpen(pPager->sjfd) ){ /* Only truncate if it is an in-memory sub-journal. */ if( sqlite3JournalIsInMemory(pPager->sjfd) ){ - rc = sqlite3OsTruncate(pPager->sjfd, 0); + i64 sz = (pPager->pageSize+4)*pRel->iSubRec; + rc = sqlite3OsTruncate(pPager->sjfd, sz); assert( rc==SQLITE_OK ); } - pPager->nSubRec = 0; + pPager->nSubRec = pRel->iSubRec; } } /* Else this is a rollback operation, playback the specified savepoint. From dee1cb300648b06ea56f02de9cfe94c4eb92e79b Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 22 Feb 2021 19:57:58 +0000 Subject: [PATCH 234/257] Add a few simple test cases for MATERIALIZED and NOT MATERIALIZED. FossilOrigin-Name: 64878124c160f790bc5861fd799ada03bd7db0c4426b8abc3b7ad1f7aa181168 --- manifest | 12 +-- manifest.uuid | 2 +- test/with6.test | 255 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 262 insertions(+), 7 deletions(-) create mode 100644 test/with6.test diff --git a/manifest b/manifest index 7cb01ef31b..ab0ad06cfb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Implement\sthe\sMATERIALIZED\sand\sNOT\sMATERIALIZED\shints\son\scommon\ntable\sexpressions. -D 2021-02-22T16:42:09.548 +C Add\sa\sfew\ssimple\stest\scases\sfor\sMATERIALIZED\sand\sNOT\sMATERIALIZED. +D 2021-02-22T19:57:58.697 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1788,6 +1788,7 @@ F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1 F test/with3.test 85e059bf4c2ef5626411ee59f399b4bb4b4a0f009bcb7db86f254e570ed11831 F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205 F test/with5.test 6248213c41fab36290b5b73aa3f937309dfba337004d9d8434c3fabc8c7d4be8 +F test/with6.test 3001b59179cbdc26a8c67ff8f46944e3141fdece9ab064c49bbf08459b67b207 F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64 F test/without_rowid1.test e4034c0849ccc2e8bb749c69f15bd69bb9fcf8fe77e8d17ce02369604242fe83 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 @@ -1905,8 +1906,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 bfd5bf2c73110fcb36db9ba2a949ff516131fbd3e89325f88fe9f5c2b4ed87b2 ace54c5bd50176db7c60b7e3cf9293a86d9ecf2fea897467044020b9684c0af3 -R 35005ad1dc5275fcaf2f3b302048786b -T +closed ace54c5bd50176db7c60b7e3cf9293a86d9ecf2fea897467044020b9684c0af3 +P b5a0778cc5a98a864bea72670f83262da940aceb91fa4cdf46ec097337a38a95 +R a0e8651539d2046a2eacfb9a26cd3050 U drh -Z 8fbd20db3052ba56fcae9ee5726a7d36 +Z 9ff3dc4427ac90918959bed5bdbcba59 diff --git a/manifest.uuid b/manifest.uuid index 1b94224fc1..afadf1dc1b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b5a0778cc5a98a864bea72670f83262da940aceb91fa4cdf46ec097337a38a95 \ No newline at end of file +64878124c160f790bc5861fd799ada03bd7db0c4426b8abc3b7ad1f7aa181168 \ No newline at end of file diff --git a/test/with6.test b/test/with6.test new file mode 100644 index 0000000000..ef63ec8bee --- /dev/null +++ b/test/with6.test @@ -0,0 +1,255 @@ +# 2021-02-22 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this file is the MATERIALIZED hint to common table expressions +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set ::testprefix with6 + +ifcapable {!cte} { + finish_test + return +} + +do_execsql_test 100 { + WITH c(x) AS (VALUES(0),(1)) + SELECT c1.x||c2.x||c3.x FROM c c1, c c2, c c3; +} {000 001 010 011 100 101 110 111} +do_eqp_test 101 { + WITH c(x) AS (VALUES(0),(1)) + SELECT c1.x||c2.x||c3.x FROM c c1, c c2, c c3; +} { + QUERY PLAN + |--MATERIALIZE xxxxxx + | `--SCAN 2 CONSTANT ROWS + |--SCAN SUBQUERY xxxxxx AS c1 + |--SCAN SUBQUERY xxxxxx AS c2 + `--SCAN SUBQUERY xxxxxx AS c3 +} + +do_execsql_test 110 { + WITH c(x) AS MATERIALIZED (VALUES(0),(1)) + SELECT c1.x||c2.x||c3.x FROM c c1, c c2, c c3; +} {000 001 010 011 100 101 110 111} +do_eqp_test 111 { + WITH c(x) AS MATERIALIZED (VALUES(0),(1)) + SELECT c1.x||c2.x||c3.x FROM c c1, c c2, c c3; +} { + QUERY PLAN + |--MATERIALIZE xxxxxx + | `--SCAN 2 CONSTANT ROWS + |--SCAN SUBQUERY xxxxxx AS c1 + |--SCAN SUBQUERY xxxxxx AS c2 + `--SCAN SUBQUERY xxxxxx AS c3 +} + +# Even though the CTE is not materialized, the self-join optimization +# kicks in and does the materialization for us. +# +do_execsql_test 120 { + WITH c(x) AS NOT MATERIALIZED (VALUES(0),(1)) + SELECT c1.x||c2.x||c3.x FROM c c1, c c2, c c3; +} {000 001 010 011 100 101 110 111} +do_eqp_test 121 { + WITH c(x) AS NOT MATERIALIZED (VALUES(0),(1)) + SELECT c1.x||c2.x||c3.x FROM c c1, c c2, c c3; +} { + QUERY PLAN + |--MATERIALIZE xxxxxx + | `--SCAN 2 CONSTANT ROWS + |--SCAN SUBQUERY xxxxxx AS c1 + |--SCAN SUBQUERY xxxxxx AS c2 + `--SCAN SUBQUERY xxxxxx AS c3 +} + +do_execsql_test 130 { + WITH c(x) AS NOT MATERIALIZED (VALUES(0),(1)) + SELECT c1.x||c2.x||c3.x + FROM (SELECT x FROM c LIMIT 5) AS c1, + (SELECT x FROM c LIMIT 5) AS c2, + (SELECT x FROM c LIMIT 5) AS c3; +} {000 001 010 011 100 101 110 111} +do_eqp_test 131 { + WITH c(x) AS NOT MATERIALIZED (VALUES(0),(1)) + SELECT c1.x||c2.x||c3.x + FROM (SELECT x FROM c LIMIT 5) AS c1, + (SELECT x FROM c LIMIT 5) AS c2, + (SELECT x FROM c LIMIT 5) AS c3; +} { + QUERY PLAN + |--MATERIALIZE xxxxxx + | |--CO-ROUTINE xxxxxx + | | `--SCAN 2 CONSTANT ROWS + | `--SCAN SUBQUERY xxxxxx + |--MATERIALIZE xxxxxx + | |--CO-ROUTINE xxxxxx + | | `--SCAN 2 CONSTANT ROWS + | `--SCAN SUBQUERY xxxxxx + |--MATERIALIZE xxxxxx + | |--CO-ROUTINE xxxxxx + | | `--SCAN 2 CONSTANT ROWS + | `--SCAN SUBQUERY xxxxxx + |--SCAN SUBQUERY xxxxxx AS c1 + |--SCAN SUBQUERY xxxxxx AS c2 + `--SCAN SUBQUERY xxxxxx AS c3 +} + +# The (SELECT x FROM c LIMIT N) subqueries get materialized once each. +# Show multiple materializations are shown. But there is only one +# materialization for c, shown by the "SCAN 2 CONSTANT ROWS" line. +# +do_execsql_test 140 { + WITH c(x) AS MATERIALIZED (VALUES(0),(1)) + SELECT c1.x||c2.x||c3.x + FROM (SELECT x FROM c LIMIT 5) AS c1, + (SELECT x FROM c LIMIT 6) AS c2, + (SELECT x FROM c LIMIT 7) AS c3; +} {000 001 010 011 100 101 110 111} +do_eqp_test 141 { + WITH c(x) AS MATERIALIZED (VALUES(0),(1)) + SELECT c1.x||c2.x||c3.x + FROM (SELECT x FROM c LIMIT 5) AS c1, + (SELECT x FROM c LIMIT 6) AS c2, + (SELECT x FROM c LIMIT 7) AS c3; +} { + QUERY PLAN + |--MATERIALIZE xxxxxx + | |--MATERIALIZE xxxxxx + | | `--SCAN 2 CONSTANT ROWS + | `--SCAN SUBQUERY xxxxxx + |--MATERIALIZE xxxxxx + | `--SCAN SUBQUERY xxxxxx + |--MATERIALIZE xxxxxx + | `--SCAN SUBQUERY xxxxxx + |--SCAN SUBQUERY xxxxxx AS c1 + |--SCAN SUBQUERY xxxxxx AS c2 + `--SCAN SUBQUERY xxxxxx AS c3 +} + +do_execsql_test 150 { + WITH c(x) AS (VALUES(0),(1)) + SELECT c1.x||c2.x||c3.x + FROM (SELECT x FROM c LIMIT 5) AS c1, + (SELECT x FROM c LIMIT 6) AS c2, + (SELECT x FROM c LIMIT 7) AS c3; +} {000 001 010 011 100 101 110 111} +do_eqp_test 151 { + WITH c(x) AS (VALUES(0),(1)) + SELECT c1.x||c2.x||c3.x + FROM (SELECT x FROM c LIMIT 5) AS c1, + (SELECT x FROM c LIMIT 6) AS c2, + (SELECT x FROM c LIMIT 7) AS c3; +} { + QUERY PLAN + |--MATERIALIZE xxxxxx + | |--MATERIALIZE xxxxxx + | | `--SCAN 2 CONSTANT ROWS + | `--SCAN SUBQUERY xxxxxx + |--MATERIALIZE xxxxxx + | `--SCAN SUBQUERY xxxxxx + |--MATERIALIZE xxxxxx + | `--SCAN SUBQUERY xxxxxx + |--SCAN SUBQUERY xxxxxx AS c1 + |--SCAN SUBQUERY xxxxxx AS c2 + `--SCAN SUBQUERY xxxxxx AS c3 +} + +do_execsql_test 160 { + WITH c(x) AS (VALUES(0),(1)) + SELECT c2.x + 100*(SELECT sum(x+1) FROM c WHERE c.x<=c2.x) + FROM c AS c2 WHERE c2.x<10; +} {100 301} +do_eqp_test 161 { + WITH c(x) AS (VALUES(0),(1)) + SELECT c2.x + 100*(SELECT sum(x+1) FROM c WHERE c.x<=c2.x) + FROM c AS c2 WHERE c2.x<10; +} { + QUERY PLAN + |--MATERIALIZE xxxxxx + | `--SCAN 2 CONSTANT ROWS + |--SCAN SUBQUERY xxxxxx AS c2 + `--CORRELATED SCALAR SUBQUERY xxxxxx + `--SCAN SUBQUERY xxxxxx +} + +do_execsql_test 170 { + WITH c(x) AS NOT MATERIALIZED (VALUES(0),(1)) + SELECT c2.x + 100*(SELECT sum(x+1) FROM c WHERE c.x<=c2.x) + FROM c AS c2 WHERE c2.x<10; +} {100 301} +do_eqp_test 171 { + WITH c(x) AS NOT MATERIALIZED (VALUES(0),(1)) + SELECT c2.x + 100*(SELECT sum(x+1) FROM c WHERE c.x<=c2.x) + FROM c AS c2 WHERE c2.x<10; +} { + QUERY PLAN + |--CO-ROUTINE xxxxxx + | `--SCAN 2 CONSTANT ROWS + |--SCAN SUBQUERY xxxxxx AS c2 + `--CORRELATED SCALAR SUBQUERY xxxxxx + |--CO-ROUTINE xxxxxx + | `--SCAN 2 CONSTANT ROWS + `--SCAN SUBQUERY xxxxxx +} + + +do_execsql_test 200 { + CREATE TABLE t1(x); + INSERT INTO t1(x) VALUES(4); + CREATE VIEW t2(y) AS + WITH c(z) AS (VALUES(4),(5),(6)) + SELECT c1.z+c2.z*100+t1.x*10000 + FROM t1, + (SELECT z FROM c LIMIT 5) AS c1, + (SELECT z FROM c LIMIT 5) AS c2; + SELECT y FROM t2 ORDER BY y; +} {40404 40405 40406 40504 40505 40506 40604 40605 40606} +do_execsql_test 210 { + DROP VIEW t2; + CREATE VIEW t2(y) AS + WITH c(z) AS NOT MATERIALIZED (VALUES(4),(5),(6)) + SELECT c1.z+c2.z*100+t1.x*10000 + FROM t1, + (SELECT z FROM c LIMIT 5) AS c1, + (SELECT z FROM c LIMIT 5) AS c2; + SELECT y FROM t2 ORDER BY y; +} {40404 40405 40406 40504 40505 40506 40604 40605 40606} +do_eqp_test 211 { + SELECT y FROM t2 ORDER BY y; +} { + QUERY PLAN + |--MATERIALIZE xxxxxx + | |--MATERIALIZE xxxxxx + | | `--SCAN 3 CONSTANT ROWS + | `--SCAN SUBQUERY xxxxxx + |--MATERIALIZE xxxxxx + | `--SCAN SUBQUERY xxxxxx + |--SCAN SUBQUERY xxxxxx AS c1 + |--SCAN SUBQUERY xxxxxx AS c2 + |--SCAN TABLE t1 + `--USE TEMP B-TREE FOR ORDER BY +} +do_execsql_test 220 { + DROP VIEW t2; + CREATE VIEW t2(y) AS + WITH c(z) AS MATERIALIZED (VALUES(4),(5),(6)) + SELECT c1.z+c2.z*100+t1.x*10000 + FROM t1, + (SELECT z FROM c LIMIT 5) AS c1, + (SELECT z FROM c LIMIT 5) AS c2; + SELECT y FROM t2 ORDER BY y; +} {40404 40405 40406 40504 40505 40506 40604 40605 40606} + + + +finish_test From 903fdd483415cd3e5db94cd532ef42734aeac0c1 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 22 Feb 2021 20:56:13 +0000 Subject: [PATCH 235/257] Allow WHERE terms to be pushed down into sub-queries that contain window functions, provided that the WHERE term is made up of entirely of constants and copies of expressions found in the PARTITION BY clauses of all window functions in the sub-query. FossilOrigin-Name: dac51f303bba1a0aac7768c688b0c134deb7641062cce2071d546f2d8f241dec --- manifest | 22 +++--- manifest.uuid | 2 +- src/select.c | 66 +++++++++++++++-- src/sqliteInt.h | 1 + src/window.c | 20 +++--- test/windowpushd.test | 160 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 246 insertions(+), 25 deletions(-) create mode 100644 test/windowpushd.test diff --git a/manifest b/manifest index ab0ad06cfb..6a7b339a38 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\sfew\ssimple\stest\scases\sfor\sMATERIALIZED\sand\sNOT\sMATERIALIZED. -D 2021-02-22T19:57:58.697 +C Allow\sWHERE\sterms\sto\sbe\spushed\sdown\sinto\ssub-queries\sthat\scontain\swindow\sfunctions,\sprovided\sthat\sthe\sWHERE\sterm\sis\smade\sup\sof\sentirely\sof\sconstants\sand\scopies\sof\sexpressions\sfound\sin\sthe\sPARTITION\sBY\sclauses\sof\sall\swindow\sfunctions\sin\sthe\ssub-query. +D 2021-02-22T20:56:13.828 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -542,12 +542,12 @@ F src/printf.c 10e61ec79dd9d41fdc77afee4e0df04fbb427f309c043118fe0b26a7d7db488a F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c c263fa5b255a03314c2418f936386e903d01c3e7cbec25a363a586ef3f10b249 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 09f15067366d8276c7444badc82863cae782e241ab1636c4bea8137dc61451e4 +F src/select.c 5d66f394afb481eb812927283a3036f7ffbda48442e3a0517d1fa1c3248aca8c F src/shell.c.in 844417f84df1f6c4fce1c815629a888cfdcf219e86513e9c332bbcc38832f477 F src/sqlite.h.in 8855a19f37ade8dad189a9e48233a2ebe1b46faf469c7eb0906a654e252dcc57 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h d7982229bd90ad5646e9250729125fb2f8a429de965c8825a8e378400e9d3c32 +F src/sqliteInt.h 11b9d47e9b9520b123bc75254da7a4e215463e811e62b89518fc5e9a192a0222 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -633,7 +633,7 @@ F src/where.c a02138440d7230493b5e508664d629f3e1e7615737a5d83aac3a2955d3a654ff F src/whereInt.h 446e5e8018f83358ef917cf32d8e6a86dc8430113d0b17e720f1839d3faa44c4 F src/wherecode.c e57a8690311a75d06e723e8d379f9831de04aba300e07174d236e32a7f9c7a13 F src/whereexpr.c 2dc51263e1fb8d8723e97a077a9a137ab0534e59e4cb88b3195f65edbe43cc32 -F src/window.c edd6f5e25a1e8f2b6f5305b7f5f7da7bb35f07f0d432b255b1d4c2fcab4205aa +F src/window.c fdf01316f6cecf060378aa1713a29e527ab683823ba7d15b8978ec70165e8bdb F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 F test/affinity3.test eecb0dabee4b7765a8465439d5e99429279ffba23ca74a7eae270a452799f9e7 @@ -1783,6 +1783,7 @@ F test/windowB.test 7a983ea1cc1cf72be7f378e4b32f6cb2d73014c5cd8b25aaee825164cd42 F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0 F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b F test/windowfault.test 72375ae71031eabf96bc88d0af128c8628a091ddc99b5a394e848b3df5fc17ad +F test/windowpushd.test c92a53ac3786d76dbf3ba95b42582c1324f1f1da0c319e670ec620ab5567f822 F test/with1.test 780be387f01e290e768bdfd1827280f9e37ba37223eb4736aba386864fac5a94 F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1ab F test/with3.test 85e059bf4c2ef5626411ee59f399b4bb4b4a0f009bcb7db86f254e570ed11831 @@ -1906,7 +1907,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 b5a0778cc5a98a864bea72670f83262da940aceb91fa4cdf46ec097337a38a95 -R a0e8651539d2046a2eacfb9a26cd3050 -U drh -Z 9ff3dc4427ac90918959bed5bdbcba59 +P 64878124c160f790bc5861fd799ada03bd7db0c4426b8abc3b7ad1f7aa181168 +R e2a54658db8d3d8e6c4194562e3b87a8 +T *branch * window-functions-pushdown +T *sym-window-functions-pushdown * +T -sym-trunk * +U dan +Z df00d38ff47c226052c8b6acf25da8b9 diff --git a/manifest.uuid b/manifest.uuid index afadf1dc1b..259a0a1cad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -64878124c160f790bc5861fd799ada03bd7db0c4426b8abc3b7ad1f7aa181168 \ No newline at end of file +dac51f303bba1a0aac7768c688b0c134deb7641062cce2071d546f2d8f241dec \ No newline at end of file diff --git a/src/select.c b/src/select.c index 82e47a5840..b1a1ea507e 100644 --- a/src/select.c +++ b/src/select.c @@ -4489,6 +4489,35 @@ static int propagateConstants( return nChng; } +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) +# if !defined(SQLITE_OMIT_WINDOWFUNC) +/* +** This function is called to determine whether or not it is safe to +** push WHERE clause expression pExpr down to FROM clause sub-query +** pSubq, which contains at least one window function. Return 1 +** if it is safe and the expression should be pushed down, or 0 +** otherwise. +** +** It is only safe to push the expression down if it consists only +** of constants and copies of expressions that appear in the PARTITION +** BY clause of all window function used by the sub-query. It is safe +** to filter out entire partitions, but not rows within partitions, as +** this may change the results of the window functions. +** +** At the time this function is called it is guaranteed that +** +** * the sub-query uses only one distinct window frame, and +** * that the window frame has a PARTITION BY clase. +*/ +static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){ + assert( pSubq->pWin->pPartition ); + assert( (pSubq->selFlags & SF_MultiPart)==0 ); + assert( pSubq->pPrior==0 ); + return sqlite3ExprIsConstantOrGroupBy(pParse, pExpr, pSubq->pWin->pPartition); +} +# endif /* SQLITE_OMIT_WINDOWFUNC */ +#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ + #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) /* ** Make copies of relevant WHERE clause terms of the outer query into @@ -4536,9 +4565,20 @@ static int propagateConstants( ** But if the (b2=2) term were to be pushed down into the bb subquery, ** then the (1,1,NULL) row would be suppressed. ** -** (6) The inner query features one or more window-functions (since -** changes to the WHERE clause of the inner query could change the -** window over which window functions are calculated). +** (6) Window functions make things tricky as changes to the WHERE clause +** of the inner query could change the window over which window +** functions are calculated. Therefore, do not attempt the optimization +** if: +** +** (6a) The inner query uses multiple incompatible window partitions. +** +** (6b) The inner query is a compound and uses window-functions. +** +** (6c) The WHERE clause does not consist entirely of constants and +** copies of expressions found in the PARTITION BY clause of +** all window-functions used by the sub-query. It is safe to +** filter out entire partitions, as this does not change the +** window over which any window-function is calculated. ** ** (7) The inner query is a Common Table Expression (CTE) that should ** be materialized. (This restriction is implemented in the calling @@ -4556,13 +4596,17 @@ static int pushDownWhereTerms( ){ Expr *pNew; int nChng = 0; - Select *pSel; if( pWhere==0 ) return 0; - if( pSubq->selFlags & SF_Recursive ) return 0; /* restriction (2) */ + if( pSubq->selFlags & (SF_Recursive|SF_MultiPart) ) return 0; #ifndef SQLITE_OMIT_WINDOWFUNC - for(pSel=pSubq; pSel; pSel=pSel->pPrior){ - if( pSel->pWin ) return 0; /* restriction (6) */ + if( pSubq->pPrior ){ + Select *pSel; + for(pSel=pSubq; pSel; pSel=pSel->pPrior){ + if( pSel->pWin ) return 0; /* restriction (6b) */ + } + }else{ + if( pSubq->pWin && pSubq->pWin->pPartition==0 ) return 0; } #endif @@ -4609,6 +4653,14 @@ static int pushDownWhereTerms( x.isLeftJoin = 0; x.pEList = pSubq->pEList; pNew = substExpr(&x, pNew); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pSubq->pWin && 0==pushDownWindowCheck(pParse, pSubq, pNew) ){ + /* Restriction 6c has prevented push-down in this case */ + sqlite3ExprDelete(pParse->db, pNew); + nChng--; + break; + } +#endif if( pSubq->selFlags & SF_Aggregate ){ pSubq->pHaving = sqlite3ExprAnd(pParse, pSubq->pHaving, pNew); }else{ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index c2db0f8b6e..1d5f0d2a87 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3204,6 +3204,7 @@ struct Select { #define SF_NoopOrderBy 0x0400000 /* ORDER BY is ignored for this query */ #define SF_UpdateFrom 0x0800000 /* Statement is an UPDATE...FROM */ #define SF_PushDown 0x1000000 /* SELECT has be modified by push-down opt */ +#define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */ /* ** The results of a SELECT can be distributed in several ways, as defined diff --git a/src/window.c b/src/window.c index 88ff7d314d..09572ec033 100644 --- a/src/window.c +++ b/src/window.c @@ -1304,15 +1304,19 @@ void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){ ** SELECT, or (b) the windows already linked use a compatible window frame. */ void sqlite3WindowLink(Select *pSel, Window *pWin){ - if( pSel!=0 - && (0==pSel->pWin || 0==sqlite3WindowCompare(0, pSel->pWin, pWin, 0)) - ){ - pWin->pNextWin = pSel->pWin; - if( pSel->pWin ){ - pSel->pWin->ppThis = &pWin->pNextWin; + if( pSel ){ + if( 0==pSel->pWin || 0==sqlite3WindowCompare(0, pSel->pWin, pWin, 0) ){ + pWin->pNextWin = pSel->pWin; + if( pSel->pWin ){ + pSel->pWin->ppThis = &pWin->pNextWin; + } + pSel->pWin = pWin; + pWin->ppThis = &pSel->pWin; + }else{ + if( sqlite3ExprListCompare(pWin->pPartition, pSel->pWin->pPartition,-1) ){ + pSel->selFlags |= SF_MultiPart; + } } - pSel->pWin = pWin; - pWin->ppThis = &pSel->pWin; } } diff --git a/test/windowpushd.test b/test/windowpushd.test new file mode 100644 index 0000000000..890290b079 --- /dev/null +++ b/test/windowpushd.test @@ -0,0 +1,160 @@ +# 2021 February 23 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this file is testing the push-down optimization when +# WHERE constraints are pushed down into a sub-query that uses +# window functions. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix windowpushd + +do_execsql_test 1.0 { + CREATE TABLE t1(id INTEGER PRIMARY KEY, grp_id); + CREATE INDEX i1 ON t1(grp_id); + CREATE VIEW lll AS SELECT + row_number() OVER (PARTITION BY grp_id), + grp_id, id + FROM t1 +} + +do_execsql_test 1.1 { + INSERT INTO t1 VALUES + (1, 2), (2, 3), (3, 3), (4, 1), (5, 1), + (6, 1), (7, 1), (8, 1), (9, 3), (10, 3), + (11, 2), (12, 3), (13, 3), (14, 2), (15, 1), + (16, 2), (17, 1), (18, 2), (19, 3), (20, 2) +} + +do_execsql_test 1.2 { + SELECT * FROM lll +} { + 1 1 4 2 1 5 3 1 6 4 1 7 5 1 8 6 1 15 7 1 17 + 1 2 1 2 2 11 3 2 14 4 2 16 5 2 18 6 2 20 + 1 3 2 2 3 3 3 3 9 4 3 10 5 3 12 6 3 13 7 3 19 +} + +do_execsql_test 1.3 { + SELECT * FROM lll WHERE grp_id=2 +} { + 1 2 1 2 2 11 3 2 14 4 2 16 5 2 18 6 2 20 +} + +do_eqp_test 1.4 { + SELECT * FROM lll WHERE grp_id=2 +} {SEARCH TABLE t1 USING COVERING INDEX i1 (grp_id=?)} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 2.0 { + CREATE TABLE t1(a, b, c, d); + INSERT INTO t1 VALUES('A', 'C', 1, 0.1); + INSERT INTO t1 VALUES('A', 'D', 2, 0.2); + INSERT INTO t1 VALUES('A', 'E', 3, 0.3); + INSERT INTO t1 VALUES('A', 'C', 4, 0.4); + INSERT INTO t1 VALUES('B', 'D', 5, 0.5); + INSERT INTO t1 VALUES('B', 'E', 6, 0.6); + INSERT INTO t1 VALUES('B', 'C', 7, 0.7); + INSERT INTO t1 VALUES('B', 'D', 8, 0.8); + INSERT INTO t1 VALUES('C', 'E', 9, 0.9); + INSERT INTO t1 VALUES('C', 'C', 10, 1.0); + INSERT INTO t1 VALUES('C', 'D', 11, 1.1); + INSERT INTO t1 VALUES('C', 'E', 12, 1.2); + + CREATE INDEX i1 ON t1(a); + CREATE INDEX i2 ON t1(b); + + CREATE VIEW v1 AS SELECT a, c, max(c) OVER (PARTITION BY a) FROM t1; + + CREATE VIEW v2 AS SELECT a, c, + max(c) OVER (PARTITION BY a), + row_number() OVER () + FROM t1; + + CREATE VIEW v3 AS SELECT b, d, + max(d) OVER (PARTITION BY b), + row_number() OVER (PARTITION BY b) + FROM t1; +} + +foreach tn {0 1} { + optimization_control db push-down $tn + + do_execsql_test 2.$tn.1.1 { + SELECT * FROM v1; + } { + A 1 4 A 2 4 A 3 4 A 4 4 + B 5 8 B 6 8 B 7 8 B 8 8 + C 9 12 C 10 12 C 11 12 C 12 12 + } + + do_execsql_test 2.$tn.1.2 { + SELECT * FROM v1 WHERE a IN ('A', 'B'); + } { + A 1 4 A 2 4 A 3 4 A 4 4 + B 5 8 B 6 8 B 7 8 B 8 8 + } + + do_execsql_test 2.$tn.1.3 { + SELECT * FROM v1 WHERE a IS 'C' + } { + C 9 12 C 10 12 C 11 12 C 12 12 + } + + if {$tn==1} { + do_eqp_test 2.$tn.1.4 { + SELECT * FROM v1 WHERE a IN ('A', 'B'); + } {USING INDEX i1 (a=?)} + + do_eqp_test 2.$tn.1.5 { + SELECT * FROM v1 WHERE a = 'c' COLLATE nocase + } {USING INDEX i1} + } + + do_execsql_test 2.$tn.2.1 { + SELECT * FROM v2; + } { + A 1 4 1 A 2 4 2 A 3 4 3 A 4 4 4 + B 5 8 5 B 6 8 6 B 7 8 7 B 8 8 8 + C 9 12 9 C 10 12 10 C 11 12 11 C 12 12 12 + } + + do_execsql_test 2.$tn.2.2 { + SELECT * FROM v2 WHERE a = 'C'; + } { + C 9 12 9 C 10 12 10 C 11 12 11 C 12 12 12 + } + + do_execsql_test 2.$tn.3.1 { SELECT * FROM v3; } { + C 0.1 1.0 1 C 0.4 1.0 2 C 0.7 1.0 3 C 1.0 1.0 4 + D 0.2 1.1 1 D 0.5 1.1 2 D 0.8 1.1 3 D 1.1 1.1 4 + E 0.3 1.2 1 E 0.6 1.2 2 E 0.9 1.2 3 E 1.2 1.2 4 + } + + do_execsql_test 2.$tn.3.2 { SELECT * FROM v3 WHERE b<'E' } { + C 0.1 1.0 1 C 0.4 1.0 2 C 0.7 1.0 3 C 1.0 1.0 4 + D 0.2 1.1 1 D 0.5 1.1 2 D 0.8 1.1 3 D 1.1 1.1 4 + } + + if {$tn==1} { + do_eqp_test 2.$tn.3.3 { + SELECT * FROM v3 WHERE b='E' + } {USING INDEX i2 (b=?)} + } + +} + + + + +finish_test + From 34a224a13bbcfa71cb3f5d05f8f340395ada243e Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 23 Feb 2021 15:36:06 +0000 Subject: [PATCH 236/257] Further tests for the push-down optimization with window functions. FossilOrigin-Name: 4b089f70117bfb440eaefd830c05576be0cc624d9d6018c869270dc68e44513e --- manifest | 17 +++++------ manifest.uuid | 2 +- test/windowfault.test | 22 +++++++++++++-- test/windowpushd.test | 66 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 6a7b339a38..f38e1b95ae 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sWHERE\sterms\sto\sbe\spushed\sdown\sinto\ssub-queries\sthat\scontain\swindow\sfunctions,\sprovided\sthat\sthe\sWHERE\sterm\sis\smade\sup\sof\sentirely\sof\sconstants\sand\scopies\sof\sexpressions\sfound\sin\sthe\sPARTITION\sBY\sclauses\sof\sall\swindow\sfunctions\sin\sthe\ssub-query. -D 2021-02-22T20:56:13.828 +C Further\stests\sfor\sthe\spush-down\soptimization\swith\swindow\sfunctions. +D 2021-02-23T15:36:06.380 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1782,8 +1782,8 @@ F test/windowA.test 6d63dc1260daa17141a55007600581778523a8b420629f1282d2acfc36af F test/windowB.test 7a983ea1cc1cf72be7f378e4b32f6cb2d73014c5cd8b25aaee825164cd4269e5 F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0 F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b -F test/windowfault.test 72375ae71031eabf96bc88d0af128c8628a091ddc99b5a394e848b3df5fc17ad -F test/windowpushd.test c92a53ac3786d76dbf3ba95b42582c1324f1f1da0c319e670ec620ab5567f822 +F test/windowfault.test d543d46571b32d19f198cb04b6505747fabf3cc369970daae47074ee793612be +F test/windowpushd.test 2f442e00639117aad235bcd576c85a9bb24d5b011e9e0be784062a9656921a40 F test/with1.test 780be387f01e290e768bdfd1827280f9e37ba37223eb4736aba386864fac5a94 F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1ab F test/with3.test 85e059bf4c2ef5626411ee59f399b4bb4b4a0f009bcb7db86f254e570ed11831 @@ -1907,10 +1907,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 64878124c160f790bc5861fd799ada03bd7db0c4426b8abc3b7ad1f7aa181168 -R e2a54658db8d3d8e6c4194562e3b87a8 -T *branch * window-functions-pushdown -T *sym-window-functions-pushdown * -T -sym-trunk * +P dac51f303bba1a0aac7768c688b0c134deb7641062cce2071d546f2d8f241dec +R 01aa28d00e9dcb21c3691c72496bc468 U dan -Z df00d38ff47c226052c8b6acf25da8b9 +Z 2da9e360e2569fcff88e5b35e5221c66 diff --git a/manifest.uuid b/manifest.uuid index 259a0a1cad..1a898e92c8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dac51f303bba1a0aac7768c688b0c134deb7641062cce2071d546f2d8f241dec \ No newline at end of file +4b089f70117bfb440eaefd830c05576be0cc624d9d6018c869270dc68e44513e \ No newline at end of file diff --git a/test/windowfault.test b/test/windowfault.test index aea2340215..27c7742b30 100644 --- a/test/windowfault.test +++ b/test/windowfault.test @@ -246,6 +246,7 @@ do_faultsim_test 10 -faults oom* -prep { faultsim_test_result {0 {}} } +#------------------------------------------------------------------------- reset_db do_execsql_test 11.0 { DROP TABLE IF EXISTS t0; @@ -253,7 +254,7 @@ do_execsql_test 11.0 { INSERT INTO t0 VALUES(0); } {} -do_faultsim_test 11 -faults oom* -prep { +do_faultsim_test 11.1 -faults oom* -prep { } -body { execsql { SELECT * FROM t0 WHERE @@ -263,7 +264,7 @@ do_faultsim_test 11 -faults oom* -prep { faultsim_test_result {0 {}} } -do_faultsim_test 11 -faults oom* -prep { +do_faultsim_test 11.2 -faults oom* -prep { } -body { execsql { VALUES(false),(current_date collate binary) @@ -274,4 +275,21 @@ do_faultsim_test 11 -faults oom* -prep { faultsim_test_result {0 {}} } +#------------------------------------------------------------------------- +reset_db +do_execsql_test 12.0 { + CREATE TABLE t1(a, b, c); +} {} +do_faultsim_test 12 -faults oom* -prep { +} -body { + execsql { + WITH v(a, b, row_number) AS ( + SELECT a, b, row_number() OVER (PARTITION BY a ORDER BY b) FROM t1 + ) + SELECT * FROM v WHERE a=2 + } +} -test { + faultsim_test_result {0 {}} +} + finish_test diff --git a/test/windowpushd.test b/test/windowpushd.test index 890290b079..256e291730 100644 --- a/test/windowpushd.test +++ b/test/windowpushd.test @@ -84,6 +84,16 @@ do_execsql_test 2.0 { max(d) OVER (PARTITION BY b), row_number() OVER (PARTITION BY b) FROM t1; + + CREATE TABLE t2(x, y, z); + INSERT INTO t2 VALUES('W', 3, 1); + INSERT INTO t2 VALUES('W', 2, 2); + INSERT INTO t2 VALUES('X', 1, 4); + INSERT INTO t2 VALUES('X', 5, 7); + INSERT INTO t2 VALUES('Y', 1, 9); + INSERT INTO t2 VALUES('Y', 4, 2); + INSERT INTO t2 VALUES('Z', 3, 3); + INSERT INTO t2 VALUES('Z', 3, 4); } foreach tn {0 1} { @@ -149,6 +159,62 @@ foreach tn {0 1} { do_eqp_test 2.$tn.3.3 { SELECT * FROM v3 WHERE b='E' } {USING INDEX i2 (b=?)} + do_eqp_test 2.$tn.3.4 { + SELECT * FROM v3 WHERE b>'C' + } {USING INDEX i2 (b>?)} + } + + do_execsql_test 2.$tn.4.1 { + SELECT * FROM ( + SELECT x, sum(y) AS s, max(z) AS m + FROM t2 GROUP BY x + ) + } { + W 5 2 + X 6 7 + Y 5 9 + Z 6 4 + } + + do_execsql_test 2.$tn.4.1 { + SELECT * FROM ( + SELECT x, sum(y) AS s, max(z) AS m, + max( max(z) ) OVER (PARTITION BY sum(y) + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) + FROM t2 GROUP BY x + ) + } { + W 5 2 9 + Y 5 9 9 + X 6 7 7 + Z 6 4 7 + } + + do_execsql_test 2.$tn.4.2 { + SELECT * FROM ( + SELECT x, sum(y) AS s, max(z) AS m, + max( max(z) ) OVER (PARTITION BY sum(y) + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) + FROM t2 GROUP BY x + ) WHERE s=6 + } { + X 6 7 7 + Z 6 4 7 + } + + do_execsql_test 2.$tn.4.3 { + SELECT * FROM ( + SELECT x, sum(y) AS s, max(z) AS m, + max( max(z) ) OVER (PARTITION BY sum(y) + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) + FROM t2 GROUP BY x + ) WHERE s<6 + } { + W 5 2 9 + Y 5 9 9 } } From ce5de60ff956a09e035bcccd388ac9b7d93d9392 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 25 Feb 2021 15:50:19 +0000 Subject: [PATCH 237/257] Ensure that tests like "rbu.test" and "notify2.test" that are only run by specific configurations during release testing are run for both release and debug versions of the tests. FossilOrigin-Name: 911df43f98297bf645688dc51e988106a0297cb60bb97dde699c2848404fcf72 --- manifest | 13 ++++++------- manifest.uuid | 2 +- test/releasetest_data.tcl | 12 +++++++++--- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index be925758bf..06696cbf2a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sa\ssub-transaction\sis\sreleased,\sif\sno\spages\srequired\sby\scontaining\ssub-transactions\swere\sjournaled,\struncate\sthe\sstatement\sjournal.\sThis\sprevents\sout\sof\scontrol\sstatement\sjournal\sgrowth\sin\ssome\scases. -D 2021-02-23T16:40:47.708 +C Ensure\sthat\stests\slike\s"rbu.test"\sand\s"notify2.test"\sthat\sare\sonly\srun\sby\sspecific\sconfigurations\sduring\srelease\stesting\sare\srun\sfor\sboth\srelease\sand\sdebug\sversions\sof\sthe\stests. +D 2021-02-25T15:50:19.870 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1289,7 +1289,7 @@ F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8 F test/regexp2.test 40e894223b3d6672655481493f1be12012f2b33c F test/reindex.test cd9d6021729910ece82267b4f5e1b5ac2911a7566c43b43c176a6a4732e2118d F test/releasetest.tcl fb76d8fcc95ac29d6356cd9e52b726ab9e43a24082897618dfbcb7c2b0049153 x -F test/releasetest_data.tcl 756514dabf6d19531a173a07853426543a2f3a6026863c1b5ef00cbcbd86ff30 +F test/releasetest_data.tcl d60628b6a04891e97cc4f5fbce08abe13c5b74cb23dcca5ac24800471a3bc6db F test/resetdb.test 8062cf10a09d8c048f8de7711e94571c38b38168db0e5877ba7561789e5eeb2b F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb F test/returning1.test 684e1c73d961422a7376c932fcdd6dacf02bad21d12f749cfe8c19991ef379f6 @@ -1907,8 +1907,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 20689468100aed264877111367b42837ca19e63e717fed2ebd4b20b908f13178 e36327fb22db08763a82fb517407ff5ab0dbc053953098033e7e50796a777810 -R eafbf0e4dfaf16461818378d022a25c1 -T +closed e36327fb22db08763a82fb517407ff5ab0dbc053953098033e7e50796a777810 +P 23ca23894af352ea351c9efcdd7d86b82455f4c81b6001052a6d13aa2d705e84 +R 72612dcbce4a940c7913dd85945718e5 U dan -Z 3cd8f5166b5a86884f09832023069c0d +Z fabac3dbdfdef97c7359526eae4bbff6 diff --git a/manifest.uuid b/manifest.uuid index a767bdc3c6..d80dc45ca3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -23ca23894af352ea351c9efcdd7d86b82455f4c81b6001052a6d13aa2d705e84 \ No newline at end of file +911df43f98297bf645688dc51e988106a0297cb60bb97dde699c2848404fcf72 \ No newline at end of file diff --git a/test/releasetest_data.tcl b/test/releasetest_data.tcl index 921ca29fad..5aa27f6e6e 100644 --- a/test/releasetest_data.tcl +++ b/test/releasetest_data.tcl @@ -586,9 +586,15 @@ proc main_tests {args} { puts "$config \"$target\"" if {$bNodebug==0 && $bNosynthetic==0} { set iHas [string first SQLITE_DEBUG $::Configs($config)] - set dtarget test - if {$target=="tcltest"} { - set dtarget tcltest + set dtarget [list] + set iQTI [lsearch -glob $target QUICKTEST_*] + if {$iQTI>=0} { + lappend dtarget [lindex $target $iQTI] + } + if {[lsearch $target tcltest]>=0} { + lappend dtarget tcltest + } else { + lappend dtarget test } if {$iHas>=0} { puts "$config-ndebug \"$dtarget\"" From 3dc864b575a74daa38ff2f0e73591978030fe0ab Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 25 Feb 2021 16:55:47 +0000 Subject: [PATCH 238/257] Fix handling of INSERT on views with implicitly named hidden columns in SQLITE_ENABLE_HIDDEN_COLUMNS builds. FossilOrigin-Name: 15795a96a8b3f4ea368b3eb29a4ff8d1b4b33ebb2bff2a5ccb045b8f01f9f99b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 06696cbf2a..ea26c5fd6a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\stests\slike\s"rbu.test"\sand\s"notify2.test"\sthat\sare\sonly\srun\sby\sspecific\sconfigurations\sduring\srelease\stesting\sare\srun\sfor\sboth\srelease\sand\sdebug\sversions\sof\sthe\stests. -D 2021-02-25T15:50:19.870 +C Fix\shandling\sof\sINSERT\son\sviews\swith\simplicitly\snamed\shidden\scolumns\sin\sSQLITE_ENABLE_HIDDEN_COLUMNS\sbuilds. +D 2021-02-25T16:55:47.813 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -486,7 +486,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 694020ad8a3af3d79b09f74c8f1421272a419cdea42a13401e3b0f7dea6e9c3e F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 -F src/build.c 30e069b646bbc94593c46e1b1ebe1822de271bf0a3791dff7b3d0af26e71fe9f +F src/build.c e1790f21cd19708af231ceed5e52f495b94c4b2609e27d2b5ce2805a9aa3464e F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 @@ -1907,7 +1907,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 23ca23894af352ea351c9efcdd7d86b82455f4c81b6001052a6d13aa2d705e84 -R 72612dcbce4a940c7913dd85945718e5 +P 911df43f98297bf645688dc51e988106a0297cb60bb97dde699c2848404fcf72 +R 541ccd041b03ce231d83952665e3168b U dan -Z fabac3dbdfdef97c7359526eae4bbff6 +Z 90ed53b5ee6ecc7b7169558c64d4ba1b diff --git a/manifest.uuid b/manifest.uuid index d80dc45ca3..7540bb517d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -911df43f98297bf645688dc51e988106a0297cb60bb97dde699c2848404fcf72 \ No newline at end of file +15795a96a8b3f4ea368b3eb29a4ff8d1b4b33ebb2bff2a5ccb045b8f01f9f99b \ No newline at end of file diff --git a/src/build.c b/src/build.c index 4068c54da2..b1812753a7 100644 --- a/src/build.c +++ b/src/build.c @@ -2859,6 +2859,7 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ assert( pTable->aCol==0 ); pTable->nCol = pSelTab->nCol; pTable->aCol = pSelTab->aCol; + pTable->tabFlags |= (pSelTab->tabFlags & COLFLAG_NOINSERT); pSelTab->nCol = 0; pSelTab->aCol = 0; assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) ); From a4656e390ac4e8f04bee327ed4307610bce23e6a Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 25 Feb 2021 18:23:39 +0000 Subject: [PATCH 239/257] Fix a problem with UPDATE and DELETE statements that use both INDEXED BY and LIMIT clauses in SQLITE_ENABLE_UPDATE_DELETE_LIMIT builds. FossilOrigin-Name: cc2b4b38668bd32ebd8cf2e0d244eef2a6c7e0a1ee0a34c9c43eaf25c9cc09ae --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/delete.c | 4 +++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index ea26c5fd6a..faae6b73ed 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\shandling\sof\sINSERT\son\sviews\swith\simplicitly\snamed\shidden\scolumns\sin\sSQLITE_ENABLE_HIDDEN_COLUMNS\sbuilds. -D 2021-02-25T16:55:47.813 +C Fix\sa\sproblem\swith\sUPDATE\sand\sDELETE\sstatements\sthat\suse\sboth\sINDEXED\sBY\sand\sLIMIT\sclauses\sin\sSQLITE_ENABLE_UPDATE_DELETE_LIMIT\sbuilds. +D 2021-02-25T18:23:39.672 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -493,7 +493,7 @@ F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 F src/date.c dace306a10d9b02ee553d454c8e1cf8d3c9b932e137738a6b15b90253a9bfc10 F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c -F src/delete.c 83dbb8d8c136a100b7a15da38c374b88d82460b3b14f036c169c2d5810223112 +F src/delete.c 73f57a9a183532c344a3135cf8f2a5589376e39183e0b5f562d6b61b2af0f4d8 F src/expr.c 6793c836aff149b14011ad546ae1648a18573779ee78f5a7d375f2a3047e8c8e F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c e9063648396c58778f77583a678342fe4a9bc82436bf23c5f9f444f2df0fdaa4 @@ -1907,7 +1907,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 911df43f98297bf645688dc51e988106a0297cb60bb97dde699c2848404fcf72 -R 541ccd041b03ce231d83952665e3168b +P 15795a96a8b3f4ea368b3eb29a4ff8d1b4b33ebb2bff2a5ccb045b8f01f9f99b +R 3e2336764ffbc96bf6253ff9862eb4d5 U dan -Z 90ed53b5ee6ecc7b7169558c64d4ba1b +Z 568c29fcdf825424835e9b3ed9d8df1e diff --git a/manifest.uuid b/manifest.uuid index 7540bb517d..54ce941b5b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -15795a96a8b3f4ea368b3eb29a4ff8d1b4b33ebb2bff2a5ccb045b8f01f9f99b \ No newline at end of file +cc2b4b38668bd32ebd8cf2e0d244eef2a6c7e0a1ee0a34c9c43eaf25c9cc09ae \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 117347ef96..0c9c7bc8d0 100644 --- a/src/delete.c +++ b/src/delete.c @@ -207,10 +207,12 @@ Expr *sqlite3LimitWhere( /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree ** and the SELECT subtree. */ pSrc->a[0].pTab = 0; - pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0); + pSelectSrc = sqlite3SrcListDup(db, pSrc, 0); pSrc->a[0].pTab = pTab; if( pSrc->a[0].fg.isIndexedBy ){ pSrc->a[0].u2.pIBIndex = 0; + pSrc->a[0].fg.isIndexedBy = 0; + sqlite3DbFree(db, pSrc->a[0].u1.zIndexedBy); }else if( pSrc->a[0].fg.isCte ){ pSrc->a[0].u2.pCteUse->nUse++; } From b3617e9d2d96822baf8caa641bb09e302ab44046 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 25 Feb 2021 18:28:11 +0000 Subject: [PATCH 240/257] Fix test case in altercorrupt.test so that it works with SQLITE_ENABLE_OVERSIZE_CELL_CHECK builds. FossilOrigin-Name: 062b338ff2ea71633b4fb3c75c6a47b5fc4fe9c2a72daacd987d1eca0bda5217 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/altercorrupt.test | 4 +--- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index faae6b73ed..d5b5e2d2aa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\sUPDATE\sand\sDELETE\sstatements\sthat\suse\sboth\sINDEXED\sBY\sand\sLIMIT\sclauses\sin\sSQLITE_ENABLE_UPDATE_DELETE_LIMIT\sbuilds. -D 2021-02-25T18:23:39.672 +C Fix\stest\scase\sin\saltercorrupt.test\sso\sthat\sit\sworks\swith\sSQLITE_ENABLE_OVERSIZE_CELL_CHECK\sbuilds. +D 2021-02-25T18:28:11.143 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -648,7 +648,7 @@ F test/alter4.test dfd6086faf461b27ca2d2999848dcd207edf23352fc1592d0005c0844f3f0 F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959 F test/alterauth2.test 794ac5cef251819fe364b4fe20f12f86e9c5d68070513c7fd26c17cb244c89af F test/altercol.test 1d6a6fe698b81e626baea4881f5717f9bc53d7d07f1cd23ee7ad1b931f117ddf -F test/altercorrupt.test 36e71e0ff3042682c9137cdd40e19ccdcd6808f31ed9ba8a29fece356736a3ef +F test/altercorrupt.test 584d707a80e106952d6382790c8919bcf9f0db678ed3a1c09fd98b7f9d1d3a10 F test/alterdropcol.test baad37ff9b07078ea02dcc33dbfb82bde655f3eee5c453e218f69501c36f02ba F test/alterdropcol2.test 3948c805ca52f4621051b35968c18c09d107eb117e2b656c78cee3b2870650c0 F test/alterlegacy.test f38c6d06cda39e1f7b955bbce57f2e3ef5b7cb566d3d1234502093e228c15811 @@ -1907,7 +1907,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 15795a96a8b3f4ea368b3eb29a4ff8d1b4b33ebb2bff2a5ccb045b8f01f9f99b -R 3e2336764ffbc96bf6253ff9862eb4d5 +P cc2b4b38668bd32ebd8cf2e0d244eef2a6c7e0a1ee0a34c9c43eaf25c9cc09ae +R b3507d71370343e14ba764ee8c538781 U dan -Z 568c29fcdf825424835e9b3ed9d8df1e +Z 9c8bfc41eb8ef032021a20979f47dc22 diff --git a/manifest.uuid b/manifest.uuid index 54ce941b5b..6a05f0061d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cc2b4b38668bd32ebd8cf2e0d244eef2a6c7e0a1ee0a34c9c43eaf25c9cc09ae \ No newline at end of file +062b338ff2ea71633b4fb3c75c6a47b5fc4fe9c2a72daacd987d1eca0bda5217 \ No newline at end of file diff --git a/test/altercorrupt.test b/test/altercorrupt.test index 612e8d72d5..5c50fa4a47 100644 --- a/test/altercorrupt.test +++ b/test/altercorrupt.test @@ -90,10 +90,8 @@ do_test 1.0 { | end crash-685346d89b5e5f.db }]} {} -do_execsql_test 1.1 { +do_catchsql_test 1.1 { ALTER TABLE t2 DROP COLUMN e; -} -do_catchsql_test 1.2 { ALTER TABLE t1 DROP COLUMN f; } {1 {database disk image is malformed}} From 4b17455ab2f38d51ab0dcd6f01dd8d99c8229e8c Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 26 Feb 2021 15:20:17 +0000 Subject: [PATCH 241/257] Minor simplification in resolve.c. FossilOrigin-Name: 310dac342e7b1f9b5a5df6a9d598e85d5fef59bba9307d9230baf77c8f2351a2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/resolve.c | 23 +++++++++++------------ 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index d5b5e2d2aa..877ec2b56e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stest\scase\sin\saltercorrupt.test\sso\sthat\sit\sworks\swith\sSQLITE_ENABLE_OVERSIZE_CELL_CHECK\sbuilds. -D 2021-02-25T18:28:11.143 +C Minor\ssimplification\sin\sresolve.c. +D 2021-02-26T15:20:17.903 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -540,7 +540,7 @@ F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf F src/prepare.c f634a9e799a6b1c136d8ee12479cffa22862bfb807d307b1db406aa0cdb042a5 F src/printf.c 10e61ec79dd9d41fdc77afee4e0df04fbb427f309c043118fe0b26a7d7db488a F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c c263fa5b255a03314c2418f936386e903d01c3e7cbec25a363a586ef3f10b249 +F src/resolve.c f3380c5570207e60cc23f2d34a8ac493a8e12f7cfeba0c89090497801dd22017 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 5d66f394afb481eb812927283a3036f7ffbda48442e3a0517d1fa1c3248aca8c F src/shell.c.in 844417f84df1f6c4fce1c815629a888cfdcf219e86513e9c332bbcc38832f477 @@ -1907,7 +1907,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 cc2b4b38668bd32ebd8cf2e0d244eef2a6c7e0a1ee0a34c9c43eaf25c9cc09ae -R b3507d71370343e14ba764ee8c538781 +P 062b338ff2ea71633b4fb3c75c6a47b5fc4fe9c2a72daacd987d1eca0bda5217 +R 07651de30eadccb5d0a1b765b39186be U dan -Z 9c8bfc41eb8ef032021a20979f47dc22 +Z a8b3d49e868cbc0b6002cfdac6e7fd25 diff --git a/manifest.uuid b/manifest.uuid index 6a05f0061d..e486d4c319 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -062b338ff2ea71633b4fb3c75c6a47b5fc4fe9c2a72daacd987d1eca0bda5217 \ No newline at end of file +310dac342e7b1f9b5a5df6a9d598e85d5fef59bba9307d9230baf77c8f2351a2 \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index a478c7d10e..689f197031 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -1589,25 +1589,24 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ for(i=0; ipSrc->nSrc; i++){ SrcItem *pItem = &p->pSrc->a[i]; if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){ - NameContext *pNC; /* Used to iterate name contexts */ - int nRef = 0; /* Refcount for pOuterNC and outer contexts */ + int nRef = pOuterNC ? pOuterNC->nRef : 0; const char *zSavedContext = pParse->zAuthContext; - /* Count the total number of references to pOuterNC and all of its - ** parent contexts. After resolving references to expressions in - ** pItem->pSelect, check if this value has changed. If so, then - ** SELECT statement pItem->pSelect must be correlated. Set the - ** pItem->fg.isCorrelated flag if this is the case. */ - for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef += pNC->nRef; - if( pItem->zName ) pParse->zAuthContext = pItem->zName; sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC); pParse->zAuthContext = zSavedContext; if( pParse->nErr || db->mallocFailed ) return WRC_Abort; - for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef -= pNC->nRef; - assert( pItem->fg.isCorrelated==0 && nRef<=0 ); - pItem->fg.isCorrelated = (nRef!=0); + /* If the number of references to the outer context changed when + ** expressions in the sub-select were resolved, the sub-select + ** is correlated. It is not required to check the refcount on any + ** but the innermost outer context object, as lookupName() increments + ** the refcount on all contexts between the current one and the + ** context containing the column when it resolves a name. */ + if( pOuterNC ){ + assert( pItem->fg.isCorrelated==0 && pOuterNC->nRef>=nRef ); + pItem->fg.isCorrelated = (pOuterNC->nRef>nRef); + } } } From 8ddf686267c58ee0e519cfd9024f177e606be0ab Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 26 Feb 2021 20:14:32 +0000 Subject: [PATCH 242/257] Attempt to optimize "x IS NULL" and "x IS NOT NULL" expressions when x is a column with a NOT NULL constraint. FossilOrigin-Name: 5ecd842555009ce27ee6390325ac5c2504143474b12b730933f0833b3dad788a --- manifest | 20 ++++++---- manifest.uuid | 2 +- src/resolve.c | 38 +++++++++++++++++++ src/select.c | 3 ++ src/whereexpr.c | 5 +++ test/notnull2.test | 91 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 150 insertions(+), 9 deletions(-) create mode 100644 test/notnull2.test diff --git a/manifest b/manifest index 877ec2b56e..7e347fdfbe 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\ssimplification\sin\sresolve.c. -D 2021-02-26T15:20:17.903 +C Attempt\sto\soptimize\s"x\sIS\sNULL"\sand\s"x\sIS\sNOT\sNULL"\sexpressions\swhen\sx\sis\sa\scolumn\swith\sa\sNOT\sNULL\sconstraint. +D 2021-02-26T20:14:32.131 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -540,9 +540,9 @@ F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf F src/prepare.c f634a9e799a6b1c136d8ee12479cffa22862bfb807d307b1db406aa0cdb042a5 F src/printf.c 10e61ec79dd9d41fdc77afee4e0df04fbb427f309c043118fe0b26a7d7db488a F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c f3380c5570207e60cc23f2d34a8ac493a8e12f7cfeba0c89090497801dd22017 +F src/resolve.c 2272b62c9f20cd6628c1d19963c4f96e41297b50cdfeffdcc47fcfded6a607d7 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 5d66f394afb481eb812927283a3036f7ffbda48442e3a0517d1fa1c3248aca8c +F src/select.c 7cf048e52f678726dadc448c41fab40262f6da37eeb1d8ff0f14ef1b17feed9e F src/shell.c.in 844417f84df1f6c4fce1c815629a888cfdcf219e86513e9c332bbcc38832f477 F src/sqlite.h.in 8855a19f37ade8dad189a9e48233a2ebe1b46faf469c7eb0906a654e252dcc57 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -632,7 +632,7 @@ F src/walker.c d42d6c80ea363ef689a462e65eefcfe87deab924c50de5baa37ecb6af7d7ddaa F src/where.c a02138440d7230493b5e508664d629f3e1e7615737a5d83aac3a2955d3a654ff F src/whereInt.h 446e5e8018f83358ef917cf32d8e6a86dc8430113d0b17e720f1839d3faa44c4 F src/wherecode.c e57a8690311a75d06e723e8d379f9831de04aba300e07174d236e32a7f9c7a13 -F src/whereexpr.c 2dc51263e1fb8d8723e97a077a9a137ab0534e59e4cb88b3195f65edbe43cc32 +F src/whereexpr.c 5bbce43bc16b8e53cd670bbbb0a8583296b1d1517303abe94a770d9d792413a8 F src/window.c fdf01316f6cecf060378aa1713a29e527ab683823ba7d15b8978ec70165e8bdb F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -1224,6 +1224,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 a5fb3d643322e5471117c7c1d70e6f116134bca84378a4ea92d021cc6a989d0d F test/null.test b7ff206a1c60fe01aa2abd33ef9ea83c93727d993ca8a613de86e925c9f2bc6f F test/nulls1.test 82c5bc33148405f21205865abf13c786084438d573a4ac4e87e11b6091cde526 F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1 @@ -1907,7 +1908,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 062b338ff2ea71633b4fb3c75c6a47b5fc4fe9c2a72daacd987d1eca0bda5217 -R 07651de30eadccb5d0a1b765b39186be +P 310dac342e7b1f9b5a5df6a9d598e85d5fef59bba9307d9230baf77c8f2351a2 +R 5da9c9b015e5cf6e85f36d061ac9c73d +T *branch * ifnull-opt +T *sym-ifnull-opt * +T -sym-trunk * U dan -Z a8b3d49e868cbc0b6002cfdac6e7fd25 +Z 9cbe82fbe7c5328bb13207c38d4a331e diff --git a/manifest.uuid b/manifest.uuid index e486d4c319..795d6c15ad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -310dac342e7b1f9b5a5df6a9d598e85d5fef59bba9307d9230baf77c8f2351a2 \ No newline at end of file +5ecd842555009ce27ee6390325ac5c2504143474b12b730933f0833b3dad788a \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index 689f197031..203253c6e3 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -785,6 +785,44 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ break; } + /* An " IS NOT NULL" or " IS NULL". After resolving the + ** LHS, check if there is a NOT NULL constraint in the schema that + ** means the value of the expression can be determined immediately. + ** If that is the case, replace the current expression node with + ** a TK_TRUEFALSE node. + ** + ** If the node is replaced with a TK_TRUEFALSE node, then also restore + ** the NameContext ref-counts to the state they where in before the + ** LHS expression was resolved. This prevents the current select + ** from being erroneously marked as correlated in some cases. + */ + case TK_NOTNULL: + case TK_ISNULL: { + int anRef[8]; + NameContext *p; + int i; + for(i=0, p=pNC; p && ipNext, i++){ + anRef[i] = p->nRef; + } + sqlite3WalkExpr(pWalker, pExpr->pLeft); + if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) ){ + if( pExpr->op==TK_NOTNULL ){ + pExpr->u.zToken = "true"; + ExprSetProperty(pExpr, EP_IsTrue); + }else{ + pExpr->u.zToken = "false"; + ExprSetProperty(pExpr, EP_IsFalse); + } + pExpr->op = TK_TRUEFALSE; + for(i=0, p=pNC; p && ipNext, i++){ + p->nRef = anRef[i]; + } + sqlite3ExprDelete(pParse->db, pExpr->pLeft); + pExpr->pLeft = 0; + } + return WRC_Prune; + } + /* A column name: ID ** Or table name and column name: ID.ID ** Or a database, table and column: ID.ID.ID diff --git a/src/select.c b/src/select.c index b1a1ea507e..798df06e1a 100644 --- a/src/select.c +++ b/src/select.c @@ -407,6 +407,9 @@ static void unsetJoinExpr(Expr *p, int iTable){ && (iTable<0 || p->iRightJoinTable==iTable) ){ ExprClearProperty(p, EP_FromJoin); } + if( p->op==TK_COLUMN && p->iTable==iTable ){ + ExprClearProperty(p, EP_CanBeNull); + } if( p->op==TK_FUNCTION && p->x.pList ){ int i; for(i=0; ix.pList->nExpr; i++){ diff --git a/src/whereexpr.c b/src/whereexpr.c index 09ed7f6c37..f547db4f00 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1407,6 +1407,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) ){ + pExpr->op = TK_TRUEFALSE; + ExprSetProperty(pExpr, EP_IsFalse); + pTerm->prereqAll = 0; + pTerm->eOperator = 0; } } diff --git a/test/notnull2.test b/test/notnull2.test new file mode 100644 index 0000000000..a2fd63e343 --- /dev/null +++ b/test/notnull2.test @@ -0,0 +1,91 @@ +# 2021 February 15 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this file is testing optimizations associated with "IS NULL" +# and "IS NOT NULL" operators on columns with NOT NULL constraints. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix notnull2 + +do_execsql_test 1.0 { + CREATE TABLE t1(a, b); + CREATE TABLE t2(c, d NOT NULL); + + WITH x(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<1000 + ) + INSERT INTO t1 SELECT i, i FROM x; + INSERT INTO t2 SELECT * FROM t1; +} + +proc do_vmstep_test {tn sql nstep {res {}}} { + uplevel [list do_execsql_test $tn.0 $sql $res] + + set vmstep [db status vmstep] + if {[string range $nstep 0 0]=="+"} { + set body "if {$vmstep<$nstep} { + error \"got $vmstep, expected more than [string range $nstep 1 end]\" + }" + } else { + set body "if {$vmstep>$nstep} { + error \"got $vmstep, expected less than $nstep\" + }" + } + + # set name "$tn.vmstep=$vmstep,expect=$nstep" + set name "$tn.1" + uplevel [list do_test $name $body {}] +} + +do_vmstep_test 1.1.1 { + SELECT * FROM t1 LEFT JOIN t2 WHERE a=c AND d IS NULL; +} 100 {} +do_vmstep_test 1.1.2 { + SELECT * FROM t1 LEFT JOIN t2 WHERE a=c AND c IS NULL; +} +1000 {} + +do_vmstep_test 1.2.1 { + SELECT * FROM ( SELECT * FROM t2 ) WHERE d IS NULL +} 100 {} +do_vmstep_test 1.2.2 { + SELECT * FROM ( SELECT * FROM t2 ) WHERE c IS NULL +} +1000 {} + +do_vmstep_test 1.3.1 { + SELECT * FROM t2 WHERE d IS NULL +} 100 {} +do_vmstep_test 1.3.2 { + SELECT * FROM t2 WHERE c IS NULL +} +1000 {} + +do_vmstep_test 1.4.1 { + SELECT (d IS NOT NULL) FROM t2 WHERE 0==( d IS NOT NULL ) +} 100 {} +do_vmstep_test 1.4.2 { + SELECT * FROM t2 WHERE 0==( c IS NOT NULL ) +} +1000 {} + +do_vmstep_test 1.5.1 { + SELECT count(*) FROM t2 WHERE EXISTS( + SELECT t2.d IS NULL FROM t1 WHERE t1.a=450 + ) +} 10000 {1000} +do_vmstep_test 1.5.2 { + SELECT count(*) FROM t2 WHERE EXISTS( + SELECT t2.c IS NULL FROM t1 WHERE t1.a=450 + ) +} +100000 {1000} + + +finish_test + From 15de3ce9abaf4ebcc6c556faea743c976c7da8d1 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 26 Feb 2021 21:39:34 +0000 Subject: [PATCH 243/257] Fix a segfault that could occur when optimizing a NOT NULL constraint against an IPK column of a sub-query. FossilOrigin-Name: e4d1970ef17b2330f78c750d71d625c2997f79ed1445d0351ec32b482485a954 --- manifest | 15 +++++++-------- manifest.uuid | 2 +- src/whereexpr.c | 1 + test/notnull2.test | 10 ++++++++++ 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 8b95e294e4..0190c2d863 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Attempt\sto\soptimize\s"x\sIS\sNULL"\sand\s"x\sIS\sNOT\sNULL"\sexpressions\swhen\sx\sis\sa\scolumn\swith\sa\sNOT\sNULL\sconstraint. -D 2021-02-26T20:39:08.934 +C Fix\sa\ssegfault\sthat\scould\soccur\swhen\soptimizing\sa\sNOT\sNULL\sconstraint\sagainst\san\sIPK\scolumn\sof\sa\ssub-query. +D 2021-02-26T21:39:34.145 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -632,7 +632,7 @@ F src/walker.c d42d6c80ea363ef689a462e65eefcfe87deab924c50de5baa37ecb6af7d7ddaa F src/where.c a02138440d7230493b5e508664d629f3e1e7615737a5d83aac3a2955d3a654ff F src/whereInt.h 446e5e8018f83358ef917cf32d8e6a86dc8430113d0b17e720f1839d3faa44c4 F src/wherecode.c e57a8690311a75d06e723e8d379f9831de04aba300e07174d236e32a7f9c7a13 -F src/whereexpr.c 5bbce43bc16b8e53cd670bbbb0a8583296b1d1517303abe94a770d9d792413a8 +F src/whereexpr.c dbae38ffb500b5b8ba18d8d46666b2794efc5c5ff99e7a97fed07fec3b86c52a F src/window.c fdf01316f6cecf060378aa1713a29e527ab683823ba7d15b8978ec70165e8bdb F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -1224,7 +1224,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 a5fb3d643322e5471117c7c1d70e6f116134bca84378a4ea92d021cc6a989d0d +F test/notnull2.test 965a893619751255e59c911a8c58504b3174a3788b1458b7c7365b232209711b F test/null.test b7ff206a1c60fe01aa2abd33ef9ea83c93727d993ca8a613de86e925c9f2bc6f F test/nulls1.test 82c5bc33148405f21205865abf13c786084438d573a4ac4e87e11b6091cde526 F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1 @@ -1908,8 +1908,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 310dac342e7b1f9b5a5df6a9d598e85d5fef59bba9307d9230baf77c8f2351a2 5ecd842555009ce27ee6390325ac5c2504143474b12b730933f0833b3dad788a -R 5da9c9b015e5cf6e85f36d061ac9c73d -T +closed 5ecd842555009ce27ee6390325ac5c2504143474b12b730933f0833b3dad788a +P de9c86c9e4cdb34f4b7d65f160d1e589fb969bbf64c66d2b24c502d1ee424dbb +R de868ee79aa60e57e3171e3ba507ccd9 U dan -Z 563142b6d6e036f424233eef5aeb4af2 +Z 7175c7b1fd51dbcd25c6978dccae9f7d diff --git a/manifest.uuid b/manifest.uuid index b039706b46..3728002a22 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -de9c86c9e4cdb34f4b7d65f160d1e589fb969bbf64c66d2b24c502d1ee424dbb \ No newline at end of file +e4d1970ef17b2330f78c750d71d625c2997f79ed1445d0351ec32b482485a954 \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index f547db4f00..30bf2a333d 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1409,6 +1409,7 @@ static void exprAnalyze( pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask; }else if( op==TK_ISNULL && 0==sqlite3ExprCanBeNull(pLeft) ){ pExpr->op = TK_TRUEFALSE; + pExpr->u.zToken = "false"; ExprSetProperty(pExpr, EP_IsFalse); pTerm->prereqAll = 0; pTerm->eOperator = 0; diff --git a/test/notnull2.test b/test/notnull2.test index a2fd63e343..9ae190fe19 100644 --- a/test/notnull2.test +++ b/test/notnull2.test @@ -86,6 +86,16 @@ do_vmstep_test 1.5.2 { ) } +100000 {1000} +#------------------------------------------------------------------------- +reset_db +do_execsql_test 2.0 { + CREATE TABLE T1(a INTEGER PRIMARY KEY, b); + CREATE TABLE T3(k, v); +} + +do_execsql_test 2.1 { + SELECT * FROM (SELECT a, b FROM t1) LEFT JOIN t3 ON a IS NULL; +} finish_test From 676c869d523bb6a6bf56f4985eeadba27b033af8 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 27 Feb 2021 15:12:24 +0000 Subject: [PATCH 244/257] Remove a NEVER() that might sometimes be tree following an OOM. FossilOrigin-Name: ccb8cf5256d01b3ff13e75e1471b1afb0055ec2c344ba886f98b83d47eba00f8 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 0190c2d863..772eb1b389 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\ssegfault\sthat\scould\soccur\swhen\soptimizing\sa\sNOT\sNULL\sconstraint\sagainst\san\sIPK\scolumn\sof\sa\ssub-query. -D 2021-02-26T21:39:34.145 +C Remove\sa\sNEVER()\sthat\smight\ssometimes\sbe\stree\sfollowing\san\sOOM. +D 2021-02-27T15:12:24.523 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -629,7 +629,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 69e770e96fd56cc21608992bf2c6f1f3dc5cf2572d0495c6a643b06c3a679f14 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c d42d6c80ea363ef689a462e65eefcfe87deab924c50de5baa37ecb6af7d7ddaa -F src/where.c a02138440d7230493b5e508664d629f3e1e7615737a5d83aac3a2955d3a654ff +F src/where.c 10d06b16670a1d2a992d52a9f08e49426d38a08fb0a7ae5f7f62fd023d560e1e F src/whereInt.h 446e5e8018f83358ef917cf32d8e6a86dc8430113d0b17e720f1839d3faa44c4 F src/wherecode.c e57a8690311a75d06e723e8d379f9831de04aba300e07174d236e32a7f9c7a13 F src/whereexpr.c dbae38ffb500b5b8ba18d8d46666b2794efc5c5ff99e7a97fed07fec3b86c52a @@ -1908,7 +1908,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 de9c86c9e4cdb34f4b7d65f160d1e589fb969bbf64c66d2b24c502d1ee424dbb -R de868ee79aa60e57e3171e3ba507ccd9 -U dan -Z 7175c7b1fd51dbcd25c6978dccae9f7d +P e4d1970ef17b2330f78c750d71d625c2997f79ed1445d0351ec32b482485a954 +R 3f067e5dcddb5320f5bc837e2a5fba4f +U drh +Z 49f860ab9b6c770a11b39db8b01a8b49 diff --git a/manifest.uuid b/manifest.uuid index 3728002a22..44520a301f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e4d1970ef17b2330f78c750d71d625c2997f79ed1445d0351ec32b482485a954 \ No newline at end of file +ccb8cf5256d01b3ff13e75e1471b1afb0055ec2c344ba886f98b83d47eba00f8 \ No newline at end of file diff --git a/src/where.c b/src/where.c index d7aa812849..75b3ceff87 100644 --- a/src/where.c +++ b/src/where.c @@ -4991,7 +4991,7 @@ WhereInfo *sqlite3WhereBegin( if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){ pWInfo->revMask = ALLBITS; } - if( pParse->nErr || NEVER(db->mallocFailed) ){ + if( pParse->nErr || db->mallocFailed ){ goto whereBeginError; } #ifdef WHERETRACE_ENABLED From a3944bc4fe7cb12d542a3bf4b70799161961889b Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 27 Feb 2021 15:32:02 +0000 Subject: [PATCH 245/257] Add OOM test case associated with the fix in the previous commit. FossilOrigin-Name: a631c38d22bc00d38b0f112a623fb24c0e03a962f661ffe0931dad32fd31ba31 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/fuzzerfault.test | 19 +++++++++++++++++++ 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 772eb1b389..e54774aa37 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\sNEVER()\sthat\smight\ssometimes\sbe\stree\sfollowing\san\sOOM. -D 2021-02-27T15:12:24.523 +C Add\sOOM\stest\scase\sassociated\swith\sthe\sfix\sin\sthe\sprevious\scommit. +D 2021-02-27T15:32:02.041 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1055,7 +1055,7 @@ F test/fuzzdata7.db 0166b56fd7a6b9636a1d60ef0a060f86ddaecf99400a666bb6e5bbd7199a F test/fuzzdata8.db 977cb95f4a5d828056dea804a6de416debe3fa0182c77f47fe19a0554aaf4db0 F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 -F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 +F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc F test/gcfault.test dd28c228a38976d6336a3fc42d7e5f1ad060cb8c F test/gencol1.test b05e6c5edb9b10d48efb634ed07342441bddc89d225043e17095c36e567521a0 F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 @@ -1908,7 +1908,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 e4d1970ef17b2330f78c750d71d625c2997f79ed1445d0351ec32b482485a954 -R 3f067e5dcddb5320f5bc837e2a5fba4f -U drh -Z 49f860ab9b6c770a11b39db8b01a8b49 +P ccb8cf5256d01b3ff13e75e1471b1afb0055ec2c344ba886f98b83d47eba00f8 +R 2795f9db27433289f60f8c83de7cdc69 +U dan +Z fb78150b0343349ad1b18165979cb24b diff --git a/manifest.uuid b/manifest.uuid index 44520a301f..3eeef78b97 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ccb8cf5256d01b3ff13e75e1471b1afb0055ec2c344ba886f98b83d47eba00f8 \ No newline at end of file +a631c38d22bc00d38b0f112a623fb24c0e03a962f661ffe0931dad32fd31ba31 \ No newline at end of file diff --git a/test/fuzzerfault.test b/test/fuzzerfault.test index 6449612a66..e281cb592e 100644 --- a/test/fuzzerfault.test +++ b/test/fuzzerfault.test @@ -88,5 +88,24 @@ do_faultsim_test 3 -prep { faultsim_test_result {0 2} {1 {vtable constructor failed: x1}} } +#------------------------------------------------------------------------- +reset_db +do_execsql_test 4.0 { + CREATE TABLE t1_a(a INTEFDR PRIMARY KEY, b TEXT); + CREATE TABLE t3_a(k FnTEGER PRIMARY KEY, v TEXT); + CREATE TABLE t3_b(k INTEÀ5R PRIMARY KEY, v TEXT); + CREATE VIEW t3 AS SELECT * FROM t3_a UNION ALL SELECT * FROM t3_b; +} +faultsim_save_and_close + +do_faultsim_test 4 -faults oom-t* -prep { + faultsim_restore_and_reopen +} -body { + execsql { + SELECT 1 FROM t1_a LEFT JOIN t3 ON ((1+1) AND k=1) + } +} -test { + faultsim_test_result {0 {}} +} finish_test From 1e06c70eb073a92e683c55ffb8471301db999b75 Mon Sep 17 00:00:00 2001 From: dan Date: Sun, 28 Feb 2021 08:24:56 +0000 Subject: [PATCH 246/257] Initialize extra field in PgHdr1 to fix an msan complaint. FossilOrigin-Name: 4cb2ea5795b0c0678665fd89bd560209beaab8a756fe00335dbfd07493b0542d --- manifest | 15 +++++++++------ manifest.uuid | 2 +- src/pcache1.c | 1 + 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index e54774aa37..63c26791c5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sOOM\stest\scase\sassociated\swith\sthe\sfix\sin\sthe\sprevious\scommit. -D 2021-02-27T15:32:02.041 +C Initialize\sextra\sfield\sin\sPgHdr1\sto\sfix\san\smsan\scomplaint. +D 2021-02-28T08:24:56.477 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -534,7 +534,7 @@ F src/pager.h 4bf9b3213a4b2bebbced5eaa8b219cf25d4a82f385d093cd64b7e93e5285f66f F src/parse.y f3e8d7978c10495850c0bb502fe2669b55cf2841c4670b1f7261782e82069471 F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 -F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a +F src/pcache1.c 388304fd2d91c39591080b5e0f3c62cfba87db20370e7e0554062bfb29740e9f F src/pragma.c 6daaaecc26a4b09481d21722525b079ce756751a43a79cc1d8f122d686806193 F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf F src/prepare.c f634a9e799a6b1c136d8ee12479cffa22862bfb807d307b1db406aa0cdb042a5 @@ -1908,7 +1908,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 ccb8cf5256d01b3ff13e75e1471b1afb0055ec2c344ba886f98b83d47eba00f8 -R 2795f9db27433289f60f8c83de7cdc69 +P a631c38d22bc00d38b0f112a623fb24c0e03a962f661ffe0931dad32fd31ba31 +R 121b1b49c8dd85bf7799053762dcf3af +T *branch * msan-fix +T *sym-msan-fix * +T -sym-trunk * U dan -Z fb78150b0343349ad1b18165979cb24b +Z f5ed21d50100afccf53ab3ca05e5bd48 diff --git a/manifest.uuid b/manifest.uuid index 3eeef78b97..13e03c3a21 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a631c38d22bc00d38b0f112a623fb24c0e03a962f661ffe0931dad32fd31ba31 \ No newline at end of file +4cb2ea5795b0c0678665fd89bd560209beaab8a756fe00335dbfd07493b0542d \ No newline at end of file diff --git a/src/pcache1.c b/src/pcache1.c index ed762ebf70..3eae6b63cd 100644 --- a/src/pcache1.c +++ b/src/pcache1.c @@ -461,6 +461,7 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){ p->page.pExtra = &p[1]; p->isBulkLocal = 0; p->isAnchor = 0; + p->pLruPrev = 0; /* Initializing this saves a valgrind error */ } (*pCache->pnPurgeable)++; return p; From 1f9f5766954d250a00da59f7f7c1fc57d9032a6e Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 1 Mar 2021 16:15:41 +0000 Subject: [PATCH 247/257] Fix another msan complain triggered by a corrupt database. FossilOrigin-Name: d235d406283191fc7b9e1299be602f1e8be6f36cee8b183cf85c8660519a1c3b --- manifest | 15 ++++++--------- manifest.uuid | 2 +- src/btree.c | 12 ++++++------ 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 63c26791c5..cfc5020c1b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Initialize\sextra\sfield\sin\sPgHdr1\sto\sfix\san\smsan\scomplaint. -D 2021-02-28T08:24:56.477 +C Fix\sanother\smsan\scomplain\striggered\sby\sa\scorrupt\sdatabase. +D 2021-03-01T16:15:41.526 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -483,7 +483,7 @@ F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 694020ad8a3af3d79b09f74c8f1421272a419cdea42a13401e3b0f7dea6e9c3e +F src/btree.c bafa3a2e8b6622a3aa8791f90c8ecc70e8ae551ba9023f865213890f5b8a8994 F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 F src/build.c e1790f21cd19708af231ceed5e52f495b94c4b2609e27d2b5ce2805a9aa3464e @@ -1908,10 +1908,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 a631c38d22bc00d38b0f112a623fb24c0e03a962f661ffe0931dad32fd31ba31 -R 121b1b49c8dd85bf7799053762dcf3af -T *branch * msan-fix -T *sym-msan-fix * -T -sym-trunk * +P 4cb2ea5795b0c0678665fd89bd560209beaab8a756fe00335dbfd07493b0542d +R 77dd21d5cda99cecce763a4b3e142b99 U dan -Z f5ed21d50100afccf53ab3ca05e5bd48 +Z 6cd7a73f945651c0ccd62f6c92141ec4 diff --git a/manifest.uuid b/manifest.uuid index 13e03c3a21..e231634832 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4cb2ea5795b0c0678665fd89bd560209beaab8a756fe00335dbfd07493b0542d \ No newline at end of file +d235d406283191fc7b9e1299be602f1e8be6f36cee8b183cf85c8660519a1c3b \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index d0e51b82dc..709445b16c 100644 --- a/src/btree.c +++ b/src/btree.c @@ -7637,7 +7637,9 @@ static int balance_nonroot( } pgno = get4byte(pRight); while( 1 ){ - rc = getAndInitPage(pBt, pgno, &apOld[i], 0, 0); + if( rc==SQLITE_OK ){ + rc = getAndInitPage(pBt, pgno, &apOld[i], 0, 0); + } if( rc ){ memset(apOld, 0, (i+1)*sizeof(MemPage*)); goto balance_cleanup; @@ -7676,12 +7678,10 @@ static int balance_nonroot( if( pBt->btsFlags & BTS_FAST_SECURE ){ int iOff; + /* If the following if() condition is not true, the db is corrupted. + ** The call to dropCell() below will detect this. */ iOff = SQLITE_PTR_TO_INT(apDiv[i]) - SQLITE_PTR_TO_INT(pParent->aData); - if( (iOff+szNew[i])>(int)pBt->usableSize ){ - rc = SQLITE_CORRUPT_BKPT; - memset(apOld, 0, (i+1)*sizeof(MemPage*)); - goto balance_cleanup; - }else{ + if( (iOff+szNew[i])<=(int)pBt->usableSize ){ memcpy(&aOvflSpace[iOff], apDiv[i], szNew[i]); apDiv[i] = &aOvflSpace[apDiv[i]-pParent->aData]; } From 2d7a691fba336aa8e269ce22a176a42d9c11d1b7 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 1 Mar 2021 21:43:25 +0000 Subject: [PATCH 248/257] Add #ifndef macros so that the build works again with -DSQLITE_OMIT_AUTHORIZATION and -DSQLITE_OMIT_WINDOWFUNC. FossilOrigin-Name: 9400bdc60294be6a938025d481e50aad9af246e64f38fafecc6ca4f24112a98c --- manifest | 17 ++++++++--------- manifest.uuid | 2 +- src/resolve.c | 2 ++ src/whereexpr.c | 5 ++++- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 6ae5fc66f9..bd22d0acd5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scouple\sof\smemory-sanitizer\scomplaints\sthat\scould\sbe\striggered\sby\sa\scorrupt\sdatabase. -D 2021-03-01T16:16:59.534 +C Add\s#ifndef\smacros\sso\sthat\sthe\sbuild\sworks\sagain\swith\n-DSQLITE_OMIT_AUTHORIZATION\sand\s-DSQLITE_OMIT_WINDOWFUNC. +D 2021-03-01T21:43:25.638 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -540,7 +540,7 @@ F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf F src/prepare.c f634a9e799a6b1c136d8ee12479cffa22862bfb807d307b1db406aa0cdb042a5 F src/printf.c 10e61ec79dd9d41fdc77afee4e0df04fbb427f309c043118fe0b26a7d7db488a F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c 2272b62c9f20cd6628c1d19963c4f96e41297b50cdfeffdcc47fcfded6a607d7 +F src/resolve.c 14fa255fdd2bd789bd792584c54a51c8b7a9d7856e8016197dbcd3ba5795f9b0 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 7cf048e52f678726dadc448c41fab40262f6da37eeb1d8ff0f14ef1b17feed9e F src/shell.c.in 844417f84df1f6c4fce1c815629a888cfdcf219e86513e9c332bbcc38832f477 @@ -632,7 +632,7 @@ F src/walker.c d42d6c80ea363ef689a462e65eefcfe87deab924c50de5baa37ecb6af7d7ddaa F src/where.c 10d06b16670a1d2a992d52a9f08e49426d38a08fb0a7ae5f7f62fd023d560e1e F src/whereInt.h 446e5e8018f83358ef917cf32d8e6a86dc8430113d0b17e720f1839d3faa44c4 F src/wherecode.c e57a8690311a75d06e723e8d379f9831de04aba300e07174d236e32a7f9c7a13 -F src/whereexpr.c dbae38ffb500b5b8ba18d8d46666b2794efc5c5ff99e7a97fed07fec3b86c52a +F src/whereexpr.c 53452fe2fb07be2f4cb17f55cc721416fae0092c00717f106faf289c990b6494 F src/window.c fdf01316f6cecf060378aa1713a29e527ab683823ba7d15b8978ec70165e8bdb F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -1908,8 +1908,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 a631c38d22bc00d38b0f112a623fb24c0e03a962f661ffe0931dad32fd31ba31 d235d406283191fc7b9e1299be602f1e8be6f36cee8b183cf85c8660519a1c3b -R 77dd21d5cda99cecce763a4b3e142b99 -T +closed d235d406283191fc7b9e1299be602f1e8be6f36cee8b183cf85c8660519a1c3b -U dan -Z 89e7b2d8688a895f01f8719482567db5 +P 39c8686cabe6c437ba4860aade49a701c4f5772b97d9fbe6cb9a394e85b9c092 +R b47568c676eea2742077055be888bea4 +U drh +Z 8e481ddbeb4774accb5bf8d02313a8c0 diff --git a/manifest.uuid b/manifest.uuid index 0e552f71e0..283301f4da 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -39c8686cabe6c437ba4860aade49a701c4f5772b97d9fbe6cb9a394e85b9c092 \ No newline at end of file +9400bdc60294be6a938025d481e50aad9af246e64f38fafecc6ca4f24112a98c \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index 203253c6e3..ef2c0c624b 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -636,11 +636,13 @@ static int lookupName( lookupname_end: if( cnt==1 ){ assert( pNC!=0 ); +#ifndef SQLITE_OMIT_AUTHORIZATION if( pParse->db->xAuth && (pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER) ){ sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList); } +#endif /* Increment the nRef value on all name contexts from TopNC up to ** the point where the name matched. */ for(;;){ diff --git a/src/whereexpr.c b/src/whereexpr.c index 30bf2a333d..7b80c41393 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1210,7 +1210,10 @@ static void exprAnalyzeExists( assert( pExpr->op==TK_EXISTS ); assert( (pExpr->flags & EP_VarSelect) && (pExpr->flags & EP_xIsSelect) ); - if( (pSel->selFlags & SF_Aggregate) || pSel->pWin ) return; + if( pSel->selFlags & SF_Aggregate ) return; +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pSel->pWin ) return; +#endif if( pSel->pPrior ) return; if( pSel->pWhere==0 ) return; if( 0==exprAnalyzeExistsFindEq(pSel, 0, 0) ) return; From 1b1a1dda9e3b06d96b092ea9b30addd25e690a0a Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 2 Mar 2021 00:42:46 +0000 Subject: [PATCH 249/257] Add ALWAYS() to an always-true conditional. FossilOrigin-Name: fa3506db2051ceade8aa535d92c0900b3cfdd8850c6d00adedeb1ebfaf6f885f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/memjournal.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index bd22d0acd5..141474764a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\s#ifndef\smacros\sso\sthat\sthe\sbuild\sworks\sagain\swith\n-DSQLITE_OMIT_AUTHORIZATION\sand\s-DSQLITE_OMIT_WINDOWFUNC. -D 2021-03-01T21:43:25.638 +C Add\sALWAYS()\sto\san\salways-true\sconditional. +D 2021-03-02T00:42:46.267 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -514,7 +514,7 @@ F src/mem2.c b93b8762ab999a29ae7751532dadf0a1ac78040308a5fb1d17fcc365171d67eb F src/mem3.c 30301196cace2a085cbedee1326a49f4b26deff0af68774ca82c1f7c06fda4f6 F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944 F src/memdb.c ab0632d42407e866d2b616bd19d4211ac0ad1b430f04c4e187d60005b8700b98 -F src/memjournal.c bb0533253ad4a9657c29742d8504b6813c8367ccf135c0fb553d786850a55ea9 +F src/memjournal.c 431c70a111223a8a6e2e7e9f014afc6c88d818d357d866afc563195f2277d50e F src/msvc.h 3a15918220367a8876be3fa4f2abe423a861491e84b864fb2b7426bf022a28f8 F src/mutex.c 5e3409715552348732e97b9194abe92fdfcd934cfb681df4ba0ab87ac6c18d25 F src/mutex.h a7b2293c48db5f27007c3bdb21d438873637d12658f5a0bf8ad025bb96803c4a @@ -1908,7 +1908,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 39c8686cabe6c437ba4860aade49a701c4f5772b97d9fbe6cb9a394e85b9c092 -R b47568c676eea2742077055be888bea4 +P 9400bdc60294be6a938025d481e50aad9af246e64f38fafecc6ca4f24112a98c +R 30fcd2895fd27cf2f215c41505bcd0d3 U drh -Z 8e481ddbeb4774accb5bf8d02313a8c0 +Z d9cac18b67f324bd9d634b6271bbaffd diff --git a/manifest.uuid b/manifest.uuid index 283301f4da..72fd649f48 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9400bdc60294be6a938025d481e50aad9af246e64f38fafecc6ca4f24112a98c \ No newline at end of file +fa3506db2051ceade8aa535d92c0900b3cfdd8850c6d00adedeb1ebfaf6f885f \ No newline at end of file diff --git a/src/memjournal.c b/src/memjournal.c index 77cd6db7f3..660a842676 100644 --- a/src/memjournal.c +++ b/src/memjournal.c @@ -267,7 +267,7 @@ static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){ for(pIter=p->pFirst; ALWAYS(pIter) && iOff<=size; pIter=pIter->pNext){ iOff += p->nChunkSize; } - if( pIter ){ + if( ALWAYS(pIter) ){ memjrnlFreeChunks(pIter->pNext); pIter->pNext = 0; } From eefef9ae80c3943e83c0230143d19c93352c3c75 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 2 Mar 2021 13:36:37 +0000 Subject: [PATCH 250/257] Do not run test file windowpushd.test as part of the "no_optimization" permutation. FossilOrigin-Name: 275a75aa82bf5d2366fd4020066d7b9fbb93a955ac9ec15dc7d5b8bfa29074e4 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/permutations.test | 3 ++- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 141474764a..adb9e65d45 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sALWAYS()\sto\san\salways-true\sconditional. -D 2021-03-02T00:42:46.267 +C Do\snot\srun\stest\sfile\swindowpushd.test\sas\spart\sof\sthe\s"no_optimization"\spermutation. +D 2021-03-02T13:36:37.748 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1261,7 +1261,7 @@ F test/parser1.test 6ccdf5e459a5dc4673d3273dc311a7e9742ca952dd0551a6a6320d27035c F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff -F test/permutations.test 661a4325a5717957a77836910ee164ba26594a502d7a3df0e1ae7b9cba829c5d +F test/permutations.test e02c8a58efca31dfadbd2a0d168e26a542664d4ff31a3d819b80cd55f974c27c F test/pg_common.tcl 3b27542224db1e713ae387459b5d117c836a5f6e328846922993b6d2b7640d9f F test/pragma.test 50b91bedea9324d3ab48e793f908ee7d2c7dcf84bfa2281e792838be59641ec8 F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f @@ -1908,7 +1908,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 9400bdc60294be6a938025d481e50aad9af246e64f38fafecc6ca4f24112a98c -R 30fcd2895fd27cf2f215c41505bcd0d3 -U drh -Z d9cac18b67f324bd9d634b6271bbaffd +P fa3506db2051ceade8aa535d92c0900b3cfdd8850c6d00adedeb1ebfaf6f885f +R 515e2102d6e6554a000688d47356945f +U dan +Z 85ac7551d468e4b7e9a78a32f2d1b64b diff --git a/manifest.uuid b/manifest.uuid index 72fd649f48..4cf36418a4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fa3506db2051ceade8aa535d92c0900b3cfdd8850c6d00adedeb1ebfaf6f885f \ No newline at end of file +275a75aa82bf5d2366fd4020066d7b9fbb93a955ac9ec15dc7d5b8bfa29074e4 \ No newline at end of file diff --git a/test/permutations.test b/test/permutations.test index 4ea6cd2806..786e787b57 100644 --- a/test/permutations.test +++ b/test/permutations.test @@ -1062,7 +1062,8 @@ test_suite "no_optimization" -description { where6.test where7.test where8.test where9.test \ whereA.test whereB.test wherelimit.test \ select1.test select2.test select3.test select4.test select5.test \ - select7.test select8.test selectA.test selectC.test + select7.test select8.test selectA.test selectC.test \ + -exclude windowpushd.test ] -dbconfig { optimization_control $::dbhandle all 0 } From 730629680a76756cf9adc22e6b377c9937eda863 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 2 Mar 2021 13:50:56 +0000 Subject: [PATCH 251/257] Change the timeout for test case "valgrindfuzz" from 600 seconds to 1200. FossilOrigin-Name: 7c6aa6f38403931df7940c7acfeba4e2f8099a419222fcab2a3c959ccae90e40 --- Makefile.in | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Makefile.in b/Makefile.in index 875bba4c04..c1f82358ff 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1267,7 +1267,7 @@ fuzztest: fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuz ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db - valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M --timeout 600 $(FUZZDATA) + valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M --timeout 1200 $(FUZZDATA) valgrind ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db # The veryquick.test TCL tests. diff --git a/manifest b/manifest index adb9e65d45..d86f7e9f53 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Do\snot\srun\stest\sfile\swindowpushd.test\sas\spart\sof\sthe\s"no_optimization"\spermutation. -D 2021-03-02T13:36:37.748 +C Change\sthe\stimeout\sfor\stest\scase\s"valgrindfuzz"\sfrom\s600\sseconds\sto\s1200. +D 2021-03-02T13:50:56.639 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 9cae1bffe5cb811216bf7425395e7fc0594daa2ce31f625835a9d0c3fb25315f +F Makefile.in 4e7322b4992da471f6644b86f174ca92e7b782b84f1f0eafb7d8daff0067a8ee F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241 F Makefile.msc ad07bbd645132533e1fd7164a03acfa9afecda378b3787c10f62ab4c7c45e6ea F README.md 1514a365ffca3c138e00c5cc839906108a01011a6b082bad19b09781e3aa498a @@ -1908,7 +1908,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 fa3506db2051ceade8aa535d92c0900b3cfdd8850c6d00adedeb1ebfaf6f885f -R 515e2102d6e6554a000688d47356945f +P 275a75aa82bf5d2366fd4020066d7b9fbb93a955ac9ec15dc7d5b8bfa29074e4 +R c373869bc96fc586d3402291bf9340d0 U dan -Z 85ac7551d468e4b7e9a78a32f2d1b64b +Z 3b4e27f86c56b854caf42a3578645a4e diff --git a/manifest.uuid b/manifest.uuid index 4cf36418a4..e88c888324 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -275a75aa82bf5d2366fd4020066d7b9fbb93a955ac9ec15dc7d5b8bfa29074e4 \ No newline at end of file +7c6aa6f38403931df7940c7acfeba4e2f8099a419222fcab2a3c959ccae90e40 \ No newline at end of file From 898ec7927ae4d25083d5a034c5ce536cfbd0cb42 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 2 Mar 2021 16:27:04 +0000 Subject: [PATCH 252/257] Limit the size of the exponent input in the second argument to the ieee754() SQL function, to avoid integer overflow. Ticket [22dea1cfdb9151e4]. FossilOrigin-Name: 99aab32da14cc76beb5c1823a70bdeab144459398d61c42a858be4d6868d361e --- ext/misc/ieee754.c | 8 ++++++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/ext/misc/ieee754.c b/ext/misc/ieee754.c index 121eb43d66..6cdd79a4d4 100644 --- a/ext/misc/ieee754.c +++ b/ext/misc/ieee754.c @@ -167,6 +167,14 @@ static void ieee754func( int isNeg = 0; m = sqlite3_value_int64(argv[0]); e = sqlite3_value_int64(argv[1]); + + /* Limit the range of e. Ticket 22dea1cfdb9151e4 2021-03-02 */ + if( e>10000 ){ + e = 10000; + }else if( e<-10000 ){ + e = -10000; + } + if( m<0 ){ isNeg = 1; m = -m; diff --git a/manifest b/manifest index d86f7e9f53..d7cab31c96 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\stimeout\sfor\stest\scase\s"valgrindfuzz"\sfrom\s600\sseconds\sto\s1200. -D 2021-03-02T13:50:56.639 +C Limit\sthe\ssize\sof\sthe\sexponent\sinput\sin\sthe\ssecond\sargument\sto\sthe\nieee754()\sSQL\sfunction,\sto\savoid\sinteger\soverflow.\nTicket\s[22dea1cfdb9151e4]. +D 2021-03-02T16:27:04.746 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -304,7 +304,7 @@ F ext/misc/explain.c 0086fab288d4352ea638cf40ac382aad3b0dc5e845a1ea829a694c015fd F ext/misc/fileio.c 9b69e25da3b51d4a1d905a464ccb96709792ad627a742ba09215bc0d1447e7bd F ext/misc/fossildelta.c 1240b2d3e52eab1d50c160c7fe1902a9bd210e052dc209200a750bbf885402d5 F ext/misc/fuzzer.c eae560134f66333e9e1ca4c8ffea75df42056e2ce8456734565dbe1c2a92bf3d -F ext/misc/ieee754.c 5c7ca326361c7368f95f5743972eade3b8b24f60359ed7cba4706668a5682896 +F ext/misc/ieee754.c cd6ab89f85fda8a020559b3f4d03001a8a62dd856beda5af3f558621d12be913 F ext/misc/json1.c f31e89171f932d1821c91f10d2cb4979fc0447030030a8bce70420cd43d074c0 F ext/misc/memstat.c 3017a0832c645c0f8c773435620d663855f04690172316bd127270d1a7523d4d F ext/misc/memtrace.c 7c0d115d2ef716ad0ba632c91e05bd119cb16c1aedf3bec9f06196ead2d5537b @@ -1908,7 +1908,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 275a75aa82bf5d2366fd4020066d7b9fbb93a955ac9ec15dc7d5b8bfa29074e4 -R c373869bc96fc586d3402291bf9340d0 -U dan -Z 3b4e27f86c56b854caf42a3578645a4e +P 7c6aa6f38403931df7940c7acfeba4e2f8099a419222fcab2a3c959ccae90e40 +R 4b7008b2d896fb2345868e9330fd6fad +U drh +Z 8d007010cf38126393218aad44f4b7ca diff --git a/manifest.uuid b/manifest.uuid index e88c888324..cd003681d9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7c6aa6f38403931df7940c7acfeba4e2f8099a419222fcab2a3c959ccae90e40 \ No newline at end of file +99aab32da14cc76beb5c1823a70bdeab144459398d61c42a858be4d6868d361e \ No newline at end of file From bb05976dac48ab37a486dc4b839e6f85773d74e0 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 2 Mar 2021 21:07:41 +0000 Subject: [PATCH 253/257] Cast a string size variable to 64-bit to avoid any possibility of integer overflow. FossilOrigin-Name: a5940294b2ac8d157d7fa72f65ee70b713f7feb8a0a98d7f47e71acd1b6942b1 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/printf.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index d7cab31c96..92c99c9248 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Limit\sthe\ssize\sof\sthe\sexponent\sinput\sin\sthe\ssecond\sargument\sto\sthe\nieee754()\sSQL\sfunction,\sto\savoid\sinteger\soverflow.\nTicket\s[22dea1cfdb9151e4]. -D 2021-03-02T16:27:04.746 +C Cast\sa\sstring\ssize\svariable\sto\s64-bit\sto\savoid\sany\spossibility\sof\ninteger\soverflow. +D 2021-03-02T21:07:41.429 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -538,7 +538,7 @@ F src/pcache1.c 388304fd2d91c39591080b5e0f3c62cfba87db20370e7e0554062bfb29740e9f F src/pragma.c 6daaaecc26a4b09481d21722525b079ce756751a43a79cc1d8f122d686806193 F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf F src/prepare.c f634a9e799a6b1c136d8ee12479cffa22862bfb807d307b1db406aa0cdb042a5 -F src/printf.c 10e61ec79dd9d41fdc77afee4e0df04fbb427f309c043118fe0b26a7d7db488a +F src/printf.c 2b03a80d7c11bb422115dca175a18bf430e9c9dbaa0eee63b758f0c022f8f34f F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 14fa255fdd2bd789bd792584c54a51c8b7a9d7856e8016197dbcd3ba5795f9b0 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 @@ -1908,7 +1908,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 7c6aa6f38403931df7940c7acfeba4e2f8099a419222fcab2a3c959ccae90e40 -R 4b7008b2d896fb2345868e9330fd6fad +P 99aab32da14cc76beb5c1823a70bdeab144459398d61c42a858be4d6868d361e +R e29356ef3c8971c7f2ece96d7e581c9d U drh -Z 8d007010cf38126393218aad44f4b7ca +Z cc62deac5b0c740612d90bc9deff87dd diff --git a/manifest.uuid b/manifest.uuid index cd003681d9..6930961c73 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -99aab32da14cc76beb5c1823a70bdeab144459398d61c42a858be4d6868d361e \ No newline at end of file +a5940294b2ac8d157d7fa72f65ee70b713f7feb8a0a98d7f47e71acd1b6942b1 \ No newline at end of file diff --git a/src/printf.c b/src/printf.c index 476d13e789..9aab863ed2 100644 --- a/src/printf.c +++ b/src/printf.c @@ -921,7 +921,7 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){ }else{ char *zOld = isMalloced(p) ? p->zText : 0; i64 szNew = p->nChar; - szNew += N + 1; + szNew += (sqlite3_int64)N + 1; if( szNew+p->nChar<=p->mxAlloc ){ /* Force exponential buffer size growth as long as it does not overflow, ** to avoid having to call this routine too often */ From 3083d5f5eacc9adc7445894452364234daac61e6 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 3 Mar 2021 11:00:31 +0000 Subject: [PATCH 254/257] Fix a problem with using ALTER TABLE commands on database schemas that contain expressions of the form " NOT NULL" or " IS NULL" that can be evaluated at prepare time. FossilOrigin-Name: d2630ffafa077b8cfd75110b6b73da30f780edc920d2788769a4dc747f09d3f6 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/resolve.c | 2 +- test/altercol.test | 21 +++++++++++++++++++-- 4 files changed, 29 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 92c99c9248..c228301bca 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Cast\sa\sstring\ssize\svariable\sto\s64-bit\sto\savoid\sany\spossibility\sof\ninteger\soverflow. -D 2021-03-02T21:07:41.429 +C Fix\sa\sproblem\swith\susing\sALTER\sTABLE\scommands\son\sdatabase\sschemas\sthat\scontain\sexpressions\sof\sthe\sform\s"\sNOT\sNULL"\sor\s"\sIS\sNULL"\sthat\scan\sbe\sevaluated\sat\sprepare\stime. +D 2021-03-03T11:00:31.388 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -540,7 +540,7 @@ F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf F src/prepare.c f634a9e799a6b1c136d8ee12479cffa22862bfb807d307b1db406aa0cdb042a5 F src/printf.c 2b03a80d7c11bb422115dca175a18bf430e9c9dbaa0eee63b758f0c022f8f34f F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c 14fa255fdd2bd789bd792584c54a51c8b7a9d7856e8016197dbcd3ba5795f9b0 +F src/resolve.c 889469e6980181ce77ee8ab3fc84bd52ed6c1c3577fd102d52623d66cc65a3d0 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 7cf048e52f678726dadc448c41fab40262f6da37eeb1d8ff0f14ef1b17feed9e F src/shell.c.in 844417f84df1f6c4fce1c815629a888cfdcf219e86513e9c332bbcc38832f477 @@ -647,7 +647,7 @@ F test/alter3.test e487958dec7932453e0b83baf21d6b1e71d5e7d9a55bc20eadfa62a51ddff F test/alter4.test dfd6086faf461b27ca2d2999848dcd207edf23352fc1592d0005c0844f3f08cf F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959 F test/alterauth2.test 794ac5cef251819fe364b4fe20f12f86e9c5d68070513c7fd26c17cb244c89af -F test/altercol.test 1d6a6fe698b81e626baea4881f5717f9bc53d7d07f1cd23ee7ad1b931f117ddf +F test/altercol.test 65eef562f0eea7a1f5ddd4a140c4274c2bfc5712bb2ab2096f738852b0efce86 F test/altercorrupt.test 584d707a80e106952d6382790c8919bcf9f0db678ed3a1c09fd98b7f9d1d3a10 F test/alterdropcol.test baad37ff9b07078ea02dcc33dbfb82bde655f3eee5c453e218f69501c36f02ba F test/alterdropcol2.test 3948c805ca52f4621051b35968c18c09d107eb117e2b656c78cee3b2870650c0 @@ -1908,7 +1908,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 99aab32da14cc76beb5c1823a70bdeab144459398d61c42a858be4d6868d361e -R e29356ef3c8971c7f2ece96d7e581c9d -U drh -Z cc62deac5b0c740612d90bc9deff87dd +P a5940294b2ac8d157d7fa72f65ee70b713f7feb8a0a98d7f47e71acd1b6942b1 +R 7d64297e574a5c0c8d42ec3e32f9d9eb +U dan +Z eee2d7c12369536ff778406cd8f62fda diff --git a/manifest.uuid b/manifest.uuid index 6930961c73..137e1eb0a8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a5940294b2ac8d157d7fa72f65ee70b713f7feb8a0a98d7f47e71acd1b6942b1 \ No newline at end of file +d2630ffafa077b8cfd75110b6b73da30f780edc920d2788769a4dc747f09d3f6 \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index ef2c0c624b..6d3ed62f93 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -807,7 +807,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ anRef[i] = p->nRef; } sqlite3WalkExpr(pWalker, pExpr->pLeft); - if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) ){ + if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) && !IN_RENAME_OBJECT ){ if( pExpr->op==TK_NOTNULL ){ pExpr->u.zToken = "true"; ExprSetProperty(pExpr, EP_IsTrue); diff --git a/test/altercol.test b/test/altercol.test index 1479b3a7d3..d2406e4c96 100644 --- a/test/altercol.test +++ b/test/altercol.test @@ -13,8 +13,6 @@ # file format change that may be used in the future to implement # "ALTER TABLE ... RENAME COLUMN ... TO". # -# $Id: alter4.test,v 1.1 2009/02/02 18:03:22 drh Exp $ -# set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -804,6 +802,25 @@ do_execsql_test 20.110 { SELECT sql FROM sqlite_master WHERE name='t1'; } {{CREATE TABLE t1(xx UNIQUE,yy UNIQUE,zz UNIQUE,UNIQUE(xx),PRIMARY KEY(yy),UNIQUE(zz))}} +#------------------------------------------------------------------------- +reset_db +do_execsql_test 21.0 { + CREATE TABLE t1(a, b, c NOT NULL); + CREATE TRIGGER tr1 AFTER INSERT ON t1 WHEN new.c IS NOT NULL BEGIN + SELECT c NOT NULL FROM t1; + END; +} + +do_execsql_test 21.1 { + ALTER TABLE t1 RENAME c TO d; +} + +do_execsql_test 21.2 { + SELECT sql FROM sqlite_schema WHERE name IS 'tr1' +} {{CREATE TRIGGER tr1 AFTER INSERT ON t1 WHEN new.d IS NOT NULL BEGIN + SELECT d NOT NULL FROM t1; + END} +} finish_test From fad1ad0526da6f0e90ce044ebf0f4c7e1d1a5aa9 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 3 Mar 2021 14:07:52 +0000 Subject: [PATCH 255/257] Fix a harmless assertion fault resulting from [6e6b3729e0549de0] that was discovered by dbsqlfuzz. Enhance .selecttrace output to show omitted ORDER BY clauses. New dbsqlfuzz test cases added. FossilOrigin-Name: 27a0388ad616f80e8dcc986c247a5c23a8565dae9081b04ff85bac0d357e531b --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/select.c | 14 ++++++++++++-- test/fuzzdata8.db | Bin 1626112 -> 1646592 bytes 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index c228301bca..2ca68c655b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\susing\sALTER\sTABLE\scommands\son\sdatabase\sschemas\sthat\scontain\sexpressions\sof\sthe\sform\s"\sNOT\sNULL"\sor\s"\sIS\sNULL"\sthat\scan\sbe\sevaluated\sat\sprepare\stime. -D 2021-03-03T11:00:31.388 +C Fix\sa\sharmless\sassertion\sfault\sresulting\sfrom\s[6e6b3729e0549de0]\sthat\swas\ndiscovered\sby\sdbsqlfuzz.\s\sEnhance\s.selecttrace\soutput\sto\sshow\somitted\nORDER\sBY\sclauses.\s\sNew\sdbsqlfuzz\stest\scases\sadded. +D 2021-03-03T14:07:52.842 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -542,7 +542,7 @@ F src/printf.c 2b03a80d7c11bb422115dca175a18bf430e9c9dbaa0eee63b758f0c022f8f34f F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 889469e6980181ce77ee8ab3fc84bd52ed6c1c3577fd102d52623d66cc65a3d0 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 7cf048e52f678726dadc448c41fab40262f6da37eeb1d8ff0f14ef1b17feed9e +F src/select.c 0e242e141cc1b28f16b8973454aeeabd4367377f05507e3961044ae3035d80cd F src/shell.c.in 844417f84df1f6c4fce1c815629a888cfdcf219e86513e9c332bbcc38832f477 F src/sqlite.h.in 8855a19f37ade8dad189a9e48233a2ebe1b46faf469c7eb0906a654e252dcc57 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1052,7 +1052,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 977cb95f4a5d828056dea804a6de416debe3fa0182c77f47fe19a0554aaf4db0 +F test/fuzzdata8.db c8325de6fbdd24d030cd3a01384a2ff325dda5d5e3ff5d531a26ada3d9d7e010 F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc @@ -1908,7 +1908,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 a5940294b2ac8d157d7fa72f65ee70b713f7feb8a0a98d7f47e71acd1b6942b1 -R 7d64297e574a5c0c8d42ec3e32f9d9eb -U dan -Z eee2d7c12369536ff778406cd8f62fda +P d2630ffafa077b8cfd75110b6b73da30f780edc920d2788769a4dc747f09d3f6 +R 6fc5bf1132cdf5c151148fe503404c74 +U drh +Z a92fbd9560cb903dfca1138c12b65d20 diff --git a/manifest.uuid b/manifest.uuid index 137e1eb0a8..f9c8948b2f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d2630ffafa077b8cfd75110b6b73da30f780edc920d2788769a4dc747f09d3f6 \ No newline at end of file +27a0388ad616f80e8dcc986c247a5c23a8565dae9081b04ff85bac0d357e531b \ No newline at end of file diff --git a/src/select.c b/src/select.c index 798df06e1a..53c83c9a33 100644 --- a/src/select.c +++ b/src/select.c @@ -6034,8 +6034,18 @@ int sqlite3Select( pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard || pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_DistFifo ); /* All of these destinations are also able to ignore the ORDER BY clause */ - sqlite3ExprListDelete(db, p->pOrderBy); - p->pOrderBy = 0; + if( p->pOrderBy ){ +#if SELECTTRACE_ENABLED + SELECTTRACE(1,pParse,p, ("dropping superfluous ORDER BY:\n")); + if( sqlite3SelectTrace & 0x100 ){ + sqlite3TreeViewExprList(0, p->pOrderBy, 0, "ORDERBY"); + } +#endif + sqlite3ParserAddCleanup(pParse, + (void(*)(sqlite3*,void*))sqlite3ExprListDelete, + p->pOrderBy); + p->pOrderBy = 0; + } p->selFlags &= ~SF_Distinct; p->selFlags |= SF_NoopOrderBy; } diff --git a/test/fuzzdata8.db b/test/fuzzdata8.db index eb5b897ec024c77226996266cbe6719a1ef173e5..a5e90841924e632ab55ced944e768cf6c7185191 100644 GIT binary patch delta 35430 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

@w!TZ~yGa>t z0iupbR>cw5-p`31>@6N=a$cy=3G`LCfe`Quai-C~(e7tTR*9WtS*&OweM|Td6e7eZ zMa<=miEdXTANMJbl~xZiK`!0P<7j&iG2OPM$7JLhUP%YzMIUBs%h{p)1zLZb7{J(Z zs_iH;Vc#DTljWHWybFa!iQa~OyR$)+?HIMES|53^(h8GdJMeqA6tNAckc$vHvZew0{JdKr}&;C0<^8+gK1K{n4z&#a!07ZNur~8$*ltc zb>Ojj;l?Q8{%3_Vcn2z=UX%Gv-B&REB<}lCLKOjb{1eLB(yH#_L8RfO@IM`z$J@(( zNBKCyM7`)nqPntSVw8U7sGT+Tl4DXTO?+!)npjJeB&5 z6y!ot&#XR%DdUD46KQ^q5FTd-WJ6U>sT4XrQ3NzrTQW(c>j};VbDxnrhUm#OZIUDM6|-6#ZKn$?S{G=@dty1G{jZ9SnmjsNv<8$dHx)@Fe}j68TP4_iXfZR5eS}1nHSw%yt@QbXN={0Emi(-JrE+J0iOodl) zeAp0LvQWHZm(MwmlkX5ckzObjLFT!Ko*Jo^lq5Tt>!L zamlF}#>!$Ztl-1m!3yYZ%G6b&P?mmzs@$t*;CV>39HgQ?@grUwdcqy|$$aU}F9w!R zt`7oM_RwmvOvxKMxW&6s5&b{S0J`mZ2``5|xk~0JH5m;LRs7Ri%w*SM@pnb`KmxJL z&`(1;ut~&2#y_!e%KAto8G0vJOM=hbkMjlINy`h5Zp%5?sa5&>FD<(hj5A*F+e*k%#M4Lh+_6-4`)Wg1r8(Av7ra*SiTB9-5ZdRSy{6)MafSv31z1Zqf1&xaP7c*A} zWF;1xJm!qyL7)cb^|$p%Mqd>1?!Xo!n0)meizFqB(V7vm`H~nNqG|{&8;_^sWU1Sl z>$!DaZV;!0rH|oKyd3GV65ZCELBYG64Hl>cD1oXyRx3^CApI6{hFGYJ)|8w9^|u+t z&vB-(KY_tjEZ4#m!?(%YaQ~&vk(R@Oa-j8*I2BWEOHnaajm9D_w(U zcBIIB|6GU6c+UBxYA{OX#`^cj>^A{g8k2%*r+U1Foka?*OSUo{AxOz*#B@qZz+0Tj z#i`q4RIR)#Zk9%IJuFPH*zy)Zy#L+P8l|@?iV1d;8NICajiT{TYrG1HmqLq+IyaHW zd$^*g+dbBfO1$aZ-PBleVlma7t-sA%*oPYCuwY-x1jj~dICkFkFA;a;mi*E4Wi#!a_f02luUsE5t1 delta 23958 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 Date: Wed, 3 Mar 2021 16:00:26 +0000 Subject: [PATCH 256/257] Fix a case where fts3 was erroneously reporting corruption. FossilOrigin-Name: e6c7683c7503ac743d1d476c60c31f887b7ad829e26e812c25acdd4366044db8 --- ext/fts3/fts3_write.c | 37 ++++++++++++++++++------------------- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 26 insertions(+), 27 deletions(-) diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c index f7ab6432b6..bc42fc3d63 100644 --- a/ext/fts3/fts3_write.c +++ b/ext/fts3/fts3_write.c @@ -4335,27 +4335,26 @@ static int fts3IncrmergeLoad( while( reader.aNode && rc==SQLITE_OK ) rc = nodeReaderNext(&reader); blobGrowBuffer(&pNode->key, reader.term.n, &rc); if( rc==SQLITE_OK ){ - if( reader.term.n<=0 ){ - rc = FTS_CORRUPT_VTAB; - }else{ + assert_fts3_nc( reader.term.n>0 || reader.aNode==0 ); + if( reader.term.n>0 ){ memcpy(pNode->key.a, reader.term.a, reader.term.n); - pNode->key.n = reader.term.n; - if( i>0 ){ - char *aBlock = 0; - int nBlock = 0; - pNode = &pWriter->aNodeWriter[i-1]; - pNode->iBlock = reader.iChild; - rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock,0); - blobGrowBuffer(&pNode->block, - MAX(nBlock, p->nNodeSize)+FTS3_NODE_PADDING, &rc - ); - if( rc==SQLITE_OK ){ - memcpy(pNode->block.a, aBlock, nBlock); - pNode->block.n = nBlock; - memset(&pNode->block.a[nBlock], 0, FTS3_NODE_PADDING); - } - sqlite3_free(aBlock); + } + pNode->key.n = reader.term.n; + if( i>0 ){ + char *aBlock = 0; + int nBlock = 0; + pNode = &pWriter->aNodeWriter[i-1]; + pNode->iBlock = reader.iChild; + rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock,0); + blobGrowBuffer(&pNode->block, + MAX(nBlock, p->nNodeSize)+FTS3_NODE_PADDING, &rc + ); + if( rc==SQLITE_OK ){ + memcpy(pNode->block.a, aBlock, nBlock); + pNode->block.n = nBlock; + memset(&pNode->block.a[nBlock], 0, FTS3_NODE_PADDING); } + sqlite3_free(aBlock); } } } diff --git a/manifest b/manifest index 2ca68c655b..8079f23279 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sharmless\sassertion\sfault\sresulting\sfrom\s[6e6b3729e0549de0]\sthat\swas\ndiscovered\sby\sdbsqlfuzz.\s\sEnhance\s.selecttrace\soutput\sto\sshow\somitted\nORDER\sBY\sclauses.\s\sNew\sdbsqlfuzz\stest\scases\sadded. -D 2021-03-03T14:07:52.842 +C Fix\sa\scase\swhere\sfts3\swas\serroneously\sreporting\scorruption. +D 2021-03-03T16:00:26.353 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -102,7 +102,7 @@ F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3 F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004 F ext/fts3/fts3_unicode.c 4b9af6151c29b35ed09574937083cece7c31e911f69615e168a39677569b684d F ext/fts3/fts3_unicode2.c 416eb7e1e81142703520d284b768ca2751d40e31fa912cae24ba74860532bf0f -F ext/fts3/fts3_write.c 3b5df74d6563df46f90103a84630613a9fdb782ed93161470df2186e8e906d8c +F ext/fts3/fts3_write.c a5159accfd88f85fd3fc2298286d7a9427a02d1ea9a52b7c79730cff7a0bc03f F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100 F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73 @@ -1908,7 +1908,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 d2630ffafa077b8cfd75110b6b73da30f780edc920d2788769a4dc747f09d3f6 -R 6fc5bf1132cdf5c151148fe503404c74 -U drh -Z a92fbd9560cb903dfca1138c12b65d20 +P 27a0388ad616f80e8dcc986c247a5c23a8565dae9081b04ff85bac0d357e531b +R e5c0eb34647a6c0313ec053d90365f5c +U dan +Z fd9193ef1dccf35779afbe7b97c23e4c diff --git a/manifest.uuid b/manifest.uuid index f9c8948b2f..6b634494d1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -27a0388ad616f80e8dcc986c247a5c23a8565dae9081b04ff85bac0d357e531b \ No newline at end of file +e6c7683c7503ac743d1d476c60c31f887b7ad829e26e812c25acdd4366044db8 \ No newline at end of file From 0bff34aea3243773ea723f4d8c88559d4f7e7893 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 3 Mar 2021 16:46:03 +0000 Subject: [PATCH 257/257] Remove the --timeout option from the valgrindfuzz Makefile target. FossilOrigin-Name: 3f520b8bdef7dcdad30e052ed8a07b0493bff4497603521e701fab7324df2995 --- Makefile.in | 2 +- main.mk | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Makefile.in b/Makefile.in index c1f82358ff..9bc19e658c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1267,7 +1267,7 @@ fuzztest: fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuz ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db - valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M --timeout 1200 $(FUZZDATA) + valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M $(FUZZDATA) valgrind ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db # The veryquick.test TCL tests. diff --git a/main.mk b/main.mk index dfaf7db15e..813a815deb 100644 --- a/main.mk +++ b/main.mk @@ -954,7 +954,7 @@ fuzztest: fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz- ./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db valgrindfuzz: fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz-data1.db - valgrind ./fuzzcheck$(EXE) --cell-size-check --limit-mem 10M --timeout 600 $(FUZZDATA) + valgrind ./fuzzcheck$(EXE) --cell-size-check --limit-mem 10M $(FUZZDATA) valgrind ./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db # The veryquick.test TCL tests. diff --git a/manifest b/manifest index 8079f23279..b0cebf17ce 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Fix\sa\scase\swhere\sfts3\swas\serroneously\sreporting\scorruption. -D 2021-03-03T16:00:26.353 +C Remove\sthe\s--timeout\soption\sfrom\sthe\svalgrindfuzz\sMakefile\starget. +D 2021-03-03T16:46:03.440 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 4e7322b4992da471f6644b86f174ca92e7b782b84f1f0eafb7d8daff0067a8ee +F Makefile.in 047036a560b7db51e7b7e459cd12cbe80e10ca5420b0ea5ddda023b44ab46466 F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241 F Makefile.msc ad07bbd645132533e1fd7164a03acfa9afecda378b3787c10f62ab4c7c45e6ea F README.md 1514a365ffca3c138e00c5cc839906108a01011a6b082bad19b09781e3aa498a @@ -464,7 +464,7 @@ F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 443a4ec1ca89ad267cbde45dadc68861154b99c7bd26e7b7dc74303a664002b8 +F main.mk 32765eed1aa69739a876b7e1632a092188106f99e8ad6c9d30ea982f4f9b3a46 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -1908,7 +1908,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 27a0388ad616f80e8dcc986c247a5c23a8565dae9081b04ff85bac0d357e531b -R e5c0eb34647a6c0313ec053d90365f5c +P e6c7683c7503ac743d1d476c60c31f887b7ad829e26e812c25acdd4366044db8 +R e77cda0b369ceea50b416b8516f743d1 U dan -Z fd9193ef1dccf35779afbe7b97c23e4c +Z 0efa4696a72192981e7924beabc49254 diff --git a/manifest.uuid b/manifest.uuid index 6b634494d1..119f632193 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e6c7683c7503ac743d1d476c60c31f887b7ad829e26e812c25acdd4366044db8 \ No newline at end of file +3f520b8bdef7dcdad30e052ed8a07b0493bff4497603521e701fab7324df2995 \ No newline at end of file