/ Check-in [c91065f8]
Login

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

Overview
Comment:Merge all the latest trunk enhancements into the sessions branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | sessions
Files: files | file ages | folders
SHA1: c91065f8edb1e54076791716fc20d3fcfe3070dc
User & Date: drh 2015-09-24 14:26:51
Context
2015-09-30
14:50
Merge recent enhancements from trunk, and especially the fix for ticket [1b266395d6bc10]. check-in: b2face9a user: drh tags: sessions
2015-09-24
14:26
Merge all the latest trunk enhancements into the sessions branch. check-in: c91065f8 user: drh tags: sessions
12:40
Strengthen the implementations of xShmMemoryBarrier on both the unix and windows VFSes, so that they likely work even if SQLITE_THREADSAFE=0 is used. check-in: c6ab807b user: drh tags: trunk
2015-09-15
15:55
Merge the latest trunk enhancements with this branch. check-in: b7469c44 user: dan tags: sessions
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.in.

   541    541     sqldiff$(TEXE)
   542    542   
   543    543   # Databases containing fuzzer test cases
   544    544   #
   545    545   FUZZDATA = \
   546    546     $(TOP)/test/fuzzdata1.db \
   547    547     $(TOP)/test/fuzzdata2.db \
   548         -  $(TOP)/test/fuzzdata3.db
          548  +  $(TOP)/test/fuzzdata3.db \
          549  +  $(TOP)/test/fuzzdata4.db
          550  +
          551  +# Extra arguments for including json1 in the build of tools
          552  +#
          553  +JSON1_DEP = $(TOP)/ext/misc/json1.c sqlite3ext.h
          554  +JSON1_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_CORE
          555  +JSON1_SRC = $(TOP)/ext/misc/json1.c
   549    556   
   550    557   # Standard options to testfixture
   551    558   #
   552    559   TESTOPTS = --verbose=file --output=test-out.txt
   553    560   
   554    561   # This is the default Makefile target.  The objects listed here
   555    562   # are what get build when you type just "make" with no arguments.
................................................................................
   569    576   libtclsqlite3.la:	tclsqlite.lo libsqlite3.la
   570    577   	$(LTLINK) -no-undefined -o $@ tclsqlite.lo \
   571    578   		libsqlite3.la @TCL_STUB_LIB_SPEC@ $(TLIBS) \
   572    579   		-rpath "$(TCLLIBDIR)" \
   573    580   		-version-info "8:6:8" \
   574    581   		-avoid-version
   575    582   
   576         -sqlite3$(TEXE):	$(TOP)/src/shell.c libsqlite3.la sqlite3.h $(TOP)/ext/misc/json1.c
   577         -	$(LTLINK) $(READLINE_FLAGS) -DSQLITE_ENABLE_JSON1 -o $@ \
   578         -		$(TOP)/src/shell.c $(TOP)/ext/misc/json1.c libsqlite3.la \
          583  +sqlite3$(TEXE):	$(TOP)/src/shell.c libsqlite3.la sqlite3.h $(JSON1_DEP)
          584  +	$(LTLINK) $(READLINE_FLAGS) $(JSON1_OPT) -o $@ \
          585  +		$(TOP)/src/shell.c $(JSON1_SRC) libsqlite3.la \
   579    586   		$(LIBREADLINE) $(TLIBS) -rpath "$(libdir)"
   580    587   
   581    588   sqldiff$(TEXE):	$(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h
   582    589   	$(LTLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS)
   583    590   
   584         -fuzzershell$(TEXE):	$(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h
   585         -	$(LTLINK) -o $@ $(TOP)/tool/fuzzershell.c sqlite3.c $(TLIBS)
          591  +fuzzershell$(TEXE):	$(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h $(JSON1_DEP)
          592  +	$(LTLINK) -o $@ $(JSON1_OPT) \
          593  +	  $(TOP)/tool/fuzzershell.c $(JSON1_SRC) sqlite3.c $(TLIBS)
   586    594   
   587         -fuzzcheck$(TEXE):	$(TOP)/test/fuzzcheck.c sqlite3.c sqlite3.h
   588         -	$(LTLINK) -o $@ $(TOP)/test/fuzzcheck.c sqlite3.c $(TLIBS)
          595  +fuzzcheck$(TEXE):	$(TOP)/test/fuzzcheck.c sqlite3.c sqlite3.h $(JSON1_DEP)
          596  +	$(LTLINK) -o $@ $(JSON1_OPT) $(TOP)/test/fuzzcheck.c $(JSON1_SRC) sqlite3.c $(TLIBS)
   589    597   
   590    598   mptester$(TEXE):	sqlite3.c $(TOP)/mptest/mptest.c
   591    599   	$(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
   592    600   		$(TLIBS) -rpath "$(libdir)"
   593    601   
   594    602   MPTEST1=./mptester$(TEXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20
   595    603   MPTEST2=./mptester$(TEXE) mptest.db $(TOP)/mptest/multiwrite01.test --repeat 20

Changes to Makefile.msc.

  1227   1227     sqldiff.exe
  1228   1228   
  1229   1229   # Databases containing fuzzer test cases
  1230   1230   #
  1231   1231   FUZZDATA = \
  1232   1232     $(TOP)\test\fuzzdata1.db \
  1233   1233     $(TOP)\test\fuzzdata2.db \
  1234         -  $(TOP)\test\fuzzdata3.db
         1234  +  $(TOP)\test\fuzzdata3.db \
         1235  +  $(TOP)\test\fuzzdata4.db
         1236  +
         1237  +# Extra arguments for including json1 in the build of tools
         1238  +#
         1239  +JSON1_DEP = sqlite3ext.h $(TOP)\ext\misc\json1.c
         1240  +JSON1_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_CORE
         1241  +JSON1_SRC = $(TOP)\ext\misc\json1.c
  1235   1242   
  1236   1243   # Standard options to testfixture
  1237   1244   #
  1238   1245   TESTOPTS = --verbose=file --output=test-out.txt
  1239   1246   
  1240   1247   # This is the default Makefile target.  The objects listed here
  1241   1248   # are what get build when you type just "make" with no arguments.
................................................................................
  1244   1251   
  1245   1252   libsqlite3.lib:	$(LIBOBJ)
  1246   1253   	$(LTLIB) $(LTLIBOPTS) /OUT:$@ $(LIBOBJ) $(TLIBS)
  1247   1254   
  1248   1255   libtclsqlite3.lib:	tclsqlite.lo libsqlite3.lib
  1249   1256   	$(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCL:tcl=tclstub) $(TLIBS)
  1250   1257   
  1251         -sqlite3.exe:	$(TOP)\src\shell.c $(TOP)\ext\misc\json1.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h
  1252         -	$(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\src\shell.c $(TOP)\ext\misc\json1.c \
         1258  +sqlite3.exe:	$(TOP)\src\shell.c $(JSON1_DEP) $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h
         1259  +	$(LTLINK) $(SHELL_COMPILE_OPTS) $(JSON1_OPT) $(READLINE_FLAGS) $(TOP)\src\shell.c $(JSON1_SRC) \
  1253   1260   		/link /pdb:sqlite3sh.pdb $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
  1254   1261   
  1255   1262   sqldiff.exe:	$(TOP)\tool\sqldiff.c sqlite3.c sqlite3.h
  1256   1263   	$(LTLINK) $(NO_WARN) $(TOP)\tool\sqldiff.c sqlite3.c
  1257   1264   
  1258         -fuzzershell.exe:	$(TOP)\tool\fuzzershell.c sqlite3.c sqlite3.h
  1259         -	$(LTLINK) $(NO_WARN) $(TOP)\tool\fuzzershell.c sqlite3.c
         1265  +fuzzershell.exe:	$(TOP)\tool\fuzzershell.c sqlite3.c sqlite3.h $(JSON1_DEP)
         1266  +	$(LTLINK) $(NO_WARN) $(JSON1_OPT) \
         1267  +	  $(TOP)\tool\fuzzershell.c $(JSON1_SRC) sqlite3.c
  1260   1268   
  1261         -fuzzcheck.exe:	$(TOP)\test\fuzzcheck.c sqlite3.c sqlite3.h
  1262         -	$(LTLINK) $(NO_WARN) $(TOP)\test\fuzzcheck.c sqlite3.c
         1269  +fuzzcheck.exe:	$(TOP)\test\fuzzcheck.c sqlite3.c sqlite3.h $(JSON1_DEP)
         1270  +	$(LTLINK) $(NO_WARN) $(JSON1_OPT) $(TOP)\test\fuzzcheck.c $(JSON1_SRC) sqlite3.c
  1263   1271   
  1264   1272   mptester.exe:	$(TOP)\mptest\mptest.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h
  1265   1273   	$(LTLINK) $(NO_WARN) $(SHELL_COMPILE_OPTS) $(TOP)\mptest\mptest.c \
  1266   1274   		/link $(LTLINKOPTS) $(LTLIBPATHS) $(SHELL_LINK_OPTS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
  1267   1275   
  1268   1276   MPTEST1 = mptester mptest.db $(TOP)\mptest\crash01.test --repeat 20
  1269   1277   MPTEST2 = mptester mptest.db $(TOP)\mptest\multiwrite01.test --repeat 20
................................................................................
  1294   1302   	for %i in ($(SRC4)) do copy /Y %i tsrc
  1295   1303   	for %i in ($(SRC5)) do copy /Y %i tsrc
  1296   1304   	del /Q tsrc\sqlite.h.in tsrc\parse.y 2>NUL
  1297   1305   	$(TCLSH_CMD) $(TOP)\tool\vdbe-compress.tcl $(OPTS) < tsrc\vdbe.c > vdbe.new
  1298   1306   	move vdbe.new tsrc\vdbe.c
  1299   1307   	echo > .target_source
  1300   1308   
  1301         -sqlite3.c:	.target_source $(TOP)\tool\mksqlite3c.tcl
         1309  +sqlite3.c:	.target_source sqlite3ext.h $(TOP)\tool\mksqlite3c.tcl
  1302   1310   	$(TCLSH_CMD) $(TOP)\tool\mksqlite3c.tcl $(MKSQLITE3C_ARGS)
  1303   1311   	copy tsrc\shell.c .
  1304         -	copy tsrc\sqlite3ext.h .
  1305   1312   	copy $(TOP)\ext\session\sqlite3session.h .
  1306   1313   
  1307   1314   sqlite3-all.c:	sqlite3.c $(TOP)\tool\split-sqlite3c.tcl
  1308   1315   	$(TCLSH_CMD) $(TOP)\tool\split-sqlite3c.tcl
  1309   1316   
  1310   1317   # Set the source code file to be used by executables and libraries when
  1311   1318   # they need the amalgamation.
................................................................................
  1605   1612   	copy $(TOP)\src\parse.y .
  1606   1613   	.\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) parse.y
  1607   1614   	move parse.h parse.h.temp
  1608   1615   	$(NAWK) -f $(TOP)\addopcodes.awk parse.h.temp > parse.h
  1609   1616   
  1610   1617   sqlite3.h:	$(TOP)\src\sqlite.h.in $(TOP)\manifest.uuid $(TOP)\VERSION
  1611   1618   	$(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > sqlite3.h
         1619  +
         1620  +sqlite3ext.h: .target_source
         1621  +	copy tsrc\sqlite3ext.h .
  1612   1622   
  1613   1623   mkkeywordhash.exe:	$(TOP)\tool\mkkeywordhash.c
  1614   1624   	$(BCC) $(NO_WARN) -Fe$@ $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) \
  1615   1625   		$(TOP)\tool\mkkeywordhash.c /link $(NLTLINKOPTS) $(NLTLIBPATHS)
  1616   1626   
  1617   1627   keywordhash.h:	$(TOP)\tool\mkkeywordhash.c mkkeywordhash.exe
  1618   1628   	.\mkkeywordhash.exe > keywordhash.h

Changes to ext/fts5/fts5.h.

   380    380   **            This way, even if the tokenizer does not provide synonyms
   381    381   **            when tokenizing query text (it should not - to do would be
   382    382   **            inefficient), it doesn't matter if the user queries for 
   383    383   **            'first + place' or '1st + place', as there are entires in the
   384    384   **            FTS index corresponding to both forms of the first token.
   385    385   **   </ol>
   386    386   **
   387         -**   Whether is is parsing document or query text, any call to xToken that
          387  +**   Whether it is parsing document or query text, any call to xToken that
   388    388   **   specifies a <i>tflags</i> argument with the FTS5_TOKEN_COLOCATED bit
   389    389   **   is considered to supply a synonym for the previous token. For example,
   390    390   **   when parsing the document "I won first place", a tokenizer that supports
   391    391   **   synonyms would call xToken() 5 times, as follows:
   392    392   **
   393    393   **   <codeblock>
   394    394   **       xToken(pCtx, 0, "i",                      1,  0,  1);

Changes to ext/fts5/fts5_main.c.

  1112   1112       assert( pCsr->iLastRowid==LARGEST_INT64 );
  1113   1113       assert( pCsr->iFirstRowid==SMALLEST_INT64 );
  1114   1114       pCsr->ePlan = FTS5_PLAN_SOURCE;
  1115   1115       pCsr->pExpr = pTab->pSortCsr->pExpr;
  1116   1116       rc = fts5CursorFirst(pTab, pCsr, bDesc);
  1117   1117     }else if( pMatch ){
  1118   1118       const char *zExpr = (const char*)sqlite3_value_text(apVal[0]);
         1119  +    if( zExpr==0 ) zExpr = "";
  1119   1120   
  1120   1121       rc = fts5CursorParseRank(pConfig, pCsr, pRank);
  1121   1122       if( rc==SQLITE_OK ){
  1122   1123         if( zExpr[0]=='*' ){
  1123   1124           /* The user has issued a query of the form "MATCH '*...'". This
  1124   1125           ** indicates that the MATCH expression is not a full text query,
  1125   1126           ** but a request for an internal parameter.  */

Changes to ext/fts5/test/fts5simple.test.

   164    164     INSERT INTO tt(tt, rank) VALUES('pgsz', 32);
   165    165     INSERT INTO tt VALUES('aa ab ac ad ae af');
   166    166   }
   167    167   
   168    168   do_execsql_test 5.8 {
   169    169     SELECT rowid FROM tt WHERE tt MATCH 'a*';
   170    170   } {1}
          171  +
          172  +#-------------------------------------------------------------------------
          173  +
          174  +reset_db
          175  +do_execsql_test 6.1 {
          176  +  CREATE VIRTUAL TABLE xyz USING fts5(x, y, z);
          177  +  INSERT INTO xyz VALUES('x', 'y', 'z');
          178  +}
          179  +
          180  +do_catchsql_test 6.2 { 
          181  +  SELECT * FROM xyz WHERE xyz MATCH '' 
          182  +} {1 {fts5: syntax error near ""}}
          183  +do_catchsql_test 6.3 { 
          184  +  SELECT * FROM xyz WHERE xyz MATCH NULL 
          185  +} {1 {fts5: syntax error near ""}}
          186  +
   171    187   
   172    188   finish_test
   173    189   

Changes to ext/misc/json1.c.

    29     29   #include <string.h>
    30     30   #include <ctype.h>
    31     31   #include <stdlib.h>
    32     32   #include <stdarg.h>
    33     33   
    34     34   #define UNUSED_PARAM(X)  (void)(X)
    35     35   
           36  +/*
           37  +** Versions of isspace(), isalnum() and isdigit() to which it is safe
           38  +** to pass signed char values.
           39  +*/
           40  +#define safe_isdigit(x) isdigit((unsigned char)(x))
           41  +#define safe_isalnum(x) isalnum((unsigned char)(x))
           42  +
           43  +/*
           44  +** Growing our own isspace() routine this way is twice as fast as
           45  +** the library isspace() function, resulting in a 7% overall performance
           46  +** increase for the parser.  (Ubuntu14.10 gcc 4.8.4 x64 with -Os).
           47  +*/
           48  +static const char jsonIsSpace[] = {
           49  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 1, 1, 0, 1, 1, 0, 0,
           50  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           51  +  1, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           52  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           53  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           54  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           55  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           56  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           57  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           58  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           59  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           60  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           61  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           62  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           63  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           64  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           65  +};
           66  +#define safe_isspace(x) (jsonIsSpace[(unsigned char)x])
           67  +
    36     68   /* Unsigned integer types */
    37     69   typedef sqlite3_uint64 u64;
    38     70   typedef unsigned int u32;
    39     71   typedef unsigned char u8;
    40     72   
    41     73   /* Objects */
    42     74   typedef struct JsonString JsonString;
................................................................................
   144    176     jsonZero(p);
   145    177   }
   146    178   
   147    179   
   148    180   /* Report an out-of-memory (OOM) condition 
   149    181   */
   150    182   static void jsonOom(JsonString *p){
   151         -  if( !p->bErr ){
   152         -    p->bErr = 1;
   153         -    sqlite3_result_error_nomem(p->pCtx);
   154         -    jsonReset(p);
   155         -  }
          183  +  p->bErr = 1;
          184  +  sqlite3_result_error_nomem(p->pCtx);
          185  +  jsonReset(p);
   156    186   }
   157    187   
   158    188   /* Enlarge pJson->zBuf so that it can hold at least N more bytes.
   159    189   ** Return zero on success.  Return non-zero on an OOM error
   160    190   */
   161    191   static int jsonGrow(JsonString *p, u32 N){
   162    192     u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10;
................................................................................
   227    257   static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
   228    258     u32 i;
   229    259     if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return;
   230    260     p->zBuf[p->nUsed++] = '"';
   231    261     for(i=0; i<N; i++){
   232    262       char c = zIn[i];
   233    263       if( c=='"' || c=='\\' ){
   234         -      if( (p->nUsed+N+1-i > p->nAlloc) && jsonGrow(p,N+1-i)!=0 ) return;
          264  +      if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return;
   235    265         p->zBuf[p->nUsed++] = '\\';
   236    266       }
   237    267       p->zBuf[p->nUsed++] = c;
   238    268     }
   239    269     p->zBuf[p->nUsed++] = '"';
          270  +  assert( p->nUsed<p->nAlloc );
   240    271   }
   241    272   
   242    273   /*
   243    274   ** Append a function parameter value to the JSON string under 
   244    275   ** construction.
   245    276   */
   246    277   static void jsonAppendValue(
................................................................................
   330    361   */
   331    362   static void jsonRenderNode(
   332    363     JsonNode *pNode,               /* The node to render */
   333    364     JsonString *pOut,              /* Write JSON here */
   334    365     sqlite3_value **aReplace       /* Replacement values */
   335    366   ){
   336    367     switch( pNode->eType ){
   337         -    case JSON_NULL: {
          368  +    default: {
          369  +      assert( pNode->eType==JSON_NULL );
   338    370         jsonAppendRaw(pOut, "null", 4);
   339    371         break;
   340    372       }
   341    373       case JSON_TRUE: {
   342    374         jsonAppendRaw(pOut, "true", 4);
   343    375         break;
   344    376       }
................................................................................
   428    460   */
   429    461   static void jsonReturn(
   430    462     JsonNode *pNode,            /* Node to return */
   431    463     sqlite3_context *pCtx,      /* Return value for this function */
   432    464     sqlite3_value **aReplace    /* Array of replacement values */
   433    465   ){
   434    466     switch( pNode->eType ){
   435         -    case JSON_NULL: {
          467  +    default: {
          468  +      assert( pNode->eType==JSON_NULL );
   436    469         sqlite3_result_null(pCtx);
   437    470         break;
   438    471       }
   439    472       case JSON_TRUE: {
   440    473         sqlite3_result_int(pCtx, 1);
   441    474         break;
   442    475       }
................................................................................
   455    488         if( z[0]=='-' ){ z++; }
   456    489         while( z[0]>='0' && z[0]<='9' ){ i = i*10 + *(z++) - '0'; }
   457    490         if( pNode->u.zJContent[0]=='-' ){ i = -i; }
   458    491         sqlite3_result_int64(pCtx, i);
   459    492         break;
   460    493       }
   461    494       case JSON_STRING: {
          495  +#if 0 /* Never happens because JNODE_RAW is only set by json_set(),
          496  +      ** json_insert() and json_replace() and those routines do not
          497  +      ** call jsonReturn() */
   462    498         if( pNode->jnFlags & JNODE_RAW ){
   463    499           sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n,
   464    500                               SQLITE_TRANSIENT);
   465         -      }else if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
          501  +      }else 
          502  +#endif
          503  +      assert( (pNode->jnFlags & JNODE_RAW)==0 );
          504  +      if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
   466    505           /* JSON formatted without any backslash-escapes */
   467    506           sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2,
   468    507                               SQLITE_TRANSIENT);
   469    508         }else{
   470    509           /* Translate JSON formatted string into raw text */
   471    510           u32 i;
   472    511           u32 n = pNode->n;
................................................................................
   528    567       case JSON_ARRAY:
   529    568       case JSON_OBJECT: {
   530    569         jsonReturnJson(pNode, pCtx, aReplace);
   531    570         break;
   532    571       }
   533    572     }
   534    573   }
          574  +
          575  +/* Forward reference */
          576  +static int jsonParseAddNode(JsonParse*,u32,u32,const char*);
          577  +
          578  +/*
          579  +** A macro to hint to the compiler that a function should not be
          580  +** inlined.
          581  +*/
          582  +#if defined(__GNUC__)
          583  +#  define JSON_NOINLINE  __attribute__((noinline))
          584  +#elif defined(_MSC_VER) && _MSC_VER>=1310
          585  +#  define JSON_NOINLINE  __declspec(noinline)
          586  +#else
          587  +#  define JSON_NOINLINE
          588  +#endif
          589  +
          590  +
          591  +static JSON_NOINLINE int jsonParseAddNodeExpand(
          592  +  JsonParse *pParse,        /* Append the node to this object */
          593  +  u32 eType,                /* Node type */
          594  +  u32 n,                    /* Content size or sub-node count */
          595  +  const char *zContent      /* Content */
          596  +){
          597  +  u32 nNew;
          598  +  JsonNode *pNew;
          599  +  assert( pParse->nNode>=pParse->nAlloc );
          600  +  if( pParse->oom ) return -1;
          601  +  nNew = pParse->nAlloc*2 + 10;
          602  +  pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew);
          603  +  if( pNew==0 ){
          604  +    pParse->oom = 1;
          605  +    return -1;
          606  +  }
          607  +  pParse->nAlloc = nNew;
          608  +  pParse->aNode = pNew;
          609  +  assert( pParse->nNode<pParse->nAlloc );
          610  +  return jsonParseAddNode(pParse, eType, n, zContent);
          611  +}
   535    612   
   536    613   /*
   537    614   ** Create a new JsonNode instance based on the arguments and append that
   538    615   ** instance to the JsonParse.  Return the index in pParse->aNode[] of the
   539    616   ** new node, or -1 if a memory allocation fails.
   540    617   */
   541    618   static int jsonParseAddNode(
................................................................................
   542    619     JsonParse *pParse,        /* Append the node to this object */
   543    620     u32 eType,                /* Node type */
   544    621     u32 n,                    /* Content size or sub-node count */
   545    622     const char *zContent      /* Content */
   546    623   ){
   547    624     JsonNode *p;
   548    625     if( pParse->nNode>=pParse->nAlloc ){
   549         -    u32 nNew;
   550         -    JsonNode *pNew;
   551         -    if( pParse->oom ) return -1;
   552         -    nNew = pParse->nAlloc*2 + 10;
   553         -    if( nNew<=pParse->nNode ){
   554         -      pParse->oom = 1;
   555         -      return -1;
   556         -    }
   557         -    pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew);
   558         -    if( pNew==0 ){
   559         -      pParse->oom = 1;
   560         -      return -1;
   561         -    }
   562         -    pParse->nAlloc = nNew;
   563         -    pParse->aNode = pNew;
          626  +    return jsonParseAddNodeExpand(pParse, eType, n, zContent);
   564    627     }
   565    628     p = &pParse->aNode[pParse->nNode];
   566    629     p->eType = (u8)eType;
   567    630     p->jnFlags = 0;
   568    631     p->iVal = 0;
   569    632     p->n = n;
   570    633     p->u.zJContent = zContent;
................................................................................
   581    644   */
   582    645   static int jsonParseValue(JsonParse *pParse, u32 i){
   583    646     char c;
   584    647     u32 j;
   585    648     int iThis;
   586    649     int x;
   587    650     JsonNode *pNode;
   588         -  while( isspace(pParse->zJson[i]) ){ i++; }
   589         -  if( (c = pParse->zJson[i])==0 ) return 0;
   590         -  if( c=='{' ){
          651  +  while( safe_isspace(pParse->zJson[i]) ){ i++; }
          652  +  if( (c = pParse->zJson[i])=='{' ){
   591    653       /* Parse object */
   592    654       iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
   593    655       if( iThis<0 ) return -1;
   594    656       for(j=i+1;;j++){
   595         -      while( isspace(pParse->zJson[j]) ){ j++; }
          657  +      while( safe_isspace(pParse->zJson[j]) ){ j++; }
   596    658         x = jsonParseValue(pParse, j);
   597    659         if( x<0 ){
   598    660           if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1;
   599    661           return -1;
   600    662         }
   601    663         if( pParse->oom ) return -1;
   602    664         pNode = &pParse->aNode[pParse->nNode-1];
   603    665         if( pNode->eType!=JSON_STRING ) return -1;
   604    666         pNode->jnFlags |= JNODE_LABEL;
   605    667         j = x;
   606         -      while( isspace(pParse->zJson[j]) ){ j++; }
          668  +      while( safe_isspace(pParse->zJson[j]) ){ j++; }
   607    669         if( pParse->zJson[j]!=':' ) return -1;
   608    670         j++;
   609    671         x = jsonParseValue(pParse, j);
   610    672         if( x<0 ) return -1;
   611    673         j = x;
   612         -      while( isspace(pParse->zJson[j]) ){ j++; }
          674  +      while( safe_isspace(pParse->zJson[j]) ){ j++; }
   613    675         c = pParse->zJson[j];
   614    676         if( c==',' ) continue;
   615    677         if( c!='}' ) return -1;
   616    678         break;
   617    679       }
   618    680       pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
   619    681       return j+1;
   620    682     }else if( c=='[' ){
   621    683       /* Parse array */
   622    684       iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
   623    685       if( iThis<0 ) return -1;
   624    686       for(j=i+1;;j++){
   625         -      while( isspace(pParse->zJson[j]) ){ j++; }
          687  +      while( safe_isspace(pParse->zJson[j]) ){ j++; }
   626    688         x = jsonParseValue(pParse, j);
   627    689         if( x<0 ){
   628    690           if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1;
   629    691           return -1;
   630    692         }
   631    693         j = x;
   632         -      while( isspace(pParse->zJson[j]) ){ j++; }
          694  +      while( safe_isspace(pParse->zJson[j]) ){ j++; }
   633    695         c = pParse->zJson[j];
   634    696         if( c==',' ) continue;
   635    697         if( c!=']' ) return -1;
   636    698         break;
   637    699       }
   638    700       pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
   639    701       return j+1;
................................................................................
   654    716         j++;
   655    717       }
   656    718       jsonParseAddNode(pParse, JSON_STRING, j+1-i, &pParse->zJson[i]);
   657    719       if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags;
   658    720       return j+1;
   659    721     }else if( c=='n'
   660    722            && strncmp(pParse->zJson+i,"null",4)==0
   661         -         && !isalnum(pParse->zJson[i+4]) ){
          723  +         && !safe_isalnum(pParse->zJson[i+4]) ){
   662    724       jsonParseAddNode(pParse, JSON_NULL, 0, 0);
   663    725       return i+4;
   664    726     }else if( c=='t'
   665    727            && strncmp(pParse->zJson+i,"true",4)==0
   666         -         && !isalnum(pParse->zJson[i+4]) ){
          728  +         && !safe_isalnum(pParse->zJson[i+4]) ){
   667    729       jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
   668    730       return i+4;
   669    731     }else if( c=='f'
   670    732            && strncmp(pParse->zJson+i,"false",5)==0
   671         -         && !isalnum(pParse->zJson[i+5]) ){
          733  +         && !safe_isalnum(pParse->zJson[i+5]) ){
   672    734       jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
   673    735       return i+5;
   674    736     }else if( c=='-' || (c>='0' && c<='9') ){
   675    737       /* Parse number */
   676    738       u8 seenDP = 0;
   677    739       u8 seenE = 0;
   678    740       j = i+1;
................................................................................
   703    765       jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT,
   704    766                           j - i, &pParse->zJson[i]);
   705    767       return j;
   706    768     }else if( c=='}' ){
   707    769       return -2;  /* End of {...} */
   708    770     }else if( c==']' ){
   709    771       return -3;  /* End of [...] */
          772  +  }else if( c==0 ){
          773  +    return 0;   /* End of file */
   710    774     }else{
   711    775       return -1;  /* Syntax error */
   712    776     }
   713    777   }
   714    778   
   715    779   /*
   716    780   ** Parse a complete JSON string.  Return 0 on success or non-zero if there
................................................................................
   727    791     int i;
   728    792     memset(pParse, 0, sizeof(*pParse));
   729    793     if( zJson==0 ) return 1;
   730    794     pParse->zJson = zJson;
   731    795     i = jsonParseValue(pParse, 0);
   732    796     if( pParse->oom ) i = -1;
   733    797     if( i>0 ){
   734         -    while( isspace(zJson[i]) ) i++;
          798  +    while( safe_isspace(zJson[i]) ) i++;
   735    799       if( zJson[i] ) i = -1;
   736    800     }
   737    801     if( i<=0 ){
   738    802       if( pCtx!=0 ){
   739    803         if( pParse->oom ){
   740    804           sqlite3_result_error_nomem(pCtx);
   741    805         }else{
................................................................................
   785    849     if( aUp==0 ){
   786    850       pParse->oom = 1;
   787    851       return SQLITE_NOMEM;
   788    852     }
   789    853     jsonParseFillInParentage(pParse, 0, 0);
   790    854     return SQLITE_OK;
   791    855   }
          856  +
          857  +/*
          858  +** Compare the OBJECT label at pNode against zKey,nKey.  Return true on
          859  +** a match.
          860  +*/
          861  +static int jsonLabelCompare(JsonNode *pNode, const char *zKey, int nKey){
          862  +  if( pNode->jnFlags & JNODE_RAW ){
          863  +    if( pNode->n!=nKey ) return 0;
          864  +    return strncmp(pNode->u.zJContent, zKey, nKey)==0;
          865  +  }else{
          866  +    if( pNode->n!=nKey+2 ) return 0;
          867  +    return strncmp(pNode->u.zJContent+1, zKey, nKey)==0;
          868  +  }
          869  +}
   792    870   
   793    871   /* forward declaration */
   794    872   static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**);
   795    873   
   796    874   /*
   797    875   ** Search along zPath to find the node specified.  Return a pointer
   798    876   ** to that node, or NULL if zPath is malformed or if there is no such
................................................................................
   816    894     if( zPath[0]=='.' ){
   817    895       if( pRoot->eType!=JSON_OBJECT ) return 0;
   818    896       zPath++;
   819    897       if( zPath[0]=='"' ){
   820    898         zKey = zPath + 1;
   821    899         for(i=1; zPath[i] && zPath[i]!='"'; i++){}
   822    900         nKey = i-1;
   823         -      if( zPath[i] ) i++;
          901  +      if( zPath[i] ){
          902  +        i++;
          903  +      }else{
          904  +        *pzErr = zPath;
          905  +        return 0;
          906  +      }
   824    907       }else{
   825    908         zKey = zPath;
   826    909         for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
   827    910         nKey = i;
   828    911       }
   829    912       if( nKey==0 ){
   830    913         *pzErr = zPath;
   831    914         return 0;
   832    915       }
   833    916       j = 1;
   834    917       for(;;){
   835    918         while( j<=pRoot->n ){
   836         -        if( pRoot[j].n==nKey+2
   837         -         && strncmp(&pRoot[j].u.zJContent[1],zKey,nKey)==0
   838         -        ){
          919  +        if( jsonLabelCompare(pRoot+j, zKey, nKey) ){
   839    920             return jsonLookupStep(pParse, iRoot+j+1, &zPath[i], pApnd, pzErr);
   840    921           }
   841    922           j++;
   842    923           j += jsonNodeSize(&pRoot[j]);
   843    924         }
   844    925         if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
   845    926         iRoot += pRoot->u.iAppend;
................................................................................
   858    939           pRoot = &pParse->aNode[iRoot];
   859    940           pRoot->u.iAppend = iStart - iRoot;
   860    941           pRoot->jnFlags |= JNODE_APPEND;
   861    942           pParse->aNode[iLabel].jnFlags |= JNODE_RAW;
   862    943         }
   863    944         return pNode;
   864    945       }
   865         -  }else if( zPath[0]=='[' && isdigit(zPath[1]) ){
          946  +  }else if( zPath[0]=='[' && safe_isdigit(zPath[1]) ){
   866    947       if( pRoot->eType!=JSON_ARRAY ) return 0;
   867    948       i = 0;
   868         -    zPath++;
   869         -    while( isdigit(zPath[0]) ){
   870         -      i = i*10 + zPath[0] - '0';
   871         -      zPath++;
          949  +    j = 1;
          950  +    while( safe_isdigit(zPath[j]) ){
          951  +      i = i*10 + zPath[j] - '0';
          952  +      j++;
   872    953       }
   873         -    if( zPath[0]!=']' ){
          954  +    if( zPath[j]!=']' ){
   874    955         *pzErr = zPath;
   875    956         return 0;
   876    957       }
   877         -    zPath++;
          958  +    zPath += j + 1;
   878    959       j = 1;
   879    960       for(;;){
   880    961         while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){
   881    962           if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--;
   882    963           j += jsonNodeSize(&pRoot[j]);
   883    964         }
   884    965         if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
................................................................................
   898    979         if( pNode ){
   899    980           pRoot = &pParse->aNode[iRoot];
   900    981           pRoot->u.iAppend = iStart - iRoot;
   901    982           pRoot->jnFlags |= JNODE_APPEND;
   902    983         }
   903    984         return pNode;
   904    985       }
   905         -  }else if( zPath[0]!=0 ){
          986  +  }else{
   906    987       *pzErr = zPath;
   907    988     }
   908    989     return 0;
   909    990   }
   910    991   
   911    992   /*
   912    993   ** Append content to pParse that will complete zPath.  Return a pointer
................................................................................
   956   1037     JsonParse *pParse,      /* The JSON to search */
   957   1038     const char *zPath,      /* The path to search */
   958   1039     int *pApnd,             /* Append nodes to complete path if not NULL */
   959   1040     sqlite3_context *pCtx   /* Report errors here, if not NULL */
   960   1041   ){
   961   1042     const char *zErr = 0;
   962   1043     JsonNode *pNode = 0;
         1044  +  char *zMsg;
   963   1045   
   964   1046     if( zPath==0 ) return 0;
   965   1047     if( zPath[0]!='$' ){
   966   1048       zErr = zPath;
   967   1049       goto lookup_err;
   968   1050     }
   969   1051     zPath++;
   970   1052     pNode = jsonLookupStep(pParse, 0, zPath, pApnd, &zErr);
   971         -  return pNode;
         1053  +  if( zErr==0 ) return pNode;
   972   1054   
   973   1055   lookup_err:
   974   1056     pParse->nErr++;
   975         -  if( zErr!=0 && pCtx!=0 ){
   976         -    char *z = jsonPathSyntaxError(zErr);
   977         -    if( z ){
   978         -      sqlite3_result_error(pCtx, z, -1);
   979         -      sqlite3_free(z);
   980         -    }else{
   981         -      sqlite3_result_error_nomem(pCtx);
   982         -    }
         1057  +  assert( zErr!=0 && pCtx!=0 );
         1058  +  zMsg = jsonPathSyntaxError(zErr);
         1059  +  if( zMsg ){
         1060  +    sqlite3_result_error(pCtx, zMsg, -1);
         1061  +    sqlite3_free(zMsg);
         1062  +  }else{
         1063  +    sqlite3_result_error_nomem(pCtx);
   983   1064     }
   984   1065     return 0;
   985   1066   }
   986   1067   
   987   1068   
   988   1069   /*
   989   1070   ** Report the wrong number of arguments for json_insert(), json_replace()
................................................................................
  1098   1179     sqlite3_context *ctx,
  1099   1180     int argc,
  1100   1181     sqlite3_value **argv
  1101   1182   ){
  1102   1183     JsonParse x;          /* The parse */
  1103   1184     sqlite3_int64 n = 0;
  1104   1185     u32 i;
         1186  +  JsonNode *pNode;
  1105   1187   
  1106   1188     if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
  1107         -  if( x.nNode ){
  1108         -    JsonNode *pNode;
  1109         -    if( argc==2 ){
  1110         -      const char *zPath = (const char*)sqlite3_value_text(argv[1]);
  1111         -      pNode = jsonLookup(&x, zPath, 0, ctx);
  1112         -    }else{
  1113         -      pNode = x.aNode;
  1114         -    }
  1115         -    if( pNode==0 ){
  1116         -      x.nErr = 1;
  1117         -    }else if( pNode->eType==JSON_ARRAY ){
  1118         -      assert( (pNode->jnFlags & JNODE_APPEND)==0 );
  1119         -      for(i=1; i<=pNode->n; n++){
  1120         -        i += jsonNodeSize(&pNode[i]);
  1121         -      }
         1189  +  assert( x.nNode );
         1190  +  if( argc==2 ){
         1191  +    const char *zPath = (const char*)sqlite3_value_text(argv[1]);
         1192  +    pNode = jsonLookup(&x, zPath, 0, ctx);
         1193  +  }else{
         1194  +    pNode = x.aNode;
         1195  +  }
         1196  +  if( pNode==0 ){
         1197  +    x.nErr = 1;
         1198  +  }else if( pNode->eType==JSON_ARRAY ){
         1199  +    assert( (pNode->jnFlags & JNODE_APPEND)==0 );
         1200  +    for(i=1; i<=pNode->n; n++){
         1201  +      i += jsonNodeSize(&pNode[i]);
  1122   1202       }
  1123   1203     }
  1124   1204     if( x.nErr==0 ) sqlite3_result_int64(ctx, n);
  1125   1205     jsonParseReset(&x);
  1126   1206   }
  1127   1207   
  1128   1208   /*
................................................................................
  1193   1273       return;
  1194   1274     }
  1195   1275     jsonInit(&jx, ctx);
  1196   1276     jsonAppendChar(&jx, '{');
  1197   1277     for(i=0; i<argc; i+=2){
  1198   1278       if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){
  1199   1279         sqlite3_result_error(ctx, "json_object() labels must be TEXT", -1);
  1200         -      jsonZero(&jx);
         1280  +      jsonReset(&jx);
  1201   1281         return;
  1202   1282       }
  1203   1283       jsonAppendSeparator(&jx);
  1204   1284       z = (const char*)sqlite3_value_text(argv[i]);
  1205   1285       n = (u32)sqlite3_value_bytes(argv[i]);
  1206   1286       jsonAppendString(&jx, z, n);
  1207   1287       jsonAppendChar(&jx, ':');
................................................................................
  1227   1307     JsonParse x;          /* The parse */
  1228   1308     JsonNode *pNode;
  1229   1309     const char *zPath;
  1230   1310     u32 i;
  1231   1311   
  1232   1312     if( argc<1 ) return;
  1233   1313     if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
  1234         -  if( x.nNode ){
  1235         -    for(i=1; i<(u32)argc; i++){
  1236         -      zPath = (const char*)sqlite3_value_text(argv[i]);
  1237         -      if( zPath==0 ) goto remove_done;
  1238         -      pNode = jsonLookup(&x, zPath, 0, ctx);
  1239         -      if( x.nErr ) goto remove_done;
  1240         -      if( pNode ) pNode->jnFlags |= JNODE_REMOVE;
  1241         -    }
  1242         -    if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){
  1243         -      jsonReturnJson(x.aNode, ctx, 0);
  1244         -    }
         1314  +  assert( x.nNode );
         1315  +  for(i=1; i<(u32)argc; i++){
         1316  +    zPath = (const char*)sqlite3_value_text(argv[i]);
         1317  +    if( zPath==0 ) goto remove_done;
         1318  +    pNode = jsonLookup(&x, zPath, 0, ctx);
         1319  +    if( x.nErr ) goto remove_done;
         1320  +    if( pNode ) pNode->jnFlags |= JNODE_REMOVE;
         1321  +  }
         1322  +  if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){
         1323  +    jsonReturnJson(x.aNode, ctx, 0);
  1245   1324     }
  1246   1325   remove_done:
  1247   1326     jsonParseReset(&x);
  1248   1327   }
  1249   1328   
  1250   1329   /*
  1251   1330   ** json_replace(JSON, PATH, VALUE, ...)
................................................................................
  1265   1344   
  1266   1345     if( argc<1 ) return;
  1267   1346     if( (argc&1)==0 ) {
  1268   1347       jsonWrongNumArgs(ctx, "replace");
  1269   1348       return;
  1270   1349     }
  1271   1350     if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
  1272         -  if( x.nNode ){
  1273         -    for(i=1; i<(u32)argc; i+=2){
  1274         -      zPath = (const char*)sqlite3_value_text(argv[i]);
  1275         -      pNode = jsonLookup(&x, zPath, 0, ctx);
  1276         -      if( x.nErr ) goto replace_err;
  1277         -      if( pNode ){
  1278         -        pNode->jnFlags |= (u8)JNODE_REPLACE;
  1279         -        pNode->iVal = (u8)(i+1);
  1280         -      }
         1351  +  assert( x.nNode );
         1352  +  for(i=1; i<(u32)argc; i+=2){
         1353  +    zPath = (const char*)sqlite3_value_text(argv[i]);
         1354  +    pNode = jsonLookup(&x, zPath, 0, ctx);
         1355  +    if( x.nErr ) goto replace_err;
         1356  +    if( pNode ){
         1357  +      pNode->jnFlags |= (u8)JNODE_REPLACE;
         1358  +      pNode->iVal = (u8)(i+1);
  1281   1359       }
  1282         -    if( x.aNode[0].jnFlags & JNODE_REPLACE ){
  1283         -      sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
  1284         -    }else{
  1285         -      jsonReturnJson(x.aNode, ctx, argv);
  1286         -    }
         1360  +  }
         1361  +  if( x.aNode[0].jnFlags & JNODE_REPLACE ){
         1362  +    sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
         1363  +  }else{
         1364  +    jsonReturnJson(x.aNode, ctx, argv);
  1287   1365     }
  1288   1366   replace_err:
  1289   1367     jsonParseReset(&x);
  1290   1368   }
  1291   1369   
  1292   1370   /*
  1293   1371   ** json_set(JSON, PATH, VALUE, ...)
................................................................................
  1315   1393   
  1316   1394     if( argc<1 ) return;
  1317   1395     if( (argc&1)==0 ) {
  1318   1396       jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert");
  1319   1397       return;
  1320   1398     }
  1321   1399     if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
  1322         -  if( x.nNode ){
  1323         -    for(i=1; i<(u32)argc; i+=2){
  1324         -      zPath = (const char*)sqlite3_value_text(argv[i]);
  1325         -      bApnd = 0;
  1326         -      pNode = jsonLookup(&x, zPath, &bApnd, ctx);
  1327         -      if( x.oom ){
  1328         -        sqlite3_result_error_nomem(ctx);
  1329         -        goto jsonSetDone;
  1330         -      }else if( x.nErr ){
  1331         -        goto jsonSetDone;
  1332         -      }else if( pNode && (bApnd || bIsSet) ){
  1333         -        pNode->jnFlags |= (u8)JNODE_REPLACE;
  1334         -        pNode->iVal = (u8)(i+1);
  1335         -      }
         1400  +  assert( x.nNode );
         1401  +  for(i=1; i<(u32)argc; i+=2){
         1402  +    zPath = (const char*)sqlite3_value_text(argv[i]);
         1403  +    bApnd = 0;
         1404  +    pNode = jsonLookup(&x, zPath, &bApnd, ctx);
         1405  +    if( x.oom ){
         1406  +      sqlite3_result_error_nomem(ctx);
         1407  +      goto jsonSetDone;
         1408  +    }else if( x.nErr ){
         1409  +      goto jsonSetDone;
         1410  +    }else if( pNode && (bApnd || bIsSet) ){
         1411  +      pNode->jnFlags |= (u8)JNODE_REPLACE;
         1412  +      pNode->iVal = (u8)(i+1);
  1336   1413       }
  1337         -    if( x.aNode[0].jnFlags & JNODE_REPLACE ){
  1338         -      sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
  1339         -    }else{
  1340         -      jsonReturnJson(x.aNode, ctx, argv);
  1341         -    }
         1414  +  }
         1415  +  if( x.aNode[0].jnFlags & JNODE_REPLACE ){
         1416  +    sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
         1417  +  }else{
         1418  +    jsonReturnJson(x.aNode, ctx, argv);
  1342   1419     }
  1343   1420   jsonSetDone:
  1344   1421     jsonParseReset(&x);
  1345   1422   }
  1346   1423   
  1347   1424   /*
  1348   1425   ** json_type(JSON)
................................................................................
  1354   1431   static void jsonTypeFunc(
  1355   1432     sqlite3_context *ctx,
  1356   1433     int argc,
  1357   1434     sqlite3_value **argv
  1358   1435   ){
  1359   1436     JsonParse x;          /* The parse */
  1360   1437     const char *zPath;
         1438  +  JsonNode *pNode;
  1361   1439   
  1362   1440     if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
  1363         -  if( x.nNode ){
  1364         -    JsonNode *pNode;
  1365         -    if( argc==2 ){
  1366         -      zPath = (const char*)sqlite3_value_text(argv[1]);
  1367         -      pNode = jsonLookup(&x, zPath, 0, ctx);
  1368         -    }else{
  1369         -      pNode = x.aNode;
  1370         -    }
  1371         -    if( pNode ){
  1372         -      sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC);
  1373         -    }
         1441  +  assert( x.nNode );
         1442  +  if( argc==2 ){
         1443  +    zPath = (const char*)sqlite3_value_text(argv[1]);
         1444  +    pNode = jsonLookup(&x, zPath, 0, ctx);
         1445  +  }else{
         1446  +    pNode = x.aNode;
         1447  +  }
         1448  +  if( pNode ){
         1449  +    sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC);
  1374   1450     }
  1375   1451     jsonParseReset(&x);
  1376   1452   }
  1377   1453   
  1378   1454   /*
  1379   1455   ** json_valid(JSON)
  1380   1456   **
................................................................................
  1386   1462     int argc,
  1387   1463     sqlite3_value **argv
  1388   1464   ){
  1389   1465     JsonParse x;          /* The parse */
  1390   1466     int rc = 0;
  1391   1467   
  1392   1468     UNUSED_PARAM(argc);
  1393         -  if( jsonParse(&x, 0, (const char*)sqlite3_value_text(argv[0]))==0 
  1394         -   && x.nNode>0
  1395         -  ){
         1469  +  if( jsonParse(&x, 0, (const char*)sqlite3_value_text(argv[0]))==0 ){
  1396   1470       rc = 1;
  1397   1471     }
  1398   1472     jsonParseReset(&x);
  1399   1473     sqlite3_result_int(ctx, rc);
  1400   1474   }
  1401   1475   
  1402   1476   #ifndef SQLITE_OMIT_VIRTUALTABLE
................................................................................
  1665   1739       }
  1666   1740       case JEACH_ROOT: {
  1667   1741         const char *zRoot = p->zRoot;
  1668   1742          if( zRoot==0 ) zRoot = "$";
  1669   1743         sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC);
  1670   1744         break;
  1671   1745       }
  1672         -    default: {
         1746  +    case JEACH_JSON: {
  1673   1747         assert( i==JEACH_JSON );
  1674   1748         sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC);
  1675   1749         break;
  1676   1750       }
  1677   1751     }
  1678   1752     return SQLITE_OK;
  1679   1753   }
................................................................................
  1741   1815   
  1742   1816     UNUSED_PARAM(idxStr);
  1743   1817     UNUSED_PARAM(argc);
  1744   1818     jsonEachCursorReset(p);
  1745   1819     if( idxNum==0 ) return SQLITE_OK;
  1746   1820     z = (const char*)sqlite3_value_text(argv[0]);
  1747   1821     if( z==0 ) return SQLITE_OK;
  1748         -  if( idxNum&2 ){
  1749         -    zRoot = (const char*)sqlite3_value_text(argv[1]);
  1750         -    if( zRoot==0 ) return SQLITE_OK;
  1751         -    if( zRoot[0]!='$' ){
  1752         -      sqlite3_free(cur->pVtab->zErrMsg);
  1753         -      cur->pVtab->zErrMsg = jsonPathSyntaxError(zRoot);
  1754         -      return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
  1755         -    }
  1756         -  }
  1757   1822     n = sqlite3_value_bytes(argv[0]);
  1758   1823     p->zJson = sqlite3_malloc64( n+1 );
  1759   1824     if( p->zJson==0 ) return SQLITE_NOMEM;
  1760   1825     memcpy(p->zJson, z, (size_t)n+1);
  1761   1826     if( jsonParse(&p->sParse, 0, p->zJson) ){
  1762   1827       int rc = SQLITE_NOMEM;
  1763   1828       if( p->sParse.oom==0 ){
................................................................................
  1767   1832       }
  1768   1833       jsonEachCursorReset(p);
  1769   1834       return rc;
  1770   1835     }else if( p->bRecursive && jsonParseFindParents(&p->sParse) ){
  1771   1836       jsonEachCursorReset(p);
  1772   1837       return SQLITE_NOMEM;
  1773   1838     }else{
  1774         -    JsonNode *pNode;
         1839  +    JsonNode *pNode = 0;
  1775   1840       if( idxNum==3 ){
  1776   1841         const char *zErr = 0;
         1842  +      zRoot = (const char*)sqlite3_value_text(argv[1]);
         1843  +      if( zRoot==0 ) return SQLITE_OK;
  1777   1844         n = sqlite3_value_bytes(argv[1]);
  1778   1845         p->zRoot = sqlite3_malloc64( n+1 );
  1779   1846         if( p->zRoot==0 ) return SQLITE_NOMEM;
  1780   1847         memcpy(p->zRoot, zRoot, (size_t)n+1);
  1781         -      pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr);
  1782         -      if( p->sParse.nErr ){
         1848  +      if( zRoot[0]!='$' ){
         1849  +        zErr = zRoot;
         1850  +      }else{
         1851  +        pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr);
         1852  +      }
         1853  +      if( zErr ){
  1783   1854           sqlite3_free(cur->pVtab->zErrMsg);
  1784   1855           cur->pVtab->zErrMsg = jsonPathSyntaxError(zErr);
  1785   1856           jsonEachCursorReset(p);
  1786   1857           return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
  1787   1858         }else if( pNode==0 ){
  1788   1859           return SQLITE_OK;
  1789   1860         }
................................................................................
  1792   1863       }
  1793   1864       p->iBegin = p->i = (int)(pNode - p->sParse.aNode);
  1794   1865       p->eType = pNode->eType;
  1795   1866       if( p->eType>=JSON_ARRAY ){
  1796   1867         pNode->u.iKey = 0;
  1797   1868         p->iEnd = p->i + pNode->n + 1;
  1798   1869         if( p->bRecursive ){
         1870  +        p->eType = p->sParse.aNode[p->sParse.aUp[p->i]].eType;
  1799   1871           if( p->i>0 && (p->sParse.aNode[p->i-1].jnFlags & JNODE_LABEL)!=0 ){
  1800   1872             p->i--;
  1801   1873           }
  1802   1874         }else{
  1803   1875           p->i++;
  1804   1876         }
  1805   1877       }else{
  1806   1878         p->iEnd = p->i+1;
  1807   1879       }
  1808   1880     }
  1809         -  return p->sParse.oom ? SQLITE_NOMEM : SQLITE_OK;
         1881  +  return SQLITE_OK;
  1810   1882   }
  1811   1883   
  1812   1884   /* The methods of the json_each virtual table */
  1813   1885   static sqlite3_module jsonEachModule = {
  1814   1886     0,                         /* iVersion */
  1815   1887     0,                         /* xCreate */
  1816   1888     jsonEachConnect,           /* xConnect */

Changes to main.mk.

   451    451     sqldiff$(EXE)
   452    452   
   453    453   # Databases containing fuzzer test cases
   454    454   #
   455    455   FUZZDATA = \
   456    456     $(TOP)/test/fuzzdata1.db \
   457    457     $(TOP)/test/fuzzdata2.db \
   458         -  $(TOP)/test/fuzzdata3.db
          458  +  $(TOP)/test/fuzzdata3.db \
          459  +  $(TOP)/test/fuzzdata4.db
          460  +
          461  +# Extra arguments for including json1 in the build of tools
          462  +#
          463  +JSON1_DEP = $(TOP)/ext/misc/json1.c sqlite3ext.h
          464  +JSON1_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_CORE
          465  +JSON1_SRC = $(TOP)/ext/misc/json1.c
   459    466   
   460    467   # Standard options to testfixture
   461    468   #
   462    469   TESTOPTS = --verbose=file --output=test-out.txt
   463    470   
   464    471   # This is the default Makefile target.  The objects listed here
   465    472   # are what get build when you type just "make" with no arguments.
................................................................................
   466    473   #
   467    474   all:	sqlite3.h libsqlite3.a sqlite3$(EXE)
   468    475   
   469    476   libsqlite3.a:	$(LIBOBJ)
   470    477   	$(AR) libsqlite3.a $(LIBOBJ)
   471    478   	$(RANLIB) libsqlite3.a
   472    479   
   473         -sqlite3$(EXE):	$(TOP)/src/shell.c libsqlite3.a sqlite3.h $(TOP)/ext/misc/json1.c
   474         -	$(TCCX) $(READLINE_FLAGS) -DSQLITE_ENABLE_JSON1 -o sqlite3$(EXE)  \
   475         -		$(TOP)/src/shell.c $(TOP)/ext/misc/json1.c                \
          480  +sqlite3$(EXE):	$(TOP)/src/shell.c libsqlite3.a sqlite3.h $(JSON1_DEP)
          481  +	$(TCCX) $(READLINE_FLAGS) $(JSON1_OPT) -o sqlite3$(EXE)  \
          482  +		$(TOP)/src/shell.c $(JSON1_SRC) \
   476    483   		libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB)
   477    484   
   478    485   sqldiff$(EXE):	$(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h
   479    486   	$(TCCX) -o sqldiff$(EXE) -DSQLITE_THREADSAFE=0 \
   480    487   		$(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS) $(THREADLIB)
   481    488   
   482         -fuzzershell$(EXE):	$(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h
          489  +fuzzershell$(EXE):	$(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h $(JSON1_DEP)
   483    490   	$(TCCX) -o fuzzershell$(EXE) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
   484         -		$(TOP)/tool/fuzzershell.c sqlite3.c $(TLIBS) $(THREADLIB)
          491  +	  $(JSON1_OPT)	$(TOP)/tool/fuzzershell.c $(JSON1_SRC) sqlite3.c \
          492  +	  $(TLIBS) $(THREADLIB)
   485    493   
   486         -fuzzcheck$(EXE):	$(TOP)/test/fuzzcheck.c sqlite3.c sqlite3.h
          494  +fuzzcheck$(EXE):	$(TOP)/test/fuzzcheck.c sqlite3.c sqlite3.h $(JSON1_DEP)
   487    495   	$(TCCX) -o fuzzcheck$(EXE) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
   488         -		-DSQLITE_ENABLE_MEMSYS5 \
   489         -		$(TOP)/test/fuzzcheck.c sqlite3.c $(TLIBS) $(THREADLIB)
          496  +		-DSQLITE_ENABLE_MEMSYS5 $(JSON1_OPT) \
          497  +		$(TOP)/test/fuzzcheck.c $(JSON1_SRC) sqlite3.c $(TLIBS) $(THREADLIB)
   490    498   
   491    499   mptester$(EXE):	sqlite3.c $(TOP)/mptest/mptest.c
   492    500   	$(TCCX) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
   493    501   		$(TLIBS) $(THREADLIB)
   494    502   
   495    503   MPTEST1=./mptester$(EXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20
   496    504   MPTEST2=./mptester$(EXE) mptest.db $(TOP)/mptest/multiwrite01.test --repeat 20

Changes to src/backup.c.

   764    764     ** from this function, not directly by the user.
   765    765     */
   766    766     memset(&b, 0, sizeof(b));
   767    767     b.pSrcDb = pFrom->db;
   768    768     b.pSrc = pFrom;
   769    769     b.pDest = pTo;
   770    770     b.iNext = 1;
          771  +
          772  +#ifdef SQLITE_HAS_CODEC
          773  +  sqlite3PagerAlignReserve(sqlite3BtreePager(pTo), sqlite3BtreePager(pFrom));
          774  +#endif
   771    775   
   772    776     /* 0x7FFFFFFF is the hard limit for the number of pages in a database
   773    777     ** file. By passing this as the number of pages to copy to
   774    778     ** sqlite3_backup_step(), we can guarantee that the copy finishes 
   775    779     ** within a single call (unless an error occurs). The assert() statement
   776    780     ** checks this assumption - (p->rc) should be set to either SQLITE_DONE 
   777    781     ** or an error code.

Changes to src/btree.c.

  8182   8182       }
  8183   8183       rc = balance(pCur);
  8184   8184     }
  8185   8185   
  8186   8186     if( rc==SQLITE_OK ){
  8187   8187       if( bSkipnext ){
  8188   8188         assert( bPreserve && pCur->iPage==iCellDepth );
  8189         -      assert( pPage->nCell>0 && iCellIdx<=pPage->nCell );
         8189  +      assert( pPage==pCur->apPage[pCur->iPage] );
         8190  +      assert( (pPage->nCell>0 || CORRUPT_DB) && iCellIdx<=pPage->nCell );
  8190   8191         pCur->eState = CURSOR_SKIPNEXT;
  8191   8192         if( iCellIdx>=pPage->nCell ){
  8192   8193           pCur->skipNext = -1;
  8193   8194           pCur->aiIdx[iCellDepth] = pPage->nCell-1;
  8194   8195         }else{
  8195   8196           pCur->skipNext = 1;
  8196   8197         }
................................................................................
  8917   8918           i = get4byte(pOvflData);
  8918   8919           checkPtrmap(pCheck, i, PTRMAP_OVERFLOW2, iPage);
  8919   8920         }
  8920   8921       }
  8921   8922   #endif
  8922   8923       iPage = get4byte(pOvflData);
  8923   8924       sqlite3PagerUnref(pOvflPage);
         8925  +
         8926  +    if( isFreeList && N<(iPage!=0) ){
         8927  +      checkAppendMsg(pCheck, "free-page count in header is too small");
         8928  +    }
  8924   8929     }
  8925   8930   }
  8926   8931   #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
  8927   8932   
  8928   8933   /*
  8929   8934   ** An implementation of a min-heap.
  8930   8935   **

Changes to src/delete.c.

   411    411       **  ONEPASS_SINGLE: One-pass approach - at most one row deleted.
   412    412       **  ONEPASS_MULTI:  One-pass approach - any number of rows may be deleted.
   413    413       */
   414    414       pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, wcf, iTabCur+1);
   415    415       if( pWInfo==0 ) goto delete_from_cleanup;
   416    416       eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
   417    417       assert( IsVirtual(pTab)==0 || eOnePass==ONEPASS_OFF );
          418  +    assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF );
   418    419     
   419    420       /* Keep track of the number of rows to be deleted */
   420    421       if( db->flags & SQLITE_CountRows ){
   421    422         sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1);
   422    423       }
   423    424     
   424    425       /* Extract the rowid or primary key for the current row */

Changes to src/os_unix.c.

  4656   4656   ** All loads and stores begun before the barrier must complete before
  4657   4657   ** any load or store begun after the barrier.
  4658   4658   */
  4659   4659   static void unixShmBarrier(
  4660   4660     sqlite3_file *fd                /* Database file holding the shared memory */
  4661   4661   ){
  4662   4662     UNUSED_PARAMETER(fd);
  4663         -  unixEnterMutex();
         4663  +  sqlite3MemoryBarrier();         /* compiler-defined memory barrier */
         4664  +  unixEnterMutex();               /* Also mutex, for redundancy */
  4664   4665     unixLeaveMutex();
  4665   4666   }
  4666   4667   
  4667   4668   /*
  4668   4669   ** Close a connection to shared-memory.  Delete the underlying 
  4669   4670   ** storage if deleteFlag is true.
  4670   4671   **

Changes to src/os_win.c.

  3846   3846   ** All loads and stores begun before the barrier must complete before
  3847   3847   ** any load or store begun after the barrier.
  3848   3848   */
  3849   3849   static void winShmBarrier(
  3850   3850     sqlite3_file *fd          /* Database holding the shared memory */
  3851   3851   ){
  3852   3852     UNUSED_PARAMETER(fd);
  3853         -  /* MemoryBarrier(); // does not work -- do not know why not */
  3854         -  winShmEnterMutex();
         3853  +  sqlite3MemoryBarrier();   /* compiler-defined memory barrier */
         3854  +  winShmEnterMutex();       /* Also mutex, for redundancy */
  3855   3855     winShmLeaveMutex();
  3856   3856   }
  3857   3857   
  3858   3858   /*
  3859   3859   ** This function is called to obtain a pointer to region iRegion of the
  3860   3860   ** shared-memory associated with the database file fd. Shared-memory regions
  3861   3861   ** are numbered starting from zero. Each shared-memory region is szRegion

Changes to src/pager.c.

  2111   2111       pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize,
  2112   2112                              (int)pPager->nReserve);
  2113   2113     }
  2114   2114   }
  2115   2115   #else
  2116   2116   # define pagerReportSize(X)     /* No-op if we do not support a codec */
  2117   2117   #endif
         2118  +
         2119  +#ifdef SQLITE_HAS_CODEC
         2120  +/*
         2121  +** Make sure the number of reserved bits is the same in the destination
         2122  +** pager as it is in the source.  This comes up when a VACUUM changes the
         2123  +** number of reserved bits to the "optimal" amount.
         2124  +*/
         2125  +void sqlite3PagerAlignReserve(Pager *pDest, Pager *pSrc){
         2126  +  if( pDest->nReserve!=pSrc->nReserve ){
         2127  +    pDest->nReserve = pSrc->nReserve;
         2128  +    pagerReportSize(pDest);
         2129  +  }
         2130  +}
         2131  +#endif
  2118   2132   
  2119   2133   /*
  2120   2134   ** Read a single page from either the journal file (if isMainJrnl==1) or
  2121   2135   ** from the sub-journal (if isMainJrnl==0) and playback that page.
  2122   2136   ** The page begins at offset *pOffset into the file. The *pOffset
  2123   2137   ** value is increased to the start of the next page in the journal.
  2124   2138   **

Changes to src/pager.h.

   114    114   );
   115    115   int sqlite3PagerClose(Pager *pPager);
   116    116   int sqlite3PagerReadFileheader(Pager*, int, unsigned char*);
   117    117   
   118    118   /* Functions used to configure a Pager object. */
   119    119   void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *);
   120    120   int sqlite3PagerSetPagesize(Pager*, u32*, int);
          121  +#ifdef SQLITE_HAS_CODEC
          122  +void sqlite3PagerAlignReserve(Pager*,Pager*);
          123  +#endif
   121    124   int sqlite3PagerMaxPageCount(Pager*, int);
   122    125   void sqlite3PagerSetCachesize(Pager*, int);
   123    126   void sqlite3PagerSetMmapLimit(Pager *, sqlite3_int64);
   124    127   void sqlite3PagerShrink(Pager*);
   125    128   void sqlite3PagerSetFlags(Pager*,unsigned);
   126    129   int sqlite3PagerLockingMode(Pager *, int);
   127    130   int sqlite3PagerSetJournalMode(Pager *, int);

Changes to src/pcache1.c.

   409    409       /* The group mutex must be released before pcache1Alloc() is called. This
   410    410       ** is because it might call sqlite3_release_memory(), which assumes that 
   411    411       ** this mutex is not held. */
   412    412       assert( pcache1.separateCache==0 );
   413    413       assert( pCache->pGroup==&pcache1.grp );
   414    414       pcache1LeaveMutex(pCache->pGroup);
   415    415   #endif
   416         -    if( benignMalloc ) sqlite3BeginBenignMalloc();
          416  +    if( benignMalloc ){ sqlite3BeginBenignMalloc(); }
   417    417   #ifdef SQLITE_PCACHE_SEPARATE_HEADER
   418    418       pPg = pcache1Alloc(pCache->szPage);
   419    419       p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra);
   420    420       if( !pPg || !p ){
   421    421         pcache1Free(pPg);
   422    422         sqlite3_free(p);
   423    423         pPg = 0;
   424    424       }
   425    425   #else
   426    426       pPg = pcache1Alloc(pCache->szAlloc);
   427    427       p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
   428    428   #endif
   429         -    if( benignMalloc ) sqlite3EndBenignMalloc();
          429  +    if( benignMalloc ){ sqlite3EndBenignMalloc(); }
   430    430   #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
   431    431       pcache1EnterMutex(pCache->pGroup);
   432    432   #endif
   433    433       if( pPg==0 ) return 0;
   434    434       p->page.pBuf = pPg;
   435    435       p->page.pExtra = &p[1];
   436    436       p->isBulkLocal = 0;

Changes to src/resolve.c.

   351    351         }
   352    352       }
   353    353   #endif /* !defined(SQLITE_OMIT_TRIGGER) */
   354    354   
   355    355       /*
   356    356       ** Perhaps the name is a reference to the ROWID
   357    357       */
   358         -    if( cnt==0 && cntTab==1 && pMatch && sqlite3IsRowid(zCol)
   359         -     && VisibleRowid(pMatch->pTab) ){
          358  +    if( cnt==0
          359  +     && cntTab==1
          360  +     && pMatch
          361  +     && (pNC->ncFlags & NC_IdxExpr)==0
          362  +     && sqlite3IsRowid(zCol)
          363  +     && VisibleRowid(pMatch->pTab)
          364  +    ){
   360    365         cnt = 1;
   361    366         pExpr->iColumn = -1;     /* IMP: R-44911-55124 */
   362    367         pExpr->affinity = SQLITE_AFF_INTEGER;
   363    368       }
   364    369   
   365    370       /*
   366    371       ** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z

Changes to src/select.c.

  4263   4263              pTab->zName);
  4264   4264           pFrom->pTab = 0;
  4265   4265           return WRC_Abort;
  4266   4266         }
  4267   4267         pTab->nRef++;
  4268   4268   #if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
  4269   4269         if( pTab->pSelect || IsVirtual(pTab) ){
  4270         -        /* We reach here if the named table is a really a view */
  4271   4270           if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
  4272   4271           assert( pFrom->pSelect==0 );
         4272  +        if( pFrom->fg.isTabFunc && !IsVirtual(pTab) ){
         4273  +          sqlite3ErrorMsg(pParse, "'%s' is not a function", pTab->zName);
         4274  +          return WRC_Abort;
         4275  +        }
  4273   4276           pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
  4274   4277           sqlite3SelectSetName(pFrom->pSelect, pTab->zName);
  4275   4278           sqlite3WalkSelect(pWalker, pFrom->pSelect);
  4276   4279         }
  4277   4280   #endif
  4278   4281       }
  4279   4282   

Changes to src/sqlite.h.in.

  3626   3626   ** parameter to [sqlite3_bind_blob|sqlite3_bind()].  ^A zero
  3627   3627   ** is returned if no matching parameter is found.  ^The parameter
  3628   3628   ** name must be given in UTF-8 even if the original statement
  3629   3629   ** was prepared from UTF-16 text using [sqlite3_prepare16_v2()].
  3630   3630   **
  3631   3631   ** See also: [sqlite3_bind_blob|sqlite3_bind()],
  3632   3632   ** [sqlite3_bind_parameter_count()], and
  3633         -** [sqlite3_bind_parameter_index()].
         3633  +** [sqlite3_bind_parameter_name()].
  3634   3634   */
  3635   3635   int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
  3636   3636   
  3637   3637   /*
  3638   3638   ** CAPI3REF: Reset All Bindings On A Prepared Statement
  3639   3639   ** METHOD: sqlite3_stmt
  3640   3640   **

Changes to src/vdbeapi.c.

   908    908     ** __attribute__((aligned(8))) macro.  */
   909    909     static const Mem nullMem 
   910    910   #if defined(SQLITE_DEBUG) && defined(__GNUC__)
   911    911       __attribute__((aligned(8))) 
   912    912   #endif
   913    913       = {
   914    914           /* .u          = */ {0},
   915         -        /* .flags      = */ MEM_Null,
   916         -        /* .enc        = */ 0,
   917         -        /* .n          = */ 0,
   918         -        /* .z          = */ 0,
   919         -        /* .zMalloc    = */ 0,
   920         -        /* .szMalloc   = */ 0,
   921         -        /* .iPadding1  = */ 0,
   922         -        /* .db         = */ 0,
   923         -        /* .xDel       = */ 0,
          915  +        /* .flags      = */ (u16)MEM_Null,
          916  +        /* .enc        = */ (u8)0,
          917  +        /* .eSubtype   = */ (u8)0,
          918  +        /* .n          = */ (int)0,
          919  +        /* .z          = */ (char*)0,
          920  +        /* .zMalloc    = */ (char*)0,
          921  +        /* .szMalloc   = */ (int)0,
          922  +        /* .uTemp      = */ (u32)0,
          923  +        /* .db         = */ (sqlite3*)0,
          924  +        /* .xDel       = */ (void(*)(void*))0,
   924    925   #ifdef SQLITE_DEBUG
   925         -        /* .pScopyFrom = */ 0,
   926         -        /* .pFiller    = */ 0,
          926  +        /* .pScopyFrom = */ (Mem*)0,
          927  +        /* .pFiller    = */ (void*)0,
   927    928   #endif
   928    929         };
   929    930     return &nullMem;
   930    931   }
   931    932   
   932    933   /*
   933    934   ** Check to see if column iCol of the given statement is valid.  If

Changes to src/where.c.

   178    178     WhereClause *pWC;    /* Shorthand for pScan->pWC */
   179    179     WhereTerm *pTerm;    /* The term being tested */
   180    180     int k = pScan->k;    /* Where to start scanning */
   181    181   
   182    182     while( pScan->iEquiv<=pScan->nEquiv ){
   183    183       iCur = pScan->aiCur[pScan->iEquiv-1];
   184    184       iColumn = pScan->aiColumn[pScan->iEquiv-1];
   185         -    assert( iColumn!=(-2) || pScan->pIdxExpr!=0 );
          185  +    if( iColumn==(-2) && pScan->pIdxExpr==0 ) return 0;
   186    186       while( (pWC = pScan->pWC)!=0 ){
   187    187         for(pTerm=pWC->a+k; k<pWC->nTerm; k++, pTerm++){
   188    188           if( pTerm->leftCursor==iCur
   189    189            && pTerm->u.leftColumn==iColumn
   190    190            && (iColumn!=(-2)
   191    191                  || sqlite3ExprCompare(pTerm->pExpr->pLeft,pScan->pIdxExpr,iCur)==0)
   192    192            && (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin))
   193    193           ){
   194    194             if( (pTerm->eOperator & WO_EQUIV)!=0
   195    195              && pScan->nEquiv<ArraySize(pScan->aiCur)
          196  +           && (pX = sqlite3ExprSkipCollate(pTerm->pExpr->pRight))->op==TK_COLUMN
   196    197             ){
   197    198               int j;
   198         -            pX = sqlite3ExprSkipCollate(pTerm->pExpr->pRight);
   199         -            assert( pX->op==TK_COLUMN );
   200    199               for(j=0; j<pScan->nEquiv; j++){
   201    200                 if( pScan->aiCur[j]==pX->iTable
   202    201                  && pScan->aiColumn[j]==pX->iColumn ){
   203    202                     break;
   204    203                 }
   205    204               }
   206    205               if( j==pScan->nEquiv ){

Changes to src/wherecode.c.

    61     61   **   SELECT * FROM t1 WHERE a=1 AND b>2;
    62     62   **
    63     63   ** is run and there is an index on (a, b), then this function returns a
    64     64   ** string similar to:
    65     65   **
    66     66   **   "a=? AND b>?"
    67     67   */
    68         -static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop, Table *pTab){
           68  +static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){
    69     69     Index *pIndex = pLoop->u.btree.pIndex;
    70     70     u16 nEq = pLoop->u.btree.nEq;
    71     71     u16 nSkip = pLoop->nSkip;
    72     72     int i, j;
    73     73   
    74     74     if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return;
    75     75     sqlite3StrAccumAppend(pStr, " (", 2);
................................................................................
   162    162           zFmt = "COVERING INDEX %s";
   163    163         }else{
   164    164           zFmt = "INDEX %s";
   165    165         }
   166    166         if( zFmt ){
   167    167           sqlite3StrAccumAppend(&str, " USING ", 7);
   168    168           sqlite3XPrintf(&str, 0, zFmt, pIdx->zName);
   169         -        explainIndexRange(&str, pLoop, pItem->pTab);
          169  +        explainIndexRange(&str, pLoop);
   170    170         }
   171    171       }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
   172    172         const char *zRangeOp;
   173    173         if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){
   174    174           zRangeOp = "=";
   175    175         }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
   176    176           zRangeOp = ">? AND rowid<";
................................................................................
   510    510       pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT),
   511    511                               iIdxCur, 0, regBase, nSkip);
   512    512       VdbeCoverageIf(v, bRev==0);
   513    513       VdbeCoverageIf(v, bRev!=0);
   514    514       sqlite3VdbeJumpHere(v, j);
   515    515       for(j=0; j<nSkip; j++){
   516    516         sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, j, regBase+j);
   517         -      assert( pIdx->aiColumn[j]>=0 );
   518         -      VdbeComment((v, "%s", pIdx->pTable->aCol[pIdx->aiColumn[j]].zName));
          517  +      testcase( pIdx->aiColumn[j]==(-2) );
          518  +      VdbeComment((v, "%s", explainIndexColumnName(pIdx, j)));
   519    519       }
   520    520     }    
   521    521   
   522    522     /* Evaluate the equality constraints
   523    523     */
   524    524     assert( zAff==0 || (int)strlen(zAff)>=nEq );
   525    525     for(j=nSkip; j<nEq; j++){

Changes to test/corrupt2.test.

    13     13   # This file implements tests to make sure SQLite does not crash or
    14     14   # segfault if it sees a corrupt database file.
    15     15   #
    16     16   # $Id: corrupt2.test,v 1.20 2009/04/06 17:50:03 danielk1977 Exp $
    17     17   
    18     18   set testdir [file dirname $argv0]
    19     19   source $testdir/tester.tcl
           20  +set testprefix corrupt2
    20     21   
    21     22   # Do not use a codec for tests in this file, as the database file is
    22     23   # manipulated directly using tcl scripts (using the [hexio_write] command).
    23     24   #
    24     25   do_not_use_codec
    25     26   
    26     27   # These tests deal with corrupt database files
................................................................................
   553    554         file size corrupt.db
   554    555       } [expr $::sqlite_pending_byte + 1024]
   555    556       do_test corrupt2-13.3 {
   556    557         catchsql { DELETE FROM t1 WHERE rowid < 30; }
   557    558       } {1 {database disk image is malformed}}
   558    559     }
   559    560   }
          561  +
          562  +#-------------------------------------------------------------------------
          563  +# Test that PRAGMA integrity_check detects cases where the freelist-count
          564  +# header field is smaller than the actual number of pages on the freelist.
          565  +#
          566  +
          567  +reset_db
          568  +do_execsql_test 14.0 {
          569  +  PRAGMA auto_vacuum = 0;
          570  +  CREATE TABLE t1(x);
          571  +  INSERT INTO t1 VALUES(randomblob(3500));
          572  +  DELETE FROM t1;
          573  +}
          574  +
          575  +do_execsql_test 14.1 {
          576  +  PRAGMA integrity_check;
          577  +  PRAGMA freelist_count;
          578  +} {ok 3}
          579  +
          580  +# There are now 3 free pages. Modify the header-field so that it 
          581  +# (incorrectly) says that just 2 are free.
          582  +do_test 14.2 {
          583  +  db close
          584  +  hexio_write test.db 36 [hexio_render_int32 2]
          585  +  sqlite3 db test.db
          586  +  execsql { PRAGMA freelist_count }
          587  +} {2}
          588  +
          589  +do_execsql_test 14.3 {
          590  +  PRAGMA integrity_check;
          591  +} {{*** in database main ***
          592  +Main freelist: free-page count in header is too small}}
          593  +
          594  +# Use 2 of the free pages on the free-list.
          595  +#
          596  +do_execsql_test 14.4 {
          597  +  INSERT INTO t1 VALUES(randomblob(2500));
          598  +  PRAGMA freelist_count;
          599  +} {0}
          600  +
          601  +do_execsql_test 14.5 {
          602  +  PRAGMA integrity_check;
          603  +} {{*** in database main ***
          604  +Page 3 is never used}}
          605  +
          606  +
          607  +finish_test
   560    608   
   561    609   finish_test

Changes to test/corruptC.test.

   184    184   
   185    185     # insert corrupt byte(s)
   186    186     hexio_write test.db 3074 [format %02x 0xa0]
   187    187   
   188    188     sqlite3 db test.db
   189    189     catchsql {BEGIN; UPDATE t2 SET y='abcdef-uvwxyz'; ROLLBACK;}
   190    190   } {1 {database disk image is malformed}}
          191  +
   191    192   
   192    193   # corruption (seed 179069)
          194  +# Obsolete.  With single-pass DELETE the corruption in the
          195  +# main database is not detected.
          196  +if 0 {
   193    197   do_test corruptC-2.8 {
   194    198     db close
   195    199     forcecopy test.bu test.db
   196    200   
   197    201     # insert corrupt byte(s)
   198    202     hexio_write test.db 1393 [format %02x 0x7d]
   199    203     hexio_write test.db 84 [format %02x 0x19]
................................................................................
   200    204     hexio_write test.db 3287 [format %02x 0x3b]
   201    205     hexio_write test.db 2564 [format %02x 0xed]
   202    206     hexio_write test.db 2139 [format %02x 0x55]
   203    207   
   204    208     sqlite3 db test.db
   205    209     catchsql {BEGIN; DELETE FROM t1 WHERE x>13; ROLLBACK;}
   206    210   } {1 {database disk image is malformed}}
          211  +}
   207    212   
   208    213   # corruption (seed 170434)
   209    214   #
   210    215   # UPDATE: Prior to 3.8.2, this used to return SQLITE_CORRUPT. It no longer
   211    216   # does. That is Ok, the point of these tests is to verify that no buffer
   212    217   # overruns or overreads can be caused by corrupt databases.
   213    218   do_test corruptC-2.9 {

Changes to test/fuzzcheck.c.

   291    291     if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
   292    292       sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
   293    293     }else{
   294    294       sqlite3_free(pBuf);
   295    295     }
   296    296     fclose(in);
   297    297   }
          298  +
          299  +/*
          300  +** Implementation of the "writefile(X,Y)" SQL function.  The argument Y
          301  +** is written into file X.  The number of bytes written is returned.  Or
          302  +** NULL is returned if something goes wrong, such as being unable to open
          303  +** file X for writing.
          304  +*/
          305  +static void writefileFunc(
          306  +  sqlite3_context *context,
          307  +  int argc,
          308  +  sqlite3_value **argv
          309  +){
          310  +  FILE *out;
          311  +  const char *z;
          312  +  sqlite3_int64 rc;
          313  +  const char *zFile;
          314  +
          315  +  (void)argc;
          316  +  zFile = (const char*)sqlite3_value_text(argv[0]);
          317  +  if( zFile==0 ) return;
          318  +  out = fopen(zFile, "wb");
          319  +  if( out==0 ) return;
          320  +  z = (const char*)sqlite3_value_blob(argv[1]);
          321  +  if( z==0 ){
          322  +    rc = 0;
          323  +  }else{
          324  +    rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
          325  +  }
          326  +  fclose(out);
          327  +  sqlite3_result_int64(context, rc);
          328  +}
          329  +
   298    330   
   299    331   /*
   300    332   ** Load a list of Blob objects from the database
   301    333   */
   302    334   static void blobListLoadFromDb(
   303    335     sqlite3 *db,             /* Read from this database */
   304    336     const char *zSql,        /* Query used to extract the blobs */
................................................................................
   747    779     printf("Usage: %s [options] SOURCE-DB ?ARGS...?\n", g.zArgv0);
   748    780     printf(
   749    781   "Read databases and SQL scripts from SOURCE-DB and execute each script against\n"
   750    782   "each database, checking for crashes and memory leaks.\n"
   751    783   "Options:\n"
   752    784   "  --cell-size-check     Set the PRAGMA cell_size_check=ON\n"
   753    785   "  --dbid N              Use only the database where dbid=N\n"
          786  +"  --export-db DIR       Write databases to files(s) in DIR. Works with --dbid\n"
          787  +"  --export-sql DIR      Write SQL to file(s) in DIR. Also works with --sqlid\n"
   754    788   "  --help                Show this help text\n"
   755    789   "  -q                    Reduced output\n"
   756    790   "  --quiet               Reduced output\n"
   757    791   "  --limit-mem N         Limit memory used by test SQLite instance to N bytes\n"
   758    792   "  --limit-vdbe          Panic if an sync SQL runs for more than 100,000 cycles\n"
   759    793   "  --load-sql ARGS...    Load SQL scripts fro files into SOURCE-DB\n"
   760    794   "  --load-db ARGS...     Load template databases from files into SOURCE_DB\n"
   761    795   "  -m TEXT               Add a description to the database\n"
   762    796   "  --native-vfs          Use the native VFS for initially empty database files\n"
   763    797   "  --rebuild             Rebuild and vacuum the database file\n"
   764    798   "  --result-trace        Show the results of each SQL command\n"
   765    799   "  --sqlid N             Use only SQL where sqlid=N\n"
   766         -"  --timeline N          Abort if any single test case needs more than N seconds\n"
          800  +"  --timeout N           Abort if any single test case needs more than N seconds\n"
   767    801   "  -v                    Increased output\n"
   768    802   "  --verbose             Increased output\n"
   769    803     );
   770    804   }
   771    805   
   772    806   int main(int argc, char **argv){
   773    807     sqlite3_int64 iBegin;        /* Start time of this program */
................................................................................
   795    829     int nTest = 0;               /* Total number of tests performed */
   796    830     char *zDbName = "";          /* Appreviated name of a source database */
   797    831     const char *zFailCode = 0;   /* Value of the TEST_FAILURE environment variable */
   798    832     int cellSzCkFlag = 0;        /* --cell-size-check */
   799    833     int sqlFuzz = 0;             /* True for SQL fuzz testing. False for DB fuzz */
   800    834     int iTimeout = 120;          /* Default 120-second timeout */
   801    835     int nMem = 0;                /* Memory limit */
          836  +  char *zExpDb = 0;            /* Write Databases to files in this directory */
          837  +  char *zExpSql = 0;           /* Write SQL to files in this directory */
   802    838   
   803    839     iBegin = timeOfDay();
   804    840   #ifdef __unix__
   805    841     signal(SIGALRM, timeoutHandler);
   806    842   #endif
   807    843     g.zArgv0 = argv[0];
   808    844     zFailCode = getenv("TEST_FAILURE");
................................................................................
   813    849         if( z[0]=='-' ) z++;
   814    850         if( strcmp(z,"cell-size-check")==0 ){
   815    851           cellSzCkFlag = 1;
   816    852         }else
   817    853         if( strcmp(z,"dbid")==0 ){
   818    854           if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
   819    855           onlyDbid = integerValue(argv[++i]);
          856  +      }else
          857  +      if( strcmp(z,"export-db")==0 ){
          858  +        if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
          859  +        zExpDb = argv[++i];
          860  +      }else
          861  +      if( strcmp(z,"export-sql")==0 ){
          862  +        if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
          863  +        zExpSql = argv[++i];
   820    864         }else
   821    865         if( strcmp(z,"help")==0 ){
   822    866           showHelp();
   823    867           return 0;
   824    868         }else
   825    869         if( strcmp(z,"limit-mem")==0 ){
   826    870           if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
................................................................................
   939    983         sqlite3_finalize(pStmt);
   940    984         rc = sqlite3_exec(db, "COMMIT", 0, 0, 0);
   941    985         if( rc ) fatalError("cannot commit the transaction: %s", sqlite3_errmsg(db));
   942    986         rebuild_database(db);
   943    987         sqlite3_close(db);
   944    988         return 0;
   945    989       }
          990  +    if( zExpDb!=0 || zExpSql!=0 ){
          991  +      sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0,
          992  +                              writefileFunc, 0, 0);
          993  +      if( zExpDb!=0 ){
          994  +        const char *zExDb = 
          995  +          "SELECT writefile(printf('%s/db%06d.db',?1,dbid),dbcontent),"
          996  +          "       dbid, printf('%s/db%06d.db',?1,dbid), length(dbcontent)"
          997  +          "  FROM db WHERE ?2<0 OR dbid=?2;";
          998  +        rc = sqlite3_prepare_v2(db, zExDb, -1, &pStmt, 0);
          999  +        if( rc ) fatalError("cannot prepare statement [%s]: %s",
         1000  +                            zExDb, sqlite3_errmsg(db));
         1001  +        sqlite3_bind_text64(pStmt, 1, zExpDb, strlen(zExpDb),
         1002  +                            SQLITE_STATIC, SQLITE_UTF8);
         1003  +        sqlite3_bind_int(pStmt, 2, onlyDbid);
         1004  +        while( sqlite3_step(pStmt)==SQLITE_ROW ){
         1005  +          printf("write db-%d (%d bytes) into %s\n",
         1006  +             sqlite3_column_int(pStmt,1),
         1007  +             sqlite3_column_int(pStmt,3),
         1008  +             sqlite3_column_text(pStmt,2));
         1009  +        }
         1010  +        sqlite3_finalize(pStmt);
         1011  +      }
         1012  +      if( zExpSql!=0 ){
         1013  +        const char *zExSql = 
         1014  +          "SELECT writefile(printf('%s/sql%06d.txt',?1,sqlid),sqltext),"
         1015  +          "       sqlid, printf('%s/sql%06d.txt',?1,sqlid), length(sqltext)"
         1016  +          "  FROM xsql WHERE ?2<0 OR sqlid=?2;";
         1017  +        rc = sqlite3_prepare_v2(db, zExSql, -1, &pStmt, 0);
         1018  +        if( rc ) fatalError("cannot prepare statement [%s]: %s",
         1019  +                            zExSql, sqlite3_errmsg(db));
         1020  +        sqlite3_bind_text64(pStmt, 1, zExpSql, strlen(zExpSql),
         1021  +                            SQLITE_STATIC, SQLITE_UTF8);
         1022  +        sqlite3_bind_int(pStmt, 2, onlySqlid);
         1023  +        while( sqlite3_step(pStmt)==SQLITE_ROW ){
         1024  +          printf("write sql-%d (%d bytes) into %s\n",
         1025  +             sqlite3_column_int(pStmt,1),
         1026  +             sqlite3_column_int(pStmt,3),
         1027  +             sqlite3_column_text(pStmt,2));
         1028  +        }
         1029  +        sqlite3_finalize(pStmt);
         1030  +      }
         1031  +      sqlite3_close(db);
         1032  +      return 0;
         1033  +    }
   946   1034     
   947   1035       /* Load all SQL script content and all initial database images from the
   948   1036       ** source db
   949   1037       */
   950   1038       blobListLoadFromDb(db, "SELECT sqlid, sqltext FROM xsql", onlySqlid,
   951   1039                              &g.nSql, &g.pFirstSql);
   952   1040       if( g.nSql==0 ) fatalError("need at least one SQL script");
................................................................................
  1035   1123           openFlags = SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE;
  1036   1124           if( nativeFlag && pDb->sz==0 ){
  1037   1125             openFlags |= SQLITE_OPEN_MEMORY;
  1038   1126             zVfs = 0;
  1039   1127           }
  1040   1128           rc = sqlite3_open_v2("main.db", &db, openFlags, zVfs);
  1041   1129           if( rc ) fatalError("cannot open inmem database");
         1130  +#ifdef SQLITE_ENABLE_JSON1
         1131  +        {
         1132  +          extern int sqlite3_json_init(sqlite3*);
         1133  +          sqlite3_json_init(db);
         1134  +        }
         1135  +#endif
  1042   1136           if( cellSzCkFlag ) runSql(db, "PRAGMA cell_size_check=ON", runFlags);
  1043   1137           setAlarm(iTimeout);
  1044   1138   #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  1045   1139           if( sqlFuzz || vdbeLimitFlag ){
  1046   1140             sqlite3_progress_handler(db, 100000, progressHandler, &vdbeLimitFlag);
  1047   1141           }
  1048   1142   #endif

Added test/fuzzdata4.db.

cannot compute difference between binary files

Changes to test/indexexpr1.test.

   214    214     SELECT substr(a,4,3) AS k FROM cnt, t5 WHERE k=printf('%03d',x);
   215    215   } {001 002 003 004 005}
   216    216   do_execsql_test indexexpr1-510eqp {
   217    217     EXPLAIN QUERY PLAN
   218    218     SELECT substr(a,4,3) AS k FROM cnt, t5 WHERE k=printf('%03d',x);
   219    219   } {/USING INDEX t5ax/}
   220    220   
          221  +# Skip-scan on an indexed expression
          222  +#
          223  +do_execsql_test indexexpr1-600 {
          224  +  DROP TABLE IF EXISTS t4;
          225  +  CREATE TABLE t4(a,b,c,d,e,f,g,h,i);
          226  +  CREATE INDEX t4all ON t4(a,b,c<d,e,f,i,h);
          227  +  INSERT INTO t4 VALUES(1,2,3,4,5,6,7,8,9);
          228  +  ANALYZE;
          229  +  DELETE FROM sqlite_stat1;
          230  +  INSERT INTO sqlite_stat1
          231  +    VALUES('t4','t4all','600000 160000 40000 10000 2000 600 100 40 10');
          232  +  ANALYZE sqlite_master;
          233  +  SELECT i FROM t4 WHERE e=5;
          234  +} {9}
          235  +
          236  +# Indexed expressions on both sides of an == in a WHERE clause.
          237  +#
          238  +do_execsql_test indexexpr1-700 {
          239  +  DROP TABLE IF EXISTS t7;
          240  +  CREATE TABLE t7(a,b,c);
          241  +  INSERT INTO t7(a,b,c) VALUES(1,2,2),('abc','def','def'),(4,5,6);
          242  +  CREATE INDEX t7b ON t7(+b);
          243  +  CREATE INDEX t7c ON t7(+c);
          244  +  SELECT *, '|' FROM t7 WHERE +b=+c ORDER BY +a;
          245  +} {1 2 2 | abc def def |}
          246  +do_execsql_test indexexpr1-710 {
          247  +  CREATE TABLE t71(a,b,c);
          248  +  CREATE INDEX t71bc ON t71(b+c);
          249  +  CREATE TABLE t72(x,y,z);
          250  +  CREATE INDEX t72yz ON t72(y+z);
          251  +  INSERT INTO t71(a,b,c) VALUES(1,11,2),(2,7,15),(3,5,4);
          252  +  INSERT INTO t72(x,y,z) VALUES(1,10,3),(2,8,14),(3,9,9);
          253  +  SELECT a, x, '|' FROM t71, t72
          254  +   WHERE b+c=y+z
          255  +  ORDER BY +a, +x;
          256  +} {1 1 | 2 2 |}
   221    257   
   222    258   finish_test

Changes to test/json101.test.

    12     12   # SQLite library.
    13     13   #
    14     14   
    15     15   set testdir [file dirname $argv0]
    16     16   source $testdir/tester.tcl
    17     17   
    18     18   load_static_extension db json
    19         -do_execsql_test json1-1.1.00 {
           19  +do_execsql_test json101-1.1.00 {
    20     20     SELECT json_array(1,2.5,null,'hello');
    21     21   } {[1,2.5,null,"hello"]}
    22         -do_execsql_test json1-1.1.01 {
           22  +do_execsql_test json101-1.1.01 {
    23     23     SELECT json_array(1,'{"abc":2.5,"def":null,"ghi":hello}',99);
    24     24     -- the second term goes in as a string:
    25     25   } {[1,"{\\"abc\\":2.5,\\"def\\":null,\\"ghi\\":hello}",99]}
    26         -do_execsql_test json1-1.1.02 {
           26  +do_execsql_test json101-1.1.02 {
    27     27     SELECT json_array(1,json('{"abc":2.5,"def":null,"ghi":"hello"}'),99);
    28     28     -- the second term goes in as JSON
    29     29   } {[1,{"abc":2.5,"def":null,"ghi":"hello"},99]}
    30         -do_execsql_test json1-1.1.03 {
           30  +do_execsql_test json101-1.1.03 {
    31     31     SELECT json_array(1,json_object('abc',2.5,'def',null,'ghi','hello'),99);
    32     32     -- the second term goes in as JSON
    33     33   } {[1,{"abc":2.5,"def":null,"ghi":"hello"},99]}
    34         -do_execsql_test json1-1.2 {
           34  +do_execsql_test json101-1.2 {
    35     35     SELECT hex(json_array('String "\ Test'));
    36     36   } {5B22537472696E67205C225C5C2054657374225D}
    37         -do_catchsql_test json1-1.3 {
    38         -  SELECT json_array(1,2,x'abcd',3);
           37  +do_catchsql_test json101-1.3 {
           38  +  SELECT json_array(1,printf('%.1000c','x'),x'abcd',3);
    39     39   } {1 {JSON cannot hold BLOB values}}
    40         -do_execsql_test json1-1.4 {
           40  +do_execsql_test json101-1.4 {
    41     41     SELECT json_array(-9223372036854775808,9223372036854775807,0,1,-1,
    42     42                       0.0, 1.0, -1.0, -1e99, +2e100,
    43     43                       'one','two','three',
    44     44                       4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
    45     45                       19, NULL, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
    46     46                       'abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWXYZ',
    47     47                       'abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWXYZ',
    48     48                       'abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWXYZ',
    49     49                       99);
    50     50   } {[-9223372036854775808,9223372036854775807,0,1,-1,0.0,1.0,-1.0,-1.0e+99,2.0e+100,"one","two","three",4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,null,21,22,23,24,25,26,27,28,29,30,31,"abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWXYZ",99]}
    51     51   
    52         -do_execsql_test json1-2.1 {
           52  +do_execsql_test json101-2.1 {
    53     53     SELECT json_object('a',1,'b',2.5,'c',null,'d','String Test');
    54     54   } {{{"a":1,"b":2.5,"c":null,"d":"String Test"}}}
    55         -do_catchsql_test json1-2.2 {
    56         -  SELECT json_object('a',1,2,2.5);
           55  +do_catchsql_test json101-2.2 {
           56  +  SELECT json_object('a',printf('%.1000c','x'),2,2.5);
    57     57   } {1 {json_object() labels must be TEXT}}
    58         -do_catchsql_test json1-2.3 {
           58  +do_catchsql_test json101-2.3 {
    59     59     SELECT json_object('a',1,'b');
    60     60   } {1 {json_object() requires an even number of arguments}}
    61         -do_catchsql_test json1-2.4 {
    62         -  SELECT json_object('a',1,'b',x'abcd');
           61  +do_catchsql_test json101-2.4 {
           62  +  SELECT json_object('a',printf('%.1000c','x'),'b',x'abcd');
    63     63   } {1 {JSON cannot hold BLOB values}}
    64     64   
    65         -do_execsql_test json1-3.1 {
           65  +do_execsql_test json101-3.1 {
    66     66     SELECT json_replace('{"a":1,"b":2}','$.a','[3,4,5]');
    67     67   } {{{"a":"[3,4,5]","b":2}}}
    68         -do_execsql_test json1-3.2 {
           68  +do_execsql_test json101-3.2 {
    69     69     SELECT json_replace('{"a":1,"b":2}','$.a',json('[3,4,5]'));
    70     70   } {{{"a":[3,4,5],"b":2}}}
    71         -do_execsql_test json1-3.3 {
           71  +do_execsql_test json101-3.3 {
    72     72     SELECT json_type(json_set('{"a":1,"b":2}','$.b','{"x":3,"y":4}'),'$.b');
    73     73   } {text}
    74         -do_execsql_test json1-3.4 {
           74  +do_execsql_test json101-3.4 {
    75     75     SELECT json_type(json_set('{"a":1,"b":2}','$.b',json('{"x":3,"y":4}')),'$.b');
    76     76   } {object}
           77  +ifcapable vtab {
           78  +do_execsql_test json101-3.5 {
           79  +  SELECT fullkey, atom, '|' FROM json_tree(json_set('{}','$.x',123,'$.x',456));
           80  +} {{$} {} | {$.x} 456 |}
           81  +}
    77     82   
    78     83   # Per rfc7159, any JSON value is allowed at the top level, and whitespace
    79     84   # is permitting before and/or after that value.
    80     85   #
    81         -do_execsql_test json1-4.1 {
           86  +do_execsql_test json101-4.1 {
    82     87     CREATE TABLE j1(x);
    83     88     INSERT INTO j1(x)
    84     89      VALUES('true'),('false'),('null'),('123'),('-234'),('34.5e+6'),
    85     90            ('""'),('"\""'),('"\\"'),('"abcdefghijlmnopqrstuvwxyz"'),
    86     91            ('[]'),('{}'),('[true,false,null,123,-234,34.5e+6,{},[]]'),
    87     92            ('{"a":true,"b":{"c":false}}');
    88     93     SELECT * FROM j1 WHERE NOT json_valid(x);
    89     94   } {}
    90         -do_execsql_test json1-4.2 {
           95  +do_execsql_test json101-4.2 {
    91     96     SELECT * FROM j1 WHERE NOT json_valid(char(0x20,0x09,0x0a,0x0d)||x);
    92     97   } {}
    93         -do_execsql_test json1-4.3 {
           98  +do_execsql_test json101-4.3 {
    94     99     SELECT * FROM j1 WHERE NOT json_valid(x||char(0x20,0x09,0x0a,0x0d));
    95    100   } {}
    96    101   
    97    102   # But an empty string, or a string of pure whitespace is not valid JSON.
    98    103   #
    99         -do_execsql_test json1-4.4 {
          104  +do_execsql_test json101-4.4 {
   100    105     SELECT json_valid(''), json_valid(char(0x20,0x09,0x0a,0x0d));
   101    106   } {0 0}
   102    107   
   103    108   # json_remove() and similar functions with no edit operations return their
   104    109   # input unchanged.
   105    110   #
   106         -do_execsql_test json1-4.5 {
          111  +do_execsql_test json101-4.5 {
   107    112     SELECT x FROM j1 WHERE json_remove(x)<>x;
   108    113   } {}
   109         -do_execsql_test json1-4.6 {
          114  +do_execsql_test json101-4.6 {
   110    115     SELECT x FROM j1 WHERE json_replace(x)<>x;
   111    116   } {}
   112         -do_execsql_test json1-4.7 {
          117  +do_execsql_test json101-4.7 {
   113    118     SELECT x FROM j1 WHERE json_set(x)<>x;
   114    119   } {}
   115         -do_execsql_test json1-4.8 {
          120  +do_execsql_test json101-4.8 {
   116    121     SELECT x FROM j1 WHERE json_insert(x)<>x;
   117    122   } {}
   118    123   
   119    124   # json_extract(JSON,'$') will return objects and arrays without change.
   120    125   #
   121    126   do_execsql_test json-4.10 {
   122    127     SELECT count(*) FROM j1 WHERE json_type(x) IN ('object','array');
................................................................................
   298    303   } {}
   299    304   do_execsql_test json-5.8 {
   300    305     SELECT j2.rowid, jx.rowid, fullkey, path, key
   301    306       FROM j2, json_tree(j2.json) AS jx
   302    307      WHERE jx.value<>jx.atom AND type NOT IN ('array','object');
   303    308   } {}
   304    309   
          310  +do_execsql_test json-6.1 {
          311  +  SELECT json_valid('{"a":55,"b":72,}');
          312  +} {0}
          313  +do_execsql_test json-6.2 {
          314  +  SELECT json_valid('{"a":55,"b":72}');
          315  +} {1}
          316  +do_execsql_test json-6.3 {
          317  +  SELECT json_valid('["a",55,"b",72,]');
          318  +} {0}
          319  +do_execsql_test json-6.4 {
          320  +  SELECT json_valid('["a",55,"b",72]');
          321  +} {1}
   305    322   
   306    323   
   307    324   finish_test

Changes to test/json102.test.

   273    273   do_execsql_test json102-1132 {
   274    274     SELECT DISTINCT json_extract(big.json,'$.id')
   275    275       FROM big, json_tree(big.json)
   276    276      WHERE json_tree.key='uuid'
   277    277        AND json_tree.value='6fa5181e-5721-11e5-a04e-57f3d7b32808';
   278    278   } {123}
   279    279   } ;# end ifcapable vtab
          280  +
          281  +#-------------------------------------------------------------------------
          282  +# Test that json_valid() correctly identifies non-ascii range 
          283  +# characters as non-whitespace.
          284  +#
          285  +do_execsql_test json102-1201 { SELECT json_valid(char(32)  || '"xyz"') } 1
          286  +do_execsql_test json102-1202 { SELECT json_valid(char(200) || '"xyz"') } 0
          287  +
          288  +# Off-by-one error in jsonAppendString()
          289  +#
          290  +for {set i 0} {$i<100} {incr i} {
          291  +  set str abcdef[string repeat \" [expr {$i+50}]]uvwxyz
          292  +  do_test json102-[format %d [expr {$i+1300}]] {
          293  +    db eval {SELECT json_extract(json_array($::str),'$[0]')==$::str}
          294  +  } {1}
          295  +}
   280    296   
   281    297   finish_test

Changes to test/orderby9.test.

    23     23   do_execsql_test setup {
    24     24     -- create a table with many entries
    25     25     CREATE TABLE t1(x);
    26     26     WITH RECURSIVE
    27     27        c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100)
    28     28     INSERT INTO t1 SELECT x FROM c;
    29     29   }
           30  +
           31  +# Some versions of TCL are unable to [lsort -int] for
           32  +# 64-bit integers.  So we write our own comparison
           33  +# routine.
           34  +proc bigintcompare {a b} {
           35  +  set x [expr {$a-$b}]
           36  +  if {$x<0} {return -1}
           37  +  if {$x>0} {return +1}
           38  +  return 0
           39  +}
    30     40   do_test 1.0 {
    31     41     set l1 {}
    32     42     # If random() is only evaluated once and then reused for each row, then
    33     43     # the output should appear in sorted order.  If random() is evaluated 
    34     44     # separately for the result set and the ORDER BY clause, then the output
    35     45     # order will be random.
    36     46     db eval {SELECT random() AS y FROM t1 ORDER BY 1;} {lappend l1 $y}
    37         -  expr {$l1==[lsort -int $l1]}
           47  +  expr {$l1==[lsort -command bigintcompare $l1]}
    38     48   } {1}
    39     49   
    40     50   do_test 1.1 {
    41     51     set l1 {}
    42     52     db eval {SELECT random() AS y FROM t1 ORDER BY random();} {lappend l1 $y}
    43         -  expr {$l1==[lsort -int $l1]}
           53  +  expr {$l1==[lsort -command bigintcompare $l1]}
    44     54   } {1}
    45     55   
    46     56   do_test 1.2 {
    47     57     set l1 {}
    48     58     db eval {SELECT random() AS y FROM t1 ORDER BY +random();} {lappend l1 $y}
    49         -  expr {$l1==[lsort -int $l1]}
           59  +  expr {$l1==[lsort -command bigintcompare $l1]}
    50     60   } {0}
    51     61   
    52     62   finish_test

Changes to test/releasetest.tcl.

   293    293     if {[llength $args]==2} {
   294    294       puts [lindex $args 0] [lindex $args 1]
   295    295       puts $::LOG [lindex $args 1]
   296    296     } else {
   297    297       puts [lindex $args 0]
   298    298       puts $::LOG [lindex $args 0]
   299    299     }
          300  +  flush $::LOG
   300    301   }
   301    302   puts $LOG "$argv0 $argv"
   302    303   set tm0 [clock format [clock seconds] -format {%Y-%m-%d %H:%M:%S} -gmt 1]
   303    304   puts $LOG "start-time: $tm0 UTC"
   304    305   
   305    306   # Open the file $logfile and look for a report on the number of errors
   306    307   # and the number of test cases run.  Add these values to the global

Changes to test/spellfix2.test.

    25     25     INSERT INTO demo(word) VALUES ('amsterdamweg');
    26     26     INSERT INTO demo(word) VALUES ('amsterdamsestraat');
    27     27     INSERT INTO demo(word) VALUES ('amsterdamlaan');
    28     28   }
    29     29   
    30     30   do_execsql_test 1.1 {
    31     31     SELECT word, distance, matchlen FROM demo 
    32         -  WHERE word MATCH 'amstedam*' AND top=3;
           32  +  WHERE word MATCH 'amstedam*' AND top=3
           33  +  ORDER BY +word;
    33     34   } {
    34     35      amsterdam      100 9
    35         -   amsterdammetje 100 9
    36     36      amsterdamania  100 9
           37  +   amsterdammetje 100 9
    37     38   }
    38     39   
    39     40   do_execsql_test 1.2 {
    40     41     SELECT word, distance, matchlen FROM demo WHERE 
    41         -  word MATCH 'amstedam*' AND top=3 AND distance <= 100;
           42  +  word MATCH 'amstedam*' AND top=3 AND distance <= 100
           43  +  ORDER BY +word;
    42     44   } {
    43     45      amsterdam      100 9
    44         -   amsterdammetje 100 9
    45     46      amsterdamania  100 9
           47  +   amsterdammetje 100 9
    46     48   }
    47     49   
    48     50   do_execsql_test 1.3 {
    49     51     SELECT word, distance, matchlen FROM demo WHERE 
    50         -  word MATCH 'amstedam*' AND distance <= 100;
           52  +  word MATCH 'amstedam*' AND distance <= 100
           53  +  ORDER BY +word;
    51     54   } {
    52     55      amsterdam         100 9
    53         -   amsterdammetje    100 9
    54     56      amsterdamania     100 9
    55         -   amsterdamweg      100 9
           57  +   amsterdamlaan     100 9
           58  +   amsterdammetje    100 9
    56     59      amsterdamsestraat 100 9
    57         -   amsterdamlaan     100 9
           60  +   amsterdamweg      100 9
    58     61   }
    59     62   
    60     63   do_test 1.4 {
    61     64     foreach l {a b c d e f g h i j k l m n o p q r s t u v w x y z} {
    62     65       execsql { INSERT INTO demo(word) VALUES ('amsterdam' || $l) }
    63     66     }
    64     67   } {}
................................................................................
   107    110     amsterdamp        100 9        amsterdamv        100 9
   108    111     amsterdamw        100 9        amsterdamweg      100 9
   109    112     amsterdamc        100 9        amsterdamg        100 9
   110    113   }
   111    114   
   112    115   
   113    116   finish_test
   114         -

Changes to test/sqllimits1.test.

   639    639   
   640    640   do_test sqllimits1-8.8 {
   641    641     # Columns in a view definition:
   642    642     set cols [list]
   643    643     for {set i 0} {$i <= $SQLITE_LIMIT_COLUMN} {incr i} {
   644    644       lappend cols "c$i"
   645    645     }
   646         -  catchsql "CREATE VIEW v1 AS SELECT [join $cols ,] FROM t1;"
          646  +  execsql "CREATE VIEW v1 AS SELECT [join $cols ,] FROM t1;"
          647  +  catchsql {SELECT * FROM v1}
   647    648   } {1 {too many columns in result set}}
   648    649   
   649    650   do_test sqllimits1-8.9 {
   650    651     # Columns in a view definition (testing * expansion):
   651    652     set cols [list]
   652    653     for {set i 0} {$i < $SQLITE_LIMIT_COLUMN} {incr i} {
   653    654       lappend cols "c$i"
   654    655     }
          656  +  execsql {DROP VIEW IF EXISTS v1}
   655    657     catchsql "CREATE TABLE t2([join $cols ,])"
   656    658     catchsql "CREATE VIEW v1 AS SELECT *, c1 AS o FROM t2;"
          659  +  catchsql "SELECT * FROM v1"
   657    660   } {1 {too many columns in result set}}
          661  +
   658    662   do_test sqllimits1-8.10 {
   659    663     # ORDER BY columns
   660    664     set cols [list]
   661    665     for {set i 0} {$i <= $SQLITE_LIMIT_COLUMN} {incr i} {
   662    666       lappend cols c
   663    667     }
   664    668     set sql "SELECT c FROM t1 ORDER BY [join $cols ,]"

Changes to test/tabfunc01.test.

    50     50   } {30 25 20 15 10 5 0}
    51     51   do_execsql_test tabfunc01-1.9 {
    52     52     SELECT rowid, * FROM generate_series(0,32,5) ORDER BY value DESC;
    53     53   } {1 30 2 25 3 20 4 15 5 10 6 5 7 0}
    54     54   do_execsql_test tabfunc01-1.10 {
    55     55     SELECT rowid, * FROM generate_series(0,32,5) ORDER BY +value DESC;
    56     56   } {7 30 6 25 5 20 4 15 3 10 2 5 1 0}
           57  +
           58  +do_execsql_test tabfunc01-1.20 {
           59  +  CREATE VIEW v1(a,b) AS VALUES(1,2),(3,4);
           60  +  SELECT * FROM v1;
           61  +} {1 2 3 4}
           62  +do_catchsql_test tabfunc01-1.21 {
           63  +  SELECT * FROM v1(55);
           64  +} {1 {'v1' is not a function}}
           65  +do_execsql_test tabfunc01-1.22 {
           66  +  CREATE VIEW v2(x) AS SELECT value FROM generate_series(1,5);
           67  +  SELECT * FROM v2;
           68  +} {1 2 3 4 5}
           69  +do_catchsql_test tabfunc01-1.23 {
           70  +  SELECT * FROM v2(55);
           71  +} {1 {'v2' is not a function}}
    57     72   
    58     73   do_execsql_test tabfunc01-2.1 {
    59     74     CREATE TABLE t1(x);
    60     75     INSERT INTO t1(x) VALUES(2),(3);
    61     76     SELECT *, '|' FROM t1, generate_series(1,x) ORDER BY 1, 2
    62     77   } {2 1 | 2 2 | 3 1 | 3 2 | 3 3 |}
    63     78   

Changes to test/unique2.test.

    70     70       db eval $sql
    71     71       db eval {INSERT INTO t1(w,x,y,z) VALUES(1,2,3,4),(2,3,3,4)}
    72     72     } {}
    73     73     do_test $id.2 {
    74     74       catchsql {CREATE UNIQUE INDEX t1yz ON t1(y,z)}
    75     75     } {1 {UNIQUE constraint failed: t1.y, t1.z}}
    76     76   }
           77  +
           78  +do_catchsql_test 13.1 {
           79  +  CREATE TABLE err1(a,b,c,UNIQUE(rowid));
           80  +} {1 {no such column: rowid}}
           81  +do_catchsql_test 13.2 {
           82  +  CREATE TABLE err1(a,b,c,PRIMARY KEY(rowid));
           83  +} {1 {no such column: rowid}}
           84  +
    77     85   
    78     86   finish_test

Changes to test/wal3.test.

    30     30   
    31     31   #-------------------------------------------------------------------------
    32     32   # When a rollback or savepoint rollback occurs, the client may remove
    33     33   # elements from one of the hash tables in the wal-index. This block
    34     34   # of test cases tests that nothing appears to go wrong when this is
    35     35   # done.
    36     36   #
    37         -set ans 4056
    38         -if {[info exists G(perm:name)] && $G(perm:name)=="memsubsys1"} {
    39         -  set ans 4251
    40         -}
    41     37   do_test wal3-1.0 {
    42     38     execsql {
    43     39       PRAGMA cache_size = 2000;
    44     40       PRAGMA page_size = 1024;
    45     41       PRAGMA auto_vacuum = off;
    46     42       PRAGMA synchronous = normal;
    47     43       PRAGMA journal_mode = WAL;
................................................................................
    60     56         INSERT INTO t1 SELECT a_string(800) FROM t1;             /*  512 */
    61     57         INSERT INTO t1 SELECT a_string(800) FROM t1;             /* 1024 */
    62     58         INSERT INTO t1 SELECT a_string(800) FROM t1;             /* 2048 */
    63     59         INSERT INTO t1 SELECT a_string(800) FROM t1 LIMIT 1970;  /* 4018 */
    64     60       COMMIT;
    65     61       PRAGMA cache_size = 10;
    66     62     }
    67         -  wal_frame_count test.db-wal 1024
    68         -} $ans
           63  +  set x [wal_frame_count test.db-wal 1024]
           64  +  if {$::G(perm:name)=="memsubsys1"} {
           65  +    if {$x==4251 || $x==4290} {set x 4056}
           66  +  }
           67  +  set x
           68  +} 4056
    69     69   
    70     70   for {set i 1} {$i < 50} {incr i} {
    71     71   
    72     72     do_test wal3-1.$i.1 {
    73     73       set str [a_string 800]
    74     74       execsql { UPDATE t1 SET x = $str WHERE rowid = $i }
    75     75       lappend L [wal_frame_count test.db-wal 1024]

Changes to test/without_rowid6.test.

   108    108   do_execsql_test without_rowid6-510 {
   109    109     EXPLAIN QUERY PLAN
   110    110     SELECT a FROM t1 WHERE b>3 ORDER BY b;
   111    111   } {/SEARCH TABLE t1 USING PRIMARY KEY .b>../}
   112    112   do_execsql_test without_rowid6-520 {
   113    113     PRAGMA index_list(t1);
   114    114   } {/sqlite_autoindex_t1_1 1 pk/}
          115  +
          116  +do_catchsql_test without_rowid6-600 {
          117  +  CREATE TABLE t6(a,b,c,PRIMARY KEY(a,rowid,b))WITHOUT ROWID;
          118  +} {1 {no such column: rowid}}
   115    119   
   116    120   
   117    121   finish_test

Changes to tool/fuzzershell.c.

   318    318     printf("Usage: %s [options] ?FILE...?\n", g.zArgv0);
   319    319     printf(
   320    320   "Read SQL text from FILE... (or from standard input if FILE... is omitted)\n"
   321    321   "and then evaluate each block of SQL contained therein.\n"
   322    322   "Options:\n"
   323    323   "  --autovacuum          Enable AUTOVACUUM mode\n"
   324    324   "  --database FILE       Use database FILE instead of an in-memory database\n"
          325  +"  --disable-lookaside   Turn off lookaside memory\n"
   325    326   "  --heap SZ MIN         Memory allocator uses SZ bytes & min allocation MIN\n"
   326    327   "  --help                Show this help text\n"    
   327    328   "  --lookaside N SZ      Configure lookaside for N slots of SZ bytes each\n"
   328    329   "  --oom                 Run each test multiple times in a simulated OOM loop\n"
   329    330   "  --pagesize N          Set the page size to N\n"
   330    331   "  --pcache N SZ         Configure N pages of pagecache each of size SZ bytes\n"
   331    332   "  -q                    Reduced output\n"
................................................................................
   453    454     char **azInFile = 0;          /* Array of input file names */
   454    455     int jj;                       /* Loop counter for azInFile[] */
   455    456     sqlite3_int64 iBegin;         /* Start time for the whole program */
   456    457     sqlite3_int64 iStart, iEnd;   /* Start and end-times for a test case */
   457    458     const char *zDbName = 0;      /* Name of an on-disk database file to open */
   458    459   
   459    460     iBegin = timeOfDay();
          461  +  sqlite3_shutdown();
   460    462     zFailCode = getenv("TEST_FAILURE");
   461    463     g.zArgv0 = argv[0];
   462    464     zPrompt = "<stdin>";
   463    465     for(i=1; i<argc; i++){
   464    466       const char *z = argv[i];
   465    467       if( z[0]=='-' ){
   466    468         z++;
................................................................................
   468    470         if( strcmp(z,"autovacuum")==0 ){
   469    471           doAutovac = 1;
   470    472         }else
   471    473         if( strcmp(z,"database")==0 ){
   472    474           if( i>=argc-1 ) abendError("missing argument on %s\n", argv[i]);
   473    475           zDbName = argv[i+1];
   474    476           i += 1;
          477  +      }else
          478  +      if( strcmp(z,"disable-lookaside")==0 ){
          479  +        nLook = 1;
          480  +        szLook = 0;
   475    481         }else
   476    482         if( strcmp(z, "f")==0 && i+1<argc ){
   477    483           i++;
   478    484           goto addNewInFile;
   479    485         }else
   480    486         if( strcmp(z,"heap")==0 ){
   481    487           if( i>=argc-2 ) abendError("missing arguments on %s\n", argv[i]);
................................................................................
   716    722           if( pLook ){
   717    723             rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE,pLook,szLook,nLook);
   718    724             if( rc!=SQLITE_OK ) abendError("lookaside configuration filed: %d", rc);
   719    725           }
   720    726       #ifndef SQLITE_OMIT_TRACE
   721    727           sqlite3_trace(db, verboseFlag ? traceCallback : traceNoop, 0);
   722    728       #endif
          729  +#ifdef SQLITE_ENABLE_JSON1
          730  +        {
          731  +          extern int sqlite3_json_init(sqlite3*);
          732  +          sqlite3_json_init(db);
          733  +        }
          734  +#endif
   723    735           sqlite3_create_function(db, "eval", 1, SQLITE_UTF8, 0, sqlEvalFunc, 0, 0);
   724    736           sqlite3_create_function(db, "eval", 2, SQLITE_UTF8, 0, sqlEvalFunc, 0, 0);
   725    737           sqlite3_limit(db, SQLITE_LIMIT_LENGTH, 1000000);
   726    738           if( zEncoding ) sqlexec(db, "PRAGMA encoding=%s", zEncoding);
   727    739           if( pageSize ) sqlexec(db, "PRAGMA pagesize=%d", pageSize);
   728    740           if( doAutovac ) sqlexec(db, "PRAGMA auto_vacuum=FULL");
   729    741           iStart = timeOfDay();