/ Check-in [8c57bcc3]
Login

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

Overview
Comment:Add the sqlite3VdbeChangeDest() routine that can be used to eliminate OP_Move opcodes.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | experimental
Files: files | file ages | folders
SHA1: 8c57bcc327d3d456e0311f7246efed88d6429d3f
User & Date: drh 2014-08-29 11:24:42
Context
2014-08-29
11:24
Add the sqlite3VdbeChangeDest() routine that can be used to eliminate OP_Move opcodes. Closed-Leaf check-in: 8c57bcc3 user: drh tags: experimental
2014-08-28
19:38
Improved WHERETRACE messages for the estimated output row reductions from range scans. check-in: fdd478bb user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/expr.c.

  2430   2430   ** Generate code to move content from registers iFrom...iFrom+nReg-1
  2431   2431   ** over to iTo..iTo+nReg-1. Keep the column cache up-to-date.
  2432   2432   */
  2433   2433   void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){
  2434   2434     int i;
  2435   2435     struct yColCache *p;
  2436   2436     assert( iFrom>=iTo+nReg || iFrom+nReg<=iTo );
  2437         -  sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg);
         2437  +  if( nReg!=1 || sqlite3VdbeChangeDest(pParse->pVdbe, iFrom, iTo)==0 ){
         2438  +    sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg);
         2439  +  }
  2438   2440     for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
  2439   2441       int x = p->iReg;
  2440   2442       if( x>=iFrom && x<iFrom+nReg ){
  2441   2443         p->iReg += iTo-iFrom;
  2442   2444       }
  2443   2445     }
  2444   2446   }

Changes to src/vdbe.c.

  2237   2237   ** register has changed should have this bit set.
  2238   2238   **
  2239   2239   ** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 when
  2240   2240   ** the result is guaranteed to only be used as the argument of a length()
  2241   2241   ** or typeof() function, respectively.  The loading of large blobs can be
  2242   2242   ** skipped for length() and all content loading can be skipped for typeof().
  2243   2243   */
  2244         -case OP_Column: {
         2244  +case OP_Column: {                 /* out3 */
  2245   2245     i64 payloadSize64; /* Number of bytes in the record */
  2246   2246     int p2;            /* column number to retrieve */
  2247   2247     VdbeCursor *pC;    /* The VDBE cursor */
  2248   2248     BtCursor *pCrsr;   /* The BTree cursor */
  2249   2249     u32 *aType;        /* aType[i] holds the numeric type of the i-th column */
  2250   2250     u32 *aOffset;      /* aOffset[i] is offset to start of data for i-th column */
  2251   2251     int len;           /* The length of the serialized data for the column */

Changes to src/vdbe.h.

   175    175   void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1);
   176    176   void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2);
   177    177   void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3);
   178    178   void sqlite3VdbeChangeP5(Vdbe*, u8 P5);
   179    179   void sqlite3VdbeJumpHere(Vdbe*, int addr);
   180    180   void sqlite3VdbeChangeToNoop(Vdbe*, int addr);
   181    181   int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op);
          182  +int sqlite3VdbeChangeDest(Vdbe*, int iOld, int iNew);
   182    183   void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
   183    184   void sqlite3VdbeSetP4KeyInfo(Parse*, Index*);
   184    185   void sqlite3VdbeUsesBtree(Vdbe*, int);
   185    186   VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
   186    187   int sqlite3VdbeMakeLabel(Vdbe*);
   187    188   void sqlite3VdbeRunOnlyOnce(Vdbe*);
   188    189   void sqlite3VdbeDelete(Vdbe*);

Changes to src/vdbeaux.c.

   911    911     assert( (addr>=0 && addr<p->nOp) || p->db->mallocFailed );
   912    912     if( p->db->mallocFailed ){
   913    913       return (VdbeOp*)&dummy;
   914    914     }else{
   915    915       return &p->aOp[addr];
   916    916     }
   917    917   }
          918  +
          919  +/*
          920  +** If the previous opcode is not "fixed" (if it has not be jumped over)
          921  +** and if its output register is iOldOut, then change the output register
          922  +** to iNewOut and return true.  Otherwise return false.
          923  +*/
          924  +int sqlite3VdbeChangeDest(Vdbe *p, int iOldOut, int iNewOut){
          925  +  VdbeOp *pOp;
          926  +  u8 opflags;
          927  +  if( (p->nOp-1)<=(p->pParse->iFixedOp) ) return 0;
          928  +  pOp = &p->aOp[p->nOp-1];
          929  +  opflags = sqlite3OpcodeProperty[pOp->opcode];
          930  +  if( (opflags & OPFLG_OUT3)!=0 && pOp->p3==iOldOut ){
          931  +    pOp->p3 = iNewOut;
          932  +    return 1;
          933  +  }
          934  +  if( (opflags & OPFLG_OUT2)!=0 && pOp->p3==iOldOut ){
          935  +    pOp->p2 = iNewOut;
          936  +    return 1;
          937  +  }
          938  +  return 0;
          939  +}
          940  +
   918    941   
   919    942   #if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS)
   920    943   /*
   921    944   ** Return an integer value for one of the parameters to the opcode pOp
   922    945   ** determined by character c.
   923    946   */
   924    947   static int translateP(char c, const Op *pOp){