/ Changes On Branch clear-subtype-fail
Login

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

Changes In Branch clear-subtype-fail Excluding Merge-Ins

This is equivalent to a diff from 96b780209c to ec653cbcae

2016-01-30
15:52
Only honor the register subtype value if the MEM_Subtype flag is set. Revised and improved fix for ticket [f45ac567eaa9f9]. (check-in: 1f4c667f37 user: drh tags: trunk)
15:46
A different way to clear the subtype on VDBE registers when the value of the register is overwritten with new content. To fix [[f45ac567eaa9f93]. (Closed-Leaf check-in: 2e9fb1295c user: dan tags: clear-subtype-flag)
14:53
Take care to clear the subtype on VDBE registers when the value of the register is overwritten with new content. (Closed-Leaf check-in: ec653cbcae user: drh tags: clear-subtype-fail)
14:17
Output subtype information on register traces for PRAGMA vdbe_trace. (check-in: 96b780209c user: drh tags: trunk)
13:32
Add the BTREE_FORDELETE and BTREE_AUXDELETE flags to the b-tree layer interface and use them. Add assert() statement to verify that they are correct. (check-in: 85c467041c user: drh tags: trunk)

Changes to src/vdbe.c.

   528    528   }
   529    529   static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){
   530    530     Mem *pOut;
   531    531     assert( pOp->p2>0 );
   532    532     assert( pOp->p2<=(p->nMem-p->nCursor) );
   533    533     pOut = &p->aMem[pOp->p2];
   534    534     memAboutToChange(p, pOut);
   535         -  if( VdbeMemDynamic(pOut) ){
          535  +  if( VdbeMemDynamicOrSubtype(pOut) ){
   536    536       return out2PrereleaseWithClear(pOut);
   537    537     }else{
   538    538       pOut->flags = MEM_Int;
   539    539       return pOut;
   540    540     }
   541    541   }
   542    542   
................................................................................
  2554   2554     /* Extract the content for the p2+1-th column.  Control can only
  2555   2555     ** reach this point if aOffset[p2], aOffset[p2+1], and pC->aType[p2] are
  2556   2556     ** all valid.
  2557   2557     */
  2558   2558     assert( p2<pC->nHdrParsed );
  2559   2559     assert( rc==SQLITE_OK );
  2560   2560     assert( sqlite3VdbeCheckMemInvariants(pDest) );
  2561         -  if( VdbeMemDynamic(pDest) ) sqlite3VdbeMemSetNull(pDest);
         2561  +  if( VdbeMemDynamicOrSubtype(pDest) ) sqlite3VdbeMemSetNull(pDest);
  2562   2562     assert( t==pC->aType[p2] );
  2563   2563     pDest->enc = encoding;
  2564   2564     if( pC->szRow>=aOffset[p2+1] ){
  2565   2565       /* This is the common case where the desired content fits on the original
  2566   2566       ** page - where the content is not on an overflow page */
  2567   2567       zData = pC->aRow + aOffset[p2];
  2568   2568       if( t<12 ){

Changes to src/vdbeInt.h.

   248    248   */
   249    249   #define MEM_Term      0x0200   /* String rep is nul terminated */
   250    250   #define MEM_Dyn       0x0400   /* Need to call Mem.xDel() on Mem.z */
   251    251   #define MEM_Static    0x0800   /* Mem.z points to a static string */
   252    252   #define MEM_Ephem     0x1000   /* Mem.z points to an ephemeral string */
   253    253   #define MEM_Agg       0x2000   /* Mem.z points to an agg function context */
   254    254   #define MEM_Zero      0x4000   /* Mem.i contains count of 0s appended to blob */
          255  +#define MEM_Subtype   0x8000   /* Mem.eSubtype might be non-zero */
   255    256   #ifdef SQLITE_OMIT_INCRBLOB
   256    257     #undef MEM_Zero
   257    258     #define MEM_Zero 0x0000
   258    259   #endif
          260  +
          261  +/* Return TRUE if Mem X contains dynamically allocated content - anything
          262  +** that needs to be deallocated to avoid a leak.
          263  +*/
          264  +#define VdbeMemDynamic(X)  \
          265  +  (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0)
          266  +
          267  +/* Return TRUE if MEM x contains dynamically allocated content, or if
          268  +** x might have a non-zero subtype
          269  +*/
          270  +#define VdbeMemDynamicOrSubtype(X)  \
          271  +  (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame|MEM_Subtype))!=0)
          272  +
   259    273   
   260    274   /*
   261    275   ** Clear any existing type flags from a Mem and replace them with f
   262    276   */
   263    277   #define MemSetTypeFlag(p, f) \
   264    278      ((p)->flags = ((p)->flags&~(MEM_TypeMask|MEM_Zero))|f)
   265    279   
................................................................................
   468    482   double sqlite3VdbeRealValue(Mem*);
   469    483   void sqlite3VdbeIntegerAffinity(Mem*);
   470    484   int sqlite3VdbeMemRealify(Mem*);
   471    485   int sqlite3VdbeMemNumerify(Mem*);
   472    486   void sqlite3VdbeMemCast(Mem*,u8,u8);
   473    487   int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*);
   474    488   void sqlite3VdbeMemRelease(Mem *p);
   475         -#define VdbeMemDynamic(X)  \
   476         -  (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0)
   477    489   int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
   478    490   const char *sqlite3OpcodeName(int);
   479    491   int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
   480    492   int sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
   481    493   int sqlite3VdbeCloseStatement(Vdbe *, int);
   482    494   void sqlite3VdbeFrameDelete(VdbeFrame*);
   483    495   int sqlite3VdbeFrameRestore(VdbeFrame *);

Changes to src/vdbeapi.c.

   365    365     sqlite3VdbeMemSetInt64(pCtx->pOut, iVal);
   366    366   }
   367    367   void sqlite3_result_null(sqlite3_context *pCtx){
   368    368     assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   369    369     sqlite3VdbeMemSetNull(pCtx->pOut);
   370    370   }
   371    371   void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){
   372         -  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   373         -  pCtx->pOut->eSubtype = eSubtype & 0xff;
          372  +  Mem *pOut = pCtx->pOut;
          373  +  assert( sqlite3_mutex_held(pOut->db->mutex) );
          374  +  pOut->eSubtype = eSubtype & 0xff;
          375  +  pOut->flags |= MEM_Subtype;
   374    376   }
   375    377   void sqlite3_result_text(
   376    378     sqlite3_context *pCtx, 
   377    379     const char *z, 
   378    380     int n,
   379    381     void (*xDel)(void *)
   380    382   ){

Changes to src/vdbemem.c.

   354    354   **
   355    355   ** This is a helper routine for sqlite3VdbeMemSetNull() and
   356    356   ** for sqlite3VdbeMemRelease().  Use those other routines as the
   357    357   ** entry point for releasing Mem resources.
   358    358   */
   359    359   static SQLITE_NOINLINE void vdbeMemClearExternAndSetNull(Mem *p){
   360    360     assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) );
   361         -  assert( VdbeMemDynamic(p) );
          361  +  assert( VdbeMemDynamicOrSubtype(p) );
   362    362     if( p->flags&MEM_Agg ){
   363    363       sqlite3VdbeMemFinalize(p, p->u.pDef);
   364    364       assert( (p->flags & MEM_Agg)==0 );
   365    365       testcase( p->flags & MEM_Dyn );
   366    366     }
   367    367     if( p->flags&MEM_Dyn ){
   368    368       assert( (p->flags&MEM_RowSet)==0 );
................................................................................
   372    372       sqlite3RowSetClear(p->u.pRowSet);
   373    373     }else if( p->flags&MEM_Frame ){
   374    374       VdbeFrame *pFrame = p->u.pFrame;
   375    375       pFrame->pParent = pFrame->v->pDelFrame;
   376    376       pFrame->v->pDelFrame = pFrame;
   377    377     }
   378    378     p->flags = MEM_Null;
          379  +  p->eSubtype = 0;
   379    380   }
   380    381   
   381    382   /*
   382    383   ** Release memory held by the Mem p, both external memory cleared
   383    384   ** by p->xDel and memory in p->zMalloc.
   384    385   **
   385    386   ** This is a helper routine invoked by sqlite3VdbeMemRelease() in
   386    387   ** the unusual case where there really is memory in p that needs
   387    388   ** to be freed.
   388    389   */
   389    390   static SQLITE_NOINLINE void vdbeMemClear(Mem *p){
   390         -  if( VdbeMemDynamic(p) ){
          391  +  if( VdbeMemDynamicOrSubtype(p) ){
   391    392       vdbeMemClearExternAndSetNull(p);
   392    393     }
   393    394     if( p->szMalloc ){
   394    395       sqlite3DbFree(p->db, p->zMalloc);
   395    396       p->szMalloc = 0;
   396    397     }
   397    398     p->z = 0;
................................................................................
   405    406   ** reset a Mem back to its minimum memory utilization.
   406    407   **
   407    408   ** Use sqlite3VdbeMemSetNull() to release just the Mem.xDel space
   408    409   ** prior to inserting new content into the Mem.
   409    410   */
   410    411   void sqlite3VdbeMemRelease(Mem *p){
   411    412     assert( sqlite3VdbeCheckMemInvariants(p) );
   412         -  if( VdbeMemDynamic(p) || p->szMalloc ){
          413  +  if( VdbeMemDynamicOrSubtype(p) || p->szMalloc ){
   413    414       vdbeMemClear(p);
   414    415     }
   415    416   }
   416    417   
   417    418   /*
   418    419   ** Convert a 64-bit IEEE double into a 64-bit signed integer.
   419    420   ** If the double is out of range of a 64-bit signed integer then
................................................................................
   644    645   ** routine to invoke the destructor and deallocates Mem.zMalloc.
   645    646   **
   646    647   ** Use this routine to reset the Mem prior to insert a new value.
   647    648   **
   648    649   ** Use sqlite3VdbeMemRelease() to complete erase the Mem prior to abandoning it.
   649    650   */
   650    651   void sqlite3VdbeMemSetNull(Mem *pMem){
   651         -  if( VdbeMemDynamic(pMem) ){
          652  +  if( VdbeMemDynamicOrSubtype(pMem) ){
   652    653       vdbeMemClearExternAndSetNull(pMem);
   653    654     }else{
   654    655       pMem->flags = MEM_Null;
   655    656     }
   656    657   }
   657    658   void sqlite3ValueSetNull(sqlite3_value *p){
   658    659     sqlite3VdbeMemSetNull((Mem*)p); 
................................................................................
   684    685   }
   685    686   
   686    687   /*
   687    688   ** Delete any previous value and set the value stored in *pMem to val,
   688    689   ** manifest type INTEGER.
   689    690   */
   690    691   void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){
   691         -  if( VdbeMemDynamic(pMem) ){
          692  +  if( VdbeMemDynamicOrSubtype(pMem) ){
   692    693       vdbeReleaseAndSetInt64(pMem, val);
   693    694     }else{
   694    695       pMem->u.i = val;
   695    696       pMem->flags = MEM_Int;
   696    697     }
   697    698   }
   698    699   

Changes to test/json103.test.

    56     56      WHERE rowid BETWEEN 31 AND 39 AND rowid%2==1;
    57     57   } {{{"n31":32.5,"n33":33,"n35":35,"n37":null,"n39":"orange"}}}
    58     58   do_execsql_test json103-220 {
    59     59     SELECT b, json_group_object(c,a) FROM t1
    60     60      WHERE rowid<7 GROUP BY b ORDER BY b;
    61     61   } {0 {{"n3":3,"n6":6}} 1 {{"n1":1,"n4":4}} 2 {{"n2":2,"n5":5}}}
    62     62   
    63         -
           63  +# ticket https://www.sqlite.org/src/info/f45ac567eaa9f93c 2016-01-30
           64  +# Invalid JSON generated by json_group_array() 
           65  +#
           66  +# The underlying problem is a failure to reset Mem.eSubtype
           67  +#
           68  +do_execsql_test json103-300 {
           69  +  DROP TABLE IF EXISTS t1;
           70  +  CREATE TABLE t1(x);
           71  +  INSERT INTO t1 VALUES(1),('abc');
           72  +  SELECT
           73  +     json_group_array(x),
           74  +     json_group_array(json_object('x',x))
           75  +    FROM t1;
           76  +} {{[1,"abc"]} {[{"x":1},{"x":"abc"}]}}
    64     77   
    65     78   finish_test