SQLite

Changes On Branch pointer-with-destructor
Login

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

Changes In Branch pointer-with-destructor Excluding Merge-Ins

This is equivalent to a diff from f39cb76b to d6684d2a

2017-07-27
17:45
Add destructor functions for the pointer argument (NB: not the type string) to the sqlite3_bind_pointer() and sqlite3_result_pointer() interfaces. Use this new capability to resolve a pointer leak in the custom geometry function mechanism of the RTREE extension. (check-in: 5a2340b8 user: drh tags: branch-3.20)
16:42
In sqlite3_bind_pointer(), invoke the destructor if the bind index is out of range, like sqlite3_bind_blob() does. (Closed-Leaf check-in: d6684d2a user: drh tags: pointer-with-destructor)
15:53
Improved implementation of the destructor on pointer-passing interfaces. (check-in: 601ad679 user: drh tags: pointer-with-destructor)
14:04
A demonstration of how FTS3 cursor pointers can be passed from the MATCH operator to the snippet() function securely and opaquely without having to use the sqlite3_result_pointer() and sqlite3_value_pointer() interfaces. (Closed-Leaf check-in: 49cf31da user: drh tags: pass-pointer-as-blob)
03:48
Add a destructor argument to sqlite3_bind_pointer() and sqlite3_result_pointer(). (check-in: 3d9e841f user: drh tags: pointer-with-destructor)
2017-07-25
15:12
Release candidate 2 for 3.20.0. (check-in: f39cb76b user: drh tags: branch-3.20)
01:34
Fix a bug in the deterministic date/time function logic that can only appear with STAT3 or STAT4. (check-in: 1ca707a4 user: drh tags: trunk)

Changes to ext/fts3/fts3.c.

3349
3350
3351
3352
3353
3354
3355
3356

3357
3358
3359
3360
3361
3362
3363
3349
3350
3351
3352
3353
3354
3355

3356
3357
3358
3359
3360
3361
3362
3363







-
+








  /* The column value supplied by SQLite must be in range. */
  assert( iCol>=0 && iCol<=p->nColumn+2 );

  switch( iCol-p->nColumn ){
    case 0:
      /* The special 'table-name' column */
      sqlite3_result_pointer(pCtx, pCsr, "fts3cursor");
      sqlite3_result_pointer(pCtx, pCsr, "fts3cursor", 0);
      break;

    case 1:
      /* The docid column */
      sqlite3_result_int64(pCtx, pCsr->iPrevId);
      break;

Changes to ext/fts5/fts5_tcl.c.

100
101
102
103
104
105
106
107

108
109
110
111
112
113
114
100
101
102
103
104
105
106

107
108
109
110
111
112
113
114







-
+







    fts5_api *pApi = 0;

    rc = sqlite3_prepare_v2(db, "SELECT fts5(?1)", -1, &pStmt, 0);
    if( rc!=SQLITE_OK ){
      Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), 0);
      return TCL_ERROR;
    }
    sqlite3_bind_pointer(pStmt, 1, (void*)&pApi, "fts5_api_ptr");
    sqlite3_bind_pointer(pStmt, 1, (void*)&pApi, "fts5_api_ptr", 0);
    sqlite3_step(pStmt);

    if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
      Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), 0);
      return TCL_ERROR;
    }

Changes to ext/fts5/fts5_test_mi.c.

71
72
73
74
75
76
77
78

79
80
81
82
83
84
85
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85







-
+







static int fts5_api_from_db(sqlite3 *db, fts5_api **ppApi){
  sqlite3_stmt *pStmt = 0;
  int rc;

  *ppApi = 0;
  rc = sqlite3_prepare(db, "SELECT fts5(?1)", -1, &pStmt, 0);
  if( rc==SQLITE_OK ){
    sqlite3_bind_pointer(pStmt, 1, (void*)ppApi, "fts5_api_ptr");
    sqlite3_bind_pointer(pStmt, 1, (void*)ppApi, "fts5_api_ptr", 0);
    (void)sqlite3_step(pStmt);
    rc = sqlite3_finalize(pStmt);
  }

  return rc;
}

Changes to ext/misc/carray.c.

20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34







-
+







** at the address $ptr.  $ptr is a pointer to the array of integers.
** The pointer value must be assigned to $ptr using the
** sqlite3_bind_pointer() interface with a pointer type of "carray".
** For example:
**
**    static int aX[] = { 53, 9, 17, 2231, 4, 99 };
**    int i = sqlite3_bind_parameter_index(pStmt, "$ptr");
**    sqlite3_bind_value(pStmt, i, aX, "carray");
**    sqlite3_bind_value(pStmt, i, aX, "carray", 0);
**
** There is an optional third parameter to determine the datatype of
** the C-language array.  Allowed values of the third parameter are
** 'int32', 'int64', 'double', 'char*'.  Example:
**
**      SELECT * FROM carray($ptr,10,'char*');
**
373
374
375
376
377
378
379
380

381
382
383
384
385
386
387
373
374
375
376
377
378
379

380
381
382
383
384
385
386
387







-
+







  i64 = sqlite3_value_int64(argv[0]);
  if( sizeof(i64)==sizeof(p) ){
    memcpy(&p, &i64, sizeof(p));
  }else{
    int i32 = i64 & 0xffffffff;
    memcpy(&p, &i32, sizeof(p));
  }
  sqlite3_result_pointer(context, p, "carray");
  sqlite3_result_pointer(context, p, "carray", 0);
}
#endif /* SQLITE_TEST */

#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifdef _WIN32
__declspec(dllexport)

Changes to ext/rtree/rtree.c.

335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357

358
359
360
361
362
363
364
335
336
337
338
339
340
341








342
343
344
345
346
347
348

349
350
351
352
353
354
355
356







-
-
-
-
-
-
-
-







-
+







struct RtreeGeomCallback {
  int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*);
  int (*xQueryFunc)(sqlite3_rtree_query_info*);
  void (*xDestructor)(void*);
  void *pContext;
};


/*
** Value for the first field of every RtreeMatchArg object. The MATCH
** operator tests that the first field of a blob operand matches this
** value to avoid operating on invalid blobs (which could cause a segfault).
*/
#define RTREE_GEOMETRY_MAGIC 0x891245AB

/*
** An instance of this structure (in the form of a BLOB) is returned by
** the SQL functions that sqlite3_rtree_geometry_callback() and
** sqlite3_rtree_query_callback() create, and is read as the right-hand
** operand to the MATCH operator of an R-Tree.
*/
struct RtreeMatchArg {
  u32 magic;                  /* Always RTREE_GEOMETRY_MAGIC */
  u32 iSize;                  /* Size of this object */
  RtreeGeomCallback cb;       /* Info about the callback functions */
  int nParam;                 /* Number of parameters to the SQL function */
  sqlite3_value **apSqlParam; /* Original SQL parameter values */
  RtreeDValue aParam[1];      /* Values for parameters to the SQL function */
};

#ifndef MAX
1645
1646
1647
1648
1649
1650
1651
1652

1653
1654
1655
1656
1657
1658
1659
1660
1661

1662
1663

1664
1665
1666


1667
1668
1669
1670
1671

1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1637
1638
1639
1640
1641
1642
1643

1644
1645


1646





1647


1648



1649
1650
1651
1652
1653


1654







1655
1656
1657
1658
1659
1660
1661







-
+

-
-

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



-
-
+
-
-
-
-
-
-
-







/*
** This function is called to configure the RtreeConstraint object passed
** as the second argument for a MATCH constraint. The value passed as the
** first argument to this function is the right-hand operand to the MATCH
** operator.
*/
static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){
  RtreeMatchArg *pBlob;              /* BLOB returned by geometry function */
  RtreeMatchArg *pBlob, *pSrc;       /* BLOB returned by geometry function */
  sqlite3_rtree_query_info *pInfo;   /* Callback information */
  int nBlob;                         /* Size of the geometry function blob */
  int nExpected;                     /* Expected size of the BLOB */

  /* Check that value is actually a blob. */
  if( sqlite3_value_type(pValue)!=SQLITE_BLOB ) return SQLITE_ERROR;

  /* Check that the blob is roughly the right size. */
  nBlob = sqlite3_value_bytes(pValue);
  pSrc = sqlite3_value_pointer(pValue, "RtreeMatchArg");
  if( nBlob<(int)sizeof(RtreeMatchArg) ){
    return SQLITE_ERROR;
  if( pSrc==0 ) return SQLITE_ERROR;
  }

  pInfo = (sqlite3_rtree_query_info*)sqlite3_malloc( sizeof(*pInfo)+nBlob );
  pInfo = (sqlite3_rtree_query_info*)
                sqlite3_malloc64( sizeof(*pInfo)+pSrc->iSize );
  if( !pInfo ) return SQLITE_NOMEM;
  memset(pInfo, 0, sizeof(*pInfo));
  pBlob = (RtreeMatchArg*)&pInfo[1];

  memcpy(pBlob, sqlite3_value_blob(pValue), nBlob);
  memcpy(pBlob, pSrc, pSrc->iSize);
  nExpected = (int)(sizeof(RtreeMatchArg) +
                    pBlob->nParam*sizeof(sqlite3_value*) +
                    (pBlob->nParam-1)*sizeof(RtreeDValue));
  if( pBlob->magic!=RTREE_GEOMETRY_MAGIC || nBlob!=nExpected ){
    sqlite3_free(pInfo);
    return SQLITE_ERROR;
  }
  pInfo->pContext = pBlob->cb.pContext;
  pInfo->nParam = pBlob->nParam;
  pInfo->aParam = pBlob->aParam;
  pInfo->apSqlParam = pBlob->apSqlParam;

  if( pBlob->cb.xGeom ){
    pCons->u.xGeom = pBlob->cb.xGeom;
3709
3710
3711
3712
3713
3714
3715
3716

3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733

3734
3735
3736
3737
3738
3739
3740
3685
3686
3687
3688
3689
3690
3691

3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708

3709
3710
3711
3712
3713
3714
3715
3716







-
+
















-
+







  nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue)
           + nArg*sizeof(sqlite3_value*);
  pBlob = (RtreeMatchArg *)sqlite3_malloc(nBlob);
  if( !pBlob ){
    sqlite3_result_error_nomem(ctx);
  }else{
    int i;
    pBlob->magic = RTREE_GEOMETRY_MAGIC;
    pBlob->iSize = nBlob;
    pBlob->cb = pGeomCtx[0];
    pBlob->apSqlParam = (sqlite3_value**)&pBlob->aParam[nArg];
    pBlob->nParam = nArg;
    for(i=0; i<nArg; i++){
      pBlob->apSqlParam[i] = sqlite3_value_dup(aArg[i]);
      if( pBlob->apSqlParam[i]==0 ) memErr = 1;
#ifdef SQLITE_RTREE_INT_ONLY
      pBlob->aParam[i] = sqlite3_value_int64(aArg[i]);
#else
      pBlob->aParam[i] = sqlite3_value_double(aArg[i]);
#endif
    }
    if( memErr ){
      sqlite3_result_error_nomem(ctx);
      rtreeMatchArgFree(pBlob);
    }else{
      sqlite3_result_blob(ctx, pBlob, nBlob, rtreeMatchArgFree);
      sqlite3_result_pointer(ctx, pBlob, "RtreeMatchArg", rtreeMatchArgFree);
    }
  }
}

/*
** Register a new geometry function for use with the r-tree MATCH operator.
*/

Changes to src/sqlite.h.in.

3879
3880
3881
3882
3883
3884
3885
3886

3887
3888


3889
3890
3891
3892
3893
3894
3895
3896


3897
3898
3899
3900
3901
3902
3903
3879
3880
3881
3882
3883
3884
3885

3886
3887

3888
3889
3890
3891
3892
3893
3894
3895


3896
3897
3898
3899
3900
3901
3902
3903
3904







-
+

-
+
+






-
-
+
+







** is filled with zeroes.  ^A zeroblob uses a fixed amount of memory
** (just an integer to hold its size) while it is being processed.
** Zeroblobs are intended to serve as placeholders for BLOBs whose
** content is later written using
** [sqlite3_blob_open | incremental BLOB I/O] routines.
** ^A negative value for the zeroblob results in a zero-length BLOB.
**
** ^The sqlite3_bind_pointer(S,I,P,T) routine causes the I-th parameter in
** ^The sqlite3_bind_pointer(S,I,P,T,D) routine causes the I-th parameter in
** [prepared statement] S to have an SQL value of NULL, but to also be
** associated with the pointer P of type T.
** associated with the pointer P of type T.  ^D is either a NULL pointer or
** a pointer to a destructor function that is called when P goes out of scope.
** ^The sqlite3_bind_pointer() routine can be used to pass
** host-language pointers into [application-defined SQL functions].
** ^A parameter that is initialized using [sqlite3_bind_pointer()] appears
** to be an ordinary SQL NULL value to everything other than
** [sqlite3_value_pointer()].  The T parameter should be a static string,
** preferably a string literal.  The procedure that invokes 
** sqlite3_bind_pointer(S,I,P,T) continues to own the P and T pointers and
** must guarantee that those pointers remain valid until after the last
** sqlite3_bind_pointer(S,I,P,T,D) owns the T string and
** must guarantee that it remains valid and unchanged until after the last
** access via [sqlite3_value_pointer()].  The sqlite3_bind_pointer() routine
** is part of the [pointer passing interface] added for SQLite 3.20.0.
**
** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer
** for the [prepared statement] or with a prepared statement for which
** [sqlite3_step()] has been called more recently than [sqlite3_reset()],
** then the call will return [SQLITE_MISUSE].  If any sqlite3_bind_()
3926
3927
3928
3929
3930
3931
3932
3933

3934
3935
3936
3937
3938
3939
3940
3927
3928
3929
3930
3931
3932
3933

3934
3935
3936
3937
3938
3939
3940
3941







-
+







int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
int sqlite3_bind_null(sqlite3_stmt*, int);
int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,
                         void(*)(void*), unsigned char encoding);
int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
int sqlite3_bind_pointer(sqlite3_stmt*, int, void*, const char*);
int sqlite3_bind_pointer(sqlite3_stmt*, int, void*, const char*,void(*)(void*));
int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64);

/*
** CAPI3REF: Number Of SQL Parameters
** METHOD: sqlite3_stmt
**
4759
4760
4761
4762
4763
4764
4765
4766

4767
4768
4769
4770
4771
4772
4773
4760
4761
4762
4763
4764
4765
4766

4767
4768
4769
4770
4771
4772
4773
4774







-
+







**
** ^The sqlite3_value_text16() interface extracts a UTF-16 string
** in the native byte-order of the host machine.  ^The
** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces
** extract UTF-16 strings as big-endian and little-endian respectively.
**
** ^If [sqlite3_value] object V was initialized 
** using [sqlite3_bind_pointer(S,I,P,X)] or [sqlite3_result_pointer(C,P,X)]
** using [sqlite3_bind_pointer(S,I,P,X,D)] or [sqlite3_result_pointer(C,P,X,D)]
** and if X and Y are strings that compare equal according to strcmp(X,Y),
** then sqlite3_value_pointer(V,Y) will return the pointer P.  ^Otherwise,
** sqlite3_value_pointer(V,Y) returns a NULL.
**
** ^(The sqlite3_value_type(V) interface returns the
** [SQLITE_INTEGER | datatype code] for the initial datatype of the
** [sqlite3_value] object V. The returned value is one of [SQLITE_INTEGER],
5097
5098
5099
5100
5101
5102
5103
5104

5105
5106
5107
5108



5109
5110

5111
5112
5113
5114
5115
5116
5117
5098
5099
5100
5101
5102
5103
5104

5105
5106
5107
5108
5109
5110
5111
5112
5113

5114
5115
5116
5117
5118
5119
5120
5121







-
+




+
+
+

-
+







** sqlite3_result_value() interface makes a copy of the [sqlite3_value]
** so that the [sqlite3_value] specified in the parameter may change or
** be deallocated after sqlite3_result_value() returns without harm.
** ^A [protected sqlite3_value] object may always be used where an
** [unprotected sqlite3_value] object is required, so either
** kind of [sqlite3_value] object can be used with this interface.
**
** ^The sqlite3_result_pointer(C,P,T) interface sets the result to an
** ^The sqlite3_result_pointer(C,P,T,D) interface sets the result to an
** SQL NULL value, just like [sqlite3_result_null(C)], except that it
** also associates the host-language pointer P or type T with that 
** NULL value such that the pointer can be retrieved within an
** [application-defined SQL function] using [sqlite3_value_pointer()].
** ^If the D parameter is not NULL, then it is a pointer to a destructor
** for the P parameter.  ^The destructor D is invoked on P when the result
** value goes out of scope.
** The T parameter should be a static string and preferably a string
** literal. The procedure that invokes sqlite3_result_pointer(C,P,T)
** literal. The procedure that invokes sqlite3_result_pointer(C,P,T,D)
** continues to own the P and T pointers and must guarantee that 
** those pointers remain valid until after the last access via
** [sqlite3_value_pointer()].  The sqlite3_result_pointer() routine
** is part of the [pointer passing interface] added for SQLite 3.20.0.
**
** If these routines are called from within the different thread
** than the one containing the application-defined function that received
5132
5133
5134
5135
5136
5137
5138
5139

5140
5141
5142
5143
5144
5145
5146
5136
5137
5138
5139
5140
5141
5142

5143
5144
5145
5146
5147
5148
5149
5150







-
+







void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64,
                           void(*)(void*), unsigned char encoding);
void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
void sqlite3_result_pointer(sqlite3_context*, void*, const char*);
void sqlite3_result_pointer(sqlite3_context*, void*,const char*,void(*)(void*));
void sqlite3_result_zeroblob(sqlite3_context*, int n);
int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n);


/*
** CAPI3REF: Setting The Subtype Of An SQL Function
** METHOD: sqlite3_context

Changes to src/sqlite3ext.h.

285
286
287
288
289
290
291
292
293


294
295
296
297
298
299
300
285
286
287
288
289
290
291


292
293
294
295
296
297
298
299
300







-
-
+
+







  /* Version 3.18.0 and later */
  void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64);
  /* Version 3.20.0 and later */
  int (*prepare_v3)(sqlite3*,const char*,int,unsigned int,
                    sqlite3_stmt**,const char**);
  int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int,
                      sqlite3_stmt**,const void**);
  int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*);
  void (*result_pointer)(sqlite3_context*,void*,const char*);
  int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
  void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
  void *(*value_pointer)(sqlite3_value*,const char*);
};

/*
** This is the function signature used for all extension entry points.  It
** is also defined in the file "loadext.c".
*/

Changes to src/vdbeInt.h.

185
186
187
188
189
190
191
192
193


194
195
196
197
198
199
200
185
186
187
188
189
190
191


192
193
194
195
196
197
198
199
200







-
-
+
+







** structures. Each Mem struct may cache multiple representations (string,
** integer etc.) of the same value.
*/
struct sqlite3_value {
  union MemValue {
    double r;           /* Real value used when MEM_Real is set in flags */
    i64 i;              /* Integer value used when MEM_Int is set in flags */
    int nZero;          /* Used when bit MEM_Zero is set in flags */
    void *pPtr;         /* Pointer when flags=MEM_NULL and eSubtype='p' */
    int nZero;          /* Extra zero bytes when MEM_Zero and MEM_Blob set */
    const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */
    FuncDef *pDef;      /* Used only when flags==MEM_Agg */
    RowSet *pRowSet;    /* Used only when flags==MEM_RowSet */
    VdbeFrame *pFrame;  /* Used when flags==MEM_Frame */
  } u;
  u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
  u8  enc;            /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
  u8  eSubtype;       /* Subtype for this value */
218
219
220
221
222
223
224

225

226
227
228
229
230
231
232
233

234
235
236
237
238
239
240
241
242
243

244
245
246
247
248
249
250
251

252
253
254
255
256
257
258
218
219
220
221
222
223
224
225

226
227
228
229
230
231
232
233

234
235
236
237
238
239
240
241
242
243

244
245
246
247
248
249
250
251

252
253
254
255
256
257
258
259







+
-
+







-
+









-
+







-
+







*/
#define MEMCELLSIZE offsetof(Mem,zMalloc)

/* One or more of the following flags are set to indicate the validOK
** representations of the value stored in the Mem struct.
**
** If the MEM_Null flag is set, then the value is an SQL NULL value.
** For a pointer type created using sqlite3_bind_pointer() or
** No other flags may be set in this case.
** sqlite3_result_pointer() the MEM_Term and MEM_Subtype flags are also set.
**
** If the MEM_Str flag is set then Mem.z points at a string representation.
** Usually this is encoded in the same unicode encoding as the main
** database (see below for exceptions). If the MEM_Term flag is also
** set, then the string is nul terminated. The MEM_Int and MEM_Real 
** flags may coexist with the MEM_Str flag.
*/
#define MEM_Null      0x0001   /* Value is NULL */
#define MEM_Null      0x0001   /* Value is NULL (or a pointer) */
#define MEM_Str       0x0002   /* Value is a string */
#define MEM_Int       0x0004   /* Value is an integer */
#define MEM_Real      0x0008   /* Value is a real number */
#define MEM_Blob      0x0010   /* Value is a BLOB */
#define MEM_AffMask   0x001f   /* Mask of affinity bits */
#define MEM_RowSet    0x0020   /* Value is a RowSet object */
#define MEM_Frame     0x0040   /* Value is a VdbeFrame object */
#define MEM_Undefined 0x0080   /* Value is undefined */
#define MEM_Cleared   0x0100   /* NULL set by OP_Null, not from data */
#define MEM_TypeMask  0x81ff   /* Mask of type bits */
#define MEM_TypeMask  0xc1ff   /* Mask of type bits */


/* Whenever Mem contains a valid string or blob representation, one of
** the following flags must be set to determine the memory management
** policy for Mem.z.  The MEM_Term flag tells us whether or not the
** string is \000 or \u0000 terminated
*/
#define MEM_Term      0x0200   /* String rep is nul terminated */
#define MEM_Term      0x0200   /* String in Mem.z is zero 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 is valid */
#ifdef SQLITE_OMIT_INCRBLOB
472
473
474
475
476
477
478
479

480
481
482
483
484
485
486
473
474
475
476
477
478
479

480
481
482
483
484
485
486
487







-
+







int sqlite3VdbeMemSetStr(Mem*, const char*, int, u8, void(*)(void*));
void sqlite3VdbeMemSetInt64(Mem*, i64);
#ifdef SQLITE_OMIT_FLOATING_POINT
# define sqlite3VdbeMemSetDouble sqlite3VdbeMemSetInt64
#else
  void sqlite3VdbeMemSetDouble(Mem*, double);
#endif
void sqlite3VdbeMemSetPointer(Mem*, void*, const char*);
void sqlite3VdbeMemSetPointer(Mem*, void*, const char*, void(*)(void*));
void sqlite3VdbeMemInit(Mem*,sqlite3*,u16);
void sqlite3VdbeMemSetNull(Mem*);
void sqlite3VdbeMemSetZeroBlob(Mem*,int);
void sqlite3VdbeMemSetRowSet(Mem*);
int sqlite3VdbeMemMakeWriteable(Mem*);
int sqlite3VdbeMemStringify(Mem*, u8, u8);
i64 sqlite3VdbeIntValue(Mem*);

Changes to src/vdbeapi.c.

197
198
199
200
201
202
203

204

205
206
207

208
209

210
211
212
213
214
215
216
197
198
199
200
201
202
203
204

205
206
207

208
209

210
211
212
213
214
215
216
217







+
-
+


-
+

-
+







}
unsigned int sqlite3_value_subtype(sqlite3_value *pVal){
  Mem *pMem = (Mem*)pVal;
  return ((pMem->flags & MEM_Subtype) ? pMem->eSubtype : 0);
}
void *sqlite3_value_pointer(sqlite3_value *pVal, const char *zPType){
  Mem *p = (Mem*)pVal;
  if( (p->flags&(MEM_TypeMask|MEM_Term|MEM_Subtype)) ==
  if( p->flags==(MEM_Null|MEM_Subtype|MEM_Term|MEM_Static)
                 (MEM_Null|MEM_Term|MEM_Subtype)
   && zPType!=0
   && p->eSubtype=='p'
   && strcmp(p->z, zPType)==0
   && strcmp(p->u.zPType, zPType)==0
  ){
    return p->u.pPtr;
    return (void*)p->z;
  }else{
    return 0;
  }
}
const unsigned char *sqlite3_value_text(sqlite3_value *pVal){
  return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8);
}
385
386
387
388
389
390
391
392






393
394
395
396

397
398
399
400
401
402
403
386
387
388
389
390
391
392

393
394
395
396
397
398
399
400
401

402
403
404
405
406
407
408
409







-
+
+
+
+
+
+



-
+







  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
  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_pointer(sqlite3_context *pCtx, void *pPtr, const char *zPT){
void sqlite3_result_pointer(
  sqlite3_context *pCtx,
  void *pPtr,
  const char *zPType,
  void (*xDestructor)(void*)
){
  Mem *pOut = pCtx->pOut;
  assert( sqlite3_mutex_held(pOut->db->mutex) );
  sqlite3VdbeMemSetNull(pOut);
  sqlite3VdbeMemSetPointer(pOut, pPtr, zPT);
  sqlite3VdbeMemSetPointer(pOut, pPtr, zPType, xDestructor);
}
void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){
  Mem *pOut = pCtx->pOut;
  assert( sqlite3_mutex_held(pOut->db->mutex) );
  pOut->eSubtype = eSubtype & 0xff;
  pOut->flags |= MEM_Subtype;
}
1394
1395
1396
1397
1398
1399
1400
1401







1402
1403
1404
1405
1406

1407


1408
1409
1410
1411
1412
1413
1414
1400
1401
1402
1403
1404
1405
1406

1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417

1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428







-
+
+
+
+
+
+
+




-
+

+
+







  Vdbe *p = (Vdbe*)pStmt;
  rc = vdbeUnbind(p, i);
  if( rc==SQLITE_OK ){
    sqlite3_mutex_leave(p->db->mutex);
  }
  return rc;
}
int sqlite3_bind_pointer(sqlite3_stmt *pStmt, int i, void *pPtr,const char *zT){
int sqlite3_bind_pointer(
  sqlite3_stmt *pStmt,
  int i,
  void *pPtr,
  const char *zPTtype,
  void (*xDestructor)(void*)
){
  int rc;
  Vdbe *p = (Vdbe*)pStmt;
  rc = vdbeUnbind(p, i);
  if( rc==SQLITE_OK ){
    sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zT);
    sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zPTtype, xDestructor);
    sqlite3_mutex_leave(p->db->mutex);
  }else if( xDestructor ){
    xDestructor(pPtr);
  }
  return rc;
}
int sqlite3_bind_text( 
  sqlite3_stmt *pStmt, 
  int i, 
  const char *zData, 

Changes to src/vdbemem.c.

23
24
25
26
27
28
29
30

31
32
33
34
35
36
37
38
39
40
41
42

43
44
45



























46
47
48
49
50
51
52
23
24
25
26
27
28
29

30
31
32
33
34
35
36
37
38
39
40
41
42
43



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77







-
+












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







** Check invariants on a Mem object.
**
** This routine is intended for use inside of assert() statements, like
** this:    assert( sqlite3VdbeCheckMemInvariants(pMem) );
*/
int sqlite3VdbeCheckMemInvariants(Mem *p){
  /* If MEM_Dyn is set then Mem.xDel!=0.  
  ** Mem.xDel is might not be initialized if MEM_Dyn is clear.
  ** Mem.xDel might not be initialized if MEM_Dyn is clear.
  */
  assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 );

  /* MEM_Dyn may only be set if Mem.szMalloc==0.  In this way we
  ** ensure that if Mem.szMalloc>0 then it is safe to do
  ** Mem.z = Mem.zMalloc without having to check Mem.flags&MEM_Dyn.
  ** That saves a few cycles in inner loops. */
  assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 );

  /* Cannot be both MEM_Int and MEM_Real at the same time */
  assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );

  if( p->flags & MEM_Null ){
  /* Cannot be both MEM_Null and some other type */
  assert( (p->flags & MEM_Null)==0 ||
          (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob))==0 );
    /* Cannot be both MEM_Null and some other type */
    assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob
                         |MEM_RowSet|MEM_Frame|MEM_Agg|MEM_Zero))==0 );

    /* If MEM_Null is set, then either the value is a pure NULL (the usual
    ** case) or it is a pointer set using sqlite3_bind_pointer() or
    ** sqlite3_result_pointer().  If a pointer, then MEM_Term must also be
    ** set.
    */
    if( (p->flags & (MEM_Term|MEM_Subtype))==(MEM_Term|MEM_Subtype) ){
      /* This is a pointer type.  There may be a flag to indicate what to
      ** do with the pointer. */
      assert( ((p->flags&MEM_Dyn)!=0 ? 1 : 0) +
              ((p->flags&MEM_Ephem)!=0 ? 1 : 0) +
              ((p->flags&MEM_Static)!=0 ? 1 : 0) <= 1 );

      /* No other bits set */
      assert( (p->flags & ~(MEM_Null|MEM_Term|MEM_Subtype
                           |MEM_Dyn|MEM_Ephem|MEM_Static))==0 );
    }else{
      /* A pure NULL might have other flags, such as MEM_Static, MEM_Dyn,
      ** MEM_Ephem, MEM_Cleared, or MEM_Subtype */
    }
  }else{
    /* The MEM_Cleared bit is only allowed on NULLs */
    assert( (p->flags & MEM_Cleared)==0 );
  }

  /* The szMalloc field holds the correct memory allocation size */
  assert( p->szMalloc==0
       || p->szMalloc==sqlite3DbMallocSize(p->db,p->zMalloc) );

  /* If p holds a string or blob, the Mem.z must point to exactly
  ** one of the following:
701
702
703
704
705
706
707



708
709
710
711
712






713
714
715



716
717
718


719
720
721
722
723
724
725
726
726
727
728
729
730
731
732
733
734
735
736
737
738
739

740
741
742
743
744
745
746


747
748
749



750
751

752
753
754
755
756
757
758







+
+
+




-
+
+
+
+
+
+

-
-
+
+
+
-
-
-
+
+
-







    vdbeReleaseAndSetInt64(pMem, val);
  }else{
    pMem->u.i = val;
    pMem->flags = MEM_Int;
  }
}

/* A no-op destructor */
static void sqlite3NoopDestructor(void *p){ UNUSED_PARAMETER(p); }

/*
** Set the value stored in *pMem should already be a NULL.
** Also store a pointer to go with it.
*/
void sqlite3VdbeMemSetPointer(Mem *pMem, void *pPtr, const char *zPType){
void sqlite3VdbeMemSetPointer(
  Mem *pMem,
  void *pPtr,
  const char *zPType,
  void (*xDestructor)(void*)
){
  assert( pMem->flags==MEM_Null );
  if( zPType ){
    pMem->flags = MEM_Null|MEM_Subtype|MEM_Term|MEM_Static;
  pMem->u.zPType = zPType ? zPType : "";
  pMem->z = pPtr;
  pMem->flags = MEM_Null|MEM_Dyn|MEM_Subtype|MEM_Term;
    pMem->u.pPtr = pPtr;
    pMem->eSubtype = 'p';
    pMem->z = (char*)zPType;
  pMem->eSubtype = 'p';
  pMem->xDel = xDestructor ? xDestructor : sqlite3NoopDestructor;
  }
}

#ifndef SQLITE_OMIT_FLOATING_POINT
/*
** Delete any previous value and set the value stored in *pMem to val,
** manifest type REAL.
*/