From: drh Date: Fri, 14 Dec 2018 20:20:37 +0000 (+0000) Subject: Add the OP_ColumnsUsed opcode (when compiled with X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0f2654ecd91e5e12d0cadb71da457a72ce1547f7;p=thirdparty%2Fsqlite.git Add the OP_ColumnsUsed opcode (when compiled with SQLITE_ENABLE_COLUMN_USED_MASK) as a hint to the b-tree layer as to which columns of a btree cursor will be used. (Backport from 3.8.11) FossilOrigin-Name: b29e02f877d7b85f783a9255794883a85590ff8eafac130a3234eb65d0f717f1 --- diff --git a/manifest b/manifest index 022df6e1cf..c92e507b26 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sSQLITE_ENABLE_UPDATE_DELETE_LIMIT\sfunctionality\sso\sthat\sit\sworks\swith\nviews\sand\sWITHOUT\sROWID\stables.\sThis\sis\sa\smodified\scherrypick\sof\s[dae4a97a]. -D 2017-11-14T18:26:22.534 +C Add\sthe\sOP_ColumnsUsed\sopcode\s(when\scompiled\swith\nSQLITE_ENABLE_COLUMN_USED_MASK)\sas\sa\shint\sto\sthe\sb-tree\slayer\sas\sto\swhich\ncolumns\sof\sa\sbtree\scursor\swill\sbe\sused.\n(Backport\sfrom\s3.8.11) +D 2018-12-14T20:20:37.993 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 00d12636df7a5b08af09116bcd6c7bfd49b8b3b4 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -182,7 +182,7 @@ F src/complete.c 198a0066ba60ab06fc00fba1998d870a4d575463 F src/ctime.c 98f89724adc891a1a4c655bee04e33e716e05887 F src/date.c e4d50b3283696836ec1036b695ead9a19e37a5ac F src/delete.c 7a9df72134437c7f556c2002e3df6d9cba6488aa2a264d05e3ef2b5e49c308d4 -F src/expr.c d09dac67d53c78880ba31d56e8ba2be3a6490553 +F src/expr.c b74a30503b581982e198d3c8173e2895fc4b7af3ad4641f4b84b4cf9d12f752f F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c f19ee86f39aac8069761b3c2acd65ace057d33f793b048734e5d203ef038be9e F src/func.c 8028a8f79becc879268a114729263a24733ecdb610e7b7ec6ddb228bc2c13cf1 @@ -293,11 +293,11 @@ F src/update.c 262a470e3aa82bf57648cc34eb8930d602fc3eeaf5c6039ac362a63b7c1f8072 F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/util.c 98a7627ca48ad3265b6940915a1d08355eb3fc7e F src/vacuum.c 9460b9de7b2d4e34b0d374894aa6c8a0632be8ec -F src/vdbe.c 1e2abdaedcbd3697994c4f244ae388b2afbe1e1023537a78abdf0bbf70ef23a7 -F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3 -F src/vdbeInt.h d96370101d9109cc476b42951272bd660336a638a6b8ef0d72c0911d6cdffbfd +F src/vdbe.c 6ea32aa0789fca11f02b067805b72c84794d4757af08bfa497d7ef19406a785a +F src/vdbe.h 87fd8b2c5b3af40f9e1a210d928e23e593c22b383ddc7215c76d76e4bc612331 +F src/vdbeInt.h 538f6a69152c0a6cfab17161854b793918eae73981b6c82d39d8b46c8878cc77 F src/vdbeapi.c 583d56b129dd27f12bed518270de9ebe521e6a75 -F src/vdbeaux.c c562ac4e1d5803287f5ad2718460eb7e1f22b8356b22603f67f6b849056465e1 +F src/vdbeaux.c eda1c639cec26e648de92ae61e703a4f6f857504e799c355e6e48b8ad2166f71 F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90 F src/vdbemem.c c0dc81285b7571b0a31c40f17846fe2397ec1cd9 F src/vdbesort.c 919717d7599fa31d343ec28bffd0f9e91a4ff5f6 @@ -307,7 +307,7 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 878c8e1a51cb2ec45c395d26b7d5cd9e1a098e4a F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 -F src/where.c 3508f80b35073fbf384f6465337cd6820f333b1e8ec2ddb1478af43c4eec1eeb +F src/where.c 8a445862f98a0318d4dc4db78d4834dc8188a439dcb2fc02cb86bd58686bcddf F src/whereInt.h 1d1fd0b3b9b56e08f5d3583c70a2c785a3c43941 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1252,7 +1252,8 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 30aa941fc16c1affe3821ff2d9a4955e14ab18cd4ece27037bd6bb532fcaa052 -R c0304b6b74e580ff6d98e75086a36094 -U dan -Z 127d4fcc427982bc4413b5e864902384 +P b2679d3b7ad090cbcb536317989f3ad1a9470e9f39daef561934d9d18dc69240 +Q +711a176cbfad5dde6defa9648fba6d0d663af134 +R 8838f6e2ca1bc8379cdfc7dc2e1821b8 +U drh +Z de0aa8652dbca2b433cca1f20e9d3056 diff --git a/manifest.uuid b/manifest.uuid index 15951044ad..7315ae469a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b2679d3b7ad090cbcb536317989f3ad1a9470e9f39daef561934d9d18dc69240 \ No newline at end of file +b29e02f877d7b85f783a9255794883a85590ff8eafac130a3234eb65d0f717f1 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index e6ac0f6796..7d63c2258f 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2206,17 +2206,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 @@ -2229,12 +2218,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 @@ -2260,10 +2247,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 750f61f578..f39d4040ff 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3504,6 +3504,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 b715241b41..62bc853a3f 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 b3ebccabab..d7cba523d0 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -89,7 +89,6 @@ struct VdbeCursor { #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 ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of diff --git a/src/vdbeaux.c b/src/vdbeaux.c index f1262489e6..0ebc7e8d21 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -222,6 +222,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 c1b4c861e9..5bd9f65a8c 100644 --- a/src/where.c +++ b/src/where.c @@ -6891,6 +6891,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); } @@ -6936,6 +6940,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);