From: dan Date: Mon, 1 Jun 2026 17:40:23 +0000 (+0000) Subject: Fix minor problems surrounding transitive WHERE constraints and explicit COLLATE... X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=2c351bbf823a38ef6f2ebe7094063edfe348cbfd;p=thirdparty%2Fsqlite.git Fix minor problems surrounding transitive WHERE constraints and explicit COLLATE terms. FossilOrigin-Name: 9500238a1d603a3f08a8fc0954725d5d217aab339720146ea0bc700e47b81c3c --- diff --git a/manifest b/manifest index 50b3013c6f..678ea89adf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C For\sexpressions\sof\sthe\sform\s"(x,\sy...)\sIN\s(SELECT\sa,\sb\s...)"\swhere\sthe\sresult\sis\snot\strue,\sconsider\sthe\scollation\ssequences\sof\scolumns\s"a"\sand\s"b"\swhen\sdeterminining\sif\sthe\sresult\sshould\sbe\sfalse\sor\sNULL.\sBug\sreport\s[bugs:/info/0785f45e67\s|\s2026-05-31T02:10:44Z]. -D 2026-06-01T16:20:40.090 +C Fix\sminor\sproblems\ssurrounding\stransitive\sWHERE\sconstraints\sand\sexplicit\sCOLLATE\sterms. +D 2026-06-01T17:40:23.826 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -821,8 +821,8 @@ F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 F src/where.c 33e4a6558ee69f33d6a4e7069e3a40a55959d14e5653a9a83926e70305d471f3 F src/whereInt.h 8d94cb116c9e06205c3d5ac87af065fc044f8cf08bfdccd94b6ea1c1308e65da -F src/wherecode.c 4d573077652f79780d6b50840ab8cbb72053dbb4eb230780dd2a146ab034475d -F src/whereexpr.c d111a5cb6147253a54010d883474b6aecc0b3009d352c087ee5295d74697bfef +F src/wherecode.c bc39ccbe3648f01157038b16cc55bdbff128590972b7185521b5526dc2815765 +F src/whereexpr.c 93d4bc513853d30ea32812f0ccb450c40e24cc6320b6127fd51e0eaaae418515 F src/window.c c0a38cd32473e8e8e7bc435039f914a36ca42465506dc491c65870c01ddac9fb F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test 4d7a34d328e58ca2a2d78fd76c27614a41ca7ddf4312ded9c68c04f430b3b47d @@ -1893,7 +1893,7 @@ F test/trace3.test 2deeac66359c9f007f0fc9fb6336994a5d68fc1a65129f322a9e9546fd537 F test/trans.test 45f6f9ab6f66a7b5744f1caac06b558f95da62501916906cf55586a896f9f439 F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76 F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94 -F test/transitive1.test 342b398e4c68deee65a940c5af22a95f44c3090b6539c7a19175afb48ac3fb93 +F test/transitive1.test d6252d06ddc104d13372fce0da93af501546bf5d75cb4d2a1f83b8c27238997a F test/trigger1.test 141bd2bbfa82fa91aed7391f50517373c9823ff8f55af35e56313dbc75112ca1 F test/trigger2.test 30fcb3a6aa6782020d47968735ee6086ed795f73a7affa9406c8d5a36e7b5265 F test/trigger3.test aa640bb2bbb03edd5ff69c055117ea088f121945 @@ -2207,8 +2207,11 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c -P 9d0e39408075f22dd56ad5fb50ef458c0cd6a4ec234dd43b3a5f5e0ac4447b61 -R 6c45aea14ae78491d19d28f656b2630e +P 04d7a9d788cf0bb811483baceb9142f67d4a2380d4af409d5300a92f7972472e +R 1e97b514b880ee32443ecbfc2b420010 +T *branch * transitive-where-collate-bugs +T *sym-transitive-where-collate-bugs * +T -sym-trunk * U dan -Z bab66a4f49188f1b9bc42e9017a50609 +Z 922c3ff18e7c90a79ce111a4037533f3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.tags b/manifest.tags index bec971799f..9b05b4774c 100644 --- a/manifest.tags +++ b/manifest.tags @@ -1,2 +1,2 @@ -branch trunk -tag trunk +branch transitive-where-collate-bugs +tag transitive-where-collate-bugs diff --git a/manifest.uuid b/manifest.uuid index 8e835dfb67..d7dfed4f30 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -04d7a9d788cf0bb811483baceb9142f67d4a2380d4af409d5300a92f7972472e +9500238a1d603a3f08a8fc0954725d5d217aab339720146ea0bc700e47b81c3c diff --git a/src/wherecode.c b/src/wherecode.c index 8da485f64e..8a1a593c70 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -2717,6 +2717,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( WO_EQ|WO_IN|WO_IS, 0); if( pAlt==0 ) continue; if( pAlt->wtFlags & (TERM_CODED) ) continue; + if( ExprHasProperty(pAlt->pExpr, EP_Collate) ) continue; if( (pAlt->eOperator & WO_IN) && ExprUseXSelect(pAlt->pExpr) && (pAlt->pExpr->x.pSelect->pEList->nExpr>1) diff --git a/src/whereexpr.c b/src/whereexpr.c index 91a3bf783a..4c4c15c72a 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -954,7 +954,8 @@ static void exprAnalyzeOrTerm( ** 3. Not originating in the ON clause of an OUTER JOIN ** 4. The operator is not IS or else the query does not contain RIGHT JOIN ** 5. The affinities of A and B must be compatible -** 6. Both operands use the same collating sequence +** 6. Both operands use the same collating sequence, and they must not +** use explicit COLLATE clauses. ** If this routine returns TRUE, that means that the RHS can be substituted ** for the LHS anyplace else in the WHERE clause where the LHS column occurs. ** This is an optimization. No harm comes from returning 0. But if 1 is @@ -963,6 +964,7 @@ static void exprAnalyzeOrTerm( static int termIsEquivalence(Parse *pParse, Expr *pExpr, SrcList *pSrc){ char aff1, aff2; if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; /* (1) */ + if( ExprHasProperty(pExpr, EP_Collate) ) return 0; if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; /* (2) */ if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* (3) */ assert( pSrc!=0 ); diff --git a/test/transitive1.test b/test/transitive1.test index 1df4ecec58..60e8cacab0 100644 --- a/test/transitive1.test +++ b/test/transitive1.test @@ -14,6 +14,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +set testprefix transitive1 do_execsql_test transitive1-100 { CREATE TABLE t1(a TEXT, b TEXT, c TEXT COLLATE NOCASE); @@ -437,4 +438,89 @@ do_execsql_test transitive1-900 { SELECT * FROM t1 CROSS JOIN t2 WHERE a=b AND b='ABC'; } {abc abc} +#------------------------------------------------------------------------- +reset_db +db cache size 0 + +do_execsql_test 1000 { + PRAGMA automatic_index = 0; + + CREATE TABLE t1(a TEXT); + CREATE TABLE t2(b TEXT); + + INSERT INTO t1 VALUES ('hello'); + INSERT INTO t1 VALUES ('Hello'); + INSERT INTO t1 VALUES ('HELLO'); + INSERT INTO t1 VALUES ('HeLLo'); + + INSERT INTO t2 VALUES ('hello'); + INSERT INTO t2 VALUES ('Hello'); + INSERT INTO t2 VALUES ('HELLO'); + INSERT INTO t2 VALUES ('HeLLo'); +} + +optimization_control db transitive 1 + +do_execsql_test 1010 { + SELECT t1.a, t2.b + FROM t1 CROSS JOIN t2 + WHERE t1.a = t2.b + AND t2.b COLLATE NOCASE = 'Hello'; +} { + hello hello + Hello Hello + HELLO HELLO + HeLLo HeLLo +} + +optimization_control db transitive 0 + +do_execsql_test 1020 { + SELECT t1.a, t2.b + FROM t1 CROSS JOIN t2 + WHERE t1.a = t2.b + AND t2.b COLLATE NOCASE = 'Hello'; +} { + hello hello + Hello Hello + HELLO HELLO + HeLLo HeLLo +} + +#------------------------------------------------------------------------- +reset_db + +do_execsql_test 1100 { + PRAGMA automatic_index = 0; + CREATE TABLE t1(x); + CREATE TABLE t2(y); + + INSERT INTO t1 VALUES('ABC'); + INSERT INTO t2 VALUES('abc'); +} + +do_execsql_test 1110 { + SELECT * FROM t1 CROSS JOIN t2 + WHERE (t1.x COLLATE nocase) = (t2.y COLLATE nocase) + AND (t2.y = 'ABC') +} {} + +#------------------------------------------------------------------------- +reset_db + +do_execsql_test 1200 { + PRAGMA automatic_index = 0; + CREATE TABLE t1(x); + CREATE TABLE t2(y); + + INSERT INTO t1 VALUES('ABC'); + INSERT INTO t2 VALUES('ABC'); +} + +do_execsql_test 1210 { + SELECT * FROM t1 CROSS JOIN t2 + WHERE t1.x = t2.y + AND (t1.x COLLATE nocase = 'abc') +} {ABC ABC} + finish_test