From: drh <> Date: Mon, 1 Jun 2026 16:38:10 +0000 (+0000) Subject: For expressions of the form "(x, y...) IN (SELECT a, b ...)" where the X-Git-Tag: release~14 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=4902f35e63f7e56ce36bc577b8281ad2edad64ed;p=thirdparty%2Fsqlite.git For expressions of the form "(x, y...) IN (SELECT a, b ...)" where the result is not true, consider the collation sequences of columns "a" and "b" when determinining if the result should be false or NULL. FossilOrigin-Name: 5ceba3fe8d9fb2b1e44a048b6e010d427b7f464b727b58824a2af1b53d57f1ec --- diff --git a/manifest b/manifest index d36fecd9e5..68bdecb6ed 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sminor\sproblem\swith\stest\scase\smjournal-3.3. -D 2026-06-01T15:47:23.358 +C For\sexpressions\sof\sthe\sform\s"(x,\sy...)\sIN\s(SELECT\sa,\sb\s...)"\swhere\sthe\s\nresult\sis\snot\strue,\sconsider\sthe\scollation\ssequences\sof\scolumns\s"a"\sand\s"b"\s\nwhen\sdeterminining\sif\sthe\sresult\sshould\sbe\sfalse\sor\sNULL. +D 2026-06-01T16:38:10.425 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -685,7 +685,7 @@ F src/date.c 61e92f1f7e2e88e1cd91e91dc69eb2b2854e7877254470f9fabd776bfac922b8 F src/dbpage.c 98c716bc5c0c70af4e7934bfcddd707f14e78b5d4cf1e0602a07b485e1af2e74 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/delete.c 1f2268d6fe3c78fc1bf794ba65d7026498b78e2342ffaf85825dedae546e6fde -F src/expr.c 36b66d6b5b44a88ec2d54009257b72ad80405905c3910782a35bd8be80dc19c3 +F src/expr.c 8a458928fe502526d4ce90fa4e084a6e1a4dceb6da747381973b5b0086b1492c F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 931f74cec1dc8038a0217ef340c91ce147dd1bbed08dc40c47ee0ec6edfffb08 F src/func.c 76e790b7b32895195e4c474259952d6a0ae10b53c0e35f4a2a2c4bc79eb29067 @@ -1468,7 +1468,7 @@ F test/notnull.test a37b663d5bb728d66fc182016613fb8e4a0a4bbf3d75b8876a7527f7d4ed F test/notnull2.test c2c7b670fb8fa6ffe5f9cc08af88864fbb8237e28b56ad528e8dee921019c5fe F test/notnullfault.test fc4bb7845582a2b3db376001ef49118393b1b11abe0d24adb03db057ee2b73d5 F test/null.test b7ff206a1c60fe01aa2abd33ef9ea83c93727d993ca8a613de86e925c9f2bc6f -F test/nulls1.test 7a5e4346ee4285034100b4cd20e6784f16a9d6c927e44ecdf10034086bbee9c9 +F test/nulls1.test 8fc70d75ab363b0f2ce9151669c2cb897def5064e2e30f7d9322970480bf6e87 F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1 F test/numindex1.test 20a5450d4b056e48cd5db30e659f13347a099823 F test/offset1.test c21e67d2d5ae8ed310243fbe84fc2f0dca49e9ffed3ea89110c0d5914c0de620 @@ -2198,9 +2198,9 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c -P 27b4f821c752a65197746952cc168fab6a3aa0039d1a0100e3d8415225b5d4bf -Q +80093dc0610438cd506d230eca12e699e05395aecb8048c5bc066379b927e8bb -R 778148befaeb7e051c603e7b3044770a +P dc1cc4d908df0e36447d0422ecbbbb6d2f59c7b49243407f8a9602e7bb0d1a00 +Q +04d7a9d788cf0bb811483baceb9142f67d4a2380d4af409d5300a92f7972472e +R 407f163d07684535b5d14e92c70ec991 U drh -Z fb6b7414dfe7e76890f57c03d5307ec1 +Z c6afdb83ed161a9d5b4f6c0be022d3c7 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3db6fe14ac..a23f3edc2a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dc1cc4d908df0e36447d0422ecbbbb6d2f59c7b49243407f8a9602e7bb0d1a00 +5ceba3fe8d9fb2b1e44a048b6e010d427b7f464b727b58824a2af1b53d57f1ec diff --git a/src/expr.c b/src/expr.c index c8236c0602..0a7041bf96 100644 --- a/src/expr.c +++ b/src/expr.c @@ -4262,7 +4262,16 @@ static void sqlite3ExprCodeIN( CollSeq *pColl; int r3 = sqlite3GetTempReg(pParse); p = sqlite3VectorFieldSubexpr(pLeft, i); - pColl = sqlite3ExprCollSeq(pParse, p); + if( ExprUseXSelect(pExpr) ){ + Expr *pRhs = pExpr->x.pSelect->pEList->a[i].pExpr; + pColl = sqlite3BinaryCompareCollSeq(pParse, p, pRhs); + }else{ + /* If the RHS of the IN(...) expression are scalar expressions, do + ** not consider their collation sequences. The documentation says + ** "The collating sequence used for expressions of the form "x IN (y, z, + ** ...)" is the collating sequence of x.". */ + pColl = sqlite3ExprCollSeq(pParse, p); + } sqlite3VdbeAddOp3(v, OP_Column, iTab, i, r3); sqlite3VdbeAddOp4(v, OP_Ne, rLhs+i, destNotNull, r3, (void*)pColl, P4_COLLSEQ); diff --git a/test/nulls1.test b/test/nulls1.test index c44d0af251..76ef3dc1df 100644 --- a/test/nulls1.test +++ b/test/nulls1.test @@ -336,6 +336,34 @@ do_execsql_test 10.51 { ORDER BY +d NULLS LAST, +c NULLS LAST; } {X 3 X | X 4 X | X 5 X | X 7 X | X {} X | {} {} {} | Y {} {} |} +#------------------------------------------------------------------------- +reset_db + +do_execsql_test 11.1 { + CREATE TABLE t1(a TEXT COLLATE NOCASE, b TEXT); + INSERT INTO t1 VALUES('Hello', 'world'); +} + +foreach {tn sql res} { + 0 "SELECT null" NULL + + 1 "SELECT ('hello', NULL) IN (SELECT a, b FROM t1)" NULL + 2 "SELECT NOT ('hello', NULL) IN (SELECT a, b FROM t1)" NULL + + 3 "SELECT ('Hello', NULL) IN (SELECT a, b FROM t1)" NULL + 4 "SELECT ('Hello' COLLATE NOCASE, NULL) IN (SELECT a, b FROM t1)" NULL + 5 "SELECT ('hello', 'world') IN (SELECT a, b FROM t1)" 1 + + 6 "SELECT ('hi', NULL) IN (SELECT a, b FROM t1)" 0 + + 7 "SELECT ('hello', NULL) IN ((a, b), (3, 4), (5, 6)) FROM t1" 0 + 8 "SELECT (a, b) IN (('hello', NULL), (3, 4), (5, 6)) FROM t1" NULL + + 9 "SELECT ('Hello', NULL) IN ((a, b), (3, 4), (5, 6)) FROM t1" NULL +} { + db nullvalue NULL + do_execsql_test 11.2.$tn $sql $res +}