1
0
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:
danielk1977
2009-05-22 15:43:26 +00:00
parent dd1f4321ab
commit e672c8ed91
4 changed files with 77 additions and 10 deletions

View 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
{