Fossil SCM

Update the built-in SQLite to the latest trunk version that is destined to become 3.45.0 someday. This is beta-testing for SQLite.

drh 2023-12-14 17:24 trunk
Commit 70cae0a964299bb22c02e2da0d2be0ad604870a6cc90bcde4a8b6cc56abd2166
3 files changed +36 -24 +5220 -2573 +42 -7
+36 -24
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -432,12 +432,12 @@
432432
** Returns the number of accepted char values.
433433
*/
434434
#ifdef CONSIO_SPUTB
435435
SQLITE_INTERNAL_LINKAGE int
436436
fPutbUtf8(FILE *pfOut, const char *cBuf, int nAccept);
437
-#endif
438437
/* Like fPutbUtf8 except stream is always the designated output. */
438
+#endif
439439
SQLITE_INTERNAL_LINKAGE int
440440
oPutbUtf8(const char *cBuf, int nAccept);
441441
/* Like fPutbUtf8 except stream is always the designated error. */
442442
#ifdef CONSIO_EPUTB
443443
SQLITE_INTERNAL_LINKAGE int
@@ -1098,32 +1098,31 @@
10981098
return z;
10991099
}
11001100
#endif /*!(defined(SQLITE_CIO_NO_UTF8SCAN)&&defined(SQLITE_CIO_NO_TRANSLATE))*/
11011101
11021102
#ifndef SQLITE_CIO_NO_TRANSLATE
1103
-
1104
-#ifdef CONSIO_SPUTB
1103
+# ifdef CONSIO_SPUTB
11051104
SQLITE_INTERNAL_LINKAGE int
11061105
fPutbUtf8(FILE *pfO, const char *cBuf, int nAccept){
11071106
assert(pfO!=0);
1108
-# if CIO_WIN_WC_XLATE
1107
+# if CIO_WIN_WC_XLATE
11091108
PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */
11101109
PerStreamTags *ppst = getEmitStreamInfo(0, &pst, &pfO);
11111110
if( pstReachesConsole(ppst) ){
11121111
int rv;
11131112
maybeSetupAsConsole(ppst, 1);
11141113
rv = conZstrEmit(ppst, cBuf, nAccept);
11151114
if( 0 == isKnownWritable(ppst->pf) ) restoreConsoleArb(ppst);
11161115
return rv;
11171116
}else {
1118
-# endif
1117
+# endif
11191118
return (int)fwrite(cBuf, 1, nAccept, pfO);
1120
-# if CIO_WIN_WC_XLATE
1119
+# if CIO_WIN_WC_XLATE
11211120
}
1121
+# endif
1122
+}
11221123
# endif
1123
-}
1124
-#endif /* defined(CONSIO_SPUTB) */
11251124
11261125
SQLITE_INTERNAL_LINKAGE int
11271126
oPutbUtf8(const char *cBuf, int nAccept){
11281127
FILE *pfOut;
11291128
PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */
@@ -1230,10 +1229,11 @@
12301229
#undef SHELL_INVALID_FILE_PTR
12311230
12321231
/************************* End ../ext/consio/console_io.c ********************/
12331232
12341233
#ifndef SQLITE_SHELL_FIDDLE
1234
+
12351235
/* From here onward, fgets() is redirected to the console_io library. */
12361236
# define fgets(b,n,f) fGetsUtf8(b,n,f)
12371237
/*
12381238
* Define macros for emitting output text in various ways:
12391239
* sputz(s, z) => emit 0-terminated string z to given stream s
@@ -1254,10 +1254,11 @@
12541254
# define oputz(z) oPutsUtf8(z)
12551255
# define oputf oPrintfUtf8
12561256
# define eputz(z) ePutsUtf8(z)
12571257
# define eputf ePrintfUtf8
12581258
# define oputb(buf,na) oPutbUtf8(buf,na)
1259
+
12591260
#else
12601261
/* For Fiddle, all console handling and emit redirection is omitted. */
12611262
# define sputz(fp,z) fputs(z,fp)
12621263
# define sputf(fp,fmt, ...) fprintf(fp,fmt,__VA_ARGS__)
12631264
# define oputz(z) fputs(z,stdout)
@@ -1337,11 +1338,11 @@
13371338
static void endTimer(void){
13381339
if( enableTimer ){
13391340
sqlite3_int64 iEnd = timeOfDay();
13401341
struct rusage sEnd;
13411342
getrusage(RUSAGE_SELF, &sEnd);
1342
- oputf("Run Time: real %.3f user %f sys %f\n",
1343
+ sputf(stdout, "Run Time: real %.3f user %f sys %f\n",
13431344
(iEnd - iBegin)*0.001,
13441345
timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
13451346
timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
13461347
}
13471348
}
@@ -1416,11 +1417,11 @@
14161417
static void endTimer(void){
14171418
if( enableTimer && getProcessTimesAddr){
14181419
FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
14191420
sqlite3_int64 ftWallEnd = timeOfDay();
14201421
getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
1421
- oputf("Run Time: real %.3f user %f sys %f\n",
1422
+ sputf(stdout, "Run Time: real %.3f user %f sys %f\n",
14221423
(ftWallEnd - ftWallBegin)*0.001,
14231424
timeDiff(&ftUserBegin, &ftUserEnd),
14241425
timeDiff(&ftKernelBegin, &ftKernelEnd));
14251426
}
14261427
}
@@ -1713,18 +1714,18 @@
17131714
** and is an ordinary file or a character stream source.
17141715
** Otherwise return 0.
17151716
*/
17161717
static FILE * openChrSource(const char *zFile){
17171718
#if defined(_WIN32) || defined(WIN32)
1718
- struct _stat x = {0};
1719
+ struct __stat64 x = {0};
17191720
# define STAT_CHR_SRC(mode) ((mode & (_S_IFCHR|_S_IFIFO|_S_IFREG))!=0)
17201721
/* On Windows, open first, then check the stream nature. This order
17211722
** is necessary because _stat() and sibs, when checking a named pipe,
17221723
** effectively break the pipe as its supplier sees it. */
17231724
FILE *rv = fopen(zFile, "rb");
17241725
if( rv==0 ) return 0;
1725
- if( _fstat(_fileno(rv), &x) != 0
1726
+ if( _fstat64(_fileno(rv), &x) != 0
17261727
|| !STAT_CHR_SRC(x.st_mode)){
17271728
fclose(rv);
17281729
rv = 0;
17291730
}
17301731
return rv;
@@ -14825,10 +14826,11 @@
1482514826
/* Load the "byte of payload including overflow" field */
1482614827
if( bNextPage || iOff>pCsr->nPage ){
1482714828
bNextPage = 1;
1482814829
}else{
1482914830
iOff += dbdataGetVarintU32(&pCsr->aPage[iOff], &nPayload);
14831
+ if( nPayload>0x7fffff00 ) nPayload &= 0x3fff;
1483014832
}
1483114833
1483214834
/* If this is a leaf intkey cell, load the rowid */
1483314835
if( bHasRowid && !bNextPage && iOff<pCsr->nPage ){
1483414836
iOff += dbdataGetVarint(&pCsr->aPage[iOff], &pCsr->iIntkey);
@@ -27605,10 +27607,11 @@
2760527607
{"extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,0,"BOOLEAN" },
2760627608
/*{"fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, 1,"" },*/
2760727609
{"fk_no_action", SQLITE_TESTCTRL_FK_NO_ACTION, 0, "BOOLEAN" },
2760827610
{"imposter", SQLITE_TESTCTRL_IMPOSTER,1,"SCHEMA ON/OFF ROOTPAGE"},
2760927611
{"internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS,0,"" },
27612
+ {"json_selfcheck", SQLITE_TESTCTRL_JSON_SELFCHECK ,0,"BOOLEAN" },
2761027613
{"localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,0,"BOOLEAN" },
2761127614
{"never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT,1, "BOOLEAN" },
2761227615
{"optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS,0,"DISABLE-MASK" },
2761327616
#ifdef YYCOVERAGE
2761427617
{"parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE,0,"" },
@@ -27823,10 +27826,20 @@
2782327826
int opt = (unsigned int)integerValue(azArg[2]);
2782427827
rc2 = sqlite3_test_control(testctrl, p->db, opt);
2782527828
isOk = 3;
2782627829
}
2782727830
break;
27831
+ case SQLITE_TESTCTRL_JSON_SELFCHECK:
27832
+ if( nArg==2 ){
27833
+ rc2 = -1;
27834
+ isOk = 1;
27835
+ }else{
27836
+ rc2 = booleanValue(azArg[2]);
27837
+ isOk = 3;
27838
+ }
27839
+ sqlite3_test_control(testctrl, &rc2);
27840
+ break;
2782827841
}
2782927842
}
2783027843
if( isOk==0 && iCtrl>=0 ){
2783127844
oputf("Usage: .testctrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage);
2783227845
rc = 1;
@@ -28709,18 +28722,18 @@
2870928722
GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
2871028723
SetConsoleTextAttribute(out,
2871128724
FOREGROUND_RED|FOREGROUND_INTENSITY
2871228725
);
2871328726
#endif
28714
- oputz(zText);
28727
+ sputz(stdout, zText);
2871528728
#if !SQLITE_OS_WINRT
2871628729
SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
2871728730
#endif
2871828731
}
2871928732
#else
2872028733
static void printBold(const char *zText){
28721
- oputf("\033[1m%s\033[0m", zText);
28734
+ sputf(stdout, "\033[1m%s\033[0m", zText);
2872228735
}
2872328736
#endif
2872428737
2872528738
/*
2872628739
** Get the argument to an --option. Throw an error and die if no argument
@@ -28910,14 +28923,10 @@
2891028923
){
2891128924
(void)cmdline_option_value(argc, argv, ++i);
2891228925
}else if( cli_strcmp(z,"-init")==0 ){
2891328926
zInitFile = cmdline_option_value(argc, argv, ++i);
2891428927
}else if( cli_strcmp(z,"-interactive")==0 ){
28915
- /* Need to check for interactive override here to so that it can
28916
- ** affect console setup (for Windows only) and testing thereof.
28917
- */
28918
- stdin_is_interactive = 1;
2891928928
}else if( cli_strcmp(z,"-batch")==0 ){
2892028929
/* Need to check for batch mode here to so we can avoid printing
2892128930
** informational messages (like from process_sqliterc) before
2892228931
** we do the actual processing of arguments later in a second pass.
2892328932
*/
@@ -29183,15 +29192,18 @@
2918329192
*/
2918429193
ShellSetFlag(&data, SHFLG_Backslash);
2918529194
}else if( cli_strcmp(z,"-bail")==0 ){
2918629195
/* No-op. The bail_on_error flag should already be set. */
2918729196
}else if( cli_strcmp(z,"-version")==0 ){
29188
- oputf("%s %s (%d-bit)\n", sqlite3_libversion(), sqlite3_sourceid(),
29189
- 8*(int)sizeof(char*));
29197
+ sputf(stdout, "%s %s (%d-bit)\n",
29198
+ sqlite3_libversion(), sqlite3_sourceid(), 8*(int)sizeof(char*));
2919029199
return 0;
2919129200
}else if( cli_strcmp(z,"-interactive")==0 ){
29192
- /* already handled */
29201
+ /* Need to check for interactive override here to so that it can
29202
+ ** affect console setup (for Windows only) and testing thereof.
29203
+ */
29204
+ stdin_is_interactive = 1;
2919329205
}else if( cli_strcmp(z,"-batch")==0 ){
2919429206
/* already handled */
2919529207
}else if( cli_strcmp(z,"-utf8")==0 ){
2919629208
/* already handled */
2919729209
}else if( cli_strcmp(z,"-no-utf8")==0 ){
@@ -29316,17 +29328,17 @@
2931629328
#if CIO_WIN_WC_XLATE
2931729329
# define SHELL_CIO_CHAR_SET (stdout_is_console? " (UTF-16 console I/O)" : "")
2931829330
#else
2931929331
# define SHELL_CIO_CHAR_SET ""
2932029332
#endif
29321
- oputf("SQLite version %s %.19s%s\n" /*extra-version-info*/
29333
+ sputf(stdout, "SQLite version %s %.19s%s\n" /*extra-version-info*/
2932229334
"Enter \".help\" for usage hints.\n",
2932329335
sqlite3_libversion(), sqlite3_sourceid(), SHELL_CIO_CHAR_SET);
2932429336
if( warnInmemoryDb ){
29325
- oputz("Connected to a ");
29337
+ sputz(stdout, "Connected to a ");
2932629338
printBold("transient in-memory database");
29327
- oputz(".\nUse \".open FILENAME\" to reopen on a"
29339
+ sputz(stdout, ".\nUse \".open FILENAME\" to reopen on a"
2932829340
" persistent database.\n");
2932929341
}
2933029342
zHistory = getenv("SQLITE_HISTORY");
2933129343
if( zHistory ){
2933229344
zHistory = strdup(zHistory);
2933329345
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -432,12 +432,12 @@
432 ** Returns the number of accepted char values.
433 */
434 #ifdef CONSIO_SPUTB
435 SQLITE_INTERNAL_LINKAGE int
436 fPutbUtf8(FILE *pfOut, const char *cBuf, int nAccept);
437 #endif
438 /* Like fPutbUtf8 except stream is always the designated output. */
 
439 SQLITE_INTERNAL_LINKAGE int
440 oPutbUtf8(const char *cBuf, int nAccept);
441 /* Like fPutbUtf8 except stream is always the designated error. */
442 #ifdef CONSIO_EPUTB
443 SQLITE_INTERNAL_LINKAGE int
@@ -1098,32 +1098,31 @@
1098 return z;
1099 }
1100 #endif /*!(defined(SQLITE_CIO_NO_UTF8SCAN)&&defined(SQLITE_CIO_NO_TRANSLATE))*/
1101
1102 #ifndef SQLITE_CIO_NO_TRANSLATE
1103
1104 #ifdef CONSIO_SPUTB
1105 SQLITE_INTERNAL_LINKAGE int
1106 fPutbUtf8(FILE *pfO, const char *cBuf, int nAccept){
1107 assert(pfO!=0);
1108 # if CIO_WIN_WC_XLATE
1109 PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */
1110 PerStreamTags *ppst = getEmitStreamInfo(0, &pst, &pfO);
1111 if( pstReachesConsole(ppst) ){
1112 int rv;
1113 maybeSetupAsConsole(ppst, 1);
1114 rv = conZstrEmit(ppst, cBuf, nAccept);
1115 if( 0 == isKnownWritable(ppst->pf) ) restoreConsoleArb(ppst);
1116 return rv;
1117 }else {
1118 # endif
1119 return (int)fwrite(cBuf, 1, nAccept, pfO);
1120 # if CIO_WIN_WC_XLATE
1121 }
 
 
1122 # endif
1123 }
1124 #endif /* defined(CONSIO_SPUTB) */
1125
1126 SQLITE_INTERNAL_LINKAGE int
1127 oPutbUtf8(const char *cBuf, int nAccept){
1128 FILE *pfOut;
1129 PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */
@@ -1230,10 +1229,11 @@
1230 #undef SHELL_INVALID_FILE_PTR
1231
1232 /************************* End ../ext/consio/console_io.c ********************/
1233
1234 #ifndef SQLITE_SHELL_FIDDLE
 
1235 /* From here onward, fgets() is redirected to the console_io library. */
1236 # define fgets(b,n,f) fGetsUtf8(b,n,f)
1237 /*
1238 * Define macros for emitting output text in various ways:
1239 * sputz(s, z) => emit 0-terminated string z to given stream s
@@ -1254,10 +1254,11 @@
1254 # define oputz(z) oPutsUtf8(z)
1255 # define oputf oPrintfUtf8
1256 # define eputz(z) ePutsUtf8(z)
1257 # define eputf ePrintfUtf8
1258 # define oputb(buf,na) oPutbUtf8(buf,na)
 
1259 #else
1260 /* For Fiddle, all console handling and emit redirection is omitted. */
1261 # define sputz(fp,z) fputs(z,fp)
1262 # define sputf(fp,fmt, ...) fprintf(fp,fmt,__VA_ARGS__)
1263 # define oputz(z) fputs(z,stdout)
@@ -1337,11 +1338,11 @@
1337 static void endTimer(void){
1338 if( enableTimer ){
1339 sqlite3_int64 iEnd = timeOfDay();
1340 struct rusage sEnd;
1341 getrusage(RUSAGE_SELF, &sEnd);
1342 oputf("Run Time: real %.3f user %f sys %f\n",
1343 (iEnd - iBegin)*0.001,
1344 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
1345 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
1346 }
1347 }
@@ -1416,11 +1417,11 @@
1416 static void endTimer(void){
1417 if( enableTimer && getProcessTimesAddr){
1418 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
1419 sqlite3_int64 ftWallEnd = timeOfDay();
1420 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
1421 oputf("Run Time: real %.3f user %f sys %f\n",
1422 (ftWallEnd - ftWallBegin)*0.001,
1423 timeDiff(&ftUserBegin, &ftUserEnd),
1424 timeDiff(&ftKernelBegin, &ftKernelEnd));
1425 }
1426 }
@@ -1713,18 +1714,18 @@
1713 ** and is an ordinary file or a character stream source.
1714 ** Otherwise return 0.
1715 */
1716 static FILE * openChrSource(const char *zFile){
1717 #if defined(_WIN32) || defined(WIN32)
1718 struct _stat x = {0};
1719 # define STAT_CHR_SRC(mode) ((mode & (_S_IFCHR|_S_IFIFO|_S_IFREG))!=0)
1720 /* On Windows, open first, then check the stream nature. This order
1721 ** is necessary because _stat() and sibs, when checking a named pipe,
1722 ** effectively break the pipe as its supplier sees it. */
1723 FILE *rv = fopen(zFile, "rb");
1724 if( rv==0 ) return 0;
1725 if( _fstat(_fileno(rv), &x) != 0
1726 || !STAT_CHR_SRC(x.st_mode)){
1727 fclose(rv);
1728 rv = 0;
1729 }
1730 return rv;
@@ -14825,10 +14826,11 @@
14825 /* Load the "byte of payload including overflow" field */
14826 if( bNextPage || iOff>pCsr->nPage ){
14827 bNextPage = 1;
14828 }else{
14829 iOff += dbdataGetVarintU32(&pCsr->aPage[iOff], &nPayload);
 
14830 }
14831
14832 /* If this is a leaf intkey cell, load the rowid */
14833 if( bHasRowid && !bNextPage && iOff<pCsr->nPage ){
14834 iOff += dbdataGetVarint(&pCsr->aPage[iOff], &pCsr->iIntkey);
@@ -27605,10 +27607,11 @@
27605 {"extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,0,"BOOLEAN" },
27606 /*{"fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, 1,"" },*/
27607 {"fk_no_action", SQLITE_TESTCTRL_FK_NO_ACTION, 0, "BOOLEAN" },
27608 {"imposter", SQLITE_TESTCTRL_IMPOSTER,1,"SCHEMA ON/OFF ROOTPAGE"},
27609 {"internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS,0,"" },
 
27610 {"localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,0,"BOOLEAN" },
27611 {"never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT,1, "BOOLEAN" },
27612 {"optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS,0,"DISABLE-MASK" },
27613 #ifdef YYCOVERAGE
27614 {"parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE,0,"" },
@@ -27823,10 +27826,20 @@
27823 int opt = (unsigned int)integerValue(azArg[2]);
27824 rc2 = sqlite3_test_control(testctrl, p->db, opt);
27825 isOk = 3;
27826 }
27827 break;
 
 
 
 
 
 
 
 
 
 
27828 }
27829 }
27830 if( isOk==0 && iCtrl>=0 ){
27831 oputf("Usage: .testctrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage);
27832 rc = 1;
@@ -28709,18 +28722,18 @@
28709 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
28710 SetConsoleTextAttribute(out,
28711 FOREGROUND_RED|FOREGROUND_INTENSITY
28712 );
28713 #endif
28714 oputz(zText);
28715 #if !SQLITE_OS_WINRT
28716 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
28717 #endif
28718 }
28719 #else
28720 static void printBold(const char *zText){
28721 oputf("\033[1m%s\033[0m", zText);
28722 }
28723 #endif
28724
28725 /*
28726 ** Get the argument to an --option. Throw an error and die if no argument
@@ -28910,14 +28923,10 @@
28910 ){
28911 (void)cmdline_option_value(argc, argv, ++i);
28912 }else if( cli_strcmp(z,"-init")==0 ){
28913 zInitFile = cmdline_option_value(argc, argv, ++i);
28914 }else if( cli_strcmp(z,"-interactive")==0 ){
28915 /* Need to check for interactive override here to so that it can
28916 ** affect console setup (for Windows only) and testing thereof.
28917 */
28918 stdin_is_interactive = 1;
28919 }else if( cli_strcmp(z,"-batch")==0 ){
28920 /* Need to check for batch mode here to so we can avoid printing
28921 ** informational messages (like from process_sqliterc) before
28922 ** we do the actual processing of arguments later in a second pass.
28923 */
@@ -29183,15 +29192,18 @@
29183 */
29184 ShellSetFlag(&data, SHFLG_Backslash);
29185 }else if( cli_strcmp(z,"-bail")==0 ){
29186 /* No-op. The bail_on_error flag should already be set. */
29187 }else if( cli_strcmp(z,"-version")==0 ){
29188 oputf("%s %s (%d-bit)\n", sqlite3_libversion(), sqlite3_sourceid(),
29189 8*(int)sizeof(char*));
29190 return 0;
29191 }else if( cli_strcmp(z,"-interactive")==0 ){
29192 /* already handled */
 
 
 
29193 }else if( cli_strcmp(z,"-batch")==0 ){
29194 /* already handled */
29195 }else if( cli_strcmp(z,"-utf8")==0 ){
29196 /* already handled */
29197 }else if( cli_strcmp(z,"-no-utf8")==0 ){
@@ -29316,17 +29328,17 @@
29316 #if CIO_WIN_WC_XLATE
29317 # define SHELL_CIO_CHAR_SET (stdout_is_console? " (UTF-16 console I/O)" : "")
29318 #else
29319 # define SHELL_CIO_CHAR_SET ""
29320 #endif
29321 oputf("SQLite version %s %.19s%s\n" /*extra-version-info*/
29322 "Enter \".help\" for usage hints.\n",
29323 sqlite3_libversion(), sqlite3_sourceid(), SHELL_CIO_CHAR_SET);
29324 if( warnInmemoryDb ){
29325 oputz("Connected to a ");
29326 printBold("transient in-memory database");
29327 oputz(".\nUse \".open FILENAME\" to reopen on a"
29328 " persistent database.\n");
29329 }
29330 zHistory = getenv("SQLITE_HISTORY");
29331 if( zHistory ){
29332 zHistory = strdup(zHistory);
29333
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -432,12 +432,12 @@
432 ** Returns the number of accepted char values.
433 */
434 #ifdef CONSIO_SPUTB
435 SQLITE_INTERNAL_LINKAGE int
436 fPutbUtf8(FILE *pfOut, const char *cBuf, int nAccept);
 
437 /* Like fPutbUtf8 except stream is always the designated output. */
438 #endif
439 SQLITE_INTERNAL_LINKAGE int
440 oPutbUtf8(const char *cBuf, int nAccept);
441 /* Like fPutbUtf8 except stream is always the designated error. */
442 #ifdef CONSIO_EPUTB
443 SQLITE_INTERNAL_LINKAGE int
@@ -1098,32 +1098,31 @@
1098 return z;
1099 }
1100 #endif /*!(defined(SQLITE_CIO_NO_UTF8SCAN)&&defined(SQLITE_CIO_NO_TRANSLATE))*/
1101
1102 #ifndef SQLITE_CIO_NO_TRANSLATE
1103 # ifdef CONSIO_SPUTB
 
1104 SQLITE_INTERNAL_LINKAGE int
1105 fPutbUtf8(FILE *pfO, const char *cBuf, int nAccept){
1106 assert(pfO!=0);
1107 # if CIO_WIN_WC_XLATE
1108 PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */
1109 PerStreamTags *ppst = getEmitStreamInfo(0, &pst, &pfO);
1110 if( pstReachesConsole(ppst) ){
1111 int rv;
1112 maybeSetupAsConsole(ppst, 1);
1113 rv = conZstrEmit(ppst, cBuf, nAccept);
1114 if( 0 == isKnownWritable(ppst->pf) ) restoreConsoleArb(ppst);
1115 return rv;
1116 }else {
1117 # endif
1118 return (int)fwrite(cBuf, 1, nAccept, pfO);
1119 # if CIO_WIN_WC_XLATE
1120 }
1121 # endif
1122 }
1123 # endif
 
 
1124
1125 SQLITE_INTERNAL_LINKAGE int
1126 oPutbUtf8(const char *cBuf, int nAccept){
1127 FILE *pfOut;
1128 PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */
@@ -1230,10 +1229,11 @@
1229 #undef SHELL_INVALID_FILE_PTR
1230
1231 /************************* End ../ext/consio/console_io.c ********************/
1232
1233 #ifndef SQLITE_SHELL_FIDDLE
1234
1235 /* From here onward, fgets() is redirected to the console_io library. */
1236 # define fgets(b,n,f) fGetsUtf8(b,n,f)
1237 /*
1238 * Define macros for emitting output text in various ways:
1239 * sputz(s, z) => emit 0-terminated string z to given stream s
@@ -1254,10 +1254,11 @@
1254 # define oputz(z) oPutsUtf8(z)
1255 # define oputf oPrintfUtf8
1256 # define eputz(z) ePutsUtf8(z)
1257 # define eputf ePrintfUtf8
1258 # define oputb(buf,na) oPutbUtf8(buf,na)
1259
1260 #else
1261 /* For Fiddle, all console handling and emit redirection is omitted. */
1262 # define sputz(fp,z) fputs(z,fp)
1263 # define sputf(fp,fmt, ...) fprintf(fp,fmt,__VA_ARGS__)
1264 # define oputz(z) fputs(z,stdout)
@@ -1337,11 +1338,11 @@
1338 static void endTimer(void){
1339 if( enableTimer ){
1340 sqlite3_int64 iEnd = timeOfDay();
1341 struct rusage sEnd;
1342 getrusage(RUSAGE_SELF, &sEnd);
1343 sputf(stdout, "Run Time: real %.3f user %f sys %f\n",
1344 (iEnd - iBegin)*0.001,
1345 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
1346 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
1347 }
1348 }
@@ -1416,11 +1417,11 @@
1417 static void endTimer(void){
1418 if( enableTimer && getProcessTimesAddr){
1419 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
1420 sqlite3_int64 ftWallEnd = timeOfDay();
1421 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
1422 sputf(stdout, "Run Time: real %.3f user %f sys %f\n",
1423 (ftWallEnd - ftWallBegin)*0.001,
1424 timeDiff(&ftUserBegin, &ftUserEnd),
1425 timeDiff(&ftKernelBegin, &ftKernelEnd));
1426 }
1427 }
@@ -1713,18 +1714,18 @@
1714 ** and is an ordinary file or a character stream source.
1715 ** Otherwise return 0.
1716 */
1717 static FILE * openChrSource(const char *zFile){
1718 #if defined(_WIN32) || defined(WIN32)
1719 struct __stat64 x = {0};
1720 # define STAT_CHR_SRC(mode) ((mode & (_S_IFCHR|_S_IFIFO|_S_IFREG))!=0)
1721 /* On Windows, open first, then check the stream nature. This order
1722 ** is necessary because _stat() and sibs, when checking a named pipe,
1723 ** effectively break the pipe as its supplier sees it. */
1724 FILE *rv = fopen(zFile, "rb");
1725 if( rv==0 ) return 0;
1726 if( _fstat64(_fileno(rv), &x) != 0
1727 || !STAT_CHR_SRC(x.st_mode)){
1728 fclose(rv);
1729 rv = 0;
1730 }
1731 return rv;
@@ -14825,10 +14826,11 @@
14826 /* Load the "byte of payload including overflow" field */
14827 if( bNextPage || iOff>pCsr->nPage ){
14828 bNextPage = 1;
14829 }else{
14830 iOff += dbdataGetVarintU32(&pCsr->aPage[iOff], &nPayload);
14831 if( nPayload>0x7fffff00 ) nPayload &= 0x3fff;
14832 }
14833
14834 /* If this is a leaf intkey cell, load the rowid */
14835 if( bHasRowid && !bNextPage && iOff<pCsr->nPage ){
14836 iOff += dbdataGetVarint(&pCsr->aPage[iOff], &pCsr->iIntkey);
@@ -27605,10 +27607,11 @@
27607 {"extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,0,"BOOLEAN" },
27608 /*{"fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, 1,"" },*/
27609 {"fk_no_action", SQLITE_TESTCTRL_FK_NO_ACTION, 0, "BOOLEAN" },
27610 {"imposter", SQLITE_TESTCTRL_IMPOSTER,1,"SCHEMA ON/OFF ROOTPAGE"},
27611 {"internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS,0,"" },
27612 {"json_selfcheck", SQLITE_TESTCTRL_JSON_SELFCHECK ,0,"BOOLEAN" },
27613 {"localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,0,"BOOLEAN" },
27614 {"never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT,1, "BOOLEAN" },
27615 {"optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS,0,"DISABLE-MASK" },
27616 #ifdef YYCOVERAGE
27617 {"parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE,0,"" },
@@ -27823,10 +27826,20 @@
27826 int opt = (unsigned int)integerValue(azArg[2]);
27827 rc2 = sqlite3_test_control(testctrl, p->db, opt);
27828 isOk = 3;
27829 }
27830 break;
27831 case SQLITE_TESTCTRL_JSON_SELFCHECK:
27832 if( nArg==2 ){
27833 rc2 = -1;
27834 isOk = 1;
27835 }else{
27836 rc2 = booleanValue(azArg[2]);
27837 isOk = 3;
27838 }
27839 sqlite3_test_control(testctrl, &rc2);
27840 break;
27841 }
27842 }
27843 if( isOk==0 && iCtrl>=0 ){
27844 oputf("Usage: .testctrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage);
27845 rc = 1;
@@ -28709,18 +28722,18 @@
28722 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
28723 SetConsoleTextAttribute(out,
28724 FOREGROUND_RED|FOREGROUND_INTENSITY
28725 );
28726 #endif
28727 sputz(stdout, zText);
28728 #if !SQLITE_OS_WINRT
28729 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
28730 #endif
28731 }
28732 #else
28733 static void printBold(const char *zText){
28734 sputf(stdout, "\033[1m%s\033[0m", zText);
28735 }
28736 #endif
28737
28738 /*
28739 ** Get the argument to an --option. Throw an error and die if no argument
@@ -28910,14 +28923,10 @@
28923 ){
28924 (void)cmdline_option_value(argc, argv, ++i);
28925 }else if( cli_strcmp(z,"-init")==0 ){
28926 zInitFile = cmdline_option_value(argc, argv, ++i);
28927 }else if( cli_strcmp(z,"-interactive")==0 ){
 
 
 
 
28928 }else if( cli_strcmp(z,"-batch")==0 ){
28929 /* Need to check for batch mode here to so we can avoid printing
28930 ** informational messages (like from process_sqliterc) before
28931 ** we do the actual processing of arguments later in a second pass.
28932 */
@@ -29183,15 +29192,18 @@
29192 */
29193 ShellSetFlag(&data, SHFLG_Backslash);
29194 }else if( cli_strcmp(z,"-bail")==0 ){
29195 /* No-op. The bail_on_error flag should already be set. */
29196 }else if( cli_strcmp(z,"-version")==0 ){
29197 sputf(stdout, "%s %s (%d-bit)\n",
29198 sqlite3_libversion(), sqlite3_sourceid(), 8*(int)sizeof(char*));
29199 return 0;
29200 }else if( cli_strcmp(z,"-interactive")==0 ){
29201 /* Need to check for interactive override here to so that it can
29202 ** affect console setup (for Windows only) and testing thereof.
29203 */
29204 stdin_is_interactive = 1;
29205 }else if( cli_strcmp(z,"-batch")==0 ){
29206 /* already handled */
29207 }else if( cli_strcmp(z,"-utf8")==0 ){
29208 /* already handled */
29209 }else if( cli_strcmp(z,"-no-utf8")==0 ){
@@ -29316,17 +29328,17 @@
29328 #if CIO_WIN_WC_XLATE
29329 # define SHELL_CIO_CHAR_SET (stdout_is_console? " (UTF-16 console I/O)" : "")
29330 #else
29331 # define SHELL_CIO_CHAR_SET ""
29332 #endif
29333 sputf(stdout, "SQLite version %s %.19s%s\n" /*extra-version-info*/
29334 "Enter \".help\" for usage hints.\n",
29335 sqlite3_libversion(), sqlite3_sourceid(), SHELL_CIO_CHAR_SET);
29336 if( warnInmemoryDb ){
29337 sputz(stdout, "Connected to a ");
29338 printBold("transient in-memory database");
29339 sputz(stdout, ".\nUse \".open FILENAME\" to reopen on a"
29340 " persistent database.\n");
29341 }
29342 zHistory = getenv("SQLITE_HISTORY");
29343 if( zHistory ){
29344 zHistory = strdup(zHistory);
29345
+5220 -2573
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -1,8 +1,8 @@
11
/******************************************************************************
22
** This file is an amalgamation of many separate C source files from SQLite
3
-** version 3.44.2. By combining all the individual C code files into this
3
+** version 3.45.0. By combining all the individual C code files into this
44
** single large file, the entire code can be compiled as a single translation
55
** unit. This allows many compilers to do optimizations that would not be
66
** possible if the files were compiled separately. Performance improvements
77
** of 5% or more are commonly seen when SQLite is compiled as a single
88
** translation unit.
@@ -16,11 +16,11 @@
1616
** if you want a wrapper to interface SQLite with your choice of programming
1717
** language. The code for the "sqlite3" command-line shell is also in a
1818
** separate file. This file contains only code for the core SQLite library.
1919
**
2020
** The content in this amalgamation comes from Fossil check-in
21
-** ebead0e7230cd33bcec9f95d2183069565b9.
21
+** 27d4a89a5ff96b7b7fc5dc9650e1269f7c7e.
2222
*/
2323
#define SQLITE_CORE 1
2424
#define SQLITE_AMALGAMATION 1
2525
#ifndef SQLITE_PRIVATE
2626
# define SQLITE_PRIVATE static
@@ -457,13 +457,13 @@
457457
**
458458
** See also: [sqlite3_libversion()],
459459
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
460460
** [sqlite_version()] and [sqlite_source_id()].
461461
*/
462
-#define SQLITE_VERSION "3.44.2"
463
-#define SQLITE_VERSION_NUMBER 3044002
464
-#define SQLITE_SOURCE_ID "2023-11-24 11:41:44 ebead0e7230cd33bcec9f95d2183069565b9e709bf745c9b5db65cc0cbf92c0f"
462
+#define SQLITE_VERSION "3.45.0"
463
+#define SQLITE_VERSION_NUMBER 3045000
464
+#define SQLITE_SOURCE_ID "2023-12-14 16:34:47 27d4a89a5ff96b7b7fc5dc9650e1269f7c7edf91de9b9aafce40be9ecc8b95e9"
465465
466466
/*
467467
** CAPI3REF: Run-Time Library Version Numbers
468468
** KEYWORDS: sqlite3_version sqlite3_sourceid
469469
**
@@ -4265,19 +4265,21 @@
42654265
** <li> sqlite3_errmsg16()
42664266
** <li> sqlite3_error_offset()
42674267
** </ul>
42684268
**
42694269
** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
4270
-** text that describes the error, as either UTF-8 or UTF-16 respectively.
4270
+** text that describes the error, as either UTF-8 or UTF-16 respectively,
4271
+** or NULL if no error message is available.
42714272
** (See how SQLite handles [invalid UTF] for exceptions to this rule.)
42724273
** ^(Memory to hold the error message string is managed internally.
42734274
** The application does not need to worry about freeing the result.
42744275
** However, the error string might be overwritten or deallocated by
42754276
** subsequent calls to other SQLite interface functions.)^
42764277
**
4277
-** ^The sqlite3_errstr() interface returns the English-language text
4278
-** that describes the [result code], as UTF-8.
4278
+** ^The sqlite3_errstr(E) interface returns the English-language text
4279
+** that describes the [result code] E, as UTF-8, or NULL if E is not an
4280
+** result code for which a text error message is available.
42794281
** ^(Memory to hold the error message string is managed internally
42804282
** and must not be freed by the application)^.
42814283
**
42824284
** ^If the most recent error references a specific token in the input
42834285
** SQL, the sqlite3_error_offset() interface returns the byte offset
@@ -8609,10 +8611,11 @@
86098611
#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10
86108612
#define SQLITE_TESTCTRL_PENDING_BYTE 11
86118613
#define SQLITE_TESTCTRL_ASSERT 12
86128614
#define SQLITE_TESTCTRL_ALWAYS 13
86138615
#define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */
8616
+#define SQLITE_TESTCTRL_JSON_SELFCHECK 14
86148617
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
86158618
#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
86168619
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
86178620
#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17
86188621
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
@@ -13295,13 +13298,38 @@
1329513298
** significantly more efficient than those alternatives when used with
1329613299
** "detail=column" tables.
1329713300
**
1329813301
** xPhraseNextColumn()
1329913302
** See xPhraseFirstColumn above.
13303
+**
13304
+** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken)
13305
+** This is used to access token iToken of phrase iPhrase of the current
13306
+** query. Before returning, output parameter *ppToken is set to point
13307
+** to a buffer containing the requested token, and *pnToken to the
13308
+** size of this buffer in bytes.
13309
+**
13310
+** The output text is not a copy of the query text that specified the
13311
+** token. It is the output of the tokenizer module. For tokendata=1
13312
+** tables, this includes any embedded 0x00 and trailing data.
13313
+**
13314
+** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken)
13315
+** This is used to access token iToken of phrase hit iIdx within the
13316
+** current row. Output variable (*ppToken) is set to point to a buffer
13317
+** containing the matching document token, and (*pnToken) to the size
13318
+** of that buffer in bytes. This API is not available if the specified
13319
+** token matches a prefix query term. In that case both output variables
13320
+** are always set to 0.
13321
+**
13322
+** The output text is not a copy of the document text that was tokenized.
13323
+** It is the output of the tokenizer module. For tokendata=1 tables, this
13324
+** includes any embedded 0x00 and trailing data.
13325
+**
13326
+** This API can be quite slow if used with an FTS5 table created with the
13327
+** "detail=none" or "detail=column" option.
1330013328
*/
1330113329
struct Fts5ExtensionApi {
13302
- int iVersion; /* Currently always set to 2 */
13330
+ int iVersion; /* Currently always set to 3 */
1330313331
1330413332
void *(*xUserData)(Fts5Context*);
1330513333
1330613334
int (*xColumnCount)(Fts5Context*);
1330713335
int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
@@ -13332,10 +13360,17 @@
1333213360
int (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*);
1333313361
void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff);
1333413362
1333513363
int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*);
1333613364
void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol);
13365
+
13366
+ /* Below this point are iVersion>=3 only */
13367
+ int (*xQueryToken)(Fts5Context*,
13368
+ int iPhrase, int iToken,
13369
+ const char **ppToken, int *pnToken
13370
+ );
13371
+ int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*);
1333713372
};
1333813373
1333913374
/*
1334013375
** CUSTOM AUXILIARY FUNCTIONS
1334113376
*************************************************************************/
@@ -16426,10 +16461,11 @@
1642616461
#define P4_VTAB (-11) /* P4 is a pointer to an sqlite3_vtab structure */
1642716462
#define P4_REAL (-12) /* P4 is a 64-bit floating point value */
1642816463
#define P4_INT64 (-13) /* P4 is a 64-bit signed integer */
1642916464
#define P4_INTARRAY (-14) /* P4 is a vector of 32-bit integers */
1643016465
#define P4_FUNCCTX (-15) /* P4 is a pointer to an sqlite3_context object */
16466
+#define P4_TABLEREF (-16) /* Like P4_TABLE, but reference counted */
1643116467
1643216468
/* Error message codes for OP_Halt */
1643316469
#define P5_ConstraintNotNull 1
1643416470
#define P5_ConstraintUnique 2
1643516471
#define P5_ConstraintCheck 3
@@ -16648,17 +16684,19 @@
1664816684
#define OP_VColumn 176 /* synopsis: r[P3]=vcolumn(P2) */
1664916685
#define OP_VRename 177
1665016686
#define OP_Pagecount 178
1665116687
#define OP_MaxPgcnt 179
1665216688
#define OP_ClrSubtype 180 /* synopsis: r[P1].subtype = 0 */
16653
-#define OP_FilterAdd 181 /* synopsis: filter(P1) += key(P3@P4) */
16654
-#define OP_Trace 182
16655
-#define OP_CursorHint 183
16656
-#define OP_ReleaseReg 184 /* synopsis: release r[P1@P2] mask P3 */
16657
-#define OP_Noop 185
16658
-#define OP_Explain 186
16659
-#define OP_Abortable 187
16689
+#define OP_GetSubtype 181 /* synopsis: r[P2] = r[P1].subtype */
16690
+#define OP_SetSubtype 182 /* synopsis: r[P2].subtype = r[P1] */
16691
+#define OP_FilterAdd 183 /* synopsis: filter(P1) += key(P3@P4) */
16692
+#define OP_Trace 184
16693
+#define OP_CursorHint 185
16694
+#define OP_ReleaseReg 186 /* synopsis: release r[P1@P2] mask P3 */
16695
+#define OP_Noop 187
16696
+#define OP_Explain 188
16697
+#define OP_Abortable 189
1666016698
1666116699
/* Properties such as "out2" or "jump" that are specified in
1666216700
** comments following the "case" for each opcode in the vdbe.c
1666316701
** are encoded into bitvectors as follows:
1666416702
*/
@@ -16690,12 +16728,12 @@
1669016728
/* 136 */ 0x00, 0x40, 0x04, 0x04, 0x00, 0x40, 0x50, 0x40,\
1669116729
/* 144 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\
1669216730
/* 152 */ 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\
1669316731
/* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
1669416732
/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x50,\
16695
-/* 176 */ 0x40, 0x00, 0x10, 0x10, 0x02, 0x00, 0x00, 0x00,\
16696
-/* 184 */ 0x00, 0x00, 0x00, 0x00,}
16733
+/* 176 */ 0x40, 0x00, 0x10, 0x10, 0x02, 0x12, 0x12, 0x00,\
16734
+/* 184 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}
1669716735
1669816736
/* The resolve3P2Values() routine is able to run faster if it knows
1669916737
** the value of the largest JUMP opcode. The smaller the maximum
1670016738
** JUMP opcode the better, so the mkopcodeh.tcl script that
1670116739
** generated this include file strives to group all JUMP opcodes
@@ -17952,15 +17990,15 @@
1795217990
{nArg, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_DIRECTONLY|SQLITE_FUNC_UNSAFE, \
1795317991
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
1795417992
#define MFUNCTION(zName, nArg, xPtr, xFunc) \
1795517993
{nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \
1795617994
xPtr, 0, xFunc, 0, 0, 0, #zName, {0} }
17957
-#define JFUNCTION(zName, nArg, bUseCache, bWS, bRS, iArg, xFunc) \
17995
+#define JFUNCTION(zName, nArg, bUseCache, bWS, bRS, bJsonB, iArg, xFunc) \
1795817996
{nArg, SQLITE_FUNC_BUILTIN|SQLITE_DETERMINISTIC|SQLITE_FUNC_CONSTANT|\
1795917997
SQLITE_UTF8|((bUseCache)*SQLITE_FUNC_RUNONLY)|\
1796017998
((bRS)*SQLITE_SUBTYPE)|((bWS)*SQLITE_RESULT_SUBTYPE), \
17961
- SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
17999
+ SQLITE_INT_TO_PTR(iArg|((bJsonB)*JSON_BLOB)),0,xFunc,0, 0, 0, #zName, {0} }
1796218000
#define INLINE_FUNC(zName, nArg, iArg, mFlags) \
1796318001
{nArg, SQLITE_FUNC_BUILTIN|\
1796418002
SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \
1796518003
SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} }
1796618004
#define TEST_FUNC(zName, nArg, iArg, mFlags) \
@@ -18704,10 +18742,11 @@
1870418742
int iDistinct; /* Ephemeral table used to enforce DISTINCT */
1870518743
int iDistAddr; /* Address of OP_OpenEphemeral */
1870618744
int iOBTab; /* Ephemeral table to implement ORDER BY */
1870718745
u8 bOBPayload; /* iOBTab has payload columns separate from key */
1870818746
u8 bOBUnique; /* Enforce uniqueness on iOBTab keys */
18747
+ u8 bUseSubtype; /* Transfer subtype info through sorter */
1870918748
} *aFunc;
1871018749
int nFunc; /* Number of entries in aFunc[] */
1871118750
u32 selId; /* Select to which this AggInfo belongs */
1871218751
#ifdef SQLITE_DEBUG
1871318752
Select *pSelect; /* SELECT statement that this AggInfo supports */
@@ -19237,10 +19276,11 @@
1923719276
} uNC;
1923819277
NameContext *pNext; /* Next outer name context. NULL for outermost */
1923919278
int nRef; /* Number of names resolved by this context */
1924019279
int nNcErr; /* Number of errors encountered while resolving names */
1924119280
int ncFlags; /* Zero or more NC_* flags defined below */
19281
+ u32 nNestedSelect; /* Number of nested selects using this NC */
1924219282
Select *pWinSelect; /* SELECT statement for any window functions */
1924319283
};
1924419284
1924519285
/*
1924619286
** Allowed values for the NameContext, ncFlags field.
@@ -19953,10 +19993,13 @@
1995319993
** 2. Use sqlite3RCStrUnref() to free an RCStr string rather than
1995419994
** sqlite3_free()
1995519995
**
1995619996
** 3. Make a (read-only) copy of a read-only RCStr string using
1995719997
** sqlite3RCStrRef().
19998
+**
19999
+** "String" is in the name, but an RCStr object can also be used to hold
20000
+** binary data.
1995820001
*/
1995920002
struct RCStr {
1996020003
u64 nRCRef; /* Number of references */
1996120004
/* Total structure size should be a multiple of 8 bytes for alignment */
1996220005
};
@@ -20011,10 +20054,13 @@
2001120054
u8 bOpenUri; /* True to interpret filenames as URIs */
2001220055
u8 bUseCis; /* Use covering indices for full-scans */
2001320056
u8 bSmallMalloc; /* Avoid large memory allocations if true */
2001420057
u8 bExtraSchemaChecks; /* Verify type,name,tbl_name in schema */
2001520058
u8 bUseLongDouble; /* Make use of long double */
20059
+#ifdef SQLITE_DEBUG
20060
+ u8 bJsonSelfcheck; /* Double-check JSON parsing */
20061
+#endif
2001620062
int mxStrlen; /* Maximum string length */
2001720063
int neverCorrupt; /* Database is always well-formed */
2001820064
int szLookaside; /* Default lookaside buffer size */
2001920065
int nLookaside; /* Default lookaside buffer count */
2002020066
int nStmtSpill; /* Stmt-journal spill-to-disk threshold */
@@ -20637,19 +20683,21 @@
2063720683
SQLITE_PRIVATE void sqlite3ExprAddFunctionOrderBy(Parse*,Expr*,ExprList*);
2063820684
SQLITE_PRIVATE void sqlite3ExprOrderByAggregateError(Parse*,Expr*);
2063920685
SQLITE_PRIVATE void sqlite3ExprFunctionUsable(Parse*,const Expr*,const FuncDef*);
2064020686
SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
2064120687
SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
20688
+SQLITE_PRIVATE void sqlite3ExprDeleteGeneric(sqlite3*,void*);
2064220689
SQLITE_PRIVATE void sqlite3ExprDeferredDelete(Parse*, Expr*);
2064320690
SQLITE_PRIVATE void sqlite3ExprUnmapAndDelete(Parse*, Expr*);
2064420691
SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
2064520692
SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
2064620693
SQLITE_PRIVATE Select *sqlite3ExprListToValues(Parse*, int, ExprList*);
2064720694
SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList*,int,int);
2064820695
SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,const Token*,int);
2064920696
SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*);
2065020697
SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*);
20698
+SQLITE_PRIVATE void sqlite3ExprListDeleteGeneric(sqlite3*,void*);
2065120699
SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*);
2065220700
SQLITE_PRIVATE int sqlite3IndexHasDuplicateRootPage(Index*);
2065320701
SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**);
2065420702
SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**);
2065520703
SQLITE_PRIVATE int sqlite3InitOne(sqlite3*, int, char**, u32);
@@ -20736,10 +20784,11 @@
2073620784
SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask);
2073720785
#endif
2073820786
SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int);
2073920787
SQLITE_PRIVATE void sqlite3CodeDropTable(Parse*, Table*, int, int);
2074020788
SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*);
20789
+SQLITE_PRIVATE void sqlite3DeleteTableGeneric(sqlite3*, void*);
2074120790
SQLITE_PRIVATE void sqlite3FreeIndex(sqlite3*, Index*);
2074220791
#ifndef SQLITE_OMIT_AUTOINCREMENT
2074320792
SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse);
2074420793
SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse);
2074520794
#else
@@ -20772,10 +20821,11 @@
2077220821
SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
2077320822
SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*);
2077420823
SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
2077520824
Expr*,ExprList*,u32,Expr*);
2077620825
SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*);
20826
+SQLITE_PRIVATE void sqlite3SelectDeleteGeneric(sqlite3*,void*);
2077720827
SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*);
2077820828
SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, Trigger*);
2077920829
SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
2078020830
#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
2078120831
SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,char*);
@@ -20998,10 +21048,11 @@
2099821048
#ifndef SQLITE_OMIT_UTF16
2099921049
SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nChar);
2100021050
#endif
2100121051
SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte);
2100221052
SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**);
21053
+SQLITE_PRIVATE int sqlite3Utf8ReadLimited(const u8*, int, u32*);
2100321054
SQLITE_PRIVATE LogEst sqlite3LogEst(u64);
2100421055
SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst,LogEst);
2100521056
SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double);
2100621057
SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst);
2100721058
SQLITE_PRIVATE VList *sqlite3VListAdd(sqlite3*,VList*,const char*,int,int);
@@ -21344,10 +21395,11 @@
2134421395
#ifndef SQLITE_OMIT_CTE
2134521396
SQLITE_PRIVATE Cte *sqlite3CteNew(Parse*,Token*,ExprList*,Select*,u8);
2134621397
SQLITE_PRIVATE void sqlite3CteDelete(sqlite3*,Cte*);
2134721398
SQLITE_PRIVATE With *sqlite3WithAdd(Parse*,With*,Cte*);
2134821399
SQLITE_PRIVATE void sqlite3WithDelete(sqlite3*,With*);
21400
+SQLITE_PRIVATE void sqlite3WithDeleteGeneric(sqlite3*,void*);
2134921401
SQLITE_PRIVATE With *sqlite3WithPush(Parse*, With*, u8);
2135021402
#else
2135121403
# define sqlite3CteNew(P,T,E,S) ((void*)0)
2135221404
# define sqlite3CteDelete(D,C)
2135321405
# define sqlite3CteWithAdd(P,W,C) ((void*)0)
@@ -22721,10 +22773,13 @@
2272122773
SQLITE_USE_URI, /* bOpenUri */
2272222774
SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */
2272322775
0, /* bSmallMalloc */
2272422776
1, /* bExtraSchemaChecks */
2272522777
sizeof(LONGDOUBLE_TYPE)>8, /* bUseLongDouble */
22778
+#ifdef SQLITE_DEBUG
22779
+ 0, /* bJsonSelfcheck */
22780
+#endif
2272622781
0x7ffffffe, /* mxStrlen */
2272722782
0, /* neverCorrupt */
2272822783
SQLITE_DEFAULT_LOOKASIDE, /* szLookaside, nLookaside */
2272922784
SQLITE_STMTJRNL_SPILL, /* nStmtSpill */
2273022785
{0,0,0,0,0,0,0,0}, /* m */
@@ -25055,10 +25110,16 @@
2505525110
n = sqlite3_value_bytes(argv[i]);
2505625111
if( z==0 || parseModifier(context, (char*)z, n, p, i) ) return 1;
2505725112
}
2505825113
computeJD(p);
2505925114
if( p->isError || !validJulianDay(p->iJD) ) return 1;
25115
+ if( argc==1 && p->validYMD && p->D>28 ){
25116
+ /* Make sure a YYYY-MM-DD is normalized.
25117
+ ** Example: 2023-02-31 -> 2023-03-03 */
25118
+ assert( p->validJD );
25119
+ p->validYMD = 0;
25120
+ }
2506025121
return 0;
2506125122
}
2506225123
2506325124
2506425125
/*
@@ -32083,11 +32144,11 @@
3208332144
va_end(ap);
3208432145
}
3208532146
3208632147
3208732148
/*****************************************************************************
32088
-** Reference counted string storage
32149
+** Reference counted string/blob storage
3208932150
*****************************************************************************/
3209032151
3209132152
/*
3209232153
** Increase the reference count of the string by one.
3209332154
**
@@ -32935,11 +32996,11 @@
3293532996
pX = pExpr->pLeft;
3293632997
assert( ExprUseXList(pExpr) );
3293732998
assert( pExpr->x.pList->nExpr==2 );
3293832999
pY = pExpr->x.pList->a[0].pExpr;
3293933000
pZ = pExpr->x.pList->a[1].pExpr;
32940
- sqlite3TreeViewLine(pView, "BETWEEN");
33001
+ sqlite3TreeViewLine(pView, "BETWEEN%s", zFlgs);
3294133002
sqlite3TreeViewExpr(pView, pX, 1);
3294233003
sqlite3TreeViewExpr(pView, pY, 1);
3294333004
sqlite3TreeViewExpr(pView, pZ, 0);
3294433005
break;
3294533006
}
@@ -34070,11 +34131,42 @@
3407034131
|| (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; }
3407134132
}
3407234133
return c;
3407334134
}
3407434135
34075
-
34136
+/*
34137
+** Read a single UTF8 character out of buffer z[], but reading no
34138
+** more than n characters from the buffer. z[] is not zero-terminated.
34139
+**
34140
+** Return the number of bytes used to construct the character.
34141
+**
34142
+** Invalid UTF8 might generate a strange result. No effort is made
34143
+** to detect invalid UTF8.
34144
+**
34145
+** At most 4 bytes will be read out of z[]. The return value will always
34146
+** be between 1 and 4.
34147
+*/
34148
+SQLITE_PRIVATE int sqlite3Utf8ReadLimited(
34149
+ const u8 *z,
34150
+ int n,
34151
+ u32 *piOut
34152
+){
34153
+ u32 c;
34154
+ int i = 1;
34155
+ assert( n>0 );
34156
+ c = z[0];
34157
+ if( c>=0xc0 ){
34158
+ c = sqlite3Utf8Trans1[c-0xc0];
34159
+ if( n>4 ) n = 4;
34160
+ while( i<n && (z[i] & 0xc0)==0x80 ){
34161
+ c = (c<<6) + (0x3f & z[i]);
34162
+ i++;
34163
+ }
34164
+ }
34165
+ *piOut = c;
34166
+ return i;
34167
+}
3407634168
3407734169
3407834170
/*
3407934171
** If the TRANSLATE_TRACE macro is defined, the value of each Mem is
3408034172
** printed on stderr on the way into and out of sqlite3VdbeMemTranslate().
@@ -36839,17 +36931,19 @@
3683936931
/* 176 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
3684036932
/* 177 */ "VRename" OpHelp(""),
3684136933
/* 178 */ "Pagecount" OpHelp(""),
3684236934
/* 179 */ "MaxPgcnt" OpHelp(""),
3684336935
/* 180 */ "ClrSubtype" OpHelp("r[P1].subtype = 0"),
36844
- /* 181 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"),
36845
- /* 182 */ "Trace" OpHelp(""),
36846
- /* 183 */ "CursorHint" OpHelp(""),
36847
- /* 184 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"),
36848
- /* 185 */ "Noop" OpHelp(""),
36849
- /* 186 */ "Explain" OpHelp(""),
36850
- /* 187 */ "Abortable" OpHelp(""),
36936
+ /* 181 */ "GetSubtype" OpHelp("r[P2] = r[P1].subtype"),
36937
+ /* 182 */ "SetSubtype" OpHelp("r[P2].subtype = r[P1]"),
36938
+ /* 183 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"),
36939
+ /* 184 */ "Trace" OpHelp(""),
36940
+ /* 185 */ "CursorHint" OpHelp(""),
36941
+ /* 186 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"),
36942
+ /* 187 */ "Noop" OpHelp(""),
36943
+ /* 188 */ "Explain" OpHelp(""),
36944
+ /* 189 */ "Abortable" OpHelp(""),
3685136945
};
3685236946
return azName[i];
3685336947
}
3685436948
#endif
3685536949
@@ -41891,11 +41985,17 @@
4189141985
return SQLITE_OK;
4189241986
}
4189341987
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
4189441988
case SQLITE_FCNTL_LOCK_TIMEOUT: {
4189541989
int iOld = pFile->iBusyTimeout;
41990
+#if SQLITE_ENABLE_SETLK_TIMEOUT==1
4189641991
pFile->iBusyTimeout = *(int*)pArg;
41992
+#elif SQLITE_ENABLE_SETLK_TIMEOUT==2
41993
+ pFile->iBusyTimeout = !!(*(int*)pArg);
41994
+#else
41995
+# error "SQLITE_ENABLE_SETLK_TIMEOUT must be set to 1 or 2"
41996
+#endif
4189741997
*(int*)pArg = iOld;
4189841998
return SQLITE_OK;
4189941999
}
4190042000
#endif
4190142001
#if SQLITE_MAX_MMAP_SIZE>0
@@ -42144,10 +42244,29 @@
4214442244
** zFilename
4214542245
**
4214642246
** Either unixShmNode.pShmMutex must be held or unixShmNode.nRef==0 and
4214742247
** unixMutexHeld() is true when reading or writing any other field
4214842248
** in this structure.
42249
+**
42250
+** aLock[SQLITE_SHM_NLOCK]:
42251
+** This array records the various locks held by clients on each of the
42252
+** SQLITE_SHM_NLOCK slots. If the aLock[] entry is set to 0, then no
42253
+** locks are held by the process on this slot. If it is set to -1, then
42254
+** some client holds an EXCLUSIVE lock on the locking slot. If the aLock[]
42255
+** value is set to a positive value, then it is the number of shared
42256
+** locks currently held on the slot.
42257
+**
42258
+** aMutex[SQLITE_SHM_NLOCK]:
42259
+** Normally, when SQLITE_ENABLE_SETLK_TIMEOUT is not defined, mutex
42260
+** pShmMutex is used to protect the aLock[] array and the right to
42261
+** call fcntl() on unixShmNode.hShm to obtain or release locks.
42262
+**
42263
+** If SQLITE_ENABLE_SETLK_TIMEOUT is defined though, we use an array
42264
+** of mutexes - one for each locking slot. To read or write locking
42265
+** slot aLock[iSlot], the caller must hold the corresponding mutex
42266
+** aMutex[iSlot]. Similarly, to call fcntl() to obtain or release a
42267
+** lock corresponding to slot iSlot, mutex aMutex[iSlot] must be held.
4214942268
*/
4215042269
struct unixShmNode {
4215142270
unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */
4215242271
sqlite3_mutex *pShmMutex; /* Mutex to access this object */
4215342272
char *zFilename; /* Name of the mmapped file */
@@ -42157,14 +42276,15 @@
4215742276
u8 isReadonly; /* True if read-only */
4215842277
u8 isUnlocked; /* True if no DMS lock held */
4215942278
char **apRegion; /* Array of mapped shared-memory regions */
4216042279
int nRef; /* Number of unixShm objects pointing to this */
4216142280
unixShm *pFirst; /* All unixShm objects pointing to this */
42281
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
42282
+ sqlite3_mutex *aMutex[SQLITE_SHM_NLOCK];
42283
+#endif
4216242284
int aLock[SQLITE_SHM_NLOCK]; /* # shared locks on slot, -1==excl lock */
4216342285
#ifdef SQLITE_DEBUG
42164
- u8 exclMask; /* Mask of exclusive locks held */
42165
- u8 sharedMask; /* Mask of shared locks held */
4216642286
u8 nextShmId; /* Next available unixShm.id value */
4216742287
#endif
4216842288
};
4216942289
4217042290
/*
@@ -42243,20 +42363,33 @@
4224342363
){
4224442364
unixShmNode *pShmNode; /* Apply locks to this open shared-memory segment */
4224542365
struct flock f; /* The posix advisory locking structure */
4224642366
int rc = SQLITE_OK; /* Result code form fcntl() */
4224742367
42248
- /* Access to the unixShmNode object is serialized by the caller */
4224942368
pShmNode = pFile->pInode->pShmNode;
42250
- assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) );
42251
- assert( pShmNode->nRef>0 || unixMutexHeld() );
42369
+
42370
+ /* Assert that the correct mutex or mutexes are held. */
42371
+ if( pShmNode->nRef==0 ){
42372
+ assert( ofst==UNIX_SHM_DMS && n==1 && unixMutexHeld() );
42373
+ }else{
42374
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
42375
+ int ii;
42376
+ for(ii=ofst-UNIX_SHM_BASE; ii<ofst-UNIX_SHM_BASE+n; ii++){
42377
+ assert( sqlite3_mutex_held(pShmNode->aMutex[ii]) );
42378
+ }
42379
+#else
42380
+ assert( sqlite3_mutex_held(pShmNode->pShmMutex) );
42381
+ assert( pShmNode->nRef>0 );
42382
+#endif
42383
+ }
4225242384
4225342385
/* Shared locks never span more than one byte */
4225442386
assert( n==1 || lockType!=F_RDLCK );
4225542387
4225642388
/* Locks are within range */
4225742389
assert( n>=1 && n<=SQLITE_SHM_NLOCK );
42390
+ assert( ofst>=UNIX_SHM_BASE && ofst<=(UNIX_SHM_DMS+SQLITE_SHM_NLOCK) );
4225842391
4225942392
if( pShmNode->hShm>=0 ){
4226042393
int res;
4226142394
/* Initialize the locking parameters */
4226242395
f.l_type = lockType;
@@ -42263,50 +42396,39 @@
4226342396
f.l_whence = SEEK_SET;
4226442397
f.l_start = ofst;
4226542398
f.l_len = n;
4226642399
res = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile);
4226742400
if( res==-1 ){
42268
-#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
42401
+#if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && SQLITE_ENABLE_SETLK_TIMEOUT==1
4226942402
rc = (pFile->iBusyTimeout ? SQLITE_BUSY_TIMEOUT : SQLITE_BUSY);
4227042403
#else
4227142404
rc = SQLITE_BUSY;
4227242405
#endif
4227342406
}
4227442407
}
4227542408
42276
- /* Update the global lock state and do debug tracing */
42277
-#ifdef SQLITE_DEBUG
42278
- { u16 mask;
42279
- OSTRACE(("SHM-LOCK "));
42280
- mask = ofst>31 ? 0xffff : (1<<(ofst+n)) - (1<<ofst);
42281
- if( rc==SQLITE_OK ){
42282
- if( lockType==F_UNLCK ){
42283
- OSTRACE(("unlock %d ok", ofst));
42284
- pShmNode->exclMask &= ~mask;
42285
- pShmNode->sharedMask &= ~mask;
42286
- }else if( lockType==F_RDLCK ){
42287
- OSTRACE(("read-lock %d ok", ofst));
42288
- pShmNode->exclMask &= ~mask;
42289
- pShmNode->sharedMask |= mask;
42290
- }else{
42291
- assert( lockType==F_WRLCK );
42292
- OSTRACE(("write-lock %d ok", ofst));
42293
- pShmNode->exclMask |= mask;
42294
- pShmNode->sharedMask &= ~mask;
42295
- }
42296
- }else{
42297
- if( lockType==F_UNLCK ){
42298
- OSTRACE(("unlock %d failed", ofst));
42299
- }else if( lockType==F_RDLCK ){
42300
- OSTRACE(("read-lock failed"));
42301
- }else{
42302
- assert( lockType==F_WRLCK );
42303
- OSTRACE(("write-lock %d failed", ofst));
42304
- }
42305
- }
42306
- OSTRACE((" - afterwards %03x,%03x\n",
42307
- pShmNode->sharedMask, pShmNode->exclMask));
42409
+ /* Do debug tracing */
42410
+#ifdef SQLITE_DEBUG
42411
+ OSTRACE(("SHM-LOCK "));
42412
+ if( rc==SQLITE_OK ){
42413
+ if( lockType==F_UNLCK ){
42414
+ OSTRACE(("unlock %d..%d ok\n", ofst, ofst+n-1));
42415
+ }else if( lockType==F_RDLCK ){
42416
+ OSTRACE(("read-lock %d..%d ok\n", ofst, ofst+n-1));
42417
+ }else{
42418
+ assert( lockType==F_WRLCK );
42419
+ OSTRACE(("write-lock %d..%d ok\n", ofst, ofst+n-1));
42420
+ }
42421
+ }else{
42422
+ if( lockType==F_UNLCK ){
42423
+ OSTRACE(("unlock %d..%d failed\n", ofst, ofst+n-1));
42424
+ }else if( lockType==F_RDLCK ){
42425
+ OSTRACE(("read-lock %d..%d failed\n", ofst, ofst+n-1));
42426
+ }else{
42427
+ assert( lockType==F_WRLCK );
42428
+ OSTRACE(("write-lock %d..%d failed\n", ofst, ofst+n-1));
42429
+ }
4230842430
}
4230942431
#endif
4231042432
4231142433
return rc;
4231242434
}
@@ -42340,10 +42462,15 @@
4234042462
if( p && ALWAYS(p->nRef==0) ){
4234142463
int nShmPerMap = unixShmRegionPerMap();
4234242464
int i;
4234342465
assert( p->pInode==pFd->pInode );
4234442466
sqlite3_mutex_free(p->pShmMutex);
42467
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
42468
+ for(i=0; i<SQLITE_SHM_NLOCK; i++){
42469
+ sqlite3_mutex_free(p->aMutex[i]);
42470
+ }
42471
+#endif
4234542472
for(i=0; i<p->nRegion; i+=nShmPerMap){
4234642473
if( p->hShm>=0 ){
4234742474
osMunmap(p->apRegion[i], p->szRegion);
4234842475
}else{
4234942476
sqlite3_free(p->apRegion[i]);
@@ -42399,11 +42526,24 @@
4239942526
}else if( lock.l_type==F_UNLCK ){
4240042527
if( pShmNode->isReadonly ){
4240142528
pShmNode->isUnlocked = 1;
4240242529
rc = SQLITE_READONLY_CANTINIT;
4240342530
}else{
42531
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
42532
+ /* Do not use a blocking lock here. If the lock cannot be obtained
42533
+ ** immediately, it means some other connection is truncating the
42534
+ ** *-shm file. And after it has done so, it will not release its
42535
+ ** lock, but only downgrade it to a shared lock. So no point in
42536
+ ** blocking here. The call below to obtain the shared DMS lock may
42537
+ ** use a blocking lock. */
42538
+ int iSaveTimeout = pDbFd->iBusyTimeout;
42539
+ pDbFd->iBusyTimeout = 0;
42540
+#endif
4240442541
rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1);
42542
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
42543
+ pDbFd->iBusyTimeout = iSaveTimeout;
42544
+#endif
4240542545
/* The first connection to attach must truncate the -shm file. We
4240642546
** truncate to 3 bytes (an arbitrary small number, less than the
4240742547
** -shm header size) rather than 0 as a system debugging aid, to
4240842548
** help detect if a -shm file truncation is legitimate or is the work
4240942549
** or a rogue process. */
@@ -42520,10 +42660,22 @@
4252042660
pShmNode->pShmMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
4252142661
if( pShmNode->pShmMutex==0 ){
4252242662
rc = SQLITE_NOMEM_BKPT;
4252342663
goto shm_open_err;
4252442664
}
42665
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
42666
+ {
42667
+ int ii;
42668
+ for(ii=0; ii<SQLITE_SHM_NLOCK; ii++){
42669
+ pShmNode->aMutex[ii] = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
42670
+ if( pShmNode->aMutex[ii]==0 ){
42671
+ rc = SQLITE_NOMEM_BKPT;
42672
+ goto shm_open_err;
42673
+ }
42674
+ }
42675
+ }
42676
+#endif
4252542677
}
4252642678
4252742679
if( pInode->bProcessLock==0 ){
4252842680
if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
4252942681
pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT|O_NOFOLLOW,
@@ -42741,13 +42893,15 @@
4274142893
**
4274242894
** assert( assertLockingArrayOk(pShmNode) );
4274342895
*/
4274442896
#ifdef SQLITE_DEBUG
4274542897
static int assertLockingArrayOk(unixShmNode *pShmNode){
42898
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
42899
+ return 1;
42900
+#else
4274642901
unixShm *pX;
4274742902
int aLock[SQLITE_SHM_NLOCK];
42748
- assert( sqlite3_mutex_held(pShmNode->pShmMutex) );
4274942903
4275042904
memset(aLock, 0, sizeof(aLock));
4275142905
for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
4275242906
int i;
4275342907
for(i=0; i<SQLITE_SHM_NLOCK; i++){
@@ -42761,17 +42915,18 @@
4276142915
}
4276242916
}
4276342917
4276442918
assert( 0==memcmp(pShmNode->aLock, aLock, sizeof(aLock)) );
4276542919
return (memcmp(pShmNode->aLock, aLock, sizeof(aLock))==0);
42920
+#endif
4276642921
}
4276742922
#endif
4276842923
4276942924
/*
4277042925
** Change the lock state for a shared-memory segment.
4277142926
**
42772
-** Note that the relationship between SHAREd and EXCLUSIVE locks is a little
42927
+** Note that the relationship between SHARED and EXCLUSIVE locks is a little
4277342928
** different here than in posix. In xShmLock(), one can go from unlocked
4277442929
** to shared and back or from unlocked to exclusive and back. But one may
4277542930
** not go from shared to exclusive or from exclusive to shared.
4277642931
*/
4277742932
static int unixShmLock(
@@ -42782,11 +42937,11 @@
4278242937
){
4278342938
unixFile *pDbFd = (unixFile*)fd; /* Connection holding shared memory */
4278442939
unixShm *p; /* The shared memory being locked */
4278542940
unixShmNode *pShmNode; /* The underlying file iNode */
4278642941
int rc = SQLITE_OK; /* Result code */
42787
- u16 mask; /* Mask of locks to take or release */
42942
+ u16 mask = (1<<(ofst+n)) - (1<<ofst); /* Mask of locks to take or release */
4278842943
int *aLock;
4278942944
4279042945
p = pDbFd->pShm;
4279142946
if( p==0 ) return SQLITE_IOERR_SHMLOCK;
4279242947
pShmNode = p->pShmNode;
@@ -42817,92 +42972,154 @@
4281742972
** held.
4281842973
**
4281942974
** It is not permitted to block on the RECOVER lock.
4282042975
*/
4282142976
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
42822
- assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || (
42823
- (ofst!=2) /* not RECOVER */
42824
- && (ofst!=1 || (p->exclMask|p->sharedMask)==0)
42825
- && (ofst!=0 || (p->exclMask|p->sharedMask)<3)
42826
- && (ofst<3 || (p->exclMask|p->sharedMask)<(1<<ofst))
42827
- ));
42828
-#endif
42829
-
42830
- mask = (1<<(ofst+n)) - (1<<ofst);
42831
- assert( n>1 || mask==(1<<ofst) );
42832
- sqlite3_mutex_enter(pShmNode->pShmMutex);
42833
- assert( assertLockingArrayOk(pShmNode) );
42834
- if( flags & SQLITE_SHM_UNLOCK ){
42835
- if( (p->exclMask|p->sharedMask) & mask ){
42836
- int ii;
42837
- int bUnlock = 1;
42838
-
42839
- for(ii=ofst; ii<ofst+n; ii++){
42840
- if( aLock[ii]>((p->sharedMask & (1<<ii)) ? 1 : 0) ){
42841
- bUnlock = 0;
42842
- }
42843
- }
42844
-
42845
- if( bUnlock ){
42846
- rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n);
42847
- if( rc==SQLITE_OK ){
42848
- memset(&aLock[ofst], 0, sizeof(int)*n);
42849
- }
42850
- }else if( ALWAYS(p->sharedMask & (1<<ofst)) ){
42851
- assert( n==1 && aLock[ofst]>1 );
42852
- aLock[ofst]--;
42853
- }
42854
-
42855
- /* Undo the local locks */
42856
- if( rc==SQLITE_OK ){
42857
- p->exclMask &= ~mask;
42858
- p->sharedMask &= ~mask;
42859
- }
42860
- }
42861
- }else if( flags & SQLITE_SHM_SHARED ){
42862
- assert( n==1 );
42863
- assert( (p->exclMask & (1<<ofst))==0 );
42864
- if( (p->sharedMask & mask)==0 ){
42865
- if( aLock[ofst]<0 ){
42866
- rc = SQLITE_BUSY;
42867
- }else if( aLock[ofst]==0 ){
42868
- rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n);
42869
- }
42870
-
42871
- /* Get the local shared locks */
42872
- if( rc==SQLITE_OK ){
42873
- p->sharedMask |= mask;
42874
- aLock[ofst]++;
42875
- }
42876
- }
42877
- }else{
42878
- /* Make sure no sibling connections hold locks that will block this
42879
- ** lock. If any do, return SQLITE_BUSY right away. */
42880
- int ii;
42881
- for(ii=ofst; ii<ofst+n; ii++){
42882
- assert( (p->sharedMask & mask)==0 );
42883
- if( ALWAYS((p->exclMask & (1<<ii))==0) && aLock[ii] ){
42884
- rc = SQLITE_BUSY;
42885
- break;
42886
- }
42887
- }
42888
-
42889
- /* Get the exclusive locks at the system level. Then if successful
42890
- ** also update the in-memory values. */
42891
- if( rc==SQLITE_OK ){
42892
- rc = unixShmSystemLock(pDbFd, F_WRLCK, ofst+UNIX_SHM_BASE, n);
42893
- if( rc==SQLITE_OK ){
42894
- assert( (p->sharedMask & mask)==0 );
42895
- p->exclMask |= mask;
42896
- for(ii=ofst; ii<ofst+n; ii++){
42897
- aLock[ii] = -1;
42898
- }
42899
- }
42900
- }
42901
- }
42902
- assert( assertLockingArrayOk(pShmNode) );
42903
- sqlite3_mutex_leave(pShmNode->pShmMutex);
42977
+ {
42978
+ u16 lockMask = (p->exclMask|p->sharedMask);
42979
+ assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || (
42980
+ (ofst!=2) /* not RECOVER */
42981
+ && (ofst!=1 || lockMask==0 || lockMask==2)
42982
+ && (ofst!=0 || lockMask<3)
42983
+ && (ofst<3 || lockMask<(1<<ofst))
42984
+ ));
42985
+ }
42986
+#endif
42987
+
42988
+ /* Check if there is any work to do. There are three cases:
42989
+ **
42990
+ ** a) An unlock operation where there are locks to unlock,
42991
+ ** b) An shared lock where the requested lock is not already held
42992
+ ** c) An exclusive lock where the requested lock is not already held
42993
+ **
42994
+ ** The SQLite core never requests an exclusive lock that it already holds.
42995
+ ** This is assert()ed below.
42996
+ */
42997
+ assert( flags!=(SQLITE_SHM_EXCLUSIVE|SQLITE_SHM_LOCK)
42998
+ || 0==(p->exclMask & mask)
42999
+ );
43000
+ if( ((flags & SQLITE_SHM_UNLOCK) && ((p->exclMask|p->sharedMask) & mask))
43001
+ || (flags==(SQLITE_SHM_SHARED|SQLITE_SHM_LOCK) && 0==(p->sharedMask & mask))
43002
+ || (flags==(SQLITE_SHM_EXCLUSIVE|SQLITE_SHM_LOCK))
43003
+ ){
43004
+
43005
+ /* Take the required mutexes. In SETLK_TIMEOUT mode (blocking locks), if
43006
+ ** this is an attempt on an exclusive lock use sqlite3_mutex_try(). If any
43007
+ ** other thread is holding this mutex, then it is either holding or about
43008
+ ** to hold a lock exclusive to the one being requested, and we may
43009
+ ** therefore return SQLITE_BUSY to the caller.
43010
+ **
43011
+ ** Doing this prevents some deadlock scenarios. For example, thread 1 may
43012
+ ** be a checkpointer blocked waiting on the WRITER lock. And thread 2
43013
+ ** may be a normal SQL client upgrading to a write transaction. In this
43014
+ ** case thread 2 does a non-blocking request for the WRITER lock. But -
43015
+ ** if it were to use sqlite3_mutex_enter() then it would effectively
43016
+ ** become a (doomed) blocking request, as thread 2 would block until thread
43017
+ ** 1 obtained WRITER and released the mutex. Since thread 2 already holds
43018
+ ** a lock on a read-locking slot at this point, this breaks the
43019
+ ** anti-deadlock rules (see above). */
43020
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
43021
+ int iMutex;
43022
+ for(iMutex=ofst; iMutex<ofst+n; iMutex++){
43023
+ if( flags==(SQLITE_SHM_LOCK|SQLITE_SHM_EXCLUSIVE) ){
43024
+ rc = sqlite3_mutex_try(pShmNode->aMutex[iMutex]);
43025
+ if( rc!=SQLITE_OK ) break;
43026
+ }else{
43027
+ sqlite3_mutex_enter(pShmNode->aMutex[iMutex]);
43028
+ }
43029
+ }
43030
+#else
43031
+ sqlite3_mutex_enter(pShmNode->pShmMutex);
43032
+#endif
43033
+
43034
+ if( rc==SQLITE_OK ){
43035
+ if( flags & SQLITE_SHM_UNLOCK ){
43036
+ /* Case (a) - unlock. */
43037
+ int bUnlock = 1;
43038
+ assert( (p->exclMask & p->sharedMask)==0 );
43039
+ assert( !(flags & SQLITE_SHM_EXCLUSIVE) || (p->exclMask & mask)==mask );
43040
+ assert( !(flags & SQLITE_SHM_SHARED) || (p->sharedMask & mask)==mask );
43041
+
43042
+ /* If this is a SHARED lock being unlocked, it is possible that other
43043
+ ** clients within this process are holding the same SHARED lock. In
43044
+ ** this case, set bUnlock to 0 so that the posix lock is not removed
43045
+ ** from the file-descriptor below. */
43046
+ if( flags & SQLITE_SHM_SHARED ){
43047
+ assert( n==1 );
43048
+ assert( aLock[ofst]>=1 );
43049
+ if( aLock[ofst]>1 ){
43050
+ bUnlock = 0;
43051
+ aLock[ofst]--;
43052
+ p->sharedMask &= ~mask;
43053
+ }
43054
+ }
43055
+
43056
+ if( bUnlock ){
43057
+ rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n);
43058
+ if( rc==SQLITE_OK ){
43059
+ memset(&aLock[ofst], 0, sizeof(int)*n);
43060
+ p->sharedMask &= ~mask;
43061
+ p->exclMask &= ~mask;
43062
+ }
43063
+ }
43064
+ }else if( flags & SQLITE_SHM_SHARED ){
43065
+ /* Case (b) - a shared lock. */
43066
+
43067
+ if( aLock[ofst]<0 ){
43068
+ /* An exclusive lock is held by some other connection. BUSY. */
43069
+ rc = SQLITE_BUSY;
43070
+ }else if( aLock[ofst]==0 ){
43071
+ rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n);
43072
+ }
43073
+
43074
+ /* Get the local shared locks */
43075
+ if( rc==SQLITE_OK ){
43076
+ p->sharedMask |= mask;
43077
+ aLock[ofst]++;
43078
+ }
43079
+ }else{
43080
+ /* Case (c) - an exclusive lock. */
43081
+ int ii;
43082
+
43083
+ assert( flags==(SQLITE_SHM_LOCK|SQLITE_SHM_EXCLUSIVE) );
43084
+ assert( (p->sharedMask & mask)==0 );
43085
+ assert( (p->exclMask & mask)==0 );
43086
+
43087
+ /* Make sure no sibling connections hold locks that will block this
43088
+ ** lock. If any do, return SQLITE_BUSY right away. */
43089
+ for(ii=ofst; ii<ofst+n; ii++){
43090
+ if( aLock[ii] ){
43091
+ rc = SQLITE_BUSY;
43092
+ break;
43093
+ }
43094
+ }
43095
+
43096
+ /* Get the exclusive locks at the system level. Then if successful
43097
+ ** also update the in-memory values. */
43098
+ if( rc==SQLITE_OK ){
43099
+ rc = unixShmSystemLock(pDbFd, F_WRLCK, ofst+UNIX_SHM_BASE, n);
43100
+ if( rc==SQLITE_OK ){
43101
+ p->exclMask |= mask;
43102
+ for(ii=ofst; ii<ofst+n; ii++){
43103
+ aLock[ii] = -1;
43104
+ }
43105
+ }
43106
+ }
43107
+ }
43108
+ assert( assertLockingArrayOk(pShmNode) );
43109
+ }
43110
+
43111
+ /* Drop the mutexes acquired above. */
43112
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
43113
+ for(iMutex--; iMutex>=ofst; iMutex--){
43114
+ sqlite3_mutex_leave(pShmNode->aMutex[iMutex]);
43115
+ }
43116
+#else
43117
+ sqlite3_mutex_leave(pShmNode->pShmMutex);
43118
+#endif
43119
+ }
43120
+
4290443121
OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n",
4290543122
p->id, osGetpid(0), p->sharedMask, p->exclMask));
4290643123
return rc;
4290743124
}
4290843125
@@ -66236,10 +66453,23 @@
6623666453
*pp = p;
6623766454
return rc;
6623866455
}
6623966456
6624066457
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
66458
+
66459
+
66460
+/*
66461
+** Attempt to enable blocking locks that block for nMs ms. Return 1 if
66462
+** blocking locks are successfully enabled, or 0 otherwise.
66463
+*/
66464
+static int walEnableBlockingMs(Wal *pWal, int nMs){
66465
+ int rc = sqlite3OsFileControl(
66466
+ pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&nMs
66467
+ );
66468
+ return (rc==SQLITE_OK);
66469
+}
66470
+
6624166471
/*
6624266472
** Attempt to enable blocking locks. Blocking locks are enabled only if (a)
6624366473
** they are supported by the VFS, and (b) the database handle is configured
6624466474
** with a busy-timeout. Return 1 if blocking locks are successfully enabled,
6624566475
** or 0 otherwise.
@@ -66247,15 +66477,11 @@
6624766477
static int walEnableBlocking(Wal *pWal){
6624866478
int res = 0;
6624966479
if( pWal->db ){
6625066480
int tmout = pWal->db->busyTimeout;
6625166481
if( tmout ){
66252
- int rc;
66253
- rc = sqlite3OsFileControl(
66254
- pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout
66255
- );
66256
- res = (rc==SQLITE_OK);
66482
+ res = walEnableBlockingMs(pWal, tmout);
6625766483
}
6625866484
}
6625966485
return res;
6626066486
}
6626166487
@@ -66300,24 +66526,14 @@
6630066526
*/
6630166527
SQLITE_PRIVATE void sqlite3WalDb(Wal *pWal, sqlite3 *db){
6630266528
pWal->db = db;
6630366529
}
6630466530
66305
-/*
66306
-** Take an exclusive WRITE lock. Blocking if so configured.
66307
-*/
66308
-static int walLockWriter(Wal *pWal){
66309
- int rc;
66310
- walEnableBlocking(pWal);
66311
- rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
66312
- walDisableBlocking(pWal);
66313
- return rc;
66314
-}
6631566531
#else
6631666532
# define walEnableBlocking(x) 0
6631766533
# define walDisableBlocking(x)
66318
-# define walLockWriter(pWal) walLockExclusive((pWal), WAL_WRITE_LOCK, 1)
66534
+# define walEnableBlockingMs(pWal, ms) 0
6631966535
# define sqlite3WalDb(pWal, db)
6632066536
#endif /* ifdef SQLITE_ENABLE_SETLK_TIMEOUT */
6632166537
6632266538
6632366539
/*
@@ -66914,19 +67130,22 @@
6691467130
walUnlockShared(pWal, WAL_WRITE_LOCK);
6691567131
rc = SQLITE_READONLY_RECOVERY;
6691667132
}
6691767133
}else{
6691867134
int bWriteLock = pWal->writeLock;
66919
- if( bWriteLock || SQLITE_OK==(rc = walLockWriter(pWal)) ){
67135
+ if( bWriteLock
67136
+ || SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1))
67137
+ ){
6692067138
pWal->writeLock = 1;
6692167139
if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){
6692267140
badHdr = walIndexTryHdr(pWal, pChanged);
6692367141
if( badHdr ){
6692467142
/* If the wal-index header is still malformed even while holding
6692567143
** a WRITE lock, it can only mean that the header is corrupted and
6692667144
** needs to be reconstructed. So run recovery to do exactly that.
66927
- */
67145
+ ** Disable blocking locks first. */
67146
+ walDisableBlocking(pWal);
6692867147
rc = walIndexRecover(pWal);
6692967148
*pChanged = 1;
6693067149
}
6693167150
}
6693267151
if( bWriteLock==0 ){
@@ -67189,10 +67408,13 @@
6718967408
u32 mxReadMark; /* Largest aReadMark[] value */
6719067409
int mxI; /* Index of largest aReadMark[] value */
6719167410
int i; /* Loop counter */
6719267411
int rc = SQLITE_OK; /* Return code */
6719367412
u32 mxFrame; /* Wal frame to lock to */
67413
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
67414
+ int nBlockTmout = 0;
67415
+#endif
6719467416
6719567417
assert( pWal->readLock<0 ); /* Not currently locked */
6719667418
6719767419
/* useWal may only be set for read/write connections */
6719867420
assert( (pWal->readOnly & WAL_SHM_RDONLY)==0 || useWal==0 );
@@ -67219,18 +67441,35 @@
6721967441
if( cnt>100 ){
6722067442
VVA_ONLY( pWal->lockError = 1; )
6722167443
return SQLITE_PROTOCOL;
6722267444
}
6722367445
if( cnt>=10 ) nDelay = (cnt-9)*(cnt-9)*39;
67446
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
67447
+ /* In SQLITE_ENABLE_SETLK_TIMEOUT builds, configure the file-descriptor
67448
+ ** to block for locks for approximately nDelay us. This affects three
67449
+ ** locks: (a) the shared lock taken on the DMS slot in os_unix.c (if
67450
+ ** using os_unix.c), (b) the WRITER lock taken in walIndexReadHdr() if the
67451
+ ** first attempted read fails, and (c) the shared lock taken on the DMS
67452
+ ** slot in os_unix.c. All three of these locks are attempted from within
67453
+ ** the call to walIndexReadHdr() below. */
67454
+ nBlockTmout = (nDelay+998) / 1000;
67455
+ if( !useWal && walEnableBlockingMs(pWal, nBlockTmout) ){
67456
+ nDelay = 1;
67457
+ }
67458
+#endif
6722467459
sqlite3OsSleep(pWal->pVfs, nDelay);
6722567460
}
6722667461
6722767462
if( !useWal ){
6722867463
assert( rc==SQLITE_OK );
6722967464
if( pWal->bShmUnreliable==0 ){
6723067465
rc = walIndexReadHdr(pWal, pChanged);
6723167466
}
67467
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
67468
+ walDisableBlocking(pWal);
67469
+ if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY;
67470
+#endif
6723267471
if( rc==SQLITE_BUSY ){
6723367472
/* If there is not a recovery running in another thread or process
6723467473
** then convert BUSY errors to WAL_RETRY. If recovery is known to
6723567474
** be running, convert BUSY to BUSY_RECOVERY. There is a race here
6723667475
** which might cause WAL_RETRY to be returned even if BUSY_RECOVERY
@@ -67341,13 +67580,16 @@
6734167580
if( mxI==0 ){
6734267581
assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 );
6734367582
return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTINIT;
6734467583
}
6734567584
67585
+ (void)walEnableBlockingMs(pWal, nBlockTmout);
6734667586
rc = walLockShared(pWal, WAL_READ_LOCK(mxI));
67587
+ walDisableBlocking(pWal);
6734767588
if( rc ){
67348
- return rc==SQLITE_BUSY ? WAL_RETRY : rc;
67589
+ assert( (rc&0xFF)!=SQLITE_BUSY||rc==SQLITE_BUSY||rc==SQLITE_BUSY_TIMEOUT );
67590
+ return (rc&0xFF)==SQLITE_BUSY ? WAL_RETRY : rc;
6734967591
}
6735067592
/* Now that the read-lock has been obtained, check that neither the
6735167593
** value in the aReadMark[] array or the contents of the wal-index
6735267594
** header have changed.
6735367595
**
@@ -68436,14 +68678,13 @@
6843668678
assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
6843768679
6843868680
if( pWal->readOnly ) return SQLITE_READONLY;
6843968681
WALTRACE(("WAL%p: checkpoint begins\n", pWal));
6844068682
68441
- /* Enable blocking locks, if possible. If blocking locks are successfully
68442
- ** enabled, set xBusy2=0 so that the busy-handler is never invoked. */
68683
+ /* Enable blocking locks, if possible. */
6844368684
sqlite3WalDb(pWal, db);
68444
- (void)walEnableBlocking(pWal);
68685
+ if( xBusy2 ) (void)walEnableBlocking(pWal);
6844568686
6844668687
/* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive
6844768688
** "checkpoint" lock on the database file.
6844868689
** EVIDENCE-OF: R-10421-19736 If any other process is running a
6844968690
** checkpoint operation at the same time, the lock cannot be obtained and
@@ -68480,13 +68721,18 @@
6848068721
6848168722
6848268723
/* Read the wal-index header. */
6848368724
SEH_TRY {
6848468725
if( rc==SQLITE_OK ){
68726
+ /* For a passive checkpoint, do not re-enable blocking locks after
68727
+ ** reading the wal-index header. A passive checkpoint should not block
68728
+ ** or invoke the busy handler. The only lock such a checkpoint may
68729
+ ** attempt to obtain is a lock on a read-slot, and it should give up
68730
+ ** immediately and do a partial checkpoint if it cannot obtain it. */
6848568731
walDisableBlocking(pWal);
6848668732
rc = walIndexReadHdr(pWal, &isChanged);
68487
- (void)walEnableBlocking(pWal);
68733
+ if( eMode2!=SQLITE_CHECKPOINT_PASSIVE ) (void)walEnableBlocking(pWal);
6848868734
if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){
6848968735
sqlite3OsUnfetch(pWal->pDbFd, 0, 0);
6849068736
}
6849168737
}
6849268738
@@ -68819,11 +69065,11 @@
6881969065
** 20 1 Bytes of unused space at the end of each page
6882069066
** 21 1 Max embedded payload fraction (must be 64)
6882169067
** 22 1 Min embedded payload fraction (must be 32)
6882269068
** 23 1 Min leaf payload fraction (must be 32)
6882369069
** 24 4 File change counter
68824
-** 28 4 Reserved for future use
69070
+** 28 4 The size of the database in pages
6882569071
** 32 4 First freelist page
6882669072
** 36 4 Number of freelist pages in the file
6882769073
** 40 60 15 4-byte meta values passed to higher layers
6882869074
**
6882969075
** 40 4 Schema cookie
@@ -85370,10 +85616,14 @@
8537085616
}
8537185617
case P4_VTAB : {
8537285618
if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4);
8537385619
break;
8537485620
}
85621
+ case P4_TABLEREF: {
85622
+ if( db->pnBytesFreed==0 ) sqlite3DeleteTable(db, (Table*)p4);
85623
+ break;
85624
+ }
8537585625
}
8537685626
}
8537785627
8537885628
/*
8537985629
** Free the space allocated for aOp and any p4 values allocated for the
@@ -85497,11 +85747,11 @@
8549785747
Op *pOp,
8549885748
const char *zP4,
8549985749
int n
8550085750
){
8550185751
if( pOp->p4type ){
85502
- freeP4(p->db, pOp->p4type, pOp->p4.p);
85752
+ assert( pOp->p4type > P4_FREE_IF_LE );
8550385753
pOp->p4type = 0;
8550485754
pOp->p4.p = 0;
8550585755
}
8550685756
if( n<0 ){
8550785757
sqlite3VdbeChangeP4(p, (int)(pOp - p->aOp), zP4, n);
@@ -89620,11 +89870,19 @@
8962089870
SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
8962189871
int i;
8962289872
int rc = SQLITE_OK;
8962389873
Vdbe *p = (Vdbe*)pStmt;
8962489874
#if SQLITE_THREADSAFE
89625
- sqlite3_mutex *mutex = ((Vdbe*)pStmt)->db->mutex;
89875
+ sqlite3_mutex *mutex;
89876
+#endif
89877
+#ifdef SQLITE_ENABLE_API_ARMOR
89878
+ if( pStmt==0 ){
89879
+ return SQLITE_MISUSE_BKPT;
89880
+ }
89881
+#endif
89882
+#if SQLITE_THREADSAFE
89883
+ mutex = p->db->mutex;
8962689884
#endif
8962789885
sqlite3_mutex_enter(mutex);
8962889886
for(i=0; i<p->nVar; i++){
8962989887
sqlite3VdbeMemRelease(&p->aVar[i]);
8963089888
p->aVar[i].flags = MEM_Null;
@@ -90410,13 +90668,12 @@
9041090668
** pointer to it.
9041190669
*/
9041290670
SQLITE_API void *sqlite3_user_data(sqlite3_context *p){
9041390671
#ifdef SQLITE_ENABLE_API_ARMOR
9041490672
if( p==0 ) return 0;
90415
-#else
90673
+#endif
9041690674
assert( p && p->pFunc );
90417
-#endif
9041890675
return p->pFunc->pUserData;
9041990676
}
9042090677
9042190678
/*
9042290679
** Extract the user data from a sqlite3_context structure and return a
@@ -94231,11 +94488,11 @@
9423194488
*/
9423294489
case OP_AddImm: { /* in1 */
9423394490
pIn1 = &aMem[pOp->p1];
9423494491
memAboutToChange(p, pIn1);
9423594492
sqlite3VdbeMemIntegerify(pIn1);
94236
- pIn1->u.i += pOp->p2;
94493
+ *(u64*)&pIn1->u.i += (u64)pOp->p2;
9423794494
break;
9423894495
}
9423994496
9424094497
/* Opcode: MustBeInt P1 P2 * * *
9424194498
**
@@ -100377,28 +100634,27 @@
100377100634
const sqlite3_module *pModule;
100378100635
char *zErr = 0;
100379100636
100380100637
pOut = &aMem[pOp->p2];
100381100638
sqlite3VdbeMemSetNull(pOut); /* Innocent until proven guilty */
100382
- assert( pOp->p4type==P4_TABLE );
100639
+ assert( pOp->p4type==P4_TABLEREF );
100383100640
pTab = pOp->p4.pTab;
100384100641
assert( pTab!=0 );
100642
+ assert( pTab->nTabRef>0 );
100385100643
assert( IsVirtual(pTab) );
100386100644
if( pTab->u.vtab.p==0 ) break;
100387100645
pVtab = pTab->u.vtab.p->pVtab;
100388100646
assert( pVtab!=0 );
100389100647
pModule = pVtab->pModule;
100390100648
assert( pModule!=0 );
100391100649
assert( pModule->iVersion>=4 );
100392100650
assert( pModule->xIntegrity!=0 );
100393
- pTab->nTabRef++;
100394100651
sqlite3VtabLock(pTab->u.vtab.p);
100395100652
assert( pOp->p1>=0 && pOp->p1<db->nDb );
100396100653
rc = pModule->xIntegrity(pVtab, db->aDb[pOp->p1].zDbSName, pTab->zName,
100397100654
pOp->p3, &zErr);
100398100655
sqlite3VtabUnlock(pTab->u.vtab.p);
100399
- sqlite3DeleteTable(db, pTab);
100400100656
if( rc ){
100401100657
sqlite3_free(zErr);
100402100658
goto abort_due_to_error;
100403100659
}
100404100660
if( zErr ){
@@ -100519,10 +100775,11 @@
100519100775
case OP_VColumn: { /* ncycle */
100520100776
sqlite3_vtab *pVtab;
100521100777
const sqlite3_module *pModule;
100522100778
Mem *pDest;
100523100779
sqlite3_context sContext;
100780
+ FuncDef nullFunc;
100524100781
100525100782
VdbeCursor *pCur = p->apCsr[pOp->p1];
100526100783
assert( pCur!=0 );
100527100784
assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
100528100785
pDest = &aMem[pOp->p3];
@@ -100536,10 +100793,13 @@
100536100793
pModule = pVtab->pModule;
100537100794
assert( pModule->xColumn );
100538100795
memset(&sContext, 0, sizeof(sContext));
100539100796
sContext.pOut = pDest;
100540100797
sContext.enc = encoding;
100798
+ nullFunc.pUserData = 0;
100799
+ nullFunc.funcFlags = SQLITE_RESULT_SUBTYPE;
100800
+ sContext.pFunc = &nullFunc;
100541100801
assert( pOp->p5==OPFLAG_NOCHNG || pOp->p5==0 );
100542100802
if( pOp->p5 & OPFLAG_NOCHNG ){
100543100803
sqlite3VdbeMemSetNull(pDest);
100544100804
pDest->flags = MEM_Null|MEM_Zero;
100545100805
pDest->u.nZero = 0;
@@ -100867,10 +101127,46 @@
100867101127
case OP_ClrSubtype: { /* in1 */
100868101128
pIn1 = &aMem[pOp->p1];
100869101129
pIn1->flags &= ~MEM_Subtype;
100870101130
break;
100871101131
}
101132
+
101133
+/* Opcode: GetSubtype P1 P2 * * *
101134
+** Synopsis: r[P2] = r[P1].subtype
101135
+**
101136
+** Extract the subtype value from register P1 and write that subtype
101137
+** into register P2. If P1 has no subtype, then P1 gets a NULL.
101138
+*/
101139
+case OP_GetSubtype: { /* in1 out2 */
101140
+ pIn1 = &aMem[pOp->p1];
101141
+ pOut = &aMem[pOp->p2];
101142
+ if( pIn1->flags & MEM_Subtype ){
101143
+ sqlite3VdbeMemSetInt64(pOut, pIn1->eSubtype);
101144
+ }else{
101145
+ sqlite3VdbeMemSetNull(pOut);
101146
+ }
101147
+ break;
101148
+}
101149
+
101150
+/* Opcode: SetSubtype P1 P2 * * *
101151
+** Synopsis: r[P2].subtype = r[P1]
101152
+**
101153
+** Set the subtype value of register P2 to the integer from register P1.
101154
+** If P1 is NULL, clear the subtype from p2.
101155
+*/
101156
+case OP_SetSubtype: { /* in1 out2 */
101157
+ pIn1 = &aMem[pOp->p1];
101158
+ pOut = &aMem[pOp->p2];
101159
+ if( pIn1->flags & MEM_Null ){
101160
+ pOut->flags &= ~MEM_Subtype;
101161
+ }else{
101162
+ assert( pIn1->flags & MEM_Int );
101163
+ pOut->flags |= MEM_Subtype;
101164
+ pOut->eSubtype = (u8)(pIn1->u.i & 0xff);
101165
+ }
101166
+ break;
101167
+}
100872101168
100873101169
/* Opcode: FilterAdd P1 * P3 P4 *
100874101170
** Synopsis: filter(P1) += key(P3@P4)
100875101171
**
100876101172
** Compute a hash on the P4 registers starting with r[P3] and
@@ -105916,10 +106212,11 @@
105916106212
105917106213
n = pExpr->iColumn;
105918106214
assert( ExprUseYTab(pExpr) );
105919106215
pExTab = pExpr->y.pTab;
105920106216
assert( pExTab!=0 );
106217
+ assert( n < pExTab->nCol );
105921106218
if( (pExTab->tabFlags & TF_HasGenerated)!=0
105922106219
&& (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0
105923106220
){
105924106221
testcase( pExTab->nCol==BMS-1 );
105925106222
testcase( pExTab->nCol==BMS );
@@ -106518,11 +106815,11 @@
106518106815
** (See ticket [b92e5e8ec2cdbaa1]).
106519106816
**
106520106817
** If a generated column is referenced, set bits for every column
106521106818
** of the table.
106522106819
*/
106523
- if( pExpr->iColumn>=0 && pMatch!=0 ){
106820
+ if( pExpr->iColumn>=0 && cnt==1 && pMatch!=0 ){
106524106821
pMatch->colUsed |= sqlite3ExprColUsed(pExpr);
106525106822
}
106526106823
106527106824
pExpr->op = eNewExprOp;
106528106825
lookupname_end:
@@ -106983,15 +107280,16 @@
106983107280
#endif
106984107281
pNC2 = pNC;
106985107282
while( pNC2
106986107283
&& sqlite3ReferencesSrcList(pParse, pExpr, pNC2->pSrcList)==0
106987107284
){
106988
- pExpr->op2++;
107285
+ pExpr->op2 += (1 + pNC2->nNestedSelect);
106989107286
pNC2 = pNC2->pNext;
106990107287
}
106991107288
assert( pDef!=0 || IN_RENAME_OBJECT );
106992107289
if( pNC2 && pDef ){
107290
+ pExpr->op2 += pNC2->nNestedSelect;
106993107291
assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg );
106994107292
assert( SQLITE_FUNC_ANYORDER==NC_OrderAgg );
106995107293
testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 );
106996107294
testcase( (pDef->funcFlags & SQLITE_FUNC_ANYORDER)!=0 );
106997107295
pNC2->ncFlags |= NC_HasAgg
@@ -107546,10 +107844,11 @@
107546107844
p->pOrderBy = 0;
107547107845
}
107548107846
107549107847
/* Recursively resolve names in all subqueries in the FROM clause
107550107848
*/
107849
+ if( pOuterNC ) pOuterNC->nNestedSelect++;
107551107850
for(i=0; i<p->pSrc->nSrc; i++){
107552107851
SrcItem *pItem = &p->pSrc->a[i];
107553107852
if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){
107554107853
int nRef = pOuterNC ? pOuterNC->nRef : 0;
107555107854
const char *zSavedContext = pParse->zAuthContext;
@@ -107569,10 +107868,13 @@
107569107868
if( pOuterNC ){
107570107869
assert( pItem->fg.isCorrelated==0 && pOuterNC->nRef>=nRef );
107571107870
pItem->fg.isCorrelated = (pOuterNC->nRef>nRef);
107572107871
}
107573107872
}
107873
+ }
107874
+ if( pOuterNC && ALWAYS(pOuterNC->nNestedSelect>0) ){
107875
+ pOuterNC->nNestedSelect--;
107574107876
}
107575107877
107576107878
/* Set up the local name-context to pass to sqlite3ResolveExprNames() to
107577107879
** resolve the result-set expression list.
107578107880
*/
@@ -109157,13 +109459,11 @@
109157109459
assert( pExpr->op==TK_FUNCTION );
109158109460
assert( pExpr->pLeft==0 );
109159109461
assert( ExprUseXList(pExpr) );
109160109462
if( pExpr->x.pList==0 || NEVER(pExpr->x.pList->nExpr==0) ){
109161109463
/* Ignore ORDER BY on zero-argument aggregates */
109162
- sqlite3ParserAddCleanup(pParse,
109163
- (void(*)(sqlite3*,void*))sqlite3ExprListDelete,
109164
- pOrderBy);
109464
+ sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, pOrderBy);
109165109465
return;
109166109466
}
109167109467
if( IsWindowFunc(pExpr) ){
109168109468
sqlite3ExprOrderByAggregateError(pParse, pExpr);
109169109469
sqlite3ExprListDelete(db, pOrderBy);
@@ -109340,10 +109640,13 @@
109340109640
}
109341109641
}
109342109642
SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
109343109643
if( p ) sqlite3ExprDeleteNN(db, p);
109344109644
}
109645
+SQLITE_PRIVATE void sqlite3ExprDeleteGeneric(sqlite3 *db, void *p){
109646
+ if( ALWAYS(p) ) sqlite3ExprDeleteNN(db, (Expr*)p);
109647
+}
109345109648
109346109649
/*
109347109650
** Clear both elements of an OnOrUsing object
109348109651
*/
109349109652
SQLITE_PRIVATE void sqlite3ClearOnOrUsing(sqlite3 *db, OnOrUsing *p){
@@ -109365,13 +109668,11 @@
109365109668
**
109366109669
** The deferred delete is (currently) implemented by adding the
109367109670
** pExpr to the pParse->pConstExpr list with a register number of 0.
109368109671
*/
109369109672
SQLITE_PRIVATE void sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){
109370
- sqlite3ParserAddCleanup(pParse,
109371
- (void(*)(sqlite3*,void*))sqlite3ExprDelete,
109372
- pExpr);
109673
+ sqlite3ParserAddCleanup(pParse, sqlite3ExprDeleteGeneric, pExpr);
109373109674
}
109374109675
109375109676
/* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the
109376109677
** expression.
109377109678
*/
@@ -110172,10 +110473,13 @@
110172110473
}while( --i>0 );
110173110474
sqlite3DbNNFreeNN(db, pList);
110174110475
}
110175110476
SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
110176110477
if( pList ) exprListDeleteNN(db, pList);
110478
+}
110479
+SQLITE_PRIVATE void sqlite3ExprListDeleteGeneric(sqlite3 *db, void *pList){
110480
+ if( ALWAYS(pList) ) exprListDeleteNN(db, (ExprList*)pList);
110177110481
}
110178110482
110179110483
/*
110180110484
** Return the bitwise-OR of all Expr.flags fields in the given
110181110485
** ExprList.
@@ -114703,17 +115007,18 @@
114703115007
return WRC_Continue;
114704115008
}
114705115009
case TK_AGG_FUNCTION: {
114706115010
if( (pNC->ncFlags & NC_InAggFunc)==0
114707115011
&& pWalker->walkerDepth==pExpr->op2
115012
+ && pExpr->pAggInfo==0
114708115013
){
114709115014
/* Check to see if pExpr is a duplicate of another aggregate
114710115015
** function that is already in the pAggInfo structure
114711115016
*/
114712115017
struct AggInfo_func *pItem = pAggInfo->aFunc;
114713115018
for(i=0; i<pAggInfo->nFunc; i++, pItem++){
114714
- if( pItem->pFExpr==pExpr ) break;
115019
+ if( NEVER(pItem->pFExpr==pExpr) ) break;
114715115020
if( sqlite3ExprCompare(0, pItem->pFExpr, pExpr, -1)==0 ){
114716115021
break;
114717115022
}
114718115023
}
114719115024
if( i>=pAggInfo->nFunc ){
@@ -114752,10 +115057,12 @@
114752115057
pItem->bOBPayload = 0;
114753115058
pItem->bOBUnique = ExprHasProperty(pExpr, EP_Distinct);
114754115059
}else{
114755115060
pItem->bOBPayload = 1;
114756115061
}
115062
+ pItem->bUseSubtype =
115063
+ (pItem->pFunc->funcFlags & SQLITE_SUBTYPE)!=0;
114757115064
}else{
114758115065
pItem->iOBTab = -1;
114759115066
}
114760115067
if( ExprHasProperty(pExpr, EP_Distinct) && !pItem->bOBUnique ){
114761115068
pItem->iDistinct = pParse->nTab++;
@@ -120856,11 +121163,11 @@
120856121163
** the DEFAULT clause or the AS clause of a generated column.
120857121164
** Return NULL if the column has no associated expression.
120858121165
*/
120859121166
SQLITE_PRIVATE Expr *sqlite3ColumnExpr(Table *pTab, Column *pCol){
120860121167
if( pCol->iDflt==0 ) return 0;
120861
- if( NEVER(!IsOrdinaryTable(pTab)) ) return 0;
121168
+ if( !IsOrdinaryTable(pTab) ) return 0;
120862121169
if( NEVER(pTab->u.tab.pDfltList==0) ) return 0;
120863121170
if( NEVER(pTab->u.tab.pDfltList->nExpr<pCol->iDflt) ) return 0;
120864121171
return pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr;
120865121172
}
120866121173
@@ -121008,10 +121315,13 @@
121008121315
/* Do not delete the table until the reference count reaches zero. */
121009121316
assert( db!=0 );
121010121317
if( !pTable ) return;
121011121318
if( db->pnBytesFreed==0 && (--pTable->nTabRef)>0 ) return;
121012121319
deleteTable(db, pTable);
121320
+}
121321
+SQLITE_PRIVATE void sqlite3DeleteTableGeneric(sqlite3 *db, void *pTable){
121322
+ sqlite3DeleteTable(db, (Table*)pTable);
121013121323
}
121014121324
121015121325
121016121326
/*
121017121327
** Unlink the given table from the hash tables and the delete the
@@ -121546,11 +121856,12 @@
121546121856
#endif
121547121857
121548121858
/*
121549121859
** Clean up the data structures associated with the RETURNING clause.
121550121860
*/
121551
-static void sqlite3DeleteReturning(sqlite3 *db, Returning *pRet){
121861
+static void sqlite3DeleteReturning(sqlite3 *db, void *pArg){
121862
+ Returning *pRet = (Returning*)pArg;
121552121863
Hash *pHash;
121553121864
pHash = &(db->aDb[1].pSchema->trigHash);
121554121865
sqlite3HashInsert(pHash, pRet->zName, 0);
121555121866
sqlite3ExprListDelete(db, pRet->pReturnEL);
121556121867
sqlite3DbFree(db, pRet);
@@ -121588,12 +121899,11 @@
121588121899
return;
121589121900
}
121590121901
pParse->u1.pReturning = pRet;
121591121902
pRet->pParse = pParse;
121592121903
pRet->pReturnEL = pList;
121593
- sqlite3ParserAddCleanup(pParse,
121594
- (void(*)(sqlite3*,void*))sqlite3DeleteReturning, pRet);
121904
+ sqlite3ParserAddCleanup(pParse, sqlite3DeleteReturning, pRet);
121595121905
testcase( pParse->earlyCleanup );
121596121906
if( db->mallocFailed ) return;
121597121907
sqlite3_snprintf(sizeof(pRet->zName), pRet->zName,
121598121908
"sqlite_returning_%p", pParse);
121599121909
pRet->retTrig.zName = pRet->zName;
@@ -125827,10 +126137,13 @@
125827126137
for(i=0; i<pWith->nCte; i++){
125828126138
cteClear(db, &pWith->a[i]);
125829126139
}
125830126140
sqlite3DbFree(db, pWith);
125831126141
}
126142
+}
126143
+SQLITE_PRIVATE void sqlite3WithDeleteGeneric(sqlite3 *db, void *pWith){
126144
+ sqlite3WithDelete(db, (With*)pWith);
125832126145
}
125833126146
#endif /* !defined(SQLITE_OMIT_CTE) */
125834126147
125835126148
/************** End of build.c ***********************************************/
125836126149
/************** Begin file callback.c ****************************************/
@@ -139053,11 +139366,12 @@
139053139366
if( NEVER(pVTab==0) ) continue;
139054139367
if( NEVER(pVTab->pModule==0) ) continue;
139055139368
if( pVTab->pModule->iVersion<4 ) continue;
139056139369
if( pVTab->pModule->xIntegrity==0 ) continue;
139057139370
sqlite3VdbeAddOp3(v, OP_VCheck, i, 3, isQuick);
139058
- sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
139371
+ pTab->nTabRef++;
139372
+ sqlite3VdbeAppendP4(v, pTab, P4_TABLEREF);
139059139373
a1 = sqlite3VdbeAddOp1(v, OP_IsNull, 3); VdbeCoverage(v);
139060139374
integrityCheckResultRow(v);
139061139375
sqlite3VdbeJumpHere(v, a1);
139062139376
#endif
139063139377
continue;
@@ -141080,10 +141394,11 @@
141080141394
sqlite3BtreeLeaveAll(db);
141081141395
rc = sqlite3ApiExit(db, rc);
141082141396
assert( (rc&db->errMask)==rc );
141083141397
db->busyHandler.nBusy = 0;
141084141398
sqlite3_mutex_leave(db->mutex);
141399
+ assert( rc==SQLITE_OK || (*ppStmt)==0 );
141085141400
return rc;
141086141401
}
141087141402
141088141403
141089141404
/*
@@ -141476,10 +141791,13 @@
141476141791
/*
141477141792
** Delete the given Select structure and all of its substructures.
141478141793
*/
141479141794
SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){
141480141795
if( OK_IF_ALWAYS_TRUE(p) ) clearSelect(db, p, 1);
141796
+}
141797
+SQLITE_PRIVATE void sqlite3SelectDeleteGeneric(sqlite3 *db, void *p){
141798
+ if( ALWAYS(p) ) clearSelect(db, (Select*)p, 1);
141481141799
}
141482141800
141483141801
/*
141484141802
** Return a pointer to the right-most SELECT statement in a compound.
141485141803
*/
@@ -144497,13 +144815,11 @@
144497144815
144498144816
multi_select_end:
144499144817
pDest->iSdst = dest.iSdst;
144500144818
pDest->nSdst = dest.nSdst;
144501144819
if( pDelete ){
144502
- sqlite3ParserAddCleanup(pParse,
144503
- (void(*)(sqlite3*,void*))sqlite3SelectDelete,
144504
- pDelete);
144820
+ sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pDelete);
144505144821
}
144506144822
return rc;
144507144823
}
144508144824
#endif /* SQLITE_OMIT_COMPOUND_SELECT */
144509144825
@@ -145050,12 +145366,11 @@
145050145366
sqlite3VdbeResolveLabel(v, labelEnd);
145051145367
145052145368
/* Make arrangements to free the 2nd and subsequent arms of the compound
145053145369
** after the parse has finished */
145054145370
if( pSplit->pPrior ){
145055
- sqlite3ParserAddCleanup(pParse,
145056
- (void(*)(sqlite3*,void*))sqlite3SelectDelete, pSplit->pPrior);
145371
+ sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pSplit->pPrior);
145057145372
}
145058145373
pSplit->pPrior = pPrior;
145059145374
pPrior->pNext = pSplit;
145060145375
sqlite3ExprListDelete(db, pPrior->pOrderBy);
145061145376
pPrior->pOrderBy = 0;
@@ -145872,13 +146187,11 @@
145872146187
*/
145873146188
if( ALWAYS(pSubitem->pTab!=0) ){
145874146189
Table *pTabToDel = pSubitem->pTab;
145875146190
if( pTabToDel->nTabRef==1 ){
145876146191
Parse *pToplevel = sqlite3ParseToplevel(pParse);
145877
- sqlite3ParserAddCleanup(pToplevel,
145878
- (void(*)(sqlite3*,void*))sqlite3DeleteTable,
145879
- pTabToDel);
146192
+ sqlite3ParserAddCleanup(pToplevel, sqlite3DeleteTableGeneric, pTabToDel);
145880146193
testcase( pToplevel->earlyCleanup );
145881146194
}else{
145882146195
pTabToDel->nTabRef--;
145883146196
}
145884146197
pSubitem->pTab = 0;
@@ -146921,12 +147234,11 @@
146921147234
** calling this routine, Instead, use only the return value.
146922147235
*/
146923147236
SQLITE_PRIVATE With *sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){
146924147237
if( pWith ){
146925147238
if( bFree ){
146926
- pWith = (With*)sqlite3ParserAddCleanup(pParse,
146927
- (void(*)(sqlite3*,void*))sqlite3WithDelete,
147239
+ pWith = (With*)sqlite3ParserAddCleanup(pParse, sqlite3WithDeleteGeneric,
146928147240
pWith);
146929147241
if( pWith==0 ) return 0;
146930147242
}
146931147243
if( pParse->nErr==0 ){
146932147244
assert( pParse->pWith!=pWith );
@@ -147955,19 +148267,23 @@
147955148267
KeyInfo *pKeyInfo;
147956148268
int nExtra = 0;
147957148269
assert( pFunc->pFExpr->pLeft!=0 );
147958148270
assert( pFunc->pFExpr->pLeft->op==TK_ORDER );
147959148271
assert( ExprUseXList(pFunc->pFExpr->pLeft) );
148272
+ assert( pFunc->pFunc!=0 );
147960148273
pOBList = pFunc->pFExpr->pLeft->x.pList;
147961148274
if( !pFunc->bOBUnique ){
147962148275
nExtra++; /* One extra column for the OP_Sequence */
147963148276
}
147964148277
if( pFunc->bOBPayload ){
147965148278
/* extra columns for the function arguments */
147966148279
assert( ExprUseXList(pFunc->pFExpr) );
147967148280
nExtra += pFunc->pFExpr->x.pList->nExpr;
147968148281
}
148282
+ if( pFunc->bUseSubtype ){
148283
+ nExtra += pFunc->pFExpr->x.pList->nExpr;
148284
+ }
147969148285
pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOBList, 0, nExtra);
147970148286
if( !pFunc->bOBUnique && pParse->nErr==0 ){
147971148287
pKeyInfo->nKeyField++;
147972148288
}
147973148289
sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
@@ -147990,20 +148306,21 @@
147990148306
for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
147991148307
ExprList *pList;
147992148308
assert( ExprUseXList(pF->pFExpr) );
147993148309
pList = pF->pFExpr->x.pList;
147994148310
if( pF->iOBTab>=0 ){
147995
- /* For an ORDER BY aggregate, calls to OP_AggStep where deferred and
147996
- ** all content was stored in emphermal table pF->iOBTab. Extract that
147997
- ** content now (in ORDER BY order) and make all calls to OP_AggStep
148311
+ /* For an ORDER BY aggregate, calls to OP_AggStep were deferred. Inputs
148312
+ ** were stored in emphermal table pF->iOBTab. Here, we extract those
148313
+ ** inputs (in ORDER BY order) and make all calls to OP_AggStep
147998148314
** before doing the OP_AggFinal call. */
147999148315
int iTop; /* Start of loop for extracting columns */
148000148316
int nArg; /* Number of columns to extract */
148001148317
int nKey; /* Key columns to be skipped */
148002148318
int regAgg; /* Extract into this array */
148003148319
int j; /* Loop counter */
148004148320
148321
+ assert( pF->pFunc!=0 );
148005148322
nArg = pList->nExpr;
148006148323
regAgg = sqlite3GetTempRange(pParse, nArg);
148007148324
148008148325
if( pF->bOBPayload==0 ){
148009148326
nKey = 0;
@@ -148016,10 +148333,19 @@
148016148333
}
148017148334
iTop = sqlite3VdbeAddOp1(v, OP_Rewind, pF->iOBTab); VdbeCoverage(v);
148018148335
for(j=nArg-1; j>=0; j--){
148019148336
sqlite3VdbeAddOp3(v, OP_Column, pF->iOBTab, nKey+j, regAgg+j);
148020148337
}
148338
+ if( pF->bUseSubtype ){
148339
+ int regSubtype = sqlite3GetTempReg(pParse);
148340
+ int iBaseCol = nKey + nArg + (pF->bOBPayload==0 && pF->bOBUnique==0);
148341
+ for(j=nArg-1; j>=0; j--){
148342
+ sqlite3VdbeAddOp3(v, OP_Column, pF->iOBTab, iBaseCol+j, regSubtype);
148343
+ sqlite3VdbeAddOp2(v, OP_SetSubtype, regSubtype, regAgg+j);
148344
+ }
148345
+ sqlite3ReleaseTempReg(pParse, regSubtype);
148346
+ }
148021148347
sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i));
148022148348
sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
148023148349
sqlite3VdbeChangeP5(v, (u8)nArg);
148024148350
sqlite3VdbeAddOp2(v, OP_Next, pF->iOBTab, iTop+1); VdbeCoverage(v);
148025148351
sqlite3VdbeJumpHere(v, iTop);
@@ -148070,10 +148396,11 @@
148070148396
int regAggSz = 0;
148071148397
int regDistinct = 0;
148072148398
ExprList *pList;
148073148399
assert( ExprUseXList(pF->pFExpr) );
148074148400
assert( !IsWindowFunc(pF->pFExpr) );
148401
+ assert( pF->pFunc!=0 );
148075148402
pList = pF->pFExpr->x.pList;
148076148403
if( ExprHasProperty(pF->pFExpr, EP_WinFunc) ){
148077148404
Expr *pFilter = pF->pFExpr->y.pWin->pFilter;
148078148405
if( pAggInfo->nAccumulator
148079148406
&& (pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)
@@ -148113,10 +148440,13 @@
148113148440
if( !pF->bOBUnique ){
148114148441
regAggSz++; /* One register for OP_Sequence */
148115148442
}
148116148443
if( pF->bOBPayload ){
148117148444
regAggSz += nArg;
148445
+ }
148446
+ if( pF->bUseSubtype ){
148447
+ regAggSz += nArg;
148118148448
}
148119148449
regAggSz++; /* One extra register to hold result of MakeRecord */
148120148450
regAgg = sqlite3GetTempRange(pParse, regAggSz);
148121148451
regDistinct = regAgg;
148122148452
sqlite3ExprCodeExprList(pParse, pOBList, regAgg, 0, SQLITE_ECEL_DUP);
@@ -148126,10 +148456,18 @@
148126148456
jj++;
148127148457
}
148128148458
if( pF->bOBPayload ){
148129148459
regDistinct = regAgg+jj;
148130148460
sqlite3ExprCodeExprList(pParse, pList, regDistinct, 0, SQLITE_ECEL_DUP);
148461
+ jj += nArg;
148462
+ }
148463
+ if( pF->bUseSubtype ){
148464
+ int kk;
148465
+ int regBase = pF->bOBPayload ? regDistinct : regAgg;
148466
+ for(kk=0; kk<nArg; kk++, jj++){
148467
+ sqlite3VdbeAddOp2(v, OP_GetSubtype, regBase+kk, regAgg+jj);
148468
+ }
148131148469
}
148132148470
}else if( pList ){
148133148471
nArg = pList->nExpr;
148134148472
regAgg = sqlite3GetTempRange(pParse, nArg);
148135148473
regDistinct = regAgg;
@@ -148330,11 +148668,12 @@
148330148668
}
148331148669
148332148670
/*
148333148671
** Deallocate a single AggInfo object
148334148672
*/
148335
-static void agginfoFree(sqlite3 *db, AggInfo *p){
148673
+static void agginfoFree(sqlite3 *db, void *pArg){
148674
+ AggInfo *p = (AggInfo*)pArg;
148336148675
sqlite3DbFree(db, p->aCol);
148337148676
sqlite3DbFree(db, p->aFunc);
148338148677
sqlite3DbFreeNN(db, p);
148339148678
}
148340148679
@@ -148584,13 +148923,12 @@
148584148923
TREETRACE(0x800,pParse,p, ("dropping superfluous ORDER BY:\n"));
148585148924
if( sqlite3TreeTrace & 0x800 ){
148586148925
sqlite3TreeViewExprList(0, p->pOrderBy, 0, "ORDERBY");
148587148926
}
148588148927
#endif
148589
- sqlite3ParserAddCleanup(pParse,
148590
- (void(*)(sqlite3*,void*))sqlite3ExprListDelete,
148591
- p->pOrderBy);
148928
+ sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric,
148929
+ p->pOrderBy);
148592148930
testcase( pParse->earlyCleanup );
148593148931
p->pOrderBy = 0;
148594148932
}
148595148933
p->selFlags &= ~SF_Distinct;
148596148934
p->selFlags |= SF_NoopOrderBy;
@@ -148778,13 +149116,12 @@
148778149116
&& (p->selFlags & SF_OrderByReqd)==0 /* Condition (3) and (4) */
148779149117
&& OptimizationEnabled(db, SQLITE_OmitOrderBy)
148780149118
){
148781149119
TREETRACE(0x800,pParse,p,
148782149120
("omit superfluous ORDER BY on %r FROM-clause subquery\n",i+1));
148783
- sqlite3ParserAddCleanup(pParse,
148784
- (void(*)(sqlite3*,void*))sqlite3ExprListDelete,
148785
- pSub->pOrderBy);
149121
+ sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric,
149122
+ pSub->pOrderBy);
148786149123
pSub->pOrderBy = 0;
148787149124
}
148788149125
148789149126
/* If the outer query contains a "complex" result set (that is,
148790149127
** if the result set of the outer query uses functions or subqueries)
@@ -149309,12 +149646,11 @@
149309149646
** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the
149310149647
** SELECT statement.
149311149648
*/
149312149649
pAggInfo = sqlite3DbMallocZero(db, sizeof(*pAggInfo) );
149313149650
if( pAggInfo ){
149314
- sqlite3ParserAddCleanup(pParse,
149315
- (void(*)(sqlite3*,void*))agginfoFree, pAggInfo);
149651
+ sqlite3ParserAddCleanup(pParse, agginfoFree, pAggInfo);
149316149652
testcase( pParse->earlyCleanup );
149317149653
}
149318149654
if( db->mallocFailed ){
149319149655
goto select_end;
149320149656
}
@@ -160987,16 +161323,26 @@
160987161323
int iEnd = sqlite3VdbeCurrentAddr(v);
160988161324
if( pParse->db->mallocFailed ) return;
160989161325
for(; iStart<iEnd; iStart++, pOp++){
160990161326
if( pOp->p1!=iTabCur ) continue;
160991161327
if( pOp->opcode==OP_Column ){
161328
+#ifdef SQLITE_DEBUG
161329
+ if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
161330
+ printf("TRANSLATE OP_Column to OP_Copy at %d\n", iStart);
161331
+ }
161332
+#endif
160992161333
pOp->opcode = OP_Copy;
160993161334
pOp->p1 = pOp->p2 + iRegister;
160994161335
pOp->p2 = pOp->p3;
160995161336
pOp->p3 = 0;
160996161337
pOp->p5 = 2; /* Cause the MEM_Subtype flag to be cleared */
160997161338
}else if( pOp->opcode==OP_Rowid ){
161339
+#ifdef SQLITE_DEBUG
161340
+ if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
161341
+ printf("TRANSLATE OP_Rowid to OP_Sequence at %d\n", iStart);
161342
+ }
161343
+#endif
160998161344
pOp->opcode = OP_Sequence;
160999161345
pOp->p1 = iAutoidxCur;
161000161346
#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
161001161347
if( iAutoidxCur==0 ){
161002161348
pOp->opcode = OP_Null;
@@ -162319,11 +162665,12 @@
162319162665
nNew = sqlite3LogEst(iUpper - iLower);
162320162666
/* TUNING: If both iUpper and iLower are derived from the same
162321162667
** sample, then assume they are 4x more selective. This brings
162322162668
** the estimated selectivity more in line with what it would be
162323162669
** if estimated without the use of STAT4 tables. */
162324
- if( iLwrIdx==iUprIdx ) nNew -= 20; assert( 20==sqlite3LogEst(4) );
162670
+ if( iLwrIdx==iUprIdx ){ nNew -= 20; }
162671
+ assert( 20==sqlite3LogEst(4) );
162325162672
}else{
162326162673
nNew = 10; assert( 10==sqlite3LogEst(2) );
162327162674
}
162328162675
if( nNew<nOut ){
162329162676
nOut = nNew;
@@ -182234,10 +182581,32 @@
182234182581
rc = SQLITE_NOTFOUND;
182235182582
}
182236182583
break;
182237182584
}
182238182585
#endif
182586
+
182587
+ /* sqlite3_test_control(SQLITE_TESTCTRL_JSON_SELFCHECK, &onOff);
182588
+ **
182589
+ ** Activate or deactivate validation of JSONB that is generated from
182590
+ ** text. Off by default, as the validation is slow. Validation is
182591
+ ** only available if compiled using SQLITE_DEBUG.
182592
+ **
182593
+ ** If onOff is initially 1, then turn it on. If onOff is initially
182594
+ ** off, turn it off. If onOff is initially -1, then change onOff
182595
+ ** to be the current setting.
182596
+ */
182597
+ case SQLITE_TESTCTRL_JSON_SELFCHECK: {
182598
+#if defined(SQLITE_DEBUG)
182599
+ int *pOnOff = va_arg(ap, int*);
182600
+ if( *pOnOff<0 ){
182601
+ *pOnOff = sqlite3Config.bJsonSelfcheck;
182602
+ }else{
182603
+ sqlite3Config.bJsonSelfcheck = (u8)((*pOnOff)&0xff);
182604
+ }
182605
+#endif
182606
+ break;
182607
+ }
182239182608
}
182240182609
va_end(ap);
182241182610
#endif /* SQLITE_UNTESTABLE */
182242182611
return rc;
182243182612
}
@@ -202648,28 +203017,146 @@
202648203017
** May you find forgiveness for yourself and forgive others.
202649203018
** May you share freely, never taking more than you give.
202650203019
**
202651203020
******************************************************************************
202652203021
**
202653
-** This SQLite JSON functions.
203022
+** SQLite JSON functions.
202654203023
**
202655203024
** This file began as an extension in ext/misc/json1.c in 2015. That
202656203025
** extension proved so useful that it has now been moved into the core.
202657203026
**
202658
-** For the time being, all JSON is stored as pure text. (We might add
202659
-** a JSONB type in the future which stores a binary encoding of JSON in
202660
-** a BLOB, but there is no support for JSONB in the current implementation.
202661
-** This implementation parses JSON text at 250 MB/s, so it is hard to see
202662
-** how JSONB might improve on that.)
203027
+** The original design stored all JSON as pure text, canonical RFC-8259.
203028
+** Support for JSON-5 extensions was added with version 3.42.0 (2023-05-16).
203029
+** All generated JSON text still conforms strictly to RFC-8259, but text
203030
+** with JSON-5 extensions is accepted as input.
203031
+**
203032
+** Beginning with version 3.45.0 (pending), these routines also accept
203033
+** BLOB values that have JSON encoded using a binary representation we
203034
+** call JSONB. The name JSONB comes from PostgreSQL, however the on-disk
203035
+** format SQLite JSONB is completely different and incompatible with
203036
+** PostgreSQL JSONB.
203037
+**
203038
+** Decoding and interpreting JSONB is still O(N) where N is the size of
203039
+** the input, the same as text JSON. However, the constant of proportionality
203040
+** for JSONB is much smaller due to faster parsing. The size of each
203041
+** element in JSONB is encoded in its header, so there is no need to search
203042
+** for delimiters using persnickety syntax rules. JSONB seems to be about
203043
+** 3x faster than text JSON as a result. JSONB is also tends to be slightly
203044
+** smaller than text JSON, by 5% or 10%, but there are corner cases where
203045
+** JSONB can be slightly larger. So you are not far mistaken to say that
203046
+** a JSONB blob is the same size as the equivalent RFC-8259 text.
203047
+**
203048
+**
203049
+** THE JSONB ENCODING:
203050
+**
203051
+** Every JSON element is encoded in JSONB as a header and a payload.
203052
+** The header is between 1 and 9 bytes in size. The payload is zero
203053
+** or more bytes.
203054
+**
203055
+** The lower 4 bits of the first byte of the header determines the
203056
+** element type:
203057
+**
203058
+** 0: NULL
203059
+** 1: TRUE
203060
+** 2: FALSE
203061
+** 3: INT -- RFC-8259 integer literal
203062
+** 4: INT5 -- JSON5 integer literal
203063
+** 5: FLOAT -- RFC-8259 floating point literal
203064
+** 6: FLOAT5 -- JSON5 floating point literal
203065
+** 7: TEXT -- Text literal acceptable to both SQL and JSON
203066
+** 8: TEXTJ -- Text containing RFC-8259 escapes
203067
+** 9: TEXT5 -- Text containing JSON5 and/or RFC-8259 escapes
203068
+** 10: TEXTRAW -- Text containing unescaped syntax characters
203069
+** 11: ARRAY
203070
+** 12: OBJECT
203071
+**
203072
+** The other three possible values (13-15) are reserved for future
203073
+** enhancements.
203074
+**
203075
+** The upper 4 bits of the first byte determine the size of the header
203076
+** and sometimes also the size of the payload. If X is the first byte
203077
+** of the element and if X>>4 is between 0 and 11, then the payload
203078
+** will be that many bytes in size and the header is exactly one byte
203079
+** in size. Other four values for X>>4 (12-15) indicate that the header
203080
+** is more than one byte in size and that the payload size is determined
203081
+** by the remainder of the header, interpreted as a unsigned big-endian
203082
+** integer.
203083
+**
203084
+** Value of X>>4 Size integer Total header size
203085
+** ------------- -------------------- -----------------
203086
+** 12 1 byte (0-255) 2
203087
+** 13 2 byte (0-65535) 3
203088
+** 14 4 byte (0-4294967295) 5
203089
+** 15 8 byte (0-1.8e19) 9
203090
+**
203091
+** The payload size need not be expressed in its minimal form. For example,
203092
+** if the payload size is 10, the size can be expressed in any of 5 different
203093
+** ways: (1) (X>>4)==10, (2) (X>>4)==12 following by on 0x0a byte,
203094
+** (3) (X>>4)==13 followed by 0x00 and 0x0a, (4) (X>>4)==14 followed by
203095
+** 0x00 0x00 0x00 0x0a, or (5) (X>>4)==15 followed by 7 bytes of 0x00 and
203096
+** a single byte of 0x0a. The shorter forms are preferred, of course, but
203097
+** sometimes when generating JSONB, the payload size is not known in advance
203098
+** and it is convenient to reserve sufficient header space to cover the
203099
+** largest possible payload size and then come back later and patch up
203100
+** the size when it becomes known, resulting in a non-minimal encoding.
203101
+**
203102
+** The value (X>>4)==15 is not actually used in the current implementation
203103
+** (as SQLite is currently unable handle BLOBs larger than about 2GB)
203104
+** but is included in the design to allow for future enhancements.
203105
+**
203106
+** The payload follows the header. NULL, TRUE, and FALSE have no payload and
203107
+** their payload size must always be zero. The payload for INT, INT5,
203108
+** FLOAT, FLOAT5, TEXT, TEXTJ, TEXT5, and TEXTROW is text. Note that the
203109
+** "..." or '...' delimiters are omitted from the various text encodings.
203110
+** The payload for ARRAY and OBJECT is a list of additional elements that
203111
+** are the content for the array or object. The payload for an OBJECT
203112
+** must be an even number of elements. The first element of each pair is
203113
+** the label and must be of type TEXT, TEXTJ, TEXT5, or TEXTRAW.
203114
+**
203115
+** A valid JSONB blob consists of a single element, as described above.
203116
+** Usually this will be an ARRAY or OBJECT element which has many more
203117
+** elements as its content. But the overall blob is just a single element.
203118
+**
203119
+** Input validation for JSONB blobs simply checks that the element type
203120
+** code is between 0 and 12 and that the total size of the element
203121
+** (header plus payload) is the same as the size of the BLOB. If those
203122
+** checks are true, the BLOB is assumed to be JSONB and processing continues.
203123
+** Errors are only raised if some other miscoding is discovered during
203124
+** processing.
202663203125
*/
202664203126
#ifndef SQLITE_OMIT_JSON
202665203127
/* #include "sqliteInt.h" */
202666203128
203129
+/* JSONB element types
203130
+*/
203131
+#define JSONB_NULL 0 /* "null" */
203132
+#define JSONB_TRUE 1 /* "true" */
203133
+#define JSONB_FALSE 2 /* "false" */
203134
+#define JSONB_INT 3 /* integer acceptable to JSON and SQL */
203135
+#define JSONB_INT5 4 /* integer in 0x000 notation */
203136
+#define JSONB_FLOAT 5 /* float acceptable to JSON and SQL */
203137
+#define JSONB_FLOAT5 6 /* float with JSON5 extensions */
203138
+#define JSONB_TEXT 7 /* Text compatible with both JSON and SQL */
203139
+#define JSONB_TEXTJ 8 /* Text with JSON escapes */
203140
+#define JSONB_TEXT5 9 /* Text with JSON-5 escape */
203141
+#define JSONB_TEXTRAW 10 /* SQL text that needs escaping for JSON */
203142
+#define JSONB_ARRAY 11 /* An array */
203143
+#define JSONB_OBJECT 12 /* An object */
203144
+
203145
+/* Human-readable names for the JSONB values. The index for each
203146
+** string must correspond to the JSONB_* integer above.
203147
+*/
203148
+static const char * const jsonbType[] = {
203149
+ "null", "true", "false", "integer", "integer",
203150
+ "real", "real", "text", "text", "text",
203151
+ "text", "array", "object", "", "", "", ""
203152
+};
203153
+
202667203154
/*
202668203155
** Growing our own isspace() routine this way is twice as fast as
202669203156
** the library isspace() function, resulting in a 7% overall performance
202670
-** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os).
203157
+** increase for the text-JSON parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os).
202671203158
*/
202672203159
static const char jsonIsSpace[] = {
202673203160
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
202674203161
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
202675203162
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -202686,15 +203173,23 @@
202686203173
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
202687203174
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
202688203175
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
202689203176
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
202690203177
};
202691
-#define fast_isspace(x) (jsonIsSpace[(unsigned char)x])
203178
+#define jsonIsspace(x) (jsonIsSpace[(unsigned char)x])
202692203179
202693203180
/*
202694
-** Characters that are special to JSON. Control charaters,
202695
-** '"' and '\\'.
203181
+** The set of all space characters recognized by jsonIsspace().
203182
+** Useful as the second argument to strspn().
203183
+*/
203184
+static const char jsonSpaces[] = "\011\012\015\040";
203185
+
203186
+/*
203187
+** Characters that are special to JSON. Control characters,
203188
+** '"' and '\\' and '\''. Actually, '\'' is not special to
203189
+** canonical JSON, but it is special in JSON-5, so we include
203190
+** it in the set of special characters.
202696203191
*/
202697203192
static const char jsonIsOk[256] = {
202698203193
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
202699203194
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
202700203195
1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -202712,247 +203207,353 @@
202712203207
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
202713203208
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
202714203209
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
202715203210
};
202716203211
202717
-
202718
-#if !defined(SQLITE_DEBUG) && !defined(SQLITE_COVERAGE_TEST)
202719
-# define VVA(X)
202720
-#else
202721
-# define VVA(X) X
202722
-#endif
202723
-
202724203212
/* Objects */
203213
+typedef struct JsonCache JsonCache;
202725203214
typedef struct JsonString JsonString;
202726
-typedef struct JsonNode JsonNode;
202727203215
typedef struct JsonParse JsonParse;
202728
-typedef struct JsonCleanup JsonCleanup;
203216
+
203217
+/*
203218
+** Magic number used for the JSON parse cache in sqlite3_get_auxdata()
203219
+*/
203220
+#define JSON_CACHE_ID (-429938) /* Cache entry */
203221
+#define JSON_CACHE_SIZE 4 /* Max number of cache entries */
203222
+
203223
+/* A cache mapping JSON text into JSONB blobs.
203224
+**
203225
+** Each cache entry is a JsonParse object with the following restrictions:
203226
+**
203227
+** * The bReadOnly flag must be set
203228
+**
203229
+** * The aBlob[] array must be owned by the JsonParse object. In other
203230
+** words, nBlobAlloc must be non-zero.
203231
+**
203232
+** * zJson must be an RCStr. In other words bJsonIsRCStr must be true.
203233
+*/
203234
+struct JsonCache {
203235
+ sqlite3 *db; /* Database connection */
203236
+ int nUsed; /* Number of active entries in the cache */
203237
+ JsonParse *a[JSON_CACHE_SIZE]; /* One line for each cache entry */
203238
+};
202729203239
202730203240
/* An instance of this object represents a JSON string
202731203241
** under construction. Really, this is a generic string accumulator
202732203242
** that can be and is used to create strings other than JSON.
203243
+**
203244
+** If the generated string is longer than will fit into the zSpace[] buffer,
203245
+** then it will be an RCStr string. This aids with caching of large
203246
+** JSON strings.
202733203247
*/
202734203248
struct JsonString {
202735203249
sqlite3_context *pCtx; /* Function context - put error messages here */
202736203250
char *zBuf; /* Append JSON content here */
202737203251
u64 nAlloc; /* Bytes of storage available in zBuf[] */
202738203252
u64 nUsed; /* Bytes of zBuf[] currently used */
202739203253
u8 bStatic; /* True if zBuf is static space */
202740
- u8 bErr; /* True if an error has been encountered */
203254
+ u8 eErr; /* True if an error has been encountered */
202741203255
char zSpace[100]; /* Initial static space */
202742203256
};
202743203257
202744
-/* A deferred cleanup task. A list of JsonCleanup objects might be
202745
-** run when the JsonParse object is destroyed.
202746
-*/
202747
-struct JsonCleanup {
202748
- JsonCleanup *pJCNext; /* Next in a list */
202749
- void (*xOp)(void*); /* Routine to run */
202750
- void *pArg; /* Argument to xOp() */
202751
-};
202752
-
202753
-/* JSON type values
202754
-*/
202755
-#define JSON_SUBST 0 /* Special edit node. Uses u.iPrev */
202756
-#define JSON_NULL 1
202757
-#define JSON_TRUE 2
202758
-#define JSON_FALSE 3
202759
-#define JSON_INT 4
202760
-#define JSON_REAL 5
202761
-#define JSON_STRING 6
202762
-#define JSON_ARRAY 7
202763
-#define JSON_OBJECT 8
202764
-
202765
-/* The "subtype" set for JSON values */
203258
+/* Allowed values for JsonString.eErr */
203259
+#define JSTRING_OOM 0x01 /* Out of memory */
203260
+#define JSTRING_MALFORMED 0x02 /* Malformed JSONB */
203261
+#define JSTRING_ERR 0x04 /* Error already sent to sqlite3_result */
203262
+
203263
+/* The "subtype" set for text JSON values passed through using
203264
+** sqlite3_result_subtype() and sqlite3_value_subtype().
203265
+*/
202766203266
#define JSON_SUBTYPE 74 /* Ascii for "J" */
202767203267
202768203268
/*
202769
-** Names of the various JSON types:
202770
-*/
202771
-static const char * const jsonType[] = {
202772
- "subst",
202773
- "null", "true", "false", "integer", "real", "text", "array", "object"
202774
-};
202775
-
202776
-/* Bit values for the JsonNode.jnFlag field
202777
-*/
202778
-#define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */
202779
-#define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */
202780
-#define JNODE_REMOVE 0x04 /* Do not output */
202781
-#define JNODE_REPLACE 0x08 /* Target of a JSON_SUBST node */
202782
-#define JNODE_APPEND 0x10 /* More ARRAY/OBJECT entries at u.iAppend */
202783
-#define JNODE_LABEL 0x20 /* Is a label of an object */
202784
-#define JNODE_JSON5 0x40 /* Node contains JSON5 enhancements */
202785
-
202786
-
202787
-/* A single node of parsed JSON. An array of these nodes describes
202788
-** a parse of JSON + edits.
202789
-**
202790
-** Use the json_parse() SQL function (available when compiled with
202791
-** -DSQLITE_DEBUG) to see a dump of complete JsonParse objects, including
202792
-** a complete listing and decoding of the array of JsonNodes.
202793
-*/
202794
-struct JsonNode {
202795
- u8 eType; /* One of the JSON_ type values */
202796
- u8 jnFlags; /* JNODE flags */
202797
- u8 eU; /* Which union element to use */
202798
- u32 n; /* Bytes of content for INT, REAL or STRING
202799
- ** Number of sub-nodes for ARRAY and OBJECT
202800
- ** Node that SUBST applies to */
202801
- union {
202802
- const char *zJContent; /* 1: Content for INT, REAL, and STRING */
202803
- u32 iAppend; /* 2: More terms for ARRAY and OBJECT */
202804
- u32 iKey; /* 3: Key for ARRAY objects in json_tree() */
202805
- u32 iPrev; /* 4: Previous SUBST node, or 0 */
202806
- } u;
202807
-};
202808
-
202809
-
202810
-/* A parsed and possibly edited JSON string. Lifecycle:
202811
-**
202812
-** 1. JSON comes in and is parsed into an array aNode[]. The original
202813
-** JSON text is stored in zJson.
202814
-**
202815
-** 2. Zero or more changes are made (via json_remove() or json_replace()
202816
-** or similar) to the aNode[] array.
202817
-**
202818
-** 3. A new, edited and mimified JSON string is generated from aNode
202819
-** and stored in zAlt. The JsonParse object always owns zAlt.
202820
-**
202821
-** Step 1 always happens. Step 2 and 3 may or may not happen, depending
202822
-** on the operation.
202823
-**
202824
-** aNode[].u.zJContent entries typically point into zJson. Hence zJson
202825
-** must remain valid for the lifespan of the parse. For edits,
202826
-** aNode[].u.zJContent might point to malloced space other than zJson.
202827
-** Entries in pClup are responsible for freeing that extra malloced space.
202828
-**
202829
-** When walking the parse tree in aNode[], edits are ignored if useMod is
202830
-** false.
203269
+** Bit values for the flags passed into various SQL function implementations
203270
+** via the sqlite3_user_data() value.
203271
+*/
203272
+#define JSON_JSON 0x01 /* Result is always JSON */
203273
+#define JSON_SQL 0x02 /* Result is always SQL */
203274
+#define JSON_ABPATH 0x03 /* Allow abbreviated JSON path specs */
203275
+#define JSON_ISSET 0x04 /* json_set(), not json_insert() */
203276
+#define JSON_BLOB 0x08 /* Use the BLOB output format */
203277
+
203278
+
203279
+/* A parsed JSON value. Lifecycle:
203280
+**
203281
+** 1. JSON comes in and is parsed into a JSONB value in aBlob. The
203282
+** original text is stored in zJson. This step is skipped if the
203283
+** input is JSONB instead of text JSON.
203284
+**
203285
+** 2. The aBlob[] array is searched using the JSON path notation, if needed.
203286
+**
203287
+** 3. Zero or more changes are made to aBlob[] (via json_remove() or
203288
+** json_replace() or json_patch() or similar).
203289
+**
203290
+** 4. New JSON text is generated from the aBlob[] for output. This step
203291
+** is skipped the function is one of the jsonb_* functions that returns
203292
+** JSONB instead of text JSON.
202831203293
*/
202832203294
struct JsonParse {
202833
- u32 nNode; /* Number of slots of aNode[] used */
202834
- u32 nAlloc; /* Number of slots of aNode[] allocated */
202835
- JsonNode *aNode; /* Array of nodes containing the parse */
202836
- char *zJson; /* Original JSON string (before edits) */
202837
- char *zAlt; /* Revised and/or mimified JSON */
202838
- u32 *aUp; /* Index of parent of each node */
202839
- JsonCleanup *pClup;/* Cleanup operations prior to freeing this object */
203295
+ u8 *aBlob; /* JSONB representation of JSON value */
203296
+ u32 nBlob; /* Bytes of aBlob[] actually used */
203297
+ u32 nBlobAlloc; /* Bytes allocated to aBlob[]. 0 if aBlob is external */
203298
+ char *zJson; /* Json text used for parsing */
203299
+ int nJson; /* Length of the zJson string in bytes */
202840203300
u16 iDepth; /* Nesting depth */
202841203301
u8 nErr; /* Number of errors seen */
202842203302
u8 oom; /* Set to true if out of memory */
202843203303
u8 bJsonIsRCStr; /* True if zJson is an RCStr */
202844203304
u8 hasNonstd; /* True if input uses non-standard features like JSON5 */
202845
- u8 useMod; /* Actually use the edits contain inside aNode */
202846
- u8 hasMod; /* aNode contains edits from the original zJson */
203305
+ u8 bReadOnly; /* Do not modify. */
202847203306
u32 nJPRef; /* Number of references to this object */
202848
- int nJson; /* Length of the zJson string in bytes */
202849
- int nAlt; /* Length of alternative JSON string zAlt, in bytes */
202850203307
u32 iErr; /* Error location in zJson[] */
202851
- u32 iSubst; /* Last JSON_SUBST entry in aNode[] */
202852
- u32 iHold; /* Age of this entry in the cache for LRU replacement */
203308
+ /* Search and edit information. See jsonLookupStep() */
203309
+ u8 eEdit; /* Edit operation to apply */
203310
+ int delta; /* Size change due to the edit */
203311
+ u32 nIns; /* Number of bytes to insert */
203312
+ u32 iLabel; /* Location of label if search landed on an object value */
203313
+ u8 *aIns; /* Content to be inserted */
202853203314
};
202854203315
203316
+/* Allowed values for JsonParse.eEdit */
203317
+#define JEDIT_DEL 1 /* Delete if exists */
203318
+#define JEDIT_REPL 2 /* Overwrite if exists */
203319
+#define JEDIT_INS 3 /* Insert if not exists */
203320
+#define JEDIT_SET 4 /* Insert or overwrite */
203321
+
202855203322
/*
202856203323
** Maximum nesting depth of JSON for this implementation.
202857203324
**
202858203325
** This limit is needed to avoid a stack overflow in the recursive
202859203326
** descent parser. A depth of 1000 is far deeper than any sane JSON
202860203327
** should go. Historical note: This limit was 2000 prior to version 3.42.0
202861203328
*/
202862
-#define JSON_MAX_DEPTH 1000
203329
+#ifndef SQLITE_JSON_MAX_DEPTH
203330
+# define JSON_MAX_DEPTH 1000
203331
+#else
203332
+# define JSON_MAX_DEPTH SQLITE_JSON_MAX_DEPTH
203333
+#endif
203334
+
203335
+/*
203336
+** Allowed values for the flgs argument to jsonParseFuncArg();
203337
+*/
203338
+#define JSON_EDITABLE 0x01 /* Generate a writable JsonParse object */
203339
+#define JSON_KEEPERROR 0x02 /* Return non-NULL even if there is an error */
203340
+
203341
+/**************************************************************************
203342
+** Forward references
203343
+**************************************************************************/
203344
+static void jsonReturnStringAsBlob(JsonString*);
203345
+static int jsonFuncArgMightBeBinary(sqlite3_value *pJson);
203346
+static u32 jsonXlateBlobToText(const JsonParse*,u32,JsonString*);
203347
+static void jsonReturnParse(sqlite3_context*,JsonParse*);
203348
+static JsonParse *jsonParseFuncArg(sqlite3_context*,sqlite3_value*,u32);
203349
+static void jsonParseFree(JsonParse*);
203350
+static u32 jsonbPayloadSize(const JsonParse*, u32, u32*);
203351
+static u32 jsonUnescapeOneChar(const char*, u32, u32*);
203352
+
203353
+/**************************************************************************
203354
+** Utility routines for dealing with JsonCache objects
203355
+**************************************************************************/
203356
+
203357
+/*
203358
+** Free a JsonCache object.
203359
+*/
203360
+static void jsonCacheDelete(JsonCache *p){
203361
+ int i;
203362
+ for(i=0; i<p->nUsed; i++){
203363
+ jsonParseFree(p->a[i]);
203364
+ }
203365
+ sqlite3DbFree(p->db, p);
203366
+}
203367
+static void jsonCacheDeleteGeneric(void *p){
203368
+ jsonCacheDelete((JsonCache*)p);
203369
+}
203370
+
203371
+/*
203372
+** Insert a new entry into the cache. If the cache is full, expel
203373
+** the least recently used entry. Return SQLITE_OK on success or a
203374
+** result code otherwise.
203375
+**
203376
+** Cache entries are stored in age order, oldest first.
203377
+*/
203378
+static int jsonCacheInsert(
203379
+ sqlite3_context *ctx, /* The SQL statement context holding the cache */
203380
+ JsonParse *pParse /* The parse object to be added to the cache */
203381
+){
203382
+ JsonCache *p;
203383
+
203384
+ assert( pParse->zJson!=0 );
203385
+ assert( pParse->bJsonIsRCStr );
203386
+ p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID);
203387
+ if( p==0 ){
203388
+ sqlite3 *db = sqlite3_context_db_handle(ctx);
203389
+ p = sqlite3DbMallocZero(db, sizeof(*p));
203390
+ if( p==0 ) return SQLITE_NOMEM;
203391
+ p->db = db;
203392
+ sqlite3_set_auxdata(ctx, JSON_CACHE_ID, p, jsonCacheDeleteGeneric);
203393
+ p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID);
203394
+ if( p==0 ) return SQLITE_NOMEM;
203395
+ }
203396
+ if( p->nUsed >= JSON_CACHE_SIZE ){
203397
+ jsonParseFree(p->a[0]);
203398
+ memmove(p->a, &p->a[1], (JSON_CACHE_SIZE-1)*sizeof(p->a[0]));
203399
+ p->nUsed = JSON_CACHE_SIZE-1;
203400
+ }
203401
+ assert( pParse->nBlobAlloc>0 );
203402
+ pParse->eEdit = 0;
203403
+ pParse->nJPRef++;
203404
+ pParse->bReadOnly = 1;
203405
+ p->a[p->nUsed] = pParse;
203406
+ p->nUsed++;
203407
+ return SQLITE_OK;
203408
+}
203409
+
203410
+/*
203411
+** Search for a cached translation the json text supplied by pArg. Return
203412
+** the JsonParse object if found. Return NULL if not found.
203413
+**
203414
+** When a match if found, the matching entry is moved to become the
203415
+** most-recently used entry if it isn't so already.
203416
+**
203417
+** The JsonParse object returned still belongs to the Cache and might
203418
+** be deleted at any moment. If the caller whants the JsonParse to
203419
+** linger, it needs to increment the nPJRef reference counter.
203420
+*/
203421
+static JsonParse *jsonCacheSearch(
203422
+ sqlite3_context *ctx, /* The SQL statement context holding the cache */
203423
+ sqlite3_value *pArg /* Function argument containing SQL text */
203424
+){
203425
+ JsonCache *p;
203426
+ int i;
203427
+ const char *zJson;
203428
+ int nJson;
203429
+
203430
+ if( sqlite3_value_type(pArg)!=SQLITE_TEXT ){
203431
+ return 0;
203432
+ }
203433
+ zJson = (const char*)sqlite3_value_text(pArg);
203434
+ if( zJson==0 ) return 0;
203435
+ nJson = sqlite3_value_bytes(pArg);
203436
+
203437
+ p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID);
203438
+ if( p==0 ){
203439
+ return 0;
203440
+ }
203441
+ for(i=0; i<p->nUsed; i++){
203442
+ if( p->a[i]->zJson==zJson ) break;
203443
+ }
203444
+ if( i>=p->nUsed ){
203445
+ for(i=0; i<p->nUsed; i++){
203446
+ if( p->a[i]->nJson!=nJson ) continue;
203447
+ if( memcmp(p->a[i]->zJson, zJson, nJson)==0 ) break;
203448
+ }
203449
+ }
203450
+ if( i<p->nUsed ){
203451
+ if( i<p->nUsed-1 ){
203452
+ /* Make the matching entry the most recently used entry */
203453
+ JsonParse *tmp = p->a[i];
203454
+ memmove(&p->a[i], &p->a[i+1], (p->nUsed-i-1)*sizeof(tmp));
203455
+ p->a[p->nUsed-1] = tmp;
203456
+ i = p->nUsed - 1;
203457
+ }
203458
+ return p->a[i];
203459
+ }else{
203460
+ return 0;
203461
+ }
203462
+}
202863203463
202864203464
/**************************************************************************
202865203465
** Utility routines for dealing with JsonString objects
202866203466
**************************************************************************/
202867203467
202868
-/* Set the JsonString object to an empty string
203468
+/* Turn uninitialized bulk memory into a valid JsonString object
203469
+** holding a zero-length string.
202869203470
*/
202870
-static void jsonZero(JsonString *p){
203471
+static void jsonStringZero(JsonString *p){
202871203472
p->zBuf = p->zSpace;
202872203473
p->nAlloc = sizeof(p->zSpace);
202873203474
p->nUsed = 0;
202874203475
p->bStatic = 1;
202875203476
}
202876203477
202877203478
/* Initialize the JsonString object
202878203479
*/
202879
-static void jsonInit(JsonString *p, sqlite3_context *pCtx){
203480
+static void jsonStringInit(JsonString *p, sqlite3_context *pCtx){
202880203481
p->pCtx = pCtx;
202881
- p->bErr = 0;
202882
- jsonZero(p);
203482
+ p->eErr = 0;
203483
+ jsonStringZero(p);
202883203484
}
202884203485
202885203486
/* Free all allocated memory and reset the JsonString object back to its
202886203487
** initial state.
202887203488
*/
202888
-static void jsonReset(JsonString *p){
203489
+static void jsonStringReset(JsonString *p){
202889203490
if( !p->bStatic ) sqlite3RCStrUnref(p->zBuf);
202890
- jsonZero(p);
203491
+ jsonStringZero(p);
202891203492
}
202892203493
202893203494
/* Report an out-of-memory (OOM) condition
202894203495
*/
202895
-static void jsonOom(JsonString *p){
202896
- p->bErr = 1;
202897
- sqlite3_result_error_nomem(p->pCtx);
202898
- jsonReset(p);
203496
+static void jsonStringOom(JsonString *p){
203497
+ p->eErr |= JSTRING_OOM;
203498
+ if( p->pCtx ) sqlite3_result_error_nomem(p->pCtx);
203499
+ jsonStringReset(p);
202899203500
}
202900203501
202901203502
/* Enlarge pJson->zBuf so that it can hold at least N more bytes.
202902203503
** Return zero on success. Return non-zero on an OOM error
202903203504
*/
202904
-static int jsonGrow(JsonString *p, u32 N){
203505
+static int jsonStringGrow(JsonString *p, u32 N){
202905203506
u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10;
202906203507
char *zNew;
202907203508
if( p->bStatic ){
202908
- if( p->bErr ) return 1;
203509
+ if( p->eErr ) return 1;
202909203510
zNew = sqlite3RCStrNew(nTotal);
202910203511
if( zNew==0 ){
202911
- jsonOom(p);
203512
+ jsonStringOom(p);
202912203513
return SQLITE_NOMEM;
202913203514
}
202914203515
memcpy(zNew, p->zBuf, (size_t)p->nUsed);
202915203516
p->zBuf = zNew;
202916203517
p->bStatic = 0;
202917203518
}else{
202918203519
p->zBuf = sqlite3RCStrResize(p->zBuf, nTotal);
202919203520
if( p->zBuf==0 ){
202920
- p->bErr = 1;
202921
- jsonZero(p);
203521
+ p->eErr |= JSTRING_OOM;
203522
+ jsonStringZero(p);
202922203523
return SQLITE_NOMEM;
202923203524
}
202924203525
}
202925203526
p->nAlloc = nTotal;
202926203527
return SQLITE_OK;
202927203528
}
202928203529
202929203530
/* Append N bytes from zIn onto the end of the JsonString string.
202930203531
*/
202931
-static SQLITE_NOINLINE void jsonAppendExpand(
203532
+static SQLITE_NOINLINE void jsonStringExpandAndAppend(
202932203533
JsonString *p,
202933203534
const char *zIn,
202934203535
u32 N
202935203536
){
202936203537
assert( N>0 );
202937
- if( jsonGrow(p,N) ) return;
203538
+ if( jsonStringGrow(p,N) ) return;
202938203539
memcpy(p->zBuf+p->nUsed, zIn, N);
202939203540
p->nUsed += N;
202940203541
}
202941203542
static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
202942203543
if( N==0 ) return;
202943203544
if( N+p->nUsed >= p->nAlloc ){
202944
- jsonAppendExpand(p,zIn,N);
203545
+ jsonStringExpandAndAppend(p,zIn,N);
202945203546
}else{
202946203547
memcpy(p->zBuf+p->nUsed, zIn, N);
202947203548
p->nUsed += N;
202948203549
}
202949203550
}
202950203551
static void jsonAppendRawNZ(JsonString *p, const char *zIn, u32 N){
202951203552
assert( N>0 );
202952203553
if( N+p->nUsed >= p->nAlloc ){
202953
- jsonAppendExpand(p,zIn,N);
203554
+ jsonStringExpandAndAppend(p,zIn,N);
202954203555
}else{
202955203556
memcpy(p->zBuf+p->nUsed, zIn, N);
202956203557
p->nUsed += N;
202957203558
}
202958203559
}
@@ -202960,21 +203561,21 @@
202960203561
202961203562
/* Append formatted text (not to exceed N bytes) to the JsonString.
202962203563
*/
202963203564
static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){
202964203565
va_list ap;
202965
- if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return;
203566
+ if( (p->nUsed + N >= p->nAlloc) && jsonStringGrow(p, N) ) return;
202966203567
va_start(ap, zFormat);
202967203568
sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap);
202968203569
va_end(ap);
202969203570
p->nUsed += (int)strlen(p->zBuf+p->nUsed);
202970203571
}
202971203572
202972203573
/* Append a single character
202973203574
*/
202974203575
static SQLITE_NOINLINE void jsonAppendCharExpand(JsonString *p, char c){
202975
- if( jsonGrow(p,1) ) return;
203576
+ if( jsonStringGrow(p,1) ) return;
202976203577
p->zBuf[p->nUsed++] = c;
202977203578
}
202978203579
static void jsonAppendChar(JsonString *p, char c){
202979203580
if( p->nUsed>=p->nAlloc ){
202980203581
jsonAppendCharExpand(p,c);
@@ -202981,27 +203582,20 @@
202981203582
}else{
202982203583
p->zBuf[p->nUsed++] = c;
202983203584
}
202984203585
}
202985203586
202986
-/* Try to force the string to be a zero-terminated RCStr string.
203587
+/* Make sure there is a zero terminator on p->zBuf[]
202987203588
**
202988203589
** Return true on success. Return false if an OOM prevents this
202989203590
** from happening.
202990203591
*/
202991
-static int jsonForceRCStr(JsonString *p){
202992
- jsonAppendChar(p, 0);
202993
- if( p->bErr ) return 0;
202994
- p->nUsed--;
202995
- if( p->bStatic==0 ) return 1;
202996
- p->nAlloc = 0;
202997
- p->nUsed++;
202998
- jsonGrow(p, p->nUsed);
202999
- p->nUsed--;
203000
- return p->bStatic==0;
203001
-}
203002
-
203592
+static int jsonStringTerminate(JsonString *p){
203593
+ jsonAppendChar(p, 0);
203594
+ p->nUsed--;
203595
+ return p->eErr==0;
203596
+}
203003203597
203004203598
/* Append a comma separator to the output buffer, if the previous
203005203599
** character is not '[' or '{'.
203006203600
*/
203007203601
static void jsonAppendSeparator(JsonString *p){
@@ -203011,25 +203605,45 @@
203011203605
if( c=='[' || c=='{' ) return;
203012203606
jsonAppendChar(p, ',');
203013203607
}
203014203608
203015203609
/* Append the N-byte string in zIn to the end of the JsonString string
203016
-** under construction. Enclose the string in "..." and escape
203017
-** any double-quotes or backslash characters contained within the
203610
+** under construction. Enclose the string in double-quotes ("...") and
203611
+** escape any double-quotes or backslash characters contained within the
203018203612
** string.
203613
+**
203614
+** This routine is a high-runner. There is a measurable performance
203615
+** increase associated with unwinding the jsonIsOk[] loop.
203019203616
*/
203020203617
static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
203021
- u32 i;
203022
- if( zIn==0 || ((N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0) ) return;
203618
+ u32 k;
203619
+ u8 c;
203620
+ const u8 *z = (const u8*)zIn;
203621
+ if( z==0 ) return;
203622
+ if( (N+p->nUsed+2 >= p->nAlloc) && jsonStringGrow(p,N+2)!=0 ) return;
203023203623
p->zBuf[p->nUsed++] = '"';
203024
- for(i=0; i<N; i++){
203025
- unsigned char c = ((unsigned const char*)zIn)[i];
203026
- if( jsonIsOk[c] ){
203027
- p->zBuf[p->nUsed++] = c;
203028
- }else if( c=='"' || c=='\\' ){
203624
+ while( 1 /*exit-by-break*/ ){
203625
+ k = 0;
203626
+ while( k+1<N && jsonIsOk[z[k]] && jsonIsOk[z[k+1]] ){ k += 2; } /* <--, */
203627
+ while( k<N && jsonIsOk[z[k]] ){ k++; } /* <-- loop unwound for speed */
203628
+ if( k>=N ){
203629
+ if( k>0 ){
203630
+ memcpy(&p->zBuf[p->nUsed], z, k);
203631
+ p->nUsed += k;
203632
+ }
203633
+ break;
203634
+ }
203635
+ if( k>0 ){
203636
+ memcpy(&p->zBuf[p->nUsed], z, k);
203637
+ p->nUsed += k;
203638
+ z += k;
203639
+ N -= k;
203640
+ }
203641
+ c = z[0];
203642
+ if( c=='"' || c=='\\' ){
203029203643
json_simple_escape:
203030
- if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return;
203644
+ if( (p->nUsed+N+3 > p->nAlloc) && jsonStringGrow(p,N+3)!=0 ) return;
203031203645
p->zBuf[p->nUsed++] = '\\';
203032203646
p->zBuf[p->nUsed++] = c;
203033203647
}else if( c=='\'' ){
203034203648
p->zBuf[p->nUsed++] = c;
203035203649
}else{
@@ -203046,158 +203660,30 @@
203046203660
assert( c>=0 && c<sizeof(aSpecial) );
203047203661
if( aSpecial[c] ){
203048203662
c = aSpecial[c];
203049203663
goto json_simple_escape;
203050203664
}
203051
- if( (p->nUsed+N+7+i > p->nAlloc) && jsonGrow(p,N+7-i)!=0 ) return;
203665
+ if( (p->nUsed+N+7 > p->nAlloc) && jsonStringGrow(p,N+7)!=0 ) return;
203052203666
p->zBuf[p->nUsed++] = '\\';
203053203667
p->zBuf[p->nUsed++] = 'u';
203054203668
p->zBuf[p->nUsed++] = '0';
203055203669
p->zBuf[p->nUsed++] = '0';
203056203670
p->zBuf[p->nUsed++] = "0123456789abcdef"[c>>4];
203057203671
p->zBuf[p->nUsed++] = "0123456789abcdef"[c&0xf];
203058203672
}
203673
+ z++;
203674
+ N--;
203059203675
}
203060203676
p->zBuf[p->nUsed++] = '"';
203061203677
assert( p->nUsed<p->nAlloc );
203062203678
}
203063203679
203064203680
/*
203065
-** The zIn[0..N] string is a JSON5 string literal. Append to p a translation
203066
-** of the string literal that standard JSON and that omits all JSON5
203067
-** features.
203068
-*/
203069
-static void jsonAppendNormalizedString(JsonString *p, const char *zIn, u32 N){
203070
- u32 i;
203071
- jsonAppendChar(p, '"');
203072
- zIn++;
203073
- N -= 2;
203074
- while( N>0 ){
203075
- for(i=0; i<N && zIn[i]!='\\' && zIn[i]!='"'; i++){}
203076
- if( i>0 ){
203077
- jsonAppendRawNZ(p, zIn, i);
203078
- zIn += i;
203079
- N -= i;
203080
- if( N==0 ) break;
203081
- }
203082
- if( zIn[0]=='"' ){
203083
- jsonAppendRawNZ(p, "\\\"", 2);
203084
- zIn++;
203085
- N--;
203086
- continue;
203087
- }
203088
- assert( zIn[0]=='\\' );
203089
- switch( (u8)zIn[1] ){
203090
- case '\'':
203091
- jsonAppendChar(p, '\'');
203092
- break;
203093
- case 'v':
203094
- jsonAppendRawNZ(p, "\\u0009", 6);
203095
- break;
203096
- case 'x':
203097
- jsonAppendRawNZ(p, "\\u00", 4);
203098
- jsonAppendRawNZ(p, &zIn[2], 2);
203099
- zIn += 2;
203100
- N -= 2;
203101
- break;
203102
- case '0':
203103
- jsonAppendRawNZ(p, "\\u0000", 6);
203104
- break;
203105
- case '\r':
203106
- if( zIn[2]=='\n' ){
203107
- zIn++;
203108
- N--;
203109
- }
203110
- break;
203111
- case '\n':
203112
- break;
203113
- case 0xe2:
203114
- assert( N>=4 );
203115
- assert( 0x80==(u8)zIn[2] );
203116
- assert( 0xa8==(u8)zIn[3] || 0xa9==(u8)zIn[3] );
203117
- zIn += 2;
203118
- N -= 2;
203119
- break;
203120
- default:
203121
- jsonAppendRawNZ(p, zIn, 2);
203122
- break;
203123
- }
203124
- zIn += 2;
203125
- N -= 2;
203126
- }
203127
- jsonAppendChar(p, '"');
203128
-}
203129
-
203130
-/*
203131
-** The zIn[0..N] string is a JSON5 integer literal. Append to p a translation
203132
-** of the string literal that standard JSON and that omits all JSON5
203133
-** features.
203134
-*/
203135
-static void jsonAppendNormalizedInt(JsonString *p, const char *zIn, u32 N){
203136
- if( zIn[0]=='+' ){
203137
- zIn++;
203138
- N--;
203139
- }else if( zIn[0]=='-' ){
203140
- jsonAppendChar(p, '-');
203141
- zIn++;
203142
- N--;
203143
- }
203144
- if( zIn[0]=='0' && (zIn[1]=='x' || zIn[1]=='X') ){
203145
- sqlite3_int64 i = 0;
203146
- int rc = sqlite3DecOrHexToI64(zIn, &i);
203147
- if( rc<=1 ){
203148
- jsonPrintf(100,p,"%lld",i);
203149
- }else{
203150
- assert( rc==2 );
203151
- jsonAppendRawNZ(p, "9.0e999", 7);
203152
- }
203153
- return;
203154
- }
203155
- assert( N>0 );
203156
- jsonAppendRawNZ(p, zIn, N);
203157
-}
203158
-
203159
-/*
203160
-** The zIn[0..N] string is a JSON5 real literal. Append to p a translation
203161
-** of the string literal that standard JSON and that omits all JSON5
203162
-** features.
203163
-*/
203164
-static void jsonAppendNormalizedReal(JsonString *p, const char *zIn, u32 N){
203165
- u32 i;
203166
- if( zIn[0]=='+' ){
203167
- zIn++;
203168
- N--;
203169
- }else if( zIn[0]=='-' ){
203170
- jsonAppendChar(p, '-');
203171
- zIn++;
203172
- N--;
203173
- }
203174
- if( zIn[0]=='.' ){
203175
- jsonAppendChar(p, '0');
203176
- }
203177
- for(i=0; i<N; i++){
203178
- if( zIn[i]=='.' && (i+1==N || !sqlite3Isdigit(zIn[i+1])) ){
203179
- i++;
203180
- jsonAppendRaw(p, zIn, i);
203181
- zIn += i;
203182
- N -= i;
203183
- jsonAppendChar(p, '0');
203184
- break;
203185
- }
203186
- }
203187
- if( N>0 ){
203188
- jsonAppendRawNZ(p, zIn, N);
203189
- }
203190
-}
203191
-
203192
-
203193
-
203194
-/*
203195
-** Append a function parameter value to the JSON string under
203196
-** construction.
203197
-*/
203198
-static void jsonAppendValue(
203681
+** Append an sqlite3_value (such as a function parameter) to the JSON
203682
+** string under construction in p.
203683
+*/
203684
+static void jsonAppendSqlValue(
203199203685
JsonString *p, /* Append to this JSON string */
203200203686
sqlite3_value *pValue /* Value to append */
203201203687
){
203202203688
switch( sqlite3_value_type(pValue) ){
203203203689
case SQLITE_NULL: {
@@ -203223,591 +203709,147 @@
203223203709
jsonAppendString(p, z, n);
203224203710
}
203225203711
break;
203226203712
}
203227203713
default: {
203228
- if( p->bErr==0 ){
203714
+ if( jsonFuncArgMightBeBinary(pValue) ){
203715
+ JsonParse px;
203716
+ memset(&px, 0, sizeof(px));
203717
+ px.aBlob = (u8*)sqlite3_value_blob(pValue);
203718
+ px.nBlob = sqlite3_value_bytes(pValue);
203719
+ jsonXlateBlobToText(&px, 0, p);
203720
+ }else if( p->eErr==0 ){
203229203721
sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1);
203230
- p->bErr = 2;
203231
- jsonReset(p);
203722
+ p->eErr = JSTRING_ERR;
203723
+ jsonStringReset(p);
203232203724
}
203233203725
break;
203234203726
}
203235203727
}
203236203728
}
203237203729
203238
-
203239
-/* Make the JSON in p the result of the SQL function.
203730
+/* Make the text in p (which is probably a generated JSON text string)
203731
+** the result of the SQL function.
203240203732
**
203241
-** The JSON string is reset.
203733
+** The JsonString is reset.
203734
+**
203735
+** If pParse and ctx are both non-NULL, then the SQL string in p is
203736
+** loaded into the zJson field of the pParse object as a RCStr and the
203737
+** pParse is added to the cache.
203242203738
*/
203243
-static void jsonResult(JsonString *p){
203244
- if( p->bErr==0 ){
203245
- if( p->bStatic ){
203739
+static void jsonReturnString(
203740
+ JsonString *p, /* String to return */
203741
+ JsonParse *pParse, /* JSONB source or NULL */
203742
+ sqlite3_context *ctx /* Where to cache */
203743
+){
203744
+ assert( (pParse!=0)==(ctx!=0) );
203745
+ assert( ctx==0 || ctx==p->pCtx );
203746
+ if( p->eErr==0 ){
203747
+ int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(p->pCtx));
203748
+ if( flags & JSON_BLOB ){
203749
+ jsonReturnStringAsBlob(p);
203750
+ }else if( p->bStatic ){
203246203751
sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
203247203752
SQLITE_TRANSIENT, SQLITE_UTF8);
203248
- }else if( jsonForceRCStr(p) ){
203249
- sqlite3RCStrRef(p->zBuf);
203250
- sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
203753
+ }else if( jsonStringTerminate(p) ){
203754
+ if( pParse && pParse->bJsonIsRCStr==0 && pParse->nBlobAlloc>0 ){
203755
+ int rc;
203756
+ pParse->zJson = sqlite3RCStrRef(p->zBuf);
203757
+ pParse->nJson = p->nUsed;
203758
+ pParse->bJsonIsRCStr = 1;
203759
+ rc = jsonCacheInsert(ctx, pParse);
203760
+ if( rc==SQLITE_NOMEM ){
203761
+ sqlite3_result_error_nomem(ctx);
203762
+ jsonStringReset(p);
203763
+ return;
203764
+ }
203765
+ }
203766
+ sqlite3_result_text64(p->pCtx, sqlite3RCStrRef(p->zBuf), p->nUsed,
203251203767
sqlite3RCStrUnref,
203252203768
SQLITE_UTF8);
203769
+ }else{
203770
+ sqlite3_result_error_nomem(p->pCtx);
203253203771
}
203254
- }
203255
- if( p->bErr==1 ){
203772
+ }else if( p->eErr & JSTRING_OOM ){
203256203773
sqlite3_result_error_nomem(p->pCtx);
203774
+ }else if( p->eErr & JSTRING_MALFORMED ){
203775
+ sqlite3_result_error(p->pCtx, "malformed JSON", -1);
203257203776
}
203258
- jsonReset(p);
203777
+ jsonStringReset(p);
203259203778
}
203260203779
203261203780
/**************************************************************************
203262
-** Utility routines for dealing with JsonNode and JsonParse objects
203781
+** Utility routines for dealing with JsonParse objects
203263203782
**************************************************************************/
203264203783
203265
-/*
203266
-** Return the number of consecutive JsonNode slots need to represent
203267
-** the parsed JSON at pNode. The minimum answer is 1. For ARRAY and
203268
-** OBJECT types, the number might be larger.
203269
-**
203270
-** Appended elements are not counted. The value returned is the number
203271
-** by which the JsonNode counter should increment in order to go to the
203272
-** next peer value.
203273
-*/
203274
-static u32 jsonNodeSize(JsonNode *pNode){
203275
- return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1;
203276
-}
203277
-
203278203784
/*
203279203785
** Reclaim all memory allocated by a JsonParse object. But do not
203280203786
** delete the JsonParse object itself.
203281203787
*/
203282203788
static void jsonParseReset(JsonParse *pParse){
203283
- while( pParse->pClup ){
203284
- JsonCleanup *pTask = pParse->pClup;
203285
- pParse->pClup = pTask->pJCNext;
203286
- pTask->xOp(pTask->pArg);
203287
- sqlite3_free(pTask);
203288
- }
203289203789
assert( pParse->nJPRef<=1 );
203290
- if( pParse->aNode ){
203291
- sqlite3_free(pParse->aNode);
203292
- pParse->aNode = 0;
203293
- }
203294
- pParse->nNode = 0;
203295
- pParse->nAlloc = 0;
203296
- if( pParse->aUp ){
203297
- sqlite3_free(pParse->aUp);
203298
- pParse->aUp = 0;
203299
- }
203300203790
if( pParse->bJsonIsRCStr ){
203301203791
sqlite3RCStrUnref(pParse->zJson);
203302203792
pParse->zJson = 0;
203793
+ pParse->nJson = 0;
203303203794
pParse->bJsonIsRCStr = 0;
203304203795
}
203305
- if( pParse->zAlt ){
203306
- sqlite3RCStrUnref(pParse->zAlt);
203307
- pParse->zAlt = 0;
203796
+ if( pParse->nBlobAlloc ){
203797
+ sqlite3_free(pParse->aBlob);
203798
+ pParse->aBlob = 0;
203799
+ pParse->nBlob = 0;
203800
+ pParse->nBlobAlloc = 0;
203308203801
}
203309203802
}
203310203803
203311203804
/*
203312
-** Free a JsonParse object that was obtained from sqlite3_malloc().
203313
-**
203314
-** Note that destroying JsonParse might call sqlite3RCStrUnref() to
203315
-** destroy the zJson value. The RCStr object might recursively invoke
203316
-** JsonParse to destroy this pParse object again. Take care to ensure
203317
-** that this recursive destructor sequence terminates harmlessly.
203805
+** Decrement the reference count on the JsonParse object. When the
203806
+** count reaches zero, free the object.
203318203807
*/
203319203808
static void jsonParseFree(JsonParse *pParse){
203320
- if( pParse->nJPRef>1 ){
203321
- pParse->nJPRef--;
203322
- }else{
203323
- jsonParseReset(pParse);
203324
- sqlite3_free(pParse);
203325
- }
203326
-}
203327
-
203328
-/*
203329
-** Add a cleanup task to the JsonParse object.
203330
-**
203331
-** If an OOM occurs, the cleanup operation happens immediately
203332
-** and this function returns SQLITE_NOMEM.
203333
-*/
203334
-static int jsonParseAddCleanup(
203335
- JsonParse *pParse, /* Add the cleanup task to this parser */
203336
- void(*xOp)(void*), /* The cleanup task */
203337
- void *pArg /* Argument to the cleanup */
203338
-){
203339
- JsonCleanup *pTask = sqlite3_malloc64( sizeof(*pTask) );
203340
- if( pTask==0 ){
203341
- pParse->oom = 1;
203342
- xOp(pArg);
203343
- return SQLITE_ERROR;
203344
- }
203345
- pTask->pJCNext = pParse->pClup;
203346
- pParse->pClup = pTask;
203347
- pTask->xOp = xOp;
203348
- pTask->pArg = pArg;
203349
- return SQLITE_OK;
203350
-}
203351
-
203352
-/*
203353
-** Convert the JsonNode pNode into a pure JSON string and
203354
-** append to pOut. Subsubstructure is also included. Return
203355
-** the number of JsonNode objects that are encoded.
203356
-*/
203357
-static void jsonRenderNode(
203358
- JsonParse *pParse, /* the complete parse of the JSON */
203359
- JsonNode *pNode, /* The node to render */
203360
- JsonString *pOut /* Write JSON here */
203361
-){
203362
- assert( pNode!=0 );
203363
- while( (pNode->jnFlags & JNODE_REPLACE)!=0 && pParse->useMod ){
203364
- u32 idx = (u32)(pNode - pParse->aNode);
203365
- u32 i = pParse->iSubst;
203366
- while( 1 /*exit-by-break*/ ){
203367
- assert( i<pParse->nNode );
203368
- assert( pParse->aNode[i].eType==JSON_SUBST );
203369
- assert( pParse->aNode[i].eU==4 );
203370
- assert( pParse->aNode[i].u.iPrev<i );
203371
- if( pParse->aNode[i].n==idx ){
203372
- pNode = &pParse->aNode[i+1];
203373
- break;
203374
- }
203375
- i = pParse->aNode[i].u.iPrev;
203376
- }
203377
- }
203378
- switch( pNode->eType ){
203379
- default: {
203380
- assert( pNode->eType==JSON_NULL );
203381
- jsonAppendRawNZ(pOut, "null", 4);
203382
- break;
203383
- }
203384
- case JSON_TRUE: {
203385
- jsonAppendRawNZ(pOut, "true", 4);
203386
- break;
203387
- }
203388
- case JSON_FALSE: {
203389
- jsonAppendRawNZ(pOut, "false", 5);
203390
- break;
203391
- }
203392
- case JSON_STRING: {
203393
- assert( pNode->eU==1 );
203394
- if( pNode->jnFlags & JNODE_RAW ){
203395
- if( pNode->jnFlags & JNODE_LABEL ){
203396
- jsonAppendChar(pOut, '"');
203397
- jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
203398
- jsonAppendChar(pOut, '"');
203399
- }else{
203400
- jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
203401
- }
203402
- }else if( pNode->jnFlags & JNODE_JSON5 ){
203403
- jsonAppendNormalizedString(pOut, pNode->u.zJContent, pNode->n);
203404
- }else{
203405
- assert( pNode->n>0 );
203406
- jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n);
203407
- }
203408
- break;
203409
- }
203410
- case JSON_REAL: {
203411
- assert( pNode->eU==1 );
203412
- if( pNode->jnFlags & JNODE_JSON5 ){
203413
- jsonAppendNormalizedReal(pOut, pNode->u.zJContent, pNode->n);
203414
- }else{
203415
- assert( pNode->n>0 );
203416
- jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n);
203417
- }
203418
- break;
203419
- }
203420
- case JSON_INT: {
203421
- assert( pNode->eU==1 );
203422
- if( pNode->jnFlags & JNODE_JSON5 ){
203423
- jsonAppendNormalizedInt(pOut, pNode->u.zJContent, pNode->n);
203424
- }else{
203425
- assert( pNode->n>0 );
203426
- jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n);
203427
- }
203428
- break;
203429
- }
203430
- case JSON_ARRAY: {
203431
- u32 j = 1;
203432
- jsonAppendChar(pOut, '[');
203433
- for(;;){
203434
- while( j<=pNode->n ){
203435
- if( (pNode[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ){
203436
- jsonAppendSeparator(pOut);
203437
- jsonRenderNode(pParse, &pNode[j], pOut);
203438
- }
203439
- j += jsonNodeSize(&pNode[j]);
203440
- }
203441
- if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
203442
- if( pParse->useMod==0 ) break;
203443
- assert( pNode->eU==2 );
203444
- pNode = &pParse->aNode[pNode->u.iAppend];
203445
- j = 1;
203446
- }
203447
- jsonAppendChar(pOut, ']');
203448
- break;
203449
- }
203450
- case JSON_OBJECT: {
203451
- u32 j = 1;
203452
- jsonAppendChar(pOut, '{');
203453
- for(;;){
203454
- while( j<=pNode->n ){
203455
- if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ){
203456
- jsonAppendSeparator(pOut);
203457
- jsonRenderNode(pParse, &pNode[j], pOut);
203458
- jsonAppendChar(pOut, ':');
203459
- jsonRenderNode(pParse, &pNode[j+1], pOut);
203460
- }
203461
- j += 1 + jsonNodeSize(&pNode[j+1]);
203462
- }
203463
- if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
203464
- if( pParse->useMod==0 ) break;
203465
- assert( pNode->eU==2 );
203466
- pNode = &pParse->aNode[pNode->u.iAppend];
203467
- j = 1;
203468
- }
203469
- jsonAppendChar(pOut, '}');
203470
- break;
203471
- }
203472
- }
203473
-}
203474
-
203475
-/*
203476
-** Return a JsonNode and all its descendants as a JSON string.
203477
-*/
203478
-static void jsonReturnJson(
203479
- JsonParse *pParse, /* The complete JSON */
203480
- JsonNode *pNode, /* Node to return */
203481
- sqlite3_context *pCtx, /* Return value for this function */
203482
- int bGenerateAlt, /* Also store the rendered text in zAlt */
203483
- int omitSubtype /* Do not call sqlite3_result_subtype() */
203484
-){
203485
- JsonString s;
203486
- if( pParse->oom ){
203487
- sqlite3_result_error_nomem(pCtx);
203488
- return;
203489
- }
203490
- if( pParse->nErr==0 ){
203491
- jsonInit(&s, pCtx);
203492
- jsonRenderNode(pParse, pNode, &s);
203493
- if( bGenerateAlt && pParse->zAlt==0 && jsonForceRCStr(&s) ){
203494
- pParse->zAlt = sqlite3RCStrRef(s.zBuf);
203495
- pParse->nAlt = s.nUsed;
203496
- }
203497
- jsonResult(&s);
203498
- if( !omitSubtype ) sqlite3_result_subtype(pCtx, JSON_SUBTYPE);
203499
- }
203500
-}
203809
+ if( pParse ){
203810
+ if( pParse->nJPRef>1 ){
203811
+ pParse->nJPRef--;
203812
+ }else{
203813
+ jsonParseReset(pParse);
203814
+ sqlite3_free(pParse);
203815
+ }
203816
+ }
203817
+}
203818
+
203819
+/**************************************************************************
203820
+** Utility routines for the JSON text parser
203821
+**************************************************************************/
203501203822
203502203823
/*
203503203824
** Translate a single byte of Hex into an integer.
203504
-** This routine only works if h really is a valid hexadecimal
203505
-** character: 0..9a..fA..F
203825
+** This routine only gives a correct answer if h really is a valid hexadecimal
203826
+** character: 0..9a..fA..F. But unlike sqlite3HexToInt(), it does not
203827
+** assert() if the digit is not hex.
203506203828
*/
203507203829
static u8 jsonHexToInt(int h){
203508
- assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') );
203830
+#ifdef SQLITE_ASCII
203831
+ h += 9*(1&(h>>6));
203832
+#endif
203509203833
#ifdef SQLITE_EBCDIC
203510203834
h += 9*(1&~(h>>4));
203511
-#else
203512
- h += 9*(1&(h>>6));
203513203835
#endif
203514203836
return (u8)(h & 0xf);
203515203837
}
203516203838
203517203839
/*
203518203840
** Convert a 4-byte hex string into an integer
203519203841
*/
203520203842
static u32 jsonHexToInt4(const char *z){
203521203843
u32 v;
203522
- assert( sqlite3Isxdigit(z[0]) );
203523
- assert( sqlite3Isxdigit(z[1]) );
203524
- assert( sqlite3Isxdigit(z[2]) );
203525
- assert( sqlite3Isxdigit(z[3]) );
203526203844
v = (jsonHexToInt(z[0])<<12)
203527203845
+ (jsonHexToInt(z[1])<<8)
203528203846
+ (jsonHexToInt(z[2])<<4)
203529203847
+ jsonHexToInt(z[3]);
203530203848
return v;
203531203849
}
203532203850
203533
-/*
203534
-** Make the JsonNode the return value of the function.
203535
-*/
203536
-static void jsonReturn(
203537
- JsonParse *pParse, /* Complete JSON parse tree */
203538
- JsonNode *pNode, /* Node to return */
203539
- sqlite3_context *pCtx, /* Return value for this function */
203540
- int omitSubtype /* Do not call sqlite3_result_subtype() */
203541
-){
203542
- switch( pNode->eType ){
203543
- default: {
203544
- assert( pNode->eType==JSON_NULL );
203545
- sqlite3_result_null(pCtx);
203546
- break;
203547
- }
203548
- case JSON_TRUE: {
203549
- sqlite3_result_int(pCtx, 1);
203550
- break;
203551
- }
203552
- case JSON_FALSE: {
203553
- sqlite3_result_int(pCtx, 0);
203554
- break;
203555
- }
203556
- case JSON_INT: {
203557
- sqlite3_int64 i = 0;
203558
- int rc;
203559
- int bNeg = 0;
203560
- const char *z;
203561
-
203562
- assert( pNode->eU==1 );
203563
- z = pNode->u.zJContent;
203564
- if( z[0]=='-' ){ z++; bNeg = 1; }
203565
- else if( z[0]=='+' ){ z++; }
203566
- rc = sqlite3DecOrHexToI64(z, &i);
203567
- if( rc<=1 ){
203568
- sqlite3_result_int64(pCtx, bNeg ? -i : i);
203569
- }else if( rc==3 && bNeg ){
203570
- sqlite3_result_int64(pCtx, SMALLEST_INT64);
203571
- }else{
203572
- goto to_double;
203573
- }
203574
- break;
203575
- }
203576
- case JSON_REAL: {
203577
- double r;
203578
- const char *z;
203579
- assert( pNode->eU==1 );
203580
- to_double:
203581
- z = pNode->u.zJContent;
203582
- sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8);
203583
- sqlite3_result_double(pCtx, r);
203584
- break;
203585
- }
203586
- case JSON_STRING: {
203587
- if( pNode->jnFlags & JNODE_RAW ){
203588
- assert( pNode->eU==1 );
203589
- sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n,
203590
- SQLITE_TRANSIENT);
203591
- }else if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
203592
- /* JSON formatted without any backslash-escapes */
203593
- assert( pNode->eU==1 );
203594
- sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2,
203595
- SQLITE_TRANSIENT);
203596
- }else{
203597
- /* Translate JSON formatted string into raw text */
203598
- u32 i;
203599
- u32 n = pNode->n;
203600
- const char *z;
203601
- char *zOut;
203602
- u32 j;
203603
- u32 nOut = n;
203604
- assert( pNode->eU==1 );
203605
- z = pNode->u.zJContent;
203606
- zOut = sqlite3_malloc( nOut+1 );
203607
- if( zOut==0 ){
203608
- sqlite3_result_error_nomem(pCtx);
203609
- break;
203610
- }
203611
- for(i=1, j=0; i<n-1; i++){
203612
- char c = z[i];
203613
- if( c=='\\' ){
203614
- c = z[++i];
203615
- if( c=='u' ){
203616
- u32 v = jsonHexToInt4(z+i+1);
203617
- i += 4;
203618
- if( v==0 ) break;
203619
- if( v<=0x7f ){
203620
- zOut[j++] = (char)v;
203621
- }else if( v<=0x7ff ){
203622
- zOut[j++] = (char)(0xc0 | (v>>6));
203623
- zOut[j++] = 0x80 | (v&0x3f);
203624
- }else{
203625
- u32 vlo;
203626
- if( (v&0xfc00)==0xd800
203627
- && i<n-6
203628
- && z[i+1]=='\\'
203629
- && z[i+2]=='u'
203630
- && ((vlo = jsonHexToInt4(z+i+3))&0xfc00)==0xdc00
203631
- ){
203632
- /* We have a surrogate pair */
203633
- v = ((v&0x3ff)<<10) + (vlo&0x3ff) + 0x10000;
203634
- i += 6;
203635
- zOut[j++] = 0xf0 | (v>>18);
203636
- zOut[j++] = 0x80 | ((v>>12)&0x3f);
203637
- zOut[j++] = 0x80 | ((v>>6)&0x3f);
203638
- zOut[j++] = 0x80 | (v&0x3f);
203639
- }else{
203640
- zOut[j++] = 0xe0 | (v>>12);
203641
- zOut[j++] = 0x80 | ((v>>6)&0x3f);
203642
- zOut[j++] = 0x80 | (v&0x3f);
203643
- }
203644
- }
203645
- continue;
203646
- }else if( c=='b' ){
203647
- c = '\b';
203648
- }else if( c=='f' ){
203649
- c = '\f';
203650
- }else if( c=='n' ){
203651
- c = '\n';
203652
- }else if( c=='r' ){
203653
- c = '\r';
203654
- }else if( c=='t' ){
203655
- c = '\t';
203656
- }else if( c=='v' ){
203657
- c = '\v';
203658
- }else if( c=='\'' || c=='"' || c=='/' || c=='\\' ){
203659
- /* pass through unchanged */
203660
- }else if( c=='0' ){
203661
- c = 0;
203662
- }else if( c=='x' ){
203663
- c = (jsonHexToInt(z[i+1])<<4) | jsonHexToInt(z[i+2]);
203664
- i += 2;
203665
- }else if( c=='\r' && z[i+1]=='\n' ){
203666
- i++;
203667
- continue;
203668
- }else if( 0xe2==(u8)c ){
203669
- assert( 0x80==(u8)z[i+1] );
203670
- assert( 0xa8==(u8)z[i+2] || 0xa9==(u8)z[i+2] );
203671
- i += 2;
203672
- continue;
203673
- }else{
203674
- continue;
203675
- }
203676
- } /* end if( c=='\\' ) */
203677
- zOut[j++] = c;
203678
- } /* end for() */
203679
- zOut[j] = 0;
203680
- sqlite3_result_text(pCtx, zOut, j, sqlite3_free);
203681
- }
203682
- break;
203683
- }
203684
- case JSON_ARRAY:
203685
- case JSON_OBJECT: {
203686
- jsonReturnJson(pParse, pNode, pCtx, 0, omitSubtype);
203687
- break;
203688
- }
203689
- }
203690
-}
203691
-
203692
-/* Forward reference */
203693
-static int jsonParseAddNode(JsonParse*,u32,u32,const char*);
203694
-
203695
-/*
203696
-** A macro to hint to the compiler that a function should not be
203697
-** inlined.
203698
-*/
203699
-#if defined(__GNUC__)
203700
-# define JSON_NOINLINE __attribute__((noinline))
203701
-#elif defined(_MSC_VER) && _MSC_VER>=1310
203702
-# define JSON_NOINLINE __declspec(noinline)
203703
-#else
203704
-# define JSON_NOINLINE
203705
-#endif
203706
-
203707
-
203708
-/*
203709
-** Add a single node to pParse->aNode after first expanding the
203710
-** size of the aNode array. Return the index of the new node.
203711
-**
203712
-** If an OOM error occurs, set pParse->oom and return -1.
203713
-*/
203714
-static JSON_NOINLINE int jsonParseAddNodeExpand(
203715
- JsonParse *pParse, /* Append the node to this object */
203716
- u32 eType, /* Node type */
203717
- u32 n, /* Content size or sub-node count */
203718
- const char *zContent /* Content */
203719
-){
203720
- u32 nNew;
203721
- JsonNode *pNew;
203722
- assert( pParse->nNode>=pParse->nAlloc );
203723
- if( pParse->oom ) return -1;
203724
- nNew = pParse->nAlloc*2 + 10;
203725
- pNew = sqlite3_realloc64(pParse->aNode, sizeof(JsonNode)*nNew);
203726
- if( pNew==0 ){
203727
- pParse->oom = 1;
203728
- return -1;
203729
- }
203730
- pParse->nAlloc = sqlite3_msize(pNew)/sizeof(JsonNode);
203731
- pParse->aNode = pNew;
203732
- assert( pParse->nNode<pParse->nAlloc );
203733
- return jsonParseAddNode(pParse, eType, n, zContent);
203734
-}
203735
-
203736
-/*
203737
-** Create a new JsonNode instance based on the arguments and append that
203738
-** instance to the JsonParse. Return the index in pParse->aNode[] of the
203739
-** new node, or -1 if a memory allocation fails.
203740
-*/
203741
-static int jsonParseAddNode(
203742
- JsonParse *pParse, /* Append the node to this object */
203743
- u32 eType, /* Node type */
203744
- u32 n, /* Content size or sub-node count */
203745
- const char *zContent /* Content */
203746
-){
203747
- JsonNode *p;
203748
- assert( pParse->aNode!=0 || pParse->nNode>=pParse->nAlloc );
203749
- if( pParse->nNode>=pParse->nAlloc ){
203750
- return jsonParseAddNodeExpand(pParse, eType, n, zContent);
203751
- }
203752
- assert( pParse->aNode!=0 );
203753
- p = &pParse->aNode[pParse->nNode];
203754
- assert( p!=0 );
203755
- p->eType = (u8)(eType & 0xff);
203756
- p->jnFlags = (u8)(eType >> 8);
203757
- VVA( p->eU = zContent ? 1 : 0 );
203758
- p->n = n;
203759
- p->u.zJContent = zContent;
203760
- return pParse->nNode++;
203761
-}
203762
-
203763
-/*
203764
-** Add an array of new nodes to the current pParse->aNode array.
203765
-** Return the index of the first node added.
203766
-**
203767
-** If an OOM error occurs, set pParse->oom.
203768
-*/
203769
-static void jsonParseAddNodeArray(
203770
- JsonParse *pParse, /* Append the node to this object */
203771
- JsonNode *aNode, /* Array of nodes to add */
203772
- u32 nNode /* Number of elements in aNew */
203773
-){
203774
- assert( aNode!=0 );
203775
- assert( nNode>=1 );
203776
- if( pParse->nNode + nNode > pParse->nAlloc ){
203777
- u32 nNew = pParse->nNode + nNode;
203778
- JsonNode *aNew = sqlite3_realloc64(pParse->aNode, nNew*sizeof(JsonNode));
203779
- if( aNew==0 ){
203780
- pParse->oom = 1;
203781
- return;
203782
- }
203783
- pParse->nAlloc = sqlite3_msize(aNew)/sizeof(JsonNode);
203784
- pParse->aNode = aNew;
203785
- }
203786
- memcpy(&pParse->aNode[pParse->nNode], aNode, nNode*sizeof(JsonNode));
203787
- pParse->nNode += nNode;
203788
-}
203789
-
203790
-/*
203791
-** Add a new JSON_SUBST node. The node immediately following
203792
-** this new node will be the substitute content for iNode.
203793
-*/
203794
-static int jsonParseAddSubstNode(
203795
- JsonParse *pParse, /* Add the JSON_SUBST here */
203796
- u32 iNode /* References this node */
203797
-){
203798
- int idx = jsonParseAddNode(pParse, JSON_SUBST, iNode, 0);
203799
- if( pParse->oom ) return -1;
203800
- pParse->aNode[iNode].jnFlags |= JNODE_REPLACE;
203801
- pParse->aNode[idx].eU = 4;
203802
- pParse->aNode[idx].u.iPrev = pParse->iSubst;
203803
- pParse->iSubst = idx;
203804
- pParse->hasMod = 1;
203805
- pParse->useMod = 1;
203806
- return idx;
203807
-}
203808
-
203809203851
/*
203810203852
** Return true if z[] begins with 2 (or more) hexadecimal digits
203811203853
*/
203812203854
static int jsonIs2Hex(const char *z){
203813203855
return sqlite3Isxdigit(z[0]) && sqlite3Isxdigit(z[1]);
@@ -203957,101 +203999,542 @@
203957203999
char eType;
203958204000
char nRepl;
203959204001
char *zMatch;
203960204002
char *zRepl;
203961204003
} aNanInfName[] = {
203962
- { 'i', 'I', 3, JSON_REAL, 7, "inf", "9.0e999" },
203963
- { 'i', 'I', 8, JSON_REAL, 7, "infinity", "9.0e999" },
203964
- { 'n', 'N', 3, JSON_NULL, 4, "NaN", "null" },
203965
- { 'q', 'Q', 4, JSON_NULL, 4, "QNaN", "null" },
203966
- { 's', 'S', 4, JSON_NULL, 4, "SNaN", "null" },
203967
-};
203968
-
203969
-/*
203970
-** Parse a single JSON value which begins at pParse->zJson[i]. Return the
203971
-** index of the first character past the end of the value parsed.
203972
-**
203973
-** Special return values:
204004
+ { 'i', 'I', 3, JSONB_FLOAT, 7, "inf", "9.0e999" },
204005
+ { 'i', 'I', 8, JSONB_FLOAT, 7, "infinity", "9.0e999" },
204006
+ { 'n', 'N', 3, JSONB_NULL, 4, "NaN", "null" },
204007
+ { 'q', 'Q', 4, JSONB_NULL, 4, "QNaN", "null" },
204008
+ { 's', 'S', 4, JSONB_NULL, 4, "SNaN", "null" },
204009
+};
204010
+
204011
+
204012
+/*
204013
+** Report the wrong number of arguments for json_insert(), json_replace()
204014
+** or json_set().
204015
+*/
204016
+static void jsonWrongNumArgs(
204017
+ sqlite3_context *pCtx,
204018
+ const char *zFuncName
204019
+){
204020
+ char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments",
204021
+ zFuncName);
204022
+ sqlite3_result_error(pCtx, zMsg, -1);
204023
+ sqlite3_free(zMsg);
204024
+}
204025
+
204026
+/****************************************************************************
204027
+** Utility routines for dealing with the binary BLOB representation of JSON
204028
+****************************************************************************/
204029
+
204030
+/*
204031
+** Expand pParse->aBlob so that it holds at least N bytes.
204032
+**
204033
+** Return the number of errors.
204034
+*/
204035
+static int jsonBlobExpand(JsonParse *pParse, u32 N){
204036
+ u8 *aNew;
204037
+ u32 t;
204038
+ assert( N>pParse->nBlobAlloc );
204039
+ if( pParse->nBlobAlloc==0 ){
204040
+ t = 100;
204041
+ }else{
204042
+ t = pParse->nBlobAlloc*2;
204043
+ }
204044
+ if( t<N ) t = N+100;
204045
+ aNew = sqlite3_realloc64( pParse->aBlob, t );
204046
+ if( aNew==0 ){ pParse->oom = 1; return 1; }
204047
+ pParse->aBlob = aNew;
204048
+ pParse->nBlobAlloc = t;
204049
+ return 0;
204050
+}
204051
+
204052
+/*
204053
+** If pParse->aBlob is not previously editable (because it is taken
204054
+** from sqlite3_value_blob(), as indicated by the fact that
204055
+** pParse->nBlobAlloc==0 and pParse->nBlob>0) then make it editable
204056
+** by making a copy into space obtained from malloc.
204057
+**
204058
+** Return true on success. Return false on OOM.
204059
+*/
204060
+static int jsonBlobMakeEditable(JsonParse *pParse, u32 nExtra){
204061
+ u8 *aOld;
204062
+ u32 nSize;
204063
+ assert( !pParse->bReadOnly );
204064
+ if( pParse->oom ) return 0;
204065
+ if( pParse->nBlobAlloc>0 ) return 1;
204066
+ aOld = pParse->aBlob;
204067
+ nSize = pParse->nBlob + nExtra;
204068
+ pParse->aBlob = 0;
204069
+ if( jsonBlobExpand(pParse, nSize) ){
204070
+ return 0;
204071
+ }
204072
+ assert( pParse->nBlobAlloc >= pParse->nBlob + nExtra );
204073
+ memcpy(pParse->aBlob, aOld, pParse->nBlob);
204074
+ return 1;
204075
+}
204076
+
204077
+/* Expand pParse->aBlob and append one bytes.
204078
+*/
204079
+static SQLITE_NOINLINE void jsonBlobExpandAndAppendOneByte(
204080
+ JsonParse *pParse,
204081
+ u8 c
204082
+){
204083
+ jsonBlobExpand(pParse, pParse->nBlob+1);
204084
+ if( pParse->oom==0 ){
204085
+ assert( pParse->nBlob+1<=pParse->nBlobAlloc );
204086
+ pParse->aBlob[pParse->nBlob++] = c;
204087
+ }
204088
+}
204089
+
204090
+/* Append a single character.
204091
+*/
204092
+static void jsonBlobAppendOneByte(JsonParse *pParse, u8 c){
204093
+ if( pParse->nBlob >= pParse->nBlobAlloc ){
204094
+ jsonBlobExpandAndAppendOneByte(pParse, c);
204095
+ }else{
204096
+ pParse->aBlob[pParse->nBlob++] = c;
204097
+ }
204098
+}
204099
+
204100
+/* Slow version of jsonBlobAppendNode() that first resizes the
204101
+** pParse->aBlob structure.
204102
+*/
204103
+static void jsonBlobAppendNode(JsonParse*,u8,u32,const void*);
204104
+static SQLITE_NOINLINE void jsonBlobExpandAndAppendNode(
204105
+ JsonParse *pParse,
204106
+ u8 eType,
204107
+ u32 szPayload,
204108
+ const void *aPayload
204109
+){
204110
+ if( jsonBlobExpand(pParse, pParse->nBlob+szPayload+9) ) return;
204111
+ jsonBlobAppendNode(pParse, eType, szPayload, aPayload);
204112
+}
204113
+
204114
+
204115
+/* Append an node type byte together with the payload size and
204116
+** possibly also the payload.
204117
+**
204118
+** If aPayload is not NULL, then it is a pointer to the payload which
204119
+** is also appended. If aPayload is NULL, the pParse->aBlob[] array
204120
+** is resized (if necessary) so that it is big enough to hold the
204121
+** payload, but the payload is not appended and pParse->nBlob is left
204122
+** pointing to where the first byte of payload will eventually be.
204123
+*/
204124
+static void jsonBlobAppendNode(
204125
+ JsonParse *pParse, /* The JsonParse object under construction */
204126
+ u8 eType, /* Node type. One of JSONB_* */
204127
+ u32 szPayload, /* Number of bytes of payload */
204128
+ const void *aPayload /* The payload. Might be NULL */
204129
+){
204130
+ u8 *a;
204131
+ if( pParse->nBlob+szPayload+9 > pParse->nBlobAlloc ){
204132
+ jsonBlobExpandAndAppendNode(pParse,eType,szPayload,aPayload);
204133
+ return;
204134
+ }
204135
+ assert( pParse->aBlob!=0 );
204136
+ a = &pParse->aBlob[pParse->nBlob];
204137
+ if( szPayload<=11 ){
204138
+ a[0] = eType | (szPayload<<4);
204139
+ pParse->nBlob += 1;
204140
+ }else if( szPayload<=0xff ){
204141
+ a[0] = eType | 0xc0;
204142
+ a[1] = szPayload & 0xff;
204143
+ pParse->nBlob += 2;
204144
+ }else if( szPayload<=0xffff ){
204145
+ a[0] = eType | 0xd0;
204146
+ a[1] = (szPayload >> 8) & 0xff;
204147
+ a[2] = szPayload & 0xff;
204148
+ pParse->nBlob += 3;
204149
+ }else{
204150
+ a[0] = eType | 0xe0;
204151
+ a[1] = (szPayload >> 24) & 0xff;
204152
+ a[2] = (szPayload >> 16) & 0xff;
204153
+ a[3] = (szPayload >> 8) & 0xff;
204154
+ a[4] = szPayload & 0xff;
204155
+ pParse->nBlob += 5;
204156
+ }
204157
+ if( aPayload ){
204158
+ pParse->nBlob += szPayload;
204159
+ memcpy(&pParse->aBlob[pParse->nBlob-szPayload], aPayload, szPayload);
204160
+ }
204161
+}
204162
+
204163
+/* Change the payload size for the node at index i to be szPayload.
204164
+*/
204165
+static int jsonBlobChangePayloadSize(
204166
+ JsonParse *pParse,
204167
+ u32 i,
204168
+ u32 szPayload
204169
+){
204170
+ u8 *a;
204171
+ u8 szType;
204172
+ u8 nExtra;
204173
+ u8 nNeeded;
204174
+ int delta;
204175
+ if( pParse->oom ) return 0;
204176
+ a = &pParse->aBlob[i];
204177
+ szType = a[0]>>4;
204178
+ if( szType<=11 ){
204179
+ nExtra = 0;
204180
+ }else if( szType==12 ){
204181
+ nExtra = 1;
204182
+ }else if( szType==13 ){
204183
+ nExtra = 2;
204184
+ }else{
204185
+ nExtra = 4;
204186
+ }
204187
+ if( szPayload<=11 ){
204188
+ nNeeded = 0;
204189
+ }else if( szPayload<=0xff ){
204190
+ nNeeded = 1;
204191
+ }else if( szPayload<=0xffff ){
204192
+ nNeeded = 2;
204193
+ }else{
204194
+ nNeeded = 4;
204195
+ }
204196
+ delta = nNeeded - nExtra;
204197
+ if( delta ){
204198
+ u32 newSize = pParse->nBlob + delta;
204199
+ if( delta>0 ){
204200
+ if( newSize>pParse->nBlobAlloc && jsonBlobExpand(pParse, newSize) ){
204201
+ return 0; /* OOM error. Error state recorded in pParse->oom. */
204202
+ }
204203
+ a = &pParse->aBlob[i];
204204
+ memmove(&a[1+delta], &a[1], pParse->nBlob - (i+1));
204205
+ }else{
204206
+ memmove(&a[1], &a[1-delta], pParse->nBlob - (i+1-delta));
204207
+ }
204208
+ pParse->nBlob = newSize;
204209
+ }
204210
+ if( nNeeded==0 ){
204211
+ a[0] = (a[0] & 0x0f) | (szPayload<<4);
204212
+ }else if( nNeeded==1 ){
204213
+ a[0] = (a[0] & 0x0f) | 0xc0;
204214
+ a[1] = szPayload & 0xff;
204215
+ }else if( nNeeded==2 ){
204216
+ a[0] = (a[0] & 0x0f) | 0xd0;
204217
+ a[1] = (szPayload >> 8) & 0xff;
204218
+ a[2] = szPayload & 0xff;
204219
+ }else{
204220
+ a[0] = (a[0] & 0x0f) | 0xe0;
204221
+ a[1] = (szPayload >> 24) & 0xff;
204222
+ a[2] = (szPayload >> 16) & 0xff;
204223
+ a[3] = (szPayload >> 8) & 0xff;
204224
+ a[4] = szPayload & 0xff;
204225
+ }
204226
+ return delta;
204227
+}
204228
+
204229
+/*
204230
+** If z[0] is 'u' and is followed by exactly 4 hexadecimal character,
204231
+** then set *pOp to JSONB_TEXTJ and return true. If not, do not make
204232
+** any changes to *pOp and return false.
204233
+*/
204234
+static int jsonIs4HexB(const char *z, int *pOp){
204235
+ if( z[0]!='u' ) return 0;
204236
+ if( !sqlite3Isxdigit(z[1]) ) return 0;
204237
+ if( !sqlite3Isxdigit(z[2]) ) return 0;
204238
+ if( !sqlite3Isxdigit(z[3]) ) return 0;
204239
+ if( !sqlite3Isxdigit(z[4]) ) return 0;
204240
+ *pOp = JSONB_TEXTJ;
204241
+ return 1;
204242
+}
204243
+
204244
+
204245
+/*
204246
+** Check a single element of the JSONB in pParse for validity.
204247
+**
204248
+** The element to be checked starts at offset i and must end at on the
204249
+** last byte before iEnd.
204250
+**
204251
+** Return 0 if everything is correct. Return the 1-based byte offset of the
204252
+** error if a problem is detected. (In other words, if the error is at offset
204253
+** 0, return 1).
204254
+*/
204255
+static u32 jsonbValidityCheck(
204256
+ const JsonParse *pParse, /* Input JSONB. Only aBlob and nBlob are used */
204257
+ u32 i, /* Start of element as pParse->aBlob[i] */
204258
+ u32 iEnd, /* One more than the last byte of the element */
204259
+ u32 iDepth /* Current nesting depth */
204260
+){
204261
+ u32 n, sz, j, k;
204262
+ const u8 *z;
204263
+ u8 x;
204264
+ if( iDepth>JSON_MAX_DEPTH ) return i+1;
204265
+ sz = 0;
204266
+ n = jsonbPayloadSize(pParse, i, &sz);
204267
+ if( NEVER(n==0) ) return i+1; /* Checked by caller */
204268
+ if( NEVER(i+n+sz!=iEnd) ) return i+1; /* Checked by caller */
204269
+ z = pParse->aBlob;
204270
+ x = z[i] & 0x0f;
204271
+ switch( x ){
204272
+ case JSONB_NULL:
204273
+ case JSONB_TRUE:
204274
+ case JSONB_FALSE: {
204275
+ return n+sz==1 ? 0 : i+1;
204276
+ }
204277
+ case JSONB_INT: {
204278
+ if( sz<1 ) return i+1;
204279
+ j = i+n;
204280
+ if( z[j]=='-' ){
204281
+ j++;
204282
+ if( sz<2 ) return i+1;
204283
+ }
204284
+ k = i+n+sz;
204285
+ while( j<k ){
204286
+ if( sqlite3Isdigit(z[j]) ){
204287
+ j++;
204288
+ }else{
204289
+ return j+1;
204290
+ }
204291
+ }
204292
+ return 0;
204293
+ }
204294
+ case JSONB_INT5: {
204295
+ if( sz<3 ) return i+1;
204296
+ j = i+n;
204297
+ if( z[j]=='-' ){
204298
+ if( sz<4 ) return i+1;
204299
+ j++;
204300
+ }
204301
+ if( z[j]!='0' ) return i+1;
204302
+ if( z[j+1]!='x' && z[j+1]!='X' ) return j+2;
204303
+ j += 2;
204304
+ k = i+n+sz;
204305
+ while( j<k ){
204306
+ if( sqlite3Isxdigit(z[j]) ){
204307
+ j++;
204308
+ }else{
204309
+ return j+1;
204310
+ }
204311
+ }
204312
+ return 0;
204313
+ }
204314
+ case JSONB_FLOAT:
204315
+ case JSONB_FLOAT5: {
204316
+ u8 seen = 0; /* 0: initial. 1: '.' seen 2: 'e' seen */
204317
+ if( sz<2 ) return i+1;
204318
+ j = i+n;
204319
+ k = j+sz;
204320
+ if( z[j]=='-' ){
204321
+ j++;
204322
+ if( sz<3 ) return i+1;
204323
+ }
204324
+ if( z[j]=='.' ){
204325
+ if( x==JSONB_FLOAT ) return j+1;
204326
+ if( !sqlite3Isdigit(z[j+1]) ) return j+1;
204327
+ j += 2;
204328
+ seen = 1;
204329
+ }else if( z[j]=='0' && x==JSONB_FLOAT ){
204330
+ if( j+3>k ) return j+1;
204331
+ if( z[j+1]!='.' && z[j+1]!='e' && z[j+1]!='E' ) return j+1;
204332
+ j++;
204333
+ }
204334
+ for(; j<k; j++){
204335
+ if( sqlite3Isdigit(z[j]) ) continue;
204336
+ if( z[j]=='.' ){
204337
+ if( seen>0 ) return j+1;
204338
+ if( x==JSONB_FLOAT && (j==k-1 || !sqlite3Isdigit(z[j+1])) ){
204339
+ return j+1;
204340
+ }
204341
+ seen = 1;
204342
+ continue;
204343
+ }
204344
+ if( z[j]=='e' || z[j]=='E' ){
204345
+ if( seen==2 ) return j+1;
204346
+ if( j==k-1 ) return j+1;
204347
+ if( z[j+1]=='+' || z[j+1]=='-' ){
204348
+ j++;
204349
+ if( j==k-1 ) return j+1;
204350
+ }
204351
+ seen = 2;
204352
+ continue;
204353
+ }
204354
+ return j+1;
204355
+ }
204356
+ if( seen==0 ) return i+1;
204357
+ return 0;
204358
+ }
204359
+ case JSONB_TEXT: {
204360
+ j = i+n;
204361
+ k = j+sz;
204362
+ while( j<k ){
204363
+ if( !jsonIsOk[z[j]] && z[j]!='\'' ) return j+1;
204364
+ j++;
204365
+ }
204366
+ return 0;
204367
+ }
204368
+ case JSONB_TEXTJ:
204369
+ case JSONB_TEXT5: {
204370
+ j = i+n;
204371
+ k = j+sz;
204372
+ while( j<k ){
204373
+ if( !jsonIsOk[z[j]] && z[j]!='\'' ){
204374
+ if( z[j]=='"' ){
204375
+ if( x==JSONB_TEXTJ ) return j+1;
204376
+ }else if( z[j]!='\\' || j+1>=k ){
204377
+ return j+1;
204378
+ }else if( strchr("\"\\/bfnrt",z[j+1])!=0 ){
204379
+ j++;
204380
+ }else if( z[j+1]=='u' ){
204381
+ if( j+5>=k ) return j+1;
204382
+ if( !jsonIs4Hex((const char*)&z[j+2]) ) return j+1;
204383
+ j++;
204384
+ }else if( x!=JSONB_TEXT5 ){
204385
+ return j+1;
204386
+ }else{
204387
+ u32 c = 0;
204388
+ u32 szC = jsonUnescapeOneChar((const char*)&z[j], k-j, &c);
204389
+ if( c==0xfffd ) return j+1;
204390
+ j += szC - 1;
204391
+ }
204392
+ }
204393
+ j++;
204394
+ }
204395
+ return 0;
204396
+ }
204397
+ case JSONB_TEXTRAW: {
204398
+ return 0;
204399
+ }
204400
+ case JSONB_ARRAY: {
204401
+ u32 sub;
204402
+ j = i+n;
204403
+ k = j+sz;
204404
+ while( j<k ){
204405
+ sz = 0;
204406
+ n = jsonbPayloadSize(pParse, j, &sz);
204407
+ if( n==0 ) return j+1;
204408
+ if( j+n+sz>k ) return j+1;
204409
+ sub = jsonbValidityCheck(pParse, j, j+n+sz, iDepth+1);
204410
+ if( sub ) return sub;
204411
+ j += n + sz;
204412
+ }
204413
+ assert( j==k );
204414
+ return 0;
204415
+ }
204416
+ case JSONB_OBJECT: {
204417
+ u32 cnt = 0;
204418
+ u32 sub;
204419
+ j = i+n;
204420
+ k = j+sz;
204421
+ while( j<k ){
204422
+ sz = 0;
204423
+ n = jsonbPayloadSize(pParse, j, &sz);
204424
+ if( n==0 ) return j+1;
204425
+ if( j+n+sz>k ) return j+1;
204426
+ if( (cnt & 1)==0 ){
204427
+ x = z[j] & 0x0f;
204428
+ if( x<JSONB_TEXT || x>JSONB_TEXTRAW ) return j+1;
204429
+ }
204430
+ sub = jsonbValidityCheck(pParse, j, j+n+sz, iDepth+1);
204431
+ if( sub ) return sub;
204432
+ cnt++;
204433
+ j += n + sz;
204434
+ }
204435
+ assert( j==k );
204436
+ if( (cnt & 1)!=0 ) return j+1;
204437
+ return 0;
204438
+ }
204439
+ default: {
204440
+ return i+1;
204441
+ }
204442
+ }
204443
+}
204444
+
204445
+/*
204446
+** Translate a single element of JSON text at pParse->zJson[i] into
204447
+** its equivalent binary JSONB representation. Append the translation into
204448
+** pParse->aBlob[] beginning at pParse->nBlob. The size of
204449
+** pParse->aBlob[] is increased as necessary.
204450
+**
204451
+** Return the index of the first character past the end of the element parsed,
204452
+** or one of the following special result codes:
203974204453
**
203975204454
** 0 End of input
203976
-** -1 Syntax error
203977
-** -2 '}' seen
203978
-** -3 ']' seen
203979
-** -4 ',' seen
203980
-** -5 ':' seen
204455
+** -1 Syntax error or OOM
204456
+** -2 '}' seen \
204457
+** -3 ']' seen \___ For these returns, pParse->iErr is set to
204458
+** -4 ',' seen / the index in zJson[] of the seen character
204459
+** -5 ':' seen /
203981204460
*/
203982
-static int jsonParseValue(JsonParse *pParse, u32 i){
204461
+static int jsonXlateTextToBlob(JsonParse *pParse, u32 i){
203983204462
char c;
203984204463
u32 j;
203985
- int iThis;
204464
+ u32 iThis, iStart;
203986204465
int x;
203987
- JsonNode *pNode;
204466
+ u8 t;
203988204467
const char *z = pParse->zJson;
203989204468
json_parse_restart:
203990204469
switch( (u8)z[i] ){
203991204470
case '{': {
203992204471
/* Parse object */
203993
- iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
203994
- if( iThis<0 ) return -1;
204472
+ iThis = pParse->nBlob;
204473
+ jsonBlobAppendNode(pParse, JSONB_OBJECT, pParse->nJson-i, 0);
203995204474
if( ++pParse->iDepth > JSON_MAX_DEPTH ){
203996204475
pParse->iErr = i;
203997204476
return -1;
203998204477
}
204478
+ iStart = pParse->nBlob;
203999204479
for(j=i+1;;j++){
204000
- u32 nNode = pParse->nNode;
204001
- x = jsonParseValue(pParse, j);
204480
+ u32 iBlob = pParse->nBlob;
204481
+ x = jsonXlateTextToBlob(pParse, j);
204002204482
if( x<=0 ){
204483
+ int op;
204003204484
if( x==(-2) ){
204004204485
j = pParse->iErr;
204005
- if( pParse->nNode!=(u32)iThis+1 ) pParse->hasNonstd = 1;
204486
+ if( pParse->nBlob!=(u32)iStart ) pParse->hasNonstd = 1;
204006204487
break;
204007204488
}
204008204489
j += json5Whitespace(&z[j]);
204490
+ op = JSONB_TEXT;
204009204491
if( sqlite3JsonId1(z[j])
204010
- || (z[j]=='\\' && z[j+1]=='u' && jsonIs4Hex(&z[j+2]))
204492
+ || (z[j]=='\\' && jsonIs4HexB(&z[j+1], &op))
204011204493
){
204012204494
int k = j+1;
204013204495
while( (sqlite3JsonId2(z[k]) && json5Whitespace(&z[k])==0)
204014
- || (z[k]=='\\' && z[k+1]=='u' && jsonIs4Hex(&z[k+2]))
204496
+ || (z[k]=='\\' && jsonIs4HexB(&z[k+1], &op))
204015204497
){
204016204498
k++;
204017204499
}
204018
- jsonParseAddNode(pParse, JSON_STRING | (JNODE_RAW<<8), k-j, &z[j]);
204500
+ assert( iBlob==pParse->nBlob );
204501
+ jsonBlobAppendNode(pParse, op, k-j, &z[j]);
204019204502
pParse->hasNonstd = 1;
204020204503
x = k;
204021204504
}else{
204022204505
if( x!=-1 ) pParse->iErr = j;
204023204506
return -1;
204024204507
}
204025204508
}
204026204509
if( pParse->oom ) return -1;
204027
- pNode = &pParse->aNode[nNode];
204028
- if( pNode->eType!=JSON_STRING ){
204510
+ t = pParse->aBlob[iBlob] & 0x0f;
204511
+ if( t<JSONB_TEXT || t>JSONB_TEXTRAW ){
204029204512
pParse->iErr = j;
204030204513
return -1;
204031204514
}
204032
- pNode->jnFlags |= JNODE_LABEL;
204033204515
j = x;
204034204516
if( z[j]==':' ){
204035204517
j++;
204036204518
}else{
204037
- if( fast_isspace(z[j]) ){
204038
- do{ j++; }while( fast_isspace(z[j]) );
204519
+ if( jsonIsspace(z[j]) ){
204520
+ /* strspn() is not helpful here */
204521
+ do{ j++; }while( jsonIsspace(z[j]) );
204039204522
if( z[j]==':' ){
204040204523
j++;
204041204524
goto parse_object_value;
204042204525
}
204043204526
}
204044
- x = jsonParseValue(pParse, j);
204527
+ x = jsonXlateTextToBlob(pParse, j);
204045204528
if( x!=(-5) ){
204046204529
if( x!=(-1) ) pParse->iErr = j;
204047204530
return -1;
204048204531
}
204049204532
j = pParse->iErr+1;
204050204533
}
204051204534
parse_object_value:
204052
- x = jsonParseValue(pParse, j);
204535
+ x = jsonXlateTextToBlob(pParse, j);
204053204536
if( x<=0 ){
204054204537
if( x!=(-1) ) pParse->iErr = j;
204055204538
return -1;
204056204539
}
204057204540
j = x;
@@ -204058,19 +204541,19 @@
204058204541
if( z[j]==',' ){
204059204542
continue;
204060204543
}else if( z[j]=='}' ){
204061204544
break;
204062204545
}else{
204063
- if( fast_isspace(z[j]) ){
204064
- do{ j++; }while( fast_isspace(z[j]) );
204546
+ if( jsonIsspace(z[j]) ){
204547
+ j += 1 + (u32)strspn(&z[j+1], jsonSpaces);
204065204548
if( z[j]==',' ){
204066204549
continue;
204067204550
}else if( z[j]=='}' ){
204068204551
break;
204069204552
}
204070204553
}
204071
- x = jsonParseValue(pParse, j);
204554
+ x = jsonXlateTextToBlob(pParse, j);
204072204555
if( x==(-4) ){
204073204556
j = pParse->iErr;
204074204557
continue;
204075204558
}
204076204559
if( x==(-2) ){
@@ -204079,29 +204562,30 @@
204079204562
}
204080204563
}
204081204564
pParse->iErr = j;
204082204565
return -1;
204083204566
}
204084
- pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
204567
+ jsonBlobChangePayloadSize(pParse, iThis, pParse->nBlob - iStart);
204085204568
pParse->iDepth--;
204086204569
return j+1;
204087204570
}
204088204571
case '[': {
204089204572
/* Parse array */
204090
- iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
204091
- if( iThis<0 ) return -1;
204573
+ iThis = pParse->nBlob;
204574
+ jsonBlobAppendNode(pParse, JSONB_ARRAY, pParse->nJson - i, 0);
204575
+ iStart = pParse->nBlob;
204576
+ if( pParse->oom ) return -1;
204092204577
if( ++pParse->iDepth > JSON_MAX_DEPTH ){
204093204578
pParse->iErr = i;
204094204579
return -1;
204095204580
}
204096
- memset(&pParse->aNode[iThis].u, 0, sizeof(pParse->aNode[iThis].u));
204097204581
for(j=i+1;;j++){
204098
- x = jsonParseValue(pParse, j);
204582
+ x = jsonXlateTextToBlob(pParse, j);
204099204583
if( x<=0 ){
204100204584
if( x==(-3) ){
204101204585
j = pParse->iErr;
204102
- if( pParse->nNode!=(u32)iThis+1 ) pParse->hasNonstd = 1;
204586
+ if( pParse->nBlob!=iStart ) pParse->hasNonstd = 1;
204103204587
break;
204104204588
}
204105204589
if( x!=(-1) ) pParse->iErr = j;
204106204590
return -1;
204107204591
}
@@ -204109,19 +204593,19 @@
204109204593
if( z[j]==',' ){
204110204594
continue;
204111204595
}else if( z[j]==']' ){
204112204596
break;
204113204597
}else{
204114
- if( fast_isspace(z[j]) ){
204115
- do{ j++; }while( fast_isspace(z[j]) );
204598
+ if( jsonIsspace(z[j]) ){
204599
+ j += 1 + (u32)strspn(&z[j+1], jsonSpaces);
204116204600
if( z[j]==',' ){
204117204601
continue;
204118204602
}else if( z[j]==']' ){
204119204603
break;
204120204604
}
204121204605
}
204122
- x = jsonParseValue(pParse, j);
204606
+ x = jsonXlateTextToBlob(pParse, j);
204123204607
if( x==(-4) ){
204124204608
j = pParse->iErr;
204125204609
continue;
204126204610
}
204127204611
if( x==(-3) ){
@@ -204130,86 +204614,98 @@
204130204614
}
204131204615
}
204132204616
pParse->iErr = j;
204133204617
return -1;
204134204618
}
204135
- pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
204619
+ jsonBlobChangePayloadSize(pParse, iThis, pParse->nBlob - iStart);
204136204620
pParse->iDepth--;
204137204621
return j+1;
204138204622
}
204139204623
case '\'': {
204140
- u8 jnFlags;
204624
+ u8 opcode;
204141204625
char cDelim;
204142204626
pParse->hasNonstd = 1;
204143
- jnFlags = JNODE_JSON5;
204627
+ opcode = JSONB_TEXT;
204144204628
goto parse_string;
204145204629
case '"':
204146204630
/* Parse string */
204147
- jnFlags = 0;
204631
+ opcode = JSONB_TEXT;
204148204632
parse_string:
204149204633
cDelim = z[i];
204150
- for(j=i+1; 1; j++){
204151
- if( jsonIsOk[(unsigned char)z[j]] ) continue;
204634
+ j = i+1;
204635
+ while( 1 /*exit-by-break*/ ){
204636
+ if( jsonIsOk[(u8)z[j]] ){
204637
+ if( !jsonIsOk[(u8)z[j+1]] ){
204638
+ j += 1;
204639
+ }else if( !jsonIsOk[(u8)z[j+2]] ){
204640
+ j += 2;
204641
+ }else{
204642
+ j += 3;
204643
+ continue;
204644
+ }
204645
+ }
204152204646
c = z[j];
204153204647
if( c==cDelim ){
204154204648
break;
204155204649
}else if( c=='\\' ){
204156204650
c = z[++j];
204157204651
if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f'
204158204652
|| c=='n' || c=='r' || c=='t'
204159204653
|| (c=='u' && jsonIs4Hex(&z[j+1])) ){
204160
- jnFlags |= JNODE_ESCAPE;
204654
+ if( opcode==JSONB_TEXT ) opcode = JSONB_TEXTJ;
204161204655
}else if( c=='\'' || c=='0' || c=='v' || c=='\n'
204162204656
|| (0xe2==(u8)c && 0x80==(u8)z[j+1]
204163204657
&& (0xa8==(u8)z[j+2] || 0xa9==(u8)z[j+2]))
204164204658
|| (c=='x' && jsonIs2Hex(&z[j+1])) ){
204165
- jnFlags |= (JNODE_ESCAPE|JNODE_JSON5);
204659
+ opcode = JSONB_TEXT5;
204166204660
pParse->hasNonstd = 1;
204167204661
}else if( c=='\r' ){
204168204662
if( z[j+1]=='\n' ) j++;
204169
- jnFlags |= (JNODE_ESCAPE|JNODE_JSON5);
204663
+ opcode = JSONB_TEXT5;
204170204664
pParse->hasNonstd = 1;
204171204665
}else{
204172204666
pParse->iErr = j;
204173204667
return -1;
204174204668
}
204175204669
}else if( c<=0x1f ){
204176204670
/* Control characters are not allowed in strings */
204177204671
pParse->iErr = j;
204178204672
return -1;
204673
+ }else if( c=='"' ){
204674
+ opcode = JSONB_TEXT5;
204179204675
}
204676
+ j++;
204180204677
}
204181
- jsonParseAddNode(pParse, JSON_STRING | (jnFlags<<8), j+1-i, &z[i]);
204678
+ jsonBlobAppendNode(pParse, opcode, j-1-i, &z[i+1]);
204182204679
return j+1;
204183204680
}
204184204681
case 't': {
204185204682
if( strncmp(z+i,"true",4)==0 && !sqlite3Isalnum(z[i+4]) ){
204186
- jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
204683
+ jsonBlobAppendOneByte(pParse, JSONB_TRUE);
204187204684
return i+4;
204188204685
}
204189204686
pParse->iErr = i;
204190204687
return -1;
204191204688
}
204192204689
case 'f': {
204193204690
if( strncmp(z+i,"false",5)==0 && !sqlite3Isalnum(z[i+5]) ){
204194
- jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
204691
+ jsonBlobAppendOneByte(pParse, JSONB_FALSE);
204195204692
return i+5;
204196204693
}
204197204694
pParse->iErr = i;
204198204695
return -1;
204199204696
}
204200204697
case '+': {
204201
- u8 seenDP, seenE, jnFlags;
204698
+ u8 seenE;
204202204699
pParse->hasNonstd = 1;
204203
- jnFlags = JNODE_JSON5;
204700
+ t = 0x00; /* Bit 0x01: JSON5. Bit 0x02: FLOAT */
204204204701
goto parse_number;
204205204702
case '.':
204206204703
if( sqlite3Isdigit(z[i+1]) ){
204207204704
pParse->hasNonstd = 1;
204208
- jnFlags = JNODE_JSON5;
204705
+ t = 0x03; /* Bit 0x01: JSON5. Bit 0x02: FLOAT */
204209204706
seenE = 0;
204210
- seenDP = JSON_REAL;
204211204707
goto parse_number_2;
204212204708
}
204213204709
pParse->iErr = i;
204214204710
return -1;
204215204711
case '-':
@@ -204222,25 +204718,24 @@
204222204718
case '6':
204223204719
case '7':
204224204720
case '8':
204225204721
case '9':
204226204722
/* Parse number */
204227
- jnFlags = 0;
204723
+ t = 0x00; /* Bit 0x01: JSON5. Bit 0x02: FLOAT */
204228204724
parse_number:
204229
- seenDP = JSON_INT;
204230204725
seenE = 0;
204231204726
assert( '-' < '0' );
204232204727
assert( '+' < '0' );
204233204728
assert( '.' < '0' );
204234204729
c = z[i];
204235204730
204236204731
if( c<='0' ){
204237204732
if( c=='0' ){
204238204733
if( (z[i+1]=='x' || z[i+1]=='X') && sqlite3Isxdigit(z[i+2]) ){
204239
- assert( seenDP==JSON_INT );
204734
+ assert( t==0x00 );
204240204735
pParse->hasNonstd = 1;
204241
- jnFlags |= JNODE_JSON5;
204736
+ t = 0x01;
204242204737
for(j=i+3; sqlite3Isxdigit(z[j]); j++){}
204243204738
goto parse_number_finish;
204244204739
}else if( sqlite3Isdigit(z[i+1]) ){
204245204740
pParse->iErr = i+1;
204246204741
return -1;
@@ -204253,19 +204748,19 @@
204253204748
if( (z[i+1]=='I' || z[i+1]=='i')
204254204749
&& sqlite3StrNICmp(&z[i+1], "inf",3)==0
204255204750
){
204256204751
pParse->hasNonstd = 1;
204257204752
if( z[i]=='-' ){
204258
- jsonParseAddNode(pParse, JSON_REAL, 8, "-9.0e999");
204753
+ jsonBlobAppendNode(pParse, JSONB_FLOAT, 6, "-9e999");
204259204754
}else{
204260
- jsonParseAddNode(pParse, JSON_REAL, 7, "9.0e999");
204755
+ jsonBlobAppendNode(pParse, JSONB_FLOAT, 5, "9e999");
204261204756
}
204262204757
return i + (sqlite3StrNICmp(&z[i+4],"inity",5)==0 ? 9 : 4);
204263204758
}
204264204759
if( z[i+1]=='.' ){
204265204760
pParse->hasNonstd = 1;
204266
- jnFlags |= JNODE_JSON5;
204761
+ t |= 0x01;
204267204762
goto parse_number_2;
204268204763
}
204269204764
pParse->iErr = i;
204270204765
return -1;
204271204766
}
@@ -204273,44 +204768,45 @@
204273204768
if( sqlite3Isdigit(z[i+2]) ){
204274204769
pParse->iErr = i+1;
204275204770
return -1;
204276204771
}else if( (z[i+2]=='x' || z[i+2]=='X') && sqlite3Isxdigit(z[i+3]) ){
204277204772
pParse->hasNonstd = 1;
204278
- jnFlags |= JNODE_JSON5;
204773
+ t |= 0x01;
204279204774
for(j=i+4; sqlite3Isxdigit(z[j]); j++){}
204280204775
goto parse_number_finish;
204281204776
}
204282204777
}
204283204778
}
204284204779
}
204780
+
204285204781
parse_number_2:
204286204782
for(j=i+1;; j++){
204287204783
c = z[j];
204288204784
if( sqlite3Isdigit(c) ) continue;
204289204785
if( c=='.' ){
204290
- if( seenDP==JSON_REAL ){
204786
+ if( (t & 0x02)!=0 ){
204291204787
pParse->iErr = j;
204292204788
return -1;
204293204789
}
204294
- seenDP = JSON_REAL;
204790
+ t |= 0x02;
204295204791
continue;
204296204792
}
204297204793
if( c=='e' || c=='E' ){
204298204794
if( z[j-1]<'0' ){
204299204795
if( ALWAYS(z[j-1]=='.') && ALWAYS(j-2>=i) && sqlite3Isdigit(z[j-2]) ){
204300204796
pParse->hasNonstd = 1;
204301
- jnFlags |= JNODE_JSON5;
204797
+ t |= 0x01;
204302204798
}else{
204303204799
pParse->iErr = j;
204304204800
return -1;
204305204801
}
204306204802
}
204307204803
if( seenE ){
204308204804
pParse->iErr = j;
204309204805
return -1;
204310204806
}
204311
- seenDP = JSON_REAL;
204807
+ t |= 0x02;
204312204808
seenE = 1;
204313204809
c = z[j+1];
204314204810
if( c=='+' || c=='-' ){
204315204811
j++;
204316204812
c = z[j+1];
@@ -204324,18 +204820,22 @@
204324204820
break;
204325204821
}
204326204822
if( z[j-1]<'0' ){
204327204823
if( ALWAYS(z[j-1]=='.') && ALWAYS(j-2>=i) && sqlite3Isdigit(z[j-2]) ){
204328204824
pParse->hasNonstd = 1;
204329
- jnFlags |= JNODE_JSON5;
204825
+ t |= 0x01;
204330204826
}else{
204331204827
pParse->iErr = j;
204332204828
return -1;
204333204829
}
204334204830
}
204335204831
parse_number_finish:
204336
- jsonParseAddNode(pParse, seenDP | (jnFlags<<8), j - i, &z[i]);
204832
+ assert( JSONB_INT+0x01==JSONB_INT5 );
204833
+ assert( JSONB_FLOAT+0x01==JSONB_FLOAT5 );
204834
+ assert( JSONB_INT+0x02==JSONB_FLOAT );
204835
+ if( z[i]=='+' ) i++;
204836
+ jsonBlobAppendNode(pParse, JSONB_INT+t, j-i, &z[i]);
204337204837
return j;
204338204838
}
204339204839
case '}': {
204340204840
pParse->iErr = i;
204341204841
return -2; /* End of {...} */
@@ -204357,13 +204857,11 @@
204357204857
}
204358204858
case 0x09:
204359204859
case 0x0a:
204360204860
case 0x0d:
204361204861
case 0x20: {
204362
- do{
204363
- i++;
204364
- }while( fast_isspace(z[i]) );
204862
+ i += 1 + (u32)strspn(&z[i+1], jsonSpaces);
204365204863
goto json_parse_restart;
204366204864
}
204367204865
case 0x0b:
204368204866
case 0x0c:
204369204867
case '/':
@@ -204381,11 +204879,11 @@
204381204879
pParse->iErr = i;
204382204880
return -1;
204383204881
}
204384204882
case 'n': {
204385204883
if( strncmp(z+i,"null",4)==0 && !sqlite3Isalnum(z[i+4]) ){
204386
- jsonParseAddNode(pParse, JSON_NULL, 0, 0);
204884
+ jsonBlobAppendOneByte(pParse, JSONB_NULL);
204387204885
return i+4;
204388204886
}
204389204887
/* fall-through into the default case that checks for NaN */
204390204888
}
204391204889
default: {
@@ -204397,43 +204895,53 @@
204397204895
nn = aNanInfName[k].n;
204398204896
if( sqlite3StrNICmp(&z[i], aNanInfName[k].zMatch, nn)!=0 ){
204399204897
continue;
204400204898
}
204401204899
if( sqlite3Isalnum(z[i+nn]) ) continue;
204402
- jsonParseAddNode(pParse, aNanInfName[k].eType,
204403
- aNanInfName[k].nRepl, aNanInfName[k].zRepl);
204900
+ if( aNanInfName[k].eType==JSONB_FLOAT ){
204901
+ jsonBlobAppendNode(pParse, JSONB_FLOAT, 5, "9e999");
204902
+ }else{
204903
+ jsonBlobAppendOneByte(pParse, JSONB_NULL);
204904
+ }
204404204905
pParse->hasNonstd = 1;
204405204906
return i + nn;
204406204907
}
204407204908
pParse->iErr = i;
204408204909
return -1; /* Syntax error */
204409204910
}
204410204911
} /* End switch(z[i]) */
204411204912
}
204913
+
204412204914
204413204915
/*
204414204916
** Parse a complete JSON string. Return 0 on success or non-zero if there
204415204917
** are any errors. If an error occurs, free all memory held by pParse,
204416204918
** but not pParse itself.
204417204919
**
204418204920
** pParse must be initialized to an empty parse object prior to calling
204419204921
** this routine.
204420204922
*/
204421
-static int jsonParse(
204923
+static int jsonConvertTextToBlob(
204422204924
JsonParse *pParse, /* Initialize and fill this JsonParse object */
204423204925
sqlite3_context *pCtx /* Report errors here */
204424204926
){
204425204927
int i;
204426204928
const char *zJson = pParse->zJson;
204427
- i = jsonParseValue(pParse, 0);
204929
+ i = jsonXlateTextToBlob(pParse, 0);
204428204930
if( pParse->oom ) i = -1;
204429204931
if( i>0 ){
204932
+#ifdef SQLITE_DEBUG
204430204933
assert( pParse->iDepth==0 );
204431
- while( fast_isspace(zJson[i]) ) i++;
204934
+ if( sqlite3Config.bJsonSelfcheck ){
204935
+ assert( jsonbValidityCheck(pParse, 0, pParse->nBlob, 0)==0 );
204936
+ }
204937
+#endif
204938
+ while( jsonIsspace(zJson[i]) ) i++;
204432204939
if( zJson[i] ){
204433204940
i += json5Whitespace(&zJson[i]);
204434204941
if( zJson[i] ){
204942
+ if( pCtx ) sqlite3_result_error(pCtx, "malformed JSON", -1);
204435204943
jsonParseReset(pParse);
204436204944
return 1;
204437204945
}
204438204946
pParse->hasNonstd = 1;
204439204947
}
@@ -204450,617 +204958,1508 @@
204450204958
return 1;
204451204959
}
204452204960
return 0;
204453204961
}
204454204962
204455
-
204456
-/* Mark node i of pParse as being a child of iParent. Call recursively
204457
-** to fill in all the descendants of node i.
204458
-*/
204459
-static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){
204460
- JsonNode *pNode = &pParse->aNode[i];
204461
- u32 j;
204462
- pParse->aUp[i] = iParent;
204463
- switch( pNode->eType ){
204464
- case JSON_ARRAY: {
204465
- for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){
204466
- jsonParseFillInParentage(pParse, i+j, i);
204467
- }
204468
- break;
204469
- }
204470
- case JSON_OBJECT: {
204471
- for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){
204472
- pParse->aUp[i+j] = i;
204473
- jsonParseFillInParentage(pParse, i+j+1, i);
204474
- }
204475
- break;
204476
- }
204477
- default: {
204478
- break;
204479
- }
204480
- }
204481
-}
204482
-
204483
-/*
204484
-** Compute the parentage of all nodes in a completed parse.
204485
-*/
204486
-static int jsonParseFindParents(JsonParse *pParse){
204487
- u32 *aUp;
204488
- assert( pParse->aUp==0 );
204489
- aUp = pParse->aUp = sqlite3_malloc64( sizeof(u32)*pParse->nNode );
204490
- if( aUp==0 ){
204491
- pParse->oom = 1;
204492
- return SQLITE_NOMEM;
204493
- }
204494
- jsonParseFillInParentage(pParse, 0, 0);
204495
- return SQLITE_OK;
204496
-}
204497
-
204498
-/*
204499
-** Magic number used for the JSON parse cache in sqlite3_get_auxdata()
204500
-*/
204501
-#define JSON_CACHE_ID (-429938) /* First cache entry */
204502
-#define JSON_CACHE_SZ 4 /* Max number of cache entries */
204503
-
204504
-/*
204505
-** Obtain a complete parse of the JSON found in the pJson argument
204506
-**
204507
-** Use the sqlite3_get_auxdata() cache to find a preexisting parse
204508
-** if it is available. If the cache is not available or if it
204509
-** is no longer valid, parse the JSON again and return the new parse.
204510
-** Also register the new parse so that it will be available for
204511
-** future sqlite3_get_auxdata() calls.
204512
-**
204513
-** If an error occurs and pErrCtx!=0 then report the error on pErrCtx
204514
-** and return NULL.
204515
-**
204516
-** The returned pointer (if it is not NULL) is owned by the cache in
204517
-** most cases, not the caller. The caller does NOT need to invoke
204518
-** jsonParseFree(), in most cases.
204519
-**
204520
-** Except, if an error occurs and pErrCtx==0 then return the JsonParse
204521
-** object with JsonParse.nErr non-zero and the caller will own the JsonParse
204522
-** object. In that case, it will be the responsibility of the caller to
204523
-** invoke jsonParseFree(). To summarize:
204524
-**
204525
-** pErrCtx!=0 || p->nErr==0 ==> Return value p is owned by the
204526
-** cache. Call does not need to
204527
-** free it.
204528
-**
204529
-** pErrCtx==0 && p->nErr!=0 ==> Return value is owned by the caller
204530
-** and so the caller must free it.
204531
-*/
204532
-static JsonParse *jsonParseCached(
204533
- sqlite3_context *pCtx, /* Context to use for cache search */
204534
- sqlite3_value *pJson, /* Function param containing JSON text */
204535
- sqlite3_context *pErrCtx, /* Write parse errors here if not NULL */
204536
- int bUnedited /* No prior edits allowed */
204537
-){
204538
- char *zJson = (char*)sqlite3_value_text(pJson);
204539
- int nJson = sqlite3_value_bytes(pJson);
204540
- JsonParse *p;
204541
- JsonParse *pMatch = 0;
204542
- int iKey;
204543
- int iMinKey = 0;
204544
- u32 iMinHold = 0xffffffff;
204545
- u32 iMaxHold = 0;
204546
- int bJsonRCStr;
204547
-
204548
- if( zJson==0 ) return 0;
204549
- for(iKey=0; iKey<JSON_CACHE_SZ; iKey++){
204550
- p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iKey);
204551
- if( p==0 ){
204552
- iMinKey = iKey;
204553
- break;
204554
- }
204555
- if( pMatch==0
204556
- && p->nJson==nJson
204557
- && (p->hasMod==0 || bUnedited==0)
204558
- && (p->zJson==zJson || memcmp(p->zJson,zJson,nJson)==0)
204559
- ){
204560
- p->nErr = 0;
204561
- p->useMod = 0;
204562
- pMatch = p;
204563
- }else
204564
- if( pMatch==0
204565
- && p->zAlt!=0
204566
- && bUnedited==0
204567
- && p->nAlt==nJson
204568
- && memcmp(p->zAlt, zJson, nJson)==0
204569
- ){
204570
- p->nErr = 0;
204571
- p->useMod = 1;
204572
- pMatch = p;
204573
- }else if( p->iHold<iMinHold ){
204574
- iMinHold = p->iHold;
204575
- iMinKey = iKey;
204576
- }
204577
- if( p->iHold>iMaxHold ){
204578
- iMaxHold = p->iHold;
204579
- }
204580
- }
204581
- if( pMatch ){
204582
- /* The input JSON text was found in the cache. Use the preexisting
204583
- ** parse of this JSON */
204584
- pMatch->nErr = 0;
204585
- pMatch->iHold = iMaxHold+1;
204586
- assert( pMatch->nJPRef>0 ); /* pMatch is owned by the cache */
204587
- return pMatch;
204588
- }
204589
-
204590
- /* The input JSON was not found anywhere in the cache. We will need
204591
- ** to parse it ourselves and generate a new JsonParse object.
204592
- */
204593
- bJsonRCStr = sqlite3ValueIsOfClass(pJson,sqlite3RCStrUnref);
204594
- p = sqlite3_malloc64( sizeof(*p) + (bJsonRCStr ? 0 : nJson+1) );
204595
- if( p==0 ){
204596
- sqlite3_result_error_nomem(pCtx);
204597
- return 0;
204598
- }
204599
- memset(p, 0, sizeof(*p));
204600
- if( bJsonRCStr ){
204601
- p->zJson = sqlite3RCStrRef(zJson);
204602
- p->bJsonIsRCStr = 1;
204603
- }else{
204604
- p->zJson = (char*)&p[1];
204605
- memcpy(p->zJson, zJson, nJson+1);
204606
- }
204607
- p->nJPRef = 1;
204608
- if( jsonParse(p, pErrCtx) ){
204609
- if( pErrCtx==0 ){
204610
- p->nErr = 1;
204611
- assert( p->nJPRef==1 ); /* Caller will own the new JsonParse object p */
204612
- return p;
204613
- }
204614
- jsonParseFree(p);
204615
- return 0;
204616
- }
204617
- p->nJson = nJson;
204618
- p->iHold = iMaxHold+1;
204619
- /* Transfer ownership of the new JsonParse to the cache */
204620
- sqlite3_set_auxdata(pCtx, JSON_CACHE_ID+iMinKey, p,
204621
- (void(*)(void*))jsonParseFree);
204622
- return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iMinKey);
204623
-}
204624
-
204625
-/*
204626
-** Compare the OBJECT label at pNode against zKey,nKey. Return true on
204627
-** a match.
204628
-*/
204629
-static int jsonLabelCompare(const JsonNode *pNode, const char *zKey, u32 nKey){
204630
- assert( pNode->eU==1 );
204631
- if( pNode->jnFlags & JNODE_RAW ){
204632
- if( pNode->n!=nKey ) return 0;
204633
- return strncmp(pNode->u.zJContent, zKey, nKey)==0;
204634
- }else{
204635
- if( pNode->n!=nKey+2 ) return 0;
204636
- return strncmp(pNode->u.zJContent+1, zKey, nKey)==0;
204637
- }
204638
-}
204639
-static int jsonSameLabel(const JsonNode *p1, const JsonNode *p2){
204640
- if( p1->jnFlags & JNODE_RAW ){
204641
- return jsonLabelCompare(p2, p1->u.zJContent, p1->n);
204642
- }else if( p2->jnFlags & JNODE_RAW ){
204643
- return jsonLabelCompare(p1, p2->u.zJContent, p2->n);
204644
- }else{
204645
- return p1->n==p2->n && strncmp(p1->u.zJContent,p2->u.zJContent,p1->n)==0;
204646
- }
204647
-}
204648
-
204649
-/* forward declaration */
204650
-static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**);
204651
-
204652
-/*
204653
-** Search along zPath to find the node specified. Return a pointer
204654
-** to that node, or NULL if zPath is malformed or if there is no such
204655
-** node.
204656
-**
204657
-** If pApnd!=0, then try to append new nodes to complete zPath if it is
204658
-** possible to do so and if no existing node corresponds to zPath. If
204659
-** new nodes are appended *pApnd is set to 1.
204660
-*/
204661
-static JsonNode *jsonLookupStep(
204662
- JsonParse *pParse, /* The JSON to search */
204663
- u32 iRoot, /* Begin the search at this node */
204664
- const char *zPath, /* The path to search */
204665
- int *pApnd, /* Append nodes to complete path if not NULL */
204666
- const char **pzErr /* Make *pzErr point to any syntax error in zPath */
204667
-){
204668
- u32 i, j, nKey;
204669
- const char *zKey;
204670
- JsonNode *pRoot;
204671
- if( pParse->oom ) return 0;
204672
- pRoot = &pParse->aNode[iRoot];
204673
- if( pRoot->jnFlags & (JNODE_REPLACE|JNODE_REMOVE) && pParse->useMod ){
204674
- while( (pRoot->jnFlags & JNODE_REPLACE)!=0 ){
204675
- u32 idx = (u32)(pRoot - pParse->aNode);
204676
- i = pParse->iSubst;
204677
- while( 1 /*exit-by-break*/ ){
204678
- assert( i<pParse->nNode );
204679
- assert( pParse->aNode[i].eType==JSON_SUBST );
204680
- assert( pParse->aNode[i].eU==4 );
204681
- assert( pParse->aNode[i].u.iPrev<i );
204682
- if( pParse->aNode[i].n==idx ){
204683
- pRoot = &pParse->aNode[i+1];
204684
- iRoot = i+1;
204685
- break;
204686
- }
204687
- i = pParse->aNode[i].u.iPrev;
204688
- }
204689
- }
204690
- if( pRoot->jnFlags & JNODE_REMOVE ){
204691
- return 0;
204692
- }
204693
- }
204694
- if( zPath[0]==0 ) return pRoot;
204695
- if( zPath[0]=='.' ){
204696
- if( pRoot->eType!=JSON_OBJECT ) return 0;
204963
+/*
204964
+** The input string pStr is a well-formed JSON text string. Convert
204965
+** this into the JSONB format and make it the return value of the
204966
+** SQL function.
204967
+*/
204968
+static void jsonReturnStringAsBlob(JsonString *pStr){
204969
+ JsonParse px;
204970
+ memset(&px, 0, sizeof(px));
204971
+ jsonStringTerminate(pStr);
204972
+ px.zJson = pStr->zBuf;
204973
+ px.nJson = pStr->nUsed;
204974
+ (void)jsonXlateTextToBlob(&px, 0);
204975
+ if( px.oom ){
204976
+ sqlite3_free(px.aBlob);
204977
+ sqlite3_result_error_nomem(pStr->pCtx);
204978
+ }else{
204979
+ assert( px.nBlobAlloc>0 );
204980
+ assert( !px.bReadOnly );
204981
+ sqlite3_result_blob(pStr->pCtx, px.aBlob, px.nBlob, sqlite3_free);
204982
+ }
204983
+}
204984
+
204985
+/* The byte at index i is a node type-code. This routine
204986
+** determines the payload size for that node and writes that
204987
+** payload size in to *pSz. It returns the offset from i to the
204988
+** beginning of the payload. Return 0 on error.
204989
+*/
204990
+static u32 jsonbPayloadSize(const JsonParse *pParse, u32 i, u32 *pSz){
204991
+ u8 x;
204992
+ u32 sz;
204993
+ u32 n;
204994
+ if( NEVER(i>pParse->nBlob) ){
204995
+ *pSz = 0;
204996
+ return 0;
204997
+ }
204998
+ x = pParse->aBlob[i]>>4;
204999
+ if( x<=11 ){
205000
+ sz = x;
205001
+ n = 1;
205002
+ }else if( x==12 ){
205003
+ if( i+1>=pParse->nBlob ){
205004
+ *pSz = 0;
205005
+ return 0;
205006
+ }
205007
+ sz = pParse->aBlob[i+1];
205008
+ n = 2;
205009
+ }else if( x==13 ){
205010
+ if( i+2>=pParse->nBlob ){
205011
+ *pSz = 0;
205012
+ return 0;
205013
+ }
205014
+ sz = (pParse->aBlob[i+1]<<8) + pParse->aBlob[i+2];
205015
+ n = 3;
205016
+ }else if( x==14 ){
205017
+ if( i+4>=pParse->nBlob ){
205018
+ *pSz = 0;
205019
+ return 0;
205020
+ }
205021
+ sz = ((u32)pParse->aBlob[i+1]<<24) + (pParse->aBlob[i+2]<<16) +
205022
+ (pParse->aBlob[i+3]<<8) + pParse->aBlob[i+4];
205023
+ n = 5;
205024
+ }else{
205025
+ if( i+8>=pParse->nBlob
205026
+ || pParse->aBlob[i+1]!=0
205027
+ || pParse->aBlob[i+2]!=0
205028
+ || pParse->aBlob[i+3]!=0
205029
+ || pParse->aBlob[i+4]!=0
205030
+ ){
205031
+ *pSz = 0;
205032
+ return 0;
205033
+ }
205034
+ sz = (pParse->aBlob[i+5]<<24) + (pParse->aBlob[i+6]<<16) +
205035
+ (pParse->aBlob[i+7]<<8) + pParse->aBlob[i+8];
205036
+ n = 9;
205037
+ }
205038
+ if( i+sz+n > pParse->nBlob
205039
+ && i+sz+n > pParse->nBlob-pParse->delta
205040
+ ){
205041
+ sz = 0;
205042
+ n = 0;
205043
+ }
205044
+ *pSz = sz;
205045
+ return n;
205046
+}
205047
+
205048
+
205049
+/*
205050
+** Translate the binary JSONB representation of JSON beginning at
205051
+** pParse->aBlob[i] into a JSON text string. Append the JSON
205052
+** text onto the end of pOut. Return the index in pParse->aBlob[]
205053
+** of the first byte past the end of the element that is translated.
205054
+**
205055
+** If an error is detected in the BLOB input, the pOut->eErr flag
205056
+** might get set to JSTRING_MALFORMED. But not all BLOB input errors
205057
+** are detected. So a malformed JSONB input might either result
205058
+** in an error, or in incorrect JSON.
205059
+**
205060
+** The pOut->eErr JSTRING_OOM flag is set on a OOM.
205061
+*/
205062
+static u32 jsonXlateBlobToText(
205063
+ const JsonParse *pParse, /* the complete parse of the JSON */
205064
+ u32 i, /* Start rendering at this index */
205065
+ JsonString *pOut /* Write JSON here */
205066
+){
205067
+ u32 sz, n, j, iEnd;
205068
+
205069
+ n = jsonbPayloadSize(pParse, i, &sz);
205070
+ if( n==0 ){
205071
+ pOut->eErr |= JSTRING_MALFORMED;
205072
+ return pParse->nBlob+1;
205073
+ }
205074
+ switch( pParse->aBlob[i] & 0x0f ){
205075
+ case JSONB_NULL: {
205076
+ jsonAppendRawNZ(pOut, "null", 4);
205077
+ return i+1;
205078
+ }
205079
+ case JSONB_TRUE: {
205080
+ jsonAppendRawNZ(pOut, "true", 4);
205081
+ return i+1;
205082
+ }
205083
+ case JSONB_FALSE: {
205084
+ jsonAppendRawNZ(pOut, "false", 5);
205085
+ return i+1;
205086
+ }
205087
+ case JSONB_INT:
205088
+ case JSONB_FLOAT: {
205089
+ jsonAppendRaw(pOut, (const char*)&pParse->aBlob[i+n], sz);
205090
+ break;
205091
+ }
205092
+ case JSONB_INT5: { /* Integer literal in hexadecimal notation */
205093
+ u32 k = 2;
205094
+ sqlite3_uint64 u = 0;
205095
+ const char *zIn = (const char*)&pParse->aBlob[i+n];
205096
+ int bOverflow = 0;
205097
+ if( zIn[0]=='-' ){
205098
+ jsonAppendChar(pOut, '-');
205099
+ k++;
205100
+ }else if( zIn[0]=='+' ){
205101
+ k++;
205102
+ }
205103
+ for(; k<sz; k++){
205104
+ if( !sqlite3Isxdigit(zIn[k]) ){
205105
+ pOut->eErr |= JSTRING_MALFORMED;
205106
+ break;
205107
+ }else if( (u>>60)!=0 ){
205108
+ bOverflow = 1;
205109
+ }else{
205110
+ u = u*16 + sqlite3HexToInt(zIn[k]);
205111
+ }
205112
+ }
205113
+ jsonPrintf(100,pOut,bOverflow?"9.0e999":"%llu", u);
205114
+ break;
205115
+ }
205116
+ case JSONB_FLOAT5: { /* Float literal missing digits beside "." */
205117
+ u32 k = 0;
205118
+ const char *zIn = (const char*)&pParse->aBlob[i+n];
205119
+ if( zIn[0]=='-' ){
205120
+ jsonAppendChar(pOut, '-');
205121
+ k++;
205122
+ }
205123
+ if( zIn[k]=='.' ){
205124
+ jsonAppendChar(pOut, '0');
205125
+ }
205126
+ for(; k<sz; k++){
205127
+ jsonAppendChar(pOut, zIn[k]);
205128
+ if( zIn[k]=='.' && (k+1==sz || !sqlite3Isdigit(zIn[k+1])) ){
205129
+ jsonAppendChar(pOut, '0');
205130
+ }
205131
+ }
205132
+ break;
205133
+ }
205134
+ case JSONB_TEXT:
205135
+ case JSONB_TEXTJ: {
205136
+ jsonAppendChar(pOut, '"');
205137
+ jsonAppendRaw(pOut, (const char*)&pParse->aBlob[i+n], sz);
205138
+ jsonAppendChar(pOut, '"');
205139
+ break;
205140
+ }
205141
+ case JSONB_TEXT5: {
205142
+ const char *zIn;
205143
+ u32 k;
205144
+ u32 sz2 = sz;
205145
+ zIn = (const char*)&pParse->aBlob[i+n];
205146
+ jsonAppendChar(pOut, '"');
205147
+ while( sz2>0 ){
205148
+ for(k=0; k<sz2 && zIn[k]!='\\' && zIn[k]!='"'; k++){}
205149
+ if( k>0 ){
205150
+ jsonAppendRawNZ(pOut, zIn, k);
205151
+ if( k>=sz2 ){
205152
+ break;
205153
+ }
205154
+ zIn += k;
205155
+ sz2 -= k;
205156
+ }
205157
+ if( zIn[0]=='"' ){
205158
+ jsonAppendRawNZ(pOut, "\\\"", 2);
205159
+ zIn++;
205160
+ sz2--;
205161
+ continue;
205162
+ }
205163
+ assert( zIn[0]=='\\' );
205164
+ assert( sz2>=1 );
205165
+ if( sz2<2 ){
205166
+ pOut->eErr |= JSTRING_MALFORMED;
205167
+ break;
205168
+ }
205169
+ switch( (u8)zIn[1] ){
205170
+ case '\'':
205171
+ jsonAppendChar(pOut, '\'');
205172
+ break;
205173
+ case 'v':
205174
+ jsonAppendRawNZ(pOut, "\\u0009", 6);
205175
+ break;
205176
+ case 'x':
205177
+ if( sz2<4 ){
205178
+ pOut->eErr |= JSTRING_MALFORMED;
205179
+ sz2 = 2;
205180
+ break;
205181
+ }
205182
+ jsonAppendRawNZ(pOut, "\\u00", 4);
205183
+ jsonAppendRawNZ(pOut, &zIn[2], 2);
205184
+ zIn += 2;
205185
+ sz2 -= 2;
205186
+ break;
205187
+ case '0':
205188
+ jsonAppendRawNZ(pOut, "\\u0000", 6);
205189
+ break;
205190
+ case '\r':
205191
+ if( sz2>2 && zIn[2]=='\n' ){
205192
+ zIn++;
205193
+ sz2--;
205194
+ }
205195
+ break;
205196
+ case '\n':
205197
+ break;
205198
+ case 0xe2:
205199
+ /* '\' followed by either U+2028 or U+2029 is ignored as
205200
+ ** whitespace. Not that in UTF8, U+2028 is 0xe2 0x80 0x29.
205201
+ ** U+2029 is the same except for the last byte */
205202
+ if( sz2<4
205203
+ || 0x80!=(u8)zIn[2]
205204
+ || (0xa8!=(u8)zIn[3] && 0xa9!=(u8)zIn[3])
205205
+ ){
205206
+ pOut->eErr |= JSTRING_MALFORMED;
205207
+ sz2 = 2;
205208
+ break;
205209
+ }
205210
+ zIn += 2;
205211
+ sz2 -= 2;
205212
+ break;
205213
+ default:
205214
+ jsonAppendRawNZ(pOut, zIn, 2);
205215
+ break;
205216
+ }
205217
+ assert( sz2>=2 );
205218
+ zIn += 2;
205219
+ sz2 -= 2;
205220
+ }
205221
+ jsonAppendChar(pOut, '"');
205222
+ break;
205223
+ }
205224
+ case JSONB_TEXTRAW: {
205225
+ jsonAppendString(pOut, (const char*)&pParse->aBlob[i+n], sz);
205226
+ break;
205227
+ }
205228
+ case JSONB_ARRAY: {
205229
+ jsonAppendChar(pOut, '[');
205230
+ j = i+n;
205231
+ iEnd = j+sz;
205232
+ while( j<iEnd ){
205233
+ j = jsonXlateBlobToText(pParse, j, pOut);
205234
+ jsonAppendChar(pOut, ',');
205235
+ }
205236
+ if( sz>0 ) pOut->nUsed--;
205237
+ jsonAppendChar(pOut, ']');
205238
+ break;
205239
+ }
205240
+ case JSONB_OBJECT: {
205241
+ int x = 0;
205242
+ jsonAppendChar(pOut, '{');
205243
+ j = i+n;
205244
+ iEnd = j+sz;
205245
+ while( j<iEnd ){
205246
+ j = jsonXlateBlobToText(pParse, j, pOut);
205247
+ jsonAppendChar(pOut, (x++ & 1) ? ',' : ':');
205248
+ }
205249
+ if( x & 1 ) pOut->eErr |= JSTRING_MALFORMED;
205250
+ if( sz>0 ) pOut->nUsed--;
205251
+ jsonAppendChar(pOut, '}');
205252
+ break;
205253
+ }
205254
+
205255
+ default: {
205256
+ pOut->eErr |= JSTRING_MALFORMED;
205257
+ break;
205258
+ }
205259
+ }
205260
+ return i+n+sz;
205261
+}
205262
+
205263
+/* Return true if the input pJson
205264
+**
205265
+** For performance reasons, this routine does not do a detailed check of the
205266
+** input BLOB to ensure that it is well-formed. Hence, false positives are
205267
+** possible. False negatives should never occur, however.
205268
+*/
205269
+static int jsonFuncArgMightBeBinary(sqlite3_value *pJson){
205270
+ u32 sz, n;
205271
+ const u8 *aBlob;
205272
+ int nBlob;
205273
+ JsonParse s;
205274
+ if( sqlite3_value_type(pJson)!=SQLITE_BLOB ) return 0;
205275
+ aBlob = sqlite3_value_blob(pJson);
205276
+ nBlob = sqlite3_value_bytes(pJson);
205277
+ if( nBlob<1 ) return 0;
205278
+ if( NEVER(aBlob==0) || (aBlob[0] & 0x0f)>JSONB_OBJECT ) return 0;
205279
+ memset(&s, 0, sizeof(s));
205280
+ s.aBlob = (u8*)aBlob;
205281
+ s.nBlob = nBlob;
205282
+ n = jsonbPayloadSize(&s, 0, &sz);
205283
+ if( n==0 ) return 0;
205284
+ if( sz+n!=(u32)nBlob ) return 0;
205285
+ if( (aBlob[0] & 0x0f)<=JSONB_FALSE && sz>0 ) return 0;
205286
+ return sz+n==(u32)nBlob;
205287
+}
205288
+
205289
+/*
205290
+** Given that a JSONB_ARRAY object starts at offset i, return
205291
+** the number of entries in that array.
205292
+*/
205293
+static u32 jsonbArrayCount(JsonParse *pParse, u32 iRoot){
205294
+ u32 n, sz, i, iEnd;
205295
+ u32 k = 0;
205296
+ n = jsonbPayloadSize(pParse, iRoot, &sz);
205297
+ iEnd = iRoot+n+sz;
205298
+ for(i=iRoot+n; n>0 && i<iEnd; i+=sz+n, k++){
205299
+ n = jsonbPayloadSize(pParse, i, &sz);
205300
+ }
205301
+ return k;
205302
+}
205303
+
205304
+/*
205305
+** Edit the payload size of the element at iRoot by the amount in
205306
+** pParse->delta.
205307
+*/
205308
+static void jsonAfterEditSizeAdjust(JsonParse *pParse, u32 iRoot){
205309
+ u32 sz = 0;
205310
+ u32 nBlob;
205311
+ assert( pParse->delta!=0 );
205312
+ assert( pParse->nBlobAlloc >= pParse->nBlob );
205313
+ nBlob = pParse->nBlob;
205314
+ pParse->nBlob = pParse->nBlobAlloc;
205315
+ (void)jsonbPayloadSize(pParse, iRoot, &sz);
205316
+ pParse->nBlob = nBlob;
205317
+ sz += pParse->delta;
205318
+ pParse->delta += jsonBlobChangePayloadSize(pParse, iRoot, sz);
205319
+}
205320
+
205321
+/*
205322
+** Modify the JSONB blob at pParse->aBlob by removing nDel bytes of
205323
+** content beginning at iDel, and replacing them with nIns bytes of
205324
+** content given by aIns.
205325
+**
205326
+** nDel may be zero, in which case no bytes are removed. But iDel is
205327
+** still important as new bytes will be insert beginning at iDel.
205328
+**
205329
+** aIns may be zero, in which case space is created to hold nIns bytes
205330
+** beginning at iDel, but that space is uninitialized.
205331
+**
205332
+** Set pParse->oom if an OOM occurs.
205333
+*/
205334
+static void jsonBlobEdit(
205335
+ JsonParse *pParse, /* The JSONB to be modified is in pParse->aBlob */
205336
+ u32 iDel, /* First byte to be removed */
205337
+ u32 nDel, /* Number of bytes to remove */
205338
+ const u8 *aIns, /* Content to insert */
205339
+ u32 nIns /* Bytes of content to insert */
205340
+){
205341
+ i64 d = (i64)nIns - (i64)nDel;
205342
+ if( d!=0 ){
205343
+ if( pParse->nBlob + d > pParse->nBlobAlloc ){
205344
+ jsonBlobExpand(pParse, pParse->nBlob+d);
205345
+ if( pParse->oom ) return;
205346
+ }
205347
+ memmove(&pParse->aBlob[iDel+nIns],
205348
+ &pParse->aBlob[iDel+nDel],
205349
+ pParse->nBlob - (iDel+nDel));
205350
+ pParse->nBlob += d;
205351
+ pParse->delta += d;
205352
+ }
205353
+ if( nIns && aIns ) memcpy(&pParse->aBlob[iDel], aIns, nIns);
205354
+}
205355
+
205356
+/*
205357
+** Return the number of escaped newlines to be ignored.
205358
+** An escaped newline is a one of the following byte sequences:
205359
+**
205360
+** 0x5c 0x0a
205361
+** 0x5c 0x0d
205362
+** 0x5c 0x0d 0x0a
205363
+** 0x5c 0xe2 0x80 0xa8
205364
+** 0x5c 0xe2 0x80 0xa9
205365
+*/
205366
+static u32 jsonBytesToBypass(const char *z, u32 n){
205367
+ u32 i = 0;
205368
+ while( i+1<n ){
205369
+ if( z[i]!='\\' ) return i;
205370
+ if( z[i+1]=='\n' ){
205371
+ i += 2;
205372
+ continue;
205373
+ }
205374
+ if( z[i+1]=='\r' ){
205375
+ if( i+2<n && z[i+2]=='\n' ){
205376
+ i += 3;
205377
+ }else{
205378
+ i += 2;
205379
+ }
205380
+ continue;
205381
+ }
205382
+ if( 0xe2==(u8)z[i+1]
205383
+ && i+3<n
205384
+ && 0x80==(u8)z[i+2]
205385
+ && (0xa8==(u8)z[i+3] || 0xa9==(u8)z[i+3])
205386
+ ){
205387
+ i += 4;
205388
+ continue;
205389
+ }
205390
+ break;
205391
+ }
205392
+ return i;
205393
+}
205394
+
205395
+/*
205396
+** Input z[0..n] defines JSON escape sequence including the leading '\\'.
205397
+** Decode that escape sequence into a single character. Write that
205398
+** character into *piOut. Return the number of bytes in the escape sequence.
205399
+*/
205400
+static u32 jsonUnescapeOneChar(const char *z, u32 n, u32 *piOut){
205401
+ assert( n>0 );
205402
+ assert( z[0]=='\\' );
205403
+ if( n<2 ){
205404
+ *piOut = 0xFFFD;
205405
+ return n;
205406
+ }
205407
+ switch( (u8)z[1] ){
205408
+ case 'u': {
205409
+ u32 v, vlo;
205410
+ if( n<6 ){
205411
+ *piOut = 0xFFFD;
205412
+ return n;
205413
+ }
205414
+ v = jsonHexToInt4(&z[2]);
205415
+ if( (v & 0xfc00)==0xd800
205416
+ && n>=12
205417
+ && z[6]=='\\'
205418
+ && z[7]=='u'
205419
+ && ((vlo = jsonHexToInt4(&z[8]))&0xfc00)==0xdc00
205420
+ ){
205421
+ *piOut = ((v&0x3ff)<<10) + (vlo&0x3ff) + 0x10000;
205422
+ return 12;
205423
+ }else{
205424
+ *piOut = v;
205425
+ return 6;
205426
+ }
205427
+ }
205428
+ case 'b': { *piOut = '\b'; return 2; }
205429
+ case 'f': { *piOut = '\f'; return 2; }
205430
+ case 'n': { *piOut = '\n'; return 2; }
205431
+ case 'r': { *piOut = '\r'; return 2; }
205432
+ case 't': { *piOut = '\t'; return 2; }
205433
+ case 'v': { *piOut = '\v'; return 2; }
205434
+ case '0': { *piOut = 0; return 2; }
205435
+ case '\'':
205436
+ case '"':
205437
+ case '/':
205438
+ case '\\':{ *piOut = z[1]; return 2; }
205439
+ case 'x': {
205440
+ if( n<4 ){
205441
+ *piOut = 0xFFFD;
205442
+ return n;
205443
+ }
205444
+ *piOut = (jsonHexToInt(z[2])<<4) | jsonHexToInt(z[3]);
205445
+ return 4;
205446
+ }
205447
+ case 0xe2:
205448
+ case '\r':
205449
+ case '\n': {
205450
+ u32 nSkip = jsonBytesToBypass(z, n);
205451
+ if( nSkip==0 ){
205452
+ *piOut = 0xFFFD;
205453
+ return n;
205454
+ }else if( nSkip==n ){
205455
+ *piOut = 0;
205456
+ return n;
205457
+ }else if( z[nSkip]=='\\' ){
205458
+ return nSkip + jsonUnescapeOneChar(&z[nSkip], n-nSkip, piOut);
205459
+ }else{
205460
+ int sz = sqlite3Utf8ReadLimited((u8*)&z[nSkip], n-nSkip, piOut);
205461
+ return nSkip + sz;
205462
+ }
205463
+ }
205464
+ default: {
205465
+ *piOut = 0xFFFD;
205466
+ return 2;
205467
+ }
205468
+ }
205469
+}
205470
+
205471
+
205472
+/*
205473
+** Compare two object labels. Return 1 if they are equal and
205474
+** 0 if they differ.
205475
+**
205476
+** In this version, we know that one or the other or both of the
205477
+** two comparands contains an escape sequence.
205478
+*/
205479
+static SQLITE_NOINLINE int jsonLabelCompareEscaped(
205480
+ const char *zLeft, /* The left label */
205481
+ u32 nLeft, /* Size of the left label in bytes */
205482
+ int rawLeft, /* True if zLeft contains no escapes */
205483
+ const char *zRight, /* The right label */
205484
+ u32 nRight, /* Size of the right label in bytes */
205485
+ int rawRight /* True if zRight is escape-free */
205486
+){
205487
+ u32 cLeft, cRight;
205488
+ assert( rawLeft==0 || rawRight==0 );
205489
+ while( 1 /*exit-by-return*/ ){
205490
+ if( nLeft==0 ){
205491
+ cLeft = 0;
205492
+ }else if( rawLeft || zLeft[0]!='\\' ){
205493
+ cLeft = ((u8*)zLeft)[0];
205494
+ if( cLeft>=0xc0 ){
205495
+ int sz = sqlite3Utf8ReadLimited((u8*)zLeft, nLeft, &cLeft);
205496
+ zLeft += sz;
205497
+ nLeft -= sz;
205498
+ }else{
205499
+ zLeft++;
205500
+ nLeft--;
205501
+ }
205502
+ }else{
205503
+ u32 n = jsonUnescapeOneChar(zLeft, nLeft, &cLeft);
205504
+ zLeft += n;
205505
+ assert( n<=nLeft );
205506
+ nLeft -= n;
205507
+ }
205508
+ if( nRight==0 ){
205509
+ cRight = 0;
205510
+ }else if( rawRight || zRight[0]!='\\' ){
205511
+ cRight = ((u8*)zRight)[0];
205512
+ if( cRight>=0xc0 ){
205513
+ int sz = sqlite3Utf8ReadLimited((u8*)zRight, nRight, &cRight);
205514
+ zRight += sz;
205515
+ nRight -= sz;
205516
+ }else{
205517
+ zRight++;
205518
+ nRight--;
205519
+ }
205520
+ }else{
205521
+ u32 n = jsonUnescapeOneChar(zRight, nRight, &cRight);
205522
+ zRight += n;
205523
+ assert( n<=nRight );
205524
+ nRight -= n;
205525
+ }
205526
+ if( cLeft!=cRight ) return 0;
205527
+ if( cLeft==0 ) return 1;
205528
+ }
205529
+}
205530
+
205531
+/*
205532
+** Compare two object labels. Return 1 if they are equal and
205533
+** 0 if they differ. Return -1 if an OOM occurs.
205534
+*/
205535
+static int jsonLabelCompare(
205536
+ const char *zLeft, /* The left label */
205537
+ u32 nLeft, /* Size of the left label in bytes */
205538
+ int rawLeft, /* True if zLeft contains no escapes */
205539
+ const char *zRight, /* The right label */
205540
+ u32 nRight, /* Size of the right label in bytes */
205541
+ int rawRight /* True if zRight is escape-free */
205542
+){
205543
+ if( rawLeft && rawRight ){
205544
+ /* Simpliest case: Neither label contains escapes. A simple
205545
+ ** memcmp() is sufficient. */
205546
+ if( nLeft!=nRight ) return 0;
205547
+ return memcmp(zLeft, zRight, nLeft)==0;
205548
+ }else{
205549
+ return jsonLabelCompareEscaped(zLeft, nLeft, rawLeft,
205550
+ zRight, nRight, rawRight);
205551
+ }
205552
+}
205553
+
205554
+/*
205555
+** Error returns from jsonLookupStep()
205556
+*/
205557
+#define JSON_LOOKUP_ERROR 0xffffffff
205558
+#define JSON_LOOKUP_NOTFOUND 0xfffffffe
205559
+#define JSON_LOOKUP_PATHERROR 0xfffffffd
205560
+#define JSON_LOOKUP_ISERROR(x) ((x)>=JSON_LOOKUP_PATHERROR)
205561
+
205562
+/* Forward declaration */
205563
+static u32 jsonLookupStep(JsonParse*,u32,const char*,u32);
205564
+
205565
+
205566
+/* This helper routine for jsonLookupStep() populates pIns with
205567
+** binary data that is to be inserted into pParse.
205568
+**
205569
+** In the common case, pIns just points to pParse->aIns and pParse->nIns.
205570
+** But if the zPath of the original edit operation includes path elements
205571
+** that go deeper, additional substructure must be created.
205572
+**
205573
+** For example:
205574
+**
205575
+** json_insert('{}', '$.a.b.c', 123);
205576
+**
205577
+** The search stops at '$.a' But additional substructure must be
205578
+** created for the ".b.c" part of the patch so that the final result
205579
+** is: {"a":{"b":{"c"::123}}}. This routine populates pIns with
205580
+** the binary equivalent of {"b":{"c":123}} so that it can be inserted.
205581
+**
205582
+** The caller is responsible for resetting pIns when it has finished
205583
+** using the substructure.
205584
+*/
205585
+static u32 jsonCreateEditSubstructure(
205586
+ JsonParse *pParse, /* The original JSONB that is being edited */
205587
+ JsonParse *pIns, /* Populate this with the blob data to insert */
205588
+ const char *zTail /* Tail of the path that determins substructure */
205589
+){
205590
+ static const u8 emptyObject[] = { JSONB_ARRAY, JSONB_OBJECT };
205591
+ int rc;
205592
+ memset(pIns, 0, sizeof(*pIns));
205593
+ if( zTail[0]==0 ){
205594
+ /* No substructure. Just insert what is given in pParse. */
205595
+ pIns->aBlob = pParse->aIns;
205596
+ pIns->nBlob = pParse->nIns;
205597
+ rc = 0;
205598
+ }else{
205599
+ /* Construct the binary substructure */
205600
+ pIns->nBlob = 1;
205601
+ pIns->aBlob = (u8*)&emptyObject[zTail[0]=='.'];
205602
+ pIns->eEdit = pParse->eEdit;
205603
+ pIns->nIns = pParse->nIns;
205604
+ pIns->aIns = pParse->aIns;
205605
+ rc = jsonLookupStep(pIns, 0, zTail, 0);
205606
+ pParse->oom |= pIns->oom;
205607
+ }
205608
+ return rc; /* Error code only */
205609
+}
205610
+
205611
+/*
205612
+** Search along zPath to find the Json element specified. Return an
205613
+** index into pParse->aBlob[] for the start of that element's value.
205614
+**
205615
+** If the value found by this routine is the value half of label/value pair
205616
+** within an object, then set pPath->iLabel to the start of the corresponding
205617
+** label, before returning.
205618
+**
205619
+** Return one of the JSON_LOOKUP error codes if problems are seen.
205620
+**
205621
+** This routine will also modify the blob. If pParse->eEdit is one of
205622
+** JEDIT_DEL, JEDIT_REPL, JEDIT_INS, or JEDIT_SET, then changes might be
205623
+** made to the selected value. If an edit is performed, then the return
205624
+** value does not necessarily point to the select element. If an edit
205625
+** is performed, the return value is only useful for detecting error
205626
+** conditions.
205627
+*/
205628
+static u32 jsonLookupStep(
205629
+ JsonParse *pParse, /* The JSON to search */
205630
+ u32 iRoot, /* Begin the search at this element of aBlob[] */
205631
+ const char *zPath, /* The path to search */
205632
+ u32 iLabel /* Label if iRoot is a value of in an object */
205633
+){
205634
+ u32 i, j, k, nKey, sz, n, iEnd, rc;
205635
+ const char *zKey;
205636
+ u8 x;
205637
+
205638
+ if( zPath[0]==0 ){
205639
+ if( pParse->eEdit && jsonBlobMakeEditable(pParse, pParse->nIns) ){
205640
+ n = jsonbPayloadSize(pParse, iRoot, &sz);
205641
+ sz += n;
205642
+ if( pParse->eEdit==JEDIT_DEL ){
205643
+ if( iLabel>0 ){
205644
+ sz += iRoot - iLabel;
205645
+ iRoot = iLabel;
205646
+ }
205647
+ jsonBlobEdit(pParse, iRoot, sz, 0, 0);
205648
+ }else if( pParse->eEdit==JEDIT_INS ){
205649
+ /* Already exists, so json_insert() is a no-op */
205650
+ }else{
205651
+ /* json_set() or json_replace() */
205652
+ jsonBlobEdit(pParse, iRoot, sz, pParse->aIns, pParse->nIns);
205653
+ }
205654
+ }
205655
+ pParse->iLabel = iLabel;
205656
+ return iRoot;
205657
+ }
205658
+ if( zPath[0]=='.' ){
205659
+ int rawKey = 1;
205660
+ x = pParse->aBlob[iRoot];
204697205661
zPath++;
204698205662
if( zPath[0]=='"' ){
204699205663
zKey = zPath + 1;
204700205664
for(i=1; zPath[i] && zPath[i]!='"'; i++){}
204701205665
nKey = i-1;
204702205666
if( zPath[i] ){
204703205667
i++;
204704205668
}else{
204705
- *pzErr = zPath;
204706
- return 0;
205669
+ return JSON_LOOKUP_PATHERROR;
204707205670
}
204708205671
testcase( nKey==0 );
205672
+ rawKey = memchr(zKey, '\\', nKey)==0;
204709205673
}else{
204710205674
zKey = zPath;
204711205675
for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
204712205676
nKey = i;
204713205677
if( nKey==0 ){
204714
- *pzErr = zPath;
204715
- return 0;
204716
- }
204717
- }
204718
- j = 1;
204719
- for(;;){
204720
- while( j<=pRoot->n ){
204721
- if( jsonLabelCompare(pRoot+j, zKey, nKey) ){
204722
- return jsonLookupStep(pParse, iRoot+j+1, &zPath[i], pApnd, pzErr);
204723
- }
204724
- j++;
204725
- j += jsonNodeSize(&pRoot[j]);
204726
- }
204727
- if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
204728
- if( pParse->useMod==0 ) break;
204729
- assert( pRoot->eU==2 );
204730
- iRoot = pRoot->u.iAppend;
204731
- pRoot = &pParse->aNode[iRoot];
204732
- j = 1;
204733
- }
204734
- if( pApnd ){
204735
- u32 iStart, iLabel;
204736
- JsonNode *pNode;
204737
- assert( pParse->useMod );
204738
- iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
204739
- iLabel = jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
204740
- zPath += i;
204741
- pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
204742
- if( pParse->oom ) return 0;
204743
- if( pNode ){
204744
- pRoot = &pParse->aNode[iRoot];
204745
- assert( pRoot->eU==0 );
204746
- pRoot->u.iAppend = iStart;
204747
- pRoot->jnFlags |= JNODE_APPEND;
204748
- VVA( pRoot->eU = 2 );
204749
- pParse->aNode[iLabel].jnFlags |= JNODE_RAW;
204750
- }
204751
- return pNode;
205678
+ return JSON_LOOKUP_PATHERROR;
205679
+ }
205680
+ }
205681
+ if( (x & 0x0f)!=JSONB_OBJECT ) return JSON_LOOKUP_NOTFOUND;
205682
+ n = jsonbPayloadSize(pParse, iRoot, &sz);
205683
+ j = iRoot + n; /* j is the index of a label */
205684
+ iEnd = j+sz;
205685
+ while( j<iEnd ){
205686
+ int rawLabel;
205687
+ const char *zLabel;
205688
+ x = pParse->aBlob[j] & 0x0f;
205689
+ if( x<JSONB_TEXT || x>JSONB_TEXTRAW ) return JSON_LOOKUP_ERROR;
205690
+ n = jsonbPayloadSize(pParse, j, &sz);
205691
+ if( n==0 ) return JSON_LOOKUP_ERROR;
205692
+ k = j+n; /* k is the index of the label text */
205693
+ if( k+sz>=iEnd ) return JSON_LOOKUP_ERROR;
205694
+ zLabel = (const char*)&pParse->aBlob[k];
205695
+ rawLabel = x==JSONB_TEXT || x==JSONB_TEXTRAW;
205696
+ if( jsonLabelCompare(zKey, nKey, rawKey, zLabel, sz, rawLabel) ){
205697
+ u32 v = k+sz; /* v is the index of the value */
205698
+ if( ((pParse->aBlob[v])&0x0f)>JSONB_OBJECT ) return JSON_LOOKUP_ERROR;
205699
+ n = jsonbPayloadSize(pParse, v, &sz);
205700
+ if( n==0 || v+n+sz>iEnd ) return JSON_LOOKUP_ERROR;
205701
+ assert( j>0 );
205702
+ rc = jsonLookupStep(pParse, v, &zPath[i], j);
205703
+ if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot);
205704
+ return rc;
205705
+ }
205706
+ j = k+sz;
205707
+ if( ((pParse->aBlob[j])&0x0f)>JSONB_OBJECT ) return JSON_LOOKUP_ERROR;
205708
+ n = jsonbPayloadSize(pParse, j, &sz);
205709
+ if( n==0 ) return JSON_LOOKUP_ERROR;
205710
+ j += n+sz;
205711
+ }
205712
+ if( j>iEnd ) return JSON_LOOKUP_ERROR;
205713
+ if( pParse->eEdit>=JEDIT_INS ){
205714
+ u32 nIns; /* Total bytes to insert (label+value) */
205715
+ JsonParse v; /* BLOB encoding of the value to be inserted */
205716
+ JsonParse ix; /* Header of the label to be inserted */
205717
+ testcase( pParse->eEdit==JEDIT_INS );
205718
+ testcase( pParse->eEdit==JEDIT_SET );
205719
+ memset(&ix, 0, sizeof(ix));
205720
+ jsonBlobAppendNode(&ix, rawKey?JSONB_TEXTRAW:JSONB_TEXT5, nKey, 0);
205721
+ pParse->oom |= ix.oom;
205722
+ rc = jsonCreateEditSubstructure(pParse, &v, &zPath[i]);
205723
+ if( !JSON_LOOKUP_ISERROR(rc)
205724
+ && jsonBlobMakeEditable(pParse, ix.nBlob+nKey+v.nBlob)
205725
+ ){
205726
+ assert( !pParse->oom );
205727
+ nIns = ix.nBlob + nKey + v.nBlob;
205728
+ jsonBlobEdit(pParse, j, 0, 0, nIns);
205729
+ if( !pParse->oom ){
205730
+ assert( pParse->aBlob!=0 ); /* Because pParse->oom!=0 */
205731
+ assert( ix.aBlob!=0 ); /* Because pPasre->oom!=0 */
205732
+ memcpy(&pParse->aBlob[j], ix.aBlob, ix.nBlob);
205733
+ k = j + ix.nBlob;
205734
+ memcpy(&pParse->aBlob[k], zKey, nKey);
205735
+ k += nKey;
205736
+ memcpy(&pParse->aBlob[k], v.aBlob, v.nBlob);
205737
+ if( ALWAYS(pParse->delta) ) jsonAfterEditSizeAdjust(pParse, iRoot);
205738
+ }
205739
+ }
205740
+ jsonParseReset(&v);
205741
+ jsonParseReset(&ix);
205742
+ return rc;
204752205743
}
204753205744
}else if( zPath[0]=='[' ){
204754
- i = 0;
204755
- j = 1;
204756
- while( sqlite3Isdigit(zPath[j]) ){
204757
- i = i*10 + zPath[j] - '0';
204758
- j++;
204759
- }
204760
- if( j<2 || zPath[j]!=']' ){
204761
- if( zPath[1]=='#' ){
204762
- JsonNode *pBase = pRoot;
204763
- int iBase = iRoot;
204764
- if( pRoot->eType!=JSON_ARRAY ) return 0;
204765
- for(;;){
204766
- while( j<=pBase->n ){
204767
- if( (pBase[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ) i++;
204768
- j += jsonNodeSize(&pBase[j]);
204769
- }
204770
- if( (pBase->jnFlags & JNODE_APPEND)==0 ) break;
204771
- if( pParse->useMod==0 ) break;
204772
- assert( pBase->eU==2 );
204773
- iBase = pBase->u.iAppend;
204774
- pBase = &pParse->aNode[iBase];
204775
- j = 1;
204776
- }
204777
- j = 2;
204778
- if( zPath[2]=='-' && sqlite3Isdigit(zPath[3]) ){
204779
- unsigned int x = 0;
204780
- j = 3;
204781
- do{
204782
- x = x*10 + zPath[j] - '0';
204783
- j++;
204784
- }while( sqlite3Isdigit(zPath[j]) );
204785
- if( x>i ) return 0;
204786
- i -= x;
204787
- }
204788
- if( zPath[j]!=']' ){
204789
- *pzErr = zPath;
204790
- return 0;
204791
- }
204792
- }else{
204793
- *pzErr = zPath;
204794
- return 0;
204795
- }
204796
- }
204797
- if( pRoot->eType!=JSON_ARRAY ) return 0;
204798
- zPath += j + 1;
204799
- j = 1;
204800
- for(;;){
204801
- while( j<=pRoot->n
204802
- && (i>0 || ((pRoot[j].jnFlags & JNODE_REMOVE)!=0 && pParse->useMod))
204803
- ){
204804
- if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ) i--;
204805
- j += jsonNodeSize(&pRoot[j]);
204806
- }
204807
- if( i==0 && j<=pRoot->n ) break;
204808
- if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
204809
- if( pParse->useMod==0 ) break;
204810
- assert( pRoot->eU==2 );
204811
- iRoot = pRoot->u.iAppend;
204812
- pRoot = &pParse->aNode[iRoot];
204813
- j = 1;
204814
- }
204815
- if( j<=pRoot->n ){
204816
- return jsonLookupStep(pParse, iRoot+j, zPath, pApnd, pzErr);
204817
- }
204818
- if( i==0 && pApnd ){
204819
- u32 iStart;
204820
- JsonNode *pNode;
204821
- assert( pParse->useMod );
204822
- iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
204823
- pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
204824
- if( pParse->oom ) return 0;
204825
- if( pNode ){
204826
- pRoot = &pParse->aNode[iRoot];
204827
- assert( pRoot->eU==0 );
204828
- pRoot->u.iAppend = iStart;
204829
- pRoot->jnFlags |= JNODE_APPEND;
204830
- VVA( pRoot->eU = 2 );
204831
- }
204832
- return pNode;
204833
- }
204834
- }else{
204835
- *pzErr = zPath;
204836
- }
204837
- return 0;
204838
-}
204839
-
204840
-/*
204841
-** Append content to pParse that will complete zPath. Return a pointer
204842
-** to the inserted node, or return NULL if the append fails.
204843
-*/
204844
-static JsonNode *jsonLookupAppend(
204845
- JsonParse *pParse, /* Append content to the JSON parse */
204846
- const char *zPath, /* Description of content to append */
204847
- int *pApnd, /* Set this flag to 1 */
204848
- const char **pzErr /* Make this point to any syntax error */
204849
-){
204850
- *pApnd = 1;
204851
- if( zPath[0]==0 ){
204852
- jsonParseAddNode(pParse, JSON_NULL, 0, 0);
204853
- return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1];
204854
- }
204855
- if( zPath[0]=='.' ){
204856
- jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
204857
- }else if( strncmp(zPath,"[0]",3)==0 ){
204858
- jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
204859
- }else{
204860
- return 0;
204861
- }
204862
- if( pParse->oom ) return 0;
204863
- return jsonLookupStep(pParse, pParse->nNode-1, zPath, pApnd, pzErr);
204864
-}
204865
-
204866
-/*
204867
-** Return the text of a syntax error message on a JSON path. Space is
204868
-** obtained from sqlite3_malloc().
204869
-*/
204870
-static char *jsonPathSyntaxError(const char *zErr){
204871
- return sqlite3_mprintf("JSON path error near '%q'", zErr);
204872
-}
204873
-
204874
-/*
204875
-** Do a node lookup using zPath. Return a pointer to the node on success.
204876
-** Return NULL if not found or if there is an error.
204877
-**
204878
-** On an error, write an error message into pCtx and increment the
204879
-** pParse->nErr counter.
204880
-**
204881
-** If pApnd!=NULL then try to append missing nodes and set *pApnd = 1 if
204882
-** nodes are appended.
204883
-*/
204884
-static JsonNode *jsonLookup(
204885
- JsonParse *pParse, /* The JSON to search */
204886
- const char *zPath, /* The path to search */
204887
- int *pApnd, /* Append nodes to complete path if not NULL */
204888
- sqlite3_context *pCtx /* Report errors here, if not NULL */
204889
-){
204890
- const char *zErr = 0;
204891
- JsonNode *pNode = 0;
204892
- char *zMsg;
204893
-
204894
- if( zPath==0 ) return 0;
204895
- if( zPath[0]!='$' ){
204896
- zErr = zPath;
204897
- goto lookup_err;
204898
- }
204899
- zPath++;
204900
- pNode = jsonLookupStep(pParse, 0, zPath, pApnd, &zErr);
204901
- if( zErr==0 ) return pNode;
204902
-
204903
-lookup_err:
204904
- pParse->nErr++;
204905
- assert( zErr!=0 && pCtx!=0 );
204906
- zMsg = jsonPathSyntaxError(zErr);
204907
- if( zMsg ){
204908
- sqlite3_result_error(pCtx, zMsg, -1);
204909
- sqlite3_free(zMsg);
204910
- }else{
204911
- sqlite3_result_error_nomem(pCtx);
204912
- }
204913
- return 0;
204914
-}
204915
-
204916
-
204917
-/*
204918
-** Report the wrong number of arguments for json_insert(), json_replace()
204919
-** or json_set().
204920
-*/
204921
-static void jsonWrongNumArgs(
204922
- sqlite3_context *pCtx,
204923
- const char *zFuncName
204924
-){
204925
- char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments",
204926
- zFuncName);
204927
- sqlite3_result_error(pCtx, zMsg, -1);
204928
- sqlite3_free(zMsg);
204929
-}
204930
-
204931
-/*
204932
-** Mark all NULL entries in the Object passed in as JNODE_REMOVE.
204933
-*/
204934
-static void jsonRemoveAllNulls(JsonNode *pNode){
204935
- int i, n;
204936
- assert( pNode->eType==JSON_OBJECT );
204937
- n = pNode->n;
204938
- for(i=2; i<=n; i += jsonNodeSize(&pNode[i])+1){
204939
- switch( pNode[i].eType ){
204940
- case JSON_NULL:
204941
- pNode[i].jnFlags |= JNODE_REMOVE;
204942
- break;
204943
- case JSON_OBJECT:
204944
- jsonRemoveAllNulls(&pNode[i]);
204945
- break;
204946
- }
204947
- }
204948
-}
204949
-
205745
+ x = pParse->aBlob[iRoot] & 0x0f;
205746
+ if( x!=JSONB_ARRAY ) return JSON_LOOKUP_NOTFOUND;
205747
+ n = jsonbPayloadSize(pParse, iRoot, &sz);
205748
+ k = 0;
205749
+ i = 1;
205750
+ while( sqlite3Isdigit(zPath[i]) ){
205751
+ k = k*10 + zPath[i] - '0';
205752
+ i++;
205753
+ }
205754
+ if( i<2 || zPath[i]!=']' ){
205755
+ if( zPath[1]=='#' ){
205756
+ k = jsonbArrayCount(pParse, iRoot);
205757
+ i = 2;
205758
+ if( zPath[2]=='-' && sqlite3Isdigit(zPath[3]) ){
205759
+ unsigned int nn = 0;
205760
+ i = 3;
205761
+ do{
205762
+ nn = nn*10 + zPath[i] - '0';
205763
+ i++;
205764
+ }while( sqlite3Isdigit(zPath[i]) );
205765
+ if( nn>k ) return JSON_LOOKUP_NOTFOUND;
205766
+ k -= nn;
205767
+ }
205768
+ if( zPath[i]!=']' ){
205769
+ return JSON_LOOKUP_PATHERROR;
205770
+ }
205771
+ }else{
205772
+ return JSON_LOOKUP_PATHERROR;
205773
+ }
205774
+ }
205775
+ j = iRoot+n;
205776
+ iEnd = j+sz;
205777
+ while( j<iEnd ){
205778
+ if( k==0 ){
205779
+ rc = jsonLookupStep(pParse, j, &zPath[i+1], 0);
205780
+ if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot);
205781
+ return rc;
205782
+ }
205783
+ k--;
205784
+ n = jsonbPayloadSize(pParse, j, &sz);
205785
+ if( n==0 ) return JSON_LOOKUP_ERROR;
205786
+ j += n+sz;
205787
+ }
205788
+ if( j>iEnd ) return JSON_LOOKUP_ERROR;
205789
+ if( k>0 ) return JSON_LOOKUP_NOTFOUND;
205790
+ if( pParse->eEdit>=JEDIT_INS ){
205791
+ JsonParse v;
205792
+ testcase( pParse->eEdit==JEDIT_INS );
205793
+ testcase( pParse->eEdit==JEDIT_SET );
205794
+ rc = jsonCreateEditSubstructure(pParse, &v, &zPath[i+1]);
205795
+ if( !JSON_LOOKUP_ISERROR(rc)
205796
+ && jsonBlobMakeEditable(pParse, v.nBlob)
205797
+ ){
205798
+ assert( !pParse->oom );
205799
+ jsonBlobEdit(pParse, j, 0, v.aBlob, v.nBlob);
205800
+ }
205801
+ jsonParseReset(&v);
205802
+ if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot);
205803
+ return rc;
205804
+ }
205805
+ }else{
205806
+ return JSON_LOOKUP_PATHERROR;
205807
+ }
205808
+ return JSON_LOOKUP_NOTFOUND;
205809
+}
205810
+
205811
+/*
205812
+** Convert a JSON BLOB into text and make that text the return value
205813
+** of an SQL function.
205814
+*/
205815
+static void jsonReturnTextJsonFromBlob(
205816
+ sqlite3_context *ctx,
205817
+ const u8 *aBlob,
205818
+ u32 nBlob
205819
+){
205820
+ JsonParse x;
205821
+ JsonString s;
205822
+
205823
+ if( NEVER(aBlob==0) ) return;
205824
+ memset(&x, 0, sizeof(x));
205825
+ x.aBlob = (u8*)aBlob;
205826
+ x.nBlob = nBlob;
205827
+ jsonStringInit(&s, ctx);
205828
+ jsonXlateBlobToText(&x, 0, &s);
205829
+ jsonReturnString(&s, 0, 0);
205830
+}
205831
+
205832
+
205833
+/*
205834
+** Return the value of the BLOB node at index i.
205835
+**
205836
+** If the value is a primitive, return it as an SQL value.
205837
+** If the value is an array or object, return it as either
205838
+** JSON text or the BLOB encoding, depending on the JSON_B flag
205839
+** on the userdata.
205840
+*/
205841
+static void jsonReturnFromBlob(
205842
+ JsonParse *pParse, /* Complete JSON parse tree */
205843
+ u32 i, /* Index of the node */
205844
+ sqlite3_context *pCtx, /* Return value for this function */
205845
+ int textOnly /* return text JSON. Disregard user-data */
205846
+){
205847
+ u32 n, sz;
205848
+ int rc;
205849
+ sqlite3 *db = sqlite3_context_db_handle(pCtx);
205850
+
205851
+ n = jsonbPayloadSize(pParse, i, &sz);
205852
+ if( n==0 ){
205853
+ sqlite3_result_error(pCtx, "malformed JSON", -1);
205854
+ return;
205855
+ }
205856
+ switch( pParse->aBlob[i] & 0x0f ){
205857
+ case JSONB_NULL: {
205858
+ if( sz ) goto returnfromblob_malformed;
205859
+ sqlite3_result_null(pCtx);
205860
+ break;
205861
+ }
205862
+ case JSONB_TRUE: {
205863
+ if( sz ) goto returnfromblob_malformed;
205864
+ sqlite3_result_int(pCtx, 1);
205865
+ break;
205866
+ }
205867
+ case JSONB_FALSE: {
205868
+ if( sz ) goto returnfromblob_malformed;
205869
+ sqlite3_result_int(pCtx, 0);
205870
+ break;
205871
+ }
205872
+ case JSONB_INT5:
205873
+ case JSONB_INT: {
205874
+ sqlite3_int64 iRes = 0;
205875
+ char *z;
205876
+ int bNeg = 0;
205877
+ char x;
205878
+ if( sz==0 ) goto returnfromblob_malformed;
205879
+ x = (char)pParse->aBlob[i+n];
205880
+ if( x=='-' ){
205881
+ if( sz<2 ) goto returnfromblob_malformed;
205882
+ n++;
205883
+ sz--;
205884
+ bNeg = 1;
205885
+ }
205886
+ z = sqlite3DbStrNDup(db, (const char*)&pParse->aBlob[i+n], (int)sz);
205887
+ if( z==0 ) goto returnfromblob_oom;
205888
+ rc = sqlite3DecOrHexToI64(z, &iRes);
205889
+ sqlite3DbFree(db, z);
205890
+ if( rc==0 ){
205891
+ sqlite3_result_int64(pCtx, bNeg ? -iRes : iRes);
205892
+ }else if( rc==3 && bNeg ){
205893
+ sqlite3_result_int64(pCtx, SMALLEST_INT64);
205894
+ }else if( rc==1 ){
205895
+ goto returnfromblob_malformed;
205896
+ }else{
205897
+ if( bNeg ){ n--; sz++; }
205898
+ goto to_double;
205899
+ }
205900
+ break;
205901
+ }
205902
+ case JSONB_FLOAT5:
205903
+ case JSONB_FLOAT: {
205904
+ double r;
205905
+ char *z;
205906
+ if( sz==0 ) goto returnfromblob_malformed;
205907
+ to_double:
205908
+ z = sqlite3DbStrNDup(db, (const char*)&pParse->aBlob[i+n], (int)sz);
205909
+ if( z==0 ) goto returnfromblob_oom;
205910
+ rc = sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8);
205911
+ sqlite3DbFree(db, z);
205912
+ if( rc<=0 ) goto returnfromblob_malformed;
205913
+ sqlite3_result_double(pCtx, r);
205914
+ break;
205915
+ }
205916
+ case JSONB_TEXTRAW:
205917
+ case JSONB_TEXT: {
205918
+ sqlite3_result_text(pCtx, (char*)&pParse->aBlob[i+n], sz,
205919
+ SQLITE_TRANSIENT);
205920
+ break;
205921
+ }
205922
+ case JSONB_TEXT5:
205923
+ case JSONB_TEXTJ: {
205924
+ /* Translate JSON formatted string into raw text */
205925
+ u32 iIn, iOut;
205926
+ const char *z;
205927
+ char *zOut;
205928
+ u32 nOut = sz;
205929
+ z = (const char*)&pParse->aBlob[i+n];
205930
+ zOut = sqlite3_malloc( nOut+1 );
205931
+ if( zOut==0 ) goto returnfromblob_oom;
205932
+ for(iIn=iOut=0; iIn<sz; iIn++){
205933
+ char c = z[iIn];
205934
+ if( c=='\\' ){
205935
+ u32 v;
205936
+ u32 szEscape = jsonUnescapeOneChar(&z[iIn], sz-iIn, &v);
205937
+ if( v<=0x7f ){
205938
+ zOut[iOut++] = (char)v;
205939
+ }else if( v==0xfffd ){
205940
+ /* Silently ignore illegal unicode */
205941
+ }else if( v<=0x7ff ){
205942
+ assert( szEscape>=2 );
205943
+ zOut[iOut++] = (char)(0xc0 | (v>>6));
205944
+ zOut[iOut++] = 0x80 | (v&0x3f);
205945
+ }else if( v<0x10000 ){
205946
+ assert( szEscape>=3 );
205947
+ zOut[iOut++] = 0xe0 | (v>>12);
205948
+ zOut[iOut++] = 0x80 | ((v>>6)&0x3f);
205949
+ zOut[iOut++] = 0x80 | (v&0x3f);
205950
+ }else{
205951
+ assert( szEscape>=4 );
205952
+ zOut[iOut++] = 0xf0 | (v>>18);
205953
+ zOut[iOut++] = 0x80 | ((v>>12)&0x3f);
205954
+ zOut[iOut++] = 0x80 | ((v>>6)&0x3f);
205955
+ zOut[iOut++] = 0x80 | (v&0x3f);
205956
+ }
205957
+ iIn += szEscape - 1;
205958
+ }else{
205959
+ zOut[iOut++] = c;
205960
+ }
205961
+ } /* end for() */
205962
+ assert( iOut<=nOut );
205963
+ zOut[iOut] = 0;
205964
+ sqlite3_result_text(pCtx, zOut, iOut, sqlite3_free);
205965
+ break;
205966
+ }
205967
+ case JSONB_ARRAY:
205968
+ case JSONB_OBJECT: {
205969
+ int flags = textOnly ? 0 : SQLITE_PTR_TO_INT(sqlite3_user_data(pCtx));
205970
+ if( flags & JSON_BLOB ){
205971
+ sqlite3_result_blob(pCtx, &pParse->aBlob[i], sz+n, SQLITE_TRANSIENT);
205972
+ }else{
205973
+ jsonReturnTextJsonFromBlob(pCtx, &pParse->aBlob[i], sz+n);
205974
+ }
205975
+ break;
205976
+ }
205977
+ default: {
205978
+ goto returnfromblob_malformed;
205979
+ }
205980
+ }
205981
+ return;
205982
+
205983
+returnfromblob_oom:
205984
+ sqlite3_result_error_nomem(pCtx);
205985
+ return;
205986
+
205987
+returnfromblob_malformed:
205988
+ sqlite3_result_error(pCtx, "malformed JSON", -1);
205989
+ return;
205990
+}
205991
+
205992
+/*
205993
+** pArg is a function argument that might be an SQL value or a JSON
205994
+** value. Figure out what it is and encode it as a JSONB blob.
205995
+** Return the results in pParse.
205996
+**
205997
+** pParse is uninitialized upon entry. This routine will handle the
205998
+** initialization of pParse. The result will be contained in
205999
+** pParse->aBlob and pParse->nBlob. pParse->aBlob might be dynamically
206000
+** allocated (if pParse->nBlobAlloc is greater than zero) in which case
206001
+** the caller is responsible for freeing the space allocated to pParse->aBlob
206002
+** when it has finished with it. Or pParse->aBlob might be a static string
206003
+** or a value obtained from sqlite3_value_blob(pArg).
206004
+**
206005
+** If the argument is a BLOB that is clearly not a JSONB, then this
206006
+** function might set an error message in ctx and return non-zero.
206007
+** It might also set an error message and return non-zero on an OOM error.
206008
+*/
206009
+static int jsonFunctionArgToBlob(
206010
+ sqlite3_context *ctx,
206011
+ sqlite3_value *pArg,
206012
+ JsonParse *pParse
206013
+){
206014
+ int eType = sqlite3_value_type(pArg);
206015
+ static u8 aNull[] = { 0x00 };
206016
+ memset(pParse, 0, sizeof(pParse[0]));
206017
+ switch( eType ){
206018
+ default: {
206019
+ pParse->aBlob = aNull;
206020
+ pParse->nBlob = 1;
206021
+ return 0;
206022
+ }
206023
+ case SQLITE_BLOB: {
206024
+ if( jsonFuncArgMightBeBinary(pArg) ){
206025
+ pParse->aBlob = (u8*)sqlite3_value_blob(pArg);
206026
+ pParse->nBlob = sqlite3_value_bytes(pArg);
206027
+ }else{
206028
+ sqlite3_result_error(ctx, "JSON cannot hold BLOB values", -1);
206029
+ return 1;
206030
+ }
206031
+ break;
206032
+ }
206033
+ case SQLITE_TEXT: {
206034
+ const char *zJson = (const char*)sqlite3_value_text(pArg);
206035
+ int nJson = sqlite3_value_bytes(pArg);
206036
+ if( zJson==0 ) return 1;
206037
+ if( sqlite3_value_subtype(pArg)==JSON_SUBTYPE ){
206038
+ pParse->zJson = (char*)zJson;
206039
+ pParse->nJson = nJson;
206040
+ if( jsonConvertTextToBlob(pParse, ctx) ){
206041
+ sqlite3_result_error(ctx, "malformed JSON", -1);
206042
+ sqlite3_free(pParse->aBlob);
206043
+ memset(pParse, 0, sizeof(pParse[0]));
206044
+ return 1;
206045
+ }
206046
+ }else{
206047
+ jsonBlobAppendNode(pParse, JSONB_TEXTRAW, nJson, zJson);
206048
+ }
206049
+ break;
206050
+ }
206051
+ case SQLITE_FLOAT:
206052
+ case SQLITE_INTEGER: {
206053
+ int n = sqlite3_value_bytes(pArg);
206054
+ const char *z = (const char*)sqlite3_value_text(pArg);
206055
+ int e = eType==SQLITE_INTEGER ? JSONB_INT : JSONB_FLOAT;
206056
+ if( z==0 ) return 1;
206057
+ jsonBlobAppendNode(pParse, e, n, z);
206058
+ break;
206059
+ }
206060
+ }
206061
+ if( pParse->oom ){
206062
+ sqlite3_result_error_nomem(ctx);
206063
+ return 1;
206064
+ }else{
206065
+ return 0;
206066
+ }
206067
+}
206068
+
206069
+/*
206070
+** Generate a bad path error.
206071
+**
206072
+** If ctx is not NULL then push the error message into ctx and return NULL.
206073
+** If ctx is NULL, then return the text of the error message.
206074
+*/
206075
+static char *jsonBadPathError(
206076
+ sqlite3_context *ctx, /* The function call containing the error */
206077
+ const char *zPath /* The path with the problem */
206078
+){
206079
+ char *zMsg = sqlite3_mprintf("bad JSON path: %Q", zPath);
206080
+ if( ctx==0 ) return zMsg;
206081
+ if( zMsg ){
206082
+ sqlite3_result_error(ctx, zMsg, -1);
206083
+ sqlite3_free(zMsg);
206084
+ }else{
206085
+ sqlite3_result_error_nomem(ctx);
206086
+ }
206087
+ return 0;
206088
+}
206089
+
206090
+/* argv[0] is a BLOB that seems likely to be a JSONB. Subsequent
206091
+** arguments come in parse where each pair contains a JSON path and
206092
+** content to insert or set at that patch. Do the updates
206093
+** and return the result.
206094
+**
206095
+** The specific operation is determined by eEdit, which can be one
206096
+** of JEDIT_INS, JEDIT_REPL, or JEDIT_SET.
206097
+*/
206098
+static void jsonInsertIntoBlob(
206099
+ sqlite3_context *ctx,
206100
+ int argc,
206101
+ sqlite3_value **argv,
206102
+ int eEdit /* JEDIT_INS, JEDIT_REPL, or JEDIT_SET */
206103
+){
206104
+ int i;
206105
+ u32 rc = 0;
206106
+ const char *zPath = 0;
206107
+ int flgs;
206108
+ JsonParse *p;
206109
+ JsonParse ax;
206110
+
206111
+ assert( (argc&1)==1 );
206112
+ flgs = argc==1 ? 0 : JSON_EDITABLE;
206113
+ p = jsonParseFuncArg(ctx, argv[0], flgs);
206114
+ if( p==0 ) return;
206115
+ for(i=1; i<argc-1; i+=2){
206116
+ if( sqlite3_value_type(argv[i])==SQLITE_NULL ) continue;
206117
+ zPath = (const char*)sqlite3_value_text(argv[i]);
206118
+ if( zPath==0 ){
206119
+ sqlite3_result_error_nomem(ctx);
206120
+ jsonParseFree(p);
206121
+ return;
206122
+ }
206123
+ if( zPath[0]!='$' ) goto jsonInsertIntoBlob_patherror;
206124
+ if( jsonFunctionArgToBlob(ctx, argv[i+1], &ax) ){
206125
+ jsonParseReset(&ax);
206126
+ jsonParseFree(p);
206127
+ return;
206128
+ }
206129
+ if( zPath[1]==0 ){
206130
+ if( eEdit==JEDIT_REPL || eEdit==JEDIT_SET ){
206131
+ jsonBlobEdit(p, 0, p->nBlob, ax.aBlob, ax.nBlob);
206132
+ }
206133
+ rc = 0;
206134
+ }else{
206135
+ p->eEdit = eEdit;
206136
+ p->nIns = ax.nBlob;
206137
+ p->aIns = ax.aBlob;
206138
+ p->delta = 0;
206139
+ rc = jsonLookupStep(p, 0, zPath+1, 0);
206140
+ }
206141
+ jsonParseReset(&ax);
206142
+ if( rc==JSON_LOOKUP_NOTFOUND ) continue;
206143
+ if( JSON_LOOKUP_ISERROR(rc) ) goto jsonInsertIntoBlob_patherror;
206144
+ }
206145
+ jsonReturnParse(ctx, p);
206146
+ jsonParseFree(p);
206147
+ return;
206148
+
206149
+jsonInsertIntoBlob_patherror:
206150
+ jsonParseFree(p);
206151
+ if( rc==JSON_LOOKUP_ERROR ){
206152
+ sqlite3_result_error(ctx, "malformed JSON", -1);
206153
+ }else{
206154
+ jsonBadPathError(ctx, zPath);
206155
+ }
206156
+ return;
206157
+}
206158
+
206159
+/*
206160
+** Make a copy of a JsonParse object. The copy will be editable.
206161
+*/
206162
+
206163
+
206164
+/*
206165
+** Generate a JsonParse object, containing valid JSONB in aBlob and nBlob,
206166
+** from the SQL function argument pArg. Return a pointer to the new
206167
+** JsonParse object.
206168
+**
206169
+** Ownership of the new JsonParse object is passed to the caller. The
206170
+** caller should invoke jsonParseFree() on the return value when it
206171
+** has finished using it.
206172
+**
206173
+** If any errors are detected, an appropriate error messages is set
206174
+** using sqlite3_result_error() or the equivalent and this routine
206175
+** returns NULL. This routine also returns NULL if the pArg argument
206176
+** is an SQL NULL value, but no error message is set in that case. This
206177
+** is so that SQL functions that are given NULL arguments will return
206178
+** a NULL value.
206179
+*/
206180
+static JsonParse *jsonParseFuncArg(
206181
+ sqlite3_context *ctx,
206182
+ sqlite3_value *pArg,
206183
+ u32 flgs
206184
+){
206185
+ int eType; /* Datatype of pArg */
206186
+ JsonParse *p = 0; /* Value to be returned */
206187
+ JsonParse *pFromCache = 0; /* Value taken from cache */
206188
+
206189
+ assert( ctx!=0 );
206190
+ eType = sqlite3_value_type(pArg);
206191
+ if( eType==SQLITE_NULL ){
206192
+ return 0;
206193
+ }
206194
+ pFromCache = jsonCacheSearch(ctx, pArg);
206195
+ if( pFromCache ){
206196
+ pFromCache->nJPRef++;
206197
+ if( (flgs & JSON_EDITABLE)==0 ){
206198
+ return pFromCache;
206199
+ }
206200
+ }
206201
+rebuild_from_cache:
206202
+ p = sqlite3_malloc64( sizeof(*p) );
206203
+ if( p==0 ) goto json_pfa_oom;
206204
+ memset(p, 0, sizeof(*p));
206205
+ p->nJPRef = 1;
206206
+ if( pFromCache!=0 ){
206207
+ u32 nBlob = pFromCache->nBlob;
206208
+ p->aBlob = sqlite3_malloc64( nBlob );
206209
+ if( p->aBlob==0 ) goto json_pfa_oom;
206210
+ memcpy(p->aBlob, pFromCache->aBlob, nBlob);
206211
+ p->nBlobAlloc = p->nBlob = nBlob;
206212
+ p->hasNonstd = pFromCache->hasNonstd;
206213
+ jsonParseFree(pFromCache);
206214
+ return p;
206215
+ }
206216
+ if( eType==SQLITE_BLOB ){
206217
+ u32 n, sz = 0;
206218
+ p->aBlob = (u8*)sqlite3_value_blob(pArg);
206219
+ p->nBlob = (u32)sqlite3_value_bytes(pArg);
206220
+ if( p->nBlob==0 ){
206221
+ goto json_pfa_malformed;
206222
+ }
206223
+ if( NEVER(p->aBlob==0) ){
206224
+ goto json_pfa_oom;
206225
+ }
206226
+ if( (p->aBlob[0] & 0x0f)>JSONB_OBJECT ){
206227
+ goto json_pfa_malformed;
206228
+ }
206229
+ n = jsonbPayloadSize(p, 0, &sz);
206230
+ if( n==0
206231
+ || sz+n!=p->nBlob
206232
+ || ((p->aBlob[0] & 0x0f)<=JSONB_FALSE && sz>0)
206233
+ ){
206234
+ goto json_pfa_malformed;
206235
+ }
206236
+ if( (flgs & JSON_EDITABLE)!=0 && jsonBlobMakeEditable(p, 0)==0 ){
206237
+ goto json_pfa_oom;
206238
+ }
206239
+ return p;
206240
+ }
206241
+ p->zJson = (char*)sqlite3_value_text(pArg);
206242
+ p->nJson = sqlite3_value_bytes(pArg);
206243
+ if( p->nJson==0 ) goto json_pfa_malformed;
206244
+ if( NEVER(p->zJson==0) ) goto json_pfa_oom;
206245
+ if( jsonConvertTextToBlob(p, (flgs & JSON_KEEPERROR) ? 0 : ctx) ){
206246
+ if( flgs & JSON_KEEPERROR ){
206247
+ p->nErr = 1;
206248
+ return p;
206249
+ }else{
206250
+ jsonParseFree(p);
206251
+ return 0;
206252
+ }
206253
+ }else{
206254
+ int isRCStr = sqlite3ValueIsOfClass(pArg, sqlite3RCStrUnref);
206255
+ int rc;
206256
+ if( !isRCStr ){
206257
+ char *zNew = sqlite3RCStrNew( p->nJson );
206258
+ if( zNew==0 ) goto json_pfa_oom;
206259
+ memcpy(zNew, p->zJson, p->nJson);
206260
+ p->zJson = zNew;
206261
+ p->zJson[p->nJson] = 0;
206262
+ }else{
206263
+ sqlite3RCStrRef(p->zJson);
206264
+ }
206265
+ p->bJsonIsRCStr = 1;
206266
+ rc = jsonCacheInsert(ctx, p);
206267
+ if( rc==SQLITE_NOMEM ) goto json_pfa_oom;
206268
+ if( flgs & JSON_EDITABLE ){
206269
+ pFromCache = p;
206270
+ p = 0;
206271
+ goto rebuild_from_cache;
206272
+ }
206273
+ }
206274
+ return p;
206275
+
206276
+json_pfa_malformed:
206277
+ if( flgs & JSON_KEEPERROR ){
206278
+ p->nErr = 1;
206279
+ return p;
206280
+ }else{
206281
+ jsonParseFree(p);
206282
+ sqlite3_result_error(ctx, "malformed JSON", -1);
206283
+ return 0;
206284
+ }
206285
+
206286
+json_pfa_oom:
206287
+ jsonParseFree(pFromCache);
206288
+ jsonParseFree(p);
206289
+ sqlite3_result_error_nomem(ctx);
206290
+ return 0;
206291
+}
206292
+
206293
+/*
206294
+** Make the return value of a JSON function either the raw JSONB blob
206295
+** or make it JSON text, depending on whether the JSON_BLOB flag is
206296
+** set on the function.
206297
+*/
206298
+static void jsonReturnParse(
206299
+ sqlite3_context *ctx,
206300
+ JsonParse *p
206301
+){
206302
+ int flgs;
206303
+ if( p->oom ){
206304
+ sqlite3_result_error_nomem(ctx);
206305
+ return;
206306
+ }
206307
+ flgs = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx));
206308
+ if( flgs & JSON_BLOB ){
206309
+ if( p->nBlobAlloc>0 && !p->bReadOnly ){
206310
+ sqlite3_result_blob(ctx, p->aBlob, p->nBlob, SQLITE_DYNAMIC);
206311
+ p->nBlobAlloc = 0;
206312
+ }else{
206313
+ sqlite3_result_blob(ctx, p->aBlob, p->nBlob, SQLITE_TRANSIENT);
206314
+ }
206315
+ }else{
206316
+ JsonString s;
206317
+ jsonStringInit(&s, ctx);
206318
+ jsonXlateBlobToText(p, 0, &s);
206319
+ jsonReturnString(&s, p, ctx);
206320
+ sqlite3_result_subtype(ctx, JSON_SUBTYPE);
206321
+ }
206322
+}
204950206323
204951206324
/****************************************************************************
204952206325
** SQL functions used for testing and debugging
204953206326
****************************************************************************/
204954206327
204955206328
#if SQLITE_DEBUG
204956206329
/*
204957
-** Print N node entries.
204958
-*/
204959
-static void jsonDebugPrintNodeEntries(
204960
- JsonNode *aNode, /* First node entry to print */
204961
- int N /* Number of node entries to print */
204962
-){
204963
- int i;
204964
- for(i=0; i<N; i++){
204965
- const char *zType;
204966
- if( aNode[i].jnFlags & JNODE_LABEL ){
204967
- zType = "label";
204968
- }else{
204969
- zType = jsonType[aNode[i].eType];
204970
- }
204971
- printf("node %4u: %-7s n=%-5d", i, zType, aNode[i].n);
204972
- if( (aNode[i].jnFlags & ~JNODE_LABEL)!=0 ){
204973
- u8 f = aNode[i].jnFlags;
204974
- if( f & JNODE_RAW ) printf(" RAW");
204975
- if( f & JNODE_ESCAPE ) printf(" ESCAPE");
204976
- if( f & JNODE_REMOVE ) printf(" REMOVE");
204977
- if( f & JNODE_REPLACE ) printf(" REPLACE");
204978
- if( f & JNODE_APPEND ) printf(" APPEND");
204979
- if( f & JNODE_JSON5 ) printf(" JSON5");
204980
- }
204981
- switch( aNode[i].eU ){
204982
- case 1: printf(" zJContent=[%.*s]\n",
204983
- aNode[i].n, aNode[i].u.zJContent); break;
204984
- case 2: printf(" iAppend=%u\n", aNode[i].u.iAppend); break;
204985
- case 3: printf(" iKey=%u\n", aNode[i].u.iKey); break;
204986
- case 4: printf(" iPrev=%u\n", aNode[i].u.iPrev); break;
204987
- default: printf("\n");
204988
- }
204989
- }
204990
-}
204991
-#endif /* SQLITE_DEBUG */
204992
-
204993
-
204994
-#if 0 /* 1 for debugging. 0 normally. Requires -DSQLITE_DEBUG too */
204995
-static void jsonDebugPrintParse(JsonParse *p){
204996
- jsonDebugPrintNodeEntries(p->aNode, p->nNode);
204997
-}
204998
-static void jsonDebugPrintNode(JsonNode *pNode){
204999
- jsonDebugPrintNodeEntries(pNode, jsonNodeSize(pNode));
205000
-}
205001
-#else
205002
- /* The usual case */
205003
-# define jsonDebugPrintNode(X)
205004
-# define jsonDebugPrintParse(X)
205005
-#endif
206330
+** Decode JSONB bytes in aBlob[] starting at iStart through but not
206331
+** including iEnd. Indent the
206332
+** content by nIndent spaces.
206333
+*/
206334
+static void jsonDebugPrintBlob(
206335
+ JsonParse *pParse, /* JSON content */
206336
+ u32 iStart, /* Start rendering here */
206337
+ u32 iEnd, /* Do not render this byte or any byte after this one */
206338
+ int nIndent /* Indent by this many spaces */
206339
+){
206340
+ while( iStart<iEnd ){
206341
+ u32 i, n, nn, sz = 0;
206342
+ int showContent = 1;
206343
+ u8 x = pParse->aBlob[iStart] & 0x0f;
206344
+ u32 savedNBlob = pParse->nBlob;
206345
+ printf("%5d:%*s", iStart, nIndent, "");
206346
+ if( pParse->nBlobAlloc>pParse->nBlob ){
206347
+ pParse->nBlob = pParse->nBlobAlloc;
206348
+ }
206349
+ nn = n = jsonbPayloadSize(pParse, iStart, &sz);
206350
+ if( nn==0 ) nn = 1;
206351
+ if( sz>0 && x<JSONB_ARRAY ){
206352
+ nn += sz;
206353
+ }
206354
+ for(i=0; i<nn; i++) printf(" %02x", pParse->aBlob[iStart+i]);
206355
+ if( n==0 ){
206356
+ printf(" ERROR invalid node size\n");
206357
+ iStart = n==0 ? iStart+1 : iEnd;
206358
+ continue;
206359
+ }
206360
+ pParse->nBlob = savedNBlob;
206361
+ if( iStart+n+sz>iEnd ){
206362
+ iEnd = iStart+n+sz;
206363
+ if( iEnd>pParse->nBlob ){
206364
+ if( pParse->nBlobAlloc>0 && iEnd>pParse->nBlobAlloc ){
206365
+ iEnd = pParse->nBlobAlloc;
206366
+ }else{
206367
+ iEnd = pParse->nBlob;
206368
+ }
206369
+ }
206370
+ }
206371
+ printf(" <-- ");
206372
+ switch( x ){
206373
+ case JSONB_NULL: printf("null"); break;
206374
+ case JSONB_TRUE: printf("true"); break;
206375
+ case JSONB_FALSE: printf("false"); break;
206376
+ case JSONB_INT: printf("int"); break;
206377
+ case JSONB_INT5: printf("int5"); break;
206378
+ case JSONB_FLOAT: printf("float"); break;
206379
+ case JSONB_FLOAT5: printf("float5"); break;
206380
+ case JSONB_TEXT: printf("text"); break;
206381
+ case JSONB_TEXTJ: printf("textj"); break;
206382
+ case JSONB_TEXT5: printf("text5"); break;
206383
+ case JSONB_TEXTRAW: printf("textraw"); break;
206384
+ case JSONB_ARRAY: {
206385
+ printf("array, %u bytes\n", sz);
206386
+ jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2);
206387
+ showContent = 0;
206388
+ break;
206389
+ }
206390
+ case JSONB_OBJECT: {
206391
+ printf("object, %u bytes\n", sz);
206392
+ jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2);
206393
+ showContent = 0;
206394
+ break;
206395
+ }
206396
+ default: {
206397
+ printf("ERROR: unknown node type\n");
206398
+ showContent = 0;
206399
+ break;
206400
+ }
206401
+ }
206402
+ if( showContent ){
206403
+ if( sz==0 && x<=JSONB_FALSE ){
206404
+ printf("\n");
206405
+ }else{
206406
+ u32 i;
206407
+ printf(": \"");
206408
+ for(i=iStart+n; i<iStart+n+sz; i++){
206409
+ u8 c = pParse->aBlob[i];
206410
+ if( c<0x20 || c>=0x7f ) c = '.';
206411
+ putchar(c);
206412
+ }
206413
+ printf("\"\n");
206414
+ }
206415
+ }
206416
+ iStart += n + sz;
206417
+ }
206418
+}
206419
+static void jsonShowParse(JsonParse *pParse){
206420
+ if( pParse==0 ){
206421
+ printf("NULL pointer\n");
206422
+ return;
206423
+ }else{
206424
+ printf("nBlobAlloc = %u\n", pParse->nBlobAlloc);
206425
+ printf("nBlob = %u\n", pParse->nBlob);
206426
+ printf("delta = %d\n", pParse->delta);
206427
+ if( pParse->nBlob==0 ) return;
206428
+ printf("content (bytes 0..%u):\n", pParse->nBlob-1);
206429
+ }
206430
+ jsonDebugPrintBlob(pParse, 0, pParse->nBlob, 0);
206431
+}
206432
+#endif /* SQLITE_DEBUG */
205006206433
205007206434
#ifdef SQLITE_DEBUG
205008206435
/*
205009206436
** SQL function: json_parse(JSON)
205010206437
**
205011
-** Parse JSON using jsonParseCached(). Then print a dump of that
205012
-** parse on standard output. Return the mimified JSON result, just
205013
-** like the json() function.
206438
+** Parse JSON using jsonParseFuncArg(). Then print a dump of that
206439
+** parse on standard output.
205014206440
*/
205015206441
static void jsonParseFunc(
205016206442
sqlite3_context *ctx,
205017206443
int argc,
205018206444
sqlite3_value **argv
205019206445
){
205020206446
JsonParse *p; /* The parse */
205021206447
205022206448
assert( argc==1 );
205023
- p = jsonParseCached(ctx, argv[0], ctx, 0);
205024
- if( p==0 ) return;
205025
- printf("nNode = %u\n", p->nNode);
205026
- printf("nAlloc = %u\n", p->nAlloc);
205027
- printf("nJson = %d\n", p->nJson);
205028
- printf("nAlt = %d\n", p->nAlt);
205029
- printf("nErr = %u\n", p->nErr);
205030
- printf("oom = %u\n", p->oom);
205031
- printf("hasNonstd = %u\n", p->hasNonstd);
205032
- printf("useMod = %u\n", p->useMod);
205033
- printf("hasMod = %u\n", p->hasMod);
205034
- printf("nJPRef = %u\n", p->nJPRef);
205035
- printf("iSubst = %u\n", p->iSubst);
205036
- printf("iHold = %u\n", p->iHold);
205037
- jsonDebugPrintNodeEntries(p->aNode, p->nNode);
205038
- jsonReturnJson(p, p->aNode, ctx, 1, 0);
205039
-}
205040
-
205041
-/*
205042
-** The json_test1(JSON) function return true (1) if the input is JSON
205043
-** text generated by another json function. It returns (0) if the input
205044
-** is not known to be JSON.
205045
-*/
205046
-static void jsonTest1Func(
205047
- sqlite3_context *ctx,
205048
- int argc,
205049
- sqlite3_value **argv
205050
-){
205051
- UNUSED_PARAMETER(argc);
205052
- sqlite3_result_int(ctx, sqlite3_value_subtype(argv[0])==JSON_SUBTYPE);
206449
+ p = jsonParseFuncArg(ctx, argv[0], 0);
206450
+ jsonShowParse(p);
206451
+ jsonParseFree(p);
205053206452
}
205054206453
#endif /* SQLITE_DEBUG */
205055206454
205056206455
/****************************************************************************
205057206456
** Scalar SQL function implementations
205058206457
****************************************************************************/
205059206458
205060206459
/*
205061
-** Implementation of the json_QUOTE(VALUE) function. Return a JSON value
206460
+** Implementation of the json_quote(VALUE) function. Return a JSON value
205062206461
** corresponding to the SQL value input. Mostly this means putting
205063206462
** double-quotes around strings and returning the unquoted string "null"
205064206463
** when given a NULL input.
205065206464
*/
205066206465
static void jsonQuoteFunc(
@@ -205069,13 +206468,13 @@
205069206468
sqlite3_value **argv
205070206469
){
205071206470
JsonString jx;
205072206471
UNUSED_PARAMETER(argc);
205073206472
205074
- jsonInit(&jx, ctx);
205075
- jsonAppendValue(&jx, argv[0]);
205076
- jsonResult(&jx);
206473
+ jsonStringInit(&jx, ctx);
206474
+ jsonAppendSqlValue(&jx, argv[0]);
206475
+ jsonReturnString(&jx, 0, 0);
205077206476
sqlite3_result_subtype(ctx, JSON_SUBTYPE);
205078206477
}
205079206478
205080206479
/*
205081206480
** Implementation of the json_array(VALUE,...) function. Return a JSON
@@ -205088,21 +206487,20 @@
205088206487
sqlite3_value **argv
205089206488
){
205090206489
int i;
205091206490
JsonString jx;
205092206491
205093
- jsonInit(&jx, ctx);
206492
+ jsonStringInit(&jx, ctx);
205094206493
jsonAppendChar(&jx, '[');
205095206494
for(i=0; i<argc; i++){
205096206495
jsonAppendSeparator(&jx);
205097
- jsonAppendValue(&jx, argv[i]);
206496
+ jsonAppendSqlValue(&jx, argv[i]);
205098206497
}
205099206498
jsonAppendChar(&jx, ']');
205100
- jsonResult(&jx);
206499
+ jsonReturnString(&jx, 0, 0);
205101206500
sqlite3_result_subtype(ctx, JSON_SUBTYPE);
205102206501
}
205103
-
205104206502
205105206503
/*
205106206504
** json_array_length(JSON)
205107206505
** json_array_length(JSON, PATH)
205108206506
**
@@ -205113,50 +206511,57 @@
205113206511
sqlite3_context *ctx,
205114206512
int argc,
205115206513
sqlite3_value **argv
205116206514
){
205117206515
JsonParse *p; /* The parse */
205118
- sqlite3_int64 n = 0;
206516
+ sqlite3_int64 cnt = 0;
205119206517
u32 i;
205120
- JsonNode *pNode;
206518
+ u8 eErr = 0;
205121206519
205122
- p = jsonParseCached(ctx, argv[0], ctx, 0);
206520
+ p = jsonParseFuncArg(ctx, argv[0], 0);
205123206521
if( p==0 ) return;
205124
- assert( p->nNode );
205125206522
if( argc==2 ){
205126206523
const char *zPath = (const char*)sqlite3_value_text(argv[1]);
205127
- pNode = jsonLookup(p, zPath, 0, ctx);
205128
- }else{
205129
- pNode = p->aNode;
205130
- }
205131
- if( pNode==0 ){
205132
- return;
205133
- }
205134
- if( pNode->eType==JSON_ARRAY ){
205135
- while( 1 /*exit-by-break*/ ){
205136
- i = 1;
205137
- while( i<=pNode->n ){
205138
- if( (pNode[i].jnFlags & JNODE_REMOVE)==0 ) n++;
205139
- i += jsonNodeSize(&pNode[i]);
205140
- }
205141
- if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
205142
- if( p->useMod==0 ) break;
205143
- assert( pNode->eU==2 );
205144
- pNode = &p->aNode[pNode->u.iAppend];
205145
- }
205146
- }
205147
- sqlite3_result_int64(ctx, n);
205148
-}
205149
-
205150
-/*
205151
-** Bit values for the flags passed into jsonExtractFunc() or
205152
-** jsonSetFunc() via the user-data value.
205153
-*/
205154
-#define JSON_JSON 0x01 /* Result is always JSON */
205155
-#define JSON_SQL 0x02 /* Result is always SQL */
205156
-#define JSON_ABPATH 0x03 /* Allow abbreviated JSON path specs */
205157
-#define JSON_ISSET 0x04 /* json_set(), not json_insert() */
206524
+ if( zPath==0 ){
206525
+ jsonParseFree(p);
206526
+ return;
206527
+ }
206528
+ i = jsonLookupStep(p, 0, zPath[0]=='$' ? zPath+1 : "@", 0);
206529
+ if( JSON_LOOKUP_ISERROR(i) ){
206530
+ if( i==JSON_LOOKUP_NOTFOUND ){
206531
+ /* no-op */
206532
+ }else if( i==JSON_LOOKUP_PATHERROR ){
206533
+ jsonBadPathError(ctx, zPath);
206534
+ }else{
206535
+ sqlite3_result_error(ctx, "malformed JSON", -1);
206536
+ }
206537
+ eErr = 1;
206538
+ i = 0;
206539
+ }
206540
+ }else{
206541
+ i = 0;
206542
+ }
206543
+ if( (p->aBlob[i] & 0x0f)==JSONB_ARRAY ){
206544
+ cnt = jsonbArrayCount(p, i);
206545
+ }
206546
+ if( !eErr ) sqlite3_result_int64(ctx, cnt);
206547
+ jsonParseFree(p);
206548
+}
206549
+
206550
+/* True if the string is all digits */
206551
+static int jsonAllDigits(const char *z, int n){
206552
+ int i;
206553
+ for(i=0; i<n && sqlite3Isdigit(z[i]); i++){}
206554
+ return i==n;
206555
+}
206556
+
206557
+/* True if the string is all alphanumerics and underscores */
206558
+static int jsonAllAlphanum(const char *z, int n){
206559
+ int i;
206560
+ for(i=0; i<n && (sqlite3Isalnum(z[i]) || z[i]=='_'); i++){}
206561
+ return i==n;
206562
+}
205158206563
205159206564
/*
205160206565
** json_extract(JSON, PATH, ...)
205161206566
** "->"(JSON,PATH)
205162206567
** "->>"(JSON,PATH)
@@ -205179,154 +206584,310 @@
205179206584
static void jsonExtractFunc(
205180206585
sqlite3_context *ctx,
205181206586
int argc,
205182206587
sqlite3_value **argv
205183206588
){
205184
- JsonParse *p; /* The parse */
205185
- JsonNode *pNode;
205186
- const char *zPath;
205187
- int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx));
205188
- JsonString jx;
206589
+ JsonParse *p = 0; /* The parse */
206590
+ int flags; /* Flags associated with the function */
206591
+ int i; /* Loop counter */
206592
+ JsonString jx; /* String for array result */
205189206593
205190206594
if( argc<2 ) return;
205191
- p = jsonParseCached(ctx, argv[0], ctx, 0);
206595
+ p = jsonParseFuncArg(ctx, argv[0], 0);
205192206596
if( p==0 ) return;
205193
- if( argc==2 ){
206597
+ flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx));
206598
+ jsonStringInit(&jx, ctx);
206599
+ if( argc>2 ){
206600
+ jsonAppendChar(&jx, '[');
206601
+ }
206602
+ for(i=1; i<argc; i++){
205194206603
/* With a single PATH argument */
205195
- zPath = (const char*)sqlite3_value_text(argv[1]);
205196
- if( zPath==0 ) return;
205197
- if( flags & JSON_ABPATH ){
205198
- if( zPath[0]!='$' || (zPath[1]!='.' && zPath[1]!='[' && zPath[1]!=0) ){
205199
- /* The -> and ->> operators accept abbreviated PATH arguments. This
205200
- ** is mostly for compatibility with PostgreSQL, but also for
205201
- ** convenience.
205202
- **
205203
- ** NUMBER ==> $[NUMBER] // PG compatible
205204
- ** LABEL ==> $.LABEL // PG compatible
205205
- ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience
205206
- */
205207
- jsonInit(&jx, ctx);
205208
- if( sqlite3Isdigit(zPath[0]) ){
205209
- jsonAppendRawNZ(&jx, "$[", 2);
205210
- jsonAppendRaw(&jx, zPath, (int)strlen(zPath));
205211
- jsonAppendRawNZ(&jx, "]", 2);
205212
- }else{
205213
- jsonAppendRawNZ(&jx, "$.", 1 + (zPath[0]!='['));
205214
- jsonAppendRaw(&jx, zPath, (int)strlen(zPath));
205215
- jsonAppendChar(&jx, 0);
205216
- }
205217
- pNode = jx.bErr ? 0 : jsonLookup(p, jx.zBuf, 0, ctx);
205218
- jsonReset(&jx);
205219
- }else{
205220
- pNode = jsonLookup(p, zPath, 0, ctx);
205221
- }
205222
- if( pNode ){
206604
+ const char *zPath = (const char*)sqlite3_value_text(argv[i]);
206605
+ int nPath;
206606
+ u32 j;
206607
+ if( zPath==0 ) goto json_extract_error;
206608
+ nPath = sqlite3Strlen30(zPath);
206609
+ if( zPath[0]=='$' ){
206610
+ j = jsonLookupStep(p, 0, zPath+1, 0);
206611
+ }else if( (flags & JSON_ABPATH) ){
206612
+ /* The -> and ->> operators accept abbreviated PATH arguments. This
206613
+ ** is mostly for compatibility with PostgreSQL, but also for
206614
+ ** convenience.
206615
+ **
206616
+ ** NUMBER ==> $[NUMBER] // PG compatible
206617
+ ** LABEL ==> $.LABEL // PG compatible
206618
+ ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience
206619
+ */
206620
+ jsonStringInit(&jx, ctx);
206621
+ if( jsonAllDigits(zPath, nPath) ){
206622
+ jsonAppendRawNZ(&jx, "[", 1);
206623
+ jsonAppendRaw(&jx, zPath, nPath);
206624
+ jsonAppendRawNZ(&jx, "]", 2);
206625
+ }else if( jsonAllAlphanum(zPath, nPath) ){
206626
+ jsonAppendRawNZ(&jx, ".", 1);
206627
+ jsonAppendRaw(&jx, zPath, nPath);
206628
+ }else if( zPath[0]=='[' && nPath>=3 && zPath[nPath-1]==']' ){
206629
+ jsonAppendRaw(&jx, zPath, nPath);
206630
+ }else{
206631
+ jsonAppendRawNZ(&jx, ".\"", 2);
206632
+ jsonAppendRaw(&jx, zPath, nPath);
206633
+ jsonAppendRawNZ(&jx, "\"", 1);
206634
+ }
206635
+ jsonStringTerminate(&jx);
206636
+ j = jsonLookupStep(p, 0, jx.zBuf, 0);
206637
+ jsonStringReset(&jx);
206638
+ }else{
206639
+ jsonBadPathError(ctx, zPath);
206640
+ goto json_extract_error;
206641
+ }
206642
+ if( j<p->nBlob ){
206643
+ if( argc==2 ){
205223206644
if( flags & JSON_JSON ){
205224
- jsonReturnJson(p, pNode, ctx, 0, 0);
205225
- }else{
205226
- jsonReturn(p, pNode, ctx, 1);
205227
- }
205228
- }
205229
- }else{
205230
- pNode = jsonLookup(p, zPath, 0, ctx);
205231
- if( p->nErr==0 && pNode ) jsonReturn(p, pNode, ctx, 0);
205232
- }
205233
- }else{
205234
- /* Two or more PATH arguments results in a JSON array with each
205235
- ** element of the array being the value selected by one of the PATHs */
205236
- int i;
205237
- jsonInit(&jx, ctx);
205238
- jsonAppendChar(&jx, '[');
205239
- for(i=1; i<argc; i++){
205240
- zPath = (const char*)sqlite3_value_text(argv[i]);
205241
- pNode = jsonLookup(p, zPath, 0, ctx);
205242
- if( p->nErr ) break;
205243
- jsonAppendSeparator(&jx);
205244
- if( pNode ){
205245
- jsonRenderNode(p, pNode, &jx);
205246
- }else{
206645
+ jsonStringInit(&jx, ctx);
206646
+ jsonXlateBlobToText(p, j, &jx);
206647
+ jsonReturnString(&jx, 0, 0);
206648
+ jsonStringReset(&jx);
206649
+ assert( (flags & JSON_BLOB)==0 );
206650
+ sqlite3_result_subtype(ctx, JSON_SUBTYPE);
206651
+ }else{
206652
+ jsonReturnFromBlob(p, j, ctx, 0);
206653
+ if( (flags & (JSON_SQL|JSON_BLOB))==0
206654
+ && (p->aBlob[j]&0x0f)>=JSONB_ARRAY
206655
+ ){
206656
+ sqlite3_result_subtype(ctx, JSON_SUBTYPE);
206657
+ }
206658
+ }
206659
+ }else{
206660
+ jsonAppendSeparator(&jx);
206661
+ jsonXlateBlobToText(p, j, &jx);
206662
+ }
206663
+ }else if( j==JSON_LOOKUP_NOTFOUND ){
206664
+ if( argc==2 ){
206665
+ goto json_extract_error; /* Return NULL if not found */
206666
+ }else{
206667
+ jsonAppendSeparator(&jx);
205247206668
jsonAppendRawNZ(&jx, "null", 4);
205248206669
}
206670
+ }else if( j==JSON_LOOKUP_ERROR ){
206671
+ sqlite3_result_error(ctx, "malformed JSON", -1);
206672
+ goto json_extract_error;
206673
+ }else{
206674
+ jsonBadPathError(ctx, zPath);
206675
+ goto json_extract_error;
205249206676
}
205250
- if( i==argc ){
205251
- jsonAppendChar(&jx, ']');
205252
- jsonResult(&jx);
206677
+ }
206678
+ if( argc>2 ){
206679
+ jsonAppendChar(&jx, ']');
206680
+ jsonReturnString(&jx, 0, 0);
206681
+ if( (flags & JSON_BLOB)==0 ){
205253206682
sqlite3_result_subtype(ctx, JSON_SUBTYPE);
205254206683
}
205255
- jsonReset(&jx);
205256
- }
205257
-}
205258
-
205259
-/* This is the RFC 7396 MergePatch algorithm.
205260
-*/
205261
-static JsonNode *jsonMergePatch(
205262
- JsonParse *pParse, /* The JSON parser that contains the TARGET */
205263
- u32 iTarget, /* Node of the TARGET in pParse */
205264
- JsonNode *pPatch /* The PATCH */
205265
-){
205266
- u32 i, j;
205267
- u32 iRoot;
205268
- JsonNode *pTarget;
205269
- if( pPatch->eType!=JSON_OBJECT ){
205270
- return pPatch;
205271
- }
205272
- assert( iTarget<pParse->nNode );
205273
- pTarget = &pParse->aNode[iTarget];
205274
- assert( (pPatch->jnFlags & JNODE_APPEND)==0 );
205275
- if( pTarget->eType!=JSON_OBJECT ){
205276
- jsonRemoveAllNulls(pPatch);
205277
- return pPatch;
205278
- }
205279
- iRoot = iTarget;
205280
- for(i=1; i<pPatch->n; i += jsonNodeSize(&pPatch[i+1])+1){
205281
- u32 nKey;
205282
- const char *zKey;
205283
- assert( pPatch[i].eType==JSON_STRING );
205284
- assert( pPatch[i].jnFlags & JNODE_LABEL );
205285
- assert( pPatch[i].eU==1 );
205286
- nKey = pPatch[i].n;
205287
- zKey = pPatch[i].u.zJContent;
205288
- for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){
205289
- assert( pTarget[j].eType==JSON_STRING );
205290
- assert( pTarget[j].jnFlags & JNODE_LABEL );
205291
- if( jsonSameLabel(&pPatch[i], &pTarget[j]) ){
205292
- if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ) break;
205293
- if( pPatch[i+1].eType==JSON_NULL ){
205294
- pTarget[j+1].jnFlags |= JNODE_REMOVE;
205295
- }else{
205296
- JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]);
205297
- if( pNew==0 ) return 0;
205298
- if( pNew!=&pParse->aNode[iTarget+j+1] ){
205299
- jsonParseAddSubstNode(pParse, iTarget+j+1);
205300
- jsonParseAddNodeArray(pParse, pNew, jsonNodeSize(pNew));
205301
- }
205302
- pTarget = &pParse->aNode[iTarget];
205303
- }
205304
- break;
205305
- }
205306
- }
205307
- if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){
205308
- int iStart;
205309
- JsonNode *pApnd;
205310
- u32 nApnd;
205311
- iStart = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
205312
- jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
205313
- pApnd = &pPatch[i+1];
205314
- if( pApnd->eType==JSON_OBJECT ) jsonRemoveAllNulls(pApnd);
205315
- nApnd = jsonNodeSize(pApnd);
205316
- jsonParseAddNodeArray(pParse, pApnd, jsonNodeSize(pApnd));
205317
- if( pParse->oom ) return 0;
205318
- pParse->aNode[iStart].n = 1+nApnd;
205319
- pParse->aNode[iRoot].jnFlags |= JNODE_APPEND;
205320
- pParse->aNode[iRoot].u.iAppend = iStart;
205321
- VVA( pParse->aNode[iRoot].eU = 2 );
205322
- iRoot = iStart;
205323
- pTarget = &pParse->aNode[iTarget];
205324
- }
205325
- }
205326
- return pTarget;
205327
-}
206684
+ }
206685
+json_extract_error:
206686
+ jsonStringReset(&jx);
206687
+ jsonParseFree(p);
206688
+ return;
206689
+}
206690
+
206691
+/*
206692
+** Return codes for jsonMergePatch()
206693
+*/
206694
+#define JSON_MERGE_OK 0 /* Success */
206695
+#define JSON_MERGE_BADTARGET 1 /* Malformed TARGET blob */
206696
+#define JSON_MERGE_BADPATCH 2 /* Malformed PATCH blob */
206697
+#define JSON_MERGE_OOM 3 /* Out-of-memory condition */
206698
+
206699
+/*
206700
+** RFC-7396 MergePatch for two JSONB blobs.
206701
+**
206702
+** pTarget is the target. pPatch is the patch. The target is updated
206703
+** in place. The patch is read-only.
206704
+**
206705
+** The original RFC-7396 algorithm is this:
206706
+**
206707
+** define MergePatch(Target, Patch):
206708
+** if Patch is an Object:
206709
+** if Target is not an Object:
206710
+** Target = {} # Ignore the contents and set it to an empty Object
206711
+** for each Name/Value pair in Patch:
206712
+** if Value is null:
206713
+** if Name exists in Target:
206714
+** remove the Name/Value pair from Target
206715
+** else:
206716
+** Target[Name] = MergePatch(Target[Name], Value)
206717
+** return Target
206718
+** else:
206719
+** return Patch
206720
+**
206721
+** Here is an equivalent algorithm restructured to show the actual
206722
+** implementation:
206723
+**
206724
+** 01 define MergePatch(Target, Patch):
206725
+** 02 if Patch is not an Object:
206726
+** 03 return Patch
206727
+** 04 else: // if Patch is an Object
206728
+** 05 if Target is not an Object:
206729
+** 06 Target = {}
206730
+** 07 for each Name/Value pair in Patch:
206731
+** 08 if Name exists in Target:
206732
+** 09 if Value is null:
206733
+** 10 remove the Name/Value pair from Target
206734
+** 11 else
206735
+** 12 Target[name] = MergePatch(Target[Name], Value)
206736
+** 13 else if Value is not NULL:
206737
+** 14 if Value is not an Object:
206738
+** 15 Target[name] = Value
206739
+** 16 else:
206740
+** 17 Target[name] = MergePatch('{}',value)
206741
+** 18 return Target
206742
+** |
206743
+** ^---- Line numbers referenced in comments in the implementation
206744
+*/
206745
+static int jsonMergePatch(
206746
+ JsonParse *pTarget, /* The JSON parser that contains the TARGET */
206747
+ u32 iTarget, /* Index of TARGET in pTarget->aBlob[] */
206748
+ const JsonParse *pPatch, /* The PATCH */
206749
+ u32 iPatch /* Index of PATCH in pPatch->aBlob[] */
206750
+){
206751
+ u8 x; /* Type of a single node */
206752
+ u32 n, sz=0; /* Return values from jsonbPayloadSize() */
206753
+ u32 iTCursor; /* Cursor position while scanning the target object */
206754
+ u32 iTStart; /* First label in the target object */
206755
+ u32 iTEndBE; /* Original first byte past end of target, before edit */
206756
+ u32 iTEnd; /* Current first byte past end of target */
206757
+ u8 eTLabel; /* Node type of the target label */
206758
+ u32 iTLabel = 0; /* Index of the label */
206759
+ u32 nTLabel = 0; /* Header size in bytes for the target label */
206760
+ u32 szTLabel = 0; /* Size of the target label payload */
206761
+ u32 iTValue = 0; /* Index of the target value */
206762
+ u32 nTValue = 0; /* Header size of the target value */
206763
+ u32 szTValue = 0; /* Payload size for the target value */
206764
+
206765
+ u32 iPCursor; /* Cursor position while scanning the patch */
206766
+ u32 iPEnd; /* First byte past the end of the patch */
206767
+ u8 ePLabel; /* Node type of the patch label */
206768
+ u32 iPLabel; /* Start of patch label */
206769
+ u32 nPLabel; /* Size of header on the patch label */
206770
+ u32 szPLabel; /* Payload size of the patch label */
206771
+ u32 iPValue; /* Start of patch value */
206772
+ u32 nPValue; /* Header size for the patch value */
206773
+ u32 szPValue; /* Payload size of the patch value */
206774
+
206775
+ assert( iTarget>=0 && iTarget<pTarget->nBlob );
206776
+ assert( iPatch>=0 && iPatch<pPatch->nBlob );
206777
+ x = pPatch->aBlob[iPatch] & 0x0f;
206778
+ if( x!=JSONB_OBJECT ){ /* Algorithm line 02 */
206779
+ u32 szPatch; /* Total size of the patch, header+payload */
206780
+ u32 szTarget; /* Total size of the target, header+payload */
206781
+ n = jsonbPayloadSize(pPatch, iPatch, &sz);
206782
+ szPatch = n+sz;
206783
+ sz = 0;
206784
+ n = jsonbPayloadSize(pTarget, iTarget, &sz);
206785
+ szTarget = n+sz;
206786
+ jsonBlobEdit(pTarget, iTarget, szTarget, pPatch->aBlob+iPatch, szPatch);
206787
+ return pTarget->oom ? JSON_MERGE_OOM : JSON_MERGE_OK; /* Line 03 */
206788
+ }
206789
+ x = pTarget->aBlob[iTarget] & 0x0f;
206790
+ if( x!=JSONB_OBJECT ){ /* Algorithm line 05 */
206791
+ n = jsonbPayloadSize(pTarget, iTarget, &sz);
206792
+ jsonBlobEdit(pTarget, iTarget+n, sz, 0, 0);
206793
+ x = pTarget->aBlob[iTarget];
206794
+ pTarget->aBlob[iTarget] = (x & 0xf0) | JSONB_OBJECT;
206795
+ }
206796
+ n = jsonbPayloadSize(pPatch, iPatch, &sz);
206797
+ if( NEVER(n==0) ) return JSON_MERGE_BADPATCH;
206798
+ iPCursor = iPatch+n;
206799
+ iPEnd = iPCursor+sz;
206800
+ n = jsonbPayloadSize(pTarget, iTarget, &sz);
206801
+ if( NEVER(n==0) ) return JSON_MERGE_BADTARGET;
206802
+ iTStart = iTarget+n;
206803
+ iTEndBE = iTStart+sz;
206804
+
206805
+ while( iPCursor<iPEnd ){ /* Algorithm line 07 */
206806
+ iPLabel = iPCursor;
206807
+ ePLabel = pPatch->aBlob[iPCursor] & 0x0f;
206808
+ if( ePLabel<JSONB_TEXT || ePLabel>JSONB_TEXTRAW ){
206809
+ return JSON_MERGE_BADPATCH;
206810
+ }
206811
+ nPLabel = jsonbPayloadSize(pPatch, iPCursor, &szPLabel);
206812
+ if( nPLabel==0 ) return JSON_MERGE_BADPATCH;
206813
+ iPValue = iPCursor + nPLabel + szPLabel;
206814
+ if( iPValue>=iPEnd ) return JSON_MERGE_BADPATCH;
206815
+ nPValue = jsonbPayloadSize(pPatch, iPValue, &szPValue);
206816
+ if( nPValue==0 ) return JSON_MERGE_BADPATCH;
206817
+ iPCursor = iPValue + nPValue + szPValue;
206818
+ if( iPCursor>iPEnd ) return JSON_MERGE_BADPATCH;
206819
+
206820
+ iTCursor = iTStart;
206821
+ iTEnd = iTEndBE + pTarget->delta;
206822
+ while( iTCursor<iTEnd ){
206823
+ int isEqual; /* true if the patch and target labels match */
206824
+ iTLabel = iTCursor;
206825
+ eTLabel = pTarget->aBlob[iTCursor] & 0x0f;
206826
+ if( eTLabel<JSONB_TEXT || eTLabel>JSONB_TEXTRAW ){
206827
+ return JSON_MERGE_BADTARGET;
206828
+ }
206829
+ nTLabel = jsonbPayloadSize(pTarget, iTCursor, &szTLabel);
206830
+ if( nTLabel==0 ) return JSON_MERGE_BADTARGET;
206831
+ iTValue = iTLabel + nTLabel + szTLabel;
206832
+ if( iTValue>=iTEnd ) return JSON_MERGE_BADTARGET;
206833
+ nTValue = jsonbPayloadSize(pTarget, iTValue, &szTValue);
206834
+ if( nTValue==0 ) return JSON_MERGE_BADTARGET;
206835
+ if( iTValue + nTValue + szTValue > iTEnd ) return JSON_MERGE_BADTARGET;
206836
+ isEqual = jsonLabelCompare(
206837
+ (const char*)&pPatch->aBlob[iPLabel+nPLabel],
206838
+ szPLabel,
206839
+ (ePLabel==JSONB_TEXT || ePLabel==JSONB_TEXTRAW),
206840
+ (const char*)&pTarget->aBlob[iTLabel+nTLabel],
206841
+ szTLabel,
206842
+ (eTLabel==JSONB_TEXT || eTLabel==JSONB_TEXTRAW));
206843
+ if( isEqual ) break;
206844
+ iTCursor = iTValue + nTValue + szTValue;
206845
+ }
206846
+ x = pPatch->aBlob[iPValue] & 0x0f;
206847
+ if( iTCursor<iTEnd ){
206848
+ /* A match was found. Algorithm line 08 */
206849
+ if( x==0 ){
206850
+ /* Patch value is NULL. Algorithm line 09 */
206851
+ jsonBlobEdit(pTarget, iTLabel, nTLabel+szTLabel+nTValue+szTValue, 0,0);
206852
+ /* vvvvvv----- No OOM on a delete-only edit */
206853
+ if( NEVER(pTarget->oom) ) return JSON_MERGE_OOM;
206854
+ }else{
206855
+ /* Algorithm line 12 */
206856
+ int rc, savedDelta = pTarget->delta;
206857
+ pTarget->delta = 0;
206858
+ rc = jsonMergePatch(pTarget, iTValue, pPatch, iPValue);
206859
+ if( rc ) return rc;
206860
+ pTarget->delta += savedDelta;
206861
+ }
206862
+ }else if( x>0 ){ /* Algorithm line 13 */
206863
+ /* No match and patch value is not NULL */
206864
+ u32 szNew = szPLabel+nPLabel;
206865
+ if( (pPatch->aBlob[iPValue] & 0x0f)!=JSONB_OBJECT ){ /* Line 14 */
206866
+ jsonBlobEdit(pTarget, iTEnd, 0, 0, szPValue+nPValue+szNew);
206867
+ if( pTarget->oom ) return JSON_MERGE_OOM;
206868
+ memcpy(&pTarget->aBlob[iTEnd], &pPatch->aBlob[iPLabel], szNew);
206869
+ memcpy(&pTarget->aBlob[iTEnd+szNew],
206870
+ &pPatch->aBlob[iPValue], szPValue+nPValue);
206871
+ }else{
206872
+ int rc, savedDelta;
206873
+ jsonBlobEdit(pTarget, iTEnd, 0, 0, szNew+1);
206874
+ if( pTarget->oom ) return JSON_MERGE_OOM;
206875
+ memcpy(&pTarget->aBlob[iTEnd], &pPatch->aBlob[iPLabel], szNew);
206876
+ pTarget->aBlob[iTEnd+szNew] = 0x00;
206877
+ savedDelta = pTarget->delta;
206878
+ pTarget->delta = 0;
206879
+ rc = jsonMergePatch(pTarget, iTEnd+szNew,pPatch,iPValue);
206880
+ if( rc ) return rc;
206881
+ pTarget->delta += savedDelta;
206882
+ }
206883
+ }
206884
+ }
206885
+ if( pTarget->delta ) jsonAfterEditSizeAdjust(pTarget, iTarget);
206886
+ return pTarget->oom ? JSON_MERGE_OOM : JSON_MERGE_OK;
206887
+}
206888
+
205328206889
205329206890
/*
205330206891
** Implementation of the json_mergepatch(JSON1,JSON2) function. Return a JSON
205331206892
** object that is the result of running the RFC 7396 MergePatch() algorithm
205332206893
** on the two arguments.
@@ -205334,32 +206895,31 @@
205334206895
static void jsonPatchFunc(
205335206896
sqlite3_context *ctx,
205336206897
int argc,
205337206898
sqlite3_value **argv
205338206899
){
205339
- JsonParse *pX; /* The JSON that is being patched */
205340
- JsonParse *pY; /* The patch */
205341
- JsonNode *pResult; /* The result of the merge */
206900
+ JsonParse *pTarget; /* The TARGET */
206901
+ JsonParse *pPatch; /* The PATCH */
206902
+ int rc; /* Result code */
205342206903
205343206904
UNUSED_PARAMETER(argc);
205344
- pX = jsonParseCached(ctx, argv[0], ctx, 1);
205345
- if( pX==0 ) return;
205346
- assert( pX->hasMod==0 );
205347
- pX->hasMod = 1;
205348
- pY = jsonParseCached(ctx, argv[1], ctx, 1);
205349
- if( pY==0 ) return;
205350
- pX->useMod = 1;
205351
- pY->useMod = 1;
205352
- pResult = jsonMergePatch(pX, 0, pY->aNode);
205353
- assert( pResult!=0 || pX->oom );
205354
- if( pResult && pX->oom==0 ){
205355
- jsonDebugPrintParse(pX);
205356
- jsonDebugPrintNode(pResult);
205357
- jsonReturnJson(pX, pResult, ctx, 0, 0);
205358
- }else{
205359
- sqlite3_result_error_nomem(ctx);
205360
- }
206905
+ assert( argc==2 );
206906
+ pTarget = jsonParseFuncArg(ctx, argv[0], JSON_EDITABLE);
206907
+ if( pTarget==0 ) return;
206908
+ pPatch = jsonParseFuncArg(ctx, argv[1], 0);
206909
+ if( pPatch ){
206910
+ rc = jsonMergePatch(pTarget, 0, pPatch, 0);
206911
+ if( rc==JSON_MERGE_OK ){
206912
+ jsonReturnParse(ctx, pTarget);
206913
+ }else if( rc==JSON_MERGE_OOM ){
206914
+ sqlite3_result_error_nomem(ctx);
206915
+ }else{
206916
+ sqlite3_result_error(ctx, "malformed JSON", -1);
206917
+ }
206918
+ jsonParseFree(pPatch);
206919
+ }
206920
+ jsonParseFree(pTarget);
205361206921
}
205362206922
205363206923
205364206924
/*
205365206925
** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON
@@ -205379,27 +206939,27 @@
205379206939
if( argc&1 ){
205380206940
sqlite3_result_error(ctx, "json_object() requires an even number "
205381206941
"of arguments", -1);
205382206942
return;
205383206943
}
205384
- jsonInit(&jx, ctx);
206944
+ jsonStringInit(&jx, ctx);
205385206945
jsonAppendChar(&jx, '{');
205386206946
for(i=0; i<argc; i+=2){
205387206947
if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){
205388206948
sqlite3_result_error(ctx, "json_object() labels must be TEXT", -1);
205389
- jsonReset(&jx);
206949
+ jsonStringReset(&jx);
205390206950
return;
205391206951
}
205392206952
jsonAppendSeparator(&jx);
205393206953
z = (const char*)sqlite3_value_text(argv[i]);
205394
- n = (u32)sqlite3_value_bytes(argv[i]);
206954
+ n = sqlite3_value_bytes(argv[i]);
205395206955
jsonAppendString(&jx, z, n);
205396206956
jsonAppendChar(&jx, ':');
205397
- jsonAppendValue(&jx, argv[i+1]);
206957
+ jsonAppendSqlValue(&jx, argv[i+1]);
205398206958
}
205399206959
jsonAppendChar(&jx, '}');
205400
- jsonResult(&jx);
206960
+ jsonReturnString(&jx, 0, 0);
205401206961
sqlite3_result_subtype(ctx, JSON_SUBTYPE);
205402206962
}
205403206963
205404206964
205405206965
/*
@@ -205411,124 +206971,54 @@
205411206971
static void jsonRemoveFunc(
205412206972
sqlite3_context *ctx,
205413206973
int argc,
205414206974
sqlite3_value **argv
205415206975
){
205416
- JsonParse *pParse; /* The parse */
205417
- JsonNode *pNode;
205418
- const char *zPath;
205419
- u32 i;
206976
+ JsonParse *p; /* The parse */
206977
+ const char *zPath = 0; /* Path of element to be removed */
206978
+ int i; /* Loop counter */
206979
+ u32 rc; /* Subroutine return code */
205420206980
205421206981
if( argc<1 ) return;
205422
- pParse = jsonParseCached(ctx, argv[0], ctx, argc>1);
205423
- if( pParse==0 ) return;
205424
- for(i=1; i<(u32)argc; i++){
206982
+ p = jsonParseFuncArg(ctx, argv[0], argc>1 ? JSON_EDITABLE : 0);
206983
+ if( p==0 ) return;
206984
+ for(i=1; i<argc; i++){
205425206985
zPath = (const char*)sqlite3_value_text(argv[i]);
205426
- if( zPath==0 ) goto remove_done;
205427
- pNode = jsonLookup(pParse, zPath, 0, ctx);
205428
- if( pParse->nErr ) goto remove_done;
205429
- if( pNode ){
205430
- pNode->jnFlags |= JNODE_REMOVE;
205431
- pParse->hasMod = 1;
205432
- pParse->useMod = 1;
205433
- }
205434
- }
205435
- if( (pParse->aNode[0].jnFlags & JNODE_REMOVE)==0 ){
205436
- jsonReturnJson(pParse, pParse->aNode, ctx, 1, 0);
205437
- }
205438
-remove_done:
205439
- jsonDebugPrintParse(p);
205440
-}
205441
-
205442
-/*
205443
-** Substitute the value at iNode with the pValue parameter.
205444
-*/
205445
-static void jsonReplaceNode(
205446
- sqlite3_context *pCtx,
205447
- JsonParse *p,
205448
- int iNode,
205449
- sqlite3_value *pValue
205450
-){
205451
- int idx = jsonParseAddSubstNode(p, iNode);
205452
- if( idx<=0 ){
205453
- assert( p->oom );
205454
- return;
205455
- }
205456
- switch( sqlite3_value_type(pValue) ){
205457
- case SQLITE_NULL: {
205458
- jsonParseAddNode(p, JSON_NULL, 0, 0);
205459
- break;
205460
- }
205461
- case SQLITE_FLOAT: {
205462
- char *z = sqlite3_mprintf("%!0.15g", sqlite3_value_double(pValue));
205463
- int n;
205464
- if( z==0 ){
205465
- p->oom = 1;
205466
- break;
205467
- }
205468
- n = sqlite3Strlen30(z);
205469
- jsonParseAddNode(p, JSON_REAL, n, z);
205470
- jsonParseAddCleanup(p, sqlite3_free, z);
205471
- break;
205472
- }
205473
- case SQLITE_INTEGER: {
205474
- char *z = sqlite3_mprintf("%lld", sqlite3_value_int64(pValue));
205475
- int n;
205476
- if( z==0 ){
205477
- p->oom = 1;
205478
- break;
205479
- }
205480
- n = sqlite3Strlen30(z);
205481
- jsonParseAddNode(p, JSON_INT, n, z);
205482
- jsonParseAddCleanup(p, sqlite3_free, z);
205483
-
205484
- break;
205485
- }
205486
- case SQLITE_TEXT: {
205487
- const char *z = (const char*)sqlite3_value_text(pValue);
205488
- u32 n = (u32)sqlite3_value_bytes(pValue);
205489
- if( z==0 ){
205490
- p->oom = 1;
205491
- break;
205492
- }
205493
- if( sqlite3_value_subtype(pValue)!=JSON_SUBTYPE ){
205494
- char *zCopy = sqlite3_malloc64( n+1 );
205495
- int k;
205496
- if( zCopy ){
205497
- memcpy(zCopy, z, n);
205498
- zCopy[n] = 0;
205499
- jsonParseAddCleanup(p, sqlite3_free, zCopy);
205500
- }else{
205501
- p->oom = 1;
205502
- sqlite3_result_error_nomem(pCtx);
205503
- }
205504
- k = jsonParseAddNode(p, JSON_STRING, n, zCopy);
205505
- assert( k>0 || p->oom );
205506
- if( p->oom==0 ) p->aNode[k].jnFlags |= JNODE_RAW;
205507
- }else{
205508
- JsonParse *pPatch = jsonParseCached(pCtx, pValue, pCtx, 1);
205509
- if( pPatch==0 ){
205510
- p->oom = 1;
205511
- break;
205512
- }
205513
- jsonParseAddNodeArray(p, pPatch->aNode, pPatch->nNode);
205514
- /* The nodes copied out of pPatch and into p likely contain
205515
- ** u.zJContent pointers into pPatch->zJson. So preserve the
205516
- ** content of pPatch until p is destroyed. */
205517
- assert( pPatch->nJPRef>=1 );
205518
- pPatch->nJPRef++;
205519
- jsonParseAddCleanup(p, (void(*)(void*))jsonParseFree, pPatch);
205520
- }
205521
- break;
205522
- }
205523
- default: {
205524
- jsonParseAddNode(p, JSON_NULL, 0, 0);
205525
- sqlite3_result_error(pCtx, "JSON cannot hold BLOB values", -1);
205526
- p->nErr++;
205527
- break;
205528
- }
205529
- }
206986
+ if( zPath==0 ){
206987
+ goto json_remove_done;
206988
+ }
206989
+ if( zPath[0]!='$' ){
206990
+ goto json_remove_patherror;
206991
+ }
206992
+ if( zPath[1]==0 ){
206993
+ /* json_remove(j,'$') returns NULL */
206994
+ goto json_remove_done;
206995
+ }
206996
+ p->eEdit = JEDIT_DEL;
206997
+ p->delta = 0;
206998
+ rc = jsonLookupStep(p, 0, zPath+1, 0);
206999
+ if( JSON_LOOKUP_ISERROR(rc) ){
207000
+ if( rc==JSON_LOOKUP_NOTFOUND ){
207001
+ continue; /* No-op */
207002
+ }else if( rc==JSON_LOOKUP_PATHERROR ){
207003
+ jsonBadPathError(ctx, zPath);
207004
+ }else{
207005
+ sqlite3_result_error(ctx, "malformed JSON", -1);
207006
+ }
207007
+ goto json_remove_done;
207008
+ }
207009
+ }
207010
+ jsonReturnParse(ctx, p);
207011
+ jsonParseFree(p);
207012
+ return;
207013
+
207014
+json_remove_patherror:
207015
+ jsonBadPathError(ctx, zPath);
207016
+
207017
+json_remove_done:
207018
+ jsonParseFree(p);
207019
+ return;
205530207020
}
205531207021
205532207022
/*
205533207023
** json_replace(JSON, PATH, VALUE, ...)
205534207024
**
@@ -205538,36 +207028,16 @@
205538207028
static void jsonReplaceFunc(
205539207029
sqlite3_context *ctx,
205540207030
int argc,
205541207031
sqlite3_value **argv
205542207032
){
205543
- JsonParse *pParse; /* The parse */
205544
- JsonNode *pNode;
205545
- const char *zPath;
205546
- u32 i;
205547
-
205548207033
if( argc<1 ) return;
205549207034
if( (argc&1)==0 ) {
205550207035
jsonWrongNumArgs(ctx, "replace");
205551207036
return;
205552207037
}
205553
- pParse = jsonParseCached(ctx, argv[0], ctx, argc>1);
205554
- if( pParse==0 ) return;
205555
- pParse->nJPRef++;
205556
- for(i=1; i<(u32)argc; i+=2){
205557
- zPath = (const char*)sqlite3_value_text(argv[i]);
205558
- pParse->useMod = 1;
205559
- pNode = jsonLookup(pParse, zPath, 0, ctx);
205560
- if( pParse->nErr ) goto replace_err;
205561
- if( pNode ){
205562
- jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]);
205563
- }
205564
- }
205565
- jsonReturnJson(pParse, pParse->aNode, ctx, 1, 0);
205566
-replace_err:
205567
- jsonDebugPrintParse(pParse);
205568
- jsonParseFree(pParse);
207038
+ jsonInsertIntoBlob(ctx, argc, argv, JEDIT_REPL);
205569207039
}
205570207040
205571207041
205572207042
/*
205573207043
** json_set(JSON, PATH, VALUE, ...)
@@ -205584,43 +207054,20 @@
205584207054
static void jsonSetFunc(
205585207055
sqlite3_context *ctx,
205586207056
int argc,
205587207057
sqlite3_value **argv
205588207058
){
205589
- JsonParse *pParse; /* The parse */
205590
- JsonNode *pNode;
205591
- const char *zPath;
205592
- u32 i;
205593
- int bApnd;
205594
- int bIsSet = sqlite3_user_data(ctx)!=0;
207059
+
207060
+ int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx));
207061
+ int bIsSet = (flags&JSON_ISSET)!=0;
205595207062
205596207063
if( argc<1 ) return;
205597207064
if( (argc&1)==0 ) {
205598207065
jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert");
205599207066
return;
205600207067
}
205601
- pParse = jsonParseCached(ctx, argv[0], ctx, argc>1);
205602
- if( pParse==0 ) return;
205603
- pParse->nJPRef++;
205604
- for(i=1; i<(u32)argc; i+=2){
205605
- zPath = (const char*)sqlite3_value_text(argv[i]);
205606
- bApnd = 0;
205607
- pParse->useMod = 1;
205608
- pNode = jsonLookup(pParse, zPath, &bApnd, ctx);
205609
- if( pParse->oom ){
205610
- sqlite3_result_error_nomem(ctx);
205611
- goto jsonSetDone;
205612
- }else if( pParse->nErr ){
205613
- goto jsonSetDone;
205614
- }else if( pNode && (bApnd || bIsSet) ){
205615
- jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]);
205616
- }
205617
- }
205618
- jsonDebugPrintParse(pParse);
205619
- jsonReturnJson(pParse, pParse->aNode, ctx, 1, 0);
205620
-jsonSetDone:
205621
- jsonParseFree(pParse);
207068
+ jsonInsertIntoBlob(ctx, argc, argv, bIsSet ? JEDIT_SET : JEDIT_INS);
205622207069
}
205623207070
205624207071
/*
205625207072
** json_type(JSON)
205626207073
** json_type(JSON, PATH)
@@ -205632,110 +207079,221 @@
205632207079
sqlite3_context *ctx,
205633207080
int argc,
205634207081
sqlite3_value **argv
205635207082
){
205636207083
JsonParse *p; /* The parse */
205637
- const char *zPath;
205638
- JsonNode *pNode;
207084
+ const char *zPath = 0;
207085
+ u32 i;
205639207086
205640
- p = jsonParseCached(ctx, argv[0], ctx, 0);
207087
+ p = jsonParseFuncArg(ctx, argv[0], 0);
205641207088
if( p==0 ) return;
205642207089
if( argc==2 ){
205643207090
zPath = (const char*)sqlite3_value_text(argv[1]);
205644
- pNode = jsonLookup(p, zPath, 0, ctx);
207091
+ if( zPath==0 ) goto json_type_done;
207092
+ if( zPath[0]!='$' ){
207093
+ jsonBadPathError(ctx, zPath);
207094
+ goto json_type_done;
207095
+ }
207096
+ i = jsonLookupStep(p, 0, zPath+1, 0);
207097
+ if( JSON_LOOKUP_ISERROR(i) ){
207098
+ if( i==JSON_LOOKUP_NOTFOUND ){
207099
+ /* no-op */
207100
+ }else if( i==JSON_LOOKUP_PATHERROR ){
207101
+ jsonBadPathError(ctx, zPath);
207102
+ }else{
207103
+ sqlite3_result_error(ctx, "malformed JSON", -1);
207104
+ }
207105
+ goto json_type_done;
207106
+ }
205645207107
}else{
205646
- pNode = p->aNode;
207108
+ i = 0;
205647207109
}
205648
- if( pNode ){
205649
- sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC);
205650
- }
207110
+ sqlite3_result_text(ctx, jsonbType[p->aBlob[i]&0x0f], -1, SQLITE_STATIC);
207111
+json_type_done:
207112
+ jsonParseFree(p);
205651207113
}
205652207114
205653207115
/*
205654207116
** json_valid(JSON)
207117
+** json_valid(JSON, FLAGS)
205655207118
**
205656
-** Return 1 if JSON is a well-formed canonical JSON string according
205657
-** to RFC-7159. Return 0 otherwise.
207119
+** Check the JSON argument to see if it is well-formed. The FLAGS argument
207120
+** encodes the various constraints on what is meant by "well-formed":
207121
+**
207122
+** 0x01 Canonical RFC-8259 JSON text
207123
+** 0x02 JSON text with optional JSON-5 extensions
207124
+** 0x04 Superficially appears to be JSONB
207125
+** 0x08 Strictly well-formed JSONB
207126
+**
207127
+** If the FLAGS argument is omitted, it defaults to 1. Useful values for
207128
+** FLAGS include:
207129
+**
207130
+** 1 Strict canonical JSON text
207131
+** 2 JSON text perhaps with JSON-5 extensions
207132
+** 4 Superficially appears to be JSONB
207133
+** 5 Canonical JSON text or superficial JSONB
207134
+** 6 JSON-5 text or superficial JSONB
207135
+** 8 Strict JSONB
207136
+** 9 Canonical JSON text or strict JSONB
207137
+** 10 JSON-5 text or strict JSONB
207138
+**
207139
+** Other flag combinations are redundant. For example, every canonical
207140
+** JSON text is also well-formed JSON-5 text, so FLAG values 2 and 3
207141
+** are the same. Similarly, any input that passes a strict JSONB validation
207142
+** will also pass the superficial validation so 12 through 15 are the same
207143
+** as 8 through 11 respectively.
207144
+**
207145
+** This routine runs in linear time to validate text and when doing strict
207146
+** JSONB validation. Superficial JSONB validation is constant time,
207147
+** assuming the BLOB is already in memory. The performance advantage
207148
+** of superficial JSONB validation is why that option is provided.
207149
+** Application developers can choose to do fast superficial validation or
207150
+** slower strict validation, according to their specific needs.
207151
+**
207152
+** Only the lower four bits of the FLAGS argument are currently used.
207153
+** Higher bits are reserved for future expansion. To facilitate
207154
+** compatibility, the current implementation raises an error if any bit
207155
+** in FLAGS is set other than the lower four bits.
207156
+**
207157
+** The original circa 2015 implementation of the JSON routines in
207158
+** SQLite only supported canonical RFC-8259 JSON text and the json_valid()
207159
+** function only accepted one argument. That is why the default value
207160
+** for the FLAGS argument is 1, since FLAGS=1 causes this routine to only
207161
+** recognize canonical RFC-8259 JSON text as valid. The extra FLAGS
207162
+** argument was added when the JSON routines were extended to support
207163
+** JSON5-like extensions and binary JSONB stored in BLOBs.
207164
+**
207165
+** Return Values:
207166
+**
207167
+** * Raise an error if FLAGS is outside the range of 1 to 15.
207168
+** * Return NULL if the input is NULL
207169
+** * Return 1 if the input is well-formed.
207170
+** * Return 0 if the input is not well-formed.
205658207171
*/
205659207172
static void jsonValidFunc(
205660207173
sqlite3_context *ctx,
205661207174
int argc,
205662207175
sqlite3_value **argv
205663207176
){
205664207177
JsonParse *p; /* The parse */
205665
- UNUSED_PARAMETER(argc);
205666
- if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
207178
+ u8 flags = 1;
207179
+ u8 res = 0;
207180
+ if( argc==2 ){
207181
+ i64 f = sqlite3_value_int64(argv[1]);
207182
+ if( f<1 || f>15 ){
207183
+ sqlite3_result_error(ctx, "FLAGS parameter to json_valid() must be"
207184
+ " between 1 and 15", -1);
207185
+ return;
207186
+ }
207187
+ flags = f & 0x0f;
207188
+ }
207189
+ switch( sqlite3_value_type(argv[0]) ){
207190
+ case SQLITE_NULL: {
205667207191
#ifdef SQLITE_LEGACY_JSON_VALID
205668
- /* Incorrect legacy behavior was to return FALSE for a NULL input */
205669
- sqlite3_result_int(ctx, 0);
207192
+ /* Incorrect legacy behavior was to return FALSE for a NULL input */
207193
+ sqlite3_result_int(ctx, 0);
205670207194
#endif
205671
- return;
205672
- }
205673
- p = jsonParseCached(ctx, argv[0], 0, 0);
205674
- if( p==0 || p->oom ){
205675
- sqlite3_result_error_nomem(ctx);
205676
- sqlite3_free(p);
205677
- }else{
205678
- sqlite3_result_int(ctx, p->nErr==0 && (p->hasNonstd==0 || p->useMod));
205679
- if( p->nErr ) jsonParseFree(p);
205680
- }
207195
+ return;
207196
+ }
207197
+ case SQLITE_BLOB: {
207198
+ if( (flags & 0x0c)!=0 && jsonFuncArgMightBeBinary(argv[0]) ){
207199
+ if( flags & 0x04 ){
207200
+ /* Superficial checking only - accomplished by the
207201
+ ** jsonFuncArgMightBeBinary() call above. */
207202
+ res = 1;
207203
+ }else{
207204
+ /* Strict checking. Check by translating BLOB->TEXT->BLOB. If
207205
+ ** no errors occur, call that a "strict check". */
207206
+ JsonParse px;
207207
+ u32 iErr;
207208
+ memset(&px, 0, sizeof(px));
207209
+ px.aBlob = (u8*)sqlite3_value_blob(argv[0]);
207210
+ px.nBlob = sqlite3_value_bytes(argv[0]);
207211
+ iErr = jsonbValidityCheck(&px, 0, px.nBlob, 1);
207212
+ res = iErr==0;
207213
+ }
207214
+ }
207215
+ break;
207216
+ }
207217
+ default: {
207218
+ JsonParse px;
207219
+ if( (flags & 0x3)==0 ) break;
207220
+ memset(&px, 0, sizeof(px));
207221
+
207222
+ p = jsonParseFuncArg(ctx, argv[0], JSON_KEEPERROR);
207223
+ if( p ){
207224
+ if( p->oom ){
207225
+ sqlite3_result_error_nomem(ctx);
207226
+ }else if( p->nErr ){
207227
+ /* no-op */
207228
+ }else if( (flags & 0x02)!=0 || p->hasNonstd==0 ){
207229
+ res = 1;
207230
+ }
207231
+ jsonParseFree(p);
207232
+ }else{
207233
+ sqlite3_result_error_nomem(ctx);
207234
+ }
207235
+ break;
207236
+ }
207237
+ }
207238
+ sqlite3_result_int(ctx, res);
205681207239
}
205682207240
205683207241
/*
205684207242
** json_error_position(JSON)
205685207243
**
205686
-** If the argument is not an interpretable JSON string, then return the 1-based
205687
-** character position at which the parser first recognized that the input
205688
-** was in error. The left-most character is 1. If the string is valid
205689
-** JSON, then return 0.
205690
-**
205691
-** Note that json_valid() is only true for strictly conforming canonical JSON.
205692
-** But this routine returns zero if the input contains extension. Thus:
205693
-**
205694
-** (1) If the input X is strictly conforming canonical JSON:
205695
-**
205696
-** json_valid(X) returns true
205697
-** json_error_position(X) returns 0
205698
-**
205699
-** (2) If the input X is JSON but it includes extension (such as JSON5) that
205700
-** are not part of RFC-8259:
205701
-**
205702
-** json_valid(X) returns false
205703
-** json_error_position(X) return 0
205704
-**
205705
-** (3) If the input X cannot be interpreted as JSON even taking extensions
205706
-** into account:
205707
-**
205708
-** json_valid(X) return false
205709
-** json_error_position(X) returns 1 or more
207244
+** If the argument is NULL, return NULL
207245
+**
207246
+** If the argument is BLOB, do a full validity check and return non-zero
207247
+** if the check fails. The return value is the approximate 1-based offset
207248
+** to the byte of the element that contains the first error.
207249
+**
207250
+** Otherwise interpret the argument is TEXT (even if it is numeric) and
207251
+** return the 1-based character position for where the parser first recognized
207252
+** that the input was not valid JSON, or return 0 if the input text looks
207253
+** ok. JSON-5 extensions are accepted.
205710207254
*/
205711207255
static void jsonErrorFunc(
205712207256
sqlite3_context *ctx,
205713207257
int argc,
205714207258
sqlite3_value **argv
205715207259
){
205716
- JsonParse *p; /* The parse */
207260
+ i64 iErrPos = 0; /* Error position to be returned */
207261
+ JsonParse s;
207262
+
207263
+ assert( argc==1 );
205717207264
UNUSED_PARAMETER(argc);
205718
- if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
205719
- p = jsonParseCached(ctx, argv[0], 0, 0);
205720
- if( p==0 || p->oom ){
207265
+ memset(&s, 0, sizeof(s));
207266
+ if( jsonFuncArgMightBeBinary(argv[0]) ){
207267
+ s.aBlob = (u8*)sqlite3_value_blob(argv[0]);
207268
+ s.nBlob = sqlite3_value_bytes(argv[0]);
207269
+ iErrPos = (i64)jsonbValidityCheck(&s, 0, s.nBlob, 1);
207270
+ }else{
207271
+ s.zJson = (char*)sqlite3_value_text(argv[0]);
207272
+ if( s.zJson==0 ) return; /* NULL input or OOM */
207273
+ s.nJson = sqlite3_value_bytes(argv[0]);
207274
+ if( jsonConvertTextToBlob(&s,0) ){
207275
+ if( s.oom ){
207276
+ iErrPos = -1;
207277
+ }else{
207278
+ /* Convert byte-offset s.iErr into a character offset */
207279
+ u32 k;
207280
+ assert( s.zJson!=0 ); /* Because s.oom is false */
207281
+ for(k=0; k<s.iErr && ALWAYS(s.zJson[k]); k++){
207282
+ if( (s.zJson[k] & 0xc0)!=0x80 ) iErrPos++;
207283
+ }
207284
+ iErrPos++;
207285
+ }
207286
+ }
207287
+ }
207288
+ jsonParseReset(&s);
207289
+ if( iErrPos<0 ){
205721207290
sqlite3_result_error_nomem(ctx);
205722
- sqlite3_free(p);
205723
- }else if( p->nErr==0 ){
205724
- sqlite3_result_int(ctx, 0);
205725
- }else{
205726
- int n = 1;
205727
- u32 i;
205728
- const char *z = (const char*)sqlite3_value_text(argv[0]);
205729
- for(i=0; i<p->iErr && ALWAYS(z[i]); i++){
205730
- if( (z[i]&0xc0)!=0x80 ) n++;
205731
- }
205732
- sqlite3_result_int(ctx, n);
205733
- jsonParseFree(p);
205734
- }
205735
-}
205736
-
207291
+ }else{
207292
+ sqlite3_result_int64(ctx, iErrPos);
207293
+ }
207294
+}
205737207295
205738207296
/****************************************************************************
205739207297
** Aggregate SQL function implementations
205740207298
****************************************************************************/
205741207299
/*
@@ -205751,28 +207309,38 @@
205751207309
JsonString *pStr;
205752207310
UNUSED_PARAMETER(argc);
205753207311
pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
205754207312
if( pStr ){
205755207313
if( pStr->zBuf==0 ){
205756
- jsonInit(pStr, ctx);
207314
+ jsonStringInit(pStr, ctx);
205757207315
jsonAppendChar(pStr, '[');
205758207316
}else if( pStr->nUsed>1 ){
205759207317
jsonAppendChar(pStr, ',');
205760207318
}
205761207319
pStr->pCtx = ctx;
205762
- jsonAppendValue(pStr, argv[0]);
207320
+ jsonAppendSqlValue(pStr, argv[0]);
205763207321
}
205764207322
}
205765207323
static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){
205766207324
JsonString *pStr;
205767207325
pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
205768207326
if( pStr ){
207327
+ int flags;
205769207328
pStr->pCtx = ctx;
205770207329
jsonAppendChar(pStr, ']');
205771
- if( pStr->bErr ){
205772
- if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
205773
- assert( pStr->bStatic );
207330
+ flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx));
207331
+ if( pStr->eErr ){
207332
+ jsonReturnString(pStr, 0, 0);
207333
+ return;
207334
+ }else if( flags & JSON_BLOB ){
207335
+ jsonReturnStringAsBlob(pStr);
207336
+ if( isFinal ){
207337
+ if( !pStr->bStatic ) sqlite3RCStrUnref(pStr->zBuf);
207338
+ }else{
207339
+ pStr->nUsed--;
207340
+ }
207341
+ return;
205774207342
}else if( isFinal ){
205775207343
sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed,
205776207344
pStr->bStatic ? SQLITE_TRANSIENT :
205777207345
sqlite3RCStrUnref);
205778207346
pStr->bStatic = 1;
@@ -205857,31 +207425,42 @@
205857207425
u32 n;
205858207426
UNUSED_PARAMETER(argc);
205859207427
pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
205860207428
if( pStr ){
205861207429
if( pStr->zBuf==0 ){
205862
- jsonInit(pStr, ctx);
207430
+ jsonStringInit(pStr, ctx);
205863207431
jsonAppendChar(pStr, '{');
205864207432
}else if( pStr->nUsed>1 ){
205865207433
jsonAppendChar(pStr, ',');
205866207434
}
205867207435
pStr->pCtx = ctx;
205868207436
z = (const char*)sqlite3_value_text(argv[0]);
205869
- n = (u32)sqlite3_value_bytes(argv[0]);
207437
+ n = sqlite3Strlen30(z);
205870207438
jsonAppendString(pStr, z, n);
205871207439
jsonAppendChar(pStr, ':');
205872
- jsonAppendValue(pStr, argv[1]);
207440
+ jsonAppendSqlValue(pStr, argv[1]);
205873207441
}
205874207442
}
205875207443
static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){
205876207444
JsonString *pStr;
205877207445
pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
205878207446
if( pStr ){
207447
+ int flags;
205879207448
jsonAppendChar(pStr, '}');
205880
- if( pStr->bErr ){
205881
- if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
205882
- assert( pStr->bStatic );
207449
+ pStr->pCtx = ctx;
207450
+ flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx));
207451
+ if( pStr->eErr ){
207452
+ jsonReturnString(pStr, 0, 0);
207453
+ return;
207454
+ }else if( flags & JSON_BLOB ){
207455
+ jsonReturnStringAsBlob(pStr);
207456
+ if( isFinal ){
207457
+ if( !pStr->bStatic ) sqlite3RCStrUnref(pStr->zBuf);
207458
+ }else{
207459
+ pStr->nUsed--;
207460
+ }
207461
+ return;
205883207462
}else if( isFinal ){
205884207463
sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed,
205885207464
pStr->bStatic ? SQLITE_TRANSIENT :
205886207465
sqlite3RCStrUnref);
205887207466
pStr->bStatic = 1;
@@ -205905,33 +207484,51 @@
205905207484
205906207485
#ifndef SQLITE_OMIT_VIRTUALTABLE
205907207486
/****************************************************************************
205908207487
** The json_each virtual table
205909207488
****************************************************************************/
207489
+typedef struct JsonParent JsonParent;
207490
+struct JsonParent {
207491
+ u32 iHead; /* Start of object or array */
207492
+ u32 iValue; /* Start of the value */
207493
+ u32 iEnd; /* First byte past the end */
207494
+ u32 nPath; /* Length of path */
207495
+ i64 iKey; /* Key for JSONB_ARRAY */
207496
+};
207497
+
205910207498
typedef struct JsonEachCursor JsonEachCursor;
205911207499
struct JsonEachCursor {
205912207500
sqlite3_vtab_cursor base; /* Base class - must be first */
205913207501
u32 iRowid; /* The rowid */
205914
- u32 iBegin; /* The first node of the scan */
205915
- u32 i; /* Index in sParse.aNode[] of current row */
207502
+ u32 i; /* Index in sParse.aBlob[] of current row */
205916207503
u32 iEnd; /* EOF when i equals or exceeds this value */
205917
- u8 eType; /* Type of top-level element */
207504
+ u32 nRoot; /* Size of the root path in bytes */
207505
+ u8 eType; /* Type of the container for element i */
205918207506
u8 bRecursive; /* True for json_tree(). False for json_each() */
205919
- char *zJson; /* Input JSON */
205920
- char *zRoot; /* Path by which to filter zJson */
207507
+ u32 nParent; /* Current nesting depth */
207508
+ u32 nParentAlloc; /* Space allocated for aParent[] */
207509
+ JsonParent *aParent; /* Parent elements of i */
207510
+ sqlite3 *db; /* Database connection */
207511
+ JsonString path; /* Current path */
205921207512
JsonParse sParse; /* Parse of the input JSON */
205922207513
};
207514
+typedef struct JsonEachConnection JsonEachConnection;
207515
+struct JsonEachConnection {
207516
+ sqlite3_vtab base; /* Base class - must be first */
207517
+ sqlite3 *db; /* Database connection */
207518
+};
207519
+
205923207520
205924207521
/* Constructor for the json_each virtual table */
205925207522
static int jsonEachConnect(
205926207523
sqlite3 *db,
205927207524
void *pAux,
205928207525
int argc, const char *const*argv,
205929207526
sqlite3_vtab **ppVtab,
205930207527
char **pzErr
205931207528
){
205932
- sqlite3_vtab *pNew;
207529
+ JsonEachConnection *pNew;
205933207530
int rc;
205934207531
205935207532
/* Column numbers */
205936207533
#define JEACH_KEY 0
205937207534
#define JEACH_VALUE 1
@@ -205953,14 +207550,15 @@
205953207550
UNUSED_PARAMETER(pAux);
205954207551
rc = sqlite3_declare_vtab(db,
205955207552
"CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path,"
205956207553
"json HIDDEN,root HIDDEN)");
205957207554
if( rc==SQLITE_OK ){
205958
- pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
207555
+ pNew = (JsonEachConnection*)(*ppVtab = sqlite3_malloc( sizeof(*pNew) ));
205959207556
if( pNew==0 ) return SQLITE_NOMEM;
205960207557
memset(pNew, 0, sizeof(*pNew));
205961207558
sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
207559
+ pNew->db = db;
205962207560
}
205963207561
return rc;
205964207562
}
205965207563
205966207564
/* destructor for json_each virtual table */
@@ -205969,16 +207567,19 @@
205969207567
return SQLITE_OK;
205970207568
}
205971207569
205972207570
/* constructor for a JsonEachCursor object for json_each(). */
205973207571
static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
207572
+ JsonEachConnection *pVtab = (JsonEachConnection*)p;
205974207573
JsonEachCursor *pCur;
205975207574
205976207575
UNUSED_PARAMETER(p);
205977207576
pCur = sqlite3_malloc( sizeof(*pCur) );
205978207577
if( pCur==0 ) return SQLITE_NOMEM;
205979207578
memset(pCur, 0, sizeof(*pCur));
207579
+ pCur->db = pVtab->db;
207580
+ jsonStringZero(&pCur->path);
205980207581
*ppCursor = &pCur->base;
205981207582
return SQLITE_OK;
205982207583
}
205983207584
205984207585
/* constructor for a JsonEachCursor object for json_tree(). */
@@ -205992,24 +207593,27 @@
205992207593
}
205993207594
205994207595
/* Reset a JsonEachCursor back to its original state. Free any memory
205995207596
** held. */
205996207597
static void jsonEachCursorReset(JsonEachCursor *p){
205997
- sqlite3_free(p->zRoot);
205998207598
jsonParseReset(&p->sParse);
207599
+ jsonStringReset(&p->path);
207600
+ sqlite3DbFree(p->db, p->aParent);
205999207601
p->iRowid = 0;
206000207602
p->i = 0;
207603
+ p->aParent = 0;
207604
+ p->nParent = 0;
207605
+ p->nParentAlloc = 0;
206001207606
p->iEnd = 0;
206002207607
p->eType = 0;
206003
- p->zJson = 0;
206004
- p->zRoot = 0;
206005207608
}
206006207609
206007207610
/* Destructor for a jsonEachCursor object */
206008207611
static int jsonEachClose(sqlite3_vtab_cursor *cur){
206009207612
JsonEachCursor *p = (JsonEachCursor*)cur;
206010207613
jsonEachCursorReset(p);
207614
+
206011207615
sqlite3_free(cur);
206012207616
return SQLITE_OK;
206013207617
}
206014207618
206015207619
/* Return TRUE if the jsonEachCursor object has been advanced off the end
@@ -206016,205 +207620,235 @@
206016207620
** of the JSON object */
206017207621
static int jsonEachEof(sqlite3_vtab_cursor *cur){
206018207622
JsonEachCursor *p = (JsonEachCursor*)cur;
206019207623
return p->i >= p->iEnd;
206020207624
}
207625
+
207626
+/*
207627
+** If the cursor is currently pointing at the label of a object entry,
207628
+** then return the index of the value. For all other cases, return the
207629
+** current pointer position, which is the value.
207630
+*/
207631
+static int jsonSkipLabel(JsonEachCursor *p){
207632
+ if( p->eType==JSONB_OBJECT ){
207633
+ u32 sz = 0;
207634
+ u32 n = jsonbPayloadSize(&p->sParse, p->i, &sz);
207635
+ return p->i + n + sz;
207636
+ }else{
207637
+ return p->i;
207638
+ }
207639
+}
207640
+
207641
+/*
207642
+** Append the path name for the current element.
207643
+*/
207644
+static void jsonAppendPathName(JsonEachCursor *p){
207645
+ assert( p->nParent>0 );
207646
+ assert( p->eType==JSONB_ARRAY || p->eType==JSONB_OBJECT );
207647
+ if( p->eType==JSONB_ARRAY ){
207648
+ jsonPrintf(30, &p->path, "[%lld]", p->aParent[p->nParent-1].iKey);
207649
+ }else{
207650
+ u32 n, sz = 0, k, i;
207651
+ const char *z;
207652
+ int needQuote = 0;
207653
+ n = jsonbPayloadSize(&p->sParse, p->i, &sz);
207654
+ k = p->i + n;
207655
+ z = (const char*)&p->sParse.aBlob[k];
207656
+ if( sz==0 || !sqlite3Isalpha(z[0]) ){
207657
+ needQuote = 1;
207658
+ }else{
207659
+ for(i=0; i<sz; i++){
207660
+ if( !sqlite3Isalnum(z[i]) ){
207661
+ needQuote = 1;
207662
+ break;
207663
+ }
207664
+ }
207665
+ }
207666
+ if( needQuote ){
207667
+ jsonPrintf(sz+4,&p->path,".\"%.*s\"", sz, z);
207668
+ }else{
207669
+ jsonPrintf(sz+2,&p->path,".%.*s", sz, z);
207670
+ }
207671
+ }
207672
+}
206021207673
206022207674
/* Advance the cursor to the next element for json_tree() */
206023207675
static int jsonEachNext(sqlite3_vtab_cursor *cur){
206024207676
JsonEachCursor *p = (JsonEachCursor*)cur;
207677
+ int rc = SQLITE_OK;
206025207678
if( p->bRecursive ){
206026
- if( p->sParse.aNode[p->i].jnFlags & JNODE_LABEL ) p->i++;
206027
- p->i++;
206028
- p->iRowid++;
206029
- if( p->i<p->iEnd ){
206030
- u32 iUp = p->sParse.aUp[p->i];
206031
- JsonNode *pUp = &p->sParse.aNode[iUp];
206032
- p->eType = pUp->eType;
206033
- if( pUp->eType==JSON_ARRAY ){
206034
- assert( pUp->eU==0 || pUp->eU==3 );
206035
- testcase( pUp->eU==3 );
206036
- VVA( pUp->eU = 3 );
206037
- if( iUp==p->i-1 ){
206038
- pUp->u.iKey = 0;
206039
- }else{
206040
- pUp->u.iKey++;
206041
- }
206042
- }
206043
- }
206044
- }else{
206045
- switch( p->eType ){
206046
- case JSON_ARRAY: {
206047
- p->i += jsonNodeSize(&p->sParse.aNode[p->i]);
206048
- p->iRowid++;
206049
- break;
206050
- }
206051
- case JSON_OBJECT: {
206052
- p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]);
206053
- p->iRowid++;
206054
- break;
206055
- }
206056
- default: {
206057
- p->i = p->iEnd;
206058
- break;
206059
- }
206060
- }
206061
- }
206062
- return SQLITE_OK;
206063
-}
206064
-
206065
-/* Append an object label to the JSON Path being constructed
206066
-** in pStr.
206067
-*/
206068
-static void jsonAppendObjectPathElement(
206069
- JsonString *pStr,
206070
- JsonNode *pNode
206071
-){
206072
- int jj, nn;
206073
- const char *z;
206074
- assert( pNode->eType==JSON_STRING );
206075
- assert( pNode->jnFlags & JNODE_LABEL );
206076
- assert( pNode->eU==1 );
206077
- z = pNode->u.zJContent;
206078
- nn = pNode->n;
206079
- if( (pNode->jnFlags & JNODE_RAW)==0 ){
206080
- assert( nn>=2 );
206081
- assert( z[0]=='"' || z[0]=='\'' );
206082
- assert( z[nn-1]=='"' || z[0]=='\'' );
206083
- if( nn>2 && sqlite3Isalpha(z[1]) ){
206084
- for(jj=2; jj<nn-1 && sqlite3Isalnum(z[jj]); jj++){}
206085
- if( jj==nn-1 ){
206086
- z++;
206087
- nn -= 2;
206088
- }
206089
- }
206090
- }
206091
- jsonPrintf(nn+2, pStr, ".%.*s", nn, z);
206092
-}
206093
-
206094
-/* Append the name of the path for element i to pStr
206095
-*/
206096
-static void jsonEachComputePath(
206097
- JsonEachCursor *p, /* The cursor */
206098
- JsonString *pStr, /* Write the path here */
206099
- u32 i /* Path to this element */
206100
-){
206101
- JsonNode *pNode, *pUp;
206102
- u32 iUp;
206103
- if( i==0 ){
206104
- jsonAppendChar(pStr, '$');
206105
- return;
206106
- }
206107
- iUp = p->sParse.aUp[i];
206108
- jsonEachComputePath(p, pStr, iUp);
206109
- pNode = &p->sParse.aNode[i];
206110
- pUp = &p->sParse.aNode[iUp];
206111
- if( pUp->eType==JSON_ARRAY ){
206112
- assert( pUp->eU==3 || (pUp->eU==0 && pUp->u.iKey==0) );
206113
- testcase( pUp->eU==0 );
206114
- jsonPrintf(30, pStr, "[%d]", pUp->u.iKey);
206115
- }else{
206116
- assert( pUp->eType==JSON_OBJECT );
206117
- if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--;
206118
- jsonAppendObjectPathElement(pStr, pNode);
206119
- }
207679
+ u8 x;
207680
+ u8 levelChange = 0;
207681
+ u32 n, sz = 0;
207682
+ u32 i = jsonSkipLabel(p);
207683
+ x = p->sParse.aBlob[i] & 0x0f;
207684
+ n = jsonbPayloadSize(&p->sParse, i, &sz);
207685
+ if( x==JSONB_OBJECT || x==JSONB_ARRAY ){
207686
+ JsonParent *pParent;
207687
+ if( p->nParent>=p->nParentAlloc ){
207688
+ JsonParent *pNew;
207689
+ u64 nNew;
207690
+ nNew = p->nParentAlloc*2 + 3;
207691
+ pNew = sqlite3DbRealloc(p->db, p->aParent, sizeof(JsonParent)*nNew);
207692
+ if( pNew==0 ) return SQLITE_NOMEM;
207693
+ p->nParentAlloc = (u32)nNew;
207694
+ p->aParent = pNew;
207695
+ }
207696
+ levelChange = 1;
207697
+ pParent = &p->aParent[p->nParent];
207698
+ pParent->iHead = p->i;
207699
+ pParent->iValue = i;
207700
+ pParent->iEnd = i + n + sz;
207701
+ pParent->iKey = -1;
207702
+ pParent->nPath = (u32)p->path.nUsed;
207703
+ if( p->eType && p->nParent ){
207704
+ jsonAppendPathName(p);
207705
+ if( p->path.eErr ) rc = SQLITE_NOMEM;
207706
+ }
207707
+ p->nParent++;
207708
+ p->i = i + n;
207709
+ }else{
207710
+ p->i = i + n + sz;
207711
+ }
207712
+ while( p->nParent>0 && p->i >= p->aParent[p->nParent-1].iEnd ){
207713
+ p->nParent--;
207714
+ p->path.nUsed = p->aParent[p->nParent].nPath;
207715
+ levelChange = 1;
207716
+ }
207717
+ if( levelChange ){
207718
+ if( p->nParent>0 ){
207719
+ JsonParent *pParent = &p->aParent[p->nParent-1];
207720
+ u32 iVal = pParent->iValue;
207721
+ p->eType = p->sParse.aBlob[iVal] & 0x0f;
207722
+ }else{
207723
+ p->eType = 0;
207724
+ }
207725
+ }
207726
+ }else{
207727
+ u32 n, sz = 0;
207728
+ u32 i = jsonSkipLabel(p);
207729
+ n = jsonbPayloadSize(&p->sParse, i, &sz);
207730
+ p->i = i + n + sz;
207731
+ }
207732
+ if( p->eType==JSONB_ARRAY && p->nParent ){
207733
+ p->aParent[p->nParent-1].iKey++;
207734
+ }
207735
+ p->iRowid++;
207736
+ return rc;
207737
+}
207738
+
207739
+/* Length of the path for rowid==0 in bRecursive mode.
207740
+*/
207741
+static int jsonEachPathLength(JsonEachCursor *p){
207742
+ u32 n = p->path.nUsed;
207743
+ char *z = p->path.zBuf;
207744
+ if( p->iRowid==0 && p->bRecursive && n>=2 ){
207745
+ while( n>1 ){
207746
+ n--;
207747
+ if( z[n]=='[' || z[n]=='.' ){
207748
+ u32 x, sz = 0;
207749
+ char cSaved = z[n];
207750
+ z[n] = 0;
207751
+ assert( p->sParse.eEdit==0 );
207752
+ x = jsonLookupStep(&p->sParse, 0, z+1, 0);
207753
+ z[n] = cSaved;
207754
+ if( JSON_LOOKUP_ISERROR(x) ) continue;
207755
+ if( x + jsonbPayloadSize(&p->sParse, x, &sz) == p->i ) break;
207756
+ }
207757
+ }
207758
+ }
207759
+ return n;
206120207760
}
206121207761
206122207762
/* Return the value of a column */
206123207763
static int jsonEachColumn(
206124207764
sqlite3_vtab_cursor *cur, /* The cursor */
206125207765
sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
206126
- int i /* Which column to return */
207766
+ int iColumn /* Which column to return */
206127207767
){
206128207768
JsonEachCursor *p = (JsonEachCursor*)cur;
206129
- JsonNode *pThis = &p->sParse.aNode[p->i];
206130
- switch( i ){
207769
+ switch( iColumn ){
206131207770
case JEACH_KEY: {
206132
- if( p->i==0 ) break;
206133
- if( p->eType==JSON_OBJECT ){
206134
- jsonReturn(&p->sParse, pThis, ctx, 0);
206135
- }else if( p->eType==JSON_ARRAY ){
206136
- u32 iKey;
206137
- if( p->bRecursive ){
206138
- if( p->iRowid==0 ) break;
206139
- assert( p->sParse.aNode[p->sParse.aUp[p->i]].eU==3 );
206140
- iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey;
207771
+ if( p->nParent==0 ){
207772
+ u32 n, j;
207773
+ if( p->nRoot==1 ) break;
207774
+ j = jsonEachPathLength(p);
207775
+ n = p->nRoot - j;
207776
+ if( n==0 ){
207777
+ break;
207778
+ }else if( p->path.zBuf[j]=='[' ){
207779
+ i64 x;
207780
+ sqlite3Atoi64(&p->path.zBuf[j+1], &x, n-1, SQLITE_UTF8);
207781
+ sqlite3_result_int64(ctx, x);
207782
+ }else if( p->path.zBuf[j+1]=='"' ){
207783
+ sqlite3_result_text(ctx, &p->path.zBuf[j+2], n-3, SQLITE_TRANSIENT);
206141207784
}else{
206142
- iKey = p->iRowid;
207785
+ sqlite3_result_text(ctx, &p->path.zBuf[j+1], n-1, SQLITE_TRANSIENT);
206143207786
}
206144
- sqlite3_result_int64(ctx, (sqlite3_int64)iKey);
207787
+ break;
207788
+ }
207789
+ if( p->eType==JSONB_OBJECT ){
207790
+ jsonReturnFromBlob(&p->sParse, p->i, ctx, 1);
207791
+ }else{
207792
+ assert( p->eType==JSONB_ARRAY );
207793
+ sqlite3_result_int64(ctx, p->aParent[p->nParent-1].iKey);
206145207794
}
206146207795
break;
206147207796
}
206148207797
case JEACH_VALUE: {
206149
- if( pThis->jnFlags & JNODE_LABEL ) pThis++;
206150
- jsonReturn(&p->sParse, pThis, ctx, 0);
207798
+ u32 i = jsonSkipLabel(p);
207799
+ jsonReturnFromBlob(&p->sParse, i, ctx, 1);
206151207800
break;
206152207801
}
206153207802
case JEACH_TYPE: {
206154
- if( pThis->jnFlags & JNODE_LABEL ) pThis++;
206155
- sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC);
207803
+ u32 i = jsonSkipLabel(p);
207804
+ u8 eType = p->sParse.aBlob[i] & 0x0f;
207805
+ sqlite3_result_text(ctx, jsonbType[eType], -1, SQLITE_STATIC);
206156207806
break;
206157207807
}
206158207808
case JEACH_ATOM: {
206159
- if( pThis->jnFlags & JNODE_LABEL ) pThis++;
206160
- if( pThis->eType>=JSON_ARRAY ) break;
206161
- jsonReturn(&p->sParse, pThis, ctx, 0);
207809
+ u32 i = jsonSkipLabel(p);
207810
+ if( (p->sParse.aBlob[i] & 0x0f)<JSONB_ARRAY ){
207811
+ jsonReturnFromBlob(&p->sParse, i, ctx, 1);
207812
+ }
206162207813
break;
206163207814
}
206164207815
case JEACH_ID: {
206165
- sqlite3_result_int64(ctx,
206166
- (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0));
207816
+ sqlite3_result_int64(ctx, (sqlite3_int64)p->i);
206167207817
break;
206168207818
}
206169207819
case JEACH_PARENT: {
206170
- if( p->i>p->iBegin && p->bRecursive ){
206171
- sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]);
207820
+ if( p->nParent>0 && p->bRecursive ){
207821
+ sqlite3_result_int64(ctx, p->aParent[p->nParent-1].iHead);
206172207822
}
206173207823
break;
206174207824
}
206175207825
case JEACH_FULLKEY: {
206176
- JsonString x;
206177
- jsonInit(&x, ctx);
206178
- if( p->bRecursive ){
206179
- jsonEachComputePath(p, &x, p->i);
206180
- }else{
206181
- if( p->zRoot ){
206182
- jsonAppendRaw(&x, p->zRoot, (int)strlen(p->zRoot));
206183
- }else{
206184
- jsonAppendChar(&x, '$');
206185
- }
206186
- if( p->eType==JSON_ARRAY ){
206187
- jsonPrintf(30, &x, "[%d]", p->iRowid);
206188
- }else if( p->eType==JSON_OBJECT ){
206189
- jsonAppendObjectPathElement(&x, pThis);
206190
- }
206191
- }
206192
- jsonResult(&x);
207826
+ u64 nBase = p->path.nUsed;
207827
+ if( p->nParent ) jsonAppendPathName(p);
207828
+ sqlite3_result_text64(ctx, p->path.zBuf, p->path.nUsed,
207829
+ SQLITE_TRANSIENT, SQLITE_UTF8);
207830
+ p->path.nUsed = nBase;
206193207831
break;
206194207832
}
206195207833
case JEACH_PATH: {
206196
- if( p->bRecursive ){
206197
- JsonString x;
206198
- jsonInit(&x, ctx);
206199
- jsonEachComputePath(p, &x, p->sParse.aUp[p->i]);
206200
- jsonResult(&x);
206201
- break;
206202
- }
206203
- /* For json_each() path and root are the same so fall through
206204
- ** into the root case */
206205
- /* no break */ deliberate_fall_through
207834
+ u32 n = jsonEachPathLength(p);
207835
+ sqlite3_result_text64(ctx, p->path.zBuf, n,
207836
+ SQLITE_TRANSIENT, SQLITE_UTF8);
207837
+ break;
206206207838
}
206207207839
default: {
206208
- const char *zRoot = p->zRoot;
206209
- if( zRoot==0 ) zRoot = "$";
206210
- sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC);
207840
+ sqlite3_result_text(ctx, p->path.zBuf, p->nRoot, SQLITE_STATIC);
206211207841
break;
206212207842
}
206213207843
case JEACH_JSON: {
206214
- assert( i==JEACH_JSON );
206215
- sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC);
207844
+ if( p->sParse.zJson==0 ){
207845
+ sqlite3_result_blob(ctx, p->sParse.aBlob, p->sParse.nBlob,
207846
+ SQLITE_STATIC);
207847
+ }else{
207848
+ sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC);
207849
+ }
206216207850
break;
206217207851
}
206218207852
}
206219207853
return SQLITE_OK;
206220207854
}
@@ -206301,90 +207935,104 @@
206301207935
sqlite3_vtab_cursor *cur,
206302207936
int idxNum, const char *idxStr,
206303207937
int argc, sqlite3_value **argv
206304207938
){
206305207939
JsonEachCursor *p = (JsonEachCursor*)cur;
206306
- const char *z;
206307207940
const char *zRoot = 0;
206308
- sqlite3_int64 n;
207941
+ u32 i, n, sz;
206309207942
206310207943
UNUSED_PARAMETER(idxStr);
206311207944
UNUSED_PARAMETER(argc);
206312207945
jsonEachCursorReset(p);
206313207946
if( idxNum==0 ) return SQLITE_OK;
206314
- z = (const char*)sqlite3_value_text(argv[0]);
206315
- if( z==0 ) return SQLITE_OK;
206316207947
memset(&p->sParse, 0, sizeof(p->sParse));
206317207948
p->sParse.nJPRef = 1;
206318
- if( sqlite3ValueIsOfClass(argv[0], sqlite3RCStrUnref) ){
206319
- p->sParse.zJson = sqlite3RCStrRef((char*)z);
206320
- }else{
206321
- n = sqlite3_value_bytes(argv[0]);
206322
- p->sParse.zJson = sqlite3RCStrNew( n+1 );
206323
- if( p->sParse.zJson==0 ) return SQLITE_NOMEM;
206324
- memcpy(p->sParse.zJson, z, (size_t)n+1);
206325
- }
206326
- p->sParse.bJsonIsRCStr = 1;
206327
- p->zJson = p->sParse.zJson;
206328
- if( jsonParse(&p->sParse, 0) ){
206329
- int rc = SQLITE_NOMEM;
206330
- if( p->sParse.oom==0 ){
206331
- sqlite3_free(cur->pVtab->zErrMsg);
206332
- cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON");
206333
- if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR;
206334
- }
206335
- jsonEachCursorReset(p);
206336
- return rc;
206337
- }else if( p->bRecursive && jsonParseFindParents(&p->sParse) ){
206338
- jsonEachCursorReset(p);
206339
- return SQLITE_NOMEM;
206340
- }else{
206341
- JsonNode *pNode = 0;
206342
- if( idxNum==3 ){
206343
- const char *zErr = 0;
206344
- zRoot = (const char*)sqlite3_value_text(argv[1]);
206345
- if( zRoot==0 ) return SQLITE_OK;
206346
- n = sqlite3_value_bytes(argv[1]);
206347
- p->zRoot = sqlite3_malloc64( n+1 );
206348
- if( p->zRoot==0 ) return SQLITE_NOMEM;
206349
- memcpy(p->zRoot, zRoot, (size_t)n+1);
206350
- if( zRoot[0]!='$' ){
206351
- zErr = zRoot;
206352
- }else{
206353
- pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr);
206354
- }
206355
- if( zErr ){
206356
- sqlite3_free(cur->pVtab->zErrMsg);
206357
- cur->pVtab->zErrMsg = jsonPathSyntaxError(zErr);
207949
+ if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
207950
+ if( jsonFuncArgMightBeBinary(argv[0]) ){
207951
+ p->sParse.nBlob = sqlite3_value_bytes(argv[0]);
207952
+ p->sParse.aBlob = (u8*)sqlite3_value_blob(argv[0]);
207953
+ }else{
207954
+ goto json_each_malformed_input;
207955
+ }
207956
+ }else{
207957
+ p->sParse.zJson = (char*)sqlite3_value_text(argv[0]);
207958
+ p->sParse.nJson = sqlite3_value_bytes(argv[0]);
207959
+ if( p->sParse.zJson==0 ){
207960
+ p->i = p->iEnd = 0;
207961
+ return SQLITE_OK;
207962
+ }
207963
+ if( jsonConvertTextToBlob(&p->sParse, 0) ){
207964
+ if( p->sParse.oom ){
207965
+ return SQLITE_NOMEM;
207966
+ }
207967
+ goto json_each_malformed_input;
207968
+ }
207969
+ }
207970
+ if( idxNum==3 ){
207971
+ zRoot = (const char*)sqlite3_value_text(argv[1]);
207972
+ if( zRoot==0 ) return SQLITE_OK;
207973
+ if( zRoot[0]!='$' ){
207974
+ sqlite3_free(cur->pVtab->zErrMsg);
207975
+ cur->pVtab->zErrMsg = jsonBadPathError(0, zRoot);
207976
+ jsonEachCursorReset(p);
207977
+ return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
207978
+ }
207979
+ p->nRoot = sqlite3Strlen30(zRoot);
207980
+ if( zRoot[1]==0 ){
207981
+ i = p->i = 0;
207982
+ p->eType = 0;
207983
+ }else{
207984
+ i = jsonLookupStep(&p->sParse, 0, zRoot+1, 0);
207985
+ if( JSON_LOOKUP_ISERROR(i) ){
207986
+ if( i==JSON_LOOKUP_NOTFOUND ){
207987
+ p->i = 0;
207988
+ p->eType = 0;
207989
+ p->iEnd = 0;
207990
+ return SQLITE_OK;
207991
+ }
207992
+ sqlite3_free(cur->pVtab->zErrMsg);
207993
+ cur->pVtab->zErrMsg = jsonBadPathError(0, zRoot);
206358207994
jsonEachCursorReset(p);
206359207995
return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
206360
- }else if( pNode==0 ){
206361
- return SQLITE_OK;
206362
- }
206363
- }else{
206364
- pNode = p->sParse.aNode;
206365
- }
206366
- p->iBegin = p->i = (int)(pNode - p->sParse.aNode);
206367
- p->eType = pNode->eType;
206368
- if( p->eType>=JSON_ARRAY ){
206369
- assert( pNode->eU==0 );
206370
- VVA( pNode->eU = 3 );
206371
- pNode->u.iKey = 0;
206372
- p->iEnd = p->i + pNode->n + 1;
206373
- if( p->bRecursive ){
206374
- p->eType = p->sParse.aNode[p->sParse.aUp[p->i]].eType;
206375
- if( p->i>0 && (p->sParse.aNode[p->i-1].jnFlags & JNODE_LABEL)!=0 ){
206376
- p->i--;
206377
- }
206378
- }else{
206379
- p->i++;
206380
- }
206381
- }else{
206382
- p->iEnd = p->i+1;
206383
- }
206384
- }
206385
- return SQLITE_OK;
207996
+ }
207997
+ if( p->sParse.iLabel ){
207998
+ p->i = p->sParse.iLabel;
207999
+ p->eType = JSONB_OBJECT;
208000
+ }else{
208001
+ p->i = i;
208002
+ p->eType = JSONB_ARRAY;
208003
+ }
208004
+ }
208005
+ jsonAppendRaw(&p->path, zRoot, p->nRoot);
208006
+ }else{
208007
+ i = p->i = 0;
208008
+ p->eType = 0;
208009
+ p->nRoot = 1;
208010
+ jsonAppendRaw(&p->path, "$", 1);
208011
+ }
208012
+ p->nParent = 0;
208013
+ n = jsonbPayloadSize(&p->sParse, i, &sz);
208014
+ p->iEnd = i+n+sz;
208015
+ if( (p->sParse.aBlob[i] & 0x0f)>=JSONB_ARRAY && !p->bRecursive ){
208016
+ p->i = i + n;
208017
+ p->eType = p->sParse.aBlob[i] & 0x0f;
208018
+ p->aParent = sqlite3DbMallocZero(p->db, sizeof(JsonParent));
208019
+ if( p->aParent==0 ) return SQLITE_NOMEM;
208020
+ p->nParent = 1;
208021
+ p->nParentAlloc = 1;
208022
+ p->aParent[0].iKey = 0;
208023
+ p->aParent[0].iEnd = p->iEnd;
208024
+ p->aParent[0].iHead = p->i;
208025
+ p->aParent[0].iValue = i;
208026
+ }
208027
+ return SQLITE_OK;
208028
+
208029
+json_each_malformed_input:
208030
+ sqlite3_free(cur->pVtab->zErrMsg);
208031
+ cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON");
208032
+ jsonEachCursorReset(p);
208033
+ return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
206386208034
}
206387208035
206388208036
/* The methods of the json_each virtual table */
206389208037
static sqlite3_module jsonEachModule = {
206390208038
0, /* iVersion */
@@ -206449,44 +208097,58 @@
206449208097
** Register JSON functions.
206450208098
*/
206451208099
SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void){
206452208100
#ifndef SQLITE_OMIT_JSON
206453208101
static FuncDef aJsonFunc[] = {
206454
- /* calls sqlite3_result_subtype() */
206455
- /* | */
206456
- /* Uses cache ______ | __ calls sqlite3_value_subtype() */
206457
- /* | | | */
206458
- /* Num args _________ | | | ___ Flags */
206459
- /* | | | | | */
206460
- /* | | | | | */
206461
- JFUNCTION(json, 1, 1, 1, 0, 0, jsonRemoveFunc),
206462
- JFUNCTION(json_array, -1, 0, 1, 1, 0, jsonArrayFunc),
206463
- JFUNCTION(json_array_length, 1, 1, 0, 0, 0, jsonArrayLengthFunc),
206464
- JFUNCTION(json_array_length, 2, 1, 0, 0, 0, jsonArrayLengthFunc),
206465
- JFUNCTION(json_error_position,1, 1, 0, 0, 0, jsonErrorFunc),
206466
- JFUNCTION(json_extract, -1, 1, 1, 0, 0, jsonExtractFunc),
206467
- JFUNCTION(->, 2, 1, 1, 0, JSON_JSON, jsonExtractFunc),
206468
- JFUNCTION(->>, 2, 1, 0, 0, JSON_SQL, jsonExtractFunc),
206469
- JFUNCTION(json_insert, -1, 1, 1, 1, 0, jsonSetFunc),
206470
- JFUNCTION(json_object, -1, 0, 1, 1, 0, jsonObjectFunc),
206471
- JFUNCTION(json_patch, 2, 1, 1, 0, 0, jsonPatchFunc),
206472
- JFUNCTION(json_quote, 1, 0, 1, 1, 0, jsonQuoteFunc),
206473
- JFUNCTION(json_remove, -1, 1, 1, 0, 0, jsonRemoveFunc),
206474
- JFUNCTION(json_replace, -1, 1, 1, 1, 0, jsonReplaceFunc),
206475
- JFUNCTION(json_set, -1, 1, 1, 1, JSON_ISSET, jsonSetFunc),
206476
- JFUNCTION(json_type, 1, 1, 0, 0, 0, jsonTypeFunc),
206477
- JFUNCTION(json_type, 2, 1, 0, 0, 0, jsonTypeFunc),
206478
- JFUNCTION(json_valid, 1, 1, 0, 0, 0, jsonValidFunc),
206479
-#ifdef SQLITE_DEBUG
206480
- JFUNCTION(json_parse, 1, 1, 1, 0, 0, jsonParseFunc),
206481
- JFUNCTION(json_test1, 1, 1, 0, 1, 0, jsonTest1Func),
208102
+ /* sqlite3_result_subtype() ----, ,--- sqlite3_value_subtype() */
208103
+ /* | | */
208104
+ /* Uses cache ------, | | ,---- Returns JSONB */
208105
+ /* | | | | */
208106
+ /* Number of arguments ---, | | | | ,--- Flags */
208107
+ /* | | | | | | */
208108
+ JFUNCTION(json, 1,1,1, 0,0,0, jsonRemoveFunc),
208109
+ JFUNCTION(jsonb, 1,1,0, 0,1,0, jsonRemoveFunc),
208110
+ JFUNCTION(json_array, -1,0,1, 1,0,0, jsonArrayFunc),
208111
+ JFUNCTION(jsonb_array, -1,0,1, 1,1,0, jsonArrayFunc),
208112
+ JFUNCTION(json_array_length, 1,1,0, 0,0,0, jsonArrayLengthFunc),
208113
+ JFUNCTION(json_array_length, 2,1,0, 0,0,0, jsonArrayLengthFunc),
208114
+ JFUNCTION(json_error_position,1,1,0, 0,0,0, jsonErrorFunc),
208115
+ JFUNCTION(json_extract, -1,1,1, 0,0,0, jsonExtractFunc),
208116
+ JFUNCTION(jsonb_extract, -1,1,0, 0,1,0, jsonExtractFunc),
208117
+ JFUNCTION(->, 2,1,1, 0,0,JSON_JSON, jsonExtractFunc),
208118
+ JFUNCTION(->>, 2,1,0, 0,0,JSON_SQL, jsonExtractFunc),
208119
+ JFUNCTION(json_insert, -1,1,1, 1,0,0, jsonSetFunc),
208120
+ JFUNCTION(jsonb_insert, -1,1,0, 1,1,0, jsonSetFunc),
208121
+ JFUNCTION(json_object, -1,0,1, 1,0,0, jsonObjectFunc),
208122
+ JFUNCTION(jsonb_object, -1,0,1, 1,1,0, jsonObjectFunc),
208123
+ JFUNCTION(json_patch, 2,1,1, 0,0,0, jsonPatchFunc),
208124
+ JFUNCTION(jsonb_patch, 2,1,0, 0,1,0, jsonPatchFunc),
208125
+ JFUNCTION(json_quote, 1,0,1, 1,0,0, jsonQuoteFunc),
208126
+ JFUNCTION(json_remove, -1,1,1, 0,0,0, jsonRemoveFunc),
208127
+ JFUNCTION(jsonb_remove, -1,1,0, 0,1,0, jsonRemoveFunc),
208128
+ JFUNCTION(json_replace, -1,1,1, 1,0,0, jsonReplaceFunc),
208129
+ JFUNCTION(jsonb_replace, -1,1,0, 1,1,0, jsonReplaceFunc),
208130
+ JFUNCTION(json_set, -1,1,1, 1,0,JSON_ISSET, jsonSetFunc),
208131
+ JFUNCTION(jsonb_set, -1,1,0, 1,1,JSON_ISSET, jsonSetFunc),
208132
+ JFUNCTION(json_type, 1,1,0, 0,0,0, jsonTypeFunc),
208133
+ JFUNCTION(json_type, 2,1,0, 0,0,0, jsonTypeFunc),
208134
+ JFUNCTION(json_valid, 1,1,0, 0,0,0, jsonValidFunc),
208135
+ JFUNCTION(json_valid, 2,1,0, 0,0,0, jsonValidFunc),
208136
+#if SQLITE_DEBUG
208137
+ JFUNCTION(json_parse, 1,1,0, 0,0,0, jsonParseFunc),
206482208138
#endif
206483208139
WAGGREGATE(json_group_array, 1, 0, 0,
206484208140
jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse,
206485208141
SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|
206486208142
SQLITE_DETERMINISTIC),
208143
+ WAGGREGATE(jsonb_group_array, 1, JSON_BLOB, 0,
208144
+ jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse,
208145
+ SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC),
206487208146
WAGGREGATE(json_group_object, 2, 0, 0,
208147
+ jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse,
208148
+ SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC),
208149
+ WAGGREGATE(jsonb_group_object,2, JSON_BLOB, 0,
206488208150
jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse,
206489208151
SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|
206490208152
SQLITE_DETERMINISTIC)
206491208153
};
206492208154
sqlite3InsertBuiltinFuncs(aJsonFunc, ArraySize(aJsonFunc));
@@ -227778,13 +229440,38 @@
227778229440
** significantly more efficient than those alternatives when used with
227779229441
** "detail=column" tables.
227780229442
**
227781229443
** xPhraseNextColumn()
227782229444
** See xPhraseFirstColumn above.
229445
+**
229446
+** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken)
229447
+** This is used to access token iToken of phrase iPhrase of the current
229448
+** query. Before returning, output parameter *ppToken is set to point
229449
+** to a buffer containing the requested token, and *pnToken to the
229450
+** size of this buffer in bytes.
229451
+**
229452
+** The output text is not a copy of the query text that specified the
229453
+** token. It is the output of the tokenizer module. For tokendata=1
229454
+** tables, this includes any embedded 0x00 and trailing data.
229455
+**
229456
+** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken)
229457
+** This is used to access token iToken of phrase hit iIdx within the
229458
+** current row. Output variable (*ppToken) is set to point to a buffer
229459
+** containing the matching document token, and (*pnToken) to the size
229460
+** of that buffer in bytes. This API is not available if the specified
229461
+** token matches a prefix query term. In that case both output variables
229462
+** are always set to 0.
229463
+**
229464
+** The output text is not a copy of the document text that was tokenized.
229465
+** It is the output of the tokenizer module. For tokendata=1 tables, this
229466
+** includes any embedded 0x00 and trailing data.
229467
+**
229468
+** This API can be quite slow if used with an FTS5 table created with the
229469
+** "detail=none" or "detail=column" option.
227783229470
*/
227784229471
struct Fts5ExtensionApi {
227785
- int iVersion; /* Currently always set to 2 */
229472
+ int iVersion; /* Currently always set to 3 */
227786229473
227787229474
void *(*xUserData)(Fts5Context*);
227788229475
227789229476
int (*xColumnCount)(Fts5Context*);
227790229477
int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
@@ -227815,10 +229502,17 @@
227815229502
int (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*);
227816229503
void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff);
227817229504
227818229505
int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*);
227819229506
void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol);
229507
+
229508
+ /* Below this point are iVersion>=3 only */
229509
+ int (*xQueryToken)(Fts5Context*,
229510
+ int iPhrase, int iToken,
229511
+ const char **ppToken, int *pnToken
229512
+ );
229513
+ int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*);
227820229514
};
227821229515
227822229516
/*
227823229517
** CUSTOM AUXILIARY FUNCTIONS
227824229518
*************************************************************************/
@@ -228289,10 +229983,11 @@
228289229983
int eContent; /* An FTS5_CONTENT value */
228290229984
int bContentlessDelete; /* "contentless_delete=" option (dflt==0) */
228291229985
char *zContent; /* content table */
228292229986
char *zContentRowid; /* "content_rowid=" option value */
228293229987
int bColumnsize; /* "columnsize=" option value (dflt==1) */
229988
+ int bTokendata; /* "tokendata=" option value (dflt==0) */
228294229989
int eDetail; /* FTS5_DETAIL_XXX value */
228295229990
char *zContentExprlist;
228296229991
Fts5Tokenizer *pTok;
228297229992
fts5_tokenizer *pTokApi;
228298229993
int bLock; /* True when table is preparing statement */
@@ -228477,21 +230172,23 @@
228477230172
#define sqlite3Fts5IterEof(x) ((x)->bEof)
228478230173
228479230174
/*
228480230175
** Values used as part of the flags argument passed to IndexQuery().
228481230176
*/
228482
-#define FTS5INDEX_QUERY_PREFIX 0x0001 /* Prefix query */
228483
-#define FTS5INDEX_QUERY_DESC 0x0002 /* Docs in descending rowid order */
228484
-#define FTS5INDEX_QUERY_TEST_NOIDX 0x0004 /* Do not use prefix index */
228485
-#define FTS5INDEX_QUERY_SCAN 0x0008 /* Scan query (fts5vocab) */
230177
+#define FTS5INDEX_QUERY_PREFIX 0x0001 /* Prefix query */
230178
+#define FTS5INDEX_QUERY_DESC 0x0002 /* Docs in descending rowid order */
230179
+#define FTS5INDEX_QUERY_TEST_NOIDX 0x0004 /* Do not use prefix index */
230180
+#define FTS5INDEX_QUERY_SCAN 0x0008 /* Scan query (fts5vocab) */
228486230181
228487230182
/* The following are used internally by the fts5_index.c module. They are
228488230183
** defined here only to make it easier to avoid clashes with the flags
228489230184
** above. */
228490
-#define FTS5INDEX_QUERY_SKIPEMPTY 0x0010
228491
-#define FTS5INDEX_QUERY_NOOUTPUT 0x0020
228492
-#define FTS5INDEX_QUERY_SKIPHASH 0x0040
230185
+#define FTS5INDEX_QUERY_SKIPEMPTY 0x0010
230186
+#define FTS5INDEX_QUERY_NOOUTPUT 0x0020
230187
+#define FTS5INDEX_QUERY_SKIPHASH 0x0040
230188
+#define FTS5INDEX_QUERY_NOTOKENDATA 0x0080
230189
+#define FTS5INDEX_QUERY_SCANONETERM 0x0100
228493230190
228494230191
/*
228495230192
** Create/destroy an Fts5Index object.
228496230193
*/
228497230194
static int sqlite3Fts5IndexOpen(Fts5Config *pConfig, int bCreate, Fts5Index**, char**);
@@ -228556,10 +230253,14 @@
228556230253
static int sqlite3Fts5IterNextScan(Fts5IndexIter*);
228557230254
static void *sqlite3Fts5StructureRef(Fts5Index*);
228558230255
static void sqlite3Fts5StructureRelease(void*);
228559230256
static int sqlite3Fts5StructureTest(Fts5Index*, void*);
228560230257
230258
+/*
230259
+** Used by xInstToken():
230260
+*/
230261
+static int sqlite3Fts5IterToken(Fts5IndexIter*, i64, int, int, const char**, int*);
228561230262
228562230263
/*
228563230264
** Insert or remove data to or from the index. Each time a document is
228564230265
** added to or removed from the index, this function is called one or more
228565230266
** times.
@@ -228632,10 +230333,17 @@
228632230333
228633230334
static int sqlite3Fts5IndexLoadConfig(Fts5Index *p);
228634230335
228635230336
static int sqlite3Fts5IndexGetOrigin(Fts5Index *p, i64 *piOrigin);
228636230337
static int sqlite3Fts5IndexContentlessDelete(Fts5Index *p, i64 iOrigin, i64 iRowid);
230338
+
230339
+static void sqlite3Fts5IndexIterClearTokendata(Fts5IndexIter*);
230340
+
230341
+/* Used to populate hash tables for xInstToken in detail=none/column mode. */
230342
+static int sqlite3Fts5IndexIterWriteTokendata(
230343
+ Fts5IndexIter*, const char*, int, i64 iRowid, int iCol, int iOff
230344
+);
228637230345
228638230346
/*
228639230347
** End of interface to code in fts5_index.c.
228640230348
**************************************************************************/
228641230349
@@ -228738,10 +230446,11 @@
228738230446
);
228739230447
static void sqlite3Fts5HashScanNext(Fts5Hash*);
228740230448
static int sqlite3Fts5HashScanEof(Fts5Hash*);
228741230449
static void sqlite3Fts5HashScanEntry(Fts5Hash *,
228742230450
const char **pzTerm, /* OUT: term (nul-terminated) */
230451
+ int *pnTerm, /* OUT: Size of term in bytes */
228743230452
const u8 **ppDoclist, /* OUT: pointer to doclist */
228744230453
int *pnDoclist /* OUT: size of doclist in bytes */
228745230454
);
228746230455
228747230456
@@ -228863,10 +230572,14 @@
228863230572
static void sqlite3Fts5ExprCheckPoslists(Fts5Expr*, i64);
228864230573
228865230574
static int sqlite3Fts5ExprClonePhrase(Fts5Expr*, int, Fts5Expr**);
228866230575
228867230576
static int sqlite3Fts5ExprPhraseCollist(Fts5Expr *, int, const u8 **, int *);
230577
+
230578
+static int sqlite3Fts5ExprQueryToken(Fts5Expr*, int, int, const char**, int*);
230579
+static int sqlite3Fts5ExprInstToken(Fts5Expr*, i64, int, int, int, int, const char**, int*);
230580
+static void sqlite3Fts5ExprClearTokens(Fts5Expr*);
228868230581
228869230582
/*******************************************
228870230583
** The fts5_expr.c API above this point is used by the other hand-written
228871230584
** C code in this module. The interfaces below this point are called by
228872230585
** the parser code in fts5parse.y. */
@@ -230679,10 +232392,18 @@
230679232392
rc = fts5CInstIterNext(&p->iter);
230680232393
}
230681232394
}
230682232395
230683232396
if( iPos==p->iRangeEnd ){
232397
+ if( p->bOpen ){
232398
+ if( p->iter.iStart>=0 && iPos>=p->iter.iStart ){
232399
+ fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff);
232400
+ p->iOff = iEndOff;
232401
+ }
232402
+ fts5HighlightAppend(&rc, p, p->zClose, -1);
232403
+ p->bOpen = 0;
232404
+ }
230684232405
fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff);
230685232406
p->iOff = iEndOff;
230686232407
}
230687232408
230688232409
return rc;
@@ -231280,10 +233001,11 @@
231280233001
u32 nData,
231281233002
const u8 *pData
231282233003
){
231283233004
if( nData ){
231284233005
if( fts5BufferGrow(pRc, pBuf, nData) ) return;
233006
+ assert( pBuf->p!=0 );
231285233007
memcpy(&pBuf->p[pBuf->n], pData, nData);
231286233008
pBuf->n += nData;
231287233009
}
231288233010
}
231289233011
@@ -231381,17 +233103,19 @@
231381233103
const u8 *a, int n, /* Buffer containing poslist */
231382233104
int *pi, /* IN/OUT: Offset within a[] */
231383233105
i64 *piOff /* IN/OUT: Current offset */
231384233106
){
231385233107
int i = *pi;
233108
+ assert( a!=0 || i==0 );
231386233109
if( i>=n ){
231387233110
/* EOF */
231388233111
*piOff = -1;
231389233112
return 1;
231390233113
}else{
231391233114
i64 iOff = *piOff;
231392233115
u32 iVal;
233116
+ assert( a!=0 );
231393233117
fts5FastGetVarint32(a, i, iVal);
231394233118
if( iVal<=1 ){
231395233119
if( iVal==0 ){
231396233120
*pi = i;
231397233121
return 0;
@@ -232018,10 +233742,20 @@
232018233742
if( (rc = fts5ConfigSetEnum(aDetail, zArg, &pConfig->eDetail)) ){
232019233743
*pzErr = sqlite3_mprintf("malformed detail=... directive");
232020233744
}
232021233745
return rc;
232022233746
}
233747
+
233748
+ if( sqlite3_strnicmp("tokendata", zCmd, nCmd)==0 ){
233749
+ if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){
233750
+ *pzErr = sqlite3_mprintf("malformed tokendata=... directive");
233751
+ rc = SQLITE_ERROR;
233752
+ }else{
233753
+ pConfig->bTokendata = (zArg[0]=='1');
233754
+ }
233755
+ return rc;
233756
+ }
232023233757
232024233758
*pzErr = sqlite3_mprintf("unrecognized option: \"%.*s\"", nCmd, zCmd);
232025233759
return SQLITE_ERROR;
232026233760
}
232027233761
@@ -232752,11 +234486,13 @@
232752234486
** or term prefix.
232753234487
*/
232754234488
struct Fts5ExprTerm {
232755234489
u8 bPrefix; /* True for a prefix term */
232756234490
u8 bFirst; /* True if token must be first in column */
232757
- char *zTerm; /* nul-terminated term */
234491
+ char *pTerm; /* Term data */
234492
+ int nQueryTerm; /* Effective size of term in bytes */
234493
+ int nFullTerm; /* Size of term in bytes incl. tokendata */
232758234494
Fts5IndexIter *pIter; /* Iterator for this term */
232759234495
Fts5ExprTerm *pSynonym; /* Pointer to first in list of synonyms */
232760234496
};
232761234497
232762234498
/*
@@ -233619,11 +235355,11 @@
233619235355
if( p->pIter ){
233620235356
sqlite3Fts5IterClose(p->pIter);
233621235357
p->pIter = 0;
233622235358
}
233623235359
rc = sqlite3Fts5IndexQuery(
233624
- pExpr->pIndex, p->zTerm, (int)strlen(p->zTerm),
235360
+ pExpr->pIndex, p->pTerm, p->nQueryTerm,
233625235361
(pTerm->bPrefix ? FTS5INDEX_QUERY_PREFIX : 0) |
233626235362
(pExpr->bDesc ? FTS5INDEX_QUERY_DESC : 0),
233627235363
pNear->pColset,
233628235364
&p->pIter
233629235365
);
@@ -234256,11 +235992,11 @@
234256235992
int i;
234257235993
for(i=0; i<pPhrase->nTerm; i++){
234258235994
Fts5ExprTerm *pSyn;
234259235995
Fts5ExprTerm *pNext;
234260235996
Fts5ExprTerm *pTerm = &pPhrase->aTerm[i];
234261
- sqlite3_free(pTerm->zTerm);
235997
+ sqlite3_free(pTerm->pTerm);
234262235998
sqlite3Fts5IterClose(pTerm->pIter);
234263235999
for(pSyn=pTerm->pSynonym; pSyn; pSyn=pNext){
234264236000
pNext = pSyn->pSynonym;
234265236001
sqlite3Fts5IterClose(pSyn->pIter);
234266236002
fts5BufferFree((Fts5Buffer*)&pSyn[1]);
@@ -234354,10 +236090,11 @@
234354236090
}
234355236091
234356236092
typedef struct TokenCtx TokenCtx;
234357236093
struct TokenCtx {
234358236094
Fts5ExprPhrase *pPhrase;
236095
+ Fts5Config *pConfig;
234359236096
int rc;
234360236097
};
234361236098
234362236099
/*
234363236100
** Callback for tokenizing terms used by ParseTerm().
@@ -234387,12 +236124,16 @@
234387236124
pSyn = (Fts5ExprTerm*)sqlite3_malloc64(nByte);
234388236125
if( pSyn==0 ){
234389236126
rc = SQLITE_NOMEM;
234390236127
}else{
234391236128
memset(pSyn, 0, (size_t)nByte);
234392
- pSyn->zTerm = ((char*)pSyn) + sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer);
234393
- memcpy(pSyn->zTerm, pToken, nToken);
236129
+ pSyn->pTerm = ((char*)pSyn) + sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer);
236130
+ pSyn->nFullTerm = pSyn->nQueryTerm = nToken;
236131
+ if( pCtx->pConfig->bTokendata ){
236132
+ pSyn->nQueryTerm = (int)strlen(pSyn->pTerm);
236133
+ }
236134
+ memcpy(pSyn->pTerm, pToken, nToken);
234394236135
pSyn->pSynonym = pPhrase->aTerm[pPhrase->nTerm-1].pSynonym;
234395236136
pPhrase->aTerm[pPhrase->nTerm-1].pSynonym = pSyn;
234396236137
}
234397236138
}else{
234398236139
Fts5ExprTerm *pTerm;
@@ -234413,11 +236154,15 @@
234413236154
}
234414236155
234415236156
if( rc==SQLITE_OK ){
234416236157
pTerm = &pPhrase->aTerm[pPhrase->nTerm++];
234417236158
memset(pTerm, 0, sizeof(Fts5ExprTerm));
234418
- pTerm->zTerm = sqlite3Fts5Strndup(&rc, pToken, nToken);
236159
+ pTerm->pTerm = sqlite3Fts5Strndup(&rc, pToken, nToken);
236160
+ pTerm->nFullTerm = pTerm->nQueryTerm = nToken;
236161
+ if( pCtx->pConfig->bTokendata && rc==SQLITE_OK ){
236162
+ pTerm->nQueryTerm = (int)strlen(pTerm->pTerm);
236163
+ }
234419236164
}
234420236165
}
234421236166
234422236167
pCtx->rc = rc;
234423236168
return rc;
@@ -234480,10 +236225,11 @@
234480236225
int rc; /* Tokenize return code */
234481236226
char *z = 0;
234482236227
234483236228
memset(&sCtx, 0, sizeof(TokenCtx));
234484236229
sCtx.pPhrase = pAppend;
236230
+ sCtx.pConfig = pConfig;
234485236231
234486236232
rc = fts5ParseStringFromToken(pToken, &z);
234487236233
if( rc==SQLITE_OK ){
234488236234
int flags = FTS5_TOKENIZE_QUERY | (bPrefix ? FTS5_TOKENIZE_PREFIX : 0);
234489236235
int n;
@@ -234529,12 +236275,11 @@
234529236275
Fts5Expr **ppNew
234530236276
){
234531236277
int rc = SQLITE_OK; /* Return code */
234532236278
Fts5ExprPhrase *pOrig; /* The phrase extracted from pExpr */
234533236279
Fts5Expr *pNew = 0; /* Expression to return via *ppNew */
234534
- TokenCtx sCtx = {0,0}; /* Context object for fts5ParseTokenize */
234535
-
236280
+ TokenCtx sCtx = {0,0,0}; /* Context object for fts5ParseTokenize */
234536236281
pOrig = pExpr->apExprPhrase[iPhrase];
234537236282
pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr));
234538236283
if( rc==SQLITE_OK ){
234539236284
pNew->apExprPhrase = (Fts5ExprPhrase**)sqlite3Fts5MallocZero(&rc,
234540236285
sizeof(Fts5ExprPhrase*));
@@ -234561,17 +236306,16 @@
234561236306
}
234562236307
}
234563236308
234564236309
if( pOrig->nTerm ){
234565236310
int i; /* Used to iterate through phrase terms */
236311
+ sCtx.pConfig = pExpr->pConfig;
234566236312
for(i=0; rc==SQLITE_OK && i<pOrig->nTerm; i++){
234567236313
int tflags = 0;
234568236314
Fts5ExprTerm *p;
234569236315
for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){
234570
- const char *zTerm = p->zTerm;
234571
- rc = fts5ParseTokenize((void*)&sCtx, tflags, zTerm, (int)strlen(zTerm),
234572
- 0, 0);
236316
+ rc = fts5ParseTokenize((void*)&sCtx, tflags, p->pTerm,p->nFullTerm,0,0);
234573236317
tflags = FTS5_TOKEN_COLOCATED;
234574236318
}
234575236319
if( rc==SQLITE_OK ){
234576236320
sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix;
234577236321
sCtx.pPhrase->aTerm[i].bFirst = pOrig->aTerm[i].bFirst;
@@ -234948,15 +236692,17 @@
234948236692
);
234949236693
if( pPhrase ){
234950236694
if( parseGrowPhraseArray(pParse) ){
234951236695
fts5ExprPhraseFree(pPhrase);
234952236696
}else{
236697
+ Fts5ExprTerm *p = &pNear->apPhrase[0]->aTerm[ii];
236698
+ Fts5ExprTerm *pTo = &pPhrase->aTerm[0];
234953236699
pParse->apPhrase[pParse->nPhrase++] = pPhrase;
234954236700
pPhrase->nTerm = 1;
234955
- pPhrase->aTerm[0].zTerm = sqlite3Fts5Strndup(
234956
- &pParse->rc, pNear->apPhrase[0]->aTerm[ii].zTerm, -1
234957
- );
236701
+ pTo->pTerm = sqlite3Fts5Strndup(&pParse->rc, p->pTerm, p->nFullTerm);
236702
+ pTo->nQueryTerm = p->nQueryTerm;
236703
+ pTo->nFullTerm = p->nFullTerm;
234958236704
pRet->apChild[ii] = sqlite3Fts5ParseNode(pParse, FTS5_STRING,
234959236705
0, 0, sqlite3Fts5ParseNearset(pParse, 0, pPhrase)
234960236706
);
234961236707
}
234962236708
}
@@ -235137,20 +236883,21 @@
235137236883
Fts5ExprTerm *p;
235138236884
char *zQuoted;
235139236885
235140236886
/* Determine the maximum amount of space required. */
235141236887
for(p=pTerm; p; p=p->pSynonym){
235142
- nByte += (int)strlen(pTerm->zTerm) * 2 + 3 + 2;
236888
+ nByte += pTerm->nQueryTerm * 2 + 3 + 2;
235143236889
}
235144236890
zQuoted = sqlite3_malloc64(nByte);
235145236891
235146236892
if( zQuoted ){
235147236893
int i = 0;
235148236894
for(p=pTerm; p; p=p->pSynonym){
235149
- char *zIn = p->zTerm;
236895
+ char *zIn = p->pTerm;
236896
+ char *zEnd = &zIn[p->nQueryTerm];
235150236897
zQuoted[i++] = '"';
235151
- while( *zIn ){
236898
+ while( zIn<zEnd ){
235152236899
if( *zIn=='"' ) zQuoted[i++] = '"';
235153236900
zQuoted[i++] = *zIn++;
235154236901
}
235155236902
zQuoted[i++] = '"';
235156236903
if( p->pSynonym ) zQuoted[i++] = '|';
@@ -235224,12 +236971,14 @@
235224236971
for(i=0; i<pNear->nPhrase; i++){
235225236972
Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
235226236973
235227236974
zRet = fts5PrintfAppend(zRet, " {");
235228236975
for(iTerm=0; zRet && iTerm<pPhrase->nTerm; iTerm++){
235229
- char *zTerm = pPhrase->aTerm[iTerm].zTerm;
235230
- zRet = fts5PrintfAppend(zRet, "%s%s", iTerm==0?"":" ", zTerm);
236976
+ Fts5ExprTerm *p = &pPhrase->aTerm[iTerm];
236977
+ zRet = fts5PrintfAppend(zRet, "%s%.*s", iTerm==0?"":" ",
236978
+ p->nQueryTerm, p->pTerm
236979
+ );
235231236980
if( pPhrase->aTerm[iTerm].bPrefix ){
235232236981
zRet = fts5PrintfAppend(zRet, "*");
235233236982
}
235234236983
}
235235236984
@@ -235625,10 +237374,21 @@
235625237374
for(i=0; i<pColset->nCol; i++){
235626237375
if( pColset->aiCol[i]==iCol ) return 1;
235627237376
}
235628237377
return 0;
235629237378
}
237379
+
237380
+/*
237381
+** pToken is a buffer nToken bytes in size that may or may not contain
237382
+** an embedded 0x00 byte. If it does, return the number of bytes in
237383
+** the buffer before the 0x00. If it does not, return nToken.
237384
+*/
237385
+static int fts5QueryTerm(const char *pToken, int nToken){
237386
+ int ii;
237387
+ for(ii=0; ii<nToken && pToken[ii]; ii++){}
237388
+ return ii;
237389
+}
235630237390
235631237391
static int fts5ExprPopulatePoslistsCb(
235632237392
void *pCtx, /* Copy of 2nd argument to xTokenize() */
235633237393
int tflags, /* Mask of FTS5_TOKEN_* flags */
235634237394
const char *pToken, /* Pointer to buffer containing token */
@@ -235637,26 +237397,37 @@
235637237397
int iUnused2 /* Byte offset of end of token within input text */
235638237398
){
235639237399
Fts5ExprCtx *p = (Fts5ExprCtx*)pCtx;
235640237400
Fts5Expr *pExpr = p->pExpr;
235641237401
int i;
237402
+ int nQuery = nToken;
237403
+ i64 iRowid = pExpr->pRoot->iRowid;
235642237404
235643237405
UNUSED_PARAM2(iUnused1, iUnused2);
235644237406
235645
- if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE;
237407
+ if( nQuery>FTS5_MAX_TOKEN_SIZE ) nQuery = FTS5_MAX_TOKEN_SIZE;
237408
+ if( pExpr->pConfig->bTokendata ){
237409
+ nQuery = fts5QueryTerm(pToken, nQuery);
237410
+ }
235646237411
if( (tflags & FTS5_TOKEN_COLOCATED)==0 ) p->iOff++;
235647237412
for(i=0; i<pExpr->nPhrase; i++){
235648
- Fts5ExprTerm *pTerm;
237413
+ Fts5ExprTerm *pT;
235649237414
if( p->aPopulator[i].bOk==0 ) continue;
235650
- for(pTerm=&pExpr->apExprPhrase[i]->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){
235651
- int nTerm = (int)strlen(pTerm->zTerm);
235652
- if( (nTerm==nToken || (nTerm<nToken && pTerm->bPrefix))
235653
- && memcmp(pTerm->zTerm, pToken, nTerm)==0
237415
+ for(pT=&pExpr->apExprPhrase[i]->aTerm[0]; pT; pT=pT->pSynonym){
237416
+ if( (pT->nQueryTerm==nQuery || (pT->nQueryTerm<nQuery && pT->bPrefix))
237417
+ && memcmp(pT->pTerm, pToken, pT->nQueryTerm)==0
235654237418
){
235655237419
int rc = sqlite3Fts5PoslistWriterAppend(
235656237420
&pExpr->apExprPhrase[i]->poslist, &p->aPopulator[i].writer, p->iOff
235657237421
);
237422
+ if( rc==SQLITE_OK && pExpr->pConfig->bTokendata && !pT->bPrefix ){
237423
+ int iCol = p->iOff>>32;
237424
+ int iTokOff = p->iOff & 0x7FFFFFFF;
237425
+ rc = sqlite3Fts5IndexIterWriteTokendata(
237426
+ pT->pIter, pToken, nToken, iRowid, iCol, iTokOff
237427
+ );
237428
+ }
235658237429
if( rc ) return rc;
235659237430
break;
235660237431
}
235661237432
}
235662237433
}
@@ -235787,10 +237558,87 @@
235787237558
*pnCollist = 0;
235788237559
}
235789237560
235790237561
return rc;
235791237562
}
237563
+
237564
+/*
237565
+** Does the work of the fts5_api.xQueryToken() API method.
237566
+*/
237567
+static int sqlite3Fts5ExprQueryToken(
237568
+ Fts5Expr *pExpr,
237569
+ int iPhrase,
237570
+ int iToken,
237571
+ const char **ppOut,
237572
+ int *pnOut
237573
+){
237574
+ Fts5ExprPhrase *pPhrase = 0;
237575
+
237576
+ if( iPhrase<0 || iPhrase>=pExpr->nPhrase ){
237577
+ return SQLITE_RANGE;
237578
+ }
237579
+ pPhrase = pExpr->apExprPhrase[iPhrase];
237580
+ if( iToken<0 || iToken>=pPhrase->nTerm ){
237581
+ return SQLITE_RANGE;
237582
+ }
237583
+
237584
+ *ppOut = pPhrase->aTerm[iToken].pTerm;
237585
+ *pnOut = pPhrase->aTerm[iToken].nFullTerm;
237586
+ return SQLITE_OK;
237587
+}
237588
+
237589
+/*
237590
+** Does the work of the fts5_api.xInstToken() API method.
237591
+*/
237592
+static int sqlite3Fts5ExprInstToken(
237593
+ Fts5Expr *pExpr,
237594
+ i64 iRowid,
237595
+ int iPhrase,
237596
+ int iCol,
237597
+ int iOff,
237598
+ int iToken,
237599
+ const char **ppOut,
237600
+ int *pnOut
237601
+){
237602
+ Fts5ExprPhrase *pPhrase = 0;
237603
+ Fts5ExprTerm *pTerm = 0;
237604
+ int rc = SQLITE_OK;
237605
+
237606
+ if( iPhrase<0 || iPhrase>=pExpr->nPhrase ){
237607
+ return SQLITE_RANGE;
237608
+ }
237609
+ pPhrase = pExpr->apExprPhrase[iPhrase];
237610
+ if( iToken<0 || iToken>=pPhrase->nTerm ){
237611
+ return SQLITE_RANGE;
237612
+ }
237613
+ pTerm = &pPhrase->aTerm[iToken];
237614
+ if( pTerm->bPrefix==0 ){
237615
+ if( pExpr->pConfig->bTokendata ){
237616
+ rc = sqlite3Fts5IterToken(
237617
+ pTerm->pIter, iRowid, iCol, iOff+iToken, ppOut, pnOut
237618
+ );
237619
+ }else{
237620
+ *ppOut = pTerm->pTerm;
237621
+ *pnOut = pTerm->nFullTerm;
237622
+ }
237623
+ }
237624
+ return rc;
237625
+}
237626
+
237627
+/*
237628
+** Clear the token mappings for all Fts5IndexIter objects mannaged by
237629
+** the expression passed as the only argument.
237630
+*/
237631
+static void sqlite3Fts5ExprClearTokens(Fts5Expr *pExpr){
237632
+ int ii;
237633
+ for(ii=0; ii<pExpr->nPhrase; ii++){
237634
+ Fts5ExprTerm *pT;
237635
+ for(pT=&pExpr->apExprPhrase[ii]->aTerm[0]; pT; pT=pT->pSynonym){
237636
+ sqlite3Fts5IndexIterClearTokendata(pT->pIter);
237637
+ }
237638
+ }
237639
+}
235792237640
235793237641
/*
235794237642
** 2014 August 11
235795237643
**
235796237644
** The author disclaims copyright to this source code. In place of
@@ -235826,14 +237674,19 @@
235826237674
Fts5HashEntry **aSlot; /* Array of hash slots */
235827237675
};
235828237676
235829237677
/*
235830237678
** Each entry in the hash table is represented by an object of the
235831
-** following type. Each object, its key (a nul-terminated string) and
235832
-** its current data are stored in a single memory allocation. The
235833
-** key immediately follows the object in memory. The position list
235834
-** data immediately follows the key data in memory.
237679
+** following type. Each object, its key, and its current data are stored
237680
+** in a single memory allocation. The key immediately follows the object
237681
+** in memory. The position list data immediately follows the key data
237682
+** in memory.
237683
+**
237684
+** The key is Fts5HashEntry.nKey bytes in size. It consists of a single
237685
+** byte identifying the index (either the main term index or a prefix-index),
237686
+** followed by the term data. For example: "0token". There is no
237687
+** nul-terminator - in this case nKey=6.
235835237688
**
235836237689
** The data that follows the key is in a similar, but not identical format
235837237690
** to the doclist data stored in the database. It is:
235838237691
**
235839237692
** * Rowid, as a varint
@@ -235964,12 +237817,11 @@
235964237817
for(i=0; i<pHash->nSlot; i++){
235965237818
while( apOld[i] ){
235966237819
unsigned int iHash;
235967237820
Fts5HashEntry *p = apOld[i];
235968237821
apOld[i] = p->pHashNext;
235969
- iHash = fts5HashKey(nNew, (u8*)fts5EntryKey(p),
235970
- (int)strlen(fts5EntryKey(p)));
237822
+ iHash = fts5HashKey(nNew, (u8*)fts5EntryKey(p), p->nKey);
235971237823
p->pHashNext = apNew[iHash];
235972237824
apNew[iHash] = p;
235973237825
}
235974237826
}
235975237827
@@ -236049,11 +237901,11 @@
236049237901
/* Attempt to locate an existing hash entry */
236050237902
iHash = fts5HashKey2(pHash->nSlot, (u8)bByte, (const u8*)pToken, nToken);
236051237903
for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){
236052237904
char *zKey = fts5EntryKey(p);
236053237905
if( zKey[0]==bByte
236054
- && p->nKey==nToken
237906
+ && p->nKey==nToken+1
236055237907
&& memcmp(&zKey[1], pToken, nToken)==0
236056237908
){
236057237909
break;
236058237910
}
236059237911
}
@@ -236079,13 +237931,13 @@
236079237931
p->nAlloc = (int)nByte;
236080237932
zKey = fts5EntryKey(p);
236081237933
zKey[0] = bByte;
236082237934
memcpy(&zKey[1], pToken, nToken);
236083237935
assert( iHash==fts5HashKey(pHash->nSlot, (u8*)zKey, nToken+1) );
236084
- p->nKey = nToken;
237936
+ p->nKey = nToken+1;
236085237937
zKey[nToken+1] = '\0';
236086
- p->nData = nToken+1 + 1 + sizeof(Fts5HashEntry);
237938
+ p->nData = nToken+1 + sizeof(Fts5HashEntry);
236087237939
p->pHashNext = pHash->aSlot[iHash];
236088237940
pHash->aSlot[iHash] = p;
236089237941
pHash->nEntry++;
236090237942
236091237943
/* Add the first rowid field to the hash-entry */
@@ -236198,16 +238050,21 @@
236198238050
p2 = 0;
236199238051
}else if( p2==0 ){
236200238052
*ppOut = p1;
236201238053
p1 = 0;
236202238054
}else{
236203
- int i = 0;
236204238055
char *zKey1 = fts5EntryKey(p1);
236205238056
char *zKey2 = fts5EntryKey(p2);
236206
- while( zKey1[i]==zKey2[i] ) i++;
238057
+ int nMin = MIN(p1->nKey, p2->nKey);
236207238058
236208
- if( ((u8)zKey1[i])>((u8)zKey2[i]) ){
238059
+ int cmp = memcmp(zKey1, zKey2, nMin);
238060
+ if( cmp==0 ){
238061
+ cmp = p1->nKey - p2->nKey;
238062
+ }
238063
+ assert( cmp!=0 );
238064
+
238065
+ if( cmp>0 ){
236209238066
/* p2 is smaller */
236210238067
*ppOut = p2;
236211238068
ppOut = &p2->pScanNext;
236212238069
p2 = p2->pScanNext;
236213238070
}else{
@@ -236245,11 +238102,11 @@
236245238102
236246238103
for(iSlot=0; iSlot<pHash->nSlot; iSlot++){
236247238104
Fts5HashEntry *pIter;
236248238105
for(pIter=pHash->aSlot[iSlot]; pIter; pIter=pIter->pHashNext){
236249238106
if( pTerm==0
236250
- || (pIter->nKey+1>=nTerm && 0==memcmp(fts5EntryKey(pIter), pTerm, nTerm))
238107
+ || (pIter->nKey>=nTerm && 0==memcmp(fts5EntryKey(pIter), pTerm, nTerm))
236251238108
){
236252238109
Fts5HashEntry *pEntry = pIter;
236253238110
pEntry->pScanNext = 0;
236254238111
for(i=0; ap[i]; i++){
236255238112
pEntry = fts5HashEntryMerge(pEntry, ap[i]);
@@ -236284,16 +238141,15 @@
236284238141
char *zKey = 0;
236285238142
Fts5HashEntry *p;
236286238143
236287238144
for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){
236288238145
zKey = fts5EntryKey(p);
236289
- assert( p->nKey+1==(int)strlen(zKey) );
236290
- if( nTerm==p->nKey+1 && memcmp(zKey, pTerm, nTerm)==0 ) break;
238146
+ if( nTerm==p->nKey && memcmp(zKey, pTerm, nTerm)==0 ) break;
236291238147
}
236292238148
236293238149
if( p ){
236294
- int nHashPre = sizeof(Fts5HashEntry) + nTerm + 1;
238150
+ int nHashPre = sizeof(Fts5HashEntry) + nTerm;
236295238151
int nList = p->nData - nHashPre;
236296238152
u8 *pRet = (u8*)(*ppOut = sqlite3_malloc64(nPre + nList + 10));
236297238153
if( pRet ){
236298238154
Fts5HashEntry *pFaux = (Fts5HashEntry*)&pRet[nPre-nHashPre];
236299238155
memcpy(&pRet[nPre], &((u8*)p)[nHashPre], nList);
@@ -236350,23 +238206,26 @@
236350238206
}
236351238207
236352238208
static void sqlite3Fts5HashScanEntry(
236353238209
Fts5Hash *pHash,
236354238210
const char **pzTerm, /* OUT: term (nul-terminated) */
238211
+ int *pnTerm, /* OUT: Size of term in bytes */
236355238212
const u8 **ppDoclist, /* OUT: pointer to doclist */
236356238213
int *pnDoclist /* OUT: size of doclist in bytes */
236357238214
){
236358238215
Fts5HashEntry *p;
236359238216
if( (p = pHash->pScan) ){
236360238217
char *zKey = fts5EntryKey(p);
236361
- int nTerm = (int)strlen(zKey);
238218
+ int nTerm = p->nKey;
236362238219
fts5HashAddPoslistSize(pHash, p, 0);
236363238220
*pzTerm = zKey;
236364
- *ppDoclist = (const u8*)&zKey[nTerm+1];
236365
- *pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm + 1);
238221
+ *pnTerm = nTerm;
238222
+ *ppDoclist = (const u8*)&zKey[nTerm];
238223
+ *pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm);
236366238224
}else{
236367238225
*pzTerm = 0;
238226
+ *pnTerm = 0;
236368238227
*ppDoclist = 0;
236369238228
*pnDoclist = 0;
236370238229
}
236371238230
}
236372238231
@@ -236693,10 +238552,13 @@
236693238552
typedef struct Fts5DoclistIter Fts5DoclistIter;
236694238553
typedef struct Fts5SegWriter Fts5SegWriter;
236695238554
typedef struct Fts5Structure Fts5Structure;
236696238555
typedef struct Fts5StructureLevel Fts5StructureLevel;
236697238556
typedef struct Fts5StructureSegment Fts5StructureSegment;
238557
+typedef struct Fts5TokenDataIter Fts5TokenDataIter;
238558
+typedef struct Fts5TokenDataMap Fts5TokenDataMap;
238559
+typedef struct Fts5TombstoneArray Fts5TombstoneArray;
236698238560
236699238561
struct Fts5Data {
236700238562
u8 *p; /* Pointer to buffer containing record */
236701238563
int nn; /* Size of record in bytes */
236702238564
int szLeaf; /* Size of leaf without page-index */
@@ -236727,18 +238589,20 @@
236727238589
int nContentlessDelete; /* Number of contentless delete ops */
236728238590
int nPendingRow; /* Number of INSERT in hash table */
236729238591
236730238592
/* Error state. */
236731238593
int rc; /* Current error code */
238594
+ int flushRc;
236732238595
236733238596
/* State used by the fts5DataXXX() functions. */
236734238597
sqlite3_blob *pReader; /* RO incr-blob open on %_data table */
236735238598
sqlite3_stmt *pWriter; /* "INSERT ... %_data VALUES(?,?)" */
236736238599
sqlite3_stmt *pDeleter; /* "DELETE FROM %_data ... id>=? AND id<=?" */
236737238600
sqlite3_stmt *pIdxWriter; /* "INSERT ... %_idx VALUES(?,?,?,?)" */
236738238601
sqlite3_stmt *pIdxDeleter; /* "DELETE FROM %_idx WHERE segid=?" */
236739238602
sqlite3_stmt *pIdxSelect;
238603
+ sqlite3_stmt *pIdxNextSelect;
236740238604
int nRead; /* Total number of blocks read */
236741238605
236742238606
sqlite3_stmt *pDeleteFromIdx;
236743238607
236744238608
sqlite3_stmt *pDataVersion;
@@ -236888,12 +238752,11 @@
236888238752
int flags; /* Mask of configuration flags */
236889238753
int iLeafPgno; /* Current leaf page number */
236890238754
Fts5Data *pLeaf; /* Current leaf data */
236891238755
Fts5Data *pNextLeaf; /* Leaf page (iLeafPgno+1) */
236892238756
i64 iLeafOffset; /* Byte offset within current leaf */
236893
- Fts5Data **apTombstone; /* Array of tombstone pages */
236894
- int nTombstone;
238757
+ Fts5TombstoneArray *pTombArray; /* Array of tombstone pages */
236895238758
236896238759
/* Next method */
236897238760
void (*xNext)(Fts5Index*, Fts5SegIter*, int*);
236898238761
236899238762
/* The page and offset from which the current term was read. The offset
@@ -236915,10 +238778,19 @@
236915238778
Fts5Buffer term; /* Current term */
236916238779
i64 iRowid; /* Current rowid */
236917238780
int nPos; /* Number of bytes in current position list */
236918238781
u8 bDel; /* True if the delete flag is set */
236919238782
};
238783
+
238784
+/*
238785
+** Array of tombstone pages. Reference counted.
238786
+*/
238787
+struct Fts5TombstoneArray {
238788
+ int nRef; /* Number of pointers to this object */
238789
+ int nTombstone;
238790
+ Fts5Data *apTombstone[1]; /* Array of tombstone pages */
238791
+};
236920238792
236921238793
/*
236922238794
** Argument is a pointer to an Fts5Data structure that contains a
236923238795
** leaf page.
236924238796
*/
@@ -236960,13 +238832,20 @@
236960238832
** the smallest key overall. aFirst[0] is unused.
236961238833
**
236962238834
** poslist:
236963238835
** Used by sqlite3Fts5IterPoslist() when the poslist needs to be buffered.
236964238836
** There is no way to tell if this is populated or not.
238837
+**
238838
+** pColset:
238839
+** If not NULL, points to an object containing a set of column indices.
238840
+** Only matches that occur in one of these columns will be returned.
238841
+** The Fts5Iter does not own the Fts5Colset object, and so it is not
238842
+** freed when the iterator is closed - it is owned by the upper layer.
236965238843
*/
236966238844
struct Fts5Iter {
236967238845
Fts5IndexIter base; /* Base class containing output vars */
238846
+ Fts5TokenDataIter *pTokenDataIter;
236968238847
236969238848
Fts5Index *pIndex; /* Index that owns this iterator */
236970238849
Fts5Buffer poslist; /* Buffer containing current poslist */
236971238850
Fts5Colset *pColset; /* Restrict matches to these columns */
236972238851
@@ -236979,11 +238858,10 @@
236979238858
236980238859
i64 iSwitchRowid; /* Firstest rowid of other than aFirst[1] */
236981238860
Fts5CResult *aFirst; /* Current merge state (see above) */
236982238861
Fts5SegIter aSeg[1]; /* Array of segment iterators */
236983238862
};
236984
-
236985238863
236986238864
/*
236987238865
** An instance of the following type is used to iterate through the contents
236988238866
** of a doclist-index record.
236989238867
**
@@ -238279,22 +240157,24 @@
238279240157
pIter->xNext = fts5SegIterNext;
238280240158
}
238281240159
}
238282240160
238283240161
/*
238284
-** Allocate a tombstone hash page array (pIter->apTombstone) for the
238285
-** iterator passed as the second argument. If an OOM error occurs, leave
238286
-** an error in the Fts5Index object.
240162
+** Allocate a tombstone hash page array object (pIter->pTombArray) for
240163
+** the iterator passed as the second argument. If an OOM error occurs,
240164
+** leave an error in the Fts5Index object.
238287240165
*/
238288240166
static void fts5SegIterAllocTombstone(Fts5Index *p, Fts5SegIter *pIter){
238289240167
const int nTomb = pIter->pSeg->nPgTombstone;
238290240168
if( nTomb>0 ){
238291
- Fts5Data **apTomb = 0;
238292
- apTomb = (Fts5Data**)sqlite3Fts5MallocZero(&p->rc, sizeof(Fts5Data)*nTomb);
238293
- if( apTomb ){
238294
- pIter->apTombstone = apTomb;
238295
- pIter->nTombstone = nTomb;
240169
+ int nByte = nTomb * sizeof(Fts5Data*) + sizeof(Fts5TombstoneArray);
240170
+ Fts5TombstoneArray *pNew;
240171
+ pNew = (Fts5TombstoneArray*)sqlite3Fts5MallocZero(&p->rc, nByte);
240172
+ if( pNew ){
240173
+ pNew->nTombstone = nTomb;
240174
+ pNew->nRef = 1;
240175
+ pIter->pTombArray = pNew;
238296240176
}
238297240177
}
238298240178
}
238299240179
238300240180
/*
@@ -238547,19 +240427,20 @@
238547240427
pIter->iLeafOffset = iOff;
238548240428
fts5SegIterLoadTerm(p, pIter, nKeep);
238549240429
}else{
238550240430
const u8 *pList = 0;
238551240431
const char *zTerm = 0;
240432
+ int nTerm = 0;
238552240433
int nList;
238553240434
sqlite3Fts5HashScanNext(p->pHash);
238554
- sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &pList, &nList);
240435
+ sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &nTerm, &pList, &nList);
238555240436
if( pList==0 ) goto next_none_eof;
238556240437
pIter->pLeaf->p = (u8*)pList;
238557240438
pIter->pLeaf->nn = nList;
238558240439
pIter->pLeaf->szLeaf = nList;
238559240440
pIter->iEndofDoclist = nList;
238560
- sqlite3Fts5BufferSet(&p->rc,&pIter->term, (int)strlen(zTerm), (u8*)zTerm);
240441
+ sqlite3Fts5BufferSet(&p->rc,&pIter->term, nTerm, (u8*)zTerm);
238561240442
pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid);
238562240443
}
238563240444
238564240445
if( pbNewTerm ) *pbNewTerm = 1;
238565240446
}else{
@@ -238621,26 +240502,26 @@
238621240502
pIter->iLeafOffset = iOff;
238622240503
238623240504
}else if( pIter->pSeg==0 ){
238624240505
const u8 *pList = 0;
238625240506
const char *zTerm = 0;
240507
+ int nTerm = 0;
238626240508
int nList = 0;
238627240509
assert( (pIter->flags & FTS5_SEGITER_ONETERM) || pbNewTerm );
238628240510
if( 0==(pIter->flags & FTS5_SEGITER_ONETERM) ){
238629240511
sqlite3Fts5HashScanNext(p->pHash);
238630
- sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &pList, &nList);
240512
+ sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &nTerm, &pList, &nList);
238631240513
}
238632240514
if( pList==0 ){
238633240515
fts5DataRelease(pIter->pLeaf);
238634240516
pIter->pLeaf = 0;
238635240517
}else{
238636240518
pIter->pLeaf->p = (u8*)pList;
238637240519
pIter->pLeaf->nn = nList;
238638240520
pIter->pLeaf->szLeaf = nList;
238639240521
pIter->iEndofDoclist = nList+1;
238640
- sqlite3Fts5BufferSet(&p->rc, &pIter->term, (int)strlen(zTerm),
238641
- (u8*)zTerm);
240522
+ sqlite3Fts5BufferSet(&p->rc, &pIter->term, nTerm, (u8*)zTerm);
238642240523
pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid);
238643240524
*pbNewTerm = 1;
238644240525
}
238645240526
}else{
238646240527
iOff = 0;
@@ -239022,11 +240903,11 @@
239022240903
239023240904
if( pIter->pLeaf ){
239024240905
fts5LeafSeek(p, bGe, pIter, pTerm, nTerm);
239025240906
}
239026240907
239027
- if( p->rc==SQLITE_OK && bGe==0 ){
240908
+ if( p->rc==SQLITE_OK && (bGe==0 || (flags & FTS5INDEX_QUERY_SCANONETERM)) ){
239028240909
pIter->flags |= FTS5_SEGITER_ONETERM;
239029240910
if( pIter->pLeaf ){
239030240911
if( flags & FTS5INDEX_QUERY_DESC ){
239031240912
pIter->flags |= FTS5_SEGITER_REVERSE;
239032240913
}
@@ -239038,11 +240919,13 @@
239038240919
}
239039240920
}
239040240921
}
239041240922
239042240923
fts5SegIterSetNext(p, pIter);
239043
- fts5SegIterAllocTombstone(p, pIter);
240924
+ if( 0==(flags & FTS5INDEX_QUERY_SCANONETERM) ){
240925
+ fts5SegIterAllocTombstone(p, pIter);
240926
+ }
239044240927
239045240928
/* Either:
239046240929
**
239047240930
** 1) an error has occurred, or
239048240931
** 2) the iterator points to EOF, or
@@ -239055,10 +240938,83 @@
239055240938
|| fts5BufferCompareBlob(&pIter->term, pTerm, nTerm)==0 /* 3 */
239056240939
|| (bGe && fts5BufferCompareBlob(&pIter->term, pTerm, nTerm)>0) /* 4 */
239057240940
);
239058240941
}
239059240942
240943
+
240944
+/*
240945
+** SQL used by fts5SegIterNextInit() to find the page to open.
240946
+*/
240947
+static sqlite3_stmt *fts5IdxNextStmt(Fts5Index *p){
240948
+ if( p->pIdxNextSelect==0 ){
240949
+ Fts5Config *pConfig = p->pConfig;
240950
+ fts5IndexPrepareStmt(p, &p->pIdxNextSelect, sqlite3_mprintf(
240951
+ "SELECT pgno FROM '%q'.'%q_idx' WHERE "
240952
+ "segid=? AND term>? ORDER BY term ASC LIMIT 1",
240953
+ pConfig->zDb, pConfig->zName
240954
+ ));
240955
+
240956
+ }
240957
+ return p->pIdxNextSelect;
240958
+}
240959
+
240960
+/*
240961
+** This is similar to fts5SegIterSeekInit(), except that it initializes
240962
+** the segment iterator to point to the first term following the page
240963
+** with pToken/nToken on it.
240964
+*/
240965
+static void fts5SegIterNextInit(
240966
+ Fts5Index *p,
240967
+ const char *pTerm, int nTerm,
240968
+ Fts5StructureSegment *pSeg, /* Description of segment */
240969
+ Fts5SegIter *pIter /* Object to populate */
240970
+){
240971
+ int iPg = -1; /* Page of segment to open */
240972
+ int bDlidx = 0;
240973
+ sqlite3_stmt *pSel = 0; /* SELECT to find iPg */
240974
+
240975
+ pSel = fts5IdxNextStmt(p);
240976
+ if( pSel ){
240977
+ assert( p->rc==SQLITE_OK );
240978
+ sqlite3_bind_int(pSel, 1, pSeg->iSegid);
240979
+ sqlite3_bind_blob(pSel, 2, pTerm, nTerm, SQLITE_STATIC);
240980
+
240981
+ if( sqlite3_step(pSel)==SQLITE_ROW ){
240982
+ i64 val = sqlite3_column_int64(pSel, 0);
240983
+ iPg = (int)(val>>1);
240984
+ bDlidx = (val & 0x0001);
240985
+ }
240986
+ p->rc = sqlite3_reset(pSel);
240987
+ sqlite3_bind_null(pSel, 2);
240988
+ if( p->rc ) return;
240989
+ }
240990
+
240991
+ memset(pIter, 0, sizeof(*pIter));
240992
+ pIter->pSeg = pSeg;
240993
+ pIter->flags |= FTS5_SEGITER_ONETERM;
240994
+ if( iPg>=0 ){
240995
+ pIter->iLeafPgno = iPg - 1;
240996
+ fts5SegIterNextPage(p, pIter);
240997
+ fts5SegIterSetNext(p, pIter);
240998
+ }
240999
+ if( pIter->pLeaf ){
241000
+ const u8 *a = pIter->pLeaf->p;
241001
+ int iTermOff = 0;
241002
+
241003
+ pIter->iPgidxOff = pIter->pLeaf->szLeaf;
241004
+ pIter->iPgidxOff += fts5GetVarint32(&a[pIter->iPgidxOff], iTermOff);
241005
+ pIter->iLeafOffset = iTermOff;
241006
+ fts5SegIterLoadTerm(p, pIter, 0);
241007
+ fts5SegIterLoadNPos(p, pIter);
241008
+ if( bDlidx ) fts5SegIterLoadDlidx(p, pIter);
241009
+
241010
+ assert( p->rc!=SQLITE_OK ||
241011
+ fts5BufferCompareBlob(&pIter->term, (const u8*)pTerm, nTerm)>0
241012
+ );
241013
+ }
241014
+}
241015
+
239060241016
/*
239061241017
** Initialize the object pIter to point to term pTerm/nTerm within the
239062241018
** in-memory hash table. If there is no such term in the hash-table, the
239063241019
** iterator is set to EOF.
239064241020
**
@@ -239081,12 +241037,11 @@
239081241037
239082241038
if( pTerm==0 || (flags & FTS5INDEX_QUERY_SCAN) ){
239083241039
const u8 *pList = 0;
239084241040
239085241041
p->rc = sqlite3Fts5HashScanInit(p->pHash, (const char*)pTerm, nTerm);
239086
- sqlite3Fts5HashScanEntry(p->pHash, (const char**)&z, &pList, &nList);
239087
- n = (z ? (int)strlen((const char*)z) : 0);
241042
+ sqlite3Fts5HashScanEntry(p->pHash, (const char**)&z, &n, &pList, &nList);
239088241043
if( pList ){
239089241044
pLeaf = fts5IdxMalloc(p, sizeof(Fts5Data));
239090241045
if( pLeaf ){
239091241046
pLeaf->p = (u8*)pList;
239092241047
}
@@ -239140,19 +241095,36 @@
239140241095
fts5DataRelease(ap[ii]);
239141241096
}
239142241097
sqlite3_free(ap);
239143241098
}
239144241099
}
241100
+
241101
+/*
241102
+** Decrement the ref-count of the object passed as the only argument. If it
241103
+** reaches 0, free it and its contents.
241104
+*/
241105
+static void fts5TombstoneArrayDelete(Fts5TombstoneArray *p){
241106
+ if( p ){
241107
+ p->nRef--;
241108
+ if( p->nRef<=0 ){
241109
+ int ii;
241110
+ for(ii=0; ii<p->nTombstone; ii++){
241111
+ fts5DataRelease(p->apTombstone[ii]);
241112
+ }
241113
+ sqlite3_free(p);
241114
+ }
241115
+ }
241116
+}
239145241117
239146241118
/*
239147241119
** Zero the iterator passed as the only argument.
239148241120
*/
239149241121
static void fts5SegIterClear(Fts5SegIter *pIter){
239150241122
fts5BufferFree(&pIter->term);
239151241123
fts5DataRelease(pIter->pLeaf);
239152241124
fts5DataRelease(pIter->pNextLeaf);
239153
- fts5IndexFreeArray(pIter->apTombstone, pIter->nTombstone);
241125
+ fts5TombstoneArrayDelete(pIter->pTombArray);
239154241126
fts5DlidxIterFree(pIter->pDlidx);
239155241127
sqlite3_free(pIter->aRowidOffset);
239156241128
memset(pIter, 0, sizeof(Fts5SegIter));
239157241129
}
239158241130
@@ -239393,11 +241365,10 @@
239393241365
if( bRev!=0 && pIter->iRowid<=iMatch ) break;
239394241366
bMove = 1;
239395241367
}while( p->rc==SQLITE_OK );
239396241368
}
239397241369
239398
-
239399241370
/*
239400241371
** Free the iterator object passed as the second argument.
239401241372
*/
239402241373
static void fts5MultiIterFree(Fts5Iter *pIter){
239403241374
if( pIter ){
@@ -239538,28 +241509,29 @@
239538241509
** if there is no tombstone or if the iterator is already at EOF.
239539241510
*/
239540241511
static int fts5MultiIterIsDeleted(Fts5Iter *pIter){
239541241512
int iFirst = pIter->aFirst[1].iFirst;
239542241513
Fts5SegIter *pSeg = &pIter->aSeg[iFirst];
241514
+ Fts5TombstoneArray *pArray = pSeg->pTombArray;
239543241515
239544
- if( pSeg->pLeaf && pSeg->nTombstone ){
241516
+ if( pSeg->pLeaf && pArray ){
239545241517
/* Figure out which page the rowid might be present on. */
239546
- int iPg = ((u64)pSeg->iRowid) % pSeg->nTombstone;
241518
+ int iPg = ((u64)pSeg->iRowid) % pArray->nTombstone;
239547241519
assert( iPg>=0 );
239548241520
239549241521
/* If tombstone hash page iPg has not yet been loaded from the
239550241522
** database, load it now. */
239551
- if( pSeg->apTombstone[iPg]==0 ){
239552
- pSeg->apTombstone[iPg] = fts5DataRead(pIter->pIndex,
241523
+ if( pArray->apTombstone[iPg]==0 ){
241524
+ pArray->apTombstone[iPg] = fts5DataRead(pIter->pIndex,
239553241525
FTS5_TOMBSTONE_ROWID(pSeg->pSeg->iSegid, iPg)
239554241526
);
239555
- if( pSeg->apTombstone[iPg]==0 ) return 0;
241527
+ if( pArray->apTombstone[iPg]==0 ) return 0;
239556241528
}
239557241529
239558241530
return fts5IndexTombstoneQuery(
239559
- pSeg->apTombstone[iPg],
239560
- pSeg->nTombstone,
241531
+ pArray->apTombstone[iPg],
241532
+ pArray->nTombstone,
239561241533
pSeg->iRowid
239562241534
);
239563241535
}
239564241536
239565241537
return 0;
@@ -240094,10 +242066,36 @@
240094242066
}
240095242067
}
240096242068
}
240097242069
}
240098242070
242071
+/*
242072
+** All the component segment-iterators of pIter have been set up. This
242073
+** functions finishes setup for iterator pIter itself.
242074
+*/
242075
+static void fts5MultiIterFinishSetup(Fts5Index *p, Fts5Iter *pIter){
242076
+ int iIter;
242077
+ for(iIter=pIter->nSeg-1; iIter>0; iIter--){
242078
+ int iEq;
242079
+ if( (iEq = fts5MultiIterDoCompare(pIter, iIter)) ){
242080
+ Fts5SegIter *pSeg = &pIter->aSeg[iEq];
242081
+ if( p->rc==SQLITE_OK ) pSeg->xNext(p, pSeg, 0);
242082
+ fts5MultiIterAdvanced(p, pIter, iEq, iIter);
242083
+ }
242084
+ }
242085
+ fts5MultiIterSetEof(pIter);
242086
+ fts5AssertMultiIterSetup(p, pIter);
242087
+
242088
+ if( (pIter->bSkipEmpty && fts5MultiIterIsEmpty(p, pIter))
242089
+ || fts5MultiIterIsDeleted(pIter)
242090
+ ){
242091
+ fts5MultiIterNext(p, pIter, 0, 0);
242092
+ }else if( pIter->base.bEof==0 ){
242093
+ Fts5SegIter *pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst];
242094
+ pIter->xSetOutputs(pIter, pSeg);
242095
+ }
242096
+}
240099242097
240100242098
/*
240101242099
** Allocate a new Fts5Iter object.
240102242100
**
240103242101
** The new object will be used to iterate through data in structure pStruct.
@@ -240175,35 +242173,16 @@
240175242173
}
240176242174
}
240177242175
assert( iIter==nSeg );
240178242176
}
240179242177
240180
- /* If the above was successful, each component iterators now points
242178
+ /* If the above was successful, each component iterator now points
240181242179
** to the first entry in its segment. In this case initialize the
240182242180
** aFirst[] array. Or, if an error has occurred, free the iterator
240183242181
** object and set the output variable to NULL. */
240184242182
if( p->rc==SQLITE_OK ){
240185
- for(iIter=pNew->nSeg-1; iIter>0; iIter--){
240186
- int iEq;
240187
- if( (iEq = fts5MultiIterDoCompare(pNew, iIter)) ){
240188
- Fts5SegIter *pSeg = &pNew->aSeg[iEq];
240189
- if( p->rc==SQLITE_OK ) pSeg->xNext(p, pSeg, 0);
240190
- fts5MultiIterAdvanced(p, pNew, iEq, iIter);
240191
- }
240192
- }
240193
- fts5MultiIterSetEof(pNew);
240194
- fts5AssertMultiIterSetup(p, pNew);
240195
-
240196
- if( (pNew->bSkipEmpty && fts5MultiIterIsEmpty(p, pNew))
240197
- || fts5MultiIterIsDeleted(pNew)
240198
- ){
240199
- fts5MultiIterNext(p, pNew, 0, 0);
240200
- }else if( pNew->base.bEof==0 ){
240201
- Fts5SegIter *pSeg = &pNew->aSeg[pNew->aFirst[1].iFirst];
240202
- pNew->xSetOutputs(pNew, pSeg);
240203
- }
240204
-
242183
+ fts5MultiIterFinishSetup(p, pNew);
240205242184
}else{
240206242185
fts5MultiIterFree(pNew);
240207242186
*ppOut = 0;
240208242187
}
240209242188
@@ -240224,11 +242203,10 @@
240224242203
){
240225242204
Fts5Iter *pNew;
240226242205
pNew = fts5MultiIterAlloc(p, 2);
240227242206
if( pNew ){
240228242207
Fts5SegIter *pIter = &pNew->aSeg[1];
240229
-
240230242208
pIter->flags = FTS5_SEGITER_ONETERM;
240231242209
if( pData->szLeaf>0 ){
240232242210
pIter->pLeaf = pData;
240233242211
pIter->iLeafOffset = fts5GetVarint(pData->p, (u64*)&pIter->iRowid);
240234242212
pIter->iEndofDoclist = pData->nn;
@@ -240372,10 +242350,11 @@
240372242350
assert( p->pHash || p->nPendingData==0 );
240373242351
if( p->pHash ){
240374242352
sqlite3Fts5HashClear(p->pHash);
240375242353
p->nPendingData = 0;
240376242354
p->nPendingRow = 0;
242355
+ p->flushRc = SQLITE_OK;
240377242356
}
240378242357
p->nContentlessDelete = 0;
240379242358
}
240380242359
240381242360
/*
@@ -240587,11 +242566,11 @@
240587242566
}else{
240588242567
bDone = 1;
240589242568
}
240590242569
240591242570
if( pDlidx->bPrevValid ){
240592
- iVal = iRowid - pDlidx->iPrev;
242571
+ iVal = (u64)iRowid - (u64)pDlidx->iPrev;
240593242572
}else{
240594242573
i64 iPgno = (i==0 ? pWriter->writer.pgno : pDlidx[-1].pgno);
240595242574
assert( pDlidx->buf.n==0 );
240596242575
sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, !bDone);
240597242576
sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, iPgno);
@@ -241710,14 +243689,14 @@
241710243689
*/
241711243690
static void fts5FlushSecureDelete(
241712243691
Fts5Index *p,
241713243692
Fts5Structure *pStruct,
241714243693
const char *zTerm,
243694
+ int nTerm,
241715243695
i64 iRowid
241716243696
){
241717243697
const int f = FTS5INDEX_QUERY_SKIPHASH;
241718
- int nTerm = (int)strlen(zTerm);
241719243698
Fts5Iter *pIter = 0; /* Used to find term instance */
241720243699
241721243700
fts5MultiIterNew(p, pStruct, f, 0, (const u8*)zTerm, nTerm, -1, 0, &pIter);
241722243701
if( fts5MultiIterEof(p, pIter)==0 ){
241723243702
i64 iThis = fts5MultiIterRowid(pIter);
@@ -241787,12 +243766,11 @@
241787243766
int nTerm; /* Size of zTerm in bytes */
241788243767
const u8 *pDoclist; /* Pointer to doclist for this term */
241789243768
int nDoclist; /* Size of doclist in bytes */
241790243769
241791243770
/* Get the term and doclist for this entry. */
241792
- sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist);
241793
- nTerm = (int)strlen(zTerm);
243771
+ sqlite3Fts5HashScanEntry(pHash, &zTerm, &nTerm, &pDoclist, &nDoclist);
241794243772
if( bSecureDelete==0 ){
241795243773
fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm);
241796243774
if( p->rc!=SQLITE_OK ) break;
241797243775
assert( writer.bFirstRowidInPage==0 );
241798243776
}
@@ -241818,21 +243796,21 @@
241818243796
** in fact a delete, then edit the existing segments directly
241819243797
** using fts5FlushSecureDelete(). */
241820243798
if( bSecureDelete ){
241821243799
if( eDetail==FTS5_DETAIL_NONE ){
241822243800
if( iOff<nDoclist && pDoclist[iOff]==0x00 ){
241823
- fts5FlushSecureDelete(p, pStruct, zTerm, iRowid);
243801
+ fts5FlushSecureDelete(p, pStruct, zTerm, nTerm, iRowid);
241824243802
iOff++;
241825243803
if( iOff<nDoclist && pDoclist[iOff]==0x00 ){
241826243804
iOff++;
241827243805
nDoclist = 0;
241828243806
}else{
241829243807
continue;
241830243808
}
241831243809
}
241832243810
}else if( (pDoclist[iOff] & 0x01) ){
241833
- fts5FlushSecureDelete(p, pStruct, zTerm, iRowid);
243811
+ fts5FlushSecureDelete(p, pStruct, zTerm, nTerm, iRowid);
241834243812
if( p->rc!=SQLITE_OK || pDoclist[iOff]==0x01 ){
241835243813
iOff++;
241836243814
continue;
241837243815
}
241838243816
}
@@ -241954,18 +243932,24 @@
241954243932
/*
241955243933
** Flush any data stored in the in-memory hash tables to the database.
241956243934
*/
241957243935
static void fts5IndexFlush(Fts5Index *p){
241958243936
/* Unless it is empty, flush the hash table to disk */
243937
+ if( p->flushRc ){
243938
+ p->rc = p->flushRc;
243939
+ return;
243940
+ }
241959243941
if( p->nPendingData || p->nContentlessDelete ){
241960243942
assert( p->pHash );
241961243943
fts5FlushOneHash(p);
241962243944
if( p->rc==SQLITE_OK ){
241963243945
sqlite3Fts5HashClear(p->pHash);
241964243946
p->nPendingData = 0;
241965243947
p->nPendingRow = 0;
241966243948
p->nContentlessDelete = 0;
243949
+ }else if( p->nPendingData || p->nContentlessDelete ){
243950
+ p->flushRc = p->rc;
241967243951
}
241968243952
}
241969243953
}
241970243954
241971243955
static Fts5Structure *fts5IndexOptimizeStruct(
@@ -242448,11 +244432,11 @@
242448244432
int bDesc, /* True for "ORDER BY rowid DESC" */
242449244433
int iIdx, /* Index to scan for data */
242450244434
u8 *pToken, /* Buffer containing prefix to match */
242451244435
int nToken, /* Size of buffer pToken in bytes */
242452244436
Fts5Colset *pColset, /* Restrict matches to these columns */
242453
- Fts5Iter **ppIter /* OUT: New iterator */
244437
+ Fts5Iter **ppIter /* OUT: New iterator */
242454244438
){
242455244439
Fts5Structure *pStruct;
242456244440
Fts5Buffer *aBuf;
242457244441
int nBuf = 32;
242458244442
int nMerge = 1;
@@ -242469,12 +244453,13 @@
242469244453
xAppend = fts5AppendPoslist;
242470244454
}
242471244455
242472244456
aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*nBuf);
242473244457
pStruct = fts5StructureRead(p);
244458
+ assert( p->rc!=SQLITE_OK || (aBuf && pStruct) );
242474244459
242475
- if( aBuf && pStruct ){
244460
+ if( p->rc==SQLITE_OK ){
242476244461
const int flags = FTS5INDEX_QUERY_SCAN
242477244462
| FTS5INDEX_QUERY_SKIPEMPTY
242478244463
| FTS5INDEX_QUERY_NOOUTPUT;
242479244464
int i;
242480244465
i64 iLastRowid = 0;
@@ -242482,10 +244467,16 @@
242482244467
Fts5Data *pData;
242483244468
Fts5Buffer doclist;
242484244469
int bNewTerm = 1;
242485244470
242486244471
memset(&doclist, 0, sizeof(doclist));
244472
+
244473
+ /* If iIdx is non-zero, then it is the number of a prefix-index for
244474
+ ** prefixes 1 character longer than the prefix being queried for. That
244475
+ ** index contains all the doclists required, except for the one
244476
+ ** corresponding to the prefix itself. That one is extracted from the
244477
+ ** main term index here. */
242487244478
if( iIdx!=0 ){
242488244479
int dummy = 0;
242489244480
const int f2 = FTS5INDEX_QUERY_SKIPEMPTY|FTS5INDEX_QUERY_NOOUTPUT;
242490244481
pToken[0] = FTS5_MAIN_PREFIX;
242491244482
fts5MultiIterNew(p, pStruct, f2, pColset, pToken, nToken, -1, 0, &p1);
@@ -242505,10 +244496,11 @@
242505244496
}
242506244497
242507244498
pToken[0] = FTS5_MAIN_PREFIX + iIdx;
242508244499
fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1);
242509244500
fts5IterSetOutputCb(&p->rc, p1);
244501
+
242510244502
for( /* no-op */ ;
242511244503
fts5MultiIterEof(p, p1)==0;
242512244504
fts5MultiIterNext2(p, p1, &bNewTerm)
242513244505
){
242514244506
Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ];
@@ -242520,11 +244512,10 @@
242520244512
if( bNewTerm ){
242521244513
if( nTerm<nToken || memcmp(pToken, pTerm, nToken) ) break;
242522244514
}
242523244515
242524244516
if( p1->base.nData==0 ) continue;
242525
-
242526244517
if( p1->base.iRowid<=iLastRowid && doclist.n>0 ){
242527244518
for(i=0; p->rc==SQLITE_OK && doclist.n; i++){
242528244519
int i1 = i*nMerge;
242529244520
int iStore;
242530244521
assert( i1+nMerge<=nBuf );
@@ -242559,11 +244550,11 @@
242559244550
fts5BufferFree(&aBuf[iFree]);
242560244551
}
242561244552
}
242562244553
fts5MultiIterFree(p1);
242563244554
242564
- pData = fts5IdxMalloc(p, sizeof(Fts5Data)+doclist.n+FTS5_DATA_ZERO_PADDING);
244555
+ pData = fts5IdxMalloc(p, sizeof(*pData)+doclist.n+FTS5_DATA_ZERO_PADDING);
242565244556
if( pData ){
242566244557
pData->p = (u8*)&pData[1];
242567244558
pData->nn = pData->szLeaf = doclist.n;
242568244559
if( doclist.n ) memcpy(pData->p, doclist.p, doclist.n);
242569244560
fts5MultiIterNew2(p, pData, bDesc, ppIter);
@@ -242702,10 +244693,11 @@
242702244693
sqlite3_finalize(p->pWriter);
242703244694
sqlite3_finalize(p->pDeleter);
242704244695
sqlite3_finalize(p->pIdxWriter);
242705244696
sqlite3_finalize(p->pIdxDeleter);
242706244697
sqlite3_finalize(p->pIdxSelect);
244698
+ sqlite3_finalize(p->pIdxNextSelect);
242707244699
sqlite3_finalize(p->pDataVersion);
242708244700
sqlite3_finalize(p->pDeleteFromIdx);
242709244701
sqlite3Fts5HashFree(p->pHash);
242710244702
sqlite3_free(p->zDataTbl);
242711244703
sqlite3_free(p);
@@ -242796,10 +244788,458 @@
242796244788
}
242797244789
}
242798244790
242799244791
return rc;
242800244792
}
244793
+
244794
+/*
244795
+** pToken points to a buffer of size nToken bytes containing a search
244796
+** term, including the index number at the start, used on a tokendata=1
244797
+** table. This function returns true if the term in buffer pBuf matches
244798
+** token pToken/nToken.
244799
+*/
244800
+static int fts5IsTokendataPrefix(
244801
+ Fts5Buffer *pBuf,
244802
+ const u8 *pToken,
244803
+ int nToken
244804
+){
244805
+ return (
244806
+ pBuf->n>=nToken
244807
+ && 0==memcmp(pBuf->p, pToken, nToken)
244808
+ && (pBuf->n==nToken || pBuf->p[nToken]==0x00)
244809
+ );
244810
+}
244811
+
244812
+/*
244813
+** Ensure the segment-iterator passed as the only argument points to EOF.
244814
+*/
244815
+static void fts5SegIterSetEOF(Fts5SegIter *pSeg){
244816
+ fts5DataRelease(pSeg->pLeaf);
244817
+ pSeg->pLeaf = 0;
244818
+}
244819
+
244820
+/*
244821
+** Usually, a tokendata=1 iterator (struct Fts5TokenDataIter) accumulates an
244822
+** array of these for each row it visits. Or, for an iterator used by an
244823
+** "ORDER BY rank" query, it accumulates an array of these for the entire
244824
+** query.
244825
+**
244826
+** Each instance in the array indicates the iterator (and therefore term)
244827
+** associated with position iPos of rowid iRowid. This is used by the
244828
+** xInstToken() API.
244829
+*/
244830
+struct Fts5TokenDataMap {
244831
+ i64 iRowid; /* Row this token is located in */
244832
+ i64 iPos; /* Position of token */
244833
+ int iIter; /* Iterator token was read from */
244834
+};
244835
+
244836
+/*
244837
+** An object used to supplement Fts5Iter for tokendata=1 iterators.
244838
+*/
244839
+struct Fts5TokenDataIter {
244840
+ int nIter;
244841
+ int nIterAlloc;
244842
+
244843
+ int nMap;
244844
+ int nMapAlloc;
244845
+ Fts5TokenDataMap *aMap;
244846
+
244847
+ Fts5PoslistReader *aPoslistReader;
244848
+ int *aPoslistToIter;
244849
+ Fts5Iter *apIter[1];
244850
+};
244851
+
244852
+/*
244853
+** This function appends iterator pAppend to Fts5TokenDataIter pIn and
244854
+** returns the result.
244855
+*/
244856
+static Fts5TokenDataIter *fts5AppendTokendataIter(
244857
+ Fts5Index *p, /* Index object (for error code) */
244858
+ Fts5TokenDataIter *pIn, /* Current Fts5TokenDataIter struct */
244859
+ Fts5Iter *pAppend /* Append this iterator */
244860
+){
244861
+ Fts5TokenDataIter *pRet = pIn;
244862
+
244863
+ if( p->rc==SQLITE_OK ){
244864
+ if( pIn==0 || pIn->nIter==pIn->nIterAlloc ){
244865
+ int nAlloc = pIn ? pIn->nIterAlloc*2 : 16;
244866
+ int nByte = nAlloc * sizeof(Fts5Iter*) + sizeof(Fts5TokenDataIter);
244867
+ Fts5TokenDataIter *pNew = (Fts5TokenDataIter*)sqlite3_realloc(pIn, nByte);
244868
+
244869
+ if( pNew==0 ){
244870
+ p->rc = SQLITE_NOMEM;
244871
+ }else{
244872
+ if( pIn==0 ) memset(pNew, 0, nByte);
244873
+ pRet = pNew;
244874
+ pNew->nIterAlloc = nAlloc;
244875
+ }
244876
+ }
244877
+ }
244878
+ if( p->rc ){
244879
+ sqlite3Fts5IterClose((Fts5IndexIter*)pAppend);
244880
+ }else{
244881
+ pRet->apIter[pRet->nIter++] = pAppend;
244882
+ }
244883
+ assert( pRet==0 || pRet->nIter<=pRet->nIterAlloc );
244884
+
244885
+ return pRet;
244886
+}
244887
+
244888
+/*
244889
+** Delete an Fts5TokenDataIter structure and its contents.
244890
+*/
244891
+static void fts5TokendataIterDelete(Fts5TokenDataIter *pSet){
244892
+ if( pSet ){
244893
+ int ii;
244894
+ for(ii=0; ii<pSet->nIter; ii++){
244895
+ fts5MultiIterFree(pSet->apIter[ii]);
244896
+ }
244897
+ sqlite3_free(pSet->aPoslistReader);
244898
+ sqlite3_free(pSet->aMap);
244899
+ sqlite3_free(pSet);
244900
+ }
244901
+}
244902
+
244903
+/*
244904
+** Append a mapping to the token-map belonging to object pT.
244905
+*/
244906
+static void fts5TokendataIterAppendMap(
244907
+ Fts5Index *p,
244908
+ Fts5TokenDataIter *pT,
244909
+ int iIter,
244910
+ i64 iRowid,
244911
+ i64 iPos
244912
+){
244913
+ if( p->rc==SQLITE_OK ){
244914
+ if( pT->nMap==pT->nMapAlloc ){
244915
+ int nNew = pT->nMapAlloc ? pT->nMapAlloc*2 : 64;
244916
+ int nByte = nNew * sizeof(Fts5TokenDataMap);
244917
+ Fts5TokenDataMap *aNew;
244918
+
244919
+ aNew = (Fts5TokenDataMap*)sqlite3_realloc(pT->aMap, nByte);
244920
+ if( aNew==0 ){
244921
+ p->rc = SQLITE_NOMEM;
244922
+ return;
244923
+ }
244924
+
244925
+ pT->aMap = aNew;
244926
+ pT->nMapAlloc = nNew;
244927
+ }
244928
+
244929
+ pT->aMap[pT->nMap].iRowid = iRowid;
244930
+ pT->aMap[pT->nMap].iPos = iPos;
244931
+ pT->aMap[pT->nMap].iIter = iIter;
244932
+ pT->nMap++;
244933
+ }
244934
+}
244935
+
244936
+/*
244937
+** The iterator passed as the only argument must be a tokendata=1 iterator
244938
+** (pIter->pTokenDataIter!=0). This function sets the iterator output
244939
+** variables (pIter->base.*) according to the contents of the current
244940
+** row.
244941
+*/
244942
+static void fts5IterSetOutputsTokendata(Fts5Iter *pIter){
244943
+ int ii;
244944
+ int nHit = 0;
244945
+ i64 iRowid = SMALLEST_INT64;
244946
+ int iMin = 0;
244947
+
244948
+ Fts5TokenDataIter *pT = pIter->pTokenDataIter;
244949
+
244950
+ pIter->base.nData = 0;
244951
+ pIter->base.pData = 0;
244952
+
244953
+ for(ii=0; ii<pT->nIter; ii++){
244954
+ Fts5Iter *p = pT->apIter[ii];
244955
+ if( p->base.bEof==0 ){
244956
+ if( nHit==0 || p->base.iRowid<iRowid ){
244957
+ iRowid = p->base.iRowid;
244958
+ nHit = 1;
244959
+ pIter->base.pData = p->base.pData;
244960
+ pIter->base.nData = p->base.nData;
244961
+ iMin = ii;
244962
+ }else if( p->base.iRowid==iRowid ){
244963
+ nHit++;
244964
+ }
244965
+ }
244966
+ }
244967
+
244968
+ if( nHit==0 ){
244969
+ pIter->base.bEof = 1;
244970
+ }else{
244971
+ int eDetail = pIter->pIndex->pConfig->eDetail;
244972
+ pIter->base.bEof = 0;
244973
+ pIter->base.iRowid = iRowid;
244974
+
244975
+ if( nHit==1 && eDetail==FTS5_DETAIL_FULL ){
244976
+ fts5TokendataIterAppendMap(pIter->pIndex, pT, iMin, iRowid, -1);
244977
+ }else
244978
+ if( nHit>1 && eDetail!=FTS5_DETAIL_NONE ){
244979
+ int nReader = 0;
244980
+ int nByte = 0;
244981
+ i64 iPrev = 0;
244982
+
244983
+ /* Allocate array of iterators if they are not already allocated. */
244984
+ if( pT->aPoslistReader==0 ){
244985
+ pT->aPoslistReader = (Fts5PoslistReader*)sqlite3Fts5MallocZero(
244986
+ &pIter->pIndex->rc,
244987
+ pT->nIter * (sizeof(Fts5PoslistReader) + sizeof(int))
244988
+ );
244989
+ if( pT->aPoslistReader==0 ) return;
244990
+ pT->aPoslistToIter = (int*)&pT->aPoslistReader[pT->nIter];
244991
+ }
244992
+
244993
+ /* Populate an iterator for each poslist that will be merged */
244994
+ for(ii=0; ii<pT->nIter; ii++){
244995
+ Fts5Iter *p = pT->apIter[ii];
244996
+ if( iRowid==p->base.iRowid ){
244997
+ pT->aPoslistToIter[nReader] = ii;
244998
+ sqlite3Fts5PoslistReaderInit(
244999
+ p->base.pData, p->base.nData, &pT->aPoslistReader[nReader++]
245000
+ );
245001
+ nByte += p->base.nData;
245002
+ }
245003
+ }
245004
+
245005
+ /* Ensure the output buffer is large enough */
245006
+ if( fts5BufferGrow(&pIter->pIndex->rc, &pIter->poslist, nByte+nHit*10) ){
245007
+ return;
245008
+ }
245009
+
245010
+ /* Ensure the token-mapping is large enough */
245011
+ if( eDetail==FTS5_DETAIL_FULL && pT->nMapAlloc<(pT->nMap + nByte) ){
245012
+ int nNew = (pT->nMapAlloc + nByte) * 2;
245013
+ Fts5TokenDataMap *aNew = (Fts5TokenDataMap*)sqlite3_realloc(
245014
+ pT->aMap, nNew*sizeof(Fts5TokenDataMap)
245015
+ );
245016
+ if( aNew==0 ){
245017
+ pIter->pIndex->rc = SQLITE_NOMEM;
245018
+ return;
245019
+ }
245020
+ pT->aMap = aNew;
245021
+ pT->nMapAlloc = nNew;
245022
+ }
245023
+
245024
+ pIter->poslist.n = 0;
245025
+
245026
+ while( 1 ){
245027
+ i64 iMinPos = LARGEST_INT64;
245028
+
245029
+ /* Find smallest position */
245030
+ iMin = 0;
245031
+ for(ii=0; ii<nReader; ii++){
245032
+ Fts5PoslistReader *pReader = &pT->aPoslistReader[ii];
245033
+ if( pReader->bEof==0 ){
245034
+ if( pReader->iPos<iMinPos ){
245035
+ iMinPos = pReader->iPos;
245036
+ iMin = ii;
245037
+ }
245038
+ }
245039
+ }
245040
+
245041
+ /* If all readers were at EOF, break out of the loop. */
245042
+ if( iMinPos==LARGEST_INT64 ) break;
245043
+
245044
+ sqlite3Fts5PoslistSafeAppend(&pIter->poslist, &iPrev, iMinPos);
245045
+ sqlite3Fts5PoslistReaderNext(&pT->aPoslistReader[iMin]);
245046
+
245047
+ if( eDetail==FTS5_DETAIL_FULL ){
245048
+ pT->aMap[pT->nMap].iPos = iMinPos;
245049
+ pT->aMap[pT->nMap].iIter = pT->aPoslistToIter[iMin];
245050
+ pT->aMap[pT->nMap].iRowid = iRowid;
245051
+ pT->nMap++;
245052
+ }
245053
+ }
245054
+
245055
+ pIter->base.pData = pIter->poslist.p;
245056
+ pIter->base.nData = pIter->poslist.n;
245057
+ }
245058
+ }
245059
+}
245060
+
245061
+/*
245062
+** The iterator passed as the only argument must be a tokendata=1 iterator
245063
+** (pIter->pTokenDataIter!=0). This function advances the iterator. If
245064
+** argument bFrom is false, then the iterator is advanced to the next
245065
+** entry. Or, if bFrom is true, it is advanced to the first entry with
245066
+** a rowid of iFrom or greater.
245067
+*/
245068
+static void fts5TokendataIterNext(Fts5Iter *pIter, int bFrom, i64 iFrom){
245069
+ int ii;
245070
+ Fts5TokenDataIter *pT = pIter->pTokenDataIter;
245071
+
245072
+ for(ii=0; ii<pT->nIter; ii++){
245073
+ Fts5Iter *p = pT->apIter[ii];
245074
+ if( p->base.bEof==0
245075
+ && (p->base.iRowid==pIter->base.iRowid || (bFrom && p->base.iRowid<iFrom))
245076
+ ){
245077
+ fts5MultiIterNext(p->pIndex, p, bFrom, iFrom);
245078
+ while( bFrom && p->base.bEof==0
245079
+ && p->base.iRowid<iFrom
245080
+ && p->pIndex->rc==SQLITE_OK
245081
+ ){
245082
+ fts5MultiIterNext(p->pIndex, p, 0, 0);
245083
+ }
245084
+ }
245085
+ }
245086
+
245087
+ fts5IterSetOutputsTokendata(pIter);
245088
+}
245089
+
245090
+/*
245091
+** If the segment-iterator passed as the first argument is at EOF, then
245092
+** set pIter->term to a copy of buffer pTerm.
245093
+*/
245094
+static void fts5TokendataSetTermIfEof(Fts5Iter *pIter, Fts5Buffer *pTerm){
245095
+ if( pIter && pIter->aSeg[0].pLeaf==0 ){
245096
+ fts5BufferSet(&pIter->pIndex->rc, &pIter->aSeg[0].term, pTerm->n, pTerm->p);
245097
+ }
245098
+}
245099
+
245100
+/*
245101
+** This function sets up an iterator to use for a non-prefix query on a
245102
+** tokendata=1 table.
245103
+*/
245104
+static Fts5Iter *fts5SetupTokendataIter(
245105
+ Fts5Index *p, /* FTS index to query */
245106
+ const u8 *pToken, /* Buffer containing query term */
245107
+ int nToken, /* Size of buffer pToken in bytes */
245108
+ Fts5Colset *pColset /* Colset to filter on */
245109
+){
245110
+ Fts5Iter *pRet = 0;
245111
+ Fts5TokenDataIter *pSet = 0;
245112
+ Fts5Structure *pStruct = 0;
245113
+ const int flags = FTS5INDEX_QUERY_SCANONETERM | FTS5INDEX_QUERY_SCAN;
245114
+
245115
+ Fts5Buffer bSeek = {0, 0, 0};
245116
+ Fts5Buffer *pSmall = 0;
245117
+
245118
+ fts5IndexFlush(p);
245119
+ pStruct = fts5StructureRead(p);
245120
+
245121
+ while( p->rc==SQLITE_OK ){
245122
+ Fts5Iter *pPrev = pSet ? pSet->apIter[pSet->nIter-1] : 0;
245123
+ Fts5Iter *pNew = 0;
245124
+ Fts5SegIter *pNewIter = 0;
245125
+ Fts5SegIter *pPrevIter = 0;
245126
+
245127
+ int iLvl, iSeg, ii;
245128
+
245129
+ pNew = fts5MultiIterAlloc(p, pStruct->nSegment);
245130
+ if( pSmall ){
245131
+ fts5BufferSet(&p->rc, &bSeek, pSmall->n, pSmall->p);
245132
+ fts5BufferAppendBlob(&p->rc, &bSeek, 1, (const u8*)"\0");
245133
+ }else{
245134
+ fts5BufferSet(&p->rc, &bSeek, nToken, pToken);
245135
+ }
245136
+ if( p->rc ){
245137
+ sqlite3Fts5IterClose((Fts5IndexIter*)pNew);
245138
+ break;
245139
+ }
245140
+
245141
+ pNewIter = &pNew->aSeg[0];
245142
+ pPrevIter = (pPrev ? &pPrev->aSeg[0] : 0);
245143
+ for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
245144
+ for(iSeg=pStruct->aLevel[iLvl].nSeg-1; iSeg>=0; iSeg--){
245145
+ Fts5StructureSegment *pSeg = &pStruct->aLevel[iLvl].aSeg[iSeg];
245146
+ int bDone = 0;
245147
+
245148
+ if( pPrevIter ){
245149
+ if( fts5BufferCompare(pSmall, &pPrevIter->term) ){
245150
+ memcpy(pNewIter, pPrevIter, sizeof(Fts5SegIter));
245151
+ memset(pPrevIter, 0, sizeof(Fts5SegIter));
245152
+ bDone = 1;
245153
+ }else if( pPrevIter->iEndofDoclist>pPrevIter->pLeaf->szLeaf ){
245154
+ fts5SegIterNextInit(p,(const char*)bSeek.p,bSeek.n-1,pSeg,pNewIter);
245155
+ bDone = 1;
245156
+ }
245157
+ }
245158
+
245159
+ if( bDone==0 ){
245160
+ fts5SegIterSeekInit(p, bSeek.p, bSeek.n, flags, pSeg, pNewIter);
245161
+ }
245162
+
245163
+ if( pPrevIter ){
245164
+ if( pPrevIter->pTombArray ){
245165
+ pNewIter->pTombArray = pPrevIter->pTombArray;
245166
+ pNewIter->pTombArray->nRef++;
245167
+ }
245168
+ }else{
245169
+ fts5SegIterAllocTombstone(p, pNewIter);
245170
+ }
245171
+
245172
+ pNewIter++;
245173
+ if( pPrevIter ) pPrevIter++;
245174
+ if( p->rc ) break;
245175
+ }
245176
+ }
245177
+ fts5TokendataSetTermIfEof(pPrev, pSmall);
245178
+
245179
+ pNew->bSkipEmpty = 1;
245180
+ pNew->pColset = pColset;
245181
+ fts5IterSetOutputCb(&p->rc, pNew);
245182
+
245183
+ /* Loop through all segments in the new iterator. Find the smallest
245184
+ ** term that any segment-iterator points to. Iterator pNew will be
245185
+ ** used for this term. Also, set any iterator that points to a term that
245186
+ ** does not match pToken/nToken to point to EOF */
245187
+ pSmall = 0;
245188
+ for(ii=0; ii<pNew->nSeg; ii++){
245189
+ Fts5SegIter *pII = &pNew->aSeg[ii];
245190
+ if( 0==fts5IsTokendataPrefix(&pII->term, pToken, nToken) ){
245191
+ fts5SegIterSetEOF(pII);
245192
+ }
245193
+ if( pII->pLeaf && (!pSmall || fts5BufferCompare(pSmall, &pII->term)>0) ){
245194
+ pSmall = &pII->term;
245195
+ }
245196
+ }
245197
+
245198
+ /* If pSmall is still NULL at this point, then the new iterator does
245199
+ ** not point to any terms that match the query. So delete it and break
245200
+ ** out of the loop - all required iterators have been collected. */
245201
+ if( pSmall==0 ){
245202
+ sqlite3Fts5IterClose((Fts5IndexIter*)pNew);
245203
+ break;
245204
+ }
245205
+
245206
+ /* Append this iterator to the set and continue. */
245207
+ pSet = fts5AppendTokendataIter(p, pSet, pNew);
245208
+ }
245209
+
245210
+ if( p->rc==SQLITE_OK && pSet ){
245211
+ int ii;
245212
+ for(ii=0; ii<pSet->nIter; ii++){
245213
+ Fts5Iter *pIter = pSet->apIter[ii];
245214
+ int iSeg;
245215
+ for(iSeg=0; iSeg<pIter->nSeg; iSeg++){
245216
+ pIter->aSeg[iSeg].flags |= FTS5_SEGITER_ONETERM;
245217
+ }
245218
+ fts5MultiIterFinishSetup(p, pIter);
245219
+ }
245220
+ }
245221
+
245222
+ if( p->rc==SQLITE_OK ){
245223
+ pRet = fts5MultiIterAlloc(p, 0);
245224
+ }
245225
+ if( pRet ){
245226
+ pRet->pTokenDataIter = pSet;
245227
+ if( pSet ){
245228
+ fts5IterSetOutputsTokendata(pRet);
245229
+ }else{
245230
+ pRet->base.bEof = 1;
245231
+ }
245232
+ }else{
245233
+ fts5TokendataIterDelete(pSet);
245234
+ }
245235
+
245236
+ fts5StructureRelease(pStruct);
245237
+ fts5BufferFree(&bSeek);
245238
+ return pRet;
245239
+}
245240
+
242801245241
242802245242
/*
242803245243
** Open a new iterator to iterate though all rowid that match the
242804245244
** specified token or token prefix.
242805245245
*/
@@ -242818,11 +245258,16 @@
242818245258
assert( (flags & FTS5INDEX_QUERY_SCAN)==0 || flags==FTS5INDEX_QUERY_SCAN );
242819245259
242820245260
if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){
242821245261
int iIdx = 0; /* Index to search */
242822245262
int iPrefixIdx = 0; /* +1 prefix index */
245263
+ int bTokendata = pConfig->bTokendata;
242823245264
if( nToken>0 ) memcpy(&buf.p[1], pToken, nToken);
245265
+
245266
+ if( flags & (FTS5INDEX_QUERY_NOTOKENDATA|FTS5INDEX_QUERY_SCAN) ){
245267
+ bTokendata = 0;
245268
+ }
242824245269
242825245270
/* Figure out which index to search and set iIdx accordingly. If this
242826245271
** is a prefix query for which there is no prefix index, set iIdx to
242827245272
** greater than pConfig->nPrefix to indicate that the query will be
242828245273
** satisfied by scanning multiple terms in the main index.
@@ -242845,11 +245290,14 @@
242845245290
if( nIdxChar==nChar ) break;
242846245291
if( nIdxChar==nChar+1 ) iPrefixIdx = iIdx;
242847245292
}
242848245293
}
242849245294
242850
- if( iIdx<=pConfig->nPrefix ){
245295
+ if( bTokendata && iIdx==0 ){
245296
+ buf.p[0] = '0';
245297
+ pRet = fts5SetupTokendataIter(p, buf.p, nToken+1, pColset);
245298
+ }else if( iIdx<=pConfig->nPrefix ){
242851245299
/* Straight index lookup */
242852245300
Fts5Structure *pStruct = fts5StructureRead(p);
242853245301
buf.p[0] = (u8)(FTS5_MAIN_PREFIX + iIdx);
242854245302
if( pStruct ){
242855245303
fts5MultiIterNew(p, pStruct, flags | FTS5INDEX_QUERY_SKIPEMPTY,
@@ -242892,11 +245340,15 @@
242892245340
** Move to the next matching rowid.
242893245341
*/
242894245342
static int sqlite3Fts5IterNext(Fts5IndexIter *pIndexIter){
242895245343
Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
242896245344
assert( pIter->pIndex->rc==SQLITE_OK );
242897
- fts5MultiIterNext(pIter->pIndex, pIter, 0, 0);
245345
+ if( pIter->pTokenDataIter ){
245346
+ fts5TokendataIterNext(pIter, 0, 0);
245347
+ }else{
245348
+ fts5MultiIterNext(pIter->pIndex, pIter, 0, 0);
245349
+ }
242898245350
return fts5IndexReturn(pIter->pIndex);
242899245351
}
242900245352
242901245353
/*
242902245354
** Move to the next matching term/rowid. Used by the fts5vocab module.
@@ -242925,11 +245377,15 @@
242925245377
** definition of "at or after" depends on whether this iterator iterates
242926245378
** in ascending or descending rowid order.
242927245379
*/
242928245380
static int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){
242929245381
Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
242930
- fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch);
245382
+ if( pIter->pTokenDataIter ){
245383
+ fts5TokendataIterNext(pIter, 1, iMatch);
245384
+ }else{
245385
+ fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch);
245386
+ }
242931245387
return fts5IndexReturn(pIter->pIndex);
242932245388
}
242933245389
242934245390
/*
242935245391
** Return the current term.
@@ -242939,18 +245395,112 @@
242939245395
const char *z = (const char*)fts5MultiIterTerm((Fts5Iter*)pIndexIter, &n);
242940245396
assert_nc( z || n<=1 );
242941245397
*pn = n-1;
242942245398
return (z ? &z[1] : 0);
242943245399
}
245400
+
245401
+/*
245402
+** This is used by xInstToken() to access the token at offset iOff, column
245403
+** iCol of row iRowid. The token is returned via output variables *ppOut
245404
+** and *pnOut. The iterator passed as the first argument must be a tokendata=1
245405
+** iterator (pIter->pTokenDataIter!=0).
245406
+*/
245407
+static int sqlite3Fts5IterToken(
245408
+ Fts5IndexIter *pIndexIter,
245409
+ i64 iRowid,
245410
+ int iCol,
245411
+ int iOff,
245412
+ const char **ppOut, int *pnOut
245413
+){
245414
+ Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
245415
+ Fts5TokenDataIter *pT = pIter->pTokenDataIter;
245416
+ Fts5TokenDataMap *aMap = pT->aMap;
245417
+ i64 iPos = (((i64)iCol)<<32) + iOff;
245418
+
245419
+ int i1 = 0;
245420
+ int i2 = pT->nMap;
245421
+ int iTest = 0;
245422
+
245423
+ while( i2>i1 ){
245424
+ iTest = (i1 + i2) / 2;
245425
+
245426
+ if( aMap[iTest].iRowid<iRowid ){
245427
+ i1 = iTest+1;
245428
+ }else if( aMap[iTest].iRowid>iRowid ){
245429
+ i2 = iTest;
245430
+ }else{
245431
+ if( aMap[iTest].iPos<iPos ){
245432
+ if( aMap[iTest].iPos<0 ){
245433
+ break;
245434
+ }
245435
+ i1 = iTest+1;
245436
+ }else if( aMap[iTest].iPos>iPos ){
245437
+ i2 = iTest;
245438
+ }else{
245439
+ break;
245440
+ }
245441
+ }
245442
+ }
245443
+
245444
+ if( i2>i1 ){
245445
+ Fts5Iter *pMap = pT->apIter[aMap[iTest].iIter];
245446
+ *ppOut = (const char*)pMap->aSeg[0].term.p+1;
245447
+ *pnOut = pMap->aSeg[0].term.n-1;
245448
+ }
245449
+
245450
+ return SQLITE_OK;
245451
+}
245452
+
245453
+/*
245454
+** Clear any existing entries from the token-map associated with the
245455
+** iterator passed as the only argument.
245456
+*/
245457
+static void sqlite3Fts5IndexIterClearTokendata(Fts5IndexIter *pIndexIter){
245458
+ Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
245459
+ if( pIter && pIter->pTokenDataIter ){
245460
+ pIter->pTokenDataIter->nMap = 0;
245461
+ }
245462
+}
245463
+
245464
+/*
245465
+** Set a token-mapping for the iterator passed as the first argument. This
245466
+** is used in detail=column or detail=none mode when a token is requested
245467
+** using the xInstToken() API. In this case the caller tokenizers the
245468
+** current row and configures the token-mapping via multiple calls to this
245469
+** function.
245470
+*/
245471
+static int sqlite3Fts5IndexIterWriteTokendata(
245472
+ Fts5IndexIter *pIndexIter,
245473
+ const char *pToken, int nToken,
245474
+ i64 iRowid, int iCol, int iOff
245475
+){
245476
+ Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
245477
+ Fts5TokenDataIter *pT = pIter->pTokenDataIter;
245478
+ Fts5Index *p = pIter->pIndex;
245479
+ int ii;
245480
+
245481
+ assert( p->pConfig->eDetail!=FTS5_DETAIL_FULL );
245482
+ assert( pIter->pTokenDataIter );
245483
+
245484
+ for(ii=0; ii<pT->nIter; ii++){
245485
+ Fts5Buffer *pTerm = &pT->apIter[ii]->aSeg[0].term;
245486
+ if( nToken==pTerm->n-1 && memcmp(pToken, pTerm->p+1, nToken)==0 ) break;
245487
+ }
245488
+ if( ii<pT->nIter ){
245489
+ fts5TokendataIterAppendMap(p, pT, ii, iRowid, (((i64)iCol)<<32) + iOff);
245490
+ }
245491
+ return fts5IndexReturn(p);
245492
+}
242944245493
242945245494
/*
242946245495
** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery().
242947245496
*/
242948245497
static void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){
242949245498
if( pIndexIter ){
242950245499
Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
242951245500
Fts5Index *pIndex = pIter->pIndex;
245501
+ fts5TokendataIterDelete(pIter->pTokenDataIter);
242952245502
fts5MultiIterFree(pIter);
242953245503
sqlite3Fts5IndexCloseReader(pIndex);
242954245504
}
242955245505
}
242956245506
@@ -243454,11 +246004,13 @@
243454246004
u64 *pCksum /* IN/OUT: Checksum value */
243455246005
){
243456246006
int eDetail = p->pConfig->eDetail;
243457246007
u64 cksum = *pCksum;
243458246008
Fts5IndexIter *pIter = 0;
243459
- int rc = sqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIter);
246009
+ int rc = sqlite3Fts5IndexQuery(
246010
+ p, z, n, (flags | FTS5INDEX_QUERY_NOTOKENDATA), 0, &pIter
246011
+ );
243460246012
243461246013
while( rc==SQLITE_OK && ALWAYS(pIter!=0) && 0==sqlite3Fts5IterEof(pIter) ){
243462246014
i64 rowid = pIter->iRowid;
243463246015
243464246016
if( eDetail==FTS5_DETAIL_NONE ){
@@ -244151,10 +246703,28 @@
244151246703
244152246704
sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " %lld%s", iRowid, zApp);
244153246705
}
244154246706
}
244155246707
#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
246708
+
246709
+#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
246710
+static void fts5BufferAppendTerm(int *pRc, Fts5Buffer *pBuf, Fts5Buffer *pTerm){
246711
+ int ii;
246712
+ fts5BufferGrow(pRc, pBuf, pTerm->n*2 + 1);
246713
+ if( *pRc==SQLITE_OK ){
246714
+ for(ii=0; ii<pTerm->n; ii++){
246715
+ if( pTerm->p[ii]==0x00 ){
246716
+ pBuf->p[pBuf->n++] = '\\';
246717
+ pBuf->p[pBuf->n++] = '0';
246718
+ }else{
246719
+ pBuf->p[pBuf->n++] = pTerm->p[ii];
246720
+ }
246721
+ }
246722
+ pBuf->p[pBuf->n] = 0x00;
246723
+ }
246724
+}
246725
+#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
244156246726
244157246727
#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
244158246728
/*
244159246729
** The implementation of user-defined scalar function fts5_decode().
244160246730
*/
@@ -244259,13 +246829,12 @@
244259246829
244260246830
/* Read the term data for the next term*/
244261246831
iOff += fts5GetVarint32(&a[iOff], nAppend);
244262246832
term.n = nKeep;
244263246833
fts5BufferAppendBlob(&rc, &term, nAppend, &a[iOff]);
244264
- sqlite3Fts5BufferAppendPrintf(
244265
- &rc, &s, " term=%.*s", term.n, (const char*)term.p
244266
- );
246834
+ sqlite3Fts5BufferAppendPrintf(&rc, &s, " term=");
246835
+ fts5BufferAppendTerm(&rc, &s, &term);
244267246836
iOff += nAppend;
244268246837
244269246838
/* Figure out where the doclist for this term ends */
244270246839
if( iPgidxOff<n ){
244271246840
int nIncr;
@@ -244369,13 +246938,12 @@
244369246938
break;
244370246939
}
244371246940
fts5BufferAppendBlob(&rc, &term, nByte, &a[iOff]);
244372246941
iOff += nByte;
244373246942
244374
- sqlite3Fts5BufferAppendPrintf(
244375
- &rc, &s, " term=%.*s", term.n, (const char*)term.p
244376
- );
246943
+ sqlite3Fts5BufferAppendPrintf(&rc, &s, " term=");
246944
+ fts5BufferAppendTerm(&rc, &s, &term);
244377246945
iOff += fts5DecodeDoclist(&rc, &s, &a[iOff], iEnd-iOff);
244378246946
}
244379246947
244380246948
fts5BufferFree(&term);
244381246949
}
@@ -244846,11 +247414,11 @@
244846247414
Fts5Table p; /* Public class members from fts5Int.h */
244847247415
Fts5Storage *pStorage; /* Document store */
244848247416
Fts5Global *pGlobal; /* Global (connection wide) data */
244849247417
Fts5Cursor *pSortCsr; /* Sort data from this cursor */
244850247418
int iSavepoint; /* Successful xSavepoint()+1 */
244851
- int bInSavepoint;
247419
+
244852247420
#ifdef SQLITE_DEBUG
244853247421
struct Fts5TransactionState ts;
244854247422
#endif
244855247423
};
244856247424
@@ -245384,16 +247952,19 @@
245384247952
}
245385247953
}
245386247954
}
245387247955
idxStr[iIdxStr] = '\0';
245388247956
245389
- /* Set idxFlags flags for the ORDER BY clause */
247957
+ /* Set idxFlags flags for the ORDER BY clause
247958
+ **
247959
+ ** Note that tokendata=1 tables cannot currently handle "ORDER BY rowid DESC".
247960
+ */
245390247961
if( pInfo->nOrderBy==1 ){
245391247962
int iSort = pInfo->aOrderBy[0].iColumn;
245392247963
if( iSort==(pConfig->nCol+1) && bSeenMatch ){
245393247964
idxFlags |= FTS5_BI_ORDER_RANK;
245394
- }else if( iSort==-1 ){
247965
+ }else if( iSort==-1 && (!pInfo->aOrderBy[0].desc || !pConfig->bTokendata) ){
245395247966
idxFlags |= FTS5_BI_ORDER_ROWID;
245396247967
}
245397247968
if( BitFlagTest(idxFlags, FTS5_BI_ORDER_RANK|FTS5_BI_ORDER_ROWID) ){
245398247969
pInfo->orderByConsumed = 1;
245399247970
if( pInfo->aOrderBy[0].desc ){
@@ -245640,10 +248211,20 @@
245640248211
245641248212
assert( (pCsr->ePlan<3)==
245642248213
(pCsr->ePlan==FTS5_PLAN_MATCH || pCsr->ePlan==FTS5_PLAN_SOURCE)
245643248214
);
245644248215
assert( !CsrFlagTest(pCsr, FTS5CSR_EOF) );
248216
+
248217
+ /* If this cursor uses FTS5_PLAN_MATCH and this is a tokendata=1 table,
248218
+ ** clear any token mappings accumulated at the fts5_index.c level. In
248219
+ ** other cases, specifically FTS5_PLAN_SOURCE and FTS5_PLAN_SORTED_MATCH,
248220
+ ** we need to retain the mappings for the entire query. */
248221
+ if( pCsr->ePlan==FTS5_PLAN_MATCH
248222
+ && ((Fts5Table*)pCursor->pVtab)->pConfig->bTokendata
248223
+ ){
248224
+ sqlite3Fts5ExprClearTokens(pCsr->pExpr);
248225
+ }
245645248226
245646248227
if( pCsr->ePlan<3 ){
245647248228
int bSkip = 0;
245648248229
if( (rc = fts5CursorReseek(pCsr, &bSkip)) || bSkip ) return rc;
245649248230
rc = sqlite3Fts5ExprNext(pCsr->pExpr, pCsr->iLastRowid);
@@ -246791,16 +249372,10 @@
246791249372
if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_INST)==0
246792249373
|| SQLITE_OK==(rc = fts5CacheInstArray(pCsr))
246793249374
){
246794249375
if( iIdx<0 || iIdx>=pCsr->nInstCount ){
246795249376
rc = SQLITE_RANGE;
246796
-#if 0
246797
- }else if( fts5IsOffsetless((Fts5Table*)pCsr->base.pVtab) ){
246798
- *piPhrase = pCsr->aInst[iIdx*3];
246799
- *piCol = pCsr->aInst[iIdx*3 + 2];
246800
- *piOff = -1;
246801
-#endif
246802249377
}else{
246803249378
*piPhrase = pCsr->aInst[iIdx*3];
246804249379
*piCol = pCsr->aInst[iIdx*3 + 1];
246805249380
*piOff = pCsr->aInst[iIdx*3 + 2];
246806249381
}
@@ -247051,17 +249626,60 @@
247051249626
}
247052249627
247053249628
return rc;
247054249629
}
247055249630
249631
+/*
249632
+** xQueryToken() API implemenetation.
249633
+*/
249634
+static int fts5ApiQueryToken(
249635
+ Fts5Context* pCtx,
249636
+ int iPhrase,
249637
+ int iToken,
249638
+ const char **ppOut,
249639
+ int *pnOut
249640
+){
249641
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
249642
+ return sqlite3Fts5ExprQueryToken(pCsr->pExpr, iPhrase, iToken, ppOut, pnOut);
249643
+}
249644
+
249645
+/*
249646
+** xInstToken() API implemenetation.
249647
+*/
249648
+static int fts5ApiInstToken(
249649
+ Fts5Context *pCtx,
249650
+ int iIdx,
249651
+ int iToken,
249652
+ const char **ppOut, int *pnOut
249653
+){
249654
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
249655
+ int rc = SQLITE_OK;
249656
+ if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_INST)==0
249657
+ || SQLITE_OK==(rc = fts5CacheInstArray(pCsr))
249658
+ ){
249659
+ if( iIdx<0 || iIdx>=pCsr->nInstCount ){
249660
+ rc = SQLITE_RANGE;
249661
+ }else{
249662
+ int iPhrase = pCsr->aInst[iIdx*3];
249663
+ int iCol = pCsr->aInst[iIdx*3 + 1];
249664
+ int iOff = pCsr->aInst[iIdx*3 + 2];
249665
+ i64 iRowid = fts5CursorRowid(pCsr);
249666
+ rc = sqlite3Fts5ExprInstToken(
249667
+ pCsr->pExpr, iRowid, iPhrase, iCol, iOff, iToken, ppOut, pnOut
249668
+ );
249669
+ }
249670
+ }
249671
+ return rc;
249672
+}
249673
+
247056249674
247057249675
static int fts5ApiQueryPhrase(Fts5Context*, int, void*,
247058249676
int(*)(const Fts5ExtensionApi*, Fts5Context*, void*)
247059249677
);
247060249678
247061249679
static const Fts5ExtensionApi sFts5Api = {
247062
- 2, /* iVersion */
249680
+ 3, /* iVersion */
247063249681
fts5ApiUserData,
247064249682
fts5ApiColumnCount,
247065249683
fts5ApiRowCount,
247066249684
fts5ApiColumnTotalSize,
247067249685
fts5ApiTokenize,
@@ -247077,10 +249695,12 @@
247077249695
fts5ApiGetAuxdata,
247078249696
fts5ApiPhraseFirst,
247079249697
fts5ApiPhraseNext,
247080249698
fts5ApiPhraseFirstColumn,
247081249699
fts5ApiPhraseNextColumn,
249700
+ fts5ApiQueryToken,
249701
+ fts5ApiInstToken
247082249702
};
247083249703
247084249704
/*
247085249705
** Implementation of API function xQueryPhrase().
247086249706
*/
@@ -247343,13 +249963,11 @@
247343249963
sqlite3_vtab *pVtab, /* Virtual table handle */
247344249964
const char *zName /* New name of table */
247345249965
){
247346249966
int rc;
247347249967
Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
247348
- pTab->bInSavepoint = 1;
247349249968
rc = sqlite3Fts5StorageRename(pTab->pStorage, zName);
247350
- pTab->bInSavepoint = 0;
247351249969
return rc;
247352249970
}
247353249971
247354249972
static int sqlite3Fts5FlushToDisk(Fts5Table *pTab){
247355249973
fts5TripCursors((Fts5FullTable*)pTab);
@@ -247362,30 +249980,16 @@
247362249980
** Flush the contents of the pending-terms table to disk.
247363249981
*/
247364249982
static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){
247365249983
Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
247366249984
int rc = SQLITE_OK;
247367
- char *zSql = 0;
249985
+
247368249986
fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint);
247369
-
247370
- if( pTab->bInSavepoint==0 ){
247371
- zSql = sqlite3_mprintf("INSERT INTO %Q.%Q(%Q) VALUES('flush')",
247372
- pTab->p.pConfig->zDb, pTab->p.pConfig->zName, pTab->p.pConfig->zName
247373
- );
247374
- if( zSql ){
247375
- pTab->bInSavepoint = 1;
247376
- rc = sqlite3_exec(pTab->p.pConfig->db, zSql, 0, 0, 0);
247377
- pTab->bInSavepoint = 0;
247378
- sqlite3_free(zSql);
247379
- }else{
247380
- rc = SQLITE_NOMEM;
247381
- }
247382
- if( rc==SQLITE_OK ){
247383
- pTab->iSavepoint = iSavepoint+1;
247384
- }
247385
- }
247386
-
249987
+ rc = sqlite3Fts5FlushToDisk((Fts5Table*)pVtab);
249988
+ if( rc==SQLITE_OK ){
249989
+ pTab->iSavepoint = iSavepoint+1;
249990
+ }
247387249991
return rc;
247388249992
}
247389249993
247390249994
/*
247391249995
** The xRelease() method.
@@ -247619,11 +250223,11 @@
247619250223
int nArg, /* Number of args */
247620250224
sqlite3_value **apUnused /* Function arguments */
247621250225
){
247622250226
assert( nArg==0 );
247623250227
UNUSED_PARAM2(nArg, apUnused);
247624
- sqlite3_result_text(pCtx, "fts5: 2023-11-24 11:41:44 ebead0e7230cd33bcec9f95d2183069565b9e709bf745c9b5db65cc0cbf92c0f", -1, SQLITE_TRANSIENT);
250228
+ sqlite3_result_text(pCtx, "fts5: 2023-12-14 16:34:47 27d4a89a5ff96b7b7fc5dc9650e1269f7c7edf91de9b9aafce40be9ecc8b95e9", -1, SQLITE_TRANSIENT);
247625250229
}
247626250230
247627250231
/*
247628250232
** Return true if zName is the extension on one of the shadow tables used
247629250233
** by this module.
@@ -247642,11 +250246,11 @@
247642250246
/*
247643250247
** Run an integrity check on the FTS5 data structures. Return a string
247644250248
** if anything is found amiss. Return a NULL pointer if everything is
247645250249
** OK.
247646250250
*/
247647
-static int fts5Integrity(
250251
+static int fts5IntegrityMethod(
247648250252
sqlite3_vtab *pVtab, /* the FTS5 virtual table to check */
247649250253
const char *zSchema, /* Name of schema in which this table lives */
247650250254
const char *zTabname, /* Name of the table itself */
247651250255
int isQuick, /* True if this is a quick-check */
247652250256
char **pzErr /* Write error message here */
@@ -247700,11 +250304,11 @@
247700250304
/* xRename */ fts5RenameMethod,
247701250305
/* xSavepoint */ fts5SavepointMethod,
247702250306
/* xRelease */ fts5ReleaseMethod,
247703250307
/* xRollbackTo */ fts5RollbackToMethod,
247704250308
/* xShadowName */ fts5ShadowName,
247705
- /* xIntegrity */ fts5Integrity
250309
+ /* xIntegrity */ fts5IntegrityMethod
247706250310
};
247707250311
247708250312
int rc;
247709250313
Fts5Global *pGlobal = 0;
247710250314
@@ -248466,11 +251070,11 @@
248466251070
if( rc==SQLITE_OK ){
248467251071
rc = fts5StorageLoadTotals(p, 1);
248468251072
}
248469251073
248470251074
if( rc==SQLITE_OK ){
248471
- rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0);
251075
+ rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, pConfig->pzErrmsg);
248472251076
}
248473251077
248474251078
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pScan) ){
248475251079
i64 iRowid = sqlite3_column_int64(pScan, 0);
248476251080
@@ -249252,10 +251856,16 @@
249252251856
*zOut++ = 0x80 + (unsigned char)(c & 0x3F); \
249253251857
} \
249254251858
}
249255251859
249256251860
#endif /* ifndef SQLITE_AMALGAMATION */
251861
+
251862
+#define FTS5_SKIP_UTF8(zIn) { \
251863
+ if( ((unsigned char)(*(zIn++)))>=0xc0 ){ \
251864
+ while( (((unsigned char)*zIn) & 0xc0)==0x80 ){ zIn++; } \
251865
+ } \
251866
+}
249257251867
249258251868
typedef struct Unicode61Tokenizer Unicode61Tokenizer;
249259251869
struct Unicode61Tokenizer {
249260251870
unsigned char aTokenChar[128]; /* ASCII range token characters */
249261251871
char *aFold; /* Buffer to fold text into */
@@ -250288,10 +252898,11 @@
250288252898
** Start of trigram implementation.
250289252899
*/
250290252900
typedef struct TrigramTokenizer TrigramTokenizer;
250291252901
struct TrigramTokenizer {
250292252902
int bFold; /* True to fold to lower-case */
252903
+ int iFoldParam; /* Parameter to pass to Fts5UnicodeFold() */
250293252904
};
250294252905
250295252906
/*
250296252907
** Free a trigram tokenizer.
250297252908
*/
@@ -250314,22 +252925,34 @@
250314252925
if( pNew==0 ){
250315252926
rc = SQLITE_NOMEM;
250316252927
}else{
250317252928
int i;
250318252929
pNew->bFold = 1;
252930
+ pNew->iFoldParam = 0;
250319252931
for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
250320252932
const char *zArg = azArg[i+1];
250321252933
if( 0==sqlite3_stricmp(azArg[i], "case_sensitive") ){
250322252934
if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){
250323252935
rc = SQLITE_ERROR;
250324252936
}else{
250325252937
pNew->bFold = (zArg[0]=='0');
250326252938
}
252939
+ }else if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){
252940
+ if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){
252941
+ rc = SQLITE_ERROR;
252942
+ }else{
252943
+ pNew->iFoldParam = (zArg[0]!='0') ? 2 : 0;
252944
+ }
250327252945
}else{
250328252946
rc = SQLITE_ERROR;
250329252947
}
250330252948
}
252949
+
252950
+ if( pNew->iFoldParam!=0 && pNew->bFold==0 ){
252951
+ rc = SQLITE_ERROR;
252952
+ }
252953
+
250331252954
if( rc!=SQLITE_OK ){
250332252955
fts5TriDelete((Fts5Tokenizer*)pNew);
250333252956
pNew = 0;
250334252957
}
250335252958
}
@@ -250348,44 +252971,66 @@
250348252971
int (*xToken)(void*, int, const char*, int, int, int)
250349252972
){
250350252973
TrigramTokenizer *p = (TrigramTokenizer*)pTok;
250351252974
int rc = SQLITE_OK;
250352252975
char aBuf[32];
252976
+ char *zOut = aBuf;
252977
+ int ii;
250353252978
const unsigned char *zIn = (const unsigned char*)pText;
250354252979
const unsigned char *zEof = &zIn[nText];
250355252980
u32 iCode;
252981
+ int aStart[3]; /* Input offset of each character in aBuf[] */
250356252982
250357252983
UNUSED_PARAM(unusedFlags);
250358
- while( 1 ){
250359
- char *zOut = aBuf;
250360
- int iStart = zIn - (const unsigned char*)pText;
250361
- const unsigned char *zNext;
250362
-
250363
- READ_UTF8(zIn, zEof, iCode);
250364
- if( iCode==0 ) break;
250365
- zNext = zIn;
250366
- if( zIn<zEof ){
250367
- if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0);
250368
- WRITE_UTF8(zOut, iCode);
250369
- READ_UTF8(zIn, zEof, iCode);
250370
- if( iCode==0 ) break;
250371
- }else{
250372
- break;
250373
- }
250374
- if( zIn<zEof ){
250375
- if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0);
250376
- WRITE_UTF8(zOut, iCode);
250377
- READ_UTF8(zIn, zEof, iCode);
250378
- if( iCode==0 ) break;
250379
- if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0);
250380
- WRITE_UTF8(zOut, iCode);
250381
- }else{
250382
- break;
250383
- }
250384
- rc = xToken(pCtx, 0, aBuf, zOut-aBuf, iStart, iStart + zOut-aBuf);
250385
- if( rc!=SQLITE_OK ) break;
250386
- zIn = zNext;
252984
+
252985
+ /* Populate aBuf[] with the characters for the first trigram. */
252986
+ for(ii=0; ii<3; ii++){
252987
+ do {
252988
+ aStart[ii] = zIn - (const unsigned char*)pText;
252989
+ READ_UTF8(zIn, zEof, iCode);
252990
+ if( iCode==0 ) return SQLITE_OK;
252991
+ if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam);
252992
+ }while( iCode==0 );
252993
+ WRITE_UTF8(zOut, iCode);
252994
+ }
252995
+
252996
+ /* At the start of each iteration of this loop:
252997
+ **
252998
+ ** aBuf: Contains 3 characters. The 3 characters of the next trigram.
252999
+ ** zOut: Points to the byte following the last character in aBuf.
253000
+ ** aStart[3]: Contains the byte offset in the input text corresponding
253001
+ ** to the start of each of the three characters in the buffer.
253002
+ */
253003
+ assert( zIn<=zEof );
253004
+ while( 1 ){
253005
+ int iNext; /* Start of character following current tri */
253006
+ const char *z1;
253007
+
253008
+ /* Read characters from the input up until the first non-diacritic */
253009
+ do {
253010
+ iNext = zIn - (const unsigned char*)pText;
253011
+ READ_UTF8(zIn, zEof, iCode);
253012
+ if( iCode==0 ) break;
253013
+ if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam);
253014
+ }while( iCode==0 );
253015
+
253016
+ /* Pass the current trigram back to fts5 */
253017
+ rc = xToken(pCtx, 0, aBuf, zOut-aBuf, aStart[0], iNext);
253018
+ if( iCode==0 || rc!=SQLITE_OK ) break;
253019
+
253020
+ /* Remove the first character from buffer aBuf[]. Append the character
253021
+ ** with codepoint iCode. */
253022
+ z1 = aBuf;
253023
+ FTS5_SKIP_UTF8(z1);
253024
+ memmove(aBuf, z1, zOut - z1);
253025
+ zOut -= (z1 - aBuf);
253026
+ WRITE_UTF8(zOut, iCode);
253027
+
253028
+ /* Update the aStart[] array */
253029
+ aStart[0] = aStart[1];
253030
+ aStart[1] = aStart[2];
253031
+ aStart[2] = iNext;
250387253032
}
250388253033
250389253034
return rc;
250390253035
}
250391253036
@@ -250404,11 +253049,13 @@
250404253049
int (*xCreate)(void*, const char**, int, Fts5Tokenizer**),
250405253050
Fts5Tokenizer *pTok
250406253051
){
250407253052
if( xCreate==fts5TriCreate ){
250408253053
TrigramTokenizer *p = (TrigramTokenizer*)pTok;
250409
- return p->bFold ? FTS5_PATTERN_LIKE : FTS5_PATTERN_GLOB;
253054
+ if( p->iFoldParam==0 ){
253055
+ return p->bFold ? FTS5_PATTERN_LIKE : FTS5_PATTERN_GLOB;
253056
+ }
250410253057
}
250411253058
return FTS5_PATTERN_NONE;
250412253059
}
250413253060
250414253061
/*
@@ -252193,11 +254840,11 @@
252193254840
if( idxNum & FTS5_VOCAB_TERM_LE ) pLe = apVal[iVal++];
252194254841
252195254842
if( pEq ){
252196254843
zTerm = (const char *)sqlite3_value_text(pEq);
252197254844
nTerm = sqlite3_value_bytes(pEq);
252198
- f = 0;
254845
+ f = FTS5INDEX_QUERY_NOTOKENDATA;
252199254846
}else{
252200254847
if( pGe ){
252201254848
zTerm = (const char *)sqlite3_value_text(pGe);
252202254849
nTerm = sqlite3_value_bytes(pGe);
252203254850
}
252204254851
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -1,8 +1,8 @@
1 /******************************************************************************
2 ** This file is an amalgamation of many separate C source files from SQLite
3 ** version 3.44.2. By combining all the individual C code files into this
4 ** single large file, the entire code can be compiled as a single translation
5 ** unit. This allows many compilers to do optimizations that would not be
6 ** possible if the files were compiled separately. Performance improvements
7 ** of 5% or more are commonly seen when SQLite is compiled as a single
8 ** translation unit.
@@ -16,11 +16,11 @@
16 ** if you want a wrapper to interface SQLite with your choice of programming
17 ** language. The code for the "sqlite3" command-line shell is also in a
18 ** separate file. This file contains only code for the core SQLite library.
19 **
20 ** The content in this amalgamation comes from Fossil check-in
21 ** ebead0e7230cd33bcec9f95d2183069565b9.
22 */
23 #define SQLITE_CORE 1
24 #define SQLITE_AMALGAMATION 1
25 #ifndef SQLITE_PRIVATE
26 # define SQLITE_PRIVATE static
@@ -457,13 +457,13 @@
457 **
458 ** See also: [sqlite3_libversion()],
459 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
460 ** [sqlite_version()] and [sqlite_source_id()].
461 */
462 #define SQLITE_VERSION "3.44.2"
463 #define SQLITE_VERSION_NUMBER 3044002
464 #define SQLITE_SOURCE_ID "2023-11-24 11:41:44 ebead0e7230cd33bcec9f95d2183069565b9e709bf745c9b5db65cc0cbf92c0f"
465
466 /*
467 ** CAPI3REF: Run-Time Library Version Numbers
468 ** KEYWORDS: sqlite3_version sqlite3_sourceid
469 **
@@ -4265,19 +4265,21 @@
4265 ** <li> sqlite3_errmsg16()
4266 ** <li> sqlite3_error_offset()
4267 ** </ul>
4268 **
4269 ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
4270 ** text that describes the error, as either UTF-8 or UTF-16 respectively.
 
4271 ** (See how SQLite handles [invalid UTF] for exceptions to this rule.)
4272 ** ^(Memory to hold the error message string is managed internally.
4273 ** The application does not need to worry about freeing the result.
4274 ** However, the error string might be overwritten or deallocated by
4275 ** subsequent calls to other SQLite interface functions.)^
4276 **
4277 ** ^The sqlite3_errstr() interface returns the English-language text
4278 ** that describes the [result code], as UTF-8.
 
4279 ** ^(Memory to hold the error message string is managed internally
4280 ** and must not be freed by the application)^.
4281 **
4282 ** ^If the most recent error references a specific token in the input
4283 ** SQL, the sqlite3_error_offset() interface returns the byte offset
@@ -8609,10 +8611,11 @@
8609 #define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10
8610 #define SQLITE_TESTCTRL_PENDING_BYTE 11
8611 #define SQLITE_TESTCTRL_ASSERT 12
8612 #define SQLITE_TESTCTRL_ALWAYS 13
8613 #define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */
 
8614 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15
8615 #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
8616 #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
8617 #define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17
8618 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
@@ -13295,13 +13298,38 @@
13295 ** significantly more efficient than those alternatives when used with
13296 ** "detail=column" tables.
13297 **
13298 ** xPhraseNextColumn()
13299 ** See xPhraseFirstColumn above.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13300 */
13301 struct Fts5ExtensionApi {
13302 int iVersion; /* Currently always set to 2 */
13303
13304 void *(*xUserData)(Fts5Context*);
13305
13306 int (*xColumnCount)(Fts5Context*);
13307 int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
@@ -13332,10 +13360,17 @@
13332 int (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*);
13333 void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff);
13334
13335 int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*);
13336 void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol);
 
 
 
 
 
 
 
13337 };
13338
13339 /*
13340 ** CUSTOM AUXILIARY FUNCTIONS
13341 *************************************************************************/
@@ -16426,10 +16461,11 @@
16426 #define P4_VTAB (-11) /* P4 is a pointer to an sqlite3_vtab structure */
16427 #define P4_REAL (-12) /* P4 is a 64-bit floating point value */
16428 #define P4_INT64 (-13) /* P4 is a 64-bit signed integer */
16429 #define P4_INTARRAY (-14) /* P4 is a vector of 32-bit integers */
16430 #define P4_FUNCCTX (-15) /* P4 is a pointer to an sqlite3_context object */
 
16431
16432 /* Error message codes for OP_Halt */
16433 #define P5_ConstraintNotNull 1
16434 #define P5_ConstraintUnique 2
16435 #define P5_ConstraintCheck 3
@@ -16648,17 +16684,19 @@
16648 #define OP_VColumn 176 /* synopsis: r[P3]=vcolumn(P2) */
16649 #define OP_VRename 177
16650 #define OP_Pagecount 178
16651 #define OP_MaxPgcnt 179
16652 #define OP_ClrSubtype 180 /* synopsis: r[P1].subtype = 0 */
16653 #define OP_FilterAdd 181 /* synopsis: filter(P1) += key(P3@P4) */
16654 #define OP_Trace 182
16655 #define OP_CursorHint 183
16656 #define OP_ReleaseReg 184 /* synopsis: release r[P1@P2] mask P3 */
16657 #define OP_Noop 185
16658 #define OP_Explain 186
16659 #define OP_Abortable 187
 
 
16660
16661 /* Properties such as "out2" or "jump" that are specified in
16662 ** comments following the "case" for each opcode in the vdbe.c
16663 ** are encoded into bitvectors as follows:
16664 */
@@ -16690,12 +16728,12 @@
16690 /* 136 */ 0x00, 0x40, 0x04, 0x04, 0x00, 0x40, 0x50, 0x40,\
16691 /* 144 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\
16692 /* 152 */ 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\
16693 /* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
16694 /* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x50,\
16695 /* 176 */ 0x40, 0x00, 0x10, 0x10, 0x02, 0x00, 0x00, 0x00,\
16696 /* 184 */ 0x00, 0x00, 0x00, 0x00,}
16697
16698 /* The resolve3P2Values() routine is able to run faster if it knows
16699 ** the value of the largest JUMP opcode. The smaller the maximum
16700 ** JUMP opcode the better, so the mkopcodeh.tcl script that
16701 ** generated this include file strives to group all JUMP opcodes
@@ -17952,15 +17990,15 @@
17952 {nArg, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_DIRECTONLY|SQLITE_FUNC_UNSAFE, \
17953 SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
17954 #define MFUNCTION(zName, nArg, xPtr, xFunc) \
17955 {nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \
17956 xPtr, 0, xFunc, 0, 0, 0, #zName, {0} }
17957 #define JFUNCTION(zName, nArg, bUseCache, bWS, bRS, iArg, xFunc) \
17958 {nArg, SQLITE_FUNC_BUILTIN|SQLITE_DETERMINISTIC|SQLITE_FUNC_CONSTANT|\
17959 SQLITE_UTF8|((bUseCache)*SQLITE_FUNC_RUNONLY)|\
17960 ((bRS)*SQLITE_SUBTYPE)|((bWS)*SQLITE_RESULT_SUBTYPE), \
17961 SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
17962 #define INLINE_FUNC(zName, nArg, iArg, mFlags) \
17963 {nArg, SQLITE_FUNC_BUILTIN|\
17964 SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \
17965 SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} }
17966 #define TEST_FUNC(zName, nArg, iArg, mFlags) \
@@ -18704,10 +18742,11 @@
18704 int iDistinct; /* Ephemeral table used to enforce DISTINCT */
18705 int iDistAddr; /* Address of OP_OpenEphemeral */
18706 int iOBTab; /* Ephemeral table to implement ORDER BY */
18707 u8 bOBPayload; /* iOBTab has payload columns separate from key */
18708 u8 bOBUnique; /* Enforce uniqueness on iOBTab keys */
 
18709 } *aFunc;
18710 int nFunc; /* Number of entries in aFunc[] */
18711 u32 selId; /* Select to which this AggInfo belongs */
18712 #ifdef SQLITE_DEBUG
18713 Select *pSelect; /* SELECT statement that this AggInfo supports */
@@ -19237,10 +19276,11 @@
19237 } uNC;
19238 NameContext *pNext; /* Next outer name context. NULL for outermost */
19239 int nRef; /* Number of names resolved by this context */
19240 int nNcErr; /* Number of errors encountered while resolving names */
19241 int ncFlags; /* Zero or more NC_* flags defined below */
 
19242 Select *pWinSelect; /* SELECT statement for any window functions */
19243 };
19244
19245 /*
19246 ** Allowed values for the NameContext, ncFlags field.
@@ -19953,10 +19993,13 @@
19953 ** 2. Use sqlite3RCStrUnref() to free an RCStr string rather than
19954 ** sqlite3_free()
19955 **
19956 ** 3. Make a (read-only) copy of a read-only RCStr string using
19957 ** sqlite3RCStrRef().
 
 
 
19958 */
19959 struct RCStr {
19960 u64 nRCRef; /* Number of references */
19961 /* Total structure size should be a multiple of 8 bytes for alignment */
19962 };
@@ -20011,10 +20054,13 @@
20011 u8 bOpenUri; /* True to interpret filenames as URIs */
20012 u8 bUseCis; /* Use covering indices for full-scans */
20013 u8 bSmallMalloc; /* Avoid large memory allocations if true */
20014 u8 bExtraSchemaChecks; /* Verify type,name,tbl_name in schema */
20015 u8 bUseLongDouble; /* Make use of long double */
 
 
 
20016 int mxStrlen; /* Maximum string length */
20017 int neverCorrupt; /* Database is always well-formed */
20018 int szLookaside; /* Default lookaside buffer size */
20019 int nLookaside; /* Default lookaside buffer count */
20020 int nStmtSpill; /* Stmt-journal spill-to-disk threshold */
@@ -20637,19 +20683,21 @@
20637 SQLITE_PRIVATE void sqlite3ExprAddFunctionOrderBy(Parse*,Expr*,ExprList*);
20638 SQLITE_PRIVATE void sqlite3ExprOrderByAggregateError(Parse*,Expr*);
20639 SQLITE_PRIVATE void sqlite3ExprFunctionUsable(Parse*,const Expr*,const FuncDef*);
20640 SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
20641 SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
 
20642 SQLITE_PRIVATE void sqlite3ExprDeferredDelete(Parse*, Expr*);
20643 SQLITE_PRIVATE void sqlite3ExprUnmapAndDelete(Parse*, Expr*);
20644 SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
20645 SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
20646 SQLITE_PRIVATE Select *sqlite3ExprListToValues(Parse*, int, ExprList*);
20647 SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList*,int,int);
20648 SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,const Token*,int);
20649 SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*);
20650 SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*);
 
20651 SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*);
20652 SQLITE_PRIVATE int sqlite3IndexHasDuplicateRootPage(Index*);
20653 SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**);
20654 SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**);
20655 SQLITE_PRIVATE int sqlite3InitOne(sqlite3*, int, char**, u32);
@@ -20736,10 +20784,11 @@
20736 SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask);
20737 #endif
20738 SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int);
20739 SQLITE_PRIVATE void sqlite3CodeDropTable(Parse*, Table*, int, int);
20740 SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*);
 
20741 SQLITE_PRIVATE void sqlite3FreeIndex(sqlite3*, Index*);
20742 #ifndef SQLITE_OMIT_AUTOINCREMENT
20743 SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse);
20744 SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse);
20745 #else
@@ -20772,10 +20821,11 @@
20772 SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
20773 SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*);
20774 SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
20775 Expr*,ExprList*,u32,Expr*);
20776 SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*);
 
20777 SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*);
20778 SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, Trigger*);
20779 SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
20780 #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
20781 SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,char*);
@@ -20998,10 +21048,11 @@
20998 #ifndef SQLITE_OMIT_UTF16
20999 SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nChar);
21000 #endif
21001 SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte);
21002 SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**);
 
21003 SQLITE_PRIVATE LogEst sqlite3LogEst(u64);
21004 SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst,LogEst);
21005 SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double);
21006 SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst);
21007 SQLITE_PRIVATE VList *sqlite3VListAdd(sqlite3*,VList*,const char*,int,int);
@@ -21344,10 +21395,11 @@
21344 #ifndef SQLITE_OMIT_CTE
21345 SQLITE_PRIVATE Cte *sqlite3CteNew(Parse*,Token*,ExprList*,Select*,u8);
21346 SQLITE_PRIVATE void sqlite3CteDelete(sqlite3*,Cte*);
21347 SQLITE_PRIVATE With *sqlite3WithAdd(Parse*,With*,Cte*);
21348 SQLITE_PRIVATE void sqlite3WithDelete(sqlite3*,With*);
 
21349 SQLITE_PRIVATE With *sqlite3WithPush(Parse*, With*, u8);
21350 #else
21351 # define sqlite3CteNew(P,T,E,S) ((void*)0)
21352 # define sqlite3CteDelete(D,C)
21353 # define sqlite3CteWithAdd(P,W,C) ((void*)0)
@@ -22721,10 +22773,13 @@
22721 SQLITE_USE_URI, /* bOpenUri */
22722 SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */
22723 0, /* bSmallMalloc */
22724 1, /* bExtraSchemaChecks */
22725 sizeof(LONGDOUBLE_TYPE)>8, /* bUseLongDouble */
 
 
 
22726 0x7ffffffe, /* mxStrlen */
22727 0, /* neverCorrupt */
22728 SQLITE_DEFAULT_LOOKASIDE, /* szLookaside, nLookaside */
22729 SQLITE_STMTJRNL_SPILL, /* nStmtSpill */
22730 {0,0,0,0,0,0,0,0}, /* m */
@@ -25055,10 +25110,16 @@
25055 n = sqlite3_value_bytes(argv[i]);
25056 if( z==0 || parseModifier(context, (char*)z, n, p, i) ) return 1;
25057 }
25058 computeJD(p);
25059 if( p->isError || !validJulianDay(p->iJD) ) return 1;
 
 
 
 
 
 
25060 return 0;
25061 }
25062
25063
25064 /*
@@ -32083,11 +32144,11 @@
32083 va_end(ap);
32084 }
32085
32086
32087 /*****************************************************************************
32088 ** Reference counted string storage
32089 *****************************************************************************/
32090
32091 /*
32092 ** Increase the reference count of the string by one.
32093 **
@@ -32935,11 +32996,11 @@
32935 pX = pExpr->pLeft;
32936 assert( ExprUseXList(pExpr) );
32937 assert( pExpr->x.pList->nExpr==2 );
32938 pY = pExpr->x.pList->a[0].pExpr;
32939 pZ = pExpr->x.pList->a[1].pExpr;
32940 sqlite3TreeViewLine(pView, "BETWEEN");
32941 sqlite3TreeViewExpr(pView, pX, 1);
32942 sqlite3TreeViewExpr(pView, pY, 1);
32943 sqlite3TreeViewExpr(pView, pZ, 0);
32944 break;
32945 }
@@ -34070,11 +34131,42 @@
34070 || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; }
34071 }
34072 return c;
34073 }
34074
34075
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34076
34077
34078 /*
34079 ** If the TRANSLATE_TRACE macro is defined, the value of each Mem is
34080 ** printed on stderr on the way into and out of sqlite3VdbeMemTranslate().
@@ -36839,17 +36931,19 @@
36839 /* 176 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
36840 /* 177 */ "VRename" OpHelp(""),
36841 /* 178 */ "Pagecount" OpHelp(""),
36842 /* 179 */ "MaxPgcnt" OpHelp(""),
36843 /* 180 */ "ClrSubtype" OpHelp("r[P1].subtype = 0"),
36844 /* 181 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"),
36845 /* 182 */ "Trace" OpHelp(""),
36846 /* 183 */ "CursorHint" OpHelp(""),
36847 /* 184 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"),
36848 /* 185 */ "Noop" OpHelp(""),
36849 /* 186 */ "Explain" OpHelp(""),
36850 /* 187 */ "Abortable" OpHelp(""),
 
 
36851 };
36852 return azName[i];
36853 }
36854 #endif
36855
@@ -41891,11 +41985,17 @@
41891 return SQLITE_OK;
41892 }
41893 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
41894 case SQLITE_FCNTL_LOCK_TIMEOUT: {
41895 int iOld = pFile->iBusyTimeout;
 
41896 pFile->iBusyTimeout = *(int*)pArg;
 
 
 
 
 
41897 *(int*)pArg = iOld;
41898 return SQLITE_OK;
41899 }
41900 #endif
41901 #if SQLITE_MAX_MMAP_SIZE>0
@@ -42144,10 +42244,29 @@
42144 ** zFilename
42145 **
42146 ** Either unixShmNode.pShmMutex must be held or unixShmNode.nRef==0 and
42147 ** unixMutexHeld() is true when reading or writing any other field
42148 ** in this structure.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42149 */
42150 struct unixShmNode {
42151 unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */
42152 sqlite3_mutex *pShmMutex; /* Mutex to access this object */
42153 char *zFilename; /* Name of the mmapped file */
@@ -42157,14 +42276,15 @@
42157 u8 isReadonly; /* True if read-only */
42158 u8 isUnlocked; /* True if no DMS lock held */
42159 char **apRegion; /* Array of mapped shared-memory regions */
42160 int nRef; /* Number of unixShm objects pointing to this */
42161 unixShm *pFirst; /* All unixShm objects pointing to this */
 
 
 
42162 int aLock[SQLITE_SHM_NLOCK]; /* # shared locks on slot, -1==excl lock */
42163 #ifdef SQLITE_DEBUG
42164 u8 exclMask; /* Mask of exclusive locks held */
42165 u8 sharedMask; /* Mask of shared locks held */
42166 u8 nextShmId; /* Next available unixShm.id value */
42167 #endif
42168 };
42169
42170 /*
@@ -42243,20 +42363,33 @@
42243 ){
42244 unixShmNode *pShmNode; /* Apply locks to this open shared-memory segment */
42245 struct flock f; /* The posix advisory locking structure */
42246 int rc = SQLITE_OK; /* Result code form fcntl() */
42247
42248 /* Access to the unixShmNode object is serialized by the caller */
42249 pShmNode = pFile->pInode->pShmNode;
42250 assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) );
42251 assert( pShmNode->nRef>0 || unixMutexHeld() );
 
 
 
 
 
 
 
 
 
 
 
 
 
42252
42253 /* Shared locks never span more than one byte */
42254 assert( n==1 || lockType!=F_RDLCK );
42255
42256 /* Locks are within range */
42257 assert( n>=1 && n<=SQLITE_SHM_NLOCK );
 
42258
42259 if( pShmNode->hShm>=0 ){
42260 int res;
42261 /* Initialize the locking parameters */
42262 f.l_type = lockType;
@@ -42263,50 +42396,39 @@
42263 f.l_whence = SEEK_SET;
42264 f.l_start = ofst;
42265 f.l_len = n;
42266 res = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile);
42267 if( res==-1 ){
42268 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
42269 rc = (pFile->iBusyTimeout ? SQLITE_BUSY_TIMEOUT : SQLITE_BUSY);
42270 #else
42271 rc = SQLITE_BUSY;
42272 #endif
42273 }
42274 }
42275
42276 /* Update the global lock state and do debug tracing */
42277 #ifdef SQLITE_DEBUG
42278 { u16 mask;
42279 OSTRACE(("SHM-LOCK "));
42280 mask = ofst>31 ? 0xffff : (1<<(ofst+n)) - (1<<ofst);
42281 if( rc==SQLITE_OK ){
42282 if( lockType==F_UNLCK ){
42283 OSTRACE(("unlock %d ok", ofst));
42284 pShmNode->exclMask &= ~mask;
42285 pShmNode->sharedMask &= ~mask;
42286 }else if( lockType==F_RDLCK ){
42287 OSTRACE(("read-lock %d ok", ofst));
42288 pShmNode->exclMask &= ~mask;
42289 pShmNode->sharedMask |= mask;
42290 }else{
42291 assert( lockType==F_WRLCK );
42292 OSTRACE(("write-lock %d ok", ofst));
42293 pShmNode->exclMask |= mask;
42294 pShmNode->sharedMask &= ~mask;
42295 }
42296 }else{
42297 if( lockType==F_UNLCK ){
42298 OSTRACE(("unlock %d failed", ofst));
42299 }else if( lockType==F_RDLCK ){
42300 OSTRACE(("read-lock failed"));
42301 }else{
42302 assert( lockType==F_WRLCK );
42303 OSTRACE(("write-lock %d failed", ofst));
42304 }
42305 }
42306 OSTRACE((" - afterwards %03x,%03x\n",
42307 pShmNode->sharedMask, pShmNode->exclMask));
42308 }
42309 #endif
42310
42311 return rc;
42312 }
@@ -42340,10 +42462,15 @@
42340 if( p && ALWAYS(p->nRef==0) ){
42341 int nShmPerMap = unixShmRegionPerMap();
42342 int i;
42343 assert( p->pInode==pFd->pInode );
42344 sqlite3_mutex_free(p->pShmMutex);
 
 
 
 
 
42345 for(i=0; i<p->nRegion; i+=nShmPerMap){
42346 if( p->hShm>=0 ){
42347 osMunmap(p->apRegion[i], p->szRegion);
42348 }else{
42349 sqlite3_free(p->apRegion[i]);
@@ -42399,11 +42526,24 @@
42399 }else if( lock.l_type==F_UNLCK ){
42400 if( pShmNode->isReadonly ){
42401 pShmNode->isUnlocked = 1;
42402 rc = SQLITE_READONLY_CANTINIT;
42403 }else{
 
 
 
 
 
 
 
 
 
 
42404 rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1);
 
 
 
42405 /* The first connection to attach must truncate the -shm file. We
42406 ** truncate to 3 bytes (an arbitrary small number, less than the
42407 ** -shm header size) rather than 0 as a system debugging aid, to
42408 ** help detect if a -shm file truncation is legitimate or is the work
42409 ** or a rogue process. */
@@ -42520,10 +42660,22 @@
42520 pShmNode->pShmMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
42521 if( pShmNode->pShmMutex==0 ){
42522 rc = SQLITE_NOMEM_BKPT;
42523 goto shm_open_err;
42524 }
 
 
 
 
 
 
 
 
 
 
 
 
42525 }
42526
42527 if( pInode->bProcessLock==0 ){
42528 if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
42529 pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT|O_NOFOLLOW,
@@ -42741,13 +42893,15 @@
42741 **
42742 ** assert( assertLockingArrayOk(pShmNode) );
42743 */
42744 #ifdef SQLITE_DEBUG
42745 static int assertLockingArrayOk(unixShmNode *pShmNode){
 
 
 
42746 unixShm *pX;
42747 int aLock[SQLITE_SHM_NLOCK];
42748 assert( sqlite3_mutex_held(pShmNode->pShmMutex) );
42749
42750 memset(aLock, 0, sizeof(aLock));
42751 for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
42752 int i;
42753 for(i=0; i<SQLITE_SHM_NLOCK; i++){
@@ -42761,17 +42915,18 @@
42761 }
42762 }
42763
42764 assert( 0==memcmp(pShmNode->aLock, aLock, sizeof(aLock)) );
42765 return (memcmp(pShmNode->aLock, aLock, sizeof(aLock))==0);
 
42766 }
42767 #endif
42768
42769 /*
42770 ** Change the lock state for a shared-memory segment.
42771 **
42772 ** Note that the relationship between SHAREd and EXCLUSIVE locks is a little
42773 ** different here than in posix. In xShmLock(), one can go from unlocked
42774 ** to shared and back or from unlocked to exclusive and back. But one may
42775 ** not go from shared to exclusive or from exclusive to shared.
42776 */
42777 static int unixShmLock(
@@ -42782,11 +42937,11 @@
42782 ){
42783 unixFile *pDbFd = (unixFile*)fd; /* Connection holding shared memory */
42784 unixShm *p; /* The shared memory being locked */
42785 unixShmNode *pShmNode; /* The underlying file iNode */
42786 int rc = SQLITE_OK; /* Result code */
42787 u16 mask; /* Mask of locks to take or release */
42788 int *aLock;
42789
42790 p = pDbFd->pShm;
42791 if( p==0 ) return SQLITE_IOERR_SHMLOCK;
42792 pShmNode = p->pShmNode;
@@ -42817,92 +42972,154 @@
42817 ** held.
42818 **
42819 ** It is not permitted to block on the RECOVER lock.
42820 */
42821 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
42822 assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || (
42823 (ofst!=2) /* not RECOVER */
42824 && (ofst!=1 || (p->exclMask|p->sharedMask)==0)
42825 && (ofst!=0 || (p->exclMask|p->sharedMask)<3)
42826 && (ofst<3 || (p->exclMask|p->sharedMask)<(1<<ofst))
42827 ));
42828 #endif
42829
42830 mask = (1<<(ofst+n)) - (1<<ofst);
42831 assert( n>1 || mask==(1<<ofst) );
42832 sqlite3_mutex_enter(pShmNode->pShmMutex);
42833 assert( assertLockingArrayOk(pShmNode) );
42834 if( flags & SQLITE_SHM_UNLOCK ){
42835 if( (p->exclMask|p->sharedMask) & mask ){
42836 int ii;
42837 int bUnlock = 1;
42838
42839 for(ii=ofst; ii<ofst+n; ii++){
42840 if( aLock[ii]>((p->sharedMask & (1<<ii)) ? 1 : 0) ){
42841 bUnlock = 0;
42842 }
42843 }
42844
42845 if( bUnlock ){
42846 rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n);
42847 if( rc==SQLITE_OK ){
42848 memset(&aLock[ofst], 0, sizeof(int)*n);
42849 }
42850 }else if( ALWAYS(p->sharedMask & (1<<ofst)) ){
42851 assert( n==1 && aLock[ofst]>1 );
42852 aLock[ofst]--;
42853 }
42854
42855 /* Undo the local locks */
42856 if( rc==SQLITE_OK ){
42857 p->exclMask &= ~mask;
42858 p->sharedMask &= ~mask;
42859 }
42860 }
42861 }else if( flags & SQLITE_SHM_SHARED ){
42862 assert( n==1 );
42863 assert( (p->exclMask & (1<<ofst))==0 );
42864 if( (p->sharedMask & mask)==0 ){
42865 if( aLock[ofst]<0 ){
42866 rc = SQLITE_BUSY;
42867 }else if( aLock[ofst]==0 ){
42868 rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n);
42869 }
42870
42871 /* Get the local shared locks */
42872 if( rc==SQLITE_OK ){
42873 p->sharedMask |= mask;
42874 aLock[ofst]++;
42875 }
42876 }
42877 }else{
42878 /* Make sure no sibling connections hold locks that will block this
42879 ** lock. If any do, return SQLITE_BUSY right away. */
42880 int ii;
42881 for(ii=ofst; ii<ofst+n; ii++){
42882 assert( (p->sharedMask & mask)==0 );
42883 if( ALWAYS((p->exclMask & (1<<ii))==0) && aLock[ii] ){
42884 rc = SQLITE_BUSY;
42885 break;
42886 }
42887 }
42888
42889 /* Get the exclusive locks at the system level. Then if successful
42890 ** also update the in-memory values. */
42891 if( rc==SQLITE_OK ){
42892 rc = unixShmSystemLock(pDbFd, F_WRLCK, ofst+UNIX_SHM_BASE, n);
42893 if( rc==SQLITE_OK ){
42894 assert( (p->sharedMask & mask)==0 );
42895 p->exclMask |= mask;
42896 for(ii=ofst; ii<ofst+n; ii++){
42897 aLock[ii] = -1;
42898 }
42899 }
42900 }
42901 }
42902 assert( assertLockingArrayOk(pShmNode) );
42903 sqlite3_mutex_leave(pShmNode->pShmMutex);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42904 OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n",
42905 p->id, osGetpid(0), p->sharedMask, p->exclMask));
42906 return rc;
42907 }
42908
@@ -66236,10 +66453,23 @@
66236 *pp = p;
66237 return rc;
66238 }
66239
66240 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
 
 
 
 
 
 
 
 
 
 
 
 
 
66241 /*
66242 ** Attempt to enable blocking locks. Blocking locks are enabled only if (a)
66243 ** they are supported by the VFS, and (b) the database handle is configured
66244 ** with a busy-timeout. Return 1 if blocking locks are successfully enabled,
66245 ** or 0 otherwise.
@@ -66247,15 +66477,11 @@
66247 static int walEnableBlocking(Wal *pWal){
66248 int res = 0;
66249 if( pWal->db ){
66250 int tmout = pWal->db->busyTimeout;
66251 if( tmout ){
66252 int rc;
66253 rc = sqlite3OsFileControl(
66254 pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout
66255 );
66256 res = (rc==SQLITE_OK);
66257 }
66258 }
66259 return res;
66260 }
66261
@@ -66300,24 +66526,14 @@
66300 */
66301 SQLITE_PRIVATE void sqlite3WalDb(Wal *pWal, sqlite3 *db){
66302 pWal->db = db;
66303 }
66304
66305 /*
66306 ** Take an exclusive WRITE lock. Blocking if so configured.
66307 */
66308 static int walLockWriter(Wal *pWal){
66309 int rc;
66310 walEnableBlocking(pWal);
66311 rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
66312 walDisableBlocking(pWal);
66313 return rc;
66314 }
66315 #else
66316 # define walEnableBlocking(x) 0
66317 # define walDisableBlocking(x)
66318 # define walLockWriter(pWal) walLockExclusive((pWal), WAL_WRITE_LOCK, 1)
66319 # define sqlite3WalDb(pWal, db)
66320 #endif /* ifdef SQLITE_ENABLE_SETLK_TIMEOUT */
66321
66322
66323 /*
@@ -66914,19 +67130,22 @@
66914 walUnlockShared(pWal, WAL_WRITE_LOCK);
66915 rc = SQLITE_READONLY_RECOVERY;
66916 }
66917 }else{
66918 int bWriteLock = pWal->writeLock;
66919 if( bWriteLock || SQLITE_OK==(rc = walLockWriter(pWal)) ){
 
 
66920 pWal->writeLock = 1;
66921 if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){
66922 badHdr = walIndexTryHdr(pWal, pChanged);
66923 if( badHdr ){
66924 /* If the wal-index header is still malformed even while holding
66925 ** a WRITE lock, it can only mean that the header is corrupted and
66926 ** needs to be reconstructed. So run recovery to do exactly that.
66927 */
 
66928 rc = walIndexRecover(pWal);
66929 *pChanged = 1;
66930 }
66931 }
66932 if( bWriteLock==0 ){
@@ -67189,10 +67408,13 @@
67189 u32 mxReadMark; /* Largest aReadMark[] value */
67190 int mxI; /* Index of largest aReadMark[] value */
67191 int i; /* Loop counter */
67192 int rc = SQLITE_OK; /* Return code */
67193 u32 mxFrame; /* Wal frame to lock to */
 
 
 
67194
67195 assert( pWal->readLock<0 ); /* Not currently locked */
67196
67197 /* useWal may only be set for read/write connections */
67198 assert( (pWal->readOnly & WAL_SHM_RDONLY)==0 || useWal==0 );
@@ -67219,18 +67441,35 @@
67219 if( cnt>100 ){
67220 VVA_ONLY( pWal->lockError = 1; )
67221 return SQLITE_PROTOCOL;
67222 }
67223 if( cnt>=10 ) nDelay = (cnt-9)*(cnt-9)*39;
 
 
 
 
 
 
 
 
 
 
 
 
 
67224 sqlite3OsSleep(pWal->pVfs, nDelay);
67225 }
67226
67227 if( !useWal ){
67228 assert( rc==SQLITE_OK );
67229 if( pWal->bShmUnreliable==0 ){
67230 rc = walIndexReadHdr(pWal, pChanged);
67231 }
 
 
 
 
67232 if( rc==SQLITE_BUSY ){
67233 /* If there is not a recovery running in another thread or process
67234 ** then convert BUSY errors to WAL_RETRY. If recovery is known to
67235 ** be running, convert BUSY to BUSY_RECOVERY. There is a race here
67236 ** which might cause WAL_RETRY to be returned even if BUSY_RECOVERY
@@ -67341,13 +67580,16 @@
67341 if( mxI==0 ){
67342 assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 );
67343 return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTINIT;
67344 }
67345
 
67346 rc = walLockShared(pWal, WAL_READ_LOCK(mxI));
 
67347 if( rc ){
67348 return rc==SQLITE_BUSY ? WAL_RETRY : rc;
 
67349 }
67350 /* Now that the read-lock has been obtained, check that neither the
67351 ** value in the aReadMark[] array or the contents of the wal-index
67352 ** header have changed.
67353 **
@@ -68436,14 +68678,13 @@
68436 assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
68437
68438 if( pWal->readOnly ) return SQLITE_READONLY;
68439 WALTRACE(("WAL%p: checkpoint begins\n", pWal));
68440
68441 /* Enable blocking locks, if possible. If blocking locks are successfully
68442 ** enabled, set xBusy2=0 so that the busy-handler is never invoked. */
68443 sqlite3WalDb(pWal, db);
68444 (void)walEnableBlocking(pWal);
68445
68446 /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive
68447 ** "checkpoint" lock on the database file.
68448 ** EVIDENCE-OF: R-10421-19736 If any other process is running a
68449 ** checkpoint operation at the same time, the lock cannot be obtained and
@@ -68480,13 +68721,18 @@
68480
68481
68482 /* Read the wal-index header. */
68483 SEH_TRY {
68484 if( rc==SQLITE_OK ){
 
 
 
 
 
68485 walDisableBlocking(pWal);
68486 rc = walIndexReadHdr(pWal, &isChanged);
68487 (void)walEnableBlocking(pWal);
68488 if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){
68489 sqlite3OsUnfetch(pWal->pDbFd, 0, 0);
68490 }
68491 }
68492
@@ -68819,11 +69065,11 @@
68819 ** 20 1 Bytes of unused space at the end of each page
68820 ** 21 1 Max embedded payload fraction (must be 64)
68821 ** 22 1 Min embedded payload fraction (must be 32)
68822 ** 23 1 Min leaf payload fraction (must be 32)
68823 ** 24 4 File change counter
68824 ** 28 4 Reserved for future use
68825 ** 32 4 First freelist page
68826 ** 36 4 Number of freelist pages in the file
68827 ** 40 60 15 4-byte meta values passed to higher layers
68828 **
68829 ** 40 4 Schema cookie
@@ -85370,10 +85616,14 @@
85370 }
85371 case P4_VTAB : {
85372 if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4);
85373 break;
85374 }
 
 
 
 
85375 }
85376 }
85377
85378 /*
85379 ** Free the space allocated for aOp and any p4 values allocated for the
@@ -85497,11 +85747,11 @@
85497 Op *pOp,
85498 const char *zP4,
85499 int n
85500 ){
85501 if( pOp->p4type ){
85502 freeP4(p->db, pOp->p4type, pOp->p4.p);
85503 pOp->p4type = 0;
85504 pOp->p4.p = 0;
85505 }
85506 if( n<0 ){
85507 sqlite3VdbeChangeP4(p, (int)(pOp - p->aOp), zP4, n);
@@ -89620,11 +89870,19 @@
89620 SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
89621 int i;
89622 int rc = SQLITE_OK;
89623 Vdbe *p = (Vdbe*)pStmt;
89624 #if SQLITE_THREADSAFE
89625 sqlite3_mutex *mutex = ((Vdbe*)pStmt)->db->mutex;
 
 
 
 
 
 
 
 
89626 #endif
89627 sqlite3_mutex_enter(mutex);
89628 for(i=0; i<p->nVar; i++){
89629 sqlite3VdbeMemRelease(&p->aVar[i]);
89630 p->aVar[i].flags = MEM_Null;
@@ -90410,13 +90668,12 @@
90410 ** pointer to it.
90411 */
90412 SQLITE_API void *sqlite3_user_data(sqlite3_context *p){
90413 #ifdef SQLITE_ENABLE_API_ARMOR
90414 if( p==0 ) return 0;
90415 #else
90416 assert( p && p->pFunc );
90417 #endif
90418 return p->pFunc->pUserData;
90419 }
90420
90421 /*
90422 ** Extract the user data from a sqlite3_context structure and return a
@@ -94231,11 +94488,11 @@
94231 */
94232 case OP_AddImm: { /* in1 */
94233 pIn1 = &aMem[pOp->p1];
94234 memAboutToChange(p, pIn1);
94235 sqlite3VdbeMemIntegerify(pIn1);
94236 pIn1->u.i += pOp->p2;
94237 break;
94238 }
94239
94240 /* Opcode: MustBeInt P1 P2 * * *
94241 **
@@ -100377,28 +100634,27 @@
100377 const sqlite3_module *pModule;
100378 char *zErr = 0;
100379
100380 pOut = &aMem[pOp->p2];
100381 sqlite3VdbeMemSetNull(pOut); /* Innocent until proven guilty */
100382 assert( pOp->p4type==P4_TABLE );
100383 pTab = pOp->p4.pTab;
100384 assert( pTab!=0 );
 
100385 assert( IsVirtual(pTab) );
100386 if( pTab->u.vtab.p==0 ) break;
100387 pVtab = pTab->u.vtab.p->pVtab;
100388 assert( pVtab!=0 );
100389 pModule = pVtab->pModule;
100390 assert( pModule!=0 );
100391 assert( pModule->iVersion>=4 );
100392 assert( pModule->xIntegrity!=0 );
100393 pTab->nTabRef++;
100394 sqlite3VtabLock(pTab->u.vtab.p);
100395 assert( pOp->p1>=0 && pOp->p1<db->nDb );
100396 rc = pModule->xIntegrity(pVtab, db->aDb[pOp->p1].zDbSName, pTab->zName,
100397 pOp->p3, &zErr);
100398 sqlite3VtabUnlock(pTab->u.vtab.p);
100399 sqlite3DeleteTable(db, pTab);
100400 if( rc ){
100401 sqlite3_free(zErr);
100402 goto abort_due_to_error;
100403 }
100404 if( zErr ){
@@ -100519,10 +100775,11 @@
100519 case OP_VColumn: { /* ncycle */
100520 sqlite3_vtab *pVtab;
100521 const sqlite3_module *pModule;
100522 Mem *pDest;
100523 sqlite3_context sContext;
 
100524
100525 VdbeCursor *pCur = p->apCsr[pOp->p1];
100526 assert( pCur!=0 );
100527 assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
100528 pDest = &aMem[pOp->p3];
@@ -100536,10 +100793,13 @@
100536 pModule = pVtab->pModule;
100537 assert( pModule->xColumn );
100538 memset(&sContext, 0, sizeof(sContext));
100539 sContext.pOut = pDest;
100540 sContext.enc = encoding;
 
 
 
100541 assert( pOp->p5==OPFLAG_NOCHNG || pOp->p5==0 );
100542 if( pOp->p5 & OPFLAG_NOCHNG ){
100543 sqlite3VdbeMemSetNull(pDest);
100544 pDest->flags = MEM_Null|MEM_Zero;
100545 pDest->u.nZero = 0;
@@ -100867,10 +101127,46 @@
100867 case OP_ClrSubtype: { /* in1 */
100868 pIn1 = &aMem[pOp->p1];
100869 pIn1->flags &= ~MEM_Subtype;
100870 break;
100871 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100872
100873 /* Opcode: FilterAdd P1 * P3 P4 *
100874 ** Synopsis: filter(P1) += key(P3@P4)
100875 **
100876 ** Compute a hash on the P4 registers starting with r[P3] and
@@ -105916,10 +106212,11 @@
105916
105917 n = pExpr->iColumn;
105918 assert( ExprUseYTab(pExpr) );
105919 pExTab = pExpr->y.pTab;
105920 assert( pExTab!=0 );
 
105921 if( (pExTab->tabFlags & TF_HasGenerated)!=0
105922 && (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0
105923 ){
105924 testcase( pExTab->nCol==BMS-1 );
105925 testcase( pExTab->nCol==BMS );
@@ -106518,11 +106815,11 @@
106518 ** (See ticket [b92e5e8ec2cdbaa1]).
106519 **
106520 ** If a generated column is referenced, set bits for every column
106521 ** of the table.
106522 */
106523 if( pExpr->iColumn>=0 && pMatch!=0 ){
106524 pMatch->colUsed |= sqlite3ExprColUsed(pExpr);
106525 }
106526
106527 pExpr->op = eNewExprOp;
106528 lookupname_end:
@@ -106983,15 +107280,16 @@
106983 #endif
106984 pNC2 = pNC;
106985 while( pNC2
106986 && sqlite3ReferencesSrcList(pParse, pExpr, pNC2->pSrcList)==0
106987 ){
106988 pExpr->op2++;
106989 pNC2 = pNC2->pNext;
106990 }
106991 assert( pDef!=0 || IN_RENAME_OBJECT );
106992 if( pNC2 && pDef ){
 
106993 assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg );
106994 assert( SQLITE_FUNC_ANYORDER==NC_OrderAgg );
106995 testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 );
106996 testcase( (pDef->funcFlags & SQLITE_FUNC_ANYORDER)!=0 );
106997 pNC2->ncFlags |= NC_HasAgg
@@ -107546,10 +107844,11 @@
107546 p->pOrderBy = 0;
107547 }
107548
107549 /* Recursively resolve names in all subqueries in the FROM clause
107550 */
 
107551 for(i=0; i<p->pSrc->nSrc; i++){
107552 SrcItem *pItem = &p->pSrc->a[i];
107553 if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){
107554 int nRef = pOuterNC ? pOuterNC->nRef : 0;
107555 const char *zSavedContext = pParse->zAuthContext;
@@ -107569,10 +107868,13 @@
107569 if( pOuterNC ){
107570 assert( pItem->fg.isCorrelated==0 && pOuterNC->nRef>=nRef );
107571 pItem->fg.isCorrelated = (pOuterNC->nRef>nRef);
107572 }
107573 }
 
 
 
107574 }
107575
107576 /* Set up the local name-context to pass to sqlite3ResolveExprNames() to
107577 ** resolve the result-set expression list.
107578 */
@@ -109157,13 +109459,11 @@
109157 assert( pExpr->op==TK_FUNCTION );
109158 assert( pExpr->pLeft==0 );
109159 assert( ExprUseXList(pExpr) );
109160 if( pExpr->x.pList==0 || NEVER(pExpr->x.pList->nExpr==0) ){
109161 /* Ignore ORDER BY on zero-argument aggregates */
109162 sqlite3ParserAddCleanup(pParse,
109163 (void(*)(sqlite3*,void*))sqlite3ExprListDelete,
109164 pOrderBy);
109165 return;
109166 }
109167 if( IsWindowFunc(pExpr) ){
109168 sqlite3ExprOrderByAggregateError(pParse, pExpr);
109169 sqlite3ExprListDelete(db, pOrderBy);
@@ -109340,10 +109640,13 @@
109340 }
109341 }
109342 SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
109343 if( p ) sqlite3ExprDeleteNN(db, p);
109344 }
 
 
 
109345
109346 /*
109347 ** Clear both elements of an OnOrUsing object
109348 */
109349 SQLITE_PRIVATE void sqlite3ClearOnOrUsing(sqlite3 *db, OnOrUsing *p){
@@ -109365,13 +109668,11 @@
109365 **
109366 ** The deferred delete is (currently) implemented by adding the
109367 ** pExpr to the pParse->pConstExpr list with a register number of 0.
109368 */
109369 SQLITE_PRIVATE void sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){
109370 sqlite3ParserAddCleanup(pParse,
109371 (void(*)(sqlite3*,void*))sqlite3ExprDelete,
109372 pExpr);
109373 }
109374
109375 /* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the
109376 ** expression.
109377 */
@@ -110172,10 +110473,13 @@
110172 }while( --i>0 );
110173 sqlite3DbNNFreeNN(db, pList);
110174 }
110175 SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
110176 if( pList ) exprListDeleteNN(db, pList);
 
 
 
110177 }
110178
110179 /*
110180 ** Return the bitwise-OR of all Expr.flags fields in the given
110181 ** ExprList.
@@ -114703,17 +115007,18 @@
114703 return WRC_Continue;
114704 }
114705 case TK_AGG_FUNCTION: {
114706 if( (pNC->ncFlags & NC_InAggFunc)==0
114707 && pWalker->walkerDepth==pExpr->op2
 
114708 ){
114709 /* Check to see if pExpr is a duplicate of another aggregate
114710 ** function that is already in the pAggInfo structure
114711 */
114712 struct AggInfo_func *pItem = pAggInfo->aFunc;
114713 for(i=0; i<pAggInfo->nFunc; i++, pItem++){
114714 if( pItem->pFExpr==pExpr ) break;
114715 if( sqlite3ExprCompare(0, pItem->pFExpr, pExpr, -1)==0 ){
114716 break;
114717 }
114718 }
114719 if( i>=pAggInfo->nFunc ){
@@ -114752,10 +115057,12 @@
114752 pItem->bOBPayload = 0;
114753 pItem->bOBUnique = ExprHasProperty(pExpr, EP_Distinct);
114754 }else{
114755 pItem->bOBPayload = 1;
114756 }
 
 
114757 }else{
114758 pItem->iOBTab = -1;
114759 }
114760 if( ExprHasProperty(pExpr, EP_Distinct) && !pItem->bOBUnique ){
114761 pItem->iDistinct = pParse->nTab++;
@@ -120856,11 +121163,11 @@
120856 ** the DEFAULT clause or the AS clause of a generated column.
120857 ** Return NULL if the column has no associated expression.
120858 */
120859 SQLITE_PRIVATE Expr *sqlite3ColumnExpr(Table *pTab, Column *pCol){
120860 if( pCol->iDflt==0 ) return 0;
120861 if( NEVER(!IsOrdinaryTable(pTab)) ) return 0;
120862 if( NEVER(pTab->u.tab.pDfltList==0) ) return 0;
120863 if( NEVER(pTab->u.tab.pDfltList->nExpr<pCol->iDflt) ) return 0;
120864 return pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr;
120865 }
120866
@@ -121008,10 +121315,13 @@
121008 /* Do not delete the table until the reference count reaches zero. */
121009 assert( db!=0 );
121010 if( !pTable ) return;
121011 if( db->pnBytesFreed==0 && (--pTable->nTabRef)>0 ) return;
121012 deleteTable(db, pTable);
 
 
 
121013 }
121014
121015
121016 /*
121017 ** Unlink the given table from the hash tables and the delete the
@@ -121546,11 +121856,12 @@
121546 #endif
121547
121548 /*
121549 ** Clean up the data structures associated with the RETURNING clause.
121550 */
121551 static void sqlite3DeleteReturning(sqlite3 *db, Returning *pRet){
 
121552 Hash *pHash;
121553 pHash = &(db->aDb[1].pSchema->trigHash);
121554 sqlite3HashInsert(pHash, pRet->zName, 0);
121555 sqlite3ExprListDelete(db, pRet->pReturnEL);
121556 sqlite3DbFree(db, pRet);
@@ -121588,12 +121899,11 @@
121588 return;
121589 }
121590 pParse->u1.pReturning = pRet;
121591 pRet->pParse = pParse;
121592 pRet->pReturnEL = pList;
121593 sqlite3ParserAddCleanup(pParse,
121594 (void(*)(sqlite3*,void*))sqlite3DeleteReturning, pRet);
121595 testcase( pParse->earlyCleanup );
121596 if( db->mallocFailed ) return;
121597 sqlite3_snprintf(sizeof(pRet->zName), pRet->zName,
121598 "sqlite_returning_%p", pParse);
121599 pRet->retTrig.zName = pRet->zName;
@@ -125827,10 +126137,13 @@
125827 for(i=0; i<pWith->nCte; i++){
125828 cteClear(db, &pWith->a[i]);
125829 }
125830 sqlite3DbFree(db, pWith);
125831 }
 
 
 
125832 }
125833 #endif /* !defined(SQLITE_OMIT_CTE) */
125834
125835 /************** End of build.c ***********************************************/
125836 /************** Begin file callback.c ****************************************/
@@ -139053,11 +139366,12 @@
139053 if( NEVER(pVTab==0) ) continue;
139054 if( NEVER(pVTab->pModule==0) ) continue;
139055 if( pVTab->pModule->iVersion<4 ) continue;
139056 if( pVTab->pModule->xIntegrity==0 ) continue;
139057 sqlite3VdbeAddOp3(v, OP_VCheck, i, 3, isQuick);
139058 sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
 
139059 a1 = sqlite3VdbeAddOp1(v, OP_IsNull, 3); VdbeCoverage(v);
139060 integrityCheckResultRow(v);
139061 sqlite3VdbeJumpHere(v, a1);
139062 #endif
139063 continue;
@@ -141080,10 +141394,11 @@
141080 sqlite3BtreeLeaveAll(db);
141081 rc = sqlite3ApiExit(db, rc);
141082 assert( (rc&db->errMask)==rc );
141083 db->busyHandler.nBusy = 0;
141084 sqlite3_mutex_leave(db->mutex);
 
141085 return rc;
141086 }
141087
141088
141089 /*
@@ -141476,10 +141791,13 @@
141476 /*
141477 ** Delete the given Select structure and all of its substructures.
141478 */
141479 SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){
141480 if( OK_IF_ALWAYS_TRUE(p) ) clearSelect(db, p, 1);
 
 
 
141481 }
141482
141483 /*
141484 ** Return a pointer to the right-most SELECT statement in a compound.
141485 */
@@ -144497,13 +144815,11 @@
144497
144498 multi_select_end:
144499 pDest->iSdst = dest.iSdst;
144500 pDest->nSdst = dest.nSdst;
144501 if( pDelete ){
144502 sqlite3ParserAddCleanup(pParse,
144503 (void(*)(sqlite3*,void*))sqlite3SelectDelete,
144504 pDelete);
144505 }
144506 return rc;
144507 }
144508 #endif /* SQLITE_OMIT_COMPOUND_SELECT */
144509
@@ -145050,12 +145366,11 @@
145050 sqlite3VdbeResolveLabel(v, labelEnd);
145051
145052 /* Make arrangements to free the 2nd and subsequent arms of the compound
145053 ** after the parse has finished */
145054 if( pSplit->pPrior ){
145055 sqlite3ParserAddCleanup(pParse,
145056 (void(*)(sqlite3*,void*))sqlite3SelectDelete, pSplit->pPrior);
145057 }
145058 pSplit->pPrior = pPrior;
145059 pPrior->pNext = pSplit;
145060 sqlite3ExprListDelete(db, pPrior->pOrderBy);
145061 pPrior->pOrderBy = 0;
@@ -145872,13 +146187,11 @@
145872 */
145873 if( ALWAYS(pSubitem->pTab!=0) ){
145874 Table *pTabToDel = pSubitem->pTab;
145875 if( pTabToDel->nTabRef==1 ){
145876 Parse *pToplevel = sqlite3ParseToplevel(pParse);
145877 sqlite3ParserAddCleanup(pToplevel,
145878 (void(*)(sqlite3*,void*))sqlite3DeleteTable,
145879 pTabToDel);
145880 testcase( pToplevel->earlyCleanup );
145881 }else{
145882 pTabToDel->nTabRef--;
145883 }
145884 pSubitem->pTab = 0;
@@ -146921,12 +147234,11 @@
146921 ** calling this routine, Instead, use only the return value.
146922 */
146923 SQLITE_PRIVATE With *sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){
146924 if( pWith ){
146925 if( bFree ){
146926 pWith = (With*)sqlite3ParserAddCleanup(pParse,
146927 (void(*)(sqlite3*,void*))sqlite3WithDelete,
146928 pWith);
146929 if( pWith==0 ) return 0;
146930 }
146931 if( pParse->nErr==0 ){
146932 assert( pParse->pWith!=pWith );
@@ -147955,19 +148267,23 @@
147955 KeyInfo *pKeyInfo;
147956 int nExtra = 0;
147957 assert( pFunc->pFExpr->pLeft!=0 );
147958 assert( pFunc->pFExpr->pLeft->op==TK_ORDER );
147959 assert( ExprUseXList(pFunc->pFExpr->pLeft) );
 
147960 pOBList = pFunc->pFExpr->pLeft->x.pList;
147961 if( !pFunc->bOBUnique ){
147962 nExtra++; /* One extra column for the OP_Sequence */
147963 }
147964 if( pFunc->bOBPayload ){
147965 /* extra columns for the function arguments */
147966 assert( ExprUseXList(pFunc->pFExpr) );
147967 nExtra += pFunc->pFExpr->x.pList->nExpr;
147968 }
 
 
 
147969 pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOBList, 0, nExtra);
147970 if( !pFunc->bOBUnique && pParse->nErr==0 ){
147971 pKeyInfo->nKeyField++;
147972 }
147973 sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
@@ -147990,20 +148306,21 @@
147990 for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
147991 ExprList *pList;
147992 assert( ExprUseXList(pF->pFExpr) );
147993 pList = pF->pFExpr->x.pList;
147994 if( pF->iOBTab>=0 ){
147995 /* For an ORDER BY aggregate, calls to OP_AggStep where deferred and
147996 ** all content was stored in emphermal table pF->iOBTab. Extract that
147997 ** content now (in ORDER BY order) and make all calls to OP_AggStep
147998 ** before doing the OP_AggFinal call. */
147999 int iTop; /* Start of loop for extracting columns */
148000 int nArg; /* Number of columns to extract */
148001 int nKey; /* Key columns to be skipped */
148002 int regAgg; /* Extract into this array */
148003 int j; /* Loop counter */
148004
 
148005 nArg = pList->nExpr;
148006 regAgg = sqlite3GetTempRange(pParse, nArg);
148007
148008 if( pF->bOBPayload==0 ){
148009 nKey = 0;
@@ -148016,10 +148333,19 @@
148016 }
148017 iTop = sqlite3VdbeAddOp1(v, OP_Rewind, pF->iOBTab); VdbeCoverage(v);
148018 for(j=nArg-1; j>=0; j--){
148019 sqlite3VdbeAddOp3(v, OP_Column, pF->iOBTab, nKey+j, regAgg+j);
148020 }
 
 
 
 
 
 
 
 
 
148021 sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i));
148022 sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
148023 sqlite3VdbeChangeP5(v, (u8)nArg);
148024 sqlite3VdbeAddOp2(v, OP_Next, pF->iOBTab, iTop+1); VdbeCoverage(v);
148025 sqlite3VdbeJumpHere(v, iTop);
@@ -148070,10 +148396,11 @@
148070 int regAggSz = 0;
148071 int regDistinct = 0;
148072 ExprList *pList;
148073 assert( ExprUseXList(pF->pFExpr) );
148074 assert( !IsWindowFunc(pF->pFExpr) );
 
148075 pList = pF->pFExpr->x.pList;
148076 if( ExprHasProperty(pF->pFExpr, EP_WinFunc) ){
148077 Expr *pFilter = pF->pFExpr->y.pWin->pFilter;
148078 if( pAggInfo->nAccumulator
148079 && (pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)
@@ -148113,10 +148440,13 @@
148113 if( !pF->bOBUnique ){
148114 regAggSz++; /* One register for OP_Sequence */
148115 }
148116 if( pF->bOBPayload ){
148117 regAggSz += nArg;
 
 
 
148118 }
148119 regAggSz++; /* One extra register to hold result of MakeRecord */
148120 regAgg = sqlite3GetTempRange(pParse, regAggSz);
148121 regDistinct = regAgg;
148122 sqlite3ExprCodeExprList(pParse, pOBList, regAgg, 0, SQLITE_ECEL_DUP);
@@ -148126,10 +148456,18 @@
148126 jj++;
148127 }
148128 if( pF->bOBPayload ){
148129 regDistinct = regAgg+jj;
148130 sqlite3ExprCodeExprList(pParse, pList, regDistinct, 0, SQLITE_ECEL_DUP);
 
 
 
 
 
 
 
 
148131 }
148132 }else if( pList ){
148133 nArg = pList->nExpr;
148134 regAgg = sqlite3GetTempRange(pParse, nArg);
148135 regDistinct = regAgg;
@@ -148330,11 +148668,12 @@
148330 }
148331
148332 /*
148333 ** Deallocate a single AggInfo object
148334 */
148335 static void agginfoFree(sqlite3 *db, AggInfo *p){
 
148336 sqlite3DbFree(db, p->aCol);
148337 sqlite3DbFree(db, p->aFunc);
148338 sqlite3DbFreeNN(db, p);
148339 }
148340
@@ -148584,13 +148923,12 @@
148584 TREETRACE(0x800,pParse,p, ("dropping superfluous ORDER BY:\n"));
148585 if( sqlite3TreeTrace & 0x800 ){
148586 sqlite3TreeViewExprList(0, p->pOrderBy, 0, "ORDERBY");
148587 }
148588 #endif
148589 sqlite3ParserAddCleanup(pParse,
148590 (void(*)(sqlite3*,void*))sqlite3ExprListDelete,
148591 p->pOrderBy);
148592 testcase( pParse->earlyCleanup );
148593 p->pOrderBy = 0;
148594 }
148595 p->selFlags &= ~SF_Distinct;
148596 p->selFlags |= SF_NoopOrderBy;
@@ -148778,13 +149116,12 @@
148778 && (p->selFlags & SF_OrderByReqd)==0 /* Condition (3) and (4) */
148779 && OptimizationEnabled(db, SQLITE_OmitOrderBy)
148780 ){
148781 TREETRACE(0x800,pParse,p,
148782 ("omit superfluous ORDER BY on %r FROM-clause subquery\n",i+1));
148783 sqlite3ParserAddCleanup(pParse,
148784 (void(*)(sqlite3*,void*))sqlite3ExprListDelete,
148785 pSub->pOrderBy);
148786 pSub->pOrderBy = 0;
148787 }
148788
148789 /* If the outer query contains a "complex" result set (that is,
148790 ** if the result set of the outer query uses functions or subqueries)
@@ -149309,12 +149646,11 @@
149309 ** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the
149310 ** SELECT statement.
149311 */
149312 pAggInfo = sqlite3DbMallocZero(db, sizeof(*pAggInfo) );
149313 if( pAggInfo ){
149314 sqlite3ParserAddCleanup(pParse,
149315 (void(*)(sqlite3*,void*))agginfoFree, pAggInfo);
149316 testcase( pParse->earlyCleanup );
149317 }
149318 if( db->mallocFailed ){
149319 goto select_end;
149320 }
@@ -160987,16 +161323,26 @@
160987 int iEnd = sqlite3VdbeCurrentAddr(v);
160988 if( pParse->db->mallocFailed ) return;
160989 for(; iStart<iEnd; iStart++, pOp++){
160990 if( pOp->p1!=iTabCur ) continue;
160991 if( pOp->opcode==OP_Column ){
 
 
 
 
 
160992 pOp->opcode = OP_Copy;
160993 pOp->p1 = pOp->p2 + iRegister;
160994 pOp->p2 = pOp->p3;
160995 pOp->p3 = 0;
160996 pOp->p5 = 2; /* Cause the MEM_Subtype flag to be cleared */
160997 }else if( pOp->opcode==OP_Rowid ){
 
 
 
 
 
160998 pOp->opcode = OP_Sequence;
160999 pOp->p1 = iAutoidxCur;
161000 #ifdef SQLITE_ALLOW_ROWID_IN_VIEW
161001 if( iAutoidxCur==0 ){
161002 pOp->opcode = OP_Null;
@@ -162319,11 +162665,12 @@
162319 nNew = sqlite3LogEst(iUpper - iLower);
162320 /* TUNING: If both iUpper and iLower are derived from the same
162321 ** sample, then assume they are 4x more selective. This brings
162322 ** the estimated selectivity more in line with what it would be
162323 ** if estimated without the use of STAT4 tables. */
162324 if( iLwrIdx==iUprIdx ) nNew -= 20; assert( 20==sqlite3LogEst(4) );
 
162325 }else{
162326 nNew = 10; assert( 10==sqlite3LogEst(2) );
162327 }
162328 if( nNew<nOut ){
162329 nOut = nNew;
@@ -182234,10 +182581,32 @@
182234 rc = SQLITE_NOTFOUND;
182235 }
182236 break;
182237 }
182238 #endif
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182239 }
182240 va_end(ap);
182241 #endif /* SQLITE_UNTESTABLE */
182242 return rc;
182243 }
@@ -202648,28 +203017,146 @@
202648 ** May you find forgiveness for yourself and forgive others.
202649 ** May you share freely, never taking more than you give.
202650 **
202651 ******************************************************************************
202652 **
202653 ** This SQLite JSON functions.
202654 **
202655 ** This file began as an extension in ext/misc/json1.c in 2015. That
202656 ** extension proved so useful that it has now been moved into the core.
202657 **
202658 ** For the time being, all JSON is stored as pure text. (We might add
202659 ** a JSONB type in the future which stores a binary encoding of JSON in
202660 ** a BLOB, but there is no support for JSONB in the current implementation.
202661 ** This implementation parses JSON text at 250 MB/s, so it is hard to see
202662 ** how JSONB might improve on that.)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202663 */
202664 #ifndef SQLITE_OMIT_JSON
202665 /* #include "sqliteInt.h" */
202666
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202667 /*
202668 ** Growing our own isspace() routine this way is twice as fast as
202669 ** the library isspace() function, resulting in a 7% overall performance
202670 ** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os).
202671 */
202672 static const char jsonIsSpace[] = {
202673 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
202674 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
202675 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -202686,15 +203173,23 @@
202686 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
202687 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
202688 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
202689 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
202690 };
202691 #define fast_isspace(x) (jsonIsSpace[(unsigned char)x])
202692
202693 /*
202694 ** Characters that are special to JSON. Control charaters,
202695 ** '"' and '\\'.
 
 
 
 
 
 
 
 
202696 */
202697 static const char jsonIsOk[256] = {
202698 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
202699 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
202700 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -202712,247 +203207,353 @@
202712 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
202713 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
202714 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
202715 };
202716
202717
202718 #if !defined(SQLITE_DEBUG) && !defined(SQLITE_COVERAGE_TEST)
202719 # define VVA(X)
202720 #else
202721 # define VVA(X) X
202722 #endif
202723
202724 /* Objects */
 
202725 typedef struct JsonString JsonString;
202726 typedef struct JsonNode JsonNode;
202727 typedef struct JsonParse JsonParse;
202728 typedef struct JsonCleanup JsonCleanup;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202729
202730 /* An instance of this object represents a JSON string
202731 ** under construction. Really, this is a generic string accumulator
202732 ** that can be and is used to create strings other than JSON.
 
 
 
 
202733 */
202734 struct JsonString {
202735 sqlite3_context *pCtx; /* Function context - put error messages here */
202736 char *zBuf; /* Append JSON content here */
202737 u64 nAlloc; /* Bytes of storage available in zBuf[] */
202738 u64 nUsed; /* Bytes of zBuf[] currently used */
202739 u8 bStatic; /* True if zBuf is static space */
202740 u8 bErr; /* True if an error has been encountered */
202741 char zSpace[100]; /* Initial static space */
202742 };
202743
202744 /* A deferred cleanup task. A list of JsonCleanup objects might be
202745 ** run when the JsonParse object is destroyed.
202746 */
202747 struct JsonCleanup {
202748 JsonCleanup *pJCNext; /* Next in a list */
202749 void (*xOp)(void*); /* Routine to run */
202750 void *pArg; /* Argument to xOp() */
202751 };
202752
202753 /* JSON type values
202754 */
202755 #define JSON_SUBST 0 /* Special edit node. Uses u.iPrev */
202756 #define JSON_NULL 1
202757 #define JSON_TRUE 2
202758 #define JSON_FALSE 3
202759 #define JSON_INT 4
202760 #define JSON_REAL 5
202761 #define JSON_STRING 6
202762 #define JSON_ARRAY 7
202763 #define JSON_OBJECT 8
202764
202765 /* The "subtype" set for JSON values */
202766 #define JSON_SUBTYPE 74 /* Ascii for "J" */
202767
202768 /*
202769 ** Names of the various JSON types:
202770 */
202771 static const char * const jsonType[] = {
202772 "subst",
202773 "null", "true", "false", "integer", "real", "text", "array", "object"
202774 };
202775
202776 /* Bit values for the JsonNode.jnFlag field
202777 */
202778 #define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */
202779 #define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */
202780 #define JNODE_REMOVE 0x04 /* Do not output */
202781 #define JNODE_REPLACE 0x08 /* Target of a JSON_SUBST node */
202782 #define JNODE_APPEND 0x10 /* More ARRAY/OBJECT entries at u.iAppend */
202783 #define JNODE_LABEL 0x20 /* Is a label of an object */
202784 #define JNODE_JSON5 0x40 /* Node contains JSON5 enhancements */
202785
202786
202787 /* A single node of parsed JSON. An array of these nodes describes
202788 ** a parse of JSON + edits.
202789 **
202790 ** Use the json_parse() SQL function (available when compiled with
202791 ** -DSQLITE_DEBUG) to see a dump of complete JsonParse objects, including
202792 ** a complete listing and decoding of the array of JsonNodes.
202793 */
202794 struct JsonNode {
202795 u8 eType; /* One of the JSON_ type values */
202796 u8 jnFlags; /* JNODE flags */
202797 u8 eU; /* Which union element to use */
202798 u32 n; /* Bytes of content for INT, REAL or STRING
202799 ** Number of sub-nodes for ARRAY and OBJECT
202800 ** Node that SUBST applies to */
202801 union {
202802 const char *zJContent; /* 1: Content for INT, REAL, and STRING */
202803 u32 iAppend; /* 2: More terms for ARRAY and OBJECT */
202804 u32 iKey; /* 3: Key for ARRAY objects in json_tree() */
202805 u32 iPrev; /* 4: Previous SUBST node, or 0 */
202806 } u;
202807 };
202808
202809
202810 /* A parsed and possibly edited JSON string. Lifecycle:
202811 **
202812 ** 1. JSON comes in and is parsed into an array aNode[]. The original
202813 ** JSON text is stored in zJson.
202814 **
202815 ** 2. Zero or more changes are made (via json_remove() or json_replace()
202816 ** or similar) to the aNode[] array.
202817 **
202818 ** 3. A new, edited and mimified JSON string is generated from aNode
202819 ** and stored in zAlt. The JsonParse object always owns zAlt.
202820 **
202821 ** Step 1 always happens. Step 2 and 3 may or may not happen, depending
202822 ** on the operation.
202823 **
202824 ** aNode[].u.zJContent entries typically point into zJson. Hence zJson
202825 ** must remain valid for the lifespan of the parse. For edits,
202826 ** aNode[].u.zJContent might point to malloced space other than zJson.
202827 ** Entries in pClup are responsible for freeing that extra malloced space.
202828 **
202829 ** When walking the parse tree in aNode[], edits are ignored if useMod is
202830 ** false.
202831 */
202832 struct JsonParse {
202833 u32 nNode; /* Number of slots of aNode[] used */
202834 u32 nAlloc; /* Number of slots of aNode[] allocated */
202835 JsonNode *aNode; /* Array of nodes containing the parse */
202836 char *zJson; /* Original JSON string (before edits) */
202837 char *zAlt; /* Revised and/or mimified JSON */
202838 u32 *aUp; /* Index of parent of each node */
202839 JsonCleanup *pClup;/* Cleanup operations prior to freeing this object */
202840 u16 iDepth; /* Nesting depth */
202841 u8 nErr; /* Number of errors seen */
202842 u8 oom; /* Set to true if out of memory */
202843 u8 bJsonIsRCStr; /* True if zJson is an RCStr */
202844 u8 hasNonstd; /* True if input uses non-standard features like JSON5 */
202845 u8 useMod; /* Actually use the edits contain inside aNode */
202846 u8 hasMod; /* aNode contains edits from the original zJson */
202847 u32 nJPRef; /* Number of references to this object */
202848 int nJson; /* Length of the zJson string in bytes */
202849 int nAlt; /* Length of alternative JSON string zAlt, in bytes */
202850 u32 iErr; /* Error location in zJson[] */
202851 u32 iSubst; /* Last JSON_SUBST entry in aNode[] */
202852 u32 iHold; /* Age of this entry in the cache for LRU replacement */
 
 
 
 
202853 };
202854
 
 
 
 
 
 
202855 /*
202856 ** Maximum nesting depth of JSON for this implementation.
202857 **
202858 ** This limit is needed to avoid a stack overflow in the recursive
202859 ** descent parser. A depth of 1000 is far deeper than any sane JSON
202860 ** should go. Historical note: This limit was 2000 prior to version 3.42.0
202861 */
202862 #define JSON_MAX_DEPTH 1000
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202863
202864 /**************************************************************************
202865 ** Utility routines for dealing with JsonString objects
202866 **************************************************************************/
202867
202868 /* Set the JsonString object to an empty string
 
202869 */
202870 static void jsonZero(JsonString *p){
202871 p->zBuf = p->zSpace;
202872 p->nAlloc = sizeof(p->zSpace);
202873 p->nUsed = 0;
202874 p->bStatic = 1;
202875 }
202876
202877 /* Initialize the JsonString object
202878 */
202879 static void jsonInit(JsonString *p, sqlite3_context *pCtx){
202880 p->pCtx = pCtx;
202881 p->bErr = 0;
202882 jsonZero(p);
202883 }
202884
202885 /* Free all allocated memory and reset the JsonString object back to its
202886 ** initial state.
202887 */
202888 static void jsonReset(JsonString *p){
202889 if( !p->bStatic ) sqlite3RCStrUnref(p->zBuf);
202890 jsonZero(p);
202891 }
202892
202893 /* Report an out-of-memory (OOM) condition
202894 */
202895 static void jsonOom(JsonString *p){
202896 p->bErr = 1;
202897 sqlite3_result_error_nomem(p->pCtx);
202898 jsonReset(p);
202899 }
202900
202901 /* Enlarge pJson->zBuf so that it can hold at least N more bytes.
202902 ** Return zero on success. Return non-zero on an OOM error
202903 */
202904 static int jsonGrow(JsonString *p, u32 N){
202905 u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10;
202906 char *zNew;
202907 if( p->bStatic ){
202908 if( p->bErr ) return 1;
202909 zNew = sqlite3RCStrNew(nTotal);
202910 if( zNew==0 ){
202911 jsonOom(p);
202912 return SQLITE_NOMEM;
202913 }
202914 memcpy(zNew, p->zBuf, (size_t)p->nUsed);
202915 p->zBuf = zNew;
202916 p->bStatic = 0;
202917 }else{
202918 p->zBuf = sqlite3RCStrResize(p->zBuf, nTotal);
202919 if( p->zBuf==0 ){
202920 p->bErr = 1;
202921 jsonZero(p);
202922 return SQLITE_NOMEM;
202923 }
202924 }
202925 p->nAlloc = nTotal;
202926 return SQLITE_OK;
202927 }
202928
202929 /* Append N bytes from zIn onto the end of the JsonString string.
202930 */
202931 static SQLITE_NOINLINE void jsonAppendExpand(
202932 JsonString *p,
202933 const char *zIn,
202934 u32 N
202935 ){
202936 assert( N>0 );
202937 if( jsonGrow(p,N) ) return;
202938 memcpy(p->zBuf+p->nUsed, zIn, N);
202939 p->nUsed += N;
202940 }
202941 static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
202942 if( N==0 ) return;
202943 if( N+p->nUsed >= p->nAlloc ){
202944 jsonAppendExpand(p,zIn,N);
202945 }else{
202946 memcpy(p->zBuf+p->nUsed, zIn, N);
202947 p->nUsed += N;
202948 }
202949 }
202950 static void jsonAppendRawNZ(JsonString *p, const char *zIn, u32 N){
202951 assert( N>0 );
202952 if( N+p->nUsed >= p->nAlloc ){
202953 jsonAppendExpand(p,zIn,N);
202954 }else{
202955 memcpy(p->zBuf+p->nUsed, zIn, N);
202956 p->nUsed += N;
202957 }
202958 }
@@ -202960,21 +203561,21 @@
202960
202961 /* Append formatted text (not to exceed N bytes) to the JsonString.
202962 */
202963 static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){
202964 va_list ap;
202965 if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return;
202966 va_start(ap, zFormat);
202967 sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap);
202968 va_end(ap);
202969 p->nUsed += (int)strlen(p->zBuf+p->nUsed);
202970 }
202971
202972 /* Append a single character
202973 */
202974 static SQLITE_NOINLINE void jsonAppendCharExpand(JsonString *p, char c){
202975 if( jsonGrow(p,1) ) return;
202976 p->zBuf[p->nUsed++] = c;
202977 }
202978 static void jsonAppendChar(JsonString *p, char c){
202979 if( p->nUsed>=p->nAlloc ){
202980 jsonAppendCharExpand(p,c);
@@ -202981,27 +203582,20 @@
202981 }else{
202982 p->zBuf[p->nUsed++] = c;
202983 }
202984 }
202985
202986 /* Try to force the string to be a zero-terminated RCStr string.
202987 **
202988 ** Return true on success. Return false if an OOM prevents this
202989 ** from happening.
202990 */
202991 static int jsonForceRCStr(JsonString *p){
202992 jsonAppendChar(p, 0);
202993 if( p->bErr ) return 0;
202994 p->nUsed--;
202995 if( p->bStatic==0 ) return 1;
202996 p->nAlloc = 0;
202997 p->nUsed++;
202998 jsonGrow(p, p->nUsed);
202999 p->nUsed--;
203000 return p->bStatic==0;
203001 }
203002
203003
203004 /* Append a comma separator to the output buffer, if the previous
203005 ** character is not '[' or '{'.
203006 */
203007 static void jsonAppendSeparator(JsonString *p){
@@ -203011,25 +203605,45 @@
203011 if( c=='[' || c=='{' ) return;
203012 jsonAppendChar(p, ',');
203013 }
203014
203015 /* Append the N-byte string in zIn to the end of the JsonString string
203016 ** under construction. Enclose the string in "..." and escape
203017 ** any double-quotes or backslash characters contained within the
203018 ** string.
 
 
 
203019 */
203020 static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
203021 u32 i;
203022 if( zIn==0 || ((N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0) ) return;
 
 
 
203023 p->zBuf[p->nUsed++] = '"';
203024 for(i=0; i<N; i++){
203025 unsigned char c = ((unsigned const char*)zIn)[i];
203026 if( jsonIsOk[c] ){
203027 p->zBuf[p->nUsed++] = c;
203028 }else if( c=='"' || c=='\\' ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203029 json_simple_escape:
203030 if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return;
203031 p->zBuf[p->nUsed++] = '\\';
203032 p->zBuf[p->nUsed++] = c;
203033 }else if( c=='\'' ){
203034 p->zBuf[p->nUsed++] = c;
203035 }else{
@@ -203046,158 +203660,30 @@
203046 assert( c>=0 && c<sizeof(aSpecial) );
203047 if( aSpecial[c] ){
203048 c = aSpecial[c];
203049 goto json_simple_escape;
203050 }
203051 if( (p->nUsed+N+7+i > p->nAlloc) && jsonGrow(p,N+7-i)!=0 ) return;
203052 p->zBuf[p->nUsed++] = '\\';
203053 p->zBuf[p->nUsed++] = 'u';
203054 p->zBuf[p->nUsed++] = '0';
203055 p->zBuf[p->nUsed++] = '0';
203056 p->zBuf[p->nUsed++] = "0123456789abcdef"[c>>4];
203057 p->zBuf[p->nUsed++] = "0123456789abcdef"[c&0xf];
203058 }
 
 
203059 }
203060 p->zBuf[p->nUsed++] = '"';
203061 assert( p->nUsed<p->nAlloc );
203062 }
203063
203064 /*
203065 ** The zIn[0..N] string is a JSON5 string literal. Append to p a translation
203066 ** of the string literal that standard JSON and that omits all JSON5
203067 ** features.
203068 */
203069 static void jsonAppendNormalizedString(JsonString *p, const char *zIn, u32 N){
203070 u32 i;
203071 jsonAppendChar(p, '"');
203072 zIn++;
203073 N -= 2;
203074 while( N>0 ){
203075 for(i=0; i<N && zIn[i]!='\\' && zIn[i]!='"'; i++){}
203076 if( i>0 ){
203077 jsonAppendRawNZ(p, zIn, i);
203078 zIn += i;
203079 N -= i;
203080 if( N==0 ) break;
203081 }
203082 if( zIn[0]=='"' ){
203083 jsonAppendRawNZ(p, "\\\"", 2);
203084 zIn++;
203085 N--;
203086 continue;
203087 }
203088 assert( zIn[0]=='\\' );
203089 switch( (u8)zIn[1] ){
203090 case '\'':
203091 jsonAppendChar(p, '\'');
203092 break;
203093 case 'v':
203094 jsonAppendRawNZ(p, "\\u0009", 6);
203095 break;
203096 case 'x':
203097 jsonAppendRawNZ(p, "\\u00", 4);
203098 jsonAppendRawNZ(p, &zIn[2], 2);
203099 zIn += 2;
203100 N -= 2;
203101 break;
203102 case '0':
203103 jsonAppendRawNZ(p, "\\u0000", 6);
203104 break;
203105 case '\r':
203106 if( zIn[2]=='\n' ){
203107 zIn++;
203108 N--;
203109 }
203110 break;
203111 case '\n':
203112 break;
203113 case 0xe2:
203114 assert( N>=4 );
203115 assert( 0x80==(u8)zIn[2] );
203116 assert( 0xa8==(u8)zIn[3] || 0xa9==(u8)zIn[3] );
203117 zIn += 2;
203118 N -= 2;
203119 break;
203120 default:
203121 jsonAppendRawNZ(p, zIn, 2);
203122 break;
203123 }
203124 zIn += 2;
203125 N -= 2;
203126 }
203127 jsonAppendChar(p, '"');
203128 }
203129
203130 /*
203131 ** The zIn[0..N] string is a JSON5 integer literal. Append to p a translation
203132 ** of the string literal that standard JSON and that omits all JSON5
203133 ** features.
203134 */
203135 static void jsonAppendNormalizedInt(JsonString *p, const char *zIn, u32 N){
203136 if( zIn[0]=='+' ){
203137 zIn++;
203138 N--;
203139 }else if( zIn[0]=='-' ){
203140 jsonAppendChar(p, '-');
203141 zIn++;
203142 N--;
203143 }
203144 if( zIn[0]=='0' && (zIn[1]=='x' || zIn[1]=='X') ){
203145 sqlite3_int64 i = 0;
203146 int rc = sqlite3DecOrHexToI64(zIn, &i);
203147 if( rc<=1 ){
203148 jsonPrintf(100,p,"%lld",i);
203149 }else{
203150 assert( rc==2 );
203151 jsonAppendRawNZ(p, "9.0e999", 7);
203152 }
203153 return;
203154 }
203155 assert( N>0 );
203156 jsonAppendRawNZ(p, zIn, N);
203157 }
203158
203159 /*
203160 ** The zIn[0..N] string is a JSON5 real literal. Append to p a translation
203161 ** of the string literal that standard JSON and that omits all JSON5
203162 ** features.
203163 */
203164 static void jsonAppendNormalizedReal(JsonString *p, const char *zIn, u32 N){
203165 u32 i;
203166 if( zIn[0]=='+' ){
203167 zIn++;
203168 N--;
203169 }else if( zIn[0]=='-' ){
203170 jsonAppendChar(p, '-');
203171 zIn++;
203172 N--;
203173 }
203174 if( zIn[0]=='.' ){
203175 jsonAppendChar(p, '0');
203176 }
203177 for(i=0; i<N; i++){
203178 if( zIn[i]=='.' && (i+1==N || !sqlite3Isdigit(zIn[i+1])) ){
203179 i++;
203180 jsonAppendRaw(p, zIn, i);
203181 zIn += i;
203182 N -= i;
203183 jsonAppendChar(p, '0');
203184 break;
203185 }
203186 }
203187 if( N>0 ){
203188 jsonAppendRawNZ(p, zIn, N);
203189 }
203190 }
203191
203192
203193
203194 /*
203195 ** Append a function parameter value to the JSON string under
203196 ** construction.
203197 */
203198 static void jsonAppendValue(
203199 JsonString *p, /* Append to this JSON string */
203200 sqlite3_value *pValue /* Value to append */
203201 ){
203202 switch( sqlite3_value_type(pValue) ){
203203 case SQLITE_NULL: {
@@ -203223,591 +203709,147 @@
203223 jsonAppendString(p, z, n);
203224 }
203225 break;
203226 }
203227 default: {
203228 if( p->bErr==0 ){
 
 
 
 
 
 
203229 sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1);
203230 p->bErr = 2;
203231 jsonReset(p);
203232 }
203233 break;
203234 }
203235 }
203236 }
203237
203238
203239 /* Make the JSON in p the result of the SQL function.
203240 **
203241 ** The JSON string is reset.
 
 
 
 
203242 */
203243 static void jsonResult(JsonString *p){
203244 if( p->bErr==0 ){
203245 if( p->bStatic ){
 
 
 
 
 
 
 
 
 
203246 sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
203247 SQLITE_TRANSIENT, SQLITE_UTF8);
203248 }else if( jsonForceRCStr(p) ){
203249 sqlite3RCStrRef(p->zBuf);
203250 sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
 
 
 
 
 
 
 
 
 
 
 
203251 sqlite3RCStrUnref,
203252 SQLITE_UTF8);
 
 
203253 }
203254 }
203255 if( p->bErr==1 ){
203256 sqlite3_result_error_nomem(p->pCtx);
 
 
203257 }
203258 jsonReset(p);
203259 }
203260
203261 /**************************************************************************
203262 ** Utility routines for dealing with JsonNode and JsonParse objects
203263 **************************************************************************/
203264
203265 /*
203266 ** Return the number of consecutive JsonNode slots need to represent
203267 ** the parsed JSON at pNode. The minimum answer is 1. For ARRAY and
203268 ** OBJECT types, the number might be larger.
203269 **
203270 ** Appended elements are not counted. The value returned is the number
203271 ** by which the JsonNode counter should increment in order to go to the
203272 ** next peer value.
203273 */
203274 static u32 jsonNodeSize(JsonNode *pNode){
203275 return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1;
203276 }
203277
203278 /*
203279 ** Reclaim all memory allocated by a JsonParse object. But do not
203280 ** delete the JsonParse object itself.
203281 */
203282 static void jsonParseReset(JsonParse *pParse){
203283 while( pParse->pClup ){
203284 JsonCleanup *pTask = pParse->pClup;
203285 pParse->pClup = pTask->pJCNext;
203286 pTask->xOp(pTask->pArg);
203287 sqlite3_free(pTask);
203288 }
203289 assert( pParse->nJPRef<=1 );
203290 if( pParse->aNode ){
203291 sqlite3_free(pParse->aNode);
203292 pParse->aNode = 0;
203293 }
203294 pParse->nNode = 0;
203295 pParse->nAlloc = 0;
203296 if( pParse->aUp ){
203297 sqlite3_free(pParse->aUp);
203298 pParse->aUp = 0;
203299 }
203300 if( pParse->bJsonIsRCStr ){
203301 sqlite3RCStrUnref(pParse->zJson);
203302 pParse->zJson = 0;
 
203303 pParse->bJsonIsRCStr = 0;
203304 }
203305 if( pParse->zAlt ){
203306 sqlite3RCStrUnref(pParse->zAlt);
203307 pParse->zAlt = 0;
 
 
203308 }
203309 }
203310
203311 /*
203312 ** Free a JsonParse object that was obtained from sqlite3_malloc().
203313 **
203314 ** Note that destroying JsonParse might call sqlite3RCStrUnref() to
203315 ** destroy the zJson value. The RCStr object might recursively invoke
203316 ** JsonParse to destroy this pParse object again. Take care to ensure
203317 ** that this recursive destructor sequence terminates harmlessly.
203318 */
203319 static void jsonParseFree(JsonParse *pParse){
203320 if( pParse->nJPRef>1 ){
203321 pParse->nJPRef--;
203322 }else{
203323 jsonParseReset(pParse);
203324 sqlite3_free(pParse);
203325 }
203326 }
203327
203328 /*
203329 ** Add a cleanup task to the JsonParse object.
203330 **
203331 ** If an OOM occurs, the cleanup operation happens immediately
203332 ** and this function returns SQLITE_NOMEM.
203333 */
203334 static int jsonParseAddCleanup(
203335 JsonParse *pParse, /* Add the cleanup task to this parser */
203336 void(*xOp)(void*), /* The cleanup task */
203337 void *pArg /* Argument to the cleanup */
203338 ){
203339 JsonCleanup *pTask = sqlite3_malloc64( sizeof(*pTask) );
203340 if( pTask==0 ){
203341 pParse->oom = 1;
203342 xOp(pArg);
203343 return SQLITE_ERROR;
203344 }
203345 pTask->pJCNext = pParse->pClup;
203346 pParse->pClup = pTask;
203347 pTask->xOp = xOp;
203348 pTask->pArg = pArg;
203349 return SQLITE_OK;
203350 }
203351
203352 /*
203353 ** Convert the JsonNode pNode into a pure JSON string and
203354 ** append to pOut. Subsubstructure is also included. Return
203355 ** the number of JsonNode objects that are encoded.
203356 */
203357 static void jsonRenderNode(
203358 JsonParse *pParse, /* the complete parse of the JSON */
203359 JsonNode *pNode, /* The node to render */
203360 JsonString *pOut /* Write JSON here */
203361 ){
203362 assert( pNode!=0 );
203363 while( (pNode->jnFlags & JNODE_REPLACE)!=0 && pParse->useMod ){
203364 u32 idx = (u32)(pNode - pParse->aNode);
203365 u32 i = pParse->iSubst;
203366 while( 1 /*exit-by-break*/ ){
203367 assert( i<pParse->nNode );
203368 assert( pParse->aNode[i].eType==JSON_SUBST );
203369 assert( pParse->aNode[i].eU==4 );
203370 assert( pParse->aNode[i].u.iPrev<i );
203371 if( pParse->aNode[i].n==idx ){
203372 pNode = &pParse->aNode[i+1];
203373 break;
203374 }
203375 i = pParse->aNode[i].u.iPrev;
203376 }
203377 }
203378 switch( pNode->eType ){
203379 default: {
203380 assert( pNode->eType==JSON_NULL );
203381 jsonAppendRawNZ(pOut, "null", 4);
203382 break;
203383 }
203384 case JSON_TRUE: {
203385 jsonAppendRawNZ(pOut, "true", 4);
203386 break;
203387 }
203388 case JSON_FALSE: {
203389 jsonAppendRawNZ(pOut, "false", 5);
203390 break;
203391 }
203392 case JSON_STRING: {
203393 assert( pNode->eU==1 );
203394 if( pNode->jnFlags & JNODE_RAW ){
203395 if( pNode->jnFlags & JNODE_LABEL ){
203396 jsonAppendChar(pOut, '"');
203397 jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
203398 jsonAppendChar(pOut, '"');
203399 }else{
203400 jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
203401 }
203402 }else if( pNode->jnFlags & JNODE_JSON5 ){
203403 jsonAppendNormalizedString(pOut, pNode->u.zJContent, pNode->n);
203404 }else{
203405 assert( pNode->n>0 );
203406 jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n);
203407 }
203408 break;
203409 }
203410 case JSON_REAL: {
203411 assert( pNode->eU==1 );
203412 if( pNode->jnFlags & JNODE_JSON5 ){
203413 jsonAppendNormalizedReal(pOut, pNode->u.zJContent, pNode->n);
203414 }else{
203415 assert( pNode->n>0 );
203416 jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n);
203417 }
203418 break;
203419 }
203420 case JSON_INT: {
203421 assert( pNode->eU==1 );
203422 if( pNode->jnFlags & JNODE_JSON5 ){
203423 jsonAppendNormalizedInt(pOut, pNode->u.zJContent, pNode->n);
203424 }else{
203425 assert( pNode->n>0 );
203426 jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n);
203427 }
203428 break;
203429 }
203430 case JSON_ARRAY: {
203431 u32 j = 1;
203432 jsonAppendChar(pOut, '[');
203433 for(;;){
203434 while( j<=pNode->n ){
203435 if( (pNode[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ){
203436 jsonAppendSeparator(pOut);
203437 jsonRenderNode(pParse, &pNode[j], pOut);
203438 }
203439 j += jsonNodeSize(&pNode[j]);
203440 }
203441 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
203442 if( pParse->useMod==0 ) break;
203443 assert( pNode->eU==2 );
203444 pNode = &pParse->aNode[pNode->u.iAppend];
203445 j = 1;
203446 }
203447 jsonAppendChar(pOut, ']');
203448 break;
203449 }
203450 case JSON_OBJECT: {
203451 u32 j = 1;
203452 jsonAppendChar(pOut, '{');
203453 for(;;){
203454 while( j<=pNode->n ){
203455 if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ){
203456 jsonAppendSeparator(pOut);
203457 jsonRenderNode(pParse, &pNode[j], pOut);
203458 jsonAppendChar(pOut, ':');
203459 jsonRenderNode(pParse, &pNode[j+1], pOut);
203460 }
203461 j += 1 + jsonNodeSize(&pNode[j+1]);
203462 }
203463 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
203464 if( pParse->useMod==0 ) break;
203465 assert( pNode->eU==2 );
203466 pNode = &pParse->aNode[pNode->u.iAppend];
203467 j = 1;
203468 }
203469 jsonAppendChar(pOut, '}');
203470 break;
203471 }
203472 }
203473 }
203474
203475 /*
203476 ** Return a JsonNode and all its descendants as a JSON string.
203477 */
203478 static void jsonReturnJson(
203479 JsonParse *pParse, /* The complete JSON */
203480 JsonNode *pNode, /* Node to return */
203481 sqlite3_context *pCtx, /* Return value for this function */
203482 int bGenerateAlt, /* Also store the rendered text in zAlt */
203483 int omitSubtype /* Do not call sqlite3_result_subtype() */
203484 ){
203485 JsonString s;
203486 if( pParse->oom ){
203487 sqlite3_result_error_nomem(pCtx);
203488 return;
203489 }
203490 if( pParse->nErr==0 ){
203491 jsonInit(&s, pCtx);
203492 jsonRenderNode(pParse, pNode, &s);
203493 if( bGenerateAlt && pParse->zAlt==0 && jsonForceRCStr(&s) ){
203494 pParse->zAlt = sqlite3RCStrRef(s.zBuf);
203495 pParse->nAlt = s.nUsed;
203496 }
203497 jsonResult(&s);
203498 if( !omitSubtype ) sqlite3_result_subtype(pCtx, JSON_SUBTYPE);
203499 }
203500 }
203501
203502 /*
203503 ** Translate a single byte of Hex into an integer.
203504 ** This routine only works if h really is a valid hexadecimal
203505 ** character: 0..9a..fA..F
 
203506 */
203507 static u8 jsonHexToInt(int h){
203508 assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') );
 
 
203509 #ifdef SQLITE_EBCDIC
203510 h += 9*(1&~(h>>4));
203511 #else
203512 h += 9*(1&(h>>6));
203513 #endif
203514 return (u8)(h & 0xf);
203515 }
203516
203517 /*
203518 ** Convert a 4-byte hex string into an integer
203519 */
203520 static u32 jsonHexToInt4(const char *z){
203521 u32 v;
203522 assert( sqlite3Isxdigit(z[0]) );
203523 assert( sqlite3Isxdigit(z[1]) );
203524 assert( sqlite3Isxdigit(z[2]) );
203525 assert( sqlite3Isxdigit(z[3]) );
203526 v = (jsonHexToInt(z[0])<<12)
203527 + (jsonHexToInt(z[1])<<8)
203528 + (jsonHexToInt(z[2])<<4)
203529 + jsonHexToInt(z[3]);
203530 return v;
203531 }
203532
203533 /*
203534 ** Make the JsonNode the return value of the function.
203535 */
203536 static void jsonReturn(
203537 JsonParse *pParse, /* Complete JSON parse tree */
203538 JsonNode *pNode, /* Node to return */
203539 sqlite3_context *pCtx, /* Return value for this function */
203540 int omitSubtype /* Do not call sqlite3_result_subtype() */
203541 ){
203542 switch( pNode->eType ){
203543 default: {
203544 assert( pNode->eType==JSON_NULL );
203545 sqlite3_result_null(pCtx);
203546 break;
203547 }
203548 case JSON_TRUE: {
203549 sqlite3_result_int(pCtx, 1);
203550 break;
203551 }
203552 case JSON_FALSE: {
203553 sqlite3_result_int(pCtx, 0);
203554 break;
203555 }
203556 case JSON_INT: {
203557 sqlite3_int64 i = 0;
203558 int rc;
203559 int bNeg = 0;
203560 const char *z;
203561
203562 assert( pNode->eU==1 );
203563 z = pNode->u.zJContent;
203564 if( z[0]=='-' ){ z++; bNeg = 1; }
203565 else if( z[0]=='+' ){ z++; }
203566 rc = sqlite3DecOrHexToI64(z, &i);
203567 if( rc<=1 ){
203568 sqlite3_result_int64(pCtx, bNeg ? -i : i);
203569 }else if( rc==3 && bNeg ){
203570 sqlite3_result_int64(pCtx, SMALLEST_INT64);
203571 }else{
203572 goto to_double;
203573 }
203574 break;
203575 }
203576 case JSON_REAL: {
203577 double r;
203578 const char *z;
203579 assert( pNode->eU==1 );
203580 to_double:
203581 z = pNode->u.zJContent;
203582 sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8);
203583 sqlite3_result_double(pCtx, r);
203584 break;
203585 }
203586 case JSON_STRING: {
203587 if( pNode->jnFlags & JNODE_RAW ){
203588 assert( pNode->eU==1 );
203589 sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n,
203590 SQLITE_TRANSIENT);
203591 }else if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
203592 /* JSON formatted without any backslash-escapes */
203593 assert( pNode->eU==1 );
203594 sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2,
203595 SQLITE_TRANSIENT);
203596 }else{
203597 /* Translate JSON formatted string into raw text */
203598 u32 i;
203599 u32 n = pNode->n;
203600 const char *z;
203601 char *zOut;
203602 u32 j;
203603 u32 nOut = n;
203604 assert( pNode->eU==1 );
203605 z = pNode->u.zJContent;
203606 zOut = sqlite3_malloc( nOut+1 );
203607 if( zOut==0 ){
203608 sqlite3_result_error_nomem(pCtx);
203609 break;
203610 }
203611 for(i=1, j=0; i<n-1; i++){
203612 char c = z[i];
203613 if( c=='\\' ){
203614 c = z[++i];
203615 if( c=='u' ){
203616 u32 v = jsonHexToInt4(z+i+1);
203617 i += 4;
203618 if( v==0 ) break;
203619 if( v<=0x7f ){
203620 zOut[j++] = (char)v;
203621 }else if( v<=0x7ff ){
203622 zOut[j++] = (char)(0xc0 | (v>>6));
203623 zOut[j++] = 0x80 | (v&0x3f);
203624 }else{
203625 u32 vlo;
203626 if( (v&0xfc00)==0xd800
203627 && i<n-6
203628 && z[i+1]=='\\'
203629 && z[i+2]=='u'
203630 && ((vlo = jsonHexToInt4(z+i+3))&0xfc00)==0xdc00
203631 ){
203632 /* We have a surrogate pair */
203633 v = ((v&0x3ff)<<10) + (vlo&0x3ff) + 0x10000;
203634 i += 6;
203635 zOut[j++] = 0xf0 | (v>>18);
203636 zOut[j++] = 0x80 | ((v>>12)&0x3f);
203637 zOut[j++] = 0x80 | ((v>>6)&0x3f);
203638 zOut[j++] = 0x80 | (v&0x3f);
203639 }else{
203640 zOut[j++] = 0xe0 | (v>>12);
203641 zOut[j++] = 0x80 | ((v>>6)&0x3f);
203642 zOut[j++] = 0x80 | (v&0x3f);
203643 }
203644 }
203645 continue;
203646 }else if( c=='b' ){
203647 c = '\b';
203648 }else if( c=='f' ){
203649 c = '\f';
203650 }else if( c=='n' ){
203651 c = '\n';
203652 }else if( c=='r' ){
203653 c = '\r';
203654 }else if( c=='t' ){
203655 c = '\t';
203656 }else if( c=='v' ){
203657 c = '\v';
203658 }else if( c=='\'' || c=='"' || c=='/' || c=='\\' ){
203659 /* pass through unchanged */
203660 }else if( c=='0' ){
203661 c = 0;
203662 }else if( c=='x' ){
203663 c = (jsonHexToInt(z[i+1])<<4) | jsonHexToInt(z[i+2]);
203664 i += 2;
203665 }else if( c=='\r' && z[i+1]=='\n' ){
203666 i++;
203667 continue;
203668 }else if( 0xe2==(u8)c ){
203669 assert( 0x80==(u8)z[i+1] );
203670 assert( 0xa8==(u8)z[i+2] || 0xa9==(u8)z[i+2] );
203671 i += 2;
203672 continue;
203673 }else{
203674 continue;
203675 }
203676 } /* end if( c=='\\' ) */
203677 zOut[j++] = c;
203678 } /* end for() */
203679 zOut[j] = 0;
203680 sqlite3_result_text(pCtx, zOut, j, sqlite3_free);
203681 }
203682 break;
203683 }
203684 case JSON_ARRAY:
203685 case JSON_OBJECT: {
203686 jsonReturnJson(pParse, pNode, pCtx, 0, omitSubtype);
203687 break;
203688 }
203689 }
203690 }
203691
203692 /* Forward reference */
203693 static int jsonParseAddNode(JsonParse*,u32,u32,const char*);
203694
203695 /*
203696 ** A macro to hint to the compiler that a function should not be
203697 ** inlined.
203698 */
203699 #if defined(__GNUC__)
203700 # define JSON_NOINLINE __attribute__((noinline))
203701 #elif defined(_MSC_VER) && _MSC_VER>=1310
203702 # define JSON_NOINLINE __declspec(noinline)
203703 #else
203704 # define JSON_NOINLINE
203705 #endif
203706
203707
203708 /*
203709 ** Add a single node to pParse->aNode after first expanding the
203710 ** size of the aNode array. Return the index of the new node.
203711 **
203712 ** If an OOM error occurs, set pParse->oom and return -1.
203713 */
203714 static JSON_NOINLINE int jsonParseAddNodeExpand(
203715 JsonParse *pParse, /* Append the node to this object */
203716 u32 eType, /* Node type */
203717 u32 n, /* Content size or sub-node count */
203718 const char *zContent /* Content */
203719 ){
203720 u32 nNew;
203721 JsonNode *pNew;
203722 assert( pParse->nNode>=pParse->nAlloc );
203723 if( pParse->oom ) return -1;
203724 nNew = pParse->nAlloc*2 + 10;
203725 pNew = sqlite3_realloc64(pParse->aNode, sizeof(JsonNode)*nNew);
203726 if( pNew==0 ){
203727 pParse->oom = 1;
203728 return -1;
203729 }
203730 pParse->nAlloc = sqlite3_msize(pNew)/sizeof(JsonNode);
203731 pParse->aNode = pNew;
203732 assert( pParse->nNode<pParse->nAlloc );
203733 return jsonParseAddNode(pParse, eType, n, zContent);
203734 }
203735
203736 /*
203737 ** Create a new JsonNode instance based on the arguments and append that
203738 ** instance to the JsonParse. Return the index in pParse->aNode[] of the
203739 ** new node, or -1 if a memory allocation fails.
203740 */
203741 static int jsonParseAddNode(
203742 JsonParse *pParse, /* Append the node to this object */
203743 u32 eType, /* Node type */
203744 u32 n, /* Content size or sub-node count */
203745 const char *zContent /* Content */
203746 ){
203747 JsonNode *p;
203748 assert( pParse->aNode!=0 || pParse->nNode>=pParse->nAlloc );
203749 if( pParse->nNode>=pParse->nAlloc ){
203750 return jsonParseAddNodeExpand(pParse, eType, n, zContent);
203751 }
203752 assert( pParse->aNode!=0 );
203753 p = &pParse->aNode[pParse->nNode];
203754 assert( p!=0 );
203755 p->eType = (u8)(eType & 0xff);
203756 p->jnFlags = (u8)(eType >> 8);
203757 VVA( p->eU = zContent ? 1 : 0 );
203758 p->n = n;
203759 p->u.zJContent = zContent;
203760 return pParse->nNode++;
203761 }
203762
203763 /*
203764 ** Add an array of new nodes to the current pParse->aNode array.
203765 ** Return the index of the first node added.
203766 **
203767 ** If an OOM error occurs, set pParse->oom.
203768 */
203769 static void jsonParseAddNodeArray(
203770 JsonParse *pParse, /* Append the node to this object */
203771 JsonNode *aNode, /* Array of nodes to add */
203772 u32 nNode /* Number of elements in aNew */
203773 ){
203774 assert( aNode!=0 );
203775 assert( nNode>=1 );
203776 if( pParse->nNode + nNode > pParse->nAlloc ){
203777 u32 nNew = pParse->nNode + nNode;
203778 JsonNode *aNew = sqlite3_realloc64(pParse->aNode, nNew*sizeof(JsonNode));
203779 if( aNew==0 ){
203780 pParse->oom = 1;
203781 return;
203782 }
203783 pParse->nAlloc = sqlite3_msize(aNew)/sizeof(JsonNode);
203784 pParse->aNode = aNew;
203785 }
203786 memcpy(&pParse->aNode[pParse->nNode], aNode, nNode*sizeof(JsonNode));
203787 pParse->nNode += nNode;
203788 }
203789
203790 /*
203791 ** Add a new JSON_SUBST node. The node immediately following
203792 ** this new node will be the substitute content for iNode.
203793 */
203794 static int jsonParseAddSubstNode(
203795 JsonParse *pParse, /* Add the JSON_SUBST here */
203796 u32 iNode /* References this node */
203797 ){
203798 int idx = jsonParseAddNode(pParse, JSON_SUBST, iNode, 0);
203799 if( pParse->oom ) return -1;
203800 pParse->aNode[iNode].jnFlags |= JNODE_REPLACE;
203801 pParse->aNode[idx].eU = 4;
203802 pParse->aNode[idx].u.iPrev = pParse->iSubst;
203803 pParse->iSubst = idx;
203804 pParse->hasMod = 1;
203805 pParse->useMod = 1;
203806 return idx;
203807 }
203808
203809 /*
203810 ** Return true if z[] begins with 2 (or more) hexadecimal digits
203811 */
203812 static int jsonIs2Hex(const char *z){
203813 return sqlite3Isxdigit(z[0]) && sqlite3Isxdigit(z[1]);
@@ -203957,101 +203999,542 @@
203957 char eType;
203958 char nRepl;
203959 char *zMatch;
203960 char *zRepl;
203961 } aNanInfName[] = {
203962 { 'i', 'I', 3, JSON_REAL, 7, "inf", "9.0e999" },
203963 { 'i', 'I', 8, JSON_REAL, 7, "infinity", "9.0e999" },
203964 { 'n', 'N', 3, JSON_NULL, 4, "NaN", "null" },
203965 { 'q', 'Q', 4, JSON_NULL, 4, "QNaN", "null" },
203966 { 's', 'S', 4, JSON_NULL, 4, "SNaN", "null" },
203967 };
203968
203969 /*
203970 ** Parse a single JSON value which begins at pParse->zJson[i]. Return the
203971 ** index of the first character past the end of the value parsed.
203972 **
203973 ** Special return values:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203974 **
203975 ** 0 End of input
203976 ** -1 Syntax error
203977 ** -2 '}' seen
203978 ** -3 ']' seen
203979 ** -4 ',' seen
203980 ** -5 ':' seen
203981 */
203982 static int jsonParseValue(JsonParse *pParse, u32 i){
203983 char c;
203984 u32 j;
203985 int iThis;
203986 int x;
203987 JsonNode *pNode;
203988 const char *z = pParse->zJson;
203989 json_parse_restart:
203990 switch( (u8)z[i] ){
203991 case '{': {
203992 /* Parse object */
203993 iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
203994 if( iThis<0 ) return -1;
203995 if( ++pParse->iDepth > JSON_MAX_DEPTH ){
203996 pParse->iErr = i;
203997 return -1;
203998 }
 
203999 for(j=i+1;;j++){
204000 u32 nNode = pParse->nNode;
204001 x = jsonParseValue(pParse, j);
204002 if( x<=0 ){
 
204003 if( x==(-2) ){
204004 j = pParse->iErr;
204005 if( pParse->nNode!=(u32)iThis+1 ) pParse->hasNonstd = 1;
204006 break;
204007 }
204008 j += json5Whitespace(&z[j]);
 
204009 if( sqlite3JsonId1(z[j])
204010 || (z[j]=='\\' && z[j+1]=='u' && jsonIs4Hex(&z[j+2]))
204011 ){
204012 int k = j+1;
204013 while( (sqlite3JsonId2(z[k]) && json5Whitespace(&z[k])==0)
204014 || (z[k]=='\\' && z[k+1]=='u' && jsonIs4Hex(&z[k+2]))
204015 ){
204016 k++;
204017 }
204018 jsonParseAddNode(pParse, JSON_STRING | (JNODE_RAW<<8), k-j, &z[j]);
 
204019 pParse->hasNonstd = 1;
204020 x = k;
204021 }else{
204022 if( x!=-1 ) pParse->iErr = j;
204023 return -1;
204024 }
204025 }
204026 if( pParse->oom ) return -1;
204027 pNode = &pParse->aNode[nNode];
204028 if( pNode->eType!=JSON_STRING ){
204029 pParse->iErr = j;
204030 return -1;
204031 }
204032 pNode->jnFlags |= JNODE_LABEL;
204033 j = x;
204034 if( z[j]==':' ){
204035 j++;
204036 }else{
204037 if( fast_isspace(z[j]) ){
204038 do{ j++; }while( fast_isspace(z[j]) );
 
204039 if( z[j]==':' ){
204040 j++;
204041 goto parse_object_value;
204042 }
204043 }
204044 x = jsonParseValue(pParse, j);
204045 if( x!=(-5) ){
204046 if( x!=(-1) ) pParse->iErr = j;
204047 return -1;
204048 }
204049 j = pParse->iErr+1;
204050 }
204051 parse_object_value:
204052 x = jsonParseValue(pParse, j);
204053 if( x<=0 ){
204054 if( x!=(-1) ) pParse->iErr = j;
204055 return -1;
204056 }
204057 j = x;
@@ -204058,19 +204541,19 @@
204058 if( z[j]==',' ){
204059 continue;
204060 }else if( z[j]=='}' ){
204061 break;
204062 }else{
204063 if( fast_isspace(z[j]) ){
204064 do{ j++; }while( fast_isspace(z[j]) );
204065 if( z[j]==',' ){
204066 continue;
204067 }else if( z[j]=='}' ){
204068 break;
204069 }
204070 }
204071 x = jsonParseValue(pParse, j);
204072 if( x==(-4) ){
204073 j = pParse->iErr;
204074 continue;
204075 }
204076 if( x==(-2) ){
@@ -204079,29 +204562,30 @@
204079 }
204080 }
204081 pParse->iErr = j;
204082 return -1;
204083 }
204084 pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
204085 pParse->iDepth--;
204086 return j+1;
204087 }
204088 case '[': {
204089 /* Parse array */
204090 iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
204091 if( iThis<0 ) return -1;
 
 
204092 if( ++pParse->iDepth > JSON_MAX_DEPTH ){
204093 pParse->iErr = i;
204094 return -1;
204095 }
204096 memset(&pParse->aNode[iThis].u, 0, sizeof(pParse->aNode[iThis].u));
204097 for(j=i+1;;j++){
204098 x = jsonParseValue(pParse, j);
204099 if( x<=0 ){
204100 if( x==(-3) ){
204101 j = pParse->iErr;
204102 if( pParse->nNode!=(u32)iThis+1 ) pParse->hasNonstd = 1;
204103 break;
204104 }
204105 if( x!=(-1) ) pParse->iErr = j;
204106 return -1;
204107 }
@@ -204109,19 +204593,19 @@
204109 if( z[j]==',' ){
204110 continue;
204111 }else if( z[j]==']' ){
204112 break;
204113 }else{
204114 if( fast_isspace(z[j]) ){
204115 do{ j++; }while( fast_isspace(z[j]) );
204116 if( z[j]==',' ){
204117 continue;
204118 }else if( z[j]==']' ){
204119 break;
204120 }
204121 }
204122 x = jsonParseValue(pParse, j);
204123 if( x==(-4) ){
204124 j = pParse->iErr;
204125 continue;
204126 }
204127 if( x==(-3) ){
@@ -204130,86 +204614,98 @@
204130 }
204131 }
204132 pParse->iErr = j;
204133 return -1;
204134 }
204135 pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
204136 pParse->iDepth--;
204137 return j+1;
204138 }
204139 case '\'': {
204140 u8 jnFlags;
204141 char cDelim;
204142 pParse->hasNonstd = 1;
204143 jnFlags = JNODE_JSON5;
204144 goto parse_string;
204145 case '"':
204146 /* Parse string */
204147 jnFlags = 0;
204148 parse_string:
204149 cDelim = z[i];
204150 for(j=i+1; 1; j++){
204151 if( jsonIsOk[(unsigned char)z[j]] ) continue;
 
 
 
 
 
 
 
 
 
 
204152 c = z[j];
204153 if( c==cDelim ){
204154 break;
204155 }else if( c=='\\' ){
204156 c = z[++j];
204157 if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f'
204158 || c=='n' || c=='r' || c=='t'
204159 || (c=='u' && jsonIs4Hex(&z[j+1])) ){
204160 jnFlags |= JNODE_ESCAPE;
204161 }else if( c=='\'' || c=='0' || c=='v' || c=='\n'
204162 || (0xe2==(u8)c && 0x80==(u8)z[j+1]
204163 && (0xa8==(u8)z[j+2] || 0xa9==(u8)z[j+2]))
204164 || (c=='x' && jsonIs2Hex(&z[j+1])) ){
204165 jnFlags |= (JNODE_ESCAPE|JNODE_JSON5);
204166 pParse->hasNonstd = 1;
204167 }else if( c=='\r' ){
204168 if( z[j+1]=='\n' ) j++;
204169 jnFlags |= (JNODE_ESCAPE|JNODE_JSON5);
204170 pParse->hasNonstd = 1;
204171 }else{
204172 pParse->iErr = j;
204173 return -1;
204174 }
204175 }else if( c<=0x1f ){
204176 /* Control characters are not allowed in strings */
204177 pParse->iErr = j;
204178 return -1;
 
 
204179 }
 
204180 }
204181 jsonParseAddNode(pParse, JSON_STRING | (jnFlags<<8), j+1-i, &z[i]);
204182 return j+1;
204183 }
204184 case 't': {
204185 if( strncmp(z+i,"true",4)==0 && !sqlite3Isalnum(z[i+4]) ){
204186 jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
204187 return i+4;
204188 }
204189 pParse->iErr = i;
204190 return -1;
204191 }
204192 case 'f': {
204193 if( strncmp(z+i,"false",5)==0 && !sqlite3Isalnum(z[i+5]) ){
204194 jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
204195 return i+5;
204196 }
204197 pParse->iErr = i;
204198 return -1;
204199 }
204200 case '+': {
204201 u8 seenDP, seenE, jnFlags;
204202 pParse->hasNonstd = 1;
204203 jnFlags = JNODE_JSON5;
204204 goto parse_number;
204205 case '.':
204206 if( sqlite3Isdigit(z[i+1]) ){
204207 pParse->hasNonstd = 1;
204208 jnFlags = JNODE_JSON5;
204209 seenE = 0;
204210 seenDP = JSON_REAL;
204211 goto parse_number_2;
204212 }
204213 pParse->iErr = i;
204214 return -1;
204215 case '-':
@@ -204222,25 +204718,24 @@
204222 case '6':
204223 case '7':
204224 case '8':
204225 case '9':
204226 /* Parse number */
204227 jnFlags = 0;
204228 parse_number:
204229 seenDP = JSON_INT;
204230 seenE = 0;
204231 assert( '-' < '0' );
204232 assert( '+' < '0' );
204233 assert( '.' < '0' );
204234 c = z[i];
204235
204236 if( c<='0' ){
204237 if( c=='0' ){
204238 if( (z[i+1]=='x' || z[i+1]=='X') && sqlite3Isxdigit(z[i+2]) ){
204239 assert( seenDP==JSON_INT );
204240 pParse->hasNonstd = 1;
204241 jnFlags |= JNODE_JSON5;
204242 for(j=i+3; sqlite3Isxdigit(z[j]); j++){}
204243 goto parse_number_finish;
204244 }else if( sqlite3Isdigit(z[i+1]) ){
204245 pParse->iErr = i+1;
204246 return -1;
@@ -204253,19 +204748,19 @@
204253 if( (z[i+1]=='I' || z[i+1]=='i')
204254 && sqlite3StrNICmp(&z[i+1], "inf",3)==0
204255 ){
204256 pParse->hasNonstd = 1;
204257 if( z[i]=='-' ){
204258 jsonParseAddNode(pParse, JSON_REAL, 8, "-9.0e999");
204259 }else{
204260 jsonParseAddNode(pParse, JSON_REAL, 7, "9.0e999");
204261 }
204262 return i + (sqlite3StrNICmp(&z[i+4],"inity",5)==0 ? 9 : 4);
204263 }
204264 if( z[i+1]=='.' ){
204265 pParse->hasNonstd = 1;
204266 jnFlags |= JNODE_JSON5;
204267 goto parse_number_2;
204268 }
204269 pParse->iErr = i;
204270 return -1;
204271 }
@@ -204273,44 +204768,45 @@
204273 if( sqlite3Isdigit(z[i+2]) ){
204274 pParse->iErr = i+1;
204275 return -1;
204276 }else if( (z[i+2]=='x' || z[i+2]=='X') && sqlite3Isxdigit(z[i+3]) ){
204277 pParse->hasNonstd = 1;
204278 jnFlags |= JNODE_JSON5;
204279 for(j=i+4; sqlite3Isxdigit(z[j]); j++){}
204280 goto parse_number_finish;
204281 }
204282 }
204283 }
204284 }
 
204285 parse_number_2:
204286 for(j=i+1;; j++){
204287 c = z[j];
204288 if( sqlite3Isdigit(c) ) continue;
204289 if( c=='.' ){
204290 if( seenDP==JSON_REAL ){
204291 pParse->iErr = j;
204292 return -1;
204293 }
204294 seenDP = JSON_REAL;
204295 continue;
204296 }
204297 if( c=='e' || c=='E' ){
204298 if( z[j-1]<'0' ){
204299 if( ALWAYS(z[j-1]=='.') && ALWAYS(j-2>=i) && sqlite3Isdigit(z[j-2]) ){
204300 pParse->hasNonstd = 1;
204301 jnFlags |= JNODE_JSON5;
204302 }else{
204303 pParse->iErr = j;
204304 return -1;
204305 }
204306 }
204307 if( seenE ){
204308 pParse->iErr = j;
204309 return -1;
204310 }
204311 seenDP = JSON_REAL;
204312 seenE = 1;
204313 c = z[j+1];
204314 if( c=='+' || c=='-' ){
204315 j++;
204316 c = z[j+1];
@@ -204324,18 +204820,22 @@
204324 break;
204325 }
204326 if( z[j-1]<'0' ){
204327 if( ALWAYS(z[j-1]=='.') && ALWAYS(j-2>=i) && sqlite3Isdigit(z[j-2]) ){
204328 pParse->hasNonstd = 1;
204329 jnFlags |= JNODE_JSON5;
204330 }else{
204331 pParse->iErr = j;
204332 return -1;
204333 }
204334 }
204335 parse_number_finish:
204336 jsonParseAddNode(pParse, seenDP | (jnFlags<<8), j - i, &z[i]);
 
 
 
 
204337 return j;
204338 }
204339 case '}': {
204340 pParse->iErr = i;
204341 return -2; /* End of {...} */
@@ -204357,13 +204857,11 @@
204357 }
204358 case 0x09:
204359 case 0x0a:
204360 case 0x0d:
204361 case 0x20: {
204362 do{
204363 i++;
204364 }while( fast_isspace(z[i]) );
204365 goto json_parse_restart;
204366 }
204367 case 0x0b:
204368 case 0x0c:
204369 case '/':
@@ -204381,11 +204879,11 @@
204381 pParse->iErr = i;
204382 return -1;
204383 }
204384 case 'n': {
204385 if( strncmp(z+i,"null",4)==0 && !sqlite3Isalnum(z[i+4]) ){
204386 jsonParseAddNode(pParse, JSON_NULL, 0, 0);
204387 return i+4;
204388 }
204389 /* fall-through into the default case that checks for NaN */
204390 }
204391 default: {
@@ -204397,43 +204895,53 @@
204397 nn = aNanInfName[k].n;
204398 if( sqlite3StrNICmp(&z[i], aNanInfName[k].zMatch, nn)!=0 ){
204399 continue;
204400 }
204401 if( sqlite3Isalnum(z[i+nn]) ) continue;
204402 jsonParseAddNode(pParse, aNanInfName[k].eType,
204403 aNanInfName[k].nRepl, aNanInfName[k].zRepl);
 
 
 
204404 pParse->hasNonstd = 1;
204405 return i + nn;
204406 }
204407 pParse->iErr = i;
204408 return -1; /* Syntax error */
204409 }
204410 } /* End switch(z[i]) */
204411 }
 
204412
204413 /*
204414 ** Parse a complete JSON string. Return 0 on success or non-zero if there
204415 ** are any errors. If an error occurs, free all memory held by pParse,
204416 ** but not pParse itself.
204417 **
204418 ** pParse must be initialized to an empty parse object prior to calling
204419 ** this routine.
204420 */
204421 static int jsonParse(
204422 JsonParse *pParse, /* Initialize and fill this JsonParse object */
204423 sqlite3_context *pCtx /* Report errors here */
204424 ){
204425 int i;
204426 const char *zJson = pParse->zJson;
204427 i = jsonParseValue(pParse, 0);
204428 if( pParse->oom ) i = -1;
204429 if( i>0 ){
 
204430 assert( pParse->iDepth==0 );
204431 while( fast_isspace(zJson[i]) ) i++;
 
 
 
 
204432 if( zJson[i] ){
204433 i += json5Whitespace(&zJson[i]);
204434 if( zJson[i] ){
 
204435 jsonParseReset(pParse);
204436 return 1;
204437 }
204438 pParse->hasNonstd = 1;
204439 }
@@ -204450,617 +204958,1508 @@
204450 return 1;
204451 }
204452 return 0;
204453 }
204454
204455
204456 /* Mark node i of pParse as being a child of iParent. Call recursively
204457 ** to fill in all the descendants of node i.
204458 */
204459 static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){
204460 JsonNode *pNode = &pParse->aNode[i];
204461 u32 j;
204462 pParse->aUp[i] = iParent;
204463 switch( pNode->eType ){
204464 case JSON_ARRAY: {
204465 for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){
204466 jsonParseFillInParentage(pParse, i+j, i);
204467 }
204468 break;
204469 }
204470 case JSON_OBJECT: {
204471 for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){
204472 pParse->aUp[i+j] = i;
204473 jsonParseFillInParentage(pParse, i+j+1, i);
204474 }
204475 break;
204476 }
204477 default: {
204478 break;
204479 }
204480 }
204481 }
204482
204483 /*
204484 ** Compute the parentage of all nodes in a completed parse.
204485 */
204486 static int jsonParseFindParents(JsonParse *pParse){
204487 u32 *aUp;
204488 assert( pParse->aUp==0 );
204489 aUp = pParse->aUp = sqlite3_malloc64( sizeof(u32)*pParse->nNode );
204490 if( aUp==0 ){
204491 pParse->oom = 1;
204492 return SQLITE_NOMEM;
204493 }
204494 jsonParseFillInParentage(pParse, 0, 0);
204495 return SQLITE_OK;
204496 }
204497
204498 /*
204499 ** Magic number used for the JSON parse cache in sqlite3_get_auxdata()
204500 */
204501 #define JSON_CACHE_ID (-429938) /* First cache entry */
204502 #define JSON_CACHE_SZ 4 /* Max number of cache entries */
204503
204504 /*
204505 ** Obtain a complete parse of the JSON found in the pJson argument
204506 **
204507 ** Use the sqlite3_get_auxdata() cache to find a preexisting parse
204508 ** if it is available. If the cache is not available or if it
204509 ** is no longer valid, parse the JSON again and return the new parse.
204510 ** Also register the new parse so that it will be available for
204511 ** future sqlite3_get_auxdata() calls.
204512 **
204513 ** If an error occurs and pErrCtx!=0 then report the error on pErrCtx
204514 ** and return NULL.
204515 **
204516 ** The returned pointer (if it is not NULL) is owned by the cache in
204517 ** most cases, not the caller. The caller does NOT need to invoke
204518 ** jsonParseFree(), in most cases.
204519 **
204520 ** Except, if an error occurs and pErrCtx==0 then return the JsonParse
204521 ** object with JsonParse.nErr non-zero and the caller will own the JsonParse
204522 ** object. In that case, it will be the responsibility of the caller to
204523 ** invoke jsonParseFree(). To summarize:
204524 **
204525 ** pErrCtx!=0 || p->nErr==0 ==> Return value p is owned by the
204526 ** cache. Call does not need to
204527 ** free it.
204528 **
204529 ** pErrCtx==0 && p->nErr!=0 ==> Return value is owned by the caller
204530 ** and so the caller must free it.
204531 */
204532 static JsonParse *jsonParseCached(
204533 sqlite3_context *pCtx, /* Context to use for cache search */
204534 sqlite3_value *pJson, /* Function param containing JSON text */
204535 sqlite3_context *pErrCtx, /* Write parse errors here if not NULL */
204536 int bUnedited /* No prior edits allowed */
204537 ){
204538 char *zJson = (char*)sqlite3_value_text(pJson);
204539 int nJson = sqlite3_value_bytes(pJson);
204540 JsonParse *p;
204541 JsonParse *pMatch = 0;
204542 int iKey;
204543 int iMinKey = 0;
204544 u32 iMinHold = 0xffffffff;
204545 u32 iMaxHold = 0;
204546 int bJsonRCStr;
204547
204548 if( zJson==0 ) return 0;
204549 for(iKey=0; iKey<JSON_CACHE_SZ; iKey++){
204550 p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iKey);
204551 if( p==0 ){
204552 iMinKey = iKey;
204553 break;
204554 }
204555 if( pMatch==0
204556 && p->nJson==nJson
204557 && (p->hasMod==0 || bUnedited==0)
204558 && (p->zJson==zJson || memcmp(p->zJson,zJson,nJson)==0)
204559 ){
204560 p->nErr = 0;
204561 p->useMod = 0;
204562 pMatch = p;
204563 }else
204564 if( pMatch==0
204565 && p->zAlt!=0
204566 && bUnedited==0
204567 && p->nAlt==nJson
204568 && memcmp(p->zAlt, zJson, nJson)==0
204569 ){
204570 p->nErr = 0;
204571 p->useMod = 1;
204572 pMatch = p;
204573 }else if( p->iHold<iMinHold ){
204574 iMinHold = p->iHold;
204575 iMinKey = iKey;
204576 }
204577 if( p->iHold>iMaxHold ){
204578 iMaxHold = p->iHold;
204579 }
204580 }
204581 if( pMatch ){
204582 /* The input JSON text was found in the cache. Use the preexisting
204583 ** parse of this JSON */
204584 pMatch->nErr = 0;
204585 pMatch->iHold = iMaxHold+1;
204586 assert( pMatch->nJPRef>0 ); /* pMatch is owned by the cache */
204587 return pMatch;
204588 }
204589
204590 /* The input JSON was not found anywhere in the cache. We will need
204591 ** to parse it ourselves and generate a new JsonParse object.
204592 */
204593 bJsonRCStr = sqlite3ValueIsOfClass(pJson,sqlite3RCStrUnref);
204594 p = sqlite3_malloc64( sizeof(*p) + (bJsonRCStr ? 0 : nJson+1) );
204595 if( p==0 ){
204596 sqlite3_result_error_nomem(pCtx);
204597 return 0;
204598 }
204599 memset(p, 0, sizeof(*p));
204600 if( bJsonRCStr ){
204601 p->zJson = sqlite3RCStrRef(zJson);
204602 p->bJsonIsRCStr = 1;
204603 }else{
204604 p->zJson = (char*)&p[1];
204605 memcpy(p->zJson, zJson, nJson+1);
204606 }
204607 p->nJPRef = 1;
204608 if( jsonParse(p, pErrCtx) ){
204609 if( pErrCtx==0 ){
204610 p->nErr = 1;
204611 assert( p->nJPRef==1 ); /* Caller will own the new JsonParse object p */
204612 return p;
204613 }
204614 jsonParseFree(p);
204615 return 0;
204616 }
204617 p->nJson = nJson;
204618 p->iHold = iMaxHold+1;
204619 /* Transfer ownership of the new JsonParse to the cache */
204620 sqlite3_set_auxdata(pCtx, JSON_CACHE_ID+iMinKey, p,
204621 (void(*)(void*))jsonParseFree);
204622 return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iMinKey);
204623 }
204624
204625 /*
204626 ** Compare the OBJECT label at pNode against zKey,nKey. Return true on
204627 ** a match.
204628 */
204629 static int jsonLabelCompare(const JsonNode *pNode, const char *zKey, u32 nKey){
204630 assert( pNode->eU==1 );
204631 if( pNode->jnFlags & JNODE_RAW ){
204632 if( pNode->n!=nKey ) return 0;
204633 return strncmp(pNode->u.zJContent, zKey, nKey)==0;
204634 }else{
204635 if( pNode->n!=nKey+2 ) return 0;
204636 return strncmp(pNode->u.zJContent+1, zKey, nKey)==0;
204637 }
204638 }
204639 static int jsonSameLabel(const JsonNode *p1, const JsonNode *p2){
204640 if( p1->jnFlags & JNODE_RAW ){
204641 return jsonLabelCompare(p2, p1->u.zJContent, p1->n);
204642 }else if( p2->jnFlags & JNODE_RAW ){
204643 return jsonLabelCompare(p1, p2->u.zJContent, p2->n);
204644 }else{
204645 return p1->n==p2->n && strncmp(p1->u.zJContent,p2->u.zJContent,p1->n)==0;
204646 }
204647 }
204648
204649 /* forward declaration */
204650 static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**);
204651
204652 /*
204653 ** Search along zPath to find the node specified. Return a pointer
204654 ** to that node, or NULL if zPath is malformed or if there is no such
204655 ** node.
204656 **
204657 ** If pApnd!=0, then try to append new nodes to complete zPath if it is
204658 ** possible to do so and if no existing node corresponds to zPath. If
204659 ** new nodes are appended *pApnd is set to 1.
204660 */
204661 static JsonNode *jsonLookupStep(
204662 JsonParse *pParse, /* The JSON to search */
204663 u32 iRoot, /* Begin the search at this node */
204664 const char *zPath, /* The path to search */
204665 int *pApnd, /* Append nodes to complete path if not NULL */
204666 const char **pzErr /* Make *pzErr point to any syntax error in zPath */
204667 ){
204668 u32 i, j, nKey;
204669 const char *zKey;
204670 JsonNode *pRoot;
204671 if( pParse->oom ) return 0;
204672 pRoot = &pParse->aNode[iRoot];
204673 if( pRoot->jnFlags & (JNODE_REPLACE|JNODE_REMOVE) && pParse->useMod ){
204674 while( (pRoot->jnFlags & JNODE_REPLACE)!=0 ){
204675 u32 idx = (u32)(pRoot - pParse->aNode);
204676 i = pParse->iSubst;
204677 while( 1 /*exit-by-break*/ ){
204678 assert( i<pParse->nNode );
204679 assert( pParse->aNode[i].eType==JSON_SUBST );
204680 assert( pParse->aNode[i].eU==4 );
204681 assert( pParse->aNode[i].u.iPrev<i );
204682 if( pParse->aNode[i].n==idx ){
204683 pRoot = &pParse->aNode[i+1];
204684 iRoot = i+1;
204685 break;
204686 }
204687 i = pParse->aNode[i].u.iPrev;
204688 }
204689 }
204690 if( pRoot->jnFlags & JNODE_REMOVE ){
204691 return 0;
204692 }
204693 }
204694 if( zPath[0]==0 ) return pRoot;
204695 if( zPath[0]=='.' ){
204696 if( pRoot->eType!=JSON_OBJECT ) return 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204697 zPath++;
204698 if( zPath[0]=='"' ){
204699 zKey = zPath + 1;
204700 for(i=1; zPath[i] && zPath[i]!='"'; i++){}
204701 nKey = i-1;
204702 if( zPath[i] ){
204703 i++;
204704 }else{
204705 *pzErr = zPath;
204706 return 0;
204707 }
204708 testcase( nKey==0 );
 
204709 }else{
204710 zKey = zPath;
204711 for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
204712 nKey = i;
204713 if( nKey==0 ){
204714 *pzErr = zPath;
204715 return 0;
204716 }
204717 }
204718 j = 1;
204719 for(;;){
204720 while( j<=pRoot->n ){
204721 if( jsonLabelCompare(pRoot+j, zKey, nKey) ){
204722 return jsonLookupStep(pParse, iRoot+j+1, &zPath[i], pApnd, pzErr);
204723 }
204724 j++;
204725 j += jsonNodeSize(&pRoot[j]);
204726 }
204727 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
204728 if( pParse->useMod==0 ) break;
204729 assert( pRoot->eU==2 );
204730 iRoot = pRoot->u.iAppend;
204731 pRoot = &pParse->aNode[iRoot];
204732 j = 1;
204733 }
204734 if( pApnd ){
204735 u32 iStart, iLabel;
204736 JsonNode *pNode;
204737 assert( pParse->useMod );
204738 iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
204739 iLabel = jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
204740 zPath += i;
204741 pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
204742 if( pParse->oom ) return 0;
204743 if( pNode ){
204744 pRoot = &pParse->aNode[iRoot];
204745 assert( pRoot->eU==0 );
204746 pRoot->u.iAppend = iStart;
204747 pRoot->jnFlags |= JNODE_APPEND;
204748 VVA( pRoot->eU = 2 );
204749 pParse->aNode[iLabel].jnFlags |= JNODE_RAW;
204750 }
204751 return pNode;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204752 }
204753 }else if( zPath[0]=='[' ){
204754 i = 0;
204755 j = 1;
204756 while( sqlite3Isdigit(zPath[j]) ){
204757 i = i*10 + zPath[j] - '0';
204758 j++;
204759 }
204760 if( j<2 || zPath[j]!=']' ){
204761 if( zPath[1]=='#' ){
204762 JsonNode *pBase = pRoot;
204763 int iBase = iRoot;
204764 if( pRoot->eType!=JSON_ARRAY ) return 0;
204765 for(;;){
204766 while( j<=pBase->n ){
204767 if( (pBase[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ) i++;
204768 j += jsonNodeSize(&pBase[j]);
204769 }
204770 if( (pBase->jnFlags & JNODE_APPEND)==0 ) break;
204771 if( pParse->useMod==0 ) break;
204772 assert( pBase->eU==2 );
204773 iBase = pBase->u.iAppend;
204774 pBase = &pParse->aNode[iBase];
204775 j = 1;
204776 }
204777 j = 2;
204778 if( zPath[2]=='-' && sqlite3Isdigit(zPath[3]) ){
204779 unsigned int x = 0;
204780 j = 3;
204781 do{
204782 x = x*10 + zPath[j] - '0';
204783 j++;
204784 }while( sqlite3Isdigit(zPath[j]) );
204785 if( x>i ) return 0;
204786 i -= x;
204787 }
204788 if( zPath[j]!=']' ){
204789 *pzErr = zPath;
204790 return 0;
204791 }
204792 }else{
204793 *pzErr = zPath;
204794 return 0;
204795 }
204796 }
204797 if( pRoot->eType!=JSON_ARRAY ) return 0;
204798 zPath += j + 1;
204799 j = 1;
204800 for(;;){
204801 while( j<=pRoot->n
204802 && (i>0 || ((pRoot[j].jnFlags & JNODE_REMOVE)!=0 && pParse->useMod))
204803 ){
204804 if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ) i--;
204805 j += jsonNodeSize(&pRoot[j]);
204806 }
204807 if( i==0 && j<=pRoot->n ) break;
204808 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
204809 if( pParse->useMod==0 ) break;
204810 assert( pRoot->eU==2 );
204811 iRoot = pRoot->u.iAppend;
204812 pRoot = &pParse->aNode[iRoot];
204813 j = 1;
204814 }
204815 if( j<=pRoot->n ){
204816 return jsonLookupStep(pParse, iRoot+j, zPath, pApnd, pzErr);
204817 }
204818 if( i==0 && pApnd ){
204819 u32 iStart;
204820 JsonNode *pNode;
204821 assert( pParse->useMod );
204822 iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
204823 pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
204824 if( pParse->oom ) return 0;
204825 if( pNode ){
204826 pRoot = &pParse->aNode[iRoot];
204827 assert( pRoot->eU==0 );
204828 pRoot->u.iAppend = iStart;
204829 pRoot->jnFlags |= JNODE_APPEND;
204830 VVA( pRoot->eU = 2 );
204831 }
204832 return pNode;
204833 }
204834 }else{
204835 *pzErr = zPath;
204836 }
204837 return 0;
204838 }
204839
204840 /*
204841 ** Append content to pParse that will complete zPath. Return a pointer
204842 ** to the inserted node, or return NULL if the append fails.
204843 */
204844 static JsonNode *jsonLookupAppend(
204845 JsonParse *pParse, /* Append content to the JSON parse */
204846 const char *zPath, /* Description of content to append */
204847 int *pApnd, /* Set this flag to 1 */
204848 const char **pzErr /* Make this point to any syntax error */
204849 ){
204850 *pApnd = 1;
204851 if( zPath[0]==0 ){
204852 jsonParseAddNode(pParse, JSON_NULL, 0, 0);
204853 return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1];
204854 }
204855 if( zPath[0]=='.' ){
204856 jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
204857 }else if( strncmp(zPath,"[0]",3)==0 ){
204858 jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
204859 }else{
204860 return 0;
204861 }
204862 if( pParse->oom ) return 0;
204863 return jsonLookupStep(pParse, pParse->nNode-1, zPath, pApnd, pzErr);
204864 }
204865
204866 /*
204867 ** Return the text of a syntax error message on a JSON path. Space is
204868 ** obtained from sqlite3_malloc().
204869 */
204870 static char *jsonPathSyntaxError(const char *zErr){
204871 return sqlite3_mprintf("JSON path error near '%q'", zErr);
204872 }
204873
204874 /*
204875 ** Do a node lookup using zPath. Return a pointer to the node on success.
204876 ** Return NULL if not found or if there is an error.
204877 **
204878 ** On an error, write an error message into pCtx and increment the
204879 ** pParse->nErr counter.
204880 **
204881 ** If pApnd!=NULL then try to append missing nodes and set *pApnd = 1 if
204882 ** nodes are appended.
204883 */
204884 static JsonNode *jsonLookup(
204885 JsonParse *pParse, /* The JSON to search */
204886 const char *zPath, /* The path to search */
204887 int *pApnd, /* Append nodes to complete path if not NULL */
204888 sqlite3_context *pCtx /* Report errors here, if not NULL */
204889 ){
204890 const char *zErr = 0;
204891 JsonNode *pNode = 0;
204892 char *zMsg;
204893
204894 if( zPath==0 ) return 0;
204895 if( zPath[0]!='$' ){
204896 zErr = zPath;
204897 goto lookup_err;
204898 }
204899 zPath++;
204900 pNode = jsonLookupStep(pParse, 0, zPath, pApnd, &zErr);
204901 if( zErr==0 ) return pNode;
204902
204903 lookup_err:
204904 pParse->nErr++;
204905 assert( zErr!=0 && pCtx!=0 );
204906 zMsg = jsonPathSyntaxError(zErr);
204907 if( zMsg ){
204908 sqlite3_result_error(pCtx, zMsg, -1);
204909 sqlite3_free(zMsg);
204910 }else{
204911 sqlite3_result_error_nomem(pCtx);
204912 }
204913 return 0;
204914 }
204915
204916
204917 /*
204918 ** Report the wrong number of arguments for json_insert(), json_replace()
204919 ** or json_set().
204920 */
204921 static void jsonWrongNumArgs(
204922 sqlite3_context *pCtx,
204923 const char *zFuncName
204924 ){
204925 char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments",
204926 zFuncName);
204927 sqlite3_result_error(pCtx, zMsg, -1);
204928 sqlite3_free(zMsg);
204929 }
204930
204931 /*
204932 ** Mark all NULL entries in the Object passed in as JNODE_REMOVE.
204933 */
204934 static void jsonRemoveAllNulls(JsonNode *pNode){
204935 int i, n;
204936 assert( pNode->eType==JSON_OBJECT );
204937 n = pNode->n;
204938 for(i=2; i<=n; i += jsonNodeSize(&pNode[i])+1){
204939 switch( pNode[i].eType ){
204940 case JSON_NULL:
204941 pNode[i].jnFlags |= JNODE_REMOVE;
204942 break;
204943 case JSON_OBJECT:
204944 jsonRemoveAllNulls(&pNode[i]);
204945 break;
204946 }
204947 }
204948 }
204949
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204950
204951 /****************************************************************************
204952 ** SQL functions used for testing and debugging
204953 ****************************************************************************/
204954
204955 #if SQLITE_DEBUG
204956 /*
204957 ** Print N node entries.
204958 */
204959 static void jsonDebugPrintNodeEntries(
204960 JsonNode *aNode, /* First node entry to print */
204961 int N /* Number of node entries to print */
204962 ){
204963 int i;
204964 for(i=0; i<N; i++){
204965 const char *zType;
204966 if( aNode[i].jnFlags & JNODE_LABEL ){
204967 zType = "label";
204968 }else{
204969 zType = jsonType[aNode[i].eType];
204970 }
204971 printf("node %4u: %-7s n=%-5d", i, zType, aNode[i].n);
204972 if( (aNode[i].jnFlags & ~JNODE_LABEL)!=0 ){
204973 u8 f = aNode[i].jnFlags;
204974 if( f & JNODE_RAW ) printf(" RAW");
204975 if( f & JNODE_ESCAPE ) printf(" ESCAPE");
204976 if( f & JNODE_REMOVE ) printf(" REMOVE");
204977 if( f & JNODE_REPLACE ) printf(" REPLACE");
204978 if( f & JNODE_APPEND ) printf(" APPEND");
204979 if( f & JNODE_JSON5 ) printf(" JSON5");
204980 }
204981 switch( aNode[i].eU ){
204982 case 1: printf(" zJContent=[%.*s]\n",
204983 aNode[i].n, aNode[i].u.zJContent); break;
204984 case 2: printf(" iAppend=%u\n", aNode[i].u.iAppend); break;
204985 case 3: printf(" iKey=%u\n", aNode[i].u.iKey); break;
204986 case 4: printf(" iPrev=%u\n", aNode[i].u.iPrev); break;
204987 default: printf("\n");
204988 }
204989 }
204990 }
204991 #endif /* SQLITE_DEBUG */
204992
204993
204994 #if 0 /* 1 for debugging. 0 normally. Requires -DSQLITE_DEBUG too */
204995 static void jsonDebugPrintParse(JsonParse *p){
204996 jsonDebugPrintNodeEntries(p->aNode, p->nNode);
204997 }
204998 static void jsonDebugPrintNode(JsonNode *pNode){
204999 jsonDebugPrintNodeEntries(pNode, jsonNodeSize(pNode));
205000 }
205001 #else
205002 /* The usual case */
205003 # define jsonDebugPrintNode(X)
205004 # define jsonDebugPrintParse(X)
205005 #endif
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205006
205007 #ifdef SQLITE_DEBUG
205008 /*
205009 ** SQL function: json_parse(JSON)
205010 **
205011 ** Parse JSON using jsonParseCached(). Then print a dump of that
205012 ** parse on standard output. Return the mimified JSON result, just
205013 ** like the json() function.
205014 */
205015 static void jsonParseFunc(
205016 sqlite3_context *ctx,
205017 int argc,
205018 sqlite3_value **argv
205019 ){
205020 JsonParse *p; /* The parse */
205021
205022 assert( argc==1 );
205023 p = jsonParseCached(ctx, argv[0], ctx, 0);
205024 if( p==0 ) return;
205025 printf("nNode = %u\n", p->nNode);
205026 printf("nAlloc = %u\n", p->nAlloc);
205027 printf("nJson = %d\n", p->nJson);
205028 printf("nAlt = %d\n", p->nAlt);
205029 printf("nErr = %u\n", p->nErr);
205030 printf("oom = %u\n", p->oom);
205031 printf("hasNonstd = %u\n", p->hasNonstd);
205032 printf("useMod = %u\n", p->useMod);
205033 printf("hasMod = %u\n", p->hasMod);
205034 printf("nJPRef = %u\n", p->nJPRef);
205035 printf("iSubst = %u\n", p->iSubst);
205036 printf("iHold = %u\n", p->iHold);
205037 jsonDebugPrintNodeEntries(p->aNode, p->nNode);
205038 jsonReturnJson(p, p->aNode, ctx, 1, 0);
205039 }
205040
205041 /*
205042 ** The json_test1(JSON) function return true (1) if the input is JSON
205043 ** text generated by another json function. It returns (0) if the input
205044 ** is not known to be JSON.
205045 */
205046 static void jsonTest1Func(
205047 sqlite3_context *ctx,
205048 int argc,
205049 sqlite3_value **argv
205050 ){
205051 UNUSED_PARAMETER(argc);
205052 sqlite3_result_int(ctx, sqlite3_value_subtype(argv[0])==JSON_SUBTYPE);
205053 }
205054 #endif /* SQLITE_DEBUG */
205055
205056 /****************************************************************************
205057 ** Scalar SQL function implementations
205058 ****************************************************************************/
205059
205060 /*
205061 ** Implementation of the json_QUOTE(VALUE) function. Return a JSON value
205062 ** corresponding to the SQL value input. Mostly this means putting
205063 ** double-quotes around strings and returning the unquoted string "null"
205064 ** when given a NULL input.
205065 */
205066 static void jsonQuoteFunc(
@@ -205069,13 +206468,13 @@
205069 sqlite3_value **argv
205070 ){
205071 JsonString jx;
205072 UNUSED_PARAMETER(argc);
205073
205074 jsonInit(&jx, ctx);
205075 jsonAppendValue(&jx, argv[0]);
205076 jsonResult(&jx);
205077 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
205078 }
205079
205080 /*
205081 ** Implementation of the json_array(VALUE,...) function. Return a JSON
@@ -205088,21 +206487,20 @@
205088 sqlite3_value **argv
205089 ){
205090 int i;
205091 JsonString jx;
205092
205093 jsonInit(&jx, ctx);
205094 jsonAppendChar(&jx, '[');
205095 for(i=0; i<argc; i++){
205096 jsonAppendSeparator(&jx);
205097 jsonAppendValue(&jx, argv[i]);
205098 }
205099 jsonAppendChar(&jx, ']');
205100 jsonResult(&jx);
205101 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
205102 }
205103
205104
205105 /*
205106 ** json_array_length(JSON)
205107 ** json_array_length(JSON, PATH)
205108 **
@@ -205113,50 +206511,57 @@
205113 sqlite3_context *ctx,
205114 int argc,
205115 sqlite3_value **argv
205116 ){
205117 JsonParse *p; /* The parse */
205118 sqlite3_int64 n = 0;
205119 u32 i;
205120 JsonNode *pNode;
205121
205122 p = jsonParseCached(ctx, argv[0], ctx, 0);
205123 if( p==0 ) return;
205124 assert( p->nNode );
205125 if( argc==2 ){
205126 const char *zPath = (const char*)sqlite3_value_text(argv[1]);
205127 pNode = jsonLookup(p, zPath, 0, ctx);
205128 }else{
205129 pNode = p->aNode;
205130 }
205131 if( pNode==0 ){
205132 return;
205133 }
205134 if( pNode->eType==JSON_ARRAY ){
205135 while( 1 /*exit-by-break*/ ){
205136 i = 1;
205137 while( i<=pNode->n ){
205138 if( (pNode[i].jnFlags & JNODE_REMOVE)==0 ) n++;
205139 i += jsonNodeSize(&pNode[i]);
205140 }
205141 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
205142 if( p->useMod==0 ) break;
205143 assert( pNode->eU==2 );
205144 pNode = &p->aNode[pNode->u.iAppend];
205145 }
205146 }
205147 sqlite3_result_int64(ctx, n);
205148 }
205149
205150 /*
205151 ** Bit values for the flags passed into jsonExtractFunc() or
205152 ** jsonSetFunc() via the user-data value.
205153 */
205154 #define JSON_JSON 0x01 /* Result is always JSON */
205155 #define JSON_SQL 0x02 /* Result is always SQL */
205156 #define JSON_ABPATH 0x03 /* Allow abbreviated JSON path specs */
205157 #define JSON_ISSET 0x04 /* json_set(), not json_insert() */
 
 
 
 
 
 
 
 
205158
205159 /*
205160 ** json_extract(JSON, PATH, ...)
205161 ** "->"(JSON,PATH)
205162 ** "->>"(JSON,PATH)
@@ -205179,154 +206584,310 @@
205179 static void jsonExtractFunc(
205180 sqlite3_context *ctx,
205181 int argc,
205182 sqlite3_value **argv
205183 ){
205184 JsonParse *p; /* The parse */
205185 JsonNode *pNode;
205186 const char *zPath;
205187 int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx));
205188 JsonString jx;
205189
205190 if( argc<2 ) return;
205191 p = jsonParseCached(ctx, argv[0], ctx, 0);
205192 if( p==0 ) return;
205193 if( argc==2 ){
 
 
 
 
 
205194 /* With a single PATH argument */
205195 zPath = (const char*)sqlite3_value_text(argv[1]);
205196 if( zPath==0 ) return;
205197 if( flags & JSON_ABPATH ){
205198 if( zPath[0]!='$' || (zPath[1]!='.' && zPath[1]!='[' && zPath[1]!=0) ){
205199 /* The -> and ->> operators accept abbreviated PATH arguments. This
205200 ** is mostly for compatibility with PostgreSQL, but also for
205201 ** convenience.
205202 **
205203 ** NUMBER ==> $[NUMBER] // PG compatible
205204 ** LABEL ==> $.LABEL // PG compatible
205205 ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience
205206 */
205207 jsonInit(&jx, ctx);
205208 if( sqlite3Isdigit(zPath[0]) ){
205209 jsonAppendRawNZ(&jx, "$[", 2);
205210 jsonAppendRaw(&jx, zPath, (int)strlen(zPath));
205211 jsonAppendRawNZ(&jx, "]", 2);
205212 }else{
205213 jsonAppendRawNZ(&jx, "$.", 1 + (zPath[0]!='['));
205214 jsonAppendRaw(&jx, zPath, (int)strlen(zPath));
205215 jsonAppendChar(&jx, 0);
205216 }
205217 pNode = jx.bErr ? 0 : jsonLookup(p, jx.zBuf, 0, ctx);
205218 jsonReset(&jx);
205219 }else{
205220 pNode = jsonLookup(p, zPath, 0, ctx);
205221 }
205222 if( pNode ){
 
 
 
 
 
 
 
 
 
 
 
 
205223 if( flags & JSON_JSON ){
205224 jsonReturnJson(p, pNode, ctx, 0, 0);
205225 }else{
205226 jsonReturn(p, pNode, ctx, 1);
205227 }
205228 }
205229 }else{
205230 pNode = jsonLookup(p, zPath, 0, ctx);
205231 if( p->nErr==0 && pNode ) jsonReturn(p, pNode, ctx, 0);
205232 }
205233 }else{
205234 /* Two or more PATH arguments results in a JSON array with each
205235 ** element of the array being the value selected by one of the PATHs */
205236 int i;
205237 jsonInit(&jx, ctx);
205238 jsonAppendChar(&jx, '[');
205239 for(i=1; i<argc; i++){
205240 zPath = (const char*)sqlite3_value_text(argv[i]);
205241 pNode = jsonLookup(p, zPath, 0, ctx);
205242 if( p->nErr ) break;
205243 jsonAppendSeparator(&jx);
205244 if( pNode ){
205245 jsonRenderNode(p, pNode, &jx);
205246 }else{
205247 jsonAppendRawNZ(&jx, "null", 4);
205248 }
 
 
 
 
 
 
205249 }
205250 if( i==argc ){
205251 jsonAppendChar(&jx, ']');
205252 jsonResult(&jx);
 
 
205253 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
205254 }
205255 jsonReset(&jx);
205256 }
205257 }
205258
205259 /* This is the RFC 7396 MergePatch algorithm.
205260 */
205261 static JsonNode *jsonMergePatch(
205262 JsonParse *pParse, /* The JSON parser that contains the TARGET */
205263 u32 iTarget, /* Node of the TARGET in pParse */
205264 JsonNode *pPatch /* The PATCH */
205265 ){
205266 u32 i, j;
205267 u32 iRoot;
205268 JsonNode *pTarget;
205269 if( pPatch->eType!=JSON_OBJECT ){
205270 return pPatch;
205271 }
205272 assert( iTarget<pParse->nNode );
205273 pTarget = &pParse->aNode[iTarget];
205274 assert( (pPatch->jnFlags & JNODE_APPEND)==0 );
205275 if( pTarget->eType!=JSON_OBJECT ){
205276 jsonRemoveAllNulls(pPatch);
205277 return pPatch;
205278 }
205279 iRoot = iTarget;
205280 for(i=1; i<pPatch->n; i += jsonNodeSize(&pPatch[i+1])+1){
205281 u32 nKey;
205282 const char *zKey;
205283 assert( pPatch[i].eType==JSON_STRING );
205284 assert( pPatch[i].jnFlags & JNODE_LABEL );
205285 assert( pPatch[i].eU==1 );
205286 nKey = pPatch[i].n;
205287 zKey = pPatch[i].u.zJContent;
205288 for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){
205289 assert( pTarget[j].eType==JSON_STRING );
205290 assert( pTarget[j].jnFlags & JNODE_LABEL );
205291 if( jsonSameLabel(&pPatch[i], &pTarget[j]) ){
205292 if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ) break;
205293 if( pPatch[i+1].eType==JSON_NULL ){
205294 pTarget[j+1].jnFlags |= JNODE_REMOVE;
205295 }else{
205296 JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]);
205297 if( pNew==0 ) return 0;
205298 if( pNew!=&pParse->aNode[iTarget+j+1] ){
205299 jsonParseAddSubstNode(pParse, iTarget+j+1);
205300 jsonParseAddNodeArray(pParse, pNew, jsonNodeSize(pNew));
205301 }
205302 pTarget = &pParse->aNode[iTarget];
205303 }
205304 break;
205305 }
205306 }
205307 if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){
205308 int iStart;
205309 JsonNode *pApnd;
205310 u32 nApnd;
205311 iStart = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
205312 jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
205313 pApnd = &pPatch[i+1];
205314 if( pApnd->eType==JSON_OBJECT ) jsonRemoveAllNulls(pApnd);
205315 nApnd = jsonNodeSize(pApnd);
205316 jsonParseAddNodeArray(pParse, pApnd, jsonNodeSize(pApnd));
205317 if( pParse->oom ) return 0;
205318 pParse->aNode[iStart].n = 1+nApnd;
205319 pParse->aNode[iRoot].jnFlags |= JNODE_APPEND;
205320 pParse->aNode[iRoot].u.iAppend = iStart;
205321 VVA( pParse->aNode[iRoot].eU = 2 );
205322 iRoot = iStart;
205323 pTarget = &pParse->aNode[iTarget];
205324 }
205325 }
205326 return pTarget;
205327 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205328
205329 /*
205330 ** Implementation of the json_mergepatch(JSON1,JSON2) function. Return a JSON
205331 ** object that is the result of running the RFC 7396 MergePatch() algorithm
205332 ** on the two arguments.
@@ -205334,32 +206895,31 @@
205334 static void jsonPatchFunc(
205335 sqlite3_context *ctx,
205336 int argc,
205337 sqlite3_value **argv
205338 ){
205339 JsonParse *pX; /* The JSON that is being patched */
205340 JsonParse *pY; /* The patch */
205341 JsonNode *pResult; /* The result of the merge */
205342
205343 UNUSED_PARAMETER(argc);
205344 pX = jsonParseCached(ctx, argv[0], ctx, 1);
205345 if( pX==0 ) return;
205346 assert( pX->hasMod==0 );
205347 pX->hasMod = 1;
205348 pY = jsonParseCached(ctx, argv[1], ctx, 1);
205349 if( pY==0 ) return;
205350 pX->useMod = 1;
205351 pY->useMod = 1;
205352 pResult = jsonMergePatch(pX, 0, pY->aNode);
205353 assert( pResult!=0 || pX->oom );
205354 if( pResult && pX->oom==0 ){
205355 jsonDebugPrintParse(pX);
205356 jsonDebugPrintNode(pResult);
205357 jsonReturnJson(pX, pResult, ctx, 0, 0);
205358 }else{
205359 sqlite3_result_error_nomem(ctx);
205360 }
205361 }
205362
205363
205364 /*
205365 ** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON
@@ -205379,27 +206939,27 @@
205379 if( argc&1 ){
205380 sqlite3_result_error(ctx, "json_object() requires an even number "
205381 "of arguments", -1);
205382 return;
205383 }
205384 jsonInit(&jx, ctx);
205385 jsonAppendChar(&jx, '{');
205386 for(i=0; i<argc; i+=2){
205387 if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){
205388 sqlite3_result_error(ctx, "json_object() labels must be TEXT", -1);
205389 jsonReset(&jx);
205390 return;
205391 }
205392 jsonAppendSeparator(&jx);
205393 z = (const char*)sqlite3_value_text(argv[i]);
205394 n = (u32)sqlite3_value_bytes(argv[i]);
205395 jsonAppendString(&jx, z, n);
205396 jsonAppendChar(&jx, ':');
205397 jsonAppendValue(&jx, argv[i+1]);
205398 }
205399 jsonAppendChar(&jx, '}');
205400 jsonResult(&jx);
205401 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
205402 }
205403
205404
205405 /*
@@ -205411,124 +206971,54 @@
205411 static void jsonRemoveFunc(
205412 sqlite3_context *ctx,
205413 int argc,
205414 sqlite3_value **argv
205415 ){
205416 JsonParse *pParse; /* The parse */
205417 JsonNode *pNode;
205418 const char *zPath;
205419 u32 i;
205420
205421 if( argc<1 ) return;
205422 pParse = jsonParseCached(ctx, argv[0], ctx, argc>1);
205423 if( pParse==0 ) return;
205424 for(i=1; i<(u32)argc; i++){
205425 zPath = (const char*)sqlite3_value_text(argv[i]);
205426 if( zPath==0 ) goto remove_done;
205427 pNode = jsonLookup(pParse, zPath, 0, ctx);
205428 if( pParse->nErr ) goto remove_done;
205429 if( pNode ){
205430 pNode->jnFlags |= JNODE_REMOVE;
205431 pParse->hasMod = 1;
205432 pParse->useMod = 1;
205433 }
205434 }
205435 if( (pParse->aNode[0].jnFlags & JNODE_REMOVE)==0 ){
205436 jsonReturnJson(pParse, pParse->aNode, ctx, 1, 0);
205437 }
205438 remove_done:
205439 jsonDebugPrintParse(p);
205440 }
205441
205442 /*
205443 ** Substitute the value at iNode with the pValue parameter.
205444 */
205445 static void jsonReplaceNode(
205446 sqlite3_context *pCtx,
205447 JsonParse *p,
205448 int iNode,
205449 sqlite3_value *pValue
205450 ){
205451 int idx = jsonParseAddSubstNode(p, iNode);
205452 if( idx<=0 ){
205453 assert( p->oom );
205454 return;
205455 }
205456 switch( sqlite3_value_type(pValue) ){
205457 case SQLITE_NULL: {
205458 jsonParseAddNode(p, JSON_NULL, 0, 0);
205459 break;
205460 }
205461 case SQLITE_FLOAT: {
205462 char *z = sqlite3_mprintf("%!0.15g", sqlite3_value_double(pValue));
205463 int n;
205464 if( z==0 ){
205465 p->oom = 1;
205466 break;
205467 }
205468 n = sqlite3Strlen30(z);
205469 jsonParseAddNode(p, JSON_REAL, n, z);
205470 jsonParseAddCleanup(p, sqlite3_free, z);
205471 break;
205472 }
205473 case SQLITE_INTEGER: {
205474 char *z = sqlite3_mprintf("%lld", sqlite3_value_int64(pValue));
205475 int n;
205476 if( z==0 ){
205477 p->oom = 1;
205478 break;
205479 }
205480 n = sqlite3Strlen30(z);
205481 jsonParseAddNode(p, JSON_INT, n, z);
205482 jsonParseAddCleanup(p, sqlite3_free, z);
205483
205484 break;
205485 }
205486 case SQLITE_TEXT: {
205487 const char *z = (const char*)sqlite3_value_text(pValue);
205488 u32 n = (u32)sqlite3_value_bytes(pValue);
205489 if( z==0 ){
205490 p->oom = 1;
205491 break;
205492 }
205493 if( sqlite3_value_subtype(pValue)!=JSON_SUBTYPE ){
205494 char *zCopy = sqlite3_malloc64( n+1 );
205495 int k;
205496 if( zCopy ){
205497 memcpy(zCopy, z, n);
205498 zCopy[n] = 0;
205499 jsonParseAddCleanup(p, sqlite3_free, zCopy);
205500 }else{
205501 p->oom = 1;
205502 sqlite3_result_error_nomem(pCtx);
205503 }
205504 k = jsonParseAddNode(p, JSON_STRING, n, zCopy);
205505 assert( k>0 || p->oom );
205506 if( p->oom==0 ) p->aNode[k].jnFlags |= JNODE_RAW;
205507 }else{
205508 JsonParse *pPatch = jsonParseCached(pCtx, pValue, pCtx, 1);
205509 if( pPatch==0 ){
205510 p->oom = 1;
205511 break;
205512 }
205513 jsonParseAddNodeArray(p, pPatch->aNode, pPatch->nNode);
205514 /* The nodes copied out of pPatch and into p likely contain
205515 ** u.zJContent pointers into pPatch->zJson. So preserve the
205516 ** content of pPatch until p is destroyed. */
205517 assert( pPatch->nJPRef>=1 );
205518 pPatch->nJPRef++;
205519 jsonParseAddCleanup(p, (void(*)(void*))jsonParseFree, pPatch);
205520 }
205521 break;
205522 }
205523 default: {
205524 jsonParseAddNode(p, JSON_NULL, 0, 0);
205525 sqlite3_result_error(pCtx, "JSON cannot hold BLOB values", -1);
205526 p->nErr++;
205527 break;
205528 }
205529 }
205530 }
205531
205532 /*
205533 ** json_replace(JSON, PATH, VALUE, ...)
205534 **
@@ -205538,36 +207028,16 @@
205538 static void jsonReplaceFunc(
205539 sqlite3_context *ctx,
205540 int argc,
205541 sqlite3_value **argv
205542 ){
205543 JsonParse *pParse; /* The parse */
205544 JsonNode *pNode;
205545 const char *zPath;
205546 u32 i;
205547
205548 if( argc<1 ) return;
205549 if( (argc&1)==0 ) {
205550 jsonWrongNumArgs(ctx, "replace");
205551 return;
205552 }
205553 pParse = jsonParseCached(ctx, argv[0], ctx, argc>1);
205554 if( pParse==0 ) return;
205555 pParse->nJPRef++;
205556 for(i=1; i<(u32)argc; i+=2){
205557 zPath = (const char*)sqlite3_value_text(argv[i]);
205558 pParse->useMod = 1;
205559 pNode = jsonLookup(pParse, zPath, 0, ctx);
205560 if( pParse->nErr ) goto replace_err;
205561 if( pNode ){
205562 jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]);
205563 }
205564 }
205565 jsonReturnJson(pParse, pParse->aNode, ctx, 1, 0);
205566 replace_err:
205567 jsonDebugPrintParse(pParse);
205568 jsonParseFree(pParse);
205569 }
205570
205571
205572 /*
205573 ** json_set(JSON, PATH, VALUE, ...)
@@ -205584,43 +207054,20 @@
205584 static void jsonSetFunc(
205585 sqlite3_context *ctx,
205586 int argc,
205587 sqlite3_value **argv
205588 ){
205589 JsonParse *pParse; /* The parse */
205590 JsonNode *pNode;
205591 const char *zPath;
205592 u32 i;
205593 int bApnd;
205594 int bIsSet = sqlite3_user_data(ctx)!=0;
205595
205596 if( argc<1 ) return;
205597 if( (argc&1)==0 ) {
205598 jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert");
205599 return;
205600 }
205601 pParse = jsonParseCached(ctx, argv[0], ctx, argc>1);
205602 if( pParse==0 ) return;
205603 pParse->nJPRef++;
205604 for(i=1; i<(u32)argc; i+=2){
205605 zPath = (const char*)sqlite3_value_text(argv[i]);
205606 bApnd = 0;
205607 pParse->useMod = 1;
205608 pNode = jsonLookup(pParse, zPath, &bApnd, ctx);
205609 if( pParse->oom ){
205610 sqlite3_result_error_nomem(ctx);
205611 goto jsonSetDone;
205612 }else if( pParse->nErr ){
205613 goto jsonSetDone;
205614 }else if( pNode && (bApnd || bIsSet) ){
205615 jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]);
205616 }
205617 }
205618 jsonDebugPrintParse(pParse);
205619 jsonReturnJson(pParse, pParse->aNode, ctx, 1, 0);
205620 jsonSetDone:
205621 jsonParseFree(pParse);
205622 }
205623
205624 /*
205625 ** json_type(JSON)
205626 ** json_type(JSON, PATH)
@@ -205632,110 +207079,221 @@
205632 sqlite3_context *ctx,
205633 int argc,
205634 sqlite3_value **argv
205635 ){
205636 JsonParse *p; /* The parse */
205637 const char *zPath;
205638 JsonNode *pNode;
205639
205640 p = jsonParseCached(ctx, argv[0], ctx, 0);
205641 if( p==0 ) return;
205642 if( argc==2 ){
205643 zPath = (const char*)sqlite3_value_text(argv[1]);
205644 pNode = jsonLookup(p, zPath, 0, ctx);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205645 }else{
205646 pNode = p->aNode;
205647 }
205648 if( pNode ){
205649 sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC);
205650 }
205651 }
205652
205653 /*
205654 ** json_valid(JSON)
 
205655 **
205656 ** Return 1 if JSON is a well-formed canonical JSON string according
205657 ** to RFC-7159. Return 0 otherwise.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205658 */
205659 static void jsonValidFunc(
205660 sqlite3_context *ctx,
205661 int argc,
205662 sqlite3_value **argv
205663 ){
205664 JsonParse *p; /* The parse */
205665 UNUSED_PARAMETER(argc);
205666 if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
 
 
 
 
 
 
 
 
 
 
 
205667 #ifdef SQLITE_LEGACY_JSON_VALID
205668 /* Incorrect legacy behavior was to return FALSE for a NULL input */
205669 sqlite3_result_int(ctx, 0);
205670 #endif
205671 return;
205672 }
205673 p = jsonParseCached(ctx, argv[0], 0, 0);
205674 if( p==0 || p->oom ){
205675 sqlite3_result_error_nomem(ctx);
205676 sqlite3_free(p);
205677 }else{
205678 sqlite3_result_int(ctx, p->nErr==0 && (p->hasNonstd==0 || p->useMod));
205679 if( p->nErr ) jsonParseFree(p);
205680 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205681 }
205682
205683 /*
205684 ** json_error_position(JSON)
205685 **
205686 ** If the argument is not an interpretable JSON string, then return the 1-based
205687 ** character position at which the parser first recognized that the input
205688 ** was in error. The left-most character is 1. If the string is valid
205689 ** JSON, then return 0.
205690 **
205691 ** Note that json_valid() is only true for strictly conforming canonical JSON.
205692 ** But this routine returns zero if the input contains extension. Thus:
205693 **
205694 ** (1) If the input X is strictly conforming canonical JSON:
205695 **
205696 ** json_valid(X) returns true
205697 ** json_error_position(X) returns 0
205698 **
205699 ** (2) If the input X is JSON but it includes extension (such as JSON5) that
205700 ** are not part of RFC-8259:
205701 **
205702 ** json_valid(X) returns false
205703 ** json_error_position(X) return 0
205704 **
205705 ** (3) If the input X cannot be interpreted as JSON even taking extensions
205706 ** into account:
205707 **
205708 ** json_valid(X) return false
205709 ** json_error_position(X) returns 1 or more
205710 */
205711 static void jsonErrorFunc(
205712 sqlite3_context *ctx,
205713 int argc,
205714 sqlite3_value **argv
205715 ){
205716 JsonParse *p; /* The parse */
 
 
 
205717 UNUSED_PARAMETER(argc);
205718 if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
205719 p = jsonParseCached(ctx, argv[0], 0, 0);
205720 if( p==0 || p->oom ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205721 sqlite3_result_error_nomem(ctx);
205722 sqlite3_free(p);
205723 }else if( p->nErr==0 ){
205724 sqlite3_result_int(ctx, 0);
205725 }else{
205726 int n = 1;
205727 u32 i;
205728 const char *z = (const char*)sqlite3_value_text(argv[0]);
205729 for(i=0; i<p->iErr && ALWAYS(z[i]); i++){
205730 if( (z[i]&0xc0)!=0x80 ) n++;
205731 }
205732 sqlite3_result_int(ctx, n);
205733 jsonParseFree(p);
205734 }
205735 }
205736
205737
205738 /****************************************************************************
205739 ** Aggregate SQL function implementations
205740 ****************************************************************************/
205741 /*
@@ -205751,28 +207309,38 @@
205751 JsonString *pStr;
205752 UNUSED_PARAMETER(argc);
205753 pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
205754 if( pStr ){
205755 if( pStr->zBuf==0 ){
205756 jsonInit(pStr, ctx);
205757 jsonAppendChar(pStr, '[');
205758 }else if( pStr->nUsed>1 ){
205759 jsonAppendChar(pStr, ',');
205760 }
205761 pStr->pCtx = ctx;
205762 jsonAppendValue(pStr, argv[0]);
205763 }
205764 }
205765 static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){
205766 JsonString *pStr;
205767 pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
205768 if( pStr ){
 
205769 pStr->pCtx = ctx;
205770 jsonAppendChar(pStr, ']');
205771 if( pStr->bErr ){
205772 if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
205773 assert( pStr->bStatic );
 
 
 
 
 
 
 
 
 
205774 }else if( isFinal ){
205775 sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed,
205776 pStr->bStatic ? SQLITE_TRANSIENT :
205777 sqlite3RCStrUnref);
205778 pStr->bStatic = 1;
@@ -205857,31 +207425,42 @@
205857 u32 n;
205858 UNUSED_PARAMETER(argc);
205859 pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
205860 if( pStr ){
205861 if( pStr->zBuf==0 ){
205862 jsonInit(pStr, ctx);
205863 jsonAppendChar(pStr, '{');
205864 }else if( pStr->nUsed>1 ){
205865 jsonAppendChar(pStr, ',');
205866 }
205867 pStr->pCtx = ctx;
205868 z = (const char*)sqlite3_value_text(argv[0]);
205869 n = (u32)sqlite3_value_bytes(argv[0]);
205870 jsonAppendString(pStr, z, n);
205871 jsonAppendChar(pStr, ':');
205872 jsonAppendValue(pStr, argv[1]);
205873 }
205874 }
205875 static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){
205876 JsonString *pStr;
205877 pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
205878 if( pStr ){
 
205879 jsonAppendChar(pStr, '}');
205880 if( pStr->bErr ){
205881 if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
205882 assert( pStr->bStatic );
 
 
 
 
 
 
 
 
 
 
205883 }else if( isFinal ){
205884 sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed,
205885 pStr->bStatic ? SQLITE_TRANSIENT :
205886 sqlite3RCStrUnref);
205887 pStr->bStatic = 1;
@@ -205905,33 +207484,51 @@
205905
205906 #ifndef SQLITE_OMIT_VIRTUALTABLE
205907 /****************************************************************************
205908 ** The json_each virtual table
205909 ****************************************************************************/
 
 
 
 
 
 
 
 
 
205910 typedef struct JsonEachCursor JsonEachCursor;
205911 struct JsonEachCursor {
205912 sqlite3_vtab_cursor base; /* Base class - must be first */
205913 u32 iRowid; /* The rowid */
205914 u32 iBegin; /* The first node of the scan */
205915 u32 i; /* Index in sParse.aNode[] of current row */
205916 u32 iEnd; /* EOF when i equals or exceeds this value */
205917 u8 eType; /* Type of top-level element */
 
205918 u8 bRecursive; /* True for json_tree(). False for json_each() */
205919 char *zJson; /* Input JSON */
205920 char *zRoot; /* Path by which to filter zJson */
 
 
 
205921 JsonParse sParse; /* Parse of the input JSON */
205922 };
 
 
 
 
 
 
205923
205924 /* Constructor for the json_each virtual table */
205925 static int jsonEachConnect(
205926 sqlite3 *db,
205927 void *pAux,
205928 int argc, const char *const*argv,
205929 sqlite3_vtab **ppVtab,
205930 char **pzErr
205931 ){
205932 sqlite3_vtab *pNew;
205933 int rc;
205934
205935 /* Column numbers */
205936 #define JEACH_KEY 0
205937 #define JEACH_VALUE 1
@@ -205953,14 +207550,15 @@
205953 UNUSED_PARAMETER(pAux);
205954 rc = sqlite3_declare_vtab(db,
205955 "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path,"
205956 "json HIDDEN,root HIDDEN)");
205957 if( rc==SQLITE_OK ){
205958 pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
205959 if( pNew==0 ) return SQLITE_NOMEM;
205960 memset(pNew, 0, sizeof(*pNew));
205961 sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
 
205962 }
205963 return rc;
205964 }
205965
205966 /* destructor for json_each virtual table */
@@ -205969,16 +207567,19 @@
205969 return SQLITE_OK;
205970 }
205971
205972 /* constructor for a JsonEachCursor object for json_each(). */
205973 static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
 
205974 JsonEachCursor *pCur;
205975
205976 UNUSED_PARAMETER(p);
205977 pCur = sqlite3_malloc( sizeof(*pCur) );
205978 if( pCur==0 ) return SQLITE_NOMEM;
205979 memset(pCur, 0, sizeof(*pCur));
 
 
205980 *ppCursor = &pCur->base;
205981 return SQLITE_OK;
205982 }
205983
205984 /* constructor for a JsonEachCursor object for json_tree(). */
@@ -205992,24 +207593,27 @@
205992 }
205993
205994 /* Reset a JsonEachCursor back to its original state. Free any memory
205995 ** held. */
205996 static void jsonEachCursorReset(JsonEachCursor *p){
205997 sqlite3_free(p->zRoot);
205998 jsonParseReset(&p->sParse);
 
 
205999 p->iRowid = 0;
206000 p->i = 0;
 
 
 
206001 p->iEnd = 0;
206002 p->eType = 0;
206003 p->zJson = 0;
206004 p->zRoot = 0;
206005 }
206006
206007 /* Destructor for a jsonEachCursor object */
206008 static int jsonEachClose(sqlite3_vtab_cursor *cur){
206009 JsonEachCursor *p = (JsonEachCursor*)cur;
206010 jsonEachCursorReset(p);
 
206011 sqlite3_free(cur);
206012 return SQLITE_OK;
206013 }
206014
206015 /* Return TRUE if the jsonEachCursor object has been advanced off the end
@@ -206016,205 +207620,235 @@
206016 ** of the JSON object */
206017 static int jsonEachEof(sqlite3_vtab_cursor *cur){
206018 JsonEachCursor *p = (JsonEachCursor*)cur;
206019 return p->i >= p->iEnd;
206020 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206021
206022 /* Advance the cursor to the next element for json_tree() */
206023 static int jsonEachNext(sqlite3_vtab_cursor *cur){
206024 JsonEachCursor *p = (JsonEachCursor*)cur;
 
206025 if( p->bRecursive ){
206026 if( p->sParse.aNode[p->i].jnFlags & JNODE_LABEL ) p->i++;
206027 p->i++;
206028 p->iRowid++;
206029 if( p->i<p->iEnd ){
206030 u32 iUp = p->sParse.aUp[p->i];
206031 JsonNode *pUp = &p->sParse.aNode[iUp];
206032 p->eType = pUp->eType;
206033 if( pUp->eType==JSON_ARRAY ){
206034 assert( pUp->eU==0 || pUp->eU==3 );
206035 testcase( pUp->eU==3 );
206036 VVA( pUp->eU = 3 );
206037 if( iUp==p->i-1 ){
206038 pUp->u.iKey = 0;
206039 }else{
206040 pUp->u.iKey++;
206041 }
206042 }
206043 }
206044 }else{
206045 switch( p->eType ){
206046 case JSON_ARRAY: {
206047 p->i += jsonNodeSize(&p->sParse.aNode[p->i]);
206048 p->iRowid++;
206049 break;
206050 }
206051 case JSON_OBJECT: {
206052 p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]);
206053 p->iRowid++;
206054 break;
206055 }
206056 default: {
206057 p->i = p->iEnd;
206058 break;
206059 }
206060 }
206061 }
206062 return SQLITE_OK;
206063 }
206064
206065 /* Append an object label to the JSON Path being constructed
206066 ** in pStr.
206067 */
206068 static void jsonAppendObjectPathElement(
206069 JsonString *pStr,
206070 JsonNode *pNode
206071 ){
206072 int jj, nn;
206073 const char *z;
206074 assert( pNode->eType==JSON_STRING );
206075 assert( pNode->jnFlags & JNODE_LABEL );
206076 assert( pNode->eU==1 );
206077 z = pNode->u.zJContent;
206078 nn = pNode->n;
206079 if( (pNode->jnFlags & JNODE_RAW)==0 ){
206080 assert( nn>=2 );
206081 assert( z[0]=='"' || z[0]=='\'' );
206082 assert( z[nn-1]=='"' || z[0]=='\'' );
206083 if( nn>2 && sqlite3Isalpha(z[1]) ){
206084 for(jj=2; jj<nn-1 && sqlite3Isalnum(z[jj]); jj++){}
206085 if( jj==nn-1 ){
206086 z++;
206087 nn -= 2;
206088 }
206089 }
206090 }
206091 jsonPrintf(nn+2, pStr, ".%.*s", nn, z);
206092 }
206093
206094 /* Append the name of the path for element i to pStr
206095 */
206096 static void jsonEachComputePath(
206097 JsonEachCursor *p, /* The cursor */
206098 JsonString *pStr, /* Write the path here */
206099 u32 i /* Path to this element */
206100 ){
206101 JsonNode *pNode, *pUp;
206102 u32 iUp;
206103 if( i==0 ){
206104 jsonAppendChar(pStr, '$');
206105 return;
206106 }
206107 iUp = p->sParse.aUp[i];
206108 jsonEachComputePath(p, pStr, iUp);
206109 pNode = &p->sParse.aNode[i];
206110 pUp = &p->sParse.aNode[iUp];
206111 if( pUp->eType==JSON_ARRAY ){
206112 assert( pUp->eU==3 || (pUp->eU==0 && pUp->u.iKey==0) );
206113 testcase( pUp->eU==0 );
206114 jsonPrintf(30, pStr, "[%d]", pUp->u.iKey);
206115 }else{
206116 assert( pUp->eType==JSON_OBJECT );
206117 if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--;
206118 jsonAppendObjectPathElement(pStr, pNode);
206119 }
206120 }
206121
206122 /* Return the value of a column */
206123 static int jsonEachColumn(
206124 sqlite3_vtab_cursor *cur, /* The cursor */
206125 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
206126 int i /* Which column to return */
206127 ){
206128 JsonEachCursor *p = (JsonEachCursor*)cur;
206129 JsonNode *pThis = &p->sParse.aNode[p->i];
206130 switch( i ){
206131 case JEACH_KEY: {
206132 if( p->i==0 ) break;
206133 if( p->eType==JSON_OBJECT ){
206134 jsonReturn(&p->sParse, pThis, ctx, 0);
206135 }else if( p->eType==JSON_ARRAY ){
206136 u32 iKey;
206137 if( p->bRecursive ){
206138 if( p->iRowid==0 ) break;
206139 assert( p->sParse.aNode[p->sParse.aUp[p->i]].eU==3 );
206140 iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey;
 
 
 
 
206141 }else{
206142 iKey = p->iRowid;
206143 }
206144 sqlite3_result_int64(ctx, (sqlite3_int64)iKey);
 
 
 
 
 
 
206145 }
206146 break;
206147 }
206148 case JEACH_VALUE: {
206149 if( pThis->jnFlags & JNODE_LABEL ) pThis++;
206150 jsonReturn(&p->sParse, pThis, ctx, 0);
206151 break;
206152 }
206153 case JEACH_TYPE: {
206154 if( pThis->jnFlags & JNODE_LABEL ) pThis++;
206155 sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC);
 
206156 break;
206157 }
206158 case JEACH_ATOM: {
206159 if( pThis->jnFlags & JNODE_LABEL ) pThis++;
206160 if( pThis->eType>=JSON_ARRAY ) break;
206161 jsonReturn(&p->sParse, pThis, ctx, 0);
 
206162 break;
206163 }
206164 case JEACH_ID: {
206165 sqlite3_result_int64(ctx,
206166 (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0));
206167 break;
206168 }
206169 case JEACH_PARENT: {
206170 if( p->i>p->iBegin && p->bRecursive ){
206171 sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]);
206172 }
206173 break;
206174 }
206175 case JEACH_FULLKEY: {
206176 JsonString x;
206177 jsonInit(&x, ctx);
206178 if( p->bRecursive ){
206179 jsonEachComputePath(p, &x, p->i);
206180 }else{
206181 if( p->zRoot ){
206182 jsonAppendRaw(&x, p->zRoot, (int)strlen(p->zRoot));
206183 }else{
206184 jsonAppendChar(&x, '$');
206185 }
206186 if( p->eType==JSON_ARRAY ){
206187 jsonPrintf(30, &x, "[%d]", p->iRowid);
206188 }else if( p->eType==JSON_OBJECT ){
206189 jsonAppendObjectPathElement(&x, pThis);
206190 }
206191 }
206192 jsonResult(&x);
206193 break;
206194 }
206195 case JEACH_PATH: {
206196 if( p->bRecursive ){
206197 JsonString x;
206198 jsonInit(&x, ctx);
206199 jsonEachComputePath(p, &x, p->sParse.aUp[p->i]);
206200 jsonResult(&x);
206201 break;
206202 }
206203 /* For json_each() path and root are the same so fall through
206204 ** into the root case */
206205 /* no break */ deliberate_fall_through
206206 }
206207 default: {
206208 const char *zRoot = p->zRoot;
206209 if( zRoot==0 ) zRoot = "$";
206210 sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC);
206211 break;
206212 }
206213 case JEACH_JSON: {
206214 assert( i==JEACH_JSON );
206215 sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC);
 
 
 
 
206216 break;
206217 }
206218 }
206219 return SQLITE_OK;
206220 }
@@ -206301,90 +207935,104 @@
206301 sqlite3_vtab_cursor *cur,
206302 int idxNum, const char *idxStr,
206303 int argc, sqlite3_value **argv
206304 ){
206305 JsonEachCursor *p = (JsonEachCursor*)cur;
206306 const char *z;
206307 const char *zRoot = 0;
206308 sqlite3_int64 n;
206309
206310 UNUSED_PARAMETER(idxStr);
206311 UNUSED_PARAMETER(argc);
206312 jsonEachCursorReset(p);
206313 if( idxNum==0 ) return SQLITE_OK;
206314 z = (const char*)sqlite3_value_text(argv[0]);
206315 if( z==0 ) return SQLITE_OK;
206316 memset(&p->sParse, 0, sizeof(p->sParse));
206317 p->sParse.nJPRef = 1;
206318 if( sqlite3ValueIsOfClass(argv[0], sqlite3RCStrUnref) ){
206319 p->sParse.zJson = sqlite3RCStrRef((char*)z);
206320 }else{
206321 n = sqlite3_value_bytes(argv[0]);
206322 p->sParse.zJson = sqlite3RCStrNew( n+1 );
206323 if( p->sParse.zJson==0 ) return SQLITE_NOMEM;
206324 memcpy(p->sParse.zJson, z, (size_t)n+1);
206325 }
206326 p->sParse.bJsonIsRCStr = 1;
206327 p->zJson = p->sParse.zJson;
206328 if( jsonParse(&p->sParse, 0) ){
206329 int rc = SQLITE_NOMEM;
206330 if( p->sParse.oom==0 ){
206331 sqlite3_free(cur->pVtab->zErrMsg);
206332 cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON");
206333 if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR;
206334 }
206335 jsonEachCursorReset(p);
206336 return rc;
206337 }else if( p->bRecursive && jsonParseFindParents(&p->sParse) ){
206338 jsonEachCursorReset(p);
206339 return SQLITE_NOMEM;
206340 }else{
206341 JsonNode *pNode = 0;
206342 if( idxNum==3 ){
206343 const char *zErr = 0;
206344 zRoot = (const char*)sqlite3_value_text(argv[1]);
206345 if( zRoot==0 ) return SQLITE_OK;
206346 n = sqlite3_value_bytes(argv[1]);
206347 p->zRoot = sqlite3_malloc64( n+1 );
206348 if( p->zRoot==0 ) return SQLITE_NOMEM;
206349 memcpy(p->zRoot, zRoot, (size_t)n+1);
206350 if( zRoot[0]!='$' ){
206351 zErr = zRoot;
206352 }else{
206353 pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr);
206354 }
206355 if( zErr ){
206356 sqlite3_free(cur->pVtab->zErrMsg);
206357 cur->pVtab->zErrMsg = jsonPathSyntaxError(zErr);
 
 
 
 
 
206358 jsonEachCursorReset(p);
206359 return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
206360 }else if( pNode==0 ){
206361 return SQLITE_OK;
206362 }
206363 }else{
206364 pNode = p->sParse.aNode;
206365 }
206366 p->iBegin = p->i = (int)(pNode - p->sParse.aNode);
206367 p->eType = pNode->eType;
206368 if( p->eType>=JSON_ARRAY ){
206369 assert( pNode->eU==0 );
206370 VVA( pNode->eU = 3 );
206371 pNode->u.iKey = 0;
206372 p->iEnd = p->i + pNode->n + 1;
206373 if( p->bRecursive ){
206374 p->eType = p->sParse.aNode[p->sParse.aUp[p->i]].eType;
206375 if( p->i>0 && (p->sParse.aNode[p->i-1].jnFlags & JNODE_LABEL)!=0 ){
206376 p->i--;
206377 }
206378 }else{
206379 p->i++;
206380 }
206381 }else{
206382 p->iEnd = p->i+1;
206383 }
206384 }
206385 return SQLITE_OK;
 
 
 
 
 
 
 
 
 
 
 
 
206386 }
206387
206388 /* The methods of the json_each virtual table */
206389 static sqlite3_module jsonEachModule = {
206390 0, /* iVersion */
@@ -206449,44 +208097,58 @@
206449 ** Register JSON functions.
206450 */
206451 SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void){
206452 #ifndef SQLITE_OMIT_JSON
206453 static FuncDef aJsonFunc[] = {
206454 /* calls sqlite3_result_subtype() */
206455 /* | */
206456 /* Uses cache ______ | __ calls sqlite3_value_subtype() */
206457 /* | | | */
206458 /* Num args _________ | | | ___ Flags */
206459 /* | | | | | */
206460 /* | | | | | */
206461 JFUNCTION(json, 1, 1, 1, 0, 0, jsonRemoveFunc),
206462 JFUNCTION(json_array, -1, 0, 1, 1, 0, jsonArrayFunc),
206463 JFUNCTION(json_array_length, 1, 1, 0, 0, 0, jsonArrayLengthFunc),
206464 JFUNCTION(json_array_length, 2, 1, 0, 0, 0, jsonArrayLengthFunc),
206465 JFUNCTION(json_error_position,1, 1, 0, 0, 0, jsonErrorFunc),
206466 JFUNCTION(json_extract, -1, 1, 1, 0, 0, jsonExtractFunc),
206467 JFUNCTION(->, 2, 1, 1, 0, JSON_JSON, jsonExtractFunc),
206468 JFUNCTION(->>, 2, 1, 0, 0, JSON_SQL, jsonExtractFunc),
206469 JFUNCTION(json_insert, -1, 1, 1, 1, 0, jsonSetFunc),
206470 JFUNCTION(json_object, -1, 0, 1, 1, 0, jsonObjectFunc),
206471 JFUNCTION(json_patch, 2, 1, 1, 0, 0, jsonPatchFunc),
206472 JFUNCTION(json_quote, 1, 0, 1, 1, 0, jsonQuoteFunc),
206473 JFUNCTION(json_remove, -1, 1, 1, 0, 0, jsonRemoveFunc),
206474 JFUNCTION(json_replace, -1, 1, 1, 1, 0, jsonReplaceFunc),
206475 JFUNCTION(json_set, -1, 1, 1, 1, JSON_ISSET, jsonSetFunc),
206476 JFUNCTION(json_type, 1, 1, 0, 0, 0, jsonTypeFunc),
206477 JFUNCTION(json_type, 2, 1, 0, 0, 0, jsonTypeFunc),
206478 JFUNCTION(json_valid, 1, 1, 0, 0, 0, jsonValidFunc),
206479 #ifdef SQLITE_DEBUG
206480 JFUNCTION(json_parse, 1, 1, 1, 0, 0, jsonParseFunc),
206481 JFUNCTION(json_test1, 1, 1, 0, 1, 0, jsonTest1Func),
 
 
 
 
 
 
 
 
206482 #endif
206483 WAGGREGATE(json_group_array, 1, 0, 0,
206484 jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse,
206485 SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|
206486 SQLITE_DETERMINISTIC),
 
 
 
206487 WAGGREGATE(json_group_object, 2, 0, 0,
 
 
 
206488 jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse,
206489 SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|
206490 SQLITE_DETERMINISTIC)
206491 };
206492 sqlite3InsertBuiltinFuncs(aJsonFunc, ArraySize(aJsonFunc));
@@ -227778,13 +229440,38 @@
227778 ** significantly more efficient than those alternatives when used with
227779 ** "detail=column" tables.
227780 **
227781 ** xPhraseNextColumn()
227782 ** See xPhraseFirstColumn above.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227783 */
227784 struct Fts5ExtensionApi {
227785 int iVersion; /* Currently always set to 2 */
227786
227787 void *(*xUserData)(Fts5Context*);
227788
227789 int (*xColumnCount)(Fts5Context*);
227790 int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
@@ -227815,10 +229502,17 @@
227815 int (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*);
227816 void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff);
227817
227818 int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*);
227819 void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol);
 
 
 
 
 
 
 
227820 };
227821
227822 /*
227823 ** CUSTOM AUXILIARY FUNCTIONS
227824 *************************************************************************/
@@ -228289,10 +229983,11 @@
228289 int eContent; /* An FTS5_CONTENT value */
228290 int bContentlessDelete; /* "contentless_delete=" option (dflt==0) */
228291 char *zContent; /* content table */
228292 char *zContentRowid; /* "content_rowid=" option value */
228293 int bColumnsize; /* "columnsize=" option value (dflt==1) */
 
228294 int eDetail; /* FTS5_DETAIL_XXX value */
228295 char *zContentExprlist;
228296 Fts5Tokenizer *pTok;
228297 fts5_tokenizer *pTokApi;
228298 int bLock; /* True when table is preparing statement */
@@ -228477,21 +230172,23 @@
228477 #define sqlite3Fts5IterEof(x) ((x)->bEof)
228478
228479 /*
228480 ** Values used as part of the flags argument passed to IndexQuery().
228481 */
228482 #define FTS5INDEX_QUERY_PREFIX 0x0001 /* Prefix query */
228483 #define FTS5INDEX_QUERY_DESC 0x0002 /* Docs in descending rowid order */
228484 #define FTS5INDEX_QUERY_TEST_NOIDX 0x0004 /* Do not use prefix index */
228485 #define FTS5INDEX_QUERY_SCAN 0x0008 /* Scan query (fts5vocab) */
228486
228487 /* The following are used internally by the fts5_index.c module. They are
228488 ** defined here only to make it easier to avoid clashes with the flags
228489 ** above. */
228490 #define FTS5INDEX_QUERY_SKIPEMPTY 0x0010
228491 #define FTS5INDEX_QUERY_NOOUTPUT 0x0020
228492 #define FTS5INDEX_QUERY_SKIPHASH 0x0040
 
 
228493
228494 /*
228495 ** Create/destroy an Fts5Index object.
228496 */
228497 static int sqlite3Fts5IndexOpen(Fts5Config *pConfig, int bCreate, Fts5Index**, char**);
@@ -228556,10 +230253,14 @@
228556 static int sqlite3Fts5IterNextScan(Fts5IndexIter*);
228557 static void *sqlite3Fts5StructureRef(Fts5Index*);
228558 static void sqlite3Fts5StructureRelease(void*);
228559 static int sqlite3Fts5StructureTest(Fts5Index*, void*);
228560
 
 
 
 
228561
228562 /*
228563 ** Insert or remove data to or from the index. Each time a document is
228564 ** added to or removed from the index, this function is called one or more
228565 ** times.
@@ -228632,10 +230333,17 @@
228632
228633 static int sqlite3Fts5IndexLoadConfig(Fts5Index *p);
228634
228635 static int sqlite3Fts5IndexGetOrigin(Fts5Index *p, i64 *piOrigin);
228636 static int sqlite3Fts5IndexContentlessDelete(Fts5Index *p, i64 iOrigin, i64 iRowid);
 
 
 
 
 
 
 
228637
228638 /*
228639 ** End of interface to code in fts5_index.c.
228640 **************************************************************************/
228641
@@ -228738,10 +230446,11 @@
228738 );
228739 static void sqlite3Fts5HashScanNext(Fts5Hash*);
228740 static int sqlite3Fts5HashScanEof(Fts5Hash*);
228741 static void sqlite3Fts5HashScanEntry(Fts5Hash *,
228742 const char **pzTerm, /* OUT: term (nul-terminated) */
 
228743 const u8 **ppDoclist, /* OUT: pointer to doclist */
228744 int *pnDoclist /* OUT: size of doclist in bytes */
228745 );
228746
228747
@@ -228863,10 +230572,14 @@
228863 static void sqlite3Fts5ExprCheckPoslists(Fts5Expr*, i64);
228864
228865 static int sqlite3Fts5ExprClonePhrase(Fts5Expr*, int, Fts5Expr**);
228866
228867 static int sqlite3Fts5ExprPhraseCollist(Fts5Expr *, int, const u8 **, int *);
 
 
 
 
228868
228869 /*******************************************
228870 ** The fts5_expr.c API above this point is used by the other hand-written
228871 ** C code in this module. The interfaces below this point are called by
228872 ** the parser code in fts5parse.y. */
@@ -230679,10 +232392,18 @@
230679 rc = fts5CInstIterNext(&p->iter);
230680 }
230681 }
230682
230683 if( iPos==p->iRangeEnd ){
 
 
 
 
 
 
 
 
230684 fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff);
230685 p->iOff = iEndOff;
230686 }
230687
230688 return rc;
@@ -231280,10 +233001,11 @@
231280 u32 nData,
231281 const u8 *pData
231282 ){
231283 if( nData ){
231284 if( fts5BufferGrow(pRc, pBuf, nData) ) return;
 
231285 memcpy(&pBuf->p[pBuf->n], pData, nData);
231286 pBuf->n += nData;
231287 }
231288 }
231289
@@ -231381,17 +233103,19 @@
231381 const u8 *a, int n, /* Buffer containing poslist */
231382 int *pi, /* IN/OUT: Offset within a[] */
231383 i64 *piOff /* IN/OUT: Current offset */
231384 ){
231385 int i = *pi;
 
231386 if( i>=n ){
231387 /* EOF */
231388 *piOff = -1;
231389 return 1;
231390 }else{
231391 i64 iOff = *piOff;
231392 u32 iVal;
 
231393 fts5FastGetVarint32(a, i, iVal);
231394 if( iVal<=1 ){
231395 if( iVal==0 ){
231396 *pi = i;
231397 return 0;
@@ -232018,10 +233742,20 @@
232018 if( (rc = fts5ConfigSetEnum(aDetail, zArg, &pConfig->eDetail)) ){
232019 *pzErr = sqlite3_mprintf("malformed detail=... directive");
232020 }
232021 return rc;
232022 }
 
 
 
 
 
 
 
 
 
 
232023
232024 *pzErr = sqlite3_mprintf("unrecognized option: \"%.*s\"", nCmd, zCmd);
232025 return SQLITE_ERROR;
232026 }
232027
@@ -232752,11 +234486,13 @@
232752 ** or term prefix.
232753 */
232754 struct Fts5ExprTerm {
232755 u8 bPrefix; /* True for a prefix term */
232756 u8 bFirst; /* True if token must be first in column */
232757 char *zTerm; /* nul-terminated term */
 
 
232758 Fts5IndexIter *pIter; /* Iterator for this term */
232759 Fts5ExprTerm *pSynonym; /* Pointer to first in list of synonyms */
232760 };
232761
232762 /*
@@ -233619,11 +235355,11 @@
233619 if( p->pIter ){
233620 sqlite3Fts5IterClose(p->pIter);
233621 p->pIter = 0;
233622 }
233623 rc = sqlite3Fts5IndexQuery(
233624 pExpr->pIndex, p->zTerm, (int)strlen(p->zTerm),
233625 (pTerm->bPrefix ? FTS5INDEX_QUERY_PREFIX : 0) |
233626 (pExpr->bDesc ? FTS5INDEX_QUERY_DESC : 0),
233627 pNear->pColset,
233628 &p->pIter
233629 );
@@ -234256,11 +235992,11 @@
234256 int i;
234257 for(i=0; i<pPhrase->nTerm; i++){
234258 Fts5ExprTerm *pSyn;
234259 Fts5ExprTerm *pNext;
234260 Fts5ExprTerm *pTerm = &pPhrase->aTerm[i];
234261 sqlite3_free(pTerm->zTerm);
234262 sqlite3Fts5IterClose(pTerm->pIter);
234263 for(pSyn=pTerm->pSynonym; pSyn; pSyn=pNext){
234264 pNext = pSyn->pSynonym;
234265 sqlite3Fts5IterClose(pSyn->pIter);
234266 fts5BufferFree((Fts5Buffer*)&pSyn[1]);
@@ -234354,10 +236090,11 @@
234354 }
234355
234356 typedef struct TokenCtx TokenCtx;
234357 struct TokenCtx {
234358 Fts5ExprPhrase *pPhrase;
 
234359 int rc;
234360 };
234361
234362 /*
234363 ** Callback for tokenizing terms used by ParseTerm().
@@ -234387,12 +236124,16 @@
234387 pSyn = (Fts5ExprTerm*)sqlite3_malloc64(nByte);
234388 if( pSyn==0 ){
234389 rc = SQLITE_NOMEM;
234390 }else{
234391 memset(pSyn, 0, (size_t)nByte);
234392 pSyn->zTerm = ((char*)pSyn) + sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer);
234393 memcpy(pSyn->zTerm, pToken, nToken);
 
 
 
 
234394 pSyn->pSynonym = pPhrase->aTerm[pPhrase->nTerm-1].pSynonym;
234395 pPhrase->aTerm[pPhrase->nTerm-1].pSynonym = pSyn;
234396 }
234397 }else{
234398 Fts5ExprTerm *pTerm;
@@ -234413,11 +236154,15 @@
234413 }
234414
234415 if( rc==SQLITE_OK ){
234416 pTerm = &pPhrase->aTerm[pPhrase->nTerm++];
234417 memset(pTerm, 0, sizeof(Fts5ExprTerm));
234418 pTerm->zTerm = sqlite3Fts5Strndup(&rc, pToken, nToken);
 
 
 
 
234419 }
234420 }
234421
234422 pCtx->rc = rc;
234423 return rc;
@@ -234480,10 +236225,11 @@
234480 int rc; /* Tokenize return code */
234481 char *z = 0;
234482
234483 memset(&sCtx, 0, sizeof(TokenCtx));
234484 sCtx.pPhrase = pAppend;
 
234485
234486 rc = fts5ParseStringFromToken(pToken, &z);
234487 if( rc==SQLITE_OK ){
234488 int flags = FTS5_TOKENIZE_QUERY | (bPrefix ? FTS5_TOKENIZE_PREFIX : 0);
234489 int n;
@@ -234529,12 +236275,11 @@
234529 Fts5Expr **ppNew
234530 ){
234531 int rc = SQLITE_OK; /* Return code */
234532 Fts5ExprPhrase *pOrig; /* The phrase extracted from pExpr */
234533 Fts5Expr *pNew = 0; /* Expression to return via *ppNew */
234534 TokenCtx sCtx = {0,0}; /* Context object for fts5ParseTokenize */
234535
234536 pOrig = pExpr->apExprPhrase[iPhrase];
234537 pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr));
234538 if( rc==SQLITE_OK ){
234539 pNew->apExprPhrase = (Fts5ExprPhrase**)sqlite3Fts5MallocZero(&rc,
234540 sizeof(Fts5ExprPhrase*));
@@ -234561,17 +236306,16 @@
234561 }
234562 }
234563
234564 if( pOrig->nTerm ){
234565 int i; /* Used to iterate through phrase terms */
 
234566 for(i=0; rc==SQLITE_OK && i<pOrig->nTerm; i++){
234567 int tflags = 0;
234568 Fts5ExprTerm *p;
234569 for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){
234570 const char *zTerm = p->zTerm;
234571 rc = fts5ParseTokenize((void*)&sCtx, tflags, zTerm, (int)strlen(zTerm),
234572 0, 0);
234573 tflags = FTS5_TOKEN_COLOCATED;
234574 }
234575 if( rc==SQLITE_OK ){
234576 sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix;
234577 sCtx.pPhrase->aTerm[i].bFirst = pOrig->aTerm[i].bFirst;
@@ -234948,15 +236692,17 @@
234948 );
234949 if( pPhrase ){
234950 if( parseGrowPhraseArray(pParse) ){
234951 fts5ExprPhraseFree(pPhrase);
234952 }else{
 
 
234953 pParse->apPhrase[pParse->nPhrase++] = pPhrase;
234954 pPhrase->nTerm = 1;
234955 pPhrase->aTerm[0].zTerm = sqlite3Fts5Strndup(
234956 &pParse->rc, pNear->apPhrase[0]->aTerm[ii].zTerm, -1
234957 );
234958 pRet->apChild[ii] = sqlite3Fts5ParseNode(pParse, FTS5_STRING,
234959 0, 0, sqlite3Fts5ParseNearset(pParse, 0, pPhrase)
234960 );
234961 }
234962 }
@@ -235137,20 +236883,21 @@
235137 Fts5ExprTerm *p;
235138 char *zQuoted;
235139
235140 /* Determine the maximum amount of space required. */
235141 for(p=pTerm; p; p=p->pSynonym){
235142 nByte += (int)strlen(pTerm->zTerm) * 2 + 3 + 2;
235143 }
235144 zQuoted = sqlite3_malloc64(nByte);
235145
235146 if( zQuoted ){
235147 int i = 0;
235148 for(p=pTerm; p; p=p->pSynonym){
235149 char *zIn = p->zTerm;
 
235150 zQuoted[i++] = '"';
235151 while( *zIn ){
235152 if( *zIn=='"' ) zQuoted[i++] = '"';
235153 zQuoted[i++] = *zIn++;
235154 }
235155 zQuoted[i++] = '"';
235156 if( p->pSynonym ) zQuoted[i++] = '|';
@@ -235224,12 +236971,14 @@
235224 for(i=0; i<pNear->nPhrase; i++){
235225 Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
235226
235227 zRet = fts5PrintfAppend(zRet, " {");
235228 for(iTerm=0; zRet && iTerm<pPhrase->nTerm; iTerm++){
235229 char *zTerm = pPhrase->aTerm[iTerm].zTerm;
235230 zRet = fts5PrintfAppend(zRet, "%s%s", iTerm==0?"":" ", zTerm);
 
 
235231 if( pPhrase->aTerm[iTerm].bPrefix ){
235232 zRet = fts5PrintfAppend(zRet, "*");
235233 }
235234 }
235235
@@ -235625,10 +237374,21 @@
235625 for(i=0; i<pColset->nCol; i++){
235626 if( pColset->aiCol[i]==iCol ) return 1;
235627 }
235628 return 0;
235629 }
 
 
 
 
 
 
 
 
 
 
 
235630
235631 static int fts5ExprPopulatePoslistsCb(
235632 void *pCtx, /* Copy of 2nd argument to xTokenize() */
235633 int tflags, /* Mask of FTS5_TOKEN_* flags */
235634 const char *pToken, /* Pointer to buffer containing token */
@@ -235637,26 +237397,37 @@
235637 int iUnused2 /* Byte offset of end of token within input text */
235638 ){
235639 Fts5ExprCtx *p = (Fts5ExprCtx*)pCtx;
235640 Fts5Expr *pExpr = p->pExpr;
235641 int i;
 
 
235642
235643 UNUSED_PARAM2(iUnused1, iUnused2);
235644
235645 if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE;
 
 
 
235646 if( (tflags & FTS5_TOKEN_COLOCATED)==0 ) p->iOff++;
235647 for(i=0; i<pExpr->nPhrase; i++){
235648 Fts5ExprTerm *pTerm;
235649 if( p->aPopulator[i].bOk==0 ) continue;
235650 for(pTerm=&pExpr->apExprPhrase[i]->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){
235651 int nTerm = (int)strlen(pTerm->zTerm);
235652 if( (nTerm==nToken || (nTerm<nToken && pTerm->bPrefix))
235653 && memcmp(pTerm->zTerm, pToken, nTerm)==0
235654 ){
235655 int rc = sqlite3Fts5PoslistWriterAppend(
235656 &pExpr->apExprPhrase[i]->poslist, &p->aPopulator[i].writer, p->iOff
235657 );
 
 
 
 
 
 
 
235658 if( rc ) return rc;
235659 break;
235660 }
235661 }
235662 }
@@ -235787,10 +237558,87 @@
235787 *pnCollist = 0;
235788 }
235789
235790 return rc;
235791 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235792
235793 /*
235794 ** 2014 August 11
235795 **
235796 ** The author disclaims copyright to this source code. In place of
@@ -235826,14 +237674,19 @@
235826 Fts5HashEntry **aSlot; /* Array of hash slots */
235827 };
235828
235829 /*
235830 ** Each entry in the hash table is represented by an object of the
235831 ** following type. Each object, its key (a nul-terminated string) and
235832 ** its current data are stored in a single memory allocation. The
235833 ** key immediately follows the object in memory. The position list
235834 ** data immediately follows the key data in memory.
 
 
 
 
 
235835 **
235836 ** The data that follows the key is in a similar, but not identical format
235837 ** to the doclist data stored in the database. It is:
235838 **
235839 ** * Rowid, as a varint
@@ -235964,12 +237817,11 @@
235964 for(i=0; i<pHash->nSlot; i++){
235965 while( apOld[i] ){
235966 unsigned int iHash;
235967 Fts5HashEntry *p = apOld[i];
235968 apOld[i] = p->pHashNext;
235969 iHash = fts5HashKey(nNew, (u8*)fts5EntryKey(p),
235970 (int)strlen(fts5EntryKey(p)));
235971 p->pHashNext = apNew[iHash];
235972 apNew[iHash] = p;
235973 }
235974 }
235975
@@ -236049,11 +237901,11 @@
236049 /* Attempt to locate an existing hash entry */
236050 iHash = fts5HashKey2(pHash->nSlot, (u8)bByte, (const u8*)pToken, nToken);
236051 for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){
236052 char *zKey = fts5EntryKey(p);
236053 if( zKey[0]==bByte
236054 && p->nKey==nToken
236055 && memcmp(&zKey[1], pToken, nToken)==0
236056 ){
236057 break;
236058 }
236059 }
@@ -236079,13 +237931,13 @@
236079 p->nAlloc = (int)nByte;
236080 zKey = fts5EntryKey(p);
236081 zKey[0] = bByte;
236082 memcpy(&zKey[1], pToken, nToken);
236083 assert( iHash==fts5HashKey(pHash->nSlot, (u8*)zKey, nToken+1) );
236084 p->nKey = nToken;
236085 zKey[nToken+1] = '\0';
236086 p->nData = nToken+1 + 1 + sizeof(Fts5HashEntry);
236087 p->pHashNext = pHash->aSlot[iHash];
236088 pHash->aSlot[iHash] = p;
236089 pHash->nEntry++;
236090
236091 /* Add the first rowid field to the hash-entry */
@@ -236198,16 +238050,21 @@
236198 p2 = 0;
236199 }else if( p2==0 ){
236200 *ppOut = p1;
236201 p1 = 0;
236202 }else{
236203 int i = 0;
236204 char *zKey1 = fts5EntryKey(p1);
236205 char *zKey2 = fts5EntryKey(p2);
236206 while( zKey1[i]==zKey2[i] ) i++;
236207
236208 if( ((u8)zKey1[i])>((u8)zKey2[i]) ){
 
 
 
 
 
 
236209 /* p2 is smaller */
236210 *ppOut = p2;
236211 ppOut = &p2->pScanNext;
236212 p2 = p2->pScanNext;
236213 }else{
@@ -236245,11 +238102,11 @@
236245
236246 for(iSlot=0; iSlot<pHash->nSlot; iSlot++){
236247 Fts5HashEntry *pIter;
236248 for(pIter=pHash->aSlot[iSlot]; pIter; pIter=pIter->pHashNext){
236249 if( pTerm==0
236250 || (pIter->nKey+1>=nTerm && 0==memcmp(fts5EntryKey(pIter), pTerm, nTerm))
236251 ){
236252 Fts5HashEntry *pEntry = pIter;
236253 pEntry->pScanNext = 0;
236254 for(i=0; ap[i]; i++){
236255 pEntry = fts5HashEntryMerge(pEntry, ap[i]);
@@ -236284,16 +238141,15 @@
236284 char *zKey = 0;
236285 Fts5HashEntry *p;
236286
236287 for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){
236288 zKey = fts5EntryKey(p);
236289 assert( p->nKey+1==(int)strlen(zKey) );
236290 if( nTerm==p->nKey+1 && memcmp(zKey, pTerm, nTerm)==0 ) break;
236291 }
236292
236293 if( p ){
236294 int nHashPre = sizeof(Fts5HashEntry) + nTerm + 1;
236295 int nList = p->nData - nHashPre;
236296 u8 *pRet = (u8*)(*ppOut = sqlite3_malloc64(nPre + nList + 10));
236297 if( pRet ){
236298 Fts5HashEntry *pFaux = (Fts5HashEntry*)&pRet[nPre-nHashPre];
236299 memcpy(&pRet[nPre], &((u8*)p)[nHashPre], nList);
@@ -236350,23 +238206,26 @@
236350 }
236351
236352 static void sqlite3Fts5HashScanEntry(
236353 Fts5Hash *pHash,
236354 const char **pzTerm, /* OUT: term (nul-terminated) */
 
236355 const u8 **ppDoclist, /* OUT: pointer to doclist */
236356 int *pnDoclist /* OUT: size of doclist in bytes */
236357 ){
236358 Fts5HashEntry *p;
236359 if( (p = pHash->pScan) ){
236360 char *zKey = fts5EntryKey(p);
236361 int nTerm = (int)strlen(zKey);
236362 fts5HashAddPoslistSize(pHash, p, 0);
236363 *pzTerm = zKey;
236364 *ppDoclist = (const u8*)&zKey[nTerm+1];
236365 *pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm + 1);
 
236366 }else{
236367 *pzTerm = 0;
 
236368 *ppDoclist = 0;
236369 *pnDoclist = 0;
236370 }
236371 }
236372
@@ -236693,10 +238552,13 @@
236693 typedef struct Fts5DoclistIter Fts5DoclistIter;
236694 typedef struct Fts5SegWriter Fts5SegWriter;
236695 typedef struct Fts5Structure Fts5Structure;
236696 typedef struct Fts5StructureLevel Fts5StructureLevel;
236697 typedef struct Fts5StructureSegment Fts5StructureSegment;
 
 
 
236698
236699 struct Fts5Data {
236700 u8 *p; /* Pointer to buffer containing record */
236701 int nn; /* Size of record in bytes */
236702 int szLeaf; /* Size of leaf without page-index */
@@ -236727,18 +238589,20 @@
236727 int nContentlessDelete; /* Number of contentless delete ops */
236728 int nPendingRow; /* Number of INSERT in hash table */
236729
236730 /* Error state. */
236731 int rc; /* Current error code */
 
236732
236733 /* State used by the fts5DataXXX() functions. */
236734 sqlite3_blob *pReader; /* RO incr-blob open on %_data table */
236735 sqlite3_stmt *pWriter; /* "INSERT ... %_data VALUES(?,?)" */
236736 sqlite3_stmt *pDeleter; /* "DELETE FROM %_data ... id>=? AND id<=?" */
236737 sqlite3_stmt *pIdxWriter; /* "INSERT ... %_idx VALUES(?,?,?,?)" */
236738 sqlite3_stmt *pIdxDeleter; /* "DELETE FROM %_idx WHERE segid=?" */
236739 sqlite3_stmt *pIdxSelect;
 
236740 int nRead; /* Total number of blocks read */
236741
236742 sqlite3_stmt *pDeleteFromIdx;
236743
236744 sqlite3_stmt *pDataVersion;
@@ -236888,12 +238752,11 @@
236888 int flags; /* Mask of configuration flags */
236889 int iLeafPgno; /* Current leaf page number */
236890 Fts5Data *pLeaf; /* Current leaf data */
236891 Fts5Data *pNextLeaf; /* Leaf page (iLeafPgno+1) */
236892 i64 iLeafOffset; /* Byte offset within current leaf */
236893 Fts5Data **apTombstone; /* Array of tombstone pages */
236894 int nTombstone;
236895
236896 /* Next method */
236897 void (*xNext)(Fts5Index*, Fts5SegIter*, int*);
236898
236899 /* The page and offset from which the current term was read. The offset
@@ -236915,10 +238778,19 @@
236915 Fts5Buffer term; /* Current term */
236916 i64 iRowid; /* Current rowid */
236917 int nPos; /* Number of bytes in current position list */
236918 u8 bDel; /* True if the delete flag is set */
236919 };
 
 
 
 
 
 
 
 
 
236920
236921 /*
236922 ** Argument is a pointer to an Fts5Data structure that contains a
236923 ** leaf page.
236924 */
@@ -236960,13 +238832,20 @@
236960 ** the smallest key overall. aFirst[0] is unused.
236961 **
236962 ** poslist:
236963 ** Used by sqlite3Fts5IterPoslist() when the poslist needs to be buffered.
236964 ** There is no way to tell if this is populated or not.
 
 
 
 
 
 
236965 */
236966 struct Fts5Iter {
236967 Fts5IndexIter base; /* Base class containing output vars */
 
236968
236969 Fts5Index *pIndex; /* Index that owns this iterator */
236970 Fts5Buffer poslist; /* Buffer containing current poslist */
236971 Fts5Colset *pColset; /* Restrict matches to these columns */
236972
@@ -236979,11 +238858,10 @@
236979
236980 i64 iSwitchRowid; /* Firstest rowid of other than aFirst[1] */
236981 Fts5CResult *aFirst; /* Current merge state (see above) */
236982 Fts5SegIter aSeg[1]; /* Array of segment iterators */
236983 };
236984
236985
236986 /*
236987 ** An instance of the following type is used to iterate through the contents
236988 ** of a doclist-index record.
236989 **
@@ -238279,22 +240157,24 @@
238279 pIter->xNext = fts5SegIterNext;
238280 }
238281 }
238282
238283 /*
238284 ** Allocate a tombstone hash page array (pIter->apTombstone) for the
238285 ** iterator passed as the second argument. If an OOM error occurs, leave
238286 ** an error in the Fts5Index object.
238287 */
238288 static void fts5SegIterAllocTombstone(Fts5Index *p, Fts5SegIter *pIter){
238289 const int nTomb = pIter->pSeg->nPgTombstone;
238290 if( nTomb>0 ){
238291 Fts5Data **apTomb = 0;
238292 apTomb = (Fts5Data**)sqlite3Fts5MallocZero(&p->rc, sizeof(Fts5Data)*nTomb);
238293 if( apTomb ){
238294 pIter->apTombstone = apTomb;
238295 pIter->nTombstone = nTomb;
 
 
238296 }
238297 }
238298 }
238299
238300 /*
@@ -238547,19 +240427,20 @@
238547 pIter->iLeafOffset = iOff;
238548 fts5SegIterLoadTerm(p, pIter, nKeep);
238549 }else{
238550 const u8 *pList = 0;
238551 const char *zTerm = 0;
 
238552 int nList;
238553 sqlite3Fts5HashScanNext(p->pHash);
238554 sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &pList, &nList);
238555 if( pList==0 ) goto next_none_eof;
238556 pIter->pLeaf->p = (u8*)pList;
238557 pIter->pLeaf->nn = nList;
238558 pIter->pLeaf->szLeaf = nList;
238559 pIter->iEndofDoclist = nList;
238560 sqlite3Fts5BufferSet(&p->rc,&pIter->term, (int)strlen(zTerm), (u8*)zTerm);
238561 pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid);
238562 }
238563
238564 if( pbNewTerm ) *pbNewTerm = 1;
238565 }else{
@@ -238621,26 +240502,26 @@
238621 pIter->iLeafOffset = iOff;
238622
238623 }else if( pIter->pSeg==0 ){
238624 const u8 *pList = 0;
238625 const char *zTerm = 0;
 
238626 int nList = 0;
238627 assert( (pIter->flags & FTS5_SEGITER_ONETERM) || pbNewTerm );
238628 if( 0==(pIter->flags & FTS5_SEGITER_ONETERM) ){
238629 sqlite3Fts5HashScanNext(p->pHash);
238630 sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &pList, &nList);
238631 }
238632 if( pList==0 ){
238633 fts5DataRelease(pIter->pLeaf);
238634 pIter->pLeaf = 0;
238635 }else{
238636 pIter->pLeaf->p = (u8*)pList;
238637 pIter->pLeaf->nn = nList;
238638 pIter->pLeaf->szLeaf = nList;
238639 pIter->iEndofDoclist = nList+1;
238640 sqlite3Fts5BufferSet(&p->rc, &pIter->term, (int)strlen(zTerm),
238641 (u8*)zTerm);
238642 pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid);
238643 *pbNewTerm = 1;
238644 }
238645 }else{
238646 iOff = 0;
@@ -239022,11 +240903,11 @@
239022
239023 if( pIter->pLeaf ){
239024 fts5LeafSeek(p, bGe, pIter, pTerm, nTerm);
239025 }
239026
239027 if( p->rc==SQLITE_OK && bGe==0 ){
239028 pIter->flags |= FTS5_SEGITER_ONETERM;
239029 if( pIter->pLeaf ){
239030 if( flags & FTS5INDEX_QUERY_DESC ){
239031 pIter->flags |= FTS5_SEGITER_REVERSE;
239032 }
@@ -239038,11 +240919,13 @@
239038 }
239039 }
239040 }
239041
239042 fts5SegIterSetNext(p, pIter);
239043 fts5SegIterAllocTombstone(p, pIter);
 
 
239044
239045 /* Either:
239046 **
239047 ** 1) an error has occurred, or
239048 ** 2) the iterator points to EOF, or
@@ -239055,10 +240938,83 @@
239055 || fts5BufferCompareBlob(&pIter->term, pTerm, nTerm)==0 /* 3 */
239056 || (bGe && fts5BufferCompareBlob(&pIter->term, pTerm, nTerm)>0) /* 4 */
239057 );
239058 }
239059
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239060 /*
239061 ** Initialize the object pIter to point to term pTerm/nTerm within the
239062 ** in-memory hash table. If there is no such term in the hash-table, the
239063 ** iterator is set to EOF.
239064 **
@@ -239081,12 +241037,11 @@
239081
239082 if( pTerm==0 || (flags & FTS5INDEX_QUERY_SCAN) ){
239083 const u8 *pList = 0;
239084
239085 p->rc = sqlite3Fts5HashScanInit(p->pHash, (const char*)pTerm, nTerm);
239086 sqlite3Fts5HashScanEntry(p->pHash, (const char**)&z, &pList, &nList);
239087 n = (z ? (int)strlen((const char*)z) : 0);
239088 if( pList ){
239089 pLeaf = fts5IdxMalloc(p, sizeof(Fts5Data));
239090 if( pLeaf ){
239091 pLeaf->p = (u8*)pList;
239092 }
@@ -239140,19 +241095,36 @@
239140 fts5DataRelease(ap[ii]);
239141 }
239142 sqlite3_free(ap);
239143 }
239144 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239145
239146 /*
239147 ** Zero the iterator passed as the only argument.
239148 */
239149 static void fts5SegIterClear(Fts5SegIter *pIter){
239150 fts5BufferFree(&pIter->term);
239151 fts5DataRelease(pIter->pLeaf);
239152 fts5DataRelease(pIter->pNextLeaf);
239153 fts5IndexFreeArray(pIter->apTombstone, pIter->nTombstone);
239154 fts5DlidxIterFree(pIter->pDlidx);
239155 sqlite3_free(pIter->aRowidOffset);
239156 memset(pIter, 0, sizeof(Fts5SegIter));
239157 }
239158
@@ -239393,11 +241365,10 @@
239393 if( bRev!=0 && pIter->iRowid<=iMatch ) break;
239394 bMove = 1;
239395 }while( p->rc==SQLITE_OK );
239396 }
239397
239398
239399 /*
239400 ** Free the iterator object passed as the second argument.
239401 */
239402 static void fts5MultiIterFree(Fts5Iter *pIter){
239403 if( pIter ){
@@ -239538,28 +241509,29 @@
239538 ** if there is no tombstone or if the iterator is already at EOF.
239539 */
239540 static int fts5MultiIterIsDeleted(Fts5Iter *pIter){
239541 int iFirst = pIter->aFirst[1].iFirst;
239542 Fts5SegIter *pSeg = &pIter->aSeg[iFirst];
 
239543
239544 if( pSeg->pLeaf && pSeg->nTombstone ){
239545 /* Figure out which page the rowid might be present on. */
239546 int iPg = ((u64)pSeg->iRowid) % pSeg->nTombstone;
239547 assert( iPg>=0 );
239548
239549 /* If tombstone hash page iPg has not yet been loaded from the
239550 ** database, load it now. */
239551 if( pSeg->apTombstone[iPg]==0 ){
239552 pSeg->apTombstone[iPg] = fts5DataRead(pIter->pIndex,
239553 FTS5_TOMBSTONE_ROWID(pSeg->pSeg->iSegid, iPg)
239554 );
239555 if( pSeg->apTombstone[iPg]==0 ) return 0;
239556 }
239557
239558 return fts5IndexTombstoneQuery(
239559 pSeg->apTombstone[iPg],
239560 pSeg->nTombstone,
239561 pSeg->iRowid
239562 );
239563 }
239564
239565 return 0;
@@ -240094,10 +242066,36 @@
240094 }
240095 }
240096 }
240097 }
240098
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240099
240100 /*
240101 ** Allocate a new Fts5Iter object.
240102 **
240103 ** The new object will be used to iterate through data in structure pStruct.
@@ -240175,35 +242173,16 @@
240175 }
240176 }
240177 assert( iIter==nSeg );
240178 }
240179
240180 /* If the above was successful, each component iterators now points
240181 ** to the first entry in its segment. In this case initialize the
240182 ** aFirst[] array. Or, if an error has occurred, free the iterator
240183 ** object and set the output variable to NULL. */
240184 if( p->rc==SQLITE_OK ){
240185 for(iIter=pNew->nSeg-1; iIter>0; iIter--){
240186 int iEq;
240187 if( (iEq = fts5MultiIterDoCompare(pNew, iIter)) ){
240188 Fts5SegIter *pSeg = &pNew->aSeg[iEq];
240189 if( p->rc==SQLITE_OK ) pSeg->xNext(p, pSeg, 0);
240190 fts5MultiIterAdvanced(p, pNew, iEq, iIter);
240191 }
240192 }
240193 fts5MultiIterSetEof(pNew);
240194 fts5AssertMultiIterSetup(p, pNew);
240195
240196 if( (pNew->bSkipEmpty && fts5MultiIterIsEmpty(p, pNew))
240197 || fts5MultiIterIsDeleted(pNew)
240198 ){
240199 fts5MultiIterNext(p, pNew, 0, 0);
240200 }else if( pNew->base.bEof==0 ){
240201 Fts5SegIter *pSeg = &pNew->aSeg[pNew->aFirst[1].iFirst];
240202 pNew->xSetOutputs(pNew, pSeg);
240203 }
240204
240205 }else{
240206 fts5MultiIterFree(pNew);
240207 *ppOut = 0;
240208 }
240209
@@ -240224,11 +242203,10 @@
240224 ){
240225 Fts5Iter *pNew;
240226 pNew = fts5MultiIterAlloc(p, 2);
240227 if( pNew ){
240228 Fts5SegIter *pIter = &pNew->aSeg[1];
240229
240230 pIter->flags = FTS5_SEGITER_ONETERM;
240231 if( pData->szLeaf>0 ){
240232 pIter->pLeaf = pData;
240233 pIter->iLeafOffset = fts5GetVarint(pData->p, (u64*)&pIter->iRowid);
240234 pIter->iEndofDoclist = pData->nn;
@@ -240372,10 +242350,11 @@
240372 assert( p->pHash || p->nPendingData==0 );
240373 if( p->pHash ){
240374 sqlite3Fts5HashClear(p->pHash);
240375 p->nPendingData = 0;
240376 p->nPendingRow = 0;
 
240377 }
240378 p->nContentlessDelete = 0;
240379 }
240380
240381 /*
@@ -240587,11 +242566,11 @@
240587 }else{
240588 bDone = 1;
240589 }
240590
240591 if( pDlidx->bPrevValid ){
240592 iVal = iRowid - pDlidx->iPrev;
240593 }else{
240594 i64 iPgno = (i==0 ? pWriter->writer.pgno : pDlidx[-1].pgno);
240595 assert( pDlidx->buf.n==0 );
240596 sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, !bDone);
240597 sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, iPgno);
@@ -241710,14 +243689,14 @@
241710 */
241711 static void fts5FlushSecureDelete(
241712 Fts5Index *p,
241713 Fts5Structure *pStruct,
241714 const char *zTerm,
 
241715 i64 iRowid
241716 ){
241717 const int f = FTS5INDEX_QUERY_SKIPHASH;
241718 int nTerm = (int)strlen(zTerm);
241719 Fts5Iter *pIter = 0; /* Used to find term instance */
241720
241721 fts5MultiIterNew(p, pStruct, f, 0, (const u8*)zTerm, nTerm, -1, 0, &pIter);
241722 if( fts5MultiIterEof(p, pIter)==0 ){
241723 i64 iThis = fts5MultiIterRowid(pIter);
@@ -241787,12 +243766,11 @@
241787 int nTerm; /* Size of zTerm in bytes */
241788 const u8 *pDoclist; /* Pointer to doclist for this term */
241789 int nDoclist; /* Size of doclist in bytes */
241790
241791 /* Get the term and doclist for this entry. */
241792 sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist);
241793 nTerm = (int)strlen(zTerm);
241794 if( bSecureDelete==0 ){
241795 fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm);
241796 if( p->rc!=SQLITE_OK ) break;
241797 assert( writer.bFirstRowidInPage==0 );
241798 }
@@ -241818,21 +243796,21 @@
241818 ** in fact a delete, then edit the existing segments directly
241819 ** using fts5FlushSecureDelete(). */
241820 if( bSecureDelete ){
241821 if( eDetail==FTS5_DETAIL_NONE ){
241822 if( iOff<nDoclist && pDoclist[iOff]==0x00 ){
241823 fts5FlushSecureDelete(p, pStruct, zTerm, iRowid);
241824 iOff++;
241825 if( iOff<nDoclist && pDoclist[iOff]==0x00 ){
241826 iOff++;
241827 nDoclist = 0;
241828 }else{
241829 continue;
241830 }
241831 }
241832 }else if( (pDoclist[iOff] & 0x01) ){
241833 fts5FlushSecureDelete(p, pStruct, zTerm, iRowid);
241834 if( p->rc!=SQLITE_OK || pDoclist[iOff]==0x01 ){
241835 iOff++;
241836 continue;
241837 }
241838 }
@@ -241954,18 +243932,24 @@
241954 /*
241955 ** Flush any data stored in the in-memory hash tables to the database.
241956 */
241957 static void fts5IndexFlush(Fts5Index *p){
241958 /* Unless it is empty, flush the hash table to disk */
 
 
 
 
241959 if( p->nPendingData || p->nContentlessDelete ){
241960 assert( p->pHash );
241961 fts5FlushOneHash(p);
241962 if( p->rc==SQLITE_OK ){
241963 sqlite3Fts5HashClear(p->pHash);
241964 p->nPendingData = 0;
241965 p->nPendingRow = 0;
241966 p->nContentlessDelete = 0;
 
 
241967 }
241968 }
241969 }
241970
241971 static Fts5Structure *fts5IndexOptimizeStruct(
@@ -242448,11 +244432,11 @@
242448 int bDesc, /* True for "ORDER BY rowid DESC" */
242449 int iIdx, /* Index to scan for data */
242450 u8 *pToken, /* Buffer containing prefix to match */
242451 int nToken, /* Size of buffer pToken in bytes */
242452 Fts5Colset *pColset, /* Restrict matches to these columns */
242453 Fts5Iter **ppIter /* OUT: New iterator */
242454 ){
242455 Fts5Structure *pStruct;
242456 Fts5Buffer *aBuf;
242457 int nBuf = 32;
242458 int nMerge = 1;
@@ -242469,12 +244453,13 @@
242469 xAppend = fts5AppendPoslist;
242470 }
242471
242472 aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*nBuf);
242473 pStruct = fts5StructureRead(p);
 
242474
242475 if( aBuf && pStruct ){
242476 const int flags = FTS5INDEX_QUERY_SCAN
242477 | FTS5INDEX_QUERY_SKIPEMPTY
242478 | FTS5INDEX_QUERY_NOOUTPUT;
242479 int i;
242480 i64 iLastRowid = 0;
@@ -242482,10 +244467,16 @@
242482 Fts5Data *pData;
242483 Fts5Buffer doclist;
242484 int bNewTerm = 1;
242485
242486 memset(&doclist, 0, sizeof(doclist));
 
 
 
 
 
 
242487 if( iIdx!=0 ){
242488 int dummy = 0;
242489 const int f2 = FTS5INDEX_QUERY_SKIPEMPTY|FTS5INDEX_QUERY_NOOUTPUT;
242490 pToken[0] = FTS5_MAIN_PREFIX;
242491 fts5MultiIterNew(p, pStruct, f2, pColset, pToken, nToken, -1, 0, &p1);
@@ -242505,10 +244496,11 @@
242505 }
242506
242507 pToken[0] = FTS5_MAIN_PREFIX + iIdx;
242508 fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1);
242509 fts5IterSetOutputCb(&p->rc, p1);
 
242510 for( /* no-op */ ;
242511 fts5MultiIterEof(p, p1)==0;
242512 fts5MultiIterNext2(p, p1, &bNewTerm)
242513 ){
242514 Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ];
@@ -242520,11 +244512,10 @@
242520 if( bNewTerm ){
242521 if( nTerm<nToken || memcmp(pToken, pTerm, nToken) ) break;
242522 }
242523
242524 if( p1->base.nData==0 ) continue;
242525
242526 if( p1->base.iRowid<=iLastRowid && doclist.n>0 ){
242527 for(i=0; p->rc==SQLITE_OK && doclist.n; i++){
242528 int i1 = i*nMerge;
242529 int iStore;
242530 assert( i1+nMerge<=nBuf );
@@ -242559,11 +244550,11 @@
242559 fts5BufferFree(&aBuf[iFree]);
242560 }
242561 }
242562 fts5MultiIterFree(p1);
242563
242564 pData = fts5IdxMalloc(p, sizeof(Fts5Data)+doclist.n+FTS5_DATA_ZERO_PADDING);
242565 if( pData ){
242566 pData->p = (u8*)&pData[1];
242567 pData->nn = pData->szLeaf = doclist.n;
242568 if( doclist.n ) memcpy(pData->p, doclist.p, doclist.n);
242569 fts5MultiIterNew2(p, pData, bDesc, ppIter);
@@ -242702,10 +244693,11 @@
242702 sqlite3_finalize(p->pWriter);
242703 sqlite3_finalize(p->pDeleter);
242704 sqlite3_finalize(p->pIdxWriter);
242705 sqlite3_finalize(p->pIdxDeleter);
242706 sqlite3_finalize(p->pIdxSelect);
 
242707 sqlite3_finalize(p->pDataVersion);
242708 sqlite3_finalize(p->pDeleteFromIdx);
242709 sqlite3Fts5HashFree(p->pHash);
242710 sqlite3_free(p->zDataTbl);
242711 sqlite3_free(p);
@@ -242796,10 +244788,458 @@
242796 }
242797 }
242798
242799 return rc;
242800 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
242801
242802 /*
242803 ** Open a new iterator to iterate though all rowid that match the
242804 ** specified token or token prefix.
242805 */
@@ -242818,11 +245258,16 @@
242818 assert( (flags & FTS5INDEX_QUERY_SCAN)==0 || flags==FTS5INDEX_QUERY_SCAN );
242819
242820 if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){
242821 int iIdx = 0; /* Index to search */
242822 int iPrefixIdx = 0; /* +1 prefix index */
 
242823 if( nToken>0 ) memcpy(&buf.p[1], pToken, nToken);
 
 
 
 
242824
242825 /* Figure out which index to search and set iIdx accordingly. If this
242826 ** is a prefix query for which there is no prefix index, set iIdx to
242827 ** greater than pConfig->nPrefix to indicate that the query will be
242828 ** satisfied by scanning multiple terms in the main index.
@@ -242845,11 +245290,14 @@
242845 if( nIdxChar==nChar ) break;
242846 if( nIdxChar==nChar+1 ) iPrefixIdx = iIdx;
242847 }
242848 }
242849
242850 if( iIdx<=pConfig->nPrefix ){
 
 
 
242851 /* Straight index lookup */
242852 Fts5Structure *pStruct = fts5StructureRead(p);
242853 buf.p[0] = (u8)(FTS5_MAIN_PREFIX + iIdx);
242854 if( pStruct ){
242855 fts5MultiIterNew(p, pStruct, flags | FTS5INDEX_QUERY_SKIPEMPTY,
@@ -242892,11 +245340,15 @@
242892 ** Move to the next matching rowid.
242893 */
242894 static int sqlite3Fts5IterNext(Fts5IndexIter *pIndexIter){
242895 Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
242896 assert( pIter->pIndex->rc==SQLITE_OK );
242897 fts5MultiIterNext(pIter->pIndex, pIter, 0, 0);
 
 
 
 
242898 return fts5IndexReturn(pIter->pIndex);
242899 }
242900
242901 /*
242902 ** Move to the next matching term/rowid. Used by the fts5vocab module.
@@ -242925,11 +245377,15 @@
242925 ** definition of "at or after" depends on whether this iterator iterates
242926 ** in ascending or descending rowid order.
242927 */
242928 static int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){
242929 Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
242930 fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch);
 
 
 
 
242931 return fts5IndexReturn(pIter->pIndex);
242932 }
242933
242934 /*
242935 ** Return the current term.
@@ -242939,18 +245395,112 @@
242939 const char *z = (const char*)fts5MultiIterTerm((Fts5Iter*)pIndexIter, &n);
242940 assert_nc( z || n<=1 );
242941 *pn = n-1;
242942 return (z ? &z[1] : 0);
242943 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
242944
242945 /*
242946 ** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery().
242947 */
242948 static void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){
242949 if( pIndexIter ){
242950 Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
242951 Fts5Index *pIndex = pIter->pIndex;
 
242952 fts5MultiIterFree(pIter);
242953 sqlite3Fts5IndexCloseReader(pIndex);
242954 }
242955 }
242956
@@ -243454,11 +246004,13 @@
243454 u64 *pCksum /* IN/OUT: Checksum value */
243455 ){
243456 int eDetail = p->pConfig->eDetail;
243457 u64 cksum = *pCksum;
243458 Fts5IndexIter *pIter = 0;
243459 int rc = sqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIter);
 
 
243460
243461 while( rc==SQLITE_OK && ALWAYS(pIter!=0) && 0==sqlite3Fts5IterEof(pIter) ){
243462 i64 rowid = pIter->iRowid;
243463
243464 if( eDetail==FTS5_DETAIL_NONE ){
@@ -244151,10 +246703,28 @@
244151
244152 sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " %lld%s", iRowid, zApp);
244153 }
244154 }
244155 #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244156
244157 #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
244158 /*
244159 ** The implementation of user-defined scalar function fts5_decode().
244160 */
@@ -244259,13 +246829,12 @@
244259
244260 /* Read the term data for the next term*/
244261 iOff += fts5GetVarint32(&a[iOff], nAppend);
244262 term.n = nKeep;
244263 fts5BufferAppendBlob(&rc, &term, nAppend, &a[iOff]);
244264 sqlite3Fts5BufferAppendPrintf(
244265 &rc, &s, " term=%.*s", term.n, (const char*)term.p
244266 );
244267 iOff += nAppend;
244268
244269 /* Figure out where the doclist for this term ends */
244270 if( iPgidxOff<n ){
244271 int nIncr;
@@ -244369,13 +246938,12 @@
244369 break;
244370 }
244371 fts5BufferAppendBlob(&rc, &term, nByte, &a[iOff]);
244372 iOff += nByte;
244373
244374 sqlite3Fts5BufferAppendPrintf(
244375 &rc, &s, " term=%.*s", term.n, (const char*)term.p
244376 );
244377 iOff += fts5DecodeDoclist(&rc, &s, &a[iOff], iEnd-iOff);
244378 }
244379
244380 fts5BufferFree(&term);
244381 }
@@ -244846,11 +247414,11 @@
244846 Fts5Table p; /* Public class members from fts5Int.h */
244847 Fts5Storage *pStorage; /* Document store */
244848 Fts5Global *pGlobal; /* Global (connection wide) data */
244849 Fts5Cursor *pSortCsr; /* Sort data from this cursor */
244850 int iSavepoint; /* Successful xSavepoint()+1 */
244851 int bInSavepoint;
244852 #ifdef SQLITE_DEBUG
244853 struct Fts5TransactionState ts;
244854 #endif
244855 };
244856
@@ -245384,16 +247952,19 @@
245384 }
245385 }
245386 }
245387 idxStr[iIdxStr] = '\0';
245388
245389 /* Set idxFlags flags for the ORDER BY clause */
 
 
 
245390 if( pInfo->nOrderBy==1 ){
245391 int iSort = pInfo->aOrderBy[0].iColumn;
245392 if( iSort==(pConfig->nCol+1) && bSeenMatch ){
245393 idxFlags |= FTS5_BI_ORDER_RANK;
245394 }else if( iSort==-1 ){
245395 idxFlags |= FTS5_BI_ORDER_ROWID;
245396 }
245397 if( BitFlagTest(idxFlags, FTS5_BI_ORDER_RANK|FTS5_BI_ORDER_ROWID) ){
245398 pInfo->orderByConsumed = 1;
245399 if( pInfo->aOrderBy[0].desc ){
@@ -245640,10 +248211,20 @@
245640
245641 assert( (pCsr->ePlan<3)==
245642 (pCsr->ePlan==FTS5_PLAN_MATCH || pCsr->ePlan==FTS5_PLAN_SOURCE)
245643 );
245644 assert( !CsrFlagTest(pCsr, FTS5CSR_EOF) );
 
 
 
 
 
 
 
 
 
 
245645
245646 if( pCsr->ePlan<3 ){
245647 int bSkip = 0;
245648 if( (rc = fts5CursorReseek(pCsr, &bSkip)) || bSkip ) return rc;
245649 rc = sqlite3Fts5ExprNext(pCsr->pExpr, pCsr->iLastRowid);
@@ -246791,16 +249372,10 @@
246791 if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_INST)==0
246792 || SQLITE_OK==(rc = fts5CacheInstArray(pCsr))
246793 ){
246794 if( iIdx<0 || iIdx>=pCsr->nInstCount ){
246795 rc = SQLITE_RANGE;
246796 #if 0
246797 }else if( fts5IsOffsetless((Fts5Table*)pCsr->base.pVtab) ){
246798 *piPhrase = pCsr->aInst[iIdx*3];
246799 *piCol = pCsr->aInst[iIdx*3 + 2];
246800 *piOff = -1;
246801 #endif
246802 }else{
246803 *piPhrase = pCsr->aInst[iIdx*3];
246804 *piCol = pCsr->aInst[iIdx*3 + 1];
246805 *piOff = pCsr->aInst[iIdx*3 + 2];
246806 }
@@ -247051,17 +249626,60 @@
247051 }
247052
247053 return rc;
247054 }
247055
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247056
247057 static int fts5ApiQueryPhrase(Fts5Context*, int, void*,
247058 int(*)(const Fts5ExtensionApi*, Fts5Context*, void*)
247059 );
247060
247061 static const Fts5ExtensionApi sFts5Api = {
247062 2, /* iVersion */
247063 fts5ApiUserData,
247064 fts5ApiColumnCount,
247065 fts5ApiRowCount,
247066 fts5ApiColumnTotalSize,
247067 fts5ApiTokenize,
@@ -247077,10 +249695,12 @@
247077 fts5ApiGetAuxdata,
247078 fts5ApiPhraseFirst,
247079 fts5ApiPhraseNext,
247080 fts5ApiPhraseFirstColumn,
247081 fts5ApiPhraseNextColumn,
 
 
247082 };
247083
247084 /*
247085 ** Implementation of API function xQueryPhrase().
247086 */
@@ -247343,13 +249963,11 @@
247343 sqlite3_vtab *pVtab, /* Virtual table handle */
247344 const char *zName /* New name of table */
247345 ){
247346 int rc;
247347 Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
247348 pTab->bInSavepoint = 1;
247349 rc = sqlite3Fts5StorageRename(pTab->pStorage, zName);
247350 pTab->bInSavepoint = 0;
247351 return rc;
247352 }
247353
247354 static int sqlite3Fts5FlushToDisk(Fts5Table *pTab){
247355 fts5TripCursors((Fts5FullTable*)pTab);
@@ -247362,30 +249980,16 @@
247362 ** Flush the contents of the pending-terms table to disk.
247363 */
247364 static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){
247365 Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
247366 int rc = SQLITE_OK;
247367 char *zSql = 0;
247368 fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint);
247369
247370 if( pTab->bInSavepoint==0 ){
247371 zSql = sqlite3_mprintf("INSERT INTO %Q.%Q(%Q) VALUES('flush')",
247372 pTab->p.pConfig->zDb, pTab->p.pConfig->zName, pTab->p.pConfig->zName
247373 );
247374 if( zSql ){
247375 pTab->bInSavepoint = 1;
247376 rc = sqlite3_exec(pTab->p.pConfig->db, zSql, 0, 0, 0);
247377 pTab->bInSavepoint = 0;
247378 sqlite3_free(zSql);
247379 }else{
247380 rc = SQLITE_NOMEM;
247381 }
247382 if( rc==SQLITE_OK ){
247383 pTab->iSavepoint = iSavepoint+1;
247384 }
247385 }
247386
247387 return rc;
247388 }
247389
247390 /*
247391 ** The xRelease() method.
@@ -247619,11 +250223,11 @@
247619 int nArg, /* Number of args */
247620 sqlite3_value **apUnused /* Function arguments */
247621 ){
247622 assert( nArg==0 );
247623 UNUSED_PARAM2(nArg, apUnused);
247624 sqlite3_result_text(pCtx, "fts5: 2023-11-24 11:41:44 ebead0e7230cd33bcec9f95d2183069565b9e709bf745c9b5db65cc0cbf92c0f", -1, SQLITE_TRANSIENT);
247625 }
247626
247627 /*
247628 ** Return true if zName is the extension on one of the shadow tables used
247629 ** by this module.
@@ -247642,11 +250246,11 @@
247642 /*
247643 ** Run an integrity check on the FTS5 data structures. Return a string
247644 ** if anything is found amiss. Return a NULL pointer if everything is
247645 ** OK.
247646 */
247647 static int fts5Integrity(
247648 sqlite3_vtab *pVtab, /* the FTS5 virtual table to check */
247649 const char *zSchema, /* Name of schema in which this table lives */
247650 const char *zTabname, /* Name of the table itself */
247651 int isQuick, /* True if this is a quick-check */
247652 char **pzErr /* Write error message here */
@@ -247700,11 +250304,11 @@
247700 /* xRename */ fts5RenameMethod,
247701 /* xSavepoint */ fts5SavepointMethod,
247702 /* xRelease */ fts5ReleaseMethod,
247703 /* xRollbackTo */ fts5RollbackToMethod,
247704 /* xShadowName */ fts5ShadowName,
247705 /* xIntegrity */ fts5Integrity
247706 };
247707
247708 int rc;
247709 Fts5Global *pGlobal = 0;
247710
@@ -248466,11 +251070,11 @@
248466 if( rc==SQLITE_OK ){
248467 rc = fts5StorageLoadTotals(p, 1);
248468 }
248469
248470 if( rc==SQLITE_OK ){
248471 rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0);
248472 }
248473
248474 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pScan) ){
248475 i64 iRowid = sqlite3_column_int64(pScan, 0);
248476
@@ -249252,10 +251856,16 @@
249252 *zOut++ = 0x80 + (unsigned char)(c & 0x3F); \
249253 } \
249254 }
249255
249256 #endif /* ifndef SQLITE_AMALGAMATION */
 
 
 
 
 
 
249257
249258 typedef struct Unicode61Tokenizer Unicode61Tokenizer;
249259 struct Unicode61Tokenizer {
249260 unsigned char aTokenChar[128]; /* ASCII range token characters */
249261 char *aFold; /* Buffer to fold text into */
@@ -250288,10 +252898,11 @@
250288 ** Start of trigram implementation.
250289 */
250290 typedef struct TrigramTokenizer TrigramTokenizer;
250291 struct TrigramTokenizer {
250292 int bFold; /* True to fold to lower-case */
 
250293 };
250294
250295 /*
250296 ** Free a trigram tokenizer.
250297 */
@@ -250314,22 +252925,34 @@
250314 if( pNew==0 ){
250315 rc = SQLITE_NOMEM;
250316 }else{
250317 int i;
250318 pNew->bFold = 1;
 
250319 for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
250320 const char *zArg = azArg[i+1];
250321 if( 0==sqlite3_stricmp(azArg[i], "case_sensitive") ){
250322 if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){
250323 rc = SQLITE_ERROR;
250324 }else{
250325 pNew->bFold = (zArg[0]=='0');
250326 }
 
 
 
 
 
 
250327 }else{
250328 rc = SQLITE_ERROR;
250329 }
250330 }
 
 
 
 
 
250331 if( rc!=SQLITE_OK ){
250332 fts5TriDelete((Fts5Tokenizer*)pNew);
250333 pNew = 0;
250334 }
250335 }
@@ -250348,44 +252971,66 @@
250348 int (*xToken)(void*, int, const char*, int, int, int)
250349 ){
250350 TrigramTokenizer *p = (TrigramTokenizer*)pTok;
250351 int rc = SQLITE_OK;
250352 char aBuf[32];
 
 
250353 const unsigned char *zIn = (const unsigned char*)pText;
250354 const unsigned char *zEof = &zIn[nText];
250355 u32 iCode;
 
250356
250357 UNUSED_PARAM(unusedFlags);
250358 while( 1 ){
250359 char *zOut = aBuf;
250360 int iStart = zIn - (const unsigned char*)pText;
250361 const unsigned char *zNext;
250362
250363 READ_UTF8(zIn, zEof, iCode);
250364 if( iCode==0 ) break;
250365 zNext = zIn;
250366 if( zIn<zEof ){
250367 if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0);
250368 WRITE_UTF8(zOut, iCode);
250369 READ_UTF8(zIn, zEof, iCode);
250370 if( iCode==0 ) break;
250371 }else{
250372 break;
250373 }
250374 if( zIn<zEof ){
250375 if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0);
250376 WRITE_UTF8(zOut, iCode);
250377 READ_UTF8(zIn, zEof, iCode);
250378 if( iCode==0 ) break;
250379 if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0);
250380 WRITE_UTF8(zOut, iCode);
250381 }else{
250382 break;
250383 }
250384 rc = xToken(pCtx, 0, aBuf, zOut-aBuf, iStart, iStart + zOut-aBuf);
250385 if( rc!=SQLITE_OK ) break;
250386 zIn = zNext;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
250387 }
250388
250389 return rc;
250390 }
250391
@@ -250404,11 +253049,13 @@
250404 int (*xCreate)(void*, const char**, int, Fts5Tokenizer**),
250405 Fts5Tokenizer *pTok
250406 ){
250407 if( xCreate==fts5TriCreate ){
250408 TrigramTokenizer *p = (TrigramTokenizer*)pTok;
250409 return p->bFold ? FTS5_PATTERN_LIKE : FTS5_PATTERN_GLOB;
 
 
250410 }
250411 return FTS5_PATTERN_NONE;
250412 }
250413
250414 /*
@@ -252193,11 +254840,11 @@
252193 if( idxNum & FTS5_VOCAB_TERM_LE ) pLe = apVal[iVal++];
252194
252195 if( pEq ){
252196 zTerm = (const char *)sqlite3_value_text(pEq);
252197 nTerm = sqlite3_value_bytes(pEq);
252198 f = 0;
252199 }else{
252200 if( pGe ){
252201 zTerm = (const char *)sqlite3_value_text(pGe);
252202 nTerm = sqlite3_value_bytes(pGe);
252203 }
252204
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -1,8 +1,8 @@
1 /******************************************************************************
2 ** This file is an amalgamation of many separate C source files from SQLite
3 ** version 3.45.0. By combining all the individual C code files into this
4 ** single large file, the entire code can be compiled as a single translation
5 ** unit. This allows many compilers to do optimizations that would not be
6 ** possible if the files were compiled separately. Performance improvements
7 ** of 5% or more are commonly seen when SQLite is compiled as a single
8 ** translation unit.
@@ -16,11 +16,11 @@
16 ** if you want a wrapper to interface SQLite with your choice of programming
17 ** language. The code for the "sqlite3" command-line shell is also in a
18 ** separate file. This file contains only code for the core SQLite library.
19 **
20 ** The content in this amalgamation comes from Fossil check-in
21 ** 27d4a89a5ff96b7b7fc5dc9650e1269f7c7e.
22 */
23 #define SQLITE_CORE 1
24 #define SQLITE_AMALGAMATION 1
25 #ifndef SQLITE_PRIVATE
26 # define SQLITE_PRIVATE static
@@ -457,13 +457,13 @@
457 **
458 ** See also: [sqlite3_libversion()],
459 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
460 ** [sqlite_version()] and [sqlite_source_id()].
461 */
462 #define SQLITE_VERSION "3.45.0"
463 #define SQLITE_VERSION_NUMBER 3045000
464 #define SQLITE_SOURCE_ID "2023-12-14 16:34:47 27d4a89a5ff96b7b7fc5dc9650e1269f7c7edf91de9b9aafce40be9ecc8b95e9"
465
466 /*
467 ** CAPI3REF: Run-Time Library Version Numbers
468 ** KEYWORDS: sqlite3_version sqlite3_sourceid
469 **
@@ -4265,19 +4265,21 @@
4265 ** <li> sqlite3_errmsg16()
4266 ** <li> sqlite3_error_offset()
4267 ** </ul>
4268 **
4269 ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
4270 ** text that describes the error, as either UTF-8 or UTF-16 respectively,
4271 ** or NULL if no error message is available.
4272 ** (See how SQLite handles [invalid UTF] for exceptions to this rule.)
4273 ** ^(Memory to hold the error message string is managed internally.
4274 ** The application does not need to worry about freeing the result.
4275 ** However, the error string might be overwritten or deallocated by
4276 ** subsequent calls to other SQLite interface functions.)^
4277 **
4278 ** ^The sqlite3_errstr(E) interface returns the English-language text
4279 ** that describes the [result code] E, as UTF-8, or NULL if E is not an
4280 ** result code for which a text error message is available.
4281 ** ^(Memory to hold the error message string is managed internally
4282 ** and must not be freed by the application)^.
4283 **
4284 ** ^If the most recent error references a specific token in the input
4285 ** SQL, the sqlite3_error_offset() interface returns the byte offset
@@ -8609,10 +8611,11 @@
8611 #define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10
8612 #define SQLITE_TESTCTRL_PENDING_BYTE 11
8613 #define SQLITE_TESTCTRL_ASSERT 12
8614 #define SQLITE_TESTCTRL_ALWAYS 13
8615 #define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */
8616 #define SQLITE_TESTCTRL_JSON_SELFCHECK 14
8617 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15
8618 #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
8619 #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
8620 #define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17
8621 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
@@ -13295,13 +13298,38 @@
13298 ** significantly more efficient than those alternatives when used with
13299 ** "detail=column" tables.
13300 **
13301 ** xPhraseNextColumn()
13302 ** See xPhraseFirstColumn above.
13303 **
13304 ** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken)
13305 ** This is used to access token iToken of phrase iPhrase of the current
13306 ** query. Before returning, output parameter *ppToken is set to point
13307 ** to a buffer containing the requested token, and *pnToken to the
13308 ** size of this buffer in bytes.
13309 **
13310 ** The output text is not a copy of the query text that specified the
13311 ** token. It is the output of the tokenizer module. For tokendata=1
13312 ** tables, this includes any embedded 0x00 and trailing data.
13313 **
13314 ** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken)
13315 ** This is used to access token iToken of phrase hit iIdx within the
13316 ** current row. Output variable (*ppToken) is set to point to a buffer
13317 ** containing the matching document token, and (*pnToken) to the size
13318 ** of that buffer in bytes. This API is not available if the specified
13319 ** token matches a prefix query term. In that case both output variables
13320 ** are always set to 0.
13321 **
13322 ** The output text is not a copy of the document text that was tokenized.
13323 ** It is the output of the tokenizer module. For tokendata=1 tables, this
13324 ** includes any embedded 0x00 and trailing data.
13325 **
13326 ** This API can be quite slow if used with an FTS5 table created with the
13327 ** "detail=none" or "detail=column" option.
13328 */
13329 struct Fts5ExtensionApi {
13330 int iVersion; /* Currently always set to 3 */
13331
13332 void *(*xUserData)(Fts5Context*);
13333
13334 int (*xColumnCount)(Fts5Context*);
13335 int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
@@ -13332,10 +13360,17 @@
13360 int (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*);
13361 void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff);
13362
13363 int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*);
13364 void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol);
13365
13366 /* Below this point are iVersion>=3 only */
13367 int (*xQueryToken)(Fts5Context*,
13368 int iPhrase, int iToken,
13369 const char **ppToken, int *pnToken
13370 );
13371 int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*);
13372 };
13373
13374 /*
13375 ** CUSTOM AUXILIARY FUNCTIONS
13376 *************************************************************************/
@@ -16426,10 +16461,11 @@
16461 #define P4_VTAB (-11) /* P4 is a pointer to an sqlite3_vtab structure */
16462 #define P4_REAL (-12) /* P4 is a 64-bit floating point value */
16463 #define P4_INT64 (-13) /* P4 is a 64-bit signed integer */
16464 #define P4_INTARRAY (-14) /* P4 is a vector of 32-bit integers */
16465 #define P4_FUNCCTX (-15) /* P4 is a pointer to an sqlite3_context object */
16466 #define P4_TABLEREF (-16) /* Like P4_TABLE, but reference counted */
16467
16468 /* Error message codes for OP_Halt */
16469 #define P5_ConstraintNotNull 1
16470 #define P5_ConstraintUnique 2
16471 #define P5_ConstraintCheck 3
@@ -16648,17 +16684,19 @@
16684 #define OP_VColumn 176 /* synopsis: r[P3]=vcolumn(P2) */
16685 #define OP_VRename 177
16686 #define OP_Pagecount 178
16687 #define OP_MaxPgcnt 179
16688 #define OP_ClrSubtype 180 /* synopsis: r[P1].subtype = 0 */
16689 #define OP_GetSubtype 181 /* synopsis: r[P2] = r[P1].subtype */
16690 #define OP_SetSubtype 182 /* synopsis: r[P2].subtype = r[P1] */
16691 #define OP_FilterAdd 183 /* synopsis: filter(P1) += key(P3@P4) */
16692 #define OP_Trace 184
16693 #define OP_CursorHint 185
16694 #define OP_ReleaseReg 186 /* synopsis: release r[P1@P2] mask P3 */
16695 #define OP_Noop 187
16696 #define OP_Explain 188
16697 #define OP_Abortable 189
16698
16699 /* Properties such as "out2" or "jump" that are specified in
16700 ** comments following the "case" for each opcode in the vdbe.c
16701 ** are encoded into bitvectors as follows:
16702 */
@@ -16690,12 +16728,12 @@
16728 /* 136 */ 0x00, 0x40, 0x04, 0x04, 0x00, 0x40, 0x50, 0x40,\
16729 /* 144 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\
16730 /* 152 */ 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\
16731 /* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
16732 /* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x50,\
16733 /* 176 */ 0x40, 0x00, 0x10, 0x10, 0x02, 0x12, 0x12, 0x00,\
16734 /* 184 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}
16735
16736 /* The resolve3P2Values() routine is able to run faster if it knows
16737 ** the value of the largest JUMP opcode. The smaller the maximum
16738 ** JUMP opcode the better, so the mkopcodeh.tcl script that
16739 ** generated this include file strives to group all JUMP opcodes
@@ -17952,15 +17990,15 @@
17990 {nArg, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_DIRECTONLY|SQLITE_FUNC_UNSAFE, \
17991 SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
17992 #define MFUNCTION(zName, nArg, xPtr, xFunc) \
17993 {nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \
17994 xPtr, 0, xFunc, 0, 0, 0, #zName, {0} }
17995 #define JFUNCTION(zName, nArg, bUseCache, bWS, bRS, bJsonB, iArg, xFunc) \
17996 {nArg, SQLITE_FUNC_BUILTIN|SQLITE_DETERMINISTIC|SQLITE_FUNC_CONSTANT|\
17997 SQLITE_UTF8|((bUseCache)*SQLITE_FUNC_RUNONLY)|\
17998 ((bRS)*SQLITE_SUBTYPE)|((bWS)*SQLITE_RESULT_SUBTYPE), \
17999 SQLITE_INT_TO_PTR(iArg|((bJsonB)*JSON_BLOB)),0,xFunc,0, 0, 0, #zName, {0} }
18000 #define INLINE_FUNC(zName, nArg, iArg, mFlags) \
18001 {nArg, SQLITE_FUNC_BUILTIN|\
18002 SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \
18003 SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} }
18004 #define TEST_FUNC(zName, nArg, iArg, mFlags) \
@@ -18704,10 +18742,11 @@
18742 int iDistinct; /* Ephemeral table used to enforce DISTINCT */
18743 int iDistAddr; /* Address of OP_OpenEphemeral */
18744 int iOBTab; /* Ephemeral table to implement ORDER BY */
18745 u8 bOBPayload; /* iOBTab has payload columns separate from key */
18746 u8 bOBUnique; /* Enforce uniqueness on iOBTab keys */
18747 u8 bUseSubtype; /* Transfer subtype info through sorter */
18748 } *aFunc;
18749 int nFunc; /* Number of entries in aFunc[] */
18750 u32 selId; /* Select to which this AggInfo belongs */
18751 #ifdef SQLITE_DEBUG
18752 Select *pSelect; /* SELECT statement that this AggInfo supports */
@@ -19237,10 +19276,11 @@
19276 } uNC;
19277 NameContext *pNext; /* Next outer name context. NULL for outermost */
19278 int nRef; /* Number of names resolved by this context */
19279 int nNcErr; /* Number of errors encountered while resolving names */
19280 int ncFlags; /* Zero or more NC_* flags defined below */
19281 u32 nNestedSelect; /* Number of nested selects using this NC */
19282 Select *pWinSelect; /* SELECT statement for any window functions */
19283 };
19284
19285 /*
19286 ** Allowed values for the NameContext, ncFlags field.
@@ -19953,10 +19993,13 @@
19993 ** 2. Use sqlite3RCStrUnref() to free an RCStr string rather than
19994 ** sqlite3_free()
19995 **
19996 ** 3. Make a (read-only) copy of a read-only RCStr string using
19997 ** sqlite3RCStrRef().
19998 **
19999 ** "String" is in the name, but an RCStr object can also be used to hold
20000 ** binary data.
20001 */
20002 struct RCStr {
20003 u64 nRCRef; /* Number of references */
20004 /* Total structure size should be a multiple of 8 bytes for alignment */
20005 };
@@ -20011,10 +20054,13 @@
20054 u8 bOpenUri; /* True to interpret filenames as URIs */
20055 u8 bUseCis; /* Use covering indices for full-scans */
20056 u8 bSmallMalloc; /* Avoid large memory allocations if true */
20057 u8 bExtraSchemaChecks; /* Verify type,name,tbl_name in schema */
20058 u8 bUseLongDouble; /* Make use of long double */
20059 #ifdef SQLITE_DEBUG
20060 u8 bJsonSelfcheck; /* Double-check JSON parsing */
20061 #endif
20062 int mxStrlen; /* Maximum string length */
20063 int neverCorrupt; /* Database is always well-formed */
20064 int szLookaside; /* Default lookaside buffer size */
20065 int nLookaside; /* Default lookaside buffer count */
20066 int nStmtSpill; /* Stmt-journal spill-to-disk threshold */
@@ -20637,19 +20683,21 @@
20683 SQLITE_PRIVATE void sqlite3ExprAddFunctionOrderBy(Parse*,Expr*,ExprList*);
20684 SQLITE_PRIVATE void sqlite3ExprOrderByAggregateError(Parse*,Expr*);
20685 SQLITE_PRIVATE void sqlite3ExprFunctionUsable(Parse*,const Expr*,const FuncDef*);
20686 SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
20687 SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
20688 SQLITE_PRIVATE void sqlite3ExprDeleteGeneric(sqlite3*,void*);
20689 SQLITE_PRIVATE void sqlite3ExprDeferredDelete(Parse*, Expr*);
20690 SQLITE_PRIVATE void sqlite3ExprUnmapAndDelete(Parse*, Expr*);
20691 SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
20692 SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
20693 SQLITE_PRIVATE Select *sqlite3ExprListToValues(Parse*, int, ExprList*);
20694 SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList*,int,int);
20695 SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,const Token*,int);
20696 SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*);
20697 SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*);
20698 SQLITE_PRIVATE void sqlite3ExprListDeleteGeneric(sqlite3*,void*);
20699 SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*);
20700 SQLITE_PRIVATE int sqlite3IndexHasDuplicateRootPage(Index*);
20701 SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**);
20702 SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**);
20703 SQLITE_PRIVATE int sqlite3InitOne(sqlite3*, int, char**, u32);
@@ -20736,10 +20784,11 @@
20784 SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask);
20785 #endif
20786 SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int);
20787 SQLITE_PRIVATE void sqlite3CodeDropTable(Parse*, Table*, int, int);
20788 SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*);
20789 SQLITE_PRIVATE void sqlite3DeleteTableGeneric(sqlite3*, void*);
20790 SQLITE_PRIVATE void sqlite3FreeIndex(sqlite3*, Index*);
20791 #ifndef SQLITE_OMIT_AUTOINCREMENT
20792 SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse);
20793 SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse);
20794 #else
@@ -20772,10 +20821,11 @@
20821 SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
20822 SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*);
20823 SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
20824 Expr*,ExprList*,u32,Expr*);
20825 SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*);
20826 SQLITE_PRIVATE void sqlite3SelectDeleteGeneric(sqlite3*,void*);
20827 SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*);
20828 SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, Trigger*);
20829 SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
20830 #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
20831 SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,char*);
@@ -20998,10 +21048,11 @@
21048 #ifndef SQLITE_OMIT_UTF16
21049 SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nChar);
21050 #endif
21051 SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte);
21052 SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**);
21053 SQLITE_PRIVATE int sqlite3Utf8ReadLimited(const u8*, int, u32*);
21054 SQLITE_PRIVATE LogEst sqlite3LogEst(u64);
21055 SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst,LogEst);
21056 SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double);
21057 SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst);
21058 SQLITE_PRIVATE VList *sqlite3VListAdd(sqlite3*,VList*,const char*,int,int);
@@ -21344,10 +21395,11 @@
21395 #ifndef SQLITE_OMIT_CTE
21396 SQLITE_PRIVATE Cte *sqlite3CteNew(Parse*,Token*,ExprList*,Select*,u8);
21397 SQLITE_PRIVATE void sqlite3CteDelete(sqlite3*,Cte*);
21398 SQLITE_PRIVATE With *sqlite3WithAdd(Parse*,With*,Cte*);
21399 SQLITE_PRIVATE void sqlite3WithDelete(sqlite3*,With*);
21400 SQLITE_PRIVATE void sqlite3WithDeleteGeneric(sqlite3*,void*);
21401 SQLITE_PRIVATE With *sqlite3WithPush(Parse*, With*, u8);
21402 #else
21403 # define sqlite3CteNew(P,T,E,S) ((void*)0)
21404 # define sqlite3CteDelete(D,C)
21405 # define sqlite3CteWithAdd(P,W,C) ((void*)0)
@@ -22721,10 +22773,13 @@
22773 SQLITE_USE_URI, /* bOpenUri */
22774 SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */
22775 0, /* bSmallMalloc */
22776 1, /* bExtraSchemaChecks */
22777 sizeof(LONGDOUBLE_TYPE)>8, /* bUseLongDouble */
22778 #ifdef SQLITE_DEBUG
22779 0, /* bJsonSelfcheck */
22780 #endif
22781 0x7ffffffe, /* mxStrlen */
22782 0, /* neverCorrupt */
22783 SQLITE_DEFAULT_LOOKASIDE, /* szLookaside, nLookaside */
22784 SQLITE_STMTJRNL_SPILL, /* nStmtSpill */
22785 {0,0,0,0,0,0,0,0}, /* m */
@@ -25055,10 +25110,16 @@
25110 n = sqlite3_value_bytes(argv[i]);
25111 if( z==0 || parseModifier(context, (char*)z, n, p, i) ) return 1;
25112 }
25113 computeJD(p);
25114 if( p->isError || !validJulianDay(p->iJD) ) return 1;
25115 if( argc==1 && p->validYMD && p->D>28 ){
25116 /* Make sure a YYYY-MM-DD is normalized.
25117 ** Example: 2023-02-31 -> 2023-03-03 */
25118 assert( p->validJD );
25119 p->validYMD = 0;
25120 }
25121 return 0;
25122 }
25123
25124
25125 /*
@@ -32083,11 +32144,11 @@
32144 va_end(ap);
32145 }
32146
32147
32148 /*****************************************************************************
32149 ** Reference counted string/blob storage
32150 *****************************************************************************/
32151
32152 /*
32153 ** Increase the reference count of the string by one.
32154 **
@@ -32935,11 +32996,11 @@
32996 pX = pExpr->pLeft;
32997 assert( ExprUseXList(pExpr) );
32998 assert( pExpr->x.pList->nExpr==2 );
32999 pY = pExpr->x.pList->a[0].pExpr;
33000 pZ = pExpr->x.pList->a[1].pExpr;
33001 sqlite3TreeViewLine(pView, "BETWEEN%s", zFlgs);
33002 sqlite3TreeViewExpr(pView, pX, 1);
33003 sqlite3TreeViewExpr(pView, pY, 1);
33004 sqlite3TreeViewExpr(pView, pZ, 0);
33005 break;
33006 }
@@ -34070,11 +34131,42 @@
34131 || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; }
34132 }
34133 return c;
34134 }
34135
34136 /*
34137 ** Read a single UTF8 character out of buffer z[], but reading no
34138 ** more than n characters from the buffer. z[] is not zero-terminated.
34139 **
34140 ** Return the number of bytes used to construct the character.
34141 **
34142 ** Invalid UTF8 might generate a strange result. No effort is made
34143 ** to detect invalid UTF8.
34144 **
34145 ** At most 4 bytes will be read out of z[]. The return value will always
34146 ** be between 1 and 4.
34147 */
34148 SQLITE_PRIVATE int sqlite3Utf8ReadLimited(
34149 const u8 *z,
34150 int n,
34151 u32 *piOut
34152 ){
34153 u32 c;
34154 int i = 1;
34155 assert( n>0 );
34156 c = z[0];
34157 if( c>=0xc0 ){
34158 c = sqlite3Utf8Trans1[c-0xc0];
34159 if( n>4 ) n = 4;
34160 while( i<n && (z[i] & 0xc0)==0x80 ){
34161 c = (c<<6) + (0x3f & z[i]);
34162 i++;
34163 }
34164 }
34165 *piOut = c;
34166 return i;
34167 }
34168
34169
34170 /*
34171 ** If the TRANSLATE_TRACE macro is defined, the value of each Mem is
34172 ** printed on stderr on the way into and out of sqlite3VdbeMemTranslate().
@@ -36839,17 +36931,19 @@
36931 /* 176 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
36932 /* 177 */ "VRename" OpHelp(""),
36933 /* 178 */ "Pagecount" OpHelp(""),
36934 /* 179 */ "MaxPgcnt" OpHelp(""),
36935 /* 180 */ "ClrSubtype" OpHelp("r[P1].subtype = 0"),
36936 /* 181 */ "GetSubtype" OpHelp("r[P2] = r[P1].subtype"),
36937 /* 182 */ "SetSubtype" OpHelp("r[P2].subtype = r[P1]"),
36938 /* 183 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"),
36939 /* 184 */ "Trace" OpHelp(""),
36940 /* 185 */ "CursorHint" OpHelp(""),
36941 /* 186 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"),
36942 /* 187 */ "Noop" OpHelp(""),
36943 /* 188 */ "Explain" OpHelp(""),
36944 /* 189 */ "Abortable" OpHelp(""),
36945 };
36946 return azName[i];
36947 }
36948 #endif
36949
@@ -41891,11 +41985,17 @@
41985 return SQLITE_OK;
41986 }
41987 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
41988 case SQLITE_FCNTL_LOCK_TIMEOUT: {
41989 int iOld = pFile->iBusyTimeout;
41990 #if SQLITE_ENABLE_SETLK_TIMEOUT==1
41991 pFile->iBusyTimeout = *(int*)pArg;
41992 #elif SQLITE_ENABLE_SETLK_TIMEOUT==2
41993 pFile->iBusyTimeout = !!(*(int*)pArg);
41994 #else
41995 # error "SQLITE_ENABLE_SETLK_TIMEOUT must be set to 1 or 2"
41996 #endif
41997 *(int*)pArg = iOld;
41998 return SQLITE_OK;
41999 }
42000 #endif
42001 #if SQLITE_MAX_MMAP_SIZE>0
@@ -42144,10 +42244,29 @@
42244 ** zFilename
42245 **
42246 ** Either unixShmNode.pShmMutex must be held or unixShmNode.nRef==0 and
42247 ** unixMutexHeld() is true when reading or writing any other field
42248 ** in this structure.
42249 **
42250 ** aLock[SQLITE_SHM_NLOCK]:
42251 ** This array records the various locks held by clients on each of the
42252 ** SQLITE_SHM_NLOCK slots. If the aLock[] entry is set to 0, then no
42253 ** locks are held by the process on this slot. If it is set to -1, then
42254 ** some client holds an EXCLUSIVE lock on the locking slot. If the aLock[]
42255 ** value is set to a positive value, then it is the number of shared
42256 ** locks currently held on the slot.
42257 **
42258 ** aMutex[SQLITE_SHM_NLOCK]:
42259 ** Normally, when SQLITE_ENABLE_SETLK_TIMEOUT is not defined, mutex
42260 ** pShmMutex is used to protect the aLock[] array and the right to
42261 ** call fcntl() on unixShmNode.hShm to obtain or release locks.
42262 **
42263 ** If SQLITE_ENABLE_SETLK_TIMEOUT is defined though, we use an array
42264 ** of mutexes - one for each locking slot. To read or write locking
42265 ** slot aLock[iSlot], the caller must hold the corresponding mutex
42266 ** aMutex[iSlot]. Similarly, to call fcntl() to obtain or release a
42267 ** lock corresponding to slot iSlot, mutex aMutex[iSlot] must be held.
42268 */
42269 struct unixShmNode {
42270 unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */
42271 sqlite3_mutex *pShmMutex; /* Mutex to access this object */
42272 char *zFilename; /* Name of the mmapped file */
@@ -42157,14 +42276,15 @@
42276 u8 isReadonly; /* True if read-only */
42277 u8 isUnlocked; /* True if no DMS lock held */
42278 char **apRegion; /* Array of mapped shared-memory regions */
42279 int nRef; /* Number of unixShm objects pointing to this */
42280 unixShm *pFirst; /* All unixShm objects pointing to this */
42281 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
42282 sqlite3_mutex *aMutex[SQLITE_SHM_NLOCK];
42283 #endif
42284 int aLock[SQLITE_SHM_NLOCK]; /* # shared locks on slot, -1==excl lock */
42285 #ifdef SQLITE_DEBUG
 
 
42286 u8 nextShmId; /* Next available unixShm.id value */
42287 #endif
42288 };
42289
42290 /*
@@ -42243,20 +42363,33 @@
42363 ){
42364 unixShmNode *pShmNode; /* Apply locks to this open shared-memory segment */
42365 struct flock f; /* The posix advisory locking structure */
42366 int rc = SQLITE_OK; /* Result code form fcntl() */
42367
 
42368 pShmNode = pFile->pInode->pShmNode;
42369
42370 /* Assert that the correct mutex or mutexes are held. */
42371 if( pShmNode->nRef==0 ){
42372 assert( ofst==UNIX_SHM_DMS && n==1 && unixMutexHeld() );
42373 }else{
42374 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
42375 int ii;
42376 for(ii=ofst-UNIX_SHM_BASE; ii<ofst-UNIX_SHM_BASE+n; ii++){
42377 assert( sqlite3_mutex_held(pShmNode->aMutex[ii]) );
42378 }
42379 #else
42380 assert( sqlite3_mutex_held(pShmNode->pShmMutex) );
42381 assert( pShmNode->nRef>0 );
42382 #endif
42383 }
42384
42385 /* Shared locks never span more than one byte */
42386 assert( n==1 || lockType!=F_RDLCK );
42387
42388 /* Locks are within range */
42389 assert( n>=1 && n<=SQLITE_SHM_NLOCK );
42390 assert( ofst>=UNIX_SHM_BASE && ofst<=(UNIX_SHM_DMS+SQLITE_SHM_NLOCK) );
42391
42392 if( pShmNode->hShm>=0 ){
42393 int res;
42394 /* Initialize the locking parameters */
42395 f.l_type = lockType;
@@ -42263,50 +42396,39 @@
42396 f.l_whence = SEEK_SET;
42397 f.l_start = ofst;
42398 f.l_len = n;
42399 res = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile);
42400 if( res==-1 ){
42401 #if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && SQLITE_ENABLE_SETLK_TIMEOUT==1
42402 rc = (pFile->iBusyTimeout ? SQLITE_BUSY_TIMEOUT : SQLITE_BUSY);
42403 #else
42404 rc = SQLITE_BUSY;
42405 #endif
42406 }
42407 }
42408
42409 /* Do debug tracing */
42410 #ifdef SQLITE_DEBUG
42411 OSTRACE(("SHM-LOCK "));
42412 if( rc==SQLITE_OK ){
42413 if( lockType==F_UNLCK ){
42414 OSTRACE(("unlock %d..%d ok\n", ofst, ofst+n-1));
42415 }else if( lockType==F_RDLCK ){
42416 OSTRACE(("read-lock %d..%d ok\n", ofst, ofst+n-1));
42417 }else{
42418 assert( lockType==F_WRLCK );
42419 OSTRACE(("write-lock %d..%d ok\n", ofst, ofst+n-1));
42420 }
42421 }else{
42422 if( lockType==F_UNLCK ){
42423 OSTRACE(("unlock %d..%d failed\n", ofst, ofst+n-1));
42424 }else if( lockType==F_RDLCK ){
42425 OSTRACE(("read-lock %d..%d failed\n", ofst, ofst+n-1));
42426 }else{
42427 assert( lockType==F_WRLCK );
42428 OSTRACE(("write-lock %d..%d failed\n", ofst, ofst+n-1));
42429 }
 
 
 
 
 
 
 
 
 
 
 
42430 }
42431 #endif
42432
42433 return rc;
42434 }
@@ -42340,10 +42462,15 @@
42462 if( p && ALWAYS(p->nRef==0) ){
42463 int nShmPerMap = unixShmRegionPerMap();
42464 int i;
42465 assert( p->pInode==pFd->pInode );
42466 sqlite3_mutex_free(p->pShmMutex);
42467 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
42468 for(i=0; i<SQLITE_SHM_NLOCK; i++){
42469 sqlite3_mutex_free(p->aMutex[i]);
42470 }
42471 #endif
42472 for(i=0; i<p->nRegion; i+=nShmPerMap){
42473 if( p->hShm>=0 ){
42474 osMunmap(p->apRegion[i], p->szRegion);
42475 }else{
42476 sqlite3_free(p->apRegion[i]);
@@ -42399,11 +42526,24 @@
42526 }else if( lock.l_type==F_UNLCK ){
42527 if( pShmNode->isReadonly ){
42528 pShmNode->isUnlocked = 1;
42529 rc = SQLITE_READONLY_CANTINIT;
42530 }else{
42531 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
42532 /* Do not use a blocking lock here. If the lock cannot be obtained
42533 ** immediately, it means some other connection is truncating the
42534 ** *-shm file. And after it has done so, it will not release its
42535 ** lock, but only downgrade it to a shared lock. So no point in
42536 ** blocking here. The call below to obtain the shared DMS lock may
42537 ** use a blocking lock. */
42538 int iSaveTimeout = pDbFd->iBusyTimeout;
42539 pDbFd->iBusyTimeout = 0;
42540 #endif
42541 rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1);
42542 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
42543 pDbFd->iBusyTimeout = iSaveTimeout;
42544 #endif
42545 /* The first connection to attach must truncate the -shm file. We
42546 ** truncate to 3 bytes (an arbitrary small number, less than the
42547 ** -shm header size) rather than 0 as a system debugging aid, to
42548 ** help detect if a -shm file truncation is legitimate or is the work
42549 ** or a rogue process. */
@@ -42520,10 +42660,22 @@
42660 pShmNode->pShmMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
42661 if( pShmNode->pShmMutex==0 ){
42662 rc = SQLITE_NOMEM_BKPT;
42663 goto shm_open_err;
42664 }
42665 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
42666 {
42667 int ii;
42668 for(ii=0; ii<SQLITE_SHM_NLOCK; ii++){
42669 pShmNode->aMutex[ii] = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
42670 if( pShmNode->aMutex[ii]==0 ){
42671 rc = SQLITE_NOMEM_BKPT;
42672 goto shm_open_err;
42673 }
42674 }
42675 }
42676 #endif
42677 }
42678
42679 if( pInode->bProcessLock==0 ){
42680 if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
42681 pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT|O_NOFOLLOW,
@@ -42741,13 +42893,15 @@
42893 **
42894 ** assert( assertLockingArrayOk(pShmNode) );
42895 */
42896 #ifdef SQLITE_DEBUG
42897 static int assertLockingArrayOk(unixShmNode *pShmNode){
42898 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
42899 return 1;
42900 #else
42901 unixShm *pX;
42902 int aLock[SQLITE_SHM_NLOCK];
 
42903
42904 memset(aLock, 0, sizeof(aLock));
42905 for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
42906 int i;
42907 for(i=0; i<SQLITE_SHM_NLOCK; i++){
@@ -42761,17 +42915,18 @@
42915 }
42916 }
42917
42918 assert( 0==memcmp(pShmNode->aLock, aLock, sizeof(aLock)) );
42919 return (memcmp(pShmNode->aLock, aLock, sizeof(aLock))==0);
42920 #endif
42921 }
42922 #endif
42923
42924 /*
42925 ** Change the lock state for a shared-memory segment.
42926 **
42927 ** Note that the relationship between SHARED and EXCLUSIVE locks is a little
42928 ** different here than in posix. In xShmLock(), one can go from unlocked
42929 ** to shared and back or from unlocked to exclusive and back. But one may
42930 ** not go from shared to exclusive or from exclusive to shared.
42931 */
42932 static int unixShmLock(
@@ -42782,11 +42937,11 @@
42937 ){
42938 unixFile *pDbFd = (unixFile*)fd; /* Connection holding shared memory */
42939 unixShm *p; /* The shared memory being locked */
42940 unixShmNode *pShmNode; /* The underlying file iNode */
42941 int rc = SQLITE_OK; /* Result code */
42942 u16 mask = (1<<(ofst+n)) - (1<<ofst); /* Mask of locks to take or release */
42943 int *aLock;
42944
42945 p = pDbFd->pShm;
42946 if( p==0 ) return SQLITE_IOERR_SHMLOCK;
42947 pShmNode = p->pShmNode;
@@ -42817,92 +42972,154 @@
42972 ** held.
42973 **
42974 ** It is not permitted to block on the RECOVER lock.
42975 */
42976 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
42977 {
42978 u16 lockMask = (p->exclMask|p->sharedMask);
42979 assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || (
42980 (ofst!=2) /* not RECOVER */
42981 && (ofst!=1 || lockMask==0 || lockMask==2)
42982 && (ofst!=0 || lockMask<3)
42983 && (ofst<3 || lockMask<(1<<ofst))
42984 ));
42985 }
42986 #endif
42987
42988 /* Check if there is any work to do. There are three cases:
42989 **
42990 ** a) An unlock operation where there are locks to unlock,
42991 ** b) An shared lock where the requested lock is not already held
42992 ** c) An exclusive lock where the requested lock is not already held
42993 **
42994 ** The SQLite core never requests an exclusive lock that it already holds.
42995 ** This is assert()ed below.
42996 */
42997 assert( flags!=(SQLITE_SHM_EXCLUSIVE|SQLITE_SHM_LOCK)
42998 || 0==(p->exclMask & mask)
42999 );
43000 if( ((flags & SQLITE_SHM_UNLOCK) && ((p->exclMask|p->sharedMask) & mask))
43001 || (flags==(SQLITE_SHM_SHARED|SQLITE_SHM_LOCK) && 0==(p->sharedMask & mask))
43002 || (flags==(SQLITE_SHM_EXCLUSIVE|SQLITE_SHM_LOCK))
43003 ){
43004
43005 /* Take the required mutexes. In SETLK_TIMEOUT mode (blocking locks), if
43006 ** this is an attempt on an exclusive lock use sqlite3_mutex_try(). If any
43007 ** other thread is holding this mutex, then it is either holding or about
43008 ** to hold a lock exclusive to the one being requested, and we may
43009 ** therefore return SQLITE_BUSY to the caller.
43010 **
43011 ** Doing this prevents some deadlock scenarios. For example, thread 1 may
43012 ** be a checkpointer blocked waiting on the WRITER lock. And thread 2
43013 ** may be a normal SQL client upgrading to a write transaction. In this
43014 ** case thread 2 does a non-blocking request for the WRITER lock. But -
43015 ** if it were to use sqlite3_mutex_enter() then it would effectively
43016 ** become a (doomed) blocking request, as thread 2 would block until thread
43017 ** 1 obtained WRITER and released the mutex. Since thread 2 already holds
43018 ** a lock on a read-locking slot at this point, this breaks the
43019 ** anti-deadlock rules (see above). */
43020 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
43021 int iMutex;
43022 for(iMutex=ofst; iMutex<ofst+n; iMutex++){
43023 if( flags==(SQLITE_SHM_LOCK|SQLITE_SHM_EXCLUSIVE) ){
43024 rc = sqlite3_mutex_try(pShmNode->aMutex[iMutex]);
43025 if( rc!=SQLITE_OK ) break;
43026 }else{
43027 sqlite3_mutex_enter(pShmNode->aMutex[iMutex]);
43028 }
43029 }
43030 #else
43031 sqlite3_mutex_enter(pShmNode->pShmMutex);
43032 #endif
43033
43034 if( rc==SQLITE_OK ){
43035 if( flags & SQLITE_SHM_UNLOCK ){
43036 /* Case (a) - unlock. */
43037 int bUnlock = 1;
43038 assert( (p->exclMask & p->sharedMask)==0 );
43039 assert( !(flags & SQLITE_SHM_EXCLUSIVE) || (p->exclMask & mask)==mask );
43040 assert( !(flags & SQLITE_SHM_SHARED) || (p->sharedMask & mask)==mask );
43041
43042 /* If this is a SHARED lock being unlocked, it is possible that other
43043 ** clients within this process are holding the same SHARED lock. In
43044 ** this case, set bUnlock to 0 so that the posix lock is not removed
43045 ** from the file-descriptor below. */
43046 if( flags & SQLITE_SHM_SHARED ){
43047 assert( n==1 );
43048 assert( aLock[ofst]>=1 );
43049 if( aLock[ofst]>1 ){
43050 bUnlock = 0;
43051 aLock[ofst]--;
43052 p->sharedMask &= ~mask;
43053 }
43054 }
43055
43056 if( bUnlock ){
43057 rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n);
43058 if( rc==SQLITE_OK ){
43059 memset(&aLock[ofst], 0, sizeof(int)*n);
43060 p->sharedMask &= ~mask;
43061 p->exclMask &= ~mask;
43062 }
43063 }
43064 }else if( flags & SQLITE_SHM_SHARED ){
43065 /* Case (b) - a shared lock. */
43066
43067 if( aLock[ofst]<0 ){
43068 /* An exclusive lock is held by some other connection. BUSY. */
43069 rc = SQLITE_BUSY;
43070 }else if( aLock[ofst]==0 ){
43071 rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n);
43072 }
43073
43074 /* Get the local shared locks */
43075 if( rc==SQLITE_OK ){
43076 p->sharedMask |= mask;
43077 aLock[ofst]++;
43078 }
43079 }else{
43080 /* Case (c) - an exclusive lock. */
43081 int ii;
43082
43083 assert( flags==(SQLITE_SHM_LOCK|SQLITE_SHM_EXCLUSIVE) );
43084 assert( (p->sharedMask & mask)==0 );
43085 assert( (p->exclMask & mask)==0 );
43086
43087 /* Make sure no sibling connections hold locks that will block this
43088 ** lock. If any do, return SQLITE_BUSY right away. */
43089 for(ii=ofst; ii<ofst+n; ii++){
43090 if( aLock[ii] ){
43091 rc = SQLITE_BUSY;
43092 break;
43093 }
43094 }
43095
43096 /* Get the exclusive locks at the system level. Then if successful
43097 ** also update the in-memory values. */
43098 if( rc==SQLITE_OK ){
43099 rc = unixShmSystemLock(pDbFd, F_WRLCK, ofst+UNIX_SHM_BASE, n);
43100 if( rc==SQLITE_OK ){
43101 p->exclMask |= mask;
43102 for(ii=ofst; ii<ofst+n; ii++){
43103 aLock[ii] = -1;
43104 }
43105 }
43106 }
43107 }
43108 assert( assertLockingArrayOk(pShmNode) );
43109 }
43110
43111 /* Drop the mutexes acquired above. */
43112 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
43113 for(iMutex--; iMutex>=ofst; iMutex--){
43114 sqlite3_mutex_leave(pShmNode->aMutex[iMutex]);
43115 }
43116 #else
43117 sqlite3_mutex_leave(pShmNode->pShmMutex);
43118 #endif
43119 }
43120
43121 OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n",
43122 p->id, osGetpid(0), p->sharedMask, p->exclMask));
43123 return rc;
43124 }
43125
@@ -66236,10 +66453,23 @@
66453 *pp = p;
66454 return rc;
66455 }
66456
66457 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
66458
66459
66460 /*
66461 ** Attempt to enable blocking locks that block for nMs ms. Return 1 if
66462 ** blocking locks are successfully enabled, or 0 otherwise.
66463 */
66464 static int walEnableBlockingMs(Wal *pWal, int nMs){
66465 int rc = sqlite3OsFileControl(
66466 pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&nMs
66467 );
66468 return (rc==SQLITE_OK);
66469 }
66470
66471 /*
66472 ** Attempt to enable blocking locks. Blocking locks are enabled only if (a)
66473 ** they are supported by the VFS, and (b) the database handle is configured
66474 ** with a busy-timeout. Return 1 if blocking locks are successfully enabled,
66475 ** or 0 otherwise.
@@ -66247,15 +66477,11 @@
66477 static int walEnableBlocking(Wal *pWal){
66478 int res = 0;
66479 if( pWal->db ){
66480 int tmout = pWal->db->busyTimeout;
66481 if( tmout ){
66482 res = walEnableBlockingMs(pWal, tmout);
 
 
 
 
66483 }
66484 }
66485 return res;
66486 }
66487
@@ -66300,24 +66526,14 @@
66526 */
66527 SQLITE_PRIVATE void sqlite3WalDb(Wal *pWal, sqlite3 *db){
66528 pWal->db = db;
66529 }
66530
 
 
 
 
 
 
 
 
 
 
66531 #else
66532 # define walEnableBlocking(x) 0
66533 # define walDisableBlocking(x)
66534 # define walEnableBlockingMs(pWal, ms) 0
66535 # define sqlite3WalDb(pWal, db)
66536 #endif /* ifdef SQLITE_ENABLE_SETLK_TIMEOUT */
66537
66538
66539 /*
@@ -66914,19 +67130,22 @@
67130 walUnlockShared(pWal, WAL_WRITE_LOCK);
67131 rc = SQLITE_READONLY_RECOVERY;
67132 }
67133 }else{
67134 int bWriteLock = pWal->writeLock;
67135 if( bWriteLock
67136 || SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1))
67137 ){
67138 pWal->writeLock = 1;
67139 if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){
67140 badHdr = walIndexTryHdr(pWal, pChanged);
67141 if( badHdr ){
67142 /* If the wal-index header is still malformed even while holding
67143 ** a WRITE lock, it can only mean that the header is corrupted and
67144 ** needs to be reconstructed. So run recovery to do exactly that.
67145 ** Disable blocking locks first. */
67146 walDisableBlocking(pWal);
67147 rc = walIndexRecover(pWal);
67148 *pChanged = 1;
67149 }
67150 }
67151 if( bWriteLock==0 ){
@@ -67189,10 +67408,13 @@
67408 u32 mxReadMark; /* Largest aReadMark[] value */
67409 int mxI; /* Index of largest aReadMark[] value */
67410 int i; /* Loop counter */
67411 int rc = SQLITE_OK; /* Return code */
67412 u32 mxFrame; /* Wal frame to lock to */
67413 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
67414 int nBlockTmout = 0;
67415 #endif
67416
67417 assert( pWal->readLock<0 ); /* Not currently locked */
67418
67419 /* useWal may only be set for read/write connections */
67420 assert( (pWal->readOnly & WAL_SHM_RDONLY)==0 || useWal==0 );
@@ -67219,18 +67441,35 @@
67441 if( cnt>100 ){
67442 VVA_ONLY( pWal->lockError = 1; )
67443 return SQLITE_PROTOCOL;
67444 }
67445 if( cnt>=10 ) nDelay = (cnt-9)*(cnt-9)*39;
67446 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
67447 /* In SQLITE_ENABLE_SETLK_TIMEOUT builds, configure the file-descriptor
67448 ** to block for locks for approximately nDelay us. This affects three
67449 ** locks: (a) the shared lock taken on the DMS slot in os_unix.c (if
67450 ** using os_unix.c), (b) the WRITER lock taken in walIndexReadHdr() if the
67451 ** first attempted read fails, and (c) the shared lock taken on the DMS
67452 ** slot in os_unix.c. All three of these locks are attempted from within
67453 ** the call to walIndexReadHdr() below. */
67454 nBlockTmout = (nDelay+998) / 1000;
67455 if( !useWal && walEnableBlockingMs(pWal, nBlockTmout) ){
67456 nDelay = 1;
67457 }
67458 #endif
67459 sqlite3OsSleep(pWal->pVfs, nDelay);
67460 }
67461
67462 if( !useWal ){
67463 assert( rc==SQLITE_OK );
67464 if( pWal->bShmUnreliable==0 ){
67465 rc = walIndexReadHdr(pWal, pChanged);
67466 }
67467 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
67468 walDisableBlocking(pWal);
67469 if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY;
67470 #endif
67471 if( rc==SQLITE_BUSY ){
67472 /* If there is not a recovery running in another thread or process
67473 ** then convert BUSY errors to WAL_RETRY. If recovery is known to
67474 ** be running, convert BUSY to BUSY_RECOVERY. There is a race here
67475 ** which might cause WAL_RETRY to be returned even if BUSY_RECOVERY
@@ -67341,13 +67580,16 @@
67580 if( mxI==0 ){
67581 assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 );
67582 return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTINIT;
67583 }
67584
67585 (void)walEnableBlockingMs(pWal, nBlockTmout);
67586 rc = walLockShared(pWal, WAL_READ_LOCK(mxI));
67587 walDisableBlocking(pWal);
67588 if( rc ){
67589 assert( (rc&0xFF)!=SQLITE_BUSY||rc==SQLITE_BUSY||rc==SQLITE_BUSY_TIMEOUT );
67590 return (rc&0xFF)==SQLITE_BUSY ? WAL_RETRY : rc;
67591 }
67592 /* Now that the read-lock has been obtained, check that neither the
67593 ** value in the aReadMark[] array or the contents of the wal-index
67594 ** header have changed.
67595 **
@@ -68436,14 +68678,13 @@
68678 assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
68679
68680 if( pWal->readOnly ) return SQLITE_READONLY;
68681 WALTRACE(("WAL%p: checkpoint begins\n", pWal));
68682
68683 /* Enable blocking locks, if possible. */
 
68684 sqlite3WalDb(pWal, db);
68685 if( xBusy2 ) (void)walEnableBlocking(pWal);
68686
68687 /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive
68688 ** "checkpoint" lock on the database file.
68689 ** EVIDENCE-OF: R-10421-19736 If any other process is running a
68690 ** checkpoint operation at the same time, the lock cannot be obtained and
@@ -68480,13 +68721,18 @@
68721
68722
68723 /* Read the wal-index header. */
68724 SEH_TRY {
68725 if( rc==SQLITE_OK ){
68726 /* For a passive checkpoint, do not re-enable blocking locks after
68727 ** reading the wal-index header. A passive checkpoint should not block
68728 ** or invoke the busy handler. The only lock such a checkpoint may
68729 ** attempt to obtain is a lock on a read-slot, and it should give up
68730 ** immediately and do a partial checkpoint if it cannot obtain it. */
68731 walDisableBlocking(pWal);
68732 rc = walIndexReadHdr(pWal, &isChanged);
68733 if( eMode2!=SQLITE_CHECKPOINT_PASSIVE ) (void)walEnableBlocking(pWal);
68734 if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){
68735 sqlite3OsUnfetch(pWal->pDbFd, 0, 0);
68736 }
68737 }
68738
@@ -68819,11 +69065,11 @@
69065 ** 20 1 Bytes of unused space at the end of each page
69066 ** 21 1 Max embedded payload fraction (must be 64)
69067 ** 22 1 Min embedded payload fraction (must be 32)
69068 ** 23 1 Min leaf payload fraction (must be 32)
69069 ** 24 4 File change counter
69070 ** 28 4 The size of the database in pages
69071 ** 32 4 First freelist page
69072 ** 36 4 Number of freelist pages in the file
69073 ** 40 60 15 4-byte meta values passed to higher layers
69074 **
69075 ** 40 4 Schema cookie
@@ -85370,10 +85616,14 @@
85616 }
85617 case P4_VTAB : {
85618 if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4);
85619 break;
85620 }
85621 case P4_TABLEREF: {
85622 if( db->pnBytesFreed==0 ) sqlite3DeleteTable(db, (Table*)p4);
85623 break;
85624 }
85625 }
85626 }
85627
85628 /*
85629 ** Free the space allocated for aOp and any p4 values allocated for the
@@ -85497,11 +85747,11 @@
85747 Op *pOp,
85748 const char *zP4,
85749 int n
85750 ){
85751 if( pOp->p4type ){
85752 assert( pOp->p4type > P4_FREE_IF_LE );
85753 pOp->p4type = 0;
85754 pOp->p4.p = 0;
85755 }
85756 if( n<0 ){
85757 sqlite3VdbeChangeP4(p, (int)(pOp - p->aOp), zP4, n);
@@ -89620,11 +89870,19 @@
89870 SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
89871 int i;
89872 int rc = SQLITE_OK;
89873 Vdbe *p = (Vdbe*)pStmt;
89874 #if SQLITE_THREADSAFE
89875 sqlite3_mutex *mutex;
89876 #endif
89877 #ifdef SQLITE_ENABLE_API_ARMOR
89878 if( pStmt==0 ){
89879 return SQLITE_MISUSE_BKPT;
89880 }
89881 #endif
89882 #if SQLITE_THREADSAFE
89883 mutex = p->db->mutex;
89884 #endif
89885 sqlite3_mutex_enter(mutex);
89886 for(i=0; i<p->nVar; i++){
89887 sqlite3VdbeMemRelease(&p->aVar[i]);
89888 p->aVar[i].flags = MEM_Null;
@@ -90410,13 +90668,12 @@
90668 ** pointer to it.
90669 */
90670 SQLITE_API void *sqlite3_user_data(sqlite3_context *p){
90671 #ifdef SQLITE_ENABLE_API_ARMOR
90672 if( p==0 ) return 0;
90673 #endif
90674 assert( p && p->pFunc );
 
90675 return p->pFunc->pUserData;
90676 }
90677
90678 /*
90679 ** Extract the user data from a sqlite3_context structure and return a
@@ -94231,11 +94488,11 @@
94488 */
94489 case OP_AddImm: { /* in1 */
94490 pIn1 = &aMem[pOp->p1];
94491 memAboutToChange(p, pIn1);
94492 sqlite3VdbeMemIntegerify(pIn1);
94493 *(u64*)&pIn1->u.i += (u64)pOp->p2;
94494 break;
94495 }
94496
94497 /* Opcode: MustBeInt P1 P2 * * *
94498 **
@@ -100377,28 +100634,27 @@
100634 const sqlite3_module *pModule;
100635 char *zErr = 0;
100636
100637 pOut = &aMem[pOp->p2];
100638 sqlite3VdbeMemSetNull(pOut); /* Innocent until proven guilty */
100639 assert( pOp->p4type==P4_TABLEREF );
100640 pTab = pOp->p4.pTab;
100641 assert( pTab!=0 );
100642 assert( pTab->nTabRef>0 );
100643 assert( IsVirtual(pTab) );
100644 if( pTab->u.vtab.p==0 ) break;
100645 pVtab = pTab->u.vtab.p->pVtab;
100646 assert( pVtab!=0 );
100647 pModule = pVtab->pModule;
100648 assert( pModule!=0 );
100649 assert( pModule->iVersion>=4 );
100650 assert( pModule->xIntegrity!=0 );
 
100651 sqlite3VtabLock(pTab->u.vtab.p);
100652 assert( pOp->p1>=0 && pOp->p1<db->nDb );
100653 rc = pModule->xIntegrity(pVtab, db->aDb[pOp->p1].zDbSName, pTab->zName,
100654 pOp->p3, &zErr);
100655 sqlite3VtabUnlock(pTab->u.vtab.p);
 
100656 if( rc ){
100657 sqlite3_free(zErr);
100658 goto abort_due_to_error;
100659 }
100660 if( zErr ){
@@ -100519,10 +100775,11 @@
100775 case OP_VColumn: { /* ncycle */
100776 sqlite3_vtab *pVtab;
100777 const sqlite3_module *pModule;
100778 Mem *pDest;
100779 sqlite3_context sContext;
100780 FuncDef nullFunc;
100781
100782 VdbeCursor *pCur = p->apCsr[pOp->p1];
100783 assert( pCur!=0 );
100784 assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
100785 pDest = &aMem[pOp->p3];
@@ -100536,10 +100793,13 @@
100793 pModule = pVtab->pModule;
100794 assert( pModule->xColumn );
100795 memset(&sContext, 0, sizeof(sContext));
100796 sContext.pOut = pDest;
100797 sContext.enc = encoding;
100798 nullFunc.pUserData = 0;
100799 nullFunc.funcFlags = SQLITE_RESULT_SUBTYPE;
100800 sContext.pFunc = &nullFunc;
100801 assert( pOp->p5==OPFLAG_NOCHNG || pOp->p5==0 );
100802 if( pOp->p5 & OPFLAG_NOCHNG ){
100803 sqlite3VdbeMemSetNull(pDest);
100804 pDest->flags = MEM_Null|MEM_Zero;
100805 pDest->u.nZero = 0;
@@ -100867,10 +101127,46 @@
101127 case OP_ClrSubtype: { /* in1 */
101128 pIn1 = &aMem[pOp->p1];
101129 pIn1->flags &= ~MEM_Subtype;
101130 break;
101131 }
101132
101133 /* Opcode: GetSubtype P1 P2 * * *
101134 ** Synopsis: r[P2] = r[P1].subtype
101135 **
101136 ** Extract the subtype value from register P1 and write that subtype
101137 ** into register P2. If P1 has no subtype, then P1 gets a NULL.
101138 */
101139 case OP_GetSubtype: { /* in1 out2 */
101140 pIn1 = &aMem[pOp->p1];
101141 pOut = &aMem[pOp->p2];
101142 if( pIn1->flags & MEM_Subtype ){
101143 sqlite3VdbeMemSetInt64(pOut, pIn1->eSubtype);
101144 }else{
101145 sqlite3VdbeMemSetNull(pOut);
101146 }
101147 break;
101148 }
101149
101150 /* Opcode: SetSubtype P1 P2 * * *
101151 ** Synopsis: r[P2].subtype = r[P1]
101152 **
101153 ** Set the subtype value of register P2 to the integer from register P1.
101154 ** If P1 is NULL, clear the subtype from p2.
101155 */
101156 case OP_SetSubtype: { /* in1 out2 */
101157 pIn1 = &aMem[pOp->p1];
101158 pOut = &aMem[pOp->p2];
101159 if( pIn1->flags & MEM_Null ){
101160 pOut->flags &= ~MEM_Subtype;
101161 }else{
101162 assert( pIn1->flags & MEM_Int );
101163 pOut->flags |= MEM_Subtype;
101164 pOut->eSubtype = (u8)(pIn1->u.i & 0xff);
101165 }
101166 break;
101167 }
101168
101169 /* Opcode: FilterAdd P1 * P3 P4 *
101170 ** Synopsis: filter(P1) += key(P3@P4)
101171 **
101172 ** Compute a hash on the P4 registers starting with r[P3] and
@@ -105916,10 +106212,11 @@
106212
106213 n = pExpr->iColumn;
106214 assert( ExprUseYTab(pExpr) );
106215 pExTab = pExpr->y.pTab;
106216 assert( pExTab!=0 );
106217 assert( n < pExTab->nCol );
106218 if( (pExTab->tabFlags & TF_HasGenerated)!=0
106219 && (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0
106220 ){
106221 testcase( pExTab->nCol==BMS-1 );
106222 testcase( pExTab->nCol==BMS );
@@ -106518,11 +106815,11 @@
106815 ** (See ticket [b92e5e8ec2cdbaa1]).
106816 **
106817 ** If a generated column is referenced, set bits for every column
106818 ** of the table.
106819 */
106820 if( pExpr->iColumn>=0 && cnt==1 && pMatch!=0 ){
106821 pMatch->colUsed |= sqlite3ExprColUsed(pExpr);
106822 }
106823
106824 pExpr->op = eNewExprOp;
106825 lookupname_end:
@@ -106983,15 +107280,16 @@
107280 #endif
107281 pNC2 = pNC;
107282 while( pNC2
107283 && sqlite3ReferencesSrcList(pParse, pExpr, pNC2->pSrcList)==0
107284 ){
107285 pExpr->op2 += (1 + pNC2->nNestedSelect);
107286 pNC2 = pNC2->pNext;
107287 }
107288 assert( pDef!=0 || IN_RENAME_OBJECT );
107289 if( pNC2 && pDef ){
107290 pExpr->op2 += pNC2->nNestedSelect;
107291 assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg );
107292 assert( SQLITE_FUNC_ANYORDER==NC_OrderAgg );
107293 testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 );
107294 testcase( (pDef->funcFlags & SQLITE_FUNC_ANYORDER)!=0 );
107295 pNC2->ncFlags |= NC_HasAgg
@@ -107546,10 +107844,11 @@
107844 p->pOrderBy = 0;
107845 }
107846
107847 /* Recursively resolve names in all subqueries in the FROM clause
107848 */
107849 if( pOuterNC ) pOuterNC->nNestedSelect++;
107850 for(i=0; i<p->pSrc->nSrc; i++){
107851 SrcItem *pItem = &p->pSrc->a[i];
107852 if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){
107853 int nRef = pOuterNC ? pOuterNC->nRef : 0;
107854 const char *zSavedContext = pParse->zAuthContext;
@@ -107569,10 +107868,13 @@
107868 if( pOuterNC ){
107869 assert( pItem->fg.isCorrelated==0 && pOuterNC->nRef>=nRef );
107870 pItem->fg.isCorrelated = (pOuterNC->nRef>nRef);
107871 }
107872 }
107873 }
107874 if( pOuterNC && ALWAYS(pOuterNC->nNestedSelect>0) ){
107875 pOuterNC->nNestedSelect--;
107876 }
107877
107878 /* Set up the local name-context to pass to sqlite3ResolveExprNames() to
107879 ** resolve the result-set expression list.
107880 */
@@ -109157,13 +109459,11 @@
109459 assert( pExpr->op==TK_FUNCTION );
109460 assert( pExpr->pLeft==0 );
109461 assert( ExprUseXList(pExpr) );
109462 if( pExpr->x.pList==0 || NEVER(pExpr->x.pList->nExpr==0) ){
109463 /* Ignore ORDER BY on zero-argument aggregates */
109464 sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, pOrderBy);
 
 
109465 return;
109466 }
109467 if( IsWindowFunc(pExpr) ){
109468 sqlite3ExprOrderByAggregateError(pParse, pExpr);
109469 sqlite3ExprListDelete(db, pOrderBy);
@@ -109340,10 +109640,13 @@
109640 }
109641 }
109642 SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
109643 if( p ) sqlite3ExprDeleteNN(db, p);
109644 }
109645 SQLITE_PRIVATE void sqlite3ExprDeleteGeneric(sqlite3 *db, void *p){
109646 if( ALWAYS(p) ) sqlite3ExprDeleteNN(db, (Expr*)p);
109647 }
109648
109649 /*
109650 ** Clear both elements of an OnOrUsing object
109651 */
109652 SQLITE_PRIVATE void sqlite3ClearOnOrUsing(sqlite3 *db, OnOrUsing *p){
@@ -109365,13 +109668,11 @@
109668 **
109669 ** The deferred delete is (currently) implemented by adding the
109670 ** pExpr to the pParse->pConstExpr list with a register number of 0.
109671 */
109672 SQLITE_PRIVATE void sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){
109673 sqlite3ParserAddCleanup(pParse, sqlite3ExprDeleteGeneric, pExpr);
 
 
109674 }
109675
109676 /* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the
109677 ** expression.
109678 */
@@ -110172,10 +110473,13 @@
110473 }while( --i>0 );
110474 sqlite3DbNNFreeNN(db, pList);
110475 }
110476 SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
110477 if( pList ) exprListDeleteNN(db, pList);
110478 }
110479 SQLITE_PRIVATE void sqlite3ExprListDeleteGeneric(sqlite3 *db, void *pList){
110480 if( ALWAYS(pList) ) exprListDeleteNN(db, (ExprList*)pList);
110481 }
110482
110483 /*
110484 ** Return the bitwise-OR of all Expr.flags fields in the given
110485 ** ExprList.
@@ -114703,17 +115007,18 @@
115007 return WRC_Continue;
115008 }
115009 case TK_AGG_FUNCTION: {
115010 if( (pNC->ncFlags & NC_InAggFunc)==0
115011 && pWalker->walkerDepth==pExpr->op2
115012 && pExpr->pAggInfo==0
115013 ){
115014 /* Check to see if pExpr is a duplicate of another aggregate
115015 ** function that is already in the pAggInfo structure
115016 */
115017 struct AggInfo_func *pItem = pAggInfo->aFunc;
115018 for(i=0; i<pAggInfo->nFunc; i++, pItem++){
115019 if( NEVER(pItem->pFExpr==pExpr) ) break;
115020 if( sqlite3ExprCompare(0, pItem->pFExpr, pExpr, -1)==0 ){
115021 break;
115022 }
115023 }
115024 if( i>=pAggInfo->nFunc ){
@@ -114752,10 +115057,12 @@
115057 pItem->bOBPayload = 0;
115058 pItem->bOBUnique = ExprHasProperty(pExpr, EP_Distinct);
115059 }else{
115060 pItem->bOBPayload = 1;
115061 }
115062 pItem->bUseSubtype =
115063 (pItem->pFunc->funcFlags & SQLITE_SUBTYPE)!=0;
115064 }else{
115065 pItem->iOBTab = -1;
115066 }
115067 if( ExprHasProperty(pExpr, EP_Distinct) && !pItem->bOBUnique ){
115068 pItem->iDistinct = pParse->nTab++;
@@ -120856,11 +121163,11 @@
121163 ** the DEFAULT clause or the AS clause of a generated column.
121164 ** Return NULL if the column has no associated expression.
121165 */
121166 SQLITE_PRIVATE Expr *sqlite3ColumnExpr(Table *pTab, Column *pCol){
121167 if( pCol->iDflt==0 ) return 0;
121168 if( !IsOrdinaryTable(pTab) ) return 0;
121169 if( NEVER(pTab->u.tab.pDfltList==0) ) return 0;
121170 if( NEVER(pTab->u.tab.pDfltList->nExpr<pCol->iDflt) ) return 0;
121171 return pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr;
121172 }
121173
@@ -121008,10 +121315,13 @@
121315 /* Do not delete the table until the reference count reaches zero. */
121316 assert( db!=0 );
121317 if( !pTable ) return;
121318 if( db->pnBytesFreed==0 && (--pTable->nTabRef)>0 ) return;
121319 deleteTable(db, pTable);
121320 }
121321 SQLITE_PRIVATE void sqlite3DeleteTableGeneric(sqlite3 *db, void *pTable){
121322 sqlite3DeleteTable(db, (Table*)pTable);
121323 }
121324
121325
121326 /*
121327 ** Unlink the given table from the hash tables and the delete the
@@ -121546,11 +121856,12 @@
121856 #endif
121857
121858 /*
121859 ** Clean up the data structures associated with the RETURNING clause.
121860 */
121861 static void sqlite3DeleteReturning(sqlite3 *db, void *pArg){
121862 Returning *pRet = (Returning*)pArg;
121863 Hash *pHash;
121864 pHash = &(db->aDb[1].pSchema->trigHash);
121865 sqlite3HashInsert(pHash, pRet->zName, 0);
121866 sqlite3ExprListDelete(db, pRet->pReturnEL);
121867 sqlite3DbFree(db, pRet);
@@ -121588,12 +121899,11 @@
121899 return;
121900 }
121901 pParse->u1.pReturning = pRet;
121902 pRet->pParse = pParse;
121903 pRet->pReturnEL = pList;
121904 sqlite3ParserAddCleanup(pParse, sqlite3DeleteReturning, pRet);
 
121905 testcase( pParse->earlyCleanup );
121906 if( db->mallocFailed ) return;
121907 sqlite3_snprintf(sizeof(pRet->zName), pRet->zName,
121908 "sqlite_returning_%p", pParse);
121909 pRet->retTrig.zName = pRet->zName;
@@ -125827,10 +126137,13 @@
126137 for(i=0; i<pWith->nCte; i++){
126138 cteClear(db, &pWith->a[i]);
126139 }
126140 sqlite3DbFree(db, pWith);
126141 }
126142 }
126143 SQLITE_PRIVATE void sqlite3WithDeleteGeneric(sqlite3 *db, void *pWith){
126144 sqlite3WithDelete(db, (With*)pWith);
126145 }
126146 #endif /* !defined(SQLITE_OMIT_CTE) */
126147
126148 /************** End of build.c ***********************************************/
126149 /************** Begin file callback.c ****************************************/
@@ -139053,11 +139366,12 @@
139366 if( NEVER(pVTab==0) ) continue;
139367 if( NEVER(pVTab->pModule==0) ) continue;
139368 if( pVTab->pModule->iVersion<4 ) continue;
139369 if( pVTab->pModule->xIntegrity==0 ) continue;
139370 sqlite3VdbeAddOp3(v, OP_VCheck, i, 3, isQuick);
139371 pTab->nTabRef++;
139372 sqlite3VdbeAppendP4(v, pTab, P4_TABLEREF);
139373 a1 = sqlite3VdbeAddOp1(v, OP_IsNull, 3); VdbeCoverage(v);
139374 integrityCheckResultRow(v);
139375 sqlite3VdbeJumpHere(v, a1);
139376 #endif
139377 continue;
@@ -141080,10 +141394,11 @@
141394 sqlite3BtreeLeaveAll(db);
141395 rc = sqlite3ApiExit(db, rc);
141396 assert( (rc&db->errMask)==rc );
141397 db->busyHandler.nBusy = 0;
141398 sqlite3_mutex_leave(db->mutex);
141399 assert( rc==SQLITE_OK || (*ppStmt)==0 );
141400 return rc;
141401 }
141402
141403
141404 /*
@@ -141476,10 +141791,13 @@
141791 /*
141792 ** Delete the given Select structure and all of its substructures.
141793 */
141794 SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){
141795 if( OK_IF_ALWAYS_TRUE(p) ) clearSelect(db, p, 1);
141796 }
141797 SQLITE_PRIVATE void sqlite3SelectDeleteGeneric(sqlite3 *db, void *p){
141798 if( ALWAYS(p) ) clearSelect(db, (Select*)p, 1);
141799 }
141800
141801 /*
141802 ** Return a pointer to the right-most SELECT statement in a compound.
141803 */
@@ -144497,13 +144815,11 @@
144815
144816 multi_select_end:
144817 pDest->iSdst = dest.iSdst;
144818 pDest->nSdst = dest.nSdst;
144819 if( pDelete ){
144820 sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pDelete);
 
 
144821 }
144822 return rc;
144823 }
144824 #endif /* SQLITE_OMIT_COMPOUND_SELECT */
144825
@@ -145050,12 +145366,11 @@
145366 sqlite3VdbeResolveLabel(v, labelEnd);
145367
145368 /* Make arrangements to free the 2nd and subsequent arms of the compound
145369 ** after the parse has finished */
145370 if( pSplit->pPrior ){
145371 sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pSplit->pPrior);
 
145372 }
145373 pSplit->pPrior = pPrior;
145374 pPrior->pNext = pSplit;
145375 sqlite3ExprListDelete(db, pPrior->pOrderBy);
145376 pPrior->pOrderBy = 0;
@@ -145872,13 +146187,11 @@
146187 */
146188 if( ALWAYS(pSubitem->pTab!=0) ){
146189 Table *pTabToDel = pSubitem->pTab;
146190 if( pTabToDel->nTabRef==1 ){
146191 Parse *pToplevel = sqlite3ParseToplevel(pParse);
146192 sqlite3ParserAddCleanup(pToplevel, sqlite3DeleteTableGeneric, pTabToDel);
 
 
146193 testcase( pToplevel->earlyCleanup );
146194 }else{
146195 pTabToDel->nTabRef--;
146196 }
146197 pSubitem->pTab = 0;
@@ -146921,12 +147234,11 @@
147234 ** calling this routine, Instead, use only the return value.
147235 */
147236 SQLITE_PRIVATE With *sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){
147237 if( pWith ){
147238 if( bFree ){
147239 pWith = (With*)sqlite3ParserAddCleanup(pParse, sqlite3WithDeleteGeneric,
 
147240 pWith);
147241 if( pWith==0 ) return 0;
147242 }
147243 if( pParse->nErr==0 ){
147244 assert( pParse->pWith!=pWith );
@@ -147955,19 +148267,23 @@
148267 KeyInfo *pKeyInfo;
148268 int nExtra = 0;
148269 assert( pFunc->pFExpr->pLeft!=0 );
148270 assert( pFunc->pFExpr->pLeft->op==TK_ORDER );
148271 assert( ExprUseXList(pFunc->pFExpr->pLeft) );
148272 assert( pFunc->pFunc!=0 );
148273 pOBList = pFunc->pFExpr->pLeft->x.pList;
148274 if( !pFunc->bOBUnique ){
148275 nExtra++; /* One extra column for the OP_Sequence */
148276 }
148277 if( pFunc->bOBPayload ){
148278 /* extra columns for the function arguments */
148279 assert( ExprUseXList(pFunc->pFExpr) );
148280 nExtra += pFunc->pFExpr->x.pList->nExpr;
148281 }
148282 if( pFunc->bUseSubtype ){
148283 nExtra += pFunc->pFExpr->x.pList->nExpr;
148284 }
148285 pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOBList, 0, nExtra);
148286 if( !pFunc->bOBUnique && pParse->nErr==0 ){
148287 pKeyInfo->nKeyField++;
148288 }
148289 sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
@@ -147990,20 +148306,21 @@
148306 for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
148307 ExprList *pList;
148308 assert( ExprUseXList(pF->pFExpr) );
148309 pList = pF->pFExpr->x.pList;
148310 if( pF->iOBTab>=0 ){
148311 /* For an ORDER BY aggregate, calls to OP_AggStep were deferred. Inputs
148312 ** were stored in emphermal table pF->iOBTab. Here, we extract those
148313 ** inputs (in ORDER BY order) and make all calls to OP_AggStep
148314 ** before doing the OP_AggFinal call. */
148315 int iTop; /* Start of loop for extracting columns */
148316 int nArg; /* Number of columns to extract */
148317 int nKey; /* Key columns to be skipped */
148318 int regAgg; /* Extract into this array */
148319 int j; /* Loop counter */
148320
148321 assert( pF->pFunc!=0 );
148322 nArg = pList->nExpr;
148323 regAgg = sqlite3GetTempRange(pParse, nArg);
148324
148325 if( pF->bOBPayload==0 ){
148326 nKey = 0;
@@ -148016,10 +148333,19 @@
148333 }
148334 iTop = sqlite3VdbeAddOp1(v, OP_Rewind, pF->iOBTab); VdbeCoverage(v);
148335 for(j=nArg-1; j>=0; j--){
148336 sqlite3VdbeAddOp3(v, OP_Column, pF->iOBTab, nKey+j, regAgg+j);
148337 }
148338 if( pF->bUseSubtype ){
148339 int regSubtype = sqlite3GetTempReg(pParse);
148340 int iBaseCol = nKey + nArg + (pF->bOBPayload==0 && pF->bOBUnique==0);
148341 for(j=nArg-1; j>=0; j--){
148342 sqlite3VdbeAddOp3(v, OP_Column, pF->iOBTab, iBaseCol+j, regSubtype);
148343 sqlite3VdbeAddOp2(v, OP_SetSubtype, regSubtype, regAgg+j);
148344 }
148345 sqlite3ReleaseTempReg(pParse, regSubtype);
148346 }
148347 sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i));
148348 sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
148349 sqlite3VdbeChangeP5(v, (u8)nArg);
148350 sqlite3VdbeAddOp2(v, OP_Next, pF->iOBTab, iTop+1); VdbeCoverage(v);
148351 sqlite3VdbeJumpHere(v, iTop);
@@ -148070,10 +148396,11 @@
148396 int regAggSz = 0;
148397 int regDistinct = 0;
148398 ExprList *pList;
148399 assert( ExprUseXList(pF->pFExpr) );
148400 assert( !IsWindowFunc(pF->pFExpr) );
148401 assert( pF->pFunc!=0 );
148402 pList = pF->pFExpr->x.pList;
148403 if( ExprHasProperty(pF->pFExpr, EP_WinFunc) ){
148404 Expr *pFilter = pF->pFExpr->y.pWin->pFilter;
148405 if( pAggInfo->nAccumulator
148406 && (pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)
@@ -148113,10 +148440,13 @@
148440 if( !pF->bOBUnique ){
148441 regAggSz++; /* One register for OP_Sequence */
148442 }
148443 if( pF->bOBPayload ){
148444 regAggSz += nArg;
148445 }
148446 if( pF->bUseSubtype ){
148447 regAggSz += nArg;
148448 }
148449 regAggSz++; /* One extra register to hold result of MakeRecord */
148450 regAgg = sqlite3GetTempRange(pParse, regAggSz);
148451 regDistinct = regAgg;
148452 sqlite3ExprCodeExprList(pParse, pOBList, regAgg, 0, SQLITE_ECEL_DUP);
@@ -148126,10 +148456,18 @@
148456 jj++;
148457 }
148458 if( pF->bOBPayload ){
148459 regDistinct = regAgg+jj;
148460 sqlite3ExprCodeExprList(pParse, pList, regDistinct, 0, SQLITE_ECEL_DUP);
148461 jj += nArg;
148462 }
148463 if( pF->bUseSubtype ){
148464 int kk;
148465 int regBase = pF->bOBPayload ? regDistinct : regAgg;
148466 for(kk=0; kk<nArg; kk++, jj++){
148467 sqlite3VdbeAddOp2(v, OP_GetSubtype, regBase+kk, regAgg+jj);
148468 }
148469 }
148470 }else if( pList ){
148471 nArg = pList->nExpr;
148472 regAgg = sqlite3GetTempRange(pParse, nArg);
148473 regDistinct = regAgg;
@@ -148330,11 +148668,12 @@
148668 }
148669
148670 /*
148671 ** Deallocate a single AggInfo object
148672 */
148673 static void agginfoFree(sqlite3 *db, void *pArg){
148674 AggInfo *p = (AggInfo*)pArg;
148675 sqlite3DbFree(db, p->aCol);
148676 sqlite3DbFree(db, p->aFunc);
148677 sqlite3DbFreeNN(db, p);
148678 }
148679
@@ -148584,13 +148923,12 @@
148923 TREETRACE(0x800,pParse,p, ("dropping superfluous ORDER BY:\n"));
148924 if( sqlite3TreeTrace & 0x800 ){
148925 sqlite3TreeViewExprList(0, p->pOrderBy, 0, "ORDERBY");
148926 }
148927 #endif
148928 sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric,
148929 p->pOrderBy);
 
148930 testcase( pParse->earlyCleanup );
148931 p->pOrderBy = 0;
148932 }
148933 p->selFlags &= ~SF_Distinct;
148934 p->selFlags |= SF_NoopOrderBy;
@@ -148778,13 +149116,12 @@
149116 && (p->selFlags & SF_OrderByReqd)==0 /* Condition (3) and (4) */
149117 && OptimizationEnabled(db, SQLITE_OmitOrderBy)
149118 ){
149119 TREETRACE(0x800,pParse,p,
149120 ("omit superfluous ORDER BY on %r FROM-clause subquery\n",i+1));
149121 sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric,
149122 pSub->pOrderBy);
 
149123 pSub->pOrderBy = 0;
149124 }
149125
149126 /* If the outer query contains a "complex" result set (that is,
149127 ** if the result set of the outer query uses functions or subqueries)
@@ -149309,12 +149646,11 @@
149646 ** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the
149647 ** SELECT statement.
149648 */
149649 pAggInfo = sqlite3DbMallocZero(db, sizeof(*pAggInfo) );
149650 if( pAggInfo ){
149651 sqlite3ParserAddCleanup(pParse, agginfoFree, pAggInfo);
 
149652 testcase( pParse->earlyCleanup );
149653 }
149654 if( db->mallocFailed ){
149655 goto select_end;
149656 }
@@ -160987,16 +161323,26 @@
161323 int iEnd = sqlite3VdbeCurrentAddr(v);
161324 if( pParse->db->mallocFailed ) return;
161325 for(; iStart<iEnd; iStart++, pOp++){
161326 if( pOp->p1!=iTabCur ) continue;
161327 if( pOp->opcode==OP_Column ){
161328 #ifdef SQLITE_DEBUG
161329 if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
161330 printf("TRANSLATE OP_Column to OP_Copy at %d\n", iStart);
161331 }
161332 #endif
161333 pOp->opcode = OP_Copy;
161334 pOp->p1 = pOp->p2 + iRegister;
161335 pOp->p2 = pOp->p3;
161336 pOp->p3 = 0;
161337 pOp->p5 = 2; /* Cause the MEM_Subtype flag to be cleared */
161338 }else if( pOp->opcode==OP_Rowid ){
161339 #ifdef SQLITE_DEBUG
161340 if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
161341 printf("TRANSLATE OP_Rowid to OP_Sequence at %d\n", iStart);
161342 }
161343 #endif
161344 pOp->opcode = OP_Sequence;
161345 pOp->p1 = iAutoidxCur;
161346 #ifdef SQLITE_ALLOW_ROWID_IN_VIEW
161347 if( iAutoidxCur==0 ){
161348 pOp->opcode = OP_Null;
@@ -162319,11 +162665,12 @@
162665 nNew = sqlite3LogEst(iUpper - iLower);
162666 /* TUNING: If both iUpper and iLower are derived from the same
162667 ** sample, then assume they are 4x more selective. This brings
162668 ** the estimated selectivity more in line with what it would be
162669 ** if estimated without the use of STAT4 tables. */
162670 if( iLwrIdx==iUprIdx ){ nNew -= 20; }
162671 assert( 20==sqlite3LogEst(4) );
162672 }else{
162673 nNew = 10; assert( 10==sqlite3LogEst(2) );
162674 }
162675 if( nNew<nOut ){
162676 nOut = nNew;
@@ -182234,10 +182581,32 @@
182581 rc = SQLITE_NOTFOUND;
182582 }
182583 break;
182584 }
182585 #endif
182586
182587 /* sqlite3_test_control(SQLITE_TESTCTRL_JSON_SELFCHECK, &onOff);
182588 **
182589 ** Activate or deactivate validation of JSONB that is generated from
182590 ** text. Off by default, as the validation is slow. Validation is
182591 ** only available if compiled using SQLITE_DEBUG.
182592 **
182593 ** If onOff is initially 1, then turn it on. If onOff is initially
182594 ** off, turn it off. If onOff is initially -1, then change onOff
182595 ** to be the current setting.
182596 */
182597 case SQLITE_TESTCTRL_JSON_SELFCHECK: {
182598 #if defined(SQLITE_DEBUG)
182599 int *pOnOff = va_arg(ap, int*);
182600 if( *pOnOff<0 ){
182601 *pOnOff = sqlite3Config.bJsonSelfcheck;
182602 }else{
182603 sqlite3Config.bJsonSelfcheck = (u8)((*pOnOff)&0xff);
182604 }
182605 #endif
182606 break;
182607 }
182608 }
182609 va_end(ap);
182610 #endif /* SQLITE_UNTESTABLE */
182611 return rc;
182612 }
@@ -202648,28 +203017,146 @@
203017 ** May you find forgiveness for yourself and forgive others.
203018 ** May you share freely, never taking more than you give.
203019 **
203020 ******************************************************************************
203021 **
203022 ** SQLite JSON functions.
203023 **
203024 ** This file began as an extension in ext/misc/json1.c in 2015. That
203025 ** extension proved so useful that it has now been moved into the core.
203026 **
203027 ** The original design stored all JSON as pure text, canonical RFC-8259.
203028 ** Support for JSON-5 extensions was added with version 3.42.0 (2023-05-16).
203029 ** All generated JSON text still conforms strictly to RFC-8259, but text
203030 ** with JSON-5 extensions is accepted as input.
203031 **
203032 ** Beginning with version 3.45.0 (pending), these routines also accept
203033 ** BLOB values that have JSON encoded using a binary representation we
203034 ** call JSONB. The name JSONB comes from PostgreSQL, however the on-disk
203035 ** format SQLite JSONB is completely different and incompatible with
203036 ** PostgreSQL JSONB.
203037 **
203038 ** Decoding and interpreting JSONB is still O(N) where N is the size of
203039 ** the input, the same as text JSON. However, the constant of proportionality
203040 ** for JSONB is much smaller due to faster parsing. The size of each
203041 ** element in JSONB is encoded in its header, so there is no need to search
203042 ** for delimiters using persnickety syntax rules. JSONB seems to be about
203043 ** 3x faster than text JSON as a result. JSONB is also tends to be slightly
203044 ** smaller than text JSON, by 5% or 10%, but there are corner cases where
203045 ** JSONB can be slightly larger. So you are not far mistaken to say that
203046 ** a JSONB blob is the same size as the equivalent RFC-8259 text.
203047 **
203048 **
203049 ** THE JSONB ENCODING:
203050 **
203051 ** Every JSON element is encoded in JSONB as a header and a payload.
203052 ** The header is between 1 and 9 bytes in size. The payload is zero
203053 ** or more bytes.
203054 **
203055 ** The lower 4 bits of the first byte of the header determines the
203056 ** element type:
203057 **
203058 ** 0: NULL
203059 ** 1: TRUE
203060 ** 2: FALSE
203061 ** 3: INT -- RFC-8259 integer literal
203062 ** 4: INT5 -- JSON5 integer literal
203063 ** 5: FLOAT -- RFC-8259 floating point literal
203064 ** 6: FLOAT5 -- JSON5 floating point literal
203065 ** 7: TEXT -- Text literal acceptable to both SQL and JSON
203066 ** 8: TEXTJ -- Text containing RFC-8259 escapes
203067 ** 9: TEXT5 -- Text containing JSON5 and/or RFC-8259 escapes
203068 ** 10: TEXTRAW -- Text containing unescaped syntax characters
203069 ** 11: ARRAY
203070 ** 12: OBJECT
203071 **
203072 ** The other three possible values (13-15) are reserved for future
203073 ** enhancements.
203074 **
203075 ** The upper 4 bits of the first byte determine the size of the header
203076 ** and sometimes also the size of the payload. If X is the first byte
203077 ** of the element and if X>>4 is between 0 and 11, then the payload
203078 ** will be that many bytes in size and the header is exactly one byte
203079 ** in size. Other four values for X>>4 (12-15) indicate that the header
203080 ** is more than one byte in size and that the payload size is determined
203081 ** by the remainder of the header, interpreted as a unsigned big-endian
203082 ** integer.
203083 **
203084 ** Value of X>>4 Size integer Total header size
203085 ** ------------- -------------------- -----------------
203086 ** 12 1 byte (0-255) 2
203087 ** 13 2 byte (0-65535) 3
203088 ** 14 4 byte (0-4294967295) 5
203089 ** 15 8 byte (0-1.8e19) 9
203090 **
203091 ** The payload size need not be expressed in its minimal form. For example,
203092 ** if the payload size is 10, the size can be expressed in any of 5 different
203093 ** ways: (1) (X>>4)==10, (2) (X>>4)==12 following by on 0x0a byte,
203094 ** (3) (X>>4)==13 followed by 0x00 and 0x0a, (4) (X>>4)==14 followed by
203095 ** 0x00 0x00 0x00 0x0a, or (5) (X>>4)==15 followed by 7 bytes of 0x00 and
203096 ** a single byte of 0x0a. The shorter forms are preferred, of course, but
203097 ** sometimes when generating JSONB, the payload size is not known in advance
203098 ** and it is convenient to reserve sufficient header space to cover the
203099 ** largest possible payload size and then come back later and patch up
203100 ** the size when it becomes known, resulting in a non-minimal encoding.
203101 **
203102 ** The value (X>>4)==15 is not actually used in the current implementation
203103 ** (as SQLite is currently unable handle BLOBs larger than about 2GB)
203104 ** but is included in the design to allow for future enhancements.
203105 **
203106 ** The payload follows the header. NULL, TRUE, and FALSE have no payload and
203107 ** their payload size must always be zero. The payload for INT, INT5,
203108 ** FLOAT, FLOAT5, TEXT, TEXTJ, TEXT5, and TEXTROW is text. Note that the
203109 ** "..." or '...' delimiters are omitted from the various text encodings.
203110 ** The payload for ARRAY and OBJECT is a list of additional elements that
203111 ** are the content for the array or object. The payload for an OBJECT
203112 ** must be an even number of elements. The first element of each pair is
203113 ** the label and must be of type TEXT, TEXTJ, TEXT5, or TEXTRAW.
203114 **
203115 ** A valid JSONB blob consists of a single element, as described above.
203116 ** Usually this will be an ARRAY or OBJECT element which has many more
203117 ** elements as its content. But the overall blob is just a single element.
203118 **
203119 ** Input validation for JSONB blobs simply checks that the element type
203120 ** code is between 0 and 12 and that the total size of the element
203121 ** (header plus payload) is the same as the size of the BLOB. If those
203122 ** checks are true, the BLOB is assumed to be JSONB and processing continues.
203123 ** Errors are only raised if some other miscoding is discovered during
203124 ** processing.
203125 */
203126 #ifndef SQLITE_OMIT_JSON
203127 /* #include "sqliteInt.h" */
203128
203129 /* JSONB element types
203130 */
203131 #define JSONB_NULL 0 /* "null" */
203132 #define JSONB_TRUE 1 /* "true" */
203133 #define JSONB_FALSE 2 /* "false" */
203134 #define JSONB_INT 3 /* integer acceptable to JSON and SQL */
203135 #define JSONB_INT5 4 /* integer in 0x000 notation */
203136 #define JSONB_FLOAT 5 /* float acceptable to JSON and SQL */
203137 #define JSONB_FLOAT5 6 /* float with JSON5 extensions */
203138 #define JSONB_TEXT 7 /* Text compatible with both JSON and SQL */
203139 #define JSONB_TEXTJ 8 /* Text with JSON escapes */
203140 #define JSONB_TEXT5 9 /* Text with JSON-5 escape */
203141 #define JSONB_TEXTRAW 10 /* SQL text that needs escaping for JSON */
203142 #define JSONB_ARRAY 11 /* An array */
203143 #define JSONB_OBJECT 12 /* An object */
203144
203145 /* Human-readable names for the JSONB values. The index for each
203146 ** string must correspond to the JSONB_* integer above.
203147 */
203148 static const char * const jsonbType[] = {
203149 "null", "true", "false", "integer", "integer",
203150 "real", "real", "text", "text", "text",
203151 "text", "array", "object", "", "", "", ""
203152 };
203153
203154 /*
203155 ** Growing our own isspace() routine this way is twice as fast as
203156 ** the library isspace() function, resulting in a 7% overall performance
203157 ** increase for the text-JSON parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os).
203158 */
203159 static const char jsonIsSpace[] = {
203160 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
203161 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
203162 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -202686,15 +203173,23 @@
203173 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
203174 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
203175 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
203176 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
203177 };
203178 #define jsonIsspace(x) (jsonIsSpace[(unsigned char)x])
203179
203180 /*
203181 ** The set of all space characters recognized by jsonIsspace().
203182 ** Useful as the second argument to strspn().
203183 */
203184 static const char jsonSpaces[] = "\011\012\015\040";
203185
203186 /*
203187 ** Characters that are special to JSON. Control characters,
203188 ** '"' and '\\' and '\''. Actually, '\'' is not special to
203189 ** canonical JSON, but it is special in JSON-5, so we include
203190 ** it in the set of special characters.
203191 */
203192 static const char jsonIsOk[256] = {
203193 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
203194 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
203195 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -202712,247 +203207,353 @@
203207 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
203208 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
203209 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
203210 };
203211
 
 
 
 
 
 
 
203212 /* Objects */
203213 typedef struct JsonCache JsonCache;
203214 typedef struct JsonString JsonString;
 
203215 typedef struct JsonParse JsonParse;
203216
203217 /*
203218 ** Magic number used for the JSON parse cache in sqlite3_get_auxdata()
203219 */
203220 #define JSON_CACHE_ID (-429938) /* Cache entry */
203221 #define JSON_CACHE_SIZE 4 /* Max number of cache entries */
203222
203223 /* A cache mapping JSON text into JSONB blobs.
203224 **
203225 ** Each cache entry is a JsonParse object with the following restrictions:
203226 **
203227 ** * The bReadOnly flag must be set
203228 **
203229 ** * The aBlob[] array must be owned by the JsonParse object. In other
203230 ** words, nBlobAlloc must be non-zero.
203231 **
203232 ** * zJson must be an RCStr. In other words bJsonIsRCStr must be true.
203233 */
203234 struct JsonCache {
203235 sqlite3 *db; /* Database connection */
203236 int nUsed; /* Number of active entries in the cache */
203237 JsonParse *a[JSON_CACHE_SIZE]; /* One line for each cache entry */
203238 };
203239
203240 /* An instance of this object represents a JSON string
203241 ** under construction. Really, this is a generic string accumulator
203242 ** that can be and is used to create strings other than JSON.
203243 **
203244 ** If the generated string is longer than will fit into the zSpace[] buffer,
203245 ** then it will be an RCStr string. This aids with caching of large
203246 ** JSON strings.
203247 */
203248 struct JsonString {
203249 sqlite3_context *pCtx; /* Function context - put error messages here */
203250 char *zBuf; /* Append JSON content here */
203251 u64 nAlloc; /* Bytes of storage available in zBuf[] */
203252 u64 nUsed; /* Bytes of zBuf[] currently used */
203253 u8 bStatic; /* True if zBuf is static space */
203254 u8 eErr; /* True if an error has been encountered */
203255 char zSpace[100]; /* Initial static space */
203256 };
203257
203258 /* Allowed values for JsonString.eErr */
203259 #define JSTRING_OOM 0x01 /* Out of memory */
203260 #define JSTRING_MALFORMED 0x02 /* Malformed JSONB */
203261 #define JSTRING_ERR 0x04 /* Error already sent to sqlite3_result */
203262
203263 /* The "subtype" set for text JSON values passed through using
203264 ** sqlite3_result_subtype() and sqlite3_value_subtype().
203265 */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203266 #define JSON_SUBTYPE 74 /* Ascii for "J" */
203267
203268 /*
203269 ** Bit values for the flags passed into various SQL function implementations
203270 ** via the sqlite3_user_data() value.
203271 */
203272 #define JSON_JSON 0x01 /* Result is always JSON */
203273 #define JSON_SQL 0x02 /* Result is always SQL */
203274 #define JSON_ABPATH 0x03 /* Allow abbreviated JSON path specs */
203275 #define JSON_ISSET 0x04 /* json_set(), not json_insert() */
203276 #define JSON_BLOB 0x08 /* Use the BLOB output format */
203277
203278
203279 /* A parsed JSON value. Lifecycle:
203280 **
203281 ** 1. JSON comes in and is parsed into a JSONB value in aBlob. The
203282 ** original text is stored in zJson. This step is skipped if the
203283 ** input is JSONB instead of text JSON.
203284 **
203285 ** 2. The aBlob[] array is searched using the JSON path notation, if needed.
203286 **
203287 ** 3. Zero or more changes are made to aBlob[] (via json_remove() or
203288 ** json_replace() or json_patch() or similar).
203289 **
203290 ** 4. New JSON text is generated from the aBlob[] for output. This step
203291 ** is skipped the function is one of the jsonb_* functions that returns
203292 ** JSONB instead of text JSON.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203293 */
203294 struct JsonParse {
203295 u8 *aBlob; /* JSONB representation of JSON value */
203296 u32 nBlob; /* Bytes of aBlob[] actually used */
203297 u32 nBlobAlloc; /* Bytes allocated to aBlob[]. 0 if aBlob is external */
203298 char *zJson; /* Json text used for parsing */
203299 int nJson; /* Length of the zJson string in bytes */
 
 
203300 u16 iDepth; /* Nesting depth */
203301 u8 nErr; /* Number of errors seen */
203302 u8 oom; /* Set to true if out of memory */
203303 u8 bJsonIsRCStr; /* True if zJson is an RCStr */
203304 u8 hasNonstd; /* True if input uses non-standard features like JSON5 */
203305 u8 bReadOnly; /* Do not modify. */
 
203306 u32 nJPRef; /* Number of references to this object */
 
 
203307 u32 iErr; /* Error location in zJson[] */
203308 /* Search and edit information. See jsonLookupStep() */
203309 u8 eEdit; /* Edit operation to apply */
203310 int delta; /* Size change due to the edit */
203311 u32 nIns; /* Number of bytes to insert */
203312 u32 iLabel; /* Location of label if search landed on an object value */
203313 u8 *aIns; /* Content to be inserted */
203314 };
203315
203316 /* Allowed values for JsonParse.eEdit */
203317 #define JEDIT_DEL 1 /* Delete if exists */
203318 #define JEDIT_REPL 2 /* Overwrite if exists */
203319 #define JEDIT_INS 3 /* Insert if not exists */
203320 #define JEDIT_SET 4 /* Insert or overwrite */
203321
203322 /*
203323 ** Maximum nesting depth of JSON for this implementation.
203324 **
203325 ** This limit is needed to avoid a stack overflow in the recursive
203326 ** descent parser. A depth of 1000 is far deeper than any sane JSON
203327 ** should go. Historical note: This limit was 2000 prior to version 3.42.0
203328 */
203329 #ifndef SQLITE_JSON_MAX_DEPTH
203330 # define JSON_MAX_DEPTH 1000
203331 #else
203332 # define JSON_MAX_DEPTH SQLITE_JSON_MAX_DEPTH
203333 #endif
203334
203335 /*
203336 ** Allowed values for the flgs argument to jsonParseFuncArg();
203337 */
203338 #define JSON_EDITABLE 0x01 /* Generate a writable JsonParse object */
203339 #define JSON_KEEPERROR 0x02 /* Return non-NULL even if there is an error */
203340
203341 /**************************************************************************
203342 ** Forward references
203343 **************************************************************************/
203344 static void jsonReturnStringAsBlob(JsonString*);
203345 static int jsonFuncArgMightBeBinary(sqlite3_value *pJson);
203346 static u32 jsonXlateBlobToText(const JsonParse*,u32,JsonString*);
203347 static void jsonReturnParse(sqlite3_context*,JsonParse*);
203348 static JsonParse *jsonParseFuncArg(sqlite3_context*,sqlite3_value*,u32);
203349 static void jsonParseFree(JsonParse*);
203350 static u32 jsonbPayloadSize(const JsonParse*, u32, u32*);
203351 static u32 jsonUnescapeOneChar(const char*, u32, u32*);
203352
203353 /**************************************************************************
203354 ** Utility routines for dealing with JsonCache objects
203355 **************************************************************************/
203356
203357 /*
203358 ** Free a JsonCache object.
203359 */
203360 static void jsonCacheDelete(JsonCache *p){
203361 int i;
203362 for(i=0; i<p->nUsed; i++){
203363 jsonParseFree(p->a[i]);
203364 }
203365 sqlite3DbFree(p->db, p);
203366 }
203367 static void jsonCacheDeleteGeneric(void *p){
203368 jsonCacheDelete((JsonCache*)p);
203369 }
203370
203371 /*
203372 ** Insert a new entry into the cache. If the cache is full, expel
203373 ** the least recently used entry. Return SQLITE_OK on success or a
203374 ** result code otherwise.
203375 **
203376 ** Cache entries are stored in age order, oldest first.
203377 */
203378 static int jsonCacheInsert(
203379 sqlite3_context *ctx, /* The SQL statement context holding the cache */
203380 JsonParse *pParse /* The parse object to be added to the cache */
203381 ){
203382 JsonCache *p;
203383
203384 assert( pParse->zJson!=0 );
203385 assert( pParse->bJsonIsRCStr );
203386 p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID);
203387 if( p==0 ){
203388 sqlite3 *db = sqlite3_context_db_handle(ctx);
203389 p = sqlite3DbMallocZero(db, sizeof(*p));
203390 if( p==0 ) return SQLITE_NOMEM;
203391 p->db = db;
203392 sqlite3_set_auxdata(ctx, JSON_CACHE_ID, p, jsonCacheDeleteGeneric);
203393 p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID);
203394 if( p==0 ) return SQLITE_NOMEM;
203395 }
203396 if( p->nUsed >= JSON_CACHE_SIZE ){
203397 jsonParseFree(p->a[0]);
203398 memmove(p->a, &p->a[1], (JSON_CACHE_SIZE-1)*sizeof(p->a[0]));
203399 p->nUsed = JSON_CACHE_SIZE-1;
203400 }
203401 assert( pParse->nBlobAlloc>0 );
203402 pParse->eEdit = 0;
203403 pParse->nJPRef++;
203404 pParse->bReadOnly = 1;
203405 p->a[p->nUsed] = pParse;
203406 p->nUsed++;
203407 return SQLITE_OK;
203408 }
203409
203410 /*
203411 ** Search for a cached translation the json text supplied by pArg. Return
203412 ** the JsonParse object if found. Return NULL if not found.
203413 **
203414 ** When a match if found, the matching entry is moved to become the
203415 ** most-recently used entry if it isn't so already.
203416 **
203417 ** The JsonParse object returned still belongs to the Cache and might
203418 ** be deleted at any moment. If the caller whants the JsonParse to
203419 ** linger, it needs to increment the nPJRef reference counter.
203420 */
203421 static JsonParse *jsonCacheSearch(
203422 sqlite3_context *ctx, /* The SQL statement context holding the cache */
203423 sqlite3_value *pArg /* Function argument containing SQL text */
203424 ){
203425 JsonCache *p;
203426 int i;
203427 const char *zJson;
203428 int nJson;
203429
203430 if( sqlite3_value_type(pArg)!=SQLITE_TEXT ){
203431 return 0;
203432 }
203433 zJson = (const char*)sqlite3_value_text(pArg);
203434 if( zJson==0 ) return 0;
203435 nJson = sqlite3_value_bytes(pArg);
203436
203437 p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID);
203438 if( p==0 ){
203439 return 0;
203440 }
203441 for(i=0; i<p->nUsed; i++){
203442 if( p->a[i]->zJson==zJson ) break;
203443 }
203444 if( i>=p->nUsed ){
203445 for(i=0; i<p->nUsed; i++){
203446 if( p->a[i]->nJson!=nJson ) continue;
203447 if( memcmp(p->a[i]->zJson, zJson, nJson)==0 ) break;
203448 }
203449 }
203450 if( i<p->nUsed ){
203451 if( i<p->nUsed-1 ){
203452 /* Make the matching entry the most recently used entry */
203453 JsonParse *tmp = p->a[i];
203454 memmove(&p->a[i], &p->a[i+1], (p->nUsed-i-1)*sizeof(tmp));
203455 p->a[p->nUsed-1] = tmp;
203456 i = p->nUsed - 1;
203457 }
203458 return p->a[i];
203459 }else{
203460 return 0;
203461 }
203462 }
203463
203464 /**************************************************************************
203465 ** Utility routines for dealing with JsonString objects
203466 **************************************************************************/
203467
203468 /* Turn uninitialized bulk memory into a valid JsonString object
203469 ** holding a zero-length string.
203470 */
203471 static void jsonStringZero(JsonString *p){
203472 p->zBuf = p->zSpace;
203473 p->nAlloc = sizeof(p->zSpace);
203474 p->nUsed = 0;
203475 p->bStatic = 1;
203476 }
203477
203478 /* Initialize the JsonString object
203479 */
203480 static void jsonStringInit(JsonString *p, sqlite3_context *pCtx){
203481 p->pCtx = pCtx;
203482 p->eErr = 0;
203483 jsonStringZero(p);
203484 }
203485
203486 /* Free all allocated memory and reset the JsonString object back to its
203487 ** initial state.
203488 */
203489 static void jsonStringReset(JsonString *p){
203490 if( !p->bStatic ) sqlite3RCStrUnref(p->zBuf);
203491 jsonStringZero(p);
203492 }
203493
203494 /* Report an out-of-memory (OOM) condition
203495 */
203496 static void jsonStringOom(JsonString *p){
203497 p->eErr |= JSTRING_OOM;
203498 if( p->pCtx ) sqlite3_result_error_nomem(p->pCtx);
203499 jsonStringReset(p);
203500 }
203501
203502 /* Enlarge pJson->zBuf so that it can hold at least N more bytes.
203503 ** Return zero on success. Return non-zero on an OOM error
203504 */
203505 static int jsonStringGrow(JsonString *p, u32 N){
203506 u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10;
203507 char *zNew;
203508 if( p->bStatic ){
203509 if( p->eErr ) return 1;
203510 zNew = sqlite3RCStrNew(nTotal);
203511 if( zNew==0 ){
203512 jsonStringOom(p);
203513 return SQLITE_NOMEM;
203514 }
203515 memcpy(zNew, p->zBuf, (size_t)p->nUsed);
203516 p->zBuf = zNew;
203517 p->bStatic = 0;
203518 }else{
203519 p->zBuf = sqlite3RCStrResize(p->zBuf, nTotal);
203520 if( p->zBuf==0 ){
203521 p->eErr |= JSTRING_OOM;
203522 jsonStringZero(p);
203523 return SQLITE_NOMEM;
203524 }
203525 }
203526 p->nAlloc = nTotal;
203527 return SQLITE_OK;
203528 }
203529
203530 /* Append N bytes from zIn onto the end of the JsonString string.
203531 */
203532 static SQLITE_NOINLINE void jsonStringExpandAndAppend(
203533 JsonString *p,
203534 const char *zIn,
203535 u32 N
203536 ){
203537 assert( N>0 );
203538 if( jsonStringGrow(p,N) ) return;
203539 memcpy(p->zBuf+p->nUsed, zIn, N);
203540 p->nUsed += N;
203541 }
203542 static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
203543 if( N==0 ) return;
203544 if( N+p->nUsed >= p->nAlloc ){
203545 jsonStringExpandAndAppend(p,zIn,N);
203546 }else{
203547 memcpy(p->zBuf+p->nUsed, zIn, N);
203548 p->nUsed += N;
203549 }
203550 }
203551 static void jsonAppendRawNZ(JsonString *p, const char *zIn, u32 N){
203552 assert( N>0 );
203553 if( N+p->nUsed >= p->nAlloc ){
203554 jsonStringExpandAndAppend(p,zIn,N);
203555 }else{
203556 memcpy(p->zBuf+p->nUsed, zIn, N);
203557 p->nUsed += N;
203558 }
203559 }
@@ -202960,21 +203561,21 @@
203561
203562 /* Append formatted text (not to exceed N bytes) to the JsonString.
203563 */
203564 static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){
203565 va_list ap;
203566 if( (p->nUsed + N >= p->nAlloc) && jsonStringGrow(p, N) ) return;
203567 va_start(ap, zFormat);
203568 sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap);
203569 va_end(ap);
203570 p->nUsed += (int)strlen(p->zBuf+p->nUsed);
203571 }
203572
203573 /* Append a single character
203574 */
203575 static SQLITE_NOINLINE void jsonAppendCharExpand(JsonString *p, char c){
203576 if( jsonStringGrow(p,1) ) return;
203577 p->zBuf[p->nUsed++] = c;
203578 }
203579 static void jsonAppendChar(JsonString *p, char c){
203580 if( p->nUsed>=p->nAlloc ){
203581 jsonAppendCharExpand(p,c);
@@ -202981,27 +203582,20 @@
203582 }else{
203583 p->zBuf[p->nUsed++] = c;
203584 }
203585 }
203586
203587 /* Make sure there is a zero terminator on p->zBuf[]
203588 **
203589 ** Return true on success. Return false if an OOM prevents this
203590 ** from happening.
203591 */
203592 static int jsonStringTerminate(JsonString *p){
203593 jsonAppendChar(p, 0);
203594 p->nUsed--;
203595 return p->eErr==0;
203596 }
 
 
 
 
 
 
 
203597
203598 /* Append a comma separator to the output buffer, if the previous
203599 ** character is not '[' or '{'.
203600 */
203601 static void jsonAppendSeparator(JsonString *p){
@@ -203011,25 +203605,45 @@
203605 if( c=='[' || c=='{' ) return;
203606 jsonAppendChar(p, ',');
203607 }
203608
203609 /* Append the N-byte string in zIn to the end of the JsonString string
203610 ** under construction. Enclose the string in double-quotes ("...") and
203611 ** escape any double-quotes or backslash characters contained within the
203612 ** string.
203613 **
203614 ** This routine is a high-runner. There is a measurable performance
203615 ** increase associated with unwinding the jsonIsOk[] loop.
203616 */
203617 static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
203618 u32 k;
203619 u8 c;
203620 const u8 *z = (const u8*)zIn;
203621 if( z==0 ) return;
203622 if( (N+p->nUsed+2 >= p->nAlloc) && jsonStringGrow(p,N+2)!=0 ) return;
203623 p->zBuf[p->nUsed++] = '"';
203624 while( 1 /*exit-by-break*/ ){
203625 k = 0;
203626 while( k+1<N && jsonIsOk[z[k]] && jsonIsOk[z[k+1]] ){ k += 2; } /* <--, */
203627 while( k<N && jsonIsOk[z[k]] ){ k++; } /* <-- loop unwound for speed */
203628 if( k>=N ){
203629 if( k>0 ){
203630 memcpy(&p->zBuf[p->nUsed], z, k);
203631 p->nUsed += k;
203632 }
203633 break;
203634 }
203635 if( k>0 ){
203636 memcpy(&p->zBuf[p->nUsed], z, k);
203637 p->nUsed += k;
203638 z += k;
203639 N -= k;
203640 }
203641 c = z[0];
203642 if( c=='"' || c=='\\' ){
203643 json_simple_escape:
203644 if( (p->nUsed+N+3 > p->nAlloc) && jsonStringGrow(p,N+3)!=0 ) return;
203645 p->zBuf[p->nUsed++] = '\\';
203646 p->zBuf[p->nUsed++] = c;
203647 }else if( c=='\'' ){
203648 p->zBuf[p->nUsed++] = c;
203649 }else{
@@ -203046,158 +203660,30 @@
203660 assert( c>=0 && c<sizeof(aSpecial) );
203661 if( aSpecial[c] ){
203662 c = aSpecial[c];
203663 goto json_simple_escape;
203664 }
203665 if( (p->nUsed+N+7 > p->nAlloc) && jsonStringGrow(p,N+7)!=0 ) return;
203666 p->zBuf[p->nUsed++] = '\\';
203667 p->zBuf[p->nUsed++] = 'u';
203668 p->zBuf[p->nUsed++] = '0';
203669 p->zBuf[p->nUsed++] = '0';
203670 p->zBuf[p->nUsed++] = "0123456789abcdef"[c>>4];
203671 p->zBuf[p->nUsed++] = "0123456789abcdef"[c&0xf];
203672 }
203673 z++;
203674 N--;
203675 }
203676 p->zBuf[p->nUsed++] = '"';
203677 assert( p->nUsed<p->nAlloc );
203678 }
203679
203680 /*
203681 ** Append an sqlite3_value (such as a function parameter) to the JSON
203682 ** string under construction in p.
203683 */
203684 static void jsonAppendSqlValue(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203685 JsonString *p, /* Append to this JSON string */
203686 sqlite3_value *pValue /* Value to append */
203687 ){
203688 switch( sqlite3_value_type(pValue) ){
203689 case SQLITE_NULL: {
@@ -203223,591 +203709,147 @@
203709 jsonAppendString(p, z, n);
203710 }
203711 break;
203712 }
203713 default: {
203714 if( jsonFuncArgMightBeBinary(pValue) ){
203715 JsonParse px;
203716 memset(&px, 0, sizeof(px));
203717 px.aBlob = (u8*)sqlite3_value_blob(pValue);
203718 px.nBlob = sqlite3_value_bytes(pValue);
203719 jsonXlateBlobToText(&px, 0, p);
203720 }else if( p->eErr==0 ){
203721 sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1);
203722 p->eErr = JSTRING_ERR;
203723 jsonStringReset(p);
203724 }
203725 break;
203726 }
203727 }
203728 }
203729
203730 /* Make the text in p (which is probably a generated JSON text string)
203731 ** the result of the SQL function.
203732 **
203733 ** The JsonString is reset.
203734 **
203735 ** If pParse and ctx are both non-NULL, then the SQL string in p is
203736 ** loaded into the zJson field of the pParse object as a RCStr and the
203737 ** pParse is added to the cache.
203738 */
203739 static void jsonReturnString(
203740 JsonString *p, /* String to return */
203741 JsonParse *pParse, /* JSONB source or NULL */
203742 sqlite3_context *ctx /* Where to cache */
203743 ){
203744 assert( (pParse!=0)==(ctx!=0) );
203745 assert( ctx==0 || ctx==p->pCtx );
203746 if( p->eErr==0 ){
203747 int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(p->pCtx));
203748 if( flags & JSON_BLOB ){
203749 jsonReturnStringAsBlob(p);
203750 }else if( p->bStatic ){
203751 sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
203752 SQLITE_TRANSIENT, SQLITE_UTF8);
203753 }else if( jsonStringTerminate(p) ){
203754 if( pParse && pParse->bJsonIsRCStr==0 && pParse->nBlobAlloc>0 ){
203755 int rc;
203756 pParse->zJson = sqlite3RCStrRef(p->zBuf);
203757 pParse->nJson = p->nUsed;
203758 pParse->bJsonIsRCStr = 1;
203759 rc = jsonCacheInsert(ctx, pParse);
203760 if( rc==SQLITE_NOMEM ){
203761 sqlite3_result_error_nomem(ctx);
203762 jsonStringReset(p);
203763 return;
203764 }
203765 }
203766 sqlite3_result_text64(p->pCtx, sqlite3RCStrRef(p->zBuf), p->nUsed,
203767 sqlite3RCStrUnref,
203768 SQLITE_UTF8);
203769 }else{
203770 sqlite3_result_error_nomem(p->pCtx);
203771 }
203772 }else if( p->eErr & JSTRING_OOM ){
 
203773 sqlite3_result_error_nomem(p->pCtx);
203774 }else if( p->eErr & JSTRING_MALFORMED ){
203775 sqlite3_result_error(p->pCtx, "malformed JSON", -1);
203776 }
203777 jsonStringReset(p);
203778 }
203779
203780 /**************************************************************************
203781 ** Utility routines for dealing with JsonParse objects
203782 **************************************************************************/
203783
 
 
 
 
 
 
 
 
 
 
 
 
 
203784 /*
203785 ** Reclaim all memory allocated by a JsonParse object. But do not
203786 ** delete the JsonParse object itself.
203787 */
203788 static void jsonParseReset(JsonParse *pParse){
 
 
 
 
 
 
203789 assert( pParse->nJPRef<=1 );
 
 
 
 
 
 
 
 
 
 
203790 if( pParse->bJsonIsRCStr ){
203791 sqlite3RCStrUnref(pParse->zJson);
203792 pParse->zJson = 0;
203793 pParse->nJson = 0;
203794 pParse->bJsonIsRCStr = 0;
203795 }
203796 if( pParse->nBlobAlloc ){
203797 sqlite3_free(pParse->aBlob);
203798 pParse->aBlob = 0;
203799 pParse->nBlob = 0;
203800 pParse->nBlobAlloc = 0;
203801 }
203802 }
203803
203804 /*
203805 ** Decrement the reference count on the JsonParse object. When the
203806 ** count reaches zero, free the object.
 
 
 
 
203807 */
203808 static void jsonParseFree(JsonParse *pParse){
203809 if( pParse ){
203810 if( pParse->nJPRef>1 ){
203811 pParse->nJPRef--;
203812 }else{
203813 jsonParseReset(pParse);
203814 sqlite3_free(pParse);
203815 }
203816 }
203817 }
203818
203819 /**************************************************************************
203820 ** Utility routines for the JSON text parser
203821 **************************************************************************/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203822
203823 /*
203824 ** Translate a single byte of Hex into an integer.
203825 ** This routine only gives a correct answer if h really is a valid hexadecimal
203826 ** character: 0..9a..fA..F. But unlike sqlite3HexToInt(), it does not
203827 ** assert() if the digit is not hex.
203828 */
203829 static u8 jsonHexToInt(int h){
203830 #ifdef SQLITE_ASCII
203831 h += 9*(1&(h>>6));
203832 #endif
203833 #ifdef SQLITE_EBCDIC
203834 h += 9*(1&~(h>>4));
 
 
203835 #endif
203836 return (u8)(h & 0xf);
203837 }
203838
203839 /*
203840 ** Convert a 4-byte hex string into an integer
203841 */
203842 static u32 jsonHexToInt4(const char *z){
203843 u32 v;
 
 
 
 
203844 v = (jsonHexToInt(z[0])<<12)
203845 + (jsonHexToInt(z[1])<<8)
203846 + (jsonHexToInt(z[2])<<4)
203847 + jsonHexToInt(z[3]);
203848 return v;
203849 }
203850
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203851 /*
203852 ** Return true if z[] begins with 2 (or more) hexadecimal digits
203853 */
203854 static int jsonIs2Hex(const char *z){
203855 return sqlite3Isxdigit(z[0]) && sqlite3Isxdigit(z[1]);
@@ -203957,101 +203999,542 @@
203999 char eType;
204000 char nRepl;
204001 char *zMatch;
204002 char *zRepl;
204003 } aNanInfName[] = {
204004 { 'i', 'I', 3, JSONB_FLOAT, 7, "inf", "9.0e999" },
204005 { 'i', 'I', 8, JSONB_FLOAT, 7, "infinity", "9.0e999" },
204006 { 'n', 'N', 3, JSONB_NULL, 4, "NaN", "null" },
204007 { 'q', 'Q', 4, JSONB_NULL, 4, "QNaN", "null" },
204008 { 's', 'S', 4, JSONB_NULL, 4, "SNaN", "null" },
204009 };
204010
204011
204012 /*
204013 ** Report the wrong number of arguments for json_insert(), json_replace()
204014 ** or json_set().
204015 */
204016 static void jsonWrongNumArgs(
204017 sqlite3_context *pCtx,
204018 const char *zFuncName
204019 ){
204020 char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments",
204021 zFuncName);
204022 sqlite3_result_error(pCtx, zMsg, -1);
204023 sqlite3_free(zMsg);
204024 }
204025
204026 /****************************************************************************
204027 ** Utility routines for dealing with the binary BLOB representation of JSON
204028 ****************************************************************************/
204029
204030 /*
204031 ** Expand pParse->aBlob so that it holds at least N bytes.
204032 **
204033 ** Return the number of errors.
204034 */
204035 static int jsonBlobExpand(JsonParse *pParse, u32 N){
204036 u8 *aNew;
204037 u32 t;
204038 assert( N>pParse->nBlobAlloc );
204039 if( pParse->nBlobAlloc==0 ){
204040 t = 100;
204041 }else{
204042 t = pParse->nBlobAlloc*2;
204043 }
204044 if( t<N ) t = N+100;
204045 aNew = sqlite3_realloc64( pParse->aBlob, t );
204046 if( aNew==0 ){ pParse->oom = 1; return 1; }
204047 pParse->aBlob = aNew;
204048 pParse->nBlobAlloc = t;
204049 return 0;
204050 }
204051
204052 /*
204053 ** If pParse->aBlob is not previously editable (because it is taken
204054 ** from sqlite3_value_blob(), as indicated by the fact that
204055 ** pParse->nBlobAlloc==0 and pParse->nBlob>0) then make it editable
204056 ** by making a copy into space obtained from malloc.
204057 **
204058 ** Return true on success. Return false on OOM.
204059 */
204060 static int jsonBlobMakeEditable(JsonParse *pParse, u32 nExtra){
204061 u8 *aOld;
204062 u32 nSize;
204063 assert( !pParse->bReadOnly );
204064 if( pParse->oom ) return 0;
204065 if( pParse->nBlobAlloc>0 ) return 1;
204066 aOld = pParse->aBlob;
204067 nSize = pParse->nBlob + nExtra;
204068 pParse->aBlob = 0;
204069 if( jsonBlobExpand(pParse, nSize) ){
204070 return 0;
204071 }
204072 assert( pParse->nBlobAlloc >= pParse->nBlob + nExtra );
204073 memcpy(pParse->aBlob, aOld, pParse->nBlob);
204074 return 1;
204075 }
204076
204077 /* Expand pParse->aBlob and append one bytes.
204078 */
204079 static SQLITE_NOINLINE void jsonBlobExpandAndAppendOneByte(
204080 JsonParse *pParse,
204081 u8 c
204082 ){
204083 jsonBlobExpand(pParse, pParse->nBlob+1);
204084 if( pParse->oom==0 ){
204085 assert( pParse->nBlob+1<=pParse->nBlobAlloc );
204086 pParse->aBlob[pParse->nBlob++] = c;
204087 }
204088 }
204089
204090 /* Append a single character.
204091 */
204092 static void jsonBlobAppendOneByte(JsonParse *pParse, u8 c){
204093 if( pParse->nBlob >= pParse->nBlobAlloc ){
204094 jsonBlobExpandAndAppendOneByte(pParse, c);
204095 }else{
204096 pParse->aBlob[pParse->nBlob++] = c;
204097 }
204098 }
204099
204100 /* Slow version of jsonBlobAppendNode() that first resizes the
204101 ** pParse->aBlob structure.
204102 */
204103 static void jsonBlobAppendNode(JsonParse*,u8,u32,const void*);
204104 static SQLITE_NOINLINE void jsonBlobExpandAndAppendNode(
204105 JsonParse *pParse,
204106 u8 eType,
204107 u32 szPayload,
204108 const void *aPayload
204109 ){
204110 if( jsonBlobExpand(pParse, pParse->nBlob+szPayload+9) ) return;
204111 jsonBlobAppendNode(pParse, eType, szPayload, aPayload);
204112 }
204113
204114
204115 /* Append an node type byte together with the payload size and
204116 ** possibly also the payload.
204117 **
204118 ** If aPayload is not NULL, then it is a pointer to the payload which
204119 ** is also appended. If aPayload is NULL, the pParse->aBlob[] array
204120 ** is resized (if necessary) so that it is big enough to hold the
204121 ** payload, but the payload is not appended and pParse->nBlob is left
204122 ** pointing to where the first byte of payload will eventually be.
204123 */
204124 static void jsonBlobAppendNode(
204125 JsonParse *pParse, /* The JsonParse object under construction */
204126 u8 eType, /* Node type. One of JSONB_* */
204127 u32 szPayload, /* Number of bytes of payload */
204128 const void *aPayload /* The payload. Might be NULL */
204129 ){
204130 u8 *a;
204131 if( pParse->nBlob+szPayload+9 > pParse->nBlobAlloc ){
204132 jsonBlobExpandAndAppendNode(pParse,eType,szPayload,aPayload);
204133 return;
204134 }
204135 assert( pParse->aBlob!=0 );
204136 a = &pParse->aBlob[pParse->nBlob];
204137 if( szPayload<=11 ){
204138 a[0] = eType | (szPayload<<4);
204139 pParse->nBlob += 1;
204140 }else if( szPayload<=0xff ){
204141 a[0] = eType | 0xc0;
204142 a[1] = szPayload & 0xff;
204143 pParse->nBlob += 2;
204144 }else if( szPayload<=0xffff ){
204145 a[0] = eType | 0xd0;
204146 a[1] = (szPayload >> 8) & 0xff;
204147 a[2] = szPayload & 0xff;
204148 pParse->nBlob += 3;
204149 }else{
204150 a[0] = eType | 0xe0;
204151 a[1] = (szPayload >> 24) & 0xff;
204152 a[2] = (szPayload >> 16) & 0xff;
204153 a[3] = (szPayload >> 8) & 0xff;
204154 a[4] = szPayload & 0xff;
204155 pParse->nBlob += 5;
204156 }
204157 if( aPayload ){
204158 pParse->nBlob += szPayload;
204159 memcpy(&pParse->aBlob[pParse->nBlob-szPayload], aPayload, szPayload);
204160 }
204161 }
204162
204163 /* Change the payload size for the node at index i to be szPayload.
204164 */
204165 static int jsonBlobChangePayloadSize(
204166 JsonParse *pParse,
204167 u32 i,
204168 u32 szPayload
204169 ){
204170 u8 *a;
204171 u8 szType;
204172 u8 nExtra;
204173 u8 nNeeded;
204174 int delta;
204175 if( pParse->oom ) return 0;
204176 a = &pParse->aBlob[i];
204177 szType = a[0]>>4;
204178 if( szType<=11 ){
204179 nExtra = 0;
204180 }else if( szType==12 ){
204181 nExtra = 1;
204182 }else if( szType==13 ){
204183 nExtra = 2;
204184 }else{
204185 nExtra = 4;
204186 }
204187 if( szPayload<=11 ){
204188 nNeeded = 0;
204189 }else if( szPayload<=0xff ){
204190 nNeeded = 1;
204191 }else if( szPayload<=0xffff ){
204192 nNeeded = 2;
204193 }else{
204194 nNeeded = 4;
204195 }
204196 delta = nNeeded - nExtra;
204197 if( delta ){
204198 u32 newSize = pParse->nBlob + delta;
204199 if( delta>0 ){
204200 if( newSize>pParse->nBlobAlloc && jsonBlobExpand(pParse, newSize) ){
204201 return 0; /* OOM error. Error state recorded in pParse->oom. */
204202 }
204203 a = &pParse->aBlob[i];
204204 memmove(&a[1+delta], &a[1], pParse->nBlob - (i+1));
204205 }else{
204206 memmove(&a[1], &a[1-delta], pParse->nBlob - (i+1-delta));
204207 }
204208 pParse->nBlob = newSize;
204209 }
204210 if( nNeeded==0 ){
204211 a[0] = (a[0] & 0x0f) | (szPayload<<4);
204212 }else if( nNeeded==1 ){
204213 a[0] = (a[0] & 0x0f) | 0xc0;
204214 a[1] = szPayload & 0xff;
204215 }else if( nNeeded==2 ){
204216 a[0] = (a[0] & 0x0f) | 0xd0;
204217 a[1] = (szPayload >> 8) & 0xff;
204218 a[2] = szPayload & 0xff;
204219 }else{
204220 a[0] = (a[0] & 0x0f) | 0xe0;
204221 a[1] = (szPayload >> 24) & 0xff;
204222 a[2] = (szPayload >> 16) & 0xff;
204223 a[3] = (szPayload >> 8) & 0xff;
204224 a[4] = szPayload & 0xff;
204225 }
204226 return delta;
204227 }
204228
204229 /*
204230 ** If z[0] is 'u' and is followed by exactly 4 hexadecimal character,
204231 ** then set *pOp to JSONB_TEXTJ and return true. If not, do not make
204232 ** any changes to *pOp and return false.
204233 */
204234 static int jsonIs4HexB(const char *z, int *pOp){
204235 if( z[0]!='u' ) return 0;
204236 if( !sqlite3Isxdigit(z[1]) ) return 0;
204237 if( !sqlite3Isxdigit(z[2]) ) return 0;
204238 if( !sqlite3Isxdigit(z[3]) ) return 0;
204239 if( !sqlite3Isxdigit(z[4]) ) return 0;
204240 *pOp = JSONB_TEXTJ;
204241 return 1;
204242 }
204243
204244
204245 /*
204246 ** Check a single element of the JSONB in pParse for validity.
204247 **
204248 ** The element to be checked starts at offset i and must end at on the
204249 ** last byte before iEnd.
204250 **
204251 ** Return 0 if everything is correct. Return the 1-based byte offset of the
204252 ** error if a problem is detected. (In other words, if the error is at offset
204253 ** 0, return 1).
204254 */
204255 static u32 jsonbValidityCheck(
204256 const JsonParse *pParse, /* Input JSONB. Only aBlob and nBlob are used */
204257 u32 i, /* Start of element as pParse->aBlob[i] */
204258 u32 iEnd, /* One more than the last byte of the element */
204259 u32 iDepth /* Current nesting depth */
204260 ){
204261 u32 n, sz, j, k;
204262 const u8 *z;
204263 u8 x;
204264 if( iDepth>JSON_MAX_DEPTH ) return i+1;
204265 sz = 0;
204266 n = jsonbPayloadSize(pParse, i, &sz);
204267 if( NEVER(n==0) ) return i+1; /* Checked by caller */
204268 if( NEVER(i+n+sz!=iEnd) ) return i+1; /* Checked by caller */
204269 z = pParse->aBlob;
204270 x = z[i] & 0x0f;
204271 switch( x ){
204272 case JSONB_NULL:
204273 case JSONB_TRUE:
204274 case JSONB_FALSE: {
204275 return n+sz==1 ? 0 : i+1;
204276 }
204277 case JSONB_INT: {
204278 if( sz<1 ) return i+1;
204279 j = i+n;
204280 if( z[j]=='-' ){
204281 j++;
204282 if( sz<2 ) return i+1;
204283 }
204284 k = i+n+sz;
204285 while( j<k ){
204286 if( sqlite3Isdigit(z[j]) ){
204287 j++;
204288 }else{
204289 return j+1;
204290 }
204291 }
204292 return 0;
204293 }
204294 case JSONB_INT5: {
204295 if( sz<3 ) return i+1;
204296 j = i+n;
204297 if( z[j]=='-' ){
204298 if( sz<4 ) return i+1;
204299 j++;
204300 }
204301 if( z[j]!='0' ) return i+1;
204302 if( z[j+1]!='x' && z[j+1]!='X' ) return j+2;
204303 j += 2;
204304 k = i+n+sz;
204305 while( j<k ){
204306 if( sqlite3Isxdigit(z[j]) ){
204307 j++;
204308 }else{
204309 return j+1;
204310 }
204311 }
204312 return 0;
204313 }
204314 case JSONB_FLOAT:
204315 case JSONB_FLOAT5: {
204316 u8 seen = 0; /* 0: initial. 1: '.' seen 2: 'e' seen */
204317 if( sz<2 ) return i+1;
204318 j = i+n;
204319 k = j+sz;
204320 if( z[j]=='-' ){
204321 j++;
204322 if( sz<3 ) return i+1;
204323 }
204324 if( z[j]=='.' ){
204325 if( x==JSONB_FLOAT ) return j+1;
204326 if( !sqlite3Isdigit(z[j+1]) ) return j+1;
204327 j += 2;
204328 seen = 1;
204329 }else if( z[j]=='0' && x==JSONB_FLOAT ){
204330 if( j+3>k ) return j+1;
204331 if( z[j+1]!='.' && z[j+1]!='e' && z[j+1]!='E' ) return j+1;
204332 j++;
204333 }
204334 for(; j<k; j++){
204335 if( sqlite3Isdigit(z[j]) ) continue;
204336 if( z[j]=='.' ){
204337 if( seen>0 ) return j+1;
204338 if( x==JSONB_FLOAT && (j==k-1 || !sqlite3Isdigit(z[j+1])) ){
204339 return j+1;
204340 }
204341 seen = 1;
204342 continue;
204343 }
204344 if( z[j]=='e' || z[j]=='E' ){
204345 if( seen==2 ) return j+1;
204346 if( j==k-1 ) return j+1;
204347 if( z[j+1]=='+' || z[j+1]=='-' ){
204348 j++;
204349 if( j==k-1 ) return j+1;
204350 }
204351 seen = 2;
204352 continue;
204353 }
204354 return j+1;
204355 }
204356 if( seen==0 ) return i+1;
204357 return 0;
204358 }
204359 case JSONB_TEXT: {
204360 j = i+n;
204361 k = j+sz;
204362 while( j<k ){
204363 if( !jsonIsOk[z[j]] && z[j]!='\'' ) return j+1;
204364 j++;
204365 }
204366 return 0;
204367 }
204368 case JSONB_TEXTJ:
204369 case JSONB_TEXT5: {
204370 j = i+n;
204371 k = j+sz;
204372 while( j<k ){
204373 if( !jsonIsOk[z[j]] && z[j]!='\'' ){
204374 if( z[j]=='"' ){
204375 if( x==JSONB_TEXTJ ) return j+1;
204376 }else if( z[j]!='\\' || j+1>=k ){
204377 return j+1;
204378 }else if( strchr("\"\\/bfnrt",z[j+1])!=0 ){
204379 j++;
204380 }else if( z[j+1]=='u' ){
204381 if( j+5>=k ) return j+1;
204382 if( !jsonIs4Hex((const char*)&z[j+2]) ) return j+1;
204383 j++;
204384 }else if( x!=JSONB_TEXT5 ){
204385 return j+1;
204386 }else{
204387 u32 c = 0;
204388 u32 szC = jsonUnescapeOneChar((const char*)&z[j], k-j, &c);
204389 if( c==0xfffd ) return j+1;
204390 j += szC - 1;
204391 }
204392 }
204393 j++;
204394 }
204395 return 0;
204396 }
204397 case JSONB_TEXTRAW: {
204398 return 0;
204399 }
204400 case JSONB_ARRAY: {
204401 u32 sub;
204402 j = i+n;
204403 k = j+sz;
204404 while( j<k ){
204405 sz = 0;
204406 n = jsonbPayloadSize(pParse, j, &sz);
204407 if( n==0 ) return j+1;
204408 if( j+n+sz>k ) return j+1;
204409 sub = jsonbValidityCheck(pParse, j, j+n+sz, iDepth+1);
204410 if( sub ) return sub;
204411 j += n + sz;
204412 }
204413 assert( j==k );
204414 return 0;
204415 }
204416 case JSONB_OBJECT: {
204417 u32 cnt = 0;
204418 u32 sub;
204419 j = i+n;
204420 k = j+sz;
204421 while( j<k ){
204422 sz = 0;
204423 n = jsonbPayloadSize(pParse, j, &sz);
204424 if( n==0 ) return j+1;
204425 if( j+n+sz>k ) return j+1;
204426 if( (cnt & 1)==0 ){
204427 x = z[j] & 0x0f;
204428 if( x<JSONB_TEXT || x>JSONB_TEXTRAW ) return j+1;
204429 }
204430 sub = jsonbValidityCheck(pParse, j, j+n+sz, iDepth+1);
204431 if( sub ) return sub;
204432 cnt++;
204433 j += n + sz;
204434 }
204435 assert( j==k );
204436 if( (cnt & 1)!=0 ) return j+1;
204437 return 0;
204438 }
204439 default: {
204440 return i+1;
204441 }
204442 }
204443 }
204444
204445 /*
204446 ** Translate a single element of JSON text at pParse->zJson[i] into
204447 ** its equivalent binary JSONB representation. Append the translation into
204448 ** pParse->aBlob[] beginning at pParse->nBlob. The size of
204449 ** pParse->aBlob[] is increased as necessary.
204450 **
204451 ** Return the index of the first character past the end of the element parsed,
204452 ** or one of the following special result codes:
204453 **
204454 ** 0 End of input
204455 ** -1 Syntax error or OOM
204456 ** -2 '}' seen \
204457 ** -3 ']' seen \___ For these returns, pParse->iErr is set to
204458 ** -4 ',' seen / the index in zJson[] of the seen character
204459 ** -5 ':' seen /
204460 */
204461 static int jsonXlateTextToBlob(JsonParse *pParse, u32 i){
204462 char c;
204463 u32 j;
204464 u32 iThis, iStart;
204465 int x;
204466 u8 t;
204467 const char *z = pParse->zJson;
204468 json_parse_restart:
204469 switch( (u8)z[i] ){
204470 case '{': {
204471 /* Parse object */
204472 iThis = pParse->nBlob;
204473 jsonBlobAppendNode(pParse, JSONB_OBJECT, pParse->nJson-i, 0);
204474 if( ++pParse->iDepth > JSON_MAX_DEPTH ){
204475 pParse->iErr = i;
204476 return -1;
204477 }
204478 iStart = pParse->nBlob;
204479 for(j=i+1;;j++){
204480 u32 iBlob = pParse->nBlob;
204481 x = jsonXlateTextToBlob(pParse, j);
204482 if( x<=0 ){
204483 int op;
204484 if( x==(-2) ){
204485 j = pParse->iErr;
204486 if( pParse->nBlob!=(u32)iStart ) pParse->hasNonstd = 1;
204487 break;
204488 }
204489 j += json5Whitespace(&z[j]);
204490 op = JSONB_TEXT;
204491 if( sqlite3JsonId1(z[j])
204492 || (z[j]=='\\' && jsonIs4HexB(&z[j+1], &op))
204493 ){
204494 int k = j+1;
204495 while( (sqlite3JsonId2(z[k]) && json5Whitespace(&z[k])==0)
204496 || (z[k]=='\\' && jsonIs4HexB(&z[k+1], &op))
204497 ){
204498 k++;
204499 }
204500 assert( iBlob==pParse->nBlob );
204501 jsonBlobAppendNode(pParse, op, k-j, &z[j]);
204502 pParse->hasNonstd = 1;
204503 x = k;
204504 }else{
204505 if( x!=-1 ) pParse->iErr = j;
204506 return -1;
204507 }
204508 }
204509 if( pParse->oom ) return -1;
204510 t = pParse->aBlob[iBlob] & 0x0f;
204511 if( t<JSONB_TEXT || t>JSONB_TEXTRAW ){
204512 pParse->iErr = j;
204513 return -1;
204514 }
 
204515 j = x;
204516 if( z[j]==':' ){
204517 j++;
204518 }else{
204519 if( jsonIsspace(z[j]) ){
204520 /* strspn() is not helpful here */
204521 do{ j++; }while( jsonIsspace(z[j]) );
204522 if( z[j]==':' ){
204523 j++;
204524 goto parse_object_value;
204525 }
204526 }
204527 x = jsonXlateTextToBlob(pParse, j);
204528 if( x!=(-5) ){
204529 if( x!=(-1) ) pParse->iErr = j;
204530 return -1;
204531 }
204532 j = pParse->iErr+1;
204533 }
204534 parse_object_value:
204535 x = jsonXlateTextToBlob(pParse, j);
204536 if( x<=0 ){
204537 if( x!=(-1) ) pParse->iErr = j;
204538 return -1;
204539 }
204540 j = x;
@@ -204058,19 +204541,19 @@
204541 if( z[j]==',' ){
204542 continue;
204543 }else if( z[j]=='}' ){
204544 break;
204545 }else{
204546 if( jsonIsspace(z[j]) ){
204547 j += 1 + (u32)strspn(&z[j+1], jsonSpaces);
204548 if( z[j]==',' ){
204549 continue;
204550 }else if( z[j]=='}' ){
204551 break;
204552 }
204553 }
204554 x = jsonXlateTextToBlob(pParse, j);
204555 if( x==(-4) ){
204556 j = pParse->iErr;
204557 continue;
204558 }
204559 if( x==(-2) ){
@@ -204079,29 +204562,30 @@
204562 }
204563 }
204564 pParse->iErr = j;
204565 return -1;
204566 }
204567 jsonBlobChangePayloadSize(pParse, iThis, pParse->nBlob - iStart);
204568 pParse->iDepth--;
204569 return j+1;
204570 }
204571 case '[': {
204572 /* Parse array */
204573 iThis = pParse->nBlob;
204574 jsonBlobAppendNode(pParse, JSONB_ARRAY, pParse->nJson - i, 0);
204575 iStart = pParse->nBlob;
204576 if( pParse->oom ) return -1;
204577 if( ++pParse->iDepth > JSON_MAX_DEPTH ){
204578 pParse->iErr = i;
204579 return -1;
204580 }
 
204581 for(j=i+1;;j++){
204582 x = jsonXlateTextToBlob(pParse, j);
204583 if( x<=0 ){
204584 if( x==(-3) ){
204585 j = pParse->iErr;
204586 if( pParse->nBlob!=iStart ) pParse->hasNonstd = 1;
204587 break;
204588 }
204589 if( x!=(-1) ) pParse->iErr = j;
204590 return -1;
204591 }
@@ -204109,19 +204593,19 @@
204593 if( z[j]==',' ){
204594 continue;
204595 }else if( z[j]==']' ){
204596 break;
204597 }else{
204598 if( jsonIsspace(z[j]) ){
204599 j += 1 + (u32)strspn(&z[j+1], jsonSpaces);
204600 if( z[j]==',' ){
204601 continue;
204602 }else if( z[j]==']' ){
204603 break;
204604 }
204605 }
204606 x = jsonXlateTextToBlob(pParse, j);
204607 if( x==(-4) ){
204608 j = pParse->iErr;
204609 continue;
204610 }
204611 if( x==(-3) ){
@@ -204130,86 +204614,98 @@
204614 }
204615 }
204616 pParse->iErr = j;
204617 return -1;
204618 }
204619 jsonBlobChangePayloadSize(pParse, iThis, pParse->nBlob - iStart);
204620 pParse->iDepth--;
204621 return j+1;
204622 }
204623 case '\'': {
204624 u8 opcode;
204625 char cDelim;
204626 pParse->hasNonstd = 1;
204627 opcode = JSONB_TEXT;
204628 goto parse_string;
204629 case '"':
204630 /* Parse string */
204631 opcode = JSONB_TEXT;
204632 parse_string:
204633 cDelim = z[i];
204634 j = i+1;
204635 while( 1 /*exit-by-break*/ ){
204636 if( jsonIsOk[(u8)z[j]] ){
204637 if( !jsonIsOk[(u8)z[j+1]] ){
204638 j += 1;
204639 }else if( !jsonIsOk[(u8)z[j+2]] ){
204640 j += 2;
204641 }else{
204642 j += 3;
204643 continue;
204644 }
204645 }
204646 c = z[j];
204647 if( c==cDelim ){
204648 break;
204649 }else if( c=='\\' ){
204650 c = z[++j];
204651 if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f'
204652 || c=='n' || c=='r' || c=='t'
204653 || (c=='u' && jsonIs4Hex(&z[j+1])) ){
204654 if( opcode==JSONB_TEXT ) opcode = JSONB_TEXTJ;
204655 }else if( c=='\'' || c=='0' || c=='v' || c=='\n'
204656 || (0xe2==(u8)c && 0x80==(u8)z[j+1]
204657 && (0xa8==(u8)z[j+2] || 0xa9==(u8)z[j+2]))
204658 || (c=='x' && jsonIs2Hex(&z[j+1])) ){
204659 opcode = JSONB_TEXT5;
204660 pParse->hasNonstd = 1;
204661 }else if( c=='\r' ){
204662 if( z[j+1]=='\n' ) j++;
204663 opcode = JSONB_TEXT5;
204664 pParse->hasNonstd = 1;
204665 }else{
204666 pParse->iErr = j;
204667 return -1;
204668 }
204669 }else if( c<=0x1f ){
204670 /* Control characters are not allowed in strings */
204671 pParse->iErr = j;
204672 return -1;
204673 }else if( c=='"' ){
204674 opcode = JSONB_TEXT5;
204675 }
204676 j++;
204677 }
204678 jsonBlobAppendNode(pParse, opcode, j-1-i, &z[i+1]);
204679 return j+1;
204680 }
204681 case 't': {
204682 if( strncmp(z+i,"true",4)==0 && !sqlite3Isalnum(z[i+4]) ){
204683 jsonBlobAppendOneByte(pParse, JSONB_TRUE);
204684 return i+4;
204685 }
204686 pParse->iErr = i;
204687 return -1;
204688 }
204689 case 'f': {
204690 if( strncmp(z+i,"false",5)==0 && !sqlite3Isalnum(z[i+5]) ){
204691 jsonBlobAppendOneByte(pParse, JSONB_FALSE);
204692 return i+5;
204693 }
204694 pParse->iErr = i;
204695 return -1;
204696 }
204697 case '+': {
204698 u8 seenE;
204699 pParse->hasNonstd = 1;
204700 t = 0x00; /* Bit 0x01: JSON5. Bit 0x02: FLOAT */
204701 goto parse_number;
204702 case '.':
204703 if( sqlite3Isdigit(z[i+1]) ){
204704 pParse->hasNonstd = 1;
204705 t = 0x03; /* Bit 0x01: JSON5. Bit 0x02: FLOAT */
204706 seenE = 0;
 
204707 goto parse_number_2;
204708 }
204709 pParse->iErr = i;
204710 return -1;
204711 case '-':
@@ -204222,25 +204718,24 @@
204718 case '6':
204719 case '7':
204720 case '8':
204721 case '9':
204722 /* Parse number */
204723 t = 0x00; /* Bit 0x01: JSON5. Bit 0x02: FLOAT */
204724 parse_number:
 
204725 seenE = 0;
204726 assert( '-' < '0' );
204727 assert( '+' < '0' );
204728 assert( '.' < '0' );
204729 c = z[i];
204730
204731 if( c<='0' ){
204732 if( c=='0' ){
204733 if( (z[i+1]=='x' || z[i+1]=='X') && sqlite3Isxdigit(z[i+2]) ){
204734 assert( t==0x00 );
204735 pParse->hasNonstd = 1;
204736 t = 0x01;
204737 for(j=i+3; sqlite3Isxdigit(z[j]); j++){}
204738 goto parse_number_finish;
204739 }else if( sqlite3Isdigit(z[i+1]) ){
204740 pParse->iErr = i+1;
204741 return -1;
@@ -204253,19 +204748,19 @@
204748 if( (z[i+1]=='I' || z[i+1]=='i')
204749 && sqlite3StrNICmp(&z[i+1], "inf",3)==0
204750 ){
204751 pParse->hasNonstd = 1;
204752 if( z[i]=='-' ){
204753 jsonBlobAppendNode(pParse, JSONB_FLOAT, 6, "-9e999");
204754 }else{
204755 jsonBlobAppendNode(pParse, JSONB_FLOAT, 5, "9e999");
204756 }
204757 return i + (sqlite3StrNICmp(&z[i+4],"inity",5)==0 ? 9 : 4);
204758 }
204759 if( z[i+1]=='.' ){
204760 pParse->hasNonstd = 1;
204761 t |= 0x01;
204762 goto parse_number_2;
204763 }
204764 pParse->iErr = i;
204765 return -1;
204766 }
@@ -204273,44 +204768,45 @@
204768 if( sqlite3Isdigit(z[i+2]) ){
204769 pParse->iErr = i+1;
204770 return -1;
204771 }else if( (z[i+2]=='x' || z[i+2]=='X') && sqlite3Isxdigit(z[i+3]) ){
204772 pParse->hasNonstd = 1;
204773 t |= 0x01;
204774 for(j=i+4; sqlite3Isxdigit(z[j]); j++){}
204775 goto parse_number_finish;
204776 }
204777 }
204778 }
204779 }
204780
204781 parse_number_2:
204782 for(j=i+1;; j++){
204783 c = z[j];
204784 if( sqlite3Isdigit(c) ) continue;
204785 if( c=='.' ){
204786 if( (t & 0x02)!=0 ){
204787 pParse->iErr = j;
204788 return -1;
204789 }
204790 t |= 0x02;
204791 continue;
204792 }
204793 if( c=='e' || c=='E' ){
204794 if( z[j-1]<'0' ){
204795 if( ALWAYS(z[j-1]=='.') && ALWAYS(j-2>=i) && sqlite3Isdigit(z[j-2]) ){
204796 pParse->hasNonstd = 1;
204797 t |= 0x01;
204798 }else{
204799 pParse->iErr = j;
204800 return -1;
204801 }
204802 }
204803 if( seenE ){
204804 pParse->iErr = j;
204805 return -1;
204806 }
204807 t |= 0x02;
204808 seenE = 1;
204809 c = z[j+1];
204810 if( c=='+' || c=='-' ){
204811 j++;
204812 c = z[j+1];
@@ -204324,18 +204820,22 @@
204820 break;
204821 }
204822 if( z[j-1]<'0' ){
204823 if( ALWAYS(z[j-1]=='.') && ALWAYS(j-2>=i) && sqlite3Isdigit(z[j-2]) ){
204824 pParse->hasNonstd = 1;
204825 t |= 0x01;
204826 }else{
204827 pParse->iErr = j;
204828 return -1;
204829 }
204830 }
204831 parse_number_finish:
204832 assert( JSONB_INT+0x01==JSONB_INT5 );
204833 assert( JSONB_FLOAT+0x01==JSONB_FLOAT5 );
204834 assert( JSONB_INT+0x02==JSONB_FLOAT );
204835 if( z[i]=='+' ) i++;
204836 jsonBlobAppendNode(pParse, JSONB_INT+t, j-i, &z[i]);
204837 return j;
204838 }
204839 case '}': {
204840 pParse->iErr = i;
204841 return -2; /* End of {...} */
@@ -204357,13 +204857,11 @@
204857 }
204858 case 0x09:
204859 case 0x0a:
204860 case 0x0d:
204861 case 0x20: {
204862 i += 1 + (u32)strspn(&z[i+1], jsonSpaces);
 
 
204863 goto json_parse_restart;
204864 }
204865 case 0x0b:
204866 case 0x0c:
204867 case '/':
@@ -204381,11 +204879,11 @@
204879 pParse->iErr = i;
204880 return -1;
204881 }
204882 case 'n': {
204883 if( strncmp(z+i,"null",4)==0 && !sqlite3Isalnum(z[i+4]) ){
204884 jsonBlobAppendOneByte(pParse, JSONB_NULL);
204885 return i+4;
204886 }
204887 /* fall-through into the default case that checks for NaN */
204888 }
204889 default: {
@@ -204397,43 +204895,53 @@
204895 nn = aNanInfName[k].n;
204896 if( sqlite3StrNICmp(&z[i], aNanInfName[k].zMatch, nn)!=0 ){
204897 continue;
204898 }
204899 if( sqlite3Isalnum(z[i+nn]) ) continue;
204900 if( aNanInfName[k].eType==JSONB_FLOAT ){
204901 jsonBlobAppendNode(pParse, JSONB_FLOAT, 5, "9e999");
204902 }else{
204903 jsonBlobAppendOneByte(pParse, JSONB_NULL);
204904 }
204905 pParse->hasNonstd = 1;
204906 return i + nn;
204907 }
204908 pParse->iErr = i;
204909 return -1; /* Syntax error */
204910 }
204911 } /* End switch(z[i]) */
204912 }
204913
204914
204915 /*
204916 ** Parse a complete JSON string. Return 0 on success or non-zero if there
204917 ** are any errors. If an error occurs, free all memory held by pParse,
204918 ** but not pParse itself.
204919 **
204920 ** pParse must be initialized to an empty parse object prior to calling
204921 ** this routine.
204922 */
204923 static int jsonConvertTextToBlob(
204924 JsonParse *pParse, /* Initialize and fill this JsonParse object */
204925 sqlite3_context *pCtx /* Report errors here */
204926 ){
204927 int i;
204928 const char *zJson = pParse->zJson;
204929 i = jsonXlateTextToBlob(pParse, 0);
204930 if( pParse->oom ) i = -1;
204931 if( i>0 ){
204932 #ifdef SQLITE_DEBUG
204933 assert( pParse->iDepth==0 );
204934 if( sqlite3Config.bJsonSelfcheck ){
204935 assert( jsonbValidityCheck(pParse, 0, pParse->nBlob, 0)==0 );
204936 }
204937 #endif
204938 while( jsonIsspace(zJson[i]) ) i++;
204939 if( zJson[i] ){
204940 i += json5Whitespace(&zJson[i]);
204941 if( zJson[i] ){
204942 if( pCtx ) sqlite3_result_error(pCtx, "malformed JSON", -1);
204943 jsonParseReset(pParse);
204944 return 1;
204945 }
204946 pParse->hasNonstd = 1;
204947 }
@@ -204450,617 +204958,1508 @@
204958 return 1;
204959 }
204960 return 0;
204961 }
204962
204963 /*
204964 ** The input string pStr is a well-formed JSON text string. Convert
204965 ** this into the JSONB format and make it the return value of the
204966 ** SQL function.
204967 */
204968 static void jsonReturnStringAsBlob(JsonString *pStr){
204969 JsonParse px;
204970 memset(&px, 0, sizeof(px));
204971 jsonStringTerminate(pStr);
204972 px.zJson = pStr->zBuf;
204973 px.nJson = pStr->nUsed;
204974 (void)jsonXlateTextToBlob(&px, 0);
204975 if( px.oom ){
204976 sqlite3_free(px.aBlob);
204977 sqlite3_result_error_nomem(pStr->pCtx);
204978 }else{
204979 assert( px.nBlobAlloc>0 );
204980 assert( !px.bReadOnly );
204981 sqlite3_result_blob(pStr->pCtx, px.aBlob, px.nBlob, sqlite3_free);
204982 }
204983 }
204984
204985 /* The byte at index i is a node type-code. This routine
204986 ** determines the payload size for that node and writes that
204987 ** payload size in to *pSz. It returns the offset from i to the
204988 ** beginning of the payload. Return 0 on error.
204989 */
204990 static u32 jsonbPayloadSize(const JsonParse *pParse, u32 i, u32 *pSz){
204991 u8 x;
204992 u32 sz;
204993 u32 n;
204994 if( NEVER(i>pParse->nBlob) ){
204995 *pSz = 0;
204996 return 0;
204997 }
204998 x = pParse->aBlob[i]>>4;
204999 if( x<=11 ){
205000 sz = x;
205001 n = 1;
205002 }else if( x==12 ){
205003 if( i+1>=pParse->nBlob ){
205004 *pSz = 0;
205005 return 0;
205006 }
205007 sz = pParse->aBlob[i+1];
205008 n = 2;
205009 }else if( x==13 ){
205010 if( i+2>=pParse->nBlob ){
205011 *pSz = 0;
205012 return 0;
205013 }
205014 sz = (pParse->aBlob[i+1]<<8) + pParse->aBlob[i+2];
205015 n = 3;
205016 }else if( x==14 ){
205017 if( i+4>=pParse->nBlob ){
205018 *pSz = 0;
205019 return 0;
205020 }
205021 sz = ((u32)pParse->aBlob[i+1]<<24) + (pParse->aBlob[i+2]<<16) +
205022 (pParse->aBlob[i+3]<<8) + pParse->aBlob[i+4];
205023 n = 5;
205024 }else{
205025 if( i+8>=pParse->nBlob
205026 || pParse->aBlob[i+1]!=0
205027 || pParse->aBlob[i+2]!=0
205028 || pParse->aBlob[i+3]!=0
205029 || pParse->aBlob[i+4]!=0
205030 ){
205031 *pSz = 0;
205032 return 0;
205033 }
205034 sz = (pParse->aBlob[i+5]<<24) + (pParse->aBlob[i+6]<<16) +
205035 (pParse->aBlob[i+7]<<8) + pParse->aBlob[i+8];
205036 n = 9;
205037 }
205038 if( i+sz+n > pParse->nBlob
205039 && i+sz+n > pParse->nBlob-pParse->delta
205040 ){
205041 sz = 0;
205042 n = 0;
205043 }
205044 *pSz = sz;
205045 return n;
205046 }
205047
205048
205049 /*
205050 ** Translate the binary JSONB representation of JSON beginning at
205051 ** pParse->aBlob[i] into a JSON text string. Append the JSON
205052 ** text onto the end of pOut. Return the index in pParse->aBlob[]
205053 ** of the first byte past the end of the element that is translated.
205054 **
205055 ** If an error is detected in the BLOB input, the pOut->eErr flag
205056 ** might get set to JSTRING_MALFORMED. But not all BLOB input errors
205057 ** are detected. So a malformed JSONB input might either result
205058 ** in an error, or in incorrect JSON.
205059 **
205060 ** The pOut->eErr JSTRING_OOM flag is set on a OOM.
205061 */
205062 static u32 jsonXlateBlobToText(
205063 const JsonParse *pParse, /* the complete parse of the JSON */
205064 u32 i, /* Start rendering at this index */
205065 JsonString *pOut /* Write JSON here */
205066 ){
205067 u32 sz, n, j, iEnd;
205068
205069 n = jsonbPayloadSize(pParse, i, &sz);
205070 if( n==0 ){
205071 pOut->eErr |= JSTRING_MALFORMED;
205072 return pParse->nBlob+1;
205073 }
205074 switch( pParse->aBlob[i] & 0x0f ){
205075 case JSONB_NULL: {
205076 jsonAppendRawNZ(pOut, "null", 4);
205077 return i+1;
205078 }
205079 case JSONB_TRUE: {
205080 jsonAppendRawNZ(pOut, "true", 4);
205081 return i+1;
205082 }
205083 case JSONB_FALSE: {
205084 jsonAppendRawNZ(pOut, "false", 5);
205085 return i+1;
205086 }
205087 case JSONB_INT:
205088 case JSONB_FLOAT: {
205089 jsonAppendRaw(pOut, (const char*)&pParse->aBlob[i+n], sz);
205090 break;
205091 }
205092 case JSONB_INT5: { /* Integer literal in hexadecimal notation */
205093 u32 k = 2;
205094 sqlite3_uint64 u = 0;
205095 const char *zIn = (const char*)&pParse->aBlob[i+n];
205096 int bOverflow = 0;
205097 if( zIn[0]=='-' ){
205098 jsonAppendChar(pOut, '-');
205099 k++;
205100 }else if( zIn[0]=='+' ){
205101 k++;
205102 }
205103 for(; k<sz; k++){
205104 if( !sqlite3Isxdigit(zIn[k]) ){
205105 pOut->eErr |= JSTRING_MALFORMED;
205106 break;
205107 }else if( (u>>60)!=0 ){
205108 bOverflow = 1;
205109 }else{
205110 u = u*16 + sqlite3HexToInt(zIn[k]);
205111 }
205112 }
205113 jsonPrintf(100,pOut,bOverflow?"9.0e999":"%llu", u);
205114 break;
205115 }
205116 case JSONB_FLOAT5: { /* Float literal missing digits beside "." */
205117 u32 k = 0;
205118 const char *zIn = (const char*)&pParse->aBlob[i+n];
205119 if( zIn[0]=='-' ){
205120 jsonAppendChar(pOut, '-');
205121 k++;
205122 }
205123 if( zIn[k]=='.' ){
205124 jsonAppendChar(pOut, '0');
205125 }
205126 for(; k<sz; k++){
205127 jsonAppendChar(pOut, zIn[k]);
205128 if( zIn[k]=='.' && (k+1==sz || !sqlite3Isdigit(zIn[k+1])) ){
205129 jsonAppendChar(pOut, '0');
205130 }
205131 }
205132 break;
205133 }
205134 case JSONB_TEXT:
205135 case JSONB_TEXTJ: {
205136 jsonAppendChar(pOut, '"');
205137 jsonAppendRaw(pOut, (const char*)&pParse->aBlob[i+n], sz);
205138 jsonAppendChar(pOut, '"');
205139 break;
205140 }
205141 case JSONB_TEXT5: {
205142 const char *zIn;
205143 u32 k;
205144 u32 sz2 = sz;
205145 zIn = (const char*)&pParse->aBlob[i+n];
205146 jsonAppendChar(pOut, '"');
205147 while( sz2>0 ){
205148 for(k=0; k<sz2 && zIn[k]!='\\' && zIn[k]!='"'; k++){}
205149 if( k>0 ){
205150 jsonAppendRawNZ(pOut, zIn, k);
205151 if( k>=sz2 ){
205152 break;
205153 }
205154 zIn += k;
205155 sz2 -= k;
205156 }
205157 if( zIn[0]=='"' ){
205158 jsonAppendRawNZ(pOut, "\\\"", 2);
205159 zIn++;
205160 sz2--;
205161 continue;
205162 }
205163 assert( zIn[0]=='\\' );
205164 assert( sz2>=1 );
205165 if( sz2<2 ){
205166 pOut->eErr |= JSTRING_MALFORMED;
205167 break;
205168 }
205169 switch( (u8)zIn[1] ){
205170 case '\'':
205171 jsonAppendChar(pOut, '\'');
205172 break;
205173 case 'v':
205174 jsonAppendRawNZ(pOut, "\\u0009", 6);
205175 break;
205176 case 'x':
205177 if( sz2<4 ){
205178 pOut->eErr |= JSTRING_MALFORMED;
205179 sz2 = 2;
205180 break;
205181 }
205182 jsonAppendRawNZ(pOut, "\\u00", 4);
205183 jsonAppendRawNZ(pOut, &zIn[2], 2);
205184 zIn += 2;
205185 sz2 -= 2;
205186 break;
205187 case '0':
205188 jsonAppendRawNZ(pOut, "\\u0000", 6);
205189 break;
205190 case '\r':
205191 if( sz2>2 && zIn[2]=='\n' ){
205192 zIn++;
205193 sz2--;
205194 }
205195 break;
205196 case '\n':
205197 break;
205198 case 0xe2:
205199 /* '\' followed by either U+2028 or U+2029 is ignored as
205200 ** whitespace. Not that in UTF8, U+2028 is 0xe2 0x80 0x29.
205201 ** U+2029 is the same except for the last byte */
205202 if( sz2<4
205203 || 0x80!=(u8)zIn[2]
205204 || (0xa8!=(u8)zIn[3] && 0xa9!=(u8)zIn[3])
205205 ){
205206 pOut->eErr |= JSTRING_MALFORMED;
205207 sz2 = 2;
205208 break;
205209 }
205210 zIn += 2;
205211 sz2 -= 2;
205212 break;
205213 default:
205214 jsonAppendRawNZ(pOut, zIn, 2);
205215 break;
205216 }
205217 assert( sz2>=2 );
205218 zIn += 2;
205219 sz2 -= 2;
205220 }
205221 jsonAppendChar(pOut, '"');
205222 break;
205223 }
205224 case JSONB_TEXTRAW: {
205225 jsonAppendString(pOut, (const char*)&pParse->aBlob[i+n], sz);
205226 break;
205227 }
205228 case JSONB_ARRAY: {
205229 jsonAppendChar(pOut, '[');
205230 j = i+n;
205231 iEnd = j+sz;
205232 while( j<iEnd ){
205233 j = jsonXlateBlobToText(pParse, j, pOut);
205234 jsonAppendChar(pOut, ',');
205235 }
205236 if( sz>0 ) pOut->nUsed--;
205237 jsonAppendChar(pOut, ']');
205238 break;
205239 }
205240 case JSONB_OBJECT: {
205241 int x = 0;
205242 jsonAppendChar(pOut, '{');
205243 j = i+n;
205244 iEnd = j+sz;
205245 while( j<iEnd ){
205246 j = jsonXlateBlobToText(pParse, j, pOut);
205247 jsonAppendChar(pOut, (x++ & 1) ? ',' : ':');
205248 }
205249 if( x & 1 ) pOut->eErr |= JSTRING_MALFORMED;
205250 if( sz>0 ) pOut->nUsed--;
205251 jsonAppendChar(pOut, '}');
205252 break;
205253 }
205254
205255 default: {
205256 pOut->eErr |= JSTRING_MALFORMED;
205257 break;
205258 }
205259 }
205260 return i+n+sz;
205261 }
205262
205263 /* Return true if the input pJson
205264 **
205265 ** For performance reasons, this routine does not do a detailed check of the
205266 ** input BLOB to ensure that it is well-formed. Hence, false positives are
205267 ** possible. False negatives should never occur, however.
205268 */
205269 static int jsonFuncArgMightBeBinary(sqlite3_value *pJson){
205270 u32 sz, n;
205271 const u8 *aBlob;
205272 int nBlob;
205273 JsonParse s;
205274 if( sqlite3_value_type(pJson)!=SQLITE_BLOB ) return 0;
205275 aBlob = sqlite3_value_blob(pJson);
205276 nBlob = sqlite3_value_bytes(pJson);
205277 if( nBlob<1 ) return 0;
205278 if( NEVER(aBlob==0) || (aBlob[0] & 0x0f)>JSONB_OBJECT ) return 0;
205279 memset(&s, 0, sizeof(s));
205280 s.aBlob = (u8*)aBlob;
205281 s.nBlob = nBlob;
205282 n = jsonbPayloadSize(&s, 0, &sz);
205283 if( n==0 ) return 0;
205284 if( sz+n!=(u32)nBlob ) return 0;
205285 if( (aBlob[0] & 0x0f)<=JSONB_FALSE && sz>0 ) return 0;
205286 return sz+n==(u32)nBlob;
205287 }
205288
205289 /*
205290 ** Given that a JSONB_ARRAY object starts at offset i, return
205291 ** the number of entries in that array.
205292 */
205293 static u32 jsonbArrayCount(JsonParse *pParse, u32 iRoot){
205294 u32 n, sz, i, iEnd;
205295 u32 k = 0;
205296 n = jsonbPayloadSize(pParse, iRoot, &sz);
205297 iEnd = iRoot+n+sz;
205298 for(i=iRoot+n; n>0 && i<iEnd; i+=sz+n, k++){
205299 n = jsonbPayloadSize(pParse, i, &sz);
205300 }
205301 return k;
205302 }
205303
205304 /*
205305 ** Edit the payload size of the element at iRoot by the amount in
205306 ** pParse->delta.
205307 */
205308 static void jsonAfterEditSizeAdjust(JsonParse *pParse, u32 iRoot){
205309 u32 sz = 0;
205310 u32 nBlob;
205311 assert( pParse->delta!=0 );
205312 assert( pParse->nBlobAlloc >= pParse->nBlob );
205313 nBlob = pParse->nBlob;
205314 pParse->nBlob = pParse->nBlobAlloc;
205315 (void)jsonbPayloadSize(pParse, iRoot, &sz);
205316 pParse->nBlob = nBlob;
205317 sz += pParse->delta;
205318 pParse->delta += jsonBlobChangePayloadSize(pParse, iRoot, sz);
205319 }
205320
205321 /*
205322 ** Modify the JSONB blob at pParse->aBlob by removing nDel bytes of
205323 ** content beginning at iDel, and replacing them with nIns bytes of
205324 ** content given by aIns.
205325 **
205326 ** nDel may be zero, in which case no bytes are removed. But iDel is
205327 ** still important as new bytes will be insert beginning at iDel.
205328 **
205329 ** aIns may be zero, in which case space is created to hold nIns bytes
205330 ** beginning at iDel, but that space is uninitialized.
205331 **
205332 ** Set pParse->oom if an OOM occurs.
205333 */
205334 static void jsonBlobEdit(
205335 JsonParse *pParse, /* The JSONB to be modified is in pParse->aBlob */
205336 u32 iDel, /* First byte to be removed */
205337 u32 nDel, /* Number of bytes to remove */
205338 const u8 *aIns, /* Content to insert */
205339 u32 nIns /* Bytes of content to insert */
205340 ){
205341 i64 d = (i64)nIns - (i64)nDel;
205342 if( d!=0 ){
205343 if( pParse->nBlob + d > pParse->nBlobAlloc ){
205344 jsonBlobExpand(pParse, pParse->nBlob+d);
205345 if( pParse->oom ) return;
205346 }
205347 memmove(&pParse->aBlob[iDel+nIns],
205348 &pParse->aBlob[iDel+nDel],
205349 pParse->nBlob - (iDel+nDel));
205350 pParse->nBlob += d;
205351 pParse->delta += d;
205352 }
205353 if( nIns && aIns ) memcpy(&pParse->aBlob[iDel], aIns, nIns);
205354 }
205355
205356 /*
205357 ** Return the number of escaped newlines to be ignored.
205358 ** An escaped newline is a one of the following byte sequences:
205359 **
205360 ** 0x5c 0x0a
205361 ** 0x5c 0x0d
205362 ** 0x5c 0x0d 0x0a
205363 ** 0x5c 0xe2 0x80 0xa8
205364 ** 0x5c 0xe2 0x80 0xa9
205365 */
205366 static u32 jsonBytesToBypass(const char *z, u32 n){
205367 u32 i = 0;
205368 while( i+1<n ){
205369 if( z[i]!='\\' ) return i;
205370 if( z[i+1]=='\n' ){
205371 i += 2;
205372 continue;
205373 }
205374 if( z[i+1]=='\r' ){
205375 if( i+2<n && z[i+2]=='\n' ){
205376 i += 3;
205377 }else{
205378 i += 2;
205379 }
205380 continue;
205381 }
205382 if( 0xe2==(u8)z[i+1]
205383 && i+3<n
205384 && 0x80==(u8)z[i+2]
205385 && (0xa8==(u8)z[i+3] || 0xa9==(u8)z[i+3])
205386 ){
205387 i += 4;
205388 continue;
205389 }
205390 break;
205391 }
205392 return i;
205393 }
205394
205395 /*
205396 ** Input z[0..n] defines JSON escape sequence including the leading '\\'.
205397 ** Decode that escape sequence into a single character. Write that
205398 ** character into *piOut. Return the number of bytes in the escape sequence.
205399 */
205400 static u32 jsonUnescapeOneChar(const char *z, u32 n, u32 *piOut){
205401 assert( n>0 );
205402 assert( z[0]=='\\' );
205403 if( n<2 ){
205404 *piOut = 0xFFFD;
205405 return n;
205406 }
205407 switch( (u8)z[1] ){
205408 case 'u': {
205409 u32 v, vlo;
205410 if( n<6 ){
205411 *piOut = 0xFFFD;
205412 return n;
205413 }
205414 v = jsonHexToInt4(&z[2]);
205415 if( (v & 0xfc00)==0xd800
205416 && n>=12
205417 && z[6]=='\\'
205418 && z[7]=='u'
205419 && ((vlo = jsonHexToInt4(&z[8]))&0xfc00)==0xdc00
205420 ){
205421 *piOut = ((v&0x3ff)<<10) + (vlo&0x3ff) + 0x10000;
205422 return 12;
205423 }else{
205424 *piOut = v;
205425 return 6;
205426 }
205427 }
205428 case 'b': { *piOut = '\b'; return 2; }
205429 case 'f': { *piOut = '\f'; return 2; }
205430 case 'n': { *piOut = '\n'; return 2; }
205431 case 'r': { *piOut = '\r'; return 2; }
205432 case 't': { *piOut = '\t'; return 2; }
205433 case 'v': { *piOut = '\v'; return 2; }
205434 case '0': { *piOut = 0; return 2; }
205435 case '\'':
205436 case '"':
205437 case '/':
205438 case '\\':{ *piOut = z[1]; return 2; }
205439 case 'x': {
205440 if( n<4 ){
205441 *piOut = 0xFFFD;
205442 return n;
205443 }
205444 *piOut = (jsonHexToInt(z[2])<<4) | jsonHexToInt(z[3]);
205445 return 4;
205446 }
205447 case 0xe2:
205448 case '\r':
205449 case '\n': {
205450 u32 nSkip = jsonBytesToBypass(z, n);
205451 if( nSkip==0 ){
205452 *piOut = 0xFFFD;
205453 return n;
205454 }else if( nSkip==n ){
205455 *piOut = 0;
205456 return n;
205457 }else if( z[nSkip]=='\\' ){
205458 return nSkip + jsonUnescapeOneChar(&z[nSkip], n-nSkip, piOut);
205459 }else{
205460 int sz = sqlite3Utf8ReadLimited((u8*)&z[nSkip], n-nSkip, piOut);
205461 return nSkip + sz;
205462 }
205463 }
205464 default: {
205465 *piOut = 0xFFFD;
205466 return 2;
205467 }
205468 }
205469 }
205470
205471
205472 /*
205473 ** Compare two object labels. Return 1 if they are equal and
205474 ** 0 if they differ.
205475 **
205476 ** In this version, we know that one or the other or both of the
205477 ** two comparands contains an escape sequence.
205478 */
205479 static SQLITE_NOINLINE int jsonLabelCompareEscaped(
205480 const char *zLeft, /* The left label */
205481 u32 nLeft, /* Size of the left label in bytes */
205482 int rawLeft, /* True if zLeft contains no escapes */
205483 const char *zRight, /* The right label */
205484 u32 nRight, /* Size of the right label in bytes */
205485 int rawRight /* True if zRight is escape-free */
205486 ){
205487 u32 cLeft, cRight;
205488 assert( rawLeft==0 || rawRight==0 );
205489 while( 1 /*exit-by-return*/ ){
205490 if( nLeft==0 ){
205491 cLeft = 0;
205492 }else if( rawLeft || zLeft[0]!='\\' ){
205493 cLeft = ((u8*)zLeft)[0];
205494 if( cLeft>=0xc0 ){
205495 int sz = sqlite3Utf8ReadLimited((u8*)zLeft, nLeft, &cLeft);
205496 zLeft += sz;
205497 nLeft -= sz;
205498 }else{
205499 zLeft++;
205500 nLeft--;
205501 }
205502 }else{
205503 u32 n = jsonUnescapeOneChar(zLeft, nLeft, &cLeft);
205504 zLeft += n;
205505 assert( n<=nLeft );
205506 nLeft -= n;
205507 }
205508 if( nRight==0 ){
205509 cRight = 0;
205510 }else if( rawRight || zRight[0]!='\\' ){
205511 cRight = ((u8*)zRight)[0];
205512 if( cRight>=0xc0 ){
205513 int sz = sqlite3Utf8ReadLimited((u8*)zRight, nRight, &cRight);
205514 zRight += sz;
205515 nRight -= sz;
205516 }else{
205517 zRight++;
205518 nRight--;
205519 }
205520 }else{
205521 u32 n = jsonUnescapeOneChar(zRight, nRight, &cRight);
205522 zRight += n;
205523 assert( n<=nRight );
205524 nRight -= n;
205525 }
205526 if( cLeft!=cRight ) return 0;
205527 if( cLeft==0 ) return 1;
205528 }
205529 }
205530
205531 /*
205532 ** Compare two object labels. Return 1 if they are equal and
205533 ** 0 if they differ. Return -1 if an OOM occurs.
205534 */
205535 static int jsonLabelCompare(
205536 const char *zLeft, /* The left label */
205537 u32 nLeft, /* Size of the left label in bytes */
205538 int rawLeft, /* True if zLeft contains no escapes */
205539 const char *zRight, /* The right label */
205540 u32 nRight, /* Size of the right label in bytes */
205541 int rawRight /* True if zRight is escape-free */
205542 ){
205543 if( rawLeft && rawRight ){
205544 /* Simpliest case: Neither label contains escapes. A simple
205545 ** memcmp() is sufficient. */
205546 if( nLeft!=nRight ) return 0;
205547 return memcmp(zLeft, zRight, nLeft)==0;
205548 }else{
205549 return jsonLabelCompareEscaped(zLeft, nLeft, rawLeft,
205550 zRight, nRight, rawRight);
205551 }
205552 }
205553
205554 /*
205555 ** Error returns from jsonLookupStep()
205556 */
205557 #define JSON_LOOKUP_ERROR 0xffffffff
205558 #define JSON_LOOKUP_NOTFOUND 0xfffffffe
205559 #define JSON_LOOKUP_PATHERROR 0xfffffffd
205560 #define JSON_LOOKUP_ISERROR(x) ((x)>=JSON_LOOKUP_PATHERROR)
205561
205562 /* Forward declaration */
205563 static u32 jsonLookupStep(JsonParse*,u32,const char*,u32);
205564
205565
205566 /* This helper routine for jsonLookupStep() populates pIns with
205567 ** binary data that is to be inserted into pParse.
205568 **
205569 ** In the common case, pIns just points to pParse->aIns and pParse->nIns.
205570 ** But if the zPath of the original edit operation includes path elements
205571 ** that go deeper, additional substructure must be created.
205572 **
205573 ** For example:
205574 **
205575 ** json_insert('{}', '$.a.b.c', 123);
205576 **
205577 ** The search stops at '$.a' But additional substructure must be
205578 ** created for the ".b.c" part of the patch so that the final result
205579 ** is: {"a":{"b":{"c"::123}}}. This routine populates pIns with
205580 ** the binary equivalent of {"b":{"c":123}} so that it can be inserted.
205581 **
205582 ** The caller is responsible for resetting pIns when it has finished
205583 ** using the substructure.
205584 */
205585 static u32 jsonCreateEditSubstructure(
205586 JsonParse *pParse, /* The original JSONB that is being edited */
205587 JsonParse *pIns, /* Populate this with the blob data to insert */
205588 const char *zTail /* Tail of the path that determins substructure */
205589 ){
205590 static const u8 emptyObject[] = { JSONB_ARRAY, JSONB_OBJECT };
205591 int rc;
205592 memset(pIns, 0, sizeof(*pIns));
205593 if( zTail[0]==0 ){
205594 /* No substructure. Just insert what is given in pParse. */
205595 pIns->aBlob = pParse->aIns;
205596 pIns->nBlob = pParse->nIns;
205597 rc = 0;
205598 }else{
205599 /* Construct the binary substructure */
205600 pIns->nBlob = 1;
205601 pIns->aBlob = (u8*)&emptyObject[zTail[0]=='.'];
205602 pIns->eEdit = pParse->eEdit;
205603 pIns->nIns = pParse->nIns;
205604 pIns->aIns = pParse->aIns;
205605 rc = jsonLookupStep(pIns, 0, zTail, 0);
205606 pParse->oom |= pIns->oom;
205607 }
205608 return rc; /* Error code only */
205609 }
205610
205611 /*
205612 ** Search along zPath to find the Json element specified. Return an
205613 ** index into pParse->aBlob[] for the start of that element's value.
205614 **
205615 ** If the value found by this routine is the value half of label/value pair
205616 ** within an object, then set pPath->iLabel to the start of the corresponding
205617 ** label, before returning.
205618 **
205619 ** Return one of the JSON_LOOKUP error codes if problems are seen.
205620 **
205621 ** This routine will also modify the blob. If pParse->eEdit is one of
205622 ** JEDIT_DEL, JEDIT_REPL, JEDIT_INS, or JEDIT_SET, then changes might be
205623 ** made to the selected value. If an edit is performed, then the return
205624 ** value does not necessarily point to the select element. If an edit
205625 ** is performed, the return value is only useful for detecting error
205626 ** conditions.
205627 */
205628 static u32 jsonLookupStep(
205629 JsonParse *pParse, /* The JSON to search */
205630 u32 iRoot, /* Begin the search at this element of aBlob[] */
205631 const char *zPath, /* The path to search */
205632 u32 iLabel /* Label if iRoot is a value of in an object */
205633 ){
205634 u32 i, j, k, nKey, sz, n, iEnd, rc;
205635 const char *zKey;
205636 u8 x;
205637
205638 if( zPath[0]==0 ){
205639 if( pParse->eEdit && jsonBlobMakeEditable(pParse, pParse->nIns) ){
205640 n = jsonbPayloadSize(pParse, iRoot, &sz);
205641 sz += n;
205642 if( pParse->eEdit==JEDIT_DEL ){
205643 if( iLabel>0 ){
205644 sz += iRoot - iLabel;
205645 iRoot = iLabel;
205646 }
205647 jsonBlobEdit(pParse, iRoot, sz, 0, 0);
205648 }else if( pParse->eEdit==JEDIT_INS ){
205649 /* Already exists, so json_insert() is a no-op */
205650 }else{
205651 /* json_set() or json_replace() */
205652 jsonBlobEdit(pParse, iRoot, sz, pParse->aIns, pParse->nIns);
205653 }
205654 }
205655 pParse->iLabel = iLabel;
205656 return iRoot;
205657 }
205658 if( zPath[0]=='.' ){
205659 int rawKey = 1;
205660 x = pParse->aBlob[iRoot];
205661 zPath++;
205662 if( zPath[0]=='"' ){
205663 zKey = zPath + 1;
205664 for(i=1; zPath[i] && zPath[i]!='"'; i++){}
205665 nKey = i-1;
205666 if( zPath[i] ){
205667 i++;
205668 }else{
205669 return JSON_LOOKUP_PATHERROR;
 
205670 }
205671 testcase( nKey==0 );
205672 rawKey = memchr(zKey, '\\', nKey)==0;
205673 }else{
205674 zKey = zPath;
205675 for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
205676 nKey = i;
205677 if( nKey==0 ){
205678 return JSON_LOOKUP_PATHERROR;
205679 }
205680 }
205681 if( (x & 0x0f)!=JSONB_OBJECT ) return JSON_LOOKUP_NOTFOUND;
205682 n = jsonbPayloadSize(pParse, iRoot, &sz);
205683 j = iRoot + n; /* j is the index of a label */
205684 iEnd = j+sz;
205685 while( j<iEnd ){
205686 int rawLabel;
205687 const char *zLabel;
205688 x = pParse->aBlob[j] & 0x0f;
205689 if( x<JSONB_TEXT || x>JSONB_TEXTRAW ) return JSON_LOOKUP_ERROR;
205690 n = jsonbPayloadSize(pParse, j, &sz);
205691 if( n==0 ) return JSON_LOOKUP_ERROR;
205692 k = j+n; /* k is the index of the label text */
205693 if( k+sz>=iEnd ) return JSON_LOOKUP_ERROR;
205694 zLabel = (const char*)&pParse->aBlob[k];
205695 rawLabel = x==JSONB_TEXT || x==JSONB_TEXTRAW;
205696 if( jsonLabelCompare(zKey, nKey, rawKey, zLabel, sz, rawLabel) ){
205697 u32 v = k+sz; /* v is the index of the value */
205698 if( ((pParse->aBlob[v])&0x0f)>JSONB_OBJECT ) return JSON_LOOKUP_ERROR;
205699 n = jsonbPayloadSize(pParse, v, &sz);
205700 if( n==0 || v+n+sz>iEnd ) return JSON_LOOKUP_ERROR;
205701 assert( j>0 );
205702 rc = jsonLookupStep(pParse, v, &zPath[i], j);
205703 if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot);
205704 return rc;
205705 }
205706 j = k+sz;
205707 if( ((pParse->aBlob[j])&0x0f)>JSONB_OBJECT ) return JSON_LOOKUP_ERROR;
205708 n = jsonbPayloadSize(pParse, j, &sz);
205709 if( n==0 ) return JSON_LOOKUP_ERROR;
205710 j += n+sz;
205711 }
205712 if( j>iEnd ) return JSON_LOOKUP_ERROR;
205713 if( pParse->eEdit>=JEDIT_INS ){
205714 u32 nIns; /* Total bytes to insert (label+value) */
205715 JsonParse v; /* BLOB encoding of the value to be inserted */
205716 JsonParse ix; /* Header of the label to be inserted */
205717 testcase( pParse->eEdit==JEDIT_INS );
205718 testcase( pParse->eEdit==JEDIT_SET );
205719 memset(&ix, 0, sizeof(ix));
205720 jsonBlobAppendNode(&ix, rawKey?JSONB_TEXTRAW:JSONB_TEXT5, nKey, 0);
205721 pParse->oom |= ix.oom;
205722 rc = jsonCreateEditSubstructure(pParse, &v, &zPath[i]);
205723 if( !JSON_LOOKUP_ISERROR(rc)
205724 && jsonBlobMakeEditable(pParse, ix.nBlob+nKey+v.nBlob)
205725 ){
205726 assert( !pParse->oom );
205727 nIns = ix.nBlob + nKey + v.nBlob;
205728 jsonBlobEdit(pParse, j, 0, 0, nIns);
205729 if( !pParse->oom ){
205730 assert( pParse->aBlob!=0 ); /* Because pParse->oom!=0 */
205731 assert( ix.aBlob!=0 ); /* Because pPasre->oom!=0 */
205732 memcpy(&pParse->aBlob[j], ix.aBlob, ix.nBlob);
205733 k = j + ix.nBlob;
205734 memcpy(&pParse->aBlob[k], zKey, nKey);
205735 k += nKey;
205736 memcpy(&pParse->aBlob[k], v.aBlob, v.nBlob);
205737 if( ALWAYS(pParse->delta) ) jsonAfterEditSizeAdjust(pParse, iRoot);
205738 }
205739 }
205740 jsonParseReset(&v);
205741 jsonParseReset(&ix);
205742 return rc;
205743 }
205744 }else if( zPath[0]=='[' ){
205745 x = pParse->aBlob[iRoot] & 0x0f;
205746 if( x!=JSONB_ARRAY ) return JSON_LOOKUP_NOTFOUND;
205747 n = jsonbPayloadSize(pParse, iRoot, &sz);
205748 k = 0;
205749 i = 1;
205750 while( sqlite3Isdigit(zPath[i]) ){
205751 k = k*10 + zPath[i] - '0';
205752 i++;
205753 }
205754 if( i<2 || zPath[i]!=']' ){
205755 if( zPath[1]=='#' ){
205756 k = jsonbArrayCount(pParse, iRoot);
205757 i = 2;
205758 if( zPath[2]=='-' && sqlite3Isdigit(zPath[3]) ){
205759 unsigned int nn = 0;
205760 i = 3;
205761 do{
205762 nn = nn*10 + zPath[i] - '0';
205763 i++;
205764 }while( sqlite3Isdigit(zPath[i]) );
205765 if( nn>k ) return JSON_LOOKUP_NOTFOUND;
205766 k -= nn;
205767 }
205768 if( zPath[i]!=']' ){
205769 return JSON_LOOKUP_PATHERROR;
205770 }
205771 }else{
205772 return JSON_LOOKUP_PATHERROR;
205773 }
205774 }
205775 j = iRoot+n;
205776 iEnd = j+sz;
205777 while( j<iEnd ){
205778 if( k==0 ){
205779 rc = jsonLookupStep(pParse, j, &zPath[i+1], 0);
205780 if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot);
205781 return rc;
205782 }
205783 k--;
205784 n = jsonbPayloadSize(pParse, j, &sz);
205785 if( n==0 ) return JSON_LOOKUP_ERROR;
205786 j += n+sz;
205787 }
205788 if( j>iEnd ) return JSON_LOOKUP_ERROR;
205789 if( k>0 ) return JSON_LOOKUP_NOTFOUND;
205790 if( pParse->eEdit>=JEDIT_INS ){
205791 JsonParse v;
205792 testcase( pParse->eEdit==JEDIT_INS );
205793 testcase( pParse->eEdit==JEDIT_SET );
205794 rc = jsonCreateEditSubstructure(pParse, &v, &zPath[i+1]);
205795 if( !JSON_LOOKUP_ISERROR(rc)
205796 && jsonBlobMakeEditable(pParse, v.nBlob)
205797 ){
205798 assert( !pParse->oom );
205799 jsonBlobEdit(pParse, j, 0, v.aBlob, v.nBlob);
205800 }
205801 jsonParseReset(&v);
205802 if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot);
205803 return rc;
205804 }
205805 }else{
205806 return JSON_LOOKUP_PATHERROR;
205807 }
205808 return JSON_LOOKUP_NOTFOUND;
205809 }
205810
205811 /*
205812 ** Convert a JSON BLOB into text and make that text the return value
205813 ** of an SQL function.
205814 */
205815 static void jsonReturnTextJsonFromBlob(
205816 sqlite3_context *ctx,
205817 const u8 *aBlob,
205818 u32 nBlob
205819 ){
205820 JsonParse x;
205821 JsonString s;
205822
205823 if( NEVER(aBlob==0) ) return;
205824 memset(&x, 0, sizeof(x));
205825 x.aBlob = (u8*)aBlob;
205826 x.nBlob = nBlob;
205827 jsonStringInit(&s, ctx);
205828 jsonXlateBlobToText(&x, 0, &s);
205829 jsonReturnString(&s, 0, 0);
205830 }
205831
205832
205833 /*
205834 ** Return the value of the BLOB node at index i.
205835 **
205836 ** If the value is a primitive, return it as an SQL value.
205837 ** If the value is an array or object, return it as either
205838 ** JSON text or the BLOB encoding, depending on the JSON_B flag
205839 ** on the userdata.
205840 */
205841 static void jsonReturnFromBlob(
205842 JsonParse *pParse, /* Complete JSON parse tree */
205843 u32 i, /* Index of the node */
205844 sqlite3_context *pCtx, /* Return value for this function */
205845 int textOnly /* return text JSON. Disregard user-data */
205846 ){
205847 u32 n, sz;
205848 int rc;
205849 sqlite3 *db = sqlite3_context_db_handle(pCtx);
205850
205851 n = jsonbPayloadSize(pParse, i, &sz);
205852 if( n==0 ){
205853 sqlite3_result_error(pCtx, "malformed JSON", -1);
205854 return;
205855 }
205856 switch( pParse->aBlob[i] & 0x0f ){
205857 case JSONB_NULL: {
205858 if( sz ) goto returnfromblob_malformed;
205859 sqlite3_result_null(pCtx);
205860 break;
205861 }
205862 case JSONB_TRUE: {
205863 if( sz ) goto returnfromblob_malformed;
205864 sqlite3_result_int(pCtx, 1);
205865 break;
205866 }
205867 case JSONB_FALSE: {
205868 if( sz ) goto returnfromblob_malformed;
205869 sqlite3_result_int(pCtx, 0);
205870 break;
205871 }
205872 case JSONB_INT5:
205873 case JSONB_INT: {
205874 sqlite3_int64 iRes = 0;
205875 char *z;
205876 int bNeg = 0;
205877 char x;
205878 if( sz==0 ) goto returnfromblob_malformed;
205879 x = (char)pParse->aBlob[i+n];
205880 if( x=='-' ){
205881 if( sz<2 ) goto returnfromblob_malformed;
205882 n++;
205883 sz--;
205884 bNeg = 1;
205885 }
205886 z = sqlite3DbStrNDup(db, (const char*)&pParse->aBlob[i+n], (int)sz);
205887 if( z==0 ) goto returnfromblob_oom;
205888 rc = sqlite3DecOrHexToI64(z, &iRes);
205889 sqlite3DbFree(db, z);
205890 if( rc==0 ){
205891 sqlite3_result_int64(pCtx, bNeg ? -iRes : iRes);
205892 }else if( rc==3 && bNeg ){
205893 sqlite3_result_int64(pCtx, SMALLEST_INT64);
205894 }else if( rc==1 ){
205895 goto returnfromblob_malformed;
205896 }else{
205897 if( bNeg ){ n--; sz++; }
205898 goto to_double;
205899 }
205900 break;
205901 }
205902 case JSONB_FLOAT5:
205903 case JSONB_FLOAT: {
205904 double r;
205905 char *z;
205906 if( sz==0 ) goto returnfromblob_malformed;
205907 to_double:
205908 z = sqlite3DbStrNDup(db, (const char*)&pParse->aBlob[i+n], (int)sz);
205909 if( z==0 ) goto returnfromblob_oom;
205910 rc = sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8);
205911 sqlite3DbFree(db, z);
205912 if( rc<=0 ) goto returnfromblob_malformed;
205913 sqlite3_result_double(pCtx, r);
205914 break;
205915 }
205916 case JSONB_TEXTRAW:
205917 case JSONB_TEXT: {
205918 sqlite3_result_text(pCtx, (char*)&pParse->aBlob[i+n], sz,
205919 SQLITE_TRANSIENT);
205920 break;
205921 }
205922 case JSONB_TEXT5:
205923 case JSONB_TEXTJ: {
205924 /* Translate JSON formatted string into raw text */
205925 u32 iIn, iOut;
205926 const char *z;
205927 char *zOut;
205928 u32 nOut = sz;
205929 z = (const char*)&pParse->aBlob[i+n];
205930 zOut = sqlite3_malloc( nOut+1 );
205931 if( zOut==0 ) goto returnfromblob_oom;
205932 for(iIn=iOut=0; iIn<sz; iIn++){
205933 char c = z[iIn];
205934 if( c=='\\' ){
205935 u32 v;
205936 u32 szEscape = jsonUnescapeOneChar(&z[iIn], sz-iIn, &v);
205937 if( v<=0x7f ){
205938 zOut[iOut++] = (char)v;
205939 }else if( v==0xfffd ){
205940 /* Silently ignore illegal unicode */
205941 }else if( v<=0x7ff ){
205942 assert( szEscape>=2 );
205943 zOut[iOut++] = (char)(0xc0 | (v>>6));
205944 zOut[iOut++] = 0x80 | (v&0x3f);
205945 }else if( v<0x10000 ){
205946 assert( szEscape>=3 );
205947 zOut[iOut++] = 0xe0 | (v>>12);
205948 zOut[iOut++] = 0x80 | ((v>>6)&0x3f);
205949 zOut[iOut++] = 0x80 | (v&0x3f);
205950 }else{
205951 assert( szEscape>=4 );
205952 zOut[iOut++] = 0xf0 | (v>>18);
205953 zOut[iOut++] = 0x80 | ((v>>12)&0x3f);
205954 zOut[iOut++] = 0x80 | ((v>>6)&0x3f);
205955 zOut[iOut++] = 0x80 | (v&0x3f);
205956 }
205957 iIn += szEscape - 1;
205958 }else{
205959 zOut[iOut++] = c;
205960 }
205961 } /* end for() */
205962 assert( iOut<=nOut );
205963 zOut[iOut] = 0;
205964 sqlite3_result_text(pCtx, zOut, iOut, sqlite3_free);
205965 break;
205966 }
205967 case JSONB_ARRAY:
205968 case JSONB_OBJECT: {
205969 int flags = textOnly ? 0 : SQLITE_PTR_TO_INT(sqlite3_user_data(pCtx));
205970 if( flags & JSON_BLOB ){
205971 sqlite3_result_blob(pCtx, &pParse->aBlob[i], sz+n, SQLITE_TRANSIENT);
205972 }else{
205973 jsonReturnTextJsonFromBlob(pCtx, &pParse->aBlob[i], sz+n);
205974 }
205975 break;
205976 }
205977 default: {
205978 goto returnfromblob_malformed;
205979 }
205980 }
205981 return;
205982
205983 returnfromblob_oom:
205984 sqlite3_result_error_nomem(pCtx);
205985 return;
205986
205987 returnfromblob_malformed:
205988 sqlite3_result_error(pCtx, "malformed JSON", -1);
205989 return;
205990 }
205991
205992 /*
205993 ** pArg is a function argument that might be an SQL value or a JSON
205994 ** value. Figure out what it is and encode it as a JSONB blob.
205995 ** Return the results in pParse.
205996 **
205997 ** pParse is uninitialized upon entry. This routine will handle the
205998 ** initialization of pParse. The result will be contained in
205999 ** pParse->aBlob and pParse->nBlob. pParse->aBlob might be dynamically
206000 ** allocated (if pParse->nBlobAlloc is greater than zero) in which case
206001 ** the caller is responsible for freeing the space allocated to pParse->aBlob
206002 ** when it has finished with it. Or pParse->aBlob might be a static string
206003 ** or a value obtained from sqlite3_value_blob(pArg).
206004 **
206005 ** If the argument is a BLOB that is clearly not a JSONB, then this
206006 ** function might set an error message in ctx and return non-zero.
206007 ** It might also set an error message and return non-zero on an OOM error.
206008 */
206009 static int jsonFunctionArgToBlob(
206010 sqlite3_context *ctx,
206011 sqlite3_value *pArg,
206012 JsonParse *pParse
206013 ){
206014 int eType = sqlite3_value_type(pArg);
206015 static u8 aNull[] = { 0x00 };
206016 memset(pParse, 0, sizeof(pParse[0]));
206017 switch( eType ){
206018 default: {
206019 pParse->aBlob = aNull;
206020 pParse->nBlob = 1;
206021 return 0;
206022 }
206023 case SQLITE_BLOB: {
206024 if( jsonFuncArgMightBeBinary(pArg) ){
206025 pParse->aBlob = (u8*)sqlite3_value_blob(pArg);
206026 pParse->nBlob = sqlite3_value_bytes(pArg);
206027 }else{
206028 sqlite3_result_error(ctx, "JSON cannot hold BLOB values", -1);
206029 return 1;
206030 }
206031 break;
206032 }
206033 case SQLITE_TEXT: {
206034 const char *zJson = (const char*)sqlite3_value_text(pArg);
206035 int nJson = sqlite3_value_bytes(pArg);
206036 if( zJson==0 ) return 1;
206037 if( sqlite3_value_subtype(pArg)==JSON_SUBTYPE ){
206038 pParse->zJson = (char*)zJson;
206039 pParse->nJson = nJson;
206040 if( jsonConvertTextToBlob(pParse, ctx) ){
206041 sqlite3_result_error(ctx, "malformed JSON", -1);
206042 sqlite3_free(pParse->aBlob);
206043 memset(pParse, 0, sizeof(pParse[0]));
206044 return 1;
206045 }
206046 }else{
206047 jsonBlobAppendNode(pParse, JSONB_TEXTRAW, nJson, zJson);
206048 }
206049 break;
206050 }
206051 case SQLITE_FLOAT:
206052 case SQLITE_INTEGER: {
206053 int n = sqlite3_value_bytes(pArg);
206054 const char *z = (const char*)sqlite3_value_text(pArg);
206055 int e = eType==SQLITE_INTEGER ? JSONB_INT : JSONB_FLOAT;
206056 if( z==0 ) return 1;
206057 jsonBlobAppendNode(pParse, e, n, z);
206058 break;
206059 }
206060 }
206061 if( pParse->oom ){
206062 sqlite3_result_error_nomem(ctx);
206063 return 1;
206064 }else{
206065 return 0;
206066 }
206067 }
206068
206069 /*
206070 ** Generate a bad path error.
206071 **
206072 ** If ctx is not NULL then push the error message into ctx and return NULL.
206073 ** If ctx is NULL, then return the text of the error message.
206074 */
206075 static char *jsonBadPathError(
206076 sqlite3_context *ctx, /* The function call containing the error */
206077 const char *zPath /* The path with the problem */
206078 ){
206079 char *zMsg = sqlite3_mprintf("bad JSON path: %Q", zPath);
206080 if( ctx==0 ) return zMsg;
206081 if( zMsg ){
206082 sqlite3_result_error(ctx, zMsg, -1);
206083 sqlite3_free(zMsg);
206084 }else{
206085 sqlite3_result_error_nomem(ctx);
206086 }
206087 return 0;
206088 }
206089
206090 /* argv[0] is a BLOB that seems likely to be a JSONB. Subsequent
206091 ** arguments come in parse where each pair contains a JSON path and
206092 ** content to insert or set at that patch. Do the updates
206093 ** and return the result.
206094 **
206095 ** The specific operation is determined by eEdit, which can be one
206096 ** of JEDIT_INS, JEDIT_REPL, or JEDIT_SET.
206097 */
206098 static void jsonInsertIntoBlob(
206099 sqlite3_context *ctx,
206100 int argc,
206101 sqlite3_value **argv,
206102 int eEdit /* JEDIT_INS, JEDIT_REPL, or JEDIT_SET */
206103 ){
206104 int i;
206105 u32 rc = 0;
206106 const char *zPath = 0;
206107 int flgs;
206108 JsonParse *p;
206109 JsonParse ax;
206110
206111 assert( (argc&1)==1 );
206112 flgs = argc==1 ? 0 : JSON_EDITABLE;
206113 p = jsonParseFuncArg(ctx, argv[0], flgs);
206114 if( p==0 ) return;
206115 for(i=1; i<argc-1; i+=2){
206116 if( sqlite3_value_type(argv[i])==SQLITE_NULL ) continue;
206117 zPath = (const char*)sqlite3_value_text(argv[i]);
206118 if( zPath==0 ){
206119 sqlite3_result_error_nomem(ctx);
206120 jsonParseFree(p);
206121 return;
206122 }
206123 if( zPath[0]!='$' ) goto jsonInsertIntoBlob_patherror;
206124 if( jsonFunctionArgToBlob(ctx, argv[i+1], &ax) ){
206125 jsonParseReset(&ax);
206126 jsonParseFree(p);
206127 return;
206128 }
206129 if( zPath[1]==0 ){
206130 if( eEdit==JEDIT_REPL || eEdit==JEDIT_SET ){
206131 jsonBlobEdit(p, 0, p->nBlob, ax.aBlob, ax.nBlob);
206132 }
206133 rc = 0;
206134 }else{
206135 p->eEdit = eEdit;
206136 p->nIns = ax.nBlob;
206137 p->aIns = ax.aBlob;
206138 p->delta = 0;
206139 rc = jsonLookupStep(p, 0, zPath+1, 0);
206140 }
206141 jsonParseReset(&ax);
206142 if( rc==JSON_LOOKUP_NOTFOUND ) continue;
206143 if( JSON_LOOKUP_ISERROR(rc) ) goto jsonInsertIntoBlob_patherror;
206144 }
206145 jsonReturnParse(ctx, p);
206146 jsonParseFree(p);
206147 return;
206148
206149 jsonInsertIntoBlob_patherror:
206150 jsonParseFree(p);
206151 if( rc==JSON_LOOKUP_ERROR ){
206152 sqlite3_result_error(ctx, "malformed JSON", -1);
206153 }else{
206154 jsonBadPathError(ctx, zPath);
206155 }
206156 return;
206157 }
206158
206159 /*
206160 ** Make a copy of a JsonParse object. The copy will be editable.
206161 */
206162
206163
206164 /*
206165 ** Generate a JsonParse object, containing valid JSONB in aBlob and nBlob,
206166 ** from the SQL function argument pArg. Return a pointer to the new
206167 ** JsonParse object.
206168 **
206169 ** Ownership of the new JsonParse object is passed to the caller. The
206170 ** caller should invoke jsonParseFree() on the return value when it
206171 ** has finished using it.
206172 **
206173 ** If any errors are detected, an appropriate error messages is set
206174 ** using sqlite3_result_error() or the equivalent and this routine
206175 ** returns NULL. This routine also returns NULL if the pArg argument
206176 ** is an SQL NULL value, but no error message is set in that case. This
206177 ** is so that SQL functions that are given NULL arguments will return
206178 ** a NULL value.
206179 */
206180 static JsonParse *jsonParseFuncArg(
206181 sqlite3_context *ctx,
206182 sqlite3_value *pArg,
206183 u32 flgs
206184 ){
206185 int eType; /* Datatype of pArg */
206186 JsonParse *p = 0; /* Value to be returned */
206187 JsonParse *pFromCache = 0; /* Value taken from cache */
206188
206189 assert( ctx!=0 );
206190 eType = sqlite3_value_type(pArg);
206191 if( eType==SQLITE_NULL ){
206192 return 0;
206193 }
206194 pFromCache = jsonCacheSearch(ctx, pArg);
206195 if( pFromCache ){
206196 pFromCache->nJPRef++;
206197 if( (flgs & JSON_EDITABLE)==0 ){
206198 return pFromCache;
206199 }
206200 }
206201 rebuild_from_cache:
206202 p = sqlite3_malloc64( sizeof(*p) );
206203 if( p==0 ) goto json_pfa_oom;
206204 memset(p, 0, sizeof(*p));
206205 p->nJPRef = 1;
206206 if( pFromCache!=0 ){
206207 u32 nBlob = pFromCache->nBlob;
206208 p->aBlob = sqlite3_malloc64( nBlob );
206209 if( p->aBlob==0 ) goto json_pfa_oom;
206210 memcpy(p->aBlob, pFromCache->aBlob, nBlob);
206211 p->nBlobAlloc = p->nBlob = nBlob;
206212 p->hasNonstd = pFromCache->hasNonstd;
206213 jsonParseFree(pFromCache);
206214 return p;
206215 }
206216 if( eType==SQLITE_BLOB ){
206217 u32 n, sz = 0;
206218 p->aBlob = (u8*)sqlite3_value_blob(pArg);
206219 p->nBlob = (u32)sqlite3_value_bytes(pArg);
206220 if( p->nBlob==0 ){
206221 goto json_pfa_malformed;
206222 }
206223 if( NEVER(p->aBlob==0) ){
206224 goto json_pfa_oom;
206225 }
206226 if( (p->aBlob[0] & 0x0f)>JSONB_OBJECT ){
206227 goto json_pfa_malformed;
206228 }
206229 n = jsonbPayloadSize(p, 0, &sz);
206230 if( n==0
206231 || sz+n!=p->nBlob
206232 || ((p->aBlob[0] & 0x0f)<=JSONB_FALSE && sz>0)
206233 ){
206234 goto json_pfa_malformed;
206235 }
206236 if( (flgs & JSON_EDITABLE)!=0 && jsonBlobMakeEditable(p, 0)==0 ){
206237 goto json_pfa_oom;
206238 }
206239 return p;
206240 }
206241 p->zJson = (char*)sqlite3_value_text(pArg);
206242 p->nJson = sqlite3_value_bytes(pArg);
206243 if( p->nJson==0 ) goto json_pfa_malformed;
206244 if( NEVER(p->zJson==0) ) goto json_pfa_oom;
206245 if( jsonConvertTextToBlob(p, (flgs & JSON_KEEPERROR) ? 0 : ctx) ){
206246 if( flgs & JSON_KEEPERROR ){
206247 p->nErr = 1;
206248 return p;
206249 }else{
206250 jsonParseFree(p);
206251 return 0;
206252 }
206253 }else{
206254 int isRCStr = sqlite3ValueIsOfClass(pArg, sqlite3RCStrUnref);
206255 int rc;
206256 if( !isRCStr ){
206257 char *zNew = sqlite3RCStrNew( p->nJson );
206258 if( zNew==0 ) goto json_pfa_oom;
206259 memcpy(zNew, p->zJson, p->nJson);
206260 p->zJson = zNew;
206261 p->zJson[p->nJson] = 0;
206262 }else{
206263 sqlite3RCStrRef(p->zJson);
206264 }
206265 p->bJsonIsRCStr = 1;
206266 rc = jsonCacheInsert(ctx, p);
206267 if( rc==SQLITE_NOMEM ) goto json_pfa_oom;
206268 if( flgs & JSON_EDITABLE ){
206269 pFromCache = p;
206270 p = 0;
206271 goto rebuild_from_cache;
206272 }
206273 }
206274 return p;
206275
206276 json_pfa_malformed:
206277 if( flgs & JSON_KEEPERROR ){
206278 p->nErr = 1;
206279 return p;
206280 }else{
206281 jsonParseFree(p);
206282 sqlite3_result_error(ctx, "malformed JSON", -1);
206283 return 0;
206284 }
206285
206286 json_pfa_oom:
206287 jsonParseFree(pFromCache);
206288 jsonParseFree(p);
206289 sqlite3_result_error_nomem(ctx);
206290 return 0;
206291 }
206292
206293 /*
206294 ** Make the return value of a JSON function either the raw JSONB blob
206295 ** or make it JSON text, depending on whether the JSON_BLOB flag is
206296 ** set on the function.
206297 */
206298 static void jsonReturnParse(
206299 sqlite3_context *ctx,
206300 JsonParse *p
206301 ){
206302 int flgs;
206303 if( p->oom ){
206304 sqlite3_result_error_nomem(ctx);
206305 return;
206306 }
206307 flgs = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx));
206308 if( flgs & JSON_BLOB ){
206309 if( p->nBlobAlloc>0 && !p->bReadOnly ){
206310 sqlite3_result_blob(ctx, p->aBlob, p->nBlob, SQLITE_DYNAMIC);
206311 p->nBlobAlloc = 0;
206312 }else{
206313 sqlite3_result_blob(ctx, p->aBlob, p->nBlob, SQLITE_TRANSIENT);
206314 }
206315 }else{
206316 JsonString s;
206317 jsonStringInit(&s, ctx);
206318 jsonXlateBlobToText(p, 0, &s);
206319 jsonReturnString(&s, p, ctx);
206320 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
206321 }
206322 }
206323
206324 /****************************************************************************
206325 ** SQL functions used for testing and debugging
206326 ****************************************************************************/
206327
206328 #if SQLITE_DEBUG
206329 /*
206330 ** Decode JSONB bytes in aBlob[] starting at iStart through but not
206331 ** including iEnd. Indent the
206332 ** content by nIndent spaces.
206333 */
206334 static void jsonDebugPrintBlob(
206335 JsonParse *pParse, /* JSON content */
206336 u32 iStart, /* Start rendering here */
206337 u32 iEnd, /* Do not render this byte or any byte after this one */
206338 int nIndent /* Indent by this many spaces */
206339 ){
206340 while( iStart<iEnd ){
206341 u32 i, n, nn, sz = 0;
206342 int showContent = 1;
206343 u8 x = pParse->aBlob[iStart] & 0x0f;
206344 u32 savedNBlob = pParse->nBlob;
206345 printf("%5d:%*s", iStart, nIndent, "");
206346 if( pParse->nBlobAlloc>pParse->nBlob ){
206347 pParse->nBlob = pParse->nBlobAlloc;
206348 }
206349 nn = n = jsonbPayloadSize(pParse, iStart, &sz);
206350 if( nn==0 ) nn = 1;
206351 if( sz>0 && x<JSONB_ARRAY ){
206352 nn += sz;
206353 }
206354 for(i=0; i<nn; i++) printf(" %02x", pParse->aBlob[iStart+i]);
206355 if( n==0 ){
206356 printf(" ERROR invalid node size\n");
206357 iStart = n==0 ? iStart+1 : iEnd;
206358 continue;
206359 }
206360 pParse->nBlob = savedNBlob;
206361 if( iStart+n+sz>iEnd ){
206362 iEnd = iStart+n+sz;
206363 if( iEnd>pParse->nBlob ){
206364 if( pParse->nBlobAlloc>0 && iEnd>pParse->nBlobAlloc ){
206365 iEnd = pParse->nBlobAlloc;
206366 }else{
206367 iEnd = pParse->nBlob;
206368 }
206369 }
206370 }
206371 printf(" <-- ");
206372 switch( x ){
206373 case JSONB_NULL: printf("null"); break;
206374 case JSONB_TRUE: printf("true"); break;
206375 case JSONB_FALSE: printf("false"); break;
206376 case JSONB_INT: printf("int"); break;
206377 case JSONB_INT5: printf("int5"); break;
206378 case JSONB_FLOAT: printf("float"); break;
206379 case JSONB_FLOAT5: printf("float5"); break;
206380 case JSONB_TEXT: printf("text"); break;
206381 case JSONB_TEXTJ: printf("textj"); break;
206382 case JSONB_TEXT5: printf("text5"); break;
206383 case JSONB_TEXTRAW: printf("textraw"); break;
206384 case JSONB_ARRAY: {
206385 printf("array, %u bytes\n", sz);
206386 jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2);
206387 showContent = 0;
206388 break;
206389 }
206390 case JSONB_OBJECT: {
206391 printf("object, %u bytes\n", sz);
206392 jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2);
206393 showContent = 0;
206394 break;
206395 }
206396 default: {
206397 printf("ERROR: unknown node type\n");
206398 showContent = 0;
206399 break;
206400 }
206401 }
206402 if( showContent ){
206403 if( sz==0 && x<=JSONB_FALSE ){
206404 printf("\n");
206405 }else{
206406 u32 i;
206407 printf(": \"");
206408 for(i=iStart+n; i<iStart+n+sz; i++){
206409 u8 c = pParse->aBlob[i];
206410 if( c<0x20 || c>=0x7f ) c = '.';
206411 putchar(c);
206412 }
206413 printf("\"\n");
206414 }
206415 }
206416 iStart += n + sz;
206417 }
206418 }
206419 static void jsonShowParse(JsonParse *pParse){
206420 if( pParse==0 ){
206421 printf("NULL pointer\n");
206422 return;
206423 }else{
206424 printf("nBlobAlloc = %u\n", pParse->nBlobAlloc);
206425 printf("nBlob = %u\n", pParse->nBlob);
206426 printf("delta = %d\n", pParse->delta);
206427 if( pParse->nBlob==0 ) return;
206428 printf("content (bytes 0..%u):\n", pParse->nBlob-1);
206429 }
206430 jsonDebugPrintBlob(pParse, 0, pParse->nBlob, 0);
206431 }
206432 #endif /* SQLITE_DEBUG */
206433
206434 #ifdef SQLITE_DEBUG
206435 /*
206436 ** SQL function: json_parse(JSON)
206437 **
206438 ** Parse JSON using jsonParseFuncArg(). Then print a dump of that
206439 ** parse on standard output.
 
206440 */
206441 static void jsonParseFunc(
206442 sqlite3_context *ctx,
206443 int argc,
206444 sqlite3_value **argv
206445 ){
206446 JsonParse *p; /* The parse */
206447
206448 assert( argc==1 );
206449 p = jsonParseFuncArg(ctx, argv[0], 0);
206450 jsonShowParse(p);
206451 jsonParseFree(p);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206452 }
206453 #endif /* SQLITE_DEBUG */
206454
206455 /****************************************************************************
206456 ** Scalar SQL function implementations
206457 ****************************************************************************/
206458
206459 /*
206460 ** Implementation of the json_quote(VALUE) function. Return a JSON value
206461 ** corresponding to the SQL value input. Mostly this means putting
206462 ** double-quotes around strings and returning the unquoted string "null"
206463 ** when given a NULL input.
206464 */
206465 static void jsonQuoteFunc(
@@ -205069,13 +206468,13 @@
206468 sqlite3_value **argv
206469 ){
206470 JsonString jx;
206471 UNUSED_PARAMETER(argc);
206472
206473 jsonStringInit(&jx, ctx);
206474 jsonAppendSqlValue(&jx, argv[0]);
206475 jsonReturnString(&jx, 0, 0);
206476 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
206477 }
206478
206479 /*
206480 ** Implementation of the json_array(VALUE,...) function. Return a JSON
@@ -205088,21 +206487,20 @@
206487 sqlite3_value **argv
206488 ){
206489 int i;
206490 JsonString jx;
206491
206492 jsonStringInit(&jx, ctx);
206493 jsonAppendChar(&jx, '[');
206494 for(i=0; i<argc; i++){
206495 jsonAppendSeparator(&jx);
206496 jsonAppendSqlValue(&jx, argv[i]);
206497 }
206498 jsonAppendChar(&jx, ']');
206499 jsonReturnString(&jx, 0, 0);
206500 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
206501 }
 
206502
206503 /*
206504 ** json_array_length(JSON)
206505 ** json_array_length(JSON, PATH)
206506 **
@@ -205113,50 +206511,57 @@
206511 sqlite3_context *ctx,
206512 int argc,
206513 sqlite3_value **argv
206514 ){
206515 JsonParse *p; /* The parse */
206516 sqlite3_int64 cnt = 0;
206517 u32 i;
206518 u8 eErr = 0;
206519
206520 p = jsonParseFuncArg(ctx, argv[0], 0);
206521 if( p==0 ) return;
 
206522 if( argc==2 ){
206523 const char *zPath = (const char*)sqlite3_value_text(argv[1]);
206524 if( zPath==0 ){
206525 jsonParseFree(p);
206526 return;
206527 }
206528 i = jsonLookupStep(p, 0, zPath[0]=='$' ? zPath+1 : "@", 0);
206529 if( JSON_LOOKUP_ISERROR(i) ){
206530 if( i==JSON_LOOKUP_NOTFOUND ){
206531 /* no-op */
206532 }else if( i==JSON_LOOKUP_PATHERROR ){
206533 jsonBadPathError(ctx, zPath);
206534 }else{
206535 sqlite3_result_error(ctx, "malformed JSON", -1);
206536 }
206537 eErr = 1;
206538 i = 0;
206539 }
206540 }else{
206541 i = 0;
206542 }
206543 if( (p->aBlob[i] & 0x0f)==JSONB_ARRAY ){
206544 cnt = jsonbArrayCount(p, i);
206545 }
206546 if( !eErr ) sqlite3_result_int64(ctx, cnt);
206547 jsonParseFree(p);
206548 }
206549
206550 /* True if the string is all digits */
206551 static int jsonAllDigits(const char *z, int n){
206552 int i;
206553 for(i=0; i<n && sqlite3Isdigit(z[i]); i++){}
206554 return i==n;
206555 }
206556
206557 /* True if the string is all alphanumerics and underscores */
206558 static int jsonAllAlphanum(const char *z, int n){
206559 int i;
206560 for(i=0; i<n && (sqlite3Isalnum(z[i]) || z[i]=='_'); i++){}
206561 return i==n;
206562 }
206563
206564 /*
206565 ** json_extract(JSON, PATH, ...)
206566 ** "->"(JSON,PATH)
206567 ** "->>"(JSON,PATH)
@@ -205179,154 +206584,310 @@
206584 static void jsonExtractFunc(
206585 sqlite3_context *ctx,
206586 int argc,
206587 sqlite3_value **argv
206588 ){
206589 JsonParse *p = 0; /* The parse */
206590 int flags; /* Flags associated with the function */
206591 int i; /* Loop counter */
206592 JsonString jx; /* String for array result */
 
206593
206594 if( argc<2 ) return;
206595 p = jsonParseFuncArg(ctx, argv[0], 0);
206596 if( p==0 ) return;
206597 flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx));
206598 jsonStringInit(&jx, ctx);
206599 if( argc>2 ){
206600 jsonAppendChar(&jx, '[');
206601 }
206602 for(i=1; i<argc; i++){
206603 /* With a single PATH argument */
206604 const char *zPath = (const char*)sqlite3_value_text(argv[i]);
206605 int nPath;
206606 u32 j;
206607 if( zPath==0 ) goto json_extract_error;
206608 nPath = sqlite3Strlen30(zPath);
206609 if( zPath[0]=='$' ){
206610 j = jsonLookupStep(p, 0, zPath+1, 0);
206611 }else if( (flags & JSON_ABPATH) ){
206612 /* The -> and ->> operators accept abbreviated PATH arguments. This
206613 ** is mostly for compatibility with PostgreSQL, but also for
206614 ** convenience.
206615 **
206616 ** NUMBER ==> $[NUMBER] // PG compatible
206617 ** LABEL ==> $.LABEL // PG compatible
206618 ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience
206619 */
206620 jsonStringInit(&jx, ctx);
206621 if( jsonAllDigits(zPath, nPath) ){
206622 jsonAppendRawNZ(&jx, "[", 1);
206623 jsonAppendRaw(&jx, zPath, nPath);
206624 jsonAppendRawNZ(&jx, "]", 2);
206625 }else if( jsonAllAlphanum(zPath, nPath) ){
206626 jsonAppendRawNZ(&jx, ".", 1);
206627 jsonAppendRaw(&jx, zPath, nPath);
206628 }else if( zPath[0]=='[' && nPath>=3 && zPath[nPath-1]==']' ){
206629 jsonAppendRaw(&jx, zPath, nPath);
206630 }else{
206631 jsonAppendRawNZ(&jx, ".\"", 2);
206632 jsonAppendRaw(&jx, zPath, nPath);
206633 jsonAppendRawNZ(&jx, "\"", 1);
206634 }
206635 jsonStringTerminate(&jx);
206636 j = jsonLookupStep(p, 0, jx.zBuf, 0);
206637 jsonStringReset(&jx);
206638 }else{
206639 jsonBadPathError(ctx, zPath);
206640 goto json_extract_error;
206641 }
206642 if( j<p->nBlob ){
206643 if( argc==2 ){
206644 if( flags & JSON_JSON ){
206645 jsonStringInit(&jx, ctx);
206646 jsonXlateBlobToText(p, j, &jx);
206647 jsonReturnString(&jx, 0, 0);
206648 jsonStringReset(&jx);
206649 assert( (flags & JSON_BLOB)==0 );
206650 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
206651 }else{
206652 jsonReturnFromBlob(p, j, ctx, 0);
206653 if( (flags & (JSON_SQL|JSON_BLOB))==0
206654 && (p->aBlob[j]&0x0f)>=JSONB_ARRAY
206655 ){
206656 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
206657 }
206658 }
206659 }else{
206660 jsonAppendSeparator(&jx);
206661 jsonXlateBlobToText(p, j, &jx);
206662 }
206663 }else if( j==JSON_LOOKUP_NOTFOUND ){
206664 if( argc==2 ){
206665 goto json_extract_error; /* Return NULL if not found */
206666 }else{
206667 jsonAppendSeparator(&jx);
206668 jsonAppendRawNZ(&jx, "null", 4);
206669 }
206670 }else if( j==JSON_LOOKUP_ERROR ){
206671 sqlite3_result_error(ctx, "malformed JSON", -1);
206672 goto json_extract_error;
206673 }else{
206674 jsonBadPathError(ctx, zPath);
206675 goto json_extract_error;
206676 }
206677 }
206678 if( argc>2 ){
206679 jsonAppendChar(&jx, ']');
206680 jsonReturnString(&jx, 0, 0);
206681 if( (flags & JSON_BLOB)==0 ){
206682 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
206683 }
206684 }
206685 json_extract_error:
206686 jsonStringReset(&jx);
206687 jsonParseFree(p);
206688 return;
206689 }
206690
206691 /*
206692 ** Return codes for jsonMergePatch()
206693 */
206694 #define JSON_MERGE_OK 0 /* Success */
206695 #define JSON_MERGE_BADTARGET 1 /* Malformed TARGET blob */
206696 #define JSON_MERGE_BADPATCH 2 /* Malformed PATCH blob */
206697 #define JSON_MERGE_OOM 3 /* Out-of-memory condition */
206698
206699 /*
206700 ** RFC-7396 MergePatch for two JSONB blobs.
206701 **
206702 ** pTarget is the target. pPatch is the patch. The target is updated
206703 ** in place. The patch is read-only.
206704 **
206705 ** The original RFC-7396 algorithm is this:
206706 **
206707 ** define MergePatch(Target, Patch):
206708 ** if Patch is an Object:
206709 ** if Target is not an Object:
206710 ** Target = {} # Ignore the contents and set it to an empty Object
206711 ** for each Name/Value pair in Patch:
206712 ** if Value is null:
206713 ** if Name exists in Target:
206714 ** remove the Name/Value pair from Target
206715 ** else:
206716 ** Target[Name] = MergePatch(Target[Name], Value)
206717 ** return Target
206718 ** else:
206719 ** return Patch
206720 **
206721 ** Here is an equivalent algorithm restructured to show the actual
206722 ** implementation:
206723 **
206724 ** 01 define MergePatch(Target, Patch):
206725 ** 02 if Patch is not an Object:
206726 ** 03 return Patch
206727 ** 04 else: // if Patch is an Object
206728 ** 05 if Target is not an Object:
206729 ** 06 Target = {}
206730 ** 07 for each Name/Value pair in Patch:
206731 ** 08 if Name exists in Target:
206732 ** 09 if Value is null:
206733 ** 10 remove the Name/Value pair from Target
206734 ** 11 else
206735 ** 12 Target[name] = MergePatch(Target[Name], Value)
206736 ** 13 else if Value is not NULL:
206737 ** 14 if Value is not an Object:
206738 ** 15 Target[name] = Value
206739 ** 16 else:
206740 ** 17 Target[name] = MergePatch('{}',value)
206741 ** 18 return Target
206742 ** |
206743 ** ^---- Line numbers referenced in comments in the implementation
206744 */
206745 static int jsonMergePatch(
206746 JsonParse *pTarget, /* The JSON parser that contains the TARGET */
206747 u32 iTarget, /* Index of TARGET in pTarget->aBlob[] */
206748 const JsonParse *pPatch, /* The PATCH */
206749 u32 iPatch /* Index of PATCH in pPatch->aBlob[] */
206750 ){
206751 u8 x; /* Type of a single node */
206752 u32 n, sz=0; /* Return values from jsonbPayloadSize() */
206753 u32 iTCursor; /* Cursor position while scanning the target object */
206754 u32 iTStart; /* First label in the target object */
206755 u32 iTEndBE; /* Original first byte past end of target, before edit */
206756 u32 iTEnd; /* Current first byte past end of target */
206757 u8 eTLabel; /* Node type of the target label */
206758 u32 iTLabel = 0; /* Index of the label */
206759 u32 nTLabel = 0; /* Header size in bytes for the target label */
206760 u32 szTLabel = 0; /* Size of the target label payload */
206761 u32 iTValue = 0; /* Index of the target value */
206762 u32 nTValue = 0; /* Header size of the target value */
206763 u32 szTValue = 0; /* Payload size for the target value */
206764
206765 u32 iPCursor; /* Cursor position while scanning the patch */
206766 u32 iPEnd; /* First byte past the end of the patch */
206767 u8 ePLabel; /* Node type of the patch label */
206768 u32 iPLabel; /* Start of patch label */
206769 u32 nPLabel; /* Size of header on the patch label */
206770 u32 szPLabel; /* Payload size of the patch label */
206771 u32 iPValue; /* Start of patch value */
206772 u32 nPValue; /* Header size for the patch value */
206773 u32 szPValue; /* Payload size of the patch value */
206774
206775 assert( iTarget>=0 && iTarget<pTarget->nBlob );
206776 assert( iPatch>=0 && iPatch<pPatch->nBlob );
206777 x = pPatch->aBlob[iPatch] & 0x0f;
206778 if( x!=JSONB_OBJECT ){ /* Algorithm line 02 */
206779 u32 szPatch; /* Total size of the patch, header+payload */
206780 u32 szTarget; /* Total size of the target, header+payload */
206781 n = jsonbPayloadSize(pPatch, iPatch, &sz);
206782 szPatch = n+sz;
206783 sz = 0;
206784 n = jsonbPayloadSize(pTarget, iTarget, &sz);
206785 szTarget = n+sz;
206786 jsonBlobEdit(pTarget, iTarget, szTarget, pPatch->aBlob+iPatch, szPatch);
206787 return pTarget->oom ? JSON_MERGE_OOM : JSON_MERGE_OK; /* Line 03 */
206788 }
206789 x = pTarget->aBlob[iTarget] & 0x0f;
206790 if( x!=JSONB_OBJECT ){ /* Algorithm line 05 */
206791 n = jsonbPayloadSize(pTarget, iTarget, &sz);
206792 jsonBlobEdit(pTarget, iTarget+n, sz, 0, 0);
206793 x = pTarget->aBlob[iTarget];
206794 pTarget->aBlob[iTarget] = (x & 0xf0) | JSONB_OBJECT;
206795 }
206796 n = jsonbPayloadSize(pPatch, iPatch, &sz);
206797 if( NEVER(n==0) ) return JSON_MERGE_BADPATCH;
206798 iPCursor = iPatch+n;
206799 iPEnd = iPCursor+sz;
206800 n = jsonbPayloadSize(pTarget, iTarget, &sz);
206801 if( NEVER(n==0) ) return JSON_MERGE_BADTARGET;
206802 iTStart = iTarget+n;
206803 iTEndBE = iTStart+sz;
206804
206805 while( iPCursor<iPEnd ){ /* Algorithm line 07 */
206806 iPLabel = iPCursor;
206807 ePLabel = pPatch->aBlob[iPCursor] & 0x0f;
206808 if( ePLabel<JSONB_TEXT || ePLabel>JSONB_TEXTRAW ){
206809 return JSON_MERGE_BADPATCH;
206810 }
206811 nPLabel = jsonbPayloadSize(pPatch, iPCursor, &szPLabel);
206812 if( nPLabel==0 ) return JSON_MERGE_BADPATCH;
206813 iPValue = iPCursor + nPLabel + szPLabel;
206814 if( iPValue>=iPEnd ) return JSON_MERGE_BADPATCH;
206815 nPValue = jsonbPayloadSize(pPatch, iPValue, &szPValue);
206816 if( nPValue==0 ) return JSON_MERGE_BADPATCH;
206817 iPCursor = iPValue + nPValue + szPValue;
206818 if( iPCursor>iPEnd ) return JSON_MERGE_BADPATCH;
206819
206820 iTCursor = iTStart;
206821 iTEnd = iTEndBE + pTarget->delta;
206822 while( iTCursor<iTEnd ){
206823 int isEqual; /* true if the patch and target labels match */
206824 iTLabel = iTCursor;
206825 eTLabel = pTarget->aBlob[iTCursor] & 0x0f;
206826 if( eTLabel<JSONB_TEXT || eTLabel>JSONB_TEXTRAW ){
206827 return JSON_MERGE_BADTARGET;
206828 }
206829 nTLabel = jsonbPayloadSize(pTarget, iTCursor, &szTLabel);
206830 if( nTLabel==0 ) return JSON_MERGE_BADTARGET;
206831 iTValue = iTLabel + nTLabel + szTLabel;
206832 if( iTValue>=iTEnd ) return JSON_MERGE_BADTARGET;
206833 nTValue = jsonbPayloadSize(pTarget, iTValue, &szTValue);
206834 if( nTValue==0 ) return JSON_MERGE_BADTARGET;
206835 if( iTValue + nTValue + szTValue > iTEnd ) return JSON_MERGE_BADTARGET;
206836 isEqual = jsonLabelCompare(
206837 (const char*)&pPatch->aBlob[iPLabel+nPLabel],
206838 szPLabel,
206839 (ePLabel==JSONB_TEXT || ePLabel==JSONB_TEXTRAW),
206840 (const char*)&pTarget->aBlob[iTLabel+nTLabel],
206841 szTLabel,
206842 (eTLabel==JSONB_TEXT || eTLabel==JSONB_TEXTRAW));
206843 if( isEqual ) break;
206844 iTCursor = iTValue + nTValue + szTValue;
206845 }
206846 x = pPatch->aBlob[iPValue] & 0x0f;
206847 if( iTCursor<iTEnd ){
206848 /* A match was found. Algorithm line 08 */
206849 if( x==0 ){
206850 /* Patch value is NULL. Algorithm line 09 */
206851 jsonBlobEdit(pTarget, iTLabel, nTLabel+szTLabel+nTValue+szTValue, 0,0);
206852 /* vvvvvv----- No OOM on a delete-only edit */
206853 if( NEVER(pTarget->oom) ) return JSON_MERGE_OOM;
206854 }else{
206855 /* Algorithm line 12 */
206856 int rc, savedDelta = pTarget->delta;
206857 pTarget->delta = 0;
206858 rc = jsonMergePatch(pTarget, iTValue, pPatch, iPValue);
206859 if( rc ) return rc;
206860 pTarget->delta += savedDelta;
206861 }
206862 }else if( x>0 ){ /* Algorithm line 13 */
206863 /* No match and patch value is not NULL */
206864 u32 szNew = szPLabel+nPLabel;
206865 if( (pPatch->aBlob[iPValue] & 0x0f)!=JSONB_OBJECT ){ /* Line 14 */
206866 jsonBlobEdit(pTarget, iTEnd, 0, 0, szPValue+nPValue+szNew);
206867 if( pTarget->oom ) return JSON_MERGE_OOM;
206868 memcpy(&pTarget->aBlob[iTEnd], &pPatch->aBlob[iPLabel], szNew);
206869 memcpy(&pTarget->aBlob[iTEnd+szNew],
206870 &pPatch->aBlob[iPValue], szPValue+nPValue);
206871 }else{
206872 int rc, savedDelta;
206873 jsonBlobEdit(pTarget, iTEnd, 0, 0, szNew+1);
206874 if( pTarget->oom ) return JSON_MERGE_OOM;
206875 memcpy(&pTarget->aBlob[iTEnd], &pPatch->aBlob[iPLabel], szNew);
206876 pTarget->aBlob[iTEnd+szNew] = 0x00;
206877 savedDelta = pTarget->delta;
206878 pTarget->delta = 0;
206879 rc = jsonMergePatch(pTarget, iTEnd+szNew,pPatch,iPValue);
206880 if( rc ) return rc;
206881 pTarget->delta += savedDelta;
206882 }
206883 }
206884 }
206885 if( pTarget->delta ) jsonAfterEditSizeAdjust(pTarget, iTarget);
206886 return pTarget->oom ? JSON_MERGE_OOM : JSON_MERGE_OK;
206887 }
206888
206889
206890 /*
206891 ** Implementation of the json_mergepatch(JSON1,JSON2) function. Return a JSON
206892 ** object that is the result of running the RFC 7396 MergePatch() algorithm
206893 ** on the two arguments.
@@ -205334,32 +206895,31 @@
206895 static void jsonPatchFunc(
206896 sqlite3_context *ctx,
206897 int argc,
206898 sqlite3_value **argv
206899 ){
206900 JsonParse *pTarget; /* The TARGET */
206901 JsonParse *pPatch; /* The PATCH */
206902 int rc; /* Result code */
206903
206904 UNUSED_PARAMETER(argc);
206905 assert( argc==2 );
206906 pTarget = jsonParseFuncArg(ctx, argv[0], JSON_EDITABLE);
206907 if( pTarget==0 ) return;
206908 pPatch = jsonParseFuncArg(ctx, argv[1], 0);
206909 if( pPatch ){
206910 rc = jsonMergePatch(pTarget, 0, pPatch, 0);
206911 if( rc==JSON_MERGE_OK ){
206912 jsonReturnParse(ctx, pTarget);
206913 }else if( rc==JSON_MERGE_OOM ){
206914 sqlite3_result_error_nomem(ctx);
206915 }else{
206916 sqlite3_result_error(ctx, "malformed JSON", -1);
206917 }
206918 jsonParseFree(pPatch);
206919 }
206920 jsonParseFree(pTarget);
 
206921 }
206922
206923
206924 /*
206925 ** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON
@@ -205379,27 +206939,27 @@
206939 if( argc&1 ){
206940 sqlite3_result_error(ctx, "json_object() requires an even number "
206941 "of arguments", -1);
206942 return;
206943 }
206944 jsonStringInit(&jx, ctx);
206945 jsonAppendChar(&jx, '{');
206946 for(i=0; i<argc; i+=2){
206947 if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){
206948 sqlite3_result_error(ctx, "json_object() labels must be TEXT", -1);
206949 jsonStringReset(&jx);
206950 return;
206951 }
206952 jsonAppendSeparator(&jx);
206953 z = (const char*)sqlite3_value_text(argv[i]);
206954 n = sqlite3_value_bytes(argv[i]);
206955 jsonAppendString(&jx, z, n);
206956 jsonAppendChar(&jx, ':');
206957 jsonAppendSqlValue(&jx, argv[i+1]);
206958 }
206959 jsonAppendChar(&jx, '}');
206960 jsonReturnString(&jx, 0, 0);
206961 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
206962 }
206963
206964
206965 /*
@@ -205411,124 +206971,54 @@
206971 static void jsonRemoveFunc(
206972 sqlite3_context *ctx,
206973 int argc,
206974 sqlite3_value **argv
206975 ){
206976 JsonParse *p; /* The parse */
206977 const char *zPath = 0; /* Path of element to be removed */
206978 int i; /* Loop counter */
206979 u32 rc; /* Subroutine return code */
206980
206981 if( argc<1 ) return;
206982 p = jsonParseFuncArg(ctx, argv[0], argc>1 ? JSON_EDITABLE : 0);
206983 if( p==0 ) return;
206984 for(i=1; i<argc; i++){
206985 zPath = (const char*)sqlite3_value_text(argv[i]);
206986 if( zPath==0 ){
206987 goto json_remove_done;
206988 }
206989 if( zPath[0]!='$' ){
206990 goto json_remove_patherror;
206991 }
206992 if( zPath[1]==0 ){
206993 /* json_remove(j,'$') returns NULL */
206994 goto json_remove_done;
206995 }
206996 p->eEdit = JEDIT_DEL;
206997 p->delta = 0;
206998 rc = jsonLookupStep(p, 0, zPath+1, 0);
206999 if( JSON_LOOKUP_ISERROR(rc) ){
207000 if( rc==JSON_LOOKUP_NOTFOUND ){
207001 continue; /* No-op */
207002 }else if( rc==JSON_LOOKUP_PATHERROR ){
207003 jsonBadPathError(ctx, zPath);
207004 }else{
207005 sqlite3_result_error(ctx, "malformed JSON", -1);
207006 }
207007 goto json_remove_done;
207008 }
207009 }
207010 jsonReturnParse(ctx, p);
207011 jsonParseFree(p);
207012 return;
207013
207014 json_remove_patherror:
207015 jsonBadPathError(ctx, zPath);
207016
207017 json_remove_done:
207018 jsonParseFree(p);
207019 return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
207020 }
207021
207022 /*
207023 ** json_replace(JSON, PATH, VALUE, ...)
207024 **
@@ -205538,36 +207028,16 @@
207028 static void jsonReplaceFunc(
207029 sqlite3_context *ctx,
207030 int argc,
207031 sqlite3_value **argv
207032 ){
 
 
 
 
 
207033 if( argc<1 ) return;
207034 if( (argc&1)==0 ) {
207035 jsonWrongNumArgs(ctx, "replace");
207036 return;
207037 }
207038 jsonInsertIntoBlob(ctx, argc, argv, JEDIT_REPL);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
207039 }
207040
207041
207042 /*
207043 ** json_set(JSON, PATH, VALUE, ...)
@@ -205584,43 +207054,20 @@
207054 static void jsonSetFunc(
207055 sqlite3_context *ctx,
207056 int argc,
207057 sqlite3_value **argv
207058 ){
207059
207060 int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx));
207061 int bIsSet = (flags&JSON_ISSET)!=0;
 
 
 
207062
207063 if( argc<1 ) return;
207064 if( (argc&1)==0 ) {
207065 jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert");
207066 return;
207067 }
207068 jsonInsertIntoBlob(ctx, argc, argv, bIsSet ? JEDIT_SET : JEDIT_INS);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
207069 }
207070
207071 /*
207072 ** json_type(JSON)
207073 ** json_type(JSON, PATH)
@@ -205632,110 +207079,221 @@
207079 sqlite3_context *ctx,
207080 int argc,
207081 sqlite3_value **argv
207082 ){
207083 JsonParse *p; /* The parse */
207084 const char *zPath = 0;
207085 u32 i;
207086
207087 p = jsonParseFuncArg(ctx, argv[0], 0);
207088 if( p==0 ) return;
207089 if( argc==2 ){
207090 zPath = (const char*)sqlite3_value_text(argv[1]);
207091 if( zPath==0 ) goto json_type_done;
207092 if( zPath[0]!='$' ){
207093 jsonBadPathError(ctx, zPath);
207094 goto json_type_done;
207095 }
207096 i = jsonLookupStep(p, 0, zPath+1, 0);
207097 if( JSON_LOOKUP_ISERROR(i) ){
207098 if( i==JSON_LOOKUP_NOTFOUND ){
207099 /* no-op */
207100 }else if( i==JSON_LOOKUP_PATHERROR ){
207101 jsonBadPathError(ctx, zPath);
207102 }else{
207103 sqlite3_result_error(ctx, "malformed JSON", -1);
207104 }
207105 goto json_type_done;
207106 }
207107 }else{
207108 i = 0;
207109 }
207110 sqlite3_result_text(ctx, jsonbType[p->aBlob[i]&0x0f], -1, SQLITE_STATIC);
207111 json_type_done:
207112 jsonParseFree(p);
207113 }
207114
207115 /*
207116 ** json_valid(JSON)
207117 ** json_valid(JSON, FLAGS)
207118 **
207119 ** Check the JSON argument to see if it is well-formed. The FLAGS argument
207120 ** encodes the various constraints on what is meant by "well-formed":
207121 **
207122 ** 0x01 Canonical RFC-8259 JSON text
207123 ** 0x02 JSON text with optional JSON-5 extensions
207124 ** 0x04 Superficially appears to be JSONB
207125 ** 0x08 Strictly well-formed JSONB
207126 **
207127 ** If the FLAGS argument is omitted, it defaults to 1. Useful values for
207128 ** FLAGS include:
207129 **
207130 ** 1 Strict canonical JSON text
207131 ** 2 JSON text perhaps with JSON-5 extensions
207132 ** 4 Superficially appears to be JSONB
207133 ** 5 Canonical JSON text or superficial JSONB
207134 ** 6 JSON-5 text or superficial JSONB
207135 ** 8 Strict JSONB
207136 ** 9 Canonical JSON text or strict JSONB
207137 ** 10 JSON-5 text or strict JSONB
207138 **
207139 ** Other flag combinations are redundant. For example, every canonical
207140 ** JSON text is also well-formed JSON-5 text, so FLAG values 2 and 3
207141 ** are the same. Similarly, any input that passes a strict JSONB validation
207142 ** will also pass the superficial validation so 12 through 15 are the same
207143 ** as 8 through 11 respectively.
207144 **
207145 ** This routine runs in linear time to validate text and when doing strict
207146 ** JSONB validation. Superficial JSONB validation is constant time,
207147 ** assuming the BLOB is already in memory. The performance advantage
207148 ** of superficial JSONB validation is why that option is provided.
207149 ** Application developers can choose to do fast superficial validation or
207150 ** slower strict validation, according to their specific needs.
207151 **
207152 ** Only the lower four bits of the FLAGS argument are currently used.
207153 ** Higher bits are reserved for future expansion. To facilitate
207154 ** compatibility, the current implementation raises an error if any bit
207155 ** in FLAGS is set other than the lower four bits.
207156 **
207157 ** The original circa 2015 implementation of the JSON routines in
207158 ** SQLite only supported canonical RFC-8259 JSON text and the json_valid()
207159 ** function only accepted one argument. That is why the default value
207160 ** for the FLAGS argument is 1, since FLAGS=1 causes this routine to only
207161 ** recognize canonical RFC-8259 JSON text as valid. The extra FLAGS
207162 ** argument was added when the JSON routines were extended to support
207163 ** JSON5-like extensions and binary JSONB stored in BLOBs.
207164 **
207165 ** Return Values:
207166 **
207167 ** * Raise an error if FLAGS is outside the range of 1 to 15.
207168 ** * Return NULL if the input is NULL
207169 ** * Return 1 if the input is well-formed.
207170 ** * Return 0 if the input is not well-formed.
207171 */
207172 static void jsonValidFunc(
207173 sqlite3_context *ctx,
207174 int argc,
207175 sqlite3_value **argv
207176 ){
207177 JsonParse *p; /* The parse */
207178 u8 flags = 1;
207179 u8 res = 0;
207180 if( argc==2 ){
207181 i64 f = sqlite3_value_int64(argv[1]);
207182 if( f<1 || f>15 ){
207183 sqlite3_result_error(ctx, "FLAGS parameter to json_valid() must be"
207184 " between 1 and 15", -1);
207185 return;
207186 }
207187 flags = f & 0x0f;
207188 }
207189 switch( sqlite3_value_type(argv[0]) ){
207190 case SQLITE_NULL: {
207191 #ifdef SQLITE_LEGACY_JSON_VALID
207192 /* Incorrect legacy behavior was to return FALSE for a NULL input */
207193 sqlite3_result_int(ctx, 0);
207194 #endif
207195 return;
207196 }
207197 case SQLITE_BLOB: {
207198 if( (flags & 0x0c)!=0 && jsonFuncArgMightBeBinary(argv[0]) ){
207199 if( flags & 0x04 ){
207200 /* Superficial checking only - accomplished by the
207201 ** jsonFuncArgMightBeBinary() call above. */
207202 res = 1;
207203 }else{
207204 /* Strict checking. Check by translating BLOB->TEXT->BLOB. If
207205 ** no errors occur, call that a "strict check". */
207206 JsonParse px;
207207 u32 iErr;
207208 memset(&px, 0, sizeof(px));
207209 px.aBlob = (u8*)sqlite3_value_blob(argv[0]);
207210 px.nBlob = sqlite3_value_bytes(argv[0]);
207211 iErr = jsonbValidityCheck(&px, 0, px.nBlob, 1);
207212 res = iErr==0;
207213 }
207214 }
207215 break;
207216 }
207217 default: {
207218 JsonParse px;
207219 if( (flags & 0x3)==0 ) break;
207220 memset(&px, 0, sizeof(px));
207221
207222 p = jsonParseFuncArg(ctx, argv[0], JSON_KEEPERROR);
207223 if( p ){
207224 if( p->oom ){
207225 sqlite3_result_error_nomem(ctx);
207226 }else if( p->nErr ){
207227 /* no-op */
207228 }else if( (flags & 0x02)!=0 || p->hasNonstd==0 ){
207229 res = 1;
207230 }
207231 jsonParseFree(p);
207232 }else{
207233 sqlite3_result_error_nomem(ctx);
207234 }
207235 break;
207236 }
207237 }
207238 sqlite3_result_int(ctx, res);
207239 }
207240
207241 /*
207242 ** json_error_position(JSON)
207243 **
207244 ** If the argument is NULL, return NULL
207245 **
207246 ** If the argument is BLOB, do a full validity check and return non-zero
207247 ** if the check fails. The return value is the approximate 1-based offset
207248 ** to the byte of the element that contains the first error.
207249 **
207250 ** Otherwise interpret the argument is TEXT (even if it is numeric) and
207251 ** return the 1-based character position for where the parser first recognized
207252 ** that the input was not valid JSON, or return 0 if the input text looks
207253 ** ok. JSON-5 extensions are accepted.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
207254 */
207255 static void jsonErrorFunc(
207256 sqlite3_context *ctx,
207257 int argc,
207258 sqlite3_value **argv
207259 ){
207260 i64 iErrPos = 0; /* Error position to be returned */
207261 JsonParse s;
207262
207263 assert( argc==1 );
207264 UNUSED_PARAMETER(argc);
207265 memset(&s, 0, sizeof(s));
207266 if( jsonFuncArgMightBeBinary(argv[0]) ){
207267 s.aBlob = (u8*)sqlite3_value_blob(argv[0]);
207268 s.nBlob = sqlite3_value_bytes(argv[0]);
207269 iErrPos = (i64)jsonbValidityCheck(&s, 0, s.nBlob, 1);
207270 }else{
207271 s.zJson = (char*)sqlite3_value_text(argv[0]);
207272 if( s.zJson==0 ) return; /* NULL input or OOM */
207273 s.nJson = sqlite3_value_bytes(argv[0]);
207274 if( jsonConvertTextToBlob(&s,0) ){
207275 if( s.oom ){
207276 iErrPos = -1;
207277 }else{
207278 /* Convert byte-offset s.iErr into a character offset */
207279 u32 k;
207280 assert( s.zJson!=0 ); /* Because s.oom is false */
207281 for(k=0; k<s.iErr && ALWAYS(s.zJson[k]); k++){
207282 if( (s.zJson[k] & 0xc0)!=0x80 ) iErrPos++;
207283 }
207284 iErrPos++;
207285 }
207286 }
207287 }
207288 jsonParseReset(&s);
207289 if( iErrPos<0 ){
207290 sqlite3_result_error_nomem(ctx);
207291 }else{
207292 sqlite3_result_int64(ctx, iErrPos);
207293 }
207294 }
 
 
 
 
 
 
 
 
 
 
 
207295
207296 /****************************************************************************
207297 ** Aggregate SQL function implementations
207298 ****************************************************************************/
207299 /*
@@ -205751,28 +207309,38 @@
207309 JsonString *pStr;
207310 UNUSED_PARAMETER(argc);
207311 pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
207312 if( pStr ){
207313 if( pStr->zBuf==0 ){
207314 jsonStringInit(pStr, ctx);
207315 jsonAppendChar(pStr, '[');
207316 }else if( pStr->nUsed>1 ){
207317 jsonAppendChar(pStr, ',');
207318 }
207319 pStr->pCtx = ctx;
207320 jsonAppendSqlValue(pStr, argv[0]);
207321 }
207322 }
207323 static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){
207324 JsonString *pStr;
207325 pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
207326 if( pStr ){
207327 int flags;
207328 pStr->pCtx = ctx;
207329 jsonAppendChar(pStr, ']');
207330 flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx));
207331 if( pStr->eErr ){
207332 jsonReturnString(pStr, 0, 0);
207333 return;
207334 }else if( flags & JSON_BLOB ){
207335 jsonReturnStringAsBlob(pStr);
207336 if( isFinal ){
207337 if( !pStr->bStatic ) sqlite3RCStrUnref(pStr->zBuf);
207338 }else{
207339 pStr->nUsed--;
207340 }
207341 return;
207342 }else if( isFinal ){
207343 sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed,
207344 pStr->bStatic ? SQLITE_TRANSIENT :
207345 sqlite3RCStrUnref);
207346 pStr->bStatic = 1;
@@ -205857,31 +207425,42 @@
207425 u32 n;
207426 UNUSED_PARAMETER(argc);
207427 pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
207428 if( pStr ){
207429 if( pStr->zBuf==0 ){
207430 jsonStringInit(pStr, ctx);
207431 jsonAppendChar(pStr, '{');
207432 }else if( pStr->nUsed>1 ){
207433 jsonAppendChar(pStr, ',');
207434 }
207435 pStr->pCtx = ctx;
207436 z = (const char*)sqlite3_value_text(argv[0]);
207437 n = sqlite3Strlen30(z);
207438 jsonAppendString(pStr, z, n);
207439 jsonAppendChar(pStr, ':');
207440 jsonAppendSqlValue(pStr, argv[1]);
207441 }
207442 }
207443 static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){
207444 JsonString *pStr;
207445 pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
207446 if( pStr ){
207447 int flags;
207448 jsonAppendChar(pStr, '}');
207449 pStr->pCtx = ctx;
207450 flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx));
207451 if( pStr->eErr ){
207452 jsonReturnString(pStr, 0, 0);
207453 return;
207454 }else if( flags & JSON_BLOB ){
207455 jsonReturnStringAsBlob(pStr);
207456 if( isFinal ){
207457 if( !pStr->bStatic ) sqlite3RCStrUnref(pStr->zBuf);
207458 }else{
207459 pStr->nUsed--;
207460 }
207461 return;
207462 }else if( isFinal ){
207463 sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed,
207464 pStr->bStatic ? SQLITE_TRANSIENT :
207465 sqlite3RCStrUnref);
207466 pStr->bStatic = 1;
@@ -205905,33 +207484,51 @@
207484
207485 #ifndef SQLITE_OMIT_VIRTUALTABLE
207486 /****************************************************************************
207487 ** The json_each virtual table
207488 ****************************************************************************/
207489 typedef struct JsonParent JsonParent;
207490 struct JsonParent {
207491 u32 iHead; /* Start of object or array */
207492 u32 iValue; /* Start of the value */
207493 u32 iEnd; /* First byte past the end */
207494 u32 nPath; /* Length of path */
207495 i64 iKey; /* Key for JSONB_ARRAY */
207496 };
207497
207498 typedef struct JsonEachCursor JsonEachCursor;
207499 struct JsonEachCursor {
207500 sqlite3_vtab_cursor base; /* Base class - must be first */
207501 u32 iRowid; /* The rowid */
207502 u32 i; /* Index in sParse.aBlob[] of current row */
 
207503 u32 iEnd; /* EOF when i equals or exceeds this value */
207504 u32 nRoot; /* Size of the root path in bytes */
207505 u8 eType; /* Type of the container for element i */
207506 u8 bRecursive; /* True for json_tree(). False for json_each() */
207507 u32 nParent; /* Current nesting depth */
207508 u32 nParentAlloc; /* Space allocated for aParent[] */
207509 JsonParent *aParent; /* Parent elements of i */
207510 sqlite3 *db; /* Database connection */
207511 JsonString path; /* Current path */
207512 JsonParse sParse; /* Parse of the input JSON */
207513 };
207514 typedef struct JsonEachConnection JsonEachConnection;
207515 struct JsonEachConnection {
207516 sqlite3_vtab base; /* Base class - must be first */
207517 sqlite3 *db; /* Database connection */
207518 };
207519
207520
207521 /* Constructor for the json_each virtual table */
207522 static int jsonEachConnect(
207523 sqlite3 *db,
207524 void *pAux,
207525 int argc, const char *const*argv,
207526 sqlite3_vtab **ppVtab,
207527 char **pzErr
207528 ){
207529 JsonEachConnection *pNew;
207530 int rc;
207531
207532 /* Column numbers */
207533 #define JEACH_KEY 0
207534 #define JEACH_VALUE 1
@@ -205953,14 +207550,15 @@
207550 UNUSED_PARAMETER(pAux);
207551 rc = sqlite3_declare_vtab(db,
207552 "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path,"
207553 "json HIDDEN,root HIDDEN)");
207554 if( rc==SQLITE_OK ){
207555 pNew = (JsonEachConnection*)(*ppVtab = sqlite3_malloc( sizeof(*pNew) ));
207556 if( pNew==0 ) return SQLITE_NOMEM;
207557 memset(pNew, 0, sizeof(*pNew));
207558 sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
207559 pNew->db = db;
207560 }
207561 return rc;
207562 }
207563
207564 /* destructor for json_each virtual table */
@@ -205969,16 +207567,19 @@
207567 return SQLITE_OK;
207568 }
207569
207570 /* constructor for a JsonEachCursor object for json_each(). */
207571 static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
207572 JsonEachConnection *pVtab = (JsonEachConnection*)p;
207573 JsonEachCursor *pCur;
207574
207575 UNUSED_PARAMETER(p);
207576 pCur = sqlite3_malloc( sizeof(*pCur) );
207577 if( pCur==0 ) return SQLITE_NOMEM;
207578 memset(pCur, 0, sizeof(*pCur));
207579 pCur->db = pVtab->db;
207580 jsonStringZero(&pCur->path);
207581 *ppCursor = &pCur->base;
207582 return SQLITE_OK;
207583 }
207584
207585 /* constructor for a JsonEachCursor object for json_tree(). */
@@ -205992,24 +207593,27 @@
207593 }
207594
207595 /* Reset a JsonEachCursor back to its original state. Free any memory
207596 ** held. */
207597 static void jsonEachCursorReset(JsonEachCursor *p){
 
207598 jsonParseReset(&p->sParse);
207599 jsonStringReset(&p->path);
207600 sqlite3DbFree(p->db, p->aParent);
207601 p->iRowid = 0;
207602 p->i = 0;
207603 p->aParent = 0;
207604 p->nParent = 0;
207605 p->nParentAlloc = 0;
207606 p->iEnd = 0;
207607 p->eType = 0;
 
 
207608 }
207609
207610 /* Destructor for a jsonEachCursor object */
207611 static int jsonEachClose(sqlite3_vtab_cursor *cur){
207612 JsonEachCursor *p = (JsonEachCursor*)cur;
207613 jsonEachCursorReset(p);
207614
207615 sqlite3_free(cur);
207616 return SQLITE_OK;
207617 }
207618
207619 /* Return TRUE if the jsonEachCursor object has been advanced off the end
@@ -206016,205 +207620,235 @@
207620 ** of the JSON object */
207621 static int jsonEachEof(sqlite3_vtab_cursor *cur){
207622 JsonEachCursor *p = (JsonEachCursor*)cur;
207623 return p->i >= p->iEnd;
207624 }
207625
207626 /*
207627 ** If the cursor is currently pointing at the label of a object entry,
207628 ** then return the index of the value. For all other cases, return the
207629 ** current pointer position, which is the value.
207630 */
207631 static int jsonSkipLabel(JsonEachCursor *p){
207632 if( p->eType==JSONB_OBJECT ){
207633 u32 sz = 0;
207634 u32 n = jsonbPayloadSize(&p->sParse, p->i, &sz);
207635 return p->i + n + sz;
207636 }else{
207637 return p->i;
207638 }
207639 }
207640
207641 /*
207642 ** Append the path name for the current element.
207643 */
207644 static void jsonAppendPathName(JsonEachCursor *p){
207645 assert( p->nParent>0 );
207646 assert( p->eType==JSONB_ARRAY || p->eType==JSONB_OBJECT );
207647 if( p->eType==JSONB_ARRAY ){
207648 jsonPrintf(30, &p->path, "[%lld]", p->aParent[p->nParent-1].iKey);
207649 }else{
207650 u32 n, sz = 0, k, i;
207651 const char *z;
207652 int needQuote = 0;
207653 n = jsonbPayloadSize(&p->sParse, p->i, &sz);
207654 k = p->i + n;
207655 z = (const char*)&p->sParse.aBlob[k];
207656 if( sz==0 || !sqlite3Isalpha(z[0]) ){
207657 needQuote = 1;
207658 }else{
207659 for(i=0; i<sz; i++){
207660 if( !sqlite3Isalnum(z[i]) ){
207661 needQuote = 1;
207662 break;
207663 }
207664 }
207665 }
207666 if( needQuote ){
207667 jsonPrintf(sz+4,&p->path,".\"%.*s\"", sz, z);
207668 }else{
207669 jsonPrintf(sz+2,&p->path,".%.*s", sz, z);
207670 }
207671 }
207672 }
207673
207674 /* Advance the cursor to the next element for json_tree() */
207675 static int jsonEachNext(sqlite3_vtab_cursor *cur){
207676 JsonEachCursor *p = (JsonEachCursor*)cur;
207677 int rc = SQLITE_OK;
207678 if( p->bRecursive ){
207679 u8 x;
207680 u8 levelChange = 0;
207681 u32 n, sz = 0;
207682 u32 i = jsonSkipLabel(p);
207683 x = p->sParse.aBlob[i] & 0x0f;
207684 n = jsonbPayloadSize(&p->sParse, i, &sz);
207685 if( x==JSONB_OBJECT || x==JSONB_ARRAY ){
207686 JsonParent *pParent;
207687 if( p->nParent>=p->nParentAlloc ){
207688 JsonParent *pNew;
207689 u64 nNew;
207690 nNew = p->nParentAlloc*2 + 3;
207691 pNew = sqlite3DbRealloc(p->db, p->aParent, sizeof(JsonParent)*nNew);
207692 if( pNew==0 ) return SQLITE_NOMEM;
207693 p->nParentAlloc = (u32)nNew;
207694 p->aParent = pNew;
207695 }
207696 levelChange = 1;
207697 pParent = &p->aParent[p->nParent];
207698 pParent->iHead = p->i;
207699 pParent->iValue = i;
207700 pParent->iEnd = i + n + sz;
207701 pParent->iKey = -1;
207702 pParent->nPath = (u32)p->path.nUsed;
207703 if( p->eType && p->nParent ){
207704 jsonAppendPathName(p);
207705 if( p->path.eErr ) rc = SQLITE_NOMEM;
207706 }
207707 p->nParent++;
207708 p->i = i + n;
207709 }else{
207710 p->i = i + n + sz;
207711 }
207712 while( p->nParent>0 && p->i >= p->aParent[p->nParent-1].iEnd ){
207713 p->nParent--;
207714 p->path.nUsed = p->aParent[p->nParent].nPath;
207715 levelChange = 1;
207716 }
207717 if( levelChange ){
207718 if( p->nParent>0 ){
207719 JsonParent *pParent = &p->aParent[p->nParent-1];
207720 u32 iVal = pParent->iValue;
207721 p->eType = p->sParse.aBlob[iVal] & 0x0f;
207722 }else{
207723 p->eType = 0;
207724 }
207725 }
207726 }else{
207727 u32 n, sz = 0;
207728 u32 i = jsonSkipLabel(p);
207729 n = jsonbPayloadSize(&p->sParse, i, &sz);
207730 p->i = i + n + sz;
207731 }
207732 if( p->eType==JSONB_ARRAY && p->nParent ){
207733 p->aParent[p->nParent-1].iKey++;
207734 }
207735 p->iRowid++;
207736 return rc;
207737 }
207738
207739 /* Length of the path for rowid==0 in bRecursive mode.
207740 */
207741 static int jsonEachPathLength(JsonEachCursor *p){
207742 u32 n = p->path.nUsed;
207743 char *z = p->path.zBuf;
207744 if( p->iRowid==0 && p->bRecursive && n>=2 ){
207745 while( n>1 ){
207746 n--;
207747 if( z[n]=='[' || z[n]=='.' ){
207748 u32 x, sz = 0;
207749 char cSaved = z[n];
207750 z[n] = 0;
207751 assert( p->sParse.eEdit==0 );
207752 x = jsonLookupStep(&p->sParse, 0, z+1, 0);
207753 z[n] = cSaved;
207754 if( JSON_LOOKUP_ISERROR(x) ) continue;
207755 if( x + jsonbPayloadSize(&p->sParse, x, &sz) == p->i ) break;
207756 }
207757 }
207758 }
207759 return n;
 
 
 
 
 
 
 
 
 
 
 
 
 
207760 }
207761
207762 /* Return the value of a column */
207763 static int jsonEachColumn(
207764 sqlite3_vtab_cursor *cur, /* The cursor */
207765 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
207766 int iColumn /* Which column to return */
207767 ){
207768 JsonEachCursor *p = (JsonEachCursor*)cur;
207769 switch( iColumn ){
 
207770 case JEACH_KEY: {
207771 if( p->nParent==0 ){
207772 u32 n, j;
207773 if( p->nRoot==1 ) break;
207774 j = jsonEachPathLength(p);
207775 n = p->nRoot - j;
207776 if( n==0 ){
207777 break;
207778 }else if( p->path.zBuf[j]=='[' ){
207779 i64 x;
207780 sqlite3Atoi64(&p->path.zBuf[j+1], &x, n-1, SQLITE_UTF8);
207781 sqlite3_result_int64(ctx, x);
207782 }else if( p->path.zBuf[j+1]=='"' ){
207783 sqlite3_result_text(ctx, &p->path.zBuf[j+2], n-3, SQLITE_TRANSIENT);
207784 }else{
207785 sqlite3_result_text(ctx, &p->path.zBuf[j+1], n-1, SQLITE_TRANSIENT);
207786 }
207787 break;
207788 }
207789 if( p->eType==JSONB_OBJECT ){
207790 jsonReturnFromBlob(&p->sParse, p->i, ctx, 1);
207791 }else{
207792 assert( p->eType==JSONB_ARRAY );
207793 sqlite3_result_int64(ctx, p->aParent[p->nParent-1].iKey);
207794 }
207795 break;
207796 }
207797 case JEACH_VALUE: {
207798 u32 i = jsonSkipLabel(p);
207799 jsonReturnFromBlob(&p->sParse, i, ctx, 1);
207800 break;
207801 }
207802 case JEACH_TYPE: {
207803 u32 i = jsonSkipLabel(p);
207804 u8 eType = p->sParse.aBlob[i] & 0x0f;
207805 sqlite3_result_text(ctx, jsonbType[eType], -1, SQLITE_STATIC);
207806 break;
207807 }
207808 case JEACH_ATOM: {
207809 u32 i = jsonSkipLabel(p);
207810 if( (p->sParse.aBlob[i] & 0x0f)<JSONB_ARRAY ){
207811 jsonReturnFromBlob(&p->sParse, i, ctx, 1);
207812 }
207813 break;
207814 }
207815 case JEACH_ID: {
207816 sqlite3_result_int64(ctx, (sqlite3_int64)p->i);
 
207817 break;
207818 }
207819 case JEACH_PARENT: {
207820 if( p->nParent>0 && p->bRecursive ){
207821 sqlite3_result_int64(ctx, p->aParent[p->nParent-1].iHead);
207822 }
207823 break;
207824 }
207825 case JEACH_FULLKEY: {
207826 u64 nBase = p->path.nUsed;
207827 if( p->nParent ) jsonAppendPathName(p);
207828 sqlite3_result_text64(ctx, p->path.zBuf, p->path.nUsed,
207829 SQLITE_TRANSIENT, SQLITE_UTF8);
207830 p->path.nUsed = nBase;
 
 
 
 
 
 
 
 
 
 
 
 
207831 break;
207832 }
207833 case JEACH_PATH: {
207834 u32 n = jsonEachPathLength(p);
207835 sqlite3_result_text64(ctx, p->path.zBuf, n,
207836 SQLITE_TRANSIENT, SQLITE_UTF8);
207837 break;
 
 
 
 
 
 
207838 }
207839 default: {
207840 sqlite3_result_text(ctx, p->path.zBuf, p->nRoot, SQLITE_STATIC);
 
 
207841 break;
207842 }
207843 case JEACH_JSON: {
207844 if( p->sParse.zJson==0 ){
207845 sqlite3_result_blob(ctx, p->sParse.aBlob, p->sParse.nBlob,
207846 SQLITE_STATIC);
207847 }else{
207848 sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC);
207849 }
207850 break;
207851 }
207852 }
207853 return SQLITE_OK;
207854 }
@@ -206301,90 +207935,104 @@
207935 sqlite3_vtab_cursor *cur,
207936 int idxNum, const char *idxStr,
207937 int argc, sqlite3_value **argv
207938 ){
207939 JsonEachCursor *p = (JsonEachCursor*)cur;
 
207940 const char *zRoot = 0;
207941 u32 i, n, sz;
207942
207943 UNUSED_PARAMETER(idxStr);
207944 UNUSED_PARAMETER(argc);
207945 jsonEachCursorReset(p);
207946 if( idxNum==0 ) return SQLITE_OK;
 
 
207947 memset(&p->sParse, 0, sizeof(p->sParse));
207948 p->sParse.nJPRef = 1;
207949 if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
207950 if( jsonFuncArgMightBeBinary(argv[0]) ){
207951 p->sParse.nBlob = sqlite3_value_bytes(argv[0]);
207952 p->sParse.aBlob = (u8*)sqlite3_value_blob(argv[0]);
207953 }else{
207954 goto json_each_malformed_input;
207955 }
207956 }else{
207957 p->sParse.zJson = (char*)sqlite3_value_text(argv[0]);
207958 p->sParse.nJson = sqlite3_value_bytes(argv[0]);
207959 if( p->sParse.zJson==0 ){
207960 p->i = p->iEnd = 0;
207961 return SQLITE_OK;
207962 }
207963 if( jsonConvertTextToBlob(&p->sParse, 0) ){
207964 if( p->sParse.oom ){
207965 return SQLITE_NOMEM;
207966 }
207967 goto json_each_malformed_input;
207968 }
207969 }
207970 if( idxNum==3 ){
207971 zRoot = (const char*)sqlite3_value_text(argv[1]);
207972 if( zRoot==0 ) return SQLITE_OK;
207973 if( zRoot[0]!='$' ){
207974 sqlite3_free(cur->pVtab->zErrMsg);
207975 cur->pVtab->zErrMsg = jsonBadPathError(0, zRoot);
207976 jsonEachCursorReset(p);
207977 return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
207978 }
207979 p->nRoot = sqlite3Strlen30(zRoot);
207980 if( zRoot[1]==0 ){
207981 i = p->i = 0;
207982 p->eType = 0;
207983 }else{
207984 i = jsonLookupStep(&p->sParse, 0, zRoot+1, 0);
207985 if( JSON_LOOKUP_ISERROR(i) ){
207986 if( i==JSON_LOOKUP_NOTFOUND ){
207987 p->i = 0;
207988 p->eType = 0;
207989 p->iEnd = 0;
207990 return SQLITE_OK;
207991 }
207992 sqlite3_free(cur->pVtab->zErrMsg);
207993 cur->pVtab->zErrMsg = jsonBadPathError(0, zRoot);
207994 jsonEachCursorReset(p);
207995 return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
207996 }
207997 if( p->sParse.iLabel ){
207998 p->i = p->sParse.iLabel;
207999 p->eType = JSONB_OBJECT;
208000 }else{
208001 p->i = i;
208002 p->eType = JSONB_ARRAY;
208003 }
208004 }
208005 jsonAppendRaw(&p->path, zRoot, p->nRoot);
208006 }else{
208007 i = p->i = 0;
208008 p->eType = 0;
208009 p->nRoot = 1;
208010 jsonAppendRaw(&p->path, "$", 1);
208011 }
208012 p->nParent = 0;
208013 n = jsonbPayloadSize(&p->sParse, i, &sz);
208014 p->iEnd = i+n+sz;
208015 if( (p->sParse.aBlob[i] & 0x0f)>=JSONB_ARRAY && !p->bRecursive ){
208016 p->i = i + n;
208017 p->eType = p->sParse.aBlob[i] & 0x0f;
208018 p->aParent = sqlite3DbMallocZero(p->db, sizeof(JsonParent));
208019 if( p->aParent==0 ) return SQLITE_NOMEM;
208020 p->nParent = 1;
208021 p->nParentAlloc = 1;
208022 p->aParent[0].iKey = 0;
208023 p->aParent[0].iEnd = p->iEnd;
208024 p->aParent[0].iHead = p->i;
208025 p->aParent[0].iValue = i;
208026 }
208027 return SQLITE_OK;
208028
208029 json_each_malformed_input:
208030 sqlite3_free(cur->pVtab->zErrMsg);
208031 cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON");
208032 jsonEachCursorReset(p);
208033 return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
208034 }
208035
208036 /* The methods of the json_each virtual table */
208037 static sqlite3_module jsonEachModule = {
208038 0, /* iVersion */
@@ -206449,44 +208097,58 @@
208097 ** Register JSON functions.
208098 */
208099 SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void){
208100 #ifndef SQLITE_OMIT_JSON
208101 static FuncDef aJsonFunc[] = {
208102 /* sqlite3_result_subtype() ----, ,--- sqlite3_value_subtype() */
208103 /* | | */
208104 /* Uses cache ------, | | ,---- Returns JSONB */
208105 /* | | | | */
208106 /* Number of arguments ---, | | | | ,--- Flags */
208107 /* | | | | | | */
208108 JFUNCTION(json, 1,1,1, 0,0,0, jsonRemoveFunc),
208109 JFUNCTION(jsonb, 1,1,0, 0,1,0, jsonRemoveFunc),
208110 JFUNCTION(json_array, -1,0,1, 1,0,0, jsonArrayFunc),
208111 JFUNCTION(jsonb_array, -1,0,1, 1,1,0, jsonArrayFunc),
208112 JFUNCTION(json_array_length, 1,1,0, 0,0,0, jsonArrayLengthFunc),
208113 JFUNCTION(json_array_length, 2,1,0, 0,0,0, jsonArrayLengthFunc),
208114 JFUNCTION(json_error_position,1,1,0, 0,0,0, jsonErrorFunc),
208115 JFUNCTION(json_extract, -1,1,1, 0,0,0, jsonExtractFunc),
208116 JFUNCTION(jsonb_extract, -1,1,0, 0,1,0, jsonExtractFunc),
208117 JFUNCTION(->, 2,1,1, 0,0,JSON_JSON, jsonExtractFunc),
208118 JFUNCTION(->>, 2,1,0, 0,0,JSON_SQL, jsonExtractFunc),
208119 JFUNCTION(json_insert, -1,1,1, 1,0,0, jsonSetFunc),
208120 JFUNCTION(jsonb_insert, -1,1,0, 1,1,0, jsonSetFunc),
208121 JFUNCTION(json_object, -1,0,1, 1,0,0, jsonObjectFunc),
208122 JFUNCTION(jsonb_object, -1,0,1, 1,1,0, jsonObjectFunc),
208123 JFUNCTION(json_patch, 2,1,1, 0,0,0, jsonPatchFunc),
208124 JFUNCTION(jsonb_patch, 2,1,0, 0,1,0, jsonPatchFunc),
208125 JFUNCTION(json_quote, 1,0,1, 1,0,0, jsonQuoteFunc),
208126 JFUNCTION(json_remove, -1,1,1, 0,0,0, jsonRemoveFunc),
208127 JFUNCTION(jsonb_remove, -1,1,0, 0,1,0, jsonRemoveFunc),
208128 JFUNCTION(json_replace, -1,1,1, 1,0,0, jsonReplaceFunc),
208129 JFUNCTION(jsonb_replace, -1,1,0, 1,1,0, jsonReplaceFunc),
208130 JFUNCTION(json_set, -1,1,1, 1,0,JSON_ISSET, jsonSetFunc),
208131 JFUNCTION(jsonb_set, -1,1,0, 1,1,JSON_ISSET, jsonSetFunc),
208132 JFUNCTION(json_type, 1,1,0, 0,0,0, jsonTypeFunc),
208133 JFUNCTION(json_type, 2,1,0, 0,0,0, jsonTypeFunc),
208134 JFUNCTION(json_valid, 1,1,0, 0,0,0, jsonValidFunc),
208135 JFUNCTION(json_valid, 2,1,0, 0,0,0, jsonValidFunc),
208136 #if SQLITE_DEBUG
208137 JFUNCTION(json_parse, 1,1,0, 0,0,0, jsonParseFunc),
208138 #endif
208139 WAGGREGATE(json_group_array, 1, 0, 0,
208140 jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse,
208141 SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|
208142 SQLITE_DETERMINISTIC),
208143 WAGGREGATE(jsonb_group_array, 1, JSON_BLOB, 0,
208144 jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse,
208145 SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC),
208146 WAGGREGATE(json_group_object, 2, 0, 0,
208147 jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse,
208148 SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC),
208149 WAGGREGATE(jsonb_group_object,2, JSON_BLOB, 0,
208150 jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse,
208151 SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|
208152 SQLITE_DETERMINISTIC)
208153 };
208154 sqlite3InsertBuiltinFuncs(aJsonFunc, ArraySize(aJsonFunc));
@@ -227778,13 +229440,38 @@
229440 ** significantly more efficient than those alternatives when used with
229441 ** "detail=column" tables.
229442 **
229443 ** xPhraseNextColumn()
229444 ** See xPhraseFirstColumn above.
229445 **
229446 ** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken)
229447 ** This is used to access token iToken of phrase iPhrase of the current
229448 ** query. Before returning, output parameter *ppToken is set to point
229449 ** to a buffer containing the requested token, and *pnToken to the
229450 ** size of this buffer in bytes.
229451 **
229452 ** The output text is not a copy of the query text that specified the
229453 ** token. It is the output of the tokenizer module. For tokendata=1
229454 ** tables, this includes any embedded 0x00 and trailing data.
229455 **
229456 ** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken)
229457 ** This is used to access token iToken of phrase hit iIdx within the
229458 ** current row. Output variable (*ppToken) is set to point to a buffer
229459 ** containing the matching document token, and (*pnToken) to the size
229460 ** of that buffer in bytes. This API is not available if the specified
229461 ** token matches a prefix query term. In that case both output variables
229462 ** are always set to 0.
229463 **
229464 ** The output text is not a copy of the document text that was tokenized.
229465 ** It is the output of the tokenizer module. For tokendata=1 tables, this
229466 ** includes any embedded 0x00 and trailing data.
229467 **
229468 ** This API can be quite slow if used with an FTS5 table created with the
229469 ** "detail=none" or "detail=column" option.
229470 */
229471 struct Fts5ExtensionApi {
229472 int iVersion; /* Currently always set to 3 */
229473
229474 void *(*xUserData)(Fts5Context*);
229475
229476 int (*xColumnCount)(Fts5Context*);
229477 int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
@@ -227815,10 +229502,17 @@
229502 int (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*);
229503 void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff);
229504
229505 int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*);
229506 void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol);
229507
229508 /* Below this point are iVersion>=3 only */
229509 int (*xQueryToken)(Fts5Context*,
229510 int iPhrase, int iToken,
229511 const char **ppToken, int *pnToken
229512 );
229513 int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*);
229514 };
229515
229516 /*
229517 ** CUSTOM AUXILIARY FUNCTIONS
229518 *************************************************************************/
@@ -228289,10 +229983,11 @@
229983 int eContent; /* An FTS5_CONTENT value */
229984 int bContentlessDelete; /* "contentless_delete=" option (dflt==0) */
229985 char *zContent; /* content table */
229986 char *zContentRowid; /* "content_rowid=" option value */
229987 int bColumnsize; /* "columnsize=" option value (dflt==1) */
229988 int bTokendata; /* "tokendata=" option value (dflt==0) */
229989 int eDetail; /* FTS5_DETAIL_XXX value */
229990 char *zContentExprlist;
229991 Fts5Tokenizer *pTok;
229992 fts5_tokenizer *pTokApi;
229993 int bLock; /* True when table is preparing statement */
@@ -228477,21 +230172,23 @@
230172 #define sqlite3Fts5IterEof(x) ((x)->bEof)
230173
230174 /*
230175 ** Values used as part of the flags argument passed to IndexQuery().
230176 */
230177 #define FTS5INDEX_QUERY_PREFIX 0x0001 /* Prefix query */
230178 #define FTS5INDEX_QUERY_DESC 0x0002 /* Docs in descending rowid order */
230179 #define FTS5INDEX_QUERY_TEST_NOIDX 0x0004 /* Do not use prefix index */
230180 #define FTS5INDEX_QUERY_SCAN 0x0008 /* Scan query (fts5vocab) */
230181
230182 /* The following are used internally by the fts5_index.c module. They are
230183 ** defined here only to make it easier to avoid clashes with the flags
230184 ** above. */
230185 #define FTS5INDEX_QUERY_SKIPEMPTY 0x0010
230186 #define FTS5INDEX_QUERY_NOOUTPUT 0x0020
230187 #define FTS5INDEX_QUERY_SKIPHASH 0x0040
230188 #define FTS5INDEX_QUERY_NOTOKENDATA 0x0080
230189 #define FTS5INDEX_QUERY_SCANONETERM 0x0100
230190
230191 /*
230192 ** Create/destroy an Fts5Index object.
230193 */
230194 static int sqlite3Fts5IndexOpen(Fts5Config *pConfig, int bCreate, Fts5Index**, char**);
@@ -228556,10 +230253,14 @@
230253 static int sqlite3Fts5IterNextScan(Fts5IndexIter*);
230254 static void *sqlite3Fts5StructureRef(Fts5Index*);
230255 static void sqlite3Fts5StructureRelease(void*);
230256 static int sqlite3Fts5StructureTest(Fts5Index*, void*);
230257
230258 /*
230259 ** Used by xInstToken():
230260 */
230261 static int sqlite3Fts5IterToken(Fts5IndexIter*, i64, int, int, const char**, int*);
230262
230263 /*
230264 ** Insert or remove data to or from the index. Each time a document is
230265 ** added to or removed from the index, this function is called one or more
230266 ** times.
@@ -228632,10 +230333,17 @@
230333
230334 static int sqlite3Fts5IndexLoadConfig(Fts5Index *p);
230335
230336 static int sqlite3Fts5IndexGetOrigin(Fts5Index *p, i64 *piOrigin);
230337 static int sqlite3Fts5IndexContentlessDelete(Fts5Index *p, i64 iOrigin, i64 iRowid);
230338
230339 static void sqlite3Fts5IndexIterClearTokendata(Fts5IndexIter*);
230340
230341 /* Used to populate hash tables for xInstToken in detail=none/column mode. */
230342 static int sqlite3Fts5IndexIterWriteTokendata(
230343 Fts5IndexIter*, const char*, int, i64 iRowid, int iCol, int iOff
230344 );
230345
230346 /*
230347 ** End of interface to code in fts5_index.c.
230348 **************************************************************************/
230349
@@ -228738,10 +230446,11 @@
230446 );
230447 static void sqlite3Fts5HashScanNext(Fts5Hash*);
230448 static int sqlite3Fts5HashScanEof(Fts5Hash*);
230449 static void sqlite3Fts5HashScanEntry(Fts5Hash *,
230450 const char **pzTerm, /* OUT: term (nul-terminated) */
230451 int *pnTerm, /* OUT: Size of term in bytes */
230452 const u8 **ppDoclist, /* OUT: pointer to doclist */
230453 int *pnDoclist /* OUT: size of doclist in bytes */
230454 );
230455
230456
@@ -228863,10 +230572,14 @@
230572 static void sqlite3Fts5ExprCheckPoslists(Fts5Expr*, i64);
230573
230574 static int sqlite3Fts5ExprClonePhrase(Fts5Expr*, int, Fts5Expr**);
230575
230576 static int sqlite3Fts5ExprPhraseCollist(Fts5Expr *, int, const u8 **, int *);
230577
230578 static int sqlite3Fts5ExprQueryToken(Fts5Expr*, int, int, const char**, int*);
230579 static int sqlite3Fts5ExprInstToken(Fts5Expr*, i64, int, int, int, int, const char**, int*);
230580 static void sqlite3Fts5ExprClearTokens(Fts5Expr*);
230581
230582 /*******************************************
230583 ** The fts5_expr.c API above this point is used by the other hand-written
230584 ** C code in this module. The interfaces below this point are called by
230585 ** the parser code in fts5parse.y. */
@@ -230679,10 +232392,18 @@
232392 rc = fts5CInstIterNext(&p->iter);
232393 }
232394 }
232395
232396 if( iPos==p->iRangeEnd ){
232397 if( p->bOpen ){
232398 if( p->iter.iStart>=0 && iPos>=p->iter.iStart ){
232399 fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff);
232400 p->iOff = iEndOff;
232401 }
232402 fts5HighlightAppend(&rc, p, p->zClose, -1);
232403 p->bOpen = 0;
232404 }
232405 fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff);
232406 p->iOff = iEndOff;
232407 }
232408
232409 return rc;
@@ -231280,10 +233001,11 @@
233001 u32 nData,
233002 const u8 *pData
233003 ){
233004 if( nData ){
233005 if( fts5BufferGrow(pRc, pBuf, nData) ) return;
233006 assert( pBuf->p!=0 );
233007 memcpy(&pBuf->p[pBuf->n], pData, nData);
233008 pBuf->n += nData;
233009 }
233010 }
233011
@@ -231381,17 +233103,19 @@
233103 const u8 *a, int n, /* Buffer containing poslist */
233104 int *pi, /* IN/OUT: Offset within a[] */
233105 i64 *piOff /* IN/OUT: Current offset */
233106 ){
233107 int i = *pi;
233108 assert( a!=0 || i==0 );
233109 if( i>=n ){
233110 /* EOF */
233111 *piOff = -1;
233112 return 1;
233113 }else{
233114 i64 iOff = *piOff;
233115 u32 iVal;
233116 assert( a!=0 );
233117 fts5FastGetVarint32(a, i, iVal);
233118 if( iVal<=1 ){
233119 if( iVal==0 ){
233120 *pi = i;
233121 return 0;
@@ -232018,10 +233742,20 @@
233742 if( (rc = fts5ConfigSetEnum(aDetail, zArg, &pConfig->eDetail)) ){
233743 *pzErr = sqlite3_mprintf("malformed detail=... directive");
233744 }
233745 return rc;
233746 }
233747
233748 if( sqlite3_strnicmp("tokendata", zCmd, nCmd)==0 ){
233749 if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){
233750 *pzErr = sqlite3_mprintf("malformed tokendata=... directive");
233751 rc = SQLITE_ERROR;
233752 }else{
233753 pConfig->bTokendata = (zArg[0]=='1');
233754 }
233755 return rc;
233756 }
233757
233758 *pzErr = sqlite3_mprintf("unrecognized option: \"%.*s\"", nCmd, zCmd);
233759 return SQLITE_ERROR;
233760 }
233761
@@ -232752,11 +234486,13 @@
234486 ** or term prefix.
234487 */
234488 struct Fts5ExprTerm {
234489 u8 bPrefix; /* True for a prefix term */
234490 u8 bFirst; /* True if token must be first in column */
234491 char *pTerm; /* Term data */
234492 int nQueryTerm; /* Effective size of term in bytes */
234493 int nFullTerm; /* Size of term in bytes incl. tokendata */
234494 Fts5IndexIter *pIter; /* Iterator for this term */
234495 Fts5ExprTerm *pSynonym; /* Pointer to first in list of synonyms */
234496 };
234497
234498 /*
@@ -233619,11 +235355,11 @@
235355 if( p->pIter ){
235356 sqlite3Fts5IterClose(p->pIter);
235357 p->pIter = 0;
235358 }
235359 rc = sqlite3Fts5IndexQuery(
235360 pExpr->pIndex, p->pTerm, p->nQueryTerm,
235361 (pTerm->bPrefix ? FTS5INDEX_QUERY_PREFIX : 0) |
235362 (pExpr->bDesc ? FTS5INDEX_QUERY_DESC : 0),
235363 pNear->pColset,
235364 &p->pIter
235365 );
@@ -234256,11 +235992,11 @@
235992 int i;
235993 for(i=0; i<pPhrase->nTerm; i++){
235994 Fts5ExprTerm *pSyn;
235995 Fts5ExprTerm *pNext;
235996 Fts5ExprTerm *pTerm = &pPhrase->aTerm[i];
235997 sqlite3_free(pTerm->pTerm);
235998 sqlite3Fts5IterClose(pTerm->pIter);
235999 for(pSyn=pTerm->pSynonym; pSyn; pSyn=pNext){
236000 pNext = pSyn->pSynonym;
236001 sqlite3Fts5IterClose(pSyn->pIter);
236002 fts5BufferFree((Fts5Buffer*)&pSyn[1]);
@@ -234354,10 +236090,11 @@
236090 }
236091
236092 typedef struct TokenCtx TokenCtx;
236093 struct TokenCtx {
236094 Fts5ExprPhrase *pPhrase;
236095 Fts5Config *pConfig;
236096 int rc;
236097 };
236098
236099 /*
236100 ** Callback for tokenizing terms used by ParseTerm().
@@ -234387,12 +236124,16 @@
236124 pSyn = (Fts5ExprTerm*)sqlite3_malloc64(nByte);
236125 if( pSyn==0 ){
236126 rc = SQLITE_NOMEM;
236127 }else{
236128 memset(pSyn, 0, (size_t)nByte);
236129 pSyn->pTerm = ((char*)pSyn) + sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer);
236130 pSyn->nFullTerm = pSyn->nQueryTerm = nToken;
236131 if( pCtx->pConfig->bTokendata ){
236132 pSyn->nQueryTerm = (int)strlen(pSyn->pTerm);
236133 }
236134 memcpy(pSyn->pTerm, pToken, nToken);
236135 pSyn->pSynonym = pPhrase->aTerm[pPhrase->nTerm-1].pSynonym;
236136 pPhrase->aTerm[pPhrase->nTerm-1].pSynonym = pSyn;
236137 }
236138 }else{
236139 Fts5ExprTerm *pTerm;
@@ -234413,11 +236154,15 @@
236154 }
236155
236156 if( rc==SQLITE_OK ){
236157 pTerm = &pPhrase->aTerm[pPhrase->nTerm++];
236158 memset(pTerm, 0, sizeof(Fts5ExprTerm));
236159 pTerm->pTerm = sqlite3Fts5Strndup(&rc, pToken, nToken);
236160 pTerm->nFullTerm = pTerm->nQueryTerm = nToken;
236161 if( pCtx->pConfig->bTokendata && rc==SQLITE_OK ){
236162 pTerm->nQueryTerm = (int)strlen(pTerm->pTerm);
236163 }
236164 }
236165 }
236166
236167 pCtx->rc = rc;
236168 return rc;
@@ -234480,10 +236225,11 @@
236225 int rc; /* Tokenize return code */
236226 char *z = 0;
236227
236228 memset(&sCtx, 0, sizeof(TokenCtx));
236229 sCtx.pPhrase = pAppend;
236230 sCtx.pConfig = pConfig;
236231
236232 rc = fts5ParseStringFromToken(pToken, &z);
236233 if( rc==SQLITE_OK ){
236234 int flags = FTS5_TOKENIZE_QUERY | (bPrefix ? FTS5_TOKENIZE_PREFIX : 0);
236235 int n;
@@ -234529,12 +236275,11 @@
236275 Fts5Expr **ppNew
236276 ){
236277 int rc = SQLITE_OK; /* Return code */
236278 Fts5ExprPhrase *pOrig; /* The phrase extracted from pExpr */
236279 Fts5Expr *pNew = 0; /* Expression to return via *ppNew */
236280 TokenCtx sCtx = {0,0,0}; /* Context object for fts5ParseTokenize */
 
236281 pOrig = pExpr->apExprPhrase[iPhrase];
236282 pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr));
236283 if( rc==SQLITE_OK ){
236284 pNew->apExprPhrase = (Fts5ExprPhrase**)sqlite3Fts5MallocZero(&rc,
236285 sizeof(Fts5ExprPhrase*));
@@ -234561,17 +236306,16 @@
236306 }
236307 }
236308
236309 if( pOrig->nTerm ){
236310 int i; /* Used to iterate through phrase terms */
236311 sCtx.pConfig = pExpr->pConfig;
236312 for(i=0; rc==SQLITE_OK && i<pOrig->nTerm; i++){
236313 int tflags = 0;
236314 Fts5ExprTerm *p;
236315 for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){
236316 rc = fts5ParseTokenize((void*)&sCtx, tflags, p->pTerm,p->nFullTerm,0,0);
 
 
236317 tflags = FTS5_TOKEN_COLOCATED;
236318 }
236319 if( rc==SQLITE_OK ){
236320 sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix;
236321 sCtx.pPhrase->aTerm[i].bFirst = pOrig->aTerm[i].bFirst;
@@ -234948,15 +236692,17 @@
236692 );
236693 if( pPhrase ){
236694 if( parseGrowPhraseArray(pParse) ){
236695 fts5ExprPhraseFree(pPhrase);
236696 }else{
236697 Fts5ExprTerm *p = &pNear->apPhrase[0]->aTerm[ii];
236698 Fts5ExprTerm *pTo = &pPhrase->aTerm[0];
236699 pParse->apPhrase[pParse->nPhrase++] = pPhrase;
236700 pPhrase->nTerm = 1;
236701 pTo->pTerm = sqlite3Fts5Strndup(&pParse->rc, p->pTerm, p->nFullTerm);
236702 pTo->nQueryTerm = p->nQueryTerm;
236703 pTo->nFullTerm = p->nFullTerm;
236704 pRet->apChild[ii] = sqlite3Fts5ParseNode(pParse, FTS5_STRING,
236705 0, 0, sqlite3Fts5ParseNearset(pParse, 0, pPhrase)
236706 );
236707 }
236708 }
@@ -235137,20 +236883,21 @@
236883 Fts5ExprTerm *p;
236884 char *zQuoted;
236885
236886 /* Determine the maximum amount of space required. */
236887 for(p=pTerm; p; p=p->pSynonym){
236888 nByte += pTerm->nQueryTerm * 2 + 3 + 2;
236889 }
236890 zQuoted = sqlite3_malloc64(nByte);
236891
236892 if( zQuoted ){
236893 int i = 0;
236894 for(p=pTerm; p; p=p->pSynonym){
236895 char *zIn = p->pTerm;
236896 char *zEnd = &zIn[p->nQueryTerm];
236897 zQuoted[i++] = '"';
236898 while( zIn<zEnd ){
236899 if( *zIn=='"' ) zQuoted[i++] = '"';
236900 zQuoted[i++] = *zIn++;
236901 }
236902 zQuoted[i++] = '"';
236903 if( p->pSynonym ) zQuoted[i++] = '|';
@@ -235224,12 +236971,14 @@
236971 for(i=0; i<pNear->nPhrase; i++){
236972 Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
236973
236974 zRet = fts5PrintfAppend(zRet, " {");
236975 for(iTerm=0; zRet && iTerm<pPhrase->nTerm; iTerm++){
236976 Fts5ExprTerm *p = &pPhrase->aTerm[iTerm];
236977 zRet = fts5PrintfAppend(zRet, "%s%.*s", iTerm==0?"":" ",
236978 p->nQueryTerm, p->pTerm
236979 );
236980 if( pPhrase->aTerm[iTerm].bPrefix ){
236981 zRet = fts5PrintfAppend(zRet, "*");
236982 }
236983 }
236984
@@ -235625,10 +237374,21 @@
237374 for(i=0; i<pColset->nCol; i++){
237375 if( pColset->aiCol[i]==iCol ) return 1;
237376 }
237377 return 0;
237378 }
237379
237380 /*
237381 ** pToken is a buffer nToken bytes in size that may or may not contain
237382 ** an embedded 0x00 byte. If it does, return the number of bytes in
237383 ** the buffer before the 0x00. If it does not, return nToken.
237384 */
237385 static int fts5QueryTerm(const char *pToken, int nToken){
237386 int ii;
237387 for(ii=0; ii<nToken && pToken[ii]; ii++){}
237388 return ii;
237389 }
237390
237391 static int fts5ExprPopulatePoslistsCb(
237392 void *pCtx, /* Copy of 2nd argument to xTokenize() */
237393 int tflags, /* Mask of FTS5_TOKEN_* flags */
237394 const char *pToken, /* Pointer to buffer containing token */
@@ -235637,26 +237397,37 @@
237397 int iUnused2 /* Byte offset of end of token within input text */
237398 ){
237399 Fts5ExprCtx *p = (Fts5ExprCtx*)pCtx;
237400 Fts5Expr *pExpr = p->pExpr;
237401 int i;
237402 int nQuery = nToken;
237403 i64 iRowid = pExpr->pRoot->iRowid;
237404
237405 UNUSED_PARAM2(iUnused1, iUnused2);
237406
237407 if( nQuery>FTS5_MAX_TOKEN_SIZE ) nQuery = FTS5_MAX_TOKEN_SIZE;
237408 if( pExpr->pConfig->bTokendata ){
237409 nQuery = fts5QueryTerm(pToken, nQuery);
237410 }
237411 if( (tflags & FTS5_TOKEN_COLOCATED)==0 ) p->iOff++;
237412 for(i=0; i<pExpr->nPhrase; i++){
237413 Fts5ExprTerm *pT;
237414 if( p->aPopulator[i].bOk==0 ) continue;
237415 for(pT=&pExpr->apExprPhrase[i]->aTerm[0]; pT; pT=pT->pSynonym){
237416 if( (pT->nQueryTerm==nQuery || (pT->nQueryTerm<nQuery && pT->bPrefix))
237417 && memcmp(pT->pTerm, pToken, pT->nQueryTerm)==0
 
237418 ){
237419 int rc = sqlite3Fts5PoslistWriterAppend(
237420 &pExpr->apExprPhrase[i]->poslist, &p->aPopulator[i].writer, p->iOff
237421 );
237422 if( rc==SQLITE_OK && pExpr->pConfig->bTokendata && !pT->bPrefix ){
237423 int iCol = p->iOff>>32;
237424 int iTokOff = p->iOff & 0x7FFFFFFF;
237425 rc = sqlite3Fts5IndexIterWriteTokendata(
237426 pT->pIter, pToken, nToken, iRowid, iCol, iTokOff
237427 );
237428 }
237429 if( rc ) return rc;
237430 break;
237431 }
237432 }
237433 }
@@ -235787,10 +237558,87 @@
237558 *pnCollist = 0;
237559 }
237560
237561 return rc;
237562 }
237563
237564 /*
237565 ** Does the work of the fts5_api.xQueryToken() API method.
237566 */
237567 static int sqlite3Fts5ExprQueryToken(
237568 Fts5Expr *pExpr,
237569 int iPhrase,
237570 int iToken,
237571 const char **ppOut,
237572 int *pnOut
237573 ){
237574 Fts5ExprPhrase *pPhrase = 0;
237575
237576 if( iPhrase<0 || iPhrase>=pExpr->nPhrase ){
237577 return SQLITE_RANGE;
237578 }
237579 pPhrase = pExpr->apExprPhrase[iPhrase];
237580 if( iToken<0 || iToken>=pPhrase->nTerm ){
237581 return SQLITE_RANGE;
237582 }
237583
237584 *ppOut = pPhrase->aTerm[iToken].pTerm;
237585 *pnOut = pPhrase->aTerm[iToken].nFullTerm;
237586 return SQLITE_OK;
237587 }
237588
237589 /*
237590 ** Does the work of the fts5_api.xInstToken() API method.
237591 */
237592 static int sqlite3Fts5ExprInstToken(
237593 Fts5Expr *pExpr,
237594 i64 iRowid,
237595 int iPhrase,
237596 int iCol,
237597 int iOff,
237598 int iToken,
237599 const char **ppOut,
237600 int *pnOut
237601 ){
237602 Fts5ExprPhrase *pPhrase = 0;
237603 Fts5ExprTerm *pTerm = 0;
237604 int rc = SQLITE_OK;
237605
237606 if( iPhrase<0 || iPhrase>=pExpr->nPhrase ){
237607 return SQLITE_RANGE;
237608 }
237609 pPhrase = pExpr->apExprPhrase[iPhrase];
237610 if( iToken<0 || iToken>=pPhrase->nTerm ){
237611 return SQLITE_RANGE;
237612 }
237613 pTerm = &pPhrase->aTerm[iToken];
237614 if( pTerm->bPrefix==0 ){
237615 if( pExpr->pConfig->bTokendata ){
237616 rc = sqlite3Fts5IterToken(
237617 pTerm->pIter, iRowid, iCol, iOff+iToken, ppOut, pnOut
237618 );
237619 }else{
237620 *ppOut = pTerm->pTerm;
237621 *pnOut = pTerm->nFullTerm;
237622 }
237623 }
237624 return rc;
237625 }
237626
237627 /*
237628 ** Clear the token mappings for all Fts5IndexIter objects mannaged by
237629 ** the expression passed as the only argument.
237630 */
237631 static void sqlite3Fts5ExprClearTokens(Fts5Expr *pExpr){
237632 int ii;
237633 for(ii=0; ii<pExpr->nPhrase; ii++){
237634 Fts5ExprTerm *pT;
237635 for(pT=&pExpr->apExprPhrase[ii]->aTerm[0]; pT; pT=pT->pSynonym){
237636 sqlite3Fts5IndexIterClearTokendata(pT->pIter);
237637 }
237638 }
237639 }
237640
237641 /*
237642 ** 2014 August 11
237643 **
237644 ** The author disclaims copyright to this source code. In place of
@@ -235826,14 +237674,19 @@
237674 Fts5HashEntry **aSlot; /* Array of hash slots */
237675 };
237676
237677 /*
237678 ** Each entry in the hash table is represented by an object of the
237679 ** following type. Each object, its key, and its current data are stored
237680 ** in a single memory allocation. The key immediately follows the object
237681 ** in memory. The position list data immediately follows the key data
237682 ** in memory.
237683 **
237684 ** The key is Fts5HashEntry.nKey bytes in size. It consists of a single
237685 ** byte identifying the index (either the main term index or a prefix-index),
237686 ** followed by the term data. For example: "0token". There is no
237687 ** nul-terminator - in this case nKey=6.
237688 **
237689 ** The data that follows the key is in a similar, but not identical format
237690 ** to the doclist data stored in the database. It is:
237691 **
237692 ** * Rowid, as a varint
@@ -235964,12 +237817,11 @@
237817 for(i=0; i<pHash->nSlot; i++){
237818 while( apOld[i] ){
237819 unsigned int iHash;
237820 Fts5HashEntry *p = apOld[i];
237821 apOld[i] = p->pHashNext;
237822 iHash = fts5HashKey(nNew, (u8*)fts5EntryKey(p), p->nKey);
 
237823 p->pHashNext = apNew[iHash];
237824 apNew[iHash] = p;
237825 }
237826 }
237827
@@ -236049,11 +237901,11 @@
237901 /* Attempt to locate an existing hash entry */
237902 iHash = fts5HashKey2(pHash->nSlot, (u8)bByte, (const u8*)pToken, nToken);
237903 for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){
237904 char *zKey = fts5EntryKey(p);
237905 if( zKey[0]==bByte
237906 && p->nKey==nToken+1
237907 && memcmp(&zKey[1], pToken, nToken)==0
237908 ){
237909 break;
237910 }
237911 }
@@ -236079,13 +237931,13 @@
237931 p->nAlloc = (int)nByte;
237932 zKey = fts5EntryKey(p);
237933 zKey[0] = bByte;
237934 memcpy(&zKey[1], pToken, nToken);
237935 assert( iHash==fts5HashKey(pHash->nSlot, (u8*)zKey, nToken+1) );
237936 p->nKey = nToken+1;
237937 zKey[nToken+1] = '\0';
237938 p->nData = nToken+1 + sizeof(Fts5HashEntry);
237939 p->pHashNext = pHash->aSlot[iHash];
237940 pHash->aSlot[iHash] = p;
237941 pHash->nEntry++;
237942
237943 /* Add the first rowid field to the hash-entry */
@@ -236198,16 +238050,21 @@
238050 p2 = 0;
238051 }else if( p2==0 ){
238052 *ppOut = p1;
238053 p1 = 0;
238054 }else{
 
238055 char *zKey1 = fts5EntryKey(p1);
238056 char *zKey2 = fts5EntryKey(p2);
238057 int nMin = MIN(p1->nKey, p2->nKey);
238058
238059 int cmp = memcmp(zKey1, zKey2, nMin);
238060 if( cmp==0 ){
238061 cmp = p1->nKey - p2->nKey;
238062 }
238063 assert( cmp!=0 );
238064
238065 if( cmp>0 ){
238066 /* p2 is smaller */
238067 *ppOut = p2;
238068 ppOut = &p2->pScanNext;
238069 p2 = p2->pScanNext;
238070 }else{
@@ -236245,11 +238102,11 @@
238102
238103 for(iSlot=0; iSlot<pHash->nSlot; iSlot++){
238104 Fts5HashEntry *pIter;
238105 for(pIter=pHash->aSlot[iSlot]; pIter; pIter=pIter->pHashNext){
238106 if( pTerm==0
238107 || (pIter->nKey>=nTerm && 0==memcmp(fts5EntryKey(pIter), pTerm, nTerm))
238108 ){
238109 Fts5HashEntry *pEntry = pIter;
238110 pEntry->pScanNext = 0;
238111 for(i=0; ap[i]; i++){
238112 pEntry = fts5HashEntryMerge(pEntry, ap[i]);
@@ -236284,16 +238141,15 @@
238141 char *zKey = 0;
238142 Fts5HashEntry *p;
238143
238144 for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){
238145 zKey = fts5EntryKey(p);
238146 if( nTerm==p->nKey && memcmp(zKey, pTerm, nTerm)==0 ) break;
 
238147 }
238148
238149 if( p ){
238150 int nHashPre = sizeof(Fts5HashEntry) + nTerm;
238151 int nList = p->nData - nHashPre;
238152 u8 *pRet = (u8*)(*ppOut = sqlite3_malloc64(nPre + nList + 10));
238153 if( pRet ){
238154 Fts5HashEntry *pFaux = (Fts5HashEntry*)&pRet[nPre-nHashPre];
238155 memcpy(&pRet[nPre], &((u8*)p)[nHashPre], nList);
@@ -236350,23 +238206,26 @@
238206 }
238207
238208 static void sqlite3Fts5HashScanEntry(
238209 Fts5Hash *pHash,
238210 const char **pzTerm, /* OUT: term (nul-terminated) */
238211 int *pnTerm, /* OUT: Size of term in bytes */
238212 const u8 **ppDoclist, /* OUT: pointer to doclist */
238213 int *pnDoclist /* OUT: size of doclist in bytes */
238214 ){
238215 Fts5HashEntry *p;
238216 if( (p = pHash->pScan) ){
238217 char *zKey = fts5EntryKey(p);
238218 int nTerm = p->nKey;
238219 fts5HashAddPoslistSize(pHash, p, 0);
238220 *pzTerm = zKey;
238221 *pnTerm = nTerm;
238222 *ppDoclist = (const u8*)&zKey[nTerm];
238223 *pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm);
238224 }else{
238225 *pzTerm = 0;
238226 *pnTerm = 0;
238227 *ppDoclist = 0;
238228 *pnDoclist = 0;
238229 }
238230 }
238231
@@ -236693,10 +238552,13 @@
238552 typedef struct Fts5DoclistIter Fts5DoclistIter;
238553 typedef struct Fts5SegWriter Fts5SegWriter;
238554 typedef struct Fts5Structure Fts5Structure;
238555 typedef struct Fts5StructureLevel Fts5StructureLevel;
238556 typedef struct Fts5StructureSegment Fts5StructureSegment;
238557 typedef struct Fts5TokenDataIter Fts5TokenDataIter;
238558 typedef struct Fts5TokenDataMap Fts5TokenDataMap;
238559 typedef struct Fts5TombstoneArray Fts5TombstoneArray;
238560
238561 struct Fts5Data {
238562 u8 *p; /* Pointer to buffer containing record */
238563 int nn; /* Size of record in bytes */
238564 int szLeaf; /* Size of leaf without page-index */
@@ -236727,18 +238589,20 @@
238589 int nContentlessDelete; /* Number of contentless delete ops */
238590 int nPendingRow; /* Number of INSERT in hash table */
238591
238592 /* Error state. */
238593 int rc; /* Current error code */
238594 int flushRc;
238595
238596 /* State used by the fts5DataXXX() functions. */
238597 sqlite3_blob *pReader; /* RO incr-blob open on %_data table */
238598 sqlite3_stmt *pWriter; /* "INSERT ... %_data VALUES(?,?)" */
238599 sqlite3_stmt *pDeleter; /* "DELETE FROM %_data ... id>=? AND id<=?" */
238600 sqlite3_stmt *pIdxWriter; /* "INSERT ... %_idx VALUES(?,?,?,?)" */
238601 sqlite3_stmt *pIdxDeleter; /* "DELETE FROM %_idx WHERE segid=?" */
238602 sqlite3_stmt *pIdxSelect;
238603 sqlite3_stmt *pIdxNextSelect;
238604 int nRead; /* Total number of blocks read */
238605
238606 sqlite3_stmt *pDeleteFromIdx;
238607
238608 sqlite3_stmt *pDataVersion;
@@ -236888,12 +238752,11 @@
238752 int flags; /* Mask of configuration flags */
238753 int iLeafPgno; /* Current leaf page number */
238754 Fts5Data *pLeaf; /* Current leaf data */
238755 Fts5Data *pNextLeaf; /* Leaf page (iLeafPgno+1) */
238756 i64 iLeafOffset; /* Byte offset within current leaf */
238757 Fts5TombstoneArray *pTombArray; /* Array of tombstone pages */
 
238758
238759 /* Next method */
238760 void (*xNext)(Fts5Index*, Fts5SegIter*, int*);
238761
238762 /* The page and offset from which the current term was read. The offset
@@ -236915,10 +238778,19 @@
238778 Fts5Buffer term; /* Current term */
238779 i64 iRowid; /* Current rowid */
238780 int nPos; /* Number of bytes in current position list */
238781 u8 bDel; /* True if the delete flag is set */
238782 };
238783
238784 /*
238785 ** Array of tombstone pages. Reference counted.
238786 */
238787 struct Fts5TombstoneArray {
238788 int nRef; /* Number of pointers to this object */
238789 int nTombstone;
238790 Fts5Data *apTombstone[1]; /* Array of tombstone pages */
238791 };
238792
238793 /*
238794 ** Argument is a pointer to an Fts5Data structure that contains a
238795 ** leaf page.
238796 */
@@ -236960,13 +238832,20 @@
238832 ** the smallest key overall. aFirst[0] is unused.
238833 **
238834 ** poslist:
238835 ** Used by sqlite3Fts5IterPoslist() when the poslist needs to be buffered.
238836 ** There is no way to tell if this is populated or not.
238837 **
238838 ** pColset:
238839 ** If not NULL, points to an object containing a set of column indices.
238840 ** Only matches that occur in one of these columns will be returned.
238841 ** The Fts5Iter does not own the Fts5Colset object, and so it is not
238842 ** freed when the iterator is closed - it is owned by the upper layer.
238843 */
238844 struct Fts5Iter {
238845 Fts5IndexIter base; /* Base class containing output vars */
238846 Fts5TokenDataIter *pTokenDataIter;
238847
238848 Fts5Index *pIndex; /* Index that owns this iterator */
238849 Fts5Buffer poslist; /* Buffer containing current poslist */
238850 Fts5Colset *pColset; /* Restrict matches to these columns */
238851
@@ -236979,11 +238858,10 @@
238858
238859 i64 iSwitchRowid; /* Firstest rowid of other than aFirst[1] */
238860 Fts5CResult *aFirst; /* Current merge state (see above) */
238861 Fts5SegIter aSeg[1]; /* Array of segment iterators */
238862 };
 
238863
238864 /*
238865 ** An instance of the following type is used to iterate through the contents
238866 ** of a doclist-index record.
238867 **
@@ -238279,22 +240157,24 @@
240157 pIter->xNext = fts5SegIterNext;
240158 }
240159 }
240160
240161 /*
240162 ** Allocate a tombstone hash page array object (pIter->pTombArray) for
240163 ** the iterator passed as the second argument. If an OOM error occurs,
240164 ** leave an error in the Fts5Index object.
240165 */
240166 static void fts5SegIterAllocTombstone(Fts5Index *p, Fts5SegIter *pIter){
240167 const int nTomb = pIter->pSeg->nPgTombstone;
240168 if( nTomb>0 ){
240169 int nByte = nTomb * sizeof(Fts5Data*) + sizeof(Fts5TombstoneArray);
240170 Fts5TombstoneArray *pNew;
240171 pNew = (Fts5TombstoneArray*)sqlite3Fts5MallocZero(&p->rc, nByte);
240172 if( pNew ){
240173 pNew->nTombstone = nTomb;
240174 pNew->nRef = 1;
240175 pIter->pTombArray = pNew;
240176 }
240177 }
240178 }
240179
240180 /*
@@ -238547,19 +240427,20 @@
240427 pIter->iLeafOffset = iOff;
240428 fts5SegIterLoadTerm(p, pIter, nKeep);
240429 }else{
240430 const u8 *pList = 0;
240431 const char *zTerm = 0;
240432 int nTerm = 0;
240433 int nList;
240434 sqlite3Fts5HashScanNext(p->pHash);
240435 sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &nTerm, &pList, &nList);
240436 if( pList==0 ) goto next_none_eof;
240437 pIter->pLeaf->p = (u8*)pList;
240438 pIter->pLeaf->nn = nList;
240439 pIter->pLeaf->szLeaf = nList;
240440 pIter->iEndofDoclist = nList;
240441 sqlite3Fts5BufferSet(&p->rc,&pIter->term, nTerm, (u8*)zTerm);
240442 pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid);
240443 }
240444
240445 if( pbNewTerm ) *pbNewTerm = 1;
240446 }else{
@@ -238621,26 +240502,26 @@
240502 pIter->iLeafOffset = iOff;
240503
240504 }else if( pIter->pSeg==0 ){
240505 const u8 *pList = 0;
240506 const char *zTerm = 0;
240507 int nTerm = 0;
240508 int nList = 0;
240509 assert( (pIter->flags & FTS5_SEGITER_ONETERM) || pbNewTerm );
240510 if( 0==(pIter->flags & FTS5_SEGITER_ONETERM) ){
240511 sqlite3Fts5HashScanNext(p->pHash);
240512 sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &nTerm, &pList, &nList);
240513 }
240514 if( pList==0 ){
240515 fts5DataRelease(pIter->pLeaf);
240516 pIter->pLeaf = 0;
240517 }else{
240518 pIter->pLeaf->p = (u8*)pList;
240519 pIter->pLeaf->nn = nList;
240520 pIter->pLeaf->szLeaf = nList;
240521 pIter->iEndofDoclist = nList+1;
240522 sqlite3Fts5BufferSet(&p->rc, &pIter->term, nTerm, (u8*)zTerm);
 
240523 pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid);
240524 *pbNewTerm = 1;
240525 }
240526 }else{
240527 iOff = 0;
@@ -239022,11 +240903,11 @@
240903
240904 if( pIter->pLeaf ){
240905 fts5LeafSeek(p, bGe, pIter, pTerm, nTerm);
240906 }
240907
240908 if( p->rc==SQLITE_OK && (bGe==0 || (flags & FTS5INDEX_QUERY_SCANONETERM)) ){
240909 pIter->flags |= FTS5_SEGITER_ONETERM;
240910 if( pIter->pLeaf ){
240911 if( flags & FTS5INDEX_QUERY_DESC ){
240912 pIter->flags |= FTS5_SEGITER_REVERSE;
240913 }
@@ -239038,11 +240919,13 @@
240919 }
240920 }
240921 }
240922
240923 fts5SegIterSetNext(p, pIter);
240924 if( 0==(flags & FTS5INDEX_QUERY_SCANONETERM) ){
240925 fts5SegIterAllocTombstone(p, pIter);
240926 }
240927
240928 /* Either:
240929 **
240930 ** 1) an error has occurred, or
240931 ** 2) the iterator points to EOF, or
@@ -239055,10 +240938,83 @@
240938 || fts5BufferCompareBlob(&pIter->term, pTerm, nTerm)==0 /* 3 */
240939 || (bGe && fts5BufferCompareBlob(&pIter->term, pTerm, nTerm)>0) /* 4 */
240940 );
240941 }
240942
240943
240944 /*
240945 ** SQL used by fts5SegIterNextInit() to find the page to open.
240946 */
240947 static sqlite3_stmt *fts5IdxNextStmt(Fts5Index *p){
240948 if( p->pIdxNextSelect==0 ){
240949 Fts5Config *pConfig = p->pConfig;
240950 fts5IndexPrepareStmt(p, &p->pIdxNextSelect, sqlite3_mprintf(
240951 "SELECT pgno FROM '%q'.'%q_idx' WHERE "
240952 "segid=? AND term>? ORDER BY term ASC LIMIT 1",
240953 pConfig->zDb, pConfig->zName
240954 ));
240955
240956 }
240957 return p->pIdxNextSelect;
240958 }
240959
240960 /*
240961 ** This is similar to fts5SegIterSeekInit(), except that it initializes
240962 ** the segment iterator to point to the first term following the page
240963 ** with pToken/nToken on it.
240964 */
240965 static void fts5SegIterNextInit(
240966 Fts5Index *p,
240967 const char *pTerm, int nTerm,
240968 Fts5StructureSegment *pSeg, /* Description of segment */
240969 Fts5SegIter *pIter /* Object to populate */
240970 ){
240971 int iPg = -1; /* Page of segment to open */
240972 int bDlidx = 0;
240973 sqlite3_stmt *pSel = 0; /* SELECT to find iPg */
240974
240975 pSel = fts5IdxNextStmt(p);
240976 if( pSel ){
240977 assert( p->rc==SQLITE_OK );
240978 sqlite3_bind_int(pSel, 1, pSeg->iSegid);
240979 sqlite3_bind_blob(pSel, 2, pTerm, nTerm, SQLITE_STATIC);
240980
240981 if( sqlite3_step(pSel)==SQLITE_ROW ){
240982 i64 val = sqlite3_column_int64(pSel, 0);
240983 iPg = (int)(val>>1);
240984 bDlidx = (val & 0x0001);
240985 }
240986 p->rc = sqlite3_reset(pSel);
240987 sqlite3_bind_null(pSel, 2);
240988 if( p->rc ) return;
240989 }
240990
240991 memset(pIter, 0, sizeof(*pIter));
240992 pIter->pSeg = pSeg;
240993 pIter->flags |= FTS5_SEGITER_ONETERM;
240994 if( iPg>=0 ){
240995 pIter->iLeafPgno = iPg - 1;
240996 fts5SegIterNextPage(p, pIter);
240997 fts5SegIterSetNext(p, pIter);
240998 }
240999 if( pIter->pLeaf ){
241000 const u8 *a = pIter->pLeaf->p;
241001 int iTermOff = 0;
241002
241003 pIter->iPgidxOff = pIter->pLeaf->szLeaf;
241004 pIter->iPgidxOff += fts5GetVarint32(&a[pIter->iPgidxOff], iTermOff);
241005 pIter->iLeafOffset = iTermOff;
241006 fts5SegIterLoadTerm(p, pIter, 0);
241007 fts5SegIterLoadNPos(p, pIter);
241008 if( bDlidx ) fts5SegIterLoadDlidx(p, pIter);
241009
241010 assert( p->rc!=SQLITE_OK ||
241011 fts5BufferCompareBlob(&pIter->term, (const u8*)pTerm, nTerm)>0
241012 );
241013 }
241014 }
241015
241016 /*
241017 ** Initialize the object pIter to point to term pTerm/nTerm within the
241018 ** in-memory hash table. If there is no such term in the hash-table, the
241019 ** iterator is set to EOF.
241020 **
@@ -239081,12 +241037,11 @@
241037
241038 if( pTerm==0 || (flags & FTS5INDEX_QUERY_SCAN) ){
241039 const u8 *pList = 0;
241040
241041 p->rc = sqlite3Fts5HashScanInit(p->pHash, (const char*)pTerm, nTerm);
241042 sqlite3Fts5HashScanEntry(p->pHash, (const char**)&z, &n, &pList, &nList);
 
241043 if( pList ){
241044 pLeaf = fts5IdxMalloc(p, sizeof(Fts5Data));
241045 if( pLeaf ){
241046 pLeaf->p = (u8*)pList;
241047 }
@@ -239140,19 +241095,36 @@
241095 fts5DataRelease(ap[ii]);
241096 }
241097 sqlite3_free(ap);
241098 }
241099 }
241100
241101 /*
241102 ** Decrement the ref-count of the object passed as the only argument. If it
241103 ** reaches 0, free it and its contents.
241104 */
241105 static void fts5TombstoneArrayDelete(Fts5TombstoneArray *p){
241106 if( p ){
241107 p->nRef--;
241108 if( p->nRef<=0 ){
241109 int ii;
241110 for(ii=0; ii<p->nTombstone; ii++){
241111 fts5DataRelease(p->apTombstone[ii]);
241112 }
241113 sqlite3_free(p);
241114 }
241115 }
241116 }
241117
241118 /*
241119 ** Zero the iterator passed as the only argument.
241120 */
241121 static void fts5SegIterClear(Fts5SegIter *pIter){
241122 fts5BufferFree(&pIter->term);
241123 fts5DataRelease(pIter->pLeaf);
241124 fts5DataRelease(pIter->pNextLeaf);
241125 fts5TombstoneArrayDelete(pIter->pTombArray);
241126 fts5DlidxIterFree(pIter->pDlidx);
241127 sqlite3_free(pIter->aRowidOffset);
241128 memset(pIter, 0, sizeof(Fts5SegIter));
241129 }
241130
@@ -239393,11 +241365,10 @@
241365 if( bRev!=0 && pIter->iRowid<=iMatch ) break;
241366 bMove = 1;
241367 }while( p->rc==SQLITE_OK );
241368 }
241369
 
241370 /*
241371 ** Free the iterator object passed as the second argument.
241372 */
241373 static void fts5MultiIterFree(Fts5Iter *pIter){
241374 if( pIter ){
@@ -239538,28 +241509,29 @@
241509 ** if there is no tombstone or if the iterator is already at EOF.
241510 */
241511 static int fts5MultiIterIsDeleted(Fts5Iter *pIter){
241512 int iFirst = pIter->aFirst[1].iFirst;
241513 Fts5SegIter *pSeg = &pIter->aSeg[iFirst];
241514 Fts5TombstoneArray *pArray = pSeg->pTombArray;
241515
241516 if( pSeg->pLeaf && pArray ){
241517 /* Figure out which page the rowid might be present on. */
241518 int iPg = ((u64)pSeg->iRowid) % pArray->nTombstone;
241519 assert( iPg>=0 );
241520
241521 /* If tombstone hash page iPg has not yet been loaded from the
241522 ** database, load it now. */
241523 if( pArray->apTombstone[iPg]==0 ){
241524 pArray->apTombstone[iPg] = fts5DataRead(pIter->pIndex,
241525 FTS5_TOMBSTONE_ROWID(pSeg->pSeg->iSegid, iPg)
241526 );
241527 if( pArray->apTombstone[iPg]==0 ) return 0;
241528 }
241529
241530 return fts5IndexTombstoneQuery(
241531 pArray->apTombstone[iPg],
241532 pArray->nTombstone,
241533 pSeg->iRowid
241534 );
241535 }
241536
241537 return 0;
@@ -240094,10 +242066,36 @@
242066 }
242067 }
242068 }
242069 }
242070
242071 /*
242072 ** All the component segment-iterators of pIter have been set up. This
242073 ** functions finishes setup for iterator pIter itself.
242074 */
242075 static void fts5MultiIterFinishSetup(Fts5Index *p, Fts5Iter *pIter){
242076 int iIter;
242077 for(iIter=pIter->nSeg-1; iIter>0; iIter--){
242078 int iEq;
242079 if( (iEq = fts5MultiIterDoCompare(pIter, iIter)) ){
242080 Fts5SegIter *pSeg = &pIter->aSeg[iEq];
242081 if( p->rc==SQLITE_OK ) pSeg->xNext(p, pSeg, 0);
242082 fts5MultiIterAdvanced(p, pIter, iEq, iIter);
242083 }
242084 }
242085 fts5MultiIterSetEof(pIter);
242086 fts5AssertMultiIterSetup(p, pIter);
242087
242088 if( (pIter->bSkipEmpty && fts5MultiIterIsEmpty(p, pIter))
242089 || fts5MultiIterIsDeleted(pIter)
242090 ){
242091 fts5MultiIterNext(p, pIter, 0, 0);
242092 }else if( pIter->base.bEof==0 ){
242093 Fts5SegIter *pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst];
242094 pIter->xSetOutputs(pIter, pSeg);
242095 }
242096 }
242097
242098 /*
242099 ** Allocate a new Fts5Iter object.
242100 **
242101 ** The new object will be used to iterate through data in structure pStruct.
@@ -240175,35 +242173,16 @@
242173 }
242174 }
242175 assert( iIter==nSeg );
242176 }
242177
242178 /* If the above was successful, each component iterator now points
242179 ** to the first entry in its segment. In this case initialize the
242180 ** aFirst[] array. Or, if an error has occurred, free the iterator
242181 ** object and set the output variable to NULL. */
242182 if( p->rc==SQLITE_OK ){
242183 fts5MultiIterFinishSetup(p, pNew);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
242184 }else{
242185 fts5MultiIterFree(pNew);
242186 *ppOut = 0;
242187 }
242188
@@ -240224,11 +242203,10 @@
242203 ){
242204 Fts5Iter *pNew;
242205 pNew = fts5MultiIterAlloc(p, 2);
242206 if( pNew ){
242207 Fts5SegIter *pIter = &pNew->aSeg[1];
 
242208 pIter->flags = FTS5_SEGITER_ONETERM;
242209 if( pData->szLeaf>0 ){
242210 pIter->pLeaf = pData;
242211 pIter->iLeafOffset = fts5GetVarint(pData->p, (u64*)&pIter->iRowid);
242212 pIter->iEndofDoclist = pData->nn;
@@ -240372,10 +242350,11 @@
242350 assert( p->pHash || p->nPendingData==0 );
242351 if( p->pHash ){
242352 sqlite3Fts5HashClear(p->pHash);
242353 p->nPendingData = 0;
242354 p->nPendingRow = 0;
242355 p->flushRc = SQLITE_OK;
242356 }
242357 p->nContentlessDelete = 0;
242358 }
242359
242360 /*
@@ -240587,11 +242566,11 @@
242566 }else{
242567 bDone = 1;
242568 }
242569
242570 if( pDlidx->bPrevValid ){
242571 iVal = (u64)iRowid - (u64)pDlidx->iPrev;
242572 }else{
242573 i64 iPgno = (i==0 ? pWriter->writer.pgno : pDlidx[-1].pgno);
242574 assert( pDlidx->buf.n==0 );
242575 sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, !bDone);
242576 sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, iPgno);
@@ -241710,14 +243689,14 @@
243689 */
243690 static void fts5FlushSecureDelete(
243691 Fts5Index *p,
243692 Fts5Structure *pStruct,
243693 const char *zTerm,
243694 int nTerm,
243695 i64 iRowid
243696 ){
243697 const int f = FTS5INDEX_QUERY_SKIPHASH;
 
243698 Fts5Iter *pIter = 0; /* Used to find term instance */
243699
243700 fts5MultiIterNew(p, pStruct, f, 0, (const u8*)zTerm, nTerm, -1, 0, &pIter);
243701 if( fts5MultiIterEof(p, pIter)==0 ){
243702 i64 iThis = fts5MultiIterRowid(pIter);
@@ -241787,12 +243766,11 @@
243766 int nTerm; /* Size of zTerm in bytes */
243767 const u8 *pDoclist; /* Pointer to doclist for this term */
243768 int nDoclist; /* Size of doclist in bytes */
243769
243770 /* Get the term and doclist for this entry. */
243771 sqlite3Fts5HashScanEntry(pHash, &zTerm, &nTerm, &pDoclist, &nDoclist);
 
243772 if( bSecureDelete==0 ){
243773 fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm);
243774 if( p->rc!=SQLITE_OK ) break;
243775 assert( writer.bFirstRowidInPage==0 );
243776 }
@@ -241818,21 +243796,21 @@
243796 ** in fact a delete, then edit the existing segments directly
243797 ** using fts5FlushSecureDelete(). */
243798 if( bSecureDelete ){
243799 if( eDetail==FTS5_DETAIL_NONE ){
243800 if( iOff<nDoclist && pDoclist[iOff]==0x00 ){
243801 fts5FlushSecureDelete(p, pStruct, zTerm, nTerm, iRowid);
243802 iOff++;
243803 if( iOff<nDoclist && pDoclist[iOff]==0x00 ){
243804 iOff++;
243805 nDoclist = 0;
243806 }else{
243807 continue;
243808 }
243809 }
243810 }else if( (pDoclist[iOff] & 0x01) ){
243811 fts5FlushSecureDelete(p, pStruct, zTerm, nTerm, iRowid);
243812 if( p->rc!=SQLITE_OK || pDoclist[iOff]==0x01 ){
243813 iOff++;
243814 continue;
243815 }
243816 }
@@ -241954,18 +243932,24 @@
243932 /*
243933 ** Flush any data stored in the in-memory hash tables to the database.
243934 */
243935 static void fts5IndexFlush(Fts5Index *p){
243936 /* Unless it is empty, flush the hash table to disk */
243937 if( p->flushRc ){
243938 p->rc = p->flushRc;
243939 return;
243940 }
243941 if( p->nPendingData || p->nContentlessDelete ){
243942 assert( p->pHash );
243943 fts5FlushOneHash(p);
243944 if( p->rc==SQLITE_OK ){
243945 sqlite3Fts5HashClear(p->pHash);
243946 p->nPendingData = 0;
243947 p->nPendingRow = 0;
243948 p->nContentlessDelete = 0;
243949 }else if( p->nPendingData || p->nContentlessDelete ){
243950 p->flushRc = p->rc;
243951 }
243952 }
243953 }
243954
243955 static Fts5Structure *fts5IndexOptimizeStruct(
@@ -242448,11 +244432,11 @@
244432 int bDesc, /* True for "ORDER BY rowid DESC" */
244433 int iIdx, /* Index to scan for data */
244434 u8 *pToken, /* Buffer containing prefix to match */
244435 int nToken, /* Size of buffer pToken in bytes */
244436 Fts5Colset *pColset, /* Restrict matches to these columns */
244437 Fts5Iter **ppIter /* OUT: New iterator */
244438 ){
244439 Fts5Structure *pStruct;
244440 Fts5Buffer *aBuf;
244441 int nBuf = 32;
244442 int nMerge = 1;
@@ -242469,12 +244453,13 @@
244453 xAppend = fts5AppendPoslist;
244454 }
244455
244456 aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*nBuf);
244457 pStruct = fts5StructureRead(p);
244458 assert( p->rc!=SQLITE_OK || (aBuf && pStruct) );
244459
244460 if( p->rc==SQLITE_OK ){
244461 const int flags = FTS5INDEX_QUERY_SCAN
244462 | FTS5INDEX_QUERY_SKIPEMPTY
244463 | FTS5INDEX_QUERY_NOOUTPUT;
244464 int i;
244465 i64 iLastRowid = 0;
@@ -242482,10 +244467,16 @@
244467 Fts5Data *pData;
244468 Fts5Buffer doclist;
244469 int bNewTerm = 1;
244470
244471 memset(&doclist, 0, sizeof(doclist));
244472
244473 /* If iIdx is non-zero, then it is the number of a prefix-index for
244474 ** prefixes 1 character longer than the prefix being queried for. That
244475 ** index contains all the doclists required, except for the one
244476 ** corresponding to the prefix itself. That one is extracted from the
244477 ** main term index here. */
244478 if( iIdx!=0 ){
244479 int dummy = 0;
244480 const int f2 = FTS5INDEX_QUERY_SKIPEMPTY|FTS5INDEX_QUERY_NOOUTPUT;
244481 pToken[0] = FTS5_MAIN_PREFIX;
244482 fts5MultiIterNew(p, pStruct, f2, pColset, pToken, nToken, -1, 0, &p1);
@@ -242505,10 +244496,11 @@
244496 }
244497
244498 pToken[0] = FTS5_MAIN_PREFIX + iIdx;
244499 fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1);
244500 fts5IterSetOutputCb(&p->rc, p1);
244501
244502 for( /* no-op */ ;
244503 fts5MultiIterEof(p, p1)==0;
244504 fts5MultiIterNext2(p, p1, &bNewTerm)
244505 ){
244506 Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ];
@@ -242520,11 +244512,10 @@
244512 if( bNewTerm ){
244513 if( nTerm<nToken || memcmp(pToken, pTerm, nToken) ) break;
244514 }
244515
244516 if( p1->base.nData==0 ) continue;
 
244517 if( p1->base.iRowid<=iLastRowid && doclist.n>0 ){
244518 for(i=0; p->rc==SQLITE_OK && doclist.n; i++){
244519 int i1 = i*nMerge;
244520 int iStore;
244521 assert( i1+nMerge<=nBuf );
@@ -242559,11 +244550,11 @@
244550 fts5BufferFree(&aBuf[iFree]);
244551 }
244552 }
244553 fts5MultiIterFree(p1);
244554
244555 pData = fts5IdxMalloc(p, sizeof(*pData)+doclist.n+FTS5_DATA_ZERO_PADDING);
244556 if( pData ){
244557 pData->p = (u8*)&pData[1];
244558 pData->nn = pData->szLeaf = doclist.n;
244559 if( doclist.n ) memcpy(pData->p, doclist.p, doclist.n);
244560 fts5MultiIterNew2(p, pData, bDesc, ppIter);
@@ -242702,10 +244693,11 @@
244693 sqlite3_finalize(p->pWriter);
244694 sqlite3_finalize(p->pDeleter);
244695 sqlite3_finalize(p->pIdxWriter);
244696 sqlite3_finalize(p->pIdxDeleter);
244697 sqlite3_finalize(p->pIdxSelect);
244698 sqlite3_finalize(p->pIdxNextSelect);
244699 sqlite3_finalize(p->pDataVersion);
244700 sqlite3_finalize(p->pDeleteFromIdx);
244701 sqlite3Fts5HashFree(p->pHash);
244702 sqlite3_free(p->zDataTbl);
244703 sqlite3_free(p);
@@ -242796,10 +244788,458 @@
244788 }
244789 }
244790
244791 return rc;
244792 }
244793
244794 /*
244795 ** pToken points to a buffer of size nToken bytes containing a search
244796 ** term, including the index number at the start, used on a tokendata=1
244797 ** table. This function returns true if the term in buffer pBuf matches
244798 ** token pToken/nToken.
244799 */
244800 static int fts5IsTokendataPrefix(
244801 Fts5Buffer *pBuf,
244802 const u8 *pToken,
244803 int nToken
244804 ){
244805 return (
244806 pBuf->n>=nToken
244807 && 0==memcmp(pBuf->p, pToken, nToken)
244808 && (pBuf->n==nToken || pBuf->p[nToken]==0x00)
244809 );
244810 }
244811
244812 /*
244813 ** Ensure the segment-iterator passed as the only argument points to EOF.
244814 */
244815 static void fts5SegIterSetEOF(Fts5SegIter *pSeg){
244816 fts5DataRelease(pSeg->pLeaf);
244817 pSeg->pLeaf = 0;
244818 }
244819
244820 /*
244821 ** Usually, a tokendata=1 iterator (struct Fts5TokenDataIter) accumulates an
244822 ** array of these for each row it visits. Or, for an iterator used by an
244823 ** "ORDER BY rank" query, it accumulates an array of these for the entire
244824 ** query.
244825 **
244826 ** Each instance in the array indicates the iterator (and therefore term)
244827 ** associated with position iPos of rowid iRowid. This is used by the
244828 ** xInstToken() API.
244829 */
244830 struct Fts5TokenDataMap {
244831 i64 iRowid; /* Row this token is located in */
244832 i64 iPos; /* Position of token */
244833 int iIter; /* Iterator token was read from */
244834 };
244835
244836 /*
244837 ** An object used to supplement Fts5Iter for tokendata=1 iterators.
244838 */
244839 struct Fts5TokenDataIter {
244840 int nIter;
244841 int nIterAlloc;
244842
244843 int nMap;
244844 int nMapAlloc;
244845 Fts5TokenDataMap *aMap;
244846
244847 Fts5PoslistReader *aPoslistReader;
244848 int *aPoslistToIter;
244849 Fts5Iter *apIter[1];
244850 };
244851
244852 /*
244853 ** This function appends iterator pAppend to Fts5TokenDataIter pIn and
244854 ** returns the result.
244855 */
244856 static Fts5TokenDataIter *fts5AppendTokendataIter(
244857 Fts5Index *p, /* Index object (for error code) */
244858 Fts5TokenDataIter *pIn, /* Current Fts5TokenDataIter struct */
244859 Fts5Iter *pAppend /* Append this iterator */
244860 ){
244861 Fts5TokenDataIter *pRet = pIn;
244862
244863 if( p->rc==SQLITE_OK ){
244864 if( pIn==0 || pIn->nIter==pIn->nIterAlloc ){
244865 int nAlloc = pIn ? pIn->nIterAlloc*2 : 16;
244866 int nByte = nAlloc * sizeof(Fts5Iter*) + sizeof(Fts5TokenDataIter);
244867 Fts5TokenDataIter *pNew = (Fts5TokenDataIter*)sqlite3_realloc(pIn, nByte);
244868
244869 if( pNew==0 ){
244870 p->rc = SQLITE_NOMEM;
244871 }else{
244872 if( pIn==0 ) memset(pNew, 0, nByte);
244873 pRet = pNew;
244874 pNew->nIterAlloc = nAlloc;
244875 }
244876 }
244877 }
244878 if( p->rc ){
244879 sqlite3Fts5IterClose((Fts5IndexIter*)pAppend);
244880 }else{
244881 pRet->apIter[pRet->nIter++] = pAppend;
244882 }
244883 assert( pRet==0 || pRet->nIter<=pRet->nIterAlloc );
244884
244885 return pRet;
244886 }
244887
244888 /*
244889 ** Delete an Fts5TokenDataIter structure and its contents.
244890 */
244891 static void fts5TokendataIterDelete(Fts5TokenDataIter *pSet){
244892 if( pSet ){
244893 int ii;
244894 for(ii=0; ii<pSet->nIter; ii++){
244895 fts5MultiIterFree(pSet->apIter[ii]);
244896 }
244897 sqlite3_free(pSet->aPoslistReader);
244898 sqlite3_free(pSet->aMap);
244899 sqlite3_free(pSet);
244900 }
244901 }
244902
244903 /*
244904 ** Append a mapping to the token-map belonging to object pT.
244905 */
244906 static void fts5TokendataIterAppendMap(
244907 Fts5Index *p,
244908 Fts5TokenDataIter *pT,
244909 int iIter,
244910 i64 iRowid,
244911 i64 iPos
244912 ){
244913 if( p->rc==SQLITE_OK ){
244914 if( pT->nMap==pT->nMapAlloc ){
244915 int nNew = pT->nMapAlloc ? pT->nMapAlloc*2 : 64;
244916 int nByte = nNew * sizeof(Fts5TokenDataMap);
244917 Fts5TokenDataMap *aNew;
244918
244919 aNew = (Fts5TokenDataMap*)sqlite3_realloc(pT->aMap, nByte);
244920 if( aNew==0 ){
244921 p->rc = SQLITE_NOMEM;
244922 return;
244923 }
244924
244925 pT->aMap = aNew;
244926 pT->nMapAlloc = nNew;
244927 }
244928
244929 pT->aMap[pT->nMap].iRowid = iRowid;
244930 pT->aMap[pT->nMap].iPos = iPos;
244931 pT->aMap[pT->nMap].iIter = iIter;
244932 pT->nMap++;
244933 }
244934 }
244935
244936 /*
244937 ** The iterator passed as the only argument must be a tokendata=1 iterator
244938 ** (pIter->pTokenDataIter!=0). This function sets the iterator output
244939 ** variables (pIter->base.*) according to the contents of the current
244940 ** row.
244941 */
244942 static void fts5IterSetOutputsTokendata(Fts5Iter *pIter){
244943 int ii;
244944 int nHit = 0;
244945 i64 iRowid = SMALLEST_INT64;
244946 int iMin = 0;
244947
244948 Fts5TokenDataIter *pT = pIter->pTokenDataIter;
244949
244950 pIter->base.nData = 0;
244951 pIter->base.pData = 0;
244952
244953 for(ii=0; ii<pT->nIter; ii++){
244954 Fts5Iter *p = pT->apIter[ii];
244955 if( p->base.bEof==0 ){
244956 if( nHit==0 || p->base.iRowid<iRowid ){
244957 iRowid = p->base.iRowid;
244958 nHit = 1;
244959 pIter->base.pData = p->base.pData;
244960 pIter->base.nData = p->base.nData;
244961 iMin = ii;
244962 }else if( p->base.iRowid==iRowid ){
244963 nHit++;
244964 }
244965 }
244966 }
244967
244968 if( nHit==0 ){
244969 pIter->base.bEof = 1;
244970 }else{
244971 int eDetail = pIter->pIndex->pConfig->eDetail;
244972 pIter->base.bEof = 0;
244973 pIter->base.iRowid = iRowid;
244974
244975 if( nHit==1 && eDetail==FTS5_DETAIL_FULL ){
244976 fts5TokendataIterAppendMap(pIter->pIndex, pT, iMin, iRowid, -1);
244977 }else
244978 if( nHit>1 && eDetail!=FTS5_DETAIL_NONE ){
244979 int nReader = 0;
244980 int nByte = 0;
244981 i64 iPrev = 0;
244982
244983 /* Allocate array of iterators if they are not already allocated. */
244984 if( pT->aPoslistReader==0 ){
244985 pT->aPoslistReader = (Fts5PoslistReader*)sqlite3Fts5MallocZero(
244986 &pIter->pIndex->rc,
244987 pT->nIter * (sizeof(Fts5PoslistReader) + sizeof(int))
244988 );
244989 if( pT->aPoslistReader==0 ) return;
244990 pT->aPoslistToIter = (int*)&pT->aPoslistReader[pT->nIter];
244991 }
244992
244993 /* Populate an iterator for each poslist that will be merged */
244994 for(ii=0; ii<pT->nIter; ii++){
244995 Fts5Iter *p = pT->apIter[ii];
244996 if( iRowid==p->base.iRowid ){
244997 pT->aPoslistToIter[nReader] = ii;
244998 sqlite3Fts5PoslistReaderInit(
244999 p->base.pData, p->base.nData, &pT->aPoslistReader[nReader++]
245000 );
245001 nByte += p->base.nData;
245002 }
245003 }
245004
245005 /* Ensure the output buffer is large enough */
245006 if( fts5BufferGrow(&pIter->pIndex->rc, &pIter->poslist, nByte+nHit*10) ){
245007 return;
245008 }
245009
245010 /* Ensure the token-mapping is large enough */
245011 if( eDetail==FTS5_DETAIL_FULL && pT->nMapAlloc<(pT->nMap + nByte) ){
245012 int nNew = (pT->nMapAlloc + nByte) * 2;
245013 Fts5TokenDataMap *aNew = (Fts5TokenDataMap*)sqlite3_realloc(
245014 pT->aMap, nNew*sizeof(Fts5TokenDataMap)
245015 );
245016 if( aNew==0 ){
245017 pIter->pIndex->rc = SQLITE_NOMEM;
245018 return;
245019 }
245020 pT->aMap = aNew;
245021 pT->nMapAlloc = nNew;
245022 }
245023
245024 pIter->poslist.n = 0;
245025
245026 while( 1 ){
245027 i64 iMinPos = LARGEST_INT64;
245028
245029 /* Find smallest position */
245030 iMin = 0;
245031 for(ii=0; ii<nReader; ii++){
245032 Fts5PoslistReader *pReader = &pT->aPoslistReader[ii];
245033 if( pReader->bEof==0 ){
245034 if( pReader->iPos<iMinPos ){
245035 iMinPos = pReader->iPos;
245036 iMin = ii;
245037 }
245038 }
245039 }
245040
245041 /* If all readers were at EOF, break out of the loop. */
245042 if( iMinPos==LARGEST_INT64 ) break;
245043
245044 sqlite3Fts5PoslistSafeAppend(&pIter->poslist, &iPrev, iMinPos);
245045 sqlite3Fts5PoslistReaderNext(&pT->aPoslistReader[iMin]);
245046
245047 if( eDetail==FTS5_DETAIL_FULL ){
245048 pT->aMap[pT->nMap].iPos = iMinPos;
245049 pT->aMap[pT->nMap].iIter = pT->aPoslistToIter[iMin];
245050 pT->aMap[pT->nMap].iRowid = iRowid;
245051 pT->nMap++;
245052 }
245053 }
245054
245055 pIter->base.pData = pIter->poslist.p;
245056 pIter->base.nData = pIter->poslist.n;
245057 }
245058 }
245059 }
245060
245061 /*
245062 ** The iterator passed as the only argument must be a tokendata=1 iterator
245063 ** (pIter->pTokenDataIter!=0). This function advances the iterator. If
245064 ** argument bFrom is false, then the iterator is advanced to the next
245065 ** entry. Or, if bFrom is true, it is advanced to the first entry with
245066 ** a rowid of iFrom or greater.
245067 */
245068 static void fts5TokendataIterNext(Fts5Iter *pIter, int bFrom, i64 iFrom){
245069 int ii;
245070 Fts5TokenDataIter *pT = pIter->pTokenDataIter;
245071
245072 for(ii=0; ii<pT->nIter; ii++){
245073 Fts5Iter *p = pT->apIter[ii];
245074 if( p->base.bEof==0
245075 && (p->base.iRowid==pIter->base.iRowid || (bFrom && p->base.iRowid<iFrom))
245076 ){
245077 fts5MultiIterNext(p->pIndex, p, bFrom, iFrom);
245078 while( bFrom && p->base.bEof==0
245079 && p->base.iRowid<iFrom
245080 && p->pIndex->rc==SQLITE_OK
245081 ){
245082 fts5MultiIterNext(p->pIndex, p, 0, 0);
245083 }
245084 }
245085 }
245086
245087 fts5IterSetOutputsTokendata(pIter);
245088 }
245089
245090 /*
245091 ** If the segment-iterator passed as the first argument is at EOF, then
245092 ** set pIter->term to a copy of buffer pTerm.
245093 */
245094 static void fts5TokendataSetTermIfEof(Fts5Iter *pIter, Fts5Buffer *pTerm){
245095 if( pIter && pIter->aSeg[0].pLeaf==0 ){
245096 fts5BufferSet(&pIter->pIndex->rc, &pIter->aSeg[0].term, pTerm->n, pTerm->p);
245097 }
245098 }
245099
245100 /*
245101 ** This function sets up an iterator to use for a non-prefix query on a
245102 ** tokendata=1 table.
245103 */
245104 static Fts5Iter *fts5SetupTokendataIter(
245105 Fts5Index *p, /* FTS index to query */
245106 const u8 *pToken, /* Buffer containing query term */
245107 int nToken, /* Size of buffer pToken in bytes */
245108 Fts5Colset *pColset /* Colset to filter on */
245109 ){
245110 Fts5Iter *pRet = 0;
245111 Fts5TokenDataIter *pSet = 0;
245112 Fts5Structure *pStruct = 0;
245113 const int flags = FTS5INDEX_QUERY_SCANONETERM | FTS5INDEX_QUERY_SCAN;
245114
245115 Fts5Buffer bSeek = {0, 0, 0};
245116 Fts5Buffer *pSmall = 0;
245117
245118 fts5IndexFlush(p);
245119 pStruct = fts5StructureRead(p);
245120
245121 while( p->rc==SQLITE_OK ){
245122 Fts5Iter *pPrev = pSet ? pSet->apIter[pSet->nIter-1] : 0;
245123 Fts5Iter *pNew = 0;
245124 Fts5SegIter *pNewIter = 0;
245125 Fts5SegIter *pPrevIter = 0;
245126
245127 int iLvl, iSeg, ii;
245128
245129 pNew = fts5MultiIterAlloc(p, pStruct->nSegment);
245130 if( pSmall ){
245131 fts5BufferSet(&p->rc, &bSeek, pSmall->n, pSmall->p);
245132 fts5BufferAppendBlob(&p->rc, &bSeek, 1, (const u8*)"\0");
245133 }else{
245134 fts5BufferSet(&p->rc, &bSeek, nToken, pToken);
245135 }
245136 if( p->rc ){
245137 sqlite3Fts5IterClose((Fts5IndexIter*)pNew);
245138 break;
245139 }
245140
245141 pNewIter = &pNew->aSeg[0];
245142 pPrevIter = (pPrev ? &pPrev->aSeg[0] : 0);
245143 for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
245144 for(iSeg=pStruct->aLevel[iLvl].nSeg-1; iSeg>=0; iSeg--){
245145 Fts5StructureSegment *pSeg = &pStruct->aLevel[iLvl].aSeg[iSeg];
245146 int bDone = 0;
245147
245148 if( pPrevIter ){
245149 if( fts5BufferCompare(pSmall, &pPrevIter->term) ){
245150 memcpy(pNewIter, pPrevIter, sizeof(Fts5SegIter));
245151 memset(pPrevIter, 0, sizeof(Fts5SegIter));
245152 bDone = 1;
245153 }else if( pPrevIter->iEndofDoclist>pPrevIter->pLeaf->szLeaf ){
245154 fts5SegIterNextInit(p,(const char*)bSeek.p,bSeek.n-1,pSeg,pNewIter);
245155 bDone = 1;
245156 }
245157 }
245158
245159 if( bDone==0 ){
245160 fts5SegIterSeekInit(p, bSeek.p, bSeek.n, flags, pSeg, pNewIter);
245161 }
245162
245163 if( pPrevIter ){
245164 if( pPrevIter->pTombArray ){
245165 pNewIter->pTombArray = pPrevIter->pTombArray;
245166 pNewIter->pTombArray->nRef++;
245167 }
245168 }else{
245169 fts5SegIterAllocTombstone(p, pNewIter);
245170 }
245171
245172 pNewIter++;
245173 if( pPrevIter ) pPrevIter++;
245174 if( p->rc ) break;
245175 }
245176 }
245177 fts5TokendataSetTermIfEof(pPrev, pSmall);
245178
245179 pNew->bSkipEmpty = 1;
245180 pNew->pColset = pColset;
245181 fts5IterSetOutputCb(&p->rc, pNew);
245182
245183 /* Loop through all segments in the new iterator. Find the smallest
245184 ** term that any segment-iterator points to. Iterator pNew will be
245185 ** used for this term. Also, set any iterator that points to a term that
245186 ** does not match pToken/nToken to point to EOF */
245187 pSmall = 0;
245188 for(ii=0; ii<pNew->nSeg; ii++){
245189 Fts5SegIter *pII = &pNew->aSeg[ii];
245190 if( 0==fts5IsTokendataPrefix(&pII->term, pToken, nToken) ){
245191 fts5SegIterSetEOF(pII);
245192 }
245193 if( pII->pLeaf && (!pSmall || fts5BufferCompare(pSmall, &pII->term)>0) ){
245194 pSmall = &pII->term;
245195 }
245196 }
245197
245198 /* If pSmall is still NULL at this point, then the new iterator does
245199 ** not point to any terms that match the query. So delete it and break
245200 ** out of the loop - all required iterators have been collected. */
245201 if( pSmall==0 ){
245202 sqlite3Fts5IterClose((Fts5IndexIter*)pNew);
245203 break;
245204 }
245205
245206 /* Append this iterator to the set and continue. */
245207 pSet = fts5AppendTokendataIter(p, pSet, pNew);
245208 }
245209
245210 if( p->rc==SQLITE_OK && pSet ){
245211 int ii;
245212 for(ii=0; ii<pSet->nIter; ii++){
245213 Fts5Iter *pIter = pSet->apIter[ii];
245214 int iSeg;
245215 for(iSeg=0; iSeg<pIter->nSeg; iSeg++){
245216 pIter->aSeg[iSeg].flags |= FTS5_SEGITER_ONETERM;
245217 }
245218 fts5MultiIterFinishSetup(p, pIter);
245219 }
245220 }
245221
245222 if( p->rc==SQLITE_OK ){
245223 pRet = fts5MultiIterAlloc(p, 0);
245224 }
245225 if( pRet ){
245226 pRet->pTokenDataIter = pSet;
245227 if( pSet ){
245228 fts5IterSetOutputsTokendata(pRet);
245229 }else{
245230 pRet->base.bEof = 1;
245231 }
245232 }else{
245233 fts5TokendataIterDelete(pSet);
245234 }
245235
245236 fts5StructureRelease(pStruct);
245237 fts5BufferFree(&bSeek);
245238 return pRet;
245239 }
245240
245241
245242 /*
245243 ** Open a new iterator to iterate though all rowid that match the
245244 ** specified token or token prefix.
245245 */
@@ -242818,11 +245258,16 @@
245258 assert( (flags & FTS5INDEX_QUERY_SCAN)==0 || flags==FTS5INDEX_QUERY_SCAN );
245259
245260 if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){
245261 int iIdx = 0; /* Index to search */
245262 int iPrefixIdx = 0; /* +1 prefix index */
245263 int bTokendata = pConfig->bTokendata;
245264 if( nToken>0 ) memcpy(&buf.p[1], pToken, nToken);
245265
245266 if( flags & (FTS5INDEX_QUERY_NOTOKENDATA|FTS5INDEX_QUERY_SCAN) ){
245267 bTokendata = 0;
245268 }
245269
245270 /* Figure out which index to search and set iIdx accordingly. If this
245271 ** is a prefix query for which there is no prefix index, set iIdx to
245272 ** greater than pConfig->nPrefix to indicate that the query will be
245273 ** satisfied by scanning multiple terms in the main index.
@@ -242845,11 +245290,14 @@
245290 if( nIdxChar==nChar ) break;
245291 if( nIdxChar==nChar+1 ) iPrefixIdx = iIdx;
245292 }
245293 }
245294
245295 if( bTokendata && iIdx==0 ){
245296 buf.p[0] = '0';
245297 pRet = fts5SetupTokendataIter(p, buf.p, nToken+1, pColset);
245298 }else if( iIdx<=pConfig->nPrefix ){
245299 /* Straight index lookup */
245300 Fts5Structure *pStruct = fts5StructureRead(p);
245301 buf.p[0] = (u8)(FTS5_MAIN_PREFIX + iIdx);
245302 if( pStruct ){
245303 fts5MultiIterNew(p, pStruct, flags | FTS5INDEX_QUERY_SKIPEMPTY,
@@ -242892,11 +245340,15 @@
245340 ** Move to the next matching rowid.
245341 */
245342 static int sqlite3Fts5IterNext(Fts5IndexIter *pIndexIter){
245343 Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
245344 assert( pIter->pIndex->rc==SQLITE_OK );
245345 if( pIter->pTokenDataIter ){
245346 fts5TokendataIterNext(pIter, 0, 0);
245347 }else{
245348 fts5MultiIterNext(pIter->pIndex, pIter, 0, 0);
245349 }
245350 return fts5IndexReturn(pIter->pIndex);
245351 }
245352
245353 /*
245354 ** Move to the next matching term/rowid. Used by the fts5vocab module.
@@ -242925,11 +245377,15 @@
245377 ** definition of "at or after" depends on whether this iterator iterates
245378 ** in ascending or descending rowid order.
245379 */
245380 static int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){
245381 Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
245382 if( pIter->pTokenDataIter ){
245383 fts5TokendataIterNext(pIter, 1, iMatch);
245384 }else{
245385 fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch);
245386 }
245387 return fts5IndexReturn(pIter->pIndex);
245388 }
245389
245390 /*
245391 ** Return the current term.
@@ -242939,18 +245395,112 @@
245395 const char *z = (const char*)fts5MultiIterTerm((Fts5Iter*)pIndexIter, &n);
245396 assert_nc( z || n<=1 );
245397 *pn = n-1;
245398 return (z ? &z[1] : 0);
245399 }
245400
245401 /*
245402 ** This is used by xInstToken() to access the token at offset iOff, column
245403 ** iCol of row iRowid. The token is returned via output variables *ppOut
245404 ** and *pnOut. The iterator passed as the first argument must be a tokendata=1
245405 ** iterator (pIter->pTokenDataIter!=0).
245406 */
245407 static int sqlite3Fts5IterToken(
245408 Fts5IndexIter *pIndexIter,
245409 i64 iRowid,
245410 int iCol,
245411 int iOff,
245412 const char **ppOut, int *pnOut
245413 ){
245414 Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
245415 Fts5TokenDataIter *pT = pIter->pTokenDataIter;
245416 Fts5TokenDataMap *aMap = pT->aMap;
245417 i64 iPos = (((i64)iCol)<<32) + iOff;
245418
245419 int i1 = 0;
245420 int i2 = pT->nMap;
245421 int iTest = 0;
245422
245423 while( i2>i1 ){
245424 iTest = (i1 + i2) / 2;
245425
245426 if( aMap[iTest].iRowid<iRowid ){
245427 i1 = iTest+1;
245428 }else if( aMap[iTest].iRowid>iRowid ){
245429 i2 = iTest;
245430 }else{
245431 if( aMap[iTest].iPos<iPos ){
245432 if( aMap[iTest].iPos<0 ){
245433 break;
245434 }
245435 i1 = iTest+1;
245436 }else if( aMap[iTest].iPos>iPos ){
245437 i2 = iTest;
245438 }else{
245439 break;
245440 }
245441 }
245442 }
245443
245444 if( i2>i1 ){
245445 Fts5Iter *pMap = pT->apIter[aMap[iTest].iIter];
245446 *ppOut = (const char*)pMap->aSeg[0].term.p+1;
245447 *pnOut = pMap->aSeg[0].term.n-1;
245448 }
245449
245450 return SQLITE_OK;
245451 }
245452
245453 /*
245454 ** Clear any existing entries from the token-map associated with the
245455 ** iterator passed as the only argument.
245456 */
245457 static void sqlite3Fts5IndexIterClearTokendata(Fts5IndexIter *pIndexIter){
245458 Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
245459 if( pIter && pIter->pTokenDataIter ){
245460 pIter->pTokenDataIter->nMap = 0;
245461 }
245462 }
245463
245464 /*
245465 ** Set a token-mapping for the iterator passed as the first argument. This
245466 ** is used in detail=column or detail=none mode when a token is requested
245467 ** using the xInstToken() API. In this case the caller tokenizers the
245468 ** current row and configures the token-mapping via multiple calls to this
245469 ** function.
245470 */
245471 static int sqlite3Fts5IndexIterWriteTokendata(
245472 Fts5IndexIter *pIndexIter,
245473 const char *pToken, int nToken,
245474 i64 iRowid, int iCol, int iOff
245475 ){
245476 Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
245477 Fts5TokenDataIter *pT = pIter->pTokenDataIter;
245478 Fts5Index *p = pIter->pIndex;
245479 int ii;
245480
245481 assert( p->pConfig->eDetail!=FTS5_DETAIL_FULL );
245482 assert( pIter->pTokenDataIter );
245483
245484 for(ii=0; ii<pT->nIter; ii++){
245485 Fts5Buffer *pTerm = &pT->apIter[ii]->aSeg[0].term;
245486 if( nToken==pTerm->n-1 && memcmp(pToken, pTerm->p+1, nToken)==0 ) break;
245487 }
245488 if( ii<pT->nIter ){
245489 fts5TokendataIterAppendMap(p, pT, ii, iRowid, (((i64)iCol)<<32) + iOff);
245490 }
245491 return fts5IndexReturn(p);
245492 }
245493
245494 /*
245495 ** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery().
245496 */
245497 static void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){
245498 if( pIndexIter ){
245499 Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
245500 Fts5Index *pIndex = pIter->pIndex;
245501 fts5TokendataIterDelete(pIter->pTokenDataIter);
245502 fts5MultiIterFree(pIter);
245503 sqlite3Fts5IndexCloseReader(pIndex);
245504 }
245505 }
245506
@@ -243454,11 +246004,13 @@
246004 u64 *pCksum /* IN/OUT: Checksum value */
246005 ){
246006 int eDetail = p->pConfig->eDetail;
246007 u64 cksum = *pCksum;
246008 Fts5IndexIter *pIter = 0;
246009 int rc = sqlite3Fts5IndexQuery(
246010 p, z, n, (flags | FTS5INDEX_QUERY_NOTOKENDATA), 0, &pIter
246011 );
246012
246013 while( rc==SQLITE_OK && ALWAYS(pIter!=0) && 0==sqlite3Fts5IterEof(pIter) ){
246014 i64 rowid = pIter->iRowid;
246015
246016 if( eDetail==FTS5_DETAIL_NONE ){
@@ -244151,10 +246703,28 @@
246703
246704 sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " %lld%s", iRowid, zApp);
246705 }
246706 }
246707 #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
246708
246709 #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
246710 static void fts5BufferAppendTerm(int *pRc, Fts5Buffer *pBuf, Fts5Buffer *pTerm){
246711 int ii;
246712 fts5BufferGrow(pRc, pBuf, pTerm->n*2 + 1);
246713 if( *pRc==SQLITE_OK ){
246714 for(ii=0; ii<pTerm->n; ii++){
246715 if( pTerm->p[ii]==0x00 ){
246716 pBuf->p[pBuf->n++] = '\\';
246717 pBuf->p[pBuf->n++] = '0';
246718 }else{
246719 pBuf->p[pBuf->n++] = pTerm->p[ii];
246720 }
246721 }
246722 pBuf->p[pBuf->n] = 0x00;
246723 }
246724 }
246725 #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
246726
246727 #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
246728 /*
246729 ** The implementation of user-defined scalar function fts5_decode().
246730 */
@@ -244259,13 +246829,12 @@
246829
246830 /* Read the term data for the next term*/
246831 iOff += fts5GetVarint32(&a[iOff], nAppend);
246832 term.n = nKeep;
246833 fts5BufferAppendBlob(&rc, &term, nAppend, &a[iOff]);
246834 sqlite3Fts5BufferAppendPrintf(&rc, &s, " term=");
246835 fts5BufferAppendTerm(&rc, &s, &term);
 
246836 iOff += nAppend;
246837
246838 /* Figure out where the doclist for this term ends */
246839 if( iPgidxOff<n ){
246840 int nIncr;
@@ -244369,13 +246938,12 @@
246938 break;
246939 }
246940 fts5BufferAppendBlob(&rc, &term, nByte, &a[iOff]);
246941 iOff += nByte;
246942
246943 sqlite3Fts5BufferAppendPrintf(&rc, &s, " term=");
246944 fts5BufferAppendTerm(&rc, &s, &term);
 
246945 iOff += fts5DecodeDoclist(&rc, &s, &a[iOff], iEnd-iOff);
246946 }
246947
246948 fts5BufferFree(&term);
246949 }
@@ -244846,11 +247414,11 @@
247414 Fts5Table p; /* Public class members from fts5Int.h */
247415 Fts5Storage *pStorage; /* Document store */
247416 Fts5Global *pGlobal; /* Global (connection wide) data */
247417 Fts5Cursor *pSortCsr; /* Sort data from this cursor */
247418 int iSavepoint; /* Successful xSavepoint()+1 */
247419
247420 #ifdef SQLITE_DEBUG
247421 struct Fts5TransactionState ts;
247422 #endif
247423 };
247424
@@ -245384,16 +247952,19 @@
247952 }
247953 }
247954 }
247955 idxStr[iIdxStr] = '\0';
247956
247957 /* Set idxFlags flags for the ORDER BY clause
247958 **
247959 ** Note that tokendata=1 tables cannot currently handle "ORDER BY rowid DESC".
247960 */
247961 if( pInfo->nOrderBy==1 ){
247962 int iSort = pInfo->aOrderBy[0].iColumn;
247963 if( iSort==(pConfig->nCol+1) && bSeenMatch ){
247964 idxFlags |= FTS5_BI_ORDER_RANK;
247965 }else if( iSort==-1 && (!pInfo->aOrderBy[0].desc || !pConfig->bTokendata) ){
247966 idxFlags |= FTS5_BI_ORDER_ROWID;
247967 }
247968 if( BitFlagTest(idxFlags, FTS5_BI_ORDER_RANK|FTS5_BI_ORDER_ROWID) ){
247969 pInfo->orderByConsumed = 1;
247970 if( pInfo->aOrderBy[0].desc ){
@@ -245640,10 +248211,20 @@
248211
248212 assert( (pCsr->ePlan<3)==
248213 (pCsr->ePlan==FTS5_PLAN_MATCH || pCsr->ePlan==FTS5_PLAN_SOURCE)
248214 );
248215 assert( !CsrFlagTest(pCsr, FTS5CSR_EOF) );
248216
248217 /* If this cursor uses FTS5_PLAN_MATCH and this is a tokendata=1 table,
248218 ** clear any token mappings accumulated at the fts5_index.c level. In
248219 ** other cases, specifically FTS5_PLAN_SOURCE and FTS5_PLAN_SORTED_MATCH,
248220 ** we need to retain the mappings for the entire query. */
248221 if( pCsr->ePlan==FTS5_PLAN_MATCH
248222 && ((Fts5Table*)pCursor->pVtab)->pConfig->bTokendata
248223 ){
248224 sqlite3Fts5ExprClearTokens(pCsr->pExpr);
248225 }
248226
248227 if( pCsr->ePlan<3 ){
248228 int bSkip = 0;
248229 if( (rc = fts5CursorReseek(pCsr, &bSkip)) || bSkip ) return rc;
248230 rc = sqlite3Fts5ExprNext(pCsr->pExpr, pCsr->iLastRowid);
@@ -246791,16 +249372,10 @@
249372 if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_INST)==0
249373 || SQLITE_OK==(rc = fts5CacheInstArray(pCsr))
249374 ){
249375 if( iIdx<0 || iIdx>=pCsr->nInstCount ){
249376 rc = SQLITE_RANGE;
 
 
 
 
 
 
249377 }else{
249378 *piPhrase = pCsr->aInst[iIdx*3];
249379 *piCol = pCsr->aInst[iIdx*3 + 1];
249380 *piOff = pCsr->aInst[iIdx*3 + 2];
249381 }
@@ -247051,17 +249626,60 @@
249626 }
249627
249628 return rc;
249629 }
249630
249631 /*
249632 ** xQueryToken() API implemenetation.
249633 */
249634 static int fts5ApiQueryToken(
249635 Fts5Context* pCtx,
249636 int iPhrase,
249637 int iToken,
249638 const char **ppOut,
249639 int *pnOut
249640 ){
249641 Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
249642 return sqlite3Fts5ExprQueryToken(pCsr->pExpr, iPhrase, iToken, ppOut, pnOut);
249643 }
249644
249645 /*
249646 ** xInstToken() API implemenetation.
249647 */
249648 static int fts5ApiInstToken(
249649 Fts5Context *pCtx,
249650 int iIdx,
249651 int iToken,
249652 const char **ppOut, int *pnOut
249653 ){
249654 Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
249655 int rc = SQLITE_OK;
249656 if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_INST)==0
249657 || SQLITE_OK==(rc = fts5CacheInstArray(pCsr))
249658 ){
249659 if( iIdx<0 || iIdx>=pCsr->nInstCount ){
249660 rc = SQLITE_RANGE;
249661 }else{
249662 int iPhrase = pCsr->aInst[iIdx*3];
249663 int iCol = pCsr->aInst[iIdx*3 + 1];
249664 int iOff = pCsr->aInst[iIdx*3 + 2];
249665 i64 iRowid = fts5CursorRowid(pCsr);
249666 rc = sqlite3Fts5ExprInstToken(
249667 pCsr->pExpr, iRowid, iPhrase, iCol, iOff, iToken, ppOut, pnOut
249668 );
249669 }
249670 }
249671 return rc;
249672 }
249673
249674
249675 static int fts5ApiQueryPhrase(Fts5Context*, int, void*,
249676 int(*)(const Fts5ExtensionApi*, Fts5Context*, void*)
249677 );
249678
249679 static const Fts5ExtensionApi sFts5Api = {
249680 3, /* iVersion */
249681 fts5ApiUserData,
249682 fts5ApiColumnCount,
249683 fts5ApiRowCount,
249684 fts5ApiColumnTotalSize,
249685 fts5ApiTokenize,
@@ -247077,10 +249695,12 @@
249695 fts5ApiGetAuxdata,
249696 fts5ApiPhraseFirst,
249697 fts5ApiPhraseNext,
249698 fts5ApiPhraseFirstColumn,
249699 fts5ApiPhraseNextColumn,
249700 fts5ApiQueryToken,
249701 fts5ApiInstToken
249702 };
249703
249704 /*
249705 ** Implementation of API function xQueryPhrase().
249706 */
@@ -247343,13 +249963,11 @@
249963 sqlite3_vtab *pVtab, /* Virtual table handle */
249964 const char *zName /* New name of table */
249965 ){
249966 int rc;
249967 Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
 
249968 rc = sqlite3Fts5StorageRename(pTab->pStorage, zName);
 
249969 return rc;
249970 }
249971
249972 static int sqlite3Fts5FlushToDisk(Fts5Table *pTab){
249973 fts5TripCursors((Fts5FullTable*)pTab);
@@ -247362,30 +249980,16 @@
249980 ** Flush the contents of the pending-terms table to disk.
249981 */
249982 static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){
249983 Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
249984 int rc = SQLITE_OK;
249985
249986 fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint);
249987 rc = sqlite3Fts5FlushToDisk((Fts5Table*)pVtab);
249988 if( rc==SQLITE_OK ){
249989 pTab->iSavepoint = iSavepoint+1;
249990 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249991 return rc;
249992 }
249993
249994 /*
249995 ** The xRelease() method.
@@ -247619,11 +250223,11 @@
250223 int nArg, /* Number of args */
250224 sqlite3_value **apUnused /* Function arguments */
250225 ){
250226 assert( nArg==0 );
250227 UNUSED_PARAM2(nArg, apUnused);
250228 sqlite3_result_text(pCtx, "fts5: 2023-12-14 16:34:47 27d4a89a5ff96b7b7fc5dc9650e1269f7c7edf91de9b9aafce40be9ecc8b95e9", -1, SQLITE_TRANSIENT);
250229 }
250230
250231 /*
250232 ** Return true if zName is the extension on one of the shadow tables used
250233 ** by this module.
@@ -247642,11 +250246,11 @@
250246 /*
250247 ** Run an integrity check on the FTS5 data structures. Return a string
250248 ** if anything is found amiss. Return a NULL pointer if everything is
250249 ** OK.
250250 */
250251 static int fts5IntegrityMethod(
250252 sqlite3_vtab *pVtab, /* the FTS5 virtual table to check */
250253 const char *zSchema, /* Name of schema in which this table lives */
250254 const char *zTabname, /* Name of the table itself */
250255 int isQuick, /* True if this is a quick-check */
250256 char **pzErr /* Write error message here */
@@ -247700,11 +250304,11 @@
250304 /* xRename */ fts5RenameMethod,
250305 /* xSavepoint */ fts5SavepointMethod,
250306 /* xRelease */ fts5ReleaseMethod,
250307 /* xRollbackTo */ fts5RollbackToMethod,
250308 /* xShadowName */ fts5ShadowName,
250309 /* xIntegrity */ fts5IntegrityMethod
250310 };
250311
250312 int rc;
250313 Fts5Global *pGlobal = 0;
250314
@@ -248466,11 +251070,11 @@
251070 if( rc==SQLITE_OK ){
251071 rc = fts5StorageLoadTotals(p, 1);
251072 }
251073
251074 if( rc==SQLITE_OK ){
251075 rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, pConfig->pzErrmsg);
251076 }
251077
251078 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pScan) ){
251079 i64 iRowid = sqlite3_column_int64(pScan, 0);
251080
@@ -249252,10 +251856,16 @@
251856 *zOut++ = 0x80 + (unsigned char)(c & 0x3F); \
251857 } \
251858 }
251859
251860 #endif /* ifndef SQLITE_AMALGAMATION */
251861
251862 #define FTS5_SKIP_UTF8(zIn) { \
251863 if( ((unsigned char)(*(zIn++)))>=0xc0 ){ \
251864 while( (((unsigned char)*zIn) & 0xc0)==0x80 ){ zIn++; } \
251865 } \
251866 }
251867
251868 typedef struct Unicode61Tokenizer Unicode61Tokenizer;
251869 struct Unicode61Tokenizer {
251870 unsigned char aTokenChar[128]; /* ASCII range token characters */
251871 char *aFold; /* Buffer to fold text into */
@@ -250288,10 +252898,11 @@
252898 ** Start of trigram implementation.
252899 */
252900 typedef struct TrigramTokenizer TrigramTokenizer;
252901 struct TrigramTokenizer {
252902 int bFold; /* True to fold to lower-case */
252903 int iFoldParam; /* Parameter to pass to Fts5UnicodeFold() */
252904 };
252905
252906 /*
252907 ** Free a trigram tokenizer.
252908 */
@@ -250314,22 +252925,34 @@
252925 if( pNew==0 ){
252926 rc = SQLITE_NOMEM;
252927 }else{
252928 int i;
252929 pNew->bFold = 1;
252930 pNew->iFoldParam = 0;
252931 for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
252932 const char *zArg = azArg[i+1];
252933 if( 0==sqlite3_stricmp(azArg[i], "case_sensitive") ){
252934 if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){
252935 rc = SQLITE_ERROR;
252936 }else{
252937 pNew->bFold = (zArg[0]=='0');
252938 }
252939 }else if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){
252940 if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){
252941 rc = SQLITE_ERROR;
252942 }else{
252943 pNew->iFoldParam = (zArg[0]!='0') ? 2 : 0;
252944 }
252945 }else{
252946 rc = SQLITE_ERROR;
252947 }
252948 }
252949
252950 if( pNew->iFoldParam!=0 && pNew->bFold==0 ){
252951 rc = SQLITE_ERROR;
252952 }
252953
252954 if( rc!=SQLITE_OK ){
252955 fts5TriDelete((Fts5Tokenizer*)pNew);
252956 pNew = 0;
252957 }
252958 }
@@ -250348,44 +252971,66 @@
252971 int (*xToken)(void*, int, const char*, int, int, int)
252972 ){
252973 TrigramTokenizer *p = (TrigramTokenizer*)pTok;
252974 int rc = SQLITE_OK;
252975 char aBuf[32];
252976 char *zOut = aBuf;
252977 int ii;
252978 const unsigned char *zIn = (const unsigned char*)pText;
252979 const unsigned char *zEof = &zIn[nText];
252980 u32 iCode;
252981 int aStart[3]; /* Input offset of each character in aBuf[] */
252982
252983 UNUSED_PARAM(unusedFlags);
252984
252985 /* Populate aBuf[] with the characters for the first trigram. */
252986 for(ii=0; ii<3; ii++){
252987 do {
252988 aStart[ii] = zIn - (const unsigned char*)pText;
252989 READ_UTF8(zIn, zEof, iCode);
252990 if( iCode==0 ) return SQLITE_OK;
252991 if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam);
252992 }while( iCode==0 );
252993 WRITE_UTF8(zOut, iCode);
252994 }
252995
252996 /* At the start of each iteration of this loop:
252997 **
252998 ** aBuf: Contains 3 characters. The 3 characters of the next trigram.
252999 ** zOut: Points to the byte following the last character in aBuf.
253000 ** aStart[3]: Contains the byte offset in the input text corresponding
253001 ** to the start of each of the three characters in the buffer.
253002 */
253003 assert( zIn<=zEof );
253004 while( 1 ){
253005 int iNext; /* Start of character following current tri */
253006 const char *z1;
253007
253008 /* Read characters from the input up until the first non-diacritic */
253009 do {
253010 iNext = zIn - (const unsigned char*)pText;
253011 READ_UTF8(zIn, zEof, iCode);
253012 if( iCode==0 ) break;
253013 if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam);
253014 }while( iCode==0 );
253015
253016 /* Pass the current trigram back to fts5 */
253017 rc = xToken(pCtx, 0, aBuf, zOut-aBuf, aStart[0], iNext);
253018 if( iCode==0 || rc!=SQLITE_OK ) break;
253019
253020 /* Remove the first character from buffer aBuf[]. Append the character
253021 ** with codepoint iCode. */
253022 z1 = aBuf;
253023 FTS5_SKIP_UTF8(z1);
253024 memmove(aBuf, z1, zOut - z1);
253025 zOut -= (z1 - aBuf);
253026 WRITE_UTF8(zOut, iCode);
253027
253028 /* Update the aStart[] array */
253029 aStart[0] = aStart[1];
253030 aStart[1] = aStart[2];
253031 aStart[2] = iNext;
253032 }
253033
253034 return rc;
253035 }
253036
@@ -250404,11 +253049,13 @@
253049 int (*xCreate)(void*, const char**, int, Fts5Tokenizer**),
253050 Fts5Tokenizer *pTok
253051 ){
253052 if( xCreate==fts5TriCreate ){
253053 TrigramTokenizer *p = (TrigramTokenizer*)pTok;
253054 if( p->iFoldParam==0 ){
253055 return p->bFold ? FTS5_PATTERN_LIKE : FTS5_PATTERN_GLOB;
253056 }
253057 }
253058 return FTS5_PATTERN_NONE;
253059 }
253060
253061 /*
@@ -252193,11 +254840,11 @@
254840 if( idxNum & FTS5_VOCAB_TERM_LE ) pLe = apVal[iVal++];
254841
254842 if( pEq ){
254843 zTerm = (const char *)sqlite3_value_text(pEq);
254844 nTerm = sqlite3_value_bytes(pEq);
254845 f = FTS5INDEX_QUERY_NOTOKENDATA;
254846 }else{
254847 if( pGe ){
254848 zTerm = (const char *)sqlite3_value_text(pGe);
254849 nTerm = sqlite3_value_bytes(pGe);
254850 }
254851
+42 -7
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -144,13 +144,13 @@
144144
**
145145
** See also: [sqlite3_libversion()],
146146
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147147
** [sqlite_version()] and [sqlite_source_id()].
148148
*/
149
-#define SQLITE_VERSION "3.44.2"
150
-#define SQLITE_VERSION_NUMBER 3044002
151
-#define SQLITE_SOURCE_ID "2023-11-24 11:41:44 ebead0e7230cd33bcec9f95d2183069565b9e709bf745c9b5db65cc0cbf92c0f"
149
+#define SQLITE_VERSION "3.45.0"
150
+#define SQLITE_VERSION_NUMBER 3045000
151
+#define SQLITE_SOURCE_ID "2023-12-14 16:34:47 27d4a89a5ff96b7b7fc5dc9650e1269f7c7edf91de9b9aafce40be9ecc8b95e9"
152152
153153
/*
154154
** CAPI3REF: Run-Time Library Version Numbers
155155
** KEYWORDS: sqlite3_version sqlite3_sourceid
156156
**
@@ -3952,19 +3952,21 @@
39523952
** <li> sqlite3_errmsg16()
39533953
** <li> sqlite3_error_offset()
39543954
** </ul>
39553955
**
39563956
** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
3957
-** text that describes the error, as either UTF-8 or UTF-16 respectively.
3957
+** text that describes the error, as either UTF-8 or UTF-16 respectively,
3958
+** or NULL if no error message is available.
39583959
** (See how SQLite handles [invalid UTF] for exceptions to this rule.)
39593960
** ^(Memory to hold the error message string is managed internally.
39603961
** The application does not need to worry about freeing the result.
39613962
** However, the error string might be overwritten or deallocated by
39623963
** subsequent calls to other SQLite interface functions.)^
39633964
**
3964
-** ^The sqlite3_errstr() interface returns the English-language text
3965
-** that describes the [result code], as UTF-8.
3965
+** ^The sqlite3_errstr(E) interface returns the English-language text
3966
+** that describes the [result code] E, as UTF-8, or NULL if E is not an
3967
+** result code for which a text error message is available.
39663968
** ^(Memory to hold the error message string is managed internally
39673969
** and must not be freed by the application)^.
39683970
**
39693971
** ^If the most recent error references a specific token in the input
39703972
** SQL, the sqlite3_error_offset() interface returns the byte offset
@@ -8296,10 +8298,11 @@
82968298
#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10
82978299
#define SQLITE_TESTCTRL_PENDING_BYTE 11
82988300
#define SQLITE_TESTCTRL_ASSERT 12
82998301
#define SQLITE_TESTCTRL_ALWAYS 13
83008302
#define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */
8303
+#define SQLITE_TESTCTRL_JSON_SELFCHECK 14
83018304
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
83028305
#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
83038306
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
83048307
#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17
83058308
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
@@ -12982,13 +12985,38 @@
1298212985
** significantly more efficient than those alternatives when used with
1298312986
** "detail=column" tables.
1298412987
**
1298512988
** xPhraseNextColumn()
1298612989
** See xPhraseFirstColumn above.
12990
+**
12991
+** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken)
12992
+** This is used to access token iToken of phrase iPhrase of the current
12993
+** query. Before returning, output parameter *ppToken is set to point
12994
+** to a buffer containing the requested token, and *pnToken to the
12995
+** size of this buffer in bytes.
12996
+**
12997
+** The output text is not a copy of the query text that specified the
12998
+** token. It is the output of the tokenizer module. For tokendata=1
12999
+** tables, this includes any embedded 0x00 and trailing data.
13000
+**
13001
+** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken)
13002
+** This is used to access token iToken of phrase hit iIdx within the
13003
+** current row. Output variable (*ppToken) is set to point to a buffer
13004
+** containing the matching document token, and (*pnToken) to the size
13005
+** of that buffer in bytes. This API is not available if the specified
13006
+** token matches a prefix query term. In that case both output variables
13007
+** are always set to 0.
13008
+**
13009
+** The output text is not a copy of the document text that was tokenized.
13010
+** It is the output of the tokenizer module. For tokendata=1 tables, this
13011
+** includes any embedded 0x00 and trailing data.
13012
+**
13013
+** This API can be quite slow if used with an FTS5 table created with the
13014
+** "detail=none" or "detail=column" option.
1298713015
*/
1298813016
struct Fts5ExtensionApi {
12989
- int iVersion; /* Currently always set to 2 */
13017
+ int iVersion; /* Currently always set to 3 */
1299013018
1299113019
void *(*xUserData)(Fts5Context*);
1299213020
1299313021
int (*xColumnCount)(Fts5Context*);
1299413022
int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
@@ -13019,10 +13047,17 @@
1301913047
int (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*);
1302013048
void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff);
1302113049
1302213050
int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*);
1302313051
void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol);
13052
+
13053
+ /* Below this point are iVersion>=3 only */
13054
+ int (*xQueryToken)(Fts5Context*,
13055
+ int iPhrase, int iToken,
13056
+ const char **ppToken, int *pnToken
13057
+ );
13058
+ int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*);
1302413059
};
1302513060
1302613061
/*
1302713062
** CUSTOM AUXILIARY FUNCTIONS
1302813063
*************************************************************************/
1302913064
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -144,13 +144,13 @@
144 **
145 ** See also: [sqlite3_libversion()],
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.44.2"
150 #define SQLITE_VERSION_NUMBER 3044002
151 #define SQLITE_SOURCE_ID "2023-11-24 11:41:44 ebead0e7230cd33bcec9f95d2183069565b9e709bf745c9b5db65cc0cbf92c0f"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
@@ -3952,19 +3952,21 @@
3952 ** <li> sqlite3_errmsg16()
3953 ** <li> sqlite3_error_offset()
3954 ** </ul>
3955 **
3956 ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
3957 ** text that describes the error, as either UTF-8 or UTF-16 respectively.
 
3958 ** (See how SQLite handles [invalid UTF] for exceptions to this rule.)
3959 ** ^(Memory to hold the error message string is managed internally.
3960 ** The application does not need to worry about freeing the result.
3961 ** However, the error string might be overwritten or deallocated by
3962 ** subsequent calls to other SQLite interface functions.)^
3963 **
3964 ** ^The sqlite3_errstr() interface returns the English-language text
3965 ** that describes the [result code], as UTF-8.
 
3966 ** ^(Memory to hold the error message string is managed internally
3967 ** and must not be freed by the application)^.
3968 **
3969 ** ^If the most recent error references a specific token in the input
3970 ** SQL, the sqlite3_error_offset() interface returns the byte offset
@@ -8296,10 +8298,11 @@
8296 #define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10
8297 #define SQLITE_TESTCTRL_PENDING_BYTE 11
8298 #define SQLITE_TESTCTRL_ASSERT 12
8299 #define SQLITE_TESTCTRL_ALWAYS 13
8300 #define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */
 
8301 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15
8302 #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
8303 #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
8304 #define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17
8305 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
@@ -12982,13 +12985,38 @@
12982 ** significantly more efficient than those alternatives when used with
12983 ** "detail=column" tables.
12984 **
12985 ** xPhraseNextColumn()
12986 ** See xPhraseFirstColumn above.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12987 */
12988 struct Fts5ExtensionApi {
12989 int iVersion; /* Currently always set to 2 */
12990
12991 void *(*xUserData)(Fts5Context*);
12992
12993 int (*xColumnCount)(Fts5Context*);
12994 int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
@@ -13019,10 +13047,17 @@
13019 int (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*);
13020 void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff);
13021
13022 int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*);
13023 void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol);
 
 
 
 
 
 
 
13024 };
13025
13026 /*
13027 ** CUSTOM AUXILIARY FUNCTIONS
13028 *************************************************************************/
13029
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -144,13 +144,13 @@
144 **
145 ** See also: [sqlite3_libversion()],
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.45.0"
150 #define SQLITE_VERSION_NUMBER 3045000
151 #define SQLITE_SOURCE_ID "2023-12-14 16:34:47 27d4a89a5ff96b7b7fc5dc9650e1269f7c7edf91de9b9aafce40be9ecc8b95e9"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
@@ -3952,19 +3952,21 @@
3952 ** <li> sqlite3_errmsg16()
3953 ** <li> sqlite3_error_offset()
3954 ** </ul>
3955 **
3956 ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
3957 ** text that describes the error, as either UTF-8 or UTF-16 respectively,
3958 ** or NULL if no error message is available.
3959 ** (See how SQLite handles [invalid UTF] for exceptions to this rule.)
3960 ** ^(Memory to hold the error message string is managed internally.
3961 ** The application does not need to worry about freeing the result.
3962 ** However, the error string might be overwritten or deallocated by
3963 ** subsequent calls to other SQLite interface functions.)^
3964 **
3965 ** ^The sqlite3_errstr(E) interface returns the English-language text
3966 ** that describes the [result code] E, as UTF-8, or NULL if E is not an
3967 ** result code for which a text error message is available.
3968 ** ^(Memory to hold the error message string is managed internally
3969 ** and must not be freed by the application)^.
3970 **
3971 ** ^If the most recent error references a specific token in the input
3972 ** SQL, the sqlite3_error_offset() interface returns the byte offset
@@ -8296,10 +8298,11 @@
8298 #define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10
8299 #define SQLITE_TESTCTRL_PENDING_BYTE 11
8300 #define SQLITE_TESTCTRL_ASSERT 12
8301 #define SQLITE_TESTCTRL_ALWAYS 13
8302 #define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */
8303 #define SQLITE_TESTCTRL_JSON_SELFCHECK 14
8304 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15
8305 #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
8306 #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
8307 #define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17
8308 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
@@ -12982,13 +12985,38 @@
12985 ** significantly more efficient than those alternatives when used with
12986 ** "detail=column" tables.
12987 **
12988 ** xPhraseNextColumn()
12989 ** See xPhraseFirstColumn above.
12990 **
12991 ** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken)
12992 ** This is used to access token iToken of phrase iPhrase of the current
12993 ** query. Before returning, output parameter *ppToken is set to point
12994 ** to a buffer containing the requested token, and *pnToken to the
12995 ** size of this buffer in bytes.
12996 **
12997 ** The output text is not a copy of the query text that specified the
12998 ** token. It is the output of the tokenizer module. For tokendata=1
12999 ** tables, this includes any embedded 0x00 and trailing data.
13000 **
13001 ** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken)
13002 ** This is used to access token iToken of phrase hit iIdx within the
13003 ** current row. Output variable (*ppToken) is set to point to a buffer
13004 ** containing the matching document token, and (*pnToken) to the size
13005 ** of that buffer in bytes. This API is not available if the specified
13006 ** token matches a prefix query term. In that case both output variables
13007 ** are always set to 0.
13008 **
13009 ** The output text is not a copy of the document text that was tokenized.
13010 ** It is the output of the tokenizer module. For tokendata=1 tables, this
13011 ** includes any embedded 0x00 and trailing data.
13012 **
13013 ** This API can be quite slow if used with an FTS5 table created with the
13014 ** "detail=none" or "detail=column" option.
13015 */
13016 struct Fts5ExtensionApi {
13017 int iVersion; /* Currently always set to 3 */
13018
13019 void *(*xUserData)(Fts5Context*);
13020
13021 int (*xColumnCount)(Fts5Context*);
13022 int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
@@ -13019,10 +13047,17 @@
13047 int (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*);
13048 void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff);
13049
13050 int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*);
13051 void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol);
13052
13053 /* Below this point are iVersion>=3 only */
13054 int (*xQueryToken)(Fts5Context*,
13055 int iPhrase, int iToken,
13056 const char **ppToken, int *pnToken
13057 );
13058 int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*);
13059 };
13060
13061 /*
13062 ** CUSTOM AUXILIARY FUNCTIONS
13063 *************************************************************************/
13064

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button