/ Check-in [78fb8838]
Login

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

Overview
Comment:Make sure registers are cleared properly prior to being used to store the result of an OP_Column operator.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | micro-optimizations
Files: files | file ages | folders
SHA1: 78fb8838d80b229418c347c63579989432e1af7d
User & Date: drh 2014-09-16 20:05:21
Context
2014-09-16
21:54
Continuing cleanup of memory register memory allocation handling. check-in: 2598aedc user: drh tags: micro-optimizations
20:05
Make sure registers are cleared properly prior to being used to store the result of an OP_Column operator. check-in: 78fb8838 user: drh tags: micro-optimizations
18:22
Simplification of the OP_Column logic for the case of rows with overflow. check-in: f7367803 user: drh tags: micro-optimizations
Changes
Hide Diffs Side-by-Side Diffs Show Whitespace Changes Patch

Changes to src/vdbe.c.

  2433   2433     /* Extract the content for the p2+1-th column.  Control can only
  2434   2434     ** reach this point if aOffset[p2], aOffset[p2+1], and aType[p2] are
  2435   2435     ** all valid.
  2436   2436     */
  2437   2437     assert( p2<pC->nHdrParsed );
  2438   2438     assert( rc==SQLITE_OK );
  2439   2439     assert( sqlite3VdbeCheckMemInvariants(pDest) );
         2440  +  VdbeMemReleaseExtern(pDest);
  2440   2441     if( pC->szRow>=aOffset[p2+1] ){
  2441   2442       /* This is the common case where the desired content fits on the original
  2442   2443       ** page - where the content is not on an overflow page */
  2443         -    VdbeMemReleaseExtern(pDest);
  2444   2444       sqlite3VdbeSerialGet(pC->aRow+aOffset[p2], aType[p2], pDest);
  2445   2445     }else{
  2446   2446       /* This branch happens only when content is on overflow pages */
  2447   2447       t = aType[p2];
  2448   2448       if( ((pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0
  2449   2449             && ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0))
  2450   2450        || (len = sqlite3VdbeSerialTypeLen(t))==0

Changes to src/vdbeaux.c.

  3302   3302       const void *v1, *v2;
  3303   3303       int n1, n2;
  3304   3304       Mem c1;
  3305   3305       Mem c2;
  3306   3306       c1.db = c2.db = pMem1->db;
  3307   3307       c1.flags = c2.flags = 0;
  3308   3308       c1.zMalloc = c2.zMalloc = 0;
         3309  +    c1.xDel = c2.xDel = 0;
  3309   3310       sqlite3VdbeMemShallowCopy(&c1, pMem1, MEM_Ephem);
  3310   3311       sqlite3VdbeMemShallowCopy(&c2, pMem2, MEM_Ephem);
  3311   3312       v1 = sqlite3ValueText((sqlite3_value*)&c1, pColl->enc);
  3312   3313       n1 = v1==0 ? 0 : c1.n;
  3313   3314       v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc);
  3314   3315       n2 = v2==0 ? 0 : c2.n;
  3315   3316       rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2);

Changes to src/vdbemem.c.

   306    306       memcpy(pMem, &t, sizeof(t));
   307    307       rc = ctx.isError;
   308    308     }
   309    309     return rc;
   310    310   }
   311    311   
   312    312   /*
   313         -** If the memory cell contains a string value that must be freed by
   314         -** invoking an external callback, free it now. Calling this function
   315         -** does not free any Mem.zMalloc buffer.
          313  +** If the memory cell contains a value that must be freed by
          314  +** invoking an external callback, then free it now. 
          315  +**
          316  +** This routine does NOT do any of the following:
          317  +**    (1)  Set the Mem.flags field to a rational value.
          318  +**    (2)  Free memory held by Mem.zMalloc
          319  +** The caller is expected to take care of setting Mem.flags appropriately.
   316    320   **
   317    321   ** The VdbeMemReleaseExtern() macro invokes this routine if only if there
   318    322   ** is work for this routine to do.
   319    323   */
   320    324   void sqlite3VdbeMemReleaseExternal(Mem *p){
   321    325     assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) );
   322    326     if( p->flags&MEM_Agg ){
................................................................................
   336    340   }
   337    341   
   338    342   /*
   339    343   ** Release memory held by the Mem p, both external memory cleared
   340    344   ** by p->xDel and memory in p->zMalloc.
   341    345   **
   342    346   ** This is a helper routine invoked by sqlite3VdbeMemRelease() in
   343         -** the uncommon case when there really is memory in p that is
   344         -** need of freeing.
          347  +** the uncommon case when there really is memory in p that needs
          348  +** to be freeing.
   345    349   */
   346    350   static SQLITE_NOINLINE void vdbeMemRelease(Mem *p){
   347    351     if( VdbeMemDynamic(p) ){
   348    352       sqlite3VdbeMemReleaseExternal(p);
   349    353     }
   350    354     if( p->zMalloc ){
   351    355       sqlite3DbFree(p->db, p->zMalloc);
   352    356       p->zMalloc = 0;
   353    357     }
   354    358     p->z = 0;
   355    359   }
   356    360   
   357    361   /*
   358         -** Release any memory held by the Mem. This may leave the Mem in an
   359         -** inconsistent state, for example with (Mem.z==0) and
   360         -** (Mem.flags==MEM_Str).
          362  +** Release any memory held by the Mem. This may leave the Mem.flags in an
          363  +** inconsistent state, for example with (Mem.z==0) and (Mem.flags==MEM_Str).
          364  +**
          365  +** This routine releases both the Mem.xDel space and the Mem.zMalloc space.
          366  +** Use sqlite3VdbeMemReleaseExternal() to release just the Mem.xDel space.
   361    367   */
   362    368   void sqlite3VdbeMemRelease(Mem *p){
   363    369     assert( sqlite3VdbeCheckMemInvariants(p) );
   364    370     if( VdbeMemDynamic(p) || p->zMalloc ){
   365    371       vdbeMemRelease(p);
   366    372     }else{
   367    373       p->z = 0;
................................................................................
   729    735   ** and flags gets srcType (either MEM_Ephem or MEM_Static).
   730    736   */
   731    737   void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
   732    738     assert( (pFrom->flags & MEM_RowSet)==0 );
   733    739     assert( pTo->db==pFrom->db );
   734    740     VdbeMemReleaseExtern(pTo);
   735    741     memcpy(pTo, pFrom, MEMCELLSIZE);
   736         -  pTo->xDel = 0;
          742  +  assert( pTo->xDel==0 );
   737    743     if( (pFrom->flags&MEM_Static)==0 ){
   738    744       pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Ephem);
   739    745       assert( srcType==MEM_Ephem || srcType==MEM_Static );
   740    746       pTo->flags |= srcType;
   741    747     }
   742    748   }
   743    749   
................................................................................
   749    755     int rc = SQLITE_OK;
   750    756   
   751    757     assert( pTo->db==pFrom->db );
   752    758     assert( (pFrom->flags & MEM_RowSet)==0 );
   753    759     VdbeMemReleaseExtern(pTo);
   754    760     memcpy(pTo, pFrom, MEMCELLSIZE);
   755    761     pTo->flags &= ~MEM_Dyn;
   756         -  pTo->xDel = 0;
          762  +  assert( pTo->xDel==0 );
   757    763   
   758    764     if( pTo->flags&(MEM_Str|MEM_Blob) ){
   759    765       if( 0==(pFrom->flags&MEM_Static) ){
   760    766         pTo->flags |= MEM_Ephem;
   761    767         rc = sqlite3VdbeMemMakeWriteable(pTo);
   762    768       }
   763    769     }
................................................................................
   902    908     Mem *pMem         /* OUT: Return data in this Mem structure. */
   903    909   ){
   904    910     char *zData;        /* Data from the btree layer */
   905    911     u32 available = 0;  /* Number of bytes available on the local btree page */
   906    912     int rc = SQLITE_OK; /* Return code */
   907    913   
   908    914     assert( sqlite3BtreeCursorIsValid(pCur) );
          915  +  assert( pMem->xDel==0 );
   909    916   
   910    917     /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert() 
   911    918     ** that both the BtShared and database handle mutexes are held. */
   912    919     assert( (pMem->flags & MEM_RowSet)==0 );
   913    920     if( key ){
   914    921       zData = (char *)sqlite3BtreeKeyFetch(pCur, &available);
   915    922     }else{
................................................................................
   918    925     assert( zData!=0 );
   919    926   
   920    927     if( offset+amt<=available ){
   921    928       sqlite3VdbeMemRelease(pMem);
   922    929       pMem->z = &zData[offset];
   923    930       pMem->flags = MEM_Blob|MEM_Ephem;
   924    931       pMem->n = (int)amt;
   925         -  }else if( SQLITE_OK==(rc = sqlite3VdbeMemGrow(pMem, amt+2, 0)) ){
          932  +  }else{
          933  +    pMem->flags = MEM_Null;
          934  +    if( SQLITE_OK==(rc = sqlite3VdbeMemGrow(pMem, amt+2, 0)) ){
   926    935       if( key ){
   927    936         rc = sqlite3BtreeKey(pCur, offset, amt, pMem->z);
   928    937       }else{
   929    938         rc = sqlite3BtreeData(pCur, offset, amt, pMem->z);
   930    939       }
   931    940       if( rc==SQLITE_OK ){
   932    941         pMem->z[amt] = 0;
................................................................................
   933    942         pMem->z[amt+1] = 0;
   934    943         pMem->flags = MEM_Blob|MEM_Term;
   935    944         pMem->n = (int)amt;
   936    945       }else{
   937    946         sqlite3VdbeMemRelease(pMem);
   938    947       }
   939    948     }
          949  +  }
   940    950   
   941    951     return rc;
   942    952   }
   943    953   
   944    954   /*
   945    955   ** The pVal argument is known to be a value other than NULL.
   946    956   ** Convert it into a string with encoding enc and return a pointer