Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
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: |
c91065f8edb1e54076791716fc20d3fc |
User & Date: | drh 2015-09-24 14:26:51 |
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 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();