]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add logic to the query planner to only use partial indices if the WHERE clause
authordrh <drh@noemail.net>
Wed, 31 Jul 2013 23:22:39 +0000 (23:22 +0000)
committerdrh <drh@noemail.net>
Wed, 31 Jul 2013 23:22:39 +0000 (23:22 +0000)
constrains the search to rows covered by the partial index.  This is just
infrastructure.  The key routine, sqlite3ExprImpliesExpr(), is currently a
no-op so that partial indices will never be used.

FossilOrigin-Name: 8ca3eac111e06a1854f878a74bffe8f20eb47f1b

manifest
manifest.uuid
src/expr.c
src/sqliteInt.h
src/where.c

index ac70fd7d00d8d2bea2d9da466a41a7b1b8bbe24a..71bc8d11ba1caf5eee3d8dc98dcad6c2ef98b88d 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Resolve\snames\sin\sCREATE\sINDEX\sWHERE\sclauses\sand\sdetect\serrors.\s\sDisallow\nexpressions\sthat\scontain\svariables,\ssubqueries,\sor\sfunctions.\nThe\sexpression\sis\sstill\snot\sused\sfor\sanything,\showever.\nstill\sunused.
-D 2013-07-31T19:05:22.844
+C Add\slogic\sto\sthe\squery\splanner\sto\sonly\suse\spartial\sindices\sif\sthe\sWHERE\sclause\nconstrains\sthe\ssearch\sto\srows\scovered\sby\sthe\spartial\sindex.\s\sThis\sis\sjust\ninfrastructure.\s\sThe\skey\sroutine,\ssqlite3ExprImpliesExpr(),\sis\scurrently\sa\nno-op\sso\sthat\spartial\sindices\swill\snever\sbe\sused.
+D 2013-07-31T23:22:39.876
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -172,7 +172,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
 F src/ctime.c 4262c227bc91cecc61ae37ed3a40f08069cfa267
 F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4
 F src/delete.c aeabdabeeeaa0584127f291baa9617153d334778
-F src/expr.c 2b47ae9da6c9f34eff6736962ea2e102c6c4a755
+F src/expr.c 8a5e78f47c4919bd53c2ef3c652088d71d5c4d79
 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
 F src/fkey.c 914a6bbd987d857c41ac9d244efa6641f36faadb
 F src/func.c 5c50c1ea31fd864b0fe921fe1a8d4c55acd609ef
@@ -221,7 +221,7 @@ F src/shell.c 52f975eae87c8338c4dfbf4c2842d2a0971f01fd
 F src/sqlite.h.in d6a7523d6795317aac574fccc67d9df25253771c
 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0
 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
-F src/sqliteInt.h ffe632c1de338b459af86e6df712f4583c05b8af
+F src/sqliteInt.h 911e2fe9bbd45c394e6396a1c00a8539285f82e6
 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
 F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -290,7 +290,7 @@ F src/vtab.c 2e8b489db47e20ae36cd247932dc671c9ded0624
 F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4
 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
 F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73
-F src/where.c a55e27475c3d4c72c8bf1aaf9ece70e47e8731cf
+F src/where.c afa338426730378f3d0aa9b24218462b6cca31f3
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
@@ -1104,7 +1104,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae
 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
-P 6794b2dcb48b3507caccfc7867fc185818cf8291
-R 1d2a041bdd5863b9d0e35692b3da5ea5
+P f2aa7842c8b9df24294f09e2bde27b3f08c455c7
+R 7502b7f00f8eb060c8cfe6d979c2a415
 U drh
-Z 96979d6477d3e0c5f80978a86c33129b
+Z 8c5239fd3bb5391973b43192e175e4ae
index 9efb9eb1f1167f9c1b86329c769ff31d372eaa02..d8663d417555d437508cc2b7ead80ba0bb396c1e 100644 (file)
@@ -1 +1 @@
-f2aa7842c8b9df24294f09e2bde27b3f08c455c7
\ No newline at end of file
+8ca3eac111e06a1854f878a74bffe8f20eb47f1b
\ No newline at end of file
index 2c0419aa2e789e70b7bd8501b93c0cf8f4f99f2f..03258c32c90753a50c83142c275317bd911536a8 100644 (file)
@@ -3865,6 +3865,26 @@ int sqlite3ExprListCompare(ExprList *pA, ExprList *pB){
   return 0;
 }
 
+/*
+** Return true if we can prove the pE2 will always be true if pE1 is
+** true.  Return false if we cannot complete the proof or if pE2 might
+** be false.  Examples:
+**
+**     pE1: x==5      pE2: x>0              Result: true
+**     pE1: x>0       pE2: x==5             Result: false
+**     pE1: x!=123    pE2: x IS NOT NULL    Result: true
+**
+** When comparing TK_COLUMN nodes between pE1 and pE2, if pE2 has
+** Expr.iTable<0 then assume a table number given by iTab.
+**
+** When in doubt, return false.  Returning true might give a performance
+** improvement.  Returning false might cause a performance reduction, but
+** it will always give the correct answer and is hence always safe.
+*/
+int sqlite3ExprImpliesExpr(Expr *pE1, Expr *pE2, int iTab){
+  return 0;  /* FIXME: this needs to be worked out */
+}
+
 /*
 ** An instance of the following structure is used by the tree walker
 ** to count references to table columns in the arguments of an 
index 3d4a57f3a4239d47527efee5db93203428e21929..9d5580f9281446340db79b2575a7c383bb0e4e41 100644 (file)
@@ -2835,6 +2835,7 @@ int sqlite3RunVacuum(char**, sqlite3*);
 char *sqlite3NameFromToken(sqlite3*, Token*);
 int sqlite3ExprCompare(Expr*, Expr*);
 int sqlite3ExprListCompare(ExprList*, ExprList*);
+int sqlite3ExprImpliesExpr(Expr*, Expr*, int);
 void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
 void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
 int sqlite3FunctionUsesThisSrc(Expr*, SrcList*);
index 9f65d551a345096ca3b495caa300f8ccb9af8286..315c4035cb4830d96df349b4d9effeae68d90215 100644 (file)
@@ -4503,6 +4503,17 @@ static Bitmask columnsInIndex(Index *pIdx){
   return m;
 }
 
+/* Check to see if a partial index with pPartIndexWhere can be used
+** in the current query.  Return true if it can be and false if not.
+*/
+static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){
+  int i;
+  WhereTerm *pTerm;
+  for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
+    if( sqlite3ExprImpliesExpr(pTerm->pExpr, pWhere, iTab) ) return 1;
+  }
+  return 0;
+}
 
 /*
 ** Add all WhereLoop objects for a single table of the join where the table
@@ -4526,11 +4537,13 @@ static int whereLoopAddBtree(
   int b;                      /* A boolean value */
   WhereCost rSize;            /* number of rows in the table */
   WhereCost rLogSize;         /* Logarithm of the number of rows in the table */
+  WhereClause *pWC;           /* The parsed WHERE clause */
   
   pNew = pBuilder->pNew;
   pWInfo = pBuilder->pWInfo;
   pTabList = pWInfo->pTabList;
   pSrc = pTabList->a + pNew->iTab;
+  pWC = pBuilder->pWC;
   assert( !IsVirtual(pSrc->pTab) );
 
   if( pSrc->pIndex ){
@@ -4570,7 +4583,6 @@ static int whereLoopAddBtree(
    && !pSrc->isCorrelated
   ){
     /* Generate auto-index WhereLoops */
-    WhereClause *pWC = pBuilder->pWC;
     WhereTerm *pTerm;
     WhereTerm *pWCEnd = pWC->a + pWC->nTerm;
     for(pTerm=pWC->a; rc==SQLITE_OK && pTerm<pWCEnd; pTerm++){
@@ -4600,6 +4612,10 @@ static int whereLoopAddBtree(
   /* Loop over all indices
   */
   for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){
+    if( pProbe->pPartIdxWhere!=0
+     && !whereUsablePartialIndex(pNew->iTab, pWC, pProbe->pPartIdxWhere) ){
+      continue;  /* Partial index inappropriate for this query */
+    }
     pNew->u.btree.nEq = 0;
     pNew->nLTerm = 0;
     pNew->iSortIdx = 0;