SQLite

Changes On Branch branch-3.8.6
Login

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

Changes In Branch branch-3.8.6 Excluding Merge-Ins

This is equivalent to a diff from 9491ba7d to a66a5b39

2017-07-21
03:23
Add new interfaces sqlite3_result_pointer(), and sqlite3_value_pointer() and use them to transfer the eponymous FTS3 column pointer to the snippet() and offsets() routines. This is a cherry-pick of [f0f492245e95], which is in turn inspired by check-in [72de49f2]. (Leaf check-in: a66a5b39 user: drh tags: branch-3.8.6)
03:09
Add new interfaces sqlite3_result_pointer(), and sqlite3_value_pointer() and use them to transfer the eponymous FTS3 column pointer to the snippet() and offsets() routines. This changes is inspired by check-in [72de49f2] but is new implementation, not a cherry-pick. (Leaf check-in: f0f49224 user: drh tags: branch-3.7.11)
2015-05-21
17:24
Prevent a virtual table from being destroyed while it is in use. Also: replace Vdbe.inVtabMethod with sqlite3.nVDestroy. Simplify the EXPLAIN output for P4.pVtab to only show the sqlite3_vtab pointer. Cherrypick of [cbeb9a1aed8c]. (check-in: b3bb660a user: dan tags: branch-3.8.6)
2014-10-22
02:43
Call fsync() right after ftruncate() when in journal_mode=TRUNCATE and when synchronous=FULL in order to ensure that transactions are durable across a power loss that happens moments after the commit. Proposed fix for https://bugzilla.mozilla.org/show_bug.cgi?id=1072773. This is a cherry-pick of [3e922208b68563] (check-in: 67484807 user: drh tags: branch-3.8.6)
2014-08-15
16:13
Fix compiler warnings on WinCE. (check-in: 28a379fc user: drh tags: trunk)
16:10
Merge the 3.8.6 changes into the apple-osx branch. (check-in: b91fcb3b user: drh tags: apple-osx)
15:46
Merge the 3.8.6 release into the threads branch. (check-in: 05807c41 user: drh tags: threads)
15:10
Update the sessions branch for version 3.8.6. (check-in: 2acbeac1 user: drh tags: sessions)
11:46
Version 3.8.6 (check-in: 9491ba7d user: drh tags: trunk, release, version-3.8.6)
2014-08-14
19:53
Fix an assert that can fail if the database file is corrupted. (check-in: 3f45b819 user: dan tags: trunk)

Changes to VERSION.

1


1
-
+
3.8.6
3.8.6.1

Changes to configure.

1
2
3

4
5
6
7
8
9
10
1
2

3
4
5
6
7
8
9
10


-
+







#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.62 for sqlite 3.8.6.
# Generated by GNU Autoconf 2.62 for sqlite 3.8.6.1.
#
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
## --------------------- ##
## M4sh Initialization.  ##
739
740
741
742
743
744
745
746
747


748
749
750
751
752
753
754
739
740
741
742
743
744
745


746
747
748
749
750
751
752
753
754







-
-
+
+







MFLAGS=
MAKEFLAGS=
SHELL=${CONFIG_SHELL-/bin/sh}

# Identity of this package.
PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite'
PACKAGE_VERSION='3.8.6'
PACKAGE_STRING='sqlite 3.8.6'
PACKAGE_VERSION='3.8.6.1'
PACKAGE_STRING='sqlite 3.8.6.1'
PACKAGE_BUGREPORT=''

# Factoring default headers for most tests.
ac_includes_default="\
#include <stdio.h>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
1479
1480
1481
1482
1483
1484
1485
1486

1487
1488
1489
1490
1491
1492
1493
1479
1480
1481
1482
1483
1484
1485

1486
1487
1488
1489
1490
1491
1492
1493







-
+







#
# Report the --help message.
#
if test "$ac_init_help" = "long"; then
  # Omit some internal or obsolete options to make the list less imposing.
  # This message is too long to be a string in the A/UX 3.1 sh.
  cat <<_ACEOF
\`configure' configures sqlite 3.8.6 to adapt to many kinds of systems.
\`configure' configures sqlite 3.8.6.1 to adapt to many kinds of systems.

Usage: $0 [OPTION]... [VAR=VALUE]...

To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.  See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.
1544
1545
1546
1547
1548
1549
1550
1551

1552
1553
1554
1555
1556
1557
1558
1544
1545
1546
1547
1548
1549
1550

1551
1552
1553
1554
1555
1556
1557
1558







-
+







  --build=BUILD     configure for building on BUILD [guessed]
  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
_ACEOF
fi

if test -n "$ac_init_help"; then
  case $ac_init_help in
     short | recursive ) echo "Configuration of sqlite 3.8.6:";;
     short | recursive ) echo "Configuration of sqlite 3.8.6.1:";;
   esac
  cat <<\_ACEOF

Optional Features:
  --disable-option-checking  ignore unrecognized --enable/--with options
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
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
1686
1687
1688
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
1686
1687
1688







-
+













-
+







    cd "$ac_pwd" || { ac_status=$?; break; }
  done
fi

test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
  cat <<\_ACEOF
sqlite configure 3.8.6
sqlite configure 3.8.6.1
generated by GNU Autoconf 2.62

Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
  exit
fi
cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.

It was created by sqlite $as_me 3.8.6, which was
It was created by sqlite $as_me 3.8.6.1, which was
generated by GNU Autoconf 2.62.  Invocation command line was

  $ $0 $@

_ACEOF
exec 5>>config.log
{
14017
14018
14019
14020
14021
14022
14023
14024

14025
14026
14027
14028
14029
14030
14031
14017
14018
14019
14020
14021
14022
14023

14024
14025
14026
14027
14028
14029
14030
14031







-
+








exec 6>&1

# Save the log message, to keep $[0] and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by sqlite $as_me 3.8.6, which was
This file was extended by sqlite $as_me 3.8.6.1, which was
generated by GNU Autoconf 2.62.  Invocation command line was

  CONFIG_FILES    = $CONFIG_FILES
  CONFIG_HEADERS  = $CONFIG_HEADERS
  CONFIG_LINKS    = $CONFIG_LINKS
  CONFIG_COMMANDS = $CONFIG_COMMANDS
  $ $0 $@
14070
14071
14072
14073
14074
14075
14076
14077

14078
14079
14080
14081
14082
14083
14084
14070
14071
14072
14073
14074
14075
14076

14077
14078
14079
14080
14081
14082
14083
14084







-
+







$config_commands

Report bugs to <bug-autoconf@gnu.org>."

_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_version="\\
sqlite config.status 3.8.6
sqlite config.status 3.8.6.1
configured by $0, generated by GNU Autoconf 2.62,
  with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"

Copyright (C) 2008 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."

Changes to ext/fts3/fts3.c.

953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971




972


973
974
975
976

977
978
979
980
981
982
983
953
954
955
956
957
958
959

960
961
962
963
964
965
966
967
968
969
970
971
972
973
974

975
976
977
978
979
980
981
982
983
984
985
986
987
988







-











+
+
+
+
-
+
+




+







    for(p=zParam; *p; p++){
      if( *p==',' ) nIndex++;
    }
  }

  aIndex = sqlite3_malloc(sizeof(struct Fts3Index) * nIndex);
  *apIndex = aIndex;
  *pnIndex = nIndex;
  if( !aIndex ){
    return SQLITE_NOMEM;
  }

  memset(aIndex, 0, sizeof(struct Fts3Index) * nIndex);
  if( zParam ){
    const char *p = zParam;
    int i;
    for(i=1; i<nIndex; i++){
      int nPrefix;
      if( fts3GobbleInt(&p, &nPrefix) ) return SQLITE_ERROR;
      if( nPrefix<=0 ){
        nIndex--;
        i--;
      }else{
      aIndex[i].nPrefix = nPrefix;
        aIndex[i].nPrefix = nPrefix;
      }
      p++;
    }
  }

  *pnIndex = nIndex;
  return SQLITE_OK;
}

/*
** This function is called when initializing an FTS4 table that uses the
** content=xxx option. It determines the number of and names of the columns
** of the new FTS4 table.
1004
1005
1006
1007
1008
1009
1010
1011


1012
1013
1014
1015
1016
1017
1018
1019
1020
1021



1022
1023
1024
1025
1026
1027
1028
1009
1010
1011
1012
1013
1014
1015

1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037







-
+
+










+
+
+







*/
static int fts3ContentColumns(
  sqlite3 *db,                    /* Database handle */
  const char *zDb,                /* Name of db (i.e. "main", "temp" etc.) */
  const char *zTbl,               /* Name of content table */
  const char ***pazCol,           /* OUT: Malloc'd array of column names */
  int *pnCol,                     /* OUT: Size of array *pazCol */
  int *pnStr                      /* OUT: Bytes of string content */
  int *pnStr,                     /* OUT: Bytes of string content */
  char **pzErr                    /* OUT: error message */
){
  int rc = SQLITE_OK;             /* Return code */
  char *zSql;                     /* "SELECT *" statement on zTbl */  
  sqlite3_stmt *pStmt = 0;        /* Compiled version of zSql */

  zSql = sqlite3_mprintf("SELECT * FROM %Q.%Q", zDb, zTbl);
  if( !zSql ){
    rc = SQLITE_NOMEM;
  }else{
    rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
    if( rc!=SQLITE_OK ){
      *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
    }
  }
  sqlite3_free(zSql);

  if( rc==SQLITE_OK ){
    const char **azCol;           /* Output array */
    int nStr = 0;                 /* Size of all column names (incl. 0x00) */
    int nCol;                     /* Number of table columns */
1266
1267
1268
1269
1270
1271
1272
1273

1274
1275
1276
1277
1278
1279
1280
1275
1276
1277
1278
1279
1280
1281

1282
1283
1284
1285
1286
1287
1288
1289







-
+







    sqlite3_free(zCompress); 
    sqlite3_free(zUncompress); 
    zCompress = 0;
    zUncompress = 0;
    if( nCol==0 ){
      sqlite3_free((void*)aCol); 
      aCol = 0;
      rc = fts3ContentColumns(db, argv[1], zContent, &aCol, &nCol, &nString);
      rc = fts3ContentColumns(db, argv[1], zContent,&aCol,&nCol,&nString,pzErr);

      /* If a languageid= option was specified, remove the language id
      ** column from the aCol[] array. */ 
      if( rc==SQLITE_OK && zLanguageid ){
        int j;
        for(j=0; j<nCol; j++){
          if( sqlite3_stricmp(zLanguageid, aCol[j])==0 ){
2757
2758
2759
2760
2761
2762
2763
2764

2765
2766
2767
2768
2769
2770
2771
2766
2767
2768
2769
2770
2771
2772

2773
2774
2775
2776
2777
2778
2779
2780







-
+







  ** for the pending-terms. If this is a scan, then this call must be being
  ** made by an fts4aux module, not an FTS table. In this case calling
  ** Fts3SegReaderPending might segfault, as the data structures used by 
  ** fts4aux are not completely populated. So it's easiest to filter these
  ** calls out here.  */
  if( iLevel<0 && p->aIndex ){
    Fts3SegReader *pSeg = 0;
    rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix, &pSeg);
    rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix||isScan, &pSeg);
    if( rc==SQLITE_OK && pSeg ){
      rc = fts3SegReaderCursorAppend(pCsr, pSeg);
    }
  }

  if( iLevel!=FTS3_SEGCURSOR_PENDING ){
    if( rc==SQLITE_OK ){
3231
3232
3233
3234
3235
3236
3237
3238

3239
3240
3241
3242
3243
3244
3245
3240
3241
3242
3243
3244
3245
3246

3247
3248
3249
3250
3251
3252
3253
3254







-
+







    /* This call is a request for the "docid" column. Since "docid" is an 
    ** alias for "rowid", use the xRowid() method to obtain the value.
    */
    sqlite3_result_int64(pCtx, pCsr->iPrevId);
  }else if( iCol==p->nColumn ){
    /* The extra column whose name is the same as the table.
    ** Return a blob which is a pointer to the cursor.  */
    sqlite3_result_blob(pCtx, &pCsr, sizeof(pCsr), SQLITE_TRANSIENT);
    sqlite3_result_pointer(pCtx, pCsr);
  }else if( iCol==p->nColumn+2 && pCsr->pExpr ){
    sqlite3_result_int64(pCtx, pCsr->iLangid);
  }else{
    /* The requested column is either a user column (one that contains 
    ** indexed data), or the language-id column.  */
    rc = fts3CursorSeek(0, pCsr);

3423
3424
3425
3426
3427
3428
3429
3430

3431
3432
3433

3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3432
3433
3434
3435
3436
3437
3438

3439



3440
3441
3442
3443
3444
3445

3446
3447
3448
3449
3450
3451
3452







-
+
-
-
-
+





-







*/
static int fts3FunctionArg(
  sqlite3_context *pContext,      /* SQL function call context */
  const char *zFunc,              /* Function name */
  sqlite3_value *pVal,            /* argv[0] passed to function */
  Fts3Cursor **ppCsr              /* OUT: Store cursor handle here */
){
  Fts3Cursor *pRet;
  Fts3Cursor *pRet = (Fts3Cursor*)sqlite3_value_pointer(pVal);
  if( sqlite3_value_type(pVal)!=SQLITE_BLOB 
   || sqlite3_value_bytes(pVal)!=sizeof(Fts3Cursor *)
  ){
  if( pRet==0 ){
    char *zErr = sqlite3_mprintf("illegal first argument to %s", zFunc);
    sqlite3_result_error(pContext, zErr, -1);
    sqlite3_free(zErr);
    return SQLITE_ERROR;
  }
  memcpy(&pRet, sqlite3_value_blob(pVal), sizeof(Fts3Cursor *));
  *ppCsr = pRet;
  return SQLITE_OK;
}

/*
** Implementation of the snippet() function for FTS3
*/

Changes to ext/fts3/fts3_write.c.

322
323
324
325
326
327
328
329

330
331
332
333
334
335
336
322
323
324
325
326
327
328

329
330
331
332
333
334
335
336







-
+







/* 21 */  "SELECT size FROM %Q.'%q_docsize' WHERE docid=?",
/* 22 */  "SELECT value FROM %Q.'%q_stat' WHERE id=?",
/* 23 */  "REPLACE INTO %Q.'%q_stat' VALUES(?,?)",
/* 24 */  "",
/* 25 */  "",

/* 26 */ "DELETE FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?",
/* 27 */ "SELECT DISTINCT level / (1024 * ?) FROM %Q.'%q_segdir'",
/* 27 */ "SELECT ? UNION SELECT level / (1024 * ?) FROM %Q.'%q_segdir'",

/* This statement is used to determine which level to read the input from
** when performing an incremental merge. It returns the absolute level number
** of the oldest level in the db that contains at least ? segments. Or,
** if no level in the FTS index contains more than ? segments, the statement
** returns zero rows.  */
/* 28 */ "SELECT level FROM %Q.'%q_segdir' GROUP BY level HAVING count(*)>=?"
3437
3438
3439
3440
3441
3442
3443
3444


3445
3446
3447
3448
3449
3450
3451
3437
3438
3439
3440
3441
3442
3443

3444
3445
3446
3447
3448
3449
3450
3451
3452







-
+
+







  int bSeenDone = 0;
  int rc;
  sqlite3_stmt *pAllLangid = 0;

  rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
  if( rc==SQLITE_OK ){
    int rc2;
    sqlite3_bind_int(pAllLangid, 1, p->nIndex);
    sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid);
    sqlite3_bind_int(pAllLangid, 2, p->nIndex);
    while( sqlite3_step(pAllLangid)==SQLITE_ROW ){
      int i;
      int iLangid = sqlite3_column_int(pAllLangid, 0);
      for(i=0; rc==SQLITE_OK && i<p->nIndex; i++){
        rc = fts3SegmentMerge(p, iLangid, i, FTS3_SEGCURSOR_ALL);
        if( rc==SQLITE_DONE ){
          bSeenDone = 1;
4769
4770
4771
4772
4773
4774
4775
4776

4777
4778
4779
4780
4781
4782
4783
4770
4771
4772
4773
4774
4775
4776

4777
4778
4779
4780
4781
4782
4783
4784







-
+







  i = pHint->n-2;
  while( i>0 && (pHint->a[i-1] & 0x80) ) i--;
  while( i>0 && (pHint->a[i-1] & 0x80) ) i--;

  pHint->n = i;
  i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel);
  i += fts3GetVarint32(&pHint->a[i], pnInput);
  if( i!=nHint ) return SQLITE_CORRUPT_VTAB;
  if( i!=nHint ) return FTS_CORRUPT_VTAB;

  return SQLITE_OK;
}


/*
** Attempt an incremental merge that writes nMerge leaf blocks.
5137
5138
5139
5140
5141
5142
5143
5144


5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5138
5139
5140
5141
5142
5143
5144

5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158

5159
5160
5161
5162
5163
5164
5165







-
+
+












-







  u64 cksum2 = 0;                 /* Checksum based on %_content contents */
  sqlite3_stmt *pAllLangid = 0;   /* Statement to return all language-ids */

  /* This block calculates the checksum according to the FTS index. */
  rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
  if( rc==SQLITE_OK ){
    int rc2;
    sqlite3_bind_int(pAllLangid, 1, p->nIndex);
    sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid);
    sqlite3_bind_int(pAllLangid, 2, p->nIndex);
    while( rc==SQLITE_OK && sqlite3_step(pAllLangid)==SQLITE_ROW ){
      int iLangid = sqlite3_column_int(pAllLangid, 0);
      int i;
      for(i=0; i<p->nIndex; i++){
        cksum1 = cksum1 ^ fts3ChecksumIndex(p, iLangid, i, &rc);
      }
    }
    rc2 = sqlite3_reset(pAllLangid);
    if( rc==SQLITE_OK ) rc = rc2;
  }

  /* This block calculates the checksum according to the %_content table */
  rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
  if( rc==SQLITE_OK ){
    sqlite3_tokenizer_module const *pModule = p->pTokenizer->pModule;
    sqlite3_stmt *pStmt = 0;
    char *zSql;
   
    zSql = sqlite3_mprintf("SELECT %s" , p->zReadExprlist);
    if( !zSql ){
5247
5248
5249
5250
5251
5252
5253
5254

5255
5256
5257
5258
5259
5260
5261
5248
5249
5250
5251
5252
5253
5254

5255
5256
5257
5258
5259
5260
5261
5262







-
+







*/
static int fts3DoIntegrityCheck(
  Fts3Table *p                    /* FTS3 table handle */
){
  int rc;
  int bOk = 0;
  rc = fts3IntegrityCheck(p, &bOk);
  if( rc==SQLITE_OK && bOk==0 ) rc = SQLITE_CORRUPT_VTAB;
  if( rc==SQLITE_OK && bOk==0 ) rc = FTS_CORRUPT_VTAB;
  return rc;
}

/*
** Handle a 'special' INSERT of the form:
**
**   "INSERT INTO tbl(tbl) VALUES(<expr>)"

Changes to src/btree.c.

3963
3964
3965
3966
3967
3968
3969

3970

3971
3972
3973
3974
3975
3976
3977
3963
3964
3965
3966
3967
3968
3969
3970

3971
3972
3973
3974
3975
3976
3977
3978







+
-
+







  unsigned char *aPayload;
  int rc = SQLITE_OK;
  u32 nKey;
  int iIdx = 0;
  MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */
  BtShared *pBt = pCur->pBt;                  /* Btree this cursor belongs to */
#ifdef SQLITE_DIRECT_OVERFLOW_READ
  unsigned char * const pBufStart = pBuf;
  int bEnd;                                   /* True if reading to end of data */
  int bEnd;                                 /* True if reading to end of data */
#endif

  assert( pPage );
  assert( pCur->eState==CURSOR_VALID );
  assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
  assert( cursorHoldsMutex(pCur) );
  assert( eOp!=2 || offset==0 );      /* Always start from beginning for eOp==2 */
4090
4091
4092
4093
4094
4095
4096

4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107

4108
4109
4110

4111
4112
4113
4114
4115
4116
4117
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121







+











+



+







        **
        **   1) this is a read operation, and 
        **   2) data is required from the start of this overflow page, and
        **   3) the database is file-backed, and
        **   4) there is no open write-transaction, and
        **   5) the database is not a WAL database,
        **   6) all data from the page is being read.
        **   7) at least 4 bytes have already been read into the output buffer 
        **
        ** then data can be read directly from the database file into the
        ** output buffer, bypassing the page-cache altogether. This speeds
        ** up loading large records that span many overflow pages.
        */
        if( (eOp&0x01)==0                                      /* (1) */
         && offset==0                                          /* (2) */
         && (bEnd || a==ovflSize)                              /* (6) */
         && pBt->inTransaction==TRANS_READ                     /* (4) */
         && (fd = sqlite3PagerFile(pBt->pPager))->pMethods     /* (3) */
         && pBt->pPage1->aData[19]==0x01                       /* (5) */
         && &pBuf[-4]>=pBufStart                               /* (7) */
        ){
          u8 aSave[4];
          u8 *aWrite = &pBuf[-4];
          assert( aWrite>=pBufStart );                         /* hence (7) */
          memcpy(aSave, aWrite, 4);
          rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1));
          nextPage = get4byte(aWrite);
          memcpy(aWrite, aSave, 4);
        }else
#endif

Changes to src/expr.c.

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
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







-
+
+


-
+













-
+







**
** If a memory allocation error occurs, that fact is recorded in pParse->db
** and the pExpr parameter is returned unchanged.
*/
Expr *sqlite3ExprAddCollateToken(
  Parse *pParse,           /* Parsing context */
  Expr *pExpr,             /* Add the "COLLATE" clause to this expression */
  const Token *pCollName   /* Name of collating sequence */
  const Token *pCollName,  /* Name of collating sequence */
  int dequote              /* True to dequote pCollName */
){
  if( pCollName->n>0 ){
    Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, 1);
    Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote);
    if( pNew ){
      pNew->pLeft = pExpr;
      pNew->flags |= EP_Collate|EP_Skip;
      pExpr = pNew;
    }
  }
  return pExpr;
}
Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){
  Token s;
  assert( zC!=0 );
  s.z = zC;
  s.n = sqlite3Strlen30(s.z);
  return sqlite3ExprAddCollateToken(pParse, pExpr, &s);
  return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0);
}

/*
** Skip over any TK_COLLATE or TK_AS operators and any unlikely()
** or likelihood() function at the root of an expression.
*/
Expr *sqlite3ExprSkipCollate(Expr *pExpr){
1205
1206
1207
1208
1209
1210
1211
















1212

1213
1214
1215



1216
1217
1218
1219
1220
1221
1222
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228

1229



1230
1231
1232
1233
1234
1235
1236
1237
1238
1239







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







    sqlite3DbFree(db, pItem->zSpan);
  }
  sqlite3DbFree(db, pList->a);
  sqlite3DbFree(db, pList);
}

/*
** Return the bitwise-OR of all Expr.flags fields in the given
** ExprList.
*/
u32 sqlite3ExprListFlags(const ExprList *pList){
  int i;
  u32 m = 0;
  if( pList ){
    for(i=0; i<pList->nExpr; i++){
       Expr *pExpr = pList->a[i].pExpr;
       if( pExpr ) m |= pList->a[i].pExpr->flags;
    }
  }
  return m;
}

/*
** These routines are Walker callbacks.  Walker.u.pi is a pointer
** These routines are Walker callbacks used to check expressions to
** to an integer.  These routines are checking an expression to see
** if it is a constant.  Set *Walker.u.pi to 0 if the expression is
** not constant.
** see if they are "constant" for some definition of constant.  The
** Walker.eCode value determines the type of "constant" we are looking
** for.
**
** These callback routines are used to implement the following:
**
**     sqlite3ExprIsConstant()
**     sqlite3ExprIsConstantNotJoin()
**     sqlite3ExprIsConstantOrFunction()
**

Changes to src/fkey.c.

1154
1155
1156
1157
1158
1159
1160
1161
1162


1163
1164

1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177


1178
1179
1180
1181


1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192


1193
1194
1195
1196
1197
1198
1199
1154
1155
1156
1157
1158
1159
1160


1161
1162
1163

1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175


1176
1177
1178
1179


1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190


1191
1192
1193
1194
1195
1196
1197
1198
1199







-
-
+
+

-
+











-
-
+
+


-
-
+
+









-
-
+
+








      /* Create the expression "OLD.zToCol = zFromCol". It is important
      ** that the "OLD.zToCol" term is on the LHS of the = operator, so
      ** that the affinity and collation sequence associated with the
      ** parent table are used for the comparison. */
      pEq = sqlite3PExpr(pParse, TK_EQ,
          sqlite3PExpr(pParse, TK_DOT, 
            sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld),
            sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol)
            sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
            sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)
          , 0),
          sqlite3PExpr(pParse, TK_ID, 0, 0, &tFromCol)
          sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0)
      , 0);
      pWhere = sqlite3ExprAnd(db, pWhere, pEq);

      /* For ON UPDATE, construct the next term of the WHEN clause.
      ** The final WHEN clause will be like this:
      **
      **    WHEN NOT(old.col1 IS new.col1 AND ... AND old.colN IS new.colN)
      */
      if( pChanges ){
        pEq = sqlite3PExpr(pParse, TK_IS,
            sqlite3PExpr(pParse, TK_DOT, 
              sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld),
              sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol),
              sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
              sqlite3ExprAlloc(db, TK_ID, &tToCol, 0),
              0),
            sqlite3PExpr(pParse, TK_DOT, 
              sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew),
              sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol),
              sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
              sqlite3ExprAlloc(db, TK_ID, &tToCol, 0),
              0),
            0);
        pWhen = sqlite3ExprAnd(db, pWhen, pEq);
      }
  
      if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){
        Expr *pNew;
        if( action==OE_Cascade ){
          pNew = sqlite3PExpr(pParse, TK_DOT, 
            sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew),
            sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol)
            sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
            sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)
          , 0);
        }else if( action==OE_SetDflt ){
          Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt;
          if( pDflt ){
            pNew = sqlite3ExprDup(db, pDflt, 0);
          }else{
            pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0);
1232
1233
1234
1235
1236
1237
1238
1239

1240
1241
1242
1243

1244
1245

1246
1247
1248
1249
1250
1251
1252
1232
1233
1234
1235
1236
1237
1238

1239
1240
1241
1242

1243


1244
1245
1246
1247
1248
1249
1250
1251







-
+



-
+
-
-
+







    /* Disable lookaside memory allocation */
    enableLookaside = db->lookaside.bEnabled;
    db->lookaside.bEnabled = 0;

    pTrigger = (Trigger *)sqlite3DbMallocZero(db, 
        sizeof(Trigger) +         /* struct Trigger */
        sizeof(TriggerStep) +     /* Single step in trigger program */
        nFrom + 1                 /* Space for pStep->target.z */
        nFrom + 1                 /* Space for pStep->zTarget */
    );
    if( pTrigger ){
      pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1];
      pStep->target.z = (char *)&pStep[1];
      pStep->zTarget = (char *)&pStep[1];
      pStep->target.n = nFrom;
      memcpy((char *)pStep->target.z, zFrom, nFrom);
      memcpy((char *)pStep->zTarget, zFrom, nFrom);
  
      pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
      pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE);
      pStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
      if( pWhen ){
        pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0, 0);
        pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE);

Changes to src/pager.c.

1952
1953
1954
1955
1956
1957
1958








1959
1960
1961
1962
1963
1964
1965
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973







+
+
+
+
+
+
+
+







      assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY );
      sqlite3OsClose(pPager->jfd);
    }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){
      if( pPager->journalOff==0 ){
        rc = SQLITE_OK;
      }else{
        rc = sqlite3OsTruncate(pPager->jfd, 0);
        if( rc==SQLITE_OK && pPager->fullSync ){
          /* Make sure the new file size is written into the inode right away.
          ** Otherwise the journal might resurrect following a power loss and
          ** cause the last transaction to roll back.  See
          ** https://bugzilla.mozilla.org/show_bug.cgi?id=1072773
          */
          rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags);
        }
      }
      pPager->journalOff = 0;
    }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST
      || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL)
    ){
      rc = zeroJournalHdr(pPager, hasMaster);
      pPager->journalOff = 0;

Changes to src/parse.y.

829
830
831
832
833
834
835
836

837
838
839
840
841
842
843
829
830
831
832
833
834
835

836
837
838
839
840
841
842
843







-
+







  }else{
    spanExpr(&A, pParse, TK_VARIABLE, &X);
    sqlite3ExprAssignVarNumber(pParse, A.pExpr);
  }
  spanSet(&A, &X, &X);
}
expr(A) ::= expr(E) COLLATE ids(C). {
  A.pExpr = sqlite3ExprAddCollateToken(pParse, E.pExpr, &C);
  A.pExpr = sqlite3ExprAddCollateToken(pParse, E.pExpr, &C, 1);
  A.zStart = E.zStart;
  A.zEnd = &C.z[C.n];
}
%ifndef SQLITE_OMIT_CAST
expr(A) ::= CAST(X) LP expr(E) AS typetoken(T) RP(Y). {
  A.pExpr = sqlite3PExpr(pParse, TK_CAST, E.pExpr, 0, &T);
  spanSet(&A,&X,&Y);
1175
1176
1177
1178
1179
1180
1181
1182

1183
1184
1185
1186
1187
1188
1189

1190
1191
1192
1193
1194
1195
1196
1175
1176
1177
1178
1179
1180
1181

1182
1183
1184
1185
1186
1187
1188

1189
1190
1191
1192
1193
1194
1195
1196







-
+






-
+







%destructor idxlist {sqlite3ExprListDelete(pParse->db, $$);}
%type idxlist_opt {ExprList*}
%destructor idxlist_opt {sqlite3ExprListDelete(pParse->db, $$);}

idxlist_opt(A) ::= .                         {A = 0;}
idxlist_opt(A) ::= LP idxlist(X) RP.         {A = X;}
idxlist(A) ::= idxlist(X) COMMA nm(Y) collate(C) sortorder(Z).  {
  Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C);
  Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C, 1);
  A = sqlite3ExprListAppend(pParse,X, p);
  sqlite3ExprListSetName(pParse,A,&Y,1);
  sqlite3ExprListCheckLength(pParse, A, "index");
  if( A ) A->a[A->nExpr-1].sortOrder = (u8)Z;
}
idxlist(A) ::= nm(Y) collate(C) sortorder(Z). {
  Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C);
  Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C, 1);
  A = sqlite3ExprListAppend(pParse,0, p);
  sqlite3ExprListSetName(pParse, A, &Y, 1);
  sqlite3ExprListCheckLength(pParse, A, "index");
  if( A ) A->a[A->nExpr-1].sortOrder = (u8)Z;
}

%type collate {Token}

Changes to src/prepare.c.

63
64
65
66
67
68
69
70

71
72
73
74
75
76
77
63
64
65
66
67
68
69

70
71
72
73
74
75
76
77







-
+







    return 1;
  }

  assert( iDb>=0 && iDb<db->nDb );
  if( argv==0 ) return 0;   /* Might happen if EMPTY_RESULT_CALLBACKS are on */
  if( argv[1]==0 ){
    corruptSchema(pData, argv[0], 0);
  }else if( argv[2] && argv[2][0] ){
  }else if( argv[2] && sqlite3_strnicmp(argv[2],"create ",7)==0 ){
    /* Call the parser to process a CREATE TABLE, INDEX or VIEW.
    ** But because db->init.busy is set to 1, no VDBE code is generated
    ** or executed.  All the parser does is build the internal data
    ** structures that describe the table, index, or view.
    */
    int rc;
    sqlite3_stmt *pStmt;
94
95
96
97
98
99
100
101
102


103
104
105
106
107
108
109
94
95
96
97
98
99
100


101
102
103
104
105
106
107
108
109







-
-
+
+







          db->mallocFailed = 1;
        }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){
          corruptSchema(pData, argv[0], sqlite3_errmsg(db));
        }
      }
    }
    sqlite3_finalize(pStmt);
  }else if( argv[0]==0 ){
    corruptSchema(pData, 0, 0);
  }else if( argv[0]==0 || (argv[2]!=0 && argv[2][0]!=0) ){
    corruptSchema(pData, argv[0], 0);
  }else{
    /* If the SQL column is blank it means this is an index that
    ** was created to be the PRIMARY KEY or to fulfill a UNIQUE
    ** constraint for a CREATE TABLE.  The index should have already
    ** been created when we processed the CREATE TABLE.  All we have
    ** to do here is record the root page number for that index.
    */

Changes to src/printf.c.

253
254
255
256
257
258
259
260

261
262
263

264
265

266
267


268

269
270
271
272
273
274
275
276
277
278
279
280



281

282
283

284
285


286
287
288
289
290
291
292
253
254
255
256
257
258
259

260
261
262
263
264
265

266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282

283
284
285
286
287
288
289

290
291
292
293
294
295
296
297
298
299
300
301







-
+



+

-
+


+
+

+










-

+
+
+

+

-
+


+
+







      if( bArgList ){
        width = (int)getIntArg(pArgList);
      }else{
        width = va_arg(ap,int);
      }
      if( width<0 ){
        flag_leftjustify = 1;
        width = -width;
        width = width >= -2147483647 ? -width : 0;
      }
      c = *++fmt;
    }else{
      unsigned wx = 0;
      while( c>='0' && c<='9' ){
        width = width*10 + c - '0';
        wx = wx*10 + c - '0';
        c = *++fmt;
      }
      testcase( wx>0x7fffffff );
      width = wx & 0x7fffffff;
    }

    /* Get the precision */
    if( c=='.' ){
      precision = 0;
      c = *++fmt;
      if( c=='*' ){
        if( bArgList ){
          precision = (int)getIntArg(pArgList);
        }else{
          precision = va_arg(ap,int);
        }
        if( precision<0 ) precision = -precision;
        c = *++fmt;
        if( precision<0 ){
          precision = precision >= -2147483647 ? -precision : -1;
        }
      }else{
        unsigned px = 0;
        while( c>='0' && c<='9' ){
          precision = precision*10 + c - '0';
          px = px*10 + c - '0';
          c = *++fmt;
        }
        testcase( px>0x7fffffff );
        precision = px & 0x7fffffff;
      }
    }else{
      precision = -1;
    }
    /* Get the conversion type modifier */
    if( c=='l' ){
      flag_long = 1;
443
444
445
446
447
448
449

450

451
452
453
454
455
456
457
452
453
454
455
456
457
458
459

460
461
462
463
464
465
466
467







+
-
+







          prefix = '-';
        }else{
          if( flag_plussign )          prefix = '+';
          else if( flag_blanksign )    prefix = ' ';
          else                         prefix = 0;
        }
        if( xtype==etGENERIC && precision>0 ) precision--;
        testcase( precision>0xfff );
        for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1){}
        for(idx=precision&0xfff, rounder=0.5; idx>0; idx--, rounder*=0.1){}
        if( xtype==etFLOAT ) realvalue += rounder;
        /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
        exp = 0;
        if( sqlite3IsNaN((double)realvalue) ){
          bufpt = "NaN";
          length = 3;
          break;
498
499
500
501
502
503
504
505
506



507
508
509
510
511
512
513
508
509
510
511
512
513
514


515
516
517
518
519
520
521
522
523
524







-
-
+
+
+







          flag_rtz = flag_altform2;
        }
        if( xtype==etEXP ){
          e2 = 0;
        }else{
          e2 = exp;
        }
        if( MAX(e2,0)+precision+width > etBUFSIZE - 15 ){
          bufpt = zExtra = sqlite3Malloc( MAX(e2,0)+precision+width+15 );
        if( MAX(e2,0)+(i64)precision+(i64)width > etBUFSIZE - 15 ){
          bufpt = zExtra 
              = sqlite3Malloc( MAX(e2,0)+(i64)precision+(i64)width+15 );
          if( bufpt==0 ){
            setStrAccumError(pAccum, STRACCUM_NOMEM);
            return;
          }
        }
        zOut = bufpt;
        nsd = 16 + flag_altform2*10;
725
726
727
728
729
730
731
732

733
734
735
736
737
738
739
736
737
738
739
740
741
742

743
744
745
746
747
748
749
750







-
+







** able to accept at least N more bytes of text.
**
** Return the number of bytes of text that StrAccum is able to accept
** after the attempted enlargement.  The value returned might be zero.
*/
static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
  char *zNew;
  assert( p->nChar+N >= p->nAlloc ); /* Only called if really needed */
  assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */
  if( p->accError ){
    testcase(p->accError==STRACCUM_TOOBIG);
    testcase(p->accError==STRACCUM_NOMEM);
    return 0;
  }
  if( !p->useMalloc ){
    N = p->nAlloc - p->nChar - 1;
768
769
770
771
772
773
774

775



776
777
778
779
780
781
782
779
780
781
782
783
784
785
786

787
788
789
790
791
792
793
794
795
796







+
-
+
+
+







  return N;
}

/*
** Append N space characters to the given string buffer.
*/
void sqlite3AppendSpace(StrAccum *p, int N){
  testcase( p->nChar + (i64)N > 0x7fffffff );
  if( p->nChar+N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ) return;
  if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){
    return;
  }
  while( (N--)>0 ) p->zText[p->nChar++] = ' ';
}

/*
** The StrAccum "p" is not large enough to accept N new bytes of z[].
** So enlarge if first, then do the append.
**

Changes to src/select.c.

2524
2525
2526
2527
2528
2529
2530
2531

2532
2533
2534
2535
2536
2537
2538
2524
2525
2526
2527
2528
2529
2530

2531
2532
2533
2534
2535
2536
2537
2538







-
+







    ** starting at pDest->iSdst.  Then the co-routine yields.
    */
    case SRT_Coroutine: {
      if( pDest->iSdst==0 ){
        pDest->iSdst = sqlite3GetTempRange(pParse, pIn->nSdst);
        pDest->nSdst = pIn->nSdst;
      }
      sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pDest->nSdst);
      sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pIn->nSdst);
      sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
      break;
    }

    /* If none of the above, then the result destination must be
    ** SRT_Output.  This routine is never called with any other
    ** destination other than the ones handled above or SRT_Output.

Changes to src/sqlite.h.in.

4186
4187
4188
4189
4190
4191
4192

4193
4194
4195
4196
4197
4198
4199
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200







+







*/
const void *sqlite3_value_blob(sqlite3_value*);
int sqlite3_value_bytes(sqlite3_value*);
int sqlite3_value_bytes16(sqlite3_value*);
double sqlite3_value_double(sqlite3_value*);
int sqlite3_value_int(sqlite3_value*);
sqlite3_int64 sqlite3_value_int64(sqlite3_value*);
void *sqlite3_value_pointer(sqlite3_value*);
const unsigned char *sqlite3_value_text(sqlite3_value*);
const void *sqlite3_value_text16(sqlite3_value*);
const void *sqlite3_value_text16le(sqlite3_value*);
const void *sqlite3_value_text16be(sqlite3_value*);
int sqlite3_value_type(sqlite3_value*);
int sqlite3_value_numeric_type(sqlite3_value*);

4454
4455
4456
4457
4458
4459
4460

4461
4462
4463
4464
4465
4466
4467
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469







+







void sqlite3_result_error16(sqlite3_context*, const void*, int);
void sqlite3_result_error_toobig(sqlite3_context*);
void sqlite3_result_error_nomem(sqlite3_context*);
void sqlite3_result_error_code(sqlite3_context*, int);
void sqlite3_result_int(sqlite3_context*, int);
void sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
void sqlite3_result_null(sqlite3_context*);
void sqlite3_result_pointer(sqlite3_context*, void*);
void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
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_zeroblob(sqlite3_context*, int n);

5494
5495
5496
5497
5498
5499
5500
5501

5502
5503
5504
5505
5506
5507
5508
5496
5497
5498
5499
5500
5501
5502

5503
5504
5505
5506
5507
5508
5509
5510







-
+







** take care that any prior string is freed by a call to [sqlite3_free()]
** prior to assigning a new string to zErrMsg.  ^After the error message
** is delivered up to the client application, the string will be automatically
** freed by sqlite3_free() and the zErrMsg field will be zeroed.
*/
struct sqlite3_vtab {
  const sqlite3_module *pModule;  /* The module for this virtual table */
  int nRef;                       /* NO LONGER USED */
  int nRef;                       /* Number of open cursors */
  char *zErrMsg;                  /* Error message from sqlite3_mprintf() */
  /* Virtual table implementations will typically add additional fields */
};

/*
** CAPI3REF: Virtual Table Cursor Object
** KEYWORDS: sqlite3_vtab_cursor {virtual table cursor}

Changes to src/sqliteInt.h.

990
991
992
993
994
995
996

997
998
999
1000
1001
1002
1003
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004







+







    u8 busy;                    /* TRUE if currently initializing */
    u8 orphanTrigger;           /* Last statement is orphaned TEMP trigger */
  } init;
  int nVdbeActive;              /* Number of VDBEs currently running */
  int nVdbeRead;                /* Number of active VDBEs that read or write */
  int nVdbeWrite;               /* Number of active VDBEs that read and write */
  int nVdbeExec;                /* Number of nested calls to VdbeExec() */
  int nVDestroy;                /* Number of active OP_VDestroy operations */
  int nExtension;               /* Number of loaded extensions */
  void **aExtension;            /* Array of shared library handles */
  void (*xTrace)(void*,const char*);        /* Trace function */
  void *pTraceArg;                          /* Argument to the trace function */
  void (*xProfile)(void*,const char*,u64);  /* Profiling function */
  void *pProfileArg;                        /* Argument to profile function */
  void *pCommitArg;                 /* Argument to xCommitCallback() */   
2617
2618
2619
2620
2621
2622
2623
2624

2625
2626
2627
2628
2629
2630
2631
2632

2633
2634
2635
2636
2637

2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650


2651
2652
2653
2654
2655
2656
2657
2618
2619
2620
2621
2622
2623
2624

2625
2626
2627
2628
2629
2630
2631
2632

2633
2634
2635
2636
2637

2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649


2650
2651
2652
2653
2654
2655
2656
2657
2658







-
+







-
+




-
+











-
-
+
+







 * "SELECT" statement. The meanings of the other members is determined by the 
 * value of "op" as follows:
 *
 * (op == TK_INSERT)
 * orconf    -> stores the ON CONFLICT algorithm
 * pSelect   -> If this is an INSERT INTO ... SELECT ... statement, then
 *              this stores a pointer to the SELECT statement. Otherwise NULL.
 * target    -> A token holding the quoted name of the table to insert into.
 * zTarget   -> Dequoted name of the table to insert into.
 * pExprList -> If this is an INSERT INTO ... VALUES ... statement, then
 *              this stores values to be inserted. Otherwise NULL.
 * pIdList   -> If this is an INSERT INTO ... (<column-names>) VALUES ... 
 *              statement, then this stores the column-names to be
 *              inserted into.
 *
 * (op == TK_DELETE)
 * target    -> A token holding the quoted name of the table to delete from.
 * zTarget   -> Dequoted name of the table to delete from.
 * pWhere    -> The WHERE clause of the DELETE statement if one is specified.
 *              Otherwise NULL.
 * 
 * (op == TK_UPDATE)
 * target    -> A token holding the quoted name of the table to update rows of.
 * zTarget   -> Dequoted name of the table to update.
 * pWhere    -> The WHERE clause of the UPDATE statement if one is specified.
 *              Otherwise NULL.
 * pExprList -> A list of the columns to update and the expressions to update
 *              them to. See sqlite3Update() documentation of "pChanges"
 *              argument.
 * 
 */
struct TriggerStep {
  u8 op;               /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */
  u8 orconf;           /* OE_Rollback etc. */
  Trigger *pTrig;      /* The trigger that this step is a part of */
  Select *pSelect;     /* SELECT statment or RHS of INSERT INTO .. SELECT ... */
  Token target;        /* Target table for DELETE, UPDATE, INSERT */
  Select *pSelect;     /* SELECT statement or RHS of INSERT INTO SELECT ... */
  char *zTarget;       /* Target table for DELETE, UPDATE, INSERT */
  Expr *pWhere;        /* The WHERE clause for DELETE or UPDATE steps */
  ExprList *pExprList; /* SET clause for UPDATE. */
  IdList *pIdList;     /* Column names for INSERT */
  TriggerStep *pNext;  /* Next in the link-list */
  TriggerStep *pLast;  /* Last element in link-list. Valid for 1st elem only */
};

3348
3349
3350
3351
3352
3353
3354
3355

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

3356
3357
3358
3359
3360
3361
3362
3363







-
+







#endif

const char *sqlite3ErrStr(int);
int sqlite3ReadSchema(Parse *pParse);
CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*);
Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int);
Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
Expr *sqlite3ExprSkipCollate(Expr*);
int sqlite3CheckCollSeq(Parse *, CollSeq *);
int sqlite3CheckObjectName(Parse *, const char *);
void sqlite3VdbeSetChanges(sqlite3 *, int);
int sqlite3AddInt64(i64*,i64);
int sqlite3SubInt64(i64*,i64);

Changes to src/trigger.c.

371
372
373
374
375
376
377
378

379
380
381

382

383
384
385
386
387
388
389
390
371
372
373
374
375
376
377

378
379
380
381
382

383

384
385
386
387
388
389
390







-
+



+
-
+
-







static TriggerStep *triggerStepAllocate(
  sqlite3 *db,                /* Database connection */
  u8 op,                      /* Trigger opcode */
  Token *pName                /* The target name */
){
  TriggerStep *pTriggerStep;

  pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n);
  pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1);
  if( pTriggerStep ){
    char *z = (char*)&pTriggerStep[1];
    memcpy(z, pName->z, pName->n);
    sqlite3Dequote(z);
    pTriggerStep->target.z = z;
    pTriggerStep->zTarget = z;
    pTriggerStep->target.n = pName->n;
    pTriggerStep->op = op;
  }
  return pTriggerStep;
}

/*
** Build a trigger step out of an INSERT statement.  Return a pointer
662
663
664
665
666
667
668
669

670
671
672
673
674
675
676
677
678
679
680
681

682
683
684
685

686
687
688
689


690
691
692

693
694
695
696
697
698
699
662
663
664
665
666
667
668

669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685

686
687
688


689
690
691


692
693
694
695
696
697
698
699







-
+












+



-
+


-
-
+
+

-
-
+







  if( pMask ){
    *pMask = mask;
  }
  return (mask ? pList : 0);
}

/*
** Convert the pStep->target token into a SrcList and return a pointer
** Convert the pStep->zTarget string into a SrcList and return a pointer
** to that SrcList.
**
** This routine adds a specific database name, if needed, to the target when
** forming the SrcList.  This prevents a trigger in one database from
** referring to a target in another database.  An exception is when the
** trigger is in TEMP in which case it can refer to any other database it
** wants.
*/
static SrcList *targetSrcList(
  Parse *pParse,       /* The parsing context */
  TriggerStep *pStep   /* The trigger containing the target token */
){
  sqlite3 *db = pParse->db;
  int iDb;             /* Index of the database to use */
  SrcList *pSrc;       /* SrcList to be returned */

  pSrc = sqlite3SrcListAppend(pParse->db, 0, &pStep->target, 0);
  pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
  if( pSrc ){
    assert( pSrc->nSrc>0 );
    assert( pSrc->a!=0 );
    iDb = sqlite3SchemaToIndex(pParse->db, pStep->pTrig->pSchema);
    pSrc->a[pSrc->nSrc-1].zName = sqlite3DbStrDup(db, pStep->zTarget);
    iDb = sqlite3SchemaToIndex(db, pStep->pTrig->pSchema);
    if( iDb==0 || iDb>=2 ){
      sqlite3 *db = pParse->db;
      assert( iDb<pParse->db->nDb );
      assert( iDb<db->nDb );
      pSrc->a[pSrc->nSrc-1].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName);
    }
  }
  return pSrc;
}

/*

Changes to src/vdbe.c.

1982
1983
1984
1985
1986
1987
1988


1989
1990
1991
1992
1993
1994
1995
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997







+
+







    /* Neither operand is NULL.  Do a comparison. */
    affinity = pOp->p5 & SQLITE_AFF_MASK;
    if( affinity ){
      applyAffinity(pIn1, affinity, encoding);
      applyAffinity(pIn3, affinity, encoding);
      if( db->mallocFailed ) goto no_mem;
    }
    flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
    flags3 = (pIn3->flags & ~MEM_TypeMask) | (flags3 & MEM_TypeMask);

    assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );
    ExpandBlob(pIn1);
    ExpandBlob(pIn3);
    res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
  }
  switch( pOp->opcode ){
2010
2011
2012
2013
2014
2015
2016

2017

2018
2019
2020
2021
2022
2023
2024
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028







+

+







  }else{
    VdbeBranchTaken(res!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
    if( res ){
      pc = pOp->p2-1;
    }
  }
  /* Undo any changes made by applyAffinity() to the input registers. */
  assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) );
  pIn1->flags = (pIn1->flags&~MEM_TypeMask) | (flags1&MEM_TypeMask);
  assert( (pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn) );
  pIn3->flags = (pIn3->flags&~MEM_TypeMask) | (flags3&MEM_TypeMask);
  break;
}

/* Opcode: Permutation * * * P4 *
**
** Set the permutation used by the OP_Compare operator to be the array
2612
2613
2614
2615
2616
2617
2618
2619

2620
2621
2622
2623
2624
2625
2626
2616
2617
2618
2619
2620
2621
2622

2623
2624
2625
2626
2627
2628
2629
2630







-
+







*/
case OP_MakeRecord: {
  u8 *zNewRecord;        /* A buffer to hold the data for the new record */
  Mem *pRec;             /* The new record */
  u64 nData;             /* Number of bytes of data space */
  int nHdr;              /* Number of bytes of header space */
  i64 nByte;             /* Data space required for this record */
  int nZero;             /* Number of zero bytes at the end of the record */
  i64 nZero;             /* Number of zero bytes at the end of the record */
  int nVarint;           /* Number of bytes in a varint */
  u32 serial_type;       /* Type field */
  Mem *pData0;           /* First field to be combined into the record */
  Mem *pLast;            /* Last field of the record */
  int nField;            /* Number of fields in the record */
  char *zAffinity;       /* The affinity string for the record */
  int file_format;       /* File format to use for encoding */
2701
2702
2703
2704
2705
2706
2707
2708

2709
2710
2711
2712
2713
2714
2715
2705
2706
2707
2708
2709
2710
2711

2712
2713
2714
2715
2716
2717
2718
2719







-
+







  }else{
    /* Rare case of a really large header */
    nVarint = sqlite3VarintLen(nHdr);
    nHdr += nVarint;
    if( nVarint<sqlite3VarintLen(nHdr) ) nHdr++;
  }
  nByte = nHdr+nData;
  if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
  if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){
    goto too_big;
  }

  /* Make sure the output register has a buffer large enough to store 
  ** the new record. The output register (pOp->p3) is not allowed to
  ** be one of the input registers (because the following call to
  ** sqlite3VdbeMemGrow() could clobber the value before it is used).
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963

4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4942
4943
4944
4945
4946
4947
4948


4949
4950
4951












4952

4953
4954
4955
4956
4957

4958
4959
4960
4961
4962
4963
4964







-
-



-
-
-
-
-
-
-
-
-
-
-
-

-
+




-







** the last one in the database) then a zero is stored in register P2.
** If AUTOVACUUM is disabled then a zero is stored in register P2.
**
** See also: Clear
*/
case OP_Destroy: {     /* out2-prerelease */
  int iMoved;
  int iCnt;
  Vdbe *pVdbe;
  int iDb;

  assert( p->readOnly==0 );
#ifndef SQLITE_OMIT_VIRTUALTABLE
  iCnt = 0;
  for(pVdbe=db->pVdbe; pVdbe; pVdbe = pVdbe->pNext){
    if( pVdbe->magic==VDBE_MAGIC_RUN && pVdbe->bIsReader 
     && pVdbe->inVtabMethod<2 && pVdbe->pc>=0 
    ){
      iCnt++;
    }
  }
#else
  iCnt = db->nVdbeRead;
#endif
  pOut->flags = MEM_Null;
  if( iCnt>1 ){
  if( db->nVdbeRead > db->nVDestroy+1 ){
    rc = SQLITE_LOCKED;
    p->errorAction = OE_Abort;
  }else{
    iDb = pOp->p3;
    assert( iCnt==1 );
    assert( DbMaskTest(p->btreeMask, iDb) );
    iMoved = 0;  /* Not needed.  Only to silence a warning. */
    rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved);
    pOut->flags = MEM_Int;
    pOut->u.i = iMoved;
#ifndef SQLITE_OMIT_AUTOVACUUM
    if( rc==SQLITE_OK && iMoved!=0 ){
5999
6000
6001
6002
6003
6004
6005
6006

6007
6008

6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024

6025
6026
6027
6028
6029
6030
6031





6032
6033
6034
6035
6036
6037
6038
6039
6040
6041

6042
6043
6044
6045
6046
6047
6048
5988
5989
5990
5991
5992
5993
5994

5995
5996

5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012

6013
6014
6015
6016
6017
6018


6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041







-
+

-
+















-
+





-
-
+
+
+
+
+










+







#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VDestroy P1 * * P4 *
**
** P4 is the name of a virtual table in database P1.  Call the xDestroy method
** of that table.
*/
case OP_VDestroy: {
  p->inVtabMethod = 2;
  db->nVDestroy++;
  rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z);
  p->inVtabMethod = 0;
  db->nVDestroy--;
  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VOpen P1 * * P4 *
**
** P4 is a pointer to a virtual table object, an sqlite3_vtab structure.
** P1 is a cursor number.  This opcode opens a cursor to the virtual
** table and stores that cursor in P1.
*/
case OP_VOpen: {
  VdbeCursor *pCur;
  sqlite3_vtab_cursor *pVtabCursor;
  sqlite3_vtab *pVtab;
  sqlite3_module *pModule;
  const sqlite3_module *pModule;

  assert( p->bIsReader );
  pCur = 0;
  pVtabCursor = 0;
  pVtab = pOp->p4.pVtab->pVtab;
  pModule = (sqlite3_module *)pVtab->pModule;
  assert(pVtab && pModule);
  if( pVtab==0 || NEVER(pVtab->pModule==0) ){
    rc = SQLITE_LOCKED;
    break;
  }
  pModule = pVtab->pModule;
  rc = pModule->xOpen(pVtab, &pVtabCursor);
  sqlite3VtabImportErrmsg(p, pVtab);
  if( SQLITE_OK==rc ){
    /* Initialize sqlite3_vtab_cursor base class */
    pVtabCursor->pVtab = pVtab;

    /* Initialize vdbe cursor object */
    pCur = allocateCursor(p, pOp->p1, 0, -1, 0);
    if( pCur ){
      pCur->pVtabCursor = pVtabCursor;
      pVtab->nRef++;
    }else{
      db->mallocFailed = 1;
      pModule->xClose(pVtabCursor);
    }
  }
  break;
}
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6093
6094
6095
6096
6097
6098
6099

6100

6101
6102
6103
6104
6105
6106
6107







-

-







  {
    res = 0;
    apArg = p->apArg;
    for(i = 0; i<nArg; i++){
      apArg[i] = &pArgc[i+1];
    }

    p->inVtabMethod = 1;
    rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
    p->inVtabMethod = 0;
    sqlite3VtabImportErrmsg(p, pVtab);
    if( rc==SQLITE_OK ){
      res = pModule->xEof(pVtabCursor);
    }
    VdbeBranchTaken(res!=0,2);
    if( res ){
      pc = pOp->p2 - 1;
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6196
6197
6198
6199
6200
6201
6202

6203

6204
6205
6206
6207
6208
6209
6210







-

-








  /* Invoke the xNext() method of the module. There is no way for the
  ** underlying implementation to return an error if one occurs during
  ** xNext(). Instead, if an error occurs, true is returned (indicating that 
  ** data is available) and the error code returned when xColumn or
  ** some other method is next invoked on the save virtual table cursor.
  */
  p->inVtabMethod = 1;
  rc = pModule->xNext(pCur->pVtabCursor);
  p->inVtabMethod = 0;
  sqlite3VtabImportErrmsg(p, pVtab);
  if( rc==SQLITE_OK ){
    res = pModule->xEof(pCur->pVtabCursor);
  }
  VdbeBranchTaken(!res,2);
  if( !res ){
    /* If there is data, jump to P2 */
6282
6283
6284
6285
6286
6287
6288
6289

6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300




6301

6302
6303
6304
6305
6306
6307
6308
6271
6272
6273
6274
6275
6276
6277

6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293

6294
6295
6296
6297
6298
6299
6300
6301







-
+











+
+
+
+
-
+







** is set to the value of the rowid for the row just inserted.
**
** P5 is the error actions (OE_Replace, OE_Fail, OE_Ignore, etc) to
** apply in the case of a constraint failure on an insert or update.
*/
case OP_VUpdate: {
  sqlite3_vtab *pVtab;
  sqlite3_module *pModule;
  const sqlite3_module *pModule;
  int nArg;
  int i;
  sqlite_int64 rowid;
  Mem **apArg;
  Mem *pX;

  assert( pOp->p2==1        || pOp->p5==OE_Fail   || pOp->p5==OE_Rollback 
       || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace
  );
  assert( p->readOnly==0 );
  pVtab = pOp->p4.pVtab->pVtab;
  if( pVtab==0 || NEVER(pVtab->pModule==0) ){
    rc = SQLITE_LOCKED;
    break;
  }
  pModule = (sqlite3_module *)pVtab->pModule;
  pModule = pVtab->pModule;
  nArg = pOp->p2;
  assert( pOp->p4type==P4_VTAB );
  if( ALWAYS(pModule->xUpdate) ){
    u8 vtabOnConflict = db->vtabOnConflict;
    apArg = p->apArg;
    pX = &aMem[pOp->p3];
    for(i=0; i<nArg; i++){

Changes to src/vdbeInt.h.

163
164
165
166
167
168
169

170
171
172
173
174
175
176
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177







+







struct Mem {
  sqlite3 *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 */
    void *pPtr;         /* Pointer when flags==MEM_Ptr|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;
  int n;              /* Number of characters in string value, excluding '\0' */
  u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
  u8  enc;            /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
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
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







+















-
+









/* 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_Ptr       0x8000   /* u.pPtr is valid if type==SQLITE_NULL */
#define MEM_Term      0x0200   /* String rep is nul terminated */
#define MEM_Dyn       0x0400   /* Need to call Mem.xDel() on Mem.z */
#define MEM_Static    0x0800   /* Mem.z points to a static string */
#define MEM_Ephem     0x1000   /* Mem.z points to an ephemeral string */
#define MEM_Agg       0x2000   /* Mem.z points to an agg function context */
#define MEM_Zero      0x4000   /* Mem.i contains count of 0s appended to blob */
#ifdef SQLITE_OMIT_INCRBLOB
  #undef MEM_Zero
  #define MEM_Zero 0x0000
#endif

/*
** 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)
   ((p)->flags = ((p)->flags&~(MEM_TypeMask|MEM_Zero|MEM_Ptr))|f)

/*
** Return true if a memory cell is not marked as invalid.  This macro
** is for use inside assert() statements only.
*/
#ifdef SQLITE_DEBUG
#define memIsValid(M)  ((M)->flags & MEM_Undefined)==0
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
298
299
300
301
302
303
304








305
306
307
308
309
310
311







-
-
-
-
-
-
-
-








/*
** An instance of the virtual machine.  This structure contains the complete
** state of the virtual machine.
**
** The "sqlite3_stmt" structure pointer that is returned by sqlite3_prepare()
** is really a pointer to an instance of this structure.
**
** The Vdbe.inVtabMethod variable is set to non-zero for the duration of
** any virtual table method invocations made by the vdbe program. It is
** set to 2 for xDestroy method calls and 1 for all other methods. This
** variable is used for two purposes: to allow xDestroy methods to execute
** "DROP TABLE" statements and to prevent some nasty side effects of
** malloc failure when SQLite is invoked recursively by a virtual table 
** method function.
*/
struct Vdbe {
  sqlite3 *db;            /* The database connection that owns this statement */
  Op *aOp;                /* Space to hold the virtual machine's program */
  Mem *aMem;              /* The memory locations */
  Mem **apArg;            /* Arguments to currently executing user function */
  Mem *aColName;          /* Column names to return */
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
325
326
327
328
329
330
331

332
333
334
335
336
337
338







-







  u32 cacheCtr;           /* VdbeCursor row cache generation counter */
  int pc;                 /* The program counter */
  int rc;                 /* Value to return */
  u16 nResColumn;         /* Number of columns in one row of the result set */
  u8 errorAction;         /* Recovery action to do in case of an error */
  u8 minWriteFileFormat;  /* Minimum file format for writable database files */
  bft explain:2;          /* True if EXPLAIN present on SQL command */
  bft inVtabMethod:2;     /* See comments above */
  bft changeCntOn:1;      /* True to update the change-counter */
  bft expired:1;          /* True if the VM needs to be recompiled */
  bft runOnlyOnce:1;      /* Automatically expire on reset */
  bft usesStmtJournal:1;  /* True if uses a statement journal */
  bft readOnly:1;         /* True for statements that do not write */
  bft bIsReader:1;        /* True for statements that read */
  bft isPrepareV2:1;      /* True if prepared with prepare_v2() */

Changes to src/vdbeapi.c.

151
152
153
154
155
156
157





158
159
160
161
162
163
164
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169







+
+
+
+
+







  return sqlite3VdbeRealValue((Mem*)pVal);
}
int sqlite3_value_int(sqlite3_value *pVal){
  return (int)sqlite3VdbeIntValue((Mem*)pVal);
}
sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){
  return sqlite3VdbeIntValue((Mem*)pVal);
}
void *sqlite3_value_pointer(sqlite3_value *pVal){
  Mem *p = (Mem*)pVal;
  if( (p->flags&(MEM_TypeMask|MEM_Ptr))==(MEM_Null|MEM_Ptr) ) return p->u.pPtr;
  return 0;
}
const unsigned char *sqlite3_value_text(sqlite3_value *pVal){
  return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8);
}
#ifndef SQLITE_OMIT_UTF16
const void *sqlite3_value_text16(sqlite3_value* pVal){
  return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE);
258
259
260
261
262
263
264







265
266
267
268
269
270
271
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283







+
+
+
+
+
+
+







void sqlite3_result_int(sqlite3_context *pCtx, int iVal){
  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
  sqlite3VdbeMemSetInt64(&pCtx->s, (i64)iVal);
}
void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){
  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
  sqlite3VdbeMemSetInt64(&pCtx->s, iVal);
}
void sqlite3_result_pointer(sqlite3_context *pCtx, void *pPtr){
  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
  sqlite3VdbeMemSetNull(&pCtx->s);
  assert( (pCtx->s.flags & (MEM_TypeMask|MEM_Ptr))==MEM_Null );
  pCtx->s.flags |= MEM_Ptr;
  pCtx->s.u.pPtr = pPtr;
}
void sqlite3_result_null(sqlite3_context *pCtx){
  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
  sqlite3VdbeMemSetNull(&pCtx->s);
}
void sqlite3_result_text(
  sqlite3_context *pCtx, 

Changes to src/vdbeaux.c.

1084
1085
1086
1087
1088
1089
1090
1091

1092
1093
1094
1095
1096
1097
1098
1084
1085
1086
1087
1088
1089
1090

1091
1092
1093
1094
1095
1096
1097
1098







-
+







        zP4 = "(blob)";
      }
      break;
    }
#ifndef SQLITE_OMIT_VIRTUALTABLE
    case P4_VTAB: {
      sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab;
      sqlite3_snprintf(nTemp, zTemp, "vtab:%p:%p", pVtab, pVtab->pModule);
      sqlite3_snprintf(nTemp, zTemp, "vtab:%p", pVtab);
      break;
    }
#endif
    case P4_INTARRAY: {
      sqlite3_snprintf(nTemp, zTemp, "intarray");
      break;
    }
1745
1746
1747
1748
1749
1750
1751

1752

1753
1754
1755
1756
1757
1758
1759
1760
1761
1745
1746
1747
1748
1749
1750
1751
1752

1753
1754

1755
1756
1757
1758
1759
1760
1761







+
-
+

-







  }else if( pCx->pCursor ){
    sqlite3BtreeCloseCursor(pCx->pCursor);
  }
#ifndef SQLITE_OMIT_VIRTUALTABLE
  if( pCx->pVtabCursor ){
    sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor;
    const sqlite3_module *pModule = pVtabCursor->pVtab->pModule;
    assert( pVtabCursor->pVtab->nRef>0 );
    p->inVtabMethod = 1;
    pVtabCursor->pVtab->nRef--;
    pModule->xClose(pVtabCursor);
    p->inVtabMethod = 0;
  }
#endif
}

/*
** Copy the values stored in the VdbeFrame structure to its Vdbe. This
** is used, for example, when a trigger sub-program is halted to restore

Changes to src/vtab.c.

20
21
22
23
24
25
26


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







+
+







** this struct allocated on the stack. It is used by the implementation of 
** the sqlite3_declare_vtab() and sqlite3_vtab_config() APIs, both of which
** are invoked only from within xCreate and xConnect methods.
*/
struct VtabCtx {
  VTable *pVTable;    /* The virtual table being constructed */
  Table *pTab;        /* The Table object to which the virtual table belongs */
  VtabCtx *pPrior;    /* Parent context (if any) */
  int bDeclared;      /* True after sqlite3_declare_vtab() is called */
};

/*
** The actual function that does the work of creating a new module.
** This function implements the sqlite3_create_module() and
** sqlite3_create_module_v2() interfaces.
*/
470
471
472
473
474
475
476
477

478
479
480
481
482
483

484

485











486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506


507
508
509

510

511
512
513
514
515
516
517
518
519
520
521
522
523
524
525

526
527
528
529
530
531
532
472
473
474
475
476
477
478

479
480
481
482
483
484

485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519

520
521
522
523

524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540

541
542
543
544
545
546
547
548







-
+





-
+

+

+
+
+
+
+
+
+
+
+
+
+




















-
+
+


-
+

+














-
+







static int vtabCallConstructor(
  sqlite3 *db, 
  Table *pTab,
  Module *pMod,
  int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**),
  char **pzErr
){
  VtabCtx sCtx, *pPriorCtx;
  VtabCtx sCtx;
  VTable *pVTable;
  int rc;
  const char *const*azArg = (const char *const*)pTab->azModuleArg;
  int nArg = pTab->nModuleArg;
  char *zErr = 0;
  char *zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
  char *zModuleName;
  int iDb;
  VtabCtx *pCtx;

  /* Check that the virtual-table is not already being initialized */
  for(pCtx=db->pVtabCtx; pCtx; pCtx=pCtx->pPrior){
    if( pCtx->pTab==pTab ){
      *pzErr = sqlite3MPrintf(db, 
          "vtable constructor called recursively: %s", pTab->zName
      );
      return SQLITE_LOCKED;
    }
  }

  zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
  if( !zModuleName ){
    return SQLITE_NOMEM;
  }

  pVTable = sqlite3DbMallocZero(db, sizeof(VTable));
  if( !pVTable ){
    sqlite3DbFree(db, zModuleName);
    return SQLITE_NOMEM;
  }
  pVTable->db = db;
  pVTable->pMod = pMod;

  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
  pTab->azModuleArg[1] = db->aDb[iDb].zName;

  /* Invoke the virtual table constructor */
  assert( &db->pVtabCtx );
  assert( xConstruct );
  sCtx.pTab = pTab;
  sCtx.pVTable = pVTable;
  pPriorCtx = db->pVtabCtx;
  sCtx.pPrior = db->pVtabCtx;
  sCtx.bDeclared = 0;
  db->pVtabCtx = &sCtx;
  rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
  db->pVtabCtx = pPriorCtx;
  db->pVtabCtx = sCtx.pPrior;
  if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
  assert( sCtx.pTab==pTab );

  if( SQLITE_OK!=rc ){
    if( zErr==0 ){
      *pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName);
    }else {
      *pzErr = sqlite3MPrintf(db, "%s", zErr);
      sqlite3_free(zErr);
    }
    sqlite3DbFree(db, pVTable);
  }else if( ALWAYS(pVTable->pVtab) ){
    /* Justification of ALWAYS():  A correct vtab constructor must allocate
    ** the sqlite3_vtab object if successful.  */
    pVTable->pVtab->pModule = pMod->pModule;
    pVTable->nRef = 1;
    if( sCtx.pTab ){
    if( sCtx.bDeclared==0 ){
      const char *zFormat = "vtable constructor did not declare schema: %s";
      *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName);
      sqlite3VtabUnlock(pVTable);
      rc = SQLITE_ERROR;
    }else{
      int iCol;
      /* If everything went according to plan, link the new VTable structure
688
689
690
691
692
693
694

695
696
697
698
699
700
701
702

703
704
705
706

707
708
709
710
711
712
713
704
705
706
707
708
709
710
711
712

713
714
715
716
717

718
719
720
721
722
723
724
725
726
727
728
729
730







+

-





-
+




+








/*
** This function is used to set the schema of a virtual table.  It is only
** valid to call this function from within the xCreate() or xConnect() of a
** virtual table module.
*/
int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
  VtabCtx *pCtx = db->pVtabCtx;
  Parse *pParse;

  int rc = SQLITE_OK;
  Table *pTab;
  char *zErr = 0;

  sqlite3_mutex_enter(db->mutex);
  if( !db->pVtabCtx || !(pTab = db->pVtabCtx->pTab) ){
  if( !pCtx || pCtx->bDeclared ){
    sqlite3Error(db, SQLITE_MISUSE, 0);
    sqlite3_mutex_leave(db->mutex);
    return SQLITE_MISUSE_BKPT;
  }
  pTab = pCtx->pTab;
  assert( (pTab->tabFlags & TF_Virtual)!=0 );

  pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
  if( pParse==0 ){
    rc = SQLITE_NOMEM;
  }else{
    pParse->declareVtab = 1;
722
723
724
725
726
727
728
729

730
731
732
733
734
735
736
739
740
741
742
743
744
745

746
747
748
749
750
751
752
753







-
+







    ){
      if( !pTab->aCol ){
        pTab->aCol = pParse->pNewTable->aCol;
        pTab->nCol = pParse->pNewTable->nCol;
        pParse->pNewTable->nCol = 0;
        pParse->pNewTable->aCol = 0;
      }
      db->pVtabCtx->pTab = 0;
      pCtx->bDeclared = 1;
    }else{
      sqlite3Error(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr);
      sqlite3DbFree(db, zErr);
      rc = SQLITE_ERROR;
    }
    pParse->declareVtab = 0;
  
757
758
759
760
761
762
763
764
765






766
767
768



769
770
771
772
773
774
775
774
775
776
777
778
779
780


781
782
783
784
785
786



787
788
789
790
791
792
793
794
795
796







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







*/
int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
  int rc = SQLITE_OK;
  Table *pTab;

  pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName);
  if( ALWAYS(pTab!=0 && pTab->pVTable!=0) ){
    VTable *p = vtabDisconnectAll(db, pTab);

    VTable *p;
    for(p=pTab->pVTable; p; p=p->pNext){
      assert( p->pVtab );
      if( p->pVtab->nRef>0 ){
        return SQLITE_LOCKED;
      }
    assert( rc==SQLITE_OK );
    rc = p->pMod->pModule->xDestroy(p->pVtab);

    }
    p = vtabDisconnectAll(db, pTab);
    rc = p->pMod->pModule->xDestroy(p->pVtab);
    /* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */
    if( rc==SQLITE_OK ){
      assert( pTab->pVTable==p && p->pNext==0 );
      p->pVtab = 0;
      pTab->pVTable = 0;
      sqlite3VtabUnlock(p);
    }

Changes to src/where.c.

1253
1254
1255
1256
1257
1258
1259
1260

1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280

1281
1282
1283
1284

1285
1286
1287
1288
1289
1290
1291
1292

1293
1294
1295
1296
1297
1298
1299
1253
1254
1255
1256
1257
1258
1259

1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279

1280

1281
1282

1283
1284
1285
1286
1287
1288
1289
1290

1291
1292
1293
1294
1295
1296
1297
1298







-
+



















-
+
-


-
+







-
+







  ){
    Expr *pLeft;       /* LHS of LIKE/GLOB operator */
    Expr *pStr2;       /* Copy of pStr1 - RHS of LIKE/GLOB operator */
    Expr *pNewExpr1;
    Expr *pNewExpr2;
    int idxNew1;
    int idxNew2;
    Token sCollSeqName;  /* Name of collating sequence */
    const char *zCollSeqName;     /* Name of collating sequence */

    pLeft = pExpr->x.pList->a[1].pExpr;
    pStr2 = sqlite3ExprDup(db, pStr1, 0);
    if( !db->mallocFailed ){
      u8 c, *pC;       /* Last character before the first wildcard */
      pC = (u8*)&pStr2->u.zToken[sqlite3Strlen30(pStr2->u.zToken)-1];
      c = *pC;
      if( noCase ){
        /* The point is to increment the last character before the first
        ** wildcard.  But if we increment '@', that will push it into the
        ** alphabetic range where case conversions will mess up the 
        ** inequality.  To avoid this, make sure to also run the full
        ** LIKE on all candidate expressions by clearing the isComplete flag
        */
        if( c=='A'-1 ) isComplete = 0;
        c = sqlite3UpperToLower[c];
      }
      *pC = c + 1;
    }
    sCollSeqName.z = noCase ? "NOCASE" : "BINARY";
    zCollSeqName = noCase ? "NOCASE" : "BINARY";
    sCollSeqName.n = 6;
    pNewExpr1 = sqlite3ExprDup(db, pLeft, 0);
    pNewExpr1 = sqlite3PExpr(pParse, TK_GE, 
           sqlite3ExprAddCollateToken(pParse,pNewExpr1,&sCollSeqName),
           sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName),
           pStr1, 0);
    transferJoinMarkings(pNewExpr1, pExpr);
    idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
    testcase( idxNew1==0 );
    exprAnalyze(pSrc, pWC, idxNew1);
    pNewExpr2 = sqlite3ExprDup(db, pLeft, 0);
    pNewExpr2 = sqlite3PExpr(pParse, TK_LT,
           sqlite3ExprAddCollateToken(pParse,pNewExpr2,&sCollSeqName),
           sqlite3ExprAddCollateString(pParse,pNewExpr2,zCollSeqName),
           pStr2, 0);
    transferJoinMarkings(pNewExpr2, pExpr);
    idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
    testcase( idxNew2==0 );
    exprAnalyze(pSrc, pWC, idxNew2);
    pTerm = &pWC->a[idxTerm];
    if( isComplete ){

Changes to test/analyze.test.

355
356
357
358
359
360
361
362

363
364
355
356
357
358
359
360
361

362
363
364







-
+


    UPDATE sqlite_master SET sql='nonsense' WHERE name='sqlite_stat1';
  }
  db close
  catch { sqlite3 db test.db }
  catchsql {
    ANALYZE
  }
} {1 {malformed database schema (sqlite_stat1) - near "nonsense": syntax error}}
} {1 {malformed database schema (sqlite_stat1)}}

finish_test

Changes to test/collate1.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
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












-
+

-



+







#
# 2001 September 15
#
# 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 script is page cache subsystem.
# focus of this script is testing collation sequences.
#
# $Id: collate1.test,v 1.5 2007/02/01 23:02:46 drh Exp $

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

#
# Tests are roughly organised as follows:
#
# collate1-1.* - Single-field ORDER BY with an explicit COLLATE clause.
# collate1-2.* - Multi-field ORDER BY with an explicit COLLATE clause.
# collate1-3.* - ORDER BY using a default collation type. Also that an 
329
330
331
332
333
334
335




















































336


329
330
331
332
333
334
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
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390







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

+
+
} {1}
do_test collate1-5.3 {
  execsql {
    SELECT id FROM c5 WHERE c='abc' ORDER BY id;
  }
} {1 2}



#-------------------------------------------------------------------------
# Fix problems with handling collation sequences named '"""'.
#
do_execsql_test 6.1 {
  SELECT """""""";
} {\"\"\"}

do_catchsql_test 6.2 {
  CREATE TABLE x1(a);
  SELECT a FROM x1 ORDER BY a COLLATE """""""";
} {1 {no such collation sequence: """}}

do_catchsql_test 6.3 {
  SELECT a FROM x1 ORDER BY 1 COLLATE """""""";
} {1 {no such collation sequence: """}}

do_catchsql_test 6.4 {
  SELECT 0 UNION SELECT 0 ORDER BY 1 COLLATE """""""";
} {1 {no such collation sequence: """}}

db collate {"""} [list string compare -nocase]

do_execsql_test 6.5 {
  PRAGMA foreign_keys = ON;
  CREATE TABLE p1(a PRIMARY KEY COLLATE '"""');
  CREATE TABLE c1(x, y REFERENCES p1);
} {}

do_execsql_test 6.6 { 
  INSERT INTO p1 VALUES('abc'); 
  INSERT INTO c1 VALUES(1, 'ABC'); 
}

ifcapable foreignkey {
  do_catchsql_test 6.7 { 
    DELETE FROM p1 WHERE rowid = 1 
  } {1 {FOREIGN KEY constraint failed}}
}

do_execsql_test 6.8 { 
  INSERT INTO p1 VALUES('abb');
  INSERT INTO p1 VALUES('wxz');
  INSERT INTO p1 VALUES('wxy');

  INSERT INTO c1 VALUES(2, 'abb');
  INSERT INTO c1 VALUES(3, 'wxz');
  INSERT INTO c1 VALUES(4, 'WXY');
  SELECT x, y FROM c1 ORDER BY y COLLATE """""""";
} {2 abb 1 ABC 4 WXY 3 wxz}

finish_test


Changes to test/e_reindex.test.

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
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







+
+
+

-
+









-
+
+







#    Test this by corrupting some database indexes, running REINDEX, and
#    observing that the corruption is gone.
#
do_execsql_test e_reindex-1.1 {
  INSERT INTO t1 VALUES(1, 2);
  INSERT INTO t1 VALUES(3, 4);
  INSERT INTO t1 VALUES(5, 6);

  CREATE TABLE saved(a,b,c,d,e);
  INSERT INTO saved SELECT * FROM sqlite_master WHERE type = 'index';
  PRAGMA writable_schema = 1;
  UPDATE sqlite_master SET sql = '-- ' || sql WHERE type = 'index';
  DELETE FROM sqlite_master WHERE type = 'index';
} {}

db close
sqlite3 db test.db
do_execsql_test e_reindex-1.2 {
  DELETE FROM t1 WHERE a = 3;
  INSERT INTO t1 VALUES(7, 8);
  INSERT INTO t1 VALUES(9, 10);
  PRAGMA writable_schema = 1;
  UPDATE sqlite_master SET sql = substr(sql, 4) WHERE type = 'index';
  INSERT INTO sqlite_master SELECT * FROM saved;
  DROP TABLE saved;
} {}

db close
sqlite3 db test.db
do_execsql_test e_reindex-1.3 {
  PRAGMA integrity_check;
} [list \

Changes to test/fkey1.test.

116
117
118
119
120
121
122






























123
124
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







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


} [concat                        \
  {0 0 t5 d {} {SET DEFAULT} CASCADE NONE} \
  {0 1 t5 e {} {SET DEFAULT} CASCADE NONE} \
]
do_test fkey1-3.5 {
  sqlite3_db_status db DBSTATUS_DEFERRED_FKS 0
} {0 0 0}

# Stress the dequoting logic.  The first test is not so bad.
do_execsql_test fkey1-4.0 {
  PRAGMA foreign_keys=ON;
  CREATE TABLE "xx1"("xx2" TEXT PRIMARY KEY, "xx3" TEXT);
  INSERT INTO "xx1"("xx2","xx3") VALUES('abc','def');
  CREATE TABLE "xx4"("xx5" TEXT REFERENCES "xx1" ON DELETE CASCADE);
  INSERT INTO "xx4"("xx5") VALUES('abc');
  INSERT INTO "xx1"("xx2","xx3") VALUES('uvw','xyz');
  SELECT 1, "xx5" FROM "xx4";
  DELETE FROM "xx1";
  SELECT 2, "xx5" FROM "xx4";
} {1 abc}

# This case is identical to the previous except the "xx" in each name
# is changed to a single escaped double-quote character.
do_execsql_test fkey1-4.1 {
  PRAGMA foreign_keys=ON;
  CREATE TABLE """1"("""2" TEXT PRIMARY KEY, """3" TEXT);
  INSERT INTO """1"("""2","""3") VALUES('abc','def');
  CREATE TABLE """4"("""5" TEXT REFERENCES """1" ON DELETE CASCADE);
  INSERT INTO """4"("""5") VALUES('abc');
  INSERT INTO """1"("""2","""3") VALUES('uvw','xyz');
  SELECT 1, """5" FROM """4";
  DELETE FROM """1";
  SELECT 2, """5" FROM """4";
} {1 abc}
do_execsql_test fkey1-4.2 {
  PRAGMA table_info="""1";
} {0 {"2} TEXT 0 {} 1 1 {"3} TEXT 0 {} 0}

finish_test

Changes to test/fts3prefix.test.

205
206
207
208
209
210
211
































































212
213
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
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277







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


#
do_catchsql_test 5.1 {
  CREATE VIRTUAL TABLE t4 USING fts4(prefix="abc");
} {1 {error parsing prefix parameter: abc}}
do_catchsql_test 5.2 {
  CREATE VIRTUAL TABLE t4 USING fts4(prefix="");
} {0 {}}
do_catchsql_test 5.3 {
  CREATE VIRTUAL TABLE t5 USING fts4(prefix="-1");
} {1 {error parsing prefix parameter: -1}}

#-------------------------------------------------------------------------
# Prefix indexes of size 0 are ignored. Demonstrate this by showing that
# adding prefix=0 does not change the contents of the %_segdir table.
#
reset_db
do_execsql_test 6.1.1 {
  CREATE VIRTUAL TABLE t1 USING fts4(prefix=0);
  CREATE VIRTUAL TABLE t2 USING fts4;
  INSERT INTO t1 VALUES('Twas Mulga Bill, from Eaglehawk, ');
  INSERT INTO t2 VALUES('Twas Mulga Bill, from Eaglehawk, ');
} {}
do_execsql_test 6.1.2 {
  SELECT md5sum(quote(root)) FROM t1_segdir;
} [db eval {SELECT md5sum(quote(root)) FROM t2_segdir}]

reset_db
do_execsql_test 6.2.1 {
  CREATE VIRTUAL TABLE t1 USING fts4(prefix="1,0,2");
  CREATE VIRTUAL TABLE t2 USING fts4(prefix="1,2");
  INSERT INTO t1 VALUES('that caught the cycling craze;');
  INSERT INTO t2 VALUES('that caught the cycling craze;');
} {}
do_execsql_test 6.2.2 {
  SELECT md5sum(quote(root)) FROM t1_segdir;
} [db eval {SELECT md5sum(quote(root)) FROM t2_segdir}]

reset_db
do_execsql_test 6.3.1 {
  CREATE VIRTUAL TABLE t1 USING fts4(prefix="1,3,2");
  CREATE VIRTUAL TABLE t2 USING fts4(prefix="1,2");
  INSERT INTO t1 VALUES('He turned away the good old horse');
  INSERT INTO t2 VALUES('He turned away the good old horse');
} {}
do_test 6.3.2 {
  set one [db eval {SELECT md5sum(quote(root)) FROM t1_segdir}]
  set two [db eval {SELECT md5sum(quote(root)) FROM t2_segdir}]
  expr {$one == $two}
} 0

reset_db
do_execsql_test 6.4.1 {
  CREATE VIRTUAL TABLE t1 USING fts4(prefix="1,600,2");
  CREATE VIRTUAL TABLE t2 USING fts4(prefix="1,2");
  INSERT INTO t1 VALUES('that served him many days;');
  INSERT INTO t2 VALUES('that served him many days;');
} {}
do_execsql_test 6.4.2 {
  SELECT md5sum(quote(root)) FROM t1_segdir;
} [db eval {SELECT md5sum(quote(root)) FROM t2_segdir}]

reset_db
do_execsql_test 6.5.1 {
  CREATE VIRTUAL TABLE t1 USING fts4(prefix="2147483647,2147483648,2147483649");
  CREATE VIRTUAL TABLE t2 USING fts4(prefix="");
  INSERT INTO t1 VALUES('He dressed himself in cycling clothes');
  INSERT INTO t2 VALUES('He dressed himself in cycling clothes');
} {}
do_execsql_test 6.5.2 {
  SELECT md5sum(quote(root)) FROM t1_segdir;
} [db eval {SELECT md5sum(quote(root)) FROM t2_segdir}]

finish_test

Changes to test/fts4check.test.

174
175
176
177
178
179
180






























181
182
183
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







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



  db close
  sqlite3 db test.db
  catchsql {
    INSERT INTO t4(t4) VALUES('integrity-check');
  }
} {1 {database disk image is malformed}}
reset_db

#--------------------------------------------------------------------------
# Test case 5.*
#
# Test that the integrity-check works if there is uncommitted data.
#
do_execsql_test 5.0 {
  BEGIN;
  CREATE VIRTUAL TABLE t5 USING fts4(a, prefix="1,2,3");
  INSERT INTO t5 VALUES('And down by Kosiosko, where the reed-banks sweep');
  INSERT INTO t5 VALUES('and sway, and the rolling plains are wide, the');
  INSERT INTO t5 VALUES('man from snowy river is a household name today,');
  INSERT INTO t5 VALUES('and the stockmen tell the story of his ride');
}

do_execsql_test 5.1 {
  INSERT INTO t5(t5) VALUES('integrity-check');
} {}

do_catchsql_test 5.2 {
  INSERT INTO t5_content VALUES(5, 'his hardy mountain pony');
  INSERT INTO t5(t5) VALUES('integrity-check');
} {1 {database disk image is malformed}}

do_execsql_test 5.3 ROLLBACK

do_execsql_test 5.4 {
  CREATE VIRTUAL TABLE t5 USING fts4(a, prefix="1,2,3");
  INSERT INTO t5(t5) VALUES('integrity-check');
} {}

finish_test

Changes to test/fts4content.test.

44
45
46
47
48
49
50



51
52
53
54
55
56
57
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60







+
+
+







#         SELECT statements.
#
#   8.* - Test that if the content=xxx and prefix options are used together,
#         the 'rebuild' command still works.
#
#   9.* - Test using content=xxx where xxx is a virtual table.
#
#   11.* - Test that circular references (e.g. "t1(content=t1)") are
#          detected.
#

do_execsql_test 1.1.1 {
  CREATE TABLE t1(a, b, c);
  INSERT INTO t1 VALUES('w x', 'x y', 'y z');
  CREATE VIRTUAL TABLE ft1 USING fts4(content=t1);
}

402
403
404
405
406
407
408
409

410
411
412
413
414
415
416
405
406
407
408
409
410
411

412
413
414
415
416
417
418
419







-
+







}

#-------------------------------------------------------------------------
# Test cases 6.* test 
# 
do_catchsql_test 6.1.1 {
  CREATE VIRTUAL TABLE ft7 USING fts4(content=t7);
} {1 {vtable constructor failed: ft7}}
} {1 {no such table: main.t7}}

do_execsql_test 6.2.1 {
  CREATE TABLE t7(one, two);
  CREATE VIRTUAL TABLE ft7 USING fts4(content=t7);
  INSERT INTO t7 VALUES('A B', 'B A');
  INSERT INTO t7 VALUES('C D', 'A A');
  SELECT * FROM ft7;
429
430
431
432
433
434
435
436

437
438
439
440
441
442
443
432
433
434
435
436
437
438

439
440
441
442
443
444
445
446







-
+







  SELECT name FROM sqlite_master WHERE name LIKE '%t7%'
} {
  ft7 ft7_segments ft7_segdir sqlite_autoindex_ft7_segdir_1 
  ft7_docsize ft7_stat
}
do_catchsql_test 6.2.4 {
  SELECT * FROM ft7;
} {1 {vtable constructor failed: ft7}}
} {1 {no such table: main.t7}}
do_execsql_test 6.2.5 {
  CREATE TABLE t7(x, y);
  INSERT INTO t7 VALUES('A B', 'B A');
  INSERT INTO t7 VALUES('C D', 'A A');
  SELECT * FROM ft7;
} {
  {A B} {B A} {C D} {A A}
617
618
619
620
621
622
623
624










625

620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639








+
+
+
+
+
+
+
+
+
+

+
do_execsql_test 10.6 { DELETE FROM ft WHERE docid=2 }

do_execsql_test 10.7 {
  SELECT snippet(ft, '[', ']', '...', -1, 5) FROM ft WHERE ft MATCH 'e'
} {
  {...c d [e] f g...}
}

#-------------------------------------------------------------------------
# Test cases 11.*
# 
reset_db

do_catchsql_test 11.1 {
  CREATE VIRTUAL TABLE x1 USING fts4(content=x1);
} {1 {vtable constructor called recursively: x1}}


finish_test

Changes to test/index3.test.

47
48
49
50
51
52
53
54

55
56
47
48
49
50
51
52
53

54
55
56







-
+


  execsql {
    PRAGMA writable_schema=on;
    UPDATE sqlite_master SET sql='nonsense';
  }
  db close
  catch { sqlite3 db test.db }
  catchsql { DROP INDEX i1 }
} {1 {malformed database schema (t1) - near "nonsense": syntax error}}
} {1 {malformed database schema (t1)}}

finish_test

Changes to test/insert2.test.

12
13
14
15
16
17
18

19
20
21
22
23
24
25
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26







+







# focus of this file is testing the INSERT statement that takes is
# result from a SELECT.
#
# $Id: insert2.test,v 1.19 2008/01/16 18:20:42 danielk1977 Exp $

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

# Create some tables with data that we can select against
#
do_test insert2-1.0 {
  execsql {CREATE TABLE d1(n int, log int);}
  for {set i 1} {$i<=20} {incr i} {
    for {set j 0} {(1<<$j)<$i} {incr j} {}
270
271
272
273
274
275
276
277



















278
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298








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

  do_test insert2-5.2 {
    execsql {
      INSERT INTO t2 SELECT (SELECT a FROM t2), 4;
      SELECT * FROM t2;
    }
  } {1 2 1 3 1 4}
}

do_execsql_test 6.0 { 
  CREATE TABLE t5(a, b, c DEFAULT 'c', d);
}
do_execsql_test 6.1 {
  INSERT INTO t5(a) SELECT 456 UNION ALL SELECT 123 ORDER BY 1;
  SELECT * FROM t5 ORDER BY rowid;
} {123 {} c {}   456 {} c {}}

ifcapable fts3 {
  do_execsql_test 6.2 {
    CREATE VIRTUAL TABLE t0 USING fts4(a);
  }
  do_execsql_test 6.3 {
    INSERT INTO t0 SELECT 0 UNION SELECT 0 AS 'x' ORDER BY x;
    SELECT * FROM t0;
  } {0}
}


finish_test

Changes to test/misc1.test.

616
617
618
619
620
621
622




















623
624
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644







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


  sqlite3_test_control_fault_install fault_callback
  set fault_callbacks
} {0}
do_test misc1-19.2 {
  sqlite3_test_control_fault_install
  set fault_callbacks
} {0}

do_catchsql_test misc1-20.1 {
  create table t0(o CHar(0)CHECK(0&O>O));
  insert into t0 select randomblob(0)-trim(0);
} {1 {CHECK constraint failed: t0}}


# 2015-04-19: NULL pointer dereference on a corrupt schema
#
do_execsql_test misc1-23.1 {
  DROP TABLE IF EXISTS t1;
  DROP TABLE IF EXISTS t2;
  CREATE TABLE t1(x);
  PRAGMA writable_schema=ON;
  UPDATE sqlite_master SET sql='CREATE table t(d CHECK(T(#0)';
  BEGIN;
  CREATE TABLE t2(y);
  ROLLBACK;
  DROP TABLE IF EXISTS t3;
} {}

finish_test

Added test/ovfl.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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2014 October 01
#
# 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 the SQLITE_DIRECT_OVERFLOW_READ logic.
#

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

# Populate table t2:
#
#   CREATE TABLE t1(c1 TEXT, c2 TEXT);
#
# with 2000 rows. In each row, c2 spans multiple overflow pages. The text
# value of c1 ranges in size from 1 to 2000 bytes. The idea is to create
# at least one row where the first byte of c2 is also the first byte of
# an overflow page. This was at one point exposing an obscure bug in the
# SQLITE_DIRECT_OVERFLOW_READ logic.
#
do_test 1.1 {
  set c2 [string repeat abcdefghij 200]
  execsql {
    PRAGMA cache_size = 10;
    CREATE TABLE t1(c1 TEXT, c2 TEXT);
    BEGIN;
  }
  for {set i 1} {$i <= 2000} {incr i} {
    set c1 [string repeat . $i]
    execsql { INSERT INTO t1 VALUES($c1, $c2) }
  }
  execsql COMMIT
} {}

do_execsql_test 1.2 {
  SELECT sum(length(c2)) FROM t1;
} [expr 2000 * 2000]

finish_test


Changes to test/printf.test.

468
469
470
471
472
473
474












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







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







  sqlite3_mprintf_int {abc: (% 6d) (% 6x) (% 6o) :xyz}\
       0xff676981 0xff676981 0xff676981
} {abc: (-9999999) (ff676981) (37731664601) :xyz}
do_test printf-1.16.7 {
  sqlite3_mprintf_int {abc: (%#6d) (%#6x) (%#6o) :xyz}\
       0xff676981 0xff676981 0xff676981
} {abc: (-9999999) (0xff676981) (037731664601) :xyz}
do_test printf-1.17.1 {
  sqlite3_mprintf_int {abd: %2147483647d %2147483647x %2147483647o} 1 1 1
} {}
do_test printf-1.17.2 {
  sqlite3_mprintf_int {abd: %*d %x} 2147483647 1 1
} {}
do_test printf-1.17.3 {
  sqlite3_mprintf_int {abd: %*d %x} -2147483648 1 1
} {abd: 1 1}
do_test printf-1.17.4 {
  sqlite3_mprintf_int {abd: %.2147483648d %x %x} 1 1 1
} {/.*/}
do_test printf-2.1.1.1 {
  sqlite3_mprintf_double {abc: (%*.*f) :xyz} 1 1 0.001
} {abc: (0.0) :xyz}
do_test printf-2.1.1.2 {
  sqlite3_mprintf_double {abc: (%*.*e) :xyz} 1 1 0.001
} {abc: (1.0e-03) :xyz}
do_test printf-2.1.1.3 {
522
523
524
525
526
527
528



529
530
531
532
533
534
535
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550







+
+
+







} {abc: 1 1 (0.0) :xyz}
do_test printf-2.1.2.8 {
  sqlite3_mprintf_double {abc: %d %d (%1.1e) :xyz} 1 1 1.0e-20
} {abc: 1 1 (1.0e-20) :xyz}
do_test printf-2.1.2.9 {
  sqlite3_mprintf_double {abc: %d %d (%1.1g) :xyz} 1 1 1.0e-20
} {abc: 1 1 (1e-20) :xyz}
do_test printf-2.1.2.10 {
  sqlite3_mprintf_double {abc: %*.*f}  2000000000 1000000000 1.0e-20
} {abc: }
do_test printf-2.1.3.1 {
  sqlite3_mprintf_double {abc: (%*.*f) :xyz} 1 1 1.0
} {abc: (1.0) :xyz}
do_test printf-2.1.3.2 {
  sqlite3_mprintf_double {abc: (%*.*e) :xyz} 1 1 1.0
} {abc: (1.0e+00) :xyz}
do_test printf-2.1.3.3 {
3462
3463
3464
3465
3466
3467
3468









3469
3470
3471
3472
3473
3474
3475
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499







+
+
+
+
+
+
+
+
+







} [format {%d %d A String: (%s)} 1 2 {This is the string}]
do_test printf-3.5 {
  sqlite3_mprintf_str {%d %d A String: (%30s)} 1 2 {This is the string}
} [format {%d %d A String: (%30s)} 1 2 {This is the string}]
do_test printf-3.6 {
  sqlite3_mprintf_str {%d %d A String: (%-30s)} 1 2 {This is the string}
} [format {%d %d A String: (%-30s)} 1 2 {This is the string}]
do_test printf-3.7 {
  sqlite3_mprintf_str {%d A String: (%*s)} 1 2147483647 {This is the string}
} []
do_test printf-3.8 {
  sqlite3_mprintf_str {%d A String: (%*s)} 1 -2147483648 {This is the string}
} {1 A String: (This is the string)}
do_test printf-3.9 {
  sqlite3_mprintf_str {%d A String: (%.*s)} 1 -2147483648 {This is the string}
} {1 A String: (This is the string)}
do_test snprintf-3.11 {
  sqlite3_snprintf_str 2 {x%d %d %s} 10 10 {This is the string}
} {x}
do_test snprintf-3.12 {
  sqlite3_snprintf_str 3 {x%d %d %s} 10 10 {This is the string}
} {x1}
do_test snprintf-3.13 {
3681
3682
3683
3684
3685
3686
3687



3688
3689
3690
3691
3692
3693
3694
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721







+
+
+







} {Inf}
do_test printf-13.5 {
  sqlite3_mprintf_hexdouble %.20f fff0000000000000
} {-Inf}
do_test printf-13.6 {
  sqlite3_mprintf_hexdouble %.20f fff8000000000000
} {NaN}
do_test printf-13.7 {
  sqlite3_mprintf_hexdouble %2147483648.10000f 4693b8b5b5056e17
} {/100000000000000000000000000000000.00/}

do_test printf-14.1 {
  sqlite3_mprintf_str {abc-%y-123} 0 0 {not used}
} {abc-}
do_test printf-14.2 {
  sqlite3_mprintf_n_test {xyzzy}
} 5

Changes to test/trace2.test.

139
140
141
142
143
144
145
146

147
148
149
150
151
152
153
139
140
141
142
143
144
145

146
147
148
149
150
151
152
153







-
+







    "-- SELECT level, idx, end_block FROM 'main'.'x1_segdir' WHERE level BETWEEN ? AND ? ORDER BY level DESC, idx ASC"
  }

  do_trace_test 2.3 {
    INSERT INTO x1(x1) VALUES('optimize');
  } {
    "INSERT INTO x1(x1) VALUES('optimize');"
    "-- SELECT DISTINCT level / (1024 * ?) FROM 'main'.'x1_segdir'"
    "-- SELECT ? UNION SELECT level / (1024 * ?) FROM 'main'.'x1_segdir'"
    "-- SELECT idx, start_block, leaves_end_block, end_block, root FROM 'main'.'x1_segdir' WHERE level BETWEEN ? AND ?ORDER BY level DESC, idx ASC"
    "-- SELECT max(level) FROM 'main'.'x1_segdir' WHERE level BETWEEN ? AND ?"
    "-- SELECT coalesce((SELECT max(blockid) FROM 'main'.'x1_segments') + 1, 1)"
    "-- DELETE FROM 'main'.'x1_segdir' WHERE level BETWEEN ? AND ?"
    "-- REPLACE INTO 'main'.'x1_segdir' VALUES(?,?,?,?,?,?)"
  }
}

Changes to test/trigger7.test.

110
111
112
113
114
115
116
117

118
119
110
111
112
113
114
115
116

117
118
119







-
+


  execsql {
    PRAGMA writable_schema=on;
    UPDATE sqlite_master SET sql='nonsense';
  }
  db close
  catch { sqlite3 db test.db }
  catchsql { DROP TRIGGER t2r5 }
} {1 {malformed database schema (t2r12) - near "nonsense": syntax error}}
} {1 {malformed database schema (t2r12)}}

finish_test

Changes to test/triggerC.test.

8
9
10
11
12
13
14

15
16
17
18
19
20
21
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22







+







#    May you share freely, never taking more than you give.
#
#***********************************************************************
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix triggerC
ifcapable {!trigger} {
  finish_test
  return
}

#-------------------------------------------------------------------------
# Test organization:
988
989
990
991
992
993
994
995
















































996
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045








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

}

reset_db
do_execsql_test triggerC-14.1 $SQL {1 2 3}
reset_db
optimization_control db factor-constants 0
do_execsql_test triggerC-14.2 $SQL {1 2 3}

#-------------------------------------------------------------------------
# Check that table names used by trigger programs are dequoted exactly
# once.
#
do_execsql_test 15.1.1 {
  PRAGMA recursive_triggers = 1;
  CREATE TABLE node(
      id int not null primary key, 
      pid int not null default 0 references node,
      key varchar not null, 
      path varchar default '',
      unique(pid, key)
      );
  CREATE TRIGGER node_delete_referencing AFTER DELETE ON "node"
    BEGIN
    DELETE FROM "node" WHERE pid = old."id";
  END;
}
do_execsql_test 15.1.2 {
  INSERT INTO node(id, pid, key) VALUES(9, 0, 'test');
  INSERT INTO node(id, pid, key) VALUES(90, 9, 'test1');
  INSERT INTO node(id, pid, key) VALUES(900, 90, 'test2');
  DELETE FROM node WHERE id=9;
  SELECT * FROM node;
}

do_execsql_test 15.2.1 {
  CREATE TABLE   x1  (x);

  CREATE TABLE   x2  (a, b);
  CREATE TABLE '"x2"'(a, b);

  INSERT INTO x2 VALUES(1, 2);
  INSERT INTO x2 VALUES(3, 4);
  INSERT INTO '"x2"' SELECT * FROM x2;

  CREATE TRIGGER x1ai AFTER INSERT ON x1 BEGIN
    INSERT INTO """x2""" VALUES('x', 'y');
    DELETE FROM """x2""" WHERE a=1;
    UPDATE """x2""" SET b = 11 WHERE a = 3;
  END;

  INSERT INTO x1 VALUES('go!');
}

do_execsql_test 15.2.2 { SELECT * FROM x2;       } {1 2 3 4}
do_execsql_test 15.2.3 { SELECT * FROM """x2"""; } {3 11 x y}

finish_test

Changes to test/vtab1.test.

1391
1392
1393
1394
1395
1396
1397























































1398
1391
1392
1393
1394
1395
1396
1397
1398
1399
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
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453







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

  SELECT * FROM t9v WHERE a<b;
} {1 2 3}

do_execsql_test 21.3 {
  SELECT * FROM t9v WHERE a=b;
} {2 2 2}


#-------------------------------------------------------------------------
# The following tests verify that a DROP TABLE command on a virtual
# table does not cause other operations to crash.
#
#   23.1: Dropping a vtab while a SELECT is running on it.
#
#   23.2: Dropping a vtab while a SELECT that will, but has not yet,
#         open a cursor on the vtab, is running. In this case the
#         DROP TABLE succeeds and the SELECT hits an error.
#   
#   23.3: Dropping a vtab from within a user-defined-function callback
#         in the middle of an "INSERT INTO vtab SELECT ..." statement.
#
reset_db
load_static_extension db wholenumber
#load_static_extension db eval
db func execsql execsql
register_echo_module db

do_test 23.1 {
  execsql { CREATE VIRTUAL TABLE t1 USING wholenumber }
  set res ""
  db eval { SELECT value FROM t1 WHERE value<10 } {
    if {$value == 5} {
      set res [catchsql { DROP TABLE t1 }]
    }
  }
  set res
} {1 {database table is locked}}

do_test 23.2 {
  execsql { 
    CREATE TABLE t2(value);
    INSERT INTO t2 VALUES(1), (2), (3);
  }

  set res2 [list [catch {
    db eval {
      SELECT value FROM t2 UNION ALL 
      SELECT value FROM t1 WHERE value<10
    } {
      if {$value == 2} { set res1 [catchsql { DROP TABLE t1 }] }
    }
  } msg] $msg]
  list $res1 $res2
} {{0 {}} {1 {database table is locked}}}

do_test 23.3.1 {
  execsql { CREATE VIRTUAL TABLE t1e USING echo(t2) }
  execsql { INSERT INTO t1e SELECT 4 }
  catchsql { INSERT INTO t1e SELECT execsql('DROP TABLE t1e') }
} {1 {database table is locked}}
do_execsql_test 23.3.2 { SELECT * FROM t1e } {1 2 3 4}

finish_test

Changes to test/zeroblob.test.

251
252
253
254
255
256
257









258
259
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268







+
+
+
+
+
+
+
+
+


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}

# Oversized zeroblob records
#
do_test zeroblob-10.1 {
  db eval {
    CREATE TABLE t10(a,b,c);
  }
  catchsql {INSERT INTO t10 VALUES(zeroblob(1e9),zeroblob(1e9),zeroblob(1e9))}
} {1 {string or blob too big}}


finish_test