mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-16 23:02:26 +03:00
Clarification of the operation of the OR-term optimizer in where.c. (CVS 6730)
FossilOrigin-Name: 6b42dc3d04e98f91c203c277926ed6ead62a9270
This commit is contained in:
14
manifest
14
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Change\sthe\sbtree\sbalance\scode\sso\sthat\sit\sdoes\snot\scall\sbalance_nonroot()\srecursively.\s(CVS\s6729)
|
C Clarification\sof\sthe\soperation\sof\sthe\sOR-term\soptimizer\sin\swhere.c.\s(CVS\s6730)
|
||||||
D 2009-06-08T14:49:46
|
D 2009-06-08T17:11:08
|
||||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||||
F Makefile.in 8b8fb7823264331210cddf103831816c286ba446
|
F Makefile.in 8b8fb7823264331210cddf103831816c286ba446
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@@ -212,7 +212,7 @@ F src/vdbeblob.c c25d7e7bc6d5917feeb17270bd275fa771f26e5c
|
|||||||
F src/vdbemem.c 05183d46094aa99b8f8350e5761b9369dbef35a8
|
F src/vdbemem.c 05183d46094aa99b8f8350e5761b9369dbef35a8
|
||||||
F src/vtab.c e2f4c92df7d06330b151448718c4724742ff444b
|
F src/vtab.c e2f4c92df7d06330b151448718c4724742ff444b
|
||||||
F src/walker.c ec4b9742a4077ef80346e2f9aaf0f44c2d95087a
|
F src/walker.c ec4b9742a4077ef80346e2f9aaf0f44c2d95087a
|
||||||
F src/where.c 01b8d4733f177f047014c0b391b4ecbcc867dfd8
|
F src/where.c 21555aa8b48345f5a1c706cf8ca485012f2cea03
|
||||||
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
|
||||||
@@ -733,7 +733,7 @@ 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
|
||||||
F tool/vdbe-compress.tcl 672f81d693a03f80f5ae60bfefacd8a349e76746
|
F tool/vdbe-compress.tcl 672f81d693a03f80f5ae60bfefacd8a349e76746
|
||||||
P 456ea541d67221a573b63e264c83f4448f2ed569
|
P 7863db904d6fc36417c923e3d135eb2c145b9013
|
||||||
R 7ada04c9a78d367df09e91faed8b31d8
|
R 6ef9e53cd5ad2b3cbcbea9afea1bc9a7
|
||||||
U danielk1977
|
U drh
|
||||||
Z 47cd44a7ec9eea431d4519541126ee12
|
Z aebb118da6ff464bb9146e5d93538e1c
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
7863db904d6fc36417c923e3d135eb2c145b9013
|
6b42dc3d04e98f91c203c277926ed6ead62a9270
|
||||||
44
src/where.c
44
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.402 2009/06/07 23:45:11 drh Exp $
|
** $Id: where.c,v 1.403 2009/06/08 17:11:08 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -892,6 +892,22 @@ static void exprAnalyzeOrTerm(
|
|||||||
** chngToIN holds a set of tables that *might* satisfy case 1. But
|
** chngToIN holds a set of tables that *might* satisfy case 1. But
|
||||||
** we have to do some additional checking to see if case 1 really
|
** we have to do some additional checking to see if case 1 really
|
||||||
** is satisfied.
|
** is satisfied.
|
||||||
|
**
|
||||||
|
** chngToIN will hold either 0, 1, or 2 bits. The 0-bit case means
|
||||||
|
** that there is no possibility of transforming the OR clause into an
|
||||||
|
** IN operator because one or more terms in the OR clause contain
|
||||||
|
** something other than == on a column in the single table. The 1-bit
|
||||||
|
** case means that every term of the OR clause is of the form
|
||||||
|
** "table.column=expr" for some single table. The one bit that is set
|
||||||
|
** will correspond to the common table. We still need to check to make
|
||||||
|
** sure the same column is used on all terms. The 2-bit case is when
|
||||||
|
** the all terms are of the form "table1.column=table2.column". It
|
||||||
|
** might be possible to form an IN operator with either table1.column
|
||||||
|
** or table2.column as the LHS if either is common to every term of
|
||||||
|
** the OR clause.
|
||||||
|
**
|
||||||
|
** Note that terms of the form "table.column1=table.column2" (the
|
||||||
|
** same table on both sizes of the ==) cannot be optimized.
|
||||||
*/
|
*/
|
||||||
if( chngToIN ){
|
if( chngToIN ){
|
||||||
int okToChngToIN = 0; /* True if the conversion to IN is valid */
|
int okToChngToIN = 0; /* True if the conversion to IN is valid */
|
||||||
@@ -910,18 +926,38 @@ static void exprAnalyzeOrTerm(
|
|||||||
for(i=pOrWc->nTerm-1; i>=0; i--, pOrTerm++){
|
for(i=pOrWc->nTerm-1; i>=0; i--, pOrTerm++){
|
||||||
assert( pOrTerm->eOperator==WO_EQ );
|
assert( pOrTerm->eOperator==WO_EQ );
|
||||||
pOrTerm->wtFlags &= ~TERM_OR_OK;
|
pOrTerm->wtFlags &= ~TERM_OR_OK;
|
||||||
if( pOrTerm->leftCursor==iColumn ) continue;
|
if( pOrTerm->leftCursor==iCursor ){
|
||||||
if( (chngToIN & getMask(pMaskSet, pOrTerm->leftCursor))==0 ) continue;
|
/* This is the 2-bit case and we are on the second iteration and
|
||||||
|
** current term is from the first iteration. So skip this term. */
|
||||||
|
assert( j==1 );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if( (chngToIN & getMask(pMaskSet, pOrTerm->leftCursor))==0 ){
|
||||||
|
/* This term must be of the form t1.a==t2.b where t2 is in the
|
||||||
|
** chngToIN set but t1 is not. This term will be either preceeded
|
||||||
|
** or follwed by an inverted copy (t2.b==t1.a). Skip this term
|
||||||
|
** and use its inversion. */
|
||||||
|
testcase( pOrTerm->wtFlags & TERM_COPIED );
|
||||||
|
testcase( pOrTerm->wtFlags & TERM_VIRTUAL );
|
||||||
|
assert( pOrTerm->wtFlags & (TERM_COPIED|TERM_VIRTUAL) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
iColumn = pOrTerm->u.leftColumn;
|
iColumn = pOrTerm->u.leftColumn;
|
||||||
iCursor = pOrTerm->leftCursor;
|
iCursor = pOrTerm->leftCursor;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if( i<0 ){
|
if( i<0 ){
|
||||||
|
/* No candidate table+column was found. This can only occur
|
||||||
|
** on the second iteration */
|
||||||
assert( j==1 );
|
assert( j==1 );
|
||||||
assert( (chngToIN&(chngToIN-1))==0 );
|
assert( (chngToIN&(chngToIN-1))==0 );
|
||||||
assert( chngToIN==getMask(pMaskSet, iColumn) );
|
assert( chngToIN==getMask(pMaskSet, iCursor) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
testcase( j==1 );
|
||||||
|
|
||||||
|
/* We have found a candidate table and column. Check to see if that
|
||||||
|
** table and column is common to every term in the OR clause */
|
||||||
okToChngToIN = 1;
|
okToChngToIN = 1;
|
||||||
for(; i>=0 && okToChngToIN; i--, pOrTerm++){
|
for(; i>=0 && okToChngToIN; i--, pOrTerm++){
|
||||||
assert( pOrTerm->eOperator==WO_EQ );
|
assert( pOrTerm->eOperator==WO_EQ );
|
||||||
|
|||||||
Reference in New Issue
Block a user