]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Do not transform a WHERE clause of the form "a = ? OR a = ?" to "a IN (?, ?)" if...
authordanielk1977 <danielk1977@noemail.net>
Fri, 22 May 2009 15:43:26 +0000 (15:43 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Fri, 22 May 2009 15:43:26 +0000 (15:43 +0000)
FossilOrigin-Name: fad88e71cf195e703f7b56b13f0c1818fd0dac84

manifest
manifest.uuid
src/where.c
test/tkt3871.test [new file with mode: 0644]

index 782e5ecafc339d14ce709dd76fd66668cab19d54..7dc24de90e614fa00ca0185ca838375f18183aa6 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\san\sassert()\sto\spcache1.c\sto\sdouble-check\sthat\spage\scache\sbuffer\smemory\r\nis\snever\sallocated\sif\spcache1\sis\snot\senabled.\s\sTicket\s#3872\s(CVS\s6670)
-D 2009-05-22T11:12:23
+C Do\snot\stransform\sa\sWHERE\sclause\sof\sthe\sform\s"a\s=\s?\sOR\sa\s=\s?"\sto\s"a\sIN\s(?,\s?)"\sif\s"a"\sis\sa\scolumn\sof\sa\svirtual\stable.\sTicket\s#3871.\s(CVS\s6671)
+D 2009-05-22T15:43:27
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in 583e87706abc3026960ed759aff6371faf84c211
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -212,7 +212,7 @@ F src/vdbeblob.c 5c5abe9af28316772e7829359f6f9cda2c737ebd
 F src/vdbemem.c d8b985eeb88214941380372466a30ca410043a93
 F src/vtab.c b0216337ae7d27708dedd56d220e6f4fecda92f1
 F src/walker.c 7cdf63223c953d4343c6833e940f110281a378ee
-F src/where.c c5fa4a7a58880aecc657ebce5f8df98c9b67eec0
+F src/where.c d11b8a8c49c518384292d410738bd21da5c00bf4
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
 F test/all.test 14165b3e32715b700b5f0cbf8f6e3833dda0be45
@@ -649,6 +649,7 @@ F test/tkt3824.test 3da2f5c81b057e3ff355f5dfc9aa0cf0a92e0206
 F test/tkt3832.test 7ebd5ac82d1e430accd5eec9768044133a94c2aa
 F test/tkt3838.test 2a1525946bc9d3751e1d49ce95f3a2472f2b7408
 F test/tkt3841.test fe7451fb899bc31c5fbcee53362c621d0271e25f
+F test/tkt3871.test cd3af9007cf91ed5a2c1b36243979274bb3b2632
 F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7
 F test/trace.test 19ffbc09885c3321d56358a5738feae8587fb377
 F test/trans.test d887cb07630dc39879a322d958ad8b006137485c
@@ -729,7 +730,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
-P 5153ad19daf0f3b0334b2a06655142899203abbf
-R e695d5320ab4a5af1a8f88d9b5e01a90
-U drh
-Z 682d221724db391e2f96571715710eeb
+P 93369d91abe10975507ea9302c145e3ddd0c2c76
+R 031fba78b50558f4af4dcca1f55d016a
+U danielk1977
+Z 9bdd39326969f0ae9a78f00d0f047279
index f6ff43637487d49025fc8133c928ebf30eba83df..07c1628da96f3429c55afa799c15da869ce9af62 100644 (file)
@@ -1 +1 @@
-93369d91abe10975507ea9302c145e3ddd0c2c76
\ No newline at end of file
+fad88e71cf195e703f7b56b13f0c1818fd0dac84
\ No newline at end of file
index 1d2450e189e67715d2519282f3d70491178d1ff5..6bbc4af39b889aa909da786003d0f4fa63f90951 100644 (file)
@@ -16,7 +16,7 @@
 ** so is applicable.  Because this module is responsible for selecting
 ** indices, you might also think of this module as the "query optimizer".
 **
-** $Id: where.c,v 1.396 2009/05/06 19:03:14 drh Exp $
+** $Id: where.c,v 1.397 2009/05/22 15:43:27 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 
@@ -127,6 +127,7 @@ struct WhereTerm {
 struct WhereClause {
   Parse *pParse;           /* The parser context */
   WhereMaskSet *pMaskSet;  /* Mapping of table cursor numbers to bitmasks */
+  Bitmask vmask;           /* Bitmask identifying virtual table cursors */
   u8 op;                   /* Split operator.  TK_AND or TK_OR */
   int nTerm;               /* Number of terms */
   int nSlot;               /* Number of entries in a[] */
@@ -254,6 +255,7 @@ static void whereClauseInit(
   pWC->nTerm = 0;
   pWC->nSlot = ArraySize(pWC->aStatic);
   pWC->a = pWC->aStatic;
+  pWC->vmask = 0;
 }
 
 /* Forward reference */
@@ -829,7 +831,8 @@ static void exprAnalyzeOrTerm(
   /*
   ** Compute the set of tables that might satisfy cases 1 or 2.
   */
-  indexable = chngToIN = ~(Bitmask)0;
+  indexable = ~(Bitmask)0;
+  chngToIN = ~(pWC->vmask);
   for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0 && indexable; i--, pOrTerm++){
     if( (pOrTerm->eOperator & WO_SINGLE)==0 ){
       WhereAndInfo *pAndInfo;
@@ -3166,9 +3169,18 @@ WhereInfo *sqlite3WhereBegin(
   ** of the join.  Subtracting one from the right table bitmask gives a
   ** bitmask for all tables to the left of the join.  Knowing the bitmask
   ** for all tables to the left of a left join is important.  Ticket #3015.
+  **
+  ** Configure the WhereClause.vmask variable so that bits that correspond
+  ** to virtual table cursors are set. This is used to selectively disable 
+  ** the OR-to-IN transformation in exprAnalyzeOrTerm(). It is not helpful 
+  ** with virtual tables.
   */
+  assert( pWC->vmask==0 && pMaskSet->n==0 );
   for(i=0; i<pTabList->nSrc; i++){
     createMask(pMaskSet, pTabList->a[i].iCursor);
+    if( pTabList->a[i].pTab && IsVirtual(pTabList->a[i].pTab) ){
+      pWC->vmask |= ((Bitmask)1 << i);
+    }
   }
 #ifndef NDEBUG
   {
diff --git a/test/tkt3871.test b/test/tkt3871.test
new file mode 100644 (file)
index 0000000..a23b874
--- /dev/null
@@ -0,0 +1,54 @@
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+ifcapable !vtab {
+  finish_test
+  return
+}
+
+register_echo_module [sqlite3_connection_pointer db]
+
+do_test tkt3871-1.1 {
+  execsql {
+    BEGIN;
+    CREATE TABLE t1(a PRIMARY KEY, b UNIQUE);
+  }
+  for {set i 0} {$i < 500} {incr i} {
+    execsql { INSERT INTO t1 VALUES($i, $i*$i) }
+  }
+  execsql COMMIT
+  execsql { 
+    CREATE VIRTUAL TABLE e USING echo(t1);
+    SELECT count(*) FROM e;
+  }
+} {500}
+
+do_test tkt3871-1.2 {
+  execsql { SELECT * FROM e WHERE a = 1 OR a = 2 }
+} {1 1 2 4}
+do_test tkt3871-1.3 {
+  set echo_module ""
+  execsql { SELECT * FROM e WHERE a = 1 OR a = 2 }
+  set echo_module
+} [list \
+  xFilter {SELECT rowid, * FROM 't1' WHERE a = ?} 1 \
+  xFilter {SELECT rowid, * FROM 't1' WHERE a = ?} 2 \
+]
+
+do_test tkt3871-1.4 {
+  execsql { SELECT * FROM e WHERE a = 1 OR a = 2 OR b = 9 }
+} {1 1 2 4 3 9}
+do_test tkt3871-1.5 {
+  set echo_module ""
+  execsql { SELECT * FROM e WHERE a = 1 OR a = 2 OR b = 9 }
+  set echo_module
+} [list \
+  xFilter {SELECT rowid, * FROM 't1' WHERE a = ?} 1 \
+  xFilter {SELECT rowid, * FROM 't1' WHERE a = ?} 2 \
+  xFilter {SELECT rowid, * FROM 't1' WHERE b = ?} 9
+]
+
+
+finish_test
+