/ Check-in [d805fc0c]
Login

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

Overview
Comment:Merge trunk changes into this branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | wapptest
Files: files | file ages | folders
SHA3-256: d805fc0cf1c4ef07a7bc947f75828931e3788d0e64730caab3b42ae58009a194
User & Date: dan 2019-04-11 19:04:01
Context
2019-04-11
19:07
Add the test/wapptest.tcl script, an alternative to releasetest.tcl that uses wapp to provide the user-interface. check-in: edd87cd6 user: dan tags: trunk
19:04
Merge trunk changes into this branch. Closed-Leaf check-in: d805fc0c user: dan tags: wapptest
19:03
Further tweaks to wapptest.tcl. Add the ability to run the extra (n)debug tests that releasetest.tcl runs. check-in: ec9c4f6d user: dan tags: wapptest
17:06
Remove the vfslog.c extension from the testfixture target in main.mk, as that extension has no TCL bindings and is inaccessible. check-in: d71f8bbc user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Added ext/rbu/rbupartial.test.

            1  +# 2019 April 11
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +
           13  +source [file join [file dirname [info script]] rbu_common.tcl]
           14  +set ::testprefix rbupartial
           15  +
           16  +db close
           17  +sqlite3_shutdown
           18  +sqlite3_config_uri 1
           19  +
           20  +foreach {tn without_rowid a b c d} {
           21  +  1 ""              a b c d
           22  +  2 "WITHOUT ROWID" aaa bbb ccc ddd
           23  +  3 "WITHOUT ROWID" "\"hello\"" {"one'two"}  {[c]} ddd
           24  +  4 "WITHOUT ROWID" {`a b`} {"one'two"}  {[c c c]} ddd
           25  +  5 "" a b c {"d""d"}
           26  +  6 "" {'one''two'} b {"c""c"} {"d""d"}
           27  +} {
           28  +  eval [string map [list \
           29  +    %WITHOUT_ROWID% $without_rowid %A% $a %B% $b %C% $c %D% $d
           30  +  ] {
           31  +  reset_db
           32  +  do_execsql_test $tn.1.0 {
           33  +    CREATE TABLE t1(%A% PRIMARY KEY, %B%, %C%, %D%) %WITHOUT_ROWID% ;
           34  +    CREATE INDEX i1b  ON t1(%B%);
           35  +    CREATE INDEX i1b2 ON t1(%B%) WHERE %C%<5;
           36  +    CREATE INDEX i1b3 ON t1(%B%) WHERE %C%>=5;
           37  +
           38  +    CREATE INDEX i1c  ON t1(%C%);
           39  +    CREATE INDEX i1c2 ON t1(%C%) WHERE %C% IS NULL;
           40  +    CREATE INDEX i1c3 ON t1(%C%) WHERE %C% IS NOT NULL;
           41  +
           42  +    CREATE INDEX i1c4 ON t1(%C%) WHERE %D% < 'd';
           43  +  }
           44  +
           45  +  do_execsql_test $tn.1.1 {
           46  +    INSERT INTO t1 VALUES(0, NULL, NULL, 'a');
           47  +    INSERT INTO t1 VALUES(1, 2, 3, 'b');
           48  +    INSERT INTO t1 VALUES(4, 5, 6, 'c');
           49  +    INSERT INTO t1 VALUES(7, 8, 9, 'd');
           50  +  }
           51  +
           52  +  forcedelete rbu.db
           53  +  do_test $tn.1.2 {
           54  +    sqlite3 rbu rbu.db
           55  +    rbu eval {
           56  +      CREATE TABLE data_t1(%A%, %B%, %C%, %D%, rbu_control);
           57  +
           58  +      INSERT INTO data_t1 VALUES(10, 11, 12, 'e', 0);
           59  +      INSERT INTO data_t1 VALUES(13, 14, NULL, 'f', 0);
           60  +
           61  +      INSERT INTO data_t1 VALUES(0, NULL, NULL, NULL, 1);
           62  +      INSERT INTO data_t1 VALUES(4, NULL, NULL, NULL, 1);
           63  +
           64  +      INSERT INTO data_t1 VALUES(7, NULL, 4, NULL, '..x.');
           65  +      INSERT INTO data_t1 VALUES(1, 10, NULL, NULL, '.xx.');
           66  +    }
           67  +    rbu close
           68  +  } {}
           69  +
           70  +  do_test $tn.1.3 {
           71  +    run_rbu test.db rbu.db
           72  +    execsql { PRAGMA integrity_check }
           73  +  } {ok}
           74  +
           75  +  do_execsql_test $tn.1.4 {
           76  +    SELECT * FROM t1 ORDER BY %A%;
           77  +  } {
           78  +    1 10 {} b   7 8 4 d   10 11 12 e   13 14 {} f
           79  +  }
           80  +
           81  +  set step 0
           82  +  do_rbu_vacuum_test $tn.1.5 0
           83  +  }]
           84  +}
           85  +
           86  +finish_test

Changes to ext/rbu/sqlite3rbu.c.

   236    236   **     * a special "cleanup table" state.
   237    237   **
   238    238   ** abIndexed:
   239    239   **   If the table has no indexes on it, abIndexed is set to NULL. Otherwise,
   240    240   **   it points to an array of flags nTblCol elements in size. The flag is
   241    241   **   set for each column that is either a part of the PK or a part of an
   242    242   **   index. Or clear otherwise.
          243  +**
          244  +**   If there are one or more partial indexes on the table, all fields of
          245  +**   this array set set to 1. This is because in that case, the module has
          246  +**   no way to tell which fields will be required to add and remove entries
          247  +**   from the partial indexes.
   243    248   **   
   244    249   */
   245    250   struct RbuObjIter {
   246    251     sqlite3_stmt *pTblIter;         /* Iterate through tables */
   247    252     sqlite3_stmt *pIdxIter;         /* Index iterator */
   248    253     int nTblCol;                    /* Size of azTblCol[] array */
   249    254     char **azTblCol;                /* Array of unquoted target column names */
................................................................................
  1246   1251           sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl)
  1247   1252       );
  1248   1253     }
  1249   1254   
  1250   1255     pIter->nIndex = 0;
  1251   1256     while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pList) ){
  1252   1257       const char *zIdx = (const char*)sqlite3_column_text(pList, 1);
         1258  +    int bPartial = sqlite3_column_int(pList, 4);
  1253   1259       sqlite3_stmt *pXInfo = 0;
  1254   1260       if( zIdx==0 ) break;
         1261  +    if( bPartial ){
         1262  +      memset(pIter->abIndexed, 0x01, sizeof(u8)*pIter->nTblCol);
         1263  +    }
  1255   1264       p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
  1256   1265           sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx)
  1257   1266       );
  1258   1267       while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
  1259   1268         int iCid = sqlite3_column_int(pXInfo, 1);
  1260   1269         if( iCid>=0 ) pIter->abIndexed[iCid] = 1;
  1261   1270       }
................................................................................
  1953   1962       rc = sqlite3_reset(p->objiter.pTmpInsert);
  1954   1963     }
  1955   1964   
  1956   1965     if( rc!=SQLITE_OK ){
  1957   1966       sqlite3_result_error_code(pCtx, rc);
  1958   1967     }
  1959   1968   }
         1969  +
         1970  +static char *rbuObjIterGetIndexWhere(sqlite3rbu *p, RbuObjIter *pIter){
         1971  +  sqlite3_stmt *pStmt = 0;
         1972  +  int rc = p->rc;
         1973  +  char *zRet = 0;
         1974  +
         1975  +  if( rc==SQLITE_OK ){
         1976  +    rc = prepareAndCollectError(p->dbMain, &pStmt, &p->zErrmsg,
         1977  +        "SELECT trim(sql) FROM sqlite_master WHERE type='index' AND name=?"
         1978  +    );
         1979  +  }
         1980  +  if( rc==SQLITE_OK ){
         1981  +    int rc2;
         1982  +    rc = sqlite3_bind_text(pStmt, 1, pIter->zIdx, -1, SQLITE_STATIC);
         1983  +    if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
         1984  +      const char *zSql = (const char*)sqlite3_column_text(pStmt, 0);
         1985  +      if( zSql ){
         1986  +        int nParen = 0;           /* Number of open parenthesis */
         1987  +        int i;
         1988  +        for(i=0; zSql[i]; i++){
         1989  +          char c = zSql[i];
         1990  +          if( c=='(' ){
         1991  +            nParen++;
         1992  +          }
         1993  +          else if( c==')' ){
         1994  +            nParen--;
         1995  +            if( nParen==0 ){
         1996  +              i++;
         1997  +              break;
         1998  +            }
         1999  +          }else if( c=='"' || c=='\'' || c=='`' ){
         2000  +            for(i++; 1; i++){
         2001  +              if( zSql[i]==c ){
         2002  +                if( zSql[i+1]!=c ) break;
         2003  +                i++;
         2004  +              }
         2005  +            }
         2006  +          }else if( c=='[' ){
         2007  +            for(i++; 1; i++){
         2008  +              if( zSql[i]==']' ) break;
         2009  +            }
         2010  +          }
         2011  +        }
         2012  +        if( zSql[i] ){
         2013  +          zRet = rbuStrndup(&zSql[i], &rc);
         2014  +        }
         2015  +      }
         2016  +    }
         2017  +
         2018  +    rc2 = sqlite3_finalize(pStmt);
         2019  +    if( rc==SQLITE_OK ) rc = rc2;
         2020  +  }
         2021  +
         2022  +  p->rc = rc;
         2023  +  return zRet;
         2024  +}
  1960   2025   
  1961   2026   /*
  1962   2027   ** Ensure that the SQLite statement handles required to update the 
  1963   2028   ** target database object currently indicated by the iterator passed 
  1964   2029   ** as the second argument are available.
  1965   2030   */
  1966   2031   static int rbuObjIterPrepareAll(
................................................................................
  1983   2048   
  1984   2049       if( zIdx ){
  1985   2050         const char *zTbl = pIter->zTbl;
  1986   2051         char *zImposterCols = 0;    /* Columns for imposter table */
  1987   2052         char *zImposterPK = 0;      /* Primary key declaration for imposter */
  1988   2053         char *zWhere = 0;           /* WHERE clause on PK columns */
  1989   2054         char *zBind = 0;
         2055  +      char *zPart = 0;
  1990   2056         int nBind = 0;
  1991   2057   
  1992   2058         assert( pIter->eType!=RBU_PK_VTAB );
  1993   2059         zCollist = rbuObjIterGetIndexCols(
  1994   2060             p, pIter, &zImposterCols, &zImposterPK, &zWhere, &nBind
  1995   2061         );
  1996   2062         zBind = rbuObjIterGetBindlist(p, nBind);
         2063  +      zPart = rbuObjIterGetIndexWhere(p, pIter);
  1997   2064   
  1998   2065         /* Create the imposter table used to write to this index. */
  1999   2066         sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1);
  2000   2067         sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1,tnum);
  2001   2068         rbuMPrintfExec(p, p->dbMain,
  2002   2069             "CREATE TABLE \"rbu_imp_%w\"( %s, PRIMARY KEY( %s ) ) WITHOUT ROWID",
  2003   2070             zTbl, zImposterCols, zImposterPK
................................................................................
  2022   2089         }
  2023   2090   
  2024   2091         /* Create the SELECT statement to read keys in sorted order */
  2025   2092         if( p->rc==SQLITE_OK ){
  2026   2093           char *zSql;
  2027   2094           if( rbuIsVacuum(p) ){
  2028   2095             zSql = sqlite3_mprintf(
  2029         -              "SELECT %s, 0 AS rbu_control FROM '%q' ORDER BY %s%s",
         2096  +              "SELECT %s, 0 AS rbu_control FROM '%q' %s ORDER BY %s%s",
  2030   2097                 zCollist, 
  2031   2098                 pIter->zDataTbl,
  2032         -              zCollist, zLimit
         2099  +              zPart, zCollist, zLimit
  2033   2100             );
  2034   2101           }else
  2035   2102   
  2036   2103           if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){
  2037   2104             zSql = sqlite3_mprintf(
  2038         -              "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' ORDER BY %s%s",
         2105  +              "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' %s ORDER BY %s%s",
  2039   2106                 zCollist, p->zStateDb, pIter->zDataTbl,
  2040         -              zCollist, zLimit
         2107  +              zPart, zCollist, zLimit
  2041   2108             );
  2042   2109           }else{
  2043   2110             zSql = sqlite3_mprintf(
  2044         -              "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' "
         2111  +              "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' %s "
  2045   2112                 "UNION ALL "
  2046   2113                 "SELECT %s, rbu_control FROM '%q' "
  2047         -              "WHERE typeof(rbu_control)='integer' AND rbu_control!=1 "
         2114  +              "%s %s typeof(rbu_control)='integer' AND rbu_control!=1 "
  2048   2115                 "ORDER BY %s%s",
  2049         -              zCollist, p->zStateDb, pIter->zDataTbl, 
         2116  +              zCollist, p->zStateDb, pIter->zDataTbl, zPart,
  2050   2117                 zCollist, pIter->zDataTbl, 
         2118  +              zPart,
         2119  +              (zPart ? "AND" : "WHERE"),
  2051   2120                 zCollist, zLimit
  2052   2121             );
  2053   2122           }
  2054   2123           p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz, zSql);
  2055   2124         }
  2056   2125   
  2057   2126         sqlite3_free(zImposterCols);
  2058   2127         sqlite3_free(zImposterPK);
  2059   2128         sqlite3_free(zWhere);
  2060   2129         sqlite3_free(zBind);
         2130  +      sqlite3_free(zPart);
  2061   2131       }else{
  2062   2132         int bRbuRowid = (pIter->eType==RBU_PK_VTAB)
  2063   2133                       ||(pIter->eType==RBU_PK_NONE)
  2064   2134                       ||(pIter->eType==RBU_PK_EXTERNAL && rbuIsVacuum(p));
  2065   2135         const char *zTbl = pIter->zTbl;       /* Table this step applies to */
  2066   2136         const char *zWrite;                   /* Imposter table name */
  2067   2137   

Changes to main.mk.

   374    374     $(TOP)/ext/misc/regexp.c \
   375    375     $(TOP)/ext/misc/remember.c \
   376    376     $(TOP)/ext/misc/series.c \
   377    377     $(TOP)/ext/misc/spellfix.c \
   378    378     $(TOP)/ext/misc/totype.c \
   379    379     $(TOP)/ext/misc/unionvtab.c \
   380    380     $(TOP)/ext/misc/wholenumber.c \
   381         -  $(TOP)/ext/misc/vfslog.c \
   382    381     $(TOP)/ext/misc/zipfile.c \
   383    382     $(TOP)/ext/fts5/fts5_tcl.c \
   384    383     $(TOP)/ext/fts5/fts5_test_mi.c \
   385    384     $(TOP)/ext/fts5/fts5_test_tok.c
   386    385   
   387    386   
   388    387   #TESTSRC += $(TOP)/ext/fts2/fts2_tokenizer.c

Changes to src/btree.c.

  6166   6166   */
  6167   6167   static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
  6168   6168     MemPage *pTrunk = 0;                /* Free-list trunk page */
  6169   6169     Pgno iTrunk = 0;                    /* Page number of free-list trunk page */ 
  6170   6170     MemPage *pPage1 = pBt->pPage1;      /* Local reference to page 1 */
  6171   6171     MemPage *pPage;                     /* Page being freed. May be NULL. */
  6172   6172     int rc;                             /* Return Code */
  6173         -  int nFree;                          /* Initial number of pages on free-list */
         6173  +  u32 nFree;                          /* Initial number of pages on free-list */
  6174   6174   
  6175   6175     assert( sqlite3_mutex_held(pBt->mutex) );
  6176   6176     assert( CORRUPT_DB || iPage>1 );
  6177   6177     assert( !pMemPage || pMemPage->pgno==iPage );
  6178   6178   
  6179   6179     if( iPage<2 || iPage>pBt->nPage ){
  6180   6180       return SQLITE_CORRUPT_BKPT;

Changes to src/build.c.

  4394   4394     Index *pIdx       /* The index that triggers the constraint */
  4395   4395   ){
  4396   4396     char *zErr;
  4397   4397     int j;
  4398   4398     StrAccum errMsg;
  4399   4399     Table *pTab = pIdx->pTable;
  4400   4400   
  4401         -  sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200);
         4401  +  sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 
         4402  +                      pParse->db->aLimit[SQLITE_LIMIT_LENGTH]);
  4402   4403     if( pIdx->aColExpr ){
  4403   4404       sqlite3_str_appendf(&errMsg, "index '%q'", pIdx->zName);
  4404   4405     }else{
  4405   4406       for(j=0; j<pIdx->nKeyCol; j++){
  4406   4407         char *zCol;
  4407   4408         assert( pIdx->aiColumn[j]>=0 );
  4408   4409         zCol = pTab->aCol[pIdx->aiColumn[j]].zName;

Changes to src/printf.c.

   133    133   /*
   134    134   ** Set the StrAccum object to an error mode.
   135    135   */
   136    136   static void setStrAccumError(StrAccum *p, u8 eError){
   137    137     assert( eError==SQLITE_NOMEM || eError==SQLITE_TOOBIG );
   138    138     p->accError = eError;
   139    139     if( p->mxAlloc ) sqlite3_str_reset(p);
          140  +  if( eError==SQLITE_TOOBIG ) sqlite3ErrorToParser(p->db, eError);
   140    141   }
   141    142   
   142    143   /*
   143    144   ** Extra argument values from a PrintfArguments object
   144    145   */
   145    146   static sqlite3_int64 getIntArg(PrintfArguments *p){
   146    147     if( p->nArg<=p->nUsed ) return 0;

Changes to src/sqliteInt.h.

  3830   3830     void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8);
  3831   3831   #endif
  3832   3832   #endif
  3833   3833   
  3834   3834   
  3835   3835   void sqlite3SetString(char **, sqlite3*, const char*);
  3836   3836   void sqlite3ErrorMsg(Parse*, const char*, ...);
         3837  +int sqlite3ErrorToParser(sqlite3*,int);
  3837   3838   void sqlite3Dequote(char*);
  3838   3839   void sqlite3DequoteExpr(Expr*);
  3839   3840   void sqlite3TokenInit(Token*,char*);
  3840   3841   int sqlite3KeywordCode(const unsigned char*, int);
  3841   3842   int sqlite3RunParser(Parse*, const char*, char **);
  3842   3843   void sqlite3FinishCoding(Parse*);
  3843   3844   int sqlite3GetTempReg(Parse*);

Changes to src/test4.c.

    60     60   #define N_THREAD 26
    61     61   static Thread threadset[N_THREAD];
    62     62   
    63     63   
    64     64   /*
    65     65   ** The main loop for a thread.  Threads use busy waiting. 
    66     66   */
    67         -static void *thread_main(void *pArg){
           67  +static void *test_thread_main(void *pArg){
    68     68     Thread *p = (Thread*)pArg;
    69     69     if( p->db ){
    70     70       sqlite3_close(p->db);
    71     71     }
    72     72     sqlite3_open(p->zFilename, &p->db);
    73     73     if( SQLITE_OK!=sqlite3_errcode(p->db) ){
    74     74       p->zErr = strdup(sqlite3_errmsg(p->db));
................................................................................
   147    147       return TCL_ERROR;
   148    148     }
   149    149     threadset[i].busy = 1;
   150    150     sqlite3_free(threadset[i].zFilename);
   151    151     threadset[i].zFilename = sqlite3_mprintf("%s", argv[2]);
   152    152     threadset[i].opnum = 1;
   153    153     threadset[i].completed = 0;
   154         -  rc = pthread_create(&x, 0, thread_main, &threadset[i]);
          154  +  rc = pthread_create(&x, 0, test_thread_main, &threadset[i]);
   155    155     if( rc ){
   156    156       Tcl_AppendResult(interp, "failed to create the thread", 0);
   157    157       sqlite3_free(threadset[i].zFilename);
   158    158       threadset[i].busy = 0;
   159    159       return TCL_ERROR;
   160    160     }
   161    161     pthread_detach(x);
   162    162     return TCL_OK;
   163    163   }
   164    164   
   165    165   /*
   166    166   ** Wait for a thread to reach its idle state.
   167    167   */
   168         -static void thread_wait(Thread *p){
          168  +static void test_thread_wait(Thread *p){
   169    169     while( p->opnum>p->completed ) sched_yield();
   170    170   }
   171    171   
   172    172   /*
   173    173   ** Usage:  thread_wait ID
   174    174   **
   175    175   ** Wait on thread ID to reach its idle state.
................................................................................
   189    189     }
   190    190     i = parse_thread_id(interp, argv[1]);
   191    191     if( i<0 ) return TCL_ERROR;
   192    192     if( !threadset[i].busy ){
   193    193       Tcl_AppendResult(interp, "no such thread", 0);
   194    194       return TCL_ERROR;
   195    195     }
   196         -  thread_wait(&threadset[i]);
          196  +  test_thread_wait(&threadset[i]);
   197    197     return TCL_OK;
   198    198   }
   199    199   
   200    200   /*
   201    201   ** Stop a thread.
   202    202   */
   203         -static void stop_thread(Thread *p){
   204         -  thread_wait(p);
          203  +static void test_stop_thread(Thread *p){
          204  +  test_thread_wait(p);
   205    205     p->xOp = 0;
   206    206     p->opnum++;
   207         -  thread_wait(p);
          207  +  test_thread_wait(p);
   208    208     sqlite3_free(p->zArg);
   209    209     p->zArg = 0;
   210    210     sqlite3_free(p->zFilename);
   211    211     p->zFilename = 0;
   212    212     p->busy = 0;
   213    213   }
   214    214   
................................................................................
   229    229     if( argc!=2 ){
   230    230       Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
   231    231          " ID", 0);
   232    232       return TCL_ERROR;
   233    233     }
   234    234     if( argv[1][0]=='*' && argv[1][1]==0 ){
   235    235       for(i=0; i<N_THREAD; i++){
   236         -      if( threadset[i].busy ) stop_thread(&threadset[i]);
          236  +      if( threadset[i].busy ) test_stop_thread(&threadset[i]);
   237    237       }
   238    238     }else{
   239    239       i = parse_thread_id(interp, argv[1]);
   240    240       if( i<0 ) return TCL_ERROR;
   241    241       if( !threadset[i].busy ){
   242    242         Tcl_AppendResult(interp, "no such thread", 0);
   243    243         return TCL_ERROR;
   244    244       }
   245         -    stop_thread(&threadset[i]);
          245  +    test_stop_thread(&threadset[i]);
   246    246     }
   247    247     return TCL_OK;
   248    248   }
   249    249   
   250    250   /*
   251    251   ** Usage: thread_argc  ID
   252    252   **
................................................................................
   269    269     }
   270    270     i = parse_thread_id(interp, argv[1]);
   271    271     if( i<0 ) return TCL_ERROR;
   272    272     if( !threadset[i].busy ){
   273    273       Tcl_AppendResult(interp, "no such thread", 0);
   274    274       return TCL_ERROR;
   275    275     }
   276         -  thread_wait(&threadset[i]);
          276  +  test_thread_wait(&threadset[i]);
   277    277     sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", threadset[i].argc);
   278    278     Tcl_AppendResult(interp, zBuf, 0);
   279    279     return TCL_OK;
   280    280   }
   281    281   
   282    282   /*
   283    283   ** Usage: thread_argv  ID   N
................................................................................
   302    302     i = parse_thread_id(interp, argv[1]);
   303    303     if( i<0 ) return TCL_ERROR;
   304    304     if( !threadset[i].busy ){
   305    305       Tcl_AppendResult(interp, "no such thread", 0);
   306    306       return TCL_ERROR;
   307    307     }
   308    308     if( Tcl_GetInt(interp, argv[2], &n) ) return TCL_ERROR;
   309         -  thread_wait(&threadset[i]);
          309  +  test_thread_wait(&threadset[i]);
   310    310     if( n<0 || n>=threadset[i].argc ){
   311    311       Tcl_AppendResult(interp, "column number out of range", 0);
   312    312       return TCL_ERROR;
   313    313     }
   314    314     Tcl_AppendResult(interp, threadset[i].argv[n], 0);
   315    315     return TCL_OK;
   316    316   }
................................................................................
   338    338     i = parse_thread_id(interp, argv[1]);
   339    339     if( i<0 ) return TCL_ERROR;
   340    340     if( !threadset[i].busy ){
   341    341       Tcl_AppendResult(interp, "no such thread", 0);
   342    342       return TCL_ERROR;
   343    343     }
   344    344     if( Tcl_GetInt(interp, argv[2], &n) ) return TCL_ERROR;
   345         -  thread_wait(&threadset[i]);
          345  +  test_thread_wait(&threadset[i]);
   346    346     if( n<0 || n>=threadset[i].argc ){
   347    347       Tcl_AppendResult(interp, "column number out of range", 0);
   348    348       return TCL_ERROR;
   349    349     }
   350    350     Tcl_AppendResult(interp, threadset[i].colv[n], 0);
   351    351     return TCL_OK;
   352    352   }
................................................................................
   373    373     }
   374    374     i = parse_thread_id(interp, argv[1]);
   375    375     if( i<0 ) return TCL_ERROR;
   376    376     if( !threadset[i].busy ){
   377    377       Tcl_AppendResult(interp, "no such thread", 0);
   378    378       return TCL_ERROR;
   379    379     }
   380         -  thread_wait(&threadset[i]);
          380  +  test_thread_wait(&threadset[i]);
   381    381     zName = sqlite3ErrName(threadset[i].rc);
   382    382     Tcl_AppendResult(interp, zName, 0);
   383    383     return TCL_OK;
   384    384   }
   385    385   
   386    386   /*
   387    387   ** Usage: thread_error  ID
................................................................................
   404    404     }
   405    405     i = parse_thread_id(interp, argv[1]);
   406    406     if( i<0 ) return TCL_ERROR;
   407    407     if( !threadset[i].busy ){
   408    408       Tcl_AppendResult(interp, "no such thread", 0);
   409    409       return TCL_ERROR;
   410    410     }
   411         -  thread_wait(&threadset[i]);
          411  +  test_thread_wait(&threadset[i]);
   412    412     Tcl_AppendResult(interp, threadset[i].zErr, 0);
   413    413     return TCL_OK;
   414    414   }
   415    415   
   416    416   /*
   417    417   ** This procedure runs in the thread to compile an SQL statement.
   418    418   */
................................................................................
   448    448     }
   449    449     i = parse_thread_id(interp, argv[1]);
   450    450     if( i<0 ) return TCL_ERROR;
   451    451     if( !threadset[i].busy ){
   452    452       Tcl_AppendResult(interp, "no such thread", 0);
   453    453       return TCL_ERROR;
   454    454     }
   455         -  thread_wait(&threadset[i]);
          455  +  test_thread_wait(&threadset[i]);
   456    456     threadset[i].xOp = do_compile;
   457    457     sqlite3_free(threadset[i].zArg);
   458    458     threadset[i].zArg = sqlite3_mprintf("%s", argv[2]);
   459    459     threadset[i].opnum++;
   460    460     return TCL_OK;
   461    461   }
   462    462   
................................................................................
   501    501     }
   502    502     i = parse_thread_id(interp, argv[1]);
   503    503     if( i<0 ) return TCL_ERROR;
   504    504     if( !threadset[i].busy ){
   505    505       Tcl_AppendResult(interp, "no such thread", 0);
   506    506       return TCL_ERROR;
   507    507     }
   508         -  thread_wait(&threadset[i]);
          508  +  test_thread_wait(&threadset[i]);
   509    509     threadset[i].xOp = do_step;
   510    510     threadset[i].opnum++;
   511    511     return TCL_OK;
   512    512   }
   513    513   
   514    514   /*
   515    515   ** This procedure runs in the thread to finalize a virtual machine.
................................................................................
   543    543     }
   544    544     i = parse_thread_id(interp, argv[1]);
   545    545     if( i<0 ) return TCL_ERROR;
   546    546     if( !threadset[i].busy ){
   547    547       Tcl_AppendResult(interp, "no such thread", 0);
   548    548       return TCL_ERROR;
   549    549     }
   550         -  thread_wait(&threadset[i]);
          550  +  test_thread_wait(&threadset[i]);
   551    551     threadset[i].xOp = do_finalize;
   552    552     sqlite3_free(threadset[i].zArg);
   553    553     threadset[i].zArg = 0;
   554    554     threadset[i].opnum++;
   555    555     return TCL_OK;
   556    556   }
   557    557   
................................................................................
   575    575     }
   576    576     i = parse_thread_id(interp, argv[1]);
   577    577     if( i<0 ) return TCL_ERROR;
   578    578     if( !threadset[i].busy ){
   579    579       Tcl_AppendResult(interp, "no such thread", 0);
   580    580       return TCL_ERROR;
   581    581     }
   582         -  thread_wait(&threadset[i]);
          582  +  test_thread_wait(&threadset[i]);
   583    583     j = parse_thread_id(interp, argv[2]);
   584    584     if( j<0 ) return TCL_ERROR;
   585    585     if( !threadset[j].busy ){
   586    586       Tcl_AppendResult(interp, "no such thread", 0);
   587    587       return TCL_ERROR;
   588    588     }
   589         -  thread_wait(&threadset[j]);
          589  +  test_thread_wait(&threadset[j]);
   590    590     temp = threadset[i].db;
   591    591     threadset[i].db = threadset[j].db;
   592    592     threadset[j].db = temp;
   593    593     return TCL_OK;
   594    594   }
   595    595   
   596    596   /*
................................................................................
   616    616     }
   617    617     i = parse_thread_id(interp, argv[1]);
   618    618     if( i<0 ) return TCL_ERROR;
   619    619     if( !threadset[i].busy ){
   620    620       Tcl_AppendResult(interp, "no such thread", 0);
   621    621       return TCL_ERROR;
   622    622     }
   623         -  thread_wait(&threadset[i]);
          623  +  test_thread_wait(&threadset[i]);
   624    624     sqlite3TestMakePointerStr(interp, zBuf, threadset[i].db);
   625    625     threadset[i].db = 0;
   626    626     Tcl_AppendResult(interp, zBuf, (char*)0);
   627    627     return TCL_OK;
   628    628   }
   629    629   
   630    630   /*
................................................................................
   647    647     }
   648    648     i = parse_thread_id(interp, argv[1]);
   649    649     if( i<0 ) return TCL_ERROR;
   650    650     if( !threadset[i].busy ){
   651    651       Tcl_AppendResult(interp, "no such thread", 0);
   652    652       return TCL_ERROR;
   653    653     }
   654         -  thread_wait(&threadset[i]);
          654  +  test_thread_wait(&threadset[i]);
   655    655     assert( !threadset[i].db );
   656    656     threadset[i].db = (sqlite3*)sqlite3TestTextToPtr(argv[2]);
   657    657     return TCL_OK;
   658    658   }
   659    659   
   660    660   /*
   661    661   ** Usage: thread_stmt_get ID
................................................................................
   679    679     }
   680    680     i = parse_thread_id(interp, argv[1]);
   681    681     if( i<0 ) return TCL_ERROR;
   682    682     if( !threadset[i].busy ){
   683    683       Tcl_AppendResult(interp, "no such thread", 0);
   684    684       return TCL_ERROR;
   685    685     }
   686         -  thread_wait(&threadset[i]);
          686  +  test_thread_wait(&threadset[i]);
   687    687     sqlite3TestMakePointerStr(interp, zBuf, threadset[i].pStmt);
   688    688     threadset[i].pStmt = 0;
   689    689     Tcl_AppendResult(interp, zBuf, (char*)0);
   690    690     return TCL_OK;
   691    691   }
   692    692   
   693    693   /*

Changes to src/util.c.

   228    228     }else{
   229    229       pParse->nErr++;
   230    230       sqlite3DbFree(db, pParse->zErrMsg);
   231    231       pParse->zErrMsg = zMsg;
   232    232       pParse->rc = SQLITE_ERROR;
   233    233     }
   234    234   }
          235  +
          236  +/*
          237  +** If database connection db is currently parsing SQL, then transfer
          238  +** error code errCode to that parser if the parser has not already
          239  +** encountered some other kind of error.
          240  +*/
          241  +int sqlite3ErrorToParser(sqlite3 *db, int errCode){
          242  +  Parse *pParse;
          243  +  if( db==0 || (pParse = db->pParse)==0 ) return errCode;
          244  +  pParse->rc = errCode;
          245  +  pParse->nErr++;
          246  +  return errCode;
          247  +}
   235    248   
   236    249   /*
   237    250   ** Convert an SQL-style quoted string into a normal string by removing
   238    251   ** the quote characters.  The conversion is done in-place.  If the
   239    252   ** input does not begin with a quote character, then this routine
   240    253   ** is a no-op.
   241    254   **

Changes to src/vdbemem.c.

   188    188   SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
   189    189     assert( sqlite3VdbeCheckMemInvariants(pMem) );
   190    190     assert( !sqlite3VdbeMemIsRowSet(pMem) );
   191    191     testcase( pMem->db==0 );
   192    192   
   193    193     /* If the bPreserve flag is set to true, then the memory cell must already
   194    194     ** contain a valid string or blob value.  */
   195         -  assert( bPreserve==0 
   196         -       || pMem->flags&(MEM_Blob|MEM_Str)
   197         -       || MemNullNochng(pMem)
   198         -  );
          195  +  assert( bPreserve==0 || pMem->flags&(MEM_Blob|MEM_Str) );
   199    196     testcase( bPreserve && pMem->z==0 );
   200    197   
   201    198     assert( pMem->szMalloc==0
   202    199          || pMem->szMalloc==sqlite3DbMallocSize(pMem->db, pMem->zMalloc) );
   203    200     if( pMem->szMalloc>0 && bPreserve && pMem->z==pMem->zMalloc ){
   204    201       pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
   205    202       bPreserve = 0;
................................................................................
   305    302     testcase( sqlite3_value_nochange(pMem) );
   306    303     assert( !sqlite3VdbeMemIsRowSet(pMem) );
   307    304     assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
   308    305   
   309    306     /* Set nByte to the number of bytes required to store the expanded blob. */
   310    307     nByte = pMem->n + pMem->u.nZero;
   311    308     if( nByte<=0 ){
          309  +    if( (pMem->flags & MEM_Blob)==0 ) return SQLITE_OK;
   312    310       nByte = 1;
   313    311     }
   314    312     if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){
   315    313       return SQLITE_NOMEM_BKPT;
   316    314     }
   317    315   
   318    316     memset(&pMem->z[pMem->n], 0, pMem->u.nZero);
................................................................................
  1061   1059     */
  1062   1060     if( xDel==SQLITE_TRANSIENT ){
  1063   1061       u32 nAlloc = nByte;
  1064   1062       if( flags&MEM_Term ){
  1065   1063         nAlloc += (enc==SQLITE_UTF8?1:2);
  1066   1064       }
  1067   1065       if( nByte>iLimit ){
  1068         -      return SQLITE_TOOBIG;
         1066  +      return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG);
  1069   1067       }
  1070   1068       testcase( nAlloc==0 );
  1071   1069       testcase( nAlloc==31 );
  1072   1070       testcase( nAlloc==32 );
  1073   1071       if( sqlite3VdbeMemClearAndResize(pMem, (int)MAX(nAlloc,32)) ){
  1074   1072         return SQLITE_NOMEM_BKPT;
  1075   1073       }

Changes to test/sqllimits1.test.

   885    885     ))))
   886    886   } "1 {too many columns in result set}"
   887    887   
   888    888   
   889    889   foreach {key value} [array get saved] {
   890    890     catch {set $key $value}
   891    891   }
          892  +
          893  +#-------------------------------------------------------------------------
          894  +# At one point the following caused an assert() to fail.
          895  +#
          896  +sqlite3_limit db SQLITE_LIMIT_LENGTH 10000
          897  +set nm [string repeat x 10000]
          898  +do_catchsql_test sqllimits1-17.1 "
          899  +  CREATE TABLE $nm (x PRIMARY KEY)
          900  +" {1 {string or blob too big}}
          901  +
   892    902   finish_test

Changes to tool/omittest.tcl.

   188    188       SQLITE_OMIT_AUTOINIT \
   189    189       SQLITE_OMIT_AUTOMATIC_INDEX \
   190    190       SQLITE_OMIT_AUTORESET \
   191    191       SQLITE_OMIT_AUTOVACUUM \
   192    192       SQLITE_OMIT_BETWEEN_OPTIMIZATION \
   193    193       SQLITE_OMIT_BLOB_LITERAL \
   194    194       SQLITE_OMIT_BTREECOUNT \
   195         -    SQLITE_OMIT_BUILTIN_TEST \
   196    195       SQLITE_OMIT_CAST \
   197    196       SQLITE_OMIT_CHECK \
   198    197       SQLITE_OMIT_COMPILEOPTION_DIAGS \
   199    198       SQLITE_OMIT_COMPLETE \
   200    199       SQLITE_OMIT_COMPOUND_SELECT \
          200  +    SQLITE_OMIT_CONFLICT_CLAUSE \
   201    201       SQLITE_OMIT_CTE \
   202    202       SQLITE_OMIT_DATETIME_FUNCS \
   203    203       SQLITE_OMIT_DECLTYPE \
   204    204       SQLITE_OMIT_DEPRECATED \
          205  +    SQLITE_OMIT_DISKIO \
   205    206       SQLITE_OMIT_EXPLAIN \
   206    207       SQLITE_OMIT_FLAG_PRAGMAS \
   207    208       SQLITE_OMIT_FLOATING_POINT \
   208    209       SQLITE_OMIT_FOREIGN_KEY \
   209    210       SQLITE_OMIT_GET_TABLE \
          211  +    SQLITE_OMIT_HEX_INTEGER \
   210    212       SQLITE_OMIT_INCRBLOB \
   211    213       SQLITE_OMIT_INTEGRITY_CHECK \
   212    214       SQLITE_OMIT_LIKE_OPTIMIZATION \
   213    215       SQLITE_OMIT_LOAD_EXTENSION \
   214    216       SQLITE_OMIT_LOCALTIME \
   215    217       SQLITE_OMIT_LOOKASIDE \
   216    218       SQLITE_OMIT_MEMORYDB \
          219  +    SQLITE_OMIT_MEMORY_ALLOCATION \
   217    220       SQLITE_OMIT_OR_OPTIMIZATION \
   218    221       SQLITE_OMIT_PAGER_PRAGMAS \
          222  +    SQLITE_OMIT_PARSER_TRACE \
          223  +    SQLITE_OMIT_POPEN \
   219    224       SQLITE_OMIT_PRAGMA \
   220    225       SQLITE_OMIT_PROGRESS_CALLBACK \
   221    226       SQLITE_OMIT_QUICKBALANCE \
          227  +    SQLITE_OMIT_RANDOMNESS \
   222    228       SQLITE_OMIT_REINDEX \
   223    229       SQLITE_OMIT_SCHEMA_PRAGMAS \
   224    230       SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS \
   225    231       SQLITE_OMIT_SHARED_CACHE \
          232  +    SQLITE_OMIT_SHUTDOWN_DIRECTORIES \
   226    233       SQLITE_OMIT_SUBQUERY \
   227    234       SQLITE_OMIT_TCL_VARIABLE \
   228    235       SQLITE_OMIT_TEMPDB \
          236  +    SQLITE_OMIT_TEST_CONTROL \
   229    237       SQLITE_OMIT_TRACE \
   230    238       SQLITE_OMIT_TRIGGER \
   231    239       SQLITE_OMIT_TRUNCATE_OPTIMIZATION \
   232         -    SQLITE_OMIT_UNIQUE_ENFORCEMENT \
          240  +    SQLITE_OMIT_UPSERT \
   233    241       SQLITE_OMIT_UTF16 \
   234    242       SQLITE_OMIT_VACUUM \
   235    243       SQLITE_OMIT_VIEW \
   236    244       SQLITE_OMIT_VIRTUALTABLE \
   237    245       SQLITE_OMIT_WAL \
          246  +    SQLITE_OMIT_WINDOWFUNC \
   238    247       SQLITE_OMIT_WSD \
   239    248       SQLITE_OMIT_XFER_OPT \
   240    249     ]
   241    250   
   242    251     set ::ENABLE_SYMBOLS [list \
   243    252       SQLITE_DISABLE_DIRSYNC \
   244    253       SQLITE_DISABLE_LFS \