-C Performance\soptimization\sfor\sthe\sOP_Column\sopcode.
-D 2015-10-15T21:30:24.579
+C Whenever\stwo\sor\smore\sOP_Column\sopcodes\son\sthe\ssame\scursor\soccur\sin\ssuccession,\ntry\sto\sreordering\sthem\sso\sthat\sthe\sone\sthat\sextracts\sthe\sright-most\scolumn\sis\nfirst,\sso\sthat\sit\swill\swarm\sup\sthe\srow\scache\sfor\sall\sthose\sthat\sfollow.\s\sThis\ngives\sa\ssmall\sperformance\sboost.
+D 2015-10-16T03:34:38.572
F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 8e42cb55739cd8c12e1fd25401956e2019448f6a
F src/backup.c c3a9c4209439b806c44cf30daf466955727bf46c
F src/bitvec.c d1f21d7d91690747881f03940584f4cc548c9d3d
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
-F src/btree.c 0b74bc28b2dc907cba03b5b4b3b81584273be699
+F src/btree.c ea8c62f65e57e49bd6b0988cd681aca7246b51af
F src/btree.h 40189aefdc2b830d25c8b58fd7d56538481bfdd7
F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0
F src/build.c d6162335d690396dfc5c4bd59e8b2b0c14ba6285
F src/sqlite.h.in 839c818e16ea68703d90d17bd2bb3607191debce
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3ext.h 4b66e3e3435da4b4c8c83696d0349f0c503b3924
-F src/sqliteInt.h 1ad779ee62efee60494af0a75d8d45592f9f53c3
+F src/sqliteInt.h 5332b07164eef1db4a60d2f1301fbb33de71c6d9
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
F src/status.c 286f6398a4d2cd1e8ff0771e3d30f8dddb4768ea
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
F src/util.c fc612367108b74573c5fd13a85d0a23027f438bd
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
-F src/vdbe.c c33faa487c474d41a082979206896988448c9df9
+F src/vdbe.c 32865d7eb6d9241879b1ef62f017abf33811bc2e
F src/vdbe.h 4bc88bd0e06f8046ee6ab7487c0015e85ad949ad
F src/vdbeInt.h 8b867eac234e28627ffcace3cd4b4b79bbec664b
F src/vdbeapi.c 020681b943e77766b32ae1cddf86d7831b7374ca
-F src/vdbeaux.c fd00b489ab3f44f2dca1e4344faf289b7bfcf649
+F src/vdbeaux.c 170a0eef214941c76f79697640219045e529fcc0
F src/vdbeblob.c 565fabd302f5fca3bdf3d56cac330483616a39b6
F src/vdbemem.c 19b3036aa4d676e7103b0fb5efd6327da455f915
F src/vdbesort.c 8b23930a1289526f6d2a3a9f2e965bcc963e4a68
F tool/mkautoconfamal.sh d1a2da0e15b2ed33d60af35c7e9d483f13a8eb9f
F tool/mkkeywordhash.c dfff09dbbfaf950e89af294f48f902181b144670
F tool/mkopcodec.tcl edde8adc42621b5e598127f8cdc6d52cfe21f52b
-F tool/mkopcodeh.tcl e04177031532b7aa9379ded50e820231ac4abd6e
+F tool/mkopcodeh.tcl 726340f306e455b478fbe777d71467d220fd3aa5
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
F tool/mkpragmatab.tcl 84af2b180484323a2ea22a2279e8bd9e3e1e492e
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 871e091df651b2275a672c35ff938bd4b6db0d7f
-R 2a9ee0eee7d0527a150149dc10bab0fb
+P 076be5474df628bbbfd2b645adba30e1e093acd0
+R fa3f71993fa566414c3dbec59bd18acc
+T *branch * reorder-column-opcodes
+T *sym-reorder-column-opcodes *
+T -sym-trunk *
U drh
-Z 586c37c7b737d31273c8670597b9862e
+Z 5fb19142d7f39beb17e045600e97d9ef
-076be5474df628bbbfd2b645adba30e1e093acd0
\ No newline at end of file
+08e8f04d1241db8f190686404874461371ffbeaa
\ No newline at end of file
/* If required, populate the overflow page-list cache. */
if( (pCur->curFlags & BTCF_ValidOvfl)!=0 ){
- assert(!pCur->aOverflow[iIdx] || pCur->aOverflow[iIdx]==nextPage);
+ assert( pCur->aOverflow[iIdx]==0
+ || pCur->aOverflow[iIdx]==nextPage
+ || CORRUPT_DB );
pCur->aOverflow[iIdx] = nextPage;
}
#define SQLITE_Transitive 0x0200 /* Transitive constraints */
#define SQLITE_OmitNoopJoin 0x0400 /* Omit unused tables in joins */
#define SQLITE_Stat34 0x0800 /* Use STAT3 or STAT4 data */
+#define SQLITE_RowCache 0x1000 /* Reorder OP_Column opcodes */
#define SQLITE_AllOpts 0xffff /* All optimizations */
/*
/* Sanity checking on other operands */
#ifdef SQLITE_DEBUG
- assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] );
+ assert( (pOp->opflags&~OPFLG_JMPDEST)==sqlite3OpcodeProperty[pOp->opcode] );
if( (pOp->opflags & OPFLG_IN1)!=0 ){
assert( pOp->p1>0 );
assert( pOp->p1<=(p->nMem-p->nCursor) );
** (4) Initialize the p4.xAdvance pointer on opcodes that use it.
**
** (5) Reclaim the memory allocated for storing labels.
+**
+** (6) Set the Op.opflags field on all opcodes, and especially the
+** OPFLG_JMPDEST bit.
+**
+** (7) Reorders OP_Column opcodes against the same cursor so that the
+** last column is extracted first. This is a performance optimization.
*/
static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
- int i;
+ int i, m;
int nMaxArgs = *pMaxFuncArgs;
Op *pOp;
Parse *pParse = p->pParse;
int *aLabel = pParse->aLabel;
p->readOnly = 1;
p->bIsReader = 0;
+
+ /* First cut at the Op.opcode flags */
for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
- u8 opcode = pOp->opcode;
+ pOp->opflags = sqlite3OpcodeProperty[pOp->opcode];
+ }
+ /* Resolve goto labels. And add OPFLG_JMPDEST flags to the
+ ** destinations of jumps. */
+ for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
+ if( (pOp->opflags & OPFLG_JUMP)!=0 ){
+ if( pOp->p2<0 ){
+ assert( -1-pOp->p2<pParse->nLabel );
+ pOp->p2 = aLabel[-1-pOp->p2];
+ }
+ if( pOp->p2>0 && pOp->p2<p->nOp ){
+ p->aOp[pOp->p2].opflags |= OPFLG_JMPDEST;
+ }
+ }
+ }
+ sqlite3DbFree(p->db, pParse->aLabel);
+ pParse->aLabel = 0;
+ pParse->nLabel = 0;
+
+ /* Third pass: fix up opcodes */
+ for(pOp=p->aOp, i=m=0; i<p->nOp; i++, pOp++){
/* NOTE: Be sure to update mkopcodeh.awk when adding or removing
** cases from this switch! */
- switch( opcode ){
+ switch( pOp->opcode ){
+ case OP_Column: {
+ if( OptimizationEnabled(p->db, SQLITE_RowCache) && i>=m ){
+ /* Reorder OP_Column opcodes so that the right-most column is
+ ** extracted first. This warms up the row cache and helps the
+ ** subsequent OP_Column opcodes to run faster */
+ int j;
+ int b = 0;
+ int p2 = pOp->p2;
+ for(j=1; pOp[j].opcode==OP_Column; j++){
+ if( pOp[j].p1!=pOp->p1 ) break;
+ if( pOp[j].opflags & OPFLG_JMPDEST ) break;
+ if( pOp[j].p2>p2 ){ b = j; p2 = pOp[j].p2; }
+ }
+ if( b ) SWAP(Op, pOp[0], pOp[b]);
+ m = i+j;
+ }
+ break;
+ }
case OP_Transaction: {
if( pOp->p2!=0 ) p->readOnly = 0;
/* fall thru */
break;
}
}
-
- pOp->opflags = sqlite3OpcodeProperty[opcode];
- if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){
- assert( -1-pOp->p2<pParse->nLabel );
- pOp->p2 = aLabel[-1-pOp->p2];
- }
}
- sqlite3DbFree(p->db, pParse->aLabel);
- pParse->aLabel = 0;
- pParse->nLabel = 0;
*pMaxFuncArgs = nMaxArgs;
assert( p->bIsReader!=0 || DbMaskAllZero(p->btreeMask) );
}
# The following are the opcodes that are processed by resolveP2Values()
#
set rp2v_ops {
+ OP_Column
OP_Transaction
OP_AutoCommit
OP_Savepoint
puts "** comments following the \"case\" for each opcode in the vdbe.c"
puts "** are encoded into bitvectors as follows:"
puts "*/"
-puts "#define OPFLG_JUMP 0x0001 /* jump: P2 holds jmp target */"
-puts "#define OPFLG_IN1 0x0002 /* in1: P1 is an input */"
-puts "#define OPFLG_IN2 0x0004 /* in2: P2 is an input */"
-puts "#define OPFLG_IN3 0x0008 /* in3: P3 is an input */"
-puts "#define OPFLG_OUT2 0x0010 /* out2: P2 is an output */"
-puts "#define OPFLG_OUT3 0x0020 /* out3: P3 is an output */"
+puts "#define OPFLG_JUMP 0x01 /* jump: P2 holds jmp target */"
+puts "#define OPFLG_IN1 0x02 /* in1: P1 is an input */"
+puts "#define OPFLG_IN2 0x04 /* in2: P2 is an input */"
+puts "#define OPFLG_IN3 0x08 /* in3: P3 is an input */"
+puts "#define OPFLG_OUT2 0x10 /* out2: P2 is an output */"
+puts "#define OPFLG_OUT3 0x20 /* out3: P3 is an output */"
+puts "#define OPFLG_JMPDEST 0x40 /* A jump destination */"
puts "#define OPFLG_INITIALIZER \173\\"
for {set i 0} {$i<=$max} {incr i} {
if {$i%8==0} {