mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-16 23:02:26 +03:00
Do not transform a WHERE clause of the form "a = ? OR a = ?" to "a IN (?, ?)" if "a" is a column of a virtual table. Ticket #3871. (CVS 6671)
FossilOrigin-Name: fad88e71cf195e703f7b56b13f0c1818fd0dac84
This commit is contained in:
15
manifest
15
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)
|
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-22T11:12:23
|
D 2009-05-22T15:43:27
|
||||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||||
F Makefile.in 583e87706abc3026960ed759aff6371faf84c211
|
F Makefile.in 583e87706abc3026960ed759aff6371faf84c211
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@@ -212,7 +212,7 @@ F src/vdbeblob.c 5c5abe9af28316772e7829359f6f9cda2c737ebd
|
|||||||
F src/vdbemem.c d8b985eeb88214941380372466a30ca410043a93
|
F src/vdbemem.c d8b985eeb88214941380372466a30ca410043a93
|
||||||
F src/vtab.c b0216337ae7d27708dedd56d220e6f4fecda92f1
|
F src/vtab.c b0216337ae7d27708dedd56d220e6f4fecda92f1
|
||||||
F src/walker.c 7cdf63223c953d4343c6833e940f110281a378ee
|
F src/walker.c 7cdf63223c953d4343c6833e940f110281a378ee
|
||||||
F src/where.c c5fa4a7a58880aecc657ebce5f8df98c9b67eec0
|
F src/where.c d11b8a8c49c518384292d410738bd21da5c00bf4
|
||||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||||
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
|
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
|
||||||
F test/all.test 14165b3e32715b700b5f0cbf8f6e3833dda0be45
|
F test/all.test 14165b3e32715b700b5f0cbf8f6e3833dda0be45
|
||||||
@@ -649,6 +649,7 @@ F test/tkt3824.test 3da2f5c81b057e3ff355f5dfc9aa0cf0a92e0206
|
|||||||
F test/tkt3832.test 7ebd5ac82d1e430accd5eec9768044133a94c2aa
|
F test/tkt3832.test 7ebd5ac82d1e430accd5eec9768044133a94c2aa
|
||||||
F test/tkt3838.test 2a1525946bc9d3751e1d49ce95f3a2472f2b7408
|
F test/tkt3838.test 2a1525946bc9d3751e1d49ce95f3a2472f2b7408
|
||||||
F test/tkt3841.test fe7451fb899bc31c5fbcee53362c621d0271e25f
|
F test/tkt3841.test fe7451fb899bc31c5fbcee53362c621d0271e25f
|
||||||
|
F test/tkt3871.test cd3af9007cf91ed5a2c1b36243979274bb3b2632
|
||||||
F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7
|
F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7
|
||||||
F test/trace.test 19ffbc09885c3321d56358a5738feae8587fb377
|
F test/trace.test 19ffbc09885c3321d56358a5738feae8587fb377
|
||||||
F test/trans.test d887cb07630dc39879a322d958ad8b006137485c
|
F test/trans.test d887cb07630dc39879a322d958ad8b006137485c
|
||||||
@@ -729,7 +730,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
|||||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
P 5153ad19daf0f3b0334b2a06655142899203abbf
|
P 93369d91abe10975507ea9302c145e3ddd0c2c76
|
||||||
R e695d5320ab4a5af1a8f88d9b5e01a90
|
R 031fba78b50558f4af4dcca1f55d016a
|
||||||
U drh
|
U danielk1977
|
||||||
Z 682d221724db391e2f96571715710eeb
|
Z 9bdd39326969f0ae9a78f00d0f047279
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
93369d91abe10975507ea9302c145e3ddd0c2c76
|
fad88e71cf195e703f7b56b13f0c1818fd0dac84
|
||||||
16
src/where.c
16
src/where.c
@@ -16,7 +16,7 @@
|
|||||||
** so is applicable. Because this module is responsible for selecting
|
** so is applicable. Because this module is responsible for selecting
|
||||||
** indices, you might also think of this module as the "query optimizer".
|
** 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"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -127,6 +127,7 @@ struct WhereTerm {
|
|||||||
struct WhereClause {
|
struct WhereClause {
|
||||||
Parse *pParse; /* The parser context */
|
Parse *pParse; /* The parser context */
|
||||||
WhereMaskSet *pMaskSet; /* Mapping of table cursor numbers to bitmasks */
|
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 */
|
u8 op; /* Split operator. TK_AND or TK_OR */
|
||||||
int nTerm; /* Number of terms */
|
int nTerm; /* Number of terms */
|
||||||
int nSlot; /* Number of entries in a[] */
|
int nSlot; /* Number of entries in a[] */
|
||||||
@@ -254,6 +255,7 @@ static void whereClauseInit(
|
|||||||
pWC->nTerm = 0;
|
pWC->nTerm = 0;
|
||||||
pWC->nSlot = ArraySize(pWC->aStatic);
|
pWC->nSlot = ArraySize(pWC->aStatic);
|
||||||
pWC->a = pWC->aStatic;
|
pWC->a = pWC->aStatic;
|
||||||
|
pWC->vmask = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Forward reference */
|
/* Forward reference */
|
||||||
@@ -829,7 +831,8 @@ static void exprAnalyzeOrTerm(
|
|||||||
/*
|
/*
|
||||||
** Compute the set of tables that might satisfy cases 1 or 2.
|
** 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++){
|
for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0 && indexable; i--, pOrTerm++){
|
||||||
if( (pOrTerm->eOperator & WO_SINGLE)==0 ){
|
if( (pOrTerm->eOperator & WO_SINGLE)==0 ){
|
||||||
WhereAndInfo *pAndInfo;
|
WhereAndInfo *pAndInfo;
|
||||||
@@ -3166,9 +3169,18 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
** of the join. Subtracting one from the right table bitmask gives a
|
** 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
|
** 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.
|
** 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++){
|
for(i=0; i<pTabList->nSrc; i++){
|
||||||
createMask(pMaskSet, pTabList->a[i].iCursor);
|
createMask(pMaskSet, pTabList->a[i].iCursor);
|
||||||
|
if( pTabList->a[i].pTab && IsVirtual(pTabList->a[i].pTab) ){
|
||||||
|
pWC->vmask |= ((Bitmask)1 << i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
{
|
{
|
||||||
|
|||||||
54
test/tkt3871.test
Normal file
54
test/tkt3871.test
Normal file
@@ -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
|
||||||
|
|
||||||
Reference in New Issue
Block a user