Simplify the generation of the sqlite3_index_info object during query planning
for virtual tables. FossilOrigin-Name: 241dc0428a6e0238c57e2449e98ea60047e777e29c83a4ebe6da16f7cba40e19
This commit is contained in:
parent
52576b78f6
commit
8a95d3d433
16
manifest
16
manifest
@ -1,5 +1,5 @@
|
||||
C Enhance\sthe\svirtual\stable\squery\splanner\sso\sthat\sit\sis\sable\sto\sdeal\swith\nORDER\sBY\sterms\sthat\scontain\sCOLLATE\sclauses\sas\slong\sas\sthe\sspecified\ncollation\smatches\sthe\svirtual\stable.\s\sThis\sis\sespecially\simportant\sfor\nUNION\sALL\ssince\sa\s"COLLATE\sbinary"\sis\sadded\sto\sORDER\sBY\sclauses\sif\sno\nCOLLATE\sclause\sexists\sin\sthe\soriginal\sSQL.
|
||||
D 2021-12-14T20:13:28.303
|
||||
C Simplify\sthe\sgeneration\sof\sthe\ssqlite3_index_info\sobject\sduring\squery\splanning\nfor\svirtual\stables.
|
||||
D 2021-12-15T20:48:15.594
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -638,10 +638,10 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c ed0398a7adf02c31e34aada42cc86c58f413a7afe5f741a5d373ad087abde028
|
||||
F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
|
||||
F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b
|
||||
F src/where.c c69fed81e5dfd38e261e9af8c3faba133434b233757b0b2814db71eba86a0a62
|
||||
F src/whereInt.h e83f7ba73db5b1b2685118fad67d178fbe04751a25419f0f6ff73e58b4807325
|
||||
F src/where.c 8696f664dceaa7bab9c18212633b1d7d61063ee8c5066b49514b148946a4c467
|
||||
F src/whereInt.h 91865afa4a3540bb3bd643619acc56fbceff7defeb8f249b8e157fd5325d88be
|
||||
F src/wherecode.c 6a594ed25bfbeb60d455868b7be62637575e4f1949152de4336e4825e0c54ba6
|
||||
F src/whereexpr.c 791544603b254cf11f8e84e3b50b0863c57322e9f213b828680f658e232ebc57
|
||||
F src/whereexpr.c 9f64c39e53070584e99e4d20c1dd3397e125fabbae8fd414ffec574c410ac7d3
|
||||
F src/window.c 5d3b397b0c026d0ff5890244ac41359e524c01ae31e78782e1ff418c3e271a9e
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
|
||||
@ -1934,7 +1934,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P a2e50712fca9dff1b8d19631f792270c82da3c8696a5d9890cf0d1e13e950d60
|
||||
R 1e0532988fdf8f21a62bc70005049044
|
||||
P 5c3d398d20b86a1558720e995eddf11403aec2d160590571fa9525fe8f6efff9
|
||||
R 508a1ec856c9c59ad14d9d50f3ec0f6a
|
||||
U drh
|
||||
Z 0d6fc2fca37175245191cba6d8527f4e
|
||||
Z 7cfa744adc9adca884cde06b49136ec0
|
||||
|
@ -1 +1 @@
|
||||
5c3d398d20b86a1558720e995eddf11403aec2d160590571fa9525fe8f6efff9
|
||||
241dc0428a6e0238c57e2449e98ea60047e777e29c83a4ebe6da16f7cba40e19
|
54
src/where.c
54
src/where.c
@ -1113,14 +1113,19 @@ static sqlite3_index_info *allocateIndexInfo(
|
||||
int nOrderBy;
|
||||
sqlite3_index_info *pIdxInfo;
|
||||
u16 mNoOmit = 0;
|
||||
const Table *pTab;
|
||||
|
||||
assert( pSrc!=0 );
|
||||
assert( pSrc->pTab!=0 );
|
||||
assert( IsVirtual(pSrc->pTab) );
|
||||
pTab = pSrc->pTab;
|
||||
assert( pTab!=0 );
|
||||
assert( IsVirtual(pTab) );
|
||||
|
||||
/* Count the number of possible WHERE clause constraints referring
|
||||
** to this virtual table */
|
||||
/* Find all WHERE clause constraints referring to this virtual table.
|
||||
** Mark each term with the TERM_OK flag. Set nTerm to the number of
|
||||
** terms found.
|
||||
*/
|
||||
for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
|
||||
pTerm->wtFlags &= ~TERM_OK;
|
||||
if( pTerm->leftCursor != pSrc->iCursor ) continue;
|
||||
if( pTerm->prereqRight & mUnusable ) continue;
|
||||
assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
|
||||
@ -1131,8 +1136,19 @@ static sqlite3_index_info *allocateIndexInfo(
|
||||
if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue;
|
||||
if( pTerm->wtFlags & TERM_VNULL ) continue;
|
||||
assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
|
||||
assert( pTerm->u.x.leftColumn>=(-1) );
|
||||
assert( pTerm->u.x.leftColumn>=XN_ROWID );
|
||||
assert( pTerm->u.x.leftColumn<pTab->nCol );
|
||||
|
||||
/* tag-20191211-002: WHERE-clause constraints are not useful to the
|
||||
** right-hand table of a LEFT JOIN. See tag-20191211-001 for the
|
||||
** equivalent restriction for ordinary tables. */
|
||||
if( (pSrc->fg.jointype & JT_LEFT)!=0
|
||||
&& !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
|
||||
){
|
||||
continue;
|
||||
}
|
||||
nTerm++;
|
||||
pTerm->wtFlags |= TERM_OK;
|
||||
}
|
||||
|
||||
/* If the ORDER BY clause contains only columns in the current
|
||||
@ -1151,7 +1167,7 @@ static sqlite3_index_info *allocateIndexInfo(
|
||||
|
||||
/* First case - a direct column references without a COLLATE operator */
|
||||
if( pExpr->op==TK_COLUMN && pExpr->iTable==pSrc->iCursor ){
|
||||
assert( pExpr->iColumn>=XN_ROWID && pExpr->iColumn<pSrc->pTab->nCol );
|
||||
assert( pExpr->iColumn>=XN_ROWID && pExpr->iColumn<pTab->nCol );
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1164,10 +1180,10 @@ static sqlite3_index_info *allocateIndexInfo(
|
||||
const char *zColl; /* The collating sequence name */
|
||||
assert( !ExprHasProperty(pExpr, EP_IntValue) );
|
||||
assert( pExpr->u.zToken!=0 );
|
||||
assert( pE2->iColumn>=XN_ROWID && pE2->iColumn<pSrc->pTab->nCol );
|
||||
assert( pE2->iColumn>=XN_ROWID && pE2->iColumn<pTab->nCol );
|
||||
pExpr->iColumn = pE2->iColumn;
|
||||
if( pE2->iColumn<0 ) continue; /* Collseq does not matter for rowid */
|
||||
zColl = sqlite3ColumnColl(&pSrc->pTab->aCol[pE2->iColumn]);
|
||||
zColl = sqlite3ColumnColl(&pTab->aCol[pE2->iColumn]);
|
||||
if( zColl==0 ) zColl = sqlite3StrBINARY;
|
||||
if( sqlite3_stricmp(pExpr->u.zToken, zColl)==0 ) continue;
|
||||
}
|
||||
@ -1201,26 +1217,7 @@ static sqlite3_index_info *allocateIndexInfo(
|
||||
pHidden->pParse = pParse;
|
||||
for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
|
||||
u16 op;
|
||||
if( pTerm->leftCursor != pSrc->iCursor ) continue;
|
||||
if( pTerm->prereqRight & mUnusable ) continue;
|
||||
assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
|
||||
testcase( pTerm->eOperator & WO_IN );
|
||||
testcase( pTerm->eOperator & WO_IS );
|
||||
testcase( pTerm->eOperator & WO_ISNULL );
|
||||
testcase( pTerm->eOperator & WO_ALL );
|
||||
if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue;
|
||||
if( pTerm->wtFlags & TERM_VNULL ) continue;
|
||||
|
||||
/* tag-20191211-002: WHERE-clause constraints are not useful to the
|
||||
** right-hand table of a LEFT JOIN. See tag-20191211-001 for the
|
||||
** equivalent restriction for ordinary tables. */
|
||||
if( (pSrc->fg.jointype & JT_LEFT)!=0
|
||||
&& !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
|
||||
){
|
||||
continue;
|
||||
}
|
||||
assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
|
||||
assert( pTerm->u.x.leftColumn>=(-1) );
|
||||
if( (pTerm->wtFlags & TERM_OK)==0 ) continue;
|
||||
pIdxCons[j].iColumn = pTerm->u.x.leftColumn;
|
||||
pIdxCons[j].iTermOffset = i;
|
||||
op = pTerm->eOperator & WO_ALL;
|
||||
@ -1257,6 +1254,7 @@ static sqlite3_index_info *allocateIndexInfo(
|
||||
|
||||
j++;
|
||||
}
|
||||
assert( j==nTerm );
|
||||
pIdxInfo->nConstraint = j;
|
||||
for(i=0; i<nOrderBy; i++){
|
||||
Expr *pExpr = pOrderBy->a[i].pExpr;
|
||||
|
@ -270,7 +270,7 @@ struct WhereTerm {
|
||||
#define TERM_COPIED 0x0008 /* Has a child */
|
||||
#define TERM_ORINFO 0x0010 /* Need to free the WhereTerm.u.pOrInfo object */
|
||||
#define TERM_ANDINFO 0x0020 /* Need to free the WhereTerm.u.pAndInfo obj */
|
||||
#define TERM_OR_OK 0x0040 /* Used during OR-clause processing */
|
||||
#define TERM_OK 0x0040 /* Used during OR-clause processing */
|
||||
#define TERM_VNULL 0x0080 /* Manufactured x>NULL or x<=NULL term */
|
||||
#define TERM_LIKEOPT 0x0100 /* Virtual terms from the LIKE optimization */
|
||||
#define TERM_LIKECOND 0x0200 /* Conditionally this LIKE operator term */
|
||||
|
@ -796,7 +796,7 @@ static void exprAnalyzeOrTerm(
|
||||
pOrTerm = pOrWc->a;
|
||||
for(i=pOrWc->nTerm-1; i>=0; i--, pOrTerm++){
|
||||
assert( pOrTerm->eOperator & WO_EQ );
|
||||
pOrTerm->wtFlags &= ~TERM_OR_OK;
|
||||
pOrTerm->wtFlags &= ~TERM_OK;
|
||||
if( pOrTerm->leftCursor==iCursor ){
|
||||
/* 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. */
|
||||
@ -837,7 +837,7 @@ static void exprAnalyzeOrTerm(
|
||||
assert( pOrTerm->eOperator & WO_EQ );
|
||||
assert( (pOrTerm->eOperator & (WO_OR|WO_AND))==0 );
|
||||
if( pOrTerm->leftCursor!=iCursor ){
|
||||
pOrTerm->wtFlags &= ~TERM_OR_OK;
|
||||
pOrTerm->wtFlags &= ~TERM_OK;
|
||||
}else if( pOrTerm->u.x.leftColumn!=iColumn || (iColumn==XN_EXPR
|
||||
&& sqlite3ExprCompare(pParse, pOrTerm->pExpr->pLeft, pLeft, -1)
|
||||
)){
|
||||
@ -853,7 +853,7 @@ static void exprAnalyzeOrTerm(
|
||||
if( affRight!=0 && affRight!=affLeft ){
|
||||
okToChngToIN = 0;
|
||||
}else{
|
||||
pOrTerm->wtFlags |= TERM_OR_OK;
|
||||
pOrTerm->wtFlags |= TERM_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -870,7 +870,7 @@ static void exprAnalyzeOrTerm(
|
||||
Expr *pNew; /* The complete IN operator */
|
||||
|
||||
for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0; i--, pOrTerm++){
|
||||
if( (pOrTerm->wtFlags & TERM_OR_OK)==0 ) continue;
|
||||
if( (pOrTerm->wtFlags & TERM_OK)==0 ) continue;
|
||||
assert( pOrTerm->eOperator & WO_EQ );
|
||||
assert( (pOrTerm->eOperator & (WO_OR|WO_AND))==0 );
|
||||
assert( pOrTerm->leftCursor==iCursor );
|
||||
|
Loading…
Reference in New Issue
Block a user