Transitive constraints should only work if operands have compatible
affinities and collating sequences. FossilOrigin-Name: 5df4056448fee1c766f8f79c735ed12abdce5101
This commit is contained in:
commit
a48bae8819
15
manifest
15
manifest
@ -1,5 +1,5 @@
|
||||
C Make\sa\shard\scopy\sof\sthe\sresults\sof\sa\ssubquery\slest\sthe\sresult\sof\sthe\nsubquery\sbe\sreferenced\safter\sa\schange\sto\sthe\stable\sthat\sgenerated\sthe\ssubquery\nresult.
|
||||
D 2015-05-18T04:24:27.963
|
||||
C Transitive\sconstraints\sshould\sonly\swork\sif\soperands\shave\scompatible\naffinities\sand\scollating\ssequences.
|
||||
D 2015-05-18T12:28:09.009
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in edfc69769e613a6359c42c06ea1d42c3bece1736
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@ -307,7 +307,7 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
|
||||
F src/wal.c ce2cb2d06faab54d1bce3e739bec79e063dd9113
|
||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||
F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804
|
||||
F src/where.c 430ae75d8850ea9e3c7ceba8e05adb105300ddb4
|
||||
F src/where.c e71eae3b1383249c3b5d136d6b71ca8d28fb8d61
|
||||
F src/whereInt.h a6f5a762bc1b4b1c76e1cea79976b437ac35a435
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
@ -1082,7 +1082,7 @@ F test/trace2.test f5cb67ad3bc09e0c58e8cca78dfd0b5639259983
|
||||
F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6
|
||||
F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76
|
||||
F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94
|
||||
F test/transitive1.test 875a9f0097a15b30a62431d183f989364d5accac
|
||||
F test/transitive1.test 293300f46916569f08875cdb2fe2134be2c27677
|
||||
F test/trigger1.test dc47573ac79ffe0ee3eecaa517d70d8dacbccd03
|
||||
F test/trigger2.test 5cd7d69a7ba1143ee045e4ae2963ff32ae4c87a6
|
||||
F test/trigger3.test aa640bb2bbb03edd5ff69c055117ea088f121945
|
||||
@ -1258,7 +1258,8 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P ee4b74250ad7a4061421d44b490cb79f649b3720
|
||||
R cec1b3be1402a8f9c8bcb82830e4cc3b
|
||||
P 9c0d80907b4dee8ee8f205c2ebdb759f5ba1d771 204e567f68e4b3e069f04ca0643c6e5db781d39f
|
||||
R a4e8ba2aafa10a2da2324dbd46c77e5c
|
||||
T +closed 204e567f68e4b3e069f04ca0643c6e5db781d39f
|
||||
U drh
|
||||
Z f5d245b9071d9cc745d677044b477f63
|
||||
Z b4b536b620859a084b09e8398affe376
|
||||
|
@ -1 +1 @@
|
||||
9c0d80907b4dee8ee8f205c2ebdb759f5ba1d771
|
||||
5df4056448fee1c766f8f79c735ed12abdce5101
|
48
src/where.c
48
src/where.c
@ -1182,6 +1182,46 @@ static void exprAnalyzeOrTerm(
|
||||
}
|
||||
#endif /* !SQLITE_OMIT_OR_OPTIMIZATION && !SQLITE_OMIT_SUBQUERY */
|
||||
|
||||
/*
|
||||
** We already know that pExpr is a binary operator where both operands are
|
||||
** column references. This routine checks to see if pExpr is an equivalence
|
||||
** relation:
|
||||
** 1. The SQLITE_Transitive optimization must be enabled
|
||||
** 2. Must be either an == or an IS operator
|
||||
** 3. Not originating the ON clause of an OUTER JOIN
|
||||
** 4. The affinities of A and B must be compatible
|
||||
** 5a. Both operands use the same collating sequence OR
|
||||
** 5b. The overall collating sequence is BINARY
|
||||
** 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
|
||||
** returned when it should not be, then incorrect answers might result.
|
||||
*/
|
||||
static int termIsEquivalence(Parse *pParse, Expr *pExpr){
|
||||
char aff1, aff2;
|
||||
CollSeq *pColl;
|
||||
const char *zColl1, *zColl2;
|
||||
if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0;
|
||||
if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0;
|
||||
if( ExprHasProperty(pExpr, EP_FromJoin) ) return 0;
|
||||
aff1 = sqlite3ExprAffinity(pExpr->pLeft);
|
||||
aff2 = sqlite3ExprAffinity(pExpr->pRight);
|
||||
if( aff1!=aff2
|
||||
&& (!sqlite3IsNumericAffinity(aff1) || !sqlite3IsNumericAffinity(aff2))
|
||||
){
|
||||
return 0;
|
||||
}
|
||||
pColl = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight);
|
||||
if( pColl==0 || sqlite3StrICmp(pColl->zName, "BINARY")==0 ) return 1;
|
||||
pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
|
||||
/* Since pLeft and pRight are both a column references, their collating
|
||||
** sequence should always be defined. */
|
||||
zColl1 = ALWAYS(pColl) ? pColl->zName : 0;
|
||||
pColl = sqlite3ExprCollSeq(pParse, pExpr->pRight);
|
||||
zColl2 = ALWAYS(pColl) ? pColl->zName : 0;
|
||||
return sqlite3StrICmp(zColl1, zColl2)==0;
|
||||
}
|
||||
|
||||
/*
|
||||
** 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
|
||||
@ -1276,16 +1316,14 @@ static void exprAnalyze(
|
||||
if( idxNew==0 ) return;
|
||||
pNew = &pWC->a[idxNew];
|
||||
markTermAsChild(pWC, idxNew, idxTerm);
|
||||
if( op==TK_IS ) pNew->wtFlags |= TERM_IS;
|
||||
pTerm = &pWC->a[idxTerm];
|
||||
pTerm->wtFlags |= TERM_COPIED;
|
||||
if( (op==TK_EQ || op==TK_IS)
|
||||
&& !ExprHasProperty(pExpr, EP_FromJoin)
|
||||
&& OptimizationEnabled(db, SQLITE_Transitive)
|
||||
){
|
||||
|
||||
if( termIsEquivalence(pParse, pDup) ){
|
||||
pTerm->eOperator |= WO_EQUIV;
|
||||
eExtraOp = WO_EQUIV;
|
||||
}
|
||||
if( op==TK_IS ) pNew->wtFlags |= TERM_IS;
|
||||
}else{
|
||||
pDup = pExpr;
|
||||
pNew = pTerm;
|
||||
|
@ -296,5 +296,61 @@ do_execsql_test transitive1-410 {
|
||||
GROUP BY episodeview.c12;
|
||||
} {1 /tmp/tvshows/The.Big.Bang.Theory/ {The Big Bang Theory} {Leonard Hofstadter and Sheldon Cooper are brilliant physicists, the kind of "beautiful minds" that understand how the universe works. But none of that genius helps them interact with people, especially women. All this begins to change when a free-spirited beauty named Penny moves in next door. Sheldon, Leonard's roommate, is quite content spending his nights playing Klingon Boggle with their socially dysfunctional friends, fellow CalTech scientists Howard Wolowitz and Raj Koothrappali. However, Leonard sees in Penny a whole new universe of possibilities... including love.} 2007-09-24 Comedy CBS TV-PG 3 1 0}
|
||||
|
||||
##############################################################################
|
||||
# 2015-05-18. Make sure transitive constraints are avoided when column
|
||||
# affinities and collating sequences get in the way.
|
||||
#
|
||||
db close
|
||||
forcedelete test.db
|
||||
sqlite3 db test.db
|
||||
do_execsql_test transitive1-500 {
|
||||
CREATE TABLE x(i INTEGER PRIMARY KEY, y TEXT);
|
||||
INSERT INTO x VALUES(10, '10');
|
||||
SELECT * FROM x WHERE x.y>='1' AND x.y<'2' AND x.i=x.y;
|
||||
} {10 10}
|
||||
do_execsql_test transitive1-510 {
|
||||
CREATE TABLE t1(x TEXT);
|
||||
CREATE TABLE t2(y TEXT);
|
||||
INSERT INTO t1 VALUES('abc');
|
||||
INSERT INTO t2 VALUES('ABC');
|
||||
SELECT * FROM t1 CROSS JOIN t2 WHERE (x=y COLLATE nocase) AND y='ABC';
|
||||
} {abc ABC}
|
||||
do_execsql_test transitive1-520 {
|
||||
CREATE TABLE t3(i INTEGER PRIMARY KEY, t TEXT);
|
||||
INSERT INTO t3 VALUES(10, '10');
|
||||
SELECT * FROM t3 WHERE i=t AND t = '10 ';
|
||||
} {}
|
||||
do_execsql_test transitive1-530 {
|
||||
CREATE TABLE u1(x TEXT, y INTEGER, z TEXT);
|
||||
CREATE INDEX i1 ON u1(x);
|
||||
INSERT INTO u1 VALUES('00013', 13, '013');
|
||||
SELECT * FROM u1 WHERE x=y AND y=z AND z='013';
|
||||
} {00013 13 013}
|
||||
do_execsql_test transitive1-540 {
|
||||
CREATE TABLE b1(x, y);
|
||||
INSERT INTO b1 VALUES('abc', 'ABC');
|
||||
CREATE INDEX b1x ON b1(x);
|
||||
SELECT * FROM b1 WHERE (x=y COLLATE nocase) AND y='ABC';
|
||||
} {abc ABC}
|
||||
do_execsql_test transitive1-550 {
|
||||
CREATE TABLE c1(x, y COLLATE nocase, z);
|
||||
INSERT INTO c1 VALUES('ABC', 'ABC', 'abc');
|
||||
SELECT * FROM c1 WHERE x=y AND y=z AND z='abc';
|
||||
} {ABC ABC abc}
|
||||
do_execsql_test transitive1-560 {
|
||||
CREATE INDEX c1x ON c1(x);
|
||||
SELECT * FROM c1 WHERE x=y AND y=z AND z='abc';
|
||||
} {ABC ABC abc}
|
||||
do_execsql_test transitive1-560eqp {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM c1 WHERE x=y AND y=z AND z='abc';
|
||||
} {/SCAN TABLE c1/}
|
||||
do_execsql_test transitive1-570 {
|
||||
SELECT * FROM c1 WHERE x=y AND z=y AND z='abc';
|
||||
} {}
|
||||
do_execsql_test transitive1-570eqp {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM c1 WHERE x=y AND z=y AND z='abc';
|
||||
} {/SEARCH TABLE c1 USING INDEX c1x/}
|
||||
|
||||
finish_test
|
||||
|
Loading…
Reference in New Issue
Block a user