]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Proof of concept for the ability to use the expression columns in an index
authordrh <drh@noemail.net>
Fri, 7 Apr 2017 19:41:31 +0000 (19:41 +0000)
committerdrh <drh@noemail.net>
Fri, 7 Apr 2017 19:41:31 +0000 (19:41 +0000)
on expressions in place of equivalent expressions in the result set or in
the WHERE clause.  This check-in compiles but is mostly untested.

FossilOrigin-Name: a52ef2ad7c0e14b78b801f16a1f6ea8d8fa9ae5d7d810e18dd24c600b662a312

manifest
manifest.uuid
src/expr.c
src/select.c
src/sqliteInt.h
src/where.c
src/whereInt.h
src/wherecode.c
tool/addopcodes.tcl

index 50c2d8faef33dfd8d8eecf8fc3c36b5df6116002..4c47ee7fcd83b5480cb2693bc315347646e1843b 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sthe\s".lint\sfkey"\sshell\scommand\sfor\scases\swhere\sthe\schild\skey\sis\salso\san\nINTEGER\sPRIMARY\sKEY.
-D 2017-04-06T14:56:26.887
+C Proof\sof\sconcept\sfor\sthe\sability\sto\suse\sthe\sexpression\scolumns\sin\san\sindex\non\sexpressions\sin\splace\sof\sequivalent\sexpressions\sin\sthe\sresult\sset\sor\sin\nthe\sWHERE\sclause.\s\sThis\scheck-in\scompiles\sbut\sis\smostly\suntested.
+D 2017-04-07T19:41:31.032
 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a
@@ -354,7 +354,7 @@ F src/ctime.c 47d91a25ad8f199a71a5b1b7b169d6dd0d6e98c5719eca801568798743d1161c
 F src/date.c ee676e7694dfadbdd2fde1a258a71be8360ba5ae
 F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d
 F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c
-F src/expr.c 6bce2cbdd822963cf28e782938a96274cc37f18ac28dec7a4e35ccac09f66ce8
+F src/expr.c 8fd6b7bc10c2c33e017b0f2715efdc83c01e348be27797022ed9eaa3002ca720
 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae
 F src/func.c 9d52522cc8ae7f5cdadfe14594262f1618bc1f86083c4cd6da861b4cf5af6174
@@ -401,12 +401,12 @@ F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2
 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706
 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
-F src/select.c afcf31d8ed7c890328a31d3f350467ccd273af345b24562382b398d6d9cd0664
+F src/select.c b24e628a2b76800171f4c86e38b5d93e27f2c40e603b24733aa8e471029e6ecd
 F src/shell.c e9fede684f847402c0373fe5e270918e6ef47f51e57ba5aebff121d8c2bc1ea8
 F src/sqlite.h.in ab77e511620eebbd4ed7e4f52fae697b6870dda66c945acd2d3066f99c98e17e
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28
-F src/sqliteInt.h 6cf244eb06119b44e155717708e54f0638c35e9bd8ef59ea570eb1f093f0da44
+F src/sqliteInt.h 9affb53bb405dcea1d86e85198ebaf6232a684cc2b2af6b3c181869f1c8f3e93
 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1
 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@@ -482,9 +482,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
 F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344
 F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71
 F src/walker.c b71a992b413b3a022572eccf29ef4b4890223791
-F src/where.c 49b48b720184fdde747c468d7270feeb1b88c6a71092cea3a1aa168dc8ac0b0f
-F src/whereInt.h 2d50c2b74a33be44cb68fdecee30b4d93552f1f4
-F src/wherecode.c 677e95413c472c0b413023b6b69a47f40fce1b04
+F src/where.c 1d14e18f32231fa7969e718e7b60ef749b0065e2a7e1b6b00883b20732d280f1
+F src/whereInt.h 7a21ef633e26acbf46df04add2eba6e0a2100c78dc5879049e93f981fc3344df
+F src/wherecode.c 38d171e309c7b54d5bdc7d8b663ec16249ad8888e01a77f6c55e9350de8e8349
 F src/whereexpr.c 130cdd1a43af71b19755270fb1224874cf55158c
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
@@ -1482,7 +1482,7 @@ F test/zerodamage.test e59a56443d6298ecf7435f618f0b27654f0c849e
 F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5
 F tool/GetTclKit.bat 6afa640edc7810725aec61c3076ac617c4aaf0b7
 F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91
-F tool/addopcodes.tcl 10c889c4a65ec6c5604e4a47306fa77ff57ae189
+F tool/addopcodes.tcl ffa614f3eac5bd6672a5ca7c936500645e01d3a9f8329ab7cbf86582dd17f936
 F tool/build-all-msvc.bat c12328d06c45fec8baada5949e3d5af54bf8c887 x
 F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367
 F tool/cg_anno.tcl f95b0006c52cf7f0496b506343415b6ee3cdcdd3 x
@@ -1570,7 +1570,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 327eff25ba2420267cc8dc49dd3c3aab45f4bf9e060d1ad480e25d016d21f3ba
-R 260410c30d599e0993c58e23cef69640
-U dan
-Z 25db1dc906fb1b522f7b655980ddd579
+P 48826b222c110a90996a84605318ea6b1e502b8c5129f4d561f8350dbdbcd264
+R c609ef75ab8f5bb5565771cdc08e2586
+T *branch * covering-index-on-expr
+T *sym-covering-index-on-expr *
+T -sym-trunk *
+U drh
+Z 9d990a9e03df0f0f8f16d32c22292949
index 3814e9cddff25c51fa44e957d3fe9fa0c5dc610d..26e5bb9e6898f647fd40a87ec7f94d8278d510cd 100644 (file)
@@ -1 +1 @@
-48826b222c110a90996a84605318ea6b1e502b8c5129f4d561f8350dbdbcd264
\ No newline at end of file
+a52ef2ad7c0e14b78b801f16a1f6ea8d8fa9ae5d7d810e18dd24c600b662a312
\ No newline at end of file
index e3db59732ee9ccaac1b39abf8b0b0249f4d05178..afdbbb1275ed574109dc901ded4cb1c24ac799ab 100644 (file)
@@ -3192,6 +3192,10 @@ void sqlite3ExprCodeGetColumnOfTable(
   int iCol,       /* Index of the column to extract */
   int regOut      /* Extract the value into this register */
 ){
+  if( pTab==0 ){
+    sqlite3VdbeAddOp3(v, OP_Column, iTabCur, iCol, regOut);
+    return;
+  }
   if( iCol<0 || iCol==pTab->iPKey ){
     sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut);
   }else{
index 334307cce79622708fc63356c083e3ddc1ffa378..55d2584fbeb70c0b2112ebc56069244c8f261954 100644 (file)
@@ -3147,7 +3147,7 @@ static void substSelect(Parse*, Select *, int, ExprList*, int);
 ** This routine is part of the flattening procedure.  A subquery
 ** whose result set is defined by pEList appears as entry in the
 ** FROM clause of a SELECT such that the VDBE cursor assigned to that
-** FORM clause entry is iTable.  This routine make the necessary 
+** FORM clause entry is iTable.  This routine makes the necessary 
 ** changes to pExpr so that it refers directly to the source table
 ** of the subquery rather the result set of the subquery.
 */
index 2b3c934ecdcd28d716731e617361c608a44182aa..40660aed997d89128d875a952620eb5c2525f0d8 100644 (file)
@@ -3324,6 +3324,7 @@ struct Walker {
     struct CCurHint *pCCurHint;                /* Used by codeCursorHint() */
     int *aiCol;                                /* array of column indexes */
     struct IdxCover *pIdxCover;                /* Check for index coverage */
+    struct IdxExprTrans *pIdxTrans;            /* Convert indexed expr to column */
   } u;
 };
 
index 5a0b35bdf125f33d481d044833710da4666e18cc..38183d6849008bb01c4e2578e3ebff93f1cfbcc6 100644 (file)
@@ -4447,6 +4447,7 @@ WhereInfo *sqlite3WhereBegin(
   pWInfo->pParse = pParse;
   pWInfo->pTabList = pTabList;
   pWInfo->pOrderBy = pOrderBy;
+  pWInfo->pWhere = pWhere;
   pWInfo->pResultSet = pResultSet;
   pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1;
   pWInfo->nLevel = nTabList;
index f065fae6ba8c686f7f9629d15e77558ed30e301a..6bd4aab2b0c4d44548011007f01ff2e1c4f72afa 100644 (file)
@@ -417,6 +417,7 @@ struct WhereInfo {
   SrcList *pTabList;        /* List of tables in the join */
   ExprList *pOrderBy;       /* The ORDER BY clause or NULL */
   ExprList *pResultSet;     /* Result set of the query */
+  Expr *pWhere;             /* The complete WHERE clause */
   LogEst iLimit;            /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */
   int aiCurOnePass[2];      /* OP_OpenWrite cursors for the ONEPASS opt */
   int iContinue;            /* Jump here to continue with next record */
index 4fd5e16fac9944c4d6903d106a691c47e70c0009..bdf732755e4930ebe7c5f3ee0f6c333ae2dbf834 100644 (file)
@@ -1039,6 +1039,61 @@ static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){
   }
 }
 
+#if 1 /* INDEXEXPRTRANS */
+typedef struct IdxExprTrans {
+  Expr *pIdxExpr;    /* The index expression */
+  int iTabCur;       /* The cursor of the corresponding table */
+  int iIdxCur;       /* The cursor for the index */
+  int iIdxCol;       /* The column for the index */
+} IdxExprTrans;
+
+static int whereIndexExprTransNode(Walker *p, Expr *pExpr){
+  IdxExprTrans *pX = p->u.pIdxTrans;
+  if( sqlite3ExprCompare(pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){
+    pExpr->op = TK_COLUMN;
+    pExpr->iTable = pX->iIdxCur;
+    pExpr->iColumn = pX->iIdxCol;
+    pExpr->pTab = 0;
+    return WRC_Prune;
+  }else{
+    return WRC_Continue;
+  }
+}
+
+/*
+** For an indexes on expression X, locate every instance of expression X in pExpr
+** and change that subexpression into a reference to the appropriate column of
+** the index.
+*/
+static void whereIndexExprTrans(
+  Index *pIdx,      /* The Index */
+  int iTabCur,      /* Cursor of the table that is being indexed */
+  int iIdxCur,      /* Cursor of the index itself */
+  WhereInfo *pWInfo /* Transform expressions in this WHERE clause */
+){
+  int iIdxCol;               /* Column number of the index */
+  ExprList *aColExpr;        /* Expressions that are indexed */
+  Walker w;
+  IdxExprTrans x;
+  aColExpr = pIdx->aColExpr;
+  if( aColExpr==0 ) return;  /* Not an index on expressions */
+  memset(&w, 0, sizeof(w));
+  w.xExprCallback = whereIndexExprTransNode;
+  w.u.pIdxTrans = &x;
+  x.iTabCur = iTabCur;
+  x.iIdxCur = iIdxCur;
+  for(iIdxCol=0; iIdxCol<aColExpr->nExpr; iIdxCol++){
+    if( pIdx->aiColumn[iIdxCol]!=XN_EXPR ) continue;
+    assert( aColExpr->a[iIdxCol].pExpr!=0 );
+    x.iIdxCol = iIdxCol;
+    x.pIdxExpr = aColExpr->a[iIdxCol].pExpr;
+    sqlite3WalkExpr(&w, pWInfo->pWhere);
+    sqlite3WalkExprList(&w, pWInfo->pOrderBy);
+    sqlite3WalkExprList(&w, pWInfo->pResultSet);
+  }
+}
+#endif
+
 /*
 ** Generate code for the start of the iLevel-th loop in the WHERE clause
 ** implementation described by pWInfo.
@@ -1620,6 +1675,10 @@ Bitmask sqlite3WhereCodeOneLoopStart(
                            iRowidReg, pPk->nKeyCol); VdbeCoverage(v);
     }
 
+#if 1  /* INDEXEXPRTANS */
+    whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo);
+#endif
+
     /* Record the instruction used to terminate the loop. */
     if( pLoop->wsFlags & WHERE_ONEROW ){
       pLevel->op = OP_Noop;
index a6c58f1a251c83cff9bc343dd1fce681cb17fce5..dc96f2cfbe4f29dd1837da9ad56d4d7ea619e226 100644 (file)
@@ -32,6 +32,7 @@ set extras {
   UNCLOSED_STRING
   FUNCTION
   COLUMN
+  IDXCOLUMN
   AGG_FUNCTION
   AGG_COLUMN
   UMINUS