/ 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
529
530
531
532
533
534
535

536
537
538
539
540
541
542
528
529
530
531
532
533
534

535
536
537
538
539
540
541
542







-
+







}
static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){
  Mem *pOut;
  assert( pOp->p2>0 );
  assert( pOp->p2<=(p->nMem-p->nCursor) );
  pOut = &p->aMem[pOp->p2];
  memAboutToChange(p, pOut);
  if( VdbeMemDynamic(pOut) ){
  if( VdbeMemDynamicOrSubtype(pOut) ){
    return out2PrereleaseWithClear(pOut);
  }else{
    pOut->flags = MEM_Int;
    return pOut;
  }
}

2554
2555
2556
2557
2558
2559
2560
2561

2562
2563
2564
2565
2566
2567
2568
2554
2555
2556
2557
2558
2559
2560

2561
2562
2563
2564
2565
2566
2567
2568







-
+







  /* Extract the content for the p2+1-th column.  Control can only
  ** reach this point if aOffset[p2], aOffset[p2+1], and pC->aType[p2] are
  ** all valid.
  */
  assert( p2<pC->nHdrParsed );
  assert( rc==SQLITE_OK );
  assert( sqlite3VdbeCheckMemInvariants(pDest) );
  if( VdbeMemDynamic(pDest) ) sqlite3VdbeMemSetNull(pDest);
  if( VdbeMemDynamicOrSubtype(pDest) ) sqlite3VdbeMemSetNull(pDest);
  assert( t==pC->aType[p2] );
  pDest->enc = encoding;
  if( pC->szRow>=aOffset[p2+1] ){
    /* This is the common case where the desired content fits on the original
    ** page - where the content is not on an overflow page */
    zData = pC->aRow + aOffset[p2];
    if( t<12 ){

Changes to src/vdbeInt.h.

248
249
250
251
252
253
254

255
256
257
258













259
260
261
262
263
264
265
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279







+




+
+
+
+
+
+
+
+
+
+
+
+
+







*/
#define MEM_Term      0x0200   /* String rep is nul terminated */
#define MEM_Dyn       0x0400   /* Need to call Mem.xDel() on Mem.z */
#define MEM_Static    0x0800   /* Mem.z points to a static string */
#define MEM_Ephem     0x1000   /* Mem.z points to an ephemeral string */
#define MEM_Agg       0x2000   /* Mem.z points to an agg function context */
#define MEM_Zero      0x4000   /* Mem.i contains count of 0s appended to blob */
#define MEM_Subtype   0x8000   /* Mem.eSubtype might be non-zero */
#ifdef SQLITE_OMIT_INCRBLOB
  #undef MEM_Zero
  #define MEM_Zero 0x0000
#endif

/* Return TRUE if Mem X contains dynamically allocated content - anything
** that needs to be deallocated to avoid a leak.
*/
#define VdbeMemDynamic(X)  \
  (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0)

/* Return TRUE if MEM x contains dynamically allocated content, or if
** x might have a non-zero subtype
*/
#define VdbeMemDynamicOrSubtype(X)  \
  (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame|MEM_Subtype))!=0)


/*
** Clear any existing type flags from a Mem and replace them with f
*/
#define MemSetTypeFlag(p, f) \
   ((p)->flags = ((p)->flags&~(MEM_TypeMask|MEM_Zero))|f)

468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
482
483
484
485
486
487
488


489
490
491
492
493
494
495







-
-







double sqlite3VdbeRealValue(Mem*);
void sqlite3VdbeIntegerAffinity(Mem*);
int sqlite3VdbeMemRealify(Mem*);
int sqlite3VdbeMemNumerify(Mem*);
void sqlite3VdbeMemCast(Mem*,u8,u8);
int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*);
void sqlite3VdbeMemRelease(Mem *p);
#define VdbeMemDynamic(X)  \
  (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0)
int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
const char *sqlite3OpcodeName(int);
int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
int sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
int sqlite3VdbeCloseStatement(Vdbe *, int);
void sqlite3VdbeFrameDelete(VdbeFrame*);
int sqlite3VdbeFrameRestore(VdbeFrame *);

Changes to src/vdbeapi.c.

365
366
367
368
369
370
371

372
373



374
375
376
377
378
379
380
365
366
367
368
369
370
371
372


373
374
375
376
377
378
379
380
381
382







+
-
-
+
+
+







  sqlite3VdbeMemSetInt64(pCtx->pOut, iVal);
}
void sqlite3_result_null(sqlite3_context *pCtx){
  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
  sqlite3VdbeMemSetNull(pCtx->pOut);
}
void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){
  Mem *pOut = pCtx->pOut;
  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
  pCtx->pOut->eSubtype = eSubtype & 0xff;
  assert( sqlite3_mutex_held(pOut->db->mutex) );
  pOut->eSubtype = eSubtype & 0xff;
  pOut->flags |= MEM_Subtype;
}
void sqlite3_result_text(
  sqlite3_context *pCtx, 
  const char *z, 
  int n,
  void (*xDel)(void *)
){

Changes to src/vdbemem.c.

354
355
356
357
358
359
360
361

362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378

379
380
381
382
383
384
385
386
387
388
389
390

391
392
393
394
395
396
397
354
355
356
357
358
359
360

361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390

391
392
393
394
395
396
397
398







-
+

















+











-
+







**
** This is a helper routine for sqlite3VdbeMemSetNull() and
** for sqlite3VdbeMemRelease().  Use those other routines as the
** entry point for releasing Mem resources.
*/
static SQLITE_NOINLINE void vdbeMemClearExternAndSetNull(Mem *p){
  assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) );
  assert( VdbeMemDynamic(p) );
  assert( VdbeMemDynamicOrSubtype(p) );
  if( p->flags&MEM_Agg ){
    sqlite3VdbeMemFinalize(p, p->u.pDef);
    assert( (p->flags & MEM_Agg)==0 );
    testcase( p->flags & MEM_Dyn );
  }
  if( p->flags&MEM_Dyn ){
    assert( (p->flags&MEM_RowSet)==0 );
    assert( p->xDel!=SQLITE_DYNAMIC && p->xDel!=0 );
    p->xDel((void *)p->z);
  }else if( p->flags&MEM_RowSet ){
    sqlite3RowSetClear(p->u.pRowSet);
  }else if( p->flags&MEM_Frame ){
    VdbeFrame *pFrame = p->u.pFrame;
    pFrame->pParent = pFrame->v->pDelFrame;
    pFrame->v->pDelFrame = pFrame;
  }
  p->flags = MEM_Null;
  p->eSubtype = 0;
}

/*
** Release memory held by the Mem p, both external memory cleared
** by p->xDel and memory in p->zMalloc.
**
** This is a helper routine invoked by sqlite3VdbeMemRelease() in
** the unusual case where there really is memory in p that needs
** to be freed.
*/
static SQLITE_NOINLINE void vdbeMemClear(Mem *p){
  if( VdbeMemDynamic(p) ){
  if( VdbeMemDynamicOrSubtype(p) ){
    vdbeMemClearExternAndSetNull(p);
  }
  if( p->szMalloc ){
    sqlite3DbFree(p->db, p->zMalloc);
    p->szMalloc = 0;
  }
  p->z = 0;
405
406
407
408
409
410
411
412

413
414
415
416
417
418
419
406
407
408
409
410
411
412

413
414
415
416
417
418
419
420







-
+







** reset a Mem back to its minimum memory utilization.
**
** Use sqlite3VdbeMemSetNull() to release just the Mem.xDel space
** prior to inserting new content into the Mem.
*/
void sqlite3VdbeMemRelease(Mem *p){
  assert( sqlite3VdbeCheckMemInvariants(p) );
  if( VdbeMemDynamic(p) || p->szMalloc ){
  if( VdbeMemDynamicOrSubtype(p) || p->szMalloc ){
    vdbeMemClear(p);
  }
}

/*
** Convert a 64-bit IEEE double into a 64-bit signed integer.
** If the double is out of range of a 64-bit signed integer then
644
645
646
647
648
649
650
651

652
653
654
655
656
657
658
645
646
647
648
649
650
651

652
653
654
655
656
657
658
659







-
+







** routine to invoke the destructor and deallocates Mem.zMalloc.
**
** Use this routine to reset the Mem prior to insert a new value.
**
** Use sqlite3VdbeMemRelease() to complete erase the Mem prior to abandoning it.
*/
void sqlite3VdbeMemSetNull(Mem *pMem){
  if( VdbeMemDynamic(pMem) ){
  if( VdbeMemDynamicOrSubtype(pMem) ){
    vdbeMemClearExternAndSetNull(pMem);
  }else{
    pMem->flags = MEM_Null;
  }
}
void sqlite3ValueSetNull(sqlite3_value *p){
  sqlite3VdbeMemSetNull((Mem*)p); 
684
685
686
687
688
689
690
691

692
693
694
695
696
697
698
685
686
687
688
689
690
691

692
693
694
695
696
697
698
699







-
+







}

/*
** Delete any previous value and set the value stored in *pMem to val,
** manifest type INTEGER.
*/
void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){
  if( VdbeMemDynamic(pMem) ){
  if( VdbeMemDynamicOrSubtype(pMem) ){
    vdbeReleaseAndSetInt64(pMem, val);
  }else{
    pMem->u.i = val;
    pMem->flags = MEM_Int;
  }
}

Changes to test/json103.test.

56
57
58
59
60
61
62


63












64
65
56
57
58
59
60
61
62
63
64

65
66
67
68
69
70
71
72
73
74
75
76
77
78







+
+
-
+
+
+
+
+
+
+
+
+
+
+
+


   WHERE rowid BETWEEN 31 AND 39 AND rowid%2==1;
} {{{"n31":32.5,"n33":33,"n35":35,"n37":null,"n39":"orange"}}}
do_execsql_test json103-220 {
  SELECT b, json_group_object(c,a) FROM t1
   WHERE rowid<7 GROUP BY b ORDER BY b;
} {0 {{"n3":3,"n6":6}} 1 {{"n1":1,"n4":4}} 2 {{"n2":2,"n5":5}}}

# ticket https://www.sqlite.org/src/info/f45ac567eaa9f93c 2016-01-30
# Invalid JSON generated by json_group_array() 

#
# The underlying problem is a failure to reset Mem.eSubtype
#
do_execsql_test json103-300 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(x);
  INSERT INTO t1 VALUES(1),('abc');
  SELECT
     json_group_array(x),
     json_group_array(json_object('x',x))
    FROM t1;
} {{[1,"abc"]} {[{"x":1},{"x":"abc"}]}}

finish_test