mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-16 23:02:26 +03:00
Fix an additional problem with the IS NULL optimization on LEFT JOINs.
Ticket #2189. See also ticket #2177. (CVS 3602) FossilOrigin-Name: 358dd82d3a921228155e2cf9e22aedd2b651ca9c
This commit is contained in:
40
src/where.c
40
src/where.c
@@ -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.235 2007/01/19 01:06:03 drh Exp $
|
||||
** $Id: where.c,v 1.236 2007/01/25 16:56:07 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@@ -160,20 +160,28 @@ struct ExprMaskSet {
|
||||
#define WO_ISNULL 128
|
||||
|
||||
/*
|
||||
** Value for flags returned by bestIndex()
|
||||
** Value for flags returned by bestIndex().
|
||||
**
|
||||
** The least significant byte is reserved as a mask for WO_ values above.
|
||||
** The WhereLevel.flags field is usually set to WO_IN|WO_EQ|WO_ISNULL.
|
||||
** But if the table is the right table of a left join, WhereLevel.flags
|
||||
** is set to WO_IN|WO_EQ. The WhereLevel.flags field can then be used as
|
||||
** the "op" parameter to findTerm when we are resolving equality constraints.
|
||||
** ISNULL constraints will then not be used on the right table of a left
|
||||
** join. Tickets #2177 and #2189.
|
||||
*/
|
||||
#define WHERE_ROWID_EQ 0x0001 /* rowid=EXPR or rowid IN (...) */
|
||||
#define WHERE_ROWID_RANGE 0x0002 /* rowid<EXPR and/or rowid>EXPR */
|
||||
#define WHERE_COLUMN_EQ 0x0010 /* x=EXPR or x IN (...) */
|
||||
#define WHERE_COLUMN_RANGE 0x0020 /* x<EXPR and/or x>EXPR */
|
||||
#define WHERE_COLUMN_IN 0x0040 /* x IN (...) */
|
||||
#define WHERE_TOP_LIMIT 0x0100 /* x<EXPR or x<=EXPR constraint */
|
||||
#define WHERE_BTM_LIMIT 0x0200 /* x>EXPR or x>=EXPR constraint */
|
||||
#define WHERE_IDX_ONLY 0x0800 /* Use index only - omit table */
|
||||
#define WHERE_ORDERBY 0x1000 /* Output will appear in correct order */
|
||||
#define WHERE_REVERSE 0x2000 /* Scan in reverse order */
|
||||
#define WHERE_UNIQUE 0x4000 /* Selects no more than one row */
|
||||
#define WHERE_VIRTUALTABLE 0x8000 /* Use virtual-table processing */
|
||||
#define WHERE_ROWID_EQ 0x000100 /* rowid=EXPR or rowid IN (...) */
|
||||
#define WHERE_ROWID_RANGE 0x000200 /* rowid<EXPR and/or rowid>EXPR */
|
||||
#define WHERE_COLUMN_EQ 0x001000 /* x=EXPR or x IN (...) */
|
||||
#define WHERE_COLUMN_RANGE 0x002000 /* x<EXPR and/or x>EXPR */
|
||||
#define WHERE_COLUMN_IN 0x004000 /* x IN (...) */
|
||||
#define WHERE_TOP_LIMIT 0x010000 /* x<EXPR or x<=EXPR constraint */
|
||||
#define WHERE_BTM_LIMIT 0x020000 /* x>EXPR or x>=EXPR constraint */
|
||||
#define WHERE_IDX_ONLY 0x080000 /* Use index only - omit table */
|
||||
#define WHERE_ORDERBY 0x100000 /* Output will appear in correct order */
|
||||
#define WHERE_REVERSE 0x200000 /* Scan in reverse order */
|
||||
#define WHERE_UNIQUE 0x400000 /* Selects no more than one row */
|
||||
#define WHERE_VIRTUALTABLE 0x800000 /* Use virtual-table processing */
|
||||
|
||||
/*
|
||||
** Initialize a preallocated WhereClause structure.
|
||||
@@ -1486,7 +1494,7 @@ static double bestIndex(
|
||||
*ppIndex = bestIdx;
|
||||
TRACE(("best index is %s, cost=%.9g, flags=%x, nEq=%d\n",
|
||||
bestIdx ? bestIdx->zName : "(none)", lowestCost, bestFlags, bestNEq));
|
||||
*pFlags = bestFlags;
|
||||
*pFlags = bestFlags | eqTermMask;
|
||||
*pnEq = bestNEq;
|
||||
return lowestCost;
|
||||
}
|
||||
@@ -1651,7 +1659,7 @@ static void codeAllEqualityTerms(
|
||||
assert( pIdx->nColumn>=nEq );
|
||||
for(j=0; j<nEq; j++){
|
||||
int k = pIdx->aiColumn[j];
|
||||
pTerm = findTerm(pWC, iCur, k, notReady, WO_EQ|WO_IN|WO_ISNULL, pIdx);
|
||||
pTerm = findTerm(pWC, iCur, k, notReady, pLevel->flags, pIdx);
|
||||
if( pTerm==0 ) break;
|
||||
assert( (pTerm->flags & TERM_CODED)==0 );
|
||||
codeEqualityTerm(pParse, pTerm, brk, pLevel);
|
||||
|
||||
Reference in New Issue
Block a user