/ Check-in [874b7e99]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Omit OP_Close operations that occur immediately prior to OP_Halt and which cannot be jumped over.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 874b7e9999811c288ad41d07709f88e458d2d497
User & Date: drh 2014-01-04 16:49:02
Context
2014-01-04
19:27
Avoid redundant register loads during index key generation when doing a DELETE or INTEGRITY_CHECK on a table with multiple indices. check-in: 8f6e6149 user: drh tags: trunk
16:49
Omit OP_Close operations that occur immediately prior to OP_Halt and which cannot be jumped over. check-in: 874b7e99 user: drh tags: trunk
15:17
Improvements to the column-cache for nested AND/OR operators. check-in: 4e725f53 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Show Whitespace Changes Patch

Changes to src/build.c.

136
137
138
139
140
141
142

143
144
145
146
147
148
149
  /* Begin by generating some termination code at the end of the
  ** vdbe program
  */
  v = sqlite3GetVdbe(pParse);
  assert( !pParse->isMultiWrite 
       || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort));
  if( v ){

    sqlite3VdbeAddOp0(v, OP_Halt);

    /* The cookie mask contains one bit for each database file open.
    ** (Bit 0 is for main, bit 1 is for temp, and so forth.)  Bits are
    ** set for each database that is used.  Generate code to start a
    ** transaction on each used database and to verify the schema cookie
    ** on each used database.







>







136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
  /* Begin by generating some termination code at the end of the
  ** vdbe program
  */
  v = sqlite3GetVdbe(pParse);
  assert( !pParse->isMultiWrite 
       || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort));
  if( v ){
    while( sqlite3VdbeDeletePriorOpcode(v, OP_Close) ){}
    sqlite3VdbeAddOp0(v, OP_Halt);

    /* The cookie mask contains one bit for each database file open.
    ** (Bit 0 is for main, bit 1 is for temp, and so forth.)  Bits are
    ** set for each database that is used.  Generate code to start a
    ** transaction on each used database and to verify the schema cookie
    ** on each used database.

Changes to src/delete.c.

786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
                                    regBase+j);
    /* If the column affinity is REAL but the number is an integer, then it
    ** might be stored in the table as an integer (using a compact
    ** representation) then converted to REAL by an OP_RealAffinity opcode.
    ** But we are getting ready to store this value back into an index, where
    ** it should be converted by to INTEGER again.  So omit the OP_RealAffinity
    ** opcode if it is present */
    if( sqlite3VdbeGetOp(v, -1)->opcode==OP_RealAffinity ){
      sqlite3VdbeDeleteLastOpcode(v);
    }
  }
  if( regOut ){
    sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut);
  }
  sqlite3ReleaseTempRange(pParse, regBase, nCol);
  return regBase;
}







<
|
<







786
787
788
789
790
791
792

793

794
795
796
797
798
799
800
                                    regBase+j);
    /* If the column affinity is REAL but the number is an integer, then it
    ** might be stored in the table as an integer (using a compact
    ** representation) then converted to REAL by an OP_RealAffinity opcode.
    ** But we are getting ready to store this value back into an index, where
    ** it should be converted by to INTEGER again.  So omit the OP_RealAffinity
    ** opcode if it is present */

    sqlite3VdbeDeletePriorOpcode(v, OP_RealAffinity);

  }
  if( regOut ){
    sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut);
  }
  sqlite3ReleaseTempRange(pParse, regBase, nCol);
  return regBase;
}

Changes to src/sqliteInt.h.

2289
2290
2291
2292
2293
2294
2295

2296
2297
2298
2299
2300
2301
2302
  int nTab;            /* Number of previously allocated VDBE cursors */
  int nMem;            /* Number of memory cells used so far */
  int nSet;            /* Number of sets used so far */
  int nOnce;           /* Number of OP_Once instructions so far */
  int nOpAlloc;        /* Number of slots allocated for Vdbe.aOp[] */
  int nLabel;          /* Number of labels used */
  int *aLabel;         /* Space to hold the labels */

  int ckBase;          /* Base register of data during check constraints */
  int iPartIdxTab;     /* Table corresponding to a partial index */
  int iCacheLevel;     /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
  int iCacheCnt;       /* Counter used to generate aColCache[].lru values */
  struct yColCache {
    int iTable;           /* Table cursor number */
    int iColumn;          /* Table column number */







>







2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
  int nTab;            /* Number of previously allocated VDBE cursors */
  int nMem;            /* Number of memory cells used so far */
  int nSet;            /* Number of sets used so far */
  int nOnce;           /* Number of OP_Once instructions so far */
  int nOpAlloc;        /* Number of slots allocated for Vdbe.aOp[] */
  int nLabel;          /* Number of labels used */
  int *aLabel;         /* Space to hold the labels */
  int iFixedOp;        /* Never back out opcodes iFixedOp-1 or earlier */
  int ckBase;          /* Base register of data during check constraints */
  int iPartIdxTab;     /* Table corresponding to a partial index */
  int iCacheLevel;     /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
  int iCacheCnt;       /* Counter used to generate aColCache[].lru values */
  struct yColCache {
    int iTable;           /* Table cursor number */
    int iColumn;          /* Table column number */

Changes to src/vdbe.h.

171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1);
void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2);
void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3);
void sqlite3VdbeChangeP5(Vdbe*, u8 P5);
void sqlite3VdbeJumpHere(Vdbe*, int addr);
void sqlite3VdbeChangeToNoop(Vdbe*, int addr);
void sqlite3VdbeDeleteLastOpcode(Vdbe*);
void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
void sqlite3VdbeSetP4KeyInfo(Parse*, Index*);
void sqlite3VdbeUsesBtree(Vdbe*, int);
VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
int sqlite3VdbeMakeLabel(Vdbe*);
void sqlite3VdbeRunOnlyOnce(Vdbe*);
void sqlite3VdbeDelete(Vdbe*);







|







171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1);
void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2);
void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3);
void sqlite3VdbeChangeP5(Vdbe*, u8 P5);
void sqlite3VdbeJumpHere(Vdbe*, int addr);
void sqlite3VdbeChangeToNoop(Vdbe*, int addr);
int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op);
void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
void sqlite3VdbeSetP4KeyInfo(Parse*, Index*);
void sqlite3VdbeUsesBtree(Vdbe*, int);
VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
int sqlite3VdbeMakeLabel(Vdbe*);
void sqlite3VdbeRunOnlyOnce(Vdbe*);
void sqlite3VdbeDelete(Vdbe*);

Changes to src/vdbeaux.c.

272
273
274
275
276
277
278

279
280
281
282
283
284
285
...
620
621
622
623
624
625
626
627

628
629
630
631
632
633
634
...
725
726
727
728
729
730
731
732
733





734
735
736
737
738
739
740
  Parse *p = v->pParse;
  int j = -1-x;
  assert( v->magic==VDBE_MAGIC_INIT );
  assert( j<p->nLabel );
  if( j>=0 && p->aLabel ){
    p->aLabel[j] = v->nOp;
  }

}

/*
** Mark the VDBE as one that can only be run one time.
*/
void sqlite3VdbeRunOnlyOnce(Vdbe *p){
  p->runOnlyOnce = 1;
................................................................................
}

/*
** Change the P2 operand of instruction addr so that it points to
** the address of the next instruction to be coded.
*/
void sqlite3VdbeJumpHere(Vdbe *p, int addr){
  if( ALWAYS(addr>=0) ) sqlite3VdbeChangeP2(p, addr, p->nOp);

}


/*
** If the input FuncDef structure is ephemeral, then free it.  If
** the FuncDef is not ephermal, then do nothing.
*/
................................................................................
    if( addr==p->nOp-1 ) p->nOp--;
  }
}

/*
** Remove the last opcode inserted
*/
void sqlite3VdbeDeleteLastOpcode(Vdbe *p){
  p->nOp--;





}

/*
** Change the value of the P4 operand for a specific instruction.
** This routine is useful when a large program is loaded from a
** static array using sqlite3VdbeAddOpList but we want to make a
** few minor changes to the program.







>







 







|
>







 







|
|
>
>
>
>
>







272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
...
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
...
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
  Parse *p = v->pParse;
  int j = -1-x;
  assert( v->magic==VDBE_MAGIC_INIT );
  assert( j<p->nLabel );
  if( j>=0 && p->aLabel ){
    p->aLabel[j] = v->nOp;
  }
  p->iFixedOp = v->nOp - 1;
}

/*
** Mark the VDBE as one that can only be run one time.
*/
void sqlite3VdbeRunOnlyOnce(Vdbe *p){
  p->runOnlyOnce = 1;
................................................................................
}

/*
** Change the P2 operand of instruction addr so that it points to
** the address of the next instruction to be coded.
*/
void sqlite3VdbeJumpHere(Vdbe *p, int addr){
  sqlite3VdbeChangeP2(p, addr, p->nOp);
  p->pParse->iFixedOp = p->nOp - 1;
}


/*
** If the input FuncDef structure is ephemeral, then free it.  If
** the FuncDef is not ephermal, then do nothing.
*/
................................................................................
    if( addr==p->nOp-1 ) p->nOp--;
  }
}

/*
** Remove the last opcode inserted
*/
int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){
  if( (p->nOp-1)>(p->pParse->iFixedOp) && p->aOp[p->nOp-1].opcode==op ){
    sqlite3VdbeChangeToNoop(p, p->nOp-1);
    return 1;
  }else{
    return 0;
  }
}

/*
** Change the value of the P4 operand for a specific instruction.
** This routine is useful when a large program is loaded from a
** static array using sqlite3VdbeAddOpList but we want to make a
** few minor changes to the program.