/ Check-in [a8e1545c]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Add and use the internal sqlite3DbSpanDup() interface.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | span-refactor
Files: files | file ages | folders
SHA3-256: a8e1545cb7aacb6a26a8c92a3ad4a3d584d150c3a00d2828c8adbb1ee19fcb6d
User & Date: drh 2017-12-27 19:43:22
Context
2017-12-27
20:38
Show the text of individual statements within a trigger, as they execute, as comments in the output from sqlite3_trace() and sqlite3_trace_v2(). check-in: fe3d2b97 user: drh tags: span-refactor
19:43
Add and use the internal sqlite3DbSpanDup() interface. check-in: a8e1545c user: drh tags: span-refactor
19:27
Merge recent enhancements from trunk. check-in: 76373091 user: drh tags: span-refactor
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/build.c.

1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
      sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
          pCol->zName);
    }else{
      /* A copy of pExpr is used instead of the original, as pExpr contains
      ** tokens that point to volatile memory.	
      */
      Expr x;
      int n;
      sqlite3ExprDelete(db, pCol->pDflt);
      memset(&x, 0, sizeof(x));
      x.op = TK_SPAN;
      while( sqlite3Isspace(zStart[0]) ) zStart++;
      n = (int)(zEnd - zStart);
      while( n>0 && sqlite3Isspace(zStart[n-1]) ) n--;
      x.u.zToken = sqlite3DbStrNDup(db, zStart, n);
      x.pLeft = pExpr;
      x.flags = EP_Skip;
      pCol->pDflt = sqlite3ExprDup(db, &x, EXPRDUP_REDUCE);
      sqlite3DbFree(db, x.u.zToken);
    }
  }
  sqlite3ExprDelete(db, pExpr);







<



<
<
<
|







1237
1238
1239
1240
1241
1242
1243

1244
1245
1246



1247
1248
1249
1250
1251
1252
1253
1254
      sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
          pCol->zName);
    }else{
      /* A copy of pExpr is used instead of the original, as pExpr contains
      ** tokens that point to volatile memory.	
      */
      Expr x;

      sqlite3ExprDelete(db, pCol->pDflt);
      memset(&x, 0, sizeof(x));
      x.op = TK_SPAN;



      x.u.zToken = sqlite3DbSpanDup(db, zStart, zEnd);
      x.pLeft = pExpr;
      x.flags = EP_Skip;
      pCol->pDflt = sqlite3ExprDup(db, &x, EXPRDUP_REDUCE);
      sqlite3DbFree(db, x.u.zToken);
    }
  }
  sqlite3ExprDelete(db, pExpr);

Changes to src/expr.c.

1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
  const char *zStart,     /* Start of the span */
  const char *zEnd        /* End of the span */
){
  sqlite3 *db = pParse->db;
  assert( pList!=0 || db->mallocFailed!=0 );
  if( pList ){
    struct ExprList_item *pItem = &pList->a[pList->nExpr-1];
    int n;
    assert( pList->nExpr>0 );
    sqlite3DbFree(db, pItem->zSpan);
    while( sqlite3Isspace(zStart[0]) ) zStart++;
    n = (int)(zEnd - zStart);
    while( n>0 && sqlite3Isspace(zStart[n-1]) ) n--;
    pItem->zSpan = sqlite3DbStrNDup(db, zStart, n);
  }
}

/*
** If the expression list pEList contains more than iLimit elements,
** leave an error message in pParse.
*/







<


<
<
<
|







1657
1658
1659
1660
1661
1662
1663

1664
1665



1666
1667
1668
1669
1670
1671
1672
1673
  const char *zStart,     /* Start of the span */
  const char *zEnd        /* End of the span */
){
  sqlite3 *db = pParse->db;
  assert( pList!=0 || db->mallocFailed!=0 );
  if( pList ){
    struct ExprList_item *pItem = &pList->a[pList->nExpr-1];

    assert( pList->nExpr>0 );
    sqlite3DbFree(db, pItem->zSpan);



    pItem->zSpan = sqlite3DbSpanDup(db, zStart, zEnd);
  }
}

/*
** If the expression list pEList contains more than iLimit elements,
** leave an error message in pParse.
*/

Changes to src/malloc.c.

622
623
624
625
626
627
628













629
630
631
632
633
634
635
  zNew = sqlite3DbMallocRawNN(db, n+1);
  if( zNew ){
    memcpy(zNew, z, (size_t)n);
    zNew[n] = 0;
  }
  return zNew;
}














/*
** Free any prior content in *pz and replace it with a copy of zNew.
*/
void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){
  sqlite3DbFree(db, *pz);
  *pz = sqlite3DbStrDup(db, zNew);







>
>
>
>
>
>
>
>
>
>
>
>
>







622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
  zNew = sqlite3DbMallocRawNN(db, n+1);
  if( zNew ){
    memcpy(zNew, z, (size_t)n);
    zNew[n] = 0;
  }
  return zNew;
}

/*
** The text between zStart and zEnd represents a phrase within a larger
** SQL statement.  Make a copy of this phrase in space obtained form
** sqlite3DbMalloc().  Omit leading and trailing whitespace.
*/
char *sqlite3DbSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){
  int n;
  while( sqlite3Isspace(zStart[0]) ) zStart++;
  n = (int)(zEnd - zStart);
  while( n>0 && sqlite3Isspace(zStart[n-1]) ) n--;
  return sqlite3DbStrNDup(db, zStart, n);
}

/*
** Free any prior content in *pz and replace it with a copy of zNew.
*/
void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){
  sqlite3DbFree(db, *pz);
  *pz = sqlite3DbStrDup(db, zNew);

Changes to src/sqliteInt.h.

3509
3510
3511
3512
3513
3514
3515

3516
3517
3518
3519
3520
3521
3522
void *sqlite3Malloc(u64);
void *sqlite3MallocZero(u64);
void *sqlite3DbMallocZero(sqlite3*, u64);
void *sqlite3DbMallocRaw(sqlite3*, u64);
void *sqlite3DbMallocRawNN(sqlite3*, u64);
char *sqlite3DbStrDup(sqlite3*,const char*);
char *sqlite3DbStrNDup(sqlite3*,const char*, u64);

void *sqlite3Realloc(void*, u64);
void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64);
void *sqlite3DbRealloc(sqlite3 *, void *, u64);
void sqlite3DbFree(sqlite3*, void*);
void sqlite3DbFreeNN(sqlite3*, void*);
int sqlite3MallocSize(void*);
int sqlite3DbMallocSize(sqlite3*, void*);







>







3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
void *sqlite3Malloc(u64);
void *sqlite3MallocZero(u64);
void *sqlite3DbMallocZero(sqlite3*, u64);
void *sqlite3DbMallocRaw(sqlite3*, u64);
void *sqlite3DbMallocRawNN(sqlite3*, u64);
char *sqlite3DbStrDup(sqlite3*,const char*);
char *sqlite3DbStrNDup(sqlite3*,const char*, u64);
char *sqlite3DbSpanDup(sqlite3*,const char*,const char*);
void *sqlite3Realloc(void*, u64);
void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64);
void *sqlite3DbRealloc(sqlite3 *, void *, u64);
void sqlite3DbFree(sqlite3*, void*);
void sqlite3DbFreeNN(sqlite3*, void*);
int sqlite3MallocSize(void*);
int sqlite3DbMallocSize(sqlite3*, void*);

Changes to test/capi2.test.

180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
  set rc [catch {
      sqlite3_prepare $DB {select bogus from sqlite_master;;;x;} -1 TAIL
  } msg]
  lappend rc $msg $TAIL
} {1 {(1) no such column: bogus} {;;x;}}
do_test capi2-3.6 {
  set rc [catch {
      sqlite3_prepare $DB {select 5/0} -1 TAIL
  } VM]
  lappend rc $TAIL
} {0 {}}
do_test capi2-3.7 {
  list [sqlite3_step $VM] \
       [sqlite3_column_count $VM] \
       [get_row_values $VM] \







|







180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
  set rc [catch {
      sqlite3_prepare $DB {select bogus from sqlite_master;;;x;} -1 TAIL
  } msg]
  lappend rc $msg $TAIL
} {1 {(1) no such column: bogus} {;;x;}}
do_test capi2-3.6 {
  set rc [catch {
      sqlite3_prepare $DB {select 5/0;} -1 TAIL
  } VM]
  lappend rc $TAIL
} {0 {}}
do_test capi2-3.7 {
  list [sqlite3_step $VM] \
       [sqlite3_column_count $VM] \
       [get_row_values $VM] \