Simplify the generation of the sqlite3_index_info object during query planning

for virtual tables.

FossilOrigin-Name: 241dc0428a6e0238c57e2449e98ea60047e777e29c83a4ebe6da16f7cba40e19
This commit is contained in:
drh 2021-12-15 20:48:15 +00:00
parent 52576b78f6
commit 8a95d3d433
5 changed files with 40 additions and 42 deletions

View File

@ -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

View File

@ -1 +1 @@
5c3d398d20b86a1558720e995eddf11403aec2d160590571fa9525fe8f6efff9
241dc0428a6e0238c57e2449e98ea60047e777e29c83a4ebe6da16f7cba40e19

View File

@ -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;

View File

@ -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 */

View File

@ -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 );