]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Simplify the generation of the sqlite3_index_info object during query planning
authordrh <>
Wed, 15 Dec 2021 20:48:15 +0000 (20:48 +0000)
committerdrh <>
Wed, 15 Dec 2021 20:48:15 +0000 (20:48 +0000)
for virtual tables.

FossilOrigin-Name: 241dc0428a6e0238c57e2449e98ea60047e777e29c83a4ebe6da16f7cba40e19

manifest
manifest.uuid
src/where.c
src/whereInt.h
src/whereexpr.c

index 19da831492c58c14211a767a144b9d7f03237cfb..9ffb0be7d05df7ca7e5cde387fb6c3edd6f803cf 100644 (file)
--- a/manifest
+++ b/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
index 17670695af86cdc76fa3ef389522a02d4a4af688..b41eacb4bb4c9eeb509218dff8b1275def31bdc3 100644 (file)
@@ -1 +1 @@
-5c3d398d20b86a1558720e995eddf11403aec2d160590571fa9525fe8f6efff9
\ No newline at end of file
+241dc0428a6e0238c57e2449e98ea60047e777e29c83a4ebe6da16f7cba40e19
\ No newline at end of file
index 33e0e43a4ceab7b2bff0f678e564e6d415bbdd5f..c7a9b856aa8d65ff6b235f2ac5d717ee9a3305ba 100644 (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;
index 8051b78a021768dd1027c3b907067caed4eb07f1..a97b4afc690e2e24d12af1e9a18a3ef00658c834 100644 (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 */
index 5a3fbe2d7fc490af42643c6ab80c7315c8af492c..f0660a990e1c38842556de0d52ed0828ee0812a9 100644 (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 );