/ 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 Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/build.c.

   136    136     /* Begin by generating some termination code at the end of the
   137    137     ** vdbe program
   138    138     */
   139    139     v = sqlite3GetVdbe(pParse);
   140    140     assert( !pParse->isMultiWrite 
   141    141          || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort));
   142    142     if( v ){
          143  +    while( sqlite3VdbeDeletePriorOpcode(v, OP_Close) ){}
   143    144       sqlite3VdbeAddOp0(v, OP_Halt);
   144    145   
   145    146       /* The cookie mask contains one bit for each database file open.
   146    147       ** (Bit 0 is for main, bit 1 is for temp, and so forth.)  Bits are
   147    148       ** set for each database that is used.  Generate code to start a
   148    149       ** transaction on each used database and to verify the schema cookie
   149    150       ** on each used database.

Changes to src/delete.c.

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

Changes to src/sqliteInt.h.

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

Changes to src/vdbe.h.

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

Changes to src/vdbeaux.c.

   272    272     Parse *p = v->pParse;
   273    273     int j = -1-x;
   274    274     assert( v->magic==VDBE_MAGIC_INIT );
   275    275     assert( j<p->nLabel );
   276    276     if( j>=0 && p->aLabel ){
   277    277       p->aLabel[j] = v->nOp;
   278    278     }
          279  +  p->iFixedOp = v->nOp - 1;
   279    280   }
   280    281   
   281    282   /*
   282    283   ** Mark the VDBE as one that can only be run one time.
   283    284   */
   284    285   void sqlite3VdbeRunOnlyOnce(Vdbe *p){
   285    286     p->runOnlyOnce = 1;
................................................................................
   620    621   }
   621    622   
   622    623   /*
   623    624   ** Change the P2 operand of instruction addr so that it points to
   624    625   ** the address of the next instruction to be coded.
   625    626   */
   626    627   void sqlite3VdbeJumpHere(Vdbe *p, int addr){
   627         -  if( ALWAYS(addr>=0) ) sqlite3VdbeChangeP2(p, addr, p->nOp);
          628  +  sqlite3VdbeChangeP2(p, addr, p->nOp);
          629  +  p->pParse->iFixedOp = p->nOp - 1;
   628    630   }
   629    631   
   630    632   
   631    633   /*
   632    634   ** If the input FuncDef structure is ephemeral, then free it.  If
   633    635   ** the FuncDef is not ephermal, then do nothing.
   634    636   */
................................................................................
   725    727       if( addr==p->nOp-1 ) p->nOp--;
   726    728     }
   727    729   }
   728    730   
   729    731   /*
   730    732   ** Remove the last opcode inserted
   731    733   */
   732         -void sqlite3VdbeDeleteLastOpcode(Vdbe *p){
   733         -  p->nOp--;
          734  +int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){
          735  +  if( (p->nOp-1)>(p->pParse->iFixedOp) && p->aOp[p->nOp-1].opcode==op ){
          736  +    sqlite3VdbeChangeToNoop(p, p->nOp-1);
          737  +    return 1;
          738  +  }else{
          739  +    return 0;
          740  +  }
   734    741   }
   735    742   
   736    743   /*
   737    744   ** Change the value of the P4 operand for a specific instruction.
   738    745   ** This routine is useful when a large program is loaded from a
   739    746   ** static array using sqlite3VdbeAddOpList but we want to make a
   740    747   ** few minor changes to the program.