From 52612bec3c7ff5f3ce61bc7380600a5831bbe1bb Mon Sep 17 00:00:00 2001 From: dan Date: Sun, 20 Oct 2019 08:26:08 +0000 Subject: [PATCH 1/6] Fix a resource leak in fts5 that could occur if an auxiliary function is called from within a query that does not use the full-text index. FossilOrigin-Name: b528bdcd45db1b783ecd9739c3d3c890f04de7003f079668970eafaf8e23b2f3 --- ext/fts5/fts5Int.h | 5 +++++ ext/fts5/fts5_index.c | 12 ++++++------ ext/fts5/fts5_main.c | 1 + ext/fts5/test/fts5matchinfo.test | 26 ++++++++++++++++++++++++++ manifest | 20 ++++++++++---------- manifest.uuid | 2 +- 6 files changed, 49 insertions(+), 17 deletions(-) diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index 8bc339de3b..e0287d1616 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -422,6 +422,11 @@ int sqlite3Fts5IterNextFrom(Fts5IndexIter*, i64 iMatch); */ void sqlite3Fts5IterClose(Fts5IndexIter*); +/* +** Close the reader blob handle, if it is open. +*/ +void sqlite3Fts5IndexCloseReader(Fts5Index*); + /* ** This interface is used by the fts5vocab module. */ diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 5c1365a51e..816274df49 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -614,7 +614,7 @@ static int fts5LeafFirstTermOff(Fts5Data *pLeaf){ /* ** Close the read-only blob handle, if it is open. */ -static void fts5CloseReader(Fts5Index *p){ +void sqlite3Fts5IndexCloseReader(Fts5Index *p){ if( p->pReader ){ sqlite3_blob *pReader = p->pReader; p->pReader = 0; @@ -643,7 +643,7 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){ assert( p->pReader==0 ); p->pReader = pBlob; if( rc!=SQLITE_OK ){ - fts5CloseReader(p); + sqlite3Fts5IndexCloseReader(p); } if( rc==SQLITE_ABORT ) rc = SQLITE_OK; } @@ -5204,7 +5204,7 @@ int sqlite3Fts5IndexBeginWrite(Fts5Index *p, int bDelete, i64 iRowid){ int sqlite3Fts5IndexSync(Fts5Index *p){ assert( p->rc==SQLITE_OK ); fts5IndexFlush(p); - fts5CloseReader(p); + sqlite3Fts5IndexCloseReader(p); return fts5IndexReturn(p); } @@ -5215,7 +5215,7 @@ int sqlite3Fts5IndexSync(Fts5Index *p){ ** records must be invalidated. */ int sqlite3Fts5IndexRollback(Fts5Index *p){ - fts5CloseReader(p); + sqlite3Fts5IndexCloseReader(p); fts5IndexDiscardData(p); fts5StructureInvalidate(p); /* assert( p->rc==SQLITE_OK ); */ @@ -5456,7 +5456,7 @@ int sqlite3Fts5IndexQuery( if( p->rc ){ sqlite3Fts5IterClose((Fts5IndexIter*)pRet); pRet = 0; - fts5CloseReader(p); + sqlite3Fts5IndexCloseReader(p); } *ppIter = (Fts5IndexIter*)pRet; @@ -5529,7 +5529,7 @@ void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; Fts5Index *pIndex = pIter->pIndex; fts5MultiIterFree(pIter); - fts5CloseReader(pIndex); + sqlite3Fts5IndexCloseReader(pIndex); } } diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index fc4ec0c482..a0450a6e4f 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -744,6 +744,7 @@ static void fts5FreeCursorComponents(Fts5Cursor *pCsr){ sqlite3_free(pCsr->zRankArgs); } + sqlite3Fts5IndexCloseReader(pTab->p.pIndex); memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan - (u8*)pCsr)); } diff --git a/ext/fts5/test/fts5matchinfo.test b/ext/fts5/test/fts5matchinfo.test index 4dc04b7897..d8d8d84e79 100644 --- a/ext/fts5/test/fts5matchinfo.test +++ b/ext/fts5/test/fts5matchinfo.test @@ -491,4 +491,30 @@ do_catchsql_test 14.2 { SELECT matchinfo(x1, 'd') FROM x1('a b c'); } {1 {unrecognized matchinfo flag: d}} +#------------------------------------------------------------------------- +# Test using matchinfo() and similar on a non-full-text query +# +do_execsql_test 15.0 { + CREATE VIRTUAL TABLE t1 USING fts5(x, y); + INSERT INTO t1 VALUES('a', 'b'); + INSERT INTO t1 VALUES('c', 'd'); +} + +do_execsql_test 15.1 { + SELECT quote(matchinfo(t1, 'n')) FROM t1 LIMIT 1; +} {X'02000000'} + +do_execsql_test 15.2 { + DELETE FROM t1_content WHERE rowid=1; + SELECT quote(matchinfo(t1, 'n')) FROM t1 LIMIT 1; +} {X'02000000'} + +fts5_aux_test_functions db +do_execsql_test 15.3 { + SELECT fts5_test_all(t1) FROM t1 LIMIT 1; +} { + {columnsize {0 0} columntext {c d} columntotalsize {2 2} poslist {} tokenize {c d} rowcount 2} +} + finish_test + diff --git a/manifest b/manifest index 2cc6986f5f..471284c55b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\s".imposter"\scommand\sin\sthe\sCLI\sso\sthat\sthe\sfirst\sargument\ncan\sbe\san\sexisting\sWITHOUT\sROWID\stable\sinstead\sof\san\sindex.\s\sThe\sresulting\nimposter\sis\sthe\ssame\stable,\sbut\swith\scolumns\sin\sstorage\sorder\sand\swith\nall\sconstraints\sremoved. -D 2019-10-18T15:58:50.284 +C Fix\sa\sresource\sleak\sin\sfts5\sthat\scould\soccur\sif\san\sauxiliary\sfunction\sis\scalled\sfrom\swithin\sa\squery\sthat\sdoes\snot\suse\sthe\sfull-text\sindex. +D 2019-10-20T08:26:08.728 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -110,14 +110,14 @@ F ext/fts3/unicode/mkunicode.tcl bf7fcaa6d68e6d38223467983785d054f1cff4d9e3905dd F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h 7c9da96f2b9dcfa4dd94081fb2d87ec418d8cdb35b25df56756c334b6b558fd7 -F ext/fts5/fts5Int.h 3966afab063063ea9fcbf84ac386f3f094c99ade4452e529c0a0d56375d984c1 +F ext/fts5/fts5Int.h d7cbc214ee167496f70905667e18f73ea0402f7ef09236ce305e117e0efc866a F ext/fts5/fts5_aux.c dcc627d8b6e3fc773db528ff67b39955dab7b51628f9dba8e15849e5bedfd7fa F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6dc8aaca70 F ext/fts5/fts5_config.c aab6117f8f85933e051c66f227414fdcaf7f2313688e16276b895f9d42d28e5c F ext/fts5/fts5_expr.c 5661fe64f4f5a499710df9561075de84b743f01e808af46df4130a9ec343a0fd F ext/fts5/fts5_hash.c 1cc0095646f5f3b46721aa112fb4f9bf29ae175cb5338f89dcec66ed97acfe75 -F ext/fts5/fts5_index.c ce199410b2cd7d625c1da5b684a5c1fbcfe90f7a10bae18e2fbb051b9a2acbe5 -F ext/fts5/fts5_main.c bf637030722badf06667d28f7159e4c209dbafd7aa76c33f387104b78ad147e1 +F ext/fts5/fts5_index.c d1bfebebe873905fe5d450e275b45af2d635b3e276452086f681c6d3d750398d +F ext/fts5/fts5_main.c 1b2d41fd7cc2e8277f60e4156826f41fe5d6b1ccc2e54d70450883ab2ca697d2 F ext/fts5/fts5_storage.c 167e3d8f8052a71032d498e32a2f2ed5ffe489e5d4d47e298adfa02ed55c7882 F ext/fts5/fts5_tcl.c 39bcbae507f594aad778172fa914cad0f585bf92fd3b078c686e249282db0d95 F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee @@ -186,7 +186,7 @@ F ext/fts5/test/fts5integrity.test 4317561cd25eca7df16aa1f7d1a700ee958059fa63978 F ext/fts5/test/fts5interrupt.test 09613247b273a99889808ef852898177e671406fe71fdde7ea00e78ea283d227 F ext/fts5/test/fts5lastrowid.test be98fe3e03235296585b72daad7aed5717ba0062bae5e5c18dd6e04e194c6b28 F ext/fts5/test/fts5leftjoin.test c0b4cafb9661379e576dc4405c0891d8fcc2782680740513c4d1fc114b43d4ad -F ext/fts5/test/fts5matchinfo.test 79129ff6c9a2d86943b287a5a8caa7ee639f6dcf004d8975d15c279374e82e35 +F ext/fts5/test/fts5matchinfo.test 50d86da66ec5b27603dcd90ba0227f5d9deb10351cbc52974a88e24f6fc9b076 F ext/fts5/test/fts5merge.test e92a8db28b45931e7a9c7b1bbd36101692759d00274df74d83fd29d25d53b3a6 F ext/fts5/test/fts5merge2.test 3ebad1a59d6ad3fb66eff6523a09e95dc6367cbefb3cd73196801dea0425c8e2 F ext/fts5/test/fts5misc.test adfccd3f065df52e306778c815f873ab779b9db34e9817b1d4b819132f914701 @@ -1847,7 +1847,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 35beaee059a6cccead4311886ca928d936f23584cf435e35e265e98feea723dc -R 79321ef818ef0b98008c7f3041b73ac3 -U drh -Z 758d9d25f4ac17fe1f5333a4da39c6af +P 9dc0d34586eebf6705d9bd81494c417ac76707b8625d1ff99eda18b4ca2d8a50 +R 1446fe5ff2305d447db9356138aa9638 +U dan +Z 8eec37beaa1889d440099062804581d3 diff --git a/manifest.uuid b/manifest.uuid index c818b549f5..27d8107492 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9dc0d34586eebf6705d9bd81494c417ac76707b8625d1ff99eda18b4ca2d8a50 \ No newline at end of file +b528bdcd45db1b783ecd9739c3d3c890f04de7003f079668970eafaf8e23b2f3 \ No newline at end of file From 276d7f78470002e09ede5bd96556cddbc23cd678 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 21 Oct 2019 16:15:57 +0000 Subject: [PATCH 2/6] Try to fix a harmless compiler warning reported by ICC. FossilOrigin-Name: 7f41b44ca2ecb907ea0fd09a974ac9dbdf911463a94f0f77c826cf1b1d9c3e8c --- manifest | 14 +++++++------- manifest.uuid | 2 +- tool/lempar.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 471284c55b..3b1a218271 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sresource\sleak\sin\sfts5\sthat\scould\soccur\sif\san\sauxiliary\sfunction\sis\scalled\sfrom\swithin\sa\squery\sthat\sdoes\snot\suse\sthe\sfull-text\sindex. -D 2019-10-20T08:26:08.728 +C Try\sto\sfix\sa\sharmless\scompiler\swarning\sreported\sby\sICC. +D 2019-10-21T16:15:57.553 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1767,7 +1767,7 @@ F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/index_usage.c 9ec344d29cbeb03fdc0fce668eedfb7495792170de933adf95cf8d6904a166ad F tool/kvtest-speed.sh 4761a9c4b3530907562314d7757995787f7aef8f F tool/lemon.c 61d5f0af1eff8f754b75ddca668c9897fd30759e389bfffb42ce9e4d38fd4746 -F tool/lempar.c eb2841e2a7fd484cf44b1f526b06e7ab0f216d2f41818bf9485e8f38e3d1db19 +F tool/lempar.c 34b136b281ae022277738d8b51061237fb330deaa317010d89375117e3a028aa F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca @@ -1847,7 +1847,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9dc0d34586eebf6705d9bd81494c417ac76707b8625d1ff99eda18b4ca2d8a50 -R 1446fe5ff2305d447db9356138aa9638 -U dan -Z 8eec37beaa1889d440099062804581d3 +P b528bdcd45db1b783ecd9739c3d3c890f04de7003f079668970eafaf8e23b2f3 +R 6092914249b2bab0f110a245cdadcc45 +U drh +Z 6dcf0ab02e4e7edf064ddf88070a5fda diff --git a/manifest.uuid b/manifest.uuid index 27d8107492..4bfc390634 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b528bdcd45db1b783ecd9739c3d3c890f04de7003f079668970eafaf8e23b2f3 \ No newline at end of file +7f41b44ca2ecb907ea0fd09a974ac9dbdf911463a94f0f77c826cf1b1d9c3e8c \ No newline at end of file diff --git a/tool/lempar.c b/tool/lempar.c index f75ad51c39..f8e0885e35 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -1068,6 +1068,6 @@ int ParseFallback(int iToken){ return yyFallback[iToken]; #else (void)iToken; -#endif return 0; +#endif } From 2c3de90da1a6dcb5291b2fdb6d889a51743d21c6 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 21 Oct 2019 23:41:56 +0000 Subject: [PATCH 3/6] Add a VdbeCoverage() macro that was omitted from check-in [eea1e7aa57e74c43]. FossilOrigin-Name: cd2317d04c1c4bcf5fe63aa02a6051bdfae8f5566a098e3f45bf9ec1dd0c3ea6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/insert.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 3b1a218271..b9d4b33a08 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Try\sto\sfix\sa\sharmless\scompiler\swarning\sreported\sby\sICC. -D 2019-10-21T16:15:57.553 +C Add\sa\sVdbeCoverage()\smacro\sthat\swas\somitted\sfrom\scheck-in\s[eea1e7aa57e74c43]. +D 2019-10-21T23:41:56.569 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -486,7 +486,7 @@ F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c d9cb78faa39180915ed940f0dcb3b168002f72e4f4926081a9553719fd12f6a1 +F src/insert.c 69e47d76598d26f87cc9b32b9e9fc84e49e3b9371b5d9ae8465f38486ad9665e F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 4ddc65ae13c0d93db0ceedc8b14a28c8c260513448b0eb8c5a2ac375e3b6a85d F src/main.c 3e01f6a1c96643381b5f9d79e4ff7f2520bc5712197746fb0852283e78cccf66 @@ -1847,7 +1847,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b528bdcd45db1b783ecd9739c3d3c890f04de7003f079668970eafaf8e23b2f3 -R 6092914249b2bab0f110a245cdadcc45 +P 7f41b44ca2ecb907ea0fd09a974ac9dbdf911463a94f0f77c826cf1b1d9c3e8c +R 68b8eca796fc459e763498795f66f3ad U drh -Z 6dcf0ab02e4e7edf064ddf88070a5fda +Z cb9fad97a2f046f52d8adf2a38eb83cb diff --git a/manifest.uuid b/manifest.uuid index 4bfc390634..3fab508907 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7f41b44ca2ecb907ea0fd09a974ac9dbdf911463a94f0f77c826cf1b1d9c3e8c \ No newline at end of file +cd2317d04c1c4bcf5fe63aa02a6051bdfae8f5566a098e3f45bf9ec1dd0c3ea6 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 690845a7da..3bb1ee706a 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1583,6 +1583,7 @@ void sqlite3GenerateConstraintChecks( sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, regNewData, 1, 0, OE_Replace, 1, -1); sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regNewData); + VdbeCoverage(v); sqlite3RowidConstraint(pParse, OE_Abort, pTab); }else{ #ifdef SQLITE_ENABLE_PREUPDATE_HOOK From 898c527eafd8bf263a3c3626ff421804558132f9 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 22 Oct 2019 00:03:41 +0000 Subject: [PATCH 4/6] When flipping ("commuting") a comparison operator, set the new EP_Commuted bit rather than adding extra EP_Collate bits, to single later processing that the order of precedence for COLLATE operators is inverted. Fix for ticket [b47e3627ecaadbde] FossilOrigin-Name: 90f7c477354d67d22d5eb0da22dac579f384ab44743fdc19887220e32203ebc2 --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/expr.c | 38 +++++++++++++++++++++++++++++++------- src/select.c | 4 ++-- src/sqliteInt.h | 3 ++- src/where.c | 10 ++++------ src/whereInt.h | 1 - src/whereexpr.c | 38 +++++--------------------------------- 8 files changed, 56 insertions(+), 62 deletions(-) diff --git a/manifest b/manifest index b9d4b33a08..b06aa5e02f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\sVdbeCoverage()\smacro\sthat\swas\somitted\sfrom\scheck-in\s[eea1e7aa57e74c43]. -D 2019-10-21T23:41:56.569 +C When\sflipping\s("commuting")\sa\scomparison\soperator,\sset\sthe\snew\sEP_Commuted\nbit\srather\sthan\sadding\sextra\sEP_Collate\sbits,\sto\ssingle\slater\sprocessing\sthat\nthe\sorder\sof\sprecedence\sfor\sCOLLATE\soperators\sis\sinverted.\nFix\sfor\sticket\s[b47e3627ecaadbde] +D 2019-10-22T00:03:41.431 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -477,7 +477,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c 4c2a0d00a0d7701811a463b9af2c63d10b0c5ee7b8bde249309184f82d27b5b0 +F src/expr.c da4b31b0dfba1bf7891d996e91eff371b4eb5672341beb0c54299f56bc745cbc F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6271fda51794b569d736eba4097d28f13080cd0c9eb66d5fcecb4b77336fae50 F src/func.c ed33e38cd642058182a31a3f518f2e34f4bbe53aa483335705c153c4d3e50b12 @@ -525,12 +525,12 @@ F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c e021be0c1c4a2125fa38aabcd8dbb764bf5b2c889a948c30d3708430ec6ccd00 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 -F src/select.c 7ef05eeb7f686f84dd1428cbdca280c898915bbf56e1ea97bd42ecc070af78d3 +F src/select.c 9c81d168b5a7ddc2277a6f6d3daec9ddd0ff5cebf12628d7e342f3c337231e7e F src/shell.c.in 3093bdf5eedd91da08f0268f1442aa510a60798c9441868149ddbecdf8bcaa79 F src/sqlite.h.in 5725a6b20190a1e8d662077a1c1c8ea889ad7be90dd803f914c2de226f5fe6ab F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h cef696ce3293242c67b2339763608427bf72ee66f1f3a05389ac2a7b46001c31 -F src/sqliteInt.h 40f81bb57b0723403d5da77314d459f536ddd0f07d57434a94df35e790b6b268 +F src/sqliteInt.h 5e98328254a8932a912cd12960cc7a4f22078a56bc9c617ffe042ad554c0db68 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -611,10 +611,10 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd -F src/where.c 9f3f23efc45934e7b7ea6c0c1042420b73053e7c3264feef6faf9ce6fbd5df61 -F src/whereInt.h 2c6bae136a7c0be6ff75dc36950d1968c67d005c8e51d7a9d77cb996bb4843d9 +F src/where.c 148fa1ce9d6421a2c325291cae7681b3492cf1f219ff58f9ef38695a7f3c61ff +F src/whereInt.h 4a296fd4fa79fdcbc2b5e8c1b898901617655811223e1082b899c23ecb092217 F src/wherecode.c 57d034a0dbca9f86e1a691f74e469ed09ff49d04712b838fb68596b76a9af7d2 -F src/whereexpr.c 05c283d26aa9c3f5d1bf13a5f6a573b43295b9db280eff18e26f97d7d7f119b4 +F src/whereexpr.c ab3c687a33aa3ca75744a74e82c0eab703a88627131cf72707f5346f04cb8539 F src/window.c 064f251451c8e2a1c76b6269229d911a651e119c6a5f522b6eaebf8dc8714041 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -1847,7 +1847,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7f41b44ca2ecb907ea0fd09a974ac9dbdf911463a94f0f77c826cf1b1d9c3e8c -R 68b8eca796fc459e763498795f66f3ad +P cd2317d04c1c4bcf5fe63aa02a6051bdfae8f5566a098e3f45bf9ec1dd0c3ea6 +R 3a3c136ff4c96296b02b1f2633ff663b U drh -Z cb9fad97a2f046f52d8adf2a38eb83cb +Z 20a6808e6237368aa12eb5e4f5b30bb2 diff --git a/manifest.uuid b/manifest.uuid index 3fab508907..c3d5218682 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cd2317d04c1c4bcf5fe63aa02a6051bdfae8f5566a098e3f45bf9ec1dd0c3ea6 \ No newline at end of file +90f7c477354d67d22d5eb0da22dac579f384ab44743fdc19887220e32203ebc2 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 0e827482b2..7e80796f4b 100644 --- a/src/expr.c +++ b/src/expr.c @@ -339,6 +339,22 @@ CollSeq *sqlite3BinaryCompareCollSeq( return pColl; } +/* Expresssion p is a comparison operator. Return a collation sequence +** appropriate for the comparison operator. +** +** This is normally just a wrapper around sqlite3BinaryCompareCollSeq(). +** However, if the OP_Commuted flag is set, then the order of the operands +** is reversed in the sqlite3BinaryCompareCollSeq() call so that the +** correct collating sequence is found. +*/ +CollSeq *sqlite3ExprCompareCollSeq(Parse *pParse, Expr *p){ + if( ExprHasProperty(p, EP_Commuted) ){ + return sqlite3BinaryCompareCollSeq(pParse, p->pRight, p->pLeft); + }else{ + return sqlite3BinaryCompareCollSeq(pParse, p->pLeft, p->pRight); + } +} + /* ** Generate code for a comparison operator. */ @@ -349,13 +365,18 @@ static int codeCompare( int opcode, /* The comparison opcode */ int in1, int in2, /* Register holding operands */ int dest, /* Jump here if true. */ - int jumpIfNull /* If true, jump if either operand is NULL */ + int jumpIfNull, /* If true, jump if either operand is NULL */ + int isCommuted /* The comparison has been commuted */ ){ int p5; int addr; CollSeq *p4; - p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight); + if( isCommuted ){ + p4 = sqlite3BinaryCompareCollSeq(pParse, pRight, pLeft); + }else{ + p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight); + } p5 = binaryCompareP5(pLeft, pRight, jumpIfNull); addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1, (void*)p4, P4_COLLSEQ); @@ -566,6 +587,7 @@ static void codeVectorCompare( int regRight = 0; u8 opx = op; int addrDone = sqlite3VdbeMakeLabel(pParse); + int isCommuted = ExprHasProperty(pExpr,EP_Commuted); if( nLeft!=sqlite3ExprVectorSize(pRight) ){ sqlite3ErrorMsg(pParse, "row value misused"); @@ -595,7 +617,7 @@ static void codeVectorCompare( assert( i>=0 && ipRight, ®Free2); codeCompare(pParse, pLeft, pExpr->pRight, op, - r1, r2, inReg, SQLITE_STOREP2 | p5); + r1, r2, inReg, SQLITE_STOREP2 | p5, + ExprHasProperty(pExpr,EP_Commuted)); assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); @@ -4585,7 +4608,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, - r1, r2, dest, jumpIfNull); + r1, r2, dest, jumpIfNull, ExprHasProperty(pExpr,EP_Commuted)); assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); @@ -4760,7 +4783,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, - r1, r2, dest, jumpIfNull); + r1, r2, dest, jumpIfNull,ExprHasProperty(pExpr,EP_Commuted)); assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); @@ -4946,7 +4969,8 @@ int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTab){ return 2; } } - if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2; + if( (pA->flags & (EP_Distinct|EP_Commuted)) + != (pB->flags & (EP_Distinct|EP_Commuted)) ) return 2; if( (combinedFlags & EP_TokenOnly)==0 ){ if( combinedFlags & EP_xIsSelect ) return 2; if( (combinedFlags & EP_FixedCol)==0 diff --git a/src/select.c b/src/select.c index a5377a2c20..abb381a16a 100644 --- a/src/select.c +++ b/src/select.c @@ -4170,14 +4170,14 @@ static void findConstInWhere(WhereConst *pConst, Expr *pExpr){ if( pRight->op==TK_COLUMN && !ExprHasProperty(pRight, EP_FixedCol) && sqlite3ExprIsConstant(pLeft) - && sqlite3IsBinary(sqlite3BinaryCompareCollSeq(pConst->pParse,pLeft,pRight)) + && sqlite3IsBinary(sqlite3ExprCompareCollSeq(pConst->pParse,pExpr)) ){ constInsert(pConst, pRight, pLeft); }else if( pLeft->op==TK_COLUMN && !ExprHasProperty(pLeft, EP_FixedCol) && sqlite3ExprIsConstant(pRight) - && sqlite3IsBinary(sqlite3BinaryCompareCollSeq(pConst->pParse,pLeft,pRight)) + && sqlite3IsBinary(sqlite3ExprCompareCollSeq(pConst->pParse,pExpr)) ){ constInsert(pConst, pLeft, pRight); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 44a82223e6..c41978acb3 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2527,7 +2527,7 @@ struct Expr { #define EP_DblQuoted 0x000040 /* token.z was originally in "..." */ #define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */ #define EP_Collate 0x000100 /* Tree contains a TK_COLLATE operator */ - /* 0x000200 Available for reuse */ +#define EP_Commuted 0x000200 /* Comparison operator has been commuted */ #define EP_IntValue 0x000400 /* Integer value contained in u.iValue */ #define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */ #define EP_Skip 0x001000 /* Operator does not contribute to affinity */ @@ -4517,6 +4517,7 @@ char *sqlite3Normalize(Vdbe*, const char*); #endif int sqlite3Reprepare(Vdbe*); void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*); +CollSeq *sqlite3ExprCompareCollSeq(Parse*,Expr*); CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *); int sqlite3TempInMemory(const sqlite3*); const char *sqlite3JournalModename(int); diff --git a/src/where.c b/src/where.c index 1a43b8d19e..a7d34961e1 100644 --- a/src/where.c +++ b/src/where.c @@ -279,8 +279,7 @@ static WhereTerm *whereScanNext(WhereScan *pScan){ continue; } assert(pX->pLeft); - pColl = sqlite3BinaryCompareCollSeq(pParse, - pX->pLeft, pX->pRight); + pColl = sqlite3ExprCompareCollSeq(pParse, pX); if( pColl==0 ) pColl = pParse->db->pDfltColl; if( sqlite3StrICmp(pColl->zName, pScan->zCollName) ){ continue; @@ -801,8 +800,8 @@ static void constructAutomaticIndex( Expr *pX = pTerm->pExpr; idxCols |= cMask; pIdx->aiColumn[n] = pTerm->u.leftColumn; - pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight); - pIdx->azColl[n] = pColl ? pColl->zName : sqlite3StrBINARY; + pColl = sqlite3ExprCompareCollSeq(pParse, pX); + pIdx->azColl[n] = ALWAYS(pColl) ? pColl->zName : sqlite3StrBINARY; n++; } } @@ -2802,7 +2801,6 @@ static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){ if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0; for(i=0, pTerm=pWC->a; inTerm; i++, pTerm++){ Expr *pExpr; - if( pTerm->wtFlags & TERM_NOPARTIDX ) continue; pExpr = pTerm->pExpr; if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab) && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab) @@ -3265,7 +3263,7 @@ const char *sqlite3_vtab_collation(sqlite3_index_info *pIdxInfo, int iCons){ int iTerm = pIdxInfo->aConstraint[iCons].iTermOffset; Expr *pX = pHidden->pWC->a[iTerm].pExpr; if( pX->pLeft ){ - pC = sqlite3BinaryCompareCollSeq(pHidden->pParse, pX->pLeft, pX->pRight); + pC = sqlite3ExprCompareCollSeq(pHidden->pParse, pX); } zRet = (pC ? pC->zName : sqlite3StrBINARY); } diff --git a/src/whereInt.h b/src/whereInt.h index 64978cf110..e63ca46d53 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -291,7 +291,6 @@ struct WhereTerm { #define TERM_LIKE 0x400 /* The original LIKE operator */ #define TERM_IS 0x800 /* Term.pExpr is an IS operator */ #define TERM_VARSELECT 0x1000 /* Term.pExpr contains a correlated sub-query */ -#define TERM_NOPARTIDX 0x2000 /* Not for use to enable a partial index */ /* ** An instance of the WhereScan object is used as an iterator for locating diff --git a/src/whereexpr.c b/src/whereexpr.c index a161310799..ea174e1f3e 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -109,39 +109,11 @@ static int allowedOp(int op){ /* ** Commute a comparison operator. Expressions of the form "X op Y" ** are converted into "Y op X". -** -** If left/right precedence rules come into play when determining the -** collating sequence, then COLLATE operators are adjusted to ensure -** that the collating sequence does not change. For example: -** "Y collate NOCASE op X" becomes "X op Y" because any collation sequence on -** the left hand side of a comparison overrides any collation sequence -** attached to the right. For the same reason the EP_Collate flag -** is not commuted. -** -** The return value is extra flags that are added to the WhereTerm object -** after it is commuted. The only extra flag ever added is TERM_NOPARTIDX -** which prevents the term from being used to enable a partial index if -** COLLATE changes have been made. */ static u16 exprCommute(Parse *pParse, Expr *pExpr){ - u16 expRight = (pExpr->pRight->flags & EP_Collate); - u16 expLeft = (pExpr->pLeft->flags & EP_Collate); - u16 wtFlags = 0; - assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN ); - if( expRight==expLeft ){ - /* Either X and Y both have COLLATE operator or neither do */ - if( expRight ){ - /* Both X and Y have COLLATE operators. Make sure X is always - ** used by clearing the EP_Collate flag from Y. */ - pExpr->pRight->flags &= ~EP_Collate; - wtFlags |= TERM_NOPARTIDX; - }else if( sqlite3ExprCollSeq(pParse, pExpr->pLeft)!=0 ){ - /* Neither X nor Y have COLLATE operators, but X has a non-default - ** collating sequence. So add the EP_Collate marker on X to cause - ** it to be searched first. */ - pExpr->pLeft->flags |= EP_Collate; - wtFlags |= TERM_NOPARTIDX; - } + if( sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight) != + sqlite3BinaryCompareCollSeq(pParse, pExpr->pRight, pExpr->pLeft) ){ + pExpr->flags ^= EP_Commuted; } SWAP(Expr*,pExpr->pRight,pExpr->pLeft); if( pExpr->op>=TK_GT ){ @@ -152,7 +124,7 @@ static u16 exprCommute(Parse *pParse, Expr *pExpr){ assert( pExpr->op>=TK_GT && pExpr->op<=TK_GE ); pExpr->op = ((pExpr->op-TK_GT)^2)+TK_GT; } - return wtFlags; + return 0; } /* @@ -930,7 +902,7 @@ static int termIsEquivalence(Parse *pParse, Expr *pExpr){ ){ return 0; } - pColl = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight); + pColl = sqlite3ExprCompareCollSeq(pParse, pExpr); if( sqlite3IsBinary(pColl) ) return 1; return sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight); } From a5d0911546c0d41f142a33fc3622df7ef7d8a81d Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 22 Oct 2019 01:00:16 +0000 Subject: [PATCH 5/6] Move the sqlite3LocateCollSeq(), sqlite3FindCollSeq(), and sqlite3GetCollSeq() routines so that they are all beside one another in the callback.c source file. No logic changes. FossilOrigin-Name: 9ff80a9bf8fee776e2f282d0597215b77d48093ebc71d047ad1457da0582ddbc --- manifest | 14 +++--- manifest.uuid | 2 +- src/build.c | 35 ------------- src/callback.c | 132 +++++++++++++++++++++++++++++++------------------ 4 files changed, 91 insertions(+), 92 deletions(-) diff --git a/manifest b/manifest index b06aa5e02f..659ff29737 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sflipping\s("commuting")\sa\scomparison\soperator,\sset\sthe\snew\sEP_Commuted\nbit\srather\sthan\sadding\sextra\sEP_Collate\sbits,\sto\ssingle\slater\sprocessing\sthat\nthe\sorder\sof\sprecedence\sfor\sCOLLATE\soperators\sis\sinverted.\nFix\sfor\sticket\s[b47e3627ecaadbde] -D 2019-10-22T00:03:41.431 +C Move\sthe\ssqlite3LocateCollSeq(),\ssqlite3FindCollSeq(),\sand\nsqlite3GetCollSeq()\sroutines\sso\sthat\sthey\sare\sall\sbeside\sone\sanother\sin\nthe\scallback.c\ssource\sfile.\s\sNo\slogic\schanges. +D 2019-10-22T01:00:16.928 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -469,8 +469,8 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c a8a9c2ce62bdf54c8cf9795143d7cb10b7473a1230a0572f702d061ffcceefe5 F src/btree.h f27a33c49280209a93385e218306c4ee5f46ba8d7649d2f81a7166b282232484 F src/btreeInt.h 91806f01fd1145a9a86ba3042f25c38d8faf6002701bf5e780742cf88bcff437 -F src/build.c 13de2fdabbabcf2e2aaf6443a049fb851d9d3170136c08345468e158ceea3dc6 -F src/callback.c 25dda5e1c2334a367b94a64077b1d06b2553369f616261ca6783c48bcb6bda73 +F src/build.c 0e558ef847ccc4b6aa38dee44cde9d9df46e953b0a66e4fa4376265824955fe3 +F src/callback.c 88615dfc0a82167b65b452b4b305dbf86be77200b3343c6ffc6d03e92a01d181 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 1b0724e66f95f33b160b1af85caaf9cceb325d22abf39bd24df4f54a73982251 F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 @@ -1847,7 +1847,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cd2317d04c1c4bcf5fe63aa02a6051bdfae8f5566a098e3f45bf9ec1dd0c3ea6 -R 3a3c136ff4c96296b02b1f2633ff663b +P 90f7c477354d67d22d5eb0da22dac579f384ab44743fdc19887220e32203ebc2 +R 3a6f62c10243ee61b28a93dbeca6af23 U drh -Z 20a6808e6237368aa12eb5e4f5b30bb2 +Z 533045e8c1f04d69c5fc59655d97ca67 diff --git a/manifest.uuid b/manifest.uuid index c3d5218682..217b679a00 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -90f7c477354d67d22d5eb0da22dac579f384ab44743fdc19887220e32203ebc2 \ No newline at end of file +9ff80a9bf8fee776e2f282d0597215b77d48093ebc71d047ad1457da0582ddbc \ No newline at end of file diff --git a/src/build.c b/src/build.c index e4f8d5e3c6..22a57a240b 100644 --- a/src/build.c +++ b/src/build.c @@ -1520,41 +1520,6 @@ void sqlite3AddCollateType(Parse *pParse, Token *pToken){ } } -/* -** This function returns the collation sequence for database native text -** encoding identified by the string zName, length nName. -** -** If the requested collation sequence is not available, or not available -** in the database native encoding, the collation factory is invoked to -** request it. If the collation factory does not supply such a sequence, -** and the sequence is available in another text encoding, then that is -** returned instead. -** -** If no versions of the requested collations sequence are available, or -** another error occurs, NULL is returned and an error message written into -** pParse. -** -** This routine is a wrapper around sqlite3FindCollSeq(). This routine -** invokes the collation factory if the named collation cannot be found -** and generates an error message. -** -** See also: sqlite3FindCollSeq(), sqlite3GetCollSeq() -*/ -CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){ - sqlite3 *db = pParse->db; - u8 enc = ENC(db); - u8 initbusy = db->init.busy; - CollSeq *pColl; - - pColl = sqlite3FindCollSeq(db, enc, zName, initbusy); - if( !initbusy && (!pColl || !pColl->xCmp) ){ - pColl = sqlite3GetCollSeq(pParse, enc, pColl, zName); - } - - return pColl; -} - - /* ** Generate code that will increment the schema cookie. ** diff --git a/src/callback.c b/src/callback.c index ad53bd4d3c..a360e46ee4 100644 --- a/src/callback.c +++ b/src/callback.c @@ -65,51 +65,6 @@ static int synthCollSeq(sqlite3 *db, CollSeq *pColl){ return SQLITE_ERROR; } -/* -** This function is responsible for invoking the collation factory callback -** or substituting a collation sequence of a different encoding when the -** requested collation sequence is not available in the desired encoding. -** -** If it is not NULL, then pColl must point to the database native encoding -** collation sequence with name zName, length nName. -** -** The return value is either the collation sequence to be used in database -** db for collation type name zName, length nName, or NULL, if no collation -** sequence can be found. If no collation is found, leave an error message. -** -** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq() -*/ -CollSeq *sqlite3GetCollSeq( - Parse *pParse, /* Parsing context */ - u8 enc, /* The desired encoding for the collating sequence */ - CollSeq *pColl, /* Collating sequence with native encoding, or NULL */ - const char *zName /* Collating sequence name */ -){ - CollSeq *p; - sqlite3 *db = pParse->db; - - p = pColl; - if( !p ){ - p = sqlite3FindCollSeq(db, enc, zName, 0); - } - if( !p || !p->xCmp ){ - /* No collation sequence of this type for this encoding is registered. - ** Call the collation factory to see if it can supply us with one. - */ - callCollNeeded(db, enc, zName); - p = sqlite3FindCollSeq(db, enc, zName, 0); - } - if( p && !p->xCmp && synthCollSeq(db, p) ){ - p = 0; - } - assert( !p || p->xCmp ); - if( p==0 ){ - sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); - pParse->rc = SQLITE_ERROR_MISSING_COLLSEQ; - } - return p; -} - /* ** This routine is called on a collation sequence before it is used to ** check that it is defined. An undefined collation sequence exists when @@ -202,10 +157,10 @@ static CollSeq *findCollSeqEntry( ** See also: sqlite3LocateCollSeq(), sqlite3GetCollSeq() */ CollSeq *sqlite3FindCollSeq( - sqlite3 *db, - u8 enc, - const char *zName, - int create + sqlite3 *db, /* Database connection to search */ + u8 enc, /* Desired text encoding */ + const char *zName, /* Name of the collating sequence. Might be NULL */ + int create /* True to create CollSeq if doesn't already exist */ ){ CollSeq *pColl; if( zName ){ @@ -219,6 +174,85 @@ CollSeq *sqlite3FindCollSeq( return pColl; } +/* +** This function is responsible for invoking the collation factory callback +** or substituting a collation sequence of a different encoding when the +** requested collation sequence is not available in the desired encoding. +** +** If it is not NULL, then pColl must point to the database native encoding +** collation sequence with name zName, length nName. +** +** The return value is either the collation sequence to be used in database +** db for collation type name zName, length nName, or NULL, if no collation +** sequence can be found. If no collation is found, leave an error message. +** +** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq() +*/ +CollSeq *sqlite3GetCollSeq( + Parse *pParse, /* Parsing context */ + u8 enc, /* The desired encoding for the collating sequence */ + CollSeq *pColl, /* Collating sequence with native encoding, or NULL */ + const char *zName /* Collating sequence name */ +){ + CollSeq *p; + sqlite3 *db = pParse->db; + + p = pColl; + if( !p ){ + p = sqlite3FindCollSeq(db, enc, zName, 0); + } + if( !p || !p->xCmp ){ + /* No collation sequence of this type for this encoding is registered. + ** Call the collation factory to see if it can supply us with one. + */ + callCollNeeded(db, enc, zName); + p = sqlite3FindCollSeq(db, enc, zName, 0); + } + if( p && !p->xCmp && synthCollSeq(db, p) ){ + p = 0; + } + assert( !p || p->xCmp ); + if( p==0 ){ + sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); + pParse->rc = SQLITE_ERROR_MISSING_COLLSEQ; + } + return p; +} + +/* +** This function returns the collation sequence for database native text +** encoding identified by the string zName. +** +** If the requested collation sequence is not available, or not available +** in the database native encoding, the collation factory is invoked to +** request it. If the collation factory does not supply such a sequence, +** and the sequence is available in another text encoding, then that is +** returned instead. +** +** If no versions of the requested collations sequence are available, or +** another error occurs, NULL is returned and an error message written into +** pParse. +** +** This routine is a wrapper around sqlite3FindCollSeq(). This routine +** invokes the collation factory if the named collation cannot be found +** and generates an error message. +** +** See also: sqlite3FindCollSeq(), sqlite3GetCollSeq() +*/ +CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){ + sqlite3 *db = pParse->db; + u8 enc = ENC(db); + u8 initbusy = db->init.busy; + CollSeq *pColl; + + pColl = sqlite3FindCollSeq(db, enc, zName, initbusy); + if( !initbusy && (!pColl || !pColl->xCmp) ){ + pColl = sqlite3GetCollSeq(pParse, enc, pColl, zName); + } + + return pColl; +} + /* During the search for the best function definition, this procedure ** is called to test how well the function passed as the first argument ** matches the request for a function with nArg arguments in a system From 98c94e60d0b6a59c63cb0618be8307d34e3b97a6 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 22 Oct 2019 11:29:22 +0000 Subject: [PATCH 6/6] Previous check-in to fix [b47e3627ecaadbde] was incomplete. This check-in completes the fix and adds a test cases. FossilOrigin-Name: c7da1c01f1f239e68c2173ac5748b8c5798271e43bdcee68f51f97cd0ca92bd5 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/whereexpr.c | 7 +++++-- test/rowvalue.test | 16 ++++++++++++++++ 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 659ff29737..8c107179f6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Move\sthe\ssqlite3LocateCollSeq(),\ssqlite3FindCollSeq(),\sand\nsqlite3GetCollSeq()\sroutines\sso\sthat\sthey\sare\sall\sbeside\sone\sanother\sin\nthe\scallback.c\ssource\sfile.\s\sNo\slogic\schanges. -D 2019-10-22T01:00:16.928 +C Previous\scheck-in\sto\sfix\s[b47e3627ecaadbde]\swas\sincomplete.\s\sThis\scheck-in\ncompletes\sthe\sfix\sand\sadds\sa\stest\scases. +D 2019-10-22T11:29:22.330 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -614,7 +614,7 @@ F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd F src/where.c 148fa1ce9d6421a2c325291cae7681b3492cf1f219ff58f9ef38695a7f3c61ff F src/whereInt.h 4a296fd4fa79fdcbc2b5e8c1b898901617655811223e1082b899c23ecb092217 F src/wherecode.c 57d034a0dbca9f86e1a691f74e469ed09ff49d04712b838fb68596b76a9af7d2 -F src/whereexpr.c ab3c687a33aa3ca75744a74e82c0eab703a88627131cf72707f5346f04cb8539 +F src/whereexpr.c 0705f608f6dbbd4e95d440528d6c760b91b6f402ba4eb8b8d964c110e2010780 F src/window.c 064f251451c8e2a1c76b6269229d911a651e119c6a5f522b6eaebf8dc8714041 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -1260,7 +1260,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 a3e729d5c1f32da03bba15af1e3128218d2ba3c40d4f4ed5fa0497a713df68ea +F test/rowvalue.test e923271bc7448eb418e22af723e90223525d9c2a9d40acfc8124beac5dbb2bd6 F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b F test/rowvalue3.test 3068f508753af69884b12125995f023da0dbb256 F test/rowvalue4.test 02e35f7762371c2f57ebd856aa056eac56cb27ef7715a0bb31eac1895a745356 @@ -1847,7 +1847,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 90f7c477354d67d22d5eb0da22dac579f384ab44743fdc19887220e32203ebc2 -R 3a6f62c10243ee61b28a93dbeca6af23 +P 9ff80a9bf8fee776e2f282d0597215b77d48093ebc71d047ad1457da0582ddbc +R afcf07bfa3aa997eb10b76d021564d31 U drh -Z 533045e8c1f04d69c5fc59655d97ca67 +Z 3c9d55fa5bc6fe09c146135efce06e8a diff --git a/manifest.uuid b/manifest.uuid index 217b679a00..60f43863b3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9ff80a9bf8fee776e2f282d0597215b77d48093ebc71d047ad1457da0582ddbc \ No newline at end of file +c7da1c01f1f239e68c2173ac5748b8c5798271e43bdcee68f51f97cd0ca92bd5 \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index ea174e1f3e..7daf7508c7 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -111,8 +111,11 @@ static int allowedOp(int op){ ** are converted into "Y op X". */ static u16 exprCommute(Parse *pParse, Expr *pExpr){ - if( sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight) != - sqlite3BinaryCompareCollSeq(pParse, pExpr->pRight, pExpr->pLeft) ){ + if( pExpr->pLeft->op==TK_VECTOR + || pExpr->pRight->op==TK_VECTOR + || sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight) != + sqlite3BinaryCompareCollSeq(pParse, pExpr->pRight, pExpr->pLeft) + ){ pExpr->flags ^= EP_Commuted; } SWAP(Expr*,pExpr->pRight,pExpr->pLeft); diff --git a/test/rowvalue.test b/test/rowvalue.test index e859024711..813795dec3 100644 --- a/test/rowvalue.test +++ b/test/rowvalue.test @@ -570,4 +570,20 @@ do_execsql_test 22.100 { SELECT (SELECT 5,6 UNION SELECT 3,4 ORDER BY 1 DESC) IN (SELECT 5,6); } {1 0 1 0 0 1 0 1} +# 2019-10-21 Ticket b47e3627ecaadbde +# +do_execsql_test 23.100 { + DROP TABLE IF EXISTS t0; + CREATE TABLE t0(aa COLLATE NOCASE, bb); + INSERT INTO t0 VALUES('a', 'A'); + SELECT (+bb,1) >= (aa, 1), (aa,1)<=(+bb,1) FROM t0; + SELECT 2 FROM t0 WHERE (+bb,1) >= (aa,1); + SELECT 3 FROM t0 WHERE (aa,1) <= (+bb,1); +} {0 1 3} +do_execsql_test 23.110 { + SELECT (SELECT +bb,1) >= (aa, 1), (aa,1)<=(SELECT +bb,1) FROM t0; + SELECT 2 FROM t0 WHERE (SELECT +bb,1) >= (aa,1); + SELECT 3 FROM t0 WHERE (aa,1) <= (SELECT +bb,1); +} {0 1 3} + finish_test