Proof of concept for the ability to use the expression columns in an index

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
This commit is contained in:
drh 2017-04-07 19:41:31 +00:00
parent 54e2efcd2f
commit aca19e19a8
9 changed files with 85 additions and 15 deletions

View File

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

View File

@ -1 +1 @@
48826b222c110a90996a84605318ea6b1e502b8c5129f4d561f8350dbdbcd264
a52ef2ad7c0e14b78b801f16a1f6ea8d8fa9ae5d7d810e18dd24c600b662a312

View 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{

View 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.
*/

View 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;
};

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

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

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

View File

@ -32,6 +32,7 @@ set extras {
UNCLOSED_STRING
FUNCTION
COLUMN
IDXCOLUMN
AGG_FUNCTION
AGG_COLUMN
UMINUS