diff --git a/manifest b/manifest index 9cfe44a4b4..fc8ac69d1e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\smalloc\sfrom\sthe\svfsstat\sextension. -D 2016-05-28T17:45:15.304 +C Experimental\schange\sto\sallow\svirtual\stables\sto\stake\sadvantage\sof\sLIKE,\sREGEXP\sand\sGLOB\sterms\sthat\sare\spart\sof\sOR\sexpressions\swithin\sWHERE\sclauses. +D 2016-05-28T18:53:55.546 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -463,7 +463,7 @@ F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c b9f5b0ddb14c3827e70b5379e659cf4cfd524c4d F src/whereInt.h e5b939701a7ceffc5a3a8188a37f9746416ebcd0 F src/wherecode.c ba71a4e4bada29aa9842200e6299714bf18c812c -F src/whereexpr.c eacc0e60d029a082b4fc0cc42ea98544add1319e +F src/whereexpr.c c32d47085dbaca0b8fd013210f56693c7d220d48 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -526,6 +526,7 @@ F test/badutf2.test f5bc7f2d280670ecd79b9cf4f0f1760c607fe51f F test/bc_common.tcl b5e42d80305be95697e6370e015af571e5333a1c F test/bestindex1.test 0cf1bd2d7b97d3a3a8c10736125274f64765c4ee F test/bestindex2.test 4a06b8922ab2fd09434870da8d1cdf525aaf7060 +F test/bestindex3.test b80da904d23581d233a7ceee7d6bbad2b23a8133 F test/between.test 34d375fb5ce1ae283ffe82b6b233e9f38e84fc6c F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59 F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc @@ -1496,7 +1497,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6a0f200957ea294a2ae06c0b039a10ac838925f2 -R 829320b2f280fbfaceb9a39efce4a03a -U drh -Z aae9a2c9c9808c4a6dec915905c542ff +P 24f258c2392290168cf34622b89a4a406a3dd853 +R 983129af8245564f55ecb1fc34584518 +T *branch * vtab-experimental +T *sym-vtab-experimental * +T -sym-trunk * +U dan +Z 81d42b1213db363a99013be9cf2ad43d diff --git a/manifest.uuid b/manifest.uuid index c667abe35c..7e28d7946f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -24f258c2392290168cf34622b89a4a406a3dd853 \ No newline at end of file +242507b4ff96bc4c7c7844dbe1c2b8508dbf1d01 \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index ff012281b1..90c4c45965 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -568,7 +568,9 @@ static void exprAnalyzeOrTerm( if( !db->mallocFailed ){ for(j=0, pAndTerm=pAndWC->a; jnTerm; j++, pAndTerm++){ assert( pAndTerm->pExpr ); - if( allowedOp(pAndTerm->pExpr->op) ){ + if( allowedOp(pAndTerm->pExpr->op) + || pAndTerm->eOperator==WO_MATCH + ){ b |= sqlite3WhereGetMask(&pWInfo->sMaskSet, pAndTerm->leftCursor); } } @@ -1122,7 +1124,7 @@ static void exprAnalyze( ** virtual tables. The native query optimizer does not attempt ** to do anything with MATCH functions. */ - if( isMatchOfColumn(pExpr, &eOp2) ){ + if( pWC->op==TK_AND && isMatchOfColumn(pExpr, &eOp2) ){ int idxNew; Expr *pRight, *pLeft; WhereTerm *pNewTerm; diff --git a/test/bestindex3.test b/test/bestindex3.test new file mode 100644 index 0000000000..bb6d5cefd1 --- /dev/null +++ b/test/bestindex3.test @@ -0,0 +1,170 @@ +# 2016 May 29 +# +# 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. +# +#*********************************************************************** + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix bestindex3 + +ifcapable !vtab { + finish_test + return +} + +#------------------------------------------------------------------------- +# Virtual table callback for a virtual table named $tbl. +# +# The table created is: +# +# "CREATE TABLE t1 (a, b, c)" +# +# This virtual table supports both LIKE and = operators on all columns. +# +proc vtab_cmd {bOmit method args} { + switch -- $method { + xConnect { + return "CREATE TABLE t1(a, b, c)" + } + + xBestIndex { + foreach {clist orderby mask} $args {} + + set ret [list] + set use use + if {$bOmit} {set use omit} + + for {set i 0} {$i < [llength $clist]} {incr i} { + array unset C + array set C [lindex $clist $i] + if {$C(usable) && ($C(op)=="like" || $C(op)=="eq")} { + lappend ret $use $i + lappend ret idxstr + lappend ret "[lindex {a b c} $C(column)] [string toupper $C(op)] ?" + break + } + } + + if {$ret==""} { + lappend ret cost 1000000 rows 1000000 + } else { + lappend ret cost 100 rows 10 + } + return $ret + } + + xFilter { + foreach {idxnum idxstr param} $args {} + set where "" + if {$bOmit && $idxstr != ""} { + set where " WHERE [string map [list ? '$param' EQ =] $idxstr]" + } + return [list sql "SELECT rowid, * FROM ttt$where"] + } + } + return "" +} + +register_tcl_module db + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t1 USING tcl("vtab_cmd 0"); +} + +do_eqp_test 1.1 { + SELECT * FROM t1 WHERE a LIKE 'abc'; +} { + 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a LIKE ?} +} + +do_eqp_test 1.2 { + SELECT * FROM t1 WHERE a = 'abc'; +} { + 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a EQ ?} +} + +do_eqp_test 1.3 { + SELECT * FROM t1 WHERE a = 'abc' OR b = 'def'; +} { + 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a EQ ?} + 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:b EQ ?} +} + +do_eqp_test 1.4 { + SELECT * FROM t1 WHERE a LIKE 'abc%' OR b = 'def'; +} { + 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a LIKE ?} + 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:b EQ ?} +} + +do_execsql_test 1.5 { + CREATE TABLE ttt(a, b, c); + + INSERT INTO ttt VALUES(1, 'two', 'three'); + INSERT INTO ttt VALUES(2, 'one', 'two'); + INSERT INTO ttt VALUES(3, 'three', 'one'); + INSERT INTO ttt VALUES(4, 'y', 'one'); + INSERT INTO ttt VALUES(5, 'x', 'two'); + INSERT INTO ttt VALUES(6, 'y', 'three'); +} + +foreach omit {0 1} { + do_execsql_test 1.6.$omit.0 " + DROP TABLE t1; + CREATE VIRTUAL TABLE t1 USING tcl('vtab_cmd $omit'); + " + do_execsql_test 1.6.$omit.1 { + SELECT rowid FROM t1 WHERE c LIKE 'o%' + } {3 4} + + do_execsql_test 1.6.$omit.2 { + SELECT rowid FROM t1 WHERE c LIKE 'o%' OR b='y' + } {3 4 6} + + do_execsql_test 1.6.$omit.3 { + SELECT rowid FROM t1 WHERE c = 'three' OR c LIKE 'o%' + } {1 6 3 4} +} + +#------------------------------------------------------------------------- +# Test the same pattern works with ordinary tables. +# +do_execsql_test 2.1 { + CREATE TABLE t2(x TEXT COLLATE nocase, y TEXT); + CREATE INDEX t2x ON t2(x COLLATE nocase); + CREATE INDEX t2y ON t2(y); +} + +do_eqp_test 2.2 { + SELECT * FROM t2 WHERE x LIKE 'abc%' OR y = 'def' +} { + 0 0 0 {SEARCH TABLE t2 USING INDEX t2x (x>? AND x