From 24ad808809ae04bb7db7a5060e3518e1875807a9 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 10 Aug 2026 15:57:42 +0000 Subject: [PATCH] When comparing row values that are sub-selects, do not consider the collation sequences of the expressions returned by the sub-select when determining the collation sequences to use for the comparisons. i.e. in "(a, b)=(SELECT c, d)", do not consider the collation sequences of "c" or "d". Fix for problem [forum:/info/2026-08-09T09:33:49Z | 2026-08-09T09:33:49Z]. FossilOrigin-Name: 88580851be734d1917809a4254f2f117df58c71b4c118509ccb4756a300fa6e6 --- manifest | 18 ++++++++--------- manifest.uuid | 2 +- src/expr.c | 19 ++++++++++++++---- test/rowvalue.test | 7 ++++++- test/rowvalueA.test | 47 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 78 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 7888994c51..5b8daf2b3b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\ssome\sstray\sdebug\soutput\sand\sobsolete\sbug-hunting\scomments.\sNo\sfunctional\schanges. -D 2026-08-10T12:45:11.856 +C When\scomparing\srow\svalues\sthat\sare\ssub-selects,\sdo\snot\sconsider\sthe\scollation\ssequences\sof\sthe\sexpressions\sreturned\sby\sthe\ssub-select\swhen\sdetermining\sthe\scollation\ssequences\sto\suse\sfor\sthe\scomparisons.\si.e.\sin\s"(a,\sb)=(SELECT\sc,\sd)",\sdo\snot\sconsider\sthe\scollation\ssequences\sof\s"c"\sor\s"d".\sFix\sfor\sproblem\s[forum:/info/2026-08-09T09:33:49Z\s|\s2026-08-09T09:33:49Z]. +D 2026-08-10T15:57:42.296 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -693,7 +693,7 @@ F src/date.c e1a002a4199bfa85e8778c0f72182c679580b131147d8e46d9221cfceffb8500 F src/dbpage.c ec8590c5e7a564cef28ca3c6156521316a4d26cb572a34841b0bcb26b67b3f97 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/delete.c 59eeca3fb88c29329afc41bb803ee568b120d9dd7470b5f38ab55cc38390b451 -F src/expr.c 43c750797e82d5686c0f198d759f77d9c9166038837d7574d75d71649e09a335 +F src/expr.c 2742c38bb91edf4912d1009c5688b3fad1fde42fb5210d7ac36f9dc9fed8daa6 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 931f74cec1dc8038a0217ef340c91ce147dd1bbed08dc40c47ee0ec6edfffb08 F src/func.c d833ab92ed95e84af60247e7d752cda33234d8979173442079d54d96e9853dd9 @@ -1572,7 +1572,7 @@ F test/round1.test 29c3c9039936ed024d672f003c4d35ee11c14c0acb75c5f7d6188ff16190c F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test d27191b5ce794c05bf61081e8b2c546a1844c1641321dcaf7fb785234256cc8e -F test/rowvalue.test ba43ff378f78c81579dd0f9f2b1e92876d29fb767f090acb7d4cbc6ff4a3c42c +F test/rowvalue.test 618aed15055f16433b190c8cde163edcc53fed030a137ae846f503b6bbbfde02 F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b F test/rowvalue3.test 103e9a224ca0548dd0d67e439f39c5dd16de4200221a333927372408c025324c F test/rowvalue4.test 6e160977d44ee715e142f63ec0e339586c61f12bbbffacee369b1cdc0b7390f0 @@ -1581,7 +1581,7 @@ F test/rowvalue6.test d19b54feb604d5601f8614b15e214e0774c01087 F test/rowvalue7.test 06ec0aca725bf683313d03793aa2943bc7f45a901848c7056a9665b769c8fc38 F test/rowvalue8.test 5900eddad9e2c3c2e26f1a95f74aafc1232ee5e0 F test/rowvalue9.test 7499a8fd7ca3a3f0e19d94e135355439aa2b596f86b775ca8de79672da2ca378 -F test/rowvalueA.test 5849865659f27ec50ba3185b2e18928a92077ceddf121ee6b95bf32300d44c91 +F test/rowvalueA.test ada58d05065f6efe6a1349fcfedb16c199100409bf5085b418f4d71ba55f2be8 F test/rowvaluefault.test 963ae9cdaed30a85a29668dd514e639f3556cae903ee9f172ea972d511c54fff F test/rowvaluevtab.test cd9747bb3f308086944c07968f547ad6b05022e698d80b9ffbdfe09ce0b8da6f F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 @@ -2218,8 +2218,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c -P fa17d89f76d50c153b6ff7ca96ae06c1ddc130abc3c0056dac3ef6d66f4f40c5 -R 127160869ca6d637e36be784d70a188c -U stephan -Z ad783f0a5f9c5e2841fc3e097e220208 +P 41443d5ffe1f6852f447181071a0d9dac89df51c836d16b1bd9420a8513d2ec2 +R b82d9adfa55d7b3598f7b5d98b79ff5b +U dan +Z 004f08304a606d23ed8cc9adf41bcc49 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4f05b2b7a5..c418693ce1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -41443d5ffe1f6852f447181071a0d9dac89df51c836d16b1bd9420a8513d2ec2 +88580851be734d1917809a4254f2f117df58c71b4c118509ccb4756a300fa6e6 diff --git a/src/expr.c b/src/expr.c index f24af0aa47..5bc19e8cb5 100644 --- a/src/expr.c +++ b/src/expr.c @@ -663,6 +663,7 @@ static int exprVectorRegister( Expr *pVector, /* Vector to extract element from */ int iField, /* Field to extract from pVector */ int regSelect, /* First in array of registers */ + Expr *pTmp, /* Temporary space */ Expr **ppExpr, /* OUT: Expression element */ int *pRegFree /* OUT: Temp register to free */ ){ @@ -674,8 +675,17 @@ static int exprVectorRegister( } if( op==TK_SELECT ){ assert( ExprUseXSelect(pVector) ); - *ppExpr = pVector->x.pSelect->pEList->a[iField].pExpr; - return regSelect+iField; + /* Use the temporary expression node to wrap expression iField of the + ** sub-select in a TK_SELECT_COLUMN node. This causes the caller to + ** use the affinity of the expression in any comparison, but not the + ** collation sequence. */ + memset(pTmp, 0, sizeof(Expr)); + pTmp->op = TK_SELECT_COLUMN; + pTmp->pLeft = pVector; + pTmp->iColumn = iField; + pTmp->iTable = pVector->x.pSelect->pEList->nExpr; + *ppExpr = pTmp; + return regSelect+iField; } if( op==TK_VECTOR ){ assert( ExprUseXList(pVector) ); @@ -742,11 +752,12 @@ static void codeVectorCompare( for(i=0; 1 /*Loop exits by "break"*/; i++){ int regFree1 = 0, regFree2 = 0; Expr *pL = 0, *pR = 0; + Expr tmp1, tmp2; int r1, r2; assert( i>=0 && i= (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} +} {1 1 2 3} +do_execsql_test 23.120 { + SELECT (SELECT +bb) >= (aa), (aa)<=(SELECT +bb) FROM t0; + SELECT 2 FROM t0 WHERE (SELECT +bb) >= (aa); + SELECT 3 FROM t0 WHERE (aa) <= (SELECT +bb); +} {1 1 2 3} # 2019-10-22 Ticket 6ef984af8972c2eb do_execsql_test 24.100 { diff --git a/test/rowvalueA.test b/test/rowvalueA.test index 9e0195f394..aa845ca895 100644 --- a/test/rowvalueA.test +++ b/test/rowvalueA.test @@ -142,4 +142,51 @@ do_execsql_test 5.3 { ORDER BY +a; } {a NULL b ABCD} +#------------------------------------------------------------------------- +# Bug report https://sqlite.org/bugs/info/2026-08-09T09:33:49Z +# +do_execsql_test 6.1 { + SELECT 'abc' = (SELECT 'ABC' COLLATE nocase); +} {0} + +do_execsql_test 6.2 { + SELECT 'abc' IN (SELECT 'ABC' COLLATE nocase); +} {1} + +do_execsql_test 6.3 { + SELECT ('abc', 1) = (SELECT 'ABC' COLLATE nocase, 1); +} {0} + +do_execsql_test 6.4 { + SELECT ( SELECT CAST(123 AS INTEGER) )=='123' +} {1} +do_execsql_test 6.5 { + SELECT (SELECT CAST(123 AS INTEGER), 1)==('123', 1) +} {1} + +do_execsql_test 6.6 { + SELECT ( SELECT 123 )=='123' +} {0} + +do_execsql_test 6.7 { + CREATE TABLE t33(a, b, c); + INSERT INTO t33 VALUES ('abc', 1, 'i'); + INSERT INTO t33 VALUES ('ABC', 1, 'ii'); +} + +do_execsql_test 6.8 { + SELECT c FROM t33 WHERE (a, b) = (SELECT 'abc' COLLATE nocase, 1); +} {i} + +do_execsql_test 6.9 { + SELECT (a, b) = (SELECT 'abc' COLLATE nocase, 1) FROM t33; +} {1 0} + +do_execsql_test 6.10 { + SELECT c FROM t33 WHERE CASE WHEN 1 + THEN (a, b) = (SELECT 'abc' COLLATE nocase, 1) + ELSE (a, b) = (SELECT 'abc' COLLATE nocase, 1) + END; +} {i} + finish_test