From 84b168ffa7b04a7d5fca80c0e98f7022673af119 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 15 Dec 2020 13:55:38 +0000 Subject: [PATCH 001/199] 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 002/199] 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 003/199] 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 004/199] 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 005/199] 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 006/199] 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 007/199] 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 008/199] 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 009/199] 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 010/199] 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 011/199] 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 012/199] 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 013/199] 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 014/199] 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 015/199] 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 016/199] 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 017/199] 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 018/199] 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 019/199] 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 020/199] 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 021/199] 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 022/199] 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 023/199] 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 024/199] 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 025/199] 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 026/199] 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 027/199] 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 028/199] 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 029/199] 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 030/199] 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 031/199] 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 032/199] 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 033/199] 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 034/199] 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 035/199] 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 036/199] 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 037/199] 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 038/199] 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 039/199] 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 040/199] 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 041/199] 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 042/199] 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 043/199] 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 044/199] 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 045/199] 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 046/199] 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 047/199] 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 048/199] 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 049/199] 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 050/199] 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 051/199] 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 052/199] 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 053/199] 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 054/199] 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 055/199] 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 056/199] 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 057/199] 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 058/199] 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 059/199] 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 060/199] 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 061/199] 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 062/199] 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 063/199] 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 064/199] 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 065/199] 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 066/199] 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 067/199] 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 068/199] 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 069/199] 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 070/199] 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 071/199] 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 072/199] 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 073/199] 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 074/199] 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 075/199] 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 076/199] 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 077/199] 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 078/199] 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 079/199] 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 080/199] 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 081/199] 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 082/199] 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 083/199] 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 084/199] 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 085/199] 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 086/199] 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 087/199] 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 088/199] 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 089/199] 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 090/199] 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 091/199] 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 092/199] 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 093/199] 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 094/199] 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 095/199] 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 096/199] 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 097/199] 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 098/199] 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 099/199] 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 100/199] 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 101/199] 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 zcmeFZd3+T`(?5E8mUCv#I%f}C7S;fPAd<5ZEA2crS^WOX3-{<%H+9$q0S1HESno$=reE(%KUBRpl}ztx zFbKcsJ*ceKAEWXM{ZT5<>fNY3tv^EL3B4>RIb+BQkk!}p>m}jN9BupYbu}1)LYSyg?fO>xq1sKXXwqToTxXYa-80T z%AtB=Dxc6BQrTZ8MueVv1eK5K;Z%0j!>H__hf>*AuS;cXy*8Ci^jcJg>wYRjbuX3m zbQ%r8th)^c_N#8EvPw^|(vJ(eh00HLmC7@^LgfkFMCC`iNacsRK;;KIqw;;7#K;b3 zQt{qGDoQhUrCF+p#fZCz?*ORd6EtGLuEEw#!eR-;s<2<&x(;A5}vb|$T5#$_=X zk|77m2Fo2FM>Wad_}qqhbVH9c8Kmectvo&97}!;OjD9UC1f(IUs7VNr9rb zJsPa2W3xG8cI2|7Na<(O=}3e zV2gn1D=cbeYRtGX0p9PpK+JghZG0+S?dWPlS1etv=!yx%j57}l(32wq<747t+QkG~ zkD=;RUO6siL~QEcs^iT;o`^%bKfV>+Z}-Q2UJ*+bZ68*cGwJU(^mm&-9tgG@#~*7) z)p38Tj^)*ejq^3{|)0)%*`mQmeqYAf@rVMP506{0QRb4|x+;<49_;{D*m1 zD=J3>;)u^!F2h!B+frlvY8BTy=J)@BRxzyutpny3Enw$wYDi>ire%->`wvBHW z-m_nLWQ#GgX3Q8jZRV)4sWZn#wTO*s(K;#+6$!h3Q~hoKczX2z&7*Nqt>U71b4{E6 z@f&RaO|9MNfAaFfe%k#{9{msfG=-eI{kemhvHJjlx0HWFJe=syqu^TB*Qk- zUtUcarbOdGrzufjNAf+UJef&`!B-@SPSR^%#z7Y${;vcz&d*hisAzD<9`?4(4Q9xL2rH)>k)5hTO0} ztDz{;Bq^(h>at`gj<2a#9IeNXr#DV6o~%p6^pJ;lVtzI@#X8MQHyAqw({p@YtQBSY zMr5Z^iZQvIvO-dOvZj&WMYA!{lq#^ZD0MSE5ZNav_256xq14BesLHBjIG)U383x3l zf;$G81_HOKZ3*#1oi9uQ?#(Vf-&{B2$&sd3%y^#u{;UnK z`W7!HjaLE;d#9TA3G5QSTWabi!s(Yx`y_hib9ncNNr&T`l@+k-S=Is*CYcTk;^mmp z;K*ZsC;(GR$r;x@RzV-N?c6({_9oL) zyz(kkC%NOHbdxCoD(9J8SbonGBSO(YcOt)i4GIsq+)zHqEkQwOh!N`Ta$U!FFPOSf zJKId*aQjWuYX0DLND!4tP_@mZ!G_08Hu(IaDHKyaH#r$5>@Yn>>R@1BfWF-1h7^}# zh1YhOhGNEI(^3=r3W{F~Nhj7c1v`IfnkL}4D@-AbeT@fin7WFPvXmuq5zOUn+`x>9 zrbQxbm|{{P2TV`1n;6l;U7MkH&2@`G&V4NmD!+1l${+p)^qEp^47a%}1-!rBBs2Cc zvZ2<_4DbEhbe?fB++?@#;62_CG2IQq>$uI3*2QIl^7E!~ypiwr9#rV=13`I{^XF#Y zL-|Eh^FNt8EU?>f>StRmtXE|6sYWXe{@Wce{hH|o1~IRMtl*>nCLjGT>G~m9g;X_- zY{9_(1&L!!4Pg7%rh$;K($o`Ht~8}XX- z(QtpGsV;bNQy!D6iH3WS>M;2^b2mix8x)WECqHo_yB{1-qygnRo^P7XiGKj8&$AI2 zKGn2=OGPkX!dX}8?;8Bs9aAJ@poiKUW7>zV9HC^RsWz)2*TG*9;LvQ+I3j$42sxWg zf&8teNBNC^jw{l*l7|1Gy-$`%iYPG|a@V;ULg{`Jbx~g-mz4HO$S4}VEJ22}7fmvr zH7n7K8KG=T$Q!uBsyrbw6GZrxD|w|QGTzXXIwDgby_a!fel52JXM2c=Ek_-hAcajI3&pl2z&?A)gvMsN>u3>3}QqELMQ9GUFP&td=A49sv2UoB{;S#MG zq>VH+gvzxcp_tZC$+IvAc|GNUi8)bf$A7x9#WY$S!O3CfXpBo#P6^C|Wv#>x49n*@ zmM}<(wE6RU33>2fo+AY2IbG3Ewa?L;cj1NH`HnDb&_k&dnGaGk?9KCa=_IBkxf(F6 z%9b<+Rfh!)3bO1?p{R@01B&`9kCWS)?hWab-`nBAK}pI^k%d6T6nh;E8>oCCvRY8_ zt<4KlS31=Ee#Rb<6lpYK+F&J5WVKNmu8<$DLtevHAId`=*CFa>+cTJ%sw@^*UC8Yx zQ!`@~vP2KJ#I{_rgMm*0pp{WOG|R;jvk6K(L{BH-xk}QME{u6GAzis*B+A0)C^zJY zqv&( z!#HPCpy-IQj4LATxrBHKOj2h+`4plx=eY6)_P(IdOxGSGzE?&wSYE1hhLxukBfj~$ zGRG)|N`}J_k#46sDOQ~d`@U3K^OicU8>81l+n0Pu_*SM9qz^DRh0aHnt`PI1x*f{h zsslT`uaq&++N)2)$ZwS`tTUYYNNEKf4=4lkiY6E_=a%xc$hts97jrbM+^nvI<)5lg z!1OZ32bHzeI@q&XdD}=+j*en8*p=wku=6iUh9ZYahV8SUFjoBzcQAE;AoDF(H%t#z z$du?huiuw#5#L`l>32ONM=IkzTSh99d6wGtLO#z4d^y^R$w>lB2d| zIN7USHOdi^VdtPfpDh$*zVYh~>29?iMue-^MAiq28>o#@^Qq4<%;}`oCx3ohsSnyS z>RnKpt9EXaeZgsTH-X#NtVxjbmM@tKu`{H+?Hi8co2u&s)(_Zk{#r1qwK^DQMX5~` z(&u%tYAI8awi)&MlHpv?^&mtAZ*^9a zWj2uPmo&0;pz0%<=Bj0Ad{q67u|be~NC{wE4>d)R8%l-)@tni`?2p!>^DLKNhnO%m zn@i?#x(37Lua!_35%Igm@HQV287<}V)M$u4q*T=CVo!{IS?xy(^!E{LJxpyW%Z(+& z50CNj+RyE7*t(v2BgycN|L@%&G}e=(K{d(+fLn2@7}i?H%ZwN-v2bxFwrm8PLFs2x%73n(m78DnE1eTur0Xj0!0 zu;a7pGLzgyGVB?~IcOamm(fJ{1T0*y@~LW(S`OtVb5ktxsuD4gr$)+hQ^|0pIXB2L zw6_%|y}Uq=qy;@V$7uU4q2uN!}SEY$f}y}{<>6;AL%Qb%<;R(_#s0+yUpSITk= z$xxEY2cU#;t(y1hL_JC}V9;!XO5K(#)H8I=M>bBK{yT$63{D72ZUJ1mrF4SwW9kOp z@G6TOpn3giuBWqki%ZuG(_cFJC>Kc{}R~wn1%uD*h1dH#fwQ<2c^;r{J zoL6vm4X&5W<3zRu3a6-}fJQYAPTZ00(DFMa8Sf}&tA#BC7N)+68$9N>6seVDc(Z0+ zYk}`KHMbG+vMx)U`Df{R0m{mWL3((ESklluNS0gE8;M*Ir}C%c1^Ib;Yz3s2h!K$R zp^}PAqs*C#97hvKGM}*r!pJ!DIyonArXE|;#{7WE%jtz&&4BGK5I{ioNhgh-P6r|O>#TQ z@LL!sC;>m6V~!N%SBRjEP{D*Kj9FklrLy>~50=p4ypZa*KyCyru|k%a536!}$?$p{ z6kf1&#riLqKWFl0dg65qd~W%b;r*A*vcTSeT~}#4T5GkLcE@kRt}iV~IB>0bm&mr^ zuA3H_p;~DERbbnpXoMvN$8I)n5ZMm6nrcbJ?ys9~o8%6X;r=k*NisfPWS%9;Td9*G z&_@g5(07=;3zEhNW+*UOhC}9iesT>r%*%rwq!tk~U+&*k}Vpf%TX7GjG;2bE2LHRv%9tqOy!xN?Ewj$eu#mRDi0Z#v5{xnz* z2_Kjbv%OgLommrjYxN*!pd44z+H*m>ECKew{Gg_@p*ZoR`J9P$!Y-efTMFiVrIYoJ zw3^eO4DtrYJ~g*xyGqV;)p{Ef!!3${*30H$Cb=^ydOiNoV95MJ@xoK%Wd)kOWNwV6 zugt$Nc|XbH0I&>N^4xmXtU+mp5Ct@FU*|U`=5TV$U$$MT4e^2m14yKb99iiFxtPHcLrZ7gD!W?R6L-9OOW509+caAf3NIs zVhI>7S#B};$UFV@E(8f#zGw2gMCMV9*lWH*E%%X}xMHE%8f^J}h}dtg1EqdTW9)9V z95k_G5ct{F_P=9dzDZ6b%^OrBlX|d{5n|Fe)bbXSKcId-0>?7*WjK*wv*P#RmR$<# zitC$NQU&=q-8}_?`i@%vUF$O#ZjQESM)?uR@P=5^M^kLy#&VP?C#ivo*qF8uanRNP zo3*oC5ZM_hZ?DwF@Q#-2BKsKbZnxEgg6@{4*ek)}HnVOxvX`Zh$>sFwIjDGGX%1EM zLrfU9!g7_BT(%5mFulKJ75fyv%e7?V(j-fU$j(EbHRe#*P>=QzEx)i-2@v{<)=8cSOSE8Z7-LBF+@;kbLKC5f?%7;($;ID>v0EN{Vx&9u7EMp|f%@EJ7! zNbHV1Q!HxKdKJPmESK@x97}}A zuH{AC48cs@qSMGfW0?u`$}q^S#DyFLd7!6CiTmEkLlgXeE$7#Pg{Ax(imobsyOl0BC{g!S>qGBzQVVQ z%$WkN>0`+V()D$XxO0(&?GxAySaDE{h2^Wwy)b)~MHkskSn-}X0w+IV$!9g9ZqEq( z;lf4|_Fj=-A9bYV4#T^JWT@;GMEzh{jLSz`o~EiTR3(2G6KEB{n4c}>EPtoj3O6TM z{9MqAk-#0cfh~u$q1I5`Rb&|`vMT6uS!{$&_gJ%1C~vK{5^3( zsLqqtcYt7)_W18oi&z*@EKfq(+oFbb7Ptt|wX>nf9`YiN+&QhNb zyeFs!|EB1d2+m){ZF_fFN!AjUy=So!yeC_!a~aCsx7>lMNUIf1s`Z{gE4s4dmgwLF z+ZIQ)u;z1diY6#KWyyvvlg+PSnA1u^RG{n(4Qai8R-GWp*R7kW^jn7;S#Mld&l<}V z^V?>BW-XVq18%KiuqgU^1fv*{+4Jp5=aBiW2_x^q-BOkZpV3o zMKX-)Y5i0nB<4`L-zGM0?A_GN^{ zp3kB!%*6*OhG;=%@ z#adV3zNf6c1s0YUm_id>n)PcFi-6p_;uOf)>l%fp=2!_itY2e2D{xSTb*I1@{An;q z2D66&t+pbuB%4#!5IRlZ*7W;A>jlWH7JtA?ORY^9YxJkp09j2eUR`FLsYv}K!#9xH z%Q6IlVUEzb<|i4n%d>tUQ+!j5M7GzJMxdC$StE7GfmpDfW=%2T2&p`N@`|;kKoCvD zG0Pb|x7ON%Lo^X5EM@_z>skyFCYzVRu1(f~ED9saE$LMA#{faXRBJJ${VdLg?_;ge zcxB*8|!zc)BCq%GvyS1^}=Fo6GNisa>#9hxA+Bt|V_e|FN zONN_69u6fI%r(#Adj+uxUC}{+6N#fZ0kz|v>va=ri&D9jc8l>?o)prawwh(Og96_B z%xaQY2MoPsrJ4VktJc{HdmO*NX>|%Rg}MpnNc}*m&2PV{$b%%q7mq;lM%!RMp0$F@ z4tVq@>jAZE-c)^{WY{|5;oSvul;6R@x!+h57<_!k8s+FDQ-pak`;vLcLPHf2S~53(s8 zLcWt7P36t(mQ-HNj-s+Mo01~rE7{GcypT<)5r6zMy0YW{7u(1*$mQ8&rSeDFgapg) zXE&tsP&VaP$R*j7Um+J~69g@9&8Ex>c~drJR>&K&>rlBqoAN8wT8Iv7iFi4lP zeNdz6w1#7F z(o5MUDxc3bQn@Ibj6j;1O;#&S&8Epv8kdDN~1o5%<{gTPUZJ{8kJY{X;glwPo?rbeG-+Kd-aL*W4%tHTXC5_hRVfy z3YA&*(~UGzazcGL+v{98WF|BG~*%>NVlH2=@( zG=}xRr_*H8c>izDr=ijPpQh7vq(}ctJ`L$|>+DCVjLIgw+8CLgKxMt`E>zaZrZ zw))shvh5eyW0)|}mO-1N5?dthh@)SzvBmbe#CoEn*-WbRq-0nege)OvqpenOZU(4j z+ao_A8D1MyON70>|p^ zw!;iRXkqIpu>Mfp)0O}UlFf|$Vr;ZwNP_CVw!>RLh_#tzngPG)RMQIu90u8T@p-j3 zU5`V~v*zKLl3?2;5(e(LZ=HdsI$LOZy*OF0>zIgeu!#kabb(W zwsRsI3T3|vwK2M*#VKI)NZVP)hQa>sHpF*QY&}Fa9QOCLoyGHGZOui(v^ySE3VK{1)ZL?^ZG@2(qjUR0u77JaTRARB~YTI;G9w`~F&IetwujHeXUQ|aP0ev^x zCaY84iqwbGAO=-s3|u*B4~2x<_7E7d$@ZE&mL8r8xoEXWx+=4j3V2YB1^-Sx-DJ6StYg=GMj=#=xDZ5#f4-ewcoJh-}?QUV%WvQdO~K14Kd#KEXBN+F~mp*R#MT>|~SvAqe_ zD>f%8H*FvBowv9E3c*HO+%IewMV0{-)wU}9@rKPIvV|D<(so*af+x*>*lDuYh03NH zB@g^y+YD8UOb(duQtI0Vgm)bhK51+Rnq9<9xc`HVc79bhP>rK#=LeIJM#;tZd*W=m zvLP|de(2=_!Gj6sY+VUo@!A8}>%MJ2V~Zg9Yg@CuE$#gjmVz0IJzJD1^-o+1xsB}P zIb?fpicq{@D~F^rw#RF@PlE@Stes%K!@i6?3xQbs417kjH&>)F6cyqiL=On9=kNfl zWq(x7Jv2ifO>5~%TzP_P>F3tQ>8TXDo6ZUC6eM&Bb^1K+ObQuJv6Xsu3J|@3)yHgZ z2FD}qo#DX|+qRPWc2Qt2Vsc&kE|IeX#7;aH=Wxacsnjaa_t^ghNrwa{?4UJ2q%9F{L&04~2dI1|gi^pR z*q?&%XZ)QY%_8*B0`akJ;$q`kw~mdY(5m<{==&`SwgGU{WZazUT-r zC|E5?kaX7(208imzSwoNouX)KAwrh6P$rwCLgi%#;-qo*H3D0Q(nNcLB9AAP$$prr zSq4=U>8qQc?&lTAwEWYfZO>N9>e%XkG|k;%I_Pb$f=u zHbe4oEe@woau^wQSzu0ZG8G(nfXVm}x3 z3xvrJ5@tfdQbz&qTx-7(Y?YAsAwmeoT;u9oE)i&c#U}M-`E4C%INf`IwGe5JJYx5& z@wW8chUY8V{e0VoiiFL zdphRg{hoF~;MzPO$jm#KJ6ua<;Arirh8U~VkxRV|!+qE7y(M-4^&Wyt;9^uU>>K+R zj2(oERze1Z*A?S2=M#IH06C+aPO>0J4pc3$Q}D_l9)gNC!YV9%lnexN`tq!TeE(b| zS(4nVvK~HE3S~yAQBc#6G)))q(9ia6jFmyeI{yGj6Ez#`T5r#V$sah(c>fo>Ns%W> zhHn#*gcCur(95=Ph$*)hb2+_B*AXn9up842zdJ8nGIxP6{O< zj*$|Z3Zv>erYjZu9@VEvhUyys8m1iITVE%Q|0WnL#PTA?H3B_;Cw>+u{xDr1ad09O zi!`m^;aw!wLW8Px0wap-S45~hAk^a&oWzJd_Q%<41Y&cETY>CqASPwldj|PDg%SJg zMiEBtFqz<>=D5w@ISpy^{5xvQt0B)Y6U%D`{IH240ugO2wIO=Dy(zA!c0BVZ6%B$^ zd<=|K`)>tIWtW3`jtFIr}gge-{=p2~yvb?y>J!u6k5Wjz2~ojoGZ3E`8UmB zxLyz_ATem3V<)4mQ*zTMuzZ1|waBhR@=pJLJdovhRHO{ji6rU?{;H;CT=yCAfJ^1F^0 zDF4h^2MWT)I4J*)P_C4P_OTdU>bT9owZTzMVTZz3{Dp)Sa?f5~=xEJj4~6Uel%TfR zL3wW9VfjXT3<1F>$f04!Hyu}H%8m#va!i(QAADS&j?0T2Ger4o>a_|ImV|h5Shb^2 zz^4S^(cl18bMvUrg2N1zy@VLd8sWG>>bpoV=U;FTo^2q^lT60NaQH>;ApYQ|=s(aN zT&nyFlAjftb1rDp^dmQ&b@267$4hXOY4*!1uHR1;<8`)4|=eh33(O2 zhGPADj;kUQA#teI2@=-$e+UW*Nl2XqlN5+)6%!NSv~(4@3hv=;%8)pks0?o*cH(n- zEI4XAG*ncrzDb@zVe{#H=1YUL?N;UCI0KFI9_}O`(Ax?WO7hzf_N6ck(jHU1ShQLT zV^|p~htpo8!kNdrP$9QUDuuM&&Kw92l~zMqFV_N`SX+CQ(OHt*AEnNa@Cmub7{RUL z{Sr!ZfTWMLBG9J0G9k2sb`8QuIRj9+QRB-L$%4hRLTDM2m0`E?v`)~H1rttlg}lVb zBWsKKGge6LB0Y)28fvFa^3#&x``Mh0!DxvHsTLsYthAUokT|5|z|;jHA5v?v&KtPP zDEAIZS_6F(PhE)BJ{Fl1!iPDRz?HhrSy1#+h!fM!XcVK%Zm;Q#xgfE-qYdVSJGU_k zo7*Y%{WE7WWbF{zahm1_n{z|qTIUa(9J5%`O*<;dGby~0SVPlA?vf-9gZV&jr_|3s zZC{?JRa>|}`V3#`t4$Ut1+?%d2MuwOMnfC|fpFSihYr+er&kNA*GLqh7_3n!zBY8~ zNER16T$`-W?rXzXZL-{Cq!|mxDz<&f*jMo~d zb>C{K&!SCfDkrT62otp5WRBWVoP;JrD2md$M!~IS6h3p(7I3Xb zTfpY9@{C5otOAXKSy52Dny;KTYc!Fz1ZSSL$;+iy2UON~J)SSqCZZtVBtM$YRRK-aezJEjOBvN9lb0F=j>fhp8+6Ahg33(P@sM0KoOefpE z?j7V4iO*H!=RQvRQm_*O5S4!3>zFveLrPE)ubK7^fjwPYSXk-ENIVV%jvkR;}R zB~Yr7L3#vJjUgLo;y}U6t@H%h-WGvcF-YAgR_3AvA<0PzLftXdPS53){z7}ZaOZOD zZ+7ls>`@HA2)!sk#m}faE;SZ&KQyB+)Dj1J;}LJ3=UXP zYv!S zWt=2}|8D;*EyBvq&IXJ<4#}OgRW)=iB^~K3<=}T+oj%3}V)|I#wcqZ8q^8a%OL{m7 zq|2rmtLkCy#2=$pm&5l@>~E*j;jSNM)oAr|+`aXq>&Y5FVub14NM8#wT>EHy7U8y{ zV}SEV#s))TMo1mdb~&pc=DzS4#2DrA@cDfqhHzHl44keb1)zMBPzM}eX+QG;A3~`_ z#v;hMApKCIj$65X_9YZV5(k?Im!rpq!pT0axtKBBxm0AsP=CcqNgbtYqy$oOPe>=; z(s0z*@!F^|ErXRzNb2@(&=4jk6gLN(KQVdTRQ2`Rp<`qmjZ#ISHF`2NYh0n?H!+VR@SHqfy)Ld4X##8P@^zC z@cTVZugKCtrz0Dnf%7S-Y_BEbqx+o)1U3WM?2!GKbjf*!cB#GWMtI5_Lc2r|5bH3SHtR+I%MZvxcjqJB&JnOs;eg$%rNz;%w(G!N6? zb%u(t<1V?OF11}R@XGm6)<~mNhf3!y6U)HrBxg&;dpgBeveH7x{Zfd<1C3md2v}7? z&XLz9^ucW575#l5^hJi*6`a|P!X?DuE&o~%JtA8w=H3%bQfG8YEU2xsD~vG@v12t zvOW^({e8Mh#!{6?WlJHet(?UjLhV22fzP0{m+Ku);j>WPMrr|9hC1K>lL@|l%b{Er zzP#)_(%Bfw6(=QG7^G#GxKSfBD!u5O%nk4X-#gh#{4SBP=kRK_6h@Qj@8^d6*sGRn ztw}Z#0FqfV#x$*wMm`0t8@Nu$i>b*MvFfCgGCWhBk%r(?ja~VSE$8xmiD7UbBXMD1(7`sh^9o zPXJTP1j=h)lwgh{P@`Uf)IL&ULKs}D8SkwwULN9_r0|2Q zKgZSh{vD7o#&t-}Bl6Zl^)ZcL*s(5xVb_6fk~1+S#F@dd4{1FlZWY=<&J4|tJ*K+e z;km|TgQQpp2Wd5yr@3g~T>udSgccZ>={lzH!>->Bsp&?=ei^P}L4K8*+64VqYQ;6@ zD|9oVNXlI1E_o+4W%!+X)e6UKSblN2ab+(Y@?_vYGK+4S(fwl%kq zZtWp$JM3!A&HOdGwqeFqS0>?fHOC@>jzxCneQZbl6Ml=Il0|+>HfV=Cu)43CAdlbL zxnuB=H(jMN+l3WtOq604bITPxOu9R0#zk1Mp4a|yo-#F9TMQK&>Cht`rEH4N>~pPA zm<^p}uI~kTCv~|80w0-9sqt}el|p2Y&t2~QH1LE4XH-%u@0_LQeXM_rpUX!yNrUCAZa zL`l{pLuvOKnL(w+9j3msJ|x>giHvbI^?&wt3sNlZ7EpEF<&cpYf0r*TI{!niw5&M* zfiU-J47IzjQ9Ah_XH9!@dJaOMf%`NRb+k5qNDdM?S7cUN(^M$IvOl{vaRiiFp`FVw zE}G5W;YX63*Jpw2gN;q4Hl?nO$liyAe9H@N(HON86Cy& zxkm1}CfP$f4?4(2UzGSmg(>;1rF*G*YGdPUI{$g(;hFtEZhp&$_d~i)6M#e~b!&8G zQBYUPv2Y!){X_Kv!P*KeEHup}ujp|vhwyE#N?6#$oed73dlhH#3>I!7f*_{KwGgIn zWh#Et$z6+%tV8j;Y5+!k6qdrl*aO(pHs}o{kbanB*U@bE(IISa9?D~MS8Y!Tx=X>W{chU4&T-S`^%^WV;BE(LKhojb#}>HXCFBsLENW8tA^_D3+;s>wbO%vG z{fL|FeVLn%D1QYDPVyFB)jF9XtVn=L3~iQ&K(CaTis@SWJ03f|>waGp z{}mGhqbl5WV9P>xdmL8kew|}<%d*|g$bY&&5#^s+(?>Jl#ib;qKF8cB5-^ve6Z2sw z+=MsYfn_V`xPMZH+lY^pb7Fo$=`8Q%-zc5u!uqxC@0?uXoZLmJl4{j^?P5}6#E-Y}@g>M|5TFeB+TiqS7i{?2Zib|_^*!c$a zn6S(3fEb^rG0rV=Zxf(FOOFpi{GM+KzKsv@L}FBk=Ti|Px_TO7le(TuqG%z3rVsE$ zQqltrabmcK$P*(yPAHA^IN;SDo~GERp@&3m1J>9R4W;!wc9_@2W5a%t9!e##qZH*K z`8YstN!>P!@mvs1T08oZOk509#CT${bFAkm$G!@idVE;Bo#&=VSXasr55?a*dMN(x zhJN)tZLocU=R=XQese=TEnz`~r#=qs=AoUpmp)CwJMh8PM?GP@YdZ$|ct}b8kl4i& z4+#xD67*h18rVC@LxvNA(m?(~El7Nf*o++Pp(rmU_rB<9g3X6}&eQ2?GE4qMT{27l zvmQi@@YIHc=|o`cM9*msN)=D{kp55gTo=`_w(Z)sBeWs_Y2!$%yQg^$a&)SAw#N@S zQ|O(*OioS&TpjBn^lXlY(6jm|E#OTzfK=Vn7&^b^F=9*>AKZqp>p9}ET=%%J+hWfl zkEw8>h%6GNRlLcjQ1*rjG!4NE3@Z7KPx!j{7{NmcWu1+GP7>!}IymgKi$m$C*^@zu!|N z$X7^vTcPwWf44PCrTk|s9>46NB$3iHo)u8=xu+HWdeox|Af6y@5;l5E3B#Z7T>v?U zNystBJxiEKtzhnX?_L4-o$?SCA)X~2OgiG}gDK^nO&pd=K0;!nnoc-mw4wLp!j{y1gN^~8N$0Y(%SR5CyaOFXZbhC#l>WM%jtaaJ&&I+ zYUECIy3o^_-|tPq(Nmrtv`~JJzG1{W2kQJ{ewD`zTR-wNg-e&YYvc9AR0!U#@K9FL z@$WtHMDLHJ(A36@w4?sQBjNYwJQS56+S>5xOHRN*j<-U z!%MK)aZh{xo0GTDE%-v$hg5}od>@MWlGluF?~#3Qi5dChP4X3QB>$xldUfDBoVQn>cmKASALFgXf2#~KY2xko ze<%ZD>t?Y3>x`hPz&+0xO7af%z7mvEG9*gAE)XvJ8bkOAZ`?n6y}{cV0DVSy2jlRL z-mM~g9IryRjQ>6L0XKsEEuOI1sGbydrmy9#Idvi%&`*=P4b|sR)=m;~l z^#rGh&;XC`BQbxVSJ^wrn<5gH>|LEd*xQ&7>T`tIgnEMl8UpNb??ec1>#c;M2ya77 z8{*9qD5)(m-a8KJb?{zCq6`Isks^+J=%_rY&QT$MqPGdBTX!87n7Jv+yH>C}Wc zmD->#tO6(KWKaMjG0@a|I;iA?V3P1z{!B0B()=Mw+C&*-I<0-&(~7e)<1YirAD#8JQkCG^uA299SIb^dDdHtGUE~&dP_y<)6?5AKj%Lv^(t>9r~G_S)DyWD zSN>D;+HhJZm+7#FJ}h+J;|l7+CqXVIV?w)N^CP?+`BPIMq0CFC^9#JEL^c%@fAk&- zDwm53qIv#yZ*8tJhaO6}*&E&qG~z|12MGaRseoC(c^U_sosQ0_-rK=9ZTb7W798yH zdTGqjdmY4gy+I{5a#}hENB$Mw^$bp67=*R;UVS+7T7>U>&^Dh2=K?Z$KKKs>m|o_6 zi8?;!b#t;l=kl|O`6s;19_qkDV*` zTT?!!3xj0OMrW+|2>}bvdtPJt=e@K>{6i;rTwk8cNu0q|*Nz#nz6C*<&x68GJo|wh zM+i5LpdKvaY}oPB``)Gm<~HC+<%Ao&DMn?$S{RF1cU)Ma3LtZ!^kIf9HmE-j1?w8G@g-u~i0SmMkz%m2~a zh%@k6kjyMh{?fCHnzMN+6X%}S$JwUM@k3_LdLo0OCdBAC&2QB6=adHXpIM6HNqE(t zc!Er66fg|)YC!5u+noQxS8K)=Kjf^g~4r%0jQ=l_^`UTH9^p_nxEh!o1aT|*}J2UR#$nzKJzU9kDda_ zQv^d8@+v5*^d9C)k@Zl~Z#DEy!_|-arZDz0re=9J&{FoKX9Q<6pQ~YWE(%*v8@gdu zf8QdBt$sP+pM_DM_{b#(PwO9K{ty^`&bJ7op74Fj*ee*2{2cxo;v@KL4O~q!df=l= zzB<@?xbJ8BJdI>Ht@7ncXDBKs#hf+P_q@mtxXV2C&gW6(+VruA4mD3Waca7cyz|U#>)7x<>Dw2-{I#1|^a z1=RQ!O#ZjeN=N#h^ZiR;ufdhqd{5)-7kzJ-SSUuU@*QRB>ucp~+L-Ti)b#xbrsexq z2G6X^Z$M(1&kbpP{Rwo2+NWXv@xDe3sqfhWdy_K#Xu6}m(_l-2ePG_m%k_2j63`|bnDrV*q} z@R?!Z1m8la?Bvhos;~zt-VFH=Pag5L5!qfSmi!H{$uZxf3X8yL<-Yo&f*YR5rjO1X z;<$GgKCF%C;D`JcUHcw>V5n69k|+4K@g@uL_GaI7!km*StuRIO*QUcB^8PkZ_@d7T z_Y){viR4lO<+c2SaPtMAn&9&-!+u_HW<6jD!tU_wpw(I;J**KDAle*nbRG zobf$?l^%aQbUI6Dq})zR7=QoQFdU1}OjB_tL{pZSo-rK*rR`ub$BqLyPJef6_xRD8?$Hu0^-HIIeFnPxAvNFkMNknYG+(q>GWHgkN`97uRG zBm}k%b`OB6;VMBF*L-u#lxS&SqRk)@DA~i(Q^*Ui`?gXzEStW|bNEj)e}l3ktCoODR?U2B59+4W%!uksgOX?{gt~{gfmVbIun9AuasRz=or~7(Cd*zc?t|4DpdD zosvIAv3P$t_58YTFfOR&e^y|p2_mBpBBj*zuU6zH8wF04R6)*Urq0gtj8Av|vu0mVh!k+%g z^2JwEvLjLJ<-g73b41-|oI3jcM<4&UqI!wGH5<%Jq5zaH0sAER(L^5*NbY6yLd;m> zTzqM;->*u|=tBw|dh3kerusbs`#gWFznk1#GOVDu)=;?}>SO)iOLT-aZIYiRgX?*$ znyh@PpQigSaOj(UN^C!o>yH)Sv#0%$l%<#6k&dAMks=#R*p$G&ixQ^N!o@cr>7w0? zBcAcU#t4l|Pte>v;kYR#%<$Cmu z%5qBzf^_1f#o?-D{%odx^G^3{+VI|SJggk}ynh>$uaP*ug#Z&0Ik6WReb2#9DZRI_ zu(mjgO5PFWWEtgH9kiuRtpJHxh_fSYLF*_p|*jDBo|V{FgcY zbjsImERy&PG9h|b?9Cyiggocswf;;F>oKE7skPbw`!Y<^{pk#ioBY2??1$G@((WK_ zn0+wM;rG%gWK+Ni?B@b)R8>d75mso|3|alDTzf_57X^g7#TL(9K1bfkiwiI==D6KF8D_!cb+M(T(Pj((`LttQ|f+M z;ZzJR_B_R!JEX}vP)ImOZ8p$mEKl@#q0;W8k1O}&=Mhx7pdh^Z5jk;EVB8?@QdT<9 z#Dd;rs{jWxV6Qf#W094Q6`2rCpj`)_=_jgnU{|=Ka0b3B(tTo87CedjD|3My9ErrA zlt)vj%faoEe4>`EvL{7Z8H{p`{!q_U(>WnID?w2tTId21Z}lZ2Qbll1Hm83BcrJ%j**e>T1PZ8a%@RgK7 zG1ZM@9VD5YbqGEaVL)_uKn)YM4bY{qR58>zJ&9)jZRL>|Ito68JeR@e#L0>n)AR9o zNFDz3(vg&%D&A~?DnSoy;l^qTzpe;eSFosITD25bk{_h=6zpW0k1R;TV1{Rzh;}MO z2B{3m$oYgwbfT(_Sr6J|jm|UxpiY zWZx2h$R*n^GP~iGLR+?&*O-s3i*>+w8vdY5@5FN-bYf8VfIC53r`oJid>n;VBoKhp h*r}dimdjcz2BP3*Y>jw%3tBaaVX-Ryx@?4+@Do^p8O8tr 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 102/199] 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 103/199] 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 104/199] 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 105/199] 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 106/199] 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 107/199] 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 108/199] 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 109/199] 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 110/199] 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 111/199] 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 112/199] 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 113/199] 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 114/199] 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 115/199] 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 116/199] 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 117/199] 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 118/199] 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 119/199] 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 120/199] 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 121/199] 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 122/199] 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 123/199] 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 124/199] 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 125/199] 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 126/199] 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 127/199] 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 128/199] 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 129/199] 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 130/199] 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 131/199] 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 132/199] 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 133/199] 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 134/199] 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 135/199] 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 136/199] 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 137/199] 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 138/199] 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 139/199] 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 140/199] 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 141/199] 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 142/199] 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 143/199] 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 144/199] 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 145/199] 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 146/199] 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 147/199] 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 148/199] 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 149/199] 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 150/199] 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 151/199] 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 152/199] 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 153/199] 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 154/199] 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 155/199] 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 156/199] 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 157/199] 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 158/199] 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 159/199] 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 160/199] 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 161/199] 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 162/199] 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 163/199] 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 164/199] 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 165/199] 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 166/199] 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 167/199] 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 168/199] 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 169/199] 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 170/199] 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 171/199] 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 172/199] 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 173/199] 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 174/199] 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 175/199] 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 176/199] 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 177/199] 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 178/199] 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 179/199] 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 180/199] 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 181/199] 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 182/199] 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 183/199] 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 184/199] 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 185/199] 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 186/199] 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 187/199] 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 188/199] 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 189/199] 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 190/199] 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 191/199] 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 192/199] 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 193/199] 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 194/199] 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 195/199] 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 196/199] 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 197/199] 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 198/199] 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 199/199] 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