SQLite4
Check-in [f63a20c194]
Not logged in

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

Overview
Comment:Remove the zeroblob interfaces.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: f63a20c1944f5d43083ed98778588a464795f12d
User & Date: drh 2013-02-20 18:41:28
Context
2013-02-20
19:36
Fix a problem in USE_LOG=0 mode. check-in: 07a6f43d58 user: dan tags: trunk
18:41
Remove the zeroblob interfaces. check-in: f63a20c194 user: drh tags: trunk
18:06
Merge read-only-clients branch with trunk. check-in: 66fe3644fd user: dan tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/func.c.

939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
....
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
      *(z++) = hexdigits[c&0xf];
    }
    *z = 0;
    sqlite4_result_text(context, zHex, n*2, SQLITE4_DYNAMIC, 0);
  }
}

/*
** The zeroblob(N) function returns a zero-filled blob of size N bytes.
*/
static void zeroblobFunc(
  sqlite4_context *context,
  int argc,
  sqlite4_value **argv
){
  i64 n;
  sqlite4 *db = sqlite4_context_db_handle(context);
  assert( argc==1 );
  UNUSED_PARAMETER(argc);
  n = sqlite4_value_int64(argv[0]);
  testcase( n==db->aLimit[SQLITE4_LIMIT_LENGTH] );
  testcase( n==db->aLimit[SQLITE4_LIMIT_LENGTH]+1 );
  if( n>db->aLimit[SQLITE4_LIMIT_LENGTH] ){
    sqlite4_result_error_toobig(context);
  }else{
    sqlite4_result_zeroblob(context, (int)n); /* IMP: R-00293-64994 */
  }
}

/*
** The replace() function.  Three arguments are all strings: call
** them A, B, and C. The result is also a string which is derived
** from A by replacing every occurance of B with C.  The match
** must be exact.  Collating sequences are not used.
*/
static void replaceFunc(
................................................................................
    FUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc  ),
#endif /* SQLITE4_OMIT_COMPILEOPTION_DIAGS */
    FUNCTION(quote,              1, 0, 0, quoteFunc        ),
    FUNCTION(last_insert_rowid,  0, 0, 0, last_insert_rowid),
    FUNCTION(changes,            0, 0, 0, changes          ),
    FUNCTION(total_changes,      0, 0, 0, total_changes    ),
    FUNCTION(replace,            3, 0, 0, replaceFunc      ),
    FUNCTION(zeroblob,           1, 0, 0, zeroblobFunc     ),
  #ifdef SQLITE4_SOUNDEX
    FUNCTION(soundex,            1, 0, 0, soundexFunc      ),
  #endif
  #if 0 /*ndef SQLITE4_OMIT_LOAD_EXTENSION*/
    FUNCTION(load_extension,     1, 0, 0, loadExt          ),
    FUNCTION(load_extension,     2, 0, 0, loadExt          ),
  #endif







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







<







939
940
941
942
943
944
945






















946
947
948
949
950
951
952
....
1540
1541
1542
1543
1544
1545
1546

1547
1548
1549
1550
1551
1552
1553
      *(z++) = hexdigits[c&0xf];
    }
    *z = 0;
    sqlite4_result_text(context, zHex, n*2, SQLITE4_DYNAMIC, 0);
  }
}























/*
** The replace() function.  Three arguments are all strings: call
** them A, B, and C. The result is also a string which is derived
** from A by replacing every occurance of B with C.  The match
** must be exact.  Collating sequences are not used.
*/
static void replaceFunc(
................................................................................
    FUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc  ),
#endif /* SQLITE4_OMIT_COMPILEOPTION_DIAGS */
    FUNCTION(quote,              1, 0, 0, quoteFunc        ),
    FUNCTION(last_insert_rowid,  0, 0, 0, last_insert_rowid),
    FUNCTION(changes,            0, 0, 0, changes          ),
    FUNCTION(total_changes,      0, 0, 0, total_changes    ),
    FUNCTION(replace,            3, 0, 0, replaceFunc      ),

  #ifdef SQLITE4_SOUNDEX
    FUNCTION(soundex,            1, 0, 0, soundexFunc      ),
  #endif
  #if 0 /*ndef SQLITE4_OMIT_LOAD_EXTENSION*/
    FUNCTION(load_extension,     1, 0, 0, loadExt          ),
    FUNCTION(load_extension,     2, 0, 0, loadExt          ),
  #endif

Changes to src/sqlite.h.in.

1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
....
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
....
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
....
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
** ^If the fifth argument is
** the special value [SQLITE4_STATIC], then SQLite assumes that the
** information is in static, unmanaged space and does not need to be freed.
** ^If the fifth argument has the value [SQLITE4_TRANSIENT], then
** SQLite makes its own private copy of the data immediately, before
** the sqlite4_bind_*() routine returns.
**
** ^The sqlite4_bind_zeroblob() routine binds a BLOB of length N that
** 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
** [sqlite4_blob_open | incremental BLOB I/O] routines.
** ^A negative value for the zeroblob results in a zero-length BLOB.
**
** ^If any of the sqlite4_bind_*() routines are called with a NULL pointer
** for the [prepared statement] or with a prepared statement for which
** [sqlite4_step()] has been called more recently than [sqlite4_reset()],
** then the call will return [SQLITE4_MISUSE].  If any sqlite4_bind_()
** routine is passed a [prepared statement] that has been finalized, the
** result is undefined and probably harmful.
**
................................................................................
int sqlite4_bind_int64(sqlite4_stmt*, int, sqlite4_int64);
int sqlite4_bind_null(sqlite4_stmt*, int);
int sqlite4_bind_text(sqlite4_stmt*, int, const char*, int n,
                      void(*)(void*,void*),void*);
int sqlite4_bind_text16(sqlite4_stmt*, int, const void*, int,
                        void(*)(void*,void*),void*);
int sqlite4_bind_value(sqlite4_stmt*, int, const sqlite4_value*);
int sqlite4_bind_zeroblob(sqlite4_stmt*, int, int n);

/*
** CAPIREF: Number Of SQL Parameters
**
** ^This routine can be used to find the number of [SQL parameters]
** in a [prepared statement].  SQL parameters are tokens of the
** form "?", "?NNN", ":AAA", "$AAA", or "@AAA" that serve as
................................................................................
** Refer to the [SQL parameter] documentation for additional information.
**
** ^The sqlite4_result_blob() interface sets the result from
** an application-defined function to be the BLOB whose content is pointed
** to by the second parameter and which is N bytes long where N is the
** third parameter.
**
** ^The sqlite4_result_zeroblob() interfaces set the result of
** the application-defined function to be a BLOB containing all zero
** bytes and N bytes in size, where N is the value of the 2nd parameter.
**
** ^The sqlite4_result_double() interface sets the result from
** an application-defined function to be a floating point value specified
** by its 2nd argument.
**
** ^The sqlite4_result_error() and sqlite4_result_error16() functions
** cause the implemented SQL function to throw an exception.
** ^SQLite uses the string pointed to by the
................................................................................
void sqlite4_result_text16(sqlite4_context*, const void*, int,
                           void(*)(void*,void*),void*);
void sqlite4_result_text16le(sqlite4_context*, const void*, int,
                             void(*)(void*,void*),void*);
void sqlite4_result_text16be(sqlite4_context*, const void*, int,
                             void(*)(void*,void*),void*);
void sqlite4_result_value(sqlite4_context*, sqlite4_value*);
void sqlite4_result_zeroblob(sqlite4_context*, int n);

/*
** CAPIREF: Define New Collating Sequences
**
** ^This function adds, removes, or modifies a [collation] associated
** with the [database connection] specified as the first argument.
**







<
<
<
<
<
<
<
<







 







<







 







<
<
<
<







 







<







1803
1804
1805
1806
1807
1808
1809








1810
1811
1812
1813
1814
1815
1816
....
1832
1833
1834
1835
1836
1837
1838

1839
1840
1841
1842
1843
1844
1845
....
2696
2697
2698
2699
2700
2701
2702




2703
2704
2705
2706
2707
2708
2709
....
2805
2806
2807
2808
2809
2810
2811

2812
2813
2814
2815
2816
2817
2818
** ^If the fifth argument is
** the special value [SQLITE4_STATIC], then SQLite assumes that the
** information is in static, unmanaged space and does not need to be freed.
** ^If the fifth argument has the value [SQLITE4_TRANSIENT], then
** SQLite makes its own private copy of the data immediately, before
** the sqlite4_bind_*() routine returns.
**








** ^If any of the sqlite4_bind_*() routines are called with a NULL pointer
** for the [prepared statement] or with a prepared statement for which
** [sqlite4_step()] has been called more recently than [sqlite4_reset()],
** then the call will return [SQLITE4_MISUSE].  If any sqlite4_bind_()
** routine is passed a [prepared statement] that has been finalized, the
** result is undefined and probably harmful.
**
................................................................................
int sqlite4_bind_int64(sqlite4_stmt*, int, sqlite4_int64);
int sqlite4_bind_null(sqlite4_stmt*, int);
int sqlite4_bind_text(sqlite4_stmt*, int, const char*, int n,
                      void(*)(void*,void*),void*);
int sqlite4_bind_text16(sqlite4_stmt*, int, const void*, int,
                        void(*)(void*,void*),void*);
int sqlite4_bind_value(sqlite4_stmt*, int, const sqlite4_value*);


/*
** CAPIREF: Number Of SQL Parameters
**
** ^This routine can be used to find the number of [SQL parameters]
** in a [prepared statement].  SQL parameters are tokens of the
** form "?", "?NNN", ":AAA", "$AAA", or "@AAA" that serve as
................................................................................
** Refer to the [SQL parameter] documentation for additional information.
**
** ^The sqlite4_result_blob() interface sets the result from
** an application-defined function to be the BLOB whose content is pointed
** to by the second parameter and which is N bytes long where N is the
** third parameter.
**




** ^The sqlite4_result_double() interface sets the result from
** an application-defined function to be a floating point value specified
** by its 2nd argument.
**
** ^The sqlite4_result_error() and sqlite4_result_error16() functions
** cause the implemented SQL function to throw an exception.
** ^SQLite uses the string pointed to by the
................................................................................
void sqlite4_result_text16(sqlite4_context*, const void*, int,
                           void(*)(void*,void*),void*);
void sqlite4_result_text16le(sqlite4_context*, const void*, int,
                             void(*)(void*,void*),void*);
void sqlite4_result_text16be(sqlite4_context*, const void*, int,
                             void(*)(void*,void*),void*);
void sqlite4_result_value(sqlite4_context*, sqlite4_value*);


/*
** CAPIREF: Define New Collating Sequences
**
** ^This function adds, removes, or modifies a [collation] associated
** with the [database connection] specified as the first argument.
**

Changes to src/vdbe.c.

349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
....
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
....
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
....
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
    for(i=0; i<16 && i<pMem->n; i++){
      char z = pMem->z[i];
      if( z<32 || z>126 ) *zCsr++ = '.';
      else *zCsr++ = z;
    }

    zCsr += sqlite4_snprintf(zCsr, 100, "]%s", encnames[pMem->enc]);
    if( f & MEM_Zero ){
      zCsr += sqlite4_snprintf(zCsr, 100, "+%dz",pMem->u.nZero);
    }
    *zCsr = '\0';
  }else if( f & MEM_Str ){
    int j, k;
    zBuf[0] = ' ';
    if( f & MEM_Dyn ){
      zBuf[1] = 'z';
      assert( (f & (MEM_Static|MEM_Ephem))==0 );
................................................................................
  pIn2 = &aMem[pOp->p2];
  pOut = &aMem[pOp->p3];
  assert( pIn1!=pOut );
  if( (pIn1->flags | pIn2->flags) & MEM_Null ){
    sqlite4VdbeMemSetNull(pOut);
    break;
  }
  if( ExpandBlob(pIn1) || ExpandBlob(pIn2) ) goto no_mem;
  Stringify(pIn1, encoding);
  Stringify(pIn2, encoding);
  nByte = pIn1->n + pIn2->n;
  if( nByte>db->aLimit[SQLITE4_LIMIT_LENGTH] ){
    goto too_big;
  }
  MemSetTypeFlag(pOut, MEM_Str);
................................................................................
case OP_ToText: {                  /* same as TK_TO_TEXT, in1 */
  pIn1 = &aMem[pOp->p1];
  memAboutToChange(p, pIn1);
  if( pIn1->flags & MEM_Null ) break;
  assert( MEM_Str==(MEM_Blob>>3) );
  pIn1->flags |= (pIn1->flags&MEM_Blob)>>3;
  applyAffinity(pIn1, SQLITE4_AFF_TEXT, encoding);
  rc = ExpandBlob(pIn1);
  assert( pIn1->flags & MEM_Str || db->mallocFailed );
  pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_Blob|MEM_Zero);
  UPDATE_MAX_BLOBSIZE(pIn1);
  break;
}

/* Opcode: ToBlob P1 * * * *
**
** Force the value in register P1 to be a BLOB.
................................................................................
  ** expand all zero-blobs.
  */
  for(pMem=pData0; pMem<=pLast; pMem++){
    assert( memIsValid(pMem) );
    if( zAffinity ){
      applyAffinity(pMem, *(zAffinity++), encoding);
    }
    if( pMem->flags&MEM_Zero ){
      (void)ExpandBlob(pMem);
    }
  }

  /* Compute the key (if this is a MakeKey opcode) */
  if( pC ){
    aRec = 0;
    rc = sqlite4VdbeEncodeKey(db, 
        pData0, pC->pKeyInfo->nField, pC->iRoot, pC->pKeyInfo, &aRec, &nRec, 0







<
<
<







 







<







 







<

|







 







<
<
<







349
350
351
352
353
354
355



356
357
358
359
360
361
362
....
1139
1140
1141
1142
1143
1144
1145

1146
1147
1148
1149
1150
1151
1152
....
1580
1581
1582
1583
1584
1585
1586

1587
1588
1589
1590
1591
1592
1593
1594
1595
....
2326
2327
2328
2329
2330
2331
2332



2333
2334
2335
2336
2337
2338
2339
    for(i=0; i<16 && i<pMem->n; i++){
      char z = pMem->z[i];
      if( z<32 || z>126 ) *zCsr++ = '.';
      else *zCsr++ = z;
    }

    zCsr += sqlite4_snprintf(zCsr, 100, "]%s", encnames[pMem->enc]);



    *zCsr = '\0';
  }else if( f & MEM_Str ){
    int j, k;
    zBuf[0] = ' ';
    if( f & MEM_Dyn ){
      zBuf[1] = 'z';
      assert( (f & (MEM_Static|MEM_Ephem))==0 );
................................................................................
  pIn2 = &aMem[pOp->p2];
  pOut = &aMem[pOp->p3];
  assert( pIn1!=pOut );
  if( (pIn1->flags | pIn2->flags) & MEM_Null ){
    sqlite4VdbeMemSetNull(pOut);
    break;
  }

  Stringify(pIn1, encoding);
  Stringify(pIn2, encoding);
  nByte = pIn1->n + pIn2->n;
  if( nByte>db->aLimit[SQLITE4_LIMIT_LENGTH] ){
    goto too_big;
  }
  MemSetTypeFlag(pOut, MEM_Str);
................................................................................
case OP_ToText: {                  /* same as TK_TO_TEXT, in1 */
  pIn1 = &aMem[pOp->p1];
  memAboutToChange(p, pIn1);
  if( pIn1->flags & MEM_Null ) break;
  assert( MEM_Str==(MEM_Blob>>3) );
  pIn1->flags |= (pIn1->flags&MEM_Blob)>>3;
  applyAffinity(pIn1, SQLITE4_AFF_TEXT, encoding);

  assert( pIn1->flags & MEM_Str || db->mallocFailed );
  pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_Blob);
  UPDATE_MAX_BLOBSIZE(pIn1);
  break;
}

/* Opcode: ToBlob P1 * * * *
**
** Force the value in register P1 to be a BLOB.
................................................................................
  ** expand all zero-blobs.
  */
  for(pMem=pData0; pMem<=pLast; pMem++){
    assert( memIsValid(pMem) );
    if( zAffinity ){
      applyAffinity(pMem, *(zAffinity++), encoding);
    }



  }

  /* Compute the key (if this is a MakeKey opcode) */
  if( pC ){
    aRec = 0;
    rc = sqlite4VdbeEncodeKey(db, 
        pData0, pC->pKeyInfo->nField, pC->iRoot, pC->pKeyInfo, &aRec, &nRec, 0

Changes to src/vdbeInt.h.

132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
...
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
...
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
...
454
455
456
457
458
459
460
461
462
463
464
*/
struct Mem {
  sqlite4 *db;        /* The associated database connection */
  char *z;            /* String or BLOB value */
  double r;           /* Real value */
  union {
    i64 i;              /* Integer value used when MEM_Int is set in flags */
    int nZero;          /* Used when bit MEM_Zero is set in flags */
    FuncDef *pDef;      /* Used only when flags==MEM_Agg */
    RowSet *pRowSet;    /* Used only when flags==MEM_RowSet */
    VdbeFrame *pFrame;  /* Used when flags==MEM_Frame */
  } u;
  int n;              /* Number of characters in string value, excluding '\0' */
  u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
  u8  type;           /* One of SQLITE4_NULL, SQLITE4_TEXT, SQLITE4_INTEGER, etc */
................................................................................
** string is \000 or \u0000 terminated
*/
#define MEM_Term      0x0200   /* String rep is nul terminated */
#define MEM_Dyn       0x0400   /* Need to call sqliteFree() 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 */

/*
** 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)

/*
** Return true if a memory cell is not marked as invalid.  This macro
** is for use inside assert() statements only.
*/
#ifdef SQLITE4_DEBUG
#define memIsValid(M)  ((M)->flags & MEM_Invalid)==0
................................................................................
void sqlite4VdbeMemSetInt64(Mem*, i64);
#ifdef SQLITE4_OMIT_FLOATING_POINT
# define sqlite4VdbeMemSetDouble sqlite4VdbeMemSetInt64
#else
  void sqlite4VdbeMemSetDouble(Mem*, double);
#endif
void sqlite4VdbeMemSetNull(Mem*);
void sqlite4VdbeMemSetZeroBlob(Mem*,int);
int sqlite4VdbeMemMakeWriteable(Mem*);
int sqlite4VdbeMemStringify(Mem*, int);
i64 sqlite4VdbeIntValue(Mem*);
int sqlite4VdbeMemIntegerify(Mem*);
double sqlite4VdbeRealValue(Mem*);
void sqlite4VdbeIntegerAffinity(Mem*);
int sqlite4VdbeMemRealify(Mem*);
................................................................................
#ifdef SQLITE4_DEBUG
  void sqlite4VdbePrintSql(Vdbe*);
  void sqlite4VdbeMemPrettyPrint(Mem *pMem, char *zBuf);
#endif
int sqlite4VdbeMemHandleBom(Mem *pMem);


#define sqlite4VdbeMemExpandBlob(x) SQLITE4_OK
#define ExpandBlob(P) SQLITE4_OK

#endif /* !defined(_VDBEINT_H_) */







<







 







<





|







 







<







 







<
<
<

132
133
134
135
136
137
138

139
140
141
142
143
144
145
...
182
183
184
185
186
187
188

189
190
191
192
193
194
195
196
197
198
199
200
201
...
403
404
405
406
407
408
409

410
411
412
413
414
415
416
...
451
452
453
454
455
456
457



458
*/
struct Mem {
  sqlite4 *db;        /* The associated database connection */
  char *z;            /* String or BLOB value */
  double r;           /* Real value */
  union {
    i64 i;              /* Integer value used when MEM_Int is set in flags */

    FuncDef *pDef;      /* Used only when flags==MEM_Agg */
    RowSet *pRowSet;    /* Used only when flags==MEM_RowSet */
    VdbeFrame *pFrame;  /* Used when flags==MEM_Frame */
  } u;
  int n;              /* Number of characters in string value, excluding '\0' */
  u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
  u8  type;           /* One of SQLITE4_NULL, SQLITE4_TEXT, SQLITE4_INTEGER, etc */
................................................................................
** string is \000 or \u0000 terminated
*/
#define MEM_Term      0x0200   /* String rep is nul terminated */
#define MEM_Dyn       0x0400   /* Need to call sqliteFree() 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 */


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

/*
** Return true if a memory cell is not marked as invalid.  This macro
** is for use inside assert() statements only.
*/
#ifdef SQLITE4_DEBUG
#define memIsValid(M)  ((M)->flags & MEM_Invalid)==0
................................................................................
void sqlite4VdbeMemSetInt64(Mem*, i64);
#ifdef SQLITE4_OMIT_FLOATING_POINT
# define sqlite4VdbeMemSetDouble sqlite4VdbeMemSetInt64
#else
  void sqlite4VdbeMemSetDouble(Mem*, double);
#endif
void sqlite4VdbeMemSetNull(Mem*);

int sqlite4VdbeMemMakeWriteable(Mem*);
int sqlite4VdbeMemStringify(Mem*, int);
i64 sqlite4VdbeIntValue(Mem*);
int sqlite4VdbeMemIntegerify(Mem*);
double sqlite4VdbeRealValue(Mem*);
void sqlite4VdbeIntegerAffinity(Mem*);
int sqlite4VdbeMemRealify(Mem*);
................................................................................
#ifdef SQLITE4_DEBUG
  void sqlite4VdbePrintSql(Vdbe*);
  void sqlite4VdbeMemPrettyPrint(Mem *pMem, char *zBuf);
#endif
int sqlite4VdbeMemHandleBom(Mem *pMem);





#endif /* !defined(_VDBEINT_H_) */

Changes to src/vdbeapi.c.

135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
...
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
...
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
....
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
/**************************** sqlite4_value_  *******************************
** The following routines extract information from a Mem or sqlite4_value
** structure.
*/
const void *sqlite4_value_blob(sqlite4_value *pVal){
  Mem *p = (Mem*)pVal;
  if( p->flags & (MEM_Blob|MEM_Str) ){
   (void)sqlite4VdbeMemExpandBlob(p);
    p->flags &= ~MEM_Str;
    p->flags |= MEM_Blob;
    return p->n ? p->z : 0;
  }else{
    return sqlite4_value_text(pVal);
  }
}
................................................................................
  setResultStrOrError(pCtx, z, n, SQLITE4_UTF16LE, xDel, pDelArg);
}
#endif /* SQLITE4_OMIT_UTF16 */
void sqlite4_result_value(sqlite4_context *pCtx, sqlite4_value *pValue){
  assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
  sqlite4VdbeMemCopy(&pCtx->s, pValue);
}
void sqlite4_result_zeroblob(sqlite4_context *pCtx, int n){
  assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
  sqlite4VdbeMemSetZeroBlob(&pCtx->s, n);
}
void sqlite4_result_error_code(sqlite4_context *pCtx, int errCode){
  pCtx->isError = errCode;
  if( pCtx->s.flags & MEM_Null ){
    sqlite4VdbeMemSetStr(&pCtx->s, sqlite4ErrStr(errCode), -1, 
                         SQLITE4_UTF8, SQLITE4_STATIC, 0);
  }
}
................................................................................
/**************************** sqlite4_column_  *******************************
** The following routines are used to access elements of the current row
** in the result set.
*/
const void *sqlite4_column_blob(sqlite4_stmt *pStmt, int i){
  const void *val;
  val = sqlite4_value_blob( columnMem(pStmt,i) );
  /* Even though there is no encoding conversion, value_blob() might
  ** need to call malloc() to expand the result of a zeroblob() 
  ** expression. 
  */
  columnMallocFailure(pStmt);
  return val;
}
int sqlite4_column_bytes(sqlite4_stmt *pStmt, int i){
  int val = sqlite4_value_bytes( columnMem(pStmt,i) );
  columnMallocFailure(pStmt);
  return val;
}
................................................................................
      break;
    }
    case SQLITE4_FLOAT: {
      rc = sqlite4_bind_double(pStmt, i, pValue->r);
      break;
    }
    case SQLITE4_BLOB: {
      if( pValue->flags & MEM_Zero ){
        rc = sqlite4_bind_zeroblob(pStmt, i, pValue->u.nZero);
      }else{
        rc = sqlite4_bind_blob(pStmt, i, pValue->z, pValue->n,
                               SQLITE4_TRANSIENT, 0);
      }
      break;
    }
    case SQLITE4_TEXT: {
      rc = bindText(pStmt,i,  pValue->z, pValue->n, SQLITE4_TRANSIENT, 0,
                              pValue->enc);
      break;
    }
    default: {
      rc = sqlite4_bind_null(pStmt, i);
      break;
    }
  }
  return rc;
}
int sqlite4_bind_zeroblob(sqlite4_stmt *pStmt, int i, int n){
  int rc;
  Vdbe *p = (Vdbe *)pStmt;
  rc = vdbeUnbind(p, i);
  if( rc==SQLITE4_OK ){
    sqlite4VdbeMemSetZeroBlob(&p->aVar[i-1], n);
    sqlite4_mutex_leave(p->db->mutex);
  }
  return rc;
}

/*
** Return the number of wildcards that can be potentially bound to.
** This routine is added to support DBD::SQLite.  
*/







<







 







<
<
<
<







 







<
<
<
<
<







 







<
<
<
|
|
<












<
<
<
<
<
<
<
<
<
<







135
136
137
138
139
140
141

142
143
144
145
146
147
148
...
285
286
287
288
289
290
291




292
293
294
295
296
297
298
...
744
745
746
747
748
749
750





751
752
753
754
755
756
757
....
1112
1113
1114
1115
1116
1117
1118



1119
1120

1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132










1133
1134
1135
1136
1137
1138
1139
/**************************** sqlite4_value_  *******************************
** The following routines extract information from a Mem or sqlite4_value
** structure.
*/
const void *sqlite4_value_blob(sqlite4_value *pVal){
  Mem *p = (Mem*)pVal;
  if( p->flags & (MEM_Blob|MEM_Str) ){

    p->flags &= ~MEM_Str;
    p->flags |= MEM_Blob;
    return p->n ? p->z : 0;
  }else{
    return sqlite4_value_text(pVal);
  }
}
................................................................................
  setResultStrOrError(pCtx, z, n, SQLITE4_UTF16LE, xDel, pDelArg);
}
#endif /* SQLITE4_OMIT_UTF16 */
void sqlite4_result_value(sqlite4_context *pCtx, sqlite4_value *pValue){
  assert( sqlite4_mutex_held(pCtx->s.db->mutex) );
  sqlite4VdbeMemCopy(&pCtx->s, pValue);
}




void sqlite4_result_error_code(sqlite4_context *pCtx, int errCode){
  pCtx->isError = errCode;
  if( pCtx->s.flags & MEM_Null ){
    sqlite4VdbeMemSetStr(&pCtx->s, sqlite4ErrStr(errCode), -1, 
                         SQLITE4_UTF8, SQLITE4_STATIC, 0);
  }
}
................................................................................
/**************************** sqlite4_column_  *******************************
** The following routines are used to access elements of the current row
** in the result set.
*/
const void *sqlite4_column_blob(sqlite4_stmt *pStmt, int i){
  const void *val;
  val = sqlite4_value_blob( columnMem(pStmt,i) );





  return val;
}
int sqlite4_column_bytes(sqlite4_stmt *pStmt, int i){
  int val = sqlite4_value_bytes( columnMem(pStmt,i) );
  columnMallocFailure(pStmt);
  return val;
}
................................................................................
      break;
    }
    case SQLITE4_FLOAT: {
      rc = sqlite4_bind_double(pStmt, i, pValue->r);
      break;
    }
    case SQLITE4_BLOB: {



      rc = sqlite4_bind_blob(pStmt, i, pValue->z, pValue->n,
                             SQLITE4_TRANSIENT, 0);

      break;
    }
    case SQLITE4_TEXT: {
      rc = bindText(pStmt,i,  pValue->z, pValue->n, SQLITE4_TRANSIENT, 0,
                              pValue->enc);
      break;
    }
    default: {
      rc = sqlite4_bind_null(pStmt, i);
      break;
    }
  }










  return rc;
}

/*
** Return the number of wildcards that can be potentially bound to.
** This routine is added to support DBD::SQLite.  
*/

Changes to src/vdbeaux.c.

2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
....
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
    return 6;
  }
  if( flags&MEM_Real ){
    return 7;
  }
  assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) );
  n = pMem->n;
  if( flags & MEM_Zero ){
    n += pMem->u.nZero;
  }
  assert( n>=0 );
  return ((n*2) + 12 + ((flags&MEM_Str)!=0));
}

/*
** Return the length of the data corresponding to the supplied serial-type.
*/
................................................................................
      v >>= 8;
    }
    return len;
  }

  /* String or blob */
  if( serial_type>=12 ){
    assert( pMem->n + ((pMem->flags & MEM_Zero)?pMem->u.nZero:0)
             == (int)sqlite4VdbeSerialTypeLen(serial_type) );
    assert( pMem->n<=nBuf );
    len = pMem->n;
    memcpy(buf, pMem->z, len);
    if( pMem->flags & MEM_Zero ){
      len += pMem->u.nZero;
      assert( nBuf>=0 );
      if( len > (u32)nBuf ){
        len = (u32)nBuf;
      }
      memset(&buf[pMem->n], 0, len-pMem->n);
    }
    return len;
  }

  /* NULL or constants 0 or 1 */
  return 0;
}








<
<
<







 







<
|



<
<
<
<
<
<
<
<







2214
2215
2216
2217
2218
2219
2220



2221
2222
2223
2224
2225
2226
2227
....
2327
2328
2329
2330
2331
2332
2333

2334
2335
2336
2337








2338
2339
2340
2341
2342
2343
2344
    return 6;
  }
  if( flags&MEM_Real ){
    return 7;
  }
  assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) );
  n = pMem->n;



  assert( n>=0 );
  return ((n*2) + 12 + ((flags&MEM_Str)!=0));
}

/*
** Return the length of the data corresponding to the supplied serial-type.
*/
................................................................................
      v >>= 8;
    }
    return len;
  }

  /* String or blob */
  if( serial_type>=12 ){

    assert( pMem->n == (int)sqlite4VdbeSerialTypeLen(serial_type) );
    assert( pMem->n<=nBuf );
    len = pMem->n;
    memcpy(buf, pMem->z, len);








    return len;
  }

  /* NULL or constants 0 or 1 */
  return 0;
}

Changes to src/vdbemem.c.

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
...
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
...
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
...
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
...
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
....
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
**
** Return SQLITE4_OK on success or SQLITE4_NOMEM if malloc fails.
*/
int sqlite4VdbeMemMakeWriteable(Mem *pMem){
  int f;
  assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
  assert( (pMem->flags&MEM_RowSet)==0 );
  (void)ExpandBlob(pMem);
  f = pMem->flags;
  if( (f&(MEM_Str|MEM_Blob)) && pMem->z!=pMem->zMalloc ){
    if( sqlite4VdbeMemGrow(pMem, pMem->n + 2, 1) ){
      return SQLITE4_NOMEM;
    }
    pMem->z[pMem->n] = 0;
    pMem->z[pMem->n+1] = 0;
................................................................................
*/
int sqlite4VdbeMemStringify(Mem *pMem, int enc){
  int rc = SQLITE4_OK;
  int fg = pMem->flags;
  const int nByte = 32;

  assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
  assert( !(fg&MEM_Zero) );
  assert( !(fg&(MEM_Str|MEM_Blob)) );
  assert( fg&(MEM_Int|MEM_Real) );
  assert( (pMem->flags&MEM_RowSet)==0 );
  assert( EIGHT_BYTE_ALIGNMENT(pMem) );


  if( sqlite4VdbeMemGrow(pMem, nByte, 0) ){
................................................................................
  }else if( pMem->flags & MEM_RowSet ){
    sqlite4RowSetClear(pMem->u.pRowSet);
  }
  MemSetTypeFlag(pMem, MEM_Null);
  pMem->type = SQLITE4_NULL;
}

/*
** Delete any previous value and set the value to be a BLOB of length
** n containing all zeros.
*/
void sqlite4VdbeMemSetZeroBlob(Mem *pMem, int n){
  sqlite4VdbeMemRelease(pMem);
  pMem->flags = MEM_Blob|MEM_Zero;
  pMem->type = SQLITE4_BLOB;
  pMem->n = 0;
  if( n<0 ) n = 0;
  pMem->u.nZero = n;
  pMem->enc = SQLITE4_UTF8;
}

/*
** Delete any previous value and set the value stored in *pMem to val,
** manifest type INTEGER.
*/
void sqlite4VdbeMemSetInt64(Mem *pMem, i64 val){
  sqlite4VdbeMemRelease(pMem);
  pMem->u.i = val;
................................................................................
** Return true if the Mem object contains a TEXT or BLOB that is
** too large - whose size exceeds SQLITE4_MAX_LENGTH.
*/
int sqlite4VdbeMemTooBig(Mem *p){
  assert( p->db!=0 );
  if( p->flags & (MEM_Str|MEM_Blob) ){
    int n = p->n;
    if( p->flags & MEM_Zero ){
      n += p->u.nZero;
    }
    return n>p->db->aLimit[SQLITE4_LIMIT_LENGTH];
  }
  return 0; 
}

#ifdef SQLITE4_DEBUG
/*
................................................................................
  assert( (pVal->flags & MEM_RowSet)==0 );

  if( pVal->flags&MEM_Null ){
    return 0;
  }
  assert( (MEM_Blob>>3) == MEM_Str );
  pVal->flags |= (pVal->flags & MEM_Blob)>>3;
  (void)ExpandBlob(pVal);
  if( pVal->flags&MEM_Str ){
    sqlite4VdbeChangeEncoding(pVal, enc & ~SQLITE4_UTF16_ALIGNED);
    if( (enc & SQLITE4_UTF16_ALIGNED)!=0 && 1==(1&SQLITE4_PTR_TO_INT(pVal->z)) ){
      assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 );
      if( sqlite4VdbeMemMakeWriteable(pVal)!=SQLITE4_OK ){
        return 0;
      }
................................................................................
/*
** Return the number of bytes in the sqlite4_value object assuming
** that it uses the encoding "enc"
*/
int sqlite4ValueBytes(sqlite4_value *pVal, u8 enc){
  Mem *p = (Mem*)pVal;
  if( (p->flags & MEM_Blob)!=0 || sqlite4ValueText(pVal, enc) ){
    if( p->flags & MEM_Zero ){
      return p->n + p->u.nZero;
    }else{
      return p->n;
    }
  }
  return 0;
}







<







 







<







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







<
<
<







 







<







 







<
<
<
|
<



114
115
116
117
118
119
120

121
122
123
124
125
126
127
...
167
168
169
170
171
172
173

174
175
176
177
178
179
180
...
452
453
454
455
456
457
458














459
460
461
462
463
464
465
...
507
508
509
510
511
512
513



514
515
516
517
518
519
520
...
835
836
837
838
839
840
841

842
843
844
845
846
847
848
....
1018
1019
1020
1021
1022
1023
1024



1025

1026
1027
1028
**
** Return SQLITE4_OK on success or SQLITE4_NOMEM if malloc fails.
*/
int sqlite4VdbeMemMakeWriteable(Mem *pMem){
  int f;
  assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
  assert( (pMem->flags&MEM_RowSet)==0 );

  f = pMem->flags;
  if( (f&(MEM_Str|MEM_Blob)) && pMem->z!=pMem->zMalloc ){
    if( sqlite4VdbeMemGrow(pMem, pMem->n + 2, 1) ){
      return SQLITE4_NOMEM;
    }
    pMem->z[pMem->n] = 0;
    pMem->z[pMem->n+1] = 0;
................................................................................
*/
int sqlite4VdbeMemStringify(Mem *pMem, int enc){
  int rc = SQLITE4_OK;
  int fg = pMem->flags;
  const int nByte = 32;

  assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );

  assert( !(fg&(MEM_Str|MEM_Blob)) );
  assert( fg&(MEM_Int|MEM_Real) );
  assert( (pMem->flags&MEM_RowSet)==0 );
  assert( EIGHT_BYTE_ALIGNMENT(pMem) );


  if( sqlite4VdbeMemGrow(pMem, nByte, 0) ){
................................................................................
  }else if( pMem->flags & MEM_RowSet ){
    sqlite4RowSetClear(pMem->u.pRowSet);
  }
  MemSetTypeFlag(pMem, MEM_Null);
  pMem->type = SQLITE4_NULL;
}















/*
** Delete any previous value and set the value stored in *pMem to val,
** manifest type INTEGER.
*/
void sqlite4VdbeMemSetInt64(Mem *pMem, i64 val){
  sqlite4VdbeMemRelease(pMem);
  pMem->u.i = val;
................................................................................
** Return true if the Mem object contains a TEXT or BLOB that is
** too large - whose size exceeds SQLITE4_MAX_LENGTH.
*/
int sqlite4VdbeMemTooBig(Mem *p){
  assert( p->db!=0 );
  if( p->flags & (MEM_Str|MEM_Blob) ){
    int n = p->n;



    return n>p->db->aLimit[SQLITE4_LIMIT_LENGTH];
  }
  return 0; 
}

#ifdef SQLITE4_DEBUG
/*
................................................................................
  assert( (pVal->flags & MEM_RowSet)==0 );

  if( pVal->flags&MEM_Null ){
    return 0;
  }
  assert( (MEM_Blob>>3) == MEM_Str );
  pVal->flags |= (pVal->flags & MEM_Blob)>>3;

  if( pVal->flags&MEM_Str ){
    sqlite4VdbeChangeEncoding(pVal, enc & ~SQLITE4_UTF16_ALIGNED);
    if( (enc & SQLITE4_UTF16_ALIGNED)!=0 && 1==(1&SQLITE4_PTR_TO_INT(pVal->z)) ){
      assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 );
      if( sqlite4VdbeMemMakeWriteable(pVal)!=SQLITE4_OK ){
        return 0;
      }
................................................................................
/*
** Return the number of bytes in the sqlite4_value object assuming
** that it uses the encoding "enc"
*/
int sqlite4ValueBytes(sqlite4_value *pVal, u8 enc){
  Mem *p = (Mem*)pVal;
  if( (p->flags & MEM_Blob)!=0 || sqlite4ValueText(pVal, enc) ){



    return p->n;

  }
  return 0;
}

Changes to src/vdbetrace.c.

135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
          sqlite4XPrintf(&out, "'%.*q'", utf8.n, utf8.z);
          sqlite4VdbeMemRelease(&utf8);
        }else
#endif
        {
          sqlite4XPrintf(&out, "'%.*q'", pVar->n, pVar->z);
        }
      }else if( pVar->flags & MEM_Zero ){
        sqlite4XPrintf(&out, "zeroblob(%d)", pVar->u.nZero);
      }else{
        assert( pVar->flags & MEM_Blob );
        sqlite4StrAccumAppend(&out, "x'", 2);
        for(i=0; i<pVar->n; i++){
          sqlite4XPrintf(&out, "%02x", pVar->z[i]&0xff);
        }
        sqlite4StrAccumAppend(&out, "'", 1);







<
<







135
136
137
138
139
140
141


142
143
144
145
146
147
148
          sqlite4XPrintf(&out, "'%.*q'", utf8.n, utf8.z);
          sqlite4VdbeMemRelease(&utf8);
        }else
#endif
        {
          sqlite4XPrintf(&out, "'%.*q'", pVar->n, pVar->z);
        }


      }else{
        assert( pVar->flags & MEM_Blob );
        sqlite4StrAccumAppend(&out, "x'", 2);
        for(i=0; i<pVar->n; i++){
          sqlite4XPrintf(&out, "%02x", pVar->z[i]&0xff);
        }
        sqlite4StrAccumAppend(&out, "'", 1);

Changes to test/boundary4.test.

210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
do_test boundary4-3.1 {
  db eval {
    UPDATE t1 SET oid=a, a=oid
  }
} {}
do_test boundary4-3.2 {
  db eval {
    ALTER TABLE t1 ADD COLUMN z; UPDATE t1 SET z=zeroblob(600)
  }
} {}
do_test boundary4-3.3 {
  db eval {
    SELECT oid, a, x FROM t1 ORDER BY +oid
  }
} {-576460752303423489 33 fffffffff7fffffff7ffffffffffffff -576460752303423488 12 fffffffff8000000f800000000000000 -36028797018963969 14 ffffffffff7fffffff7fffffffffffff -36028797018963968 41 ffffffffff800000ff80000000000000 -140737488355329 42 ffffffffffff7fffffff7fffffffffff -140737488355328 4 ffffffffffff8000ffff800000000000 -549755813889 5 ffffffffffffff7fffffff7fffffffff -549755813888 7 ffffffffffffff80ffffff8000000000 -2147483649 46 ffffffffffffffffffffffff7fffffff -2147483648 35 ffffffffffffffffffffffff80000000 -8388609 29 ffffffffffffffffffffffffff7fffff -8388608 16 ffffffffffffffffffffffffff800000 -32769 13 ffffffffffffffffffffffffffff7fff -32768 45 ffffffffffffffffffffffffffff8000 -129 1 ffffffffffffffffffffffffffffff7f -128 27 ffffffffffffffffffffffffffffff80 127 19 000000000000007f 128 30 0000000000000080 255 48 00000000000000ff 256 2 0000000000000100 32767 8 0000000000007fff 32768 44 0000000000008000 65535 37 000000000000ffff 65536 38 0000000000010000 8388607 24 00000000007fffff 8388608 36 0000000000800000 16777215 20 0000000000ffffff 16777216 34 0000000001000000 2147483647 26 000000007fffffff 2147483648 43 0000000080000000 4294967295 22 00000000ffffffff 4294967296 6 00000001100000000 549755813887 23 0000007f7fffffffff 549755813888 21 000000808000000000 1099511627775 40 000000ffffffffffff 1099511627776 28 0000010010000000000 140737488355327 3 00007fff7fffffffffff 140737488355328 47 00008000800000000000 281474976710655 39 0000ffffffffffffffff 281474976710656 10 000100001000000000000 36028797018963967 18 007fffff7fffffffffffff 36028797018963968 25 0080000080000000000000 72057594037927935 32 00ffffffffffffffffffff 72057594037927936 11 01000000100000000000000 576460752303423487 9 07ffffff7ffffffffffffff 576460752303423488 31 08000000800000000000000 1152921504606846975 15 0ffffffffffffffffffffff 1152921504606846976 17 100000001000000000000000}







|







210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
do_test boundary4-3.1 {
  db eval {
    UPDATE t1 SET oid=a, a=oid
  }
} {}
do_test boundary4-3.2 {
  db eval {
    ALTER TABLE t1 ADD COLUMN z; UPDATE t1 SET z=randomblob(600)
  }
} {}
do_test boundary4-3.3 {
  db eval {
    SELECT oid, a, x FROM t1 ORDER BY +oid
  }
} {-576460752303423489 33 fffffffff7fffffff7ffffffffffffff -576460752303423488 12 fffffffff8000000f800000000000000 -36028797018963969 14 ffffffffff7fffffff7fffffffffffff -36028797018963968 41 ffffffffff800000ff80000000000000 -140737488355329 42 ffffffffffff7fffffff7fffffffffff -140737488355328 4 ffffffffffff8000ffff800000000000 -549755813889 5 ffffffffffffff7fffffff7fffffffff -549755813888 7 ffffffffffffff80ffffff8000000000 -2147483649 46 ffffffffffffffffffffffff7fffffff -2147483648 35 ffffffffffffffffffffffff80000000 -8388609 29 ffffffffffffffffffffffffff7fffff -8388608 16 ffffffffffffffffffffffffff800000 -32769 13 ffffffffffffffffffffffffffff7fff -32768 45 ffffffffffffffffffffffffffff8000 -129 1 ffffffffffffffffffffffffffffff7f -128 27 ffffffffffffffffffffffffffffff80 127 19 000000000000007f 128 30 0000000000000080 255 48 00000000000000ff 256 2 0000000000000100 32767 8 0000000000007fff 32768 44 0000000000008000 65535 37 000000000000ffff 65536 38 0000000000010000 8388607 24 00000000007fffff 8388608 36 0000000000800000 16777215 20 0000000000ffffff 16777216 34 0000000001000000 2147483647 26 000000007fffffff 2147483648 43 0000000080000000 4294967295 22 00000000ffffffff 4294967296 6 00000001100000000 549755813887 23 0000007f7fffffffff 549755813888 21 000000808000000000 1099511627775 40 000000ffffffffffff 1099511627776 28 0000010010000000000 140737488355327 3 00007fff7fffffffffff 140737488355328 47 00008000800000000000 281474976710655 39 0000ffffffffffffffff 281474976710656 10 000100001000000000000 36028797018963967 18 007fffff7fffffffffffff 36028797018963968 25 0080000080000000000000 72057594037927935 32 00ffffffffffffffffffff 72057594037927936 11 01000000100000000000000 576460752303423487 9 07ffffff7ffffffffffffff 576460752303423488 31 08000000800000000000000 1152921504606846975 15 0ffffffffffffffffffffff 1152921504606846976 17 100000001000000000000000}

Changes to test/test_main.c.

2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
....
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  char **argv            /* Text of each argument */
){
  return TCL_OK;         /* Do nothing */
}

/*
** Usage:   sqlite4_bind_zeroblob  STMT IDX N
**
** Test the sqlite4_bind_zeroblob interface.  STMT is a prepared statement.
** IDX is the index of a wildcard in the prepared statement.  This command
** binds a N-byte zero-filled BLOB to the wildcard.
*/
static int test_bind_zeroblob(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  sqlite4_stmt *pStmt;
  int idx;
  int n;
  int rc;

  if( objc!=4 ){
    Tcl_WrongNumArgs(interp, 1, objv, "STMT IDX N");
    return TCL_ERROR;
  }

  if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
  if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
  if( Tcl_GetIntFromObj(interp, objv[3], &n) ) return TCL_ERROR;

  rc = sqlite4_bind_zeroblob(pStmt, idx, n);
  if( sqlite4TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
  if( rc!=SQLITE4_OK ){
    return TCL_ERROR;
  }

  return TCL_OK;
}

/*
** Usage:   sqlite4_bind_int  STMT N VALUE
**
** Test the sqlite4_bind_int interface.  STMT is a prepared statement.
** N is the index of a wildcard in the prepared statement.  This command
** binds a 32-bit integer VALUE to that wildcard.
*/
................................................................................
  static struct {
     char *zName;
     Tcl_ObjCmdProc *xProc;
     void *clientData;
  } aObjCmd[] = {
     { "sqlite4_connection_pointer",    get_sqlite_pointer, 0 },
     { "sqlite4_bind_int",              test_bind_int,      0 },
     { "sqlite4_bind_zeroblob",         test_bind_zeroblob, 0 },
     { "sqlite4_bind_int64",            test_bind_int64,    0 },
     { "sqlite4_bind_double",           test_bind_double,   0 },
     { "sqlite4_bind_null",             test_bind_null     ,0 },
     { "sqlite4_bind_text",             test_bind_text     ,0 },
     { "sqlite4_bind_text16",           test_bind_text16   ,0 },
     { "sqlite4_bind_blob",             test_bind_blob     ,0 },
     { "sqlite4_bind_parameter_count",  test_bind_parameter_count, 0},







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







<







2533
2534
2535
2536
2537
2538
2539




































2540
2541
2542
2543
2544
2545
2546
....
4582
4583
4584
4585
4586
4587
4588

4589
4590
4591
4592
4593
4594
4595
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  char **argv            /* Text of each argument */
){
  return TCL_OK;         /* Do nothing */
}





































/*
** Usage:   sqlite4_bind_int  STMT N VALUE
**
** Test the sqlite4_bind_int interface.  STMT is a prepared statement.
** N is the index of a wildcard in the prepared statement.  This command
** binds a 32-bit integer VALUE to that wildcard.
*/
................................................................................
  static struct {
     char *zName;
     Tcl_ObjCmdProc *xProc;
     void *clientData;
  } aObjCmd[] = {
     { "sqlite4_connection_pointer",    get_sqlite_pointer, 0 },
     { "sqlite4_bind_int",              test_bind_int,      0 },

     { "sqlite4_bind_int64",            test_bind_int64,    0 },
     { "sqlite4_bind_double",           test_bind_double,   0 },
     { "sqlite4_bind_null",             test_bind_null     ,0 },
     { "sqlite4_bind_text",             test_bind_text     ,0 },
     { "sqlite4_bind_text16",           test_bind_text16   ,0 },
     { "sqlite4_bind_blob",             test_bind_blob     ,0 },
     { "sqlite4_bind_parameter_count",  test_bind_parameter_count, 0},

Changes to test/tkt35xx.test.

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
# Trigger the problem using explicit rollback.
#
do_test tkt35xx-1.1 {
  execsql {
    PRAGMA auto_vacuum = 0;
    CREATE TABLE t1(a,b,c);
    CREATE INDEX i1 ON t1(c);
    INSERT INTO t1 VALUES(0, 0, zeroblob(676));
    INSERT INTO t1 VALUES(1, 1, zeroblob(676));
    DELETE FROM t1;
    BEGIN;
    INSERT INTO t1 VALUES(0, 0, zeroblob(676));
    INSERT INTO t1 VALUES(1, 1, zeroblob(676));
    ROLLBACK;
    INSERT INTO t1 VALUES(0, 0, zeroblob(676));
  }
  execsql {
    INSERT INTO t1 VALUES(1, 1, zeroblob(676));
  }
} {}

# Trigger the problem using statement rollback.
#
db close
delete_file test.db







|
|


|
|

|


|







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
# Trigger the problem using explicit rollback.
#
do_test tkt35xx-1.1 {
  execsql {
    PRAGMA auto_vacuum = 0;
    CREATE TABLE t1(a,b,c);
    CREATE INDEX i1 ON t1(c);
    INSERT INTO t1 VALUES(0, 0, randomblob(676));
    INSERT INTO t1 VALUES(1, 1, randomblob(676));
    DELETE FROM t1;
    BEGIN;
    INSERT INTO t1 VALUES(0, 0, randomblob(676));
    INSERT INTO t1 VALUES(1, 1, randomblob(676));
    ROLLBACK;
    INSERT INTO t1 VALUES(0, 0, randomblob(676));
  }
  execsql {
    INSERT INTO t1 VALUES(1, 1, randomblob(676));
  }
} {}

# Trigger the problem using statement rollback.
#
db close
delete_file test.db

Changes to test/tkt3918.test.

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
    PRAGMA auto_vacuum = incremental;
    CREATE TABLE t1(i, x);
  }
} {}
do_test tkt3918.2 {
  execsql {
    INSERT INTO t1 VALUES(1, randstr(1000,1000));
    INSERT INTO t1 VALUES(2, zeroblob(248*1020 + 100));
    INSERT INTO t1 VALUES(3, zeroblob(2*1020 + 100));
  }
} {}

# This set of statements sets up the free list so that the
# first free-list trunk page contains only a single leaf.
# The leaf page is also the last page in the database. The
# second free-list trunk page contains, amongst other things,







|
|







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
    PRAGMA auto_vacuum = incremental;
    CREATE TABLE t1(i, x);
  }
} {}
do_test tkt3918.2 {
  execsql {
    INSERT INTO t1 VALUES(1, randstr(1000,1000));
    INSERT INTO t1 VALUES(2, randomblob(248*1020 + 100));
    INSERT INTO t1 VALUES(3, randomblob(2*1020 + 100));
  }
} {}

# This set of statements sets up the free list so that the
# first free-list trunk page contains only a single leaf.
# The leaf page is also the last page in the database. The
# second free-list trunk page contains, amongst other things,

Deleted test/zeroblob.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
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
# 2007 May 02
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing of the zero-filled blob functionality
# including the sqlite4_bind_zeroblob(), sqlite4_result_zeroblob(),
# and the built-in zeroblob() SQL function.
#
# $Id: zeroblob.test,v 1.14 2009/07/14 02:33:02 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !incrblob {
  finish_test
  return
}

# When zeroblob() is used for the last field of a column, then the
# content of the zeroblob is never instantiated on the VDBE stack.
# But it does get inserted into the database correctly.
#
db eval {PRAGMA cache_size=10}
sqlite4_memory_highwater 1
unset -nocomplain memused
set memused [sqlite4_memory_used]
do_test zeroblob-1.1 {
  execsql {
    CREATE TABLE t1(a,b,c,d);
  }
  set ::sqlite4_max_blobsize 0
  execsql {
    INSERT INTO t1 VALUES(2,3,4,zeroblob(1000000));
  }
  set ::sqlite4_max_blobsize
} {10}
do_test zeroblob-1.1.1 {
  expr {[sqlite4_memory_highwater]<$::memused+25000}
} {1}
do_test zeroblob-1.2 {
  execsql {
    SELECT length(d) FROM t1
  }
} {1000000}

# If a non-NULL column follows the zeroblob, then the content of
# the zeroblob must be instantiated.
#
do_test zeroblob-1.3 {
  set ::sqlite4_max_blobsize 0
  execsql {
    INSERT INTO t1 VALUES(3,4,zeroblob(10000),5);
  }
  set ::sqlite4_max_blobsize
} {10010}
do_test zeroblob-1.4 {
  execsql {
    SELECT length(c), length(d) FROM t1
  }
} {1 1000000 10000 1}

# Multiple zeroblobs can appear at the end of record.  No instantiation
# of the blob content occurs on the stack.
#
do_test zeroblob-1.5 {
  set ::sqlite4_max_blobsize 0
  execsql {
    INSERT INTO t1 VALUES(4,5,zeroblob(10000),zeroblob(10000));
  }
  set ::sqlite4_max_blobsize
} {11}
do_test zeroblob-1.6 {
  execsql {
    SELECT length(c), length(d) FROM t1
  }
} {1 1000000 10000 1 10000 10000}

# NULLs can follow the zeroblob() or be intermixed with zeroblobs and
# no instantiation of the zeroblobs occurs on the stack.
#
do_test zeroblob-1.7 {
  set ::sqlite4_max_blobsize 0
  execsql {
    INSERT INTO t1 VALUES(5,zeroblob(10000),NULL,zeroblob(10000));
  }
  set ::sqlite4_max_blobsize
} {10}
do_test zeroblob-1.8 {
  execsql {
    SELECT length(b), length(d) FROM t1 WHERE a=5
  }
} {10000 10000}

# Comparisons against zeroblobs work.
#
do_test zeroblob-2.1 {
  execsql {
    SELECT a FROM t1 WHERE b=zeroblob(10000)
  }
} {5}

# Comparisons against zeroblobs work even when indexed.
#
do_test zeroblob-2.2 {
  execsql {
    CREATE INDEX i1_1 ON t1(b);
    SELECT a FROM t1 WHERE b=zeroblob(10000);
  }
} {5}

# DISTINCT works for zeroblobs
#
ifcapable bloblit&&subquery&&compound {
  do_test zeroblob-3.1 {
    execsql {
      SELECT count(DISTINCT a) FROM (
        SELECT x'00000000000000000000' AS a
        UNION ALL
        SELECT zeroblob(10) AS a
      )
    }
  } {1}
}

# Concatentation works with zeroblob
#
ifcapable bloblit {
  do_test zeroblob-4.1 {
    execsql {
      SELECT hex(zeroblob(2) || x'61')
    }
  } {000061}
}

# Check various CAST(...) operations on zeroblob.
#
do_test zeroblob-5.1 {
  execsql {
    SELECT CAST (zeroblob(100) AS REAL);
  }
} {0.0}
do_test zeroblob-5.2 {
  execsql {
    SELECT CAST (zeroblob(100) AS INTEGER);
  }
} {0}
do_test zeroblob-5.3 {
  execsql {
    SELECT CAST (zeroblob(100) AS TEXT);
  }
} {{}}
do_test zeroblob-5.4 {
  execsql {
    SELECT CAST(zeroblob(100) AS BLOB);
  }
} [execsql {SELECT zeroblob(100)}]
  

# Check for malicious use of zeroblob.  Make sure nothing crashes.
#
do_test zeroblob-6.1.1 { 
  execsql {select zeroblob(-1)} 
} {{}} 
do_test zeroblob-6.1.2 { 
  execsql {select zeroblob(-10)} 
} {{}} 
do_test zeroblob-6.1.3 { 
  execsql {select zeroblob(-100)} 
} {{}} 
do_test zeroblob-6.2 { 
  execsql {select length(zeroblob(-1))} 
} {0} 
do_test zeroblob-6.3 { 
  execsql {select zeroblob(-1)|1} 
} {1} 
do_test zeroblob-6.4 { 
  catchsql {select length(zeroblob(2147483648))} 
} {1 {string or blob too big}} 
do_test zeroblob-6.5 { 
  catchsql {select zeroblob(2147483648)} 
} {1 {string or blob too big}}
do_test zeroblob-6.6 {
  execsql {select hex(zeroblob(-1))}
} {{}}
do_test zeroblob-6.7 {
  execsql {select typeof(zeroblob(-1))}
} {blob}

# Test bind_zeroblob()
#
sqlite4_memory_highwater 1
unset -nocomplain memused
set memused [sqlite4_memory_used]
do_test zeroblob-7.1 {
  set ::STMT [sqlite4_prepare $::DB "SELECT length(?)" -1 DUMMY]
  set ::sqlite4_max_blobsize 0
  sqlite4_bind_zeroblob $::STMT 1 450000
  sqlite4_step $::STMT
} {SQLITE4_ROW}
do_test zeroblob-7.2 {
  sqlite4_column_int $::STMT 0
} {450000}
do_test zeroblob-7.3 {
  sqlite4_finalize $::STMT
} {SQLITE4_OK}
do_test zeroblob-7.4 {
  set ::sqlite4_max_blobsize
} {0}
do_test zeroblob-7.5 {
  expr {[sqlite4_memory_highwater]<$::memused+10000}
} {1}

# Test that MakeRecord can handle a value with some real content
# and a zero-blob tail.
#
do_test zeroblob-8.1 {
  llength [execsql {
    SELECT 'hello' AS a, zeroblob(10) as b from t1 ORDER BY a, b;
  }]
} {8}


# Ticket #3965
# zeroblobs on either size of an IN operator
#
do_test zeroblob-9.1 {
  db eval {SELECT x'0000' IN (x'000000')}
} {0}
do_test zeroblob-9.2 {
  db eval {SELECT x'0000' IN (x'0000')}
} {1}
do_test zeroblob-9.3 {
  db eval {SELECT zeroblob(2) IN (x'000000')}
} {0}
do_test zeroblob-9.4 {
  db eval {SELECT zeroblob(2) IN (x'0000')}
} {1}
do_test zeroblob-9.5 {
  db eval {SELECT x'0000' IN (zeroblob(3))}
} {0}
do_test zeroblob-9.6 {
  db eval {SELECT x'0000' IN (zeroblob(2))}
} {1}
do_test zeroblob-9.7 {
  db eval {SELECT zeroblob(2) IN (zeroblob(3))}
} {0}
do_test zeroblob-9.8 {
  db eval {SELECT zeroblob(2) IN (zeroblob(2))}
} {1}


finish_test
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<