From: drh Date: Thu, 17 Jan 2013 16:18:55 +0000 (+0000) Subject: Avoid unnecessary collating sequence and affinity restrictions on the use X-Git-Tag: version-3.7.16~69^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=63db0392ae67c0e2d7c188bf8fb6f47e43731663;p=thirdparty%2Fsqlite.git 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 --- diff --git a/manifest b/manifest index fb4188f095..bdde52fc74 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\smore\saggressive\suse\sof\stransitivity\sin\soptimizing\squeries.\s\sAdd\sa\stest\ncase. -D 2013-01-17T15:05:17.153 +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-17T16:18:55.615 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a48faa9e7dd7d556d84f5456eabe5825dd8a6282 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -252,7 +252,7 @@ F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83 F src/wal.c f5c7b5027d0ed0e9bc9afeb4a3a8dfea762ec7d2 F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b -F src/where.c 701c32fecbcf44d749a8fdacb887ffdcec21a3e5 +F src/where.c 79c257691c5cbe92fae9dc35465392cbd11c3e31 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 @@ -896,6 +896,7 @@ F test/trace2.test c1dc104a8d11a347c870cfea6235e3fc6f6cb06d F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6 F test/trans2.test d5337e61de45e66b1fcbf9db833fa8c82e624b22 F test/trans3.test 373ac5183cc56be69f48ae44090e7f672939f732 +F test/transitive1.test d04aa9023e425d6f2d4aa61dd81ee9e102f89062 F test/trigger1.test 30f343f91586765874a28ad539c06f5a5f049931 F test/trigger2.test 834187beafd1db383af0c659cfa49b0576832816 F test/trigger3.test d2c60d8be271c355d61727411e753181e877230a @@ -1033,7 +1034,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P fe152f8b048c9a18f99fa6096ff0e68dd630c318 -R f7b812e14ccd12b59aae7b48f0da1945 +P d96762841a461e192fb2f317d684d000376350dd +R da60dbccb0041de3b6506adfaa629abe U drh -Z eaf427dd060ebdbe2c55df9e5c68a5b1 +Z 92f034648a2e7d96254ca815101088e3 diff --git a/manifest.uuid b/manifest.uuid index c667be658b..3d368975e2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d96762841a461e192fb2f317d684d000376350dd \ No newline at end of file +56549f45666b53876012df5c2bdf813474e10925 \ No newline at end of file diff --git a/src/where.c b/src/where.c index ca59370352..46268bf0f7 100644 --- a/src/where.c +++ b/src/where.c @@ -687,7 +687,9 @@ static WhereTerm *findTerm( pX = pTerm->pExpr; pParse = pWC->pParse; 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 ** 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++){ 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; if( pTerm->prereqRight==0 ) goto findTerm_success; @@ -1196,32 +1200,6 @@ static void exprAnalyzeOrTerm( } #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 ** "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->nChild = 1; pTerm->wtFlags |= TERM_COPIED; - if( isEquivalenceExpr(pParse, pExpr) ){ + if( pExpr->op==TK_EQ && !ExprHasProperty(pExpr, EP_FromJoin) ){ pTerm->eOperator |= WO_EQUIV; eExtraOp = WO_EQUIV; } diff --git a/test/transitive1.test b/test/transitive1.test new file mode 100644 index 0000000000..ff81af6421 --- /dev/null +++ b/test/transitive1.test @@ -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