From 97bae794c202a995b9073866e894a3fc03381e1f Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 5 Jun 2015 15:59:57 +0000 Subject: [PATCH] Add a new opcode to the VDBE that gives the b-tree a hint about the set of columns in a table or index that are actually used by the query. FossilOrigin-Name: f167bba446b78dd7538d0b2bae3e6678f3b1ba28 --- manifest | 25 ++++++++++++++----------- manifest.uuid | 2 +- src/expr.c | 19 ++----------------- src/vdbe.c | 20 ++++++++++++++++++++ src/vdbe.h | 1 + src/vdbeInt.h | 3 +++ src/vdbeaux.c | 17 +++++++++++++++++ src/where.c | 19 +++++++++++++++++++ 8 files changed, 77 insertions(+), 29 deletions(-) diff --git a/manifest b/manifest index eb67a9af5b..73909a70b4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sname\sof\sSrcList.a[].zIndex\sto\sthe\smore\sdescriptive\nSrcList.a[0].zIndexedBy. -D 2015-06-04T12:08:53.261 +C Add\sa\snew\sopcode\sto\sthe\sVDBE\sthat\sgives\sthe\sb-tree\sa\shint\sabout\sthe\sset\nof\scolumns\sin\sa\stable\sor\sindex\sthat\sare\sactually\sused\sby\sthe\squery. +D 2015-06-05T15:59:57.203 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 994bab32a3a69e0c35bd148b65cde49879772964 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -202,7 +202,7 @@ F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b F src/date.c e4d50b3283696836ec1036b695ead9a19e37a5ac F src/dbstat.c f402e77e25089c6003d0c60b3233b9b3947d599a F src/delete.c 37964e6c1d73ff49cbea9ff690c9605fb15f600e -F src/expr.c d953b9f03c3c0f701f87a418fcfb9cba8befc6e0 +F src/expr.c 1980fffc7505d7696b5ec53475ed4bd6fd39f490 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c c9b63a217d86582c22121699a47f22f524608869 F src/func.c 5b8b8e77a0fb644eaf8947d413804622e32692b6 @@ -312,11 +312,11 @@ F src/update.c 487747b328b7216bb7f6af0695d6937d5c9e605f F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/util.c a6431c92803b975b7322724a7b433e538d243539 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c 0a6a1df5c31415a0e974e74e7bd412616889453d -F src/vdbe.h 7e538ecf47dccb307ea2d087c3ddc2dd8d70e79d -F src/vdbeInt.h f0ccddac48583d5f762dc554a9f79e85ea8807e0 +F src/vdbe.c c9b8985dfc5df9bd512342ea2e56af4be30cb31a +F src/vdbe.h 90048aea1910f9df93e6044592bd4a466dc9c5e7 +F src/vdbeInt.h 20295e482121d13437f69985f77db211cdc8bac1 F src/vdbeapi.c 6a0d7757987018ff6b1b81bc5293219cd26bb299 -F src/vdbeaux.c 46f9bc4b32866082eb87a36b461e487a0bbdbe8e +F src/vdbeaux.c 89c85926ce346988d275132e05ddb0c9681807c2 F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90 F src/vdbemem.c 67b302dc6df64b4d6785881c5d22bd4f9b17739d F src/vdbesort.c f5009e7a35e3065635d8918b9a31f498a499976b @@ -326,7 +326,7 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c ce2cb2d06faab54d1bce3e739bec79e063dd9113 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 -F src/where.c 2db8137f14644e2117c2e2350e08a05e02d6bdab +F src/where.c f957a39866d126cfe45bc20737085a01d241dab2 F src/whereInt.h a6f5a762bc1b4b1c76e1cea79976b437ac35a435 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1282,7 +1282,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9f035c45a4b84203e67b6e1b23cf11691dc43f1e -R ad5ce5f5b8d17995393297d9ed2a0d0e +P 6a9cf063379118dbb95c6cdc6d60af50e9867177 +R 26fb3dd084da8ca4266e7b6ea31232cf +T *branch * column-usage-hint +T *sym-column-usage-hint * +T -sym-trunk * U drh -Z de80e81db21512cdc452bca7645bb7ca +Z 4c54f566ac1c4e0f96dff99143c1643e diff --git a/manifest.uuid b/manifest.uuid index e2792cff66..206cd98c3c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6a9cf063379118dbb95c6cdc6d60af50e9867177 \ No newline at end of file +f167bba446b78dd7538d0b2bae3e6678f3b1ba28 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 56a62e0c3f..f3933b930a 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2208,17 +2208,6 @@ static void sqlite3ExprCodeIN( } #endif /* SQLITE_OMIT_SUBQUERY */ -/* -** Duplicate an 8-byte value -*/ -static char *dup8bytes(Vdbe *v, const char *in){ - char *out = sqlite3DbMallocRaw(sqlite3VdbeDb(v), 8); - if( out ){ - memcpy(out, in, 8); - } - return out; -} - #ifndef SQLITE_OMIT_FLOATING_POINT /* ** Generate an instruction that will put the floating point @@ -2231,12 +2220,10 @@ static char *dup8bytes(Vdbe *v, const char *in){ static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){ if( ALWAYS(z!=0) ){ double value; - char *zV; sqlite3AtoF(z, &value, sqlite3Strlen30(z), SQLITE_UTF8); assert( !sqlite3IsNaN(value) ); /* The new AtoF never returns NaN */ if( negateFlag ) value = -value; - zV = dup8bytes(v, (char*)&value); - sqlite3VdbeAddOp4(v, OP_Real, 0, iMem, 0, zV, P4_REAL); + sqlite3VdbeAddOp4Dup8(v, OP_Real, 0, iMem, 0, (u8*)&value, P4_REAL); } } #endif @@ -2262,10 +2249,8 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ assert( z!=0 ); c = sqlite3DecOrHexToI64(z, &value); if( c==0 || (c==2 && negFlag) ){ - char *zV; if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; } - zV = dup8bytes(v, (char*)&value); - sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64); + sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, iMem, 0, (u8*)&value, P4_INT64); }else{ #ifdef SQLITE_OMIT_FLOATING_POINT sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z); diff --git a/src/vdbe.c b/src/vdbe.c index 962d6fc3e3..d3fb3cb2d7 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3511,6 +3511,26 @@ case OP_Close: { break; } +#ifdef SQLITE_ENABLE_COLUMN_USED_MASK +/* Opcode: ColumnsUsed P1 * * P4 * +** +** This opcode (which only exists if SQLite was compiled with +** SQLITE_ENABLE_COLUMN_USED_MASK) identifies which columns of the +** table or index for cursor P1 are used. P4 is a 64-bit integer +** (P4_INT64) in which the first 63 bits are one for each of the +** first 63 columns of the table or index that are actually used +** by the cursor. The high-order bit is set if any column after +** the 64th is used. +*/ +case OP_ColumnsUsed: { + VdbeCursor *pC; + pC = p->apCsr[pOp->p1]; + assert( pC->pCursor ); + pC->maskUsed = *(u64*)pOp->p4.pI64; + break; +} +#endif + /* Opcode: SeekGE P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** diff --git a/src/vdbe.h b/src/vdbe.h index bb597b68d7..da1410282a 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -169,6 +169,7 @@ int sqlite3VdbeAddOp1(Vdbe*,int,int); int sqlite3VdbeAddOp2(Vdbe*,int,int,int); int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int); int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int); +int sqlite3VdbeAddOp4Dup8(Vdbe*,int,int,int,int,const u8*,int); int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int); int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno); void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index bb32bddc29..7ebd41d6ea 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -83,6 +83,9 @@ struct VdbeCursor { i64 seqCount; /* Sequence counter */ i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */ +#ifdef SQLITE_ENABLE_COLUMN_USED_MASK + u64 maskUsed; /* Mask of columns used by this cursor */ +#endif /* Cached information about the header for the data record that the ** cursor is currently pointing to. Only valid if cacheStatus matches diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 4c736fb33f..fc667ed47d 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -233,6 +233,23 @@ int sqlite3VdbeAddOp4( return addr; } +/* +** Add an opcode that includes the p4 value with a P4_INT64 type. +*/ +int sqlite3VdbeAddOp4Dup8( + Vdbe *p, /* Add the opcode to this VM */ + int op, /* The new opcode */ + int p1, /* The P1 operand */ + int p2, /* The P2 operand */ + int p3, /* The P3 operand */ + const u8 *zP4, /* The P4 operand */ + int p4type /* P4 operand type */ +){ + char *p4copy = sqlite3DbMallocRaw(sqlite3VdbeDb(p), 8); + if( p4copy ) memcpy(p4copy, zP4, 8); + return sqlite3VdbeAddOp4(p, op, p1, p2, p3, p4copy, p4type); +} + /* ** Add an OP_ParseSchema opcode. This routine is broken out from ** sqlite3VdbeAddOp4() since it needs to also needs to mark all btrees diff --git a/src/where.c b/src/where.c index 2dc3b17754..744448b01b 100644 --- a/src/where.c +++ b/src/where.c @@ -6871,6 +6871,10 @@ WhereInfo *sqlite3WhereBegin( SQLITE_INT_TO_PTR(n), P4_INT32); assert( n<=pTab->nCol ); } +#ifdef SQLITE_ENABLE_COLUMN_USED_MASK + sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, pTabItem->iCursor, 0, 0, + (const u8*)&pTabItem->colUsed, P4_INT64); +#endif }else{ sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); } @@ -6916,6 +6920,21 @@ WhereInfo *sqlite3WhereBegin( sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ); /* Hint to COMDB2 */ } VdbeComment((v, "%s", pIx->zName)); +#ifdef SQLITE_ENABLE_COLUMN_USED_MASK + { + u64 colUsed = 0; + int ii, jj; + for(ii=0; iinColumn; ii++){ + jj = pIx->aiColumn[ii]; + if( jj<0 ) continue; + if( jj>63 ) jj = 63; + if( (pTabItem->colUsed & MASKBIT(jj))==0 ) continue; + colUsed |= ((u64)1)<<(ii<63 ? ii : 63); + } + sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, iIndexCur, 0, 0, + (u8*)&colUsed, P4_INT64); + } +#endif /* SQLITE_ENABLE_COLUMN_USED_MASK */ } } if( iDb>=0 ) sqlite3CodeVerifySchema(pParse, iDb); -- 2.39.5