Avoid unnecessary collating sequence and affinity restrictions on the use

of transitivity.  Add test cases to show that the restrictions are not 
needed.

FossilOrigin-Name: 56549f45666b53876012df5c2bdf813474e10925
This commit is contained in:
drh 2013-01-17 16:18:55 +00:00
parent 738fc79dcf
commit 63db0392ae
4 changed files with 65 additions and 36 deletions

View File

@ -1,5 +1,5 @@
C Make\smore\saggressive\suse\sof\stransitivity\sin\soptimizing\squeries.\s\sAdd\sa\stest\ncase. C Avoid\sunnecessary\scollating\ssequence\sand\saffinity\srestrictions\son\sthe\suse\nof\stransitivity.\s\sAdd\stest\scases\sto\sshow\sthat\sthe\srestrictions\sare\snot\s\nneeded.
D 2013-01-17T15:05:17.153 D 2013-01-17T16:18:55.615
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in a48faa9e7dd7d556d84f5456eabe5825dd8a6282 F Makefile.in a48faa9e7dd7d556d84f5456eabe5825dd8a6282
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -252,7 +252,7 @@ F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83
F src/wal.c f5c7b5027d0ed0e9bc9afeb4a3a8dfea762ec7d2 F src/wal.c f5c7b5027d0ed0e9bc9afeb4a3a8dfea762ec7d2
F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6
F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b
F src/where.c 701c32fecbcf44d749a8fdacb887ffdcec21a3e5 F src/where.c 79c257691c5cbe92fae9dc35465392cbd11c3e31
F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
@ -896,6 +896,7 @@ F test/trace2.test c1dc104a8d11a347c870cfea6235e3fc6f6cb06d
F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6 F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6
F test/trans2.test d5337e61de45e66b1fcbf9db833fa8c82e624b22 F test/trans2.test d5337e61de45e66b1fcbf9db833fa8c82e624b22
F test/trans3.test 373ac5183cc56be69f48ae44090e7f672939f732 F test/trans3.test 373ac5183cc56be69f48ae44090e7f672939f732
F test/transitive1.test d04aa9023e425d6f2d4aa61dd81ee9e102f89062
F test/trigger1.test 30f343f91586765874a28ad539c06f5a5f049931 F test/trigger1.test 30f343f91586765874a28ad539c06f5a5f049931
F test/trigger2.test 834187beafd1db383af0c659cfa49b0576832816 F test/trigger2.test 834187beafd1db383af0c659cfa49b0576832816
F test/trigger3.test d2c60d8be271c355d61727411e753181e877230a F test/trigger3.test d2c60d8be271c355d61727411e753181e877230a
@ -1033,7 +1034,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
P fe152f8b048c9a18f99fa6096ff0e68dd630c318 P d96762841a461e192fb2f317d684d000376350dd
R f7b812e14ccd12b59aae7b48f0da1945 R da60dbccb0041de3b6506adfaa629abe
U drh U drh
Z eaf427dd060ebdbe2c55df9e5c68a5b1 Z 92f034648a2e7d96254ca815101088e3

View File

@ -1 +1 @@
d96762841a461e192fb2f317d684d000376350dd 56549f45666b53876012df5c2bdf813474e10925

View File

@ -687,7 +687,9 @@ static WhereTerm *findTerm(
pX = pTerm->pExpr; pX = pTerm->pExpr;
pParse = pWC->pParse; pParse = pWC->pParse;
idxaff = pIdx->pTable->aCol[iOrigCol].affinity; idxaff = pIdx->pTable->aCol[iOrigCol].affinity;
if( !sqlite3IndexAffinityOk(pX, idxaff) ) continue; if( !sqlite3IndexAffinityOk(pX, idxaff) ){
continue;
}
/* Figure out the collation sequence required from an index for /* Figure out the collation sequence required from an index for
** it to be useful for optimising expression pX. Store this ** it to be useful for optimising expression pX. Store this
@ -700,7 +702,9 @@ static WhereTerm *findTerm(
for(j=0; pIdx->aiColumn[j]!=iOrigCol; j++){ for(j=0; pIdx->aiColumn[j]!=iOrigCol; j++){
if( NEVER(j>=pIdx->nColumn) ) return 0; if( NEVER(j>=pIdx->nColumn) ) return 0;
} }
if( sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue; if( sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ){
continue;
}
} }
pResult = pTerm; pResult = pTerm;
if( pTerm->prereqRight==0 ) goto findTerm_success; if( pTerm->prereqRight==0 ) goto findTerm_success;
@ -1196,32 +1200,6 @@ static void exprAnalyzeOrTerm(
} }
#endif /* !SQLITE_OMIT_OR_OPTIMIZATION && !SQLITE_OMIT_SUBQUERY */ #endif /* !SQLITE_OMIT_OR_OPTIMIZATION && !SQLITE_OMIT_SUBQUERY */
/*
** Check to see if pExpr is an expression of the form A==B where both
** A and B are columns with the same affinity and collating sequence.
** If A and B are equivalent, return true.
*/
static int isEquivalenceExpr(Parse *pParse, Expr *pExpr){
const CollSeq *pCLeft, *pCRight;
if( pExpr->op!=TK_EQ ) return 0;
if( ExprHasProperty(pExpr, EP_FromJoin) ){
return 0;
}
assert( sqlite3ExprSkipCollate(pExpr->pRight)->op==TK_COLUMN );
assert( sqlite3ExprSkipCollate(pExpr->pLeft)->op==TK_COLUMN );
if( sqlite3ExprAffinity(pExpr->pLeft)!=sqlite3ExprAffinity(pExpr->pRight) ){
return 0;
}
pCLeft = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
if( pCLeft ){
pCRight = sqlite3ExprCollSeq(pParse, pExpr->pRight);
if( pCRight && pCRight!=pCLeft ){
return 0;
}
}
return 1;
}
/* /*
** The input to this routine is an WhereTerm structure with only the ** 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 ** "pExpr" field filled in. The job of this routine is to analyze the
@ -1317,7 +1295,7 @@ static void exprAnalyze(
pTerm = &pWC->a[idxTerm]; pTerm = &pWC->a[idxTerm];
pTerm->nChild = 1; pTerm->nChild = 1;
pTerm->wtFlags |= TERM_COPIED; pTerm->wtFlags |= TERM_COPIED;
if( isEquivalenceExpr(pParse, pExpr) ){ if( pExpr->op==TK_EQ && !ExprHasProperty(pExpr, EP_FromJoin) ){
pTerm->eOperator |= WO_EQUIV; pTerm->eOperator |= WO_EQUIV;
eExtraOp = WO_EQUIV; eExtraOp = WO_EQUIV;
} }

50
test/transitive1.test Normal file
View File

@ -0,0 +1,50 @@
# 2013 April 17
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#*************************************************************************
# This file implements regression tests for SQLite library. The
# focus of this script is testing of transitive WHERE clause constraints
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
do_execsql_test transitive1-100 {
CREATE TABLE t1(a TEXT, b TEXT, c TEXT COLLATE NOCASE);
INSERT INTO t1 VALUES('abc','abc','Abc');
INSERT INTO t1 VALUES('def','def','def');
INSERT INTO t1 VALUES('ghi','ghi','GHI');
CREATE INDEX t1a1 ON t1(a);
CREATE INDEX t1a2 ON t1(a COLLATE nocase);
SELECT * FROM t1 WHERE a=b AND c=b AND c='DEF';
} {def def def}
do_execsql_test transitive1-110 {
SELECT * FROM t1 WHERE a=b AND c=b AND c>='DEF' ORDER BY +a;
} {def def def ghi ghi GHI}
do_execsql_test transitive1-120 {
SELECT * FROM t1 WHERE a=b AND c=b AND c<='DEF' ORDER BY +a;
} {abc abc Abc def def def}
do_execsql_test transitive1-200 {
CREATE TABLE t2(a INTEGER, b INTEGER, c TEXT);
INSERT INTO t2 VALUES(100,100,100);
INSERT INTO t2 VALUES(20,20,20);
INSERT INTO t2 VALUES(3,3,3);
SELECT * FROM t2 WHERE a=b AND c=b AND c=20;
} {20 20 20}
do_execsql_test transitive1-210 {
SELECT * FROM t2 WHERE a=b AND c=b AND c>=20 ORDER BY +a;
} {3 3 3 20 20 20}
do_execsql_test transitive1-220 {
SELECT * FROM t2 WHERE a=b AND c=b AND c<=20 ORDER BY +a;
} {20 20 20 100 100 100}
finish_test