Fossil SCM

Update the built-in SQLite to the latest code from the SQLite trunk, as a beta test of SQLite.

drh 2023-08-03 11:50 trunk
Commit 23cb5373993979ba308e62fee895e5b8f189797429fe94d444c349f87ac90cb6
3 files changed +125 -92 +2731 -673 +36 -1
+125 -92
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -17388,10 +17388,11 @@
1738817388
#define MODE_Markdown 14 /* Markdown formatting */
1738917389
#define MODE_Table 15 /* MySQL-style table formatting */
1739017390
#define MODE_Box 16 /* Unicode box-drawing characters */
1739117391
#define MODE_Count 17 /* Output only a count of the rows of output */
1739217392
#define MODE_Off 18 /* No query output shown */
17393
+#define MODE_ScanExp 19 /* Like MODE_Explain, but for ".scanstats vm" */
1739317394
1739417395
static const char *modeDescr[] = {
1739517396
"line",
1739617397
"column",
1739717398
"list",
@@ -18301,42 +18302,62 @@
1830118302
utf8_printf(p->out,"%*s = %s%s", w, azCol[i],
1830218303
azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
1830318304
}
1830418305
break;
1830518306
}
18306
- case MODE_Explain: {
18307
- static const int aExplainWidth[] = {4, 13, 4, 4, 4, 13, 2, 13};
18308
- if( nArg>ArraySize(aExplainWidth) ){
18309
- nArg = ArraySize(aExplainWidth);
18310
- }
18311
- if( p->cnt++==0 ){
18312
- for(i=0; i<nArg; i++){
18313
- int w = aExplainWidth[i];
18314
- utf8_width_print(p->out, w, azCol[i]);
18315
- fputs(i==nArg-1 ? "\n" : " ", p->out);
18316
- }
18317
- for(i=0; i<nArg; i++){
18318
- int w = aExplainWidth[i];
18319
- print_dashes(p->out, w);
18320
- fputs(i==nArg-1 ? "\n" : " ", p->out);
18321
- }
18322
- }
18323
- if( azArg==0 ) break;
18324
- for(i=0; i<nArg; i++){
18325
- int w = aExplainWidth[i];
18326
- if( i==nArg-1 ) w = 0;
18327
- if( azArg[i] && strlenChar(azArg[i])>w ){
18328
- w = strlenChar(azArg[i]);
18329
- }
18330
- if( i==1 && p->aiIndent && p->pStmt ){
18307
+ case MODE_ScanExp:
18308
+ case MODE_Explain: {
18309
+ static const int aExplainWidth[] = {4, 13, 4, 4, 4, 13, 2, 13};
18310
+ static const int aExplainMap[] = {0, 1, 2, 3, 4, 5, 6, 7 };
18311
+ static const int aScanExpWidth[] = {4, 6, 6, 13, 4, 4, 4, 13, 2, 13};
18312
+ static const int aScanExpMap[] = {0, 9, 8, 1, 2, 3, 4, 5, 6, 7 };
18313
+
18314
+ const int *aWidth = aExplainWidth;
18315
+ const int *aMap = aExplainMap;
18316
+ int nWidth = ArraySize(aExplainWidth);
18317
+ int iIndent = 1;
18318
+
18319
+ if( p->cMode==MODE_ScanExp ){
18320
+ aWidth = aScanExpWidth;
18321
+ aMap = aScanExpMap;
18322
+ nWidth = ArraySize(aScanExpWidth);
18323
+ iIndent = 3;
18324
+ }
18325
+ if( nArg>nWidth ) nArg = nWidth;
18326
+
18327
+ /* If this is the first row seen, print out the headers */
18328
+ if( p->cnt++==0 ){
18329
+ for(i=0; i<nArg; i++){
18330
+ utf8_width_print(p->out, aWidth[i], azCol[ aMap[i] ]);
18331
+ fputs(i==nArg-1 ? "\n" : " ", p->out);
18332
+ }
18333
+ for(i=0; i<nArg; i++){
18334
+ print_dashes(p->out, aWidth[i]);
18335
+ fputs(i==nArg-1 ? "\n" : " ", p->out);
18336
+ }
18337
+ }
18338
+
18339
+ /* If there is no data, exit early. */
18340
+ if( azArg==0 ) break;
18341
+
18342
+ for(i=0; i<nArg; i++){
18343
+ const char *zSep = " ";
18344
+ int w = aWidth[i];
18345
+ const char *zVal = azArg[ aMap[i] ];
18346
+ if( i==nArg-1 ) w = 0;
18347
+ if( zVal && strlenChar(zVal)>w ){
18348
+ w = strlenChar(zVal);
18349
+ zSep = " ";
18350
+ }
18351
+ if( i==iIndent && p->aiIndent && p->pStmt ){
1833118352
if( p->iIndent<p->nIndent ){
1833218353
utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
1833318354
}
1833418355
p->iIndent++;
1833518356
}
18336
- utf8_width_print(p->out, w, azArg[i] ? azArg[i] : p->nullValue);
18337
- fputs(i==nArg-1 ? "\n" : " ", p->out);
18357
+ utf8_width_print(p->out, w, zVal ? zVal : p->nullValue);
18358
+ fputs(i==nArg-1 ? "\n" : zSep, p->out);
1833818359
}
1833918360
break;
1834018361
}
1834118362
case MODE_Semi: { /* .schema and .fullschema output */
1834218363
printSchemaLine(p->out, azArg[0], ";\n");
@@ -19113,21 +19134,15 @@
1911319134
}
1911419135
return ret;
1911519136
}
1911619137
#endif
1911719138
19118
-/*
19119
-** Display scan stats.
19120
-*/
19121
-static void display_scanstats(
19139
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
19140
+static void display_explain_scanstats(
1912219141
sqlite3 *db, /* Database to query */
1912319142
ShellState *pArg /* Pointer to ShellState */
1912419143
){
19125
-#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
19126
- UNUSED_PARAMETER(db);
19127
- UNUSED_PARAMETER(pArg);
19128
-#else
1912919144
static const int f = SQLITE_SCANSTAT_COMPLEX;
1913019145
sqlite3_stmt *p = pArg->pStmt;
1913119146
int ii = 0;
1913219147
i64 nTotal = 0;
1913319148
int nWidth = 0;
@@ -19195,12 +19210,13 @@
1919519210
eqp_append(pArg, iId, iPid, zText);
1919619211
sqlite3_free(zText);
1919719212
}
1919819213
1919919214
eqp_render(pArg, nTotal);
19215
+}
1920019216
#endif
19201
-}
19217
+
1920219218
1920319219
/*
1920419220
** Parameter azArray points to a zero-terminated array of strings. zStr
1920519221
** points to a single nul-terminated string. Return non-zero if zStr
1920619222
** is equal, according to strcmp(), to any of the strings in the array.
@@ -19234,12 +19250,10 @@
1923419250
** or if the P1 parameter is one instead of zero,
1923519251
** then indent all opcodes between the earlier instruction
1923619252
** and "Goto" by 2 spaces.
1923719253
*/
1923819254
static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
19239
- const char *zSql; /* The text of the SQL statement */
19240
- const char *z; /* Used to check if this is an EXPLAIN */
1924119255
int *abYield = 0; /* True if op is an OP_Yield */
1924219256
int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
1924319257
int iOp; /* Index of operation in p->aiIndent[] */
1924419258
1924519259
const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
@@ -19246,69 +19260,49 @@
1924619260
"Return", 0 };
1924719261
const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
1924819262
"Rewind", 0 };
1924919263
const char *azGoto[] = { "Goto", 0 };
1925019264
19251
- /* Try to figure out if this is really an EXPLAIN statement. If this
19252
- ** cannot be verified, return early. */
19253
- if( sqlite3_column_count(pSql)!=8 ){
19254
- p->cMode = p->mode;
19255
- return;
19256
- }
19257
- zSql = sqlite3_sql(pSql);
19258
- if( zSql==0 ) return;
19259
- for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
19260
- if( sqlite3_strnicmp(z, "explain", 7) ){
19261
- p->cMode = p->mode;
19262
- return;
19263
- }
19265
+ /* The caller guarantees that the leftmost 4 columns of the statement
19266
+ ** passed to this function are equivalent to the leftmost 4 columns
19267
+ ** of EXPLAIN statement output. In practice the statement may be
19268
+ ** an EXPLAIN, or it may be a query on the bytecode() virtual table. */
19269
+ assert( sqlite3_column_count(pSql)>=4 );
19270
+ assert( 0==sqlite3_stricmp( sqlite3_column_name(pSql, 0), "addr" ) );
19271
+ assert( 0==sqlite3_stricmp( sqlite3_column_name(pSql, 1), "opcode" ) );
19272
+ assert( 0==sqlite3_stricmp( sqlite3_column_name(pSql, 2), "p1" ) );
19273
+ assert( 0==sqlite3_stricmp( sqlite3_column_name(pSql, 3), "p2" ) );
1926419274
1926519275
for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
1926619276
int i;
1926719277
int iAddr = sqlite3_column_int(pSql, 0);
1926819278
const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
19269
-
19270
- /* Set p2 to the P2 field of the current opcode. Then, assuming that
19271
- ** p2 is an instruction address, set variable p2op to the index of that
19272
- ** instruction in the aiIndent[] array. p2 and p2op may be different if
19273
- ** the current instruction is part of a sub-program generated by an
19274
- ** SQL trigger or foreign key. */
19279
+ int p1 = sqlite3_column_int(pSql, 2);
1927519280
int p2 = sqlite3_column_int(pSql, 3);
19281
+
19282
+ /* Assuming that p2 is an instruction address, set variable p2op to the
19283
+ ** index of that instruction in the aiIndent[] array. p2 and p2op may be
19284
+ ** different if the current instruction is part of a sub-program generated
19285
+ ** by an SQL trigger or foreign key. */
1927619286
int p2op = (p2 + (iOp-iAddr));
1927719287
1927819288
/* Grow the p->aiIndent array as required */
1927919289
if( iOp>=nAlloc ){
19280
- if( iOp==0 ){
19281
- /* Do further verification that this is explain output. Abort if
19282
- ** it is not */
19283
- static const char *explainCols[] = {
19284
- "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment" };
19285
- int jj;
19286
- for(jj=0; jj<ArraySize(explainCols); jj++){
19287
- if( cli_strcmp(sqlite3_column_name(pSql,jj),explainCols[jj])!=0 ){
19288
- p->cMode = p->mode;
19289
- sqlite3_reset(pSql);
19290
- return;
19291
- }
19292
- }
19293
- }
1929419290
nAlloc += 100;
1929519291
p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
1929619292
shell_check_oom(p->aiIndent);
1929719293
abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
1929819294
shell_check_oom(abYield);
1929919295
}
19296
+
1930019297
abYield[iOp] = str_in_array(zOp, azYield);
1930119298
p->aiIndent[iOp] = 0;
1930219299
p->nIndent = iOp+1;
19303
-
1930419300
if( str_in_array(zOp, azNext) && p2op>0 ){
1930519301
for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
1930619302
}
19307
- if( str_in_array(zOp, azGoto) && p2op<p->nIndent
19308
- && (abYield[p2op] || sqlite3_column_int(pSql, 2))
19309
- ){
19303
+ if( str_in_array(zOp, azGoto) && p2op<iOp && (abYield[p2op] || p1) ){
1931019304
for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
1931119305
}
1931219306
}
1931319307
1931419308
p->iIndent = 0;
@@ -19323,10 +19317,52 @@
1932319317
sqlite3_free(p->aiIndent);
1932419318
p->aiIndent = 0;
1932519319
p->nIndent = 0;
1932619320
p->iIndent = 0;
1932719321
}
19322
+
19323
+static void exec_prepared_stmt(ShellState*, sqlite3_stmt*);
19324
+
19325
+/*
19326
+** Display scan stats.
19327
+*/
19328
+static void display_scanstats(
19329
+ sqlite3 *db, /* Database to query */
19330
+ ShellState *pArg /* Pointer to ShellState */
19331
+){
19332
+#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
19333
+ UNUSED_PARAMETER(db);
19334
+ UNUSED_PARAMETER(pArg);
19335
+#else
19336
+ if( pArg->scanstatsOn==3 ){
19337
+ const char *zSql =
19338
+ " SELECT addr, opcode, p1, p2, p3, p4, p5, comment, nexec,"
19339
+ " round(ncycle*100.0 / (sum(ncycle) OVER ()), 2)||'%' AS cycles"
19340
+ " FROM bytecode(?)";
19341
+
19342
+ int rc = SQLITE_OK;
19343
+ sqlite3_stmt *pStmt = 0;
19344
+ rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
19345
+ if( rc==SQLITE_OK ){
19346
+ sqlite3_stmt *pSave = pArg->pStmt;
19347
+ pArg->pStmt = pStmt;
19348
+ sqlite3_bind_pointer(pStmt, 1, pSave, "stmt-pointer", 0);
19349
+
19350
+ pArg->cnt = 0;
19351
+ pArg->cMode = MODE_ScanExp;
19352
+ explain_data_prepare(pArg, pStmt);
19353
+ exec_prepared_stmt(pArg, pStmt);
19354
+ explain_data_delete(pArg);
19355
+
19356
+ sqlite3_finalize(pStmt);
19357
+ pArg->pStmt = pSave;
19358
+ }
19359
+ }else{
19360
+ display_explain_scanstats(db, pArg);
19361
+ }
19362
+#endif
19363
+}
1932819364
1932919365
/*
1933019366
** Disable and restore .wheretrace and .treetrace/.selecttrace settings.
1933119367
*/
1933219368
static unsigned int savedSelectTrace;
@@ -20113,20 +20149,19 @@
2011320149
}
2011420150
2011520151
/* Show the EXPLAIN QUERY PLAN if .eqp is on */
2011620152
if( pArg && pArg->autoEQP && sqlite3_stmt_isexplain(pStmt)==0 ){
2011720153
sqlite3_stmt *pExplain;
20118
- char *zEQP;
2011920154
int triggerEQP = 0;
2012020155
disable_debug_trace_modes();
2012120156
sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, -1, &triggerEQP);
2012220157
if( pArg->autoEQP>=AUTOEQP_trigger ){
2012320158
sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 1, 0);
2012420159
}
20125
- zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql);
20126
- shell_check_oom(zEQP);
20127
- rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
20160
+ pExplain = pStmt;
20161
+ sqlite3_reset(pExplain);
20162
+ rc = sqlite3_stmt_explain(pExplain, 2);
2012820163
if( rc==SQLITE_OK ){
2012920164
while( sqlite3_step(pExplain)==SQLITE_ROW ){
2013020165
const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3);
2013120166
int iEqpId = sqlite3_column_int(pExplain, 0);
2013220167
int iParentId = sqlite3_column_int(pExplain, 1);
@@ -20134,50 +20169,45 @@
2013420169
if( zEQPLine[0]=='-' ) eqp_render(pArg, 0);
2013520170
eqp_append(pArg, iEqpId, iParentId, zEQPLine);
2013620171
}
2013720172
eqp_render(pArg, 0);
2013820173
}
20139
- sqlite3_finalize(pExplain);
20140
- sqlite3_free(zEQP);
2014120174
if( pArg->autoEQP>=AUTOEQP_full ){
2014220175
/* Also do an EXPLAIN for ".eqp full" mode */
20143
- zEQP = sqlite3_mprintf("EXPLAIN %s", zStmtSql);
20144
- shell_check_oom(zEQP);
20145
- rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
20176
+ sqlite3_reset(pExplain);
20177
+ rc = sqlite3_stmt_explain(pExplain, 1);
2014620178
if( rc==SQLITE_OK ){
2014720179
pArg->cMode = MODE_Explain;
20180
+ assert( sqlite3_stmt_isexplain(pExplain)==1 );
2014820181
explain_data_prepare(pArg, pExplain);
2014920182
exec_prepared_stmt(pArg, pExplain);
2015020183
explain_data_delete(pArg);
2015120184
}
20152
- sqlite3_finalize(pExplain);
20153
- sqlite3_free(zEQP);
2015420185
}
2015520186
if( pArg->autoEQP>=AUTOEQP_trigger && triggerEQP==0 ){
2015620187
sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 0, 0);
20157
- /* Reprepare pStmt before reactivating trace modes */
20158
- sqlite3_finalize(pStmt);
20159
- sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
20160
- if( pArg ) pArg->pStmt = pStmt;
2016120188
}
20189
+ sqlite3_reset(pStmt);
20190
+ sqlite3_stmt_explain(pStmt, 0);
2016220191
restore_debug_trace_modes();
2016320192
}
2016420193
2016520194
if( pArg ){
20195
+ int bIsExplain = (sqlite3_stmt_isexplain(pStmt)==1);
2016620196
pArg->cMode = pArg->mode;
2016720197
if( pArg->autoExplain ){
20168
- if( sqlite3_stmt_isexplain(pStmt)==1 ){
20198
+ if( bIsExplain ){
2016920199
pArg->cMode = MODE_Explain;
2017020200
}
2017120201
if( sqlite3_stmt_isexplain(pStmt)==2 ){
2017220202
pArg->cMode = MODE_EQP;
2017320203
}
2017420204
}
2017520205
2017620206
/* If the shell is currently in ".explain" mode, gather the extra
2017720207
** data required to add indents to the output.*/
20178
- if( pArg->cMode==MODE_Explain ){
20208
+ if( pArg->cMode==MODE_Explain && bIsExplain ){
2017920209
explain_data_prepare(pArg, pStmt);
2018020210
}
2018120211
}
2018220212
2018320213
bind_prepared_stmt(pArg, pStmt);
@@ -25714,10 +25744,13 @@
2571425744
}else
2571525745
#endif /* !defined(SQLITE_SHELL_FIDDLE) */
2571625746
2571725747
if( c=='s' && cli_strncmp(azArg[0], "scanstats", n)==0 ){
2571825748
if( nArg==2 ){
25749
+ if( cli_strcmp(azArg[1], "vm")==0 ){
25750
+ p->scanstatsOn = 3;
25751
+ }else
2571925752
if( cli_strcmp(azArg[1], "est")==0 ){
2572025753
p->scanstatsOn = 2;
2572125754
}else{
2572225755
p->scanstatsOn = (u8)booleanValue(azArg[1]);
2572325756
}
2572425757
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -17388,10 +17388,11 @@
17388 #define MODE_Markdown 14 /* Markdown formatting */
17389 #define MODE_Table 15 /* MySQL-style table formatting */
17390 #define MODE_Box 16 /* Unicode box-drawing characters */
17391 #define MODE_Count 17 /* Output only a count of the rows of output */
17392 #define MODE_Off 18 /* No query output shown */
 
17393
17394 static const char *modeDescr[] = {
17395 "line",
17396 "column",
17397 "list",
@@ -18301,42 +18302,62 @@
18301 utf8_printf(p->out,"%*s = %s%s", w, azCol[i],
18302 azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
18303 }
18304 break;
18305 }
18306 case MODE_Explain: {
18307 static const int aExplainWidth[] = {4, 13, 4, 4, 4, 13, 2, 13};
18308 if( nArg>ArraySize(aExplainWidth) ){
18309 nArg = ArraySize(aExplainWidth);
18310 }
18311 if( p->cnt++==0 ){
18312 for(i=0; i<nArg; i++){
18313 int w = aExplainWidth[i];
18314 utf8_width_print(p->out, w, azCol[i]);
18315 fputs(i==nArg-1 ? "\n" : " ", p->out);
18316 }
18317 for(i=0; i<nArg; i++){
18318 int w = aExplainWidth[i];
18319 print_dashes(p->out, w);
18320 fputs(i==nArg-1 ? "\n" : " ", p->out);
18321 }
18322 }
18323 if( azArg==0 ) break;
18324 for(i=0; i<nArg; i++){
18325 int w = aExplainWidth[i];
18326 if( i==nArg-1 ) w = 0;
18327 if( azArg[i] && strlenChar(azArg[i])>w ){
18328 w = strlenChar(azArg[i]);
18329 }
18330 if( i==1 && p->aiIndent && p->pStmt ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18331 if( p->iIndent<p->nIndent ){
18332 utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
18333 }
18334 p->iIndent++;
18335 }
18336 utf8_width_print(p->out, w, azArg[i] ? azArg[i] : p->nullValue);
18337 fputs(i==nArg-1 ? "\n" : " ", p->out);
18338 }
18339 break;
18340 }
18341 case MODE_Semi: { /* .schema and .fullschema output */
18342 printSchemaLine(p->out, azArg[0], ";\n");
@@ -19113,21 +19134,15 @@
19113 }
19114 return ret;
19115 }
19116 #endif
19117
19118 /*
19119 ** Display scan stats.
19120 */
19121 static void display_scanstats(
19122 sqlite3 *db, /* Database to query */
19123 ShellState *pArg /* Pointer to ShellState */
19124 ){
19125 #ifndef SQLITE_ENABLE_STMT_SCANSTATUS
19126 UNUSED_PARAMETER(db);
19127 UNUSED_PARAMETER(pArg);
19128 #else
19129 static const int f = SQLITE_SCANSTAT_COMPLEX;
19130 sqlite3_stmt *p = pArg->pStmt;
19131 int ii = 0;
19132 i64 nTotal = 0;
19133 int nWidth = 0;
@@ -19195,12 +19210,13 @@
19195 eqp_append(pArg, iId, iPid, zText);
19196 sqlite3_free(zText);
19197 }
19198
19199 eqp_render(pArg, nTotal);
 
19200 #endif
19201 }
19202
19203 /*
19204 ** Parameter azArray points to a zero-terminated array of strings. zStr
19205 ** points to a single nul-terminated string. Return non-zero if zStr
19206 ** is equal, according to strcmp(), to any of the strings in the array.
@@ -19234,12 +19250,10 @@
19234 ** or if the P1 parameter is one instead of zero,
19235 ** then indent all opcodes between the earlier instruction
19236 ** and "Goto" by 2 spaces.
19237 */
19238 static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
19239 const char *zSql; /* The text of the SQL statement */
19240 const char *z; /* Used to check if this is an EXPLAIN */
19241 int *abYield = 0; /* True if op is an OP_Yield */
19242 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
19243 int iOp; /* Index of operation in p->aiIndent[] */
19244
19245 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
@@ -19246,69 +19260,49 @@
19246 "Return", 0 };
19247 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
19248 "Rewind", 0 };
19249 const char *azGoto[] = { "Goto", 0 };
19250
19251 /* Try to figure out if this is really an EXPLAIN statement. If this
19252 ** cannot be verified, return early. */
19253 if( sqlite3_column_count(pSql)!=8 ){
19254 p->cMode = p->mode;
19255 return;
19256 }
19257 zSql = sqlite3_sql(pSql);
19258 if( zSql==0 ) return;
19259 for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
19260 if( sqlite3_strnicmp(z, "explain", 7) ){
19261 p->cMode = p->mode;
19262 return;
19263 }
19264
19265 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
19266 int i;
19267 int iAddr = sqlite3_column_int(pSql, 0);
19268 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
19269
19270 /* Set p2 to the P2 field of the current opcode. Then, assuming that
19271 ** p2 is an instruction address, set variable p2op to the index of that
19272 ** instruction in the aiIndent[] array. p2 and p2op may be different if
19273 ** the current instruction is part of a sub-program generated by an
19274 ** SQL trigger or foreign key. */
19275 int p2 = sqlite3_column_int(pSql, 3);
 
 
 
 
 
19276 int p2op = (p2 + (iOp-iAddr));
19277
19278 /* Grow the p->aiIndent array as required */
19279 if( iOp>=nAlloc ){
19280 if( iOp==0 ){
19281 /* Do further verification that this is explain output. Abort if
19282 ** it is not */
19283 static const char *explainCols[] = {
19284 "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment" };
19285 int jj;
19286 for(jj=0; jj<ArraySize(explainCols); jj++){
19287 if( cli_strcmp(sqlite3_column_name(pSql,jj),explainCols[jj])!=0 ){
19288 p->cMode = p->mode;
19289 sqlite3_reset(pSql);
19290 return;
19291 }
19292 }
19293 }
19294 nAlloc += 100;
19295 p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
19296 shell_check_oom(p->aiIndent);
19297 abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
19298 shell_check_oom(abYield);
19299 }
 
19300 abYield[iOp] = str_in_array(zOp, azYield);
19301 p->aiIndent[iOp] = 0;
19302 p->nIndent = iOp+1;
19303
19304 if( str_in_array(zOp, azNext) && p2op>0 ){
19305 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
19306 }
19307 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
19308 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
19309 ){
19310 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
19311 }
19312 }
19313
19314 p->iIndent = 0;
@@ -19323,10 +19317,52 @@
19323 sqlite3_free(p->aiIndent);
19324 p->aiIndent = 0;
19325 p->nIndent = 0;
19326 p->iIndent = 0;
19327 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19328
19329 /*
19330 ** Disable and restore .wheretrace and .treetrace/.selecttrace settings.
19331 */
19332 static unsigned int savedSelectTrace;
@@ -20113,20 +20149,19 @@
20113 }
20114
20115 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
20116 if( pArg && pArg->autoEQP && sqlite3_stmt_isexplain(pStmt)==0 ){
20117 sqlite3_stmt *pExplain;
20118 char *zEQP;
20119 int triggerEQP = 0;
20120 disable_debug_trace_modes();
20121 sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, -1, &triggerEQP);
20122 if( pArg->autoEQP>=AUTOEQP_trigger ){
20123 sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 1, 0);
20124 }
20125 zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql);
20126 shell_check_oom(zEQP);
20127 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
20128 if( rc==SQLITE_OK ){
20129 while( sqlite3_step(pExplain)==SQLITE_ROW ){
20130 const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3);
20131 int iEqpId = sqlite3_column_int(pExplain, 0);
20132 int iParentId = sqlite3_column_int(pExplain, 1);
@@ -20134,50 +20169,45 @@
20134 if( zEQPLine[0]=='-' ) eqp_render(pArg, 0);
20135 eqp_append(pArg, iEqpId, iParentId, zEQPLine);
20136 }
20137 eqp_render(pArg, 0);
20138 }
20139 sqlite3_finalize(pExplain);
20140 sqlite3_free(zEQP);
20141 if( pArg->autoEQP>=AUTOEQP_full ){
20142 /* Also do an EXPLAIN for ".eqp full" mode */
20143 zEQP = sqlite3_mprintf("EXPLAIN %s", zStmtSql);
20144 shell_check_oom(zEQP);
20145 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
20146 if( rc==SQLITE_OK ){
20147 pArg->cMode = MODE_Explain;
 
20148 explain_data_prepare(pArg, pExplain);
20149 exec_prepared_stmt(pArg, pExplain);
20150 explain_data_delete(pArg);
20151 }
20152 sqlite3_finalize(pExplain);
20153 sqlite3_free(zEQP);
20154 }
20155 if( pArg->autoEQP>=AUTOEQP_trigger && triggerEQP==0 ){
20156 sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 0, 0);
20157 /* Reprepare pStmt before reactivating trace modes */
20158 sqlite3_finalize(pStmt);
20159 sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
20160 if( pArg ) pArg->pStmt = pStmt;
20161 }
 
 
20162 restore_debug_trace_modes();
20163 }
20164
20165 if( pArg ){
 
20166 pArg->cMode = pArg->mode;
20167 if( pArg->autoExplain ){
20168 if( sqlite3_stmt_isexplain(pStmt)==1 ){
20169 pArg->cMode = MODE_Explain;
20170 }
20171 if( sqlite3_stmt_isexplain(pStmt)==2 ){
20172 pArg->cMode = MODE_EQP;
20173 }
20174 }
20175
20176 /* If the shell is currently in ".explain" mode, gather the extra
20177 ** data required to add indents to the output.*/
20178 if( pArg->cMode==MODE_Explain ){
20179 explain_data_prepare(pArg, pStmt);
20180 }
20181 }
20182
20183 bind_prepared_stmt(pArg, pStmt);
@@ -25714,10 +25744,13 @@
25714 }else
25715 #endif /* !defined(SQLITE_SHELL_FIDDLE) */
25716
25717 if( c=='s' && cli_strncmp(azArg[0], "scanstats", n)==0 ){
25718 if( nArg==2 ){
 
 
 
25719 if( cli_strcmp(azArg[1], "est")==0 ){
25720 p->scanstatsOn = 2;
25721 }else{
25722 p->scanstatsOn = (u8)booleanValue(azArg[1]);
25723 }
25724
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -17388,10 +17388,11 @@
17388 #define MODE_Markdown 14 /* Markdown formatting */
17389 #define MODE_Table 15 /* MySQL-style table formatting */
17390 #define MODE_Box 16 /* Unicode box-drawing characters */
17391 #define MODE_Count 17 /* Output only a count of the rows of output */
17392 #define MODE_Off 18 /* No query output shown */
17393 #define MODE_ScanExp 19 /* Like MODE_Explain, but for ".scanstats vm" */
17394
17395 static const char *modeDescr[] = {
17396 "line",
17397 "column",
17398 "list",
@@ -18301,42 +18302,62 @@
18302 utf8_printf(p->out,"%*s = %s%s", w, azCol[i],
18303 azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
18304 }
18305 break;
18306 }
18307 case MODE_ScanExp:
18308 case MODE_Explain: {
18309 static const int aExplainWidth[] = {4, 13, 4, 4, 4, 13, 2, 13};
18310 static const int aExplainMap[] = {0, 1, 2, 3, 4, 5, 6, 7 };
18311 static const int aScanExpWidth[] = {4, 6, 6, 13, 4, 4, 4, 13, 2, 13};
18312 static const int aScanExpMap[] = {0, 9, 8, 1, 2, 3, 4, 5, 6, 7 };
18313
18314 const int *aWidth = aExplainWidth;
18315 const int *aMap = aExplainMap;
18316 int nWidth = ArraySize(aExplainWidth);
18317 int iIndent = 1;
18318
18319 if( p->cMode==MODE_ScanExp ){
18320 aWidth = aScanExpWidth;
18321 aMap = aScanExpMap;
18322 nWidth = ArraySize(aScanExpWidth);
18323 iIndent = 3;
18324 }
18325 if( nArg>nWidth ) nArg = nWidth;
18326
18327 /* If this is the first row seen, print out the headers */
18328 if( p->cnt++==0 ){
18329 for(i=0; i<nArg; i++){
18330 utf8_width_print(p->out, aWidth[i], azCol[ aMap[i] ]);
18331 fputs(i==nArg-1 ? "\n" : " ", p->out);
18332 }
18333 for(i=0; i<nArg; i++){
18334 print_dashes(p->out, aWidth[i]);
18335 fputs(i==nArg-1 ? "\n" : " ", p->out);
18336 }
18337 }
18338
18339 /* If there is no data, exit early. */
18340 if( azArg==0 ) break;
18341
18342 for(i=0; i<nArg; i++){
18343 const char *zSep = " ";
18344 int w = aWidth[i];
18345 const char *zVal = azArg[ aMap[i] ];
18346 if( i==nArg-1 ) w = 0;
18347 if( zVal && strlenChar(zVal)>w ){
18348 w = strlenChar(zVal);
18349 zSep = " ";
18350 }
18351 if( i==iIndent && p->aiIndent && p->pStmt ){
18352 if( p->iIndent<p->nIndent ){
18353 utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
18354 }
18355 p->iIndent++;
18356 }
18357 utf8_width_print(p->out, w, zVal ? zVal : p->nullValue);
18358 fputs(i==nArg-1 ? "\n" : zSep, p->out);
18359 }
18360 break;
18361 }
18362 case MODE_Semi: { /* .schema and .fullschema output */
18363 printSchemaLine(p->out, azArg[0], ";\n");
@@ -19113,21 +19134,15 @@
19134 }
19135 return ret;
19136 }
19137 #endif
19138
19139 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
19140 static void display_explain_scanstats(
 
 
19141 sqlite3 *db, /* Database to query */
19142 ShellState *pArg /* Pointer to ShellState */
19143 ){
 
 
 
 
19144 static const int f = SQLITE_SCANSTAT_COMPLEX;
19145 sqlite3_stmt *p = pArg->pStmt;
19146 int ii = 0;
19147 i64 nTotal = 0;
19148 int nWidth = 0;
@@ -19195,12 +19210,13 @@
19210 eqp_append(pArg, iId, iPid, zText);
19211 sqlite3_free(zText);
19212 }
19213
19214 eqp_render(pArg, nTotal);
19215 }
19216 #endif
19217
19218
19219 /*
19220 ** Parameter azArray points to a zero-terminated array of strings. zStr
19221 ** points to a single nul-terminated string. Return non-zero if zStr
19222 ** is equal, according to strcmp(), to any of the strings in the array.
@@ -19234,12 +19250,10 @@
19250 ** or if the P1 parameter is one instead of zero,
19251 ** then indent all opcodes between the earlier instruction
19252 ** and "Goto" by 2 spaces.
19253 */
19254 static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
 
 
19255 int *abYield = 0; /* True if op is an OP_Yield */
19256 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
19257 int iOp; /* Index of operation in p->aiIndent[] */
19258
19259 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
@@ -19246,69 +19260,49 @@
19260 "Return", 0 };
19261 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
19262 "Rewind", 0 };
19263 const char *azGoto[] = { "Goto", 0 };
19264
19265 /* The caller guarantees that the leftmost 4 columns of the statement
19266 ** passed to this function are equivalent to the leftmost 4 columns
19267 ** of EXPLAIN statement output. In practice the statement may be
19268 ** an EXPLAIN, or it may be a query on the bytecode() virtual table. */
19269 assert( sqlite3_column_count(pSql)>=4 );
19270 assert( 0==sqlite3_stricmp( sqlite3_column_name(pSql, 0), "addr" ) );
19271 assert( 0==sqlite3_stricmp( sqlite3_column_name(pSql, 1), "opcode" ) );
19272 assert( 0==sqlite3_stricmp( sqlite3_column_name(pSql, 2), "p1" ) );
19273 assert( 0==sqlite3_stricmp( sqlite3_column_name(pSql, 3), "p2" ) );
 
 
 
 
19274
19275 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
19276 int i;
19277 int iAddr = sqlite3_column_int(pSql, 0);
19278 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
19279 int p1 = sqlite3_column_int(pSql, 2);
 
 
 
 
 
19280 int p2 = sqlite3_column_int(pSql, 3);
19281
19282 /* Assuming that p2 is an instruction address, set variable p2op to the
19283 ** index of that instruction in the aiIndent[] array. p2 and p2op may be
19284 ** different if the current instruction is part of a sub-program generated
19285 ** by an SQL trigger or foreign key. */
19286 int p2op = (p2 + (iOp-iAddr));
19287
19288 /* Grow the p->aiIndent array as required */
19289 if( iOp>=nAlloc ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19290 nAlloc += 100;
19291 p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
19292 shell_check_oom(p->aiIndent);
19293 abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
19294 shell_check_oom(abYield);
19295 }
19296
19297 abYield[iOp] = str_in_array(zOp, azYield);
19298 p->aiIndent[iOp] = 0;
19299 p->nIndent = iOp+1;
 
19300 if( str_in_array(zOp, azNext) && p2op>0 ){
19301 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
19302 }
19303 if( str_in_array(zOp, azGoto) && p2op<iOp && (abYield[p2op] || p1) ){
 
 
19304 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
19305 }
19306 }
19307
19308 p->iIndent = 0;
@@ -19323,10 +19317,52 @@
19317 sqlite3_free(p->aiIndent);
19318 p->aiIndent = 0;
19319 p->nIndent = 0;
19320 p->iIndent = 0;
19321 }
19322
19323 static void exec_prepared_stmt(ShellState*, sqlite3_stmt*);
19324
19325 /*
19326 ** Display scan stats.
19327 */
19328 static void display_scanstats(
19329 sqlite3 *db, /* Database to query */
19330 ShellState *pArg /* Pointer to ShellState */
19331 ){
19332 #ifndef SQLITE_ENABLE_STMT_SCANSTATUS
19333 UNUSED_PARAMETER(db);
19334 UNUSED_PARAMETER(pArg);
19335 #else
19336 if( pArg->scanstatsOn==3 ){
19337 const char *zSql =
19338 " SELECT addr, opcode, p1, p2, p3, p4, p5, comment, nexec,"
19339 " round(ncycle*100.0 / (sum(ncycle) OVER ()), 2)||'%' AS cycles"
19340 " FROM bytecode(?)";
19341
19342 int rc = SQLITE_OK;
19343 sqlite3_stmt *pStmt = 0;
19344 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
19345 if( rc==SQLITE_OK ){
19346 sqlite3_stmt *pSave = pArg->pStmt;
19347 pArg->pStmt = pStmt;
19348 sqlite3_bind_pointer(pStmt, 1, pSave, "stmt-pointer", 0);
19349
19350 pArg->cnt = 0;
19351 pArg->cMode = MODE_ScanExp;
19352 explain_data_prepare(pArg, pStmt);
19353 exec_prepared_stmt(pArg, pStmt);
19354 explain_data_delete(pArg);
19355
19356 sqlite3_finalize(pStmt);
19357 pArg->pStmt = pSave;
19358 }
19359 }else{
19360 display_explain_scanstats(db, pArg);
19361 }
19362 #endif
19363 }
19364
19365 /*
19366 ** Disable and restore .wheretrace and .treetrace/.selecttrace settings.
19367 */
19368 static unsigned int savedSelectTrace;
@@ -20113,20 +20149,19 @@
20149 }
20150
20151 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
20152 if( pArg && pArg->autoEQP && sqlite3_stmt_isexplain(pStmt)==0 ){
20153 sqlite3_stmt *pExplain;
 
20154 int triggerEQP = 0;
20155 disable_debug_trace_modes();
20156 sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, -1, &triggerEQP);
20157 if( pArg->autoEQP>=AUTOEQP_trigger ){
20158 sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 1, 0);
20159 }
20160 pExplain = pStmt;
20161 sqlite3_reset(pExplain);
20162 rc = sqlite3_stmt_explain(pExplain, 2);
20163 if( rc==SQLITE_OK ){
20164 while( sqlite3_step(pExplain)==SQLITE_ROW ){
20165 const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3);
20166 int iEqpId = sqlite3_column_int(pExplain, 0);
20167 int iParentId = sqlite3_column_int(pExplain, 1);
@@ -20134,50 +20169,45 @@
20169 if( zEQPLine[0]=='-' ) eqp_render(pArg, 0);
20170 eqp_append(pArg, iEqpId, iParentId, zEQPLine);
20171 }
20172 eqp_render(pArg, 0);
20173 }
 
 
20174 if( pArg->autoEQP>=AUTOEQP_full ){
20175 /* Also do an EXPLAIN for ".eqp full" mode */
20176 sqlite3_reset(pExplain);
20177 rc = sqlite3_stmt_explain(pExplain, 1);
 
20178 if( rc==SQLITE_OK ){
20179 pArg->cMode = MODE_Explain;
20180 assert( sqlite3_stmt_isexplain(pExplain)==1 );
20181 explain_data_prepare(pArg, pExplain);
20182 exec_prepared_stmt(pArg, pExplain);
20183 explain_data_delete(pArg);
20184 }
 
 
20185 }
20186 if( pArg->autoEQP>=AUTOEQP_trigger && triggerEQP==0 ){
20187 sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 0, 0);
 
 
 
 
20188 }
20189 sqlite3_reset(pStmt);
20190 sqlite3_stmt_explain(pStmt, 0);
20191 restore_debug_trace_modes();
20192 }
20193
20194 if( pArg ){
20195 int bIsExplain = (sqlite3_stmt_isexplain(pStmt)==1);
20196 pArg->cMode = pArg->mode;
20197 if( pArg->autoExplain ){
20198 if( bIsExplain ){
20199 pArg->cMode = MODE_Explain;
20200 }
20201 if( sqlite3_stmt_isexplain(pStmt)==2 ){
20202 pArg->cMode = MODE_EQP;
20203 }
20204 }
20205
20206 /* If the shell is currently in ".explain" mode, gather the extra
20207 ** data required to add indents to the output.*/
20208 if( pArg->cMode==MODE_Explain && bIsExplain ){
20209 explain_data_prepare(pArg, pStmt);
20210 }
20211 }
20212
20213 bind_prepared_stmt(pArg, pStmt);
@@ -25714,10 +25744,13 @@
25744 }else
25745 #endif /* !defined(SQLITE_SHELL_FIDDLE) */
25746
25747 if( c=='s' && cli_strncmp(azArg[0], "scanstats", n)==0 ){
25748 if( nArg==2 ){
25749 if( cli_strcmp(azArg[1], "vm")==0 ){
25750 p->scanstatsOn = 3;
25751 }else
25752 if( cli_strcmp(azArg[1], "est")==0 ){
25753 p->scanstatsOn = 2;
25754 }else{
25755 p->scanstatsOn = (u8)booleanValue(azArg[1]);
25756 }
25757
+2731 -673
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -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
-** 7d95ed60f0a17ea13b4bc19c2ab2ec9052f.
21
+** a0b9aecbaca9a8e784fd2bcb50f78cbdcf4.
2222
*/
2323
#define SQLITE_CORE 1
2424
#define SQLITE_AMALGAMATION 1
2525
#ifndef SQLITE_PRIVATE
2626
# define SQLITE_PRIVATE static
@@ -459,11 +459,11 @@
459459
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
460460
** [sqlite_version()] and [sqlite_source_id()].
461461
*/
462462
#define SQLITE_VERSION "3.43.0"
463463
#define SQLITE_VERSION_NUMBER 3043000
464
-#define SQLITE_SOURCE_ID "2023-07-08 17:42:24 07d95ed60f0a17ea13b4bc19c2ab2ec9052fedd27c9e1e57a1ec6e3a6470e5b7"
464
+#define SQLITE_SOURCE_ID "2023-08-02 16:06:02 ea0b9aecbaca9a8e784fd2bcb50f78cbdcf4c5cfb45a7700bb222e4cc104c644"
465465
466466
/*
467467
** CAPI3REF: Run-Time Library Version Numbers
468468
** KEYWORDS: sqlite3_version sqlite3_sourceid
469469
**
@@ -4732,10 +4732,45 @@
47324732
** ^The sqlite3_stmt_isexplain(S) interface returns 0 if S is
47334733
** an ordinary statement or a NULL pointer.
47344734
*/
47354735
SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt);
47364736
4737
+/*
4738
+** CAPI3REF: Change The EXPLAIN Setting For A Prepared Statement
4739
+** METHOD: sqlite3_stmt
4740
+**
4741
+** The sqlite3_stmt_explain(S,E) interface changes the EXPLAIN
4742
+** setting for [prepared statement] S. If E is zero, then S becomes
4743
+** a normal prepared statement. If E is 1, then S behaves as if
4744
+** its SQL text began with "[EXPLAIN]". If E is 2, then S behaves as if
4745
+** its SQL text began with "[EXPLAIN QUERY PLAN]".
4746
+**
4747
+** Calling sqlite3_stmt_explain(S,E) might cause S to be reprepared.
4748
+** SQLite tries to avoid a reprepare, but a reprepare might be necessary
4749
+** on the first transition into EXPLAIN or EXPLAIN QUERY PLAN mode.
4750
+**
4751
+** Because of the potential need to reprepare, a call to
4752
+** sqlite3_stmt_explain(S,E) will fail with SQLITE_ERROR if S cannot be
4753
+** reprepared because it was created using [sqlite3_prepare()] instead of
4754
+** the newer [sqlite3_prepare_v2()] or [sqlite3_prepare_v3()] interfaces and
4755
+** hence has no saved SQL text with which to reprepare.
4756
+**
4757
+** Changing the explain setting for a prepared statement does not change
4758
+** the original SQL text for the statement. Hence, if the SQL text originally
4759
+** began with EXPLAIN or EXPLAIN QUERY PLAN, but sqlite3_stmt_explain(S,0)
4760
+** is called to convert the statement into an ordinary statement, the EXPLAIN
4761
+** or EXPLAIN QUERY PLAN keywords will still appear in the sqlite3_sql(S)
4762
+** output, even though the statement now acts like a normal SQL statement.
4763
+**
4764
+** This routine returns SQLITE_OK if the explain mode is successfully
4765
+** changed, or an error code if the explain mode could not be changed.
4766
+** The explain mode cannot be changed while a statement is active.
4767
+** Hence, it is good practice to call [sqlite3_reset(S)]
4768
+** immediately prior to calling sqlite3_stmt_explain(S,E).
4769
+*/
4770
+SQLITE_API int sqlite3_stmt_explain(sqlite3_stmt *pStmt, int eMode);
4771
+
47374772
/*
47384773
** CAPI3REF: Determine If A Prepared Statement Has Been Reset
47394774
** METHOD: sqlite3_stmt
47404775
**
47414776
** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the
@@ -14590,12 +14625,35 @@
1459014625
**
1459114626
** In other words, S is a buffer and E is a pointer to the first byte after
1459214627
** the end of buffer S. This macro returns true if P points to something
1459314628
** contained within the buffer S.
1459414629
*/
14595
-#define SQLITE_WITHIN(P,S,E) (((uptr)(P)>=(uptr)(S))&&((uptr)(P)<(uptr)(E)))
14630
+#define SQLITE_WITHIN(P,S,E) (((uptr)(P)>=(uptr)(S))&&((uptr)(P)<(uptr)(E)))
1459614631
14632
+/*
14633
+** P is one byte past the end of a large buffer. Return true if a span of bytes
14634
+** between S..E crosses the end of that buffer. In other words, return true
14635
+** if the sub-buffer S..E-1 overflows the buffer show last byte is P-1.
14636
+**
14637
+** S is the start of the span. E is one byte past the end of end of span.
14638
+**
14639
+** P
14640
+** |-----------------| FALSE
14641
+** |-------|
14642
+** S E
14643
+**
14644
+** P
14645
+** |-----------------|
14646
+** |-------| TRUE
14647
+** S E
14648
+**
14649
+** P
14650
+** |-----------------|
14651
+** |-------| FALSE
14652
+** S E
14653
+*/
14654
+#define SQLITE_OVERFLOW(P,S,E) (((uptr)(S)<(uptr)(P))&&((uptr)(E)>(uptr)(P)))
1459714655
1459814656
/*
1459914657
** Macros to determine whether the machine is big or little endian,
1460014658
** and whether or not that determination is run-time or compile-time.
1460114659
**
@@ -14959,10 +15017,11 @@
1495915017
typedef struct OnOrUsing OnOrUsing;
1496015018
typedef struct Parse Parse;
1496115019
typedef struct ParseCleanup ParseCleanup;
1496215020
typedef struct PreUpdate PreUpdate;
1496315021
typedef struct PrintfArguments PrintfArguments;
15022
+typedef struct RCStr RCStr;
1496415023
typedef struct RenameToken RenameToken;
1496515024
typedef struct Returning Returning;
1496615025
typedef struct RowSet RowSet;
1496715026
typedef struct Savepoint Savepoint;
1496815027
typedef struct Select Select;
@@ -15925,13 +15984,11 @@
1592515984
SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*);
1592615985
SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int flags);
1592715986
SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor*);
1592815987
SQLITE_PRIVATE void sqlite3BtreeCursorPin(BtCursor*);
1592915988
SQLITE_PRIVATE void sqlite3BtreeCursorUnpin(BtCursor*);
15930
-#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
1593115989
SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor*);
15932
-#endif
1593315990
SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*);
1593415991
SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt);
1593515992
SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor*);
1593615993
SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor*);
1593715994
@@ -17469,10 +17526,11 @@
1746917526
#define SQLITE_FlttnUnionAll 0x00800000 /* Disable the UNION ALL flattener */
1747017527
/* TH3 expects this value ^^^^^^^^^^ See flatten04.test */
1747117528
#define SQLITE_IndexedExpr 0x01000000 /* Pull exprs from index when able */
1747217529
#define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */
1747317530
#define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */
17531
+#define SQLITE_OnePass 0x08000000 /* Single-pass DELETE and UPDATE */
1747417532
#define SQLITE_AllOpts 0xffffffff /* All optimizations */
1747517533
1747617534
/*
1747717535
** Macros for testing whether or not optimizations are enabled or disabled.
1747817536
*/
@@ -19385,11 +19443,11 @@
1938519443
ParseCleanup *pCleanup; /* List of cleanup operations to run after parse */
1938619444
union {
1938719445
int addrCrTab; /* Address of OP_CreateBtree on CREATE TABLE */
1938819446
Returning *pReturning; /* The RETURNING clause */
1938919447
} u1;
19390
- u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */
19448
+ LogEst nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */
1939119449
u32 oldmask; /* Mask of old.* columns referenced */
1939219450
u32 newmask; /* Mask of new.* columns referenced */
1939319451
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
1939419452
u32 nProgressSteps; /* xProgress steps taken during sqlite3_prepare() */
1939519453
#endif
@@ -19657,10 +19715,29 @@
1965719715
#define SQLITE_PRINTF_SQLFUNC 0x02 /* SQL function arguments to VXPrintf */
1965819716
#define SQLITE_PRINTF_MALLOCED 0x04 /* True if xText is allocated space */
1965919717
1966019718
#define isMalloced(X) (((X)->printfFlags & SQLITE_PRINTF_MALLOCED)!=0)
1966119719
19720
+/*
19721
+** The following object is the header for an "RCStr" or "reference-counted
19722
+** string". An RCStr is passed around and used like any other char*
19723
+** that has been dynamically allocated. The important interface
19724
+** differences:
19725
+**
19726
+** 1. RCStr strings are reference counted. They are deallocated
19727
+** when the reference count reaches zero.
19728
+**
19729
+** 2. Use sqlite3RCStrUnref() to free an RCStr string rather than
19730
+** sqlite3_free()
19731
+**
19732
+** 3. Make a (read-only) copy of a read-only RCStr string using
19733
+** sqlite3RCStrRef().
19734
+*/
19735
+struct RCStr {
19736
+ u64 nRCRef; /* Number of references */
19737
+ /* Total structure size should be a multiple of 8 bytes for alignment */
19738
+};
1966219739
1966319740
/*
1966419741
** A pointer to this structure is used to communicate information
1966519742
** from sqlite3Init and OP_ParseSchema into the sqlite3InitCallback.
1966619743
*/
@@ -20776,10 +20853,11 @@
2077620853
# define sqlite3FileSuffix3(X,Y)
2077720854
#endif
2077820855
SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z,u8);
2077920856
2078020857
SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8);
20858
+SQLITE_PRIVATE int sqlite3ValueIsOfClass(const sqlite3_value*, void(*)(void*));
2078120859
SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8);
2078220860
SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
2078320861
void(*)(void*));
2078420862
SQLITE_PRIVATE void sqlite3ValueSetNull(sqlite3_value*);
2078520863
SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*);
@@ -20883,10 +20961,15 @@
2088320961
SQLITE_PRIVATE void *sqlite3OomFault(sqlite3*);
2088420962
SQLITE_PRIVATE void sqlite3OomClear(sqlite3*);
2088520963
SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int);
2088620964
SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *);
2088720965
20966
+SQLITE_PRIVATE char *sqlite3RCStrRef(char*);
20967
+SQLITE_PRIVATE void sqlite3RCStrUnref(char*);
20968
+SQLITE_PRIVATE char *sqlite3RCStrNew(u64);
20969
+SQLITE_PRIVATE char *sqlite3RCStrResize(char*,u64);
20970
+
2088820971
SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int);
2088920972
SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum*, i64);
2089020973
SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*);
2089120974
SQLITE_PRIVATE void sqlite3StrAccumSetError(StrAccum*, u8);
2089220975
SQLITE_PRIVATE void sqlite3ResultStrAccum(sqlite3_context*,StrAccum*);
@@ -22623,10 +22706,13 @@
2262322706
typedef struct VdbeSorter VdbeSorter;
2262422707
2262522708
/* Elements of the linked list at Vdbe.pAuxData */
2262622709
typedef struct AuxData AuxData;
2262722710
22711
+/* A cache of large TEXT or BLOB values in a VdbeCursor */
22712
+typedef struct VdbeTxtBlbCache VdbeTxtBlbCache;
22713
+
2262822714
/* Types of VDBE cursors */
2262922715
#define CURTYPE_BTREE 0
2263022716
#define CURTYPE_SORTER 1
2263122717
#define CURTYPE_VTAB 2
2263222718
#define CURTYPE_PSEUDO 3
@@ -22654,10 +22740,11 @@
2265422740
#endif
2265522741
Bool isEphemeral:1; /* True for an ephemeral table */
2265622742
Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */
2265722743
Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */
2265822744
Bool noReuse:1; /* OpenEphemeral may not reuse this cursor */
22745
+ Bool colCache:1; /* pCache pointer is initialized and non-NULL */
2265922746
u16 seekHit; /* See the OP_SeekHit and OP_IfNoHope opcodes */
2266022747
union { /* pBtx for isEphermeral. pAltMap otherwise */
2266122748
Btree *pBtx; /* Separate file holding temporary table */
2266222749
u32 *aAltMap; /* Mapping from table to index column numbers */
2266322750
} ub;
@@ -22694,10 +22781,11 @@
2269422781
u32 payloadSize; /* Total number of bytes in the record */
2269522782
u32 szRow; /* Byte available in aRow */
2269622783
#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
2269722784
u64 maskUsed; /* Mask of columns used by this cursor */
2269822785
#endif
22786
+ VdbeTxtBlbCache *pCache; /* Cache of large TEXT or BLOB values */
2269922787
2270022788
/* 2*nField extra array elements allocated for aType[], beyond the one
2270122789
** static element declared in the structure. nField total array slots for
2270222790
** aType[] and nField+1 array slots for aOffset[] */
2270322791
u32 aType[1]; /* Type values record decode. MUST BE LAST */
@@ -22706,15 +22794,28 @@
2270622794
/* Return true if P is a null-only cursor
2270722795
*/
2270822796
#define IsNullCursor(P) \
2270922797
((P)->eCurType==CURTYPE_PSEUDO && (P)->nullRow && (P)->seekResult==0)
2271022798
22711
-
2271222799
/*
2271322800
** A value for VdbeCursor.cacheStatus that means the cache is always invalid.
2271422801
*/
2271522802
#define CACHE_STALE 0
22803
+
22804
+/*
22805
+** Large TEXT or BLOB values can be slow to load, so we want to avoid
22806
+** loading them more than once. For that reason, large TEXT and BLOB values
22807
+** can be stored in a cache defined by this object, and attached to the
22808
+** VdbeCursor using the pCache field.
22809
+*/
22810
+struct VdbeTxtBlbCache {
22811
+ char *pCValue; /* A RCStr buffer to hold the value */
22812
+ i64 iOffset; /* File offset of the row being cached */
22813
+ int iCol; /* Column for which the cache is valid */
22814
+ u32 cacheStatus; /* Vdbe.cacheCtr value */
22815
+ u32 colCacheCtr; /* Column cache counter */
22816
+};
2271622817
2271722818
/*
2271822819
** When a sub-program is executed (OP_Program), a structure of this type
2271922820
** is allocated to store the current value of the program counter, as
2272022821
** well as the current memory cell array and various other frame specific
@@ -23032,20 +23133,22 @@
2303223133
#ifdef SQLITE_DEBUG
2303323134
int rcApp; /* errcode set by sqlite3_result_error_code() */
2303423135
u32 nWrite; /* Number of write operations that have occurred */
2303523136
#endif
2303623137
u16 nResColumn; /* Number of columns in one row of the result set */
23138
+ u16 nResAlloc; /* Column slots allocated to aColName[] */
2303723139
u8 errorAction; /* Recovery action to do in case of an error */
2303823140
u8 minWriteFileFormat; /* Minimum file format for writable database files */
2303923141
u8 prepFlags; /* SQLITE_PREPARE_* flags */
2304023142
u8 eVdbeState; /* On of the VDBE_*_STATE values */
2304123143
bft expired:2; /* 1: recompile VM immediately 2: when convenient */
23042
- bft explain:2; /* True if EXPLAIN present on SQL command */
23144
+ bft explain:2; /* 0: normal, 1: EXPLAIN, 2: EXPLAIN QUERY PLAN */
2304323145
bft changeCntOn:1; /* True to update the change-counter */
2304423146
bft usesStmtJournal:1; /* True if uses a statement journal */
2304523147
bft readOnly:1; /* True for statements that do not write */
2304623148
bft bIsReader:1; /* True for statements that read */
23149
+ bft haveEqpOps:1; /* Bytecode supports EXPLAIN QUERY PLAN */
2304723150
yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
2304823151
yDbMask lockMask; /* Subset of btreeMask that requires a lock */
2304923152
u32 aCounter[9]; /* Counters used by sqlite3_stmt_status() */
2305023153
char *zSql; /* Text of the SQL statement that generated this */
2305123154
#ifdef SQLITE_ENABLE_NORMALIZE
@@ -23178,10 +23281,11 @@
2317823281
#endif
2317923282
#ifdef SQLITE_DEBUG
2318023283
SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem*);
2318123284
#endif
2318223285
SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem*);
23286
+SQLITE_PRIVATE void sqlite3VdbeMemZeroTerminateIfAble(Mem*);
2318323287
SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*);
2318423288
SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8);
2318523289
SQLITE_PRIVATE int sqlite3IntFloatCompare(i64,double);
2318623290
SQLITE_PRIVATE i64 sqlite3VdbeIntValue(const Mem*);
2318723291
SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*);
@@ -31698,10 +31802,79 @@
3169831802
va_start(ap,zFormat);
3169931803
sqlite3_str_vappendf(p, zFormat, ap);
3170031804
va_end(ap);
3170131805
}
3170231806
31807
+
31808
+/*****************************************************************************
31809
+** Reference counted string storage
31810
+*****************************************************************************/
31811
+
31812
+/*
31813
+** Increase the reference count of the string by one.
31814
+**
31815
+** The input parameter is returned.
31816
+*/
31817
+SQLITE_PRIVATE char *sqlite3RCStrRef(char *z){
31818
+ RCStr *p = (RCStr*)z;
31819
+ assert( p!=0 );
31820
+ p--;
31821
+ p->nRCRef++;
31822
+ return z;
31823
+}
31824
+
31825
+/*
31826
+** Decrease the reference count by one. Free the string when the
31827
+** reference count reaches zero.
31828
+*/
31829
+SQLITE_PRIVATE void sqlite3RCStrUnref(char *z){
31830
+ RCStr *p = (RCStr*)z;
31831
+ assert( p!=0 );
31832
+ p--;
31833
+ assert( p->nRCRef>0 );
31834
+ if( p->nRCRef>=2 ){
31835
+ p->nRCRef--;
31836
+ }else{
31837
+ sqlite3_free(p);
31838
+ }
31839
+}
31840
+
31841
+/*
31842
+** Create a new string that is capable of holding N bytes of text, not counting
31843
+** the zero byte at the end. The string is uninitialized.
31844
+**
31845
+** The reference count is initially 1. Call sqlite3RCStrUnref() to free the
31846
+** newly allocated string.
31847
+**
31848
+** This routine returns 0 on an OOM.
31849
+*/
31850
+SQLITE_PRIVATE char *sqlite3RCStrNew(u64 N){
31851
+ RCStr *p = sqlite3_malloc64( N + sizeof(*p) + 1 );
31852
+ if( p==0 ) return 0;
31853
+ p->nRCRef = 1;
31854
+ return (char*)&p[1];
31855
+}
31856
+
31857
+/*
31858
+** Change the size of the string so that it is able to hold N bytes.
31859
+** The string might be reallocated, so return the new allocation.
31860
+*/
31861
+SQLITE_PRIVATE char *sqlite3RCStrResize(char *z, u64 N){
31862
+ RCStr *p = (RCStr*)z;
31863
+ RCStr *pNew;
31864
+ assert( p!=0 );
31865
+ p--;
31866
+ assert( p->nRCRef==1 );
31867
+ pNew = sqlite3_realloc64(p, N+sizeof(RCStr)+1);
31868
+ if( pNew==0 ){
31869
+ sqlite3_free(p);
31870
+ return 0;
31871
+ }else{
31872
+ return (char*)&pNew[1];
31873
+ }
31874
+}
31875
+
3170331876
/************** End of printf.c **********************************************/
3170431877
/************** Begin file treeview.c ****************************************/
3170531878
/*
3170631879
** 2015-06-08
3170731880
**
@@ -34572,11 +34745,16 @@
3457234745
}else{
3457334746
while( e<=-100 ){ e+=100; r *= 1.0e-100L; }
3457434747
while( e<=-10 ){ e+=10; r *= 1.0e-10L; }
3457534748
while( e<=-1 ){ e+=1; r *= 1.0e-01L; }
3457634749
}
34577
- *pResult = r;
34750
+ assert( r>=0.0 );
34751
+ if( r>+1.7976931348623157081452742373e+308L ){
34752
+ *pResult = +INFINITY;
34753
+ }else{
34754
+ *pResult = (double)r;
34755
+ }
3457834756
}else{
3457934757
double rr[2];
3458034758
u64 s2;
3458134759
rr[0] = (double)s;
3458234760
s2 = (u64)rr[0];
@@ -34827,11 +35005,13 @@
3482735005
if( z[k]!=0 ) return 1;
3482835006
return 0;
3482935007
}else
3483035008
#endif /* SQLITE_OMIT_HEX_INTEGER */
3483135009
{
34832
- return sqlite3Atoi64(z, pOut, sqlite3Strlen30(z), SQLITE_UTF8);
35010
+ int n = (int)(0x3fffffff&strspn(z,"+- \n\t0123456789"));
35011
+ if( z[n] ) n++;
35012
+ return sqlite3Atoi64(z, pOut, n, SQLITE_UTF8);
3483335013
}
3483435014
}
3483535015
3483635016
/*
3483735017
** If zNum represents an integer that will fit in 32-bits, then set
@@ -65559,27 +65739,19 @@
6555965739
/* Allocate space for the WalIterator object. */
6556065740
nSegment = walFramePage(iLast) + 1;
6556165741
nByte = sizeof(WalIterator)
6556265742
+ (nSegment-1)*sizeof(struct WalSegment)
6556365743
+ iLast*sizeof(ht_slot);
65564
- p = (WalIterator *)sqlite3_malloc64(nByte);
65744
+ p = (WalIterator *)sqlite3_malloc64(nByte
65745
+ + sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast)
65746
+ );
6556565747
if( !p ){
6556665748
return SQLITE_NOMEM_BKPT;
6556765749
}
6556865750
memset(p, 0, nByte);
6556965751
p->nSegment = nSegment;
65570
-
65571
- /* Allocate temporary space used by the merge-sort routine. This block
65572
- ** of memory will be freed before this function returns.
65573
- */
65574
- aTmp = (ht_slot *)sqlite3_malloc64(
65575
- sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast)
65576
- );
65577
- if( !aTmp ){
65578
- rc = SQLITE_NOMEM_BKPT;
65579
- }
65580
-
65752
+ aTmp = (ht_slot*)&(((u8*)p)[nByte]);
6558165753
for(i=walFramePage(nBackfill+1); rc==SQLITE_OK && i<nSegment; i++){
6558265754
WalHashLoc sLoc;
6558365755
6558465756
rc = walHashGet(pWal, i, &sLoc);
6558565757
if( rc==SQLITE_OK ){
@@ -65603,12 +65775,10 @@
6560365775
p->aSegment[i].nEntry = nEntry;
6560465776
p->aSegment[i].aIndex = aIndex;
6560565777
p->aSegment[i].aPgno = (u32 *)sLoc.aPgno;
6560665778
}
6560765779
}
65608
- sqlite3_free(aTmp);
65609
-
6561065780
if( rc!=SQLITE_OK ){
6561165781
walIteratorFree(p);
6561265782
p = 0;
6561365783
}
6561465784
*pp = p;
@@ -68121,11 +68291,11 @@
6812168291
** 0x00 becomes 0x00000000
6812268292
** 0x7f becomes 0x0000007f
6812368293
** 0x81 0x00 becomes 0x00000080
6812468294
** 0x82 0x00 becomes 0x00000100
6812568295
** 0x80 0x7f becomes 0x0000007f
68126
-** 0x8a 0x91 0xd1 0xac 0x78 becomes 0x12345678
68296
+** 0x81 0x91 0xd1 0xac 0x78 becomes 0x12345678
6812768297
** 0x81 0x81 0x81 0x81 0x01 becomes 0x10204081
6812868298
**
6812968299
** Variable length integers are used for rowids and to hold the number of
6813068300
** bytes of key and data in a btree cell.
6813168301
**
@@ -70505,11 +70675,11 @@
7050570675
if( *pRC ) return;
7050670676
assert( pCell!=0 );
7050770677
pPage->xParseCell(pPage, pCell, &info);
7050870678
if( info.nLocal<info.nPayload ){
7050970679
Pgno ovfl;
70510
- if( SQLITE_WITHIN(pSrc->aDataEnd, pCell, pCell+info.nLocal) ){
70680
+ if( SQLITE_OVERFLOW(pSrc->aDataEnd, pCell, pCell+info.nLocal) ){
7051170681
testcase( pSrc!=pPage );
7051270682
*pRC = SQLITE_CORRUPT_BKPT;
7051370683
return;
7051470684
}
7051570685
ovfl = get4byte(&pCell[info.nSize-4]);
@@ -73797,11 +73967,10 @@
7379773967
SQLITE_PRIVATE void sqlite3BtreeCursorUnpin(BtCursor *pCur){
7379873968
assert( (pCur->curFlags & BTCF_Pinned)!=0 );
7379973969
pCur->curFlags &= ~BTCF_Pinned;
7380073970
}
7380173971
73802
-#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
7380373972
/*
7380473973
** Return the offset into the database file for the start of the
7380573974
** payload to which the cursor is pointing.
7380673975
*/
7380773976
SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor *pCur){
@@ -73809,11 +73978,10 @@
7380973978
assert( pCur->eState==CURSOR_VALID );
7381073979
getCellInfo(pCur);
7381173980
return (i64)pCur->pBt->pageSize*((i64)pCur->pPage->pgno - 1) +
7381273981
(i64)(pCur->info.pPayload - pCur->pPage->aData);
7381373982
}
73814
-#endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */
7381573983
7381673984
/*
7381773985
** Return the number of bytes of payload for the entry that pCur is
7381873986
** currently pointing to. For table btrees, this will be the amount
7381973987
** of data. For index btrees, this will be the size of the key.
@@ -77666,11 +77834,11 @@
7766677834
iOvflSpace += sz;
7766777835
assert( sz<=pBt->maxLocal+23 );
7766877836
assert( iOvflSpace <= (int)pBt->pageSize );
7766977837
for(k=0; ALWAYS(k<NB*2) && b.ixNx[k]<=j; k++){}
7767077838
pSrcEnd = b.apEnd[k];
77671
- if( SQLITE_WITHIN(pSrcEnd, pCell, pCell+sz) ){
77839
+ if( SQLITE_OVERFLOW(pSrcEnd, pCell, pCell+sz) ){
7767277840
rc = SQLITE_CORRUPT_BKPT;
7767377841
goto balance_cleanup;
7767477842
}
7767577843
rc = insertCell(pParent, nxDiv+i, pCell, sz, pTemp, pNew->pgno);
7767677844
if( rc!=SQLITE_OK ) goto balance_cleanup;
@@ -81439,10 +81607,44 @@
8143981607
assert( (pMem->flags & MEM_Dyn)==0 );
8144081608
pMem->z = pMem->zMalloc;
8144181609
pMem->flags &= (MEM_Null|MEM_Int|MEM_Real|MEM_IntReal);
8144281610
return SQLITE_OK;
8144381611
}
81612
+
81613
+/*
81614
+** If pMem is already a string, detect if it is a zero-terminated
81615
+** string, or make it into one if possible, and mark it as such.
81616
+**
81617
+** This is an optimization. Correct operation continues even if
81618
+** this routine is a no-op.
81619
+*/
81620
+SQLITE_PRIVATE void sqlite3VdbeMemZeroTerminateIfAble(Mem *pMem){
81621
+ if( (pMem->flags & (MEM_Str|MEM_Term|MEM_Ephem|MEM_Static))!=MEM_Str ){
81622
+ /* pMem must be a string, and it cannot be an ephemeral or static string */
81623
+ return;
81624
+ }
81625
+ if( pMem->enc!=SQLITE_UTF8 ) return;
81626
+ if( NEVER(pMem->z==0) ) return;
81627
+ if( pMem->flags & MEM_Dyn ){
81628
+ if( pMem->xDel==sqlite3_free
81629
+ && sqlite3_msize(pMem->z) >= (u64)(pMem->n+1)
81630
+ ){
81631
+ pMem->z[pMem->n] = 0;
81632
+ pMem->flags |= MEM_Term;
81633
+ return;
81634
+ }
81635
+ if( pMem->xDel==(void(*)(void*))sqlite3RCStrUnref ){
81636
+ /* Blindly assume that all RCStr objects are zero-terminated */
81637
+ pMem->flags |= MEM_Term;
81638
+ return;
81639
+ }
81640
+ }else if( pMem->szMalloc >= pMem->n+1 ){
81641
+ pMem->z[pMem->n] = 0;
81642
+ pMem->flags |= MEM_Term;
81643
+ return;
81644
+ }
81645
+}
8144481646
8144581647
/*
8144681648
** It is already known that pMem contains an unterminated string.
8144781649
** Add the zero terminator.
8144881650
**
@@ -81929,18 +82131,21 @@
8192982131
case SQLITE_AFF_REAL: {
8193082132
sqlite3VdbeMemRealify(pMem);
8193182133
break;
8193282134
}
8193382135
default: {
82136
+ int rc;
8193482137
assert( aff==SQLITE_AFF_TEXT );
8193582138
assert( MEM_Str==(MEM_Blob>>3) );
8193682139
pMem->flags |= (pMem->flags&MEM_Blob)>>3;
8193782140
sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
8193882141
assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
8193982142
pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal|MEM_Blob|MEM_Zero);
8194082143
if( encoding!=SQLITE_UTF8 ) pMem->n &= ~1;
81941
- return sqlite3VdbeChangeEncoding(pMem, encoding);
82144
+ rc = sqlite3VdbeChangeEncoding(pMem, encoding);
82145
+ if( rc ) return rc;
82146
+ sqlite3VdbeMemZeroTerminateIfAble(pMem);
8194282147
}
8194382148
}
8194482149
return SQLITE_OK;
8194582150
}
8194682151
@@ -82459,10 +82664,28 @@
8245982664
if( pVal->flags&MEM_Null ){
8246082665
return 0;
8246182666
}
8246282667
return valueToText(pVal, enc);
8246382668
}
82669
+
82670
+/* Return true if sqlit3_value object pVal is a string or blob value
82671
+** that uses the destructor specified in the second argument.
82672
+**
82673
+** TODO: Maybe someday promote this interface into a published API so
82674
+** that third-party extensions can get access to it?
82675
+*/
82676
+SQLITE_PRIVATE int sqlite3ValueIsOfClass(const sqlite3_value *pVal, void(*xFree)(void*)){
82677
+ if( ALWAYS(pVal!=0)
82678
+ && ALWAYS((pVal->flags & (MEM_Str|MEM_Blob))!=0)
82679
+ && (pVal->flags & MEM_Dyn)!=0
82680
+ && pVal->xDel==xFree
82681
+ ){
82682
+ return 1;
82683
+ }else{
82684
+ return 0;
82685
+ }
82686
+}
8246482687
8246582688
/*
8246682689
** Create a new sqlite3_value object.
8246782690
*/
8246882691
SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *db){
@@ -84596,11 +84819,10 @@
8459684819
if( bUndefine ) sqlite3VdbeChangeP5(pParse->pVdbe, 1);
8459784820
}
8459884821
}
8459984822
#endif /* SQLITE_DEBUG */
8460084823
84601
-
8460284824
/*
8460384825
** Change the value of the P4 operand for a specific instruction.
8460484826
** This routine is useful when a large program is loaded from a
8460584827
** static array using sqlite3VdbeAddOpList but we want to make a
8460684828
** few minor changes to the program.
@@ -85517,11 +85739,11 @@
8551785739
if( p->explain==2 ){
8551885740
sqlite3VdbeMemSetInt64(pMem, pOp->p1);
8551985741
sqlite3VdbeMemSetInt64(pMem+1, pOp->p2);
8552085742
sqlite3VdbeMemSetInt64(pMem+2, pOp->p3);
8552185743
sqlite3VdbeMemSetStr(pMem+3, zP4, -1, SQLITE_UTF8, sqlite3_free);
85522
- p->nResColumn = 4;
85744
+ assert( p->nResColumn==4 );
8552385745
}else{
8552485746
sqlite3VdbeMemSetInt64(pMem+0, i);
8552585747
sqlite3VdbeMemSetStr(pMem+1, (char*)sqlite3OpcodeName(pOp->opcode),
8552685748
-1, SQLITE_UTF8, SQLITE_STATIC);
8552785749
sqlite3VdbeMemSetInt64(pMem+2, pOp->p1);
@@ -85536,11 +85758,11 @@
8553685758
}
8553785759
#else
8553885760
sqlite3VdbeMemSetNull(pMem+7);
8553985761
#endif
8554085762
sqlite3VdbeMemSetStr(pMem+5, zP4, -1, SQLITE_UTF8, sqlite3_free);
85541
- p->nResColumn = 8;
85763
+ assert( p->nResColumn==8 );
8554285764
}
8554385765
p->pResultRow = pMem;
8554485766
if( db->mallocFailed ){
8554585767
p->rc = SQLITE_NOMEM;
8554685768
rc = SQLITE_ERROR;
@@ -85750,30 +85972,13 @@
8575085972
assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) );
8575185973
8575285974
resolveP2Values(p, &nArg);
8575385975
p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort);
8575485976
if( pParse->explain ){
85755
- static const char * const azColName[] = {
85756
- "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
85757
- "id", "parent", "notused", "detail"
85758
- };
85759
- int iFirst, mx, i;
8576085977
if( nMem<10 ) nMem = 10;
8576185978
p->explain = pParse->explain;
85762
- if( pParse->explain==2 ){
85763
- sqlite3VdbeSetNumCols(p, 4);
85764
- iFirst = 8;
85765
- mx = 12;
85766
- }else{
85767
- sqlite3VdbeSetNumCols(p, 8);
85768
- iFirst = 0;
85769
- mx = 8;
85770
- }
85771
- for(i=iFirst; i<mx; i++){
85772
- sqlite3VdbeSetColName(p, i-iFirst, COLNAME_NAME,
85773
- azColName[i], SQLITE_STATIC);
85774
- }
85979
+ p->nResColumn = 12 - 4*p->explain;
8577585980
}
8577685981
p->expired = 0;
8577785982
8577885983
/* Memory for registers, parameters, cursor, etc, is allocated in one or two
8577985984
** passes. On the first pass, we try to reuse unused memory at the
@@ -85820,12 +86025,28 @@
8582086025
** Close a VDBE cursor and release all the resources that cursor
8582186026
** happens to hold.
8582286027
*/
8582386028
SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
8582486029
if( pCx ) sqlite3VdbeFreeCursorNN(p,pCx);
86030
+}
86031
+static SQLITE_NOINLINE void freeCursorWithCache(Vdbe *p, VdbeCursor *pCx){
86032
+ VdbeTxtBlbCache *pCache = pCx->pCache;
86033
+ assert( pCx->colCache );
86034
+ pCx->colCache = 0;
86035
+ pCx->pCache = 0;
86036
+ if( pCache->pCValue ){
86037
+ sqlite3RCStrUnref(pCache->pCValue);
86038
+ pCache->pCValue = 0;
86039
+ }
86040
+ sqlite3DbFree(p->db, pCache);
86041
+ sqlite3VdbeFreeCursorNN(p, pCx);
8582586042
}
8582686043
SQLITE_PRIVATE void sqlite3VdbeFreeCursorNN(Vdbe *p, VdbeCursor *pCx){
86044
+ if( pCx->colCache ){
86045
+ freeCursorWithCache(p, pCx);
86046
+ return;
86047
+ }
8582786048
switch( pCx->eCurType ){
8582886049
case CURTYPE_SORTER: {
8582986050
sqlite3VdbeSorterClose(p->db, pCx);
8583086051
break;
8583186052
}
@@ -85922,16 +86143,16 @@
8592286143
*/
8592386144
SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
8592486145
int n;
8592586146
sqlite3 *db = p->db;
8592686147
85927
- if( p->nResColumn ){
85928
- releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
86148
+ if( p->nResAlloc ){
86149
+ releaseMemArray(p->aColName, p->nResAlloc*COLNAME_N);
8592986150
sqlite3DbFree(db, p->aColName);
8593086151
}
8593186152
n = nResColumn*COLNAME_N;
85932
- p->nResColumn = (u16)nResColumn;
86153
+ p->nResColumn = p->nResAlloc = (u16)nResColumn;
8593386154
p->aColName = (Mem*)sqlite3DbMallocRawNN(db, sizeof(Mem)*n );
8593486155
if( p->aColName==0 ) return;
8593586156
initMemArray(p->aColName, n, db, MEM_Null);
8593686157
}
8593786158
@@ -85952,18 +86173,18 @@
8595286173
const char *zName, /* Pointer to buffer containing name */
8595386174
void (*xDel)(void*) /* Memory management strategy for zName */
8595486175
){
8595586176
int rc;
8595686177
Mem *pColName;
85957
- assert( idx<p->nResColumn );
86178
+ assert( idx<p->nResAlloc );
8595886179
assert( var<COLNAME_N );
8595986180
if( p->db->mallocFailed ){
8596086181
assert( !zName || xDel!=SQLITE_DYNAMIC );
8596186182
return SQLITE_NOMEM_BKPT;
8596286183
}
8596386184
assert( p->aColName!=0 );
85964
- pColName = &(p->aColName[idx+var*p->nResColumn]);
86185
+ pColName = &(p->aColName[idx+var*p->nResAlloc]);
8596586186
rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, xDel);
8596686187
assert( rc!=0 || !zName || (pColName->flags&MEM_Term)!=0 );
8596786188
return rc;
8596886189
}
8596986190
@@ -86783,11 +87004,11 @@
8678387004
static void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
8678487005
SubProgram *pSub, *pNext;
8678587006
assert( db!=0 );
8678687007
assert( p->db==0 || p->db==db );
8678787008
if( p->aColName ){
86788
- releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
87009
+ releaseMemArray(p->aColName, p->nResAlloc*COLNAME_N);
8678987010
sqlite3DbNNFreeNN(db, p->aColName);
8679087011
}
8679187012
for(pSub=p->pProgram; pSub; pSub=pNext){
8679287013
pNext = pSub->pNext;
8679387014
vdbeFreeOpArray(db, pSub->aOp, pSub->nOp);
@@ -89092,10 +89313,11 @@
8909289313
}
8909389314
if( n>0x7fffffff ){
8909489315
(void)invokeValueDestructor(z, xDel, pCtx);
8909589316
}else{
8909689317
setResultStrOrError(pCtx, z, (int)n, enc, xDel);
89318
+ sqlite3VdbeMemZeroTerminateIfAble(pCtx->pOut);
8909789319
}
8909889320
}
8909989321
#ifndef SQLITE_OMIT_UTF16
8910089322
SQLITE_API void sqlite3_result_text16(
8910189323
sqlite3_context *pCtx,
@@ -89704,11 +89926,12 @@
8970489926
/*
8970589927
** Return the number of columns in the result set for the statement pStmt.
8970689928
*/
8970789929
SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt){
8970889930
Vdbe *pVm = (Vdbe *)pStmt;
89709
- return pVm ? pVm->nResColumn : 0;
89931
+ if( pVm==0 ) return 0;
89932
+ return pVm->nResColumn;
8971089933
}
8971189934
8971289935
/*
8971389936
** Return the number of values available from the current row of the
8971489937
** currently executing statement pStmt.
@@ -89877,10 +90100,36 @@
8987790100
int iType = sqlite3_value_type( columnMem(pStmt,i) );
8987890101
columnMallocFailure(pStmt);
8987990102
return iType;
8988090103
}
8988190104
90105
+/*
90106
+** Column names appropriate for EXPLAIN or EXPLAIN QUERY PLAN.
90107
+*/
90108
+static const char * const azExplainColNames8[] = {
90109
+ "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment", /* EXPLAIN */
90110
+ "id", "parent", "notused", "detail" /* EQP */
90111
+};
90112
+static const u16 azExplainColNames16data[] = {
90113
+ /* 0 */ 'a', 'd', 'd', 'r', 0,
90114
+ /* 5 */ 'o', 'p', 'c', 'o', 'd', 'e', 0,
90115
+ /* 12 */ 'p', '1', 0,
90116
+ /* 15 */ 'p', '2', 0,
90117
+ /* 18 */ 'p', '3', 0,
90118
+ /* 21 */ 'p', '4', 0,
90119
+ /* 24 */ 'p', '5', 0,
90120
+ /* 27 */ 'c', 'o', 'm', 'm', 'e', 'n', 't', 0,
90121
+ /* 35 */ 'i', 'd', 0,
90122
+ /* 38 */ 'p', 'a', 'r', 'e', 'n', 't', 0,
90123
+ /* 45 */ 'n', 'o', 't', 'u', 's', 'e', 'd', 0,
90124
+ /* 53 */ 'd', 'e', 't', 'a', 'i', 'l', 0
90125
+};
90126
+static const u8 iExplainColNames16[] = {
90127
+ 0, 5, 12, 15, 18, 21, 24, 27,
90128
+ 35, 38, 45, 53
90129
+};
90130
+
8988290131
/*
8988390132
** Convert the N-th element of pStmt->pColName[] into a string using
8988490133
** xFunc() then return that string. If N is out of range, return 0.
8988590134
**
8988690135
** There are up to 5 names for each column. useType determines which
@@ -89909,19 +90158,33 @@
8990990158
if( pStmt==0 ){
8991090159
(void)SQLITE_MISUSE_BKPT;
8991190160
return 0;
8991290161
}
8991390162
#endif
90163
+ if( N<0 ) return 0;
8991490164
ret = 0;
8991590165
p = (Vdbe *)pStmt;
8991690166
db = p->db;
8991790167
assert( db!=0 );
89918
- n = sqlite3_column_count(pStmt);
89919
- if( N<n && N>=0 ){
90168
+ sqlite3_mutex_enter(db->mutex);
90169
+
90170
+ if( p->explain ){
90171
+ if( useType>0 ) goto columnName_end;
90172
+ n = p->explain==1 ? 8 : 4;
90173
+ if( N>=n ) goto columnName_end;
90174
+ if( useUtf16 ){
90175
+ int i = iExplainColNames16[N + 8*p->explain - 8];
90176
+ ret = (void*)&azExplainColNames16data[i];
90177
+ }else{
90178
+ ret = (void*)azExplainColNames8[N + 8*p->explain - 8];
90179
+ }
90180
+ goto columnName_end;
90181
+ }
90182
+ n = p->nResColumn;
90183
+ if( N<n ){
8992090184
u8 prior_mallocFailed = db->mallocFailed;
8992190185
N += useType*n;
89922
- sqlite3_mutex_enter(db->mutex);
8992390186
#ifndef SQLITE_OMIT_UTF16
8992490187
if( useUtf16 ){
8992590188
ret = sqlite3_value_text16((sqlite3_value*)&p->aColName[N]);
8992690189
}else
8992790190
#endif
@@ -89934,12 +90197,13 @@
8993490197
assert( db->mallocFailed==0 || db->mallocFailed==1 );
8993590198
if( db->mallocFailed > prior_mallocFailed ){
8993690199
sqlite3OomClear(db);
8993790200
ret = 0;
8993890201
}
89939
- sqlite3_mutex_leave(db->mutex);
8994090202
}
90203
+columnName_end:
90204
+ sqlite3_mutex_leave(db->mutex);
8994190205
return ret;
8994290206
}
8994390207
8994490208
/*
8994590209
** Return the name of the Nth column of the result set returned by SQL
@@ -90391,10 +90655,43 @@
9039190655
** statement is an EXPLAIN QUERY PLAN
9039290656
*/
9039390657
SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt){
9039490658
return pStmt ? ((Vdbe*)pStmt)->explain : 0;
9039590659
}
90660
+
90661
+/*
90662
+** Set the explain mode for a statement.
90663
+*/
90664
+SQLITE_API int sqlite3_stmt_explain(sqlite3_stmt *pStmt, int eMode){
90665
+ Vdbe *v = (Vdbe*)pStmt;
90666
+ int rc;
90667
+ sqlite3_mutex_enter(v->db->mutex);
90668
+ if( v->explain==eMode ){
90669
+ rc = SQLITE_OK;
90670
+ }else if( eMode<0 || eMode>2 ){
90671
+ rc = SQLITE_ERROR;
90672
+ }else if( (v->prepFlags & SQLITE_PREPARE_SAVESQL)==0 ){
90673
+ rc = SQLITE_ERROR;
90674
+ }else if( v->eVdbeState!=VDBE_READY_STATE ){
90675
+ rc = SQLITE_BUSY;
90676
+ }else if( v->nMem>=10 && (eMode!=2 || v->haveEqpOps) ){
90677
+ /* No reprepare necessary */
90678
+ v->explain = eMode;
90679
+ rc = SQLITE_OK;
90680
+ }else{
90681
+ v->explain = eMode;
90682
+ rc = sqlite3Reprepare(v);
90683
+ v->haveEqpOps = eMode==2;
90684
+ }
90685
+ if( v->explain ){
90686
+ v->nResColumn = 12 - 4*v->explain;
90687
+ }else{
90688
+ v->nResColumn = v->nResAlloc;
90689
+ }
90690
+ sqlite3_mutex_leave(v->db->mutex);
90691
+ return rc;
90692
+}
9039690693
9039790694
/*
9039890695
** Return true if the prepared statement is in need of being reset.
9039990696
*/
9040090697
SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
@@ -91631,10 +91928,13 @@
9163191928
for(j=0; j<25 && j<pMem->n; j++){
9163291929
c = pMem->z[j];
9163391930
sqlite3_str_appendchar(pStr, 1, (c>=0x20&&c<=0x7f) ? c : '.');
9163491931
}
9163591932
sqlite3_str_appendf(pStr, "]%s", encnames[pMem->enc]);
91933
+ if( f & MEM_Term ){
91934
+ sqlite3_str_appendf(pStr, "(0-term)");
91935
+ }
9163691936
}
9163791937
}
9163891938
#endif
9163991939
9164091940
#ifdef SQLITE_DEBUG
@@ -91766,10 +92066,97 @@
9176692066
h += 4093 + (p->flags & (MEM_Str|MEM_Blob));
9176792067
}
9176892068
}
9176992069
return h;
9177092070
}
92071
+
92072
+
92073
+/*
92074
+** For OP_Column, factor out the case where content is loaded from
92075
+** overflow pages, so that the code to implement this case is separate
92076
+** the common case where all content fits on the page. Factoring out
92077
+** the code reduces register pressure and helps the common case
92078
+** to run faster.
92079
+*/
92080
+static SQLITE_NOINLINE int vdbeColumnFromOverflow(
92081
+ VdbeCursor *pC, /* The BTree cursor from which we are reading */
92082
+ int iCol, /* The column to read */
92083
+ int t, /* The serial-type code for the column value */
92084
+ i64 iOffset, /* Offset to the start of the content value */
92085
+ u32 cacheStatus, /* Current Vdbe.cacheCtr value */
92086
+ u32 colCacheCtr, /* Current value of the column cache counter */
92087
+ Mem *pDest /* Store the value into this register. */
92088
+){
92089
+ int rc;
92090
+ sqlite3 *db = pDest->db;
92091
+ int encoding = pDest->enc;
92092
+ int len = sqlite3VdbeSerialTypeLen(t);
92093
+ assert( pC->eCurType==CURTYPE_BTREE );
92094
+ if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) return SQLITE_TOOBIG;
92095
+ if( len > 4000 && pC->pKeyInfo==0 ){
92096
+ /* Cache large column values that are on overflow pages using
92097
+ ** an RCStr (reference counted string) so that if they are reloaded,
92098
+ ** that do not have to be copied a second time. The overhead of
92099
+ ** creating and managing the cache is such that this is only
92100
+ ** profitable for larger TEXT and BLOB values.
92101
+ **
92102
+ ** Only do this on table-btrees so that writes to index-btrees do not
92103
+ ** need to clear the cache. This buys performance in the common case
92104
+ ** in exchange for generality.
92105
+ */
92106
+ VdbeTxtBlbCache *pCache;
92107
+ char *pBuf;
92108
+ if( pC->colCache==0 ){
92109
+ pC->pCache = sqlite3DbMallocZero(db, sizeof(VdbeTxtBlbCache) );
92110
+ if( pC->pCache==0 ) return SQLITE_NOMEM;
92111
+ pC->colCache = 1;
92112
+ }
92113
+ pCache = pC->pCache;
92114
+ if( pCache->pCValue==0
92115
+ || pCache->iCol!=iCol
92116
+ || pCache->cacheStatus!=cacheStatus
92117
+ || pCache->colCacheCtr!=colCacheCtr
92118
+ || pCache->iOffset!=sqlite3BtreeOffset(pC->uc.pCursor)
92119
+ ){
92120
+ if( pCache->pCValue ) sqlite3RCStrUnref(pCache->pCValue);
92121
+ pBuf = pCache->pCValue = sqlite3RCStrNew( len+3 );
92122
+ if( pBuf==0 ) return SQLITE_NOMEM;
92123
+ rc = sqlite3BtreePayload(pC->uc.pCursor, iOffset, len, pBuf);
92124
+ if( rc ) return rc;
92125
+ pBuf[len] = 0;
92126
+ pBuf[len+1] = 0;
92127
+ pBuf[len+2] = 0;
92128
+ pCache->iCol = iCol;
92129
+ pCache->cacheStatus = cacheStatus;
92130
+ pCache->colCacheCtr = colCacheCtr;
92131
+ pCache->iOffset = sqlite3BtreeOffset(pC->uc.pCursor);
92132
+ }else{
92133
+ pBuf = pCache->pCValue;
92134
+ }
92135
+ assert( t>=12 );
92136
+ sqlite3RCStrRef(pBuf);
92137
+ if( t&1 ){
92138
+ rc = sqlite3VdbeMemSetStr(pDest, pBuf, len, encoding,
92139
+ (void(*)(void*))sqlite3RCStrUnref);
92140
+ pDest->flags |= MEM_Term;
92141
+ }else{
92142
+ rc = sqlite3VdbeMemSetStr(pDest, pBuf, len, 0,
92143
+ (void(*)(void*))sqlite3RCStrUnref);
92144
+ }
92145
+ }else{
92146
+ rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, iOffset, len, pDest);
92147
+ if( rc ) return rc;
92148
+ sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest);
92149
+ if( (t&1)!=0 && encoding==SQLITE_UTF8 ){
92150
+ pDest->z[len] = 0;
92151
+ pDest->flags |= MEM_Term;
92152
+ }
92153
+ }
92154
+ pDest->flags &= ~MEM_Ephem;
92155
+ return rc;
92156
+}
92157
+
9177192158
9177292159
/*
9177392160
** Return the symbolic name for the data type of a pMem
9177492161
*/
9177592162
static const char *vdbeMemTypeName(Mem *pMem){
@@ -91809,10 +92196,11 @@
9180992196
Mem *aMem = p->aMem; /* Copy of p->aMem */
9181092197
Mem *pIn1 = 0; /* 1st input operand */
9181192198
Mem *pIn2 = 0; /* 2nd input operand */
9181292199
Mem *pIn3 = 0; /* 3rd input operand */
9181392200
Mem *pOut = 0; /* Output operand */
92201
+ u32 colCacheCtr = 0; /* Column cache counter */
9181492202
#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE)
9181592203
u64 *pnCycle = 0;
9181692204
int bStmtScanStatus = IS_STMT_SCANSTATUS(db)!=0;
9181792205
#endif
9181892206
/*** INSERT STACK UNION HERE ***/
@@ -94133,10 +94521,11 @@
9413394521
pDest->flags = aFlag[t&1];
9413494522
}
9413594523
}else{
9413694524
u8 p5;
9413794525
pDest->enc = encoding;
94526
+ assert( pDest->db==db );
9413894527
/* This branch happens only when content is on overflow pages */
9413994528
if( ((p5 = (pOp->p5 & OPFLAG_BYTELENARG))!=0
9414094529
&& (p5==OPFLAG_TYPEOFARG
9414194530
|| (t>=12 && ((t&1)==0 || p5==OPFLAG_BYTELENARG))
9414294531
)
@@ -94156,15 +94545,17 @@
9415694545
** as that array is 256 bytes long (plenty for VdbeMemPrettyPrint())
9415794546
** and it begins with a bunch of zeros.
9415894547
*/
9415994548
sqlite3VdbeSerialGet((u8*)sqlite3CtypeMap, t, pDest);
9416094549
}else{
94161
- if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) goto too_big;
94162
- rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest);
94163
- if( rc!=SQLITE_OK ) goto abort_due_to_error;
94164
- sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest);
94165
- pDest->flags &= ~MEM_Ephem;
94550
+ rc = vdbeColumnFromOverflow(pC, p2, t, aOffset[p2],
94551
+ p->cacheCtr, colCacheCtr, pDest);
94552
+ if( rc ){
94553
+ if( rc==SQLITE_NOMEM ) goto no_mem;
94554
+ if( rc==SQLITE_TOOBIG ) goto too_big;
94555
+ goto abort_due_to_error;
94556
+ }
9416694557
}
9416794558
}
9416894559
9416994560
op_column_out:
9417094561
UPDATE_MAX_BLOBSIZE(pDest);
@@ -96693,10 +97084,11 @@
9669397084
(pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION|OPFLAG_PREFORMAT)),
9669497085
seekResult
9669597086
);
9669697087
pC->deferredMoveto = 0;
9669797088
pC->cacheStatus = CACHE_STALE;
97089
+ colCacheCtr++;
9669897090
9669997091
/* Invoke the update-hook if required. */
9670097092
if( rc ) goto abort_due_to_error;
9670197093
if( pTab ){
9670297094
assert( db->xUpdateCallback!=0 );
@@ -96853,10 +97245,11 @@
9685397245
}
9685497246
#endif
9685597247
9685697248
rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5);
9685797249
pC->cacheStatus = CACHE_STALE;
97250
+ colCacheCtr++;
9685897251
pC->seekResult = 0;
9685997252
if( rc ) goto abort_due_to_error;
9686097253
9686197254
/* Invoke the update-hook if required. */
9686297255
if( opflags & OPFLAG_NCHANGE ){
@@ -103347,10 +103740,12 @@
103347103740
"p3 INT,"
103348103741
"p4 TEXT,"
103349103742
"p5 INT,"
103350103743
"comment TEXT,"
103351103744
"subprog TEXT,"
103745
+ "nexec INT,"
103746
+ "ncycle INT,"
103352103747
"stmt HIDDEN"
103353103748
");",
103354103749
103355103750
/* Tables_used() schema */
103356103751
"CREATE TABLE x("
@@ -103509,11 +103904,11 @@
103509103904
pCur->zType = "index";
103510103905
}
103511103906
}
103512103907
}
103513103908
}
103514
- i += 10;
103909
+ i += 20;
103515103910
}
103516103911
}
103517103912
switch( i ){
103518103913
case 0: /* addr */
103519103914
sqlite3_result_int(ctx, pCur->iAddr);
@@ -103559,20 +103954,35 @@
103559103954
}else{
103560103955
sqlite3_result_text(ctx, "(FK)", 4, SQLITE_STATIC);
103561103956
}
103562103957
break;
103563103958
}
103564
- case 10: /* tables_used.type */
103959
+
103960
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
103961
+ case 9: /* nexec */
103962
+ sqlite3_result_int(ctx, pOp->nExec);
103963
+ break;
103964
+ case 10: /* ncycle */
103965
+ sqlite3_result_int(ctx, pOp->nCycle);
103966
+ break;
103967
+#else
103968
+ case 9: /* nexec */
103969
+ case 10: /* ncycle */
103970
+ sqlite3_result_int(ctx, 0);
103971
+ break;
103972
+#endif
103973
+
103974
+ case 20: /* tables_used.type */
103565103975
sqlite3_result_text(ctx, pCur->zType, -1, SQLITE_STATIC);
103566103976
break;
103567
- case 11: /* tables_used.schema */
103977
+ case 21: /* tables_used.schema */
103568103978
sqlite3_result_text(ctx, pCur->zSchema, -1, SQLITE_STATIC);
103569103979
break;
103570
- case 12: /* tables_used.name */
103980
+ case 22: /* tables_used.name */
103571103981
sqlite3_result_text(ctx, pCur->zName, -1, SQLITE_STATIC);
103572103982
break;
103573
- case 13: /* tables_used.wr */
103983
+ case 23: /* tables_used.wr */
103574103984
sqlite3_result_int(ctx, pOp->opcode==OP_OpenWrite);
103575103985
break;
103576103986
}
103577103987
return SQLITE_OK;
103578103988
}
@@ -103642,11 +104052,11 @@
103642104052
){
103643104053
int i;
103644104054
int rc = SQLITE_CONSTRAINT;
103645104055
struct sqlite3_index_constraint *p;
103646104056
bytecodevtab *pVTab = (bytecodevtab*)tab;
103647
- int iBaseCol = pVTab->bTablesUsed ? 4 : 8;
104057
+ int iBaseCol = pVTab->bTablesUsed ? 4 : 10;
103648104058
pIdxInfo->estimatedCost = (double)100;
103649104059
pIdxInfo->estimatedRows = 100;
103650104060
pIdxInfo->idxNum = 0;
103651104061
for(i=0, p=pIdxInfo->aConstraint; i<pIdxInfo->nConstraint; i++, p++){
103652104062
if( p->usable==0 ) continue;
@@ -111269,12 +111679,11 @@
111269111679
testcase( (pDef->funcFlags & OPFLAG_BYTELENARG)==OPFLAG_BYTELENARG);
111270111680
pFarg->a[0].pExpr->op2 = pDef->funcFlags & OPFLAG_BYTELENARG;
111271111681
}
111272111682
}
111273111683
111274
- sqlite3ExprCodeExprList(pParse, pFarg, r1, 0,
111275
- SQLITE_ECEL_DUP|SQLITE_ECEL_FACTOR);
111684
+ sqlite3ExprCodeExprList(pParse, pFarg, r1, 0, SQLITE_ECEL_FACTOR);
111276111685
}else{
111277111686
r1 = 0;
111278111687
}
111279111688
#ifndef SQLITE_OMIT_VIRTUALTABLE
111280111689
/* Possibly overload the function if the first argument is
@@ -125336,11 +125745,12 @@
125336125745
*/
125337125746
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0,0,wcf,iTabCur+1);
125338125747
if( pWInfo==0 ) goto delete_from_cleanup;
125339125748
eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
125340125749
assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI );
125341
- assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF );
125750
+ assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF
125751
+ || OptimizationDisabled(db, SQLITE_OnePass) );
125342125752
if( eOnePass!=ONEPASS_SINGLE ) sqlite3MultiWrite(pParse);
125343125753
if( sqlite3WhereUsesDeferredSeek(pWInfo) ){
125344125754
sqlite3VdbeAddOp1(v, OP_FinishSeek, iTabCur);
125345125755
}
125346125756
@@ -127068,10 +127478,11 @@
127068127478
*zOut++ = 0x80 + (u8)((c>>12) & 0x3F);
127069127479
*zOut++ = 0x80 + (u8)((c>>6) & 0x3F);
127070127480
*zOut++ = 0x80 + (u8)(c & 0x3F);
127071127481
} \
127072127482
}
127483
+ *zOut = 0;
127073127484
sqlite3_result_text64(context, (char*)z, zOut-z, sqlite3_free, SQLITE_UTF8);
127074127485
}
127075127486
127076127487
/*
127077127488
** The hex() function. Interpret the argument as a blob. Return
@@ -127605,15 +128016,14 @@
127605128016
p->iSum = x;
127606128017
}else{
127607128018
p->ovrfl = 1;
127608128019
kahanBabuskaNeumaierInit(p, p->iSum);
127609128020
p->approx = 1;
127610
- kahanBabuskaNeumaierStep(p, sqlite3_value_double(argv[0]));
128021
+ kahanBabuskaNeumaierStepInt64(p, sqlite3_value_int64(argv[0]));
127611128022
}
127612128023
}
127613128024
}else{
127614
- p->approx = 1;
127615128025
if( type==SQLITE_INTEGER ){
127616128026
kahanBabuskaNeumaierStepInt64(p, sqlite3_value_int64(argv[0]));
127617128027
}else{
127618128028
p->ovrfl = 0;
127619128029
kahanBabuskaNeumaierStep(p, sqlite3_value_double(argv[0]));
@@ -139192,11 +139602,16 @@
139192139602
memset(PARSE_HDR(&sParse), 0, PARSE_HDR_SZ);
139193139603
memset(PARSE_TAIL(&sParse), 0, PARSE_TAIL_SZ);
139194139604
sParse.pOuterParse = db->pParse;
139195139605
db->pParse = &sParse;
139196139606
sParse.db = db;
139197
- sParse.pReprepare = pReprepare;
139607
+ if( pReprepare ){
139608
+ sParse.pReprepare = pReprepare;
139609
+ sParse.explain = sqlite3_stmt_isexplain((sqlite3_stmt*)pReprepare);
139610
+ }else{
139611
+ assert( sParse.pReprepare==0 );
139612
+ }
139198139613
assert( ppStmt && *ppStmt==0 );
139199139614
if( db->mallocFailed ){
139200139615
sqlite3ErrorMsg(&sParse, "out of memory");
139201139616
db->errCode = rc = SQLITE_NOMEM;
139202139617
goto end_prepare;
@@ -141671,17 +142086,10 @@
141671142086
ExprList *pEList;
141672142087
sqlite3 *db = pParse->db;
141673142088
int fullName; /* TABLE.COLUMN if no AS clause and is a direct table ref */
141674142089
int srcName; /* COLUMN or TABLE.COLUMN if no AS clause and is direct */
141675142090
141676
-#ifndef SQLITE_OMIT_EXPLAIN
141677
- /* If this is an EXPLAIN, skip this step */
141678
- if( pParse->explain ){
141679
- return;
141680
- }
141681
-#endif
141682
-
141683142091
if( pParse->colNamesSet ) return;
141684142092
/* Column names are determined by the left-most term of a compound select */
141685142093
while( pSelect->pPrior ) pSelect = pSelect->pPrior;
141686142094
TREETRACE(0x80,pParse,pSelect,("generating column names\n"));
141687142095
pTabList = pSelect->pSrc;
@@ -143869,11 +144277,12 @@
143869144277
** is the first element of the parent query. Two subcases:
143870144278
** (27a) the subquery is not a compound query.
143871144279
** (27b) the subquery is a compound query and the RIGHT JOIN occurs
143872144280
** in any arm of the compound query. (See also (17g).)
143873144281
**
143874
-** (28) The subquery is not a MATERIALIZED CTE.
144282
+** (28) The subquery is not a MATERIALIZED CTE. (This is handled
144283
+** in the caller before ever reaching this routine.)
143875144284
**
143876144285
**
143877144286
** In this routine, the "p" parameter is a pointer to the outer query.
143878144287
** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query
143879144288
** uses aggregates.
@@ -143979,13 +144388,13 @@
143979144388
143980144389
assert( pSubSrc->nSrc>0 ); /* True by restriction (7) */
143981144390
if( iFrom>0 && (pSubSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){
143982144391
return 0; /* Restriction (27a) */
143983144392
}
143984
- if( pSubitem->fg.isCte && pSubitem->u2.pCteUse->eM10d==M10d_Yes ){
143985
- return 0; /* (28) */
143986
- }
144393
+
144394
+ /* Condition (28) is blocked by the caller */
144395
+ assert( !pSubitem->fg.isCte || pSubitem->u2.pCteUse->eM10d!=M10d_Yes );
143987144396
143988144397
/* Restriction (17): If the sub-query is a compound SELECT, then it must
143989144398
** use only the UNION ALL operator. And none of the simple select queries
143990144399
** that make up the compound SELECT are allowed to be aggregate or distinct
143991144400
** queries.
@@ -146861,10 +147270,18 @@
146861147270
if( pTab->nCol!=pSub->pEList->nExpr ){
146862147271
sqlite3ErrorMsg(pParse, "expected %d columns for '%s' but got %d",
146863147272
pTab->nCol, pTab->zName, pSub->pEList->nExpr);
146864147273
goto select_end;
146865147274
}
147275
+
147276
+ /* Do not attempt the usual optimizations (flattening and ORDER BY
147277
+ ** elimination) on a MATERIALIZED common table expression because
147278
+ ** a MATERIALIZED common table expression is an optimization fence.
147279
+ */
147280
+ if( pItem->fg.isCte && pItem->u2.pCteUse->eM10d==M10d_Yes ){
147281
+ continue;
147282
+ }
146866147283
146867147284
/* Do not try to flatten an aggregate subquery.
146868147285
**
146869147286
** Flattening an aggregate subquery is only possible if the outer query
146870147287
** is not a join. But if the outer query is not a join, then the subquery
@@ -146891,10 +147308,12 @@
146891147308
** (5) The ORDER BY isn't going to accomplish anything because
146892147309
** one of:
146893147310
** (a) The outer query has a different ORDER BY clause
146894147311
** (b) The subquery is part of a join
146895147312
** See forum post 062d576715d277c8
147313
+ **
147314
+ ** Also retain the ORDER BY if the OmitOrderBy optimization is disabled.
146896147315
*/
146897147316
if( pSub->pOrderBy!=0
146898147317
&& (p->pOrderBy!=0 || pTabList->nSrc>1) /* Condition (5) */
146899147318
&& pSub->pLimit==0 /* Condition (1) */
146900147319
&& (pSub->selFlags & SF_OrderByReqd)==0 /* Condition (2) */
@@ -150394,11 +150813,11 @@
150394150813
if( !pParse->nested
150395150814
&& !pTrigger
150396150815
&& !hasFK
150397150816
&& !chngKey
150398150817
&& !bReplace
150399
- && (sNC.ncFlags & NC_Subquery)==0
150818
+ && (pWhere==0 || !ExprHasProperty(pWhere, EP_Subquery))
150400150819
){
150401150820
flags |= WHERE_ONEPASS_MULTIROW;
150402150821
}
150403150822
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,0,0,0,flags,iIdxCur);
150404150823
if( pWInfo==0 ) goto update_cleanup;
@@ -160954,11 +161373,11 @@
160954161373
return 0; /* Discard pTemplate */
160955161374
}
160956161375
160957161376
/* If pTemplate is always better than p, then cause p to be overwritten
160958161377
** with pTemplate. pTemplate is better than p if:
160959
- ** (1) pTemplate has no more dependences than p, and
161378
+ ** (1) pTemplate has no more dependencies than p, and
160960161379
** (2) pTemplate has an equal or lower cost than p.
160961161380
*/
160962161381
if( (p->prereq & pTemplate->prereq)==pTemplate->prereq /* (1) */
160963161382
&& p->rRun>=pTemplate->rRun /* (2a) */
160964161383
&& p->nOut>=pTemplate->nOut /* (2b) */
@@ -163422,11 +163841,12 @@
163422163841
/* TUNING: For simple queries, only the best path is tracked.
163423163842
** For 2-way joins, the 5 best paths are followed.
163424163843
** For joins of 3 or more tables, track the 10 best paths */
163425163844
mxChoice = (nLoop<=1) ? 1 : (nLoop==2 ? 5 : 10);
163426163845
assert( nLoop<=pWInfo->pTabList->nSrc );
163427
- WHERETRACE(0x002, ("---- begin solver. (nRowEst=%d)\n", nRowEst));
163846
+ WHERETRACE(0x002, ("---- begin solver. (nRowEst=%d, nQueryLoop=%d)\n",
163847
+ nRowEst, pParse->nQueryLoop));
163428163848
163429163849
/* If nRowEst is zero and there is an ORDER BY clause, ignore it. In this
163430163850
** case the purpose of this call is to estimate the number of rows returned
163431163851
** by the overall query. Once this estimate has been obtained, the caller
163432163852
** will invoke this function a second time, passing the estimate as the
@@ -163541,13 +163961,14 @@
163541163961
rUnsorted -= 2; /* TUNING: Slight bias in favor of no-sort plans */
163542163962
}
163543163963
163544163964
/* TUNING: A full-scan of a VIEW or subquery in the outer loop
163545163965
** is not so bad. */
163546
- if( iLoop==0 && (pWLoop->wsFlags & WHERE_VIEWSCAN)!=0 ){
163966
+ if( iLoop==0 && (pWLoop->wsFlags & WHERE_VIEWSCAN)!=0 && nLoop>1 ){
163547163967
rCost += -10;
163548163968
nOut += -30;
163969
+ WHERETRACE(0x80,("VIEWSCAN cost reduction for %c\n",pWLoop->cId));
163549163970
}
163550163971
163551163972
/* Check to see if pWLoop should be added to the set of
163552163973
** mxChoice best-so-far paths.
163553163974
**
@@ -164174,10 +164595,32 @@
164174164595
if( p->pIENext==0 ){
164175164596
sqlite3ParserAddCleanup(pParse, whereIndexedExprCleanup, pParse);
164176164597
}
164177164598
}
164178164599
}
164600
+
164601
+/*
164602
+** Set the reverse-scan order mask to one for all tables in the query
164603
+** with the exception of MATERIALIZED common table expressions that have
164604
+** their own internal ORDER BY clauses.
164605
+**
164606
+** This implements the PRAGMA reverse_unordered_selects=ON setting.
164607
+** (Also SQLITE_DBCONFIG_REVERSE_SCANORDER).
164608
+*/
164609
+static SQLITE_NOINLINE void whereReverseScanOrder(WhereInfo *pWInfo){
164610
+ int ii;
164611
+ for(ii=0; ii<pWInfo->pTabList->nSrc; ii++){
164612
+ SrcItem *pItem = &pWInfo->pTabList->a[ii];
164613
+ if( !pItem->fg.isCte
164614
+ || pItem->u2.pCteUse->eM10d!=M10d_Yes
164615
+ || NEVER(pItem->pSelect==0)
164616
+ || pItem->pSelect->pOrderBy==0
164617
+ ){
164618
+ pWInfo->revMask |= MASKBIT(ii);
164619
+ }
164620
+ }
164621
+}
164179164622
164180164623
/*
164181164624
** Generate the beginning of the loop used for WHERE clause processing.
164182164625
** The return value is a pointer to an opaque structure that contains
164183164626
** information needed to terminate the loop. Later, the calling routine
@@ -164539,12 +164982,13 @@
164539164982
if( pWInfo->pOrderBy ){
164540164983
wherePathSolver(pWInfo, pWInfo->nRowOut+1);
164541164984
if( db->mallocFailed ) goto whereBeginError;
164542164985
}
164543164986
}
164987
+ assert( pWInfo->pTabList!=0 );
164544164988
if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){
164545
- pWInfo->revMask = ALLBITS;
164989
+ whereReverseScanOrder(pWInfo);
164546164990
}
164547164991
if( pParse->nErr ){
164548164992
goto whereBeginError;
164549164993
}
164550164994
assert( db->mallocFailed==0 );
@@ -164640,10 +165084,11 @@
164640165084
assert( !(wsFlags & WHERE_VIRTUALTABLE) || IsVirtual(pTabList->a[0].pTab) );
164641165085
if( bOnerow || (
164642165086
0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW)
164643165087
&& !IsVirtual(pTabList->a[0].pTab)
164644165088
&& (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK))
165089
+ && OptimizationEnabled(db, SQLITE_OnePass)
164645165090
)){
164646165091
pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI;
164647165092
if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){
164648165093
if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){
164649165094
bFordelete = OPFLAG_FORDELETE;
@@ -171937,14 +172382,14 @@
171937172382
** break;
171938172383
*/
171939172384
/********** Begin reduce actions **********************************************/
171940172385
YYMINORTYPE yylhsminor;
171941172386
case 0: /* explain ::= EXPLAIN */
171942
-{ pParse->explain = 1; }
172387
+{ if( pParse->pReprepare==0 ) pParse->explain = 1; }
171943172388
break;
171944172389
case 1: /* explain ::= EXPLAIN QUERY PLAN */
171945
-{ pParse->explain = 2; }
172390
+{ if( pParse->pReprepare==0 ) pParse->explain = 2; }
171946172391
break;
171947172392
case 2: /* cmdx ::= cmd */
171948172393
{ sqlite3FinishCoding(pParse); }
171949172394
break;
171950172395
case 3: /* cmd ::= BEGIN transtype trans_opt */
@@ -200394,28 +200839,54 @@
200394200839
** Growing our own isspace() routine this way is twice as fast as
200395200840
** the library isspace() function, resulting in a 7% overall performance
200396200841
** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os).
200397200842
*/
200398200843
static const char jsonIsSpace[] = {
200399
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
200400
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200401
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200402
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200403
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200404
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200405
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200406
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200407
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200408
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200409
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200410
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200411
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200412
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200413
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200414
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200844
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
200845
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200846
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200847
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200848
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200849
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200850
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200851
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200852
+
200853
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200854
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200855
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200856
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200857
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200858
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200859
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200860
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200415200861
};
200416200862
#define fast_isspace(x) (jsonIsSpace[(unsigned char)x])
200863
+
200864
+/*
200865
+** Characters that are special to JSON. Control charaters,
200866
+** '"' and '\\'.
200867
+*/
200868
+static const char jsonIsOk[256] = {
200869
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200870
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200871
+ 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
200872
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
200873
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
200874
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
200875
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
200876
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
200877
+
200878
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
200879
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
200880
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
200881
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
200882
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
200883
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
200884
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
200885
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
200886
+};
200887
+
200417200888
200418200889
#if !defined(SQLITE_DEBUG) && !defined(SQLITE_COVERAGE_TEST)
200419200890
# define VVA(X)
200420200891
#else
200421200892
# define VVA(X) X
@@ -200423,10 +200894,11 @@
200423200894
200424200895
/* Objects */
200425200896
typedef struct JsonString JsonString;
200426200897
typedef struct JsonNode JsonNode;
200427200898
typedef struct JsonParse JsonParse;
200899
+typedef struct JsonCleanup JsonCleanup;
200428200900
200429200901
/* An instance of this object represents a JSON string
200430200902
** under construction. Really, this is a generic string accumulator
200431200903
** that can be and is used to create strings other than JSON.
200432200904
*/
@@ -200437,75 +200909,120 @@
200437200909
u64 nUsed; /* Bytes of zBuf[] currently used */
200438200910
u8 bStatic; /* True if zBuf is static space */
200439200911
u8 bErr; /* True if an error has been encountered */
200440200912
char zSpace[100]; /* Initial static space */
200441200913
};
200914
+
200915
+/* A deferred cleanup task. A list of JsonCleanup objects might be
200916
+** run when the JsonParse object is destroyed.
200917
+*/
200918
+struct JsonCleanup {
200919
+ JsonCleanup *pJCNext; /* Next in a list */
200920
+ void (*xOp)(void*); /* Routine to run */
200921
+ void *pArg; /* Argument to xOp() */
200922
+};
200442200923
200443200924
/* JSON type values
200444200925
*/
200445
-#define JSON_NULL 0
200446
-#define JSON_TRUE 1
200447
-#define JSON_FALSE 2
200448
-#define JSON_INT 3
200449
-#define JSON_REAL 4
200450
-#define JSON_STRING 5
200451
-#define JSON_ARRAY 6
200452
-#define JSON_OBJECT 7
200926
+#define JSON_SUBST 0 /* Special edit node. Uses u.iPrev */
200927
+#define JSON_NULL 1
200928
+#define JSON_TRUE 2
200929
+#define JSON_FALSE 3
200930
+#define JSON_INT 4
200931
+#define JSON_REAL 5
200932
+#define JSON_STRING 6
200933
+#define JSON_ARRAY 7
200934
+#define JSON_OBJECT 8
200453200935
200454200936
/* The "subtype" set for JSON values */
200455200937
#define JSON_SUBTYPE 74 /* Ascii for "J" */
200456200938
200457200939
/*
200458200940
** Names of the various JSON types:
200459200941
*/
200460200942
static const char * const jsonType[] = {
200943
+ "subst",
200461200944
"null", "true", "false", "integer", "real", "text", "array", "object"
200462200945
};
200463200946
200464200947
/* Bit values for the JsonNode.jnFlag field
200465200948
*/
200466
-#define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */
200467
-#define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */
200468
-#define JNODE_REMOVE 0x04 /* Do not output */
200469
-#define JNODE_REPLACE 0x08 /* Replace with JsonNode.u.iReplace */
200470
-#define JNODE_PATCH 0x10 /* Patch with JsonNode.u.pPatch */
200471
-#define JNODE_APPEND 0x20 /* More ARRAY/OBJECT entries at u.iAppend */
200472
-#define JNODE_LABEL 0x40 /* Is a label of an object */
200473
-#define JNODE_JSON5 0x80 /* Node contains JSON5 enhancements */
200949
+#define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */
200950
+#define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */
200951
+#define JNODE_REMOVE 0x04 /* Do not output */
200952
+#define JNODE_REPLACE 0x08 /* Target of a JSON_SUBST node */
200953
+#define JNODE_APPEND 0x10 /* More ARRAY/OBJECT entries at u.iAppend */
200954
+#define JNODE_LABEL 0x20 /* Is a label of an object */
200955
+#define JNODE_JSON5 0x40 /* Node contains JSON5 enhancements */
200474200956
200475200957
200476
-/* A single node of parsed JSON
200958
+/* A single node of parsed JSON. An array of these nodes describes
200959
+** a parse of JSON + edits.
200960
+**
200961
+** Use the json_parse() SQL function (available when compiled with
200962
+** -DSQLITE_DEBUG) to see a dump of complete JsonParse objects, including
200963
+** a complete listing and decoding of the array of JsonNodes.
200477200964
*/
200478200965
struct JsonNode {
200479200966
u8 eType; /* One of the JSON_ type values */
200480200967
u8 jnFlags; /* JNODE flags */
200481200968
u8 eU; /* Which union element to use */
200482
- u32 n; /* Bytes of content, or number of sub-nodes */
200969
+ u32 n; /* Bytes of content for INT, REAL or STRING
200970
+ ** Number of sub-nodes for ARRAY and OBJECT
200971
+ ** Node that SUBST applies to */
200483200972
union {
200484200973
const char *zJContent; /* 1: Content for INT, REAL, and STRING */
200485200974
u32 iAppend; /* 2: More terms for ARRAY and OBJECT */
200486200975
u32 iKey; /* 3: Key for ARRAY objects in json_tree() */
200487
- u32 iReplace; /* 4: Replacement content for JNODE_REPLACE */
200488
- JsonNode *pPatch; /* 5: Node chain of patch for JNODE_PATCH */
200976
+ u32 iPrev; /* 4: Previous SUBST node, or 0 */
200489200977
} u;
200490200978
};
200491200979
200492
-/* A completely parsed JSON string
200980
+
200981
+/* A parsed and possibly edited JSON string. Lifecycle:
200982
+**
200983
+** 1. JSON comes in and is parsed into an array aNode[]. The original
200984
+** JSON text is stored in zJson.
200985
+**
200986
+** 2. Zero or more changes are made (via json_remove() or json_replace()
200987
+** or similar) to the aNode[] array.
200988
+**
200989
+** 3. A new, edited and mimified JSON string is generated from aNode
200990
+** and stored in zAlt. The JsonParse object always owns zAlt.
200991
+**
200992
+** Step 1 always happens. Step 2 and 3 may or may not happen, depending
200993
+** on the operation.
200994
+**
200995
+** aNode[].u.zJContent entries typically point into zJson. Hence zJson
200996
+** must remain valid for the lifespan of the parse. For edits,
200997
+** aNode[].u.zJContent might point to malloced space other than zJson.
200998
+** Entries in pClup are responsible for freeing that extra malloced space.
200999
+**
201000
+** When walking the parse tree in aNode[], edits are ignored if useMod is
201001
+** false.
200493201002
*/
200494201003
struct JsonParse {
200495201004
u32 nNode; /* Number of slots of aNode[] used */
200496201005
u32 nAlloc; /* Number of slots of aNode[] allocated */
200497201006
JsonNode *aNode; /* Array of nodes containing the parse */
200498
- const char *zJson; /* Original JSON string */
201007
+ char *zJson; /* Original JSON string (before edits) */
201008
+ char *zAlt; /* Revised and/or mimified JSON */
200499201009
u32 *aUp; /* Index of parent of each node */
201010
+ JsonCleanup *pClup;/* Cleanup operations prior to freeing this object */
200500201011
u16 iDepth; /* Nesting depth */
200501201012
u8 nErr; /* Number of errors seen */
200502201013
u8 oom; /* Set to true if out of memory */
201014
+ u8 bJsonIsRCStr; /* True if zJson is an RCStr */
200503201015
u8 hasNonstd; /* True if input uses non-standard features like JSON5 */
201016
+ u8 useMod; /* Actually use the edits contain inside aNode */
201017
+ u8 hasMod; /* aNode contains edits from the original zJson */
201018
+ u32 nJPRef; /* Number of references to this object */
200504201019
int nJson; /* Length of the zJson string in bytes */
201020
+ int nAlt; /* Length of alternative JSON string zAlt, in bytes */
200505201021
u32 iErr; /* Error location in zJson[] */
200506
- u32 iHold; /* Replace cache line with the lowest iHold value */
201022
+ u32 iSubst; /* Last JSON_SUBST entry in aNode[] */
201023
+ u32 iHold; /* Age of this entry in the cache for LRU replacement */
200507201024
};
200508201025
200509201026
/*
200510201027
** Maximum nesting depth of JSON for this implementation.
200511201028
**
@@ -200534,19 +201051,17 @@
200534201051
p->pCtx = pCtx;
200535201052
p->bErr = 0;
200536201053
jsonZero(p);
200537201054
}
200538201055
200539
-
200540201056
/* Free all allocated memory and reset the JsonString object back to its
200541201057
** initial state.
200542201058
*/
200543201059
static void jsonReset(JsonString *p){
200544
- if( !p->bStatic ) sqlite3_free(p->zBuf);
201060
+ if( !p->bStatic ) sqlite3RCStrUnref(p->zBuf);
200545201061
jsonZero(p);
200546201062
}
200547
-
200548201063
200549201064
/* Report an out-of-memory (OOM) condition
200550201065
*/
200551201066
static void jsonOom(JsonString *p){
200552201067
p->bErr = 1;
@@ -200560,38 +201075,61 @@
200560201075
static int jsonGrow(JsonString *p, u32 N){
200561201076
u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10;
200562201077
char *zNew;
200563201078
if( p->bStatic ){
200564201079
if( p->bErr ) return 1;
200565
- zNew = sqlite3_malloc64(nTotal);
201080
+ zNew = sqlite3RCStrNew(nTotal);
200566201081
if( zNew==0 ){
200567201082
jsonOom(p);
200568201083
return SQLITE_NOMEM;
200569201084
}
200570201085
memcpy(zNew, p->zBuf, (size_t)p->nUsed);
200571201086
p->zBuf = zNew;
200572201087
p->bStatic = 0;
200573201088
}else{
200574
- zNew = sqlite3_realloc64(p->zBuf, nTotal);
200575
- if( zNew==0 ){
200576
- jsonOom(p);
201089
+ p->zBuf = sqlite3RCStrResize(p->zBuf, nTotal);
201090
+ if( p->zBuf==0 ){
201091
+ p->bErr = 1;
201092
+ jsonZero(p);
200577201093
return SQLITE_NOMEM;
200578201094
}
200579
- p->zBuf = zNew;
200580201095
}
200581201096
p->nAlloc = nTotal;
200582201097
return SQLITE_OK;
200583201098
}
200584201099
200585201100
/* Append N bytes from zIn onto the end of the JsonString string.
200586201101
*/
200587
-static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
200588
- if( N==0 ) return;
200589
- if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return;
201102
+static SQLITE_NOINLINE void jsonAppendExpand(
201103
+ JsonString *p,
201104
+ const char *zIn,
201105
+ u32 N
201106
+){
201107
+ assert( N>0 );
201108
+ if( jsonGrow(p,N) ) return;
200590201109
memcpy(p->zBuf+p->nUsed, zIn, N);
200591201110
p->nUsed += N;
200592201111
}
201112
+static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
201113
+ if( N==0 ) return;
201114
+ if( N+p->nUsed >= p->nAlloc ){
201115
+ jsonAppendExpand(p,zIn,N);
201116
+ }else{
201117
+ memcpy(p->zBuf+p->nUsed, zIn, N);
201118
+ p->nUsed += N;
201119
+ }
201120
+}
201121
+static void jsonAppendRawNZ(JsonString *p, const char *zIn, u32 N){
201122
+ assert( N>0 );
201123
+ if( N+p->nUsed >= p->nAlloc ){
201124
+ jsonAppendExpand(p,zIn,N);
201125
+ }else{
201126
+ memcpy(p->zBuf+p->nUsed, zIn, N);
201127
+ p->nUsed += N;
201128
+ }
201129
+}
201130
+
200593201131
200594201132
/* Append formatted text (not to exceed N bytes) to the JsonString.
200595201133
*/
200596201134
static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){
200597201135
va_list ap;
@@ -200602,23 +201140,49 @@
200602201140
p->nUsed += (int)strlen(p->zBuf+p->nUsed);
200603201141
}
200604201142
200605201143
/* Append a single character
200606201144
*/
200607
-static void jsonAppendChar(JsonString *p, char c){
200608
- if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return;
201145
+static SQLITE_NOINLINE void jsonAppendCharExpand(JsonString *p, char c){
201146
+ if( jsonGrow(p,1) ) return;
200609201147
p->zBuf[p->nUsed++] = c;
200610201148
}
201149
+static void jsonAppendChar(JsonString *p, char c){
201150
+ if( p->nUsed>=p->nAlloc ){
201151
+ jsonAppendCharExpand(p,c);
201152
+ }else{
201153
+ p->zBuf[p->nUsed++] = c;
201154
+ }
201155
+}
201156
+
201157
+/* Try to force the string to be a zero-terminated RCStr string.
201158
+**
201159
+** Return true on success. Return false if an OOM prevents this
201160
+** from happening.
201161
+*/
201162
+static int jsonForceRCStr(JsonString *p){
201163
+ jsonAppendChar(p, 0);
201164
+ if( p->bErr ) return 0;
201165
+ p->nUsed--;
201166
+ if( p->bStatic==0 ) return 1;
201167
+ p->nAlloc = 0;
201168
+ p->nUsed++;
201169
+ jsonGrow(p, p->nUsed);
201170
+ p->nUsed--;
201171
+ return p->bStatic==0;
201172
+}
201173
+
200611201174
200612201175
/* Append a comma separator to the output buffer, if the previous
200613201176
** character is not '[' or '{'.
200614201177
*/
200615201178
static void jsonAppendSeparator(JsonString *p){
200616201179
char c;
200617201180
if( p->nUsed==0 ) return;
200618201181
c = p->zBuf[p->nUsed-1];
200619
- if( c!='[' && c!='{' ) jsonAppendChar(p, ',');
201182
+ if( c=='[' || c=='{' ) return;
201183
+ jsonAppendChar(p, ',');
200620201184
}
200621201185
200622201186
/* Append the N-byte string in zIn to the end of the JsonString string
200623201187
** under construction. Enclose the string in "..." and escape
200624201188
** any double-quotes or backslash characters contained within the
@@ -200628,15 +201192,20 @@
200628201192
u32 i;
200629201193
if( zIn==0 || ((N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0) ) return;
200630201194
p->zBuf[p->nUsed++] = '"';
200631201195
for(i=0; i<N; i++){
200632201196
unsigned char c = ((unsigned const char*)zIn)[i];
200633
- if( c=='"' || c=='\\' ){
201197
+ if( jsonIsOk[c] ){
201198
+ p->zBuf[p->nUsed++] = c;
201199
+ }else if( c=='"' || c=='\\' ){
200634201200
json_simple_escape:
200635201201
if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return;
200636201202
p->zBuf[p->nUsed++] = '\\';
200637
- }else if( c<=0x1f ){
201203
+ p->zBuf[p->nUsed++] = c;
201204
+ }else if( c=='\'' ){
201205
+ p->zBuf[p->nUsed++] = c;
201206
+ }else{
200638201207
static const char aSpecial[] = {
200639201208
0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0,
200640201209
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
200641201210
};
200642201211
assert( sizeof(aSpecial)==32 );
@@ -200643,23 +201212,23 @@
200643201212
assert( aSpecial['\b']=='b' );
200644201213
assert( aSpecial['\f']=='f' );
200645201214
assert( aSpecial['\n']=='n' );
200646201215
assert( aSpecial['\r']=='r' );
200647201216
assert( aSpecial['\t']=='t' );
201217
+ assert( c>=0 && c<sizeof(aSpecial) );
200648201218
if( aSpecial[c] ){
200649201219
c = aSpecial[c];
200650201220
goto json_simple_escape;
200651201221
}
200652201222
if( (p->nUsed+N+7+i > p->nAlloc) && jsonGrow(p,N+7-i)!=0 ) return;
200653201223
p->zBuf[p->nUsed++] = '\\';
200654201224
p->zBuf[p->nUsed++] = 'u';
200655201225
p->zBuf[p->nUsed++] = '0';
200656201226
p->zBuf[p->nUsed++] = '0';
200657
- p->zBuf[p->nUsed++] = '0' + (c>>4);
200658
- c = "0123456789abcdef"[c&0xf];
201227
+ p->zBuf[p->nUsed++] = "0123456789abcdef"[c>>4];
201228
+ p->zBuf[p->nUsed++] = "0123456789abcdef"[c&0xf];
200659201229
}
200660
- p->zBuf[p->nUsed++] = c;
200661201230
}
200662201231
p->zBuf[p->nUsed++] = '"';
200663201232
assert( p->nUsed<p->nAlloc );
200664201233
}
200665201234
@@ -200674,11 +201243,11 @@
200674201243
zIn++;
200675201244
N -= 2;
200676201245
while( N>0 ){
200677201246
for(i=0; i<N && zIn[i]!='\\'; i++){}
200678201247
if( i>0 ){
200679
- jsonAppendRaw(p, zIn, i);
201248
+ jsonAppendRawNZ(p, zIn, i);
200680201249
zIn += i;
200681201250
N -= i;
200682201251
if( N==0 ) break;
200683201252
}
200684201253
assert( zIn[0]=='\\' );
@@ -200685,20 +201254,20 @@
200685201254
switch( (u8)zIn[1] ){
200686201255
case '\'':
200687201256
jsonAppendChar(p, '\'');
200688201257
break;
200689201258
case 'v':
200690
- jsonAppendRaw(p, "\\u0009", 6);
201259
+ jsonAppendRawNZ(p, "\\u0009", 6);
200691201260
break;
200692201261
case 'x':
200693
- jsonAppendRaw(p, "\\u00", 4);
200694
- jsonAppendRaw(p, &zIn[2], 2);
201262
+ jsonAppendRawNZ(p, "\\u00", 4);
201263
+ jsonAppendRawNZ(p, &zIn[2], 2);
200695201264
zIn += 2;
200696201265
N -= 2;
200697201266
break;
200698201267
case '0':
200699
- jsonAppendRaw(p, "\\u0000", 6);
201268
+ jsonAppendRawNZ(p, "\\u0000", 6);
200700201269
break;
200701201270
case '\r':
200702201271
if( zIn[2]=='\n' ){
200703201272
zIn++;
200704201273
N--;
@@ -200712,11 +201281,11 @@
200712201281
assert( 0xa8==(u8)zIn[3] || 0xa9==(u8)zIn[3] );
200713201282
zIn += 2;
200714201283
N -= 2;
200715201284
break;
200716201285
default:
200717
- jsonAppendRaw(p, zIn, 2);
201286
+ jsonAppendRawNZ(p, zIn, 2);
200718201287
break;
200719201288
}
200720201289
zIn += 2;
200721201290
N -= 2;
200722201291
}
@@ -200742,15 +201311,16 @@
200742201311
int rc = sqlite3DecOrHexToI64(zIn, &i);
200743201312
if( rc<=1 ){
200744201313
jsonPrintf(100,p,"%lld",i);
200745201314
}else{
200746201315
assert( rc==2 );
200747
- jsonAppendRaw(p, "9.0e999", 7);
201316
+ jsonAppendRawNZ(p, "9.0e999", 7);
200748201317
}
200749201318
return;
200750201319
}
200751
- jsonAppendRaw(p, zIn, N);
201320
+ assert( N>0 );
201321
+ jsonAppendRawNZ(p, zIn, N);
200752201322
}
200753201323
200754201324
/*
200755201325
** The zIn[0..N] string is a JSON5 real literal. Append to p a translation
200756201326
** of the string literal that standard JSON and that omits all JSON5
@@ -200778,11 +201348,11 @@
200778201348
jsonAppendChar(p, '0');
200779201349
break;
200780201350
}
200781201351
}
200782201352
if( N>0 ){
200783
- jsonAppendRaw(p, zIn, N);
201353
+ jsonAppendRawNZ(p, zIn, N);
200784201354
}
200785201355
}
200786201356
200787201357
200788201358
@@ -200794,11 +201364,11 @@
200794201364
JsonString *p, /* Append to this JSON string */
200795201365
sqlite3_value *pValue /* Value to append */
200796201366
){
200797201367
switch( sqlite3_value_type(pValue) ){
200798201368
case SQLITE_NULL: {
200799
- jsonAppendRaw(p, "null", 4);
201369
+ jsonAppendRawNZ(p, "null", 4);
200800201370
break;
200801201371
}
200802201372
case SQLITE_FLOAT: {
200803201373
jsonPrintf(100, p, "%!0.15g", sqlite3_value_double(pValue));
200804201374
break;
@@ -200830,19 +201400,29 @@
200830201400
}
200831201401
}
200832201402
200833201403
200834201404
/* Make the JSON in p the result of the SQL function.
201405
+**
201406
+** The JSON string is reset.
200835201407
*/
200836201408
static void jsonResult(JsonString *p){
200837201409
if( p->bErr==0 ){
200838
- sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
200839
- p->bStatic ? SQLITE_TRANSIENT : sqlite3_free,
200840
- SQLITE_UTF8);
200841
- jsonZero(p);
201410
+ if( p->bStatic ){
201411
+ sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
201412
+ SQLITE_TRANSIENT, SQLITE_UTF8);
201413
+ }else if( jsonForceRCStr(p) ){
201414
+ sqlite3RCStrRef(p->zBuf);
201415
+ sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
201416
+ (void(*)(void*))sqlite3RCStrUnref,
201417
+ SQLITE_UTF8);
201418
+ }
200842201419
}
200843
- assert( p->bStatic );
201420
+ if( p->bErr==1 ){
201421
+ sqlite3_result_error_nomem(p->pCtx);
201422
+ }
201423
+ jsonReset(p);
200844201424
}
200845201425
200846201426
/**************************************************************************
200847201427
** Utility routines for dealing with JsonNode and JsonParse objects
200848201428
**************************************************************************/
@@ -200863,58 +201443,117 @@
200863201443
/*
200864201444
** Reclaim all memory allocated by a JsonParse object. But do not
200865201445
** delete the JsonParse object itself.
200866201446
*/
200867201447
static void jsonParseReset(JsonParse *pParse){
200868
- sqlite3_free(pParse->aNode);
200869
- pParse->aNode = 0;
201448
+ while( pParse->pClup ){
201449
+ JsonCleanup *pTask = pParse->pClup;
201450
+ pParse->pClup = pTask->pJCNext;
201451
+ pTask->xOp(pTask->pArg);
201452
+ sqlite3_free(pTask);
201453
+ }
201454
+ assert( pParse->nJPRef<=1 );
201455
+ if( pParse->aNode ){
201456
+ sqlite3_free(pParse->aNode);
201457
+ pParse->aNode = 0;
201458
+ }
200870201459
pParse->nNode = 0;
200871201460
pParse->nAlloc = 0;
200872
- sqlite3_free(pParse->aUp);
200873
- pParse->aUp = 0;
201461
+ if( pParse->aUp ){
201462
+ sqlite3_free(pParse->aUp);
201463
+ pParse->aUp = 0;
201464
+ }
201465
+ if( pParse->bJsonIsRCStr ){
201466
+ sqlite3RCStrUnref(pParse->zJson);
201467
+ pParse->zJson = 0;
201468
+ pParse->bJsonIsRCStr = 0;
201469
+ }
201470
+ if( pParse->zAlt ){
201471
+ sqlite3RCStrUnref(pParse->zAlt);
201472
+ pParse->zAlt = 0;
201473
+ }
200874201474
}
200875201475
200876201476
/*
200877201477
** Free a JsonParse object that was obtained from sqlite3_malloc().
201478
+**
201479
+** Note that destroying JsonParse might call sqlite3RCStrUnref() to
201480
+** destroy the zJson value. The RCStr object might recursively invoke
201481
+** JsonParse to destroy this pParse object again. Take care to ensure
201482
+** that this recursive destructor sequence terminates harmlessly.
200878201483
*/
200879201484
static void jsonParseFree(JsonParse *pParse){
200880
- jsonParseReset(pParse);
200881
- sqlite3_free(pParse);
201485
+ if( pParse->nJPRef>1 ){
201486
+ pParse->nJPRef--;
201487
+ }else{
201488
+ jsonParseReset(pParse);
201489
+ sqlite3_free(pParse);
201490
+ }
201491
+}
201492
+
201493
+/*
201494
+** Add a cleanup task to the JsonParse object.
201495
+**
201496
+** If an OOM occurs, the cleanup operation happens immediately
201497
+** and this function returns SQLITE_NOMEM.
201498
+*/
201499
+static int jsonParseAddCleanup(
201500
+ JsonParse *pParse, /* Add the cleanup task to this parser */
201501
+ void(*xOp)(void*), /* The cleanup task */
201502
+ void *pArg /* Argument to the cleanup */
201503
+){
201504
+ JsonCleanup *pTask = sqlite3_malloc64( sizeof(*pTask) );
201505
+ if( pTask==0 ){
201506
+ pParse->oom = 1;
201507
+ xOp(pArg);
201508
+ return SQLITE_ERROR;
201509
+ }
201510
+ pTask->pJCNext = pParse->pClup;
201511
+ pParse->pClup = pTask;
201512
+ pTask->xOp = xOp;
201513
+ pTask->pArg = pArg;
201514
+ return SQLITE_OK;
200882201515
}
200883201516
200884201517
/*
200885201518
** Convert the JsonNode pNode into a pure JSON string and
200886201519
** append to pOut. Subsubstructure is also included. Return
200887201520
** the number of JsonNode objects that are encoded.
200888201521
*/
200889201522
static void jsonRenderNode(
201523
+ JsonParse *pParse, /* the complete parse of the JSON */
200890201524
JsonNode *pNode, /* The node to render */
200891
- JsonString *pOut, /* Write JSON here */
200892
- sqlite3_value **aReplace /* Replacement values */
201525
+ JsonString *pOut /* Write JSON here */
200893201526
){
200894201527
assert( pNode!=0 );
200895
- if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){
200896
- if( (pNode->jnFlags & JNODE_REPLACE)!=0 && ALWAYS(aReplace!=0) ){
200897
- assert( pNode->eU==4 );
200898
- jsonAppendValue(pOut, aReplace[pNode->u.iReplace]);
200899
- return;
200900
- }
200901
- assert( pNode->eU==5 );
200902
- pNode = pNode->u.pPatch;
201528
+ while( (pNode->jnFlags & JNODE_REPLACE)!=0 && pParse->useMod ){
201529
+ u32 idx = (u32)(pNode - pParse->aNode);
201530
+ u32 i = pParse->iSubst;
201531
+ while( 1 /*exit-by-break*/ ){
201532
+ assert( i<pParse->nNode );
201533
+ assert( pParse->aNode[i].eType==JSON_SUBST );
201534
+ assert( pParse->aNode[i].eU==4 );
201535
+ assert( pParse->aNode[i].u.iPrev<i );
201536
+ if( pParse->aNode[i].n==idx ){
201537
+ pNode = &pParse->aNode[i+1];
201538
+ break;
201539
+ }
201540
+ i = pParse->aNode[i].u.iPrev;
201541
+ }
200903201542
}
200904201543
switch( pNode->eType ){
200905201544
default: {
200906201545
assert( pNode->eType==JSON_NULL );
200907
- jsonAppendRaw(pOut, "null", 4);
201546
+ jsonAppendRawNZ(pOut, "null", 4);
200908201547
break;
200909201548
}
200910201549
case JSON_TRUE: {
200911
- jsonAppendRaw(pOut, "true", 4);
201550
+ jsonAppendRawNZ(pOut, "true", 4);
200912201551
break;
200913201552
}
200914201553
case JSON_FALSE: {
200915
- jsonAppendRaw(pOut, "false", 5);
201554
+ jsonAppendRawNZ(pOut, "false", 5);
200916201555
break;
200917201556
}
200918201557
case JSON_STRING: {
200919201558
assert( pNode->eU==1 );
200920201559
if( pNode->jnFlags & JNODE_RAW ){
@@ -200926,46 +201565,50 @@
200926201565
jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
200927201566
}
200928201567
}else if( pNode->jnFlags & JNODE_JSON5 ){
200929201568
jsonAppendNormalizedString(pOut, pNode->u.zJContent, pNode->n);
200930201569
}else{
200931
- jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
201570
+ assert( pNode->n>0 );
201571
+ jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n);
200932201572
}
200933201573
break;
200934201574
}
200935201575
case JSON_REAL: {
200936201576
assert( pNode->eU==1 );
200937201577
if( pNode->jnFlags & JNODE_JSON5 ){
200938201578
jsonAppendNormalizedReal(pOut, pNode->u.zJContent, pNode->n);
200939201579
}else{
200940
- jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
201580
+ assert( pNode->n>0 );
201581
+ jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n);
200941201582
}
200942201583
break;
200943201584
}
200944201585
case JSON_INT: {
200945201586
assert( pNode->eU==1 );
200946201587
if( pNode->jnFlags & JNODE_JSON5 ){
200947201588
jsonAppendNormalizedInt(pOut, pNode->u.zJContent, pNode->n);
200948201589
}else{
200949
- jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
201590
+ assert( pNode->n>0 );
201591
+ jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n);
200950201592
}
200951201593
break;
200952201594
}
200953201595
case JSON_ARRAY: {
200954201596
u32 j = 1;
200955201597
jsonAppendChar(pOut, '[');
200956201598
for(;;){
200957201599
while( j<=pNode->n ){
200958
- if( (pNode[j].jnFlags & JNODE_REMOVE)==0 ){
201600
+ if( (pNode[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ){
200959201601
jsonAppendSeparator(pOut);
200960
- jsonRenderNode(&pNode[j], pOut, aReplace);
201602
+ jsonRenderNode(pParse, &pNode[j], pOut);
200961201603
}
200962201604
j += jsonNodeSize(&pNode[j]);
200963201605
}
200964201606
if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
201607
+ if( pParse->useMod==0 ) break;
200965201608
assert( pNode->eU==2 );
200966
- pNode = &pNode[pNode->u.iAppend];
201609
+ pNode = &pParse->aNode[pNode->u.iAppend];
200967201610
j = 1;
200968201611
}
200969201612
jsonAppendChar(pOut, ']');
200970201613
break;
200971201614
}
@@ -200972,21 +201615,22 @@
200972201615
case JSON_OBJECT: {
200973201616
u32 j = 1;
200974201617
jsonAppendChar(pOut, '{');
200975201618
for(;;){
200976201619
while( j<=pNode->n ){
200977
- if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){
201620
+ if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ){
200978201621
jsonAppendSeparator(pOut);
200979
- jsonRenderNode(&pNode[j], pOut, aReplace);
201622
+ jsonRenderNode(pParse, &pNode[j], pOut);
200980201623
jsonAppendChar(pOut, ':');
200981
- jsonRenderNode(&pNode[j+1], pOut, aReplace);
201624
+ jsonRenderNode(pParse, &pNode[j+1], pOut);
200982201625
}
200983201626
j += 1 + jsonNodeSize(&pNode[j+1]);
200984201627
}
200985201628
if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
201629
+ if( pParse->useMod==0 ) break;
200986201630
assert( pNode->eU==2 );
200987
- pNode = &pNode[pNode->u.iAppend];
201631
+ pNode = &pParse->aNode[pNode->u.iAppend];
200988201632
j = 1;
200989201633
}
200990201634
jsonAppendChar(pOut, '}');
200991201635
break;
200992201636
}
@@ -200995,19 +201639,30 @@
200995201639
200996201640
/*
200997201641
** Return a JsonNode and all its descendants as a JSON string.
200998201642
*/
200999201643
static void jsonReturnJson(
201644
+ JsonParse *pParse, /* The complete JSON */
201000201645
JsonNode *pNode, /* Node to return */
201001201646
sqlite3_context *pCtx, /* Return value for this function */
201002
- sqlite3_value **aReplace /* Array of replacement values */
201647
+ int bGenerateAlt /* Also store the rendered text in zAlt */
201003201648
){
201004201649
JsonString s;
201005
- jsonInit(&s, pCtx);
201006
- jsonRenderNode(pNode, &s, aReplace);
201007
- jsonResult(&s);
201008
- sqlite3_result_subtype(pCtx, JSON_SUBTYPE);
201650
+ if( pParse->oom ){
201651
+ sqlite3_result_error_nomem(pCtx);
201652
+ return;
201653
+ }
201654
+ if( pParse->nErr==0 ){
201655
+ jsonInit(&s, pCtx);
201656
+ jsonRenderNode(pParse, pNode, &s);
201657
+ if( bGenerateAlt && pParse->zAlt==0 && jsonForceRCStr(&s) ){
201658
+ pParse->zAlt = sqlite3RCStrRef(s.zBuf);
201659
+ pParse->nAlt = s.nUsed;
201660
+ }
201661
+ jsonResult(&s);
201662
+ sqlite3_result_subtype(pCtx, JSON_SUBTYPE);
201663
+ }
201009201664
}
201010201665
201011201666
/*
201012201667
** Translate a single byte of Hex into an integer.
201013201668
** This routine only works if h really is a valid hexadecimal
@@ -201041,13 +201696,13 @@
201041201696
201042201697
/*
201043201698
** Make the JsonNode the return value of the function.
201044201699
*/
201045201700
static void jsonReturn(
201701
+ JsonParse *pParse, /* Complete JSON parse tree */
201046201702
JsonNode *pNode, /* Node to return */
201047
- sqlite3_context *pCtx, /* Return value for this function */
201048
- sqlite3_value **aReplace /* Array of replacement values */
201703
+ sqlite3_context *pCtx /* Return value for this function */
201049201704
){
201050201705
switch( pNode->eType ){
201051201706
default: {
201052201707
assert( pNode->eType==JSON_NULL );
201053201708
sqlite3_result_null(pCtx);
@@ -201064,11 +201719,10 @@
201064201719
case JSON_INT: {
201065201720
sqlite3_int64 i = 0;
201066201721
int rc;
201067201722
int bNeg = 0;
201068201723
const char *z;
201069
-
201070201724
201071201725
assert( pNode->eU==1 );
201072201726
z = pNode->u.zJContent;
201073201727
if( z[0]=='-' ){ z++; bNeg = 1; }
201074201728
else if( z[0]=='+' ){ z++; }
@@ -201190,11 +201844,11 @@
201190201844
}
201191201845
break;
201192201846
}
201193201847
case JSON_ARRAY:
201194201848
case JSON_OBJECT: {
201195
- jsonReturnJson(pNode, pCtx, aReplace);
201849
+ jsonReturnJson(pParse, pNode, pCtx, 0);
201196201850
break;
201197201851
}
201198201852
}
201199201853
}
201200201854
@@ -201212,10 +201866,16 @@
201212201866
#else
201213201867
# define JSON_NOINLINE
201214201868
#endif
201215201869
201216201870
201871
+/*
201872
+** Add a single node to pParse->aNode after first expanding the
201873
+** size of the aNode array. Return the index of the new node.
201874
+**
201875
+** If an OOM error occurs, set pParse->oom and return -1.
201876
+*/
201217201877
static JSON_NOINLINE int jsonParseAddNodeExpand(
201218201878
JsonParse *pParse, /* Append the node to this object */
201219201879
u32 eType, /* Node type */
201220201880
u32 n, /* Content size or sub-node count */
201221201881
const char *zContent /* Content */
@@ -201228,11 +201888,11 @@
201228201888
pNew = sqlite3_realloc64(pParse->aNode, sizeof(JsonNode)*nNew);
201229201889
if( pNew==0 ){
201230201890
pParse->oom = 1;
201231201891
return -1;
201232201892
}
201233
- pParse->nAlloc = nNew;
201893
+ pParse->nAlloc = sqlite3_msize(pNew)/sizeof(JsonNode);
201234201894
pParse->aNode = pNew;
201235201895
assert( pParse->nNode<pParse->nAlloc );
201236201896
return jsonParseAddNode(pParse, eType, n, zContent);
201237201897
}
201238201898
@@ -201246,11 +201906,12 @@
201246201906
u32 eType, /* Node type */
201247201907
u32 n, /* Content size or sub-node count */
201248201908
const char *zContent /* Content */
201249201909
){
201250201910
JsonNode *p;
201251
- if( pParse->aNode==0 || pParse->nNode>=pParse->nAlloc ){
201911
+ assert( pParse->aNode!=0 || pParse->nNode>=pParse->nAlloc );
201912
+ if( pParse->nNode>=pParse->nAlloc ){
201252201913
return jsonParseAddNodeExpand(pParse, eType, n, zContent);
201253201914
}
201254201915
p = &pParse->aNode[pParse->nNode];
201255201916
p->eType = (u8)(eType & 0xff);
201256201917
p->jnFlags = (u8)(eType >> 8);
@@ -201257,10 +201918,54 @@
201257201918
VVA( p->eU = zContent ? 1 : 0 );
201258201919
p->n = n;
201259201920
p->u.zJContent = zContent;
201260201921
return pParse->nNode++;
201261201922
}
201923
+
201924
+/*
201925
+** Add an array of new nodes to the current pParse->aNode array.
201926
+** Return the index of the first node added.
201927
+**
201928
+** If an OOM error occurs, set pParse->oom.
201929
+*/
201930
+static void jsonParseAddNodeArray(
201931
+ JsonParse *pParse, /* Append the node to this object */
201932
+ JsonNode *aNode, /* Array of nodes to add */
201933
+ u32 nNode /* Number of elements in aNew */
201934
+){
201935
+ if( pParse->nNode + nNode > pParse->nAlloc ){
201936
+ u32 nNew = pParse->nNode + nNode;
201937
+ JsonNode *aNew = sqlite3_realloc64(pParse->aNode, nNew*sizeof(JsonNode));
201938
+ if( aNew==0 ){
201939
+ pParse->oom = 1;
201940
+ return;
201941
+ }
201942
+ pParse->nAlloc = sqlite3_msize(aNew)/sizeof(JsonNode);
201943
+ pParse->aNode = aNew;
201944
+ }
201945
+ memcpy(&pParse->aNode[pParse->nNode], aNode, nNode*sizeof(JsonNode));
201946
+ pParse->nNode += nNode;
201947
+}
201948
+
201949
+/*
201950
+** Add a new JSON_SUBST node. The node immediately following
201951
+** this new node will be the substitute content for iNode.
201952
+*/
201953
+static int jsonParseAddSubstNode(
201954
+ JsonParse *pParse, /* Add the JSON_SUBST here */
201955
+ u32 iNode /* References this node */
201956
+){
201957
+ int idx = jsonParseAddNode(pParse, JSON_SUBST, iNode, 0);
201958
+ if( pParse->oom ) return -1;
201959
+ pParse->aNode[iNode].jnFlags |= JNODE_REPLACE;
201960
+ pParse->aNode[idx].eU = 4;
201961
+ pParse->aNode[idx].u.iPrev = pParse->iSubst;
201962
+ pParse->iSubst = idx;
201963
+ pParse->hasMod = 1;
201964
+ pParse->useMod = 1;
201965
+ return idx;
201966
+}
201262201967
201263201968
/*
201264201969
** Return true if z[] begins with 2 (or more) hexadecimal digits
201265201970
*/
201266201971
static int jsonIs2Hex(const char *z){
@@ -201424,11 +202129,11 @@
201424202129
** Parse a single JSON value which begins at pParse->zJson[i]. Return the
201425202130
** index of the first character past the end of the value parsed.
201426202131
**
201427202132
** Special return values:
201428202133
**
201429
-** 0 End if input
202134
+** 0 End of input
201430202135
** -1 Syntax error
201431202136
** -2 '}' seen
201432202137
** -3 ']' seen
201433202138
** -4 ',' seen
201434202139
** -5 ':' seen
@@ -201599,19 +202304,16 @@
201599202304
case '"':
201600202305
/* Parse string */
201601202306
jnFlags = 0;
201602202307
parse_string:
201603202308
cDelim = z[i];
201604
- j = i+1;
201605
- for(;;){
202309
+ for(j=i+1; 1; j++){
202310
+ if( jsonIsOk[(unsigned char)z[j]] ) continue;
201606202311
c = z[j];
201607
- if( (c & ~0x1f)==0 ){
201608
- /* Control characters are not allowed in strings */
201609
- pParse->iErr = j;
201610
- return -1;
201611
- }
201612
- if( c=='\\' ){
202312
+ if( c==cDelim ){
202313
+ break;
202314
+ }else if( c=='\\' ){
201613202315
c = z[++j];
201614202316
if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f'
201615202317
|| c=='n' || c=='r' || c=='t'
201616202318
|| (c=='u' && jsonIs4Hex(&z[j+1])) ){
201617202319
jnFlags |= JNODE_ESCAPE;
@@ -201627,14 +202329,15 @@
201627202329
pParse->hasNonstd = 1;
201628202330
}else{
201629202331
pParse->iErr = j;
201630202332
return -1;
201631202333
}
201632
- }else if( c==cDelim ){
201633
- break;
202334
+ }else if( c<=0x1f ){
202335
+ /* Control characters are not allowed in strings */
202336
+ pParse->iErr = j;
202337
+ return -1;
201634202338
}
201635
- j++;
201636202339
}
201637202340
jsonParseAddNode(pParse, JSON_STRING | (jnFlags<<8), j+1-i, &z[i]);
201638202341
return j+1;
201639202342
}
201640202343
case 't': {
@@ -201866,24 +202569,22 @@
201866202569
} /* End switch(z[i]) */
201867202570
}
201868202571
201869202572
/*
201870202573
** Parse a complete JSON string. Return 0 on success or non-zero if there
201871
-** are any errors. If an error occurs, free all memory associated with
201872
-** pParse.
202574
+** are any errors. If an error occurs, free all memory held by pParse,
202575
+** but not pParse itself.
201873202576
**
201874
-** pParse is uninitialized when this routine is called.
202577
+** pParse must be initialized to an empty parse object prior to calling
202578
+** this routine.
201875202579
*/
201876202580
static int jsonParse(
201877202581
JsonParse *pParse, /* Initialize and fill this JsonParse object */
201878
- sqlite3_context *pCtx, /* Report errors here */
201879
- const char *zJson /* Input JSON text to be parsed */
202582
+ sqlite3_context *pCtx /* Report errors here */
201880202583
){
201881202584
int i;
201882
- memset(pParse, 0, sizeof(*pParse));
201883
- if( zJson==0 ) return 1;
201884
- pParse->zJson = zJson;
202585
+ const char *zJson = pParse->zJson;
201885202586
i = jsonParseValue(pParse, 0);
201886202587
if( pParse->oom ) i = -1;
201887202588
if( i>0 ){
201888202589
assert( pParse->iDepth==0 );
201889202590
while( fast_isspace(zJson[i]) ) i++;
@@ -201907,10 +202608,11 @@
201907202608
jsonParseReset(pParse);
201908202609
return 1;
201909202610
}
201910202611
return 0;
201911202612
}
202613
+
201912202614
201913202615
/* Mark node i of pParse as being a child of iParent. Call recursively
201914202616
** to fill in all the descendants of node i.
201915202617
*/
201916202618
static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){
@@ -201957,51 +202659,77 @@
201957202659
*/
201958202660
#define JSON_CACHE_ID (-429938) /* First cache entry */
201959202661
#define JSON_CACHE_SZ 4 /* Max number of cache entries */
201960202662
201961202663
/*
201962
-** Obtain a complete parse of the JSON found in the first argument
201963
-** of the argv array. Use the sqlite3_get_auxdata() cache for this
201964
-** parse if it is available. If the cache is not available or if it
201965
-** is no longer valid, parse the JSON again and return the new parse,
201966
-** and also register the new parse so that it will be available for
202664
+** Obtain a complete parse of the JSON found in the pJson argument
202665
+**
202666
+** Use the sqlite3_get_auxdata() cache to find a preexisting parse
202667
+** if it is available. If the cache is not available or if it
202668
+** is no longer valid, parse the JSON again and return the new parse.
202669
+** Also register the new parse so that it will be available for
201967202670
** future sqlite3_get_auxdata() calls.
201968202671
**
201969202672
** If an error occurs and pErrCtx!=0 then report the error on pErrCtx
201970202673
** and return NULL.
201971202674
**
201972
-** If an error occurs and pErrCtx==0 then return the Parse object with
201973
-** JsonParse.nErr non-zero. If the caller invokes this routine with
201974
-** pErrCtx==0 and it gets back a JsonParse with nErr!=0, then the caller
201975
-** is responsible for invoking jsonParseFree() on the returned value.
201976
-** But the caller may invoke jsonParseFree() *only* if pParse->nErr!=0.
202675
+** The returned pointer (if it is not NULL) is owned by the cache in
202676
+** most cases, not the caller. The caller does NOT need to invoke
202677
+** jsonParseFree(), in most cases.
202678
+**
202679
+** Except, if an error occurs and pErrCtx==0 then return the JsonParse
202680
+** object with JsonParse.nErr non-zero and the caller will own the JsonParse
202681
+** object. In that case, it will be the responsibility of the caller to
202682
+** invoke jsonParseFree(). To summarize:
202683
+**
202684
+** pErrCtx!=0 || p->nErr==0 ==> Return value p is owned by the
202685
+** cache. Call does not need to
202686
+** free it.
202687
+**
202688
+** pErrCtx==0 && p->nErr!=0 ==> Return value is owned by the caller
202689
+** and so the caller must free it.
201977202690
*/
201978202691
static JsonParse *jsonParseCached(
201979
- sqlite3_context *pCtx,
201980
- sqlite3_value **argv,
201981
- sqlite3_context *pErrCtx
202692
+ sqlite3_context *pCtx, /* Context to use for cache search */
202693
+ sqlite3_value *pJson, /* Function param containing JSON text */
202694
+ sqlite3_context *pErrCtx, /* Write parse errors here if not NULL */
202695
+ int bUnedited /* No prior edits allowed */
201982202696
){
201983
- const char *zJson = (const char*)sqlite3_value_text(argv[0]);
201984
- int nJson = sqlite3_value_bytes(argv[0]);
202697
+ char *zJson = (char*)sqlite3_value_text(pJson);
202698
+ int nJson = sqlite3_value_bytes(pJson);
201985202699
JsonParse *p;
201986202700
JsonParse *pMatch = 0;
201987202701
int iKey;
201988202702
int iMinKey = 0;
201989202703
u32 iMinHold = 0xffffffff;
201990202704
u32 iMaxHold = 0;
202705
+ int bJsonRCStr;
202706
+
201991202707
if( zJson==0 ) return 0;
201992202708
for(iKey=0; iKey<JSON_CACHE_SZ; iKey++){
201993202709
p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iKey);
201994202710
if( p==0 ){
201995202711
iMinKey = iKey;
201996202712
break;
201997202713
}
201998202714
if( pMatch==0
201999202715
&& p->nJson==nJson
202000
- && memcmp(p->zJson,zJson,nJson)==0
202716
+ && (p->hasMod==0 || bUnedited==0)
202717
+ && (p->zJson==zJson || memcmp(p->zJson,zJson,nJson)==0)
202718
+ ){
202719
+ p->nErr = 0;
202720
+ p->useMod = 0;
202721
+ pMatch = p;
202722
+ }else
202723
+ if( pMatch==0
202724
+ && p->zAlt!=0
202725
+ && bUnedited==0
202726
+ && p->nAlt==nJson
202727
+ && memcmp(p->zAlt, zJson, nJson)==0
202001202728
){
202002202729
p->nErr = 0;
202730
+ p->useMod = 1;
202003202731
pMatch = p;
202004202732
}else if( p->iHold<iMinHold ){
202005202733
iMinHold = p->iHold;
202006202734
iMinKey = iKey;
202007202735
}
@@ -202008,32 +202736,48 @@
202008202736
if( p->iHold>iMaxHold ){
202009202737
iMaxHold = p->iHold;
202010202738
}
202011202739
}
202012202740
if( pMatch ){
202741
+ /* The input JSON text was found in the cache. Use the preexisting
202742
+ ** parse of this JSON */
202013202743
pMatch->nErr = 0;
202014202744
pMatch->iHold = iMaxHold+1;
202745
+ assert( pMatch->nJPRef>0 ); /* pMatch is owned by the cache */
202015202746
return pMatch;
202016202747
}
202017
- p = sqlite3_malloc64( sizeof(*p) + nJson + 1 );
202748
+
202749
+ /* The input JSON was not found anywhere in the cache. We will need
202750
+ ** to parse it ourselves and generate a new JsonParse object.
202751
+ */
202752
+ bJsonRCStr = sqlite3ValueIsOfClass(pJson,(void(*)(void*))sqlite3RCStrUnref);
202753
+ p = sqlite3_malloc64( sizeof(*p) + (bJsonRCStr ? 0 : nJson+1) );
202018202754
if( p==0 ){
202019202755
sqlite3_result_error_nomem(pCtx);
202020202756
return 0;
202021202757
}
202022202758
memset(p, 0, sizeof(*p));
202023
- p->zJson = (char*)&p[1];
202024
- memcpy((char*)p->zJson, zJson, nJson+1);
202025
- if( jsonParse(p, pErrCtx, p->zJson) ){
202759
+ if( bJsonRCStr ){
202760
+ p->zJson = sqlite3RCStrRef(zJson);
202761
+ p->bJsonIsRCStr = 1;
202762
+ }else{
202763
+ p->zJson = (char*)&p[1];
202764
+ memcpy(p->zJson, zJson, nJson+1);
202765
+ }
202766
+ p->nJPRef = 1;
202767
+ if( jsonParse(p, pErrCtx) ){
202026202768
if( pErrCtx==0 ){
202027202769
p->nErr = 1;
202770
+ assert( p->nJPRef==1 ); /* Caller will own the new JsonParse object p */
202028202771
return p;
202029202772
}
202030
- sqlite3_free(p);
202773
+ jsonParseFree(p);
202031202774
return 0;
202032202775
}
202033202776
p->nJson = nJson;
202034202777
p->iHold = iMaxHold+1;
202778
+ /* Transfer ownership of the new JsonParse to the cache */
202035202779
sqlite3_set_auxdata(pCtx, JSON_CACHE_ID+iMinKey, p,
202036202780
(void(*)(void*))jsonParseFree);
202037202781
return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iMinKey);
202038202782
}
202039202783
@@ -202080,13 +202824,30 @@
202080202824
int *pApnd, /* Append nodes to complete path if not NULL */
202081202825
const char **pzErr /* Make *pzErr point to any syntax error in zPath */
202082202826
){
202083202827
u32 i, j, nKey;
202084202828
const char *zKey;
202085
- JsonNode *pRoot = &pParse->aNode[iRoot];
202829
+ JsonNode *pRoot;
202830
+ if( pParse->oom ) return 0;
202831
+ pRoot = &pParse->aNode[iRoot];
202832
+ while( (pRoot->jnFlags & JNODE_REPLACE)!=0 && pParse->useMod ){
202833
+ u32 idx = (u32)(pRoot - pParse->aNode);
202834
+ i = pParse->iSubst;
202835
+ while( 1 /*exit-by-break*/ ){
202836
+ assert( i<pParse->nNode );
202837
+ assert( pParse->aNode[i].eType==JSON_SUBST );
202838
+ assert( pParse->aNode[i].eU==4 );
202839
+ assert( pParse->aNode[i].u.iPrev<i );
202840
+ if( pParse->aNode[i].n==idx ){
202841
+ pRoot = &pParse->aNode[i+1];
202842
+ iRoot = i+1;
202843
+ break;
202844
+ }
202845
+ i = pParse->aNode[i].u.iPrev;
202846
+ }
202847
+ }
202086202848
if( zPath[0]==0 ) return pRoot;
202087
- if( pRoot->jnFlags & JNODE_REPLACE ) return 0;
202088202849
if( zPath[0]=='.' ){
202089202850
if( pRoot->eType!=JSON_OBJECT ) return 0;
202090202851
zPath++;
202091202852
if( zPath[0]=='"' ){
202092202853
zKey = zPath + 1;
@@ -202116,27 +202877,29 @@
202116202877
}
202117202878
j++;
202118202879
j += jsonNodeSize(&pRoot[j]);
202119202880
}
202120202881
if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
202882
+ if( pParse->useMod==0 ) break;
202121202883
assert( pRoot->eU==2 );
202122
- iRoot += pRoot->u.iAppend;
202884
+ iRoot = pRoot->u.iAppend;
202123202885
pRoot = &pParse->aNode[iRoot];
202124202886
j = 1;
202125202887
}
202126202888
if( pApnd ){
202127202889
u32 iStart, iLabel;
202128202890
JsonNode *pNode;
202891
+ assert( pParse->useMod );
202129202892
iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
202130202893
iLabel = jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
202131202894
zPath += i;
202132202895
pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
202133202896
if( pParse->oom ) return 0;
202134202897
if( pNode ){
202135202898
pRoot = &pParse->aNode[iRoot];
202136202899
assert( pRoot->eU==0 );
202137
- pRoot->u.iAppend = iStart - iRoot;
202900
+ pRoot->u.iAppend = iStart;
202138202901
pRoot->jnFlags |= JNODE_APPEND;
202139202902
VVA( pRoot->eU = 2 );
202140202903
pParse->aNode[iLabel].jnFlags |= JNODE_RAW;
202141202904
}
202142202905
return pNode;
@@ -202153,16 +202916,17 @@
202153202916
JsonNode *pBase = pRoot;
202154202917
int iBase = iRoot;
202155202918
if( pRoot->eType!=JSON_ARRAY ) return 0;
202156202919
for(;;){
202157202920
while( j<=pBase->n ){
202158
- if( (pBase[j].jnFlags & JNODE_REMOVE)==0 ) i++;
202921
+ if( (pBase[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ) i++;
202159202922
j += jsonNodeSize(&pBase[j]);
202160202923
}
202161202924
if( (pBase->jnFlags & JNODE_APPEND)==0 ) break;
202925
+ if( pParse->useMod==0 ) break;
202162202926
assert( pBase->eU==2 );
202163
- iBase += pBase->u.iAppend;
202927
+ iBase = pBase->u.iAppend;
202164202928
pBase = &pParse->aNode[iBase];
202165202929
j = 1;
202166202930
}
202167202931
j = 2;
202168202932
if( zPath[2]=='-' && sqlite3Isdigit(zPath[3]) ){
@@ -202186,33 +202950,37 @@
202186202950
}
202187202951
if( pRoot->eType!=JSON_ARRAY ) return 0;
202188202952
zPath += j + 1;
202189202953
j = 1;
202190202954
for(;;){
202191
- while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){
202192
- if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--;
202955
+ while( j<=pRoot->n
202956
+ && (i>0 || ((pRoot[j].jnFlags & JNODE_REMOVE)!=0 && pParse->useMod))
202957
+ ){
202958
+ if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ) i--;
202193202959
j += jsonNodeSize(&pRoot[j]);
202194202960
}
202195202961
if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
202962
+ if( pParse->useMod==0 ) break;
202196202963
assert( pRoot->eU==2 );
202197
- iRoot += pRoot->u.iAppend;
202964
+ iRoot = pRoot->u.iAppend;
202198202965
pRoot = &pParse->aNode[iRoot];
202199202966
j = 1;
202200202967
}
202201202968
if( j<=pRoot->n ){
202202202969
return jsonLookupStep(pParse, iRoot+j, zPath, pApnd, pzErr);
202203202970
}
202204202971
if( i==0 && pApnd ){
202205202972
u32 iStart;
202206202973
JsonNode *pNode;
202974
+ assert( pParse->useMod );
202207202975
iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
202208202976
pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
202209202977
if( pParse->oom ) return 0;
202210202978
if( pNode ){
202211202979
pRoot = &pParse->aNode[iRoot];
202212202980
assert( pRoot->eU==0 );
202213
- pRoot->u.iAppend = iStart - iRoot;
202981
+ pRoot->u.iAppend = iStart;
202214202982
pRoot->jnFlags |= JNODE_APPEND;
202215202983
VVA( pRoot->eU = 2 );
202216202984
}
202217202985
return pNode;
202218202986
}
@@ -202334,52 +203102,95 @@
202334203102
202335203103
202336203104
/****************************************************************************
202337203105
** SQL functions used for testing and debugging
202338203106
****************************************************************************/
203107
+
203108
+#if SQLITE_DEBUG
203109
+/*
203110
+** Print N node entries.
203111
+*/
203112
+static void jsonDebugPrintNodeEntries(
203113
+ JsonNode *aNode, /* First node entry to print */
203114
+ int N /* Number of node entries to print */
203115
+){
203116
+ int i;
203117
+ for(i=0; i<N; i++){
203118
+ const char *zType;
203119
+ if( aNode[i].jnFlags & JNODE_LABEL ){
203120
+ zType = "label";
203121
+ }else{
203122
+ zType = jsonType[aNode[i].eType];
203123
+ }
203124
+ printf("node %4u: %-7s n=%-5d", i, zType, aNode[i].n);
203125
+ if( (aNode[i].jnFlags & ~JNODE_LABEL)!=0 ){
203126
+ u8 f = aNode[i].jnFlags;
203127
+ if( f & JNODE_RAW ) printf(" RAW");
203128
+ if( f & JNODE_ESCAPE ) printf(" ESCAPE");
203129
+ if( f & JNODE_REMOVE ) printf(" REMOVE");
203130
+ if( f & JNODE_REPLACE ) printf(" REPLACE");
203131
+ if( f & JNODE_APPEND ) printf(" APPEND");
203132
+ if( f & JNODE_JSON5 ) printf(" JSON5");
203133
+ }
203134
+ switch( aNode[i].eU ){
203135
+ case 1: printf(" zJContent=[%.*s]\n",
203136
+ aNode[i].n, aNode[i].u.zJContent); break;
203137
+ case 2: printf(" iAppend=%u\n", aNode[i].u.iAppend); break;
203138
+ case 3: printf(" iKey=%u\n", aNode[i].u.iKey); break;
203139
+ case 4: printf(" iPrev=%u\n", aNode[i].u.iPrev); break;
203140
+ default: printf("\n");
203141
+ }
203142
+ }
203143
+}
203144
+#endif /* SQLITE_DEBUG */
203145
+
203146
+
203147
+#if 0 /* 1 for debugging. 0 normally. Requires -DSQLITE_DEBUG too */
203148
+static void jsonDebugPrintParse(JsonParse *p){
203149
+ jsonDebugPrintNodeEntries(p->aNode, p->nNode);
203150
+}
203151
+static void jsonDebugPrintNode(JsonNode *pNode){
203152
+ jsonDebugPrintNodeEntries(pNode, jsonNodeSize(pNode));
203153
+}
203154
+#else
203155
+ /* The usual case */
203156
+# define jsonDebugPrintNode(X)
203157
+# define jsonDebugPrintParse(X)
203158
+#endif
202339203159
202340203160
#ifdef SQLITE_DEBUG
202341203161
/*
202342
-** The json_parse(JSON) function returns a string which describes
202343
-** a parse of the JSON provided. Or it returns NULL if JSON is not
202344
-** well-formed.
203162
+** SQL function: json_parse(JSON)
203163
+**
203164
+** Parse JSON using jsonParseCached(). Then print a dump of that
203165
+** parse on standard output. Return the mimified JSON result, just
203166
+** like the json() function.
202345203167
*/
202346203168
static void jsonParseFunc(
202347203169
sqlite3_context *ctx,
202348203170
int argc,
202349203171
sqlite3_value **argv
202350203172
){
202351
- JsonString s; /* Output string - not real JSON */
202352
- JsonParse x; /* The parse */
202353
- u32 i;
203173
+ JsonParse *p; /* The parse */
202354203174
202355203175
assert( argc==1 );
202356
- if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
202357
- jsonParseFindParents(&x);
202358
- jsonInit(&s, ctx);
202359
- for(i=0; i<x.nNode; i++){
202360
- const char *zType;
202361
- if( x.aNode[i].jnFlags & JNODE_LABEL ){
202362
- assert( x.aNode[i].eType==JSON_STRING );
202363
- zType = "label";
202364
- }else{
202365
- zType = jsonType[x.aNode[i].eType];
202366
- }
202367
- jsonPrintf(100, &s,"node %3u: %7s n=%-4d up=%-4d",
202368
- i, zType, x.aNode[i].n, x.aUp[i]);
202369
- assert( x.aNode[i].eU==0 || x.aNode[i].eU==1 );
202370
- if( x.aNode[i].u.zJContent!=0 ){
202371
- assert( x.aNode[i].eU==1 );
202372
- jsonAppendRaw(&s, " ", 1);
202373
- jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n);
202374
- }else{
202375
- assert( x.aNode[i].eU==0 );
202376
- }
202377
- jsonAppendRaw(&s, "\n", 1);
202378
- }
202379
- jsonParseReset(&x);
202380
- jsonResult(&s);
203176
+ p = jsonParseCached(ctx, argv[0], ctx, 0);
203177
+ if( p==0 ) return;
203178
+ printf("nNode = %u\n", p->nNode);
203179
+ printf("nAlloc = %u\n", p->nAlloc);
203180
+ printf("nJson = %d\n", p->nJson);
203181
+ printf("nAlt = %d\n", p->nAlt);
203182
+ printf("nErr = %u\n", p->nErr);
203183
+ printf("oom = %u\n", p->oom);
203184
+ printf("hasNonstd = %u\n", p->hasNonstd);
203185
+ printf("useMod = %u\n", p->useMod);
203186
+ printf("hasMod = %u\n", p->hasMod);
203187
+ printf("nJPRef = %u\n", p->nJPRef);
203188
+ printf("iSubst = %u\n", p->iSubst);
203189
+ printf("iHold = %u\n", p->iHold);
203190
+ jsonDebugPrintNodeEntries(p->aNode, p->nNode);
203191
+ jsonReturnJson(p, p->aNode, ctx, 1);
202381203192
}
202382203193
202383203194
/*
202384203195
** The json_test1(JSON) function return true (1) if the input is JSON
202385203196
** text generated by another json function. It returns (0) if the input
@@ -202459,11 +203270,11 @@
202459203270
JsonParse *p; /* The parse */
202460203271
sqlite3_int64 n = 0;
202461203272
u32 i;
202462203273
JsonNode *pNode;
202463203274
202464
- p = jsonParseCached(ctx, argv, ctx);
203275
+ p = jsonParseCached(ctx, argv[0], ctx, 0);
202465203276
if( p==0 ) return;
202466203277
assert( p->nNode );
202467203278
if( argc==2 ){
202468203279
const char *zPath = (const char*)sqlite3_value_text(argv[1]);
202469203280
pNode = jsonLookup(p, zPath, 0, ctx);
@@ -202472,13 +203283,18 @@
202472203283
}
202473203284
if( pNode==0 ){
202474203285
return;
202475203286
}
202476203287
if( pNode->eType==JSON_ARRAY ){
202477
- assert( (pNode->jnFlags & JNODE_APPEND)==0 );
202478
- for(i=1; i<=pNode->n; n++){
202479
- i += jsonNodeSize(&pNode[i]);
203288
+ while( 1 /*exit-by-break*/ ){
203289
+ for(i=1; i<=pNode->n; n++){
203290
+ i += jsonNodeSize(&pNode[i]);
203291
+ }
203292
+ if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
203293
+ if( p->useMod==0 ) break;
203294
+ assert( pNode->eU==2 );
203295
+ pNode = &p->aNode[pNode->u.iAppend];
202480203296
}
202481203297
}
202482203298
sqlite3_result_int64(ctx, n);
202483203299
}
202484203300
@@ -202521,11 +203337,11 @@
202521203337
const char *zPath;
202522203338
int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx));
202523203339
JsonString jx;
202524203340
202525203341
if( argc<2 ) return;
202526
- p = jsonParseCached(ctx, argv, ctx);
203342
+ p = jsonParseCached(ctx, argv[0], ctx, 0);
202527203343
if( p==0 ) return;
202528203344
if( argc==2 ){
202529203345
/* With a single PATH argument */
202530203346
zPath = (const char*)sqlite3_value_text(argv[1]);
202531203347
if( zPath==0 ) return;
@@ -202539,15 +203355,15 @@
202539203355
** LABEL ==> $.LABEL // PG compatible
202540203356
** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience
202541203357
*/
202542203358
jsonInit(&jx, ctx);
202543203359
if( sqlite3Isdigit(zPath[0]) ){
202544
- jsonAppendRaw(&jx, "$[", 2);
203360
+ jsonAppendRawNZ(&jx, "$[", 2);
202545203361
jsonAppendRaw(&jx, zPath, (int)strlen(zPath));
202546
- jsonAppendRaw(&jx, "]", 2);
203362
+ jsonAppendRawNZ(&jx, "]", 2);
202547203363
}else{
202548
- jsonAppendRaw(&jx, "$.", 1 + (zPath[0]!='['));
203364
+ jsonAppendRawNZ(&jx, "$.", 1 + (zPath[0]!='['));
202549203365
jsonAppendRaw(&jx, zPath, (int)strlen(zPath));
202550203366
jsonAppendChar(&jx, 0);
202551203367
}
202552203368
pNode = jx.bErr ? 0 : jsonLookup(p, jx.zBuf, 0, ctx);
202553203369
jsonReset(&jx);
@@ -202554,19 +203370,19 @@
202554203370
}else{
202555203371
pNode = jsonLookup(p, zPath, 0, ctx);
202556203372
}
202557203373
if( pNode ){
202558203374
if( flags & JSON_JSON ){
202559
- jsonReturnJson(pNode, ctx, 0);
203375
+ jsonReturnJson(p, pNode, ctx, 0);
202560203376
}else{
202561
- jsonReturn(pNode, ctx, 0);
203377
+ jsonReturn(p, pNode, ctx);
202562203378
sqlite3_result_subtype(ctx, 0);
202563203379
}
202564203380
}
202565203381
}else{
202566203382
pNode = jsonLookup(p, zPath, 0, ctx);
202567
- if( p->nErr==0 && pNode ) jsonReturn(pNode, ctx, 0);
203383
+ if( p->nErr==0 && pNode ) jsonReturn(p, pNode, ctx);
202568203384
}
202569203385
}else{
202570203386
/* Two or more PATH arguments results in a JSON array with each
202571203387
** element of the array being the value selected by one of the PATHs */
202572203388
int i;
@@ -202576,13 +203392,13 @@
202576203392
zPath = (const char*)sqlite3_value_text(argv[i]);
202577203393
pNode = jsonLookup(p, zPath, 0, ctx);
202578203394
if( p->nErr ) break;
202579203395
jsonAppendSeparator(&jx);
202580203396
if( pNode ){
202581
- jsonRenderNode(pNode, &jx, 0);
203397
+ jsonRenderNode(p, pNode, &jx);
202582203398
}else{
202583
- jsonAppendRaw(&jx, "null", 4);
203399
+ jsonAppendRawNZ(&jx, "null", 4);
202584203400
}
202585203401
}
202586203402
if( i==argc ){
202587203403
jsonAppendChar(&jx, ']');
202588203404
jsonResult(&jx);
@@ -202623,49 +203439,42 @@
202623203439
zKey = pPatch[i].u.zJContent;
202624203440
for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){
202625203441
assert( pTarget[j].eType==JSON_STRING );
202626203442
assert( pTarget[j].jnFlags & JNODE_LABEL );
202627203443
if( jsonSameLabel(&pPatch[i], &pTarget[j]) ){
202628
- if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH) ) break;
203444
+ if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ) break;
202629203445
if( pPatch[i+1].eType==JSON_NULL ){
202630203446
pTarget[j+1].jnFlags |= JNODE_REMOVE;
202631203447
}else{
202632203448
JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]);
202633203449
if( pNew==0 ) return 0;
203450
+ if( pNew!=&pParse->aNode[iTarget+j+1] ){
203451
+ jsonParseAddSubstNode(pParse, iTarget+j+1);
203452
+ jsonParseAddNodeArray(pParse, pNew, jsonNodeSize(pNew));
203453
+ }
202634203454
pTarget = &pParse->aNode[iTarget];
202635
- if( pNew!=&pTarget[j+1] ){
202636
- assert( pTarget[j+1].eU==0
202637
- || pTarget[j+1].eU==1
202638
- || pTarget[j+1].eU==2 );
202639
- testcase( pTarget[j+1].eU==1 );
202640
- testcase( pTarget[j+1].eU==2 );
202641
- VVA( pTarget[j+1].eU = 5 );
202642
- pTarget[j+1].u.pPatch = pNew;
202643
- pTarget[j+1].jnFlags |= JNODE_PATCH;
202644
- }
202645203455
}
202646203456
break;
202647203457
}
202648203458
}
202649203459
if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){
202650
- int iStart, iPatch;
202651
- iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
203460
+ int iStart;
203461
+ JsonNode *pApnd;
203462
+ u32 nApnd;
203463
+ iStart = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
202652203464
jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
202653
- iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
203465
+ pApnd = &pPatch[i+1];
203466
+ if( pApnd->eType==JSON_OBJECT ) jsonRemoveAllNulls(pApnd);
203467
+ nApnd = jsonNodeSize(pApnd);
203468
+ jsonParseAddNodeArray(pParse, pApnd, jsonNodeSize(pApnd));
202654203469
if( pParse->oom ) return 0;
202655
- jsonRemoveAllNulls(pPatch);
202656
- pTarget = &pParse->aNode[iTarget];
202657
- assert( pParse->aNode[iRoot].eU==0 || pParse->aNode[iRoot].eU==2 );
202658
- testcase( pParse->aNode[iRoot].eU==2 );
203470
+ pParse->aNode[iStart].n = 1+nApnd;
202659203471
pParse->aNode[iRoot].jnFlags |= JNODE_APPEND;
203472
+ pParse->aNode[iRoot].u.iAppend = iStart;
202660203473
VVA( pParse->aNode[iRoot].eU = 2 );
202661
- pParse->aNode[iRoot].u.iAppend = iStart - iRoot;
202662203474
iRoot = iStart;
202663
- assert( pParse->aNode[iPatch].eU==0 );
202664
- VVA( pParse->aNode[iPatch].eU = 5 );
202665
- pParse->aNode[iPatch].jnFlags |= JNODE_PATCH;
202666
- pParse->aNode[iPatch].u.pPatch = &pPatch[i+1];
203475
+ pTarget = &pParse->aNode[iTarget];
202667203476
}
202668203477
}
202669203478
return pTarget;
202670203479
}
202671203480
@@ -202677,29 +203486,32 @@
202677203486
static void jsonPatchFunc(
202678203487
sqlite3_context *ctx,
202679203488
int argc,
202680203489
sqlite3_value **argv
202681203490
){
202682
- JsonParse x; /* The JSON that is being patched */
202683
- JsonParse y; /* The patch */
203491
+ JsonParse *pX; /* The JSON that is being patched */
203492
+ JsonParse *pY; /* The patch */
202684203493
JsonNode *pResult; /* The result of the merge */
202685203494
202686203495
UNUSED_PARAMETER(argc);
202687
- if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
202688
- if( jsonParse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){
202689
- jsonParseReset(&x);
202690
- return;
202691
- }
202692
- pResult = jsonMergePatch(&x, 0, y.aNode);
202693
- assert( pResult!=0 || x.oom );
202694
- if( pResult ){
202695
- jsonReturnJson(pResult, ctx, 0);
203496
+ pX = jsonParseCached(ctx, argv[0], ctx, 1);
203497
+ if( pX==0 ) return;
203498
+ assert( pX->hasMod==0 );
203499
+ pX->hasMod = 1;
203500
+ pY = jsonParseCached(ctx, argv[1], ctx, 1);
203501
+ if( pY==0 ) return;
203502
+ pX->useMod = 1;
203503
+ pY->useMod = 1;
203504
+ pResult = jsonMergePatch(pX, 0, pY->aNode);
203505
+ assert( pResult!=0 || pX->oom );
203506
+ if( pResult && pX->oom==0 ){
203507
+ jsonDebugPrintParse(pX);
203508
+ jsonDebugPrintNode(pResult);
203509
+ jsonReturnJson(pX, pResult, ctx, 0);
202696203510
}else{
202697203511
sqlite3_result_error_nomem(ctx);
202698203512
}
202699
- jsonParseReset(&x);
202700
- jsonParseReset(&y);
202701203513
}
202702203514
202703203515
202704203516
/*
202705203517
** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON
@@ -202751,30 +203563,122 @@
202751203563
static void jsonRemoveFunc(
202752203564
sqlite3_context *ctx,
202753203565
int argc,
202754203566
sqlite3_value **argv
202755203567
){
202756
- JsonParse x; /* The parse */
203568
+ JsonParse *pParse; /* The parse */
202757203569
JsonNode *pNode;
202758203570
const char *zPath;
202759203571
u32 i;
202760203572
202761203573
if( argc<1 ) return;
202762
- if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
202763
- assert( x.nNode );
203574
+ pParse = jsonParseCached(ctx, argv[0], ctx, argc>1);
203575
+ if( pParse==0 ) return;
202764203576
for(i=1; i<(u32)argc; i++){
202765203577
zPath = (const char*)sqlite3_value_text(argv[i]);
202766203578
if( zPath==0 ) goto remove_done;
202767
- pNode = jsonLookup(&x, zPath, 0, ctx);
202768
- if( x.nErr ) goto remove_done;
202769
- if( pNode ) pNode->jnFlags |= JNODE_REMOVE;
203579
+ pNode = jsonLookup(pParse, zPath, 0, ctx);
203580
+ if( pParse->nErr ) goto remove_done;
203581
+ if( pNode ){
203582
+ pNode->jnFlags |= JNODE_REMOVE;
203583
+ pParse->hasMod = 1;
203584
+ pParse->useMod = 1;
203585
+ }
202770203586
}
202771
- if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){
202772
- jsonReturnJson(x.aNode, ctx, 0);
203587
+ if( (pParse->aNode[0].jnFlags & JNODE_REMOVE)==0 ){
203588
+ jsonReturnJson(pParse, pParse->aNode, ctx, 1);
202773203589
}
202774203590
remove_done:
202775
- jsonParseReset(&x);
203591
+ jsonDebugPrintParse(p);
203592
+}
203593
+
203594
+/*
203595
+** Substitute the value at iNode with the pValue parameter.
203596
+*/
203597
+static void jsonReplaceNode(
203598
+ sqlite3_context *pCtx,
203599
+ JsonParse *p,
203600
+ int iNode,
203601
+ sqlite3_value *pValue
203602
+){
203603
+ int idx = jsonParseAddSubstNode(p, iNode);
203604
+ if( idx<=0 ){
203605
+ assert( p->oom );
203606
+ return;
203607
+ }
203608
+ switch( sqlite3_value_type(pValue) ){
203609
+ case SQLITE_NULL: {
203610
+ jsonParseAddNode(p, JSON_NULL, 0, 0);
203611
+ break;
203612
+ }
203613
+ case SQLITE_FLOAT: {
203614
+ char *z = sqlite3_mprintf("%!0.15g", sqlite3_value_double(pValue));
203615
+ int n;
203616
+ if( z==0 ){
203617
+ p->oom = 1;
203618
+ break;
203619
+ }
203620
+ n = sqlite3Strlen30(z);
203621
+ jsonParseAddNode(p, JSON_REAL, n, z);
203622
+ jsonParseAddCleanup(p, sqlite3_free, z);
203623
+ break;
203624
+ }
203625
+ case SQLITE_INTEGER: {
203626
+ char *z = sqlite3_mprintf("%lld", sqlite3_value_int64(pValue));
203627
+ int n;
203628
+ if( z==0 ){
203629
+ p->oom = 1;
203630
+ break;
203631
+ }
203632
+ n = sqlite3Strlen30(z);
203633
+ jsonParseAddNode(p, JSON_INT, n, z);
203634
+ jsonParseAddCleanup(p, sqlite3_free, z);
203635
+
203636
+ break;
203637
+ }
203638
+ case SQLITE_TEXT: {
203639
+ const char *z = (const char*)sqlite3_value_text(pValue);
203640
+ u32 n = (u32)sqlite3_value_bytes(pValue);
203641
+ if( z==0 ){
203642
+ p->oom = 1;
203643
+ break;
203644
+ }
203645
+ if( sqlite3_value_subtype(pValue)!=JSON_SUBTYPE ){
203646
+ char *zCopy = sqlite3DbStrDup(0, z);
203647
+ int k;
203648
+ if( zCopy ){
203649
+ jsonParseAddCleanup(p, sqlite3_free, zCopy);
203650
+ }else{
203651
+ p->oom = 1;
203652
+ sqlite3_result_error_nomem(pCtx);
203653
+ }
203654
+ k = jsonParseAddNode(p, JSON_STRING, n, zCopy);
203655
+ assert( k>0 || p->oom );
203656
+ if( p->oom==0 ) p->aNode[k].jnFlags |= JNODE_RAW;
203657
+ }else{
203658
+ JsonParse *pPatch = jsonParseCached(pCtx, pValue, pCtx, 1);
203659
+ if( pPatch==0 ){
203660
+ p->oom = 1;
203661
+ break;
203662
+ }
203663
+ jsonParseAddNodeArray(p, pPatch->aNode, pPatch->nNode);
203664
+ /* The nodes copied out of pPatch and into p likely contain
203665
+ ** u.zJContent pointers into pPatch->zJson. So preserve the
203666
+ ** content of pPatch until p is destroyed. */
203667
+ assert( pPatch->nJPRef>=1 );
203668
+ pPatch->nJPRef++;
203669
+ jsonParseAddCleanup(p, (void(*)(void*))jsonParseFree, pPatch);
203670
+ }
203671
+ break;
203672
+ }
203673
+ default: {
203674
+ jsonParseAddNode(p, JSON_NULL, 0, 0);
203675
+ sqlite3_result_error(pCtx, "JSON cannot hold BLOB values", -1);
203676
+ p->nErr++;
203677
+ break;
203678
+ }
203679
+ }
202776203680
}
202777203681
202778203682
/*
202779203683
** json_replace(JSON, PATH, VALUE, ...)
202780203684
**
@@ -202784,42 +203688,34 @@
202784203688
static void jsonReplaceFunc(
202785203689
sqlite3_context *ctx,
202786203690
int argc,
202787203691
sqlite3_value **argv
202788203692
){
202789
- JsonParse x; /* The parse */
203693
+ JsonParse *pParse; /* The parse */
202790203694
JsonNode *pNode;
202791203695
const char *zPath;
202792203696
u32 i;
202793203697
202794203698
if( argc<1 ) return;
202795203699
if( (argc&1)==0 ) {
202796203700
jsonWrongNumArgs(ctx, "replace");
202797203701
return;
202798203702
}
202799
- if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
202800
- assert( x.nNode );
203703
+ pParse = jsonParseCached(ctx, argv[0], ctx, argc>1);
203704
+ if( pParse==0 ) return;
202801203705
for(i=1; i<(u32)argc; i+=2){
202802203706
zPath = (const char*)sqlite3_value_text(argv[i]);
202803
- pNode = jsonLookup(&x, zPath, 0, ctx);
202804
- if( x.nErr ) goto replace_err;
203707
+ pParse->useMod = 1;
203708
+ pNode = jsonLookup(pParse, zPath, 0, ctx);
203709
+ if( pParse->nErr ) goto replace_err;
202805203710
if( pNode ){
202806
- assert( pNode->eU==0 || pNode->eU==1 || pNode->eU==4 );
202807
- testcase( pNode->eU!=0 && pNode->eU!=1 );
202808
- pNode->jnFlags |= (u8)JNODE_REPLACE;
202809
- VVA( pNode->eU = 4 );
202810
- pNode->u.iReplace = i + 1;
203711
+ jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]);
202811203712
}
202812203713
}
202813
- if( x.aNode[0].jnFlags & JNODE_REPLACE ){
202814
- assert( x.aNode[0].eU==4 );
202815
- sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
202816
- }else{
202817
- jsonReturnJson(x.aNode, ctx, argv);
202818
- }
203714
+ jsonReturnJson(pParse, pParse->aNode, ctx, 1);
202819203715
replace_err:
202820
- jsonParseReset(&x);
203716
+ jsonDebugPrintParse(pParse);
202821203717
}
202822203718
202823203719
202824203720
/*
202825203721
** json_set(JSON, PATH, VALUE, ...)
@@ -202836,11 +203732,11 @@
202836203732
static void jsonSetFunc(
202837203733
sqlite3_context *ctx,
202838203734
int argc,
202839203735
sqlite3_value **argv
202840203736
){
202841
- JsonParse x; /* The parse */
203737
+ JsonParse *pParse; /* The parse */
202842203738
JsonNode *pNode;
202843203739
const char *zPath;
202844203740
u32 i;
202845203741
int bApnd;
202846203742
int bIsSet = sqlite3_user_data(ctx)!=0;
@@ -202848,37 +203744,31 @@
202848203744
if( argc<1 ) return;
202849203745
if( (argc&1)==0 ) {
202850203746
jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert");
202851203747
return;
202852203748
}
202853
- if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
202854
- assert( x.nNode );
203749
+ pParse = jsonParseCached(ctx, argv[0], ctx, argc>1);
203750
+ if( pParse==0 ) return;
202855203751
for(i=1; i<(u32)argc; i+=2){
202856203752
zPath = (const char*)sqlite3_value_text(argv[i]);
202857203753
bApnd = 0;
202858
- pNode = jsonLookup(&x, zPath, &bApnd, ctx);
202859
- if( x.oom ){
203754
+ pParse->useMod = 1;
203755
+ pNode = jsonLookup(pParse, zPath, &bApnd, ctx);
203756
+ if( pParse->oom ){
202860203757
sqlite3_result_error_nomem(ctx);
202861203758
goto jsonSetDone;
202862
- }else if( x.nErr ){
203759
+ }else if( pParse->nErr ){
202863203760
goto jsonSetDone;
202864203761
}else if( pNode && (bApnd || bIsSet) ){
202865
- testcase( pNode->eU!=0 && pNode->eU!=1 );
202866
- assert( pNode->eU!=3 && pNode->eU!=5 );
202867
- VVA( pNode->eU = 4 );
202868
- pNode->jnFlags |= (u8)JNODE_REPLACE;
202869
- pNode->u.iReplace = i + 1;
203762
+ jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]);
202870203763
}
202871203764
}
202872
- if( x.aNode[0].jnFlags & JNODE_REPLACE ){
202873
- assert( x.aNode[0].eU==4 );
202874
- sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
202875
- }else{
202876
- jsonReturnJson(x.aNode, ctx, argv);
202877
- }
203765
+ jsonDebugPrintParse(pParse);
203766
+ jsonReturnJson(pParse, pParse->aNode, ctx, 1);
203767
+
202878203768
jsonSetDone:
202879
- jsonParseReset(&x);
203769
+ /* no cleanup required */;
202880203770
}
202881203771
202882203772
/*
202883203773
** json_type(JSON)
202884203774
** json_type(JSON, PATH)
@@ -202893,11 +203783,11 @@
202893203783
){
202894203784
JsonParse *p; /* The parse */
202895203785
const char *zPath;
202896203786
JsonNode *pNode;
202897203787
202898
- p = jsonParseCached(ctx, argv, ctx);
203788
+ p = jsonParseCached(ctx, argv[0], ctx, 0);
202899203789
if( p==0 ) return;
202900203790
if( argc==2 ){
202901203791
zPath = (const char*)sqlite3_value_text(argv[1]);
202902203792
pNode = jsonLookup(p, zPath, 0, ctx);
202903203793
}else{
@@ -202920,16 +203810,16 @@
202920203810
sqlite3_value **argv
202921203811
){
202922203812
JsonParse *p; /* The parse */
202923203813
UNUSED_PARAMETER(argc);
202924203814
if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
202925
- p = jsonParseCached(ctx, argv, 0);
203815
+ p = jsonParseCached(ctx, argv[0], 0, 0);
202926203816
if( p==0 || p->oom ){
202927203817
sqlite3_result_error_nomem(ctx);
202928203818
sqlite3_free(p);
202929203819
}else{
202930
- sqlite3_result_int(ctx, p->nErr==0 && p->hasNonstd==0);
203820
+ sqlite3_result_int(ctx, p->nErr==0 && (p->hasNonstd==0 || p->useMod));
202931203821
if( p->nErr ) jsonParseFree(p);
202932203822
}
202933203823
}
202934203824
202935203825
/*
@@ -202966,20 +203856,20 @@
202966203856
sqlite3_value **argv
202967203857
){
202968203858
JsonParse *p; /* The parse */
202969203859
UNUSED_PARAMETER(argc);
202970203860
if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
202971
- p = jsonParseCached(ctx, argv, 0);
203861
+ p = jsonParseCached(ctx, argv[0], 0, 0);
202972203862
if( p==0 || p->oom ){
202973203863
sqlite3_result_error_nomem(ctx);
202974203864
sqlite3_free(p);
202975203865
}else if( p->nErr==0 ){
202976203866
sqlite3_result_int(ctx, 0);
202977203867
}else{
202978203868
int n = 1;
202979203869
u32 i;
202980
- const char *z = p->zJson;
203870
+ const char *z = (const char*)sqlite3_value_text(argv[0]);
202981203871
for(i=0; i<p->iErr && ALWAYS(z[i]); i++){
202982203872
if( (z[i]&0xc0)!=0x80 ) n++;
202983203873
}
202984203874
sqlite3_result_int(ctx, n);
202985203875
jsonParseFree(p);
@@ -203023,11 +203913,12 @@
203023203913
if( pStr->bErr ){
203024203914
if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
203025203915
assert( pStr->bStatic );
203026203916
}else if( isFinal ){
203027203917
sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed,
203028
- pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
203918
+ pStr->bStatic ? SQLITE_TRANSIENT :
203919
+ (void(*)(void*))sqlite3RCStrUnref);
203029203920
pStr->bStatic = 1;
203030203921
}else{
203031203922
sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT);
203032203923
pStr->nUsed--;
203033203924
}
@@ -203131,11 +204022,12 @@
203131204022
if( pStr->bErr ){
203132204023
if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
203133204024
assert( pStr->bStatic );
203134204025
}else if( isFinal ){
203135204026
sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed,
203136
- pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
204027
+ pStr->bStatic ? SQLITE_TRANSIENT :
204028
+ (void(*)(void*))sqlite3RCStrUnref);
203137204029
pStr->bStatic = 1;
203138204030
}else{
203139204031
sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT);
203140204032
pStr->nUsed--;
203141204033
}
@@ -203242,11 +204134,10 @@
203242204134
}
203243204135
203244204136
/* Reset a JsonEachCursor back to its original state. Free any memory
203245204137
** held. */
203246204138
static void jsonEachCursorReset(JsonEachCursor *p){
203247
- sqlite3_free(p->zJson);
203248204139
sqlite3_free(p->zRoot);
203249204140
jsonParseReset(&p->sParse);
203250204141
p->iRowid = 0;
203251204142
p->i = 0;
203252204143
p->iEnd = 0;
@@ -203380,11 +204271,11 @@
203380204271
JsonNode *pThis = &p->sParse.aNode[p->i];
203381204272
switch( i ){
203382204273
case JEACH_KEY: {
203383204274
if( p->i==0 ) break;
203384204275
if( p->eType==JSON_OBJECT ){
203385
- jsonReturn(pThis, ctx, 0);
204276
+ jsonReturn(&p->sParse, pThis, ctx);
203386204277
}else if( p->eType==JSON_ARRAY ){
203387204278
u32 iKey;
203388204279
if( p->bRecursive ){
203389204280
if( p->iRowid==0 ) break;
203390204281
assert( p->sParse.aNode[p->sParse.aUp[p->i]].eU==3 );
@@ -203396,11 +204287,11 @@
203396204287
}
203397204288
break;
203398204289
}
203399204290
case JEACH_VALUE: {
203400204291
if( pThis->jnFlags & JNODE_LABEL ) pThis++;
203401
- jsonReturn(pThis, ctx, 0);
204292
+ jsonReturn(&p->sParse, pThis, ctx);
203402204293
break;
203403204294
}
203404204295
case JEACH_TYPE: {
203405204296
if( pThis->jnFlags & JNODE_LABEL ) pThis++;
203406204297
sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC);
@@ -203407,11 +204298,11 @@
203407204298
break;
203408204299
}
203409204300
case JEACH_ATOM: {
203410204301
if( pThis->jnFlags & JNODE_LABEL ) pThis++;
203411204302
if( pThis->eType>=JSON_ARRAY ) break;
203412
- jsonReturn(pThis, ctx, 0);
204303
+ jsonReturn(&p->sParse, pThis, ctx);
203413204304
break;
203414204305
}
203415204306
case JEACH_ID: {
203416204307
sqlite3_result_int64(ctx,
203417204308
(sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0));
@@ -203562,15 +204453,23 @@
203562204453
UNUSED_PARAMETER(argc);
203563204454
jsonEachCursorReset(p);
203564204455
if( idxNum==0 ) return SQLITE_OK;
203565204456
z = (const char*)sqlite3_value_text(argv[0]);
203566204457
if( z==0 ) return SQLITE_OK;
203567
- n = sqlite3_value_bytes(argv[0]);
203568
- p->zJson = sqlite3_malloc64( n+1 );
203569
- if( p->zJson==0 ) return SQLITE_NOMEM;
203570
- memcpy(p->zJson, z, (size_t)n+1);
203571
- if( jsonParse(&p->sParse, 0, p->zJson) ){
204458
+ memset(&p->sParse, 0, sizeof(p->sParse));
204459
+ p->sParse.nJPRef = 1;
204460
+ if( sqlite3ValueIsOfClass(argv[0], (void(*)(void*))sqlite3RCStrUnref) ){
204461
+ p->sParse.zJson = sqlite3RCStrRef((char*)z);
204462
+ }else{
204463
+ n = sqlite3_value_bytes(argv[0]);
204464
+ p->sParse.zJson = sqlite3RCStrNew( n+1 );
204465
+ if( p->sParse.zJson==0 ) return SQLITE_NOMEM;
204466
+ memcpy(p->sParse.zJson, z, (size_t)n+1);
204467
+ }
204468
+ p->sParse.bJsonIsRCStr = 1;
204469
+ p->zJson = p->sParse.zJson;
204470
+ if( jsonParse(&p->sParse, 0) ){
203572204471
int rc = SQLITE_NOMEM;
203573204472
if( p->sParse.oom==0 ){
203574204473
sqlite3_free(cur->pVtab->zErrMsg);
203575204474
cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON");
203576204475
if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR;
@@ -219306,10 +220205,11 @@
219306220205
}else{
219307220206
/* assert( db->pPreUpdate->pUnpacked ); */
219308220207
rc = pSession->hook.xOld(pSession->hook.pCtx, iCol, &pVal);
219309220208
}
219310220209
assert( rc==SQLITE_OK );
220210
+ (void)rc; /* Suppress warning about unused variable */
219311220211
if( sqlite3_value_type(pVal)!=eType ) return 0;
219312220212
219313220213
/* A SessionChange object never has a NULL value in a PK column */
219314220214
assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT
219315220215
|| eType==SQLITE_BLOB || eType==SQLITE_TEXT
@@ -225188,10 +226088,14 @@
225188226088
** nAutomerge:
225189226089
** The minimum number of segments that an auto-merge operation should
225190226090
** attempt to merge together. A value of 1 sets the object to use the
225191226091
** compile time default. Zero disables auto-merge altogether.
225192226092
**
226093
+** bContentlessDelete:
226094
+** True if the contentless_delete option was present in the CREATE
226095
+** VIRTUAL TABLE statement.
226096
+**
225193226097
** zContent:
225194226098
**
225195226099
** zContentRowid:
225196226100
** The value of the content_rowid= option, if one was specified. Or
225197226101
** the string "rowid" otherwise. This text is not quoted - if it is
@@ -225222,10 +226126,11 @@
225222226126
char **azCol; /* Column names */
225223226127
u8 *abUnindexed; /* True for unindexed columns */
225224226128
int nPrefix; /* Number of prefix indexes */
225225226129
int *aPrefix; /* Sizes in bytes of nPrefix prefix indexes */
225226226130
int eContent; /* An FTS5_CONTENT value */
226131
+ int bContentlessDelete; /* "contentless_delete=" option (dflt==0) */
225227226132
char *zContent; /* content table */
225228226133
char *zContentRowid; /* "content_rowid=" option value */
225229226134
int bColumnsize; /* "columnsize=" option value (dflt==1) */
225230226135
int eDetail; /* FTS5_DETAIL_XXX value */
225231226136
char *zContentExprlist;
@@ -225243,10 +226148,11 @@
225243226148
int nUsermerge; /* 'usermerge' setting */
225244226149
int nHashSize; /* Bytes of memory for in-memory hash */
225245226150
char *zRank; /* Name of rank function */
225246226151
char *zRankArgs; /* Arguments to rank function */
225247226152
int bSecureDelete; /* 'secure-delete' */
226153
+ int nDeleteMerge; /* 'deletemerge' */
225248226154
225249226155
/* If non-NULL, points to sqlite3_vtab.base.zErrmsg. Often NULL. */
225250226156
char **pzErrmsg;
225251226157
225252226158
#ifdef SQLITE_DEBUG
@@ -225565,10 +226471,13 @@
225565226471
static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge);
225566226472
static int sqlite3Fts5IndexReset(Fts5Index *p);
225567226473
225568226474
static int sqlite3Fts5IndexLoadConfig(Fts5Index *p);
225569226475
226476
+static int sqlite3Fts5IndexGetOrigin(Fts5Index *p, i64 *piOrigin);
226477
+static int sqlite3Fts5IndexContentlessDelete(Fts5Index *p, i64 iOrigin, i64 iRowid);
226478
+
225570226479
/*
225571226480
** End of interface to code in fts5_index.c.
225572226481
**************************************************************************/
225573226482
225574226483
/**************************************************************************
@@ -225649,10 +226558,15 @@
225649226558
/*
225650226559
** Empty (but do not delete) a hash table.
225651226560
*/
225652226561
static void sqlite3Fts5HashClear(Fts5Hash*);
225653226562
226563
+/*
226564
+** Return true if the hash is empty, false otherwise.
226565
+*/
226566
+static int sqlite3Fts5HashIsEmpty(Fts5Hash*);
226567
+
225654226568
static int sqlite3Fts5HashQuery(
225655226569
Fts5Hash*, /* Hash table to query */
225656226570
int nPre,
225657226571
const char *pTerm, int nTerm, /* Query term */
225658226572
void **ppObj, /* OUT: Pointer to doclist for pTerm */
@@ -225668,10 +226582,11 @@
225668226582
static void sqlite3Fts5HashScanEntry(Fts5Hash *,
225669226583
const char **pzTerm, /* OUT: term (nul-terminated) */
225670226584
const u8 **ppDoclist, /* OUT: pointer to doclist */
225671226585
int *pnDoclist /* OUT: size of doclist in bytes */
225672226586
);
226587
+
225673226588
225674226589
225675226590
/*
225676226591
** End of interface to code in fts5_hash.c.
225677226592
**************************************************************************/
@@ -228542,10 +229457,12 @@
228542229457
#define FTS5_DEFAULT_AUTOMERGE 4
228543229458
#define FTS5_DEFAULT_USERMERGE 4
228544229459
#define FTS5_DEFAULT_CRISISMERGE 16
228545229460
#define FTS5_DEFAULT_HASHSIZE (1024*1024)
228546229461
229462
+#define FTS5_DEFAULT_DELETE_AUTOMERGE 10 /* default 10% */
229463
+
228547229464
/* Maximum allowed page size */
228548229465
#define FTS5_MAX_PAGE_SIZE (64*1024)
228549229466
228550229467
static int fts5_iswhitespace(char x){
228551229468
return (x==' ');
@@ -228871,10 +229788,20 @@
228871229788
pConfig->eContent = FTS5_CONTENT_NONE;
228872229789
}
228873229790
}
228874229791
return rc;
228875229792
}
229793
+
229794
+ if( sqlite3_strnicmp("contentless_delete", zCmd, nCmd)==0 ){
229795
+ if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){
229796
+ *pzErr = sqlite3_mprintf("malformed contentless_delete=... directive");
229797
+ rc = SQLITE_ERROR;
229798
+ }else{
229799
+ pConfig->bContentlessDelete = (zArg[0]=='1');
229800
+ }
229801
+ return rc;
229802
+ }
228876229803
228877229804
if( sqlite3_strnicmp("content_rowid", zCmd, nCmd)==0 ){
228878229805
if( pConfig->zContentRowid ){
228879229806
*pzErr = sqlite3_mprintf("multiple content_rowid=... directives");
228880229807
rc = SQLITE_ERROR;
@@ -229115,10 +230042,32 @@
229115230042
}
229116230043
229117230044
sqlite3_free(zOne);
229118230045
sqlite3_free(zTwo);
229119230046
}
230047
+
230048
+ /* We only allow contentless_delete=1 if the table is indeed contentless. */
230049
+ if( rc==SQLITE_OK
230050
+ && pRet->bContentlessDelete
230051
+ && pRet->eContent!=FTS5_CONTENT_NONE
230052
+ ){
230053
+ *pzErr = sqlite3_mprintf(
230054
+ "contentless_delete=1 requires a contentless table"
230055
+ );
230056
+ rc = SQLITE_ERROR;
230057
+ }
230058
+
230059
+ /* We only allow contentless_delete=1 if columnsize=0 is not present.
230060
+ **
230061
+ ** This restriction may be removed at some point.
230062
+ */
230063
+ if( rc==SQLITE_OK && pRet->bContentlessDelete && pRet->bColumnsize==0 ){
230064
+ *pzErr = sqlite3_mprintf(
230065
+ "contentless_delete=1 is incompatible with columnsize=0"
230066
+ );
230067
+ rc = SQLITE_ERROR;
230068
+ }
229120230069
229121230070
/* If a tokenizer= option was successfully parsed, the tokenizer has
229122230071
** already been allocated. Otherwise, allocate an instance of the default
229123230072
** tokenizer (unicode61) now. */
229124230073
if( rc==SQLITE_OK && pRet->pTok==0 ){
@@ -229409,10 +230358,22 @@
229409230358
if( nCrisisMerge<=1 ) nCrisisMerge = FTS5_DEFAULT_CRISISMERGE;
229410230359
if( nCrisisMerge>=FTS5_MAX_SEGMENT ) nCrisisMerge = FTS5_MAX_SEGMENT-1;
229411230360
pConfig->nCrisisMerge = nCrisisMerge;
229412230361
}
229413230362
}
230363
+
230364
+ else if( 0==sqlite3_stricmp(zKey, "deletemerge") ){
230365
+ int nVal = -1;
230366
+ if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
230367
+ nVal = sqlite3_value_int(pVal);
230368
+ }else{
230369
+ *pbBadkey = 1;
230370
+ }
230371
+ if( nVal<0 ) nVal = FTS5_DEFAULT_DELETE_AUTOMERGE;
230372
+ if( nVal>100 ) nVal = 0;
230373
+ pConfig->nDeleteMerge = nVal;
230374
+ }
229414230375
229415230376
else if( 0==sqlite3_stricmp(zKey, "rank") ){
229416230377
const char *zIn = (const char*)sqlite3_value_text(pVal);
229417230378
char *zRank;
229418230379
char *zRankArgs;
@@ -229458,10 +230419,11 @@
229458230419
pConfig->pgsz = FTS5_DEFAULT_PAGE_SIZE;
229459230420
pConfig->nAutomerge = FTS5_DEFAULT_AUTOMERGE;
229460230421
pConfig->nUsermerge = FTS5_DEFAULT_USERMERGE;
229461230422
pConfig->nCrisisMerge = FTS5_DEFAULT_CRISISMERGE;
229462230423
pConfig->nHashSize = FTS5_DEFAULT_HASHSIZE;
230424
+ pConfig->nDeleteMerge = FTS5_DEFAULT_DELETE_AUTOMERGE;
229463230425
229464230426
zSql = sqlite3Fts5Mprintf(&rc, zSelect, pConfig->zDb, pConfig->zName);
229465230427
if( zSql ){
229466230428
rc = sqlite3_prepare_v2(pConfig->db, zSql, -1, &p, 0);
229467230429
sqlite3_free(zSql);
@@ -231981,11 +232943,11 @@
231981232943
}
231982232944
231983232945
return pRet;
231984232946
}
231985232947
231986
-#ifdef SQLITE_TEST
232948
+#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
231987232949
static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){
231988232950
sqlite3_int64 nByte = 0;
231989232951
Fts5ExprTerm *p;
231990232952
char *zQuoted;
231991232953
@@ -232348,18 +233310,18 @@
232348233310
iCode = sqlite3_value_int(apVal[0]);
232349233311
if( nArg==2 ) bRemoveDiacritics = sqlite3_value_int(apVal[1]);
232350233312
sqlite3_result_int(pCtx, sqlite3Fts5UnicodeFold(iCode, bRemoveDiacritics));
232351233313
}
232352233314
}
232353
-#endif /* ifdef SQLITE_TEST */
233315
+#endif /* if SQLITE_TEST || SQLITE_FTS5_DEBUG */
232354233316
232355233317
/*
232356233318
** This is called during initialization to register the fts5_expr() scalar
232357233319
** UDF with the SQLite handle passed as the only argument.
232358233320
*/
232359233321
static int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){
232360
-#ifdef SQLITE_TEST
233322
+#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
232361233323
struct Fts5ExprFunc {
232362233324
const char *z;
232363233325
void (*x)(sqlite3_context*,int,sqlite3_value**);
232364233326
} aFunc[] = {
232365233327
{ "fts5_expr", fts5ExprFunctionHr },
@@ -233115,11 +234077,10 @@
233115234077
pList = 0;
233116234078
for(i=0; i<nMergeSlot; i++){
233117234079
pList = fts5HashEntryMerge(pList, ap[i]);
233118234080
}
233119234081
233120
- pHash->nEntry = 0;
233121234082
sqlite3_free(ap);
233122234083
*ppSorted = pList;
233123234084
return SQLITE_OK;
233124234085
}
233125234086
@@ -233168,10 +234129,32 @@
233168234129
Fts5Hash *p, /* Hash table to query */
233169234130
const char *pTerm, int nTerm /* Query prefix */
233170234131
){
233171234132
return fts5HashEntrySort(p, pTerm, nTerm, &p->pScan);
233172234133
}
234134
+
234135
+#ifdef SQLITE_DEBUG
234136
+static int fts5HashCount(Fts5Hash *pHash){
234137
+ int nEntry = 0;
234138
+ int ii;
234139
+ for(ii=0; ii<pHash->nSlot; ii++){
234140
+ Fts5HashEntry *p = 0;
234141
+ for(p=pHash->aSlot[ii]; p; p=p->pHashNext){
234142
+ nEntry++;
234143
+ }
234144
+ }
234145
+ return nEntry;
234146
+}
234147
+#endif
234148
+
234149
+/*
234150
+** Return true if the hash table is empty, false otherwise.
234151
+*/
234152
+static int sqlite3Fts5HashIsEmpty(Fts5Hash *pHash){
234153
+ assert( pHash->nEntry==fts5HashCount(pHash) );
234154
+ return pHash->nEntry==0;
234155
+}
233173234156
233174234157
static void sqlite3Fts5HashScanNext(Fts5Hash *p){
233175234158
assert( !sqlite3Fts5HashScanEof(p) );
233176234159
p->pScan = p->pScan->pScanNext;
233177234160
}
@@ -233257,32 +234240,50 @@
233257234240
# error "FTS5_MAX_PREFIX_INDEXES is too large"
233258234241
#endif
233259234242
233260234243
#define FTS5_MAX_LEVEL 64
233261234244
234245
+/*
234246
+** There are two versions of the format used for the structure record:
234247
+**
234248
+** 1. the legacy format, that may be read by all fts5 versions, and
234249
+**
234250
+** 2. the V2 format, which is used by contentless_delete=1 databases.
234251
+**
234252
+** Both begin with a 4-byte "configuration cookie" value. Then, a legacy
234253
+** format structure record contains a varint - the number of levels in
234254
+** the structure. Whereas a V2 structure record contains the constant
234255
+** 4 bytes [0xff 0x00 0x00 0x01]. This is unambiguous as the value of a
234256
+** varint has to be at least 16256 to begin with "0xFF". And the default
234257
+** maximum number of levels is 64.
234258
+**
234259
+** See below for more on structure record formats.
234260
+*/
234261
+#define FTS5_STRUCTURE_V2 "\xFF\x00\x00\x01"
234262
+
233262234263
/*
233263234264
** Details:
233264234265
**
233265234266
** The %_data table managed by this module,
233266234267
**
233267234268
** CREATE TABLE %_data(id INTEGER PRIMARY KEY, block BLOB);
233268234269
**
233269
-** , contains the following 5 types of records. See the comments surrounding
234270
+** , contains the following 6 types of records. See the comments surrounding
233270234271
** the FTS5_*_ROWID macros below for a description of how %_data rowids are
233271234272
** assigned to each fo them.
233272234273
**
233273234274
** 1. Structure Records:
233274234275
**
233275234276
** The set of segments that make up an index - the index structure - are
233276234277
** recorded in a single record within the %_data table. The record consists
233277234278
** of a single 32-bit configuration cookie value followed by a list of
233278
-** SQLite varints. If the FTS table features more than one index (because
233279
-** there are one or more prefix indexes), it is guaranteed that all share
233280
-** the same cookie value.
234279
+** SQLite varints.
233281234280
**
233282
-** Immediately following the configuration cookie, the record begins with
233283
-** three varints:
234281
+** If the structure record is a V2 record, the configuration cookie is
234282
+** followed by the following 4 bytes: [0xFF 0x00 0x00 0x01].
234283
+**
234284
+** Next, the record continues with three varints:
233284234285
**
233285234286
** + number of levels,
233286234287
** + total number of segments on all levels,
233287234288
** + value of write counter.
233288234289
**
@@ -233293,10 +234294,16 @@
233293234294
** + for each segment from oldest to newest:
233294234295
** + segment id (always > 0)
233295234296
** + first leaf page number (often 1, always greater than 0)
233296234297
** + final leaf page number
233297234298
**
234299
+** Then, for V2 structures only:
234300
+**
234301
+** + lower origin counter value,
234302
+** + upper origin counter value,
234303
+** + the number of tombstone hash pages.
234304
+**
233298234305
** 2. The Averages Record:
233299234306
**
233300234307
** A single record within the %_data table. The data is a list of varints.
233301234308
** The first value is the number of rows in the index. Then, for each column
233302234309
** from left to right, the total number of tokens in the column for all
@@ -233408,10 +234415,42 @@
233408234415
** * Copy of first rowid on page indicated by previous field. As a varint.
233409234416
**
233410234417
** * A list of delta-encoded varints - the first rowid on each subsequent
233411234418
** child page.
233412234419
**
234420
+** 6. Tombstone Hash Page
234421
+**
234422
+** These records are only ever present in contentless_delete=1 tables.
234423
+** There are zero or more of these associated with each segment. They
234424
+** are used to store the tombstone rowids for rows contained in the
234425
+** associated segments.
234426
+**
234427
+** The set of nHashPg tombstone hash pages associated with a single
234428
+** segment together form a single hash table containing tombstone rowids.
234429
+** To find the page of the hash on which a key might be stored:
234430
+**
234431
+** iPg = (rowid % nHashPg)
234432
+**
234433
+** Then, within page iPg, which has nSlot slots:
234434
+**
234435
+** iSlot = (rowid / nHashPg) % nSlot
234436
+**
234437
+** Each tombstone hash page begins with an 8 byte header:
234438
+**
234439
+** 1-byte: Key-size (the size in bytes of each slot). Either 4 or 8.
234440
+** 1-byte: rowid-0-tombstone flag. This flag is only valid on the
234441
+** first tombstone hash page for each segment (iPg=0). If set,
234442
+** the hash table contains rowid 0. If clear, it does not.
234443
+** Rowid 0 is handled specially.
234444
+** 2-bytes: unused.
234445
+** 4-bytes: Big-endian integer containing number of entries on page.
234446
+**
234447
+** Following this are nSlot 4 or 8 byte slots (depending on the key-size
234448
+** in the first byte of the page header). The number of slots may be
234449
+** determined based on the size of the page record and the key-size:
234450
+**
234451
+** nSlot = (nByte - 8) / key-size
233413234452
*/
233414234453
233415234454
/*
233416234455
** Rowids for the averages and structure records in the %_data table.
233417234456
*/
@@ -233441,10 +234480,11 @@
233441234480
((i64)(pgno)) \
233442234481
)
233443234482
233444234483
#define FTS5_SEGMENT_ROWID(segid, pgno) fts5_dri(segid, 0, 0, pgno)
233445234484
#define FTS5_DLIDX_ROWID(segid, height, pgno) fts5_dri(segid, 1, height, pgno)
234485
+#define FTS5_TOMBSTONE_ROWID(segid,ipg) fts5_dri(segid+(1<<16), 0, 0, ipg)
233446234486
233447234487
#ifdef SQLITE_DEBUG
233448234488
static int sqlite3Fts5Corrupt() { return SQLITE_CORRUPT_VTAB; }
233449234489
#endif
233450234490
@@ -233476,10 +234516,16 @@
233476234516
int szLeaf; /* Size of leaf without page-index */
233477234517
};
233478234518
233479234519
/*
233480234520
** One object per %_data table.
234521
+**
234522
+** nContentlessDelete:
234523
+** The number of contentless delete operations since the most recent
234524
+** call to fts5IndexFlush() or fts5IndexDiscardData(). This is tracked
234525
+** so that extra auto-merge work can be done by fts5IndexFlush() to
234526
+** account for the delete operations.
233481234527
*/
233482234528
struct Fts5Index {
233483234529
Fts5Config *pConfig; /* Virtual table configuration */
233484234530
char *zDataTbl; /* Name of %_data table */
233485234531
int nWorkUnit; /* Leaf pages in a "unit" of work */
@@ -233490,10 +234536,12 @@
233490234536
*/
233491234537
Fts5Hash *pHash; /* Hash table for in-memory data */
233492234538
int nPendingData; /* Current bytes of pending data */
233493234539
i64 iWriteRowid; /* Rowid for current doc being written */
233494234540
int bDelete; /* Current write is a delete */
234541
+ int nContentlessDelete; /* Number of contentless delete ops */
234542
+ int nPendingRow; /* Number of INSERT in hash table */
233495234543
233496234544
/* Error state. */
233497234545
int rc; /* Current error code */
233498234546
233499234547
/* State used by the fts5DataXXX() functions. */
@@ -233524,24 +234572,37 @@
233524234572
233525234573
/*
233526234574
** The contents of the "structure" record for each index are represented
233527234575
** using an Fts5Structure record in memory. Which uses instances of the
233528234576
** other Fts5StructureXXX types as components.
234577
+**
234578
+** nOriginCntr:
234579
+** This value is set to non-zero for structure records created for
234580
+** contentlessdelete=1 tables only. In that case it represents the
234581
+** origin value to apply to the next top-level segment created.
233529234582
*/
233530234583
struct Fts5StructureSegment {
233531234584
int iSegid; /* Segment id */
233532234585
int pgnoFirst; /* First leaf page number in segment */
233533234586
int pgnoLast; /* Last leaf page number in segment */
234587
+
234588
+ /* contentlessdelete=1 tables only: */
234589
+ u64 iOrigin1;
234590
+ u64 iOrigin2;
234591
+ int nPgTombstone; /* Number of tombstone hash table pages */
234592
+ u64 nEntryTombstone; /* Number of tombstone entries that "count" */
234593
+ u64 nEntry; /* Number of rows in this segment */
233534234594
};
233535234595
struct Fts5StructureLevel {
233536234596
int nMerge; /* Number of segments in incr-merge */
233537234597
int nSeg; /* Total number of segments on level */
233538234598
Fts5StructureSegment *aSeg; /* Array of segments. aSeg[0] is oldest. */
233539234599
};
233540234600
struct Fts5Structure {
233541234601
int nRef; /* Object reference count */
233542234602
u64 nWriteCounter; /* Total leaves written to level 0 */
234603
+ u64 nOriginCntr; /* Origin value for next top-level segment */
233543234604
int nSegment; /* Total segments in this structure */
233544234605
int nLevel; /* Number of levels in this index */
233545234606
Fts5StructureLevel aLevel[1]; /* Array of nLevel level objects */
233546234607
};
233547234608
@@ -233626,18 +234687,27 @@
233626234687
** corresponding aRowidOffset[] entry is set to the byte offset of the
233627234688
** start of the "position-list-size" field within the page.
233628234689
**
233629234690
** iTermIdx:
233630234691
** Index of current term on iTermLeafPgno.
234692
+**
234693
+** apTombstone/nTombstone:
234694
+** These are used for contentless_delete=1 tables only. When the cursor
234695
+** is first allocated, the apTombstone[] array is allocated so that it
234696
+** is large enough for all tombstones hash pages associated with the
234697
+** segment. The pages themselves are loaded lazily from the database as
234698
+** they are required.
233631234699
*/
233632234700
struct Fts5SegIter {
233633234701
Fts5StructureSegment *pSeg; /* Segment to iterate through */
233634234702
int flags; /* Mask of configuration flags */
233635234703
int iLeafPgno; /* Current leaf page number */
233636234704
Fts5Data *pLeaf; /* Current leaf data */
233637234705
Fts5Data *pNextLeaf; /* Leaf page (iLeafPgno+1) */
233638234706
i64 iLeafOffset; /* Byte offset within current leaf */
234707
+ Fts5Data **apTombstone; /* Array of tombstone pages */
234708
+ int nTombstone;
233639234709
233640234710
/* Next method */
233641234711
void (*xNext)(Fts5Index*, Fts5SegIter*, int*);
233642234712
233643234713
/* The page and offset from which the current term was read. The offset
@@ -233762,10 +234832,64 @@
233762234832
}
233763234833
233764234834
static u16 fts5GetU16(const u8 *aIn){
233765234835
return ((u16)aIn[0] << 8) + aIn[1];
233766234836
}
234837
+
234838
+/*
234839
+** The only argument points to a buffer at least 8 bytes in size. This
234840
+** function interprets the first 8 bytes of the buffer as a 64-bit big-endian
234841
+** unsigned integer and returns the result.
234842
+*/
234843
+static u64 fts5GetU64(u8 *a){
234844
+ return ((u64)a[0] << 56)
234845
+ + ((u64)a[1] << 48)
234846
+ + ((u64)a[2] << 40)
234847
+ + ((u64)a[3] << 32)
234848
+ + ((u64)a[4] << 24)
234849
+ + ((u64)a[5] << 16)
234850
+ + ((u64)a[6] << 8)
234851
+ + ((u64)a[7] << 0);
234852
+}
234853
+
234854
+/*
234855
+** The only argument points to a buffer at least 4 bytes in size. This
234856
+** function interprets the first 4 bytes of the buffer as a 32-bit big-endian
234857
+** unsigned integer and returns the result.
234858
+*/
234859
+static u32 fts5GetU32(const u8 *a){
234860
+ return ((u32)a[0] << 24)
234861
+ + ((u32)a[1] << 16)
234862
+ + ((u32)a[2] << 8)
234863
+ + ((u32)a[3] << 0);
234864
+}
234865
+
234866
+/*
234867
+** Write iVal, formated as a 64-bit big-endian unsigned integer, to the
234868
+** buffer indicated by the first argument.
234869
+*/
234870
+static void fts5PutU64(u8 *a, u64 iVal){
234871
+ a[0] = ((iVal >> 56) & 0xFF);
234872
+ a[1] = ((iVal >> 48) & 0xFF);
234873
+ a[2] = ((iVal >> 40) & 0xFF);
234874
+ a[3] = ((iVal >> 32) & 0xFF);
234875
+ a[4] = ((iVal >> 24) & 0xFF);
234876
+ a[5] = ((iVal >> 16) & 0xFF);
234877
+ a[6] = ((iVal >> 8) & 0xFF);
234878
+ a[7] = ((iVal >> 0) & 0xFF);
234879
+}
234880
+
234881
+/*
234882
+** Write iVal, formated as a 32-bit big-endian unsigned integer, to the
234883
+** buffer indicated by the first argument.
234884
+*/
234885
+static void fts5PutU32(u8 *a, u32 iVal){
234886
+ a[0] = ((iVal >> 24) & 0xFF);
234887
+ a[1] = ((iVal >> 16) & 0xFF);
234888
+ a[2] = ((iVal >> 8) & 0xFF);
234889
+ a[3] = ((iVal >> 0) & 0xFF);
234890
+}
233767234891
233768234892
/*
233769234893
** Allocate and return a buffer at least nByte bytes in size.
233770234894
**
233771234895
** If an OOM error is encountered, return NULL and set the error code in
@@ -233990,14 +235114,21 @@
233990235114
}
233991235115
233992235116
/*
233993235117
** Remove all records associated with segment iSegid.
233994235118
*/
233995
-static void fts5DataRemoveSegment(Fts5Index *p, int iSegid){
235119
+static void fts5DataRemoveSegment(Fts5Index *p, Fts5StructureSegment *pSeg){
235120
+ int iSegid = pSeg->iSegid;
233996235121
i64 iFirst = FTS5_SEGMENT_ROWID(iSegid, 0);
233997235122
i64 iLast = FTS5_SEGMENT_ROWID(iSegid+1, 0)-1;
233998235123
fts5DataDelete(p, iFirst, iLast);
235124
+
235125
+ if( pSeg->nPgTombstone ){
235126
+ i64 iTomb1 = FTS5_TOMBSTONE_ROWID(iSegid, 0);
235127
+ i64 iTomb2 = FTS5_TOMBSTONE_ROWID(iSegid, pSeg->nPgTombstone-1);
235128
+ fts5DataDelete(p, iTomb1, iTomb2);
235129
+ }
233999235130
if( p->pIdxDeleter==0 ){
234000235131
Fts5Config *pConfig = p->pConfig;
234001235132
fts5IndexPrepareStmt(p, &p->pIdxDeleter, sqlite3_mprintf(
234002235133
"DELETE FROM '%q'.'%q_idx' WHERE segid=?",
234003235134
pConfig->zDb, pConfig->zName
@@ -234104,14 +235235,22 @@
234104235235
int iLvl;
234105235236
int nLevel = 0;
234106235237
int nSegment = 0;
234107235238
sqlite3_int64 nByte; /* Bytes of space to allocate at pRet */
234108235239
Fts5Structure *pRet = 0; /* Structure object to return */
235240
+ int bStructureV2 = 0; /* True for FTS5_STRUCTURE_V2 */
235241
+ u64 nOriginCntr = 0; /* Largest origin value seen so far */
234109235242
234110235243
/* Grab the cookie value */
234111235244
if( piCookie ) *piCookie = sqlite3Fts5Get32(pData);
234112235245
i = 4;
235246
+
235247
+ /* Check if this is a V2 structure record. Set bStructureV2 if it is. */
235248
+ if( 0==memcmp(&pData[i], FTS5_STRUCTURE_V2, 4) ){
235249
+ i += 4;
235250
+ bStructureV2 = 1;
235251
+ }
234113235252
234114235253
/* Read the total number of levels and segments from the start of the
234115235254
** structure record. */
234116235255
i += fts5GetVarint32(&pData[i], nLevel);
234117235256
i += fts5GetVarint32(&pData[i], nSegment);
@@ -234159,10 +235298,18 @@
234159235298
}
234160235299
assert( pSeg!=0 );
234161235300
i += fts5GetVarint32(&pData[i], pSeg->iSegid);
234162235301
i += fts5GetVarint32(&pData[i], pSeg->pgnoFirst);
234163235302
i += fts5GetVarint32(&pData[i], pSeg->pgnoLast);
235303
+ if( bStructureV2 ){
235304
+ i += fts5GetVarint(&pData[i], &pSeg->iOrigin1);
235305
+ i += fts5GetVarint(&pData[i], &pSeg->iOrigin2);
235306
+ i += fts5GetVarint32(&pData[i], pSeg->nPgTombstone);
235307
+ i += fts5GetVarint(&pData[i], &pSeg->nEntryTombstone);
235308
+ i += fts5GetVarint(&pData[i], &pSeg->nEntry);
235309
+ nOriginCntr = MAX(nOriginCntr, pSeg->iOrigin2);
235310
+ }
234164235311
if( pSeg->pgnoLast<pSeg->pgnoFirst ){
234165235312
rc = FTS5_CORRUPT;
234166235313
break;
234167235314
}
234168235315
}
@@ -234169,10 +235316,13 @@
234169235316
if( iLvl>0 && pLvl[-1].nMerge && nTotal==0 ) rc = FTS5_CORRUPT;
234170235317
if( iLvl==nLevel-1 && pLvl->nMerge ) rc = FTS5_CORRUPT;
234171235318
}
234172235319
}
234173235320
if( nSegment!=0 && rc==SQLITE_OK ) rc = FTS5_CORRUPT;
235321
+ if( bStructureV2 ){
235322
+ pRet->nOriginCntr = nOriginCntr+1;
235323
+ }
234174235324
234175235325
if( rc!=SQLITE_OK ){
234176235326
fts5StructureRelease(pRet);
234177235327
pRet = 0;
234178235328
}
@@ -234381,21 +235531,25 @@
234381235531
static void fts5StructureWrite(Fts5Index *p, Fts5Structure *pStruct){
234382235532
if( p->rc==SQLITE_OK ){
234383235533
Fts5Buffer buf; /* Buffer to serialize record into */
234384235534
int iLvl; /* Used to iterate through levels */
234385235535
int iCookie; /* Cookie value to store */
235536
+ int nHdr = (pStruct->nOriginCntr>0 ? (4+4+9+9+9) : (4+9+9));
234386235537
234387235538
assert( pStruct->nSegment==fts5StructureCountSegments(pStruct) );
234388235539
memset(&buf, 0, sizeof(Fts5Buffer));
234389235540
234390235541
/* Append the current configuration cookie */
234391235542
iCookie = p->pConfig->iCookie;
234392235543
if( iCookie<0 ) iCookie = 0;
234393235544
234394
- if( 0==sqlite3Fts5BufferSize(&p->rc, &buf, 4+9+9+9) ){
235545
+ if( 0==sqlite3Fts5BufferSize(&p->rc, &buf, nHdr) ){
234395235546
sqlite3Fts5Put32(buf.p, iCookie);
234396235547
buf.n = 4;
235548
+ if( pStruct->nOriginCntr>0 ){
235549
+ fts5BufferSafeAppendBlob(&buf, FTS5_STRUCTURE_V2, 4);
235550
+ }
234397235551
fts5BufferSafeAppendVarint(&buf, pStruct->nLevel);
234398235552
fts5BufferSafeAppendVarint(&buf, pStruct->nSegment);
234399235553
fts5BufferSafeAppendVarint(&buf, (i64)pStruct->nWriteCounter);
234400235554
}
234401235555
@@ -234405,13 +235559,21 @@
234405235559
fts5BufferAppendVarint(&p->rc, &buf, pLvl->nMerge);
234406235560
fts5BufferAppendVarint(&p->rc, &buf, pLvl->nSeg);
234407235561
assert( pLvl->nMerge<=pLvl->nSeg );
234408235562
234409235563
for(iSeg=0; iSeg<pLvl->nSeg; iSeg++){
234410
- fts5BufferAppendVarint(&p->rc, &buf, pLvl->aSeg[iSeg].iSegid);
234411
- fts5BufferAppendVarint(&p->rc, &buf, pLvl->aSeg[iSeg].pgnoFirst);
234412
- fts5BufferAppendVarint(&p->rc, &buf, pLvl->aSeg[iSeg].pgnoLast);
235564
+ Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg];
235565
+ fts5BufferAppendVarint(&p->rc, &buf, pSeg->iSegid);
235566
+ fts5BufferAppendVarint(&p->rc, &buf, pSeg->pgnoFirst);
235567
+ fts5BufferAppendVarint(&p->rc, &buf, pSeg->pgnoLast);
235568
+ if( pStruct->nOriginCntr>0 ){
235569
+ fts5BufferAppendVarint(&p->rc, &buf, pSeg->iOrigin1);
235570
+ fts5BufferAppendVarint(&p->rc, &buf, pSeg->iOrigin2);
235571
+ fts5BufferAppendVarint(&p->rc, &buf, pSeg->nPgTombstone);
235572
+ fts5BufferAppendVarint(&p->rc, &buf, pSeg->nEntryTombstone);
235573
+ fts5BufferAppendVarint(&p->rc, &buf, pSeg->nEntry);
235574
+ }
234413235575
}
234414235576
}
234415235577
234416235578
fts5DataWrite(p, FTS5_STRUCTURE_ROWID, buf.p, buf.n);
234417235579
fts5BufferFree(&buf);
@@ -234929,10 +236091,27 @@
234929236091
pIter->xNext = fts5SegIterNext_None;
234930236092
}else{
234931236093
pIter->xNext = fts5SegIterNext;
234932236094
}
234933236095
}
236096
+
236097
+/*
236098
+** Allocate a tombstone hash page array (pIter->apTombstone) for the
236099
+** iterator passed as the second argument. If an OOM error occurs, leave
236100
+** an error in the Fts5Index object.
236101
+*/
236102
+static void fts5SegIterAllocTombstone(Fts5Index *p, Fts5SegIter *pIter){
236103
+ const int nTomb = pIter->pSeg->nPgTombstone;
236104
+ if( nTomb>0 ){
236105
+ Fts5Data **apTomb = 0;
236106
+ apTomb = (Fts5Data**)sqlite3Fts5MallocZero(&p->rc, sizeof(Fts5Data)*nTomb);
236107
+ if( apTomb ){
236108
+ pIter->apTombstone = apTomb;
236109
+ pIter->nTombstone = nTomb;
236110
+ }
236111
+ }
236112
+}
234934236113
234935236114
/*
234936236115
** Initialize the iterator object pIter to iterate through the entries in
234937236116
** segment pSeg. The iterator is left pointing to the first entry when
234938236117
** this function returns.
@@ -234971,10 +236150,11 @@
234971236150
assert_nc( pIter->pLeaf->nn>4 );
234972236151
assert_nc( fts5LeafFirstTermOff(pIter->pLeaf)==4 );
234973236152
pIter->iPgidxOff = pIter->pLeaf->szLeaf+1;
234974236153
fts5SegIterLoadTerm(p, pIter, 0);
234975236154
fts5SegIterLoadNPos(p, pIter);
236155
+ fts5SegIterAllocTombstone(p, pIter);
234976236156
}
234977236157
}
234978236158
234979236159
/*
234980236160
** This function is only ever called on iterators created by calls to
@@ -235672,10 +236852,11 @@
235672236852
}
235673236853
}
235674236854
}
235675236855
235676236856
fts5SegIterSetNext(p, pIter);
236857
+ fts5SegIterAllocTombstone(p, pIter);
235677236858
235678236859
/* Either:
235679236860
**
235680236861
** 1) an error has occurred, or
235681236862
** 2) the iterator points to EOF, or
@@ -235751,18 +236932,33 @@
235751236932
}
235752236933
}
235753236934
235754236935
fts5SegIterSetNext(p, pIter);
235755236936
}
236937
+
236938
+/*
236939
+** Array ap[] contains n elements. Release each of these elements using
236940
+** fts5DataRelease(). Then free the array itself using sqlite3_free().
236941
+*/
236942
+static void fts5IndexFreeArray(Fts5Data **ap, int n){
236943
+ if( ap ){
236944
+ int ii;
236945
+ for(ii=0; ii<n; ii++){
236946
+ fts5DataRelease(ap[ii]);
236947
+ }
236948
+ sqlite3_free(ap);
236949
+ }
236950
+}
235756236951
235757236952
/*
235758236953
** Zero the iterator passed as the only argument.
235759236954
*/
235760236955
static void fts5SegIterClear(Fts5SegIter *pIter){
235761236956
fts5BufferFree(&pIter->term);
235762236957
fts5DataRelease(pIter->pLeaf);
235763236958
fts5DataRelease(pIter->pNextLeaf);
236959
+ fts5IndexFreeArray(pIter->apTombstone, pIter->nTombstone);
235764236960
fts5DlidxIterFree(pIter->pDlidx);
235765236961
sqlite3_free(pIter->aRowidOffset);
235766236962
memset(pIter, 0, sizeof(Fts5SegIter));
235767236963
}
235768236964
@@ -236095,10 +237291,88 @@
236095237291
static void fts5MultiIterSetEof(Fts5Iter *pIter){
236096237292
Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
236097237293
pIter->base.bEof = pSeg->pLeaf==0;
236098237294
pIter->iSwitchRowid = pSeg->iRowid;
236099237295
}
237296
+
237297
+/*
237298
+** The argument to this macro must be an Fts5Data structure containing a
237299
+** tombstone hash page. This macro returns the key-size of the hash-page.
237300
+*/
237301
+#define TOMBSTONE_KEYSIZE(pPg) (pPg->p[0]==4 ? 4 : 8)
237302
+
237303
+#define TOMBSTONE_NSLOT(pPg) \
237304
+ ((pPg->nn > 16) ? ((pPg->nn-8) / TOMBSTONE_KEYSIZE(pPg)) : 1)
237305
+
237306
+/*
237307
+** Query a single tombstone hash table for rowid iRowid. Return true if
237308
+** it is found or false otherwise. The tombstone hash table is one of
237309
+** nHashTable tables.
237310
+*/
237311
+static int fts5IndexTombstoneQuery(
237312
+ Fts5Data *pHash, /* Hash table page to query */
237313
+ int nHashTable, /* Number of pages attached to segment */
237314
+ u64 iRowid /* Rowid to query hash for */
237315
+){
237316
+ const int szKey = TOMBSTONE_KEYSIZE(pHash);
237317
+ const int nSlot = TOMBSTONE_NSLOT(pHash);
237318
+ int iSlot = (iRowid / nHashTable) % nSlot;
237319
+ int nCollide = nSlot;
237320
+
237321
+ if( iRowid==0 ){
237322
+ return pHash->p[1];
237323
+ }else if( szKey==4 ){
237324
+ u32 *aSlot = (u32*)&pHash->p[8];
237325
+ while( aSlot[iSlot] ){
237326
+ if( fts5GetU32((u8*)&aSlot[iSlot])==iRowid ) return 1;
237327
+ if( nCollide--==0 ) break;
237328
+ iSlot = (iSlot+1)%nSlot;
237329
+ }
237330
+ }else{
237331
+ u64 *aSlot = (u64*)&pHash->p[8];
237332
+ while( aSlot[iSlot] ){
237333
+ if( fts5GetU64((u8*)&aSlot[iSlot])==iRowid ) return 1;
237334
+ if( nCollide--==0 ) break;
237335
+ iSlot = (iSlot+1)%nSlot;
237336
+ }
237337
+ }
237338
+
237339
+ return 0;
237340
+}
237341
+
237342
+/*
237343
+** Return true if the iterator passed as the only argument points
237344
+** to an segment entry for which there is a tombstone. Return false
237345
+** if there is no tombstone or if the iterator is already at EOF.
237346
+*/
237347
+static int fts5MultiIterIsDeleted(Fts5Iter *pIter){
237348
+ int iFirst = pIter->aFirst[1].iFirst;
237349
+ Fts5SegIter *pSeg = &pIter->aSeg[iFirst];
237350
+
237351
+ if( pSeg->pLeaf && pSeg->nTombstone ){
237352
+ /* Figure out which page the rowid might be present on. */
237353
+ int iPg = ((u64)pSeg->iRowid) % pSeg->nTombstone;
237354
+ assert( iPg>=0 );
237355
+
237356
+ /* If tombstone hash page iPg has not yet been loaded from the
237357
+ ** database, load it now. */
237358
+ if( pSeg->apTombstone[iPg]==0 ){
237359
+ pSeg->apTombstone[iPg] = fts5DataRead(pIter->pIndex,
237360
+ FTS5_TOMBSTONE_ROWID(pSeg->pSeg->iSegid, iPg)
237361
+ );
237362
+ if( pSeg->apTombstone[iPg]==0 ) return 0;
237363
+ }
237364
+
237365
+ return fts5IndexTombstoneQuery(
237366
+ pSeg->apTombstone[iPg],
237367
+ pSeg->nTombstone,
237368
+ pSeg->iRowid
237369
+ );
237370
+ }
237371
+
237372
+ return 0;
237373
+}
236100237374
236101237375
/*
236102237376
** Move the iterator to the next entry.
236103237377
**
236104237378
** If an error occurs, an error code is left in Fts5Index.rc. It is not
@@ -236133,11 +237407,13 @@
236133237407
if( pSeg->pLeaf==0 ) return;
236134237408
}
236135237409
236136237410
fts5AssertMultiIterSetup(p, pIter);
236137237411
assert( pSeg==&pIter->aSeg[pIter->aFirst[1].iFirst] && pSeg->pLeaf );
236138
- if( pIter->bSkipEmpty==0 || pSeg->nPos ){
237412
+ if( (pIter->bSkipEmpty==0 || pSeg->nPos)
237413
+ && 0==fts5MultiIterIsDeleted(pIter)
237414
+ ){
236139237415
pIter->xSetOutputs(pIter, pSeg);
236140237416
return;
236141237417
}
236142237418
bUseFrom = 0;
236143237419
}
@@ -236165,11 +237441,13 @@
236165237441
fts5MultiIterSetEof(pIter);
236166237442
*pbNewTerm = 1;
236167237443
}
236168237444
fts5AssertMultiIterSetup(p, pIter);
236169237445
236170
- }while( fts5MultiIterIsEmpty(p, pIter) );
237446
+ }while( (fts5MultiIterIsEmpty(p, pIter) || fts5MultiIterIsDeleted(pIter))
237447
+ && (p->rc==SQLITE_OK)
237448
+ );
236171237449
}
236172237450
}
236173237451
236174237452
static void fts5IterSetOutputs_Noop(Fts5Iter *pUnused1, Fts5SegIter *pUnused2){
236175237453
UNUSED_PARAM2(pUnused1, pUnused2);
@@ -236720,11 +237998,13 @@
236720237998
}
236721237999
}
236722238000
fts5MultiIterSetEof(pNew);
236723238001
fts5AssertMultiIterSetup(p, pNew);
236724238002
236725
- if( pNew->bSkipEmpty && fts5MultiIterIsEmpty(p, pNew) ){
238003
+ if( (pNew->bSkipEmpty && fts5MultiIterIsEmpty(p, pNew))
238004
+ || fts5MultiIterIsDeleted(pNew)
238005
+ ){
236726238006
fts5MultiIterNext(p, pNew, 0, 0);
236727238007
}else if( pNew->base.bEof==0 ){
236728238008
Fts5SegIter *pSeg = &pNew->aSeg[pNew->aFirst[1].iFirst];
236729238009
pNew->xSetOutputs(pNew, pSeg);
236730238010
}
@@ -236898,11 +238178,13 @@
236898238178
static void fts5IndexDiscardData(Fts5Index *p){
236899238179
assert( p->pHash || p->nPendingData==0 );
236900238180
if( p->pHash ){
236901238181
sqlite3Fts5HashClear(p->pHash);
236902238182
p->nPendingData = 0;
238183
+ p->nPendingRow = 0;
236903238184
}
238185
+ p->nContentlessDelete = 0;
236904238186
}
236905238187
236906238188
/*
236907238189
** Return the size of the prefix, in bytes, that buffer
236908238190
** (pNew/<length-unknown>) shares with buffer (pOld/nOld).
@@ -237535,10 +238817,16 @@
237535238817
pSeg->iSegid = iSegid;
237536238818
pStruct->nSegment++;
237537238819
237538238820
/* Read input from all segments in the input level */
237539238821
nInput = pLvl->nSeg;
238822
+
238823
+ /* Set the range of origins that will go into the output segment. */
238824
+ if( pStruct->nOriginCntr>0 ){
238825
+ pSeg->iOrigin1 = pLvl->aSeg[0].iOrigin1;
238826
+ pSeg->iOrigin2 = pLvl->aSeg[pLvl->nSeg-1].iOrigin2;
238827
+ }
237540238828
}
237541238829
bOldest = (pLvlOut->nSeg==1 && pStruct->nLevel==iLvl+2);
237542238830
237543238831
assert( iLvl>=0 );
237544238832
for(fts5MultiIterNew(p, pStruct, flags, 0, 0, 0, iLvl, nInput, &pIter);
@@ -237594,12 +238882,15 @@
237594238882
assert( pIter!=0 || p->rc!=SQLITE_OK );
237595238883
if( fts5MultiIterEof(p, pIter) ){
237596238884
int i;
237597238885
237598238886
/* Remove the redundant segments from the %_data table */
238887
+ assert( pSeg->nEntry==0 );
237599238888
for(i=0; i<nInput; i++){
237600
- fts5DataRemoveSegment(p, pLvl->aSeg[i].iSegid);
238889
+ Fts5StructureSegment *pOld = &pLvl->aSeg[i];
238890
+ pSeg->nEntry += (pOld->nEntry - pOld->nEntryTombstone);
238891
+ fts5DataRemoveSegment(p, pOld);
237601238892
}
237602238893
237603238894
/* Remove the redundant segments from the input level */
237604238895
if( pLvl->nSeg!=nInput ){
237605238896
int nMove = (pLvl->nSeg - nInput) * sizeof(Fts5StructureSegment);
@@ -237620,10 +238911,47 @@
237620238911
237621238912
fts5MultiIterFree(pIter);
237622238913
fts5BufferFree(&term);
237623238914
if( pnRem ) *pnRem -= writer.nLeafWritten;
237624238915
}
238916
+
238917
+/*
238918
+** If this is not a contentless_delete=1 table, or if the 'deletemerge'
238919
+** configuration option is set to 0, then this function always returns -1.
238920
+** Otherwise, it searches the structure object passed as the second argument
238921
+** for a level suitable for merging due to having a large number of
238922
+** tombstones in the tombstone hash. If one is found, its index is returned.
238923
+** Otherwise, if there is no suitable level, -1.
238924
+*/
238925
+static int fts5IndexFindDeleteMerge(Fts5Index *p, Fts5Structure *pStruct){
238926
+ Fts5Config *pConfig = p->pConfig;
238927
+ int iRet = -1;
238928
+ if( pConfig->bContentlessDelete && pConfig->nDeleteMerge>0 ){
238929
+ int ii;
238930
+ int nBest = 0;
238931
+
238932
+ for(ii=0; ii<pStruct->nLevel; ii++){
238933
+ Fts5StructureLevel *pLvl = &pStruct->aLevel[ii];
238934
+ i64 nEntry = 0;
238935
+ i64 nTomb = 0;
238936
+ int iSeg;
238937
+ for(iSeg=0; iSeg<pLvl->nSeg; iSeg++){
238938
+ nEntry += pLvl->aSeg[iSeg].nEntry;
238939
+ nTomb += pLvl->aSeg[iSeg].nEntryTombstone;
238940
+ }
238941
+ assert_nc( nEntry>0 || pLvl->nSeg==0 );
238942
+ if( nEntry>0 ){
238943
+ int nPercent = (nTomb * 100) / nEntry;
238944
+ if( nPercent>=pConfig->nDeleteMerge && nPercent>nBest ){
238945
+ iRet = ii;
238946
+ nBest = nPercent;
238947
+ }
238948
+ }
238949
+ }
238950
+ }
238951
+ return iRet;
238952
+}
237625238953
237626238954
/*
237627238955
** Do up to nPg pages of automerge work on the index.
237628238956
**
237629238957
** Return true if any changes were actually made, or false otherwise.
@@ -237640,42 +238968,39 @@
237640238968
while( nRem>0 && p->rc==SQLITE_OK ){
237641238969
int iLvl; /* To iterate through levels */
237642238970
int iBestLvl = 0; /* Level offering the most input segments */
237643238971
int nBest = 0; /* Number of input segments on best level */
237644238972
237645
- /* Set iBestLvl to the level to read input segments from. */
238973
+ /* Set iBestLvl to the level to read input segments from. Or to -1 if
238974
+ ** there is no level suitable to merge segments from. */
237646238975
assert( pStruct->nLevel>0 );
237647238976
for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
237648238977
Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl];
237649238978
if( pLvl->nMerge ){
237650238979
if( pLvl->nMerge>nBest ){
237651238980
iBestLvl = iLvl;
237652
- nBest = pLvl->nMerge;
238981
+ nBest = nMin;
237653238982
}
237654238983
break;
237655238984
}
237656238985
if( pLvl->nSeg>nBest ){
237657238986
nBest = pLvl->nSeg;
237658238987
iBestLvl = iLvl;
237659238988
}
237660238989
}
237661
-
237662
- /* If nBest is still 0, then the index must be empty. */
237663
-#ifdef SQLITE_DEBUG
237664
- for(iLvl=0; nBest==0 && iLvl<pStruct->nLevel; iLvl++){
237665
- assert( pStruct->aLevel[iLvl].nSeg==0 );
237666
- }
237667
-#endif
237668
-
237669
- if( nBest<nMin && pStruct->aLevel[iBestLvl].nMerge==0 ){
237670
- break;
237671
- }
238990
+ if( nBest<nMin ){
238991
+ iBestLvl = fts5IndexFindDeleteMerge(p, pStruct);
238992
+ }
238993
+
238994
+ if( iBestLvl<0 ) break;
237672238995
bRet = 1;
237673238996
fts5IndexMergeLevel(p, &pStruct, iBestLvl, &nRem);
237674238997
if( p->rc==SQLITE_OK && pStruct->aLevel[iBestLvl].nMerge==0 ){
237675238998
fts5StructurePromote(p, iBestLvl+1, pStruct);
237676238999
}
239000
+
239001
+ if( nMin==1 ) nMin = 2;
237677239002
}
237678239003
*ppStruct = pStruct;
237679239004
return bRet;
237680239005
}
237681239006
@@ -237856,13 +239181,17 @@
237856239181
if( pLeaf->nn>pLeaf->szLeaf ){
237857239182
int iFirst = 0;
237858239183
int i1 = pLeaf->szLeaf;
237859239184
int i2 = 0;
237860239185
239186
+ i1 += fts5GetVarint32(&aPg[i1], iFirst);
239187
+ if( iFirst<iNext ){
239188
+ p->rc = FTS5_CORRUPT;
239189
+ break;
239190
+ }
237861239191
aIdx = sqlite3Fts5MallocZero(&p->rc, (pLeaf->nn-pLeaf->szLeaf)+2);
237862239192
if( aIdx==0 ) break;
237863
- i1 += fts5GetVarint32(&aPg[i1], iFirst);
237864239193
i2 = sqlite3Fts5PutVarint(aIdx, iFirst-nShift);
237865239194
if( i1<pLeaf->nn ){
237866239195
memcpy(&aIdx[i2], &aPg[i1], pLeaf->nn-i1);
237867239196
i2 += (pLeaf->nn-i1);
237868239197
}
@@ -238180,202 +239509,212 @@
238180239509
int pgnoLast = 0; /* Last leaf page number in segment */
238181239510
238182239511
/* Obtain a reference to the index structure and allocate a new segment-id
238183239512
** for the new level-0 segment. */
238184239513
pStruct = fts5StructureRead(p);
238185
- iSegid = fts5AllocateSegid(p, pStruct);
238186
- fts5StructureInvalidate(p);
238187
-
238188
- if( iSegid ){
238189
- const int pgsz = p->pConfig->pgsz;
238190
- int eDetail = p->pConfig->eDetail;
238191
- int bSecureDelete = p->pConfig->bSecureDelete;
238192
- Fts5StructureSegment *pSeg; /* New segment within pStruct */
238193
- Fts5Buffer *pBuf; /* Buffer in which to assemble leaf page */
238194
- Fts5Buffer *pPgidx; /* Buffer in which to assemble pgidx */
238195
-
238196
- Fts5SegWriter writer;
238197
- fts5WriteInit(p, &writer, iSegid);
238198
-
238199
- pBuf = &writer.writer.buf;
238200
- pPgidx = &writer.writer.pgidx;
238201
-
238202
- /* fts5WriteInit() should have initialized the buffers to (most likely)
238203
- ** the maximum space required. */
238204
- assert( p->rc || pBuf->nSpace>=(pgsz + FTS5_DATA_PADDING) );
238205
- assert( p->rc || pPgidx->nSpace>=(pgsz + FTS5_DATA_PADDING) );
238206
-
238207
- /* Begin scanning through hash table entries. This loop runs once for each
238208
- ** term/doclist currently stored within the hash table. */
238209
- if( p->rc==SQLITE_OK ){
238210
- p->rc = sqlite3Fts5HashScanInit(pHash, 0, 0);
238211
- }
238212
- while( p->rc==SQLITE_OK && 0==sqlite3Fts5HashScanEof(pHash) ){
238213
- const char *zTerm; /* Buffer containing term */
238214
- int nTerm; /* Size of zTerm in bytes */
238215
- const u8 *pDoclist; /* Pointer to doclist for this term */
238216
- int nDoclist; /* Size of doclist in bytes */
238217
-
238218
- /* Get the term and doclist for this entry. */
238219
- sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist);
238220
- nTerm = (int)strlen(zTerm);
238221
- if( bSecureDelete==0 ){
238222
- fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm);
238223
- if( p->rc!=SQLITE_OK ) break;
238224
- assert( writer.bFirstRowidInPage==0 );
238225
- }
238226
-
238227
- if( !bSecureDelete && pgsz>=(pBuf->n + pPgidx->n + nDoclist + 1) ){
238228
- /* The entire doclist will fit on the current leaf. */
238229
- fts5BufferSafeAppendBlob(pBuf, pDoclist, nDoclist);
238230
- }else{
238231
- int bTermWritten = !bSecureDelete;
238232
- i64 iRowid = 0;
238233
- i64 iPrev = 0;
238234
- int iOff = 0;
238235
-
238236
- /* The entire doclist will not fit on this leaf. The following
238237
- ** loop iterates through the poslists that make up the current
238238
- ** doclist. */
238239
- while( p->rc==SQLITE_OK && iOff<nDoclist ){
238240
- u64 iDelta = 0;
238241
- iOff += fts5GetVarint(&pDoclist[iOff], &iDelta);
238242
- iRowid += iDelta;
238243
-
238244
- /* If in secure delete mode, and if this entry in the poslist is
238245
- ** in fact a delete, then edit the existing segments directly
238246
- ** using fts5FlushSecureDelete(). */
238247
- if( bSecureDelete ){
238248
- if( eDetail==FTS5_DETAIL_NONE ){
238249
- if( iOff<nDoclist && pDoclist[iOff]==0x00 ){
238250
- fts5FlushSecureDelete(p, pStruct, zTerm, iRowid);
238251
- iOff++;
238252
- if( iOff<nDoclist && pDoclist[iOff]==0x00 ){
238253
- iOff++;
238254
- nDoclist = 0;
238255
- }else{
238256
- continue;
238257
- }
238258
- }
238259
- }else if( (pDoclist[iOff] & 0x01) ){
238260
- fts5FlushSecureDelete(p, pStruct, zTerm, iRowid);
238261
- if( p->rc!=SQLITE_OK || pDoclist[iOff]==0x01 ){
238262
- iOff++;
238263
- continue;
238264
- }
238265
- }
238266
- }
238267
-
238268
- if( p->rc==SQLITE_OK && bTermWritten==0 ){
238269
- fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm);
238270
- bTermWritten = 1;
238271
- assert( p->rc!=SQLITE_OK || writer.bFirstRowidInPage==0 );
238272
- }
238273
-
238274
- if( writer.bFirstRowidInPage ){
238275
- fts5PutU16(&pBuf->p[0], (u16)pBuf->n); /* first rowid on page */
238276
- pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid);
238277
- writer.bFirstRowidInPage = 0;
238278
- fts5WriteDlidxAppend(p, &writer, iRowid);
238279
- }else{
238280
- pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid-iPrev);
238281
- }
238282
- if( p->rc!=SQLITE_OK ) break;
238283
- assert( pBuf->n<=pBuf->nSpace );
238284
- iPrev = iRowid;
238285
-
238286
- if( eDetail==FTS5_DETAIL_NONE ){
238287
- if( iOff<nDoclist && pDoclist[iOff]==0 ){
238288
- pBuf->p[pBuf->n++] = 0;
238289
- iOff++;
238290
- if( iOff<nDoclist && pDoclist[iOff]==0 ){
238291
- pBuf->p[pBuf->n++] = 0;
238292
- iOff++;
238293
- }
238294
- }
238295
- if( (pBuf->n + pPgidx->n)>=pgsz ){
238296
- fts5WriteFlushLeaf(p, &writer);
238297
- }
238298
- }else{
238299
- int bDummy;
238300
- int nPos;
238301
- int nCopy = fts5GetPoslistSize(&pDoclist[iOff], &nPos, &bDummy);
238302
- nCopy += nPos;
238303
- if( (pBuf->n + pPgidx->n + nCopy) <= pgsz ){
238304
- /* The entire poslist will fit on the current leaf. So copy
238305
- ** it in one go. */
238306
- fts5BufferSafeAppendBlob(pBuf, &pDoclist[iOff], nCopy);
238307
- }else{
238308
- /* The entire poslist will not fit on this leaf. So it needs
238309
- ** to be broken into sections. The only qualification being
238310
- ** that each varint must be stored contiguously. */
238311
- const u8 *pPoslist = &pDoclist[iOff];
238312
- int iPos = 0;
238313
- while( p->rc==SQLITE_OK ){
238314
- int nSpace = pgsz - pBuf->n - pPgidx->n;
238315
- int n = 0;
238316
- if( (nCopy - iPos)<=nSpace ){
238317
- n = nCopy - iPos;
238318
- }else{
238319
- n = fts5PoslistPrefix(&pPoslist[iPos], nSpace);
238320
- }
238321
- assert( n>0 );
238322
- fts5BufferSafeAppendBlob(pBuf, &pPoslist[iPos], n);
238323
- iPos += n;
238324
- if( (pBuf->n + pPgidx->n)>=pgsz ){
238325
- fts5WriteFlushLeaf(p, &writer);
238326
- }
238327
- if( iPos>=nCopy ) break;
238328
- }
238329
- }
238330
- iOff += nCopy;
238331
- }
238332
- }
238333
- }
238334
-
238335
- /* TODO2: Doclist terminator written here. */
238336
- /* pBuf->p[pBuf->n++] = '\0'; */
238337
- assert( pBuf->n<=pBuf->nSpace );
238338
- if( p->rc==SQLITE_OK ) sqlite3Fts5HashScanNext(pHash);
238339
- }
238340
- sqlite3Fts5HashClear(pHash);
238341
- fts5WriteFinish(p, &writer, &pgnoLast);
238342
-
238343
- assert( p->rc!=SQLITE_OK || bSecureDelete || pgnoLast>0 );
238344
- if( pgnoLast>0 ){
238345
- /* Update the Fts5Structure. It is written back to the database by the
238346
- ** fts5StructureRelease() call below. */
238347
- if( pStruct->nLevel==0 ){
238348
- fts5StructureAddLevel(&p->rc, &pStruct);
238349
- }
238350
- fts5StructureExtendLevel(&p->rc, pStruct, 0, 1, 0);
238351
- if( p->rc==SQLITE_OK ){
238352
- pSeg = &pStruct->aLevel[0].aSeg[ pStruct->aLevel[0].nSeg++ ];
238353
- pSeg->iSegid = iSegid;
238354
- pSeg->pgnoFirst = 1;
238355
- pSeg->pgnoLast = pgnoLast;
238356
- pStruct->nSegment++;
238357
- }
238358
- fts5StructurePromote(p, 0, pStruct);
238359
- }
238360
- }
238361
-
238362
- fts5IndexAutomerge(p, &pStruct, pgnoLast);
238363
- fts5IndexCrisismerge(p, &pStruct);
238364
- fts5StructureWrite(p, pStruct);
238365
- fts5StructureRelease(pStruct);
239514
+ fts5StructureInvalidate(p);
239515
+
239516
+ if( sqlite3Fts5HashIsEmpty(pHash)==0 ){
239517
+ iSegid = fts5AllocateSegid(p, pStruct);
239518
+ if( iSegid ){
239519
+ const int pgsz = p->pConfig->pgsz;
239520
+ int eDetail = p->pConfig->eDetail;
239521
+ int bSecureDelete = p->pConfig->bSecureDelete;
239522
+ Fts5StructureSegment *pSeg; /* New segment within pStruct */
239523
+ Fts5Buffer *pBuf; /* Buffer in which to assemble leaf page */
239524
+ Fts5Buffer *pPgidx; /* Buffer in which to assemble pgidx */
239525
+
239526
+ Fts5SegWriter writer;
239527
+ fts5WriteInit(p, &writer, iSegid);
239528
+
239529
+ pBuf = &writer.writer.buf;
239530
+ pPgidx = &writer.writer.pgidx;
239531
+
239532
+ /* fts5WriteInit() should have initialized the buffers to (most likely)
239533
+ ** the maximum space required. */
239534
+ assert( p->rc || pBuf->nSpace>=(pgsz + FTS5_DATA_PADDING) );
239535
+ assert( p->rc || pPgidx->nSpace>=(pgsz + FTS5_DATA_PADDING) );
239536
+
239537
+ /* Begin scanning through hash table entries. This loop runs once for each
239538
+ ** term/doclist currently stored within the hash table. */
239539
+ if( p->rc==SQLITE_OK ){
239540
+ p->rc = sqlite3Fts5HashScanInit(pHash, 0, 0);
239541
+ }
239542
+ while( p->rc==SQLITE_OK && 0==sqlite3Fts5HashScanEof(pHash) ){
239543
+ const char *zTerm; /* Buffer containing term */
239544
+ int nTerm; /* Size of zTerm in bytes */
239545
+ const u8 *pDoclist; /* Pointer to doclist for this term */
239546
+ int nDoclist; /* Size of doclist in bytes */
239547
+
239548
+ /* Get the term and doclist for this entry. */
239549
+ sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist);
239550
+ nTerm = (int)strlen(zTerm);
239551
+ if( bSecureDelete==0 ){
239552
+ fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm);
239553
+ if( p->rc!=SQLITE_OK ) break;
239554
+ assert( writer.bFirstRowidInPage==0 );
239555
+ }
239556
+
239557
+ if( !bSecureDelete && pgsz>=(pBuf->n + pPgidx->n + nDoclist + 1) ){
239558
+ /* The entire doclist will fit on the current leaf. */
239559
+ fts5BufferSafeAppendBlob(pBuf, pDoclist, nDoclist);
239560
+ }else{
239561
+ int bTermWritten = !bSecureDelete;
239562
+ i64 iRowid = 0;
239563
+ i64 iPrev = 0;
239564
+ int iOff = 0;
239565
+
239566
+ /* The entire doclist will not fit on this leaf. The following
239567
+ ** loop iterates through the poslists that make up the current
239568
+ ** doclist. */
239569
+ while( p->rc==SQLITE_OK && iOff<nDoclist ){
239570
+ u64 iDelta = 0;
239571
+ iOff += fts5GetVarint(&pDoclist[iOff], &iDelta);
239572
+ iRowid += iDelta;
239573
+
239574
+ /* If in secure delete mode, and if this entry in the poslist is
239575
+ ** in fact a delete, then edit the existing segments directly
239576
+ ** using fts5FlushSecureDelete(). */
239577
+ if( bSecureDelete ){
239578
+ if( eDetail==FTS5_DETAIL_NONE ){
239579
+ if( iOff<nDoclist && pDoclist[iOff]==0x00 ){
239580
+ fts5FlushSecureDelete(p, pStruct, zTerm, iRowid);
239581
+ iOff++;
239582
+ if( iOff<nDoclist && pDoclist[iOff]==0x00 ){
239583
+ iOff++;
239584
+ nDoclist = 0;
239585
+ }else{
239586
+ continue;
239587
+ }
239588
+ }
239589
+ }else if( (pDoclist[iOff] & 0x01) ){
239590
+ fts5FlushSecureDelete(p, pStruct, zTerm, iRowid);
239591
+ if( p->rc!=SQLITE_OK || pDoclist[iOff]==0x01 ){
239592
+ iOff++;
239593
+ continue;
239594
+ }
239595
+ }
239596
+ }
239597
+
239598
+ if( p->rc==SQLITE_OK && bTermWritten==0 ){
239599
+ fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm);
239600
+ bTermWritten = 1;
239601
+ assert( p->rc!=SQLITE_OK || writer.bFirstRowidInPage==0 );
239602
+ }
239603
+
239604
+ if( writer.bFirstRowidInPage ){
239605
+ fts5PutU16(&pBuf->p[0], (u16)pBuf->n); /* first rowid on page */
239606
+ pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid);
239607
+ writer.bFirstRowidInPage = 0;
239608
+ fts5WriteDlidxAppend(p, &writer, iRowid);
239609
+ }else{
239610
+ pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid-iPrev);
239611
+ }
239612
+ if( p->rc!=SQLITE_OK ) break;
239613
+ assert( pBuf->n<=pBuf->nSpace );
239614
+ iPrev = iRowid;
239615
+
239616
+ if( eDetail==FTS5_DETAIL_NONE ){
239617
+ if( iOff<nDoclist && pDoclist[iOff]==0 ){
239618
+ pBuf->p[pBuf->n++] = 0;
239619
+ iOff++;
239620
+ if( iOff<nDoclist && pDoclist[iOff]==0 ){
239621
+ pBuf->p[pBuf->n++] = 0;
239622
+ iOff++;
239623
+ }
239624
+ }
239625
+ if( (pBuf->n + pPgidx->n)>=pgsz ){
239626
+ fts5WriteFlushLeaf(p, &writer);
239627
+ }
239628
+ }else{
239629
+ int bDummy;
239630
+ int nPos;
239631
+ int nCopy = fts5GetPoslistSize(&pDoclist[iOff], &nPos, &bDummy);
239632
+ nCopy += nPos;
239633
+ if( (pBuf->n + pPgidx->n + nCopy) <= pgsz ){
239634
+ /* The entire poslist will fit on the current leaf. So copy
239635
+ ** it in one go. */
239636
+ fts5BufferSafeAppendBlob(pBuf, &pDoclist[iOff], nCopy);
239637
+ }else{
239638
+ /* The entire poslist will not fit on this leaf. So it needs
239639
+ ** to be broken into sections. The only qualification being
239640
+ ** that each varint must be stored contiguously. */
239641
+ const u8 *pPoslist = &pDoclist[iOff];
239642
+ int iPos = 0;
239643
+ while( p->rc==SQLITE_OK ){
239644
+ int nSpace = pgsz - pBuf->n - pPgidx->n;
239645
+ int n = 0;
239646
+ if( (nCopy - iPos)<=nSpace ){
239647
+ n = nCopy - iPos;
239648
+ }else{
239649
+ n = fts5PoslistPrefix(&pPoslist[iPos], nSpace);
239650
+ }
239651
+ assert( n>0 );
239652
+ fts5BufferSafeAppendBlob(pBuf, &pPoslist[iPos], n);
239653
+ iPos += n;
239654
+ if( (pBuf->n + pPgidx->n)>=pgsz ){
239655
+ fts5WriteFlushLeaf(p, &writer);
239656
+ }
239657
+ if( iPos>=nCopy ) break;
239658
+ }
239659
+ }
239660
+ iOff += nCopy;
239661
+ }
239662
+ }
239663
+ }
239664
+
239665
+ /* TODO2: Doclist terminator written here. */
239666
+ /* pBuf->p[pBuf->n++] = '\0'; */
239667
+ assert( pBuf->n<=pBuf->nSpace );
239668
+ if( p->rc==SQLITE_OK ) sqlite3Fts5HashScanNext(pHash);
239669
+ }
239670
+ sqlite3Fts5HashClear(pHash);
239671
+ fts5WriteFinish(p, &writer, &pgnoLast);
239672
+
239673
+ assert( p->rc!=SQLITE_OK || bSecureDelete || pgnoLast>0 );
239674
+ if( pgnoLast>0 ){
239675
+ /* Update the Fts5Structure. It is written back to the database by the
239676
+ ** fts5StructureRelease() call below. */
239677
+ if( pStruct->nLevel==0 ){
239678
+ fts5StructureAddLevel(&p->rc, &pStruct);
239679
+ }
239680
+ fts5StructureExtendLevel(&p->rc, pStruct, 0, 1, 0);
239681
+ if( p->rc==SQLITE_OK ){
239682
+ pSeg = &pStruct->aLevel[0].aSeg[ pStruct->aLevel[0].nSeg++ ];
239683
+ pSeg->iSegid = iSegid;
239684
+ pSeg->pgnoFirst = 1;
239685
+ pSeg->pgnoLast = pgnoLast;
239686
+ if( pStruct->nOriginCntr>0 ){
239687
+ pSeg->iOrigin1 = pStruct->nOriginCntr;
239688
+ pSeg->iOrigin2 = pStruct->nOriginCntr;
239689
+ pSeg->nEntry = p->nPendingRow;
239690
+ pStruct->nOriginCntr++;
239691
+ }
239692
+ pStruct->nSegment++;
239693
+ }
239694
+ fts5StructurePromote(p, 0, pStruct);
239695
+ }
239696
+ }
239697
+ }
239698
+
239699
+ fts5IndexAutomerge(p, &pStruct, pgnoLast + p->nContentlessDelete);
239700
+ fts5IndexCrisismerge(p, &pStruct);
239701
+ fts5StructureWrite(p, pStruct);
239702
+ fts5StructureRelease(pStruct);
239703
+ p->nContentlessDelete = 0;
238366239704
}
238367239705
238368239706
/*
238369239707
** Flush any data stored in the in-memory hash tables to the database.
238370239708
*/
238371239709
static void fts5IndexFlush(Fts5Index *p){
238372239710
/* Unless it is empty, flush the hash table to disk */
238373
- if( p->nPendingData ){
239711
+ if( p->nPendingData || p->nContentlessDelete ){
238374239712
assert( p->pHash );
238375
- p->nPendingData = 0;
238376239713
fts5FlushOneHash(p);
239714
+ p->nPendingData = 0;
239715
+ p->nPendingRow = 0;
238377239716
}
238378239717
}
238379239718
238380239719
static Fts5Structure *fts5IndexOptimizeStruct(
238381239720
Fts5Index *p,
@@ -238387,21 +239726,26 @@
238387239726
int i;
238388239727
238389239728
/* Figure out if this structure requires optimization. A structure does
238390239729
** not require optimization if either:
238391239730
**
238392
- ** + it consists of fewer than two segments, or
238393
- ** + all segments are on the same level, or
238394
- ** + all segments except one are currently inputs to a merge operation.
239731
+ ** 1. it consists of fewer than two segments, or
239732
+ ** 2. all segments are on the same level, or
239733
+ ** 3. all segments except one are currently inputs to a merge operation.
238395239734
**
238396
- ** In the first case, return NULL. In the second, increment the ref-count
238397
- ** on *pStruct and return a copy of the pointer to it.
239735
+ ** In the first case, if there are no tombstone hash pages, return NULL. In
239736
+ ** the second, increment the ref-count on *pStruct and return a copy of the
239737
+ ** pointer to it.
238398239738
*/
238399
- if( nSeg<2 ) return 0;
239739
+ if( nSeg==0 ) return 0;
238400239740
for(i=0; i<pStruct->nLevel; i++){
238401239741
int nThis = pStruct->aLevel[i].nSeg;
238402
- if( nThis==nSeg || (nThis==nSeg-1 && pStruct->aLevel[i].nMerge==nThis) ){
239742
+ int nMerge = pStruct->aLevel[i].nMerge;
239743
+ if( nThis>0 && (nThis==nSeg || (nThis==nSeg-1 && nMerge==nThis)) ){
239744
+ if( nSeg==1 && nThis==1 && pStruct->aLevel[i].aSeg[0].nPgTombstone==0 ){
239745
+ return 0;
239746
+ }
238403239747
fts5StructureRef(pStruct);
238404239748
return pStruct;
238405239749
}
238406239750
assert( pStruct->aLevel[i].nMerge<=nThis );
238407239751
}
@@ -238413,10 +239757,11 @@
238413239757
Fts5StructureLevel *pLvl;
238414239758
nByte = nSeg * sizeof(Fts5StructureSegment);
238415239759
pNew->nLevel = MIN(pStruct->nLevel+1, FTS5_MAX_LEVEL);
238416239760
pNew->nRef = 1;
238417239761
pNew->nWriteCounter = pStruct->nWriteCounter;
239762
+ pNew->nOriginCntr = pStruct->nOriginCntr;
238418239763
pLvl = &pNew->aLevel[pNew->nLevel-1];
238419239764
pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&p->rc, nByte);
238420239765
if( pLvl->aSeg ){
238421239766
int iLvl, iSeg;
238422239767
int iSegOut = 0;
@@ -238443,10 +239788,11 @@
238443239788
Fts5Structure *pStruct;
238444239789
Fts5Structure *pNew = 0;
238445239790
238446239791
assert( p->rc==SQLITE_OK );
238447239792
fts5IndexFlush(p);
239793
+ assert( p->nContentlessDelete==0 );
238448239794
pStruct = fts5StructureRead(p);
238449239795
fts5StructureInvalidate(p);
238450239796
238451239797
if( pStruct ){
238452239798
pNew = fts5IndexOptimizeStruct(p, pStruct);
@@ -238472,19 +239818,22 @@
238472239818
/*
238473239819
** This is called to implement the special "VALUES('merge', $nMerge)"
238474239820
** INSERT command.
238475239821
*/
238476239822
static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){
238477
- Fts5Structure *pStruct = fts5StructureRead(p);
239823
+ Fts5Structure *pStruct = 0;
239824
+
239825
+ fts5IndexFlush(p);
239826
+ pStruct = fts5StructureRead(p);
238478239827
if( pStruct ){
238479239828
int nMin = p->pConfig->nUsermerge;
238480239829
fts5StructureInvalidate(p);
238481239830
if( nMerge<0 ){
238482239831
Fts5Structure *pNew = fts5IndexOptimizeStruct(p, pStruct);
238483239832
fts5StructureRelease(pStruct);
238484239833
pStruct = pNew;
238485
- nMin = 2;
239834
+ nMin = 1;
238486239835
nMerge = nMerge*-1;
238487239836
}
238488239837
if( pStruct && pStruct->nLevel ){
238489239838
if( fts5IndexMerge(p, &pStruct, nMerge, nMin) ){
238490239839
fts5StructureWrite(p, pStruct);
@@ -238994,10 +240343,13 @@
238994240343
fts5IndexFlush(p);
238995240344
}
238996240345
238997240346
p->iWriteRowid = iRowid;
238998240347
p->bDelete = bDelete;
240348
+ if( bDelete==0 ){
240349
+ p->nPendingRow++;
240350
+ }
238999240351
return fts5IndexReturn(p);
239000240352
}
239001240353
239002240354
/*
239003240355
** Commit data to disk.
@@ -239031,10 +240383,13 @@
239031240383
static int sqlite3Fts5IndexReinit(Fts5Index *p){
239032240384
Fts5Structure s;
239033240385
fts5StructureInvalidate(p);
239034240386
fts5IndexDiscardData(p);
239035240387
memset(&s, 0, sizeof(Fts5Structure));
240388
+ if( p->pConfig->bContentlessDelete ){
240389
+ s.nOriginCntr = 1;
240390
+ }
239036240391
fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0);
239037240392
fts5StructureWrite(p, &s);
239038240393
return fts5IndexReturn(p);
239039240394
}
239040240395
@@ -239422,10 +240777,351 @@
239422240777
pStruct = fts5StructureRead(p);
239423240778
fts5StructureRelease(pStruct);
239424240779
return fts5IndexReturn(p);
239425240780
}
239426240781
240782
+/*
240783
+** Retrieve the origin value that will be used for the segment currently
240784
+** being accumulated in the in-memory hash table when it is flushed to
240785
+** disk. If successful, SQLITE_OK is returned and (*piOrigin) set to
240786
+** the queried value. Or, if an error occurs, an error code is returned
240787
+** and the final value of (*piOrigin) is undefined.
240788
+*/
240789
+static int sqlite3Fts5IndexGetOrigin(Fts5Index *p, i64 *piOrigin){
240790
+ Fts5Structure *pStruct;
240791
+ pStruct = fts5StructureRead(p);
240792
+ if( pStruct ){
240793
+ *piOrigin = pStruct->nOriginCntr;
240794
+ fts5StructureRelease(pStruct);
240795
+ }
240796
+ return fts5IndexReturn(p);
240797
+}
240798
+
240799
+/*
240800
+** Buffer pPg contains a page of a tombstone hash table - one of nPg pages
240801
+** associated with the same segment. This function adds rowid iRowid to
240802
+** the hash table. The caller is required to guarantee that there is at
240803
+** least one free slot on the page.
240804
+**
240805
+** If parameter bForce is false and the hash table is deemed to be full
240806
+** (more than half of the slots are occupied), then non-zero is returned
240807
+** and iRowid not inserted. Or, if bForce is true or if the hash table page
240808
+** is not full, iRowid is inserted and zero returned.
240809
+*/
240810
+static int fts5IndexTombstoneAddToPage(
240811
+ Fts5Data *pPg,
240812
+ int bForce,
240813
+ int nPg,
240814
+ u64 iRowid
240815
+){
240816
+ const int szKey = TOMBSTONE_KEYSIZE(pPg);
240817
+ const int nSlot = TOMBSTONE_NSLOT(pPg);
240818
+ const int nElem = fts5GetU32(&pPg->p[4]);
240819
+ int iSlot = (iRowid / nPg) % nSlot;
240820
+ int nCollide = nSlot;
240821
+
240822
+ if( szKey==4 && iRowid>0xFFFFFFFF ) return 2;
240823
+ if( iRowid==0 ){
240824
+ pPg->p[1] = 0x01;
240825
+ return 0;
240826
+ }
240827
+
240828
+ if( bForce==0 && nElem>=(nSlot/2) ){
240829
+ return 1;
240830
+ }
240831
+
240832
+ fts5PutU32(&pPg->p[4], nElem+1);
240833
+ if( szKey==4 ){
240834
+ u32 *aSlot = (u32*)&pPg->p[8];
240835
+ while( aSlot[iSlot] ){
240836
+ iSlot = (iSlot + 1) % nSlot;
240837
+ if( nCollide--==0 ) return 0;
240838
+ }
240839
+ fts5PutU32((u8*)&aSlot[iSlot], (u32)iRowid);
240840
+ }else{
240841
+ u64 *aSlot = (u64*)&pPg->p[8];
240842
+ while( aSlot[iSlot] ){
240843
+ iSlot = (iSlot + 1) % nSlot;
240844
+ if( nCollide--==0 ) return 0;
240845
+ }
240846
+ fts5PutU64((u8*)&aSlot[iSlot], iRowid);
240847
+ }
240848
+
240849
+ return 0;
240850
+}
240851
+
240852
+/*
240853
+** This function attempts to build a new hash containing all the keys
240854
+** currently in the tombstone hash table for segment pSeg. The new
240855
+** hash will be stored in the nOut buffers passed in array apOut[].
240856
+** All pages of the new hash use key-size szKey (4 or 8).
240857
+**
240858
+** Return 0 if the hash is successfully rebuilt into the nOut pages.
240859
+** Or non-zero if it is not (because one page became overfull). In this
240860
+** case the caller should retry with a larger nOut parameter.
240861
+**
240862
+** Parameter pData1 is page iPg1 of the hash table being rebuilt.
240863
+*/
240864
+static int fts5IndexTombstoneRehash(
240865
+ Fts5Index *p,
240866
+ Fts5StructureSegment *pSeg, /* Segment to rebuild hash of */
240867
+ Fts5Data *pData1, /* One page of current hash - or NULL */
240868
+ int iPg1, /* Which page of the current hash is pData1 */
240869
+ int szKey, /* 4 or 8, the keysize */
240870
+ int nOut, /* Number of output pages */
240871
+ Fts5Data **apOut /* Array of output hash pages */
240872
+){
240873
+ int ii;
240874
+ int res = 0;
240875
+
240876
+ /* Initialize the headers of all the output pages */
240877
+ for(ii=0; ii<nOut; ii++){
240878
+ apOut[ii]->p[0] = szKey;
240879
+ fts5PutU32(&apOut[ii]->p[4], 0);
240880
+ }
240881
+
240882
+ /* Loop through the current pages of the hash table. */
240883
+ for(ii=0; res==0 && ii<pSeg->nPgTombstone; ii++){
240884
+ Fts5Data *pData = 0; /* Page ii of the current hash table */
240885
+ Fts5Data *pFree = 0; /* Free this at the end of the loop */
240886
+
240887
+ if( iPg1==ii ){
240888
+ pData = pData1;
240889
+ }else{
240890
+ pFree = pData = fts5DataRead(p, FTS5_TOMBSTONE_ROWID(pSeg->iSegid, ii));
240891
+ }
240892
+
240893
+ if( pData ){
240894
+ int szKeyIn = TOMBSTONE_KEYSIZE(pData);
240895
+ int nSlotIn = (pData->nn - 8) / szKeyIn;
240896
+ int iIn;
240897
+ for(iIn=0; iIn<nSlotIn; iIn++){
240898
+ u64 iVal = 0;
240899
+
240900
+ /* Read the value from slot iIn of the input page into iVal. */
240901
+ if( szKeyIn==4 ){
240902
+ u32 *aSlot = (u32*)&pData->p[8];
240903
+ if( aSlot[iIn] ) iVal = fts5GetU32((u8*)&aSlot[iIn]);
240904
+ }else{
240905
+ u64 *aSlot = (u64*)&pData->p[8];
240906
+ if( aSlot[iIn] ) iVal = fts5GetU64((u8*)&aSlot[iIn]);
240907
+ }
240908
+
240909
+ /* If iVal is not 0 at this point, insert it into the new hash table */
240910
+ if( iVal ){
240911
+ Fts5Data *pPg = apOut[(iVal % nOut)];
240912
+ res = fts5IndexTombstoneAddToPage(pPg, 0, nOut, iVal);
240913
+ if( res ) break;
240914
+ }
240915
+ }
240916
+
240917
+ /* If this is page 0 of the old hash, copy the rowid-0-flag from the
240918
+ ** old hash to the new. */
240919
+ if( ii==0 ){
240920
+ apOut[0]->p[1] = pData->p[1];
240921
+ }
240922
+ }
240923
+ fts5DataRelease(pFree);
240924
+ }
240925
+
240926
+ return res;
240927
+}
240928
+
240929
+/*
240930
+** This is called to rebuild the hash table belonging to segment pSeg.
240931
+** If parameter pData1 is not NULL, then one page of the existing hash table
240932
+** has already been loaded - pData1, which is page iPg1. The key-size for
240933
+** the new hash table is szKey (4 or 8).
240934
+**
240935
+** If successful, the new hash table is not written to disk. Instead,
240936
+** output parameter (*pnOut) is set to the number of pages in the new
240937
+** hash table, and (*papOut) to point to an array of buffers containing
240938
+** the new page data.
240939
+**
240940
+** If an error occurs, an error code is left in the Fts5Index object and
240941
+** both output parameters set to 0 before returning.
240942
+*/
240943
+static void fts5IndexTombstoneRebuild(
240944
+ Fts5Index *p,
240945
+ Fts5StructureSegment *pSeg, /* Segment to rebuild hash of */
240946
+ Fts5Data *pData1, /* One page of current hash - or NULL */
240947
+ int iPg1, /* Which page of the current hash is pData1 */
240948
+ int szKey, /* 4 or 8, the keysize */
240949
+ int *pnOut, /* OUT: Number of output pages */
240950
+ Fts5Data ***papOut /* OUT: Output hash pages */
240951
+){
240952
+ const int MINSLOT = 32;
240953
+ int nSlotPerPage = MAX(MINSLOT, (p->pConfig->pgsz - 8) / szKey);
240954
+ int nSlot = 0; /* Number of slots in each output page */
240955
+ int nOut = 0;
240956
+
240957
+ /* Figure out how many output pages (nOut) and how many slots per
240958
+ ** page (nSlot). There are three possibilities:
240959
+ **
240960
+ ** 1. The hash table does not yet exist. In this case the new hash
240961
+ ** table will consist of a single page with MINSLOT slots.
240962
+ **
240963
+ ** 2. The hash table exists but is currently a single page. In this
240964
+ ** case an attempt is made to grow the page to accommodate the new
240965
+ ** entry. The page is allowed to grow up to nSlotPerPage (see above)
240966
+ ** slots.
240967
+ **
240968
+ ** 3. The hash table already consists of more than one page, or of
240969
+ ** a single page already so large that it cannot be grown. In this
240970
+ ** case the new hash consists of (nPg*2+1) pages of nSlotPerPage
240971
+ ** slots each, where nPg is the current number of pages in the
240972
+ ** hash table.
240973
+ */
240974
+ if( pSeg->nPgTombstone==0 ){
240975
+ /* Case 1. */
240976
+ nOut = 1;
240977
+ nSlot = MINSLOT;
240978
+ }else if( pSeg->nPgTombstone==1 ){
240979
+ /* Case 2. */
240980
+ int nElem = (int)fts5GetU32(&pData1->p[4]);
240981
+ assert( pData1 && iPg1==0 );
240982
+ nOut = 1;
240983
+ nSlot = MAX(nElem*4, MINSLOT);
240984
+ if( nSlot>nSlotPerPage ) nOut = 0;
240985
+ }
240986
+ if( nOut==0 ){
240987
+ /* Case 3. */
240988
+ nOut = (pSeg->nPgTombstone * 2 + 1);
240989
+ nSlot = nSlotPerPage;
240990
+ }
240991
+
240992
+ /* Allocate the required array and output pages */
240993
+ while( 1 ){
240994
+ int res = 0;
240995
+ int ii = 0;
240996
+ int szPage = 0;
240997
+ Fts5Data **apOut = 0;
240998
+
240999
+ /* Allocate space for the new hash table */
241000
+ assert( nSlot>=MINSLOT );
241001
+ apOut = (Fts5Data**)sqlite3Fts5MallocZero(&p->rc, sizeof(Fts5Data*) * nOut);
241002
+ szPage = 8 + nSlot*szKey;
241003
+ for(ii=0; ii<nOut; ii++){
241004
+ Fts5Data *pNew = (Fts5Data*)sqlite3Fts5MallocZero(&p->rc,
241005
+ sizeof(Fts5Data)+szPage
241006
+ );
241007
+ if( pNew ){
241008
+ pNew->nn = szPage;
241009
+ pNew->p = (u8*)&pNew[1];
241010
+ apOut[ii] = pNew;
241011
+ }
241012
+ }
241013
+
241014
+ /* Rebuild the hash table. */
241015
+ if( p->rc==SQLITE_OK ){
241016
+ res = fts5IndexTombstoneRehash(p, pSeg, pData1, iPg1, szKey, nOut, apOut);
241017
+ }
241018
+ if( res==0 ){
241019
+ if( p->rc ){
241020
+ fts5IndexFreeArray(apOut, nOut);
241021
+ apOut = 0;
241022
+ nOut = 0;
241023
+ }
241024
+ *pnOut = nOut;
241025
+ *papOut = apOut;
241026
+ break;
241027
+ }
241028
+
241029
+ /* If control flows to here, it was not possible to rebuild the hash
241030
+ ** table. Free all buffers and then try again with more pages. */
241031
+ assert( p->rc==SQLITE_OK );
241032
+ fts5IndexFreeArray(apOut, nOut);
241033
+ nSlot = nSlotPerPage;
241034
+ nOut = nOut*2 + 1;
241035
+ }
241036
+}
241037
+
241038
+
241039
+/*
241040
+** Add a tombstone for rowid iRowid to segment pSeg.
241041
+*/
241042
+static void fts5IndexTombstoneAdd(
241043
+ Fts5Index *p,
241044
+ Fts5StructureSegment *pSeg,
241045
+ u64 iRowid
241046
+){
241047
+ Fts5Data *pPg = 0;
241048
+ int iPg = -1;
241049
+ int szKey = 0;
241050
+ int nHash = 0;
241051
+ Fts5Data **apHash = 0;
241052
+
241053
+ p->nContentlessDelete++;
241054
+
241055
+ if( pSeg->nPgTombstone>0 ){
241056
+ iPg = iRowid % pSeg->nPgTombstone;
241057
+ pPg = fts5DataRead(p, FTS5_TOMBSTONE_ROWID(pSeg->iSegid,iPg));
241058
+ if( pPg==0 ){
241059
+ assert( p->rc!=SQLITE_OK );
241060
+ return;
241061
+ }
241062
+
241063
+ if( 0==fts5IndexTombstoneAddToPage(pPg, 0, pSeg->nPgTombstone, iRowid) ){
241064
+ fts5DataWrite(p, FTS5_TOMBSTONE_ROWID(pSeg->iSegid,iPg), pPg->p, pPg->nn);
241065
+ fts5DataRelease(pPg);
241066
+ return;
241067
+ }
241068
+ }
241069
+
241070
+ /* Have to rebuild the hash table. First figure out the key-size (4 or 8). */
241071
+ szKey = pPg ? TOMBSTONE_KEYSIZE(pPg) : 4;
241072
+ if( iRowid>0xFFFFFFFF ) szKey = 8;
241073
+
241074
+ /* Rebuild the hash table */
241075
+ fts5IndexTombstoneRebuild(p, pSeg, pPg, iPg, szKey, &nHash, &apHash);
241076
+ assert( p->rc==SQLITE_OK || (nHash==0 && apHash==0) );
241077
+
241078
+ /* If all has succeeded, write the new rowid into one of the new hash
241079
+ ** table pages, then write them all out to disk. */
241080
+ if( nHash ){
241081
+ int ii = 0;
241082
+ fts5IndexTombstoneAddToPage(apHash[iRowid % nHash], 1, nHash, iRowid);
241083
+ for(ii=0; ii<nHash; ii++){
241084
+ i64 iTombstoneRowid = FTS5_TOMBSTONE_ROWID(pSeg->iSegid, ii);
241085
+ fts5DataWrite(p, iTombstoneRowid, apHash[ii]->p, apHash[ii]->nn);
241086
+ }
241087
+ pSeg->nPgTombstone = nHash;
241088
+ fts5StructureWrite(p, p->pStruct);
241089
+ }
241090
+
241091
+ fts5DataRelease(pPg);
241092
+ fts5IndexFreeArray(apHash, nHash);
241093
+}
241094
+
241095
+/*
241096
+** Add iRowid to the tombstone list of the segment or segments that contain
241097
+** rows from origin iOrigin. Return SQLITE_OK if successful, or an SQLite
241098
+** error code otherwise.
241099
+*/
241100
+static int sqlite3Fts5IndexContentlessDelete(Fts5Index *p, i64 iOrigin, i64 iRowid){
241101
+ Fts5Structure *pStruct;
241102
+ pStruct = fts5StructureRead(p);
241103
+ if( pStruct ){
241104
+ int bFound = 0; /* True after pSeg->nEntryTombstone incr. */
241105
+ int iLvl;
241106
+ for(iLvl=pStruct->nLevel-1; iLvl>=0; iLvl--){
241107
+ int iSeg;
241108
+ for(iSeg=pStruct->aLevel[iLvl].nSeg-1; iSeg>=0; iSeg--){
241109
+ Fts5StructureSegment *pSeg = &pStruct->aLevel[iLvl].aSeg[iSeg];
241110
+ if( pSeg->iOrigin1<=(u64)iOrigin && pSeg->iOrigin2>=(u64)iOrigin ){
241111
+ if( bFound==0 ){
241112
+ pSeg->nEntryTombstone++;
241113
+ bFound = 1;
241114
+ }
241115
+ fts5IndexTombstoneAdd(p, pSeg, iRowid);
241116
+ }
241117
+ }
241118
+ }
241119
+ fts5StructureRelease(pStruct);
241120
+ }
241121
+ return fts5IndexReturn(p);
241122
+}
239427241123
239428241124
/*************************************************************************
239429241125
**************************************************************************
239430241126
** Below this point is the implementation of the integrity-check
239431241127
** functionality.
@@ -239973,17 +241669,18 @@
239973241669
**************************************************************************
239974241670
** Below this point is the implementation of the fts5_decode() scalar
239975241671
** function only.
239976241672
*/
239977241673
239978
-#ifdef SQLITE_TEST
241674
+#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
239979241675
/*
239980241676
** Decode a segment-data rowid from the %_data table. This function is
239981241677
** the opposite of macro FTS5_SEGMENT_ROWID().
239982241678
*/
239983241679
static void fts5DecodeRowid(
239984241680
i64 iRowid, /* Rowid from %_data table */
241681
+ int *pbTombstone, /* OUT: Tombstone hash flag */
239985241682
int *piSegid, /* OUT: Segment id */
239986241683
int *pbDlidx, /* OUT: Dlidx flag */
239987241684
int *piHeight, /* OUT: Height */
239988241685
int *piPgno /* OUT: Page number */
239989241686
){
@@ -239995,34 +241692,39 @@
239995241692
239996241693
*pbDlidx = (int)(iRowid & 0x0001);
239997241694
iRowid >>= FTS5_DATA_DLI_B;
239998241695
239999241696
*piSegid = (int)(iRowid & (((i64)1 << FTS5_DATA_ID_B) - 1));
241697
+ iRowid >>= FTS5_DATA_ID_B;
241698
+
241699
+ *pbTombstone = (int)(iRowid & 0x0001);
240000241700
}
240001
-#endif /* SQLITE_TEST */
241701
+#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
240002241702
240003
-#ifdef SQLITE_TEST
241703
+#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
240004241704
static void fts5DebugRowid(int *pRc, Fts5Buffer *pBuf, i64 iKey){
240005
- int iSegid, iHeight, iPgno, bDlidx; /* Rowid compenents */
240006
- fts5DecodeRowid(iKey, &iSegid, &bDlidx, &iHeight, &iPgno);
241705
+ int iSegid, iHeight, iPgno, bDlidx, bTomb; /* Rowid compenents */
241706
+ fts5DecodeRowid(iKey, &bTomb, &iSegid, &bDlidx, &iHeight, &iPgno);
240007241707
240008241708
if( iSegid==0 ){
240009241709
if( iKey==FTS5_AVERAGES_ROWID ){
240010241710
sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{averages} ");
240011241711
}else{
240012241712
sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{structure}");
240013241713
}
240014241714
}
240015241715
else{
240016
- sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{%ssegid=%d h=%d pgno=%d}",
240017
- bDlidx ? "dlidx " : "", iSegid, iHeight, iPgno
241716
+ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{%s%ssegid=%d h=%d pgno=%d}",
241717
+ bDlidx ? "dlidx " : "",
241718
+ bTomb ? "tombstone " : "",
241719
+ iSegid, iHeight, iPgno
240018241720
);
240019241721
}
240020241722
}
240021
-#endif /* SQLITE_TEST */
241723
+#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
240022241724
240023
-#ifdef SQLITE_TEST
241725
+#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
240024241726
static void fts5DebugStructure(
240025241727
int *pRc, /* IN/OUT: error code */
240026241728
Fts5Buffer *pBuf,
240027241729
Fts5Structure *p
240028241730
){
@@ -240033,20 +241735,26 @@
240033241735
sqlite3Fts5BufferAppendPrintf(pRc, pBuf,
240034241736
" {lvl=%d nMerge=%d nSeg=%d", iLvl, pLvl->nMerge, pLvl->nSeg
240035241737
);
240036241738
for(iSeg=0; iSeg<pLvl->nSeg; iSeg++){
240037241739
Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg];
240038
- sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " {id=%d leaves=%d..%d}",
241740
+ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " {id=%d leaves=%d..%d",
240039241741
pSeg->iSegid, pSeg->pgnoFirst, pSeg->pgnoLast
240040241742
);
241743
+ if( pSeg->iOrigin1>0 ){
241744
+ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " origin=%lld..%lld",
241745
+ pSeg->iOrigin1, pSeg->iOrigin2
241746
+ );
241747
+ }
241748
+ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "}");
240041241749
}
240042241750
sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "}");
240043241751
}
240044241752
}
240045
-#endif /* SQLITE_TEST */
241753
+#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
240046241754
240047
-#ifdef SQLITE_TEST
241755
+#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
240048241756
/*
240049241757
** This is part of the fts5_decode() debugging aid.
240050241758
**
240051241759
** Arguments pBlob/nBlob contain a serialized Fts5Structure object. This
240052241760
** function appends a human-readable representation of the same object
@@ -240067,13 +241775,13 @@
240067241775
}
240068241776
240069241777
fts5DebugStructure(pRc, pBuf, p);
240070241778
fts5StructureRelease(p);
240071241779
}
240072
-#endif /* SQLITE_TEST */
241780
+#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
240073241781
240074
-#ifdef SQLITE_TEST
241782
+#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
240075241783
/*
240076241784
** This is part of the fts5_decode() debugging aid.
240077241785
**
240078241786
** Arguments pBlob/nBlob contain an "averages" record. This function
240079241787
** appends a human-readable representation of record to the buffer passed
@@ -240092,13 +241800,13 @@
240092241800
i += sqlite3Fts5GetVarint(&pBlob[i], &iVal);
240093241801
sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "%s%d", zSpace, (int)iVal);
240094241802
zSpace = " ";
240095241803
}
240096241804
}
240097
-#endif /* SQLITE_TEST */
241805
+#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
240098241806
240099
-#ifdef SQLITE_TEST
241807
+#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
240100241808
/*
240101241809
** Buffer (a/n) is assumed to contain a list of serialized varints. Read
240102241810
** each varint and append its string representation to buffer pBuf. Return
240103241811
** after either the input buffer is exhausted or a 0 value is read.
240104241812
**
@@ -240111,13 +241819,13 @@
240111241819
iOff += fts5GetVarint32(&a[iOff], iVal);
240112241820
sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " %d", iVal);
240113241821
}
240114241822
return iOff;
240115241823
}
240116
-#endif /* SQLITE_TEST */
241824
+#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
240117241825
240118
-#ifdef SQLITE_TEST
241826
+#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
240119241827
/*
240120241828
** The start of buffer (a/n) contains the start of a doclist. The doclist
240121241829
** may or may not finish within the buffer. This function appends a text
240122241830
** representation of the part of the doclist that is present to buffer
240123241831
** pBuf.
@@ -240146,13 +241854,13 @@
240146241854
}
240147241855
}
240148241856
240149241857
return iOff;
240150241858
}
240151
-#endif /* SQLITE_TEST */
241859
+#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
240152241860
240153
-#ifdef SQLITE_TEST
241861
+#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
240154241862
/*
240155241863
** This function is part of the fts5_decode() debugging function. It is
240156241864
** only ever used with detail=none tables.
240157241865
**
240158241866
** Buffer (pData/nData) contains a doclist in the format used by detail=none
@@ -240189,13 +241897,13 @@
240189241897
}
240190241898
240191241899
sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " %lld%s", iRowid, zApp);
240192241900
}
240193241901
}
240194
-#endif /* SQLITE_TEST */
241902
+#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
240195241903
240196
-#ifdef SQLITE_TEST
241904
+#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
240197241905
/*
240198241906
** The implementation of user-defined scalar function fts5_decode().
240199241907
*/
240200241908
static void fts5DecodeFunction(
240201241909
sqlite3_context *pCtx, /* Function call context */
@@ -240202,10 +241910,11 @@
240202241910
int nArg, /* Number of args (always 2) */
240203241911
sqlite3_value **apVal /* Function arguments */
240204241912
){
240205241913
i64 iRowid; /* Rowid for record being decoded */
240206241914
int iSegid,iHeight,iPgno,bDlidx;/* Rowid components */
241915
+ int bTomb;
240207241916
const u8 *aBlob; int n; /* Record to decode */
240208241917
u8 *a = 0;
240209241918
Fts5Buffer s; /* Build up text to return here */
240210241919
int rc = SQLITE_OK; /* Return code */
240211241920
sqlite3_int64 nSpace = 0;
@@ -240224,11 +241933,11 @@
240224241933
nSpace = n + FTS5_DATA_ZERO_PADDING;
240225241934
a = (u8*)sqlite3Fts5MallocZero(&rc, nSpace);
240226241935
if( a==0 ) goto decode_out;
240227241936
if( n>0 ) memcpy(a, aBlob, n);
240228241937
240229
- fts5DecodeRowid(iRowid, &iSegid, &bDlidx, &iHeight, &iPgno);
241938
+ fts5DecodeRowid(iRowid, &bTomb, &iSegid, &bDlidx, &iHeight, &iPgno);
240230241939
240231241940
fts5DebugRowid(&rc, &s, iRowid);
240232241941
if( bDlidx ){
240233241942
Fts5Data dlidx;
240234241943
Fts5DlidxLvl lvl;
@@ -240242,10 +241951,32 @@
240242241951
240243241952
for(fts5DlidxLvlNext(&lvl); lvl.bEof==0; fts5DlidxLvlNext(&lvl)){
240244241953
sqlite3Fts5BufferAppendPrintf(&rc, &s,
240245241954
" %d(%lld)", lvl.iLeafPgno, lvl.iRowid
240246241955
);
241956
+ }
241957
+ }else if( bTomb ){
241958
+ u32 nElem = fts5GetU32(&a[4]);
241959
+ int szKey = (aBlob[0]==4 || aBlob[0]==8) ? aBlob[0] : 8;
241960
+ int nSlot = (n - 8) / szKey;
241961
+ int ii;
241962
+ sqlite3Fts5BufferAppendPrintf(&rc, &s, " nElem=%d", (int)nElem);
241963
+ if( aBlob[1] ){
241964
+ sqlite3Fts5BufferAppendPrintf(&rc, &s, " 0");
241965
+ }
241966
+ for(ii=0; ii<nSlot; ii++){
241967
+ u64 iVal = 0;
241968
+ if( szKey==4 ){
241969
+ u32 *aSlot = (u32*)&aBlob[8];
241970
+ if( aSlot[ii] ) iVal = fts5GetU32((u8*)&aSlot[ii]);
241971
+ }else{
241972
+ u64 *aSlot = (u64*)&aBlob[8];
241973
+ if( aSlot[ii] ) iVal = fts5GetU64((u8*)&aSlot[ii]);
241974
+ }
241975
+ if( iVal!=0 ){
241976
+ sqlite3Fts5BufferAppendPrintf(&rc, &s, " %lld", (i64)iVal);
241977
+ }
240247241978
}
240248241979
}else if( iSegid==0 ){
240249241980
if( iRowid==FTS5_AVERAGES_ROWID ){
240250241981
fts5DecodeAverages(&rc, &s, a, n);
240251241982
}else{
@@ -240400,13 +242131,13 @@
240400242131
}else{
240401242132
sqlite3_result_error_code(pCtx, rc);
240402242133
}
240403242134
fts5BufferFree(&s);
240404242135
}
240405
-#endif /* SQLITE_TEST */
242136
+#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
240406242137
240407
-#ifdef SQLITE_TEST
242138
+#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
240408242139
/*
240409242140
** The implementation of user-defined scalar function fts5_rowid().
240410242141
*/
240411242142
static void fts5RowidFunction(
240412242143
sqlite3_context *pCtx, /* Function call context */
@@ -240436,11 +242167,239 @@
240436242167
"first arg to fts5_rowid() must be 'segment'" , -1
240437242168
);
240438242169
}
240439242170
}
240440242171
}
240441
-#endif /* SQLITE_TEST */
242172
+#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
242173
+
242174
+#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
242175
+
242176
+typedef struct Fts5StructVtab Fts5StructVtab;
242177
+struct Fts5StructVtab {
242178
+ sqlite3_vtab base;
242179
+};
242180
+
242181
+typedef struct Fts5StructVcsr Fts5StructVcsr;
242182
+struct Fts5StructVcsr {
242183
+ sqlite3_vtab_cursor base;
242184
+ Fts5Structure *pStruct;
242185
+ int iLevel;
242186
+ int iSeg;
242187
+ int iRowid;
242188
+};
242189
+
242190
+/*
242191
+** Create a new fts5_structure() table-valued function.
242192
+*/
242193
+static int fts5structConnectMethod(
242194
+ sqlite3 *db,
242195
+ void *pAux,
242196
+ int argc, const char *const*argv,
242197
+ sqlite3_vtab **ppVtab,
242198
+ char **pzErr
242199
+){
242200
+ Fts5StructVtab *pNew = 0;
242201
+ int rc = SQLITE_OK;
242202
+
242203
+ rc = sqlite3_declare_vtab(db,
242204
+ "CREATE TABLE xyz("
242205
+ "level, segment, merge, segid, leaf1, leaf2, loc1, loc2, "
242206
+ "npgtombstone, nentrytombstone, nentry, struct HIDDEN);"
242207
+ );
242208
+ if( rc==SQLITE_OK ){
242209
+ pNew = sqlite3Fts5MallocZero(&rc, sizeof(*pNew));
242210
+ }
242211
+
242212
+ *ppVtab = (sqlite3_vtab*)pNew;
242213
+ return rc;
242214
+}
242215
+
242216
+/*
242217
+** We must have a single struct=? constraint that will be passed through
242218
+** into the xFilter method. If there is no valid stmt=? constraint,
242219
+** then return an SQLITE_CONSTRAINT error.
242220
+*/
242221
+static int fts5structBestIndexMethod(
242222
+ sqlite3_vtab *tab,
242223
+ sqlite3_index_info *pIdxInfo
242224
+){
242225
+ int i;
242226
+ int rc = SQLITE_CONSTRAINT;
242227
+ struct sqlite3_index_constraint *p;
242228
+ pIdxInfo->estimatedCost = (double)100;
242229
+ pIdxInfo->estimatedRows = 100;
242230
+ pIdxInfo->idxNum = 0;
242231
+ for(i=0, p=pIdxInfo->aConstraint; i<pIdxInfo->nConstraint; i++, p++){
242232
+ if( p->usable==0 ) continue;
242233
+ if( p->op==SQLITE_INDEX_CONSTRAINT_EQ && p->iColumn==11 ){
242234
+ rc = SQLITE_OK;
242235
+ pIdxInfo->aConstraintUsage[i].omit = 1;
242236
+ pIdxInfo->aConstraintUsage[i].argvIndex = 1;
242237
+ break;
242238
+ }
242239
+ }
242240
+ return rc;
242241
+}
242242
+
242243
+/*
242244
+** This method is the destructor for bytecodevtab objects.
242245
+*/
242246
+static int fts5structDisconnectMethod(sqlite3_vtab *pVtab){
242247
+ Fts5StructVtab *p = (Fts5StructVtab*)pVtab;
242248
+ sqlite3_free(p);
242249
+ return SQLITE_OK;
242250
+}
242251
+
242252
+/*
242253
+** Constructor for a new bytecodevtab_cursor object.
242254
+*/
242255
+static int fts5structOpenMethod(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCsr){
242256
+ int rc = SQLITE_OK;
242257
+ Fts5StructVcsr *pNew = 0;
242258
+
242259
+ pNew = sqlite3Fts5MallocZero(&rc, sizeof(*pNew));
242260
+ *ppCsr = (sqlite3_vtab_cursor*)pNew;
242261
+
242262
+ return SQLITE_OK;
242263
+}
242264
+
242265
+/*
242266
+** Destructor for a bytecodevtab_cursor.
242267
+*/
242268
+static int fts5structCloseMethod(sqlite3_vtab_cursor *cur){
242269
+ Fts5StructVcsr *pCsr = (Fts5StructVcsr*)cur;
242270
+ fts5StructureRelease(pCsr->pStruct);
242271
+ sqlite3_free(pCsr);
242272
+ return SQLITE_OK;
242273
+}
242274
+
242275
+
242276
+/*
242277
+** Advance a bytecodevtab_cursor to its next row of output.
242278
+*/
242279
+static int fts5structNextMethod(sqlite3_vtab_cursor *cur){
242280
+ Fts5StructVcsr *pCsr = (Fts5StructVcsr*)cur;
242281
+ Fts5Structure *p = pCsr->pStruct;
242282
+
242283
+ assert( pCsr->pStruct );
242284
+ pCsr->iSeg++;
242285
+ pCsr->iRowid++;
242286
+ while( pCsr->iLevel<p->nLevel && pCsr->iSeg>=p->aLevel[pCsr->iLevel].nSeg ){
242287
+ pCsr->iLevel++;
242288
+ pCsr->iSeg = 0;
242289
+ }
242290
+ if( pCsr->iLevel>=p->nLevel ){
242291
+ fts5StructureRelease(pCsr->pStruct);
242292
+ pCsr->pStruct = 0;
242293
+ }
242294
+ return SQLITE_OK;
242295
+}
242296
+
242297
+/*
242298
+** Return TRUE if the cursor has been moved off of the last
242299
+** row of output.
242300
+*/
242301
+static int fts5structEofMethod(sqlite3_vtab_cursor *cur){
242302
+ Fts5StructVcsr *pCsr = (Fts5StructVcsr*)cur;
242303
+ return pCsr->pStruct==0;
242304
+}
242305
+
242306
+static int fts5structRowidMethod(
242307
+ sqlite3_vtab_cursor *cur,
242308
+ sqlite_int64 *piRowid
242309
+){
242310
+ Fts5StructVcsr *pCsr = (Fts5StructVcsr*)cur;
242311
+ *piRowid = pCsr->iRowid;
242312
+ return SQLITE_OK;
242313
+}
242314
+
242315
+/*
242316
+** Return values of columns for the row at which the bytecodevtab_cursor
242317
+** is currently pointing.
242318
+*/
242319
+static int fts5structColumnMethod(
242320
+ sqlite3_vtab_cursor *cur, /* The cursor */
242321
+ sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
242322
+ int i /* Which column to return */
242323
+){
242324
+ Fts5StructVcsr *pCsr = (Fts5StructVcsr*)cur;
242325
+ Fts5Structure *p = pCsr->pStruct;
242326
+ Fts5StructureSegment *pSeg = &p->aLevel[pCsr->iLevel].aSeg[pCsr->iSeg];
242327
+
242328
+ switch( i ){
242329
+ case 0: /* level */
242330
+ sqlite3_result_int(ctx, pCsr->iLevel);
242331
+ break;
242332
+ case 1: /* segment */
242333
+ sqlite3_result_int(ctx, pCsr->iSeg);
242334
+ break;
242335
+ case 2: /* merge */
242336
+ sqlite3_result_int(ctx, pCsr->iSeg < p->aLevel[pCsr->iLevel].nMerge);
242337
+ break;
242338
+ case 3: /* segid */
242339
+ sqlite3_result_int(ctx, pSeg->iSegid);
242340
+ break;
242341
+ case 4: /* leaf1 */
242342
+ sqlite3_result_int(ctx, pSeg->pgnoFirst);
242343
+ break;
242344
+ case 5: /* leaf2 */
242345
+ sqlite3_result_int(ctx, pSeg->pgnoLast);
242346
+ break;
242347
+ case 6: /* origin1 */
242348
+ sqlite3_result_int64(ctx, pSeg->iOrigin1);
242349
+ break;
242350
+ case 7: /* origin2 */
242351
+ sqlite3_result_int64(ctx, pSeg->iOrigin2);
242352
+ break;
242353
+ case 8: /* npgtombstone */
242354
+ sqlite3_result_int(ctx, pSeg->nPgTombstone);
242355
+ break;
242356
+ case 9: /* nentrytombstone */
242357
+ sqlite3_result_int64(ctx, pSeg->nEntryTombstone);
242358
+ break;
242359
+ case 10: /* nentry */
242360
+ sqlite3_result_int64(ctx, pSeg->nEntry);
242361
+ break;
242362
+ }
242363
+ return SQLITE_OK;
242364
+}
242365
+
242366
+/*
242367
+** Initialize a cursor.
242368
+**
242369
+** idxNum==0 means show all subprograms
242370
+** idxNum==1 means show only the main bytecode and omit subprograms.
242371
+*/
242372
+static int fts5structFilterMethod(
242373
+ sqlite3_vtab_cursor *pVtabCursor,
242374
+ int idxNum, const char *idxStr,
242375
+ int argc, sqlite3_value **argv
242376
+){
242377
+ Fts5StructVcsr *pCsr = (Fts5StructVcsr *)pVtabCursor;
242378
+ int rc = SQLITE_OK;
242379
+
242380
+ const u8 *aBlob = 0;
242381
+ int nBlob = 0;
242382
+
242383
+ assert( argc==1 );
242384
+ fts5StructureRelease(pCsr->pStruct);
242385
+ pCsr->pStruct = 0;
242386
+
242387
+ nBlob = sqlite3_value_bytes(argv[0]);
242388
+ aBlob = (const u8*)sqlite3_value_blob(argv[0]);
242389
+ rc = fts5StructureDecode(aBlob, nBlob, 0, &pCsr->pStruct);
242390
+ if( rc==SQLITE_OK ){
242391
+ pCsr->iLevel = 0;
242392
+ pCsr->iRowid = 0;
242393
+ pCsr->iSeg = -1;
242394
+ rc = fts5structNextMethod(pVtabCursor);
242395
+ }
242396
+
242397
+ return rc;
242398
+}
242399
+
242400
+#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
240442242401
240443242402
/*
240444242403
** This is called as part of registering the FTS5 module with database
240445242404
** connection db. It registers several user-defined scalar functions useful
240446242405
** with FTS5.
@@ -240447,11 +242406,11 @@
240447242406
**
240448242407
** If successful, SQLITE_OK is returned. If an error occurs, some other
240449242408
** SQLite error code is returned instead.
240450242409
*/
240451242410
static int sqlite3Fts5IndexInit(sqlite3 *db){
240452
-#ifdef SQLITE_TEST
242411
+#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
240453242412
int rc = sqlite3_create_function(
240454242413
db, "fts5_decode", 2, SQLITE_UTF8, 0, fts5DecodeFunction, 0, 0
240455242414
);
240456242415
240457242416
if( rc==SQLITE_OK ){
@@ -240464,10 +242423,40 @@
240464242423
if( rc==SQLITE_OK ){
240465242424
rc = sqlite3_create_function(
240466242425
db, "fts5_rowid", -1, SQLITE_UTF8, 0, fts5RowidFunction, 0, 0
240467242426
);
240468242427
}
242428
+
242429
+ if( rc==SQLITE_OK ){
242430
+ static const sqlite3_module fts5structure_module = {
242431
+ 0, /* iVersion */
242432
+ 0, /* xCreate */
242433
+ fts5structConnectMethod, /* xConnect */
242434
+ fts5structBestIndexMethod, /* xBestIndex */
242435
+ fts5structDisconnectMethod, /* xDisconnect */
242436
+ 0, /* xDestroy */
242437
+ fts5structOpenMethod, /* xOpen */
242438
+ fts5structCloseMethod, /* xClose */
242439
+ fts5structFilterMethod, /* xFilter */
242440
+ fts5structNextMethod, /* xNext */
242441
+ fts5structEofMethod, /* xEof */
242442
+ fts5structColumnMethod, /* xColumn */
242443
+ fts5structRowidMethod, /* xRowid */
242444
+ 0, /* xUpdate */
242445
+ 0, /* xBegin */
242446
+ 0, /* xSync */
242447
+ 0, /* xCommit */
242448
+ 0, /* xRollback */
242449
+ 0, /* xFindFunction */
242450
+ 0, /* xRename */
242451
+ 0, /* xSavepoint */
242452
+ 0, /* xRelease */
242453
+ 0, /* xRollbackTo */
242454
+ 0 /* xShadowName */
242455
+ };
242456
+ rc = sqlite3_create_module(db, "fts5_structure", &fts5structure_module, 0);
242457
+ }
240469242458
return rc;
240470242459
#else
240471242460
return SQLITE_OK;
240472242461
UNUSED_PARAM(db);
240473242462
#endif
@@ -242107,11 +244096,10 @@
242107244096
Fts5Config *pConfig = pTab->p.pConfig;
242108244097
int eType0; /* value_type() of apVal[0] */
242109244098
int rc = SQLITE_OK; /* Return code */
242110244099
int bUpdateOrDelete = 0;
242111244100
242112
-
242113244101
/* A transaction must be open when this is called. */
242114244102
assert( pTab->ts.eState==1 || pTab->ts.eState==2 );
242115244103
242116244104
assert( pVtab->zErrMsg==0 );
242117244105
assert( nArg==1 || nArg==(2+pConfig->nCol+2) );
@@ -242136,11 +244124,18 @@
242136244124
/* A "special" INSERT op. These are handled separately. */
242137244125
const char *z = (const char*)sqlite3_value_text(apVal[2+pConfig->nCol]);
242138244126
if( pConfig->eContent!=FTS5_CONTENT_NORMAL
242139244127
&& 0==sqlite3_stricmp("delete", z)
242140244128
){
242141
- rc = fts5SpecialDelete(pTab, apVal);
244129
+ if( pConfig->bContentlessDelete ){
244130
+ fts5SetVtabError(pTab,
244131
+ "'delete' may not be used with a contentless_delete=1 table"
244132
+ );
244133
+ rc = SQLITE_ERROR;
244134
+ }else{
244135
+ rc = fts5SpecialDelete(pTab, apVal);
244136
+ }
242142244137
}else{
242143244138
rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]);
242144244139
}
242145244140
}else{
242146244141
/* A regular INSERT, UPDATE or DELETE statement. The trick here is that
@@ -242153,20 +244148,24 @@
242153244148
** 4) INSERT
242154244149
**
242155244150
** Cases 3 and 4 may violate the rowid constraint.
242156244151
*/
242157244152
int eConflict = SQLITE_ABORT;
242158
- if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
244153
+ if( pConfig->eContent==FTS5_CONTENT_NORMAL || pConfig->bContentlessDelete ){
242159244154
eConflict = sqlite3_vtab_on_conflict(pConfig->db);
242160244155
}
242161244156
242162244157
assert( eType0==SQLITE_INTEGER || eType0==SQLITE_NULL );
242163244158
assert( nArg!=1 || eType0==SQLITE_INTEGER );
242164244159
242165244160
/* Filter out attempts to run UPDATE or DELETE on contentless tables.
242166
- ** This is not suported. */
242167
- if( eType0==SQLITE_INTEGER && fts5IsContentless(pTab) ){
244161
+ ** This is not suported. Except - DELETE is supported if the CREATE
244162
+ ** VIRTUAL TABLE statement contained "contentless_delete=1". */
244163
+ if( eType0==SQLITE_INTEGER
244164
+ && pConfig->eContent==FTS5_CONTENT_NONE
244165
+ && (nArg>1 || pConfig->bContentlessDelete==0)
244166
+ ){
242168244167
pTab->p.base.zErrMsg = sqlite3_mprintf(
242169244168
"cannot %s contentless fts5 table: %s",
242170244169
(nArg>1 ? "UPDATE" : "DELETE from"), pConfig->zName
242171244170
);
242172244171
rc = SQLITE_ERROR;
@@ -242249,12 +244248,11 @@
242249244248
static int fts5SyncMethod(sqlite3_vtab *pVtab){
242250244249
int rc;
242251244250
Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
242252244251
fts5CheckTransactionState(pTab, FTS5_SYNC, 0);
242253244252
pTab->p.pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
242254
- fts5TripCursors(pTab);
242255
- rc = sqlite3Fts5StorageSync(pTab->pStorage);
244253
+ rc = sqlite3Fts5FlushToDisk(&pTab->p);
242256244254
pTab->p.pConfig->pzErrmsg = 0;
242257244255
return rc;
242258244256
}
242259244257
242260244258
/*
@@ -243299,11 +245297,11 @@
243299245297
int nArg, /* Number of args */
243300245298
sqlite3_value **apUnused /* Function arguments */
243301245299
){
243302245300
assert( nArg==0 );
243303245301
UNUSED_PARAM2(nArg, apUnused);
243304
- sqlite3_result_text(pCtx, "fts5: 2023-07-08 17:42:24 07d95ed60f0a17ea13b4bc19c2ab2ec9052fedd27c9e1e57a1ec6e3a6470e5b7", -1, SQLITE_TRANSIENT);
245302
+ sqlite3_result_text(pCtx, "fts5: 2023-08-01 11:03:06 aa55c83f35c2ab134e0842201e46e021079283f9c65595c86664060b3aa8d715", -1, SQLITE_TRANSIENT);
243305245303
}
243306245304
243307245305
/*
243308245306
** Return true if zName is the extension on one of the shadow tables used
243309245307
** by this module.
@@ -243512,14 +245510,14 @@
243512245510
"SELECT %s FROM %s T WHERE T.%Q=?", /* LOOKUP */
243513245511
243514245512
"INSERT INTO %Q.'%q_content' VALUES(%s)", /* INSERT_CONTENT */
243515245513
"REPLACE INTO %Q.'%q_content' VALUES(%s)", /* REPLACE_CONTENT */
243516245514
"DELETE FROM %Q.'%q_content' WHERE id=?", /* DELETE_CONTENT */
243517
- "REPLACE INTO %Q.'%q_docsize' VALUES(?,?)", /* REPLACE_DOCSIZE */
245515
+ "REPLACE INTO %Q.'%q_docsize' VALUES(?,?%s)", /* REPLACE_DOCSIZE */
243518245516
"DELETE FROM %Q.'%q_docsize' WHERE id=?", /* DELETE_DOCSIZE */
243519245517
243520
- "SELECT sz FROM %Q.'%q_docsize' WHERE id=?", /* LOOKUP_DOCSIZE */
245518
+ "SELECT sz%s FROM %Q.'%q_docsize' WHERE id=?", /* LOOKUP_DOCSIZE */
243521245519
243522245520
"REPLACE INTO %Q.'%q_config' VALUES(?,?)", /* REPLACE_CONFIG */
243523245521
"SELECT %s FROM %s AS T", /* SCAN */
243524245522
};
243525245523
Fts5Config *pC = p->pConfig;
@@ -243562,10 +245560,23 @@
243562245560
zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName, zBind);
243563245561
sqlite3_free(zBind);
243564245562
}
243565245563
break;
243566245564
}
245565
+
245566
+ case FTS5_STMT_REPLACE_DOCSIZE:
245567
+ zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName,
245568
+ (pC->bContentlessDelete ? ",?" : "")
245569
+ );
245570
+ break;
245571
+
245572
+ case FTS5_STMT_LOOKUP_DOCSIZE:
245573
+ zSql = sqlite3_mprintf(azStmt[eStmt],
245574
+ (pC->bContentlessDelete ? ",origin" : ""),
245575
+ pC->zDb, pC->zName
245576
+ );
245577
+ break;
243567245578
243568245579
default:
243569245580
zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName);
243570245581
break;
243571245582
}
@@ -243752,13 +245763,15 @@
243752245763
}
243753245764
sqlite3_free(zDefn);
243754245765
}
243755245766
243756245767
if( rc==SQLITE_OK && pConfig->bColumnsize ){
243757
- rc = sqlite3Fts5CreateTable(
243758
- pConfig, "docsize", "id INTEGER PRIMARY KEY, sz BLOB", 0, pzErr
243759
- );
245768
+ const char *zCols = "id INTEGER PRIMARY KEY, sz BLOB";
245769
+ if( pConfig->bContentlessDelete ){
245770
+ zCols = "id INTEGER PRIMARY KEY, sz BLOB, origin INTEGER";
245771
+ }
245772
+ rc = sqlite3Fts5CreateTable(pConfig, "docsize", zCols, 0, pzErr);
243760245773
}
243761245774
if( rc==SQLITE_OK ){
243762245775
rc = sqlite3Fts5CreateTable(
243763245776
pConfig, "config", "k PRIMARY KEY, v", 1, pzErr
243764245777
);
@@ -243831,11 +245844,11 @@
243831245844
i64 iDel,
243832245845
sqlite3_value **apVal
243833245846
){
243834245847
Fts5Config *pConfig = p->pConfig;
243835245848
sqlite3_stmt *pSeek = 0; /* SELECT to read row iDel from %_data */
243836
- int rc; /* Return code */
245849
+ int rc = SQLITE_OK; /* Return code */
243837245850
int rc2; /* sqlite3_reset() return code */
243838245851
int iCol;
243839245852
Fts5InsertCtx ctx;
243840245853
243841245854
if( apVal==0 ){
@@ -243847,11 +245860,10 @@
243847245860
}
243848245861
}
243849245862
243850245863
ctx.pStorage = p;
243851245864
ctx.iCol = -1;
243852
- rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel);
243853245865
for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){
243854245866
if( pConfig->abUnindexed[iCol-1]==0 ){
243855245867
const char *zText;
243856245868
int nText;
243857245869
assert( pSeek==0 || apVal==0 );
@@ -243884,10 +245896,41 @@
243884245896
rc2 = sqlite3_reset(pSeek);
243885245897
if( rc==SQLITE_OK ) rc = rc2;
243886245898
return rc;
243887245899
}
243888245900
245901
+/*
245902
+** This function is called to process a DELETE on a contentless_delete=1
245903
+** table. It adds the tombstone required to delete the entry with rowid
245904
+** iDel. If successful, SQLITE_OK is returned. Or, if an error occurs,
245905
+** an SQLite error code.
245906
+*/
245907
+static int fts5StorageContentlessDelete(Fts5Storage *p, i64 iDel){
245908
+ i64 iOrigin = 0;
245909
+ sqlite3_stmt *pLookup = 0;
245910
+ int rc = SQLITE_OK;
245911
+
245912
+ assert( p->pConfig->bContentlessDelete );
245913
+ assert( p->pConfig->eContent==FTS5_CONTENT_NONE );
245914
+
245915
+ /* Look up the origin of the document in the %_docsize table. Store
245916
+ ** this in stack variable iOrigin. */
245917
+ rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP_DOCSIZE, &pLookup, 0);
245918
+ if( rc==SQLITE_OK ){
245919
+ sqlite3_bind_int64(pLookup, 1, iDel);
245920
+ if( SQLITE_ROW==sqlite3_step(pLookup) ){
245921
+ iOrigin = sqlite3_column_int64(pLookup, 1);
245922
+ }
245923
+ rc = sqlite3_reset(pLookup);
245924
+ }
245925
+
245926
+ if( rc==SQLITE_OK && iOrigin!=0 ){
245927
+ rc = sqlite3Fts5IndexContentlessDelete(p->pIndex, iOrigin, iDel);
245928
+ }
245929
+
245930
+ return rc;
245931
+}
243889245932
243890245933
/*
243891245934
** Insert a record into the %_docsize table. Specifically, do:
243892245935
**
243893245936
** INSERT OR REPLACE INTO %_docsize(id, sz) VALUES(iRowid, pBuf);
@@ -243904,14 +245947,21 @@
243904245947
if( p->pConfig->bColumnsize ){
243905245948
sqlite3_stmt *pReplace = 0;
243906245949
rc = fts5StorageGetStmt(p, FTS5_STMT_REPLACE_DOCSIZE, &pReplace, 0);
243907245950
if( rc==SQLITE_OK ){
243908245951
sqlite3_bind_int64(pReplace, 1, iRowid);
243909
- sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC);
243910
- sqlite3_step(pReplace);
243911
- rc = sqlite3_reset(pReplace);
243912
- sqlite3_bind_null(pReplace, 2);
245952
+ if( p->pConfig->bContentlessDelete ){
245953
+ i64 iOrigin = 0;
245954
+ rc = sqlite3Fts5IndexGetOrigin(p->pIndex, &iOrigin);
245955
+ sqlite3_bind_int64(pReplace, 3, iOrigin);
245956
+ }
245957
+ if( rc==SQLITE_OK ){
245958
+ sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC);
245959
+ sqlite3_step(pReplace);
245960
+ rc = sqlite3_reset(pReplace);
245961
+ sqlite3_bind_null(pReplace, 2);
245962
+ }
243913245963
}
243914245964
}
243915245965
return rc;
243916245966
}
243917245967
@@ -243971,11 +246021,19 @@
243971246021
assert( pConfig->eContent!=FTS5_CONTENT_NORMAL || apVal==0 );
243972246022
rc = fts5StorageLoadTotals(p, 1);
243973246023
243974246024
/* Delete the index records */
243975246025
if( rc==SQLITE_OK ){
243976
- rc = fts5StorageDeleteFromIndex(p, iDel, apVal);
246026
+ rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel);
246027
+ }
246028
+
246029
+ if( rc==SQLITE_OK ){
246030
+ if( p->pConfig->bContentlessDelete ){
246031
+ rc = fts5StorageContentlessDelete(p, iDel);
246032
+ }else{
246033
+ rc = fts5StorageDeleteFromIndex(p, iDel, apVal);
246034
+ }
243977246035
}
243978246036
243979246037
/* Delete the %_docsize record */
243980246038
if( rc==SQLITE_OK && pConfig->bColumnsize ){
243981246039
rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_DOCSIZE, &pDel, 0);
243982246040
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -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 ** 7d95ed60f0a17ea13b4bc19c2ab2ec9052f.
22 */
23 #define SQLITE_CORE 1
24 #define SQLITE_AMALGAMATION 1
25 #ifndef SQLITE_PRIVATE
26 # define SQLITE_PRIVATE static
@@ -459,11 +459,11 @@
459 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
460 ** [sqlite_version()] and [sqlite_source_id()].
461 */
462 #define SQLITE_VERSION "3.43.0"
463 #define SQLITE_VERSION_NUMBER 3043000
464 #define SQLITE_SOURCE_ID "2023-07-08 17:42:24 07d95ed60f0a17ea13b4bc19c2ab2ec9052fedd27c9e1e57a1ec6e3a6470e5b7"
465
466 /*
467 ** CAPI3REF: Run-Time Library Version Numbers
468 ** KEYWORDS: sqlite3_version sqlite3_sourceid
469 **
@@ -4732,10 +4732,45 @@
4732 ** ^The sqlite3_stmt_isexplain(S) interface returns 0 if S is
4733 ** an ordinary statement or a NULL pointer.
4734 */
4735 SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt);
4736
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4737 /*
4738 ** CAPI3REF: Determine If A Prepared Statement Has Been Reset
4739 ** METHOD: sqlite3_stmt
4740 **
4741 ** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the
@@ -14590,12 +14625,35 @@
14590 **
14591 ** In other words, S is a buffer and E is a pointer to the first byte after
14592 ** the end of buffer S. This macro returns true if P points to something
14593 ** contained within the buffer S.
14594 */
14595 #define SQLITE_WITHIN(P,S,E) (((uptr)(P)>=(uptr)(S))&&((uptr)(P)<(uptr)(E)))
14596
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14597
14598 /*
14599 ** Macros to determine whether the machine is big or little endian,
14600 ** and whether or not that determination is run-time or compile-time.
14601 **
@@ -14959,10 +15017,11 @@
14959 typedef struct OnOrUsing OnOrUsing;
14960 typedef struct Parse Parse;
14961 typedef struct ParseCleanup ParseCleanup;
14962 typedef struct PreUpdate PreUpdate;
14963 typedef struct PrintfArguments PrintfArguments;
 
14964 typedef struct RenameToken RenameToken;
14965 typedef struct Returning Returning;
14966 typedef struct RowSet RowSet;
14967 typedef struct Savepoint Savepoint;
14968 typedef struct Select Select;
@@ -15925,13 +15984,11 @@
15925 SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*);
15926 SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int flags);
15927 SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor*);
15928 SQLITE_PRIVATE void sqlite3BtreeCursorPin(BtCursor*);
15929 SQLITE_PRIVATE void sqlite3BtreeCursorUnpin(BtCursor*);
15930 #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
15931 SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor*);
15932 #endif
15933 SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*);
15934 SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt);
15935 SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor*);
15936 SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor*);
15937
@@ -17469,10 +17526,11 @@
17469 #define SQLITE_FlttnUnionAll 0x00800000 /* Disable the UNION ALL flattener */
17470 /* TH3 expects this value ^^^^^^^^^^ See flatten04.test */
17471 #define SQLITE_IndexedExpr 0x01000000 /* Pull exprs from index when able */
17472 #define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */
17473 #define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */
 
17474 #define SQLITE_AllOpts 0xffffffff /* All optimizations */
17475
17476 /*
17477 ** Macros for testing whether or not optimizations are enabled or disabled.
17478 */
@@ -19385,11 +19443,11 @@
19385 ParseCleanup *pCleanup; /* List of cleanup operations to run after parse */
19386 union {
19387 int addrCrTab; /* Address of OP_CreateBtree on CREATE TABLE */
19388 Returning *pReturning; /* The RETURNING clause */
19389 } u1;
19390 u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */
19391 u32 oldmask; /* Mask of old.* columns referenced */
19392 u32 newmask; /* Mask of new.* columns referenced */
19393 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
19394 u32 nProgressSteps; /* xProgress steps taken during sqlite3_prepare() */
19395 #endif
@@ -19657,10 +19715,29 @@
19657 #define SQLITE_PRINTF_SQLFUNC 0x02 /* SQL function arguments to VXPrintf */
19658 #define SQLITE_PRINTF_MALLOCED 0x04 /* True if xText is allocated space */
19659
19660 #define isMalloced(X) (((X)->printfFlags & SQLITE_PRINTF_MALLOCED)!=0)
19661
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19662
19663 /*
19664 ** A pointer to this structure is used to communicate information
19665 ** from sqlite3Init and OP_ParseSchema into the sqlite3InitCallback.
19666 */
@@ -20776,10 +20853,11 @@
20776 # define sqlite3FileSuffix3(X,Y)
20777 #endif
20778 SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z,u8);
20779
20780 SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8);
 
20781 SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8);
20782 SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
20783 void(*)(void*));
20784 SQLITE_PRIVATE void sqlite3ValueSetNull(sqlite3_value*);
20785 SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*);
@@ -20883,10 +20961,15 @@
20883 SQLITE_PRIVATE void *sqlite3OomFault(sqlite3*);
20884 SQLITE_PRIVATE void sqlite3OomClear(sqlite3*);
20885 SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int);
20886 SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *);
20887
 
 
 
 
 
20888 SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int);
20889 SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum*, i64);
20890 SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*);
20891 SQLITE_PRIVATE void sqlite3StrAccumSetError(StrAccum*, u8);
20892 SQLITE_PRIVATE void sqlite3ResultStrAccum(sqlite3_context*,StrAccum*);
@@ -22623,10 +22706,13 @@
22623 typedef struct VdbeSorter VdbeSorter;
22624
22625 /* Elements of the linked list at Vdbe.pAuxData */
22626 typedef struct AuxData AuxData;
22627
 
 
 
22628 /* Types of VDBE cursors */
22629 #define CURTYPE_BTREE 0
22630 #define CURTYPE_SORTER 1
22631 #define CURTYPE_VTAB 2
22632 #define CURTYPE_PSEUDO 3
@@ -22654,10 +22740,11 @@
22654 #endif
22655 Bool isEphemeral:1; /* True for an ephemeral table */
22656 Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */
22657 Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */
22658 Bool noReuse:1; /* OpenEphemeral may not reuse this cursor */
 
22659 u16 seekHit; /* See the OP_SeekHit and OP_IfNoHope opcodes */
22660 union { /* pBtx for isEphermeral. pAltMap otherwise */
22661 Btree *pBtx; /* Separate file holding temporary table */
22662 u32 *aAltMap; /* Mapping from table to index column numbers */
22663 } ub;
@@ -22694,10 +22781,11 @@
22694 u32 payloadSize; /* Total number of bytes in the record */
22695 u32 szRow; /* Byte available in aRow */
22696 #ifdef SQLITE_ENABLE_COLUMN_USED_MASK
22697 u64 maskUsed; /* Mask of columns used by this cursor */
22698 #endif
 
22699
22700 /* 2*nField extra array elements allocated for aType[], beyond the one
22701 ** static element declared in the structure. nField total array slots for
22702 ** aType[] and nField+1 array slots for aOffset[] */
22703 u32 aType[1]; /* Type values record decode. MUST BE LAST */
@@ -22706,15 +22794,28 @@
22706 /* Return true if P is a null-only cursor
22707 */
22708 #define IsNullCursor(P) \
22709 ((P)->eCurType==CURTYPE_PSEUDO && (P)->nullRow && (P)->seekResult==0)
22710
22711
22712 /*
22713 ** A value for VdbeCursor.cacheStatus that means the cache is always invalid.
22714 */
22715 #define CACHE_STALE 0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22716
22717 /*
22718 ** When a sub-program is executed (OP_Program), a structure of this type
22719 ** is allocated to store the current value of the program counter, as
22720 ** well as the current memory cell array and various other frame specific
@@ -23032,20 +23133,22 @@
23032 #ifdef SQLITE_DEBUG
23033 int rcApp; /* errcode set by sqlite3_result_error_code() */
23034 u32 nWrite; /* Number of write operations that have occurred */
23035 #endif
23036 u16 nResColumn; /* Number of columns in one row of the result set */
 
23037 u8 errorAction; /* Recovery action to do in case of an error */
23038 u8 minWriteFileFormat; /* Minimum file format for writable database files */
23039 u8 prepFlags; /* SQLITE_PREPARE_* flags */
23040 u8 eVdbeState; /* On of the VDBE_*_STATE values */
23041 bft expired:2; /* 1: recompile VM immediately 2: when convenient */
23042 bft explain:2; /* True if EXPLAIN present on SQL command */
23043 bft changeCntOn:1; /* True to update the change-counter */
23044 bft usesStmtJournal:1; /* True if uses a statement journal */
23045 bft readOnly:1; /* True for statements that do not write */
23046 bft bIsReader:1; /* True for statements that read */
 
23047 yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
23048 yDbMask lockMask; /* Subset of btreeMask that requires a lock */
23049 u32 aCounter[9]; /* Counters used by sqlite3_stmt_status() */
23050 char *zSql; /* Text of the SQL statement that generated this */
23051 #ifdef SQLITE_ENABLE_NORMALIZE
@@ -23178,10 +23281,11 @@
23178 #endif
23179 #ifdef SQLITE_DEBUG
23180 SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem*);
23181 #endif
23182 SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem*);
 
23183 SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*);
23184 SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8);
23185 SQLITE_PRIVATE int sqlite3IntFloatCompare(i64,double);
23186 SQLITE_PRIVATE i64 sqlite3VdbeIntValue(const Mem*);
23187 SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*);
@@ -31698,10 +31802,79 @@
31698 va_start(ap,zFormat);
31699 sqlite3_str_vappendf(p, zFormat, ap);
31700 va_end(ap);
31701 }
31702
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31703 /************** End of printf.c **********************************************/
31704 /************** Begin file treeview.c ****************************************/
31705 /*
31706 ** 2015-06-08
31707 **
@@ -34572,11 +34745,16 @@
34572 }else{
34573 while( e<=-100 ){ e+=100; r *= 1.0e-100L; }
34574 while( e<=-10 ){ e+=10; r *= 1.0e-10L; }
34575 while( e<=-1 ){ e+=1; r *= 1.0e-01L; }
34576 }
34577 *pResult = r;
 
 
 
 
 
34578 }else{
34579 double rr[2];
34580 u64 s2;
34581 rr[0] = (double)s;
34582 s2 = (u64)rr[0];
@@ -34827,11 +35005,13 @@
34827 if( z[k]!=0 ) return 1;
34828 return 0;
34829 }else
34830 #endif /* SQLITE_OMIT_HEX_INTEGER */
34831 {
34832 return sqlite3Atoi64(z, pOut, sqlite3Strlen30(z), SQLITE_UTF8);
 
 
34833 }
34834 }
34835
34836 /*
34837 ** If zNum represents an integer that will fit in 32-bits, then set
@@ -65559,27 +65739,19 @@
65559 /* Allocate space for the WalIterator object. */
65560 nSegment = walFramePage(iLast) + 1;
65561 nByte = sizeof(WalIterator)
65562 + (nSegment-1)*sizeof(struct WalSegment)
65563 + iLast*sizeof(ht_slot);
65564 p = (WalIterator *)sqlite3_malloc64(nByte);
 
 
65565 if( !p ){
65566 return SQLITE_NOMEM_BKPT;
65567 }
65568 memset(p, 0, nByte);
65569 p->nSegment = nSegment;
65570
65571 /* Allocate temporary space used by the merge-sort routine. This block
65572 ** of memory will be freed before this function returns.
65573 */
65574 aTmp = (ht_slot *)sqlite3_malloc64(
65575 sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast)
65576 );
65577 if( !aTmp ){
65578 rc = SQLITE_NOMEM_BKPT;
65579 }
65580
65581 for(i=walFramePage(nBackfill+1); rc==SQLITE_OK && i<nSegment; i++){
65582 WalHashLoc sLoc;
65583
65584 rc = walHashGet(pWal, i, &sLoc);
65585 if( rc==SQLITE_OK ){
@@ -65603,12 +65775,10 @@
65603 p->aSegment[i].nEntry = nEntry;
65604 p->aSegment[i].aIndex = aIndex;
65605 p->aSegment[i].aPgno = (u32 *)sLoc.aPgno;
65606 }
65607 }
65608 sqlite3_free(aTmp);
65609
65610 if( rc!=SQLITE_OK ){
65611 walIteratorFree(p);
65612 p = 0;
65613 }
65614 *pp = p;
@@ -68121,11 +68291,11 @@
68121 ** 0x00 becomes 0x00000000
68122 ** 0x7f becomes 0x0000007f
68123 ** 0x81 0x00 becomes 0x00000080
68124 ** 0x82 0x00 becomes 0x00000100
68125 ** 0x80 0x7f becomes 0x0000007f
68126 ** 0x8a 0x91 0xd1 0xac 0x78 becomes 0x12345678
68127 ** 0x81 0x81 0x81 0x81 0x01 becomes 0x10204081
68128 **
68129 ** Variable length integers are used for rowids and to hold the number of
68130 ** bytes of key and data in a btree cell.
68131 **
@@ -70505,11 +70675,11 @@
70505 if( *pRC ) return;
70506 assert( pCell!=0 );
70507 pPage->xParseCell(pPage, pCell, &info);
70508 if( info.nLocal<info.nPayload ){
70509 Pgno ovfl;
70510 if( SQLITE_WITHIN(pSrc->aDataEnd, pCell, pCell+info.nLocal) ){
70511 testcase( pSrc!=pPage );
70512 *pRC = SQLITE_CORRUPT_BKPT;
70513 return;
70514 }
70515 ovfl = get4byte(&pCell[info.nSize-4]);
@@ -73797,11 +73967,10 @@
73797 SQLITE_PRIVATE void sqlite3BtreeCursorUnpin(BtCursor *pCur){
73798 assert( (pCur->curFlags & BTCF_Pinned)!=0 );
73799 pCur->curFlags &= ~BTCF_Pinned;
73800 }
73801
73802 #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
73803 /*
73804 ** Return the offset into the database file for the start of the
73805 ** payload to which the cursor is pointing.
73806 */
73807 SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor *pCur){
@@ -73809,11 +73978,10 @@
73809 assert( pCur->eState==CURSOR_VALID );
73810 getCellInfo(pCur);
73811 return (i64)pCur->pBt->pageSize*((i64)pCur->pPage->pgno - 1) +
73812 (i64)(pCur->info.pPayload - pCur->pPage->aData);
73813 }
73814 #endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */
73815
73816 /*
73817 ** Return the number of bytes of payload for the entry that pCur is
73818 ** currently pointing to. For table btrees, this will be the amount
73819 ** of data. For index btrees, this will be the size of the key.
@@ -77666,11 +77834,11 @@
77666 iOvflSpace += sz;
77667 assert( sz<=pBt->maxLocal+23 );
77668 assert( iOvflSpace <= (int)pBt->pageSize );
77669 for(k=0; ALWAYS(k<NB*2) && b.ixNx[k]<=j; k++){}
77670 pSrcEnd = b.apEnd[k];
77671 if( SQLITE_WITHIN(pSrcEnd, pCell, pCell+sz) ){
77672 rc = SQLITE_CORRUPT_BKPT;
77673 goto balance_cleanup;
77674 }
77675 rc = insertCell(pParent, nxDiv+i, pCell, sz, pTemp, pNew->pgno);
77676 if( rc!=SQLITE_OK ) goto balance_cleanup;
@@ -81439,10 +81607,44 @@
81439 assert( (pMem->flags & MEM_Dyn)==0 );
81440 pMem->z = pMem->zMalloc;
81441 pMem->flags &= (MEM_Null|MEM_Int|MEM_Real|MEM_IntReal);
81442 return SQLITE_OK;
81443 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81444
81445 /*
81446 ** It is already known that pMem contains an unterminated string.
81447 ** Add the zero terminator.
81448 **
@@ -81929,18 +82131,21 @@
81929 case SQLITE_AFF_REAL: {
81930 sqlite3VdbeMemRealify(pMem);
81931 break;
81932 }
81933 default: {
 
81934 assert( aff==SQLITE_AFF_TEXT );
81935 assert( MEM_Str==(MEM_Blob>>3) );
81936 pMem->flags |= (pMem->flags&MEM_Blob)>>3;
81937 sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
81938 assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
81939 pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal|MEM_Blob|MEM_Zero);
81940 if( encoding!=SQLITE_UTF8 ) pMem->n &= ~1;
81941 return sqlite3VdbeChangeEncoding(pMem, encoding);
 
 
81942 }
81943 }
81944 return SQLITE_OK;
81945 }
81946
@@ -82459,10 +82664,28 @@
82459 if( pVal->flags&MEM_Null ){
82460 return 0;
82461 }
82462 return valueToText(pVal, enc);
82463 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82464
82465 /*
82466 ** Create a new sqlite3_value object.
82467 */
82468 SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *db){
@@ -84596,11 +84819,10 @@
84596 if( bUndefine ) sqlite3VdbeChangeP5(pParse->pVdbe, 1);
84597 }
84598 }
84599 #endif /* SQLITE_DEBUG */
84600
84601
84602 /*
84603 ** Change the value of the P4 operand for a specific instruction.
84604 ** This routine is useful when a large program is loaded from a
84605 ** static array using sqlite3VdbeAddOpList but we want to make a
84606 ** few minor changes to the program.
@@ -85517,11 +85739,11 @@
85517 if( p->explain==2 ){
85518 sqlite3VdbeMemSetInt64(pMem, pOp->p1);
85519 sqlite3VdbeMemSetInt64(pMem+1, pOp->p2);
85520 sqlite3VdbeMemSetInt64(pMem+2, pOp->p3);
85521 sqlite3VdbeMemSetStr(pMem+3, zP4, -1, SQLITE_UTF8, sqlite3_free);
85522 p->nResColumn = 4;
85523 }else{
85524 sqlite3VdbeMemSetInt64(pMem+0, i);
85525 sqlite3VdbeMemSetStr(pMem+1, (char*)sqlite3OpcodeName(pOp->opcode),
85526 -1, SQLITE_UTF8, SQLITE_STATIC);
85527 sqlite3VdbeMemSetInt64(pMem+2, pOp->p1);
@@ -85536,11 +85758,11 @@
85536 }
85537 #else
85538 sqlite3VdbeMemSetNull(pMem+7);
85539 #endif
85540 sqlite3VdbeMemSetStr(pMem+5, zP4, -1, SQLITE_UTF8, sqlite3_free);
85541 p->nResColumn = 8;
85542 }
85543 p->pResultRow = pMem;
85544 if( db->mallocFailed ){
85545 p->rc = SQLITE_NOMEM;
85546 rc = SQLITE_ERROR;
@@ -85750,30 +85972,13 @@
85750 assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) );
85751
85752 resolveP2Values(p, &nArg);
85753 p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort);
85754 if( pParse->explain ){
85755 static const char * const azColName[] = {
85756 "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
85757 "id", "parent", "notused", "detail"
85758 };
85759 int iFirst, mx, i;
85760 if( nMem<10 ) nMem = 10;
85761 p->explain = pParse->explain;
85762 if( pParse->explain==2 ){
85763 sqlite3VdbeSetNumCols(p, 4);
85764 iFirst = 8;
85765 mx = 12;
85766 }else{
85767 sqlite3VdbeSetNumCols(p, 8);
85768 iFirst = 0;
85769 mx = 8;
85770 }
85771 for(i=iFirst; i<mx; i++){
85772 sqlite3VdbeSetColName(p, i-iFirst, COLNAME_NAME,
85773 azColName[i], SQLITE_STATIC);
85774 }
85775 }
85776 p->expired = 0;
85777
85778 /* Memory for registers, parameters, cursor, etc, is allocated in one or two
85779 ** passes. On the first pass, we try to reuse unused memory at the
@@ -85820,12 +86025,28 @@
85820 ** Close a VDBE cursor and release all the resources that cursor
85821 ** happens to hold.
85822 */
85823 SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
85824 if( pCx ) sqlite3VdbeFreeCursorNN(p,pCx);
 
 
 
 
 
 
 
 
 
 
 
 
85825 }
85826 SQLITE_PRIVATE void sqlite3VdbeFreeCursorNN(Vdbe *p, VdbeCursor *pCx){
 
 
 
 
85827 switch( pCx->eCurType ){
85828 case CURTYPE_SORTER: {
85829 sqlite3VdbeSorterClose(p->db, pCx);
85830 break;
85831 }
@@ -85922,16 +86143,16 @@
85922 */
85923 SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
85924 int n;
85925 sqlite3 *db = p->db;
85926
85927 if( p->nResColumn ){
85928 releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
85929 sqlite3DbFree(db, p->aColName);
85930 }
85931 n = nResColumn*COLNAME_N;
85932 p->nResColumn = (u16)nResColumn;
85933 p->aColName = (Mem*)sqlite3DbMallocRawNN(db, sizeof(Mem)*n );
85934 if( p->aColName==0 ) return;
85935 initMemArray(p->aColName, n, db, MEM_Null);
85936 }
85937
@@ -85952,18 +86173,18 @@
85952 const char *zName, /* Pointer to buffer containing name */
85953 void (*xDel)(void*) /* Memory management strategy for zName */
85954 ){
85955 int rc;
85956 Mem *pColName;
85957 assert( idx<p->nResColumn );
85958 assert( var<COLNAME_N );
85959 if( p->db->mallocFailed ){
85960 assert( !zName || xDel!=SQLITE_DYNAMIC );
85961 return SQLITE_NOMEM_BKPT;
85962 }
85963 assert( p->aColName!=0 );
85964 pColName = &(p->aColName[idx+var*p->nResColumn]);
85965 rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, xDel);
85966 assert( rc!=0 || !zName || (pColName->flags&MEM_Term)!=0 );
85967 return rc;
85968 }
85969
@@ -86783,11 +87004,11 @@
86783 static void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
86784 SubProgram *pSub, *pNext;
86785 assert( db!=0 );
86786 assert( p->db==0 || p->db==db );
86787 if( p->aColName ){
86788 releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
86789 sqlite3DbNNFreeNN(db, p->aColName);
86790 }
86791 for(pSub=p->pProgram; pSub; pSub=pNext){
86792 pNext = pSub->pNext;
86793 vdbeFreeOpArray(db, pSub->aOp, pSub->nOp);
@@ -89092,10 +89313,11 @@
89092 }
89093 if( n>0x7fffffff ){
89094 (void)invokeValueDestructor(z, xDel, pCtx);
89095 }else{
89096 setResultStrOrError(pCtx, z, (int)n, enc, xDel);
 
89097 }
89098 }
89099 #ifndef SQLITE_OMIT_UTF16
89100 SQLITE_API void sqlite3_result_text16(
89101 sqlite3_context *pCtx,
@@ -89704,11 +89926,12 @@
89704 /*
89705 ** Return the number of columns in the result set for the statement pStmt.
89706 */
89707 SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt){
89708 Vdbe *pVm = (Vdbe *)pStmt;
89709 return pVm ? pVm->nResColumn : 0;
 
89710 }
89711
89712 /*
89713 ** Return the number of values available from the current row of the
89714 ** currently executing statement pStmt.
@@ -89877,10 +90100,36 @@
89877 int iType = sqlite3_value_type( columnMem(pStmt,i) );
89878 columnMallocFailure(pStmt);
89879 return iType;
89880 }
89881
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89882 /*
89883 ** Convert the N-th element of pStmt->pColName[] into a string using
89884 ** xFunc() then return that string. If N is out of range, return 0.
89885 **
89886 ** There are up to 5 names for each column. useType determines which
@@ -89909,19 +90158,33 @@
89909 if( pStmt==0 ){
89910 (void)SQLITE_MISUSE_BKPT;
89911 return 0;
89912 }
89913 #endif
 
89914 ret = 0;
89915 p = (Vdbe *)pStmt;
89916 db = p->db;
89917 assert( db!=0 );
89918 n = sqlite3_column_count(pStmt);
89919 if( N<n && N>=0 ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89920 u8 prior_mallocFailed = db->mallocFailed;
89921 N += useType*n;
89922 sqlite3_mutex_enter(db->mutex);
89923 #ifndef SQLITE_OMIT_UTF16
89924 if( useUtf16 ){
89925 ret = sqlite3_value_text16((sqlite3_value*)&p->aColName[N]);
89926 }else
89927 #endif
@@ -89934,12 +90197,13 @@
89934 assert( db->mallocFailed==0 || db->mallocFailed==1 );
89935 if( db->mallocFailed > prior_mallocFailed ){
89936 sqlite3OomClear(db);
89937 ret = 0;
89938 }
89939 sqlite3_mutex_leave(db->mutex);
89940 }
 
 
89941 return ret;
89942 }
89943
89944 /*
89945 ** Return the name of the Nth column of the result set returned by SQL
@@ -90391,10 +90655,43 @@
90391 ** statement is an EXPLAIN QUERY PLAN
90392 */
90393 SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt){
90394 return pStmt ? ((Vdbe*)pStmt)->explain : 0;
90395 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90396
90397 /*
90398 ** Return true if the prepared statement is in need of being reset.
90399 */
90400 SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
@@ -91631,10 +91928,13 @@
91631 for(j=0; j<25 && j<pMem->n; j++){
91632 c = pMem->z[j];
91633 sqlite3_str_appendchar(pStr, 1, (c>=0x20&&c<=0x7f) ? c : '.');
91634 }
91635 sqlite3_str_appendf(pStr, "]%s", encnames[pMem->enc]);
 
 
 
91636 }
91637 }
91638 #endif
91639
91640 #ifdef SQLITE_DEBUG
@@ -91766,10 +92066,97 @@
91766 h += 4093 + (p->flags & (MEM_Str|MEM_Blob));
91767 }
91768 }
91769 return h;
91770 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91771
91772 /*
91773 ** Return the symbolic name for the data type of a pMem
91774 */
91775 static const char *vdbeMemTypeName(Mem *pMem){
@@ -91809,10 +92196,11 @@
91809 Mem *aMem = p->aMem; /* Copy of p->aMem */
91810 Mem *pIn1 = 0; /* 1st input operand */
91811 Mem *pIn2 = 0; /* 2nd input operand */
91812 Mem *pIn3 = 0; /* 3rd input operand */
91813 Mem *pOut = 0; /* Output operand */
 
91814 #if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE)
91815 u64 *pnCycle = 0;
91816 int bStmtScanStatus = IS_STMT_SCANSTATUS(db)!=0;
91817 #endif
91818 /*** INSERT STACK UNION HERE ***/
@@ -94133,10 +94521,11 @@
94133 pDest->flags = aFlag[t&1];
94134 }
94135 }else{
94136 u8 p5;
94137 pDest->enc = encoding;
 
94138 /* This branch happens only when content is on overflow pages */
94139 if( ((p5 = (pOp->p5 & OPFLAG_BYTELENARG))!=0
94140 && (p5==OPFLAG_TYPEOFARG
94141 || (t>=12 && ((t&1)==0 || p5==OPFLAG_BYTELENARG))
94142 )
@@ -94156,15 +94545,17 @@
94156 ** as that array is 256 bytes long (plenty for VdbeMemPrettyPrint())
94157 ** and it begins with a bunch of zeros.
94158 */
94159 sqlite3VdbeSerialGet((u8*)sqlite3CtypeMap, t, pDest);
94160 }else{
94161 if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) goto too_big;
94162 rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest);
94163 if( rc!=SQLITE_OK ) goto abort_due_to_error;
94164 sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest);
94165 pDest->flags &= ~MEM_Ephem;
 
 
94166 }
94167 }
94168
94169 op_column_out:
94170 UPDATE_MAX_BLOBSIZE(pDest);
@@ -96693,10 +97084,11 @@
96693 (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION|OPFLAG_PREFORMAT)),
96694 seekResult
96695 );
96696 pC->deferredMoveto = 0;
96697 pC->cacheStatus = CACHE_STALE;
 
96698
96699 /* Invoke the update-hook if required. */
96700 if( rc ) goto abort_due_to_error;
96701 if( pTab ){
96702 assert( db->xUpdateCallback!=0 );
@@ -96853,10 +97245,11 @@
96853 }
96854 #endif
96855
96856 rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5);
96857 pC->cacheStatus = CACHE_STALE;
 
96858 pC->seekResult = 0;
96859 if( rc ) goto abort_due_to_error;
96860
96861 /* Invoke the update-hook if required. */
96862 if( opflags & OPFLAG_NCHANGE ){
@@ -103347,10 +103740,12 @@
103347 "p3 INT,"
103348 "p4 TEXT,"
103349 "p5 INT,"
103350 "comment TEXT,"
103351 "subprog TEXT,"
 
 
103352 "stmt HIDDEN"
103353 ");",
103354
103355 /* Tables_used() schema */
103356 "CREATE TABLE x("
@@ -103509,11 +103904,11 @@
103509 pCur->zType = "index";
103510 }
103511 }
103512 }
103513 }
103514 i += 10;
103515 }
103516 }
103517 switch( i ){
103518 case 0: /* addr */
103519 sqlite3_result_int(ctx, pCur->iAddr);
@@ -103559,20 +103954,35 @@
103559 }else{
103560 sqlite3_result_text(ctx, "(FK)", 4, SQLITE_STATIC);
103561 }
103562 break;
103563 }
103564 case 10: /* tables_used.type */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103565 sqlite3_result_text(ctx, pCur->zType, -1, SQLITE_STATIC);
103566 break;
103567 case 11: /* tables_used.schema */
103568 sqlite3_result_text(ctx, pCur->zSchema, -1, SQLITE_STATIC);
103569 break;
103570 case 12: /* tables_used.name */
103571 sqlite3_result_text(ctx, pCur->zName, -1, SQLITE_STATIC);
103572 break;
103573 case 13: /* tables_used.wr */
103574 sqlite3_result_int(ctx, pOp->opcode==OP_OpenWrite);
103575 break;
103576 }
103577 return SQLITE_OK;
103578 }
@@ -103642,11 +104052,11 @@
103642 ){
103643 int i;
103644 int rc = SQLITE_CONSTRAINT;
103645 struct sqlite3_index_constraint *p;
103646 bytecodevtab *pVTab = (bytecodevtab*)tab;
103647 int iBaseCol = pVTab->bTablesUsed ? 4 : 8;
103648 pIdxInfo->estimatedCost = (double)100;
103649 pIdxInfo->estimatedRows = 100;
103650 pIdxInfo->idxNum = 0;
103651 for(i=0, p=pIdxInfo->aConstraint; i<pIdxInfo->nConstraint; i++, p++){
103652 if( p->usable==0 ) continue;
@@ -111269,12 +111679,11 @@
111269 testcase( (pDef->funcFlags & OPFLAG_BYTELENARG)==OPFLAG_BYTELENARG);
111270 pFarg->a[0].pExpr->op2 = pDef->funcFlags & OPFLAG_BYTELENARG;
111271 }
111272 }
111273
111274 sqlite3ExprCodeExprList(pParse, pFarg, r1, 0,
111275 SQLITE_ECEL_DUP|SQLITE_ECEL_FACTOR);
111276 }else{
111277 r1 = 0;
111278 }
111279 #ifndef SQLITE_OMIT_VIRTUALTABLE
111280 /* Possibly overload the function if the first argument is
@@ -125336,11 +125745,12 @@
125336 */
125337 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0,0,wcf,iTabCur+1);
125338 if( pWInfo==0 ) goto delete_from_cleanup;
125339 eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
125340 assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI );
125341 assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF );
 
125342 if( eOnePass!=ONEPASS_SINGLE ) sqlite3MultiWrite(pParse);
125343 if( sqlite3WhereUsesDeferredSeek(pWInfo) ){
125344 sqlite3VdbeAddOp1(v, OP_FinishSeek, iTabCur);
125345 }
125346
@@ -127068,10 +127478,11 @@
127068 *zOut++ = 0x80 + (u8)((c>>12) & 0x3F);
127069 *zOut++ = 0x80 + (u8)((c>>6) & 0x3F);
127070 *zOut++ = 0x80 + (u8)(c & 0x3F);
127071 } \
127072 }
 
127073 sqlite3_result_text64(context, (char*)z, zOut-z, sqlite3_free, SQLITE_UTF8);
127074 }
127075
127076 /*
127077 ** The hex() function. Interpret the argument as a blob. Return
@@ -127605,15 +128016,14 @@
127605 p->iSum = x;
127606 }else{
127607 p->ovrfl = 1;
127608 kahanBabuskaNeumaierInit(p, p->iSum);
127609 p->approx = 1;
127610 kahanBabuskaNeumaierStep(p, sqlite3_value_double(argv[0]));
127611 }
127612 }
127613 }else{
127614 p->approx = 1;
127615 if( type==SQLITE_INTEGER ){
127616 kahanBabuskaNeumaierStepInt64(p, sqlite3_value_int64(argv[0]));
127617 }else{
127618 p->ovrfl = 0;
127619 kahanBabuskaNeumaierStep(p, sqlite3_value_double(argv[0]));
@@ -139192,11 +139602,16 @@
139192 memset(PARSE_HDR(&sParse), 0, PARSE_HDR_SZ);
139193 memset(PARSE_TAIL(&sParse), 0, PARSE_TAIL_SZ);
139194 sParse.pOuterParse = db->pParse;
139195 db->pParse = &sParse;
139196 sParse.db = db;
139197 sParse.pReprepare = pReprepare;
 
 
 
 
 
139198 assert( ppStmt && *ppStmt==0 );
139199 if( db->mallocFailed ){
139200 sqlite3ErrorMsg(&sParse, "out of memory");
139201 db->errCode = rc = SQLITE_NOMEM;
139202 goto end_prepare;
@@ -141671,17 +142086,10 @@
141671 ExprList *pEList;
141672 sqlite3 *db = pParse->db;
141673 int fullName; /* TABLE.COLUMN if no AS clause and is a direct table ref */
141674 int srcName; /* COLUMN or TABLE.COLUMN if no AS clause and is direct */
141675
141676 #ifndef SQLITE_OMIT_EXPLAIN
141677 /* If this is an EXPLAIN, skip this step */
141678 if( pParse->explain ){
141679 return;
141680 }
141681 #endif
141682
141683 if( pParse->colNamesSet ) return;
141684 /* Column names are determined by the left-most term of a compound select */
141685 while( pSelect->pPrior ) pSelect = pSelect->pPrior;
141686 TREETRACE(0x80,pParse,pSelect,("generating column names\n"));
141687 pTabList = pSelect->pSrc;
@@ -143869,11 +144277,12 @@
143869 ** is the first element of the parent query. Two subcases:
143870 ** (27a) the subquery is not a compound query.
143871 ** (27b) the subquery is a compound query and the RIGHT JOIN occurs
143872 ** in any arm of the compound query. (See also (17g).)
143873 **
143874 ** (28) The subquery is not a MATERIALIZED CTE.
 
143875 **
143876 **
143877 ** In this routine, the "p" parameter is a pointer to the outer query.
143878 ** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query
143879 ** uses aggregates.
@@ -143979,13 +144388,13 @@
143979
143980 assert( pSubSrc->nSrc>0 ); /* True by restriction (7) */
143981 if( iFrom>0 && (pSubSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){
143982 return 0; /* Restriction (27a) */
143983 }
143984 if( pSubitem->fg.isCte && pSubitem->u2.pCteUse->eM10d==M10d_Yes ){
143985 return 0; /* (28) */
143986 }
143987
143988 /* Restriction (17): If the sub-query is a compound SELECT, then it must
143989 ** use only the UNION ALL operator. And none of the simple select queries
143990 ** that make up the compound SELECT are allowed to be aggregate or distinct
143991 ** queries.
@@ -146861,10 +147270,18 @@
146861 if( pTab->nCol!=pSub->pEList->nExpr ){
146862 sqlite3ErrorMsg(pParse, "expected %d columns for '%s' but got %d",
146863 pTab->nCol, pTab->zName, pSub->pEList->nExpr);
146864 goto select_end;
146865 }
 
 
 
 
 
 
 
 
146866
146867 /* Do not try to flatten an aggregate subquery.
146868 **
146869 ** Flattening an aggregate subquery is only possible if the outer query
146870 ** is not a join. But if the outer query is not a join, then the subquery
@@ -146891,10 +147308,12 @@
146891 ** (5) The ORDER BY isn't going to accomplish anything because
146892 ** one of:
146893 ** (a) The outer query has a different ORDER BY clause
146894 ** (b) The subquery is part of a join
146895 ** See forum post 062d576715d277c8
 
 
146896 */
146897 if( pSub->pOrderBy!=0
146898 && (p->pOrderBy!=0 || pTabList->nSrc>1) /* Condition (5) */
146899 && pSub->pLimit==0 /* Condition (1) */
146900 && (pSub->selFlags & SF_OrderByReqd)==0 /* Condition (2) */
@@ -150394,11 +150813,11 @@
150394 if( !pParse->nested
150395 && !pTrigger
150396 && !hasFK
150397 && !chngKey
150398 && !bReplace
150399 && (sNC.ncFlags & NC_Subquery)==0
150400 ){
150401 flags |= WHERE_ONEPASS_MULTIROW;
150402 }
150403 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,0,0,0,flags,iIdxCur);
150404 if( pWInfo==0 ) goto update_cleanup;
@@ -160954,11 +161373,11 @@
160954 return 0; /* Discard pTemplate */
160955 }
160956
160957 /* If pTemplate is always better than p, then cause p to be overwritten
160958 ** with pTemplate. pTemplate is better than p if:
160959 ** (1) pTemplate has no more dependences than p, and
160960 ** (2) pTemplate has an equal or lower cost than p.
160961 */
160962 if( (p->prereq & pTemplate->prereq)==pTemplate->prereq /* (1) */
160963 && p->rRun>=pTemplate->rRun /* (2a) */
160964 && p->nOut>=pTemplate->nOut /* (2b) */
@@ -163422,11 +163841,12 @@
163422 /* TUNING: For simple queries, only the best path is tracked.
163423 ** For 2-way joins, the 5 best paths are followed.
163424 ** For joins of 3 or more tables, track the 10 best paths */
163425 mxChoice = (nLoop<=1) ? 1 : (nLoop==2 ? 5 : 10);
163426 assert( nLoop<=pWInfo->pTabList->nSrc );
163427 WHERETRACE(0x002, ("---- begin solver. (nRowEst=%d)\n", nRowEst));
 
163428
163429 /* If nRowEst is zero and there is an ORDER BY clause, ignore it. In this
163430 ** case the purpose of this call is to estimate the number of rows returned
163431 ** by the overall query. Once this estimate has been obtained, the caller
163432 ** will invoke this function a second time, passing the estimate as the
@@ -163541,13 +163961,14 @@
163541 rUnsorted -= 2; /* TUNING: Slight bias in favor of no-sort plans */
163542 }
163543
163544 /* TUNING: A full-scan of a VIEW or subquery in the outer loop
163545 ** is not so bad. */
163546 if( iLoop==0 && (pWLoop->wsFlags & WHERE_VIEWSCAN)!=0 ){
163547 rCost += -10;
163548 nOut += -30;
 
163549 }
163550
163551 /* Check to see if pWLoop should be added to the set of
163552 ** mxChoice best-so-far paths.
163553 **
@@ -164174,10 +164595,32 @@
164174 if( p->pIENext==0 ){
164175 sqlite3ParserAddCleanup(pParse, whereIndexedExprCleanup, pParse);
164176 }
164177 }
164178 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164179
164180 /*
164181 ** Generate the beginning of the loop used for WHERE clause processing.
164182 ** The return value is a pointer to an opaque structure that contains
164183 ** information needed to terminate the loop. Later, the calling routine
@@ -164539,12 +164982,13 @@
164539 if( pWInfo->pOrderBy ){
164540 wherePathSolver(pWInfo, pWInfo->nRowOut+1);
164541 if( db->mallocFailed ) goto whereBeginError;
164542 }
164543 }
 
164544 if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){
164545 pWInfo->revMask = ALLBITS;
164546 }
164547 if( pParse->nErr ){
164548 goto whereBeginError;
164549 }
164550 assert( db->mallocFailed==0 );
@@ -164640,10 +165084,11 @@
164640 assert( !(wsFlags & WHERE_VIRTUALTABLE) || IsVirtual(pTabList->a[0].pTab) );
164641 if( bOnerow || (
164642 0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW)
164643 && !IsVirtual(pTabList->a[0].pTab)
164644 && (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK))
 
164645 )){
164646 pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI;
164647 if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){
164648 if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){
164649 bFordelete = OPFLAG_FORDELETE;
@@ -171937,14 +172382,14 @@
171937 ** break;
171938 */
171939 /********** Begin reduce actions **********************************************/
171940 YYMINORTYPE yylhsminor;
171941 case 0: /* explain ::= EXPLAIN */
171942 { pParse->explain = 1; }
171943 break;
171944 case 1: /* explain ::= EXPLAIN QUERY PLAN */
171945 { pParse->explain = 2; }
171946 break;
171947 case 2: /* cmdx ::= cmd */
171948 { sqlite3FinishCoding(pParse); }
171949 break;
171950 case 3: /* cmd ::= BEGIN transtype trans_opt */
@@ -200394,28 +200839,54 @@
200394 ** Growing our own isspace() routine this way is twice as fast as
200395 ** the library isspace() function, resulting in a 7% overall performance
200396 ** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os).
200397 */
200398 static const char jsonIsSpace[] = {
200399 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
200400 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200401 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200402 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200403 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200404 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200405 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200406 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200407 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200408 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200409 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200410 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200411 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200412 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200413 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200414 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 
200415 };
200416 #define fast_isspace(x) (jsonIsSpace[(unsigned char)x])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200417
200418 #if !defined(SQLITE_DEBUG) && !defined(SQLITE_COVERAGE_TEST)
200419 # define VVA(X)
200420 #else
200421 # define VVA(X) X
@@ -200423,10 +200894,11 @@
200423
200424 /* Objects */
200425 typedef struct JsonString JsonString;
200426 typedef struct JsonNode JsonNode;
200427 typedef struct JsonParse JsonParse;
 
200428
200429 /* An instance of this object represents a JSON string
200430 ** under construction. Really, this is a generic string accumulator
200431 ** that can be and is used to create strings other than JSON.
200432 */
@@ -200437,75 +200909,120 @@
200437 u64 nUsed; /* Bytes of zBuf[] currently used */
200438 u8 bStatic; /* True if zBuf is static space */
200439 u8 bErr; /* True if an error has been encountered */
200440 char zSpace[100]; /* Initial static space */
200441 };
 
 
 
 
 
 
 
 
 
200442
200443 /* JSON type values
200444 */
200445 #define JSON_NULL 0
200446 #define JSON_TRUE 1
200447 #define JSON_FALSE 2
200448 #define JSON_INT 3
200449 #define JSON_REAL 4
200450 #define JSON_STRING 5
200451 #define JSON_ARRAY 6
200452 #define JSON_OBJECT 7
 
200453
200454 /* The "subtype" set for JSON values */
200455 #define JSON_SUBTYPE 74 /* Ascii for "J" */
200456
200457 /*
200458 ** Names of the various JSON types:
200459 */
200460 static const char * const jsonType[] = {
 
200461 "null", "true", "false", "integer", "real", "text", "array", "object"
200462 };
200463
200464 /* Bit values for the JsonNode.jnFlag field
200465 */
200466 #define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */
200467 #define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */
200468 #define JNODE_REMOVE 0x04 /* Do not output */
200469 #define JNODE_REPLACE 0x08 /* Replace with JsonNode.u.iReplace */
200470 #define JNODE_PATCH 0x10 /* Patch with JsonNode.u.pPatch */
200471 #define JNODE_APPEND 0x20 /* More ARRAY/OBJECT entries at u.iAppend */
200472 #define JNODE_LABEL 0x40 /* Is a label of an object */
200473 #define JNODE_JSON5 0x80 /* Node contains JSON5 enhancements */
200474
200475
200476 /* A single node of parsed JSON
 
 
 
 
 
200477 */
200478 struct JsonNode {
200479 u8 eType; /* One of the JSON_ type values */
200480 u8 jnFlags; /* JNODE flags */
200481 u8 eU; /* Which union element to use */
200482 u32 n; /* Bytes of content, or number of sub-nodes */
 
 
200483 union {
200484 const char *zJContent; /* 1: Content for INT, REAL, and STRING */
200485 u32 iAppend; /* 2: More terms for ARRAY and OBJECT */
200486 u32 iKey; /* 3: Key for ARRAY objects in json_tree() */
200487 u32 iReplace; /* 4: Replacement content for JNODE_REPLACE */
200488 JsonNode *pPatch; /* 5: Node chain of patch for JNODE_PATCH */
200489 } u;
200490 };
200491
200492 /* A completely parsed JSON string
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200493 */
200494 struct JsonParse {
200495 u32 nNode; /* Number of slots of aNode[] used */
200496 u32 nAlloc; /* Number of slots of aNode[] allocated */
200497 JsonNode *aNode; /* Array of nodes containing the parse */
200498 const char *zJson; /* Original JSON string */
 
200499 u32 *aUp; /* Index of parent of each node */
 
200500 u16 iDepth; /* Nesting depth */
200501 u8 nErr; /* Number of errors seen */
200502 u8 oom; /* Set to true if out of memory */
 
200503 u8 hasNonstd; /* True if input uses non-standard features like JSON5 */
 
 
 
200504 int nJson; /* Length of the zJson string in bytes */
 
200505 u32 iErr; /* Error location in zJson[] */
200506 u32 iHold; /* Replace cache line with the lowest iHold value */
 
200507 };
200508
200509 /*
200510 ** Maximum nesting depth of JSON for this implementation.
200511 **
@@ -200534,19 +201051,17 @@
200534 p->pCtx = pCtx;
200535 p->bErr = 0;
200536 jsonZero(p);
200537 }
200538
200539
200540 /* Free all allocated memory and reset the JsonString object back to its
200541 ** initial state.
200542 */
200543 static void jsonReset(JsonString *p){
200544 if( !p->bStatic ) sqlite3_free(p->zBuf);
200545 jsonZero(p);
200546 }
200547
200548
200549 /* Report an out-of-memory (OOM) condition
200550 */
200551 static void jsonOom(JsonString *p){
200552 p->bErr = 1;
@@ -200560,38 +201075,61 @@
200560 static int jsonGrow(JsonString *p, u32 N){
200561 u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10;
200562 char *zNew;
200563 if( p->bStatic ){
200564 if( p->bErr ) return 1;
200565 zNew = sqlite3_malloc64(nTotal);
200566 if( zNew==0 ){
200567 jsonOom(p);
200568 return SQLITE_NOMEM;
200569 }
200570 memcpy(zNew, p->zBuf, (size_t)p->nUsed);
200571 p->zBuf = zNew;
200572 p->bStatic = 0;
200573 }else{
200574 zNew = sqlite3_realloc64(p->zBuf, nTotal);
200575 if( zNew==0 ){
200576 jsonOom(p);
 
200577 return SQLITE_NOMEM;
200578 }
200579 p->zBuf = zNew;
200580 }
200581 p->nAlloc = nTotal;
200582 return SQLITE_OK;
200583 }
200584
200585 /* Append N bytes from zIn onto the end of the JsonString string.
200586 */
200587 static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
200588 if( N==0 ) return;
200589 if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return;
 
 
 
 
200590 memcpy(p->zBuf+p->nUsed, zIn, N);
200591 p->nUsed += N;
200592 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200593
200594 /* Append formatted text (not to exceed N bytes) to the JsonString.
200595 */
200596 static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){
200597 va_list ap;
@@ -200602,23 +201140,49 @@
200602 p->nUsed += (int)strlen(p->zBuf+p->nUsed);
200603 }
200604
200605 /* Append a single character
200606 */
200607 static void jsonAppendChar(JsonString *p, char c){
200608 if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return;
200609 p->zBuf[p->nUsed++] = c;
200610 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200611
200612 /* Append a comma separator to the output buffer, if the previous
200613 ** character is not '[' or '{'.
200614 */
200615 static void jsonAppendSeparator(JsonString *p){
200616 char c;
200617 if( p->nUsed==0 ) return;
200618 c = p->zBuf[p->nUsed-1];
200619 if( c!='[' && c!='{' ) jsonAppendChar(p, ',');
 
200620 }
200621
200622 /* Append the N-byte string in zIn to the end of the JsonString string
200623 ** under construction. Enclose the string in "..." and escape
200624 ** any double-quotes or backslash characters contained within the
@@ -200628,15 +201192,20 @@
200628 u32 i;
200629 if( zIn==0 || ((N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0) ) return;
200630 p->zBuf[p->nUsed++] = '"';
200631 for(i=0; i<N; i++){
200632 unsigned char c = ((unsigned const char*)zIn)[i];
200633 if( c=='"' || c=='\\' ){
 
 
200634 json_simple_escape:
200635 if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return;
200636 p->zBuf[p->nUsed++] = '\\';
200637 }else if( c<=0x1f ){
 
 
 
200638 static const char aSpecial[] = {
200639 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0,
200640 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
200641 };
200642 assert( sizeof(aSpecial)==32 );
@@ -200643,23 +201212,23 @@
200643 assert( aSpecial['\b']=='b' );
200644 assert( aSpecial['\f']=='f' );
200645 assert( aSpecial['\n']=='n' );
200646 assert( aSpecial['\r']=='r' );
200647 assert( aSpecial['\t']=='t' );
 
200648 if( aSpecial[c] ){
200649 c = aSpecial[c];
200650 goto json_simple_escape;
200651 }
200652 if( (p->nUsed+N+7+i > p->nAlloc) && jsonGrow(p,N+7-i)!=0 ) return;
200653 p->zBuf[p->nUsed++] = '\\';
200654 p->zBuf[p->nUsed++] = 'u';
200655 p->zBuf[p->nUsed++] = '0';
200656 p->zBuf[p->nUsed++] = '0';
200657 p->zBuf[p->nUsed++] = '0' + (c>>4);
200658 c = "0123456789abcdef"[c&0xf];
200659 }
200660 p->zBuf[p->nUsed++] = c;
200661 }
200662 p->zBuf[p->nUsed++] = '"';
200663 assert( p->nUsed<p->nAlloc );
200664 }
200665
@@ -200674,11 +201243,11 @@
200674 zIn++;
200675 N -= 2;
200676 while( N>0 ){
200677 for(i=0; i<N && zIn[i]!='\\'; i++){}
200678 if( i>0 ){
200679 jsonAppendRaw(p, zIn, i);
200680 zIn += i;
200681 N -= i;
200682 if( N==0 ) break;
200683 }
200684 assert( zIn[0]=='\\' );
@@ -200685,20 +201254,20 @@
200685 switch( (u8)zIn[1] ){
200686 case '\'':
200687 jsonAppendChar(p, '\'');
200688 break;
200689 case 'v':
200690 jsonAppendRaw(p, "\\u0009", 6);
200691 break;
200692 case 'x':
200693 jsonAppendRaw(p, "\\u00", 4);
200694 jsonAppendRaw(p, &zIn[2], 2);
200695 zIn += 2;
200696 N -= 2;
200697 break;
200698 case '0':
200699 jsonAppendRaw(p, "\\u0000", 6);
200700 break;
200701 case '\r':
200702 if( zIn[2]=='\n' ){
200703 zIn++;
200704 N--;
@@ -200712,11 +201281,11 @@
200712 assert( 0xa8==(u8)zIn[3] || 0xa9==(u8)zIn[3] );
200713 zIn += 2;
200714 N -= 2;
200715 break;
200716 default:
200717 jsonAppendRaw(p, zIn, 2);
200718 break;
200719 }
200720 zIn += 2;
200721 N -= 2;
200722 }
@@ -200742,15 +201311,16 @@
200742 int rc = sqlite3DecOrHexToI64(zIn, &i);
200743 if( rc<=1 ){
200744 jsonPrintf(100,p,"%lld",i);
200745 }else{
200746 assert( rc==2 );
200747 jsonAppendRaw(p, "9.0e999", 7);
200748 }
200749 return;
200750 }
200751 jsonAppendRaw(p, zIn, N);
 
200752 }
200753
200754 /*
200755 ** The zIn[0..N] string is a JSON5 real literal. Append to p a translation
200756 ** of the string literal that standard JSON and that omits all JSON5
@@ -200778,11 +201348,11 @@
200778 jsonAppendChar(p, '0');
200779 break;
200780 }
200781 }
200782 if( N>0 ){
200783 jsonAppendRaw(p, zIn, N);
200784 }
200785 }
200786
200787
200788
@@ -200794,11 +201364,11 @@
200794 JsonString *p, /* Append to this JSON string */
200795 sqlite3_value *pValue /* Value to append */
200796 ){
200797 switch( sqlite3_value_type(pValue) ){
200798 case SQLITE_NULL: {
200799 jsonAppendRaw(p, "null", 4);
200800 break;
200801 }
200802 case SQLITE_FLOAT: {
200803 jsonPrintf(100, p, "%!0.15g", sqlite3_value_double(pValue));
200804 break;
@@ -200830,19 +201400,29 @@
200830 }
200831 }
200832
200833
200834 /* Make the JSON in p the result of the SQL function.
 
 
200835 */
200836 static void jsonResult(JsonString *p){
200837 if( p->bErr==0 ){
200838 sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
200839 p->bStatic ? SQLITE_TRANSIENT : sqlite3_free,
200840 SQLITE_UTF8);
200841 jsonZero(p);
 
 
 
 
 
200842 }
200843 assert( p->bStatic );
 
 
 
200844 }
200845
200846 /**************************************************************************
200847 ** Utility routines for dealing with JsonNode and JsonParse objects
200848 **************************************************************************/
@@ -200863,58 +201443,117 @@
200863 /*
200864 ** Reclaim all memory allocated by a JsonParse object. But do not
200865 ** delete the JsonParse object itself.
200866 */
200867 static void jsonParseReset(JsonParse *pParse){
200868 sqlite3_free(pParse->aNode);
200869 pParse->aNode = 0;
 
 
 
 
 
 
 
 
 
200870 pParse->nNode = 0;
200871 pParse->nAlloc = 0;
200872 sqlite3_free(pParse->aUp);
200873 pParse->aUp = 0;
 
 
 
 
 
 
 
 
 
 
 
200874 }
200875
200876 /*
200877 ** Free a JsonParse object that was obtained from sqlite3_malloc().
 
 
 
 
 
200878 */
200879 static void jsonParseFree(JsonParse *pParse){
200880 jsonParseReset(pParse);
200881 sqlite3_free(pParse);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200882 }
200883
200884 /*
200885 ** Convert the JsonNode pNode into a pure JSON string and
200886 ** append to pOut. Subsubstructure is also included. Return
200887 ** the number of JsonNode objects that are encoded.
200888 */
200889 static void jsonRenderNode(
 
200890 JsonNode *pNode, /* The node to render */
200891 JsonString *pOut, /* Write JSON here */
200892 sqlite3_value **aReplace /* Replacement values */
200893 ){
200894 assert( pNode!=0 );
200895 if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){
200896 if( (pNode->jnFlags & JNODE_REPLACE)!=0 && ALWAYS(aReplace!=0) ){
200897 assert( pNode->eU==4 );
200898 jsonAppendValue(pOut, aReplace[pNode->u.iReplace]);
200899 return;
200900 }
200901 assert( pNode->eU==5 );
200902 pNode = pNode->u.pPatch;
 
 
 
 
 
 
200903 }
200904 switch( pNode->eType ){
200905 default: {
200906 assert( pNode->eType==JSON_NULL );
200907 jsonAppendRaw(pOut, "null", 4);
200908 break;
200909 }
200910 case JSON_TRUE: {
200911 jsonAppendRaw(pOut, "true", 4);
200912 break;
200913 }
200914 case JSON_FALSE: {
200915 jsonAppendRaw(pOut, "false", 5);
200916 break;
200917 }
200918 case JSON_STRING: {
200919 assert( pNode->eU==1 );
200920 if( pNode->jnFlags & JNODE_RAW ){
@@ -200926,46 +201565,50 @@
200926 jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
200927 }
200928 }else if( pNode->jnFlags & JNODE_JSON5 ){
200929 jsonAppendNormalizedString(pOut, pNode->u.zJContent, pNode->n);
200930 }else{
200931 jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
 
200932 }
200933 break;
200934 }
200935 case JSON_REAL: {
200936 assert( pNode->eU==1 );
200937 if( pNode->jnFlags & JNODE_JSON5 ){
200938 jsonAppendNormalizedReal(pOut, pNode->u.zJContent, pNode->n);
200939 }else{
200940 jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
 
200941 }
200942 break;
200943 }
200944 case JSON_INT: {
200945 assert( pNode->eU==1 );
200946 if( pNode->jnFlags & JNODE_JSON5 ){
200947 jsonAppendNormalizedInt(pOut, pNode->u.zJContent, pNode->n);
200948 }else{
200949 jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
 
200950 }
200951 break;
200952 }
200953 case JSON_ARRAY: {
200954 u32 j = 1;
200955 jsonAppendChar(pOut, '[');
200956 for(;;){
200957 while( j<=pNode->n ){
200958 if( (pNode[j].jnFlags & JNODE_REMOVE)==0 ){
200959 jsonAppendSeparator(pOut);
200960 jsonRenderNode(&pNode[j], pOut, aReplace);
200961 }
200962 j += jsonNodeSize(&pNode[j]);
200963 }
200964 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
 
200965 assert( pNode->eU==2 );
200966 pNode = &pNode[pNode->u.iAppend];
200967 j = 1;
200968 }
200969 jsonAppendChar(pOut, ']');
200970 break;
200971 }
@@ -200972,21 +201615,22 @@
200972 case JSON_OBJECT: {
200973 u32 j = 1;
200974 jsonAppendChar(pOut, '{');
200975 for(;;){
200976 while( j<=pNode->n ){
200977 if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){
200978 jsonAppendSeparator(pOut);
200979 jsonRenderNode(&pNode[j], pOut, aReplace);
200980 jsonAppendChar(pOut, ':');
200981 jsonRenderNode(&pNode[j+1], pOut, aReplace);
200982 }
200983 j += 1 + jsonNodeSize(&pNode[j+1]);
200984 }
200985 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
 
200986 assert( pNode->eU==2 );
200987 pNode = &pNode[pNode->u.iAppend];
200988 j = 1;
200989 }
200990 jsonAppendChar(pOut, '}');
200991 break;
200992 }
@@ -200995,19 +201639,30 @@
200995
200996 /*
200997 ** Return a JsonNode and all its descendants as a JSON string.
200998 */
200999 static void jsonReturnJson(
 
201000 JsonNode *pNode, /* Node to return */
201001 sqlite3_context *pCtx, /* Return value for this function */
201002 sqlite3_value **aReplace /* Array of replacement values */
201003 ){
201004 JsonString s;
201005 jsonInit(&s, pCtx);
201006 jsonRenderNode(pNode, &s, aReplace);
201007 jsonResult(&s);
201008 sqlite3_result_subtype(pCtx, JSON_SUBTYPE);
 
 
 
 
 
 
 
 
 
 
201009 }
201010
201011 /*
201012 ** Translate a single byte of Hex into an integer.
201013 ** This routine only works if h really is a valid hexadecimal
@@ -201041,13 +201696,13 @@
201041
201042 /*
201043 ** Make the JsonNode the return value of the function.
201044 */
201045 static void jsonReturn(
 
201046 JsonNode *pNode, /* Node to return */
201047 sqlite3_context *pCtx, /* Return value for this function */
201048 sqlite3_value **aReplace /* Array of replacement values */
201049 ){
201050 switch( pNode->eType ){
201051 default: {
201052 assert( pNode->eType==JSON_NULL );
201053 sqlite3_result_null(pCtx);
@@ -201064,11 +201719,10 @@
201064 case JSON_INT: {
201065 sqlite3_int64 i = 0;
201066 int rc;
201067 int bNeg = 0;
201068 const char *z;
201069
201070
201071 assert( pNode->eU==1 );
201072 z = pNode->u.zJContent;
201073 if( z[0]=='-' ){ z++; bNeg = 1; }
201074 else if( z[0]=='+' ){ z++; }
@@ -201190,11 +201844,11 @@
201190 }
201191 break;
201192 }
201193 case JSON_ARRAY:
201194 case JSON_OBJECT: {
201195 jsonReturnJson(pNode, pCtx, aReplace);
201196 break;
201197 }
201198 }
201199 }
201200
@@ -201212,10 +201866,16 @@
201212 #else
201213 # define JSON_NOINLINE
201214 #endif
201215
201216
 
 
 
 
 
 
201217 static JSON_NOINLINE int jsonParseAddNodeExpand(
201218 JsonParse *pParse, /* Append the node to this object */
201219 u32 eType, /* Node type */
201220 u32 n, /* Content size or sub-node count */
201221 const char *zContent /* Content */
@@ -201228,11 +201888,11 @@
201228 pNew = sqlite3_realloc64(pParse->aNode, sizeof(JsonNode)*nNew);
201229 if( pNew==0 ){
201230 pParse->oom = 1;
201231 return -1;
201232 }
201233 pParse->nAlloc = nNew;
201234 pParse->aNode = pNew;
201235 assert( pParse->nNode<pParse->nAlloc );
201236 return jsonParseAddNode(pParse, eType, n, zContent);
201237 }
201238
@@ -201246,11 +201906,12 @@
201246 u32 eType, /* Node type */
201247 u32 n, /* Content size or sub-node count */
201248 const char *zContent /* Content */
201249 ){
201250 JsonNode *p;
201251 if( pParse->aNode==0 || pParse->nNode>=pParse->nAlloc ){
 
201252 return jsonParseAddNodeExpand(pParse, eType, n, zContent);
201253 }
201254 p = &pParse->aNode[pParse->nNode];
201255 p->eType = (u8)(eType & 0xff);
201256 p->jnFlags = (u8)(eType >> 8);
@@ -201257,10 +201918,54 @@
201257 VVA( p->eU = zContent ? 1 : 0 );
201258 p->n = n;
201259 p->u.zJContent = zContent;
201260 return pParse->nNode++;
201261 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201262
201263 /*
201264 ** Return true if z[] begins with 2 (or more) hexadecimal digits
201265 */
201266 static int jsonIs2Hex(const char *z){
@@ -201424,11 +202129,11 @@
201424 ** Parse a single JSON value which begins at pParse->zJson[i]. Return the
201425 ** index of the first character past the end of the value parsed.
201426 **
201427 ** Special return values:
201428 **
201429 ** 0 End if input
201430 ** -1 Syntax error
201431 ** -2 '}' seen
201432 ** -3 ']' seen
201433 ** -4 ',' seen
201434 ** -5 ':' seen
@@ -201599,19 +202304,16 @@
201599 case '"':
201600 /* Parse string */
201601 jnFlags = 0;
201602 parse_string:
201603 cDelim = z[i];
201604 j = i+1;
201605 for(;;){
201606 c = z[j];
201607 if( (c & ~0x1f)==0 ){
201608 /* Control characters are not allowed in strings */
201609 pParse->iErr = j;
201610 return -1;
201611 }
201612 if( c=='\\' ){
201613 c = z[++j];
201614 if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f'
201615 || c=='n' || c=='r' || c=='t'
201616 || (c=='u' && jsonIs4Hex(&z[j+1])) ){
201617 jnFlags |= JNODE_ESCAPE;
@@ -201627,14 +202329,15 @@
201627 pParse->hasNonstd = 1;
201628 }else{
201629 pParse->iErr = j;
201630 return -1;
201631 }
201632 }else if( c==cDelim ){
201633 break;
 
 
201634 }
201635 j++;
201636 }
201637 jsonParseAddNode(pParse, JSON_STRING | (jnFlags<<8), j+1-i, &z[i]);
201638 return j+1;
201639 }
201640 case 't': {
@@ -201866,24 +202569,22 @@
201866 } /* End switch(z[i]) */
201867 }
201868
201869 /*
201870 ** Parse a complete JSON string. Return 0 on success or non-zero if there
201871 ** are any errors. If an error occurs, free all memory associated with
201872 ** pParse.
201873 **
201874 ** pParse is uninitialized when this routine is called.
 
201875 */
201876 static int jsonParse(
201877 JsonParse *pParse, /* Initialize and fill this JsonParse object */
201878 sqlite3_context *pCtx, /* Report errors here */
201879 const char *zJson /* Input JSON text to be parsed */
201880 ){
201881 int i;
201882 memset(pParse, 0, sizeof(*pParse));
201883 if( zJson==0 ) return 1;
201884 pParse->zJson = zJson;
201885 i = jsonParseValue(pParse, 0);
201886 if( pParse->oom ) i = -1;
201887 if( i>0 ){
201888 assert( pParse->iDepth==0 );
201889 while( fast_isspace(zJson[i]) ) i++;
@@ -201907,10 +202608,11 @@
201907 jsonParseReset(pParse);
201908 return 1;
201909 }
201910 return 0;
201911 }
 
201912
201913 /* Mark node i of pParse as being a child of iParent. Call recursively
201914 ** to fill in all the descendants of node i.
201915 */
201916 static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){
@@ -201957,51 +202659,77 @@
201957 */
201958 #define JSON_CACHE_ID (-429938) /* First cache entry */
201959 #define JSON_CACHE_SZ 4 /* Max number of cache entries */
201960
201961 /*
201962 ** Obtain a complete parse of the JSON found in the first argument
201963 ** of the argv array. Use the sqlite3_get_auxdata() cache for this
201964 ** parse if it is available. If the cache is not available or if it
201965 ** is no longer valid, parse the JSON again and return the new parse,
201966 ** and also register the new parse so that it will be available for
 
201967 ** future sqlite3_get_auxdata() calls.
201968 **
201969 ** If an error occurs and pErrCtx!=0 then report the error on pErrCtx
201970 ** and return NULL.
201971 **
201972 ** If an error occurs and pErrCtx==0 then return the Parse object with
201973 ** JsonParse.nErr non-zero. If the caller invokes this routine with
201974 ** pErrCtx==0 and it gets back a JsonParse with nErr!=0, then the caller
201975 ** is responsible for invoking jsonParseFree() on the returned value.
201976 ** But the caller may invoke jsonParseFree() *only* if pParse->nErr!=0.
 
 
 
 
 
 
 
 
 
 
201977 */
201978 static JsonParse *jsonParseCached(
201979 sqlite3_context *pCtx,
201980 sqlite3_value **argv,
201981 sqlite3_context *pErrCtx
 
201982 ){
201983 const char *zJson = (const char*)sqlite3_value_text(argv[0]);
201984 int nJson = sqlite3_value_bytes(argv[0]);
201985 JsonParse *p;
201986 JsonParse *pMatch = 0;
201987 int iKey;
201988 int iMinKey = 0;
201989 u32 iMinHold = 0xffffffff;
201990 u32 iMaxHold = 0;
 
 
201991 if( zJson==0 ) return 0;
201992 for(iKey=0; iKey<JSON_CACHE_SZ; iKey++){
201993 p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iKey);
201994 if( p==0 ){
201995 iMinKey = iKey;
201996 break;
201997 }
201998 if( pMatch==0
201999 && p->nJson==nJson
202000 && memcmp(p->zJson,zJson,nJson)==0
 
 
 
 
 
 
 
 
 
 
 
202001 ){
202002 p->nErr = 0;
 
202003 pMatch = p;
202004 }else if( p->iHold<iMinHold ){
202005 iMinHold = p->iHold;
202006 iMinKey = iKey;
202007 }
@@ -202008,32 +202736,48 @@
202008 if( p->iHold>iMaxHold ){
202009 iMaxHold = p->iHold;
202010 }
202011 }
202012 if( pMatch ){
 
 
202013 pMatch->nErr = 0;
202014 pMatch->iHold = iMaxHold+1;
 
202015 return pMatch;
202016 }
202017 p = sqlite3_malloc64( sizeof(*p) + nJson + 1 );
 
 
 
 
 
202018 if( p==0 ){
202019 sqlite3_result_error_nomem(pCtx);
202020 return 0;
202021 }
202022 memset(p, 0, sizeof(*p));
202023 p->zJson = (char*)&p[1];
202024 memcpy((char*)p->zJson, zJson, nJson+1);
202025 if( jsonParse(p, pErrCtx, p->zJson) ){
 
 
 
 
 
 
202026 if( pErrCtx==0 ){
202027 p->nErr = 1;
 
202028 return p;
202029 }
202030 sqlite3_free(p);
202031 return 0;
202032 }
202033 p->nJson = nJson;
202034 p->iHold = iMaxHold+1;
 
202035 sqlite3_set_auxdata(pCtx, JSON_CACHE_ID+iMinKey, p,
202036 (void(*)(void*))jsonParseFree);
202037 return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iMinKey);
202038 }
202039
@@ -202080,13 +202824,30 @@
202080 int *pApnd, /* Append nodes to complete path if not NULL */
202081 const char **pzErr /* Make *pzErr point to any syntax error in zPath */
202082 ){
202083 u32 i, j, nKey;
202084 const char *zKey;
202085 JsonNode *pRoot = &pParse->aNode[iRoot];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202086 if( zPath[0]==0 ) return pRoot;
202087 if( pRoot->jnFlags & JNODE_REPLACE ) return 0;
202088 if( zPath[0]=='.' ){
202089 if( pRoot->eType!=JSON_OBJECT ) return 0;
202090 zPath++;
202091 if( zPath[0]=='"' ){
202092 zKey = zPath + 1;
@@ -202116,27 +202877,29 @@
202116 }
202117 j++;
202118 j += jsonNodeSize(&pRoot[j]);
202119 }
202120 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
 
202121 assert( pRoot->eU==2 );
202122 iRoot += pRoot->u.iAppend;
202123 pRoot = &pParse->aNode[iRoot];
202124 j = 1;
202125 }
202126 if( pApnd ){
202127 u32 iStart, iLabel;
202128 JsonNode *pNode;
 
202129 iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
202130 iLabel = jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
202131 zPath += i;
202132 pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
202133 if( pParse->oom ) return 0;
202134 if( pNode ){
202135 pRoot = &pParse->aNode[iRoot];
202136 assert( pRoot->eU==0 );
202137 pRoot->u.iAppend = iStart - iRoot;
202138 pRoot->jnFlags |= JNODE_APPEND;
202139 VVA( pRoot->eU = 2 );
202140 pParse->aNode[iLabel].jnFlags |= JNODE_RAW;
202141 }
202142 return pNode;
@@ -202153,16 +202916,17 @@
202153 JsonNode *pBase = pRoot;
202154 int iBase = iRoot;
202155 if( pRoot->eType!=JSON_ARRAY ) return 0;
202156 for(;;){
202157 while( j<=pBase->n ){
202158 if( (pBase[j].jnFlags & JNODE_REMOVE)==0 ) i++;
202159 j += jsonNodeSize(&pBase[j]);
202160 }
202161 if( (pBase->jnFlags & JNODE_APPEND)==0 ) break;
 
202162 assert( pBase->eU==2 );
202163 iBase += pBase->u.iAppend;
202164 pBase = &pParse->aNode[iBase];
202165 j = 1;
202166 }
202167 j = 2;
202168 if( zPath[2]=='-' && sqlite3Isdigit(zPath[3]) ){
@@ -202186,33 +202950,37 @@
202186 }
202187 if( pRoot->eType!=JSON_ARRAY ) return 0;
202188 zPath += j + 1;
202189 j = 1;
202190 for(;;){
202191 while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){
202192 if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--;
 
 
202193 j += jsonNodeSize(&pRoot[j]);
202194 }
202195 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
 
202196 assert( pRoot->eU==2 );
202197 iRoot += pRoot->u.iAppend;
202198 pRoot = &pParse->aNode[iRoot];
202199 j = 1;
202200 }
202201 if( j<=pRoot->n ){
202202 return jsonLookupStep(pParse, iRoot+j, zPath, pApnd, pzErr);
202203 }
202204 if( i==0 && pApnd ){
202205 u32 iStart;
202206 JsonNode *pNode;
 
202207 iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
202208 pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
202209 if( pParse->oom ) return 0;
202210 if( pNode ){
202211 pRoot = &pParse->aNode[iRoot];
202212 assert( pRoot->eU==0 );
202213 pRoot->u.iAppend = iStart - iRoot;
202214 pRoot->jnFlags |= JNODE_APPEND;
202215 VVA( pRoot->eU = 2 );
202216 }
202217 return pNode;
202218 }
@@ -202334,52 +203102,95 @@
202334
202335
202336 /****************************************************************************
202337 ** SQL functions used for testing and debugging
202338 ****************************************************************************/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202339
202340 #ifdef SQLITE_DEBUG
202341 /*
202342 ** The json_parse(JSON) function returns a string which describes
202343 ** a parse of the JSON provided. Or it returns NULL if JSON is not
202344 ** well-formed.
 
 
202345 */
202346 static void jsonParseFunc(
202347 sqlite3_context *ctx,
202348 int argc,
202349 sqlite3_value **argv
202350 ){
202351 JsonString s; /* Output string - not real JSON */
202352 JsonParse x; /* The parse */
202353 u32 i;
202354
202355 assert( argc==1 );
202356 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
202357 jsonParseFindParents(&x);
202358 jsonInit(&s, ctx);
202359 for(i=0; i<x.nNode; i++){
202360 const char *zType;
202361 if( x.aNode[i].jnFlags & JNODE_LABEL ){
202362 assert( x.aNode[i].eType==JSON_STRING );
202363 zType = "label";
202364 }else{
202365 zType = jsonType[x.aNode[i].eType];
202366 }
202367 jsonPrintf(100, &s,"node %3u: %7s n=%-4d up=%-4d",
202368 i, zType, x.aNode[i].n, x.aUp[i]);
202369 assert( x.aNode[i].eU==0 || x.aNode[i].eU==1 );
202370 if( x.aNode[i].u.zJContent!=0 ){
202371 assert( x.aNode[i].eU==1 );
202372 jsonAppendRaw(&s, " ", 1);
202373 jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n);
202374 }else{
202375 assert( x.aNode[i].eU==0 );
202376 }
202377 jsonAppendRaw(&s, "\n", 1);
202378 }
202379 jsonParseReset(&x);
202380 jsonResult(&s);
202381 }
202382
202383 /*
202384 ** The json_test1(JSON) function return true (1) if the input is JSON
202385 ** text generated by another json function. It returns (0) if the input
@@ -202459,11 +203270,11 @@
202459 JsonParse *p; /* The parse */
202460 sqlite3_int64 n = 0;
202461 u32 i;
202462 JsonNode *pNode;
202463
202464 p = jsonParseCached(ctx, argv, ctx);
202465 if( p==0 ) return;
202466 assert( p->nNode );
202467 if( argc==2 ){
202468 const char *zPath = (const char*)sqlite3_value_text(argv[1]);
202469 pNode = jsonLookup(p, zPath, 0, ctx);
@@ -202472,13 +203283,18 @@
202472 }
202473 if( pNode==0 ){
202474 return;
202475 }
202476 if( pNode->eType==JSON_ARRAY ){
202477 assert( (pNode->jnFlags & JNODE_APPEND)==0 );
202478 for(i=1; i<=pNode->n; n++){
202479 i += jsonNodeSize(&pNode[i]);
 
 
 
 
 
202480 }
202481 }
202482 sqlite3_result_int64(ctx, n);
202483 }
202484
@@ -202521,11 +203337,11 @@
202521 const char *zPath;
202522 int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx));
202523 JsonString jx;
202524
202525 if( argc<2 ) return;
202526 p = jsonParseCached(ctx, argv, ctx);
202527 if( p==0 ) return;
202528 if( argc==2 ){
202529 /* With a single PATH argument */
202530 zPath = (const char*)sqlite3_value_text(argv[1]);
202531 if( zPath==0 ) return;
@@ -202539,15 +203355,15 @@
202539 ** LABEL ==> $.LABEL // PG compatible
202540 ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience
202541 */
202542 jsonInit(&jx, ctx);
202543 if( sqlite3Isdigit(zPath[0]) ){
202544 jsonAppendRaw(&jx, "$[", 2);
202545 jsonAppendRaw(&jx, zPath, (int)strlen(zPath));
202546 jsonAppendRaw(&jx, "]", 2);
202547 }else{
202548 jsonAppendRaw(&jx, "$.", 1 + (zPath[0]!='['));
202549 jsonAppendRaw(&jx, zPath, (int)strlen(zPath));
202550 jsonAppendChar(&jx, 0);
202551 }
202552 pNode = jx.bErr ? 0 : jsonLookup(p, jx.zBuf, 0, ctx);
202553 jsonReset(&jx);
@@ -202554,19 +203370,19 @@
202554 }else{
202555 pNode = jsonLookup(p, zPath, 0, ctx);
202556 }
202557 if( pNode ){
202558 if( flags & JSON_JSON ){
202559 jsonReturnJson(pNode, ctx, 0);
202560 }else{
202561 jsonReturn(pNode, ctx, 0);
202562 sqlite3_result_subtype(ctx, 0);
202563 }
202564 }
202565 }else{
202566 pNode = jsonLookup(p, zPath, 0, ctx);
202567 if( p->nErr==0 && pNode ) jsonReturn(pNode, ctx, 0);
202568 }
202569 }else{
202570 /* Two or more PATH arguments results in a JSON array with each
202571 ** element of the array being the value selected by one of the PATHs */
202572 int i;
@@ -202576,13 +203392,13 @@
202576 zPath = (const char*)sqlite3_value_text(argv[i]);
202577 pNode = jsonLookup(p, zPath, 0, ctx);
202578 if( p->nErr ) break;
202579 jsonAppendSeparator(&jx);
202580 if( pNode ){
202581 jsonRenderNode(pNode, &jx, 0);
202582 }else{
202583 jsonAppendRaw(&jx, "null", 4);
202584 }
202585 }
202586 if( i==argc ){
202587 jsonAppendChar(&jx, ']');
202588 jsonResult(&jx);
@@ -202623,49 +203439,42 @@
202623 zKey = pPatch[i].u.zJContent;
202624 for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){
202625 assert( pTarget[j].eType==JSON_STRING );
202626 assert( pTarget[j].jnFlags & JNODE_LABEL );
202627 if( jsonSameLabel(&pPatch[i], &pTarget[j]) ){
202628 if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH) ) break;
202629 if( pPatch[i+1].eType==JSON_NULL ){
202630 pTarget[j+1].jnFlags |= JNODE_REMOVE;
202631 }else{
202632 JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]);
202633 if( pNew==0 ) return 0;
 
 
 
 
202634 pTarget = &pParse->aNode[iTarget];
202635 if( pNew!=&pTarget[j+1] ){
202636 assert( pTarget[j+1].eU==0
202637 || pTarget[j+1].eU==1
202638 || pTarget[j+1].eU==2 );
202639 testcase( pTarget[j+1].eU==1 );
202640 testcase( pTarget[j+1].eU==2 );
202641 VVA( pTarget[j+1].eU = 5 );
202642 pTarget[j+1].u.pPatch = pNew;
202643 pTarget[j+1].jnFlags |= JNODE_PATCH;
202644 }
202645 }
202646 break;
202647 }
202648 }
202649 if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){
202650 int iStart, iPatch;
202651 iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
 
 
202652 jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
202653 iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
 
 
 
202654 if( pParse->oom ) return 0;
202655 jsonRemoveAllNulls(pPatch);
202656 pTarget = &pParse->aNode[iTarget];
202657 assert( pParse->aNode[iRoot].eU==0 || pParse->aNode[iRoot].eU==2 );
202658 testcase( pParse->aNode[iRoot].eU==2 );
202659 pParse->aNode[iRoot].jnFlags |= JNODE_APPEND;
 
202660 VVA( pParse->aNode[iRoot].eU = 2 );
202661 pParse->aNode[iRoot].u.iAppend = iStart - iRoot;
202662 iRoot = iStart;
202663 assert( pParse->aNode[iPatch].eU==0 );
202664 VVA( pParse->aNode[iPatch].eU = 5 );
202665 pParse->aNode[iPatch].jnFlags |= JNODE_PATCH;
202666 pParse->aNode[iPatch].u.pPatch = &pPatch[i+1];
202667 }
202668 }
202669 return pTarget;
202670 }
202671
@@ -202677,29 +203486,32 @@
202677 static void jsonPatchFunc(
202678 sqlite3_context *ctx,
202679 int argc,
202680 sqlite3_value **argv
202681 ){
202682 JsonParse x; /* The JSON that is being patched */
202683 JsonParse y; /* The patch */
202684 JsonNode *pResult; /* The result of the merge */
202685
202686 UNUSED_PARAMETER(argc);
202687 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
202688 if( jsonParse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){
202689 jsonParseReset(&x);
202690 return;
202691 }
202692 pResult = jsonMergePatch(&x, 0, y.aNode);
202693 assert( pResult!=0 || x.oom );
202694 if( pResult ){
202695 jsonReturnJson(pResult, ctx, 0);
 
 
 
 
 
202696 }else{
202697 sqlite3_result_error_nomem(ctx);
202698 }
202699 jsonParseReset(&x);
202700 jsonParseReset(&y);
202701 }
202702
202703
202704 /*
202705 ** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON
@@ -202751,30 +203563,122 @@
202751 static void jsonRemoveFunc(
202752 sqlite3_context *ctx,
202753 int argc,
202754 sqlite3_value **argv
202755 ){
202756 JsonParse x; /* The parse */
202757 JsonNode *pNode;
202758 const char *zPath;
202759 u32 i;
202760
202761 if( argc<1 ) return;
202762 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
202763 assert( x.nNode );
202764 for(i=1; i<(u32)argc; i++){
202765 zPath = (const char*)sqlite3_value_text(argv[i]);
202766 if( zPath==0 ) goto remove_done;
202767 pNode = jsonLookup(&x, zPath, 0, ctx);
202768 if( x.nErr ) goto remove_done;
202769 if( pNode ) pNode->jnFlags |= JNODE_REMOVE;
 
 
 
 
202770 }
202771 if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){
202772 jsonReturnJson(x.aNode, ctx, 0);
202773 }
202774 remove_done:
202775 jsonParseReset(&x);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202776 }
202777
202778 /*
202779 ** json_replace(JSON, PATH, VALUE, ...)
202780 **
@@ -202784,42 +203688,34 @@
202784 static void jsonReplaceFunc(
202785 sqlite3_context *ctx,
202786 int argc,
202787 sqlite3_value **argv
202788 ){
202789 JsonParse x; /* The parse */
202790 JsonNode *pNode;
202791 const char *zPath;
202792 u32 i;
202793
202794 if( argc<1 ) return;
202795 if( (argc&1)==0 ) {
202796 jsonWrongNumArgs(ctx, "replace");
202797 return;
202798 }
202799 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
202800 assert( x.nNode );
202801 for(i=1; i<(u32)argc; i+=2){
202802 zPath = (const char*)sqlite3_value_text(argv[i]);
202803 pNode = jsonLookup(&x, zPath, 0, ctx);
202804 if( x.nErr ) goto replace_err;
 
202805 if( pNode ){
202806 assert( pNode->eU==0 || pNode->eU==1 || pNode->eU==4 );
202807 testcase( pNode->eU!=0 && pNode->eU!=1 );
202808 pNode->jnFlags |= (u8)JNODE_REPLACE;
202809 VVA( pNode->eU = 4 );
202810 pNode->u.iReplace = i + 1;
202811 }
202812 }
202813 if( x.aNode[0].jnFlags & JNODE_REPLACE ){
202814 assert( x.aNode[0].eU==4 );
202815 sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
202816 }else{
202817 jsonReturnJson(x.aNode, ctx, argv);
202818 }
202819 replace_err:
202820 jsonParseReset(&x);
202821 }
202822
202823
202824 /*
202825 ** json_set(JSON, PATH, VALUE, ...)
@@ -202836,11 +203732,11 @@
202836 static void jsonSetFunc(
202837 sqlite3_context *ctx,
202838 int argc,
202839 sqlite3_value **argv
202840 ){
202841 JsonParse x; /* The parse */
202842 JsonNode *pNode;
202843 const char *zPath;
202844 u32 i;
202845 int bApnd;
202846 int bIsSet = sqlite3_user_data(ctx)!=0;
@@ -202848,37 +203744,31 @@
202848 if( argc<1 ) return;
202849 if( (argc&1)==0 ) {
202850 jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert");
202851 return;
202852 }
202853 if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
202854 assert( x.nNode );
202855 for(i=1; i<(u32)argc; i+=2){
202856 zPath = (const char*)sqlite3_value_text(argv[i]);
202857 bApnd = 0;
202858 pNode = jsonLookup(&x, zPath, &bApnd, ctx);
202859 if( x.oom ){
 
202860 sqlite3_result_error_nomem(ctx);
202861 goto jsonSetDone;
202862 }else if( x.nErr ){
202863 goto jsonSetDone;
202864 }else if( pNode && (bApnd || bIsSet) ){
202865 testcase( pNode->eU!=0 && pNode->eU!=1 );
202866 assert( pNode->eU!=3 && pNode->eU!=5 );
202867 VVA( pNode->eU = 4 );
202868 pNode->jnFlags |= (u8)JNODE_REPLACE;
202869 pNode->u.iReplace = i + 1;
202870 }
202871 }
202872 if( x.aNode[0].jnFlags & JNODE_REPLACE ){
202873 assert( x.aNode[0].eU==4 );
202874 sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
202875 }else{
202876 jsonReturnJson(x.aNode, ctx, argv);
202877 }
202878 jsonSetDone:
202879 jsonParseReset(&x);
202880 }
202881
202882 /*
202883 ** json_type(JSON)
202884 ** json_type(JSON, PATH)
@@ -202893,11 +203783,11 @@
202893 ){
202894 JsonParse *p; /* The parse */
202895 const char *zPath;
202896 JsonNode *pNode;
202897
202898 p = jsonParseCached(ctx, argv, ctx);
202899 if( p==0 ) return;
202900 if( argc==2 ){
202901 zPath = (const char*)sqlite3_value_text(argv[1]);
202902 pNode = jsonLookup(p, zPath, 0, ctx);
202903 }else{
@@ -202920,16 +203810,16 @@
202920 sqlite3_value **argv
202921 ){
202922 JsonParse *p; /* The parse */
202923 UNUSED_PARAMETER(argc);
202924 if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
202925 p = jsonParseCached(ctx, argv, 0);
202926 if( p==0 || p->oom ){
202927 sqlite3_result_error_nomem(ctx);
202928 sqlite3_free(p);
202929 }else{
202930 sqlite3_result_int(ctx, p->nErr==0 && p->hasNonstd==0);
202931 if( p->nErr ) jsonParseFree(p);
202932 }
202933 }
202934
202935 /*
@@ -202966,20 +203856,20 @@
202966 sqlite3_value **argv
202967 ){
202968 JsonParse *p; /* The parse */
202969 UNUSED_PARAMETER(argc);
202970 if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
202971 p = jsonParseCached(ctx, argv, 0);
202972 if( p==0 || p->oom ){
202973 sqlite3_result_error_nomem(ctx);
202974 sqlite3_free(p);
202975 }else if( p->nErr==0 ){
202976 sqlite3_result_int(ctx, 0);
202977 }else{
202978 int n = 1;
202979 u32 i;
202980 const char *z = p->zJson;
202981 for(i=0; i<p->iErr && ALWAYS(z[i]); i++){
202982 if( (z[i]&0xc0)!=0x80 ) n++;
202983 }
202984 sqlite3_result_int(ctx, n);
202985 jsonParseFree(p);
@@ -203023,11 +203913,12 @@
203023 if( pStr->bErr ){
203024 if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
203025 assert( pStr->bStatic );
203026 }else if( isFinal ){
203027 sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed,
203028 pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
 
203029 pStr->bStatic = 1;
203030 }else{
203031 sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT);
203032 pStr->nUsed--;
203033 }
@@ -203131,11 +204022,12 @@
203131 if( pStr->bErr ){
203132 if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
203133 assert( pStr->bStatic );
203134 }else if( isFinal ){
203135 sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed,
203136 pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
 
203137 pStr->bStatic = 1;
203138 }else{
203139 sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT);
203140 pStr->nUsed--;
203141 }
@@ -203242,11 +204134,10 @@
203242 }
203243
203244 /* Reset a JsonEachCursor back to its original state. Free any memory
203245 ** held. */
203246 static void jsonEachCursorReset(JsonEachCursor *p){
203247 sqlite3_free(p->zJson);
203248 sqlite3_free(p->zRoot);
203249 jsonParseReset(&p->sParse);
203250 p->iRowid = 0;
203251 p->i = 0;
203252 p->iEnd = 0;
@@ -203380,11 +204271,11 @@
203380 JsonNode *pThis = &p->sParse.aNode[p->i];
203381 switch( i ){
203382 case JEACH_KEY: {
203383 if( p->i==0 ) break;
203384 if( p->eType==JSON_OBJECT ){
203385 jsonReturn(pThis, ctx, 0);
203386 }else if( p->eType==JSON_ARRAY ){
203387 u32 iKey;
203388 if( p->bRecursive ){
203389 if( p->iRowid==0 ) break;
203390 assert( p->sParse.aNode[p->sParse.aUp[p->i]].eU==3 );
@@ -203396,11 +204287,11 @@
203396 }
203397 break;
203398 }
203399 case JEACH_VALUE: {
203400 if( pThis->jnFlags & JNODE_LABEL ) pThis++;
203401 jsonReturn(pThis, ctx, 0);
203402 break;
203403 }
203404 case JEACH_TYPE: {
203405 if( pThis->jnFlags & JNODE_LABEL ) pThis++;
203406 sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC);
@@ -203407,11 +204298,11 @@
203407 break;
203408 }
203409 case JEACH_ATOM: {
203410 if( pThis->jnFlags & JNODE_LABEL ) pThis++;
203411 if( pThis->eType>=JSON_ARRAY ) break;
203412 jsonReturn(pThis, ctx, 0);
203413 break;
203414 }
203415 case JEACH_ID: {
203416 sqlite3_result_int64(ctx,
203417 (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0));
@@ -203562,15 +204453,23 @@
203562 UNUSED_PARAMETER(argc);
203563 jsonEachCursorReset(p);
203564 if( idxNum==0 ) return SQLITE_OK;
203565 z = (const char*)sqlite3_value_text(argv[0]);
203566 if( z==0 ) return SQLITE_OK;
203567 n = sqlite3_value_bytes(argv[0]);
203568 p->zJson = sqlite3_malloc64( n+1 );
203569 if( p->zJson==0 ) return SQLITE_NOMEM;
203570 memcpy(p->zJson, z, (size_t)n+1);
203571 if( jsonParse(&p->sParse, 0, p->zJson) ){
 
 
 
 
 
 
 
 
203572 int rc = SQLITE_NOMEM;
203573 if( p->sParse.oom==0 ){
203574 sqlite3_free(cur->pVtab->zErrMsg);
203575 cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON");
203576 if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR;
@@ -219306,10 +220205,11 @@
219306 }else{
219307 /* assert( db->pPreUpdate->pUnpacked ); */
219308 rc = pSession->hook.xOld(pSession->hook.pCtx, iCol, &pVal);
219309 }
219310 assert( rc==SQLITE_OK );
 
219311 if( sqlite3_value_type(pVal)!=eType ) return 0;
219312
219313 /* A SessionChange object never has a NULL value in a PK column */
219314 assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT
219315 || eType==SQLITE_BLOB || eType==SQLITE_TEXT
@@ -225188,10 +226088,14 @@
225188 ** nAutomerge:
225189 ** The minimum number of segments that an auto-merge operation should
225190 ** attempt to merge together. A value of 1 sets the object to use the
225191 ** compile time default. Zero disables auto-merge altogether.
225192 **
 
 
 
 
225193 ** zContent:
225194 **
225195 ** zContentRowid:
225196 ** The value of the content_rowid= option, if one was specified. Or
225197 ** the string "rowid" otherwise. This text is not quoted - if it is
@@ -225222,10 +226126,11 @@
225222 char **azCol; /* Column names */
225223 u8 *abUnindexed; /* True for unindexed columns */
225224 int nPrefix; /* Number of prefix indexes */
225225 int *aPrefix; /* Sizes in bytes of nPrefix prefix indexes */
225226 int eContent; /* An FTS5_CONTENT value */
 
225227 char *zContent; /* content table */
225228 char *zContentRowid; /* "content_rowid=" option value */
225229 int bColumnsize; /* "columnsize=" option value (dflt==1) */
225230 int eDetail; /* FTS5_DETAIL_XXX value */
225231 char *zContentExprlist;
@@ -225243,10 +226148,11 @@
225243 int nUsermerge; /* 'usermerge' setting */
225244 int nHashSize; /* Bytes of memory for in-memory hash */
225245 char *zRank; /* Name of rank function */
225246 char *zRankArgs; /* Arguments to rank function */
225247 int bSecureDelete; /* 'secure-delete' */
 
225248
225249 /* If non-NULL, points to sqlite3_vtab.base.zErrmsg. Often NULL. */
225250 char **pzErrmsg;
225251
225252 #ifdef SQLITE_DEBUG
@@ -225565,10 +226471,13 @@
225565 static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge);
225566 static int sqlite3Fts5IndexReset(Fts5Index *p);
225567
225568 static int sqlite3Fts5IndexLoadConfig(Fts5Index *p);
225569
 
 
 
225570 /*
225571 ** End of interface to code in fts5_index.c.
225572 **************************************************************************/
225573
225574 /**************************************************************************
@@ -225649,10 +226558,15 @@
225649 /*
225650 ** Empty (but do not delete) a hash table.
225651 */
225652 static void sqlite3Fts5HashClear(Fts5Hash*);
225653
 
 
 
 
 
225654 static int sqlite3Fts5HashQuery(
225655 Fts5Hash*, /* Hash table to query */
225656 int nPre,
225657 const char *pTerm, int nTerm, /* Query term */
225658 void **ppObj, /* OUT: Pointer to doclist for pTerm */
@@ -225668,10 +226582,11 @@
225668 static void sqlite3Fts5HashScanEntry(Fts5Hash *,
225669 const char **pzTerm, /* OUT: term (nul-terminated) */
225670 const u8 **ppDoclist, /* OUT: pointer to doclist */
225671 int *pnDoclist /* OUT: size of doclist in bytes */
225672 );
 
225673
225674
225675 /*
225676 ** End of interface to code in fts5_hash.c.
225677 **************************************************************************/
@@ -228542,10 +229457,12 @@
228542 #define FTS5_DEFAULT_AUTOMERGE 4
228543 #define FTS5_DEFAULT_USERMERGE 4
228544 #define FTS5_DEFAULT_CRISISMERGE 16
228545 #define FTS5_DEFAULT_HASHSIZE (1024*1024)
228546
 
 
228547 /* Maximum allowed page size */
228548 #define FTS5_MAX_PAGE_SIZE (64*1024)
228549
228550 static int fts5_iswhitespace(char x){
228551 return (x==' ');
@@ -228871,10 +229788,20 @@
228871 pConfig->eContent = FTS5_CONTENT_NONE;
228872 }
228873 }
228874 return rc;
228875 }
 
 
 
 
 
 
 
 
 
 
228876
228877 if( sqlite3_strnicmp("content_rowid", zCmd, nCmd)==0 ){
228878 if( pConfig->zContentRowid ){
228879 *pzErr = sqlite3_mprintf("multiple content_rowid=... directives");
228880 rc = SQLITE_ERROR;
@@ -229115,10 +230042,32 @@
229115 }
229116
229117 sqlite3_free(zOne);
229118 sqlite3_free(zTwo);
229119 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229120
229121 /* If a tokenizer= option was successfully parsed, the tokenizer has
229122 ** already been allocated. Otherwise, allocate an instance of the default
229123 ** tokenizer (unicode61) now. */
229124 if( rc==SQLITE_OK && pRet->pTok==0 ){
@@ -229409,10 +230358,22 @@
229409 if( nCrisisMerge<=1 ) nCrisisMerge = FTS5_DEFAULT_CRISISMERGE;
229410 if( nCrisisMerge>=FTS5_MAX_SEGMENT ) nCrisisMerge = FTS5_MAX_SEGMENT-1;
229411 pConfig->nCrisisMerge = nCrisisMerge;
229412 }
229413 }
 
 
 
 
 
 
 
 
 
 
 
 
229414
229415 else if( 0==sqlite3_stricmp(zKey, "rank") ){
229416 const char *zIn = (const char*)sqlite3_value_text(pVal);
229417 char *zRank;
229418 char *zRankArgs;
@@ -229458,10 +230419,11 @@
229458 pConfig->pgsz = FTS5_DEFAULT_PAGE_SIZE;
229459 pConfig->nAutomerge = FTS5_DEFAULT_AUTOMERGE;
229460 pConfig->nUsermerge = FTS5_DEFAULT_USERMERGE;
229461 pConfig->nCrisisMerge = FTS5_DEFAULT_CRISISMERGE;
229462 pConfig->nHashSize = FTS5_DEFAULT_HASHSIZE;
 
229463
229464 zSql = sqlite3Fts5Mprintf(&rc, zSelect, pConfig->zDb, pConfig->zName);
229465 if( zSql ){
229466 rc = sqlite3_prepare_v2(pConfig->db, zSql, -1, &p, 0);
229467 sqlite3_free(zSql);
@@ -231981,11 +232943,11 @@
231981 }
231982
231983 return pRet;
231984 }
231985
231986 #ifdef SQLITE_TEST
231987 static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){
231988 sqlite3_int64 nByte = 0;
231989 Fts5ExprTerm *p;
231990 char *zQuoted;
231991
@@ -232348,18 +233310,18 @@
232348 iCode = sqlite3_value_int(apVal[0]);
232349 if( nArg==2 ) bRemoveDiacritics = sqlite3_value_int(apVal[1]);
232350 sqlite3_result_int(pCtx, sqlite3Fts5UnicodeFold(iCode, bRemoveDiacritics));
232351 }
232352 }
232353 #endif /* ifdef SQLITE_TEST */
232354
232355 /*
232356 ** This is called during initialization to register the fts5_expr() scalar
232357 ** UDF with the SQLite handle passed as the only argument.
232358 */
232359 static int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){
232360 #ifdef SQLITE_TEST
232361 struct Fts5ExprFunc {
232362 const char *z;
232363 void (*x)(sqlite3_context*,int,sqlite3_value**);
232364 } aFunc[] = {
232365 { "fts5_expr", fts5ExprFunctionHr },
@@ -233115,11 +234077,10 @@
233115 pList = 0;
233116 for(i=0; i<nMergeSlot; i++){
233117 pList = fts5HashEntryMerge(pList, ap[i]);
233118 }
233119
233120 pHash->nEntry = 0;
233121 sqlite3_free(ap);
233122 *ppSorted = pList;
233123 return SQLITE_OK;
233124 }
233125
@@ -233168,10 +234129,32 @@
233168 Fts5Hash *p, /* Hash table to query */
233169 const char *pTerm, int nTerm /* Query prefix */
233170 ){
233171 return fts5HashEntrySort(p, pTerm, nTerm, &p->pScan);
233172 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233173
233174 static void sqlite3Fts5HashScanNext(Fts5Hash *p){
233175 assert( !sqlite3Fts5HashScanEof(p) );
233176 p->pScan = p->pScan->pScanNext;
233177 }
@@ -233257,32 +234240,50 @@
233257 # error "FTS5_MAX_PREFIX_INDEXES is too large"
233258 #endif
233259
233260 #define FTS5_MAX_LEVEL 64
233261
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233262 /*
233263 ** Details:
233264 **
233265 ** The %_data table managed by this module,
233266 **
233267 ** CREATE TABLE %_data(id INTEGER PRIMARY KEY, block BLOB);
233268 **
233269 ** , contains the following 5 types of records. See the comments surrounding
233270 ** the FTS5_*_ROWID macros below for a description of how %_data rowids are
233271 ** assigned to each fo them.
233272 **
233273 ** 1. Structure Records:
233274 **
233275 ** The set of segments that make up an index - the index structure - are
233276 ** recorded in a single record within the %_data table. The record consists
233277 ** of a single 32-bit configuration cookie value followed by a list of
233278 ** SQLite varints. If the FTS table features more than one index (because
233279 ** there are one or more prefix indexes), it is guaranteed that all share
233280 ** the same cookie value.
233281 **
233282 ** Immediately following the configuration cookie, the record begins with
233283 ** three varints:
 
 
233284 **
233285 ** + number of levels,
233286 ** + total number of segments on all levels,
233287 ** + value of write counter.
233288 **
@@ -233293,10 +234294,16 @@
233293 ** + for each segment from oldest to newest:
233294 ** + segment id (always > 0)
233295 ** + first leaf page number (often 1, always greater than 0)
233296 ** + final leaf page number
233297 **
 
 
 
 
 
 
233298 ** 2. The Averages Record:
233299 **
233300 ** A single record within the %_data table. The data is a list of varints.
233301 ** The first value is the number of rows in the index. Then, for each column
233302 ** from left to right, the total number of tokens in the column for all
@@ -233408,10 +234415,42 @@
233408 ** * Copy of first rowid on page indicated by previous field. As a varint.
233409 **
233410 ** * A list of delta-encoded varints - the first rowid on each subsequent
233411 ** child page.
233412 **
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233413 */
233414
233415 /*
233416 ** Rowids for the averages and structure records in the %_data table.
233417 */
@@ -233441,10 +234480,11 @@
233441 ((i64)(pgno)) \
233442 )
233443
233444 #define FTS5_SEGMENT_ROWID(segid, pgno) fts5_dri(segid, 0, 0, pgno)
233445 #define FTS5_DLIDX_ROWID(segid, height, pgno) fts5_dri(segid, 1, height, pgno)
 
233446
233447 #ifdef SQLITE_DEBUG
233448 static int sqlite3Fts5Corrupt() { return SQLITE_CORRUPT_VTAB; }
233449 #endif
233450
@@ -233476,10 +234516,16 @@
233476 int szLeaf; /* Size of leaf without page-index */
233477 };
233478
233479 /*
233480 ** One object per %_data table.
 
 
 
 
 
 
233481 */
233482 struct Fts5Index {
233483 Fts5Config *pConfig; /* Virtual table configuration */
233484 char *zDataTbl; /* Name of %_data table */
233485 int nWorkUnit; /* Leaf pages in a "unit" of work */
@@ -233490,10 +234536,12 @@
233490 */
233491 Fts5Hash *pHash; /* Hash table for in-memory data */
233492 int nPendingData; /* Current bytes of pending data */
233493 i64 iWriteRowid; /* Rowid for current doc being written */
233494 int bDelete; /* Current write is a delete */
 
 
233495
233496 /* Error state. */
233497 int rc; /* Current error code */
233498
233499 /* State used by the fts5DataXXX() functions. */
@@ -233524,24 +234572,37 @@
233524
233525 /*
233526 ** The contents of the "structure" record for each index are represented
233527 ** using an Fts5Structure record in memory. Which uses instances of the
233528 ** other Fts5StructureXXX types as components.
 
 
 
 
 
233529 */
233530 struct Fts5StructureSegment {
233531 int iSegid; /* Segment id */
233532 int pgnoFirst; /* First leaf page number in segment */
233533 int pgnoLast; /* Last leaf page number in segment */
 
 
 
 
 
 
 
233534 };
233535 struct Fts5StructureLevel {
233536 int nMerge; /* Number of segments in incr-merge */
233537 int nSeg; /* Total number of segments on level */
233538 Fts5StructureSegment *aSeg; /* Array of segments. aSeg[0] is oldest. */
233539 };
233540 struct Fts5Structure {
233541 int nRef; /* Object reference count */
233542 u64 nWriteCounter; /* Total leaves written to level 0 */
 
233543 int nSegment; /* Total segments in this structure */
233544 int nLevel; /* Number of levels in this index */
233545 Fts5StructureLevel aLevel[1]; /* Array of nLevel level objects */
233546 };
233547
@@ -233626,18 +234687,27 @@
233626 ** corresponding aRowidOffset[] entry is set to the byte offset of the
233627 ** start of the "position-list-size" field within the page.
233628 **
233629 ** iTermIdx:
233630 ** Index of current term on iTermLeafPgno.
 
 
 
 
 
 
 
233631 */
233632 struct Fts5SegIter {
233633 Fts5StructureSegment *pSeg; /* Segment to iterate through */
233634 int flags; /* Mask of configuration flags */
233635 int iLeafPgno; /* Current leaf page number */
233636 Fts5Data *pLeaf; /* Current leaf data */
233637 Fts5Data *pNextLeaf; /* Leaf page (iLeafPgno+1) */
233638 i64 iLeafOffset; /* Byte offset within current leaf */
 
 
233639
233640 /* Next method */
233641 void (*xNext)(Fts5Index*, Fts5SegIter*, int*);
233642
233643 /* The page and offset from which the current term was read. The offset
@@ -233762,10 +234832,64 @@
233762 }
233763
233764 static u16 fts5GetU16(const u8 *aIn){
233765 return ((u16)aIn[0] << 8) + aIn[1];
233766 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233767
233768 /*
233769 ** Allocate and return a buffer at least nByte bytes in size.
233770 **
233771 ** If an OOM error is encountered, return NULL and set the error code in
@@ -233990,14 +235114,21 @@
233990 }
233991
233992 /*
233993 ** Remove all records associated with segment iSegid.
233994 */
233995 static void fts5DataRemoveSegment(Fts5Index *p, int iSegid){
 
233996 i64 iFirst = FTS5_SEGMENT_ROWID(iSegid, 0);
233997 i64 iLast = FTS5_SEGMENT_ROWID(iSegid+1, 0)-1;
233998 fts5DataDelete(p, iFirst, iLast);
 
 
 
 
 
 
233999 if( p->pIdxDeleter==0 ){
234000 Fts5Config *pConfig = p->pConfig;
234001 fts5IndexPrepareStmt(p, &p->pIdxDeleter, sqlite3_mprintf(
234002 "DELETE FROM '%q'.'%q_idx' WHERE segid=?",
234003 pConfig->zDb, pConfig->zName
@@ -234104,14 +235235,22 @@
234104 int iLvl;
234105 int nLevel = 0;
234106 int nSegment = 0;
234107 sqlite3_int64 nByte; /* Bytes of space to allocate at pRet */
234108 Fts5Structure *pRet = 0; /* Structure object to return */
 
 
234109
234110 /* Grab the cookie value */
234111 if( piCookie ) *piCookie = sqlite3Fts5Get32(pData);
234112 i = 4;
 
 
 
 
 
 
234113
234114 /* Read the total number of levels and segments from the start of the
234115 ** structure record. */
234116 i += fts5GetVarint32(&pData[i], nLevel);
234117 i += fts5GetVarint32(&pData[i], nSegment);
@@ -234159,10 +235298,18 @@
234159 }
234160 assert( pSeg!=0 );
234161 i += fts5GetVarint32(&pData[i], pSeg->iSegid);
234162 i += fts5GetVarint32(&pData[i], pSeg->pgnoFirst);
234163 i += fts5GetVarint32(&pData[i], pSeg->pgnoLast);
 
 
 
 
 
 
 
 
234164 if( pSeg->pgnoLast<pSeg->pgnoFirst ){
234165 rc = FTS5_CORRUPT;
234166 break;
234167 }
234168 }
@@ -234169,10 +235316,13 @@
234169 if( iLvl>0 && pLvl[-1].nMerge && nTotal==0 ) rc = FTS5_CORRUPT;
234170 if( iLvl==nLevel-1 && pLvl->nMerge ) rc = FTS5_CORRUPT;
234171 }
234172 }
234173 if( nSegment!=0 && rc==SQLITE_OK ) rc = FTS5_CORRUPT;
 
 
 
234174
234175 if( rc!=SQLITE_OK ){
234176 fts5StructureRelease(pRet);
234177 pRet = 0;
234178 }
@@ -234381,21 +235531,25 @@
234381 static void fts5StructureWrite(Fts5Index *p, Fts5Structure *pStruct){
234382 if( p->rc==SQLITE_OK ){
234383 Fts5Buffer buf; /* Buffer to serialize record into */
234384 int iLvl; /* Used to iterate through levels */
234385 int iCookie; /* Cookie value to store */
 
234386
234387 assert( pStruct->nSegment==fts5StructureCountSegments(pStruct) );
234388 memset(&buf, 0, sizeof(Fts5Buffer));
234389
234390 /* Append the current configuration cookie */
234391 iCookie = p->pConfig->iCookie;
234392 if( iCookie<0 ) iCookie = 0;
234393
234394 if( 0==sqlite3Fts5BufferSize(&p->rc, &buf, 4+9+9+9) ){
234395 sqlite3Fts5Put32(buf.p, iCookie);
234396 buf.n = 4;
 
 
 
234397 fts5BufferSafeAppendVarint(&buf, pStruct->nLevel);
234398 fts5BufferSafeAppendVarint(&buf, pStruct->nSegment);
234399 fts5BufferSafeAppendVarint(&buf, (i64)pStruct->nWriteCounter);
234400 }
234401
@@ -234405,13 +235559,21 @@
234405 fts5BufferAppendVarint(&p->rc, &buf, pLvl->nMerge);
234406 fts5BufferAppendVarint(&p->rc, &buf, pLvl->nSeg);
234407 assert( pLvl->nMerge<=pLvl->nSeg );
234408
234409 for(iSeg=0; iSeg<pLvl->nSeg; iSeg++){
234410 fts5BufferAppendVarint(&p->rc, &buf, pLvl->aSeg[iSeg].iSegid);
234411 fts5BufferAppendVarint(&p->rc, &buf, pLvl->aSeg[iSeg].pgnoFirst);
234412 fts5BufferAppendVarint(&p->rc, &buf, pLvl->aSeg[iSeg].pgnoLast);
 
 
 
 
 
 
 
 
234413 }
234414 }
234415
234416 fts5DataWrite(p, FTS5_STRUCTURE_ROWID, buf.p, buf.n);
234417 fts5BufferFree(&buf);
@@ -234929,10 +236091,27 @@
234929 pIter->xNext = fts5SegIterNext_None;
234930 }else{
234931 pIter->xNext = fts5SegIterNext;
234932 }
234933 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
234934
234935 /*
234936 ** Initialize the iterator object pIter to iterate through the entries in
234937 ** segment pSeg. The iterator is left pointing to the first entry when
234938 ** this function returns.
@@ -234971,10 +236150,11 @@
234971 assert_nc( pIter->pLeaf->nn>4 );
234972 assert_nc( fts5LeafFirstTermOff(pIter->pLeaf)==4 );
234973 pIter->iPgidxOff = pIter->pLeaf->szLeaf+1;
234974 fts5SegIterLoadTerm(p, pIter, 0);
234975 fts5SegIterLoadNPos(p, pIter);
 
234976 }
234977 }
234978
234979 /*
234980 ** This function is only ever called on iterators created by calls to
@@ -235672,10 +236852,11 @@
235672 }
235673 }
235674 }
235675
235676 fts5SegIterSetNext(p, pIter);
 
235677
235678 /* Either:
235679 **
235680 ** 1) an error has occurred, or
235681 ** 2) the iterator points to EOF, or
@@ -235751,18 +236932,33 @@
235751 }
235752 }
235753
235754 fts5SegIterSetNext(p, pIter);
235755 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235756
235757 /*
235758 ** Zero the iterator passed as the only argument.
235759 */
235760 static void fts5SegIterClear(Fts5SegIter *pIter){
235761 fts5BufferFree(&pIter->term);
235762 fts5DataRelease(pIter->pLeaf);
235763 fts5DataRelease(pIter->pNextLeaf);
 
235764 fts5DlidxIterFree(pIter->pDlidx);
235765 sqlite3_free(pIter->aRowidOffset);
235766 memset(pIter, 0, sizeof(Fts5SegIter));
235767 }
235768
@@ -236095,10 +237291,88 @@
236095 static void fts5MultiIterSetEof(Fts5Iter *pIter){
236096 Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
236097 pIter->base.bEof = pSeg->pLeaf==0;
236098 pIter->iSwitchRowid = pSeg->iRowid;
236099 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236100
236101 /*
236102 ** Move the iterator to the next entry.
236103 **
236104 ** If an error occurs, an error code is left in Fts5Index.rc. It is not
@@ -236133,11 +237407,13 @@
236133 if( pSeg->pLeaf==0 ) return;
236134 }
236135
236136 fts5AssertMultiIterSetup(p, pIter);
236137 assert( pSeg==&pIter->aSeg[pIter->aFirst[1].iFirst] && pSeg->pLeaf );
236138 if( pIter->bSkipEmpty==0 || pSeg->nPos ){
 
 
236139 pIter->xSetOutputs(pIter, pSeg);
236140 return;
236141 }
236142 bUseFrom = 0;
236143 }
@@ -236165,11 +237441,13 @@
236165 fts5MultiIterSetEof(pIter);
236166 *pbNewTerm = 1;
236167 }
236168 fts5AssertMultiIterSetup(p, pIter);
236169
236170 }while( fts5MultiIterIsEmpty(p, pIter) );
 
 
236171 }
236172 }
236173
236174 static void fts5IterSetOutputs_Noop(Fts5Iter *pUnused1, Fts5SegIter *pUnused2){
236175 UNUSED_PARAM2(pUnused1, pUnused2);
@@ -236720,11 +237998,13 @@
236720 }
236721 }
236722 fts5MultiIterSetEof(pNew);
236723 fts5AssertMultiIterSetup(p, pNew);
236724
236725 if( pNew->bSkipEmpty && fts5MultiIterIsEmpty(p, pNew) ){
 
 
236726 fts5MultiIterNext(p, pNew, 0, 0);
236727 }else if( pNew->base.bEof==0 ){
236728 Fts5SegIter *pSeg = &pNew->aSeg[pNew->aFirst[1].iFirst];
236729 pNew->xSetOutputs(pNew, pSeg);
236730 }
@@ -236898,11 +238178,13 @@
236898 static void fts5IndexDiscardData(Fts5Index *p){
236899 assert( p->pHash || p->nPendingData==0 );
236900 if( p->pHash ){
236901 sqlite3Fts5HashClear(p->pHash);
236902 p->nPendingData = 0;
 
236903 }
 
236904 }
236905
236906 /*
236907 ** Return the size of the prefix, in bytes, that buffer
236908 ** (pNew/<length-unknown>) shares with buffer (pOld/nOld).
@@ -237535,10 +238817,16 @@
237535 pSeg->iSegid = iSegid;
237536 pStruct->nSegment++;
237537
237538 /* Read input from all segments in the input level */
237539 nInput = pLvl->nSeg;
 
 
 
 
 
 
237540 }
237541 bOldest = (pLvlOut->nSeg==1 && pStruct->nLevel==iLvl+2);
237542
237543 assert( iLvl>=0 );
237544 for(fts5MultiIterNew(p, pStruct, flags, 0, 0, 0, iLvl, nInput, &pIter);
@@ -237594,12 +238882,15 @@
237594 assert( pIter!=0 || p->rc!=SQLITE_OK );
237595 if( fts5MultiIterEof(p, pIter) ){
237596 int i;
237597
237598 /* Remove the redundant segments from the %_data table */
 
237599 for(i=0; i<nInput; i++){
237600 fts5DataRemoveSegment(p, pLvl->aSeg[i].iSegid);
 
 
237601 }
237602
237603 /* Remove the redundant segments from the input level */
237604 if( pLvl->nSeg!=nInput ){
237605 int nMove = (pLvl->nSeg - nInput) * sizeof(Fts5StructureSegment);
@@ -237620,10 +238911,47 @@
237620
237621 fts5MultiIterFree(pIter);
237622 fts5BufferFree(&term);
237623 if( pnRem ) *pnRem -= writer.nLeafWritten;
237624 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
237625
237626 /*
237627 ** Do up to nPg pages of automerge work on the index.
237628 **
237629 ** Return true if any changes were actually made, or false otherwise.
@@ -237640,42 +238968,39 @@
237640 while( nRem>0 && p->rc==SQLITE_OK ){
237641 int iLvl; /* To iterate through levels */
237642 int iBestLvl = 0; /* Level offering the most input segments */
237643 int nBest = 0; /* Number of input segments on best level */
237644
237645 /* Set iBestLvl to the level to read input segments from. */
 
237646 assert( pStruct->nLevel>0 );
237647 for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
237648 Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl];
237649 if( pLvl->nMerge ){
237650 if( pLvl->nMerge>nBest ){
237651 iBestLvl = iLvl;
237652 nBest = pLvl->nMerge;
237653 }
237654 break;
237655 }
237656 if( pLvl->nSeg>nBest ){
237657 nBest = pLvl->nSeg;
237658 iBestLvl = iLvl;
237659 }
237660 }
237661
237662 /* If nBest is still 0, then the index must be empty. */
237663 #ifdef SQLITE_DEBUG
237664 for(iLvl=0; nBest==0 && iLvl<pStruct->nLevel; iLvl++){
237665 assert( pStruct->aLevel[iLvl].nSeg==0 );
237666 }
237667 #endif
237668
237669 if( nBest<nMin && pStruct->aLevel[iBestLvl].nMerge==0 ){
237670 break;
237671 }
237672 bRet = 1;
237673 fts5IndexMergeLevel(p, &pStruct, iBestLvl, &nRem);
237674 if( p->rc==SQLITE_OK && pStruct->aLevel[iBestLvl].nMerge==0 ){
237675 fts5StructurePromote(p, iBestLvl+1, pStruct);
237676 }
 
 
237677 }
237678 *ppStruct = pStruct;
237679 return bRet;
237680 }
237681
@@ -237856,13 +239181,17 @@
237856 if( pLeaf->nn>pLeaf->szLeaf ){
237857 int iFirst = 0;
237858 int i1 = pLeaf->szLeaf;
237859 int i2 = 0;
237860
 
 
 
 
 
237861 aIdx = sqlite3Fts5MallocZero(&p->rc, (pLeaf->nn-pLeaf->szLeaf)+2);
237862 if( aIdx==0 ) break;
237863 i1 += fts5GetVarint32(&aPg[i1], iFirst);
237864 i2 = sqlite3Fts5PutVarint(aIdx, iFirst-nShift);
237865 if( i1<pLeaf->nn ){
237866 memcpy(&aIdx[i2], &aPg[i1], pLeaf->nn-i1);
237867 i2 += (pLeaf->nn-i1);
237868 }
@@ -238180,202 +239509,212 @@
238180 int pgnoLast = 0; /* Last leaf page number in segment */
238181
238182 /* Obtain a reference to the index structure and allocate a new segment-id
238183 ** for the new level-0 segment. */
238184 pStruct = fts5StructureRead(p);
238185 iSegid = fts5AllocateSegid(p, pStruct);
238186 fts5StructureInvalidate(p);
238187
238188 if( iSegid ){
238189 const int pgsz = p->pConfig->pgsz;
238190 int eDetail = p->pConfig->eDetail;
238191 int bSecureDelete = p->pConfig->bSecureDelete;
238192 Fts5StructureSegment *pSeg; /* New segment within pStruct */
238193 Fts5Buffer *pBuf; /* Buffer in which to assemble leaf page */
238194 Fts5Buffer *pPgidx; /* Buffer in which to assemble pgidx */
238195
238196 Fts5SegWriter writer;
238197 fts5WriteInit(p, &writer, iSegid);
238198
238199 pBuf = &writer.writer.buf;
238200 pPgidx = &writer.writer.pgidx;
238201
238202 /* fts5WriteInit() should have initialized the buffers to (most likely)
238203 ** the maximum space required. */
238204 assert( p->rc || pBuf->nSpace>=(pgsz + FTS5_DATA_PADDING) );
238205 assert( p->rc || pPgidx->nSpace>=(pgsz + FTS5_DATA_PADDING) );
238206
238207 /* Begin scanning through hash table entries. This loop runs once for each
238208 ** term/doclist currently stored within the hash table. */
238209 if( p->rc==SQLITE_OK ){
238210 p->rc = sqlite3Fts5HashScanInit(pHash, 0, 0);
238211 }
238212 while( p->rc==SQLITE_OK && 0==sqlite3Fts5HashScanEof(pHash) ){
238213 const char *zTerm; /* Buffer containing term */
238214 int nTerm; /* Size of zTerm in bytes */
238215 const u8 *pDoclist; /* Pointer to doclist for this term */
238216 int nDoclist; /* Size of doclist in bytes */
238217
238218 /* Get the term and doclist for this entry. */
238219 sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist);
238220 nTerm = (int)strlen(zTerm);
238221 if( bSecureDelete==0 ){
238222 fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm);
238223 if( p->rc!=SQLITE_OK ) break;
238224 assert( writer.bFirstRowidInPage==0 );
238225 }
238226
238227 if( !bSecureDelete && pgsz>=(pBuf->n + pPgidx->n + nDoclist + 1) ){
238228 /* The entire doclist will fit on the current leaf. */
238229 fts5BufferSafeAppendBlob(pBuf, pDoclist, nDoclist);
238230 }else{
238231 int bTermWritten = !bSecureDelete;
238232 i64 iRowid = 0;
238233 i64 iPrev = 0;
238234 int iOff = 0;
238235
238236 /* The entire doclist will not fit on this leaf. The following
238237 ** loop iterates through the poslists that make up the current
238238 ** doclist. */
238239 while( p->rc==SQLITE_OK && iOff<nDoclist ){
238240 u64 iDelta = 0;
238241 iOff += fts5GetVarint(&pDoclist[iOff], &iDelta);
238242 iRowid += iDelta;
238243
238244 /* If in secure delete mode, and if this entry in the poslist is
238245 ** in fact a delete, then edit the existing segments directly
238246 ** using fts5FlushSecureDelete(). */
238247 if( bSecureDelete ){
238248 if( eDetail==FTS5_DETAIL_NONE ){
238249 if( iOff<nDoclist && pDoclist[iOff]==0x00 ){
238250 fts5FlushSecureDelete(p, pStruct, zTerm, iRowid);
238251 iOff++;
238252 if( iOff<nDoclist && pDoclist[iOff]==0x00 ){
238253 iOff++;
238254 nDoclist = 0;
238255 }else{
238256 continue;
238257 }
238258 }
238259 }else if( (pDoclist[iOff] & 0x01) ){
238260 fts5FlushSecureDelete(p, pStruct, zTerm, iRowid);
238261 if( p->rc!=SQLITE_OK || pDoclist[iOff]==0x01 ){
238262 iOff++;
238263 continue;
238264 }
238265 }
238266 }
238267
238268 if( p->rc==SQLITE_OK && bTermWritten==0 ){
238269 fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm);
238270 bTermWritten = 1;
238271 assert( p->rc!=SQLITE_OK || writer.bFirstRowidInPage==0 );
238272 }
238273
238274 if( writer.bFirstRowidInPage ){
238275 fts5PutU16(&pBuf->p[0], (u16)pBuf->n); /* first rowid on page */
238276 pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid);
238277 writer.bFirstRowidInPage = 0;
238278 fts5WriteDlidxAppend(p, &writer, iRowid);
238279 }else{
238280 pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid-iPrev);
238281 }
238282 if( p->rc!=SQLITE_OK ) break;
238283 assert( pBuf->n<=pBuf->nSpace );
238284 iPrev = iRowid;
238285
238286 if( eDetail==FTS5_DETAIL_NONE ){
238287 if( iOff<nDoclist && pDoclist[iOff]==0 ){
238288 pBuf->p[pBuf->n++] = 0;
238289 iOff++;
238290 if( iOff<nDoclist && pDoclist[iOff]==0 ){
238291 pBuf->p[pBuf->n++] = 0;
238292 iOff++;
238293 }
238294 }
238295 if( (pBuf->n + pPgidx->n)>=pgsz ){
238296 fts5WriteFlushLeaf(p, &writer);
238297 }
238298 }else{
238299 int bDummy;
238300 int nPos;
238301 int nCopy = fts5GetPoslistSize(&pDoclist[iOff], &nPos, &bDummy);
238302 nCopy += nPos;
238303 if( (pBuf->n + pPgidx->n + nCopy) <= pgsz ){
238304 /* The entire poslist will fit on the current leaf. So copy
238305 ** it in one go. */
238306 fts5BufferSafeAppendBlob(pBuf, &pDoclist[iOff], nCopy);
238307 }else{
238308 /* The entire poslist will not fit on this leaf. So it needs
238309 ** to be broken into sections. The only qualification being
238310 ** that each varint must be stored contiguously. */
238311 const u8 *pPoslist = &pDoclist[iOff];
238312 int iPos = 0;
238313 while( p->rc==SQLITE_OK ){
238314 int nSpace = pgsz - pBuf->n - pPgidx->n;
238315 int n = 0;
238316 if( (nCopy - iPos)<=nSpace ){
238317 n = nCopy - iPos;
238318 }else{
238319 n = fts5PoslistPrefix(&pPoslist[iPos], nSpace);
238320 }
238321 assert( n>0 );
238322 fts5BufferSafeAppendBlob(pBuf, &pPoslist[iPos], n);
238323 iPos += n;
238324 if( (pBuf->n + pPgidx->n)>=pgsz ){
238325 fts5WriteFlushLeaf(p, &writer);
238326 }
238327 if( iPos>=nCopy ) break;
238328 }
238329 }
238330 iOff += nCopy;
238331 }
238332 }
238333 }
238334
238335 /* TODO2: Doclist terminator written here. */
238336 /* pBuf->p[pBuf->n++] = '\0'; */
238337 assert( pBuf->n<=pBuf->nSpace );
238338 if( p->rc==SQLITE_OK ) sqlite3Fts5HashScanNext(pHash);
238339 }
238340 sqlite3Fts5HashClear(pHash);
238341 fts5WriteFinish(p, &writer, &pgnoLast);
238342
238343 assert( p->rc!=SQLITE_OK || bSecureDelete || pgnoLast>0 );
238344 if( pgnoLast>0 ){
238345 /* Update the Fts5Structure. It is written back to the database by the
238346 ** fts5StructureRelease() call below. */
238347 if( pStruct->nLevel==0 ){
238348 fts5StructureAddLevel(&p->rc, &pStruct);
238349 }
238350 fts5StructureExtendLevel(&p->rc, pStruct, 0, 1, 0);
238351 if( p->rc==SQLITE_OK ){
238352 pSeg = &pStruct->aLevel[0].aSeg[ pStruct->aLevel[0].nSeg++ ];
238353 pSeg->iSegid = iSegid;
238354 pSeg->pgnoFirst = 1;
238355 pSeg->pgnoLast = pgnoLast;
238356 pStruct->nSegment++;
238357 }
238358 fts5StructurePromote(p, 0, pStruct);
238359 }
238360 }
238361
238362 fts5IndexAutomerge(p, &pStruct, pgnoLast);
238363 fts5IndexCrisismerge(p, &pStruct);
238364 fts5StructureWrite(p, pStruct);
238365 fts5StructureRelease(pStruct);
 
 
 
 
 
 
 
 
 
238366 }
238367
238368 /*
238369 ** Flush any data stored in the in-memory hash tables to the database.
238370 */
238371 static void fts5IndexFlush(Fts5Index *p){
238372 /* Unless it is empty, flush the hash table to disk */
238373 if( p->nPendingData ){
238374 assert( p->pHash );
238375 p->nPendingData = 0;
238376 fts5FlushOneHash(p);
 
 
238377 }
238378 }
238379
238380 static Fts5Structure *fts5IndexOptimizeStruct(
238381 Fts5Index *p,
@@ -238387,21 +239726,26 @@
238387 int i;
238388
238389 /* Figure out if this structure requires optimization. A structure does
238390 ** not require optimization if either:
238391 **
238392 ** + it consists of fewer than two segments, or
238393 ** + all segments are on the same level, or
238394 ** + all segments except one are currently inputs to a merge operation.
238395 **
238396 ** In the first case, return NULL. In the second, increment the ref-count
238397 ** on *pStruct and return a copy of the pointer to it.
 
238398 */
238399 if( nSeg<2 ) return 0;
238400 for(i=0; i<pStruct->nLevel; i++){
238401 int nThis = pStruct->aLevel[i].nSeg;
238402 if( nThis==nSeg || (nThis==nSeg-1 && pStruct->aLevel[i].nMerge==nThis) ){
 
 
 
 
238403 fts5StructureRef(pStruct);
238404 return pStruct;
238405 }
238406 assert( pStruct->aLevel[i].nMerge<=nThis );
238407 }
@@ -238413,10 +239757,11 @@
238413 Fts5StructureLevel *pLvl;
238414 nByte = nSeg * sizeof(Fts5StructureSegment);
238415 pNew->nLevel = MIN(pStruct->nLevel+1, FTS5_MAX_LEVEL);
238416 pNew->nRef = 1;
238417 pNew->nWriteCounter = pStruct->nWriteCounter;
 
238418 pLvl = &pNew->aLevel[pNew->nLevel-1];
238419 pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&p->rc, nByte);
238420 if( pLvl->aSeg ){
238421 int iLvl, iSeg;
238422 int iSegOut = 0;
@@ -238443,10 +239788,11 @@
238443 Fts5Structure *pStruct;
238444 Fts5Structure *pNew = 0;
238445
238446 assert( p->rc==SQLITE_OK );
238447 fts5IndexFlush(p);
 
238448 pStruct = fts5StructureRead(p);
238449 fts5StructureInvalidate(p);
238450
238451 if( pStruct ){
238452 pNew = fts5IndexOptimizeStruct(p, pStruct);
@@ -238472,19 +239818,22 @@
238472 /*
238473 ** This is called to implement the special "VALUES('merge', $nMerge)"
238474 ** INSERT command.
238475 */
238476 static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){
238477 Fts5Structure *pStruct = fts5StructureRead(p);
 
 
 
238478 if( pStruct ){
238479 int nMin = p->pConfig->nUsermerge;
238480 fts5StructureInvalidate(p);
238481 if( nMerge<0 ){
238482 Fts5Structure *pNew = fts5IndexOptimizeStruct(p, pStruct);
238483 fts5StructureRelease(pStruct);
238484 pStruct = pNew;
238485 nMin = 2;
238486 nMerge = nMerge*-1;
238487 }
238488 if( pStruct && pStruct->nLevel ){
238489 if( fts5IndexMerge(p, &pStruct, nMerge, nMin) ){
238490 fts5StructureWrite(p, pStruct);
@@ -238994,10 +240343,13 @@
238994 fts5IndexFlush(p);
238995 }
238996
238997 p->iWriteRowid = iRowid;
238998 p->bDelete = bDelete;
 
 
 
238999 return fts5IndexReturn(p);
239000 }
239001
239002 /*
239003 ** Commit data to disk.
@@ -239031,10 +240383,13 @@
239031 static int sqlite3Fts5IndexReinit(Fts5Index *p){
239032 Fts5Structure s;
239033 fts5StructureInvalidate(p);
239034 fts5IndexDiscardData(p);
239035 memset(&s, 0, sizeof(Fts5Structure));
 
 
 
239036 fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0);
239037 fts5StructureWrite(p, &s);
239038 return fts5IndexReturn(p);
239039 }
239040
@@ -239422,10 +240777,351 @@
239422 pStruct = fts5StructureRead(p);
239423 fts5StructureRelease(pStruct);
239424 return fts5IndexReturn(p);
239425 }
239426
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239427
239428 /*************************************************************************
239429 **************************************************************************
239430 ** Below this point is the implementation of the integrity-check
239431 ** functionality.
@@ -239973,17 +241669,18 @@
239973 **************************************************************************
239974 ** Below this point is the implementation of the fts5_decode() scalar
239975 ** function only.
239976 */
239977
239978 #ifdef SQLITE_TEST
239979 /*
239980 ** Decode a segment-data rowid from the %_data table. This function is
239981 ** the opposite of macro FTS5_SEGMENT_ROWID().
239982 */
239983 static void fts5DecodeRowid(
239984 i64 iRowid, /* Rowid from %_data table */
 
239985 int *piSegid, /* OUT: Segment id */
239986 int *pbDlidx, /* OUT: Dlidx flag */
239987 int *piHeight, /* OUT: Height */
239988 int *piPgno /* OUT: Page number */
239989 ){
@@ -239995,34 +241692,39 @@
239995
239996 *pbDlidx = (int)(iRowid & 0x0001);
239997 iRowid >>= FTS5_DATA_DLI_B;
239998
239999 *piSegid = (int)(iRowid & (((i64)1 << FTS5_DATA_ID_B) - 1));
 
 
 
240000 }
240001 #endif /* SQLITE_TEST */
240002
240003 #ifdef SQLITE_TEST
240004 static void fts5DebugRowid(int *pRc, Fts5Buffer *pBuf, i64 iKey){
240005 int iSegid, iHeight, iPgno, bDlidx; /* Rowid compenents */
240006 fts5DecodeRowid(iKey, &iSegid, &bDlidx, &iHeight, &iPgno);
240007
240008 if( iSegid==0 ){
240009 if( iKey==FTS5_AVERAGES_ROWID ){
240010 sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{averages} ");
240011 }else{
240012 sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{structure}");
240013 }
240014 }
240015 else{
240016 sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{%ssegid=%d h=%d pgno=%d}",
240017 bDlidx ? "dlidx " : "", iSegid, iHeight, iPgno
 
 
240018 );
240019 }
240020 }
240021 #endif /* SQLITE_TEST */
240022
240023 #ifdef SQLITE_TEST
240024 static void fts5DebugStructure(
240025 int *pRc, /* IN/OUT: error code */
240026 Fts5Buffer *pBuf,
240027 Fts5Structure *p
240028 ){
@@ -240033,20 +241735,26 @@
240033 sqlite3Fts5BufferAppendPrintf(pRc, pBuf,
240034 " {lvl=%d nMerge=%d nSeg=%d", iLvl, pLvl->nMerge, pLvl->nSeg
240035 );
240036 for(iSeg=0; iSeg<pLvl->nSeg; iSeg++){
240037 Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg];
240038 sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " {id=%d leaves=%d..%d}",
240039 pSeg->iSegid, pSeg->pgnoFirst, pSeg->pgnoLast
240040 );
 
 
 
 
 
 
240041 }
240042 sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "}");
240043 }
240044 }
240045 #endif /* SQLITE_TEST */
240046
240047 #ifdef SQLITE_TEST
240048 /*
240049 ** This is part of the fts5_decode() debugging aid.
240050 **
240051 ** Arguments pBlob/nBlob contain a serialized Fts5Structure object. This
240052 ** function appends a human-readable representation of the same object
@@ -240067,13 +241775,13 @@
240067 }
240068
240069 fts5DebugStructure(pRc, pBuf, p);
240070 fts5StructureRelease(p);
240071 }
240072 #endif /* SQLITE_TEST */
240073
240074 #ifdef SQLITE_TEST
240075 /*
240076 ** This is part of the fts5_decode() debugging aid.
240077 **
240078 ** Arguments pBlob/nBlob contain an "averages" record. This function
240079 ** appends a human-readable representation of record to the buffer passed
@@ -240092,13 +241800,13 @@
240092 i += sqlite3Fts5GetVarint(&pBlob[i], &iVal);
240093 sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "%s%d", zSpace, (int)iVal);
240094 zSpace = " ";
240095 }
240096 }
240097 #endif /* SQLITE_TEST */
240098
240099 #ifdef SQLITE_TEST
240100 /*
240101 ** Buffer (a/n) is assumed to contain a list of serialized varints. Read
240102 ** each varint and append its string representation to buffer pBuf. Return
240103 ** after either the input buffer is exhausted or a 0 value is read.
240104 **
@@ -240111,13 +241819,13 @@
240111 iOff += fts5GetVarint32(&a[iOff], iVal);
240112 sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " %d", iVal);
240113 }
240114 return iOff;
240115 }
240116 #endif /* SQLITE_TEST */
240117
240118 #ifdef SQLITE_TEST
240119 /*
240120 ** The start of buffer (a/n) contains the start of a doclist. The doclist
240121 ** may or may not finish within the buffer. This function appends a text
240122 ** representation of the part of the doclist that is present to buffer
240123 ** pBuf.
@@ -240146,13 +241854,13 @@
240146 }
240147 }
240148
240149 return iOff;
240150 }
240151 #endif /* SQLITE_TEST */
240152
240153 #ifdef SQLITE_TEST
240154 /*
240155 ** This function is part of the fts5_decode() debugging function. It is
240156 ** only ever used with detail=none tables.
240157 **
240158 ** Buffer (pData/nData) contains a doclist in the format used by detail=none
@@ -240189,13 +241897,13 @@
240189 }
240190
240191 sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " %lld%s", iRowid, zApp);
240192 }
240193 }
240194 #endif /* SQLITE_TEST */
240195
240196 #ifdef SQLITE_TEST
240197 /*
240198 ** The implementation of user-defined scalar function fts5_decode().
240199 */
240200 static void fts5DecodeFunction(
240201 sqlite3_context *pCtx, /* Function call context */
@@ -240202,10 +241910,11 @@
240202 int nArg, /* Number of args (always 2) */
240203 sqlite3_value **apVal /* Function arguments */
240204 ){
240205 i64 iRowid; /* Rowid for record being decoded */
240206 int iSegid,iHeight,iPgno,bDlidx;/* Rowid components */
 
240207 const u8 *aBlob; int n; /* Record to decode */
240208 u8 *a = 0;
240209 Fts5Buffer s; /* Build up text to return here */
240210 int rc = SQLITE_OK; /* Return code */
240211 sqlite3_int64 nSpace = 0;
@@ -240224,11 +241933,11 @@
240224 nSpace = n + FTS5_DATA_ZERO_PADDING;
240225 a = (u8*)sqlite3Fts5MallocZero(&rc, nSpace);
240226 if( a==0 ) goto decode_out;
240227 if( n>0 ) memcpy(a, aBlob, n);
240228
240229 fts5DecodeRowid(iRowid, &iSegid, &bDlidx, &iHeight, &iPgno);
240230
240231 fts5DebugRowid(&rc, &s, iRowid);
240232 if( bDlidx ){
240233 Fts5Data dlidx;
240234 Fts5DlidxLvl lvl;
@@ -240242,10 +241951,32 @@
240242
240243 for(fts5DlidxLvlNext(&lvl); lvl.bEof==0; fts5DlidxLvlNext(&lvl)){
240244 sqlite3Fts5BufferAppendPrintf(&rc, &s,
240245 " %d(%lld)", lvl.iLeafPgno, lvl.iRowid
240246 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240247 }
240248 }else if( iSegid==0 ){
240249 if( iRowid==FTS5_AVERAGES_ROWID ){
240250 fts5DecodeAverages(&rc, &s, a, n);
240251 }else{
@@ -240400,13 +242131,13 @@
240400 }else{
240401 sqlite3_result_error_code(pCtx, rc);
240402 }
240403 fts5BufferFree(&s);
240404 }
240405 #endif /* SQLITE_TEST */
240406
240407 #ifdef SQLITE_TEST
240408 /*
240409 ** The implementation of user-defined scalar function fts5_rowid().
240410 */
240411 static void fts5RowidFunction(
240412 sqlite3_context *pCtx, /* Function call context */
@@ -240436,11 +242167,239 @@
240436 "first arg to fts5_rowid() must be 'segment'" , -1
240437 );
240438 }
240439 }
240440 }
240441 #endif /* SQLITE_TEST */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240442
240443 /*
240444 ** This is called as part of registering the FTS5 module with database
240445 ** connection db. It registers several user-defined scalar functions useful
240446 ** with FTS5.
@@ -240447,11 +242406,11 @@
240447 **
240448 ** If successful, SQLITE_OK is returned. If an error occurs, some other
240449 ** SQLite error code is returned instead.
240450 */
240451 static int sqlite3Fts5IndexInit(sqlite3 *db){
240452 #ifdef SQLITE_TEST
240453 int rc = sqlite3_create_function(
240454 db, "fts5_decode", 2, SQLITE_UTF8, 0, fts5DecodeFunction, 0, 0
240455 );
240456
240457 if( rc==SQLITE_OK ){
@@ -240464,10 +242423,40 @@
240464 if( rc==SQLITE_OK ){
240465 rc = sqlite3_create_function(
240466 db, "fts5_rowid", -1, SQLITE_UTF8, 0, fts5RowidFunction, 0, 0
240467 );
240468 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240469 return rc;
240470 #else
240471 return SQLITE_OK;
240472 UNUSED_PARAM(db);
240473 #endif
@@ -242107,11 +244096,10 @@
242107 Fts5Config *pConfig = pTab->p.pConfig;
242108 int eType0; /* value_type() of apVal[0] */
242109 int rc = SQLITE_OK; /* Return code */
242110 int bUpdateOrDelete = 0;
242111
242112
242113 /* A transaction must be open when this is called. */
242114 assert( pTab->ts.eState==1 || pTab->ts.eState==2 );
242115
242116 assert( pVtab->zErrMsg==0 );
242117 assert( nArg==1 || nArg==(2+pConfig->nCol+2) );
@@ -242136,11 +244124,18 @@
242136 /* A "special" INSERT op. These are handled separately. */
242137 const char *z = (const char*)sqlite3_value_text(apVal[2+pConfig->nCol]);
242138 if( pConfig->eContent!=FTS5_CONTENT_NORMAL
242139 && 0==sqlite3_stricmp("delete", z)
242140 ){
242141 rc = fts5SpecialDelete(pTab, apVal);
 
 
 
 
 
 
 
242142 }else{
242143 rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]);
242144 }
242145 }else{
242146 /* A regular INSERT, UPDATE or DELETE statement. The trick here is that
@@ -242153,20 +244148,24 @@
242153 ** 4) INSERT
242154 **
242155 ** Cases 3 and 4 may violate the rowid constraint.
242156 */
242157 int eConflict = SQLITE_ABORT;
242158 if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
242159 eConflict = sqlite3_vtab_on_conflict(pConfig->db);
242160 }
242161
242162 assert( eType0==SQLITE_INTEGER || eType0==SQLITE_NULL );
242163 assert( nArg!=1 || eType0==SQLITE_INTEGER );
242164
242165 /* Filter out attempts to run UPDATE or DELETE on contentless tables.
242166 ** This is not suported. */
242167 if( eType0==SQLITE_INTEGER && fts5IsContentless(pTab) ){
 
 
 
 
242168 pTab->p.base.zErrMsg = sqlite3_mprintf(
242169 "cannot %s contentless fts5 table: %s",
242170 (nArg>1 ? "UPDATE" : "DELETE from"), pConfig->zName
242171 );
242172 rc = SQLITE_ERROR;
@@ -242249,12 +244248,11 @@
242249 static int fts5SyncMethod(sqlite3_vtab *pVtab){
242250 int rc;
242251 Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
242252 fts5CheckTransactionState(pTab, FTS5_SYNC, 0);
242253 pTab->p.pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
242254 fts5TripCursors(pTab);
242255 rc = sqlite3Fts5StorageSync(pTab->pStorage);
242256 pTab->p.pConfig->pzErrmsg = 0;
242257 return rc;
242258 }
242259
242260 /*
@@ -243299,11 +245297,11 @@
243299 int nArg, /* Number of args */
243300 sqlite3_value **apUnused /* Function arguments */
243301 ){
243302 assert( nArg==0 );
243303 UNUSED_PARAM2(nArg, apUnused);
243304 sqlite3_result_text(pCtx, "fts5: 2023-07-08 17:42:24 07d95ed60f0a17ea13b4bc19c2ab2ec9052fedd27c9e1e57a1ec6e3a6470e5b7", -1, SQLITE_TRANSIENT);
243305 }
243306
243307 /*
243308 ** Return true if zName is the extension on one of the shadow tables used
243309 ** by this module.
@@ -243512,14 +245510,14 @@
243512 "SELECT %s FROM %s T WHERE T.%Q=?", /* LOOKUP */
243513
243514 "INSERT INTO %Q.'%q_content' VALUES(%s)", /* INSERT_CONTENT */
243515 "REPLACE INTO %Q.'%q_content' VALUES(%s)", /* REPLACE_CONTENT */
243516 "DELETE FROM %Q.'%q_content' WHERE id=?", /* DELETE_CONTENT */
243517 "REPLACE INTO %Q.'%q_docsize' VALUES(?,?)", /* REPLACE_DOCSIZE */
243518 "DELETE FROM %Q.'%q_docsize' WHERE id=?", /* DELETE_DOCSIZE */
243519
243520 "SELECT sz FROM %Q.'%q_docsize' WHERE id=?", /* LOOKUP_DOCSIZE */
243521
243522 "REPLACE INTO %Q.'%q_config' VALUES(?,?)", /* REPLACE_CONFIG */
243523 "SELECT %s FROM %s AS T", /* SCAN */
243524 };
243525 Fts5Config *pC = p->pConfig;
@@ -243562,10 +245560,23 @@
243562 zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName, zBind);
243563 sqlite3_free(zBind);
243564 }
243565 break;
243566 }
 
 
 
 
 
 
 
 
 
 
 
 
 
243567
243568 default:
243569 zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName);
243570 break;
243571 }
@@ -243752,13 +245763,15 @@
243752 }
243753 sqlite3_free(zDefn);
243754 }
243755
243756 if( rc==SQLITE_OK && pConfig->bColumnsize ){
243757 rc = sqlite3Fts5CreateTable(
243758 pConfig, "docsize", "id INTEGER PRIMARY KEY, sz BLOB", 0, pzErr
243759 );
 
 
243760 }
243761 if( rc==SQLITE_OK ){
243762 rc = sqlite3Fts5CreateTable(
243763 pConfig, "config", "k PRIMARY KEY, v", 1, pzErr
243764 );
@@ -243831,11 +245844,11 @@
243831 i64 iDel,
243832 sqlite3_value **apVal
243833 ){
243834 Fts5Config *pConfig = p->pConfig;
243835 sqlite3_stmt *pSeek = 0; /* SELECT to read row iDel from %_data */
243836 int rc; /* Return code */
243837 int rc2; /* sqlite3_reset() return code */
243838 int iCol;
243839 Fts5InsertCtx ctx;
243840
243841 if( apVal==0 ){
@@ -243847,11 +245860,10 @@
243847 }
243848 }
243849
243850 ctx.pStorage = p;
243851 ctx.iCol = -1;
243852 rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel);
243853 for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){
243854 if( pConfig->abUnindexed[iCol-1]==0 ){
243855 const char *zText;
243856 int nText;
243857 assert( pSeek==0 || apVal==0 );
@@ -243884,10 +245896,41 @@
243884 rc2 = sqlite3_reset(pSeek);
243885 if( rc==SQLITE_OK ) rc = rc2;
243886 return rc;
243887 }
243888
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243889
243890 /*
243891 ** Insert a record into the %_docsize table. Specifically, do:
243892 **
243893 ** INSERT OR REPLACE INTO %_docsize(id, sz) VALUES(iRowid, pBuf);
@@ -243904,14 +245947,21 @@
243904 if( p->pConfig->bColumnsize ){
243905 sqlite3_stmt *pReplace = 0;
243906 rc = fts5StorageGetStmt(p, FTS5_STMT_REPLACE_DOCSIZE, &pReplace, 0);
243907 if( rc==SQLITE_OK ){
243908 sqlite3_bind_int64(pReplace, 1, iRowid);
243909 sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC);
243910 sqlite3_step(pReplace);
243911 rc = sqlite3_reset(pReplace);
243912 sqlite3_bind_null(pReplace, 2);
 
 
 
 
 
 
 
243913 }
243914 }
243915 return rc;
243916 }
243917
@@ -243971,11 +246021,19 @@
243971 assert( pConfig->eContent!=FTS5_CONTENT_NORMAL || apVal==0 );
243972 rc = fts5StorageLoadTotals(p, 1);
243973
243974 /* Delete the index records */
243975 if( rc==SQLITE_OK ){
243976 rc = fts5StorageDeleteFromIndex(p, iDel, apVal);
 
 
 
 
 
 
 
 
243977 }
243978
243979 /* Delete the %_docsize record */
243980 if( rc==SQLITE_OK && pConfig->bColumnsize ){
243981 rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_DOCSIZE, &pDel, 0);
243982
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -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 ** a0b9aecbaca9a8e784fd2bcb50f78cbdcf4.
22 */
23 #define SQLITE_CORE 1
24 #define SQLITE_AMALGAMATION 1
25 #ifndef SQLITE_PRIVATE
26 # define SQLITE_PRIVATE static
@@ -459,11 +459,11 @@
459 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
460 ** [sqlite_version()] and [sqlite_source_id()].
461 */
462 #define SQLITE_VERSION "3.43.0"
463 #define SQLITE_VERSION_NUMBER 3043000
464 #define SQLITE_SOURCE_ID "2023-08-02 16:06:02 ea0b9aecbaca9a8e784fd2bcb50f78cbdcf4c5cfb45a7700bb222e4cc104c644"
465
466 /*
467 ** CAPI3REF: Run-Time Library Version Numbers
468 ** KEYWORDS: sqlite3_version sqlite3_sourceid
469 **
@@ -4732,10 +4732,45 @@
4732 ** ^The sqlite3_stmt_isexplain(S) interface returns 0 if S is
4733 ** an ordinary statement or a NULL pointer.
4734 */
4735 SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt);
4736
4737 /*
4738 ** CAPI3REF: Change The EXPLAIN Setting For A Prepared Statement
4739 ** METHOD: sqlite3_stmt
4740 **
4741 ** The sqlite3_stmt_explain(S,E) interface changes the EXPLAIN
4742 ** setting for [prepared statement] S. If E is zero, then S becomes
4743 ** a normal prepared statement. If E is 1, then S behaves as if
4744 ** its SQL text began with "[EXPLAIN]". If E is 2, then S behaves as if
4745 ** its SQL text began with "[EXPLAIN QUERY PLAN]".
4746 **
4747 ** Calling sqlite3_stmt_explain(S,E) might cause S to be reprepared.
4748 ** SQLite tries to avoid a reprepare, but a reprepare might be necessary
4749 ** on the first transition into EXPLAIN or EXPLAIN QUERY PLAN mode.
4750 **
4751 ** Because of the potential need to reprepare, a call to
4752 ** sqlite3_stmt_explain(S,E) will fail with SQLITE_ERROR if S cannot be
4753 ** reprepared because it was created using [sqlite3_prepare()] instead of
4754 ** the newer [sqlite3_prepare_v2()] or [sqlite3_prepare_v3()] interfaces and
4755 ** hence has no saved SQL text with which to reprepare.
4756 **
4757 ** Changing the explain setting for a prepared statement does not change
4758 ** the original SQL text for the statement. Hence, if the SQL text originally
4759 ** began with EXPLAIN or EXPLAIN QUERY PLAN, but sqlite3_stmt_explain(S,0)
4760 ** is called to convert the statement into an ordinary statement, the EXPLAIN
4761 ** or EXPLAIN QUERY PLAN keywords will still appear in the sqlite3_sql(S)
4762 ** output, even though the statement now acts like a normal SQL statement.
4763 **
4764 ** This routine returns SQLITE_OK if the explain mode is successfully
4765 ** changed, or an error code if the explain mode could not be changed.
4766 ** The explain mode cannot be changed while a statement is active.
4767 ** Hence, it is good practice to call [sqlite3_reset(S)]
4768 ** immediately prior to calling sqlite3_stmt_explain(S,E).
4769 */
4770 SQLITE_API int sqlite3_stmt_explain(sqlite3_stmt *pStmt, int eMode);
4771
4772 /*
4773 ** CAPI3REF: Determine If A Prepared Statement Has Been Reset
4774 ** METHOD: sqlite3_stmt
4775 **
4776 ** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the
@@ -14590,12 +14625,35 @@
14625 **
14626 ** In other words, S is a buffer and E is a pointer to the first byte after
14627 ** the end of buffer S. This macro returns true if P points to something
14628 ** contained within the buffer S.
14629 */
14630 #define SQLITE_WITHIN(P,S,E) (((uptr)(P)>=(uptr)(S))&&((uptr)(P)<(uptr)(E)))
14631
14632 /*
14633 ** P is one byte past the end of a large buffer. Return true if a span of bytes
14634 ** between S..E crosses the end of that buffer. In other words, return true
14635 ** if the sub-buffer S..E-1 overflows the buffer show last byte is P-1.
14636 **
14637 ** S is the start of the span. E is one byte past the end of end of span.
14638 **
14639 ** P
14640 ** |-----------------| FALSE
14641 ** |-------|
14642 ** S E
14643 **
14644 ** P
14645 ** |-----------------|
14646 ** |-------| TRUE
14647 ** S E
14648 **
14649 ** P
14650 ** |-----------------|
14651 ** |-------| FALSE
14652 ** S E
14653 */
14654 #define SQLITE_OVERFLOW(P,S,E) (((uptr)(S)<(uptr)(P))&&((uptr)(E)>(uptr)(P)))
14655
14656 /*
14657 ** Macros to determine whether the machine is big or little endian,
14658 ** and whether or not that determination is run-time or compile-time.
14659 **
@@ -14959,10 +15017,11 @@
15017 typedef struct OnOrUsing OnOrUsing;
15018 typedef struct Parse Parse;
15019 typedef struct ParseCleanup ParseCleanup;
15020 typedef struct PreUpdate PreUpdate;
15021 typedef struct PrintfArguments PrintfArguments;
15022 typedef struct RCStr RCStr;
15023 typedef struct RenameToken RenameToken;
15024 typedef struct Returning Returning;
15025 typedef struct RowSet RowSet;
15026 typedef struct Savepoint Savepoint;
15027 typedef struct Select Select;
@@ -15925,13 +15984,11 @@
15984 SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*);
15985 SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int flags);
15986 SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor*);
15987 SQLITE_PRIVATE void sqlite3BtreeCursorPin(BtCursor*);
15988 SQLITE_PRIVATE void sqlite3BtreeCursorUnpin(BtCursor*);
 
15989 SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor*);
 
15990 SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*);
15991 SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt);
15992 SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor*);
15993 SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor*);
15994
@@ -17469,10 +17526,11 @@
17526 #define SQLITE_FlttnUnionAll 0x00800000 /* Disable the UNION ALL flattener */
17527 /* TH3 expects this value ^^^^^^^^^^ See flatten04.test */
17528 #define SQLITE_IndexedExpr 0x01000000 /* Pull exprs from index when able */
17529 #define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */
17530 #define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */
17531 #define SQLITE_OnePass 0x08000000 /* Single-pass DELETE and UPDATE */
17532 #define SQLITE_AllOpts 0xffffffff /* All optimizations */
17533
17534 /*
17535 ** Macros for testing whether or not optimizations are enabled or disabled.
17536 */
@@ -19385,11 +19443,11 @@
19443 ParseCleanup *pCleanup; /* List of cleanup operations to run after parse */
19444 union {
19445 int addrCrTab; /* Address of OP_CreateBtree on CREATE TABLE */
19446 Returning *pReturning; /* The RETURNING clause */
19447 } u1;
19448 LogEst nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */
19449 u32 oldmask; /* Mask of old.* columns referenced */
19450 u32 newmask; /* Mask of new.* columns referenced */
19451 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
19452 u32 nProgressSteps; /* xProgress steps taken during sqlite3_prepare() */
19453 #endif
@@ -19657,10 +19715,29 @@
19715 #define SQLITE_PRINTF_SQLFUNC 0x02 /* SQL function arguments to VXPrintf */
19716 #define SQLITE_PRINTF_MALLOCED 0x04 /* True if xText is allocated space */
19717
19718 #define isMalloced(X) (((X)->printfFlags & SQLITE_PRINTF_MALLOCED)!=0)
19719
19720 /*
19721 ** The following object is the header for an "RCStr" or "reference-counted
19722 ** string". An RCStr is passed around and used like any other char*
19723 ** that has been dynamically allocated. The important interface
19724 ** differences:
19725 **
19726 ** 1. RCStr strings are reference counted. They are deallocated
19727 ** when the reference count reaches zero.
19728 **
19729 ** 2. Use sqlite3RCStrUnref() to free an RCStr string rather than
19730 ** sqlite3_free()
19731 **
19732 ** 3. Make a (read-only) copy of a read-only RCStr string using
19733 ** sqlite3RCStrRef().
19734 */
19735 struct RCStr {
19736 u64 nRCRef; /* Number of references */
19737 /* Total structure size should be a multiple of 8 bytes for alignment */
19738 };
19739
19740 /*
19741 ** A pointer to this structure is used to communicate information
19742 ** from sqlite3Init and OP_ParseSchema into the sqlite3InitCallback.
19743 */
@@ -20776,10 +20853,11 @@
20853 # define sqlite3FileSuffix3(X,Y)
20854 #endif
20855 SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z,u8);
20856
20857 SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8);
20858 SQLITE_PRIVATE int sqlite3ValueIsOfClass(const sqlite3_value*, void(*)(void*));
20859 SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8);
20860 SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
20861 void(*)(void*));
20862 SQLITE_PRIVATE void sqlite3ValueSetNull(sqlite3_value*);
20863 SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*);
@@ -20883,10 +20961,15 @@
20961 SQLITE_PRIVATE void *sqlite3OomFault(sqlite3*);
20962 SQLITE_PRIVATE void sqlite3OomClear(sqlite3*);
20963 SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int);
20964 SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *);
20965
20966 SQLITE_PRIVATE char *sqlite3RCStrRef(char*);
20967 SQLITE_PRIVATE void sqlite3RCStrUnref(char*);
20968 SQLITE_PRIVATE char *sqlite3RCStrNew(u64);
20969 SQLITE_PRIVATE char *sqlite3RCStrResize(char*,u64);
20970
20971 SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int);
20972 SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum*, i64);
20973 SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*);
20974 SQLITE_PRIVATE void sqlite3StrAccumSetError(StrAccum*, u8);
20975 SQLITE_PRIVATE void sqlite3ResultStrAccum(sqlite3_context*,StrAccum*);
@@ -22623,10 +22706,13 @@
22706 typedef struct VdbeSorter VdbeSorter;
22707
22708 /* Elements of the linked list at Vdbe.pAuxData */
22709 typedef struct AuxData AuxData;
22710
22711 /* A cache of large TEXT or BLOB values in a VdbeCursor */
22712 typedef struct VdbeTxtBlbCache VdbeTxtBlbCache;
22713
22714 /* Types of VDBE cursors */
22715 #define CURTYPE_BTREE 0
22716 #define CURTYPE_SORTER 1
22717 #define CURTYPE_VTAB 2
22718 #define CURTYPE_PSEUDO 3
@@ -22654,10 +22740,11 @@
22740 #endif
22741 Bool isEphemeral:1; /* True for an ephemeral table */
22742 Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */
22743 Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */
22744 Bool noReuse:1; /* OpenEphemeral may not reuse this cursor */
22745 Bool colCache:1; /* pCache pointer is initialized and non-NULL */
22746 u16 seekHit; /* See the OP_SeekHit and OP_IfNoHope opcodes */
22747 union { /* pBtx for isEphermeral. pAltMap otherwise */
22748 Btree *pBtx; /* Separate file holding temporary table */
22749 u32 *aAltMap; /* Mapping from table to index column numbers */
22750 } ub;
@@ -22694,10 +22781,11 @@
22781 u32 payloadSize; /* Total number of bytes in the record */
22782 u32 szRow; /* Byte available in aRow */
22783 #ifdef SQLITE_ENABLE_COLUMN_USED_MASK
22784 u64 maskUsed; /* Mask of columns used by this cursor */
22785 #endif
22786 VdbeTxtBlbCache *pCache; /* Cache of large TEXT or BLOB values */
22787
22788 /* 2*nField extra array elements allocated for aType[], beyond the one
22789 ** static element declared in the structure. nField total array slots for
22790 ** aType[] and nField+1 array slots for aOffset[] */
22791 u32 aType[1]; /* Type values record decode. MUST BE LAST */
@@ -22706,15 +22794,28 @@
22794 /* Return true if P is a null-only cursor
22795 */
22796 #define IsNullCursor(P) \
22797 ((P)->eCurType==CURTYPE_PSEUDO && (P)->nullRow && (P)->seekResult==0)
22798
 
22799 /*
22800 ** A value for VdbeCursor.cacheStatus that means the cache is always invalid.
22801 */
22802 #define CACHE_STALE 0
22803
22804 /*
22805 ** Large TEXT or BLOB values can be slow to load, so we want to avoid
22806 ** loading them more than once. For that reason, large TEXT and BLOB values
22807 ** can be stored in a cache defined by this object, and attached to the
22808 ** VdbeCursor using the pCache field.
22809 */
22810 struct VdbeTxtBlbCache {
22811 char *pCValue; /* A RCStr buffer to hold the value */
22812 i64 iOffset; /* File offset of the row being cached */
22813 int iCol; /* Column for which the cache is valid */
22814 u32 cacheStatus; /* Vdbe.cacheCtr value */
22815 u32 colCacheCtr; /* Column cache counter */
22816 };
22817
22818 /*
22819 ** When a sub-program is executed (OP_Program), a structure of this type
22820 ** is allocated to store the current value of the program counter, as
22821 ** well as the current memory cell array and various other frame specific
@@ -23032,20 +23133,22 @@
23133 #ifdef SQLITE_DEBUG
23134 int rcApp; /* errcode set by sqlite3_result_error_code() */
23135 u32 nWrite; /* Number of write operations that have occurred */
23136 #endif
23137 u16 nResColumn; /* Number of columns in one row of the result set */
23138 u16 nResAlloc; /* Column slots allocated to aColName[] */
23139 u8 errorAction; /* Recovery action to do in case of an error */
23140 u8 minWriteFileFormat; /* Minimum file format for writable database files */
23141 u8 prepFlags; /* SQLITE_PREPARE_* flags */
23142 u8 eVdbeState; /* On of the VDBE_*_STATE values */
23143 bft expired:2; /* 1: recompile VM immediately 2: when convenient */
23144 bft explain:2; /* 0: normal, 1: EXPLAIN, 2: EXPLAIN QUERY PLAN */
23145 bft changeCntOn:1; /* True to update the change-counter */
23146 bft usesStmtJournal:1; /* True if uses a statement journal */
23147 bft readOnly:1; /* True for statements that do not write */
23148 bft bIsReader:1; /* True for statements that read */
23149 bft haveEqpOps:1; /* Bytecode supports EXPLAIN QUERY PLAN */
23150 yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
23151 yDbMask lockMask; /* Subset of btreeMask that requires a lock */
23152 u32 aCounter[9]; /* Counters used by sqlite3_stmt_status() */
23153 char *zSql; /* Text of the SQL statement that generated this */
23154 #ifdef SQLITE_ENABLE_NORMALIZE
@@ -23178,10 +23281,11 @@
23281 #endif
23282 #ifdef SQLITE_DEBUG
23283 SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem*);
23284 #endif
23285 SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem*);
23286 SQLITE_PRIVATE void sqlite3VdbeMemZeroTerminateIfAble(Mem*);
23287 SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*);
23288 SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8);
23289 SQLITE_PRIVATE int sqlite3IntFloatCompare(i64,double);
23290 SQLITE_PRIVATE i64 sqlite3VdbeIntValue(const Mem*);
23291 SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*);
@@ -31698,10 +31802,79 @@
31802 va_start(ap,zFormat);
31803 sqlite3_str_vappendf(p, zFormat, ap);
31804 va_end(ap);
31805 }
31806
31807
31808 /*****************************************************************************
31809 ** Reference counted string storage
31810 *****************************************************************************/
31811
31812 /*
31813 ** Increase the reference count of the string by one.
31814 **
31815 ** The input parameter is returned.
31816 */
31817 SQLITE_PRIVATE char *sqlite3RCStrRef(char *z){
31818 RCStr *p = (RCStr*)z;
31819 assert( p!=0 );
31820 p--;
31821 p->nRCRef++;
31822 return z;
31823 }
31824
31825 /*
31826 ** Decrease the reference count by one. Free the string when the
31827 ** reference count reaches zero.
31828 */
31829 SQLITE_PRIVATE void sqlite3RCStrUnref(char *z){
31830 RCStr *p = (RCStr*)z;
31831 assert( p!=0 );
31832 p--;
31833 assert( p->nRCRef>0 );
31834 if( p->nRCRef>=2 ){
31835 p->nRCRef--;
31836 }else{
31837 sqlite3_free(p);
31838 }
31839 }
31840
31841 /*
31842 ** Create a new string that is capable of holding N bytes of text, not counting
31843 ** the zero byte at the end. The string is uninitialized.
31844 **
31845 ** The reference count is initially 1. Call sqlite3RCStrUnref() to free the
31846 ** newly allocated string.
31847 **
31848 ** This routine returns 0 on an OOM.
31849 */
31850 SQLITE_PRIVATE char *sqlite3RCStrNew(u64 N){
31851 RCStr *p = sqlite3_malloc64( N + sizeof(*p) + 1 );
31852 if( p==0 ) return 0;
31853 p->nRCRef = 1;
31854 return (char*)&p[1];
31855 }
31856
31857 /*
31858 ** Change the size of the string so that it is able to hold N bytes.
31859 ** The string might be reallocated, so return the new allocation.
31860 */
31861 SQLITE_PRIVATE char *sqlite3RCStrResize(char *z, u64 N){
31862 RCStr *p = (RCStr*)z;
31863 RCStr *pNew;
31864 assert( p!=0 );
31865 p--;
31866 assert( p->nRCRef==1 );
31867 pNew = sqlite3_realloc64(p, N+sizeof(RCStr)+1);
31868 if( pNew==0 ){
31869 sqlite3_free(p);
31870 return 0;
31871 }else{
31872 return (char*)&pNew[1];
31873 }
31874 }
31875
31876 /************** End of printf.c **********************************************/
31877 /************** Begin file treeview.c ****************************************/
31878 /*
31879 ** 2015-06-08
31880 **
@@ -34572,11 +34745,16 @@
34745 }else{
34746 while( e<=-100 ){ e+=100; r *= 1.0e-100L; }
34747 while( e<=-10 ){ e+=10; r *= 1.0e-10L; }
34748 while( e<=-1 ){ e+=1; r *= 1.0e-01L; }
34749 }
34750 assert( r>=0.0 );
34751 if( r>+1.7976931348623157081452742373e+308L ){
34752 *pResult = +INFINITY;
34753 }else{
34754 *pResult = (double)r;
34755 }
34756 }else{
34757 double rr[2];
34758 u64 s2;
34759 rr[0] = (double)s;
34760 s2 = (u64)rr[0];
@@ -34827,11 +35005,13 @@
35005 if( z[k]!=0 ) return 1;
35006 return 0;
35007 }else
35008 #endif /* SQLITE_OMIT_HEX_INTEGER */
35009 {
35010 int n = (int)(0x3fffffff&strspn(z,"+- \n\t0123456789"));
35011 if( z[n] ) n++;
35012 return sqlite3Atoi64(z, pOut, n, SQLITE_UTF8);
35013 }
35014 }
35015
35016 /*
35017 ** If zNum represents an integer that will fit in 32-bits, then set
@@ -65559,27 +65739,19 @@
65739 /* Allocate space for the WalIterator object. */
65740 nSegment = walFramePage(iLast) + 1;
65741 nByte = sizeof(WalIterator)
65742 + (nSegment-1)*sizeof(struct WalSegment)
65743 + iLast*sizeof(ht_slot);
65744 p = (WalIterator *)sqlite3_malloc64(nByte
65745 + sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast)
65746 );
65747 if( !p ){
65748 return SQLITE_NOMEM_BKPT;
65749 }
65750 memset(p, 0, nByte);
65751 p->nSegment = nSegment;
65752 aTmp = (ht_slot*)&(((u8*)p)[nByte]);
 
 
 
 
 
 
 
 
 
 
65753 for(i=walFramePage(nBackfill+1); rc==SQLITE_OK && i<nSegment; i++){
65754 WalHashLoc sLoc;
65755
65756 rc = walHashGet(pWal, i, &sLoc);
65757 if( rc==SQLITE_OK ){
@@ -65603,12 +65775,10 @@
65775 p->aSegment[i].nEntry = nEntry;
65776 p->aSegment[i].aIndex = aIndex;
65777 p->aSegment[i].aPgno = (u32 *)sLoc.aPgno;
65778 }
65779 }
 
 
65780 if( rc!=SQLITE_OK ){
65781 walIteratorFree(p);
65782 p = 0;
65783 }
65784 *pp = p;
@@ -68121,11 +68291,11 @@
68291 ** 0x00 becomes 0x00000000
68292 ** 0x7f becomes 0x0000007f
68293 ** 0x81 0x00 becomes 0x00000080
68294 ** 0x82 0x00 becomes 0x00000100
68295 ** 0x80 0x7f becomes 0x0000007f
68296 ** 0x81 0x91 0xd1 0xac 0x78 becomes 0x12345678
68297 ** 0x81 0x81 0x81 0x81 0x01 becomes 0x10204081
68298 **
68299 ** Variable length integers are used for rowids and to hold the number of
68300 ** bytes of key and data in a btree cell.
68301 **
@@ -70505,11 +70675,11 @@
70675 if( *pRC ) return;
70676 assert( pCell!=0 );
70677 pPage->xParseCell(pPage, pCell, &info);
70678 if( info.nLocal<info.nPayload ){
70679 Pgno ovfl;
70680 if( SQLITE_OVERFLOW(pSrc->aDataEnd, pCell, pCell+info.nLocal) ){
70681 testcase( pSrc!=pPage );
70682 *pRC = SQLITE_CORRUPT_BKPT;
70683 return;
70684 }
70685 ovfl = get4byte(&pCell[info.nSize-4]);
@@ -73797,11 +73967,10 @@
73967 SQLITE_PRIVATE void sqlite3BtreeCursorUnpin(BtCursor *pCur){
73968 assert( (pCur->curFlags & BTCF_Pinned)!=0 );
73969 pCur->curFlags &= ~BTCF_Pinned;
73970 }
73971
 
73972 /*
73973 ** Return the offset into the database file for the start of the
73974 ** payload to which the cursor is pointing.
73975 */
73976 SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor *pCur){
@@ -73809,11 +73978,10 @@
73978 assert( pCur->eState==CURSOR_VALID );
73979 getCellInfo(pCur);
73980 return (i64)pCur->pBt->pageSize*((i64)pCur->pPage->pgno - 1) +
73981 (i64)(pCur->info.pPayload - pCur->pPage->aData);
73982 }
 
73983
73984 /*
73985 ** Return the number of bytes of payload for the entry that pCur is
73986 ** currently pointing to. For table btrees, this will be the amount
73987 ** of data. For index btrees, this will be the size of the key.
@@ -77666,11 +77834,11 @@
77834 iOvflSpace += sz;
77835 assert( sz<=pBt->maxLocal+23 );
77836 assert( iOvflSpace <= (int)pBt->pageSize );
77837 for(k=0; ALWAYS(k<NB*2) && b.ixNx[k]<=j; k++){}
77838 pSrcEnd = b.apEnd[k];
77839 if( SQLITE_OVERFLOW(pSrcEnd, pCell, pCell+sz) ){
77840 rc = SQLITE_CORRUPT_BKPT;
77841 goto balance_cleanup;
77842 }
77843 rc = insertCell(pParent, nxDiv+i, pCell, sz, pTemp, pNew->pgno);
77844 if( rc!=SQLITE_OK ) goto balance_cleanup;
@@ -81439,10 +81607,44 @@
81607 assert( (pMem->flags & MEM_Dyn)==0 );
81608 pMem->z = pMem->zMalloc;
81609 pMem->flags &= (MEM_Null|MEM_Int|MEM_Real|MEM_IntReal);
81610 return SQLITE_OK;
81611 }
81612
81613 /*
81614 ** If pMem is already a string, detect if it is a zero-terminated
81615 ** string, or make it into one if possible, and mark it as such.
81616 **
81617 ** This is an optimization. Correct operation continues even if
81618 ** this routine is a no-op.
81619 */
81620 SQLITE_PRIVATE void sqlite3VdbeMemZeroTerminateIfAble(Mem *pMem){
81621 if( (pMem->flags & (MEM_Str|MEM_Term|MEM_Ephem|MEM_Static))!=MEM_Str ){
81622 /* pMem must be a string, and it cannot be an ephemeral or static string */
81623 return;
81624 }
81625 if( pMem->enc!=SQLITE_UTF8 ) return;
81626 if( NEVER(pMem->z==0) ) return;
81627 if( pMem->flags & MEM_Dyn ){
81628 if( pMem->xDel==sqlite3_free
81629 && sqlite3_msize(pMem->z) >= (u64)(pMem->n+1)
81630 ){
81631 pMem->z[pMem->n] = 0;
81632 pMem->flags |= MEM_Term;
81633 return;
81634 }
81635 if( pMem->xDel==(void(*)(void*))sqlite3RCStrUnref ){
81636 /* Blindly assume that all RCStr objects are zero-terminated */
81637 pMem->flags |= MEM_Term;
81638 return;
81639 }
81640 }else if( pMem->szMalloc >= pMem->n+1 ){
81641 pMem->z[pMem->n] = 0;
81642 pMem->flags |= MEM_Term;
81643 return;
81644 }
81645 }
81646
81647 /*
81648 ** It is already known that pMem contains an unterminated string.
81649 ** Add the zero terminator.
81650 **
@@ -81929,18 +82131,21 @@
82131 case SQLITE_AFF_REAL: {
82132 sqlite3VdbeMemRealify(pMem);
82133 break;
82134 }
82135 default: {
82136 int rc;
82137 assert( aff==SQLITE_AFF_TEXT );
82138 assert( MEM_Str==(MEM_Blob>>3) );
82139 pMem->flags |= (pMem->flags&MEM_Blob)>>3;
82140 sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
82141 assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
82142 pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal|MEM_Blob|MEM_Zero);
82143 if( encoding!=SQLITE_UTF8 ) pMem->n &= ~1;
82144 rc = sqlite3VdbeChangeEncoding(pMem, encoding);
82145 if( rc ) return rc;
82146 sqlite3VdbeMemZeroTerminateIfAble(pMem);
82147 }
82148 }
82149 return SQLITE_OK;
82150 }
82151
@@ -82459,10 +82664,28 @@
82664 if( pVal->flags&MEM_Null ){
82665 return 0;
82666 }
82667 return valueToText(pVal, enc);
82668 }
82669
82670 /* Return true if sqlit3_value object pVal is a string or blob value
82671 ** that uses the destructor specified in the second argument.
82672 **
82673 ** TODO: Maybe someday promote this interface into a published API so
82674 ** that third-party extensions can get access to it?
82675 */
82676 SQLITE_PRIVATE int sqlite3ValueIsOfClass(const sqlite3_value *pVal, void(*xFree)(void*)){
82677 if( ALWAYS(pVal!=0)
82678 && ALWAYS((pVal->flags & (MEM_Str|MEM_Blob))!=0)
82679 && (pVal->flags & MEM_Dyn)!=0
82680 && pVal->xDel==xFree
82681 ){
82682 return 1;
82683 }else{
82684 return 0;
82685 }
82686 }
82687
82688 /*
82689 ** Create a new sqlite3_value object.
82690 */
82691 SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *db){
@@ -84596,11 +84819,10 @@
84819 if( bUndefine ) sqlite3VdbeChangeP5(pParse->pVdbe, 1);
84820 }
84821 }
84822 #endif /* SQLITE_DEBUG */
84823
 
84824 /*
84825 ** Change the value of the P4 operand for a specific instruction.
84826 ** This routine is useful when a large program is loaded from a
84827 ** static array using sqlite3VdbeAddOpList but we want to make a
84828 ** few minor changes to the program.
@@ -85517,11 +85739,11 @@
85739 if( p->explain==2 ){
85740 sqlite3VdbeMemSetInt64(pMem, pOp->p1);
85741 sqlite3VdbeMemSetInt64(pMem+1, pOp->p2);
85742 sqlite3VdbeMemSetInt64(pMem+2, pOp->p3);
85743 sqlite3VdbeMemSetStr(pMem+3, zP4, -1, SQLITE_UTF8, sqlite3_free);
85744 assert( p->nResColumn==4 );
85745 }else{
85746 sqlite3VdbeMemSetInt64(pMem+0, i);
85747 sqlite3VdbeMemSetStr(pMem+1, (char*)sqlite3OpcodeName(pOp->opcode),
85748 -1, SQLITE_UTF8, SQLITE_STATIC);
85749 sqlite3VdbeMemSetInt64(pMem+2, pOp->p1);
@@ -85536,11 +85758,11 @@
85758 }
85759 #else
85760 sqlite3VdbeMemSetNull(pMem+7);
85761 #endif
85762 sqlite3VdbeMemSetStr(pMem+5, zP4, -1, SQLITE_UTF8, sqlite3_free);
85763 assert( p->nResColumn==8 );
85764 }
85765 p->pResultRow = pMem;
85766 if( db->mallocFailed ){
85767 p->rc = SQLITE_NOMEM;
85768 rc = SQLITE_ERROR;
@@ -85750,30 +85972,13 @@
85972 assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) );
85973
85974 resolveP2Values(p, &nArg);
85975 p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort);
85976 if( pParse->explain ){
 
 
 
 
 
85977 if( nMem<10 ) nMem = 10;
85978 p->explain = pParse->explain;
85979 p->nResColumn = 12 - 4*p->explain;
 
 
 
 
 
 
 
 
 
 
 
 
85980 }
85981 p->expired = 0;
85982
85983 /* Memory for registers, parameters, cursor, etc, is allocated in one or two
85984 ** passes. On the first pass, we try to reuse unused memory at the
@@ -85820,12 +86025,28 @@
86025 ** Close a VDBE cursor and release all the resources that cursor
86026 ** happens to hold.
86027 */
86028 SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
86029 if( pCx ) sqlite3VdbeFreeCursorNN(p,pCx);
86030 }
86031 static SQLITE_NOINLINE void freeCursorWithCache(Vdbe *p, VdbeCursor *pCx){
86032 VdbeTxtBlbCache *pCache = pCx->pCache;
86033 assert( pCx->colCache );
86034 pCx->colCache = 0;
86035 pCx->pCache = 0;
86036 if( pCache->pCValue ){
86037 sqlite3RCStrUnref(pCache->pCValue);
86038 pCache->pCValue = 0;
86039 }
86040 sqlite3DbFree(p->db, pCache);
86041 sqlite3VdbeFreeCursorNN(p, pCx);
86042 }
86043 SQLITE_PRIVATE void sqlite3VdbeFreeCursorNN(Vdbe *p, VdbeCursor *pCx){
86044 if( pCx->colCache ){
86045 freeCursorWithCache(p, pCx);
86046 return;
86047 }
86048 switch( pCx->eCurType ){
86049 case CURTYPE_SORTER: {
86050 sqlite3VdbeSorterClose(p->db, pCx);
86051 break;
86052 }
@@ -85922,16 +86143,16 @@
86143 */
86144 SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
86145 int n;
86146 sqlite3 *db = p->db;
86147
86148 if( p->nResAlloc ){
86149 releaseMemArray(p->aColName, p->nResAlloc*COLNAME_N);
86150 sqlite3DbFree(db, p->aColName);
86151 }
86152 n = nResColumn*COLNAME_N;
86153 p->nResColumn = p->nResAlloc = (u16)nResColumn;
86154 p->aColName = (Mem*)sqlite3DbMallocRawNN(db, sizeof(Mem)*n );
86155 if( p->aColName==0 ) return;
86156 initMemArray(p->aColName, n, db, MEM_Null);
86157 }
86158
@@ -85952,18 +86173,18 @@
86173 const char *zName, /* Pointer to buffer containing name */
86174 void (*xDel)(void*) /* Memory management strategy for zName */
86175 ){
86176 int rc;
86177 Mem *pColName;
86178 assert( idx<p->nResAlloc );
86179 assert( var<COLNAME_N );
86180 if( p->db->mallocFailed ){
86181 assert( !zName || xDel!=SQLITE_DYNAMIC );
86182 return SQLITE_NOMEM_BKPT;
86183 }
86184 assert( p->aColName!=0 );
86185 pColName = &(p->aColName[idx+var*p->nResAlloc]);
86186 rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, xDel);
86187 assert( rc!=0 || !zName || (pColName->flags&MEM_Term)!=0 );
86188 return rc;
86189 }
86190
@@ -86783,11 +87004,11 @@
87004 static void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
87005 SubProgram *pSub, *pNext;
87006 assert( db!=0 );
87007 assert( p->db==0 || p->db==db );
87008 if( p->aColName ){
87009 releaseMemArray(p->aColName, p->nResAlloc*COLNAME_N);
87010 sqlite3DbNNFreeNN(db, p->aColName);
87011 }
87012 for(pSub=p->pProgram; pSub; pSub=pNext){
87013 pNext = pSub->pNext;
87014 vdbeFreeOpArray(db, pSub->aOp, pSub->nOp);
@@ -89092,10 +89313,11 @@
89313 }
89314 if( n>0x7fffffff ){
89315 (void)invokeValueDestructor(z, xDel, pCtx);
89316 }else{
89317 setResultStrOrError(pCtx, z, (int)n, enc, xDel);
89318 sqlite3VdbeMemZeroTerminateIfAble(pCtx->pOut);
89319 }
89320 }
89321 #ifndef SQLITE_OMIT_UTF16
89322 SQLITE_API void sqlite3_result_text16(
89323 sqlite3_context *pCtx,
@@ -89704,11 +89926,12 @@
89926 /*
89927 ** Return the number of columns in the result set for the statement pStmt.
89928 */
89929 SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt){
89930 Vdbe *pVm = (Vdbe *)pStmt;
89931 if( pVm==0 ) return 0;
89932 return pVm->nResColumn;
89933 }
89934
89935 /*
89936 ** Return the number of values available from the current row of the
89937 ** currently executing statement pStmt.
@@ -89877,10 +90100,36 @@
90100 int iType = sqlite3_value_type( columnMem(pStmt,i) );
90101 columnMallocFailure(pStmt);
90102 return iType;
90103 }
90104
90105 /*
90106 ** Column names appropriate for EXPLAIN or EXPLAIN QUERY PLAN.
90107 */
90108 static const char * const azExplainColNames8[] = {
90109 "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment", /* EXPLAIN */
90110 "id", "parent", "notused", "detail" /* EQP */
90111 };
90112 static const u16 azExplainColNames16data[] = {
90113 /* 0 */ 'a', 'd', 'd', 'r', 0,
90114 /* 5 */ 'o', 'p', 'c', 'o', 'd', 'e', 0,
90115 /* 12 */ 'p', '1', 0,
90116 /* 15 */ 'p', '2', 0,
90117 /* 18 */ 'p', '3', 0,
90118 /* 21 */ 'p', '4', 0,
90119 /* 24 */ 'p', '5', 0,
90120 /* 27 */ 'c', 'o', 'm', 'm', 'e', 'n', 't', 0,
90121 /* 35 */ 'i', 'd', 0,
90122 /* 38 */ 'p', 'a', 'r', 'e', 'n', 't', 0,
90123 /* 45 */ 'n', 'o', 't', 'u', 's', 'e', 'd', 0,
90124 /* 53 */ 'd', 'e', 't', 'a', 'i', 'l', 0
90125 };
90126 static const u8 iExplainColNames16[] = {
90127 0, 5, 12, 15, 18, 21, 24, 27,
90128 35, 38, 45, 53
90129 };
90130
90131 /*
90132 ** Convert the N-th element of pStmt->pColName[] into a string using
90133 ** xFunc() then return that string. If N is out of range, return 0.
90134 **
90135 ** There are up to 5 names for each column. useType determines which
@@ -89909,19 +90158,33 @@
90158 if( pStmt==0 ){
90159 (void)SQLITE_MISUSE_BKPT;
90160 return 0;
90161 }
90162 #endif
90163 if( N<0 ) return 0;
90164 ret = 0;
90165 p = (Vdbe *)pStmt;
90166 db = p->db;
90167 assert( db!=0 );
90168 sqlite3_mutex_enter(db->mutex);
90169
90170 if( p->explain ){
90171 if( useType>0 ) goto columnName_end;
90172 n = p->explain==1 ? 8 : 4;
90173 if( N>=n ) goto columnName_end;
90174 if( useUtf16 ){
90175 int i = iExplainColNames16[N + 8*p->explain - 8];
90176 ret = (void*)&azExplainColNames16data[i];
90177 }else{
90178 ret = (void*)azExplainColNames8[N + 8*p->explain - 8];
90179 }
90180 goto columnName_end;
90181 }
90182 n = p->nResColumn;
90183 if( N<n ){
90184 u8 prior_mallocFailed = db->mallocFailed;
90185 N += useType*n;
 
90186 #ifndef SQLITE_OMIT_UTF16
90187 if( useUtf16 ){
90188 ret = sqlite3_value_text16((sqlite3_value*)&p->aColName[N]);
90189 }else
90190 #endif
@@ -89934,12 +90197,13 @@
90197 assert( db->mallocFailed==0 || db->mallocFailed==1 );
90198 if( db->mallocFailed > prior_mallocFailed ){
90199 sqlite3OomClear(db);
90200 ret = 0;
90201 }
 
90202 }
90203 columnName_end:
90204 sqlite3_mutex_leave(db->mutex);
90205 return ret;
90206 }
90207
90208 /*
90209 ** Return the name of the Nth column of the result set returned by SQL
@@ -90391,10 +90655,43 @@
90655 ** statement is an EXPLAIN QUERY PLAN
90656 */
90657 SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt){
90658 return pStmt ? ((Vdbe*)pStmt)->explain : 0;
90659 }
90660
90661 /*
90662 ** Set the explain mode for a statement.
90663 */
90664 SQLITE_API int sqlite3_stmt_explain(sqlite3_stmt *pStmt, int eMode){
90665 Vdbe *v = (Vdbe*)pStmt;
90666 int rc;
90667 sqlite3_mutex_enter(v->db->mutex);
90668 if( v->explain==eMode ){
90669 rc = SQLITE_OK;
90670 }else if( eMode<0 || eMode>2 ){
90671 rc = SQLITE_ERROR;
90672 }else if( (v->prepFlags & SQLITE_PREPARE_SAVESQL)==0 ){
90673 rc = SQLITE_ERROR;
90674 }else if( v->eVdbeState!=VDBE_READY_STATE ){
90675 rc = SQLITE_BUSY;
90676 }else if( v->nMem>=10 && (eMode!=2 || v->haveEqpOps) ){
90677 /* No reprepare necessary */
90678 v->explain = eMode;
90679 rc = SQLITE_OK;
90680 }else{
90681 v->explain = eMode;
90682 rc = sqlite3Reprepare(v);
90683 v->haveEqpOps = eMode==2;
90684 }
90685 if( v->explain ){
90686 v->nResColumn = 12 - 4*v->explain;
90687 }else{
90688 v->nResColumn = v->nResAlloc;
90689 }
90690 sqlite3_mutex_leave(v->db->mutex);
90691 return rc;
90692 }
90693
90694 /*
90695 ** Return true if the prepared statement is in need of being reset.
90696 */
90697 SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
@@ -91631,10 +91928,13 @@
91928 for(j=0; j<25 && j<pMem->n; j++){
91929 c = pMem->z[j];
91930 sqlite3_str_appendchar(pStr, 1, (c>=0x20&&c<=0x7f) ? c : '.');
91931 }
91932 sqlite3_str_appendf(pStr, "]%s", encnames[pMem->enc]);
91933 if( f & MEM_Term ){
91934 sqlite3_str_appendf(pStr, "(0-term)");
91935 }
91936 }
91937 }
91938 #endif
91939
91940 #ifdef SQLITE_DEBUG
@@ -91766,10 +92066,97 @@
92066 h += 4093 + (p->flags & (MEM_Str|MEM_Blob));
92067 }
92068 }
92069 return h;
92070 }
92071
92072
92073 /*
92074 ** For OP_Column, factor out the case where content is loaded from
92075 ** overflow pages, so that the code to implement this case is separate
92076 ** the common case where all content fits on the page. Factoring out
92077 ** the code reduces register pressure and helps the common case
92078 ** to run faster.
92079 */
92080 static SQLITE_NOINLINE int vdbeColumnFromOverflow(
92081 VdbeCursor *pC, /* The BTree cursor from which we are reading */
92082 int iCol, /* The column to read */
92083 int t, /* The serial-type code for the column value */
92084 i64 iOffset, /* Offset to the start of the content value */
92085 u32 cacheStatus, /* Current Vdbe.cacheCtr value */
92086 u32 colCacheCtr, /* Current value of the column cache counter */
92087 Mem *pDest /* Store the value into this register. */
92088 ){
92089 int rc;
92090 sqlite3 *db = pDest->db;
92091 int encoding = pDest->enc;
92092 int len = sqlite3VdbeSerialTypeLen(t);
92093 assert( pC->eCurType==CURTYPE_BTREE );
92094 if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) return SQLITE_TOOBIG;
92095 if( len > 4000 && pC->pKeyInfo==0 ){
92096 /* Cache large column values that are on overflow pages using
92097 ** an RCStr (reference counted string) so that if they are reloaded,
92098 ** that do not have to be copied a second time. The overhead of
92099 ** creating and managing the cache is such that this is only
92100 ** profitable for larger TEXT and BLOB values.
92101 **
92102 ** Only do this on table-btrees so that writes to index-btrees do not
92103 ** need to clear the cache. This buys performance in the common case
92104 ** in exchange for generality.
92105 */
92106 VdbeTxtBlbCache *pCache;
92107 char *pBuf;
92108 if( pC->colCache==0 ){
92109 pC->pCache = sqlite3DbMallocZero(db, sizeof(VdbeTxtBlbCache) );
92110 if( pC->pCache==0 ) return SQLITE_NOMEM;
92111 pC->colCache = 1;
92112 }
92113 pCache = pC->pCache;
92114 if( pCache->pCValue==0
92115 || pCache->iCol!=iCol
92116 || pCache->cacheStatus!=cacheStatus
92117 || pCache->colCacheCtr!=colCacheCtr
92118 || pCache->iOffset!=sqlite3BtreeOffset(pC->uc.pCursor)
92119 ){
92120 if( pCache->pCValue ) sqlite3RCStrUnref(pCache->pCValue);
92121 pBuf = pCache->pCValue = sqlite3RCStrNew( len+3 );
92122 if( pBuf==0 ) return SQLITE_NOMEM;
92123 rc = sqlite3BtreePayload(pC->uc.pCursor, iOffset, len, pBuf);
92124 if( rc ) return rc;
92125 pBuf[len] = 0;
92126 pBuf[len+1] = 0;
92127 pBuf[len+2] = 0;
92128 pCache->iCol = iCol;
92129 pCache->cacheStatus = cacheStatus;
92130 pCache->colCacheCtr = colCacheCtr;
92131 pCache->iOffset = sqlite3BtreeOffset(pC->uc.pCursor);
92132 }else{
92133 pBuf = pCache->pCValue;
92134 }
92135 assert( t>=12 );
92136 sqlite3RCStrRef(pBuf);
92137 if( t&1 ){
92138 rc = sqlite3VdbeMemSetStr(pDest, pBuf, len, encoding,
92139 (void(*)(void*))sqlite3RCStrUnref);
92140 pDest->flags |= MEM_Term;
92141 }else{
92142 rc = sqlite3VdbeMemSetStr(pDest, pBuf, len, 0,
92143 (void(*)(void*))sqlite3RCStrUnref);
92144 }
92145 }else{
92146 rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, iOffset, len, pDest);
92147 if( rc ) return rc;
92148 sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest);
92149 if( (t&1)!=0 && encoding==SQLITE_UTF8 ){
92150 pDest->z[len] = 0;
92151 pDest->flags |= MEM_Term;
92152 }
92153 }
92154 pDest->flags &= ~MEM_Ephem;
92155 return rc;
92156 }
92157
92158
92159 /*
92160 ** Return the symbolic name for the data type of a pMem
92161 */
92162 static const char *vdbeMemTypeName(Mem *pMem){
@@ -91809,10 +92196,11 @@
92196 Mem *aMem = p->aMem; /* Copy of p->aMem */
92197 Mem *pIn1 = 0; /* 1st input operand */
92198 Mem *pIn2 = 0; /* 2nd input operand */
92199 Mem *pIn3 = 0; /* 3rd input operand */
92200 Mem *pOut = 0; /* Output operand */
92201 u32 colCacheCtr = 0; /* Column cache counter */
92202 #if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE)
92203 u64 *pnCycle = 0;
92204 int bStmtScanStatus = IS_STMT_SCANSTATUS(db)!=0;
92205 #endif
92206 /*** INSERT STACK UNION HERE ***/
@@ -94133,10 +94521,11 @@
94521 pDest->flags = aFlag[t&1];
94522 }
94523 }else{
94524 u8 p5;
94525 pDest->enc = encoding;
94526 assert( pDest->db==db );
94527 /* This branch happens only when content is on overflow pages */
94528 if( ((p5 = (pOp->p5 & OPFLAG_BYTELENARG))!=0
94529 && (p5==OPFLAG_TYPEOFARG
94530 || (t>=12 && ((t&1)==0 || p5==OPFLAG_BYTELENARG))
94531 )
@@ -94156,15 +94545,17 @@
94545 ** as that array is 256 bytes long (plenty for VdbeMemPrettyPrint())
94546 ** and it begins with a bunch of zeros.
94547 */
94548 sqlite3VdbeSerialGet((u8*)sqlite3CtypeMap, t, pDest);
94549 }else{
94550 rc = vdbeColumnFromOverflow(pC, p2, t, aOffset[p2],
94551 p->cacheCtr, colCacheCtr, pDest);
94552 if( rc ){
94553 if( rc==SQLITE_NOMEM ) goto no_mem;
94554 if( rc==SQLITE_TOOBIG ) goto too_big;
94555 goto abort_due_to_error;
94556 }
94557 }
94558 }
94559
94560 op_column_out:
94561 UPDATE_MAX_BLOBSIZE(pDest);
@@ -96693,10 +97084,11 @@
97084 (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION|OPFLAG_PREFORMAT)),
97085 seekResult
97086 );
97087 pC->deferredMoveto = 0;
97088 pC->cacheStatus = CACHE_STALE;
97089 colCacheCtr++;
97090
97091 /* Invoke the update-hook if required. */
97092 if( rc ) goto abort_due_to_error;
97093 if( pTab ){
97094 assert( db->xUpdateCallback!=0 );
@@ -96853,10 +97245,11 @@
97245 }
97246 #endif
97247
97248 rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5);
97249 pC->cacheStatus = CACHE_STALE;
97250 colCacheCtr++;
97251 pC->seekResult = 0;
97252 if( rc ) goto abort_due_to_error;
97253
97254 /* Invoke the update-hook if required. */
97255 if( opflags & OPFLAG_NCHANGE ){
@@ -103347,10 +103740,12 @@
103740 "p3 INT,"
103741 "p4 TEXT,"
103742 "p5 INT,"
103743 "comment TEXT,"
103744 "subprog TEXT,"
103745 "nexec INT,"
103746 "ncycle INT,"
103747 "stmt HIDDEN"
103748 ");",
103749
103750 /* Tables_used() schema */
103751 "CREATE TABLE x("
@@ -103509,11 +103904,11 @@
103904 pCur->zType = "index";
103905 }
103906 }
103907 }
103908 }
103909 i += 20;
103910 }
103911 }
103912 switch( i ){
103913 case 0: /* addr */
103914 sqlite3_result_int(ctx, pCur->iAddr);
@@ -103559,20 +103954,35 @@
103954 }else{
103955 sqlite3_result_text(ctx, "(FK)", 4, SQLITE_STATIC);
103956 }
103957 break;
103958 }
103959
103960 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
103961 case 9: /* nexec */
103962 sqlite3_result_int(ctx, pOp->nExec);
103963 break;
103964 case 10: /* ncycle */
103965 sqlite3_result_int(ctx, pOp->nCycle);
103966 break;
103967 #else
103968 case 9: /* nexec */
103969 case 10: /* ncycle */
103970 sqlite3_result_int(ctx, 0);
103971 break;
103972 #endif
103973
103974 case 20: /* tables_used.type */
103975 sqlite3_result_text(ctx, pCur->zType, -1, SQLITE_STATIC);
103976 break;
103977 case 21: /* tables_used.schema */
103978 sqlite3_result_text(ctx, pCur->zSchema, -1, SQLITE_STATIC);
103979 break;
103980 case 22: /* tables_used.name */
103981 sqlite3_result_text(ctx, pCur->zName, -1, SQLITE_STATIC);
103982 break;
103983 case 23: /* tables_used.wr */
103984 sqlite3_result_int(ctx, pOp->opcode==OP_OpenWrite);
103985 break;
103986 }
103987 return SQLITE_OK;
103988 }
@@ -103642,11 +104052,11 @@
104052 ){
104053 int i;
104054 int rc = SQLITE_CONSTRAINT;
104055 struct sqlite3_index_constraint *p;
104056 bytecodevtab *pVTab = (bytecodevtab*)tab;
104057 int iBaseCol = pVTab->bTablesUsed ? 4 : 10;
104058 pIdxInfo->estimatedCost = (double)100;
104059 pIdxInfo->estimatedRows = 100;
104060 pIdxInfo->idxNum = 0;
104061 for(i=0, p=pIdxInfo->aConstraint; i<pIdxInfo->nConstraint; i++, p++){
104062 if( p->usable==0 ) continue;
@@ -111269,12 +111679,11 @@
111679 testcase( (pDef->funcFlags & OPFLAG_BYTELENARG)==OPFLAG_BYTELENARG);
111680 pFarg->a[0].pExpr->op2 = pDef->funcFlags & OPFLAG_BYTELENARG;
111681 }
111682 }
111683
111684 sqlite3ExprCodeExprList(pParse, pFarg, r1, 0, SQLITE_ECEL_FACTOR);
 
111685 }else{
111686 r1 = 0;
111687 }
111688 #ifndef SQLITE_OMIT_VIRTUALTABLE
111689 /* Possibly overload the function if the first argument is
@@ -125336,11 +125745,12 @@
125745 */
125746 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0,0,wcf,iTabCur+1);
125747 if( pWInfo==0 ) goto delete_from_cleanup;
125748 eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
125749 assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI );
125750 assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF
125751 || OptimizationDisabled(db, SQLITE_OnePass) );
125752 if( eOnePass!=ONEPASS_SINGLE ) sqlite3MultiWrite(pParse);
125753 if( sqlite3WhereUsesDeferredSeek(pWInfo) ){
125754 sqlite3VdbeAddOp1(v, OP_FinishSeek, iTabCur);
125755 }
125756
@@ -127068,10 +127478,11 @@
127478 *zOut++ = 0x80 + (u8)((c>>12) & 0x3F);
127479 *zOut++ = 0x80 + (u8)((c>>6) & 0x3F);
127480 *zOut++ = 0x80 + (u8)(c & 0x3F);
127481 } \
127482 }
127483 *zOut = 0;
127484 sqlite3_result_text64(context, (char*)z, zOut-z, sqlite3_free, SQLITE_UTF8);
127485 }
127486
127487 /*
127488 ** The hex() function. Interpret the argument as a blob. Return
@@ -127605,15 +128016,14 @@
128016 p->iSum = x;
128017 }else{
128018 p->ovrfl = 1;
128019 kahanBabuskaNeumaierInit(p, p->iSum);
128020 p->approx = 1;
128021 kahanBabuskaNeumaierStepInt64(p, sqlite3_value_int64(argv[0]));
128022 }
128023 }
128024 }else{
 
128025 if( type==SQLITE_INTEGER ){
128026 kahanBabuskaNeumaierStepInt64(p, sqlite3_value_int64(argv[0]));
128027 }else{
128028 p->ovrfl = 0;
128029 kahanBabuskaNeumaierStep(p, sqlite3_value_double(argv[0]));
@@ -139192,11 +139602,16 @@
139602 memset(PARSE_HDR(&sParse), 0, PARSE_HDR_SZ);
139603 memset(PARSE_TAIL(&sParse), 0, PARSE_TAIL_SZ);
139604 sParse.pOuterParse = db->pParse;
139605 db->pParse = &sParse;
139606 sParse.db = db;
139607 if( pReprepare ){
139608 sParse.pReprepare = pReprepare;
139609 sParse.explain = sqlite3_stmt_isexplain((sqlite3_stmt*)pReprepare);
139610 }else{
139611 assert( sParse.pReprepare==0 );
139612 }
139613 assert( ppStmt && *ppStmt==0 );
139614 if( db->mallocFailed ){
139615 sqlite3ErrorMsg(&sParse, "out of memory");
139616 db->errCode = rc = SQLITE_NOMEM;
139617 goto end_prepare;
@@ -141671,17 +142086,10 @@
142086 ExprList *pEList;
142087 sqlite3 *db = pParse->db;
142088 int fullName; /* TABLE.COLUMN if no AS clause and is a direct table ref */
142089 int srcName; /* COLUMN or TABLE.COLUMN if no AS clause and is direct */
142090
 
 
 
 
 
 
 
142091 if( pParse->colNamesSet ) return;
142092 /* Column names are determined by the left-most term of a compound select */
142093 while( pSelect->pPrior ) pSelect = pSelect->pPrior;
142094 TREETRACE(0x80,pParse,pSelect,("generating column names\n"));
142095 pTabList = pSelect->pSrc;
@@ -143869,11 +144277,12 @@
144277 ** is the first element of the parent query. Two subcases:
144278 ** (27a) the subquery is not a compound query.
144279 ** (27b) the subquery is a compound query and the RIGHT JOIN occurs
144280 ** in any arm of the compound query. (See also (17g).)
144281 **
144282 ** (28) The subquery is not a MATERIALIZED CTE. (This is handled
144283 ** in the caller before ever reaching this routine.)
144284 **
144285 **
144286 ** In this routine, the "p" parameter is a pointer to the outer query.
144287 ** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query
144288 ** uses aggregates.
@@ -143979,13 +144388,13 @@
144388
144389 assert( pSubSrc->nSrc>0 ); /* True by restriction (7) */
144390 if( iFrom>0 && (pSubSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){
144391 return 0; /* Restriction (27a) */
144392 }
144393
144394 /* Condition (28) is blocked by the caller */
144395 assert( !pSubitem->fg.isCte || pSubitem->u2.pCteUse->eM10d!=M10d_Yes );
144396
144397 /* Restriction (17): If the sub-query is a compound SELECT, then it must
144398 ** use only the UNION ALL operator. And none of the simple select queries
144399 ** that make up the compound SELECT are allowed to be aggregate or distinct
144400 ** queries.
@@ -146861,10 +147270,18 @@
147270 if( pTab->nCol!=pSub->pEList->nExpr ){
147271 sqlite3ErrorMsg(pParse, "expected %d columns for '%s' but got %d",
147272 pTab->nCol, pTab->zName, pSub->pEList->nExpr);
147273 goto select_end;
147274 }
147275
147276 /* Do not attempt the usual optimizations (flattening and ORDER BY
147277 ** elimination) on a MATERIALIZED common table expression because
147278 ** a MATERIALIZED common table expression is an optimization fence.
147279 */
147280 if( pItem->fg.isCte && pItem->u2.pCteUse->eM10d==M10d_Yes ){
147281 continue;
147282 }
147283
147284 /* Do not try to flatten an aggregate subquery.
147285 **
147286 ** Flattening an aggregate subquery is only possible if the outer query
147287 ** is not a join. But if the outer query is not a join, then the subquery
@@ -146891,10 +147308,12 @@
147308 ** (5) The ORDER BY isn't going to accomplish anything because
147309 ** one of:
147310 ** (a) The outer query has a different ORDER BY clause
147311 ** (b) The subquery is part of a join
147312 ** See forum post 062d576715d277c8
147313 **
147314 ** Also retain the ORDER BY if the OmitOrderBy optimization is disabled.
147315 */
147316 if( pSub->pOrderBy!=0
147317 && (p->pOrderBy!=0 || pTabList->nSrc>1) /* Condition (5) */
147318 && pSub->pLimit==0 /* Condition (1) */
147319 && (pSub->selFlags & SF_OrderByReqd)==0 /* Condition (2) */
@@ -150394,11 +150813,11 @@
150813 if( !pParse->nested
150814 && !pTrigger
150815 && !hasFK
150816 && !chngKey
150817 && !bReplace
150818 && (pWhere==0 || !ExprHasProperty(pWhere, EP_Subquery))
150819 ){
150820 flags |= WHERE_ONEPASS_MULTIROW;
150821 }
150822 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,0,0,0,flags,iIdxCur);
150823 if( pWInfo==0 ) goto update_cleanup;
@@ -160954,11 +161373,11 @@
161373 return 0; /* Discard pTemplate */
161374 }
161375
161376 /* If pTemplate is always better than p, then cause p to be overwritten
161377 ** with pTemplate. pTemplate is better than p if:
161378 ** (1) pTemplate has no more dependencies than p, and
161379 ** (2) pTemplate has an equal or lower cost than p.
161380 */
161381 if( (p->prereq & pTemplate->prereq)==pTemplate->prereq /* (1) */
161382 && p->rRun>=pTemplate->rRun /* (2a) */
161383 && p->nOut>=pTemplate->nOut /* (2b) */
@@ -163422,11 +163841,12 @@
163841 /* TUNING: For simple queries, only the best path is tracked.
163842 ** For 2-way joins, the 5 best paths are followed.
163843 ** For joins of 3 or more tables, track the 10 best paths */
163844 mxChoice = (nLoop<=1) ? 1 : (nLoop==2 ? 5 : 10);
163845 assert( nLoop<=pWInfo->pTabList->nSrc );
163846 WHERETRACE(0x002, ("---- begin solver. (nRowEst=%d, nQueryLoop=%d)\n",
163847 nRowEst, pParse->nQueryLoop));
163848
163849 /* If nRowEst is zero and there is an ORDER BY clause, ignore it. In this
163850 ** case the purpose of this call is to estimate the number of rows returned
163851 ** by the overall query. Once this estimate has been obtained, the caller
163852 ** will invoke this function a second time, passing the estimate as the
@@ -163541,13 +163961,14 @@
163961 rUnsorted -= 2; /* TUNING: Slight bias in favor of no-sort plans */
163962 }
163963
163964 /* TUNING: A full-scan of a VIEW or subquery in the outer loop
163965 ** is not so bad. */
163966 if( iLoop==0 && (pWLoop->wsFlags & WHERE_VIEWSCAN)!=0 && nLoop>1 ){
163967 rCost += -10;
163968 nOut += -30;
163969 WHERETRACE(0x80,("VIEWSCAN cost reduction for %c\n",pWLoop->cId));
163970 }
163971
163972 /* Check to see if pWLoop should be added to the set of
163973 ** mxChoice best-so-far paths.
163974 **
@@ -164174,10 +164595,32 @@
164595 if( p->pIENext==0 ){
164596 sqlite3ParserAddCleanup(pParse, whereIndexedExprCleanup, pParse);
164597 }
164598 }
164599 }
164600
164601 /*
164602 ** Set the reverse-scan order mask to one for all tables in the query
164603 ** with the exception of MATERIALIZED common table expressions that have
164604 ** their own internal ORDER BY clauses.
164605 **
164606 ** This implements the PRAGMA reverse_unordered_selects=ON setting.
164607 ** (Also SQLITE_DBCONFIG_REVERSE_SCANORDER).
164608 */
164609 static SQLITE_NOINLINE void whereReverseScanOrder(WhereInfo *pWInfo){
164610 int ii;
164611 for(ii=0; ii<pWInfo->pTabList->nSrc; ii++){
164612 SrcItem *pItem = &pWInfo->pTabList->a[ii];
164613 if( !pItem->fg.isCte
164614 || pItem->u2.pCteUse->eM10d!=M10d_Yes
164615 || NEVER(pItem->pSelect==0)
164616 || pItem->pSelect->pOrderBy==0
164617 ){
164618 pWInfo->revMask |= MASKBIT(ii);
164619 }
164620 }
164621 }
164622
164623 /*
164624 ** Generate the beginning of the loop used for WHERE clause processing.
164625 ** The return value is a pointer to an opaque structure that contains
164626 ** information needed to terminate the loop. Later, the calling routine
@@ -164539,12 +164982,13 @@
164982 if( pWInfo->pOrderBy ){
164983 wherePathSolver(pWInfo, pWInfo->nRowOut+1);
164984 if( db->mallocFailed ) goto whereBeginError;
164985 }
164986 }
164987 assert( pWInfo->pTabList!=0 );
164988 if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){
164989 whereReverseScanOrder(pWInfo);
164990 }
164991 if( pParse->nErr ){
164992 goto whereBeginError;
164993 }
164994 assert( db->mallocFailed==0 );
@@ -164640,10 +165084,11 @@
165084 assert( !(wsFlags & WHERE_VIRTUALTABLE) || IsVirtual(pTabList->a[0].pTab) );
165085 if( bOnerow || (
165086 0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW)
165087 && !IsVirtual(pTabList->a[0].pTab)
165088 && (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK))
165089 && OptimizationEnabled(db, SQLITE_OnePass)
165090 )){
165091 pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI;
165092 if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){
165093 if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){
165094 bFordelete = OPFLAG_FORDELETE;
@@ -171937,14 +172382,14 @@
172382 ** break;
172383 */
172384 /********** Begin reduce actions **********************************************/
172385 YYMINORTYPE yylhsminor;
172386 case 0: /* explain ::= EXPLAIN */
172387 { if( pParse->pReprepare==0 ) pParse->explain = 1; }
172388 break;
172389 case 1: /* explain ::= EXPLAIN QUERY PLAN */
172390 { if( pParse->pReprepare==0 ) pParse->explain = 2; }
172391 break;
172392 case 2: /* cmdx ::= cmd */
172393 { sqlite3FinishCoding(pParse); }
172394 break;
172395 case 3: /* cmd ::= BEGIN transtype trans_opt */
@@ -200394,28 +200839,54 @@
200839 ** Growing our own isspace() routine this way is twice as fast as
200840 ** the library isspace() function, resulting in a 7% overall performance
200841 ** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os).
200842 */
200843 static const char jsonIsSpace[] = {
200844 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
200845 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200846 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200847 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200848 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200849 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200850 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200851 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200852
200853 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200854 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200855 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200856 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200857 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200858 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200859 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200860 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200861 };
200862 #define fast_isspace(x) (jsonIsSpace[(unsigned char)x])
200863
200864 /*
200865 ** Characters that are special to JSON. Control charaters,
200866 ** '"' and '\\'.
200867 */
200868 static const char jsonIsOk[256] = {
200869 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200870 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200871 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
200872 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
200873 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
200874 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
200875 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
200876 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
200877
200878 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
200879 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
200880 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
200881 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
200882 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
200883 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
200884 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
200885 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
200886 };
200887
200888
200889 #if !defined(SQLITE_DEBUG) && !defined(SQLITE_COVERAGE_TEST)
200890 # define VVA(X)
200891 #else
200892 # define VVA(X) X
@@ -200423,10 +200894,11 @@
200894
200895 /* Objects */
200896 typedef struct JsonString JsonString;
200897 typedef struct JsonNode JsonNode;
200898 typedef struct JsonParse JsonParse;
200899 typedef struct JsonCleanup JsonCleanup;
200900
200901 /* An instance of this object represents a JSON string
200902 ** under construction. Really, this is a generic string accumulator
200903 ** that can be and is used to create strings other than JSON.
200904 */
@@ -200437,75 +200909,120 @@
200909 u64 nUsed; /* Bytes of zBuf[] currently used */
200910 u8 bStatic; /* True if zBuf is static space */
200911 u8 bErr; /* True if an error has been encountered */
200912 char zSpace[100]; /* Initial static space */
200913 };
200914
200915 /* A deferred cleanup task. A list of JsonCleanup objects might be
200916 ** run when the JsonParse object is destroyed.
200917 */
200918 struct JsonCleanup {
200919 JsonCleanup *pJCNext; /* Next in a list */
200920 void (*xOp)(void*); /* Routine to run */
200921 void *pArg; /* Argument to xOp() */
200922 };
200923
200924 /* JSON type values
200925 */
200926 #define JSON_SUBST 0 /* Special edit node. Uses u.iPrev */
200927 #define JSON_NULL 1
200928 #define JSON_TRUE 2
200929 #define JSON_FALSE 3
200930 #define JSON_INT 4
200931 #define JSON_REAL 5
200932 #define JSON_STRING 6
200933 #define JSON_ARRAY 7
200934 #define JSON_OBJECT 8
200935
200936 /* The "subtype" set for JSON values */
200937 #define JSON_SUBTYPE 74 /* Ascii for "J" */
200938
200939 /*
200940 ** Names of the various JSON types:
200941 */
200942 static const char * const jsonType[] = {
200943 "subst",
200944 "null", "true", "false", "integer", "real", "text", "array", "object"
200945 };
200946
200947 /* Bit values for the JsonNode.jnFlag field
200948 */
200949 #define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */
200950 #define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */
200951 #define JNODE_REMOVE 0x04 /* Do not output */
200952 #define JNODE_REPLACE 0x08 /* Target of a JSON_SUBST node */
200953 #define JNODE_APPEND 0x10 /* More ARRAY/OBJECT entries at u.iAppend */
200954 #define JNODE_LABEL 0x20 /* Is a label of an object */
200955 #define JNODE_JSON5 0x40 /* Node contains JSON5 enhancements */
 
200956
200957
200958 /* A single node of parsed JSON. An array of these nodes describes
200959 ** a parse of JSON + edits.
200960 **
200961 ** Use the json_parse() SQL function (available when compiled with
200962 ** -DSQLITE_DEBUG) to see a dump of complete JsonParse objects, including
200963 ** a complete listing and decoding of the array of JsonNodes.
200964 */
200965 struct JsonNode {
200966 u8 eType; /* One of the JSON_ type values */
200967 u8 jnFlags; /* JNODE flags */
200968 u8 eU; /* Which union element to use */
200969 u32 n; /* Bytes of content for INT, REAL or STRING
200970 ** Number of sub-nodes for ARRAY and OBJECT
200971 ** Node that SUBST applies to */
200972 union {
200973 const char *zJContent; /* 1: Content for INT, REAL, and STRING */
200974 u32 iAppend; /* 2: More terms for ARRAY and OBJECT */
200975 u32 iKey; /* 3: Key for ARRAY objects in json_tree() */
200976 u32 iPrev; /* 4: Previous SUBST node, or 0 */
 
200977 } u;
200978 };
200979
200980
200981 /* A parsed and possibly edited JSON string. Lifecycle:
200982 **
200983 ** 1. JSON comes in and is parsed into an array aNode[]. The original
200984 ** JSON text is stored in zJson.
200985 **
200986 ** 2. Zero or more changes are made (via json_remove() or json_replace()
200987 ** or similar) to the aNode[] array.
200988 **
200989 ** 3. A new, edited and mimified JSON string is generated from aNode
200990 ** and stored in zAlt. The JsonParse object always owns zAlt.
200991 **
200992 ** Step 1 always happens. Step 2 and 3 may or may not happen, depending
200993 ** on the operation.
200994 **
200995 ** aNode[].u.zJContent entries typically point into zJson. Hence zJson
200996 ** must remain valid for the lifespan of the parse. For edits,
200997 ** aNode[].u.zJContent might point to malloced space other than zJson.
200998 ** Entries in pClup are responsible for freeing that extra malloced space.
200999 **
201000 ** When walking the parse tree in aNode[], edits are ignored if useMod is
201001 ** false.
201002 */
201003 struct JsonParse {
201004 u32 nNode; /* Number of slots of aNode[] used */
201005 u32 nAlloc; /* Number of slots of aNode[] allocated */
201006 JsonNode *aNode; /* Array of nodes containing the parse */
201007 char *zJson; /* Original JSON string (before edits) */
201008 char *zAlt; /* Revised and/or mimified JSON */
201009 u32 *aUp; /* Index of parent of each node */
201010 JsonCleanup *pClup;/* Cleanup operations prior to freeing this object */
201011 u16 iDepth; /* Nesting depth */
201012 u8 nErr; /* Number of errors seen */
201013 u8 oom; /* Set to true if out of memory */
201014 u8 bJsonIsRCStr; /* True if zJson is an RCStr */
201015 u8 hasNonstd; /* True if input uses non-standard features like JSON5 */
201016 u8 useMod; /* Actually use the edits contain inside aNode */
201017 u8 hasMod; /* aNode contains edits from the original zJson */
201018 u32 nJPRef; /* Number of references to this object */
201019 int nJson; /* Length of the zJson string in bytes */
201020 int nAlt; /* Length of alternative JSON string zAlt, in bytes */
201021 u32 iErr; /* Error location in zJson[] */
201022 u32 iSubst; /* Last JSON_SUBST entry in aNode[] */
201023 u32 iHold; /* Age of this entry in the cache for LRU replacement */
201024 };
201025
201026 /*
201027 ** Maximum nesting depth of JSON for this implementation.
201028 **
@@ -200534,19 +201051,17 @@
201051 p->pCtx = pCtx;
201052 p->bErr = 0;
201053 jsonZero(p);
201054 }
201055
 
201056 /* Free all allocated memory and reset the JsonString object back to its
201057 ** initial state.
201058 */
201059 static void jsonReset(JsonString *p){
201060 if( !p->bStatic ) sqlite3RCStrUnref(p->zBuf);
201061 jsonZero(p);
201062 }
 
201063
201064 /* Report an out-of-memory (OOM) condition
201065 */
201066 static void jsonOom(JsonString *p){
201067 p->bErr = 1;
@@ -200560,38 +201075,61 @@
201075 static int jsonGrow(JsonString *p, u32 N){
201076 u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10;
201077 char *zNew;
201078 if( p->bStatic ){
201079 if( p->bErr ) return 1;
201080 zNew = sqlite3RCStrNew(nTotal);
201081 if( zNew==0 ){
201082 jsonOom(p);
201083 return SQLITE_NOMEM;
201084 }
201085 memcpy(zNew, p->zBuf, (size_t)p->nUsed);
201086 p->zBuf = zNew;
201087 p->bStatic = 0;
201088 }else{
201089 p->zBuf = sqlite3RCStrResize(p->zBuf, nTotal);
201090 if( p->zBuf==0 ){
201091 p->bErr = 1;
201092 jsonZero(p);
201093 return SQLITE_NOMEM;
201094 }
 
201095 }
201096 p->nAlloc = nTotal;
201097 return SQLITE_OK;
201098 }
201099
201100 /* Append N bytes from zIn onto the end of the JsonString string.
201101 */
201102 static SQLITE_NOINLINE void jsonAppendExpand(
201103 JsonString *p,
201104 const char *zIn,
201105 u32 N
201106 ){
201107 assert( N>0 );
201108 if( jsonGrow(p,N) ) return;
201109 memcpy(p->zBuf+p->nUsed, zIn, N);
201110 p->nUsed += N;
201111 }
201112 static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
201113 if( N==0 ) return;
201114 if( N+p->nUsed >= p->nAlloc ){
201115 jsonAppendExpand(p,zIn,N);
201116 }else{
201117 memcpy(p->zBuf+p->nUsed, zIn, N);
201118 p->nUsed += N;
201119 }
201120 }
201121 static void jsonAppendRawNZ(JsonString *p, const char *zIn, u32 N){
201122 assert( N>0 );
201123 if( N+p->nUsed >= p->nAlloc ){
201124 jsonAppendExpand(p,zIn,N);
201125 }else{
201126 memcpy(p->zBuf+p->nUsed, zIn, N);
201127 p->nUsed += N;
201128 }
201129 }
201130
201131
201132 /* Append formatted text (not to exceed N bytes) to the JsonString.
201133 */
201134 static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){
201135 va_list ap;
@@ -200602,23 +201140,49 @@
201140 p->nUsed += (int)strlen(p->zBuf+p->nUsed);
201141 }
201142
201143 /* Append a single character
201144 */
201145 static SQLITE_NOINLINE void jsonAppendCharExpand(JsonString *p, char c){
201146 if( jsonGrow(p,1) ) return;
201147 p->zBuf[p->nUsed++] = c;
201148 }
201149 static void jsonAppendChar(JsonString *p, char c){
201150 if( p->nUsed>=p->nAlloc ){
201151 jsonAppendCharExpand(p,c);
201152 }else{
201153 p->zBuf[p->nUsed++] = c;
201154 }
201155 }
201156
201157 /* Try to force the string to be a zero-terminated RCStr string.
201158 **
201159 ** Return true on success. Return false if an OOM prevents this
201160 ** from happening.
201161 */
201162 static int jsonForceRCStr(JsonString *p){
201163 jsonAppendChar(p, 0);
201164 if( p->bErr ) return 0;
201165 p->nUsed--;
201166 if( p->bStatic==0 ) return 1;
201167 p->nAlloc = 0;
201168 p->nUsed++;
201169 jsonGrow(p, p->nUsed);
201170 p->nUsed--;
201171 return p->bStatic==0;
201172 }
201173
201174
201175 /* Append a comma separator to the output buffer, if the previous
201176 ** character is not '[' or '{'.
201177 */
201178 static void jsonAppendSeparator(JsonString *p){
201179 char c;
201180 if( p->nUsed==0 ) return;
201181 c = p->zBuf[p->nUsed-1];
201182 if( c=='[' || c=='{' ) return;
201183 jsonAppendChar(p, ',');
201184 }
201185
201186 /* Append the N-byte string in zIn to the end of the JsonString string
201187 ** under construction. Enclose the string in "..." and escape
201188 ** any double-quotes or backslash characters contained within the
@@ -200628,15 +201192,20 @@
201192 u32 i;
201193 if( zIn==0 || ((N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0) ) return;
201194 p->zBuf[p->nUsed++] = '"';
201195 for(i=0; i<N; i++){
201196 unsigned char c = ((unsigned const char*)zIn)[i];
201197 if( jsonIsOk[c] ){
201198 p->zBuf[p->nUsed++] = c;
201199 }else if( c=='"' || c=='\\' ){
201200 json_simple_escape:
201201 if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return;
201202 p->zBuf[p->nUsed++] = '\\';
201203 p->zBuf[p->nUsed++] = c;
201204 }else if( c=='\'' ){
201205 p->zBuf[p->nUsed++] = c;
201206 }else{
201207 static const char aSpecial[] = {
201208 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0,
201209 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
201210 };
201211 assert( sizeof(aSpecial)==32 );
@@ -200643,23 +201212,23 @@
201212 assert( aSpecial['\b']=='b' );
201213 assert( aSpecial['\f']=='f' );
201214 assert( aSpecial['\n']=='n' );
201215 assert( aSpecial['\r']=='r' );
201216 assert( aSpecial['\t']=='t' );
201217 assert( c>=0 && c<sizeof(aSpecial) );
201218 if( aSpecial[c] ){
201219 c = aSpecial[c];
201220 goto json_simple_escape;
201221 }
201222 if( (p->nUsed+N+7+i > p->nAlloc) && jsonGrow(p,N+7-i)!=0 ) return;
201223 p->zBuf[p->nUsed++] = '\\';
201224 p->zBuf[p->nUsed++] = 'u';
201225 p->zBuf[p->nUsed++] = '0';
201226 p->zBuf[p->nUsed++] = '0';
201227 p->zBuf[p->nUsed++] = "0123456789abcdef"[c>>4];
201228 p->zBuf[p->nUsed++] = "0123456789abcdef"[c&0xf];
201229 }
 
201230 }
201231 p->zBuf[p->nUsed++] = '"';
201232 assert( p->nUsed<p->nAlloc );
201233 }
201234
@@ -200674,11 +201243,11 @@
201243 zIn++;
201244 N -= 2;
201245 while( N>0 ){
201246 for(i=0; i<N && zIn[i]!='\\'; i++){}
201247 if( i>0 ){
201248 jsonAppendRawNZ(p, zIn, i);
201249 zIn += i;
201250 N -= i;
201251 if( N==0 ) break;
201252 }
201253 assert( zIn[0]=='\\' );
@@ -200685,20 +201254,20 @@
201254 switch( (u8)zIn[1] ){
201255 case '\'':
201256 jsonAppendChar(p, '\'');
201257 break;
201258 case 'v':
201259 jsonAppendRawNZ(p, "\\u0009", 6);
201260 break;
201261 case 'x':
201262 jsonAppendRawNZ(p, "\\u00", 4);
201263 jsonAppendRawNZ(p, &zIn[2], 2);
201264 zIn += 2;
201265 N -= 2;
201266 break;
201267 case '0':
201268 jsonAppendRawNZ(p, "\\u0000", 6);
201269 break;
201270 case '\r':
201271 if( zIn[2]=='\n' ){
201272 zIn++;
201273 N--;
@@ -200712,11 +201281,11 @@
201281 assert( 0xa8==(u8)zIn[3] || 0xa9==(u8)zIn[3] );
201282 zIn += 2;
201283 N -= 2;
201284 break;
201285 default:
201286 jsonAppendRawNZ(p, zIn, 2);
201287 break;
201288 }
201289 zIn += 2;
201290 N -= 2;
201291 }
@@ -200742,15 +201311,16 @@
201311 int rc = sqlite3DecOrHexToI64(zIn, &i);
201312 if( rc<=1 ){
201313 jsonPrintf(100,p,"%lld",i);
201314 }else{
201315 assert( rc==2 );
201316 jsonAppendRawNZ(p, "9.0e999", 7);
201317 }
201318 return;
201319 }
201320 assert( N>0 );
201321 jsonAppendRawNZ(p, zIn, N);
201322 }
201323
201324 /*
201325 ** The zIn[0..N] string is a JSON5 real literal. Append to p a translation
201326 ** of the string literal that standard JSON and that omits all JSON5
@@ -200778,11 +201348,11 @@
201348 jsonAppendChar(p, '0');
201349 break;
201350 }
201351 }
201352 if( N>0 ){
201353 jsonAppendRawNZ(p, zIn, N);
201354 }
201355 }
201356
201357
201358
@@ -200794,11 +201364,11 @@
201364 JsonString *p, /* Append to this JSON string */
201365 sqlite3_value *pValue /* Value to append */
201366 ){
201367 switch( sqlite3_value_type(pValue) ){
201368 case SQLITE_NULL: {
201369 jsonAppendRawNZ(p, "null", 4);
201370 break;
201371 }
201372 case SQLITE_FLOAT: {
201373 jsonPrintf(100, p, "%!0.15g", sqlite3_value_double(pValue));
201374 break;
@@ -200830,19 +201400,29 @@
201400 }
201401 }
201402
201403
201404 /* Make the JSON in p the result of the SQL function.
201405 **
201406 ** The JSON string is reset.
201407 */
201408 static void jsonResult(JsonString *p){
201409 if( p->bErr==0 ){
201410 if( p->bStatic ){
201411 sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
201412 SQLITE_TRANSIENT, SQLITE_UTF8);
201413 }else if( jsonForceRCStr(p) ){
201414 sqlite3RCStrRef(p->zBuf);
201415 sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
201416 (void(*)(void*))sqlite3RCStrUnref,
201417 SQLITE_UTF8);
201418 }
201419 }
201420 if( p->bErr==1 ){
201421 sqlite3_result_error_nomem(p->pCtx);
201422 }
201423 jsonReset(p);
201424 }
201425
201426 /**************************************************************************
201427 ** Utility routines for dealing with JsonNode and JsonParse objects
201428 **************************************************************************/
@@ -200863,58 +201443,117 @@
201443 /*
201444 ** Reclaim all memory allocated by a JsonParse object. But do not
201445 ** delete the JsonParse object itself.
201446 */
201447 static void jsonParseReset(JsonParse *pParse){
201448 while( pParse->pClup ){
201449 JsonCleanup *pTask = pParse->pClup;
201450 pParse->pClup = pTask->pJCNext;
201451 pTask->xOp(pTask->pArg);
201452 sqlite3_free(pTask);
201453 }
201454 assert( pParse->nJPRef<=1 );
201455 if( pParse->aNode ){
201456 sqlite3_free(pParse->aNode);
201457 pParse->aNode = 0;
201458 }
201459 pParse->nNode = 0;
201460 pParse->nAlloc = 0;
201461 if( pParse->aUp ){
201462 sqlite3_free(pParse->aUp);
201463 pParse->aUp = 0;
201464 }
201465 if( pParse->bJsonIsRCStr ){
201466 sqlite3RCStrUnref(pParse->zJson);
201467 pParse->zJson = 0;
201468 pParse->bJsonIsRCStr = 0;
201469 }
201470 if( pParse->zAlt ){
201471 sqlite3RCStrUnref(pParse->zAlt);
201472 pParse->zAlt = 0;
201473 }
201474 }
201475
201476 /*
201477 ** Free a JsonParse object that was obtained from sqlite3_malloc().
201478 **
201479 ** Note that destroying JsonParse might call sqlite3RCStrUnref() to
201480 ** destroy the zJson value. The RCStr object might recursively invoke
201481 ** JsonParse to destroy this pParse object again. Take care to ensure
201482 ** that this recursive destructor sequence terminates harmlessly.
201483 */
201484 static void jsonParseFree(JsonParse *pParse){
201485 if( pParse->nJPRef>1 ){
201486 pParse->nJPRef--;
201487 }else{
201488 jsonParseReset(pParse);
201489 sqlite3_free(pParse);
201490 }
201491 }
201492
201493 /*
201494 ** Add a cleanup task to the JsonParse object.
201495 **
201496 ** If an OOM occurs, the cleanup operation happens immediately
201497 ** and this function returns SQLITE_NOMEM.
201498 */
201499 static int jsonParseAddCleanup(
201500 JsonParse *pParse, /* Add the cleanup task to this parser */
201501 void(*xOp)(void*), /* The cleanup task */
201502 void *pArg /* Argument to the cleanup */
201503 ){
201504 JsonCleanup *pTask = sqlite3_malloc64( sizeof(*pTask) );
201505 if( pTask==0 ){
201506 pParse->oom = 1;
201507 xOp(pArg);
201508 return SQLITE_ERROR;
201509 }
201510 pTask->pJCNext = pParse->pClup;
201511 pParse->pClup = pTask;
201512 pTask->xOp = xOp;
201513 pTask->pArg = pArg;
201514 return SQLITE_OK;
201515 }
201516
201517 /*
201518 ** Convert the JsonNode pNode into a pure JSON string and
201519 ** append to pOut. Subsubstructure is also included. Return
201520 ** the number of JsonNode objects that are encoded.
201521 */
201522 static void jsonRenderNode(
201523 JsonParse *pParse, /* the complete parse of the JSON */
201524 JsonNode *pNode, /* The node to render */
201525 JsonString *pOut /* Write JSON here */
 
201526 ){
201527 assert( pNode!=0 );
201528 while( (pNode->jnFlags & JNODE_REPLACE)!=0 && pParse->useMod ){
201529 u32 idx = (u32)(pNode - pParse->aNode);
201530 u32 i = pParse->iSubst;
201531 while( 1 /*exit-by-break*/ ){
201532 assert( i<pParse->nNode );
201533 assert( pParse->aNode[i].eType==JSON_SUBST );
201534 assert( pParse->aNode[i].eU==4 );
201535 assert( pParse->aNode[i].u.iPrev<i );
201536 if( pParse->aNode[i].n==idx ){
201537 pNode = &pParse->aNode[i+1];
201538 break;
201539 }
201540 i = pParse->aNode[i].u.iPrev;
201541 }
201542 }
201543 switch( pNode->eType ){
201544 default: {
201545 assert( pNode->eType==JSON_NULL );
201546 jsonAppendRawNZ(pOut, "null", 4);
201547 break;
201548 }
201549 case JSON_TRUE: {
201550 jsonAppendRawNZ(pOut, "true", 4);
201551 break;
201552 }
201553 case JSON_FALSE: {
201554 jsonAppendRawNZ(pOut, "false", 5);
201555 break;
201556 }
201557 case JSON_STRING: {
201558 assert( pNode->eU==1 );
201559 if( pNode->jnFlags & JNODE_RAW ){
@@ -200926,46 +201565,50 @@
201565 jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
201566 }
201567 }else if( pNode->jnFlags & JNODE_JSON5 ){
201568 jsonAppendNormalizedString(pOut, pNode->u.zJContent, pNode->n);
201569 }else{
201570 assert( pNode->n>0 );
201571 jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n);
201572 }
201573 break;
201574 }
201575 case JSON_REAL: {
201576 assert( pNode->eU==1 );
201577 if( pNode->jnFlags & JNODE_JSON5 ){
201578 jsonAppendNormalizedReal(pOut, pNode->u.zJContent, pNode->n);
201579 }else{
201580 assert( pNode->n>0 );
201581 jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n);
201582 }
201583 break;
201584 }
201585 case JSON_INT: {
201586 assert( pNode->eU==1 );
201587 if( pNode->jnFlags & JNODE_JSON5 ){
201588 jsonAppendNormalizedInt(pOut, pNode->u.zJContent, pNode->n);
201589 }else{
201590 assert( pNode->n>0 );
201591 jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n);
201592 }
201593 break;
201594 }
201595 case JSON_ARRAY: {
201596 u32 j = 1;
201597 jsonAppendChar(pOut, '[');
201598 for(;;){
201599 while( j<=pNode->n ){
201600 if( (pNode[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ){
201601 jsonAppendSeparator(pOut);
201602 jsonRenderNode(pParse, &pNode[j], pOut);
201603 }
201604 j += jsonNodeSize(&pNode[j]);
201605 }
201606 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
201607 if( pParse->useMod==0 ) break;
201608 assert( pNode->eU==2 );
201609 pNode = &pParse->aNode[pNode->u.iAppend];
201610 j = 1;
201611 }
201612 jsonAppendChar(pOut, ']');
201613 break;
201614 }
@@ -200972,21 +201615,22 @@
201615 case JSON_OBJECT: {
201616 u32 j = 1;
201617 jsonAppendChar(pOut, '{');
201618 for(;;){
201619 while( j<=pNode->n ){
201620 if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ){
201621 jsonAppendSeparator(pOut);
201622 jsonRenderNode(pParse, &pNode[j], pOut);
201623 jsonAppendChar(pOut, ':');
201624 jsonRenderNode(pParse, &pNode[j+1], pOut);
201625 }
201626 j += 1 + jsonNodeSize(&pNode[j+1]);
201627 }
201628 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
201629 if( pParse->useMod==0 ) break;
201630 assert( pNode->eU==2 );
201631 pNode = &pParse->aNode[pNode->u.iAppend];
201632 j = 1;
201633 }
201634 jsonAppendChar(pOut, '}');
201635 break;
201636 }
@@ -200995,19 +201639,30 @@
201639
201640 /*
201641 ** Return a JsonNode and all its descendants as a JSON string.
201642 */
201643 static void jsonReturnJson(
201644 JsonParse *pParse, /* The complete JSON */
201645 JsonNode *pNode, /* Node to return */
201646 sqlite3_context *pCtx, /* Return value for this function */
201647 int bGenerateAlt /* Also store the rendered text in zAlt */
201648 ){
201649 JsonString s;
201650 if( pParse->oom ){
201651 sqlite3_result_error_nomem(pCtx);
201652 return;
201653 }
201654 if( pParse->nErr==0 ){
201655 jsonInit(&s, pCtx);
201656 jsonRenderNode(pParse, pNode, &s);
201657 if( bGenerateAlt && pParse->zAlt==0 && jsonForceRCStr(&s) ){
201658 pParse->zAlt = sqlite3RCStrRef(s.zBuf);
201659 pParse->nAlt = s.nUsed;
201660 }
201661 jsonResult(&s);
201662 sqlite3_result_subtype(pCtx, JSON_SUBTYPE);
201663 }
201664 }
201665
201666 /*
201667 ** Translate a single byte of Hex into an integer.
201668 ** This routine only works if h really is a valid hexadecimal
@@ -201041,13 +201696,13 @@
201696
201697 /*
201698 ** Make the JsonNode the return value of the function.
201699 */
201700 static void jsonReturn(
201701 JsonParse *pParse, /* Complete JSON parse tree */
201702 JsonNode *pNode, /* Node to return */
201703 sqlite3_context *pCtx /* Return value for this function */
 
201704 ){
201705 switch( pNode->eType ){
201706 default: {
201707 assert( pNode->eType==JSON_NULL );
201708 sqlite3_result_null(pCtx);
@@ -201064,11 +201719,10 @@
201719 case JSON_INT: {
201720 sqlite3_int64 i = 0;
201721 int rc;
201722 int bNeg = 0;
201723 const char *z;
 
201724
201725 assert( pNode->eU==1 );
201726 z = pNode->u.zJContent;
201727 if( z[0]=='-' ){ z++; bNeg = 1; }
201728 else if( z[0]=='+' ){ z++; }
@@ -201190,11 +201844,11 @@
201844 }
201845 break;
201846 }
201847 case JSON_ARRAY:
201848 case JSON_OBJECT: {
201849 jsonReturnJson(pParse, pNode, pCtx, 0);
201850 break;
201851 }
201852 }
201853 }
201854
@@ -201212,10 +201866,16 @@
201866 #else
201867 # define JSON_NOINLINE
201868 #endif
201869
201870
201871 /*
201872 ** Add a single node to pParse->aNode after first expanding the
201873 ** size of the aNode array. Return the index of the new node.
201874 **
201875 ** If an OOM error occurs, set pParse->oom and return -1.
201876 */
201877 static JSON_NOINLINE int jsonParseAddNodeExpand(
201878 JsonParse *pParse, /* Append the node to this object */
201879 u32 eType, /* Node type */
201880 u32 n, /* Content size or sub-node count */
201881 const char *zContent /* Content */
@@ -201228,11 +201888,11 @@
201888 pNew = sqlite3_realloc64(pParse->aNode, sizeof(JsonNode)*nNew);
201889 if( pNew==0 ){
201890 pParse->oom = 1;
201891 return -1;
201892 }
201893 pParse->nAlloc = sqlite3_msize(pNew)/sizeof(JsonNode);
201894 pParse->aNode = pNew;
201895 assert( pParse->nNode<pParse->nAlloc );
201896 return jsonParseAddNode(pParse, eType, n, zContent);
201897 }
201898
@@ -201246,11 +201906,12 @@
201906 u32 eType, /* Node type */
201907 u32 n, /* Content size or sub-node count */
201908 const char *zContent /* Content */
201909 ){
201910 JsonNode *p;
201911 assert( pParse->aNode!=0 || pParse->nNode>=pParse->nAlloc );
201912 if( pParse->nNode>=pParse->nAlloc ){
201913 return jsonParseAddNodeExpand(pParse, eType, n, zContent);
201914 }
201915 p = &pParse->aNode[pParse->nNode];
201916 p->eType = (u8)(eType & 0xff);
201917 p->jnFlags = (u8)(eType >> 8);
@@ -201257,10 +201918,54 @@
201918 VVA( p->eU = zContent ? 1 : 0 );
201919 p->n = n;
201920 p->u.zJContent = zContent;
201921 return pParse->nNode++;
201922 }
201923
201924 /*
201925 ** Add an array of new nodes to the current pParse->aNode array.
201926 ** Return the index of the first node added.
201927 **
201928 ** If an OOM error occurs, set pParse->oom.
201929 */
201930 static void jsonParseAddNodeArray(
201931 JsonParse *pParse, /* Append the node to this object */
201932 JsonNode *aNode, /* Array of nodes to add */
201933 u32 nNode /* Number of elements in aNew */
201934 ){
201935 if( pParse->nNode + nNode > pParse->nAlloc ){
201936 u32 nNew = pParse->nNode + nNode;
201937 JsonNode *aNew = sqlite3_realloc64(pParse->aNode, nNew*sizeof(JsonNode));
201938 if( aNew==0 ){
201939 pParse->oom = 1;
201940 return;
201941 }
201942 pParse->nAlloc = sqlite3_msize(aNew)/sizeof(JsonNode);
201943 pParse->aNode = aNew;
201944 }
201945 memcpy(&pParse->aNode[pParse->nNode], aNode, nNode*sizeof(JsonNode));
201946 pParse->nNode += nNode;
201947 }
201948
201949 /*
201950 ** Add a new JSON_SUBST node. The node immediately following
201951 ** this new node will be the substitute content for iNode.
201952 */
201953 static int jsonParseAddSubstNode(
201954 JsonParse *pParse, /* Add the JSON_SUBST here */
201955 u32 iNode /* References this node */
201956 ){
201957 int idx = jsonParseAddNode(pParse, JSON_SUBST, iNode, 0);
201958 if( pParse->oom ) return -1;
201959 pParse->aNode[iNode].jnFlags |= JNODE_REPLACE;
201960 pParse->aNode[idx].eU = 4;
201961 pParse->aNode[idx].u.iPrev = pParse->iSubst;
201962 pParse->iSubst = idx;
201963 pParse->hasMod = 1;
201964 pParse->useMod = 1;
201965 return idx;
201966 }
201967
201968 /*
201969 ** Return true if z[] begins with 2 (or more) hexadecimal digits
201970 */
201971 static int jsonIs2Hex(const char *z){
@@ -201424,11 +202129,11 @@
202129 ** Parse a single JSON value which begins at pParse->zJson[i]. Return the
202130 ** index of the first character past the end of the value parsed.
202131 **
202132 ** Special return values:
202133 **
202134 ** 0 End of input
202135 ** -1 Syntax error
202136 ** -2 '}' seen
202137 ** -3 ']' seen
202138 ** -4 ',' seen
202139 ** -5 ':' seen
@@ -201599,19 +202304,16 @@
202304 case '"':
202305 /* Parse string */
202306 jnFlags = 0;
202307 parse_string:
202308 cDelim = z[i];
202309 for(j=i+1; 1; j++){
202310 if( jsonIsOk[(unsigned char)z[j]] ) continue;
202311 c = z[j];
202312 if( c==cDelim ){
202313 break;
202314 }else if( c=='\\' ){
 
 
 
202315 c = z[++j];
202316 if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f'
202317 || c=='n' || c=='r' || c=='t'
202318 || (c=='u' && jsonIs4Hex(&z[j+1])) ){
202319 jnFlags |= JNODE_ESCAPE;
@@ -201627,14 +202329,15 @@
202329 pParse->hasNonstd = 1;
202330 }else{
202331 pParse->iErr = j;
202332 return -1;
202333 }
202334 }else if( c<=0x1f ){
202335 /* Control characters are not allowed in strings */
202336 pParse->iErr = j;
202337 return -1;
202338 }
 
202339 }
202340 jsonParseAddNode(pParse, JSON_STRING | (jnFlags<<8), j+1-i, &z[i]);
202341 return j+1;
202342 }
202343 case 't': {
@@ -201866,24 +202569,22 @@
202569 } /* End switch(z[i]) */
202570 }
202571
202572 /*
202573 ** Parse a complete JSON string. Return 0 on success or non-zero if there
202574 ** are any errors. If an error occurs, free all memory held by pParse,
202575 ** but not pParse itself.
202576 **
202577 ** pParse must be initialized to an empty parse object prior to calling
202578 ** this routine.
202579 */
202580 static int jsonParse(
202581 JsonParse *pParse, /* Initialize and fill this JsonParse object */
202582 sqlite3_context *pCtx /* Report errors here */
 
202583 ){
202584 int i;
202585 const char *zJson = pParse->zJson;
 
 
202586 i = jsonParseValue(pParse, 0);
202587 if( pParse->oom ) i = -1;
202588 if( i>0 ){
202589 assert( pParse->iDepth==0 );
202590 while( fast_isspace(zJson[i]) ) i++;
@@ -201907,10 +202608,11 @@
202608 jsonParseReset(pParse);
202609 return 1;
202610 }
202611 return 0;
202612 }
202613
202614
202615 /* Mark node i of pParse as being a child of iParent. Call recursively
202616 ** to fill in all the descendants of node i.
202617 */
202618 static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){
@@ -201957,51 +202659,77 @@
202659 */
202660 #define JSON_CACHE_ID (-429938) /* First cache entry */
202661 #define JSON_CACHE_SZ 4 /* Max number of cache entries */
202662
202663 /*
202664 ** Obtain a complete parse of the JSON found in the pJson argument
202665 **
202666 ** Use the sqlite3_get_auxdata() cache to find a preexisting parse
202667 ** if it is available. If the cache is not available or if it
202668 ** is no longer valid, parse the JSON again and return the new parse.
202669 ** Also register the new parse so that it will be available for
202670 ** future sqlite3_get_auxdata() calls.
202671 **
202672 ** If an error occurs and pErrCtx!=0 then report the error on pErrCtx
202673 ** and return NULL.
202674 **
202675 ** The returned pointer (if it is not NULL) is owned by the cache in
202676 ** most cases, not the caller. The caller does NOT need to invoke
202677 ** jsonParseFree(), in most cases.
202678 **
202679 ** Except, if an error occurs and pErrCtx==0 then return the JsonParse
202680 ** object with JsonParse.nErr non-zero and the caller will own the JsonParse
202681 ** object. In that case, it will be the responsibility of the caller to
202682 ** invoke jsonParseFree(). To summarize:
202683 **
202684 ** pErrCtx!=0 || p->nErr==0 ==> Return value p is owned by the
202685 ** cache. Call does not need to
202686 ** free it.
202687 **
202688 ** pErrCtx==0 && p->nErr!=0 ==> Return value is owned by the caller
202689 ** and so the caller must free it.
202690 */
202691 static JsonParse *jsonParseCached(
202692 sqlite3_context *pCtx, /* Context to use for cache search */
202693 sqlite3_value *pJson, /* Function param containing JSON text */
202694 sqlite3_context *pErrCtx, /* Write parse errors here if not NULL */
202695 int bUnedited /* No prior edits allowed */
202696 ){
202697 char *zJson = (char*)sqlite3_value_text(pJson);
202698 int nJson = sqlite3_value_bytes(pJson);
202699 JsonParse *p;
202700 JsonParse *pMatch = 0;
202701 int iKey;
202702 int iMinKey = 0;
202703 u32 iMinHold = 0xffffffff;
202704 u32 iMaxHold = 0;
202705 int bJsonRCStr;
202706
202707 if( zJson==0 ) return 0;
202708 for(iKey=0; iKey<JSON_CACHE_SZ; iKey++){
202709 p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iKey);
202710 if( p==0 ){
202711 iMinKey = iKey;
202712 break;
202713 }
202714 if( pMatch==0
202715 && p->nJson==nJson
202716 && (p->hasMod==0 || bUnedited==0)
202717 && (p->zJson==zJson || memcmp(p->zJson,zJson,nJson)==0)
202718 ){
202719 p->nErr = 0;
202720 p->useMod = 0;
202721 pMatch = p;
202722 }else
202723 if( pMatch==0
202724 && p->zAlt!=0
202725 && bUnedited==0
202726 && p->nAlt==nJson
202727 && memcmp(p->zAlt, zJson, nJson)==0
202728 ){
202729 p->nErr = 0;
202730 p->useMod = 1;
202731 pMatch = p;
202732 }else if( p->iHold<iMinHold ){
202733 iMinHold = p->iHold;
202734 iMinKey = iKey;
202735 }
@@ -202008,32 +202736,48 @@
202736 if( p->iHold>iMaxHold ){
202737 iMaxHold = p->iHold;
202738 }
202739 }
202740 if( pMatch ){
202741 /* The input JSON text was found in the cache. Use the preexisting
202742 ** parse of this JSON */
202743 pMatch->nErr = 0;
202744 pMatch->iHold = iMaxHold+1;
202745 assert( pMatch->nJPRef>0 ); /* pMatch is owned by the cache */
202746 return pMatch;
202747 }
202748
202749 /* The input JSON was not found anywhere in the cache. We will need
202750 ** to parse it ourselves and generate a new JsonParse object.
202751 */
202752 bJsonRCStr = sqlite3ValueIsOfClass(pJson,(void(*)(void*))sqlite3RCStrUnref);
202753 p = sqlite3_malloc64( sizeof(*p) + (bJsonRCStr ? 0 : nJson+1) );
202754 if( p==0 ){
202755 sqlite3_result_error_nomem(pCtx);
202756 return 0;
202757 }
202758 memset(p, 0, sizeof(*p));
202759 if( bJsonRCStr ){
202760 p->zJson = sqlite3RCStrRef(zJson);
202761 p->bJsonIsRCStr = 1;
202762 }else{
202763 p->zJson = (char*)&p[1];
202764 memcpy(p->zJson, zJson, nJson+1);
202765 }
202766 p->nJPRef = 1;
202767 if( jsonParse(p, pErrCtx) ){
202768 if( pErrCtx==0 ){
202769 p->nErr = 1;
202770 assert( p->nJPRef==1 ); /* Caller will own the new JsonParse object p */
202771 return p;
202772 }
202773 jsonParseFree(p);
202774 return 0;
202775 }
202776 p->nJson = nJson;
202777 p->iHold = iMaxHold+1;
202778 /* Transfer ownership of the new JsonParse to the cache */
202779 sqlite3_set_auxdata(pCtx, JSON_CACHE_ID+iMinKey, p,
202780 (void(*)(void*))jsonParseFree);
202781 return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iMinKey);
202782 }
202783
@@ -202080,13 +202824,30 @@
202824 int *pApnd, /* Append nodes to complete path if not NULL */
202825 const char **pzErr /* Make *pzErr point to any syntax error in zPath */
202826 ){
202827 u32 i, j, nKey;
202828 const char *zKey;
202829 JsonNode *pRoot;
202830 if( pParse->oom ) return 0;
202831 pRoot = &pParse->aNode[iRoot];
202832 while( (pRoot->jnFlags & JNODE_REPLACE)!=0 && pParse->useMod ){
202833 u32 idx = (u32)(pRoot - pParse->aNode);
202834 i = pParse->iSubst;
202835 while( 1 /*exit-by-break*/ ){
202836 assert( i<pParse->nNode );
202837 assert( pParse->aNode[i].eType==JSON_SUBST );
202838 assert( pParse->aNode[i].eU==4 );
202839 assert( pParse->aNode[i].u.iPrev<i );
202840 if( pParse->aNode[i].n==idx ){
202841 pRoot = &pParse->aNode[i+1];
202842 iRoot = i+1;
202843 break;
202844 }
202845 i = pParse->aNode[i].u.iPrev;
202846 }
202847 }
202848 if( zPath[0]==0 ) return pRoot;
 
202849 if( zPath[0]=='.' ){
202850 if( pRoot->eType!=JSON_OBJECT ) return 0;
202851 zPath++;
202852 if( zPath[0]=='"' ){
202853 zKey = zPath + 1;
@@ -202116,27 +202877,29 @@
202877 }
202878 j++;
202879 j += jsonNodeSize(&pRoot[j]);
202880 }
202881 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
202882 if( pParse->useMod==0 ) break;
202883 assert( pRoot->eU==2 );
202884 iRoot = pRoot->u.iAppend;
202885 pRoot = &pParse->aNode[iRoot];
202886 j = 1;
202887 }
202888 if( pApnd ){
202889 u32 iStart, iLabel;
202890 JsonNode *pNode;
202891 assert( pParse->useMod );
202892 iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
202893 iLabel = jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
202894 zPath += i;
202895 pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
202896 if( pParse->oom ) return 0;
202897 if( pNode ){
202898 pRoot = &pParse->aNode[iRoot];
202899 assert( pRoot->eU==0 );
202900 pRoot->u.iAppend = iStart;
202901 pRoot->jnFlags |= JNODE_APPEND;
202902 VVA( pRoot->eU = 2 );
202903 pParse->aNode[iLabel].jnFlags |= JNODE_RAW;
202904 }
202905 return pNode;
@@ -202153,16 +202916,17 @@
202916 JsonNode *pBase = pRoot;
202917 int iBase = iRoot;
202918 if( pRoot->eType!=JSON_ARRAY ) return 0;
202919 for(;;){
202920 while( j<=pBase->n ){
202921 if( (pBase[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ) i++;
202922 j += jsonNodeSize(&pBase[j]);
202923 }
202924 if( (pBase->jnFlags & JNODE_APPEND)==0 ) break;
202925 if( pParse->useMod==0 ) break;
202926 assert( pBase->eU==2 );
202927 iBase = pBase->u.iAppend;
202928 pBase = &pParse->aNode[iBase];
202929 j = 1;
202930 }
202931 j = 2;
202932 if( zPath[2]=='-' && sqlite3Isdigit(zPath[3]) ){
@@ -202186,33 +202950,37 @@
202950 }
202951 if( pRoot->eType!=JSON_ARRAY ) return 0;
202952 zPath += j + 1;
202953 j = 1;
202954 for(;;){
202955 while( j<=pRoot->n
202956 && (i>0 || ((pRoot[j].jnFlags & JNODE_REMOVE)!=0 && pParse->useMod))
202957 ){
202958 if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ) i--;
202959 j += jsonNodeSize(&pRoot[j]);
202960 }
202961 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
202962 if( pParse->useMod==0 ) break;
202963 assert( pRoot->eU==2 );
202964 iRoot = pRoot->u.iAppend;
202965 pRoot = &pParse->aNode[iRoot];
202966 j = 1;
202967 }
202968 if( j<=pRoot->n ){
202969 return jsonLookupStep(pParse, iRoot+j, zPath, pApnd, pzErr);
202970 }
202971 if( i==0 && pApnd ){
202972 u32 iStart;
202973 JsonNode *pNode;
202974 assert( pParse->useMod );
202975 iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
202976 pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
202977 if( pParse->oom ) return 0;
202978 if( pNode ){
202979 pRoot = &pParse->aNode[iRoot];
202980 assert( pRoot->eU==0 );
202981 pRoot->u.iAppend = iStart;
202982 pRoot->jnFlags |= JNODE_APPEND;
202983 VVA( pRoot->eU = 2 );
202984 }
202985 return pNode;
202986 }
@@ -202334,52 +203102,95 @@
203102
203103
203104 /****************************************************************************
203105 ** SQL functions used for testing and debugging
203106 ****************************************************************************/
203107
203108 #if SQLITE_DEBUG
203109 /*
203110 ** Print N node entries.
203111 */
203112 static void jsonDebugPrintNodeEntries(
203113 JsonNode *aNode, /* First node entry to print */
203114 int N /* Number of node entries to print */
203115 ){
203116 int i;
203117 for(i=0; i<N; i++){
203118 const char *zType;
203119 if( aNode[i].jnFlags & JNODE_LABEL ){
203120 zType = "label";
203121 }else{
203122 zType = jsonType[aNode[i].eType];
203123 }
203124 printf("node %4u: %-7s n=%-5d", i, zType, aNode[i].n);
203125 if( (aNode[i].jnFlags & ~JNODE_LABEL)!=0 ){
203126 u8 f = aNode[i].jnFlags;
203127 if( f & JNODE_RAW ) printf(" RAW");
203128 if( f & JNODE_ESCAPE ) printf(" ESCAPE");
203129 if( f & JNODE_REMOVE ) printf(" REMOVE");
203130 if( f & JNODE_REPLACE ) printf(" REPLACE");
203131 if( f & JNODE_APPEND ) printf(" APPEND");
203132 if( f & JNODE_JSON5 ) printf(" JSON5");
203133 }
203134 switch( aNode[i].eU ){
203135 case 1: printf(" zJContent=[%.*s]\n",
203136 aNode[i].n, aNode[i].u.zJContent); break;
203137 case 2: printf(" iAppend=%u\n", aNode[i].u.iAppend); break;
203138 case 3: printf(" iKey=%u\n", aNode[i].u.iKey); break;
203139 case 4: printf(" iPrev=%u\n", aNode[i].u.iPrev); break;
203140 default: printf("\n");
203141 }
203142 }
203143 }
203144 #endif /* SQLITE_DEBUG */
203145
203146
203147 #if 0 /* 1 for debugging. 0 normally. Requires -DSQLITE_DEBUG too */
203148 static void jsonDebugPrintParse(JsonParse *p){
203149 jsonDebugPrintNodeEntries(p->aNode, p->nNode);
203150 }
203151 static void jsonDebugPrintNode(JsonNode *pNode){
203152 jsonDebugPrintNodeEntries(pNode, jsonNodeSize(pNode));
203153 }
203154 #else
203155 /* The usual case */
203156 # define jsonDebugPrintNode(X)
203157 # define jsonDebugPrintParse(X)
203158 #endif
203159
203160 #ifdef SQLITE_DEBUG
203161 /*
203162 ** SQL function: json_parse(JSON)
203163 **
203164 ** Parse JSON using jsonParseCached(). Then print a dump of that
203165 ** parse on standard output. Return the mimified JSON result, just
203166 ** like the json() function.
203167 */
203168 static void jsonParseFunc(
203169 sqlite3_context *ctx,
203170 int argc,
203171 sqlite3_value **argv
203172 ){
203173 JsonParse *p; /* The parse */
 
 
203174
203175 assert( argc==1 );
203176 p = jsonParseCached(ctx, argv[0], ctx, 0);
203177 if( p==0 ) return;
203178 printf("nNode = %u\n", p->nNode);
203179 printf("nAlloc = %u\n", p->nAlloc);
203180 printf("nJson = %d\n", p->nJson);
203181 printf("nAlt = %d\n", p->nAlt);
203182 printf("nErr = %u\n", p->nErr);
203183 printf("oom = %u\n", p->oom);
203184 printf("hasNonstd = %u\n", p->hasNonstd);
203185 printf("useMod = %u\n", p->useMod);
203186 printf("hasMod = %u\n", p->hasMod);
203187 printf("nJPRef = %u\n", p->nJPRef);
203188 printf("iSubst = %u\n", p->iSubst);
203189 printf("iHold = %u\n", p->iHold);
203190 jsonDebugPrintNodeEntries(p->aNode, p->nNode);
203191 jsonReturnJson(p, p->aNode, ctx, 1);
 
 
 
 
 
 
 
 
 
203192 }
203193
203194 /*
203195 ** The json_test1(JSON) function return true (1) if the input is JSON
203196 ** text generated by another json function. It returns (0) if the input
@@ -202459,11 +203270,11 @@
203270 JsonParse *p; /* The parse */
203271 sqlite3_int64 n = 0;
203272 u32 i;
203273 JsonNode *pNode;
203274
203275 p = jsonParseCached(ctx, argv[0], ctx, 0);
203276 if( p==0 ) return;
203277 assert( p->nNode );
203278 if( argc==2 ){
203279 const char *zPath = (const char*)sqlite3_value_text(argv[1]);
203280 pNode = jsonLookup(p, zPath, 0, ctx);
@@ -202472,13 +203283,18 @@
203283 }
203284 if( pNode==0 ){
203285 return;
203286 }
203287 if( pNode->eType==JSON_ARRAY ){
203288 while( 1 /*exit-by-break*/ ){
203289 for(i=1; i<=pNode->n; n++){
203290 i += jsonNodeSize(&pNode[i]);
203291 }
203292 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
203293 if( p->useMod==0 ) break;
203294 assert( pNode->eU==2 );
203295 pNode = &p->aNode[pNode->u.iAppend];
203296 }
203297 }
203298 sqlite3_result_int64(ctx, n);
203299 }
203300
@@ -202521,11 +203337,11 @@
203337 const char *zPath;
203338 int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx));
203339 JsonString jx;
203340
203341 if( argc<2 ) return;
203342 p = jsonParseCached(ctx, argv[0], ctx, 0);
203343 if( p==0 ) return;
203344 if( argc==2 ){
203345 /* With a single PATH argument */
203346 zPath = (const char*)sqlite3_value_text(argv[1]);
203347 if( zPath==0 ) return;
@@ -202539,15 +203355,15 @@
203355 ** LABEL ==> $.LABEL // PG compatible
203356 ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience
203357 */
203358 jsonInit(&jx, ctx);
203359 if( sqlite3Isdigit(zPath[0]) ){
203360 jsonAppendRawNZ(&jx, "$[", 2);
203361 jsonAppendRaw(&jx, zPath, (int)strlen(zPath));
203362 jsonAppendRawNZ(&jx, "]", 2);
203363 }else{
203364 jsonAppendRawNZ(&jx, "$.", 1 + (zPath[0]!='['));
203365 jsonAppendRaw(&jx, zPath, (int)strlen(zPath));
203366 jsonAppendChar(&jx, 0);
203367 }
203368 pNode = jx.bErr ? 0 : jsonLookup(p, jx.zBuf, 0, ctx);
203369 jsonReset(&jx);
@@ -202554,19 +203370,19 @@
203370 }else{
203371 pNode = jsonLookup(p, zPath, 0, ctx);
203372 }
203373 if( pNode ){
203374 if( flags & JSON_JSON ){
203375 jsonReturnJson(p, pNode, ctx, 0);
203376 }else{
203377 jsonReturn(p, pNode, ctx);
203378 sqlite3_result_subtype(ctx, 0);
203379 }
203380 }
203381 }else{
203382 pNode = jsonLookup(p, zPath, 0, ctx);
203383 if( p->nErr==0 && pNode ) jsonReturn(p, pNode, ctx);
203384 }
203385 }else{
203386 /* Two or more PATH arguments results in a JSON array with each
203387 ** element of the array being the value selected by one of the PATHs */
203388 int i;
@@ -202576,13 +203392,13 @@
203392 zPath = (const char*)sqlite3_value_text(argv[i]);
203393 pNode = jsonLookup(p, zPath, 0, ctx);
203394 if( p->nErr ) break;
203395 jsonAppendSeparator(&jx);
203396 if( pNode ){
203397 jsonRenderNode(p, pNode, &jx);
203398 }else{
203399 jsonAppendRawNZ(&jx, "null", 4);
203400 }
203401 }
203402 if( i==argc ){
203403 jsonAppendChar(&jx, ']');
203404 jsonResult(&jx);
@@ -202623,49 +203439,42 @@
203439 zKey = pPatch[i].u.zJContent;
203440 for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){
203441 assert( pTarget[j].eType==JSON_STRING );
203442 assert( pTarget[j].jnFlags & JNODE_LABEL );
203443 if( jsonSameLabel(&pPatch[i], &pTarget[j]) ){
203444 if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ) break;
203445 if( pPatch[i+1].eType==JSON_NULL ){
203446 pTarget[j+1].jnFlags |= JNODE_REMOVE;
203447 }else{
203448 JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]);
203449 if( pNew==0 ) return 0;
203450 if( pNew!=&pParse->aNode[iTarget+j+1] ){
203451 jsonParseAddSubstNode(pParse, iTarget+j+1);
203452 jsonParseAddNodeArray(pParse, pNew, jsonNodeSize(pNew));
203453 }
203454 pTarget = &pParse->aNode[iTarget];
 
 
 
 
 
 
 
 
 
 
203455 }
203456 break;
203457 }
203458 }
203459 if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){
203460 int iStart;
203461 JsonNode *pApnd;
203462 u32 nApnd;
203463 iStart = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
203464 jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
203465 pApnd = &pPatch[i+1];
203466 if( pApnd->eType==JSON_OBJECT ) jsonRemoveAllNulls(pApnd);
203467 nApnd = jsonNodeSize(pApnd);
203468 jsonParseAddNodeArray(pParse, pApnd, jsonNodeSize(pApnd));
203469 if( pParse->oom ) return 0;
203470 pParse->aNode[iStart].n = 1+nApnd;
 
 
 
203471 pParse->aNode[iRoot].jnFlags |= JNODE_APPEND;
203472 pParse->aNode[iRoot].u.iAppend = iStart;
203473 VVA( pParse->aNode[iRoot].eU = 2 );
 
203474 iRoot = iStart;
203475 pTarget = &pParse->aNode[iTarget];
 
 
 
203476 }
203477 }
203478 return pTarget;
203479 }
203480
@@ -202677,29 +203486,32 @@
203486 static void jsonPatchFunc(
203487 sqlite3_context *ctx,
203488 int argc,
203489 sqlite3_value **argv
203490 ){
203491 JsonParse *pX; /* The JSON that is being patched */
203492 JsonParse *pY; /* The patch */
203493 JsonNode *pResult; /* The result of the merge */
203494
203495 UNUSED_PARAMETER(argc);
203496 pX = jsonParseCached(ctx, argv[0], ctx, 1);
203497 if( pX==0 ) return;
203498 assert( pX->hasMod==0 );
203499 pX->hasMod = 1;
203500 pY = jsonParseCached(ctx, argv[1], ctx, 1);
203501 if( pY==0 ) return;
203502 pX->useMod = 1;
203503 pY->useMod = 1;
203504 pResult = jsonMergePatch(pX, 0, pY->aNode);
203505 assert( pResult!=0 || pX->oom );
203506 if( pResult && pX->oom==0 ){
203507 jsonDebugPrintParse(pX);
203508 jsonDebugPrintNode(pResult);
203509 jsonReturnJson(pX, pResult, ctx, 0);
203510 }else{
203511 sqlite3_result_error_nomem(ctx);
203512 }
 
 
203513 }
203514
203515
203516 /*
203517 ** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON
@@ -202751,30 +203563,122 @@
203563 static void jsonRemoveFunc(
203564 sqlite3_context *ctx,
203565 int argc,
203566 sqlite3_value **argv
203567 ){
203568 JsonParse *pParse; /* The parse */
203569 JsonNode *pNode;
203570 const char *zPath;
203571 u32 i;
203572
203573 if( argc<1 ) return;
203574 pParse = jsonParseCached(ctx, argv[0], ctx, argc>1);
203575 if( pParse==0 ) return;
203576 for(i=1; i<(u32)argc; i++){
203577 zPath = (const char*)sqlite3_value_text(argv[i]);
203578 if( zPath==0 ) goto remove_done;
203579 pNode = jsonLookup(pParse, zPath, 0, ctx);
203580 if( pParse->nErr ) goto remove_done;
203581 if( pNode ){
203582 pNode->jnFlags |= JNODE_REMOVE;
203583 pParse->hasMod = 1;
203584 pParse->useMod = 1;
203585 }
203586 }
203587 if( (pParse->aNode[0].jnFlags & JNODE_REMOVE)==0 ){
203588 jsonReturnJson(pParse, pParse->aNode, ctx, 1);
203589 }
203590 remove_done:
203591 jsonDebugPrintParse(p);
203592 }
203593
203594 /*
203595 ** Substitute the value at iNode with the pValue parameter.
203596 */
203597 static void jsonReplaceNode(
203598 sqlite3_context *pCtx,
203599 JsonParse *p,
203600 int iNode,
203601 sqlite3_value *pValue
203602 ){
203603 int idx = jsonParseAddSubstNode(p, iNode);
203604 if( idx<=0 ){
203605 assert( p->oom );
203606 return;
203607 }
203608 switch( sqlite3_value_type(pValue) ){
203609 case SQLITE_NULL: {
203610 jsonParseAddNode(p, JSON_NULL, 0, 0);
203611 break;
203612 }
203613 case SQLITE_FLOAT: {
203614 char *z = sqlite3_mprintf("%!0.15g", sqlite3_value_double(pValue));
203615 int n;
203616 if( z==0 ){
203617 p->oom = 1;
203618 break;
203619 }
203620 n = sqlite3Strlen30(z);
203621 jsonParseAddNode(p, JSON_REAL, n, z);
203622 jsonParseAddCleanup(p, sqlite3_free, z);
203623 break;
203624 }
203625 case SQLITE_INTEGER: {
203626 char *z = sqlite3_mprintf("%lld", sqlite3_value_int64(pValue));
203627 int n;
203628 if( z==0 ){
203629 p->oom = 1;
203630 break;
203631 }
203632 n = sqlite3Strlen30(z);
203633 jsonParseAddNode(p, JSON_INT, n, z);
203634 jsonParseAddCleanup(p, sqlite3_free, z);
203635
203636 break;
203637 }
203638 case SQLITE_TEXT: {
203639 const char *z = (const char*)sqlite3_value_text(pValue);
203640 u32 n = (u32)sqlite3_value_bytes(pValue);
203641 if( z==0 ){
203642 p->oom = 1;
203643 break;
203644 }
203645 if( sqlite3_value_subtype(pValue)!=JSON_SUBTYPE ){
203646 char *zCopy = sqlite3DbStrDup(0, z);
203647 int k;
203648 if( zCopy ){
203649 jsonParseAddCleanup(p, sqlite3_free, zCopy);
203650 }else{
203651 p->oom = 1;
203652 sqlite3_result_error_nomem(pCtx);
203653 }
203654 k = jsonParseAddNode(p, JSON_STRING, n, zCopy);
203655 assert( k>0 || p->oom );
203656 if( p->oom==0 ) p->aNode[k].jnFlags |= JNODE_RAW;
203657 }else{
203658 JsonParse *pPatch = jsonParseCached(pCtx, pValue, pCtx, 1);
203659 if( pPatch==0 ){
203660 p->oom = 1;
203661 break;
203662 }
203663 jsonParseAddNodeArray(p, pPatch->aNode, pPatch->nNode);
203664 /* The nodes copied out of pPatch and into p likely contain
203665 ** u.zJContent pointers into pPatch->zJson. So preserve the
203666 ** content of pPatch until p is destroyed. */
203667 assert( pPatch->nJPRef>=1 );
203668 pPatch->nJPRef++;
203669 jsonParseAddCleanup(p, (void(*)(void*))jsonParseFree, pPatch);
203670 }
203671 break;
203672 }
203673 default: {
203674 jsonParseAddNode(p, JSON_NULL, 0, 0);
203675 sqlite3_result_error(pCtx, "JSON cannot hold BLOB values", -1);
203676 p->nErr++;
203677 break;
203678 }
203679 }
203680 }
203681
203682 /*
203683 ** json_replace(JSON, PATH, VALUE, ...)
203684 **
@@ -202784,42 +203688,34 @@
203688 static void jsonReplaceFunc(
203689 sqlite3_context *ctx,
203690 int argc,
203691 sqlite3_value **argv
203692 ){
203693 JsonParse *pParse; /* The parse */
203694 JsonNode *pNode;
203695 const char *zPath;
203696 u32 i;
203697
203698 if( argc<1 ) return;
203699 if( (argc&1)==0 ) {
203700 jsonWrongNumArgs(ctx, "replace");
203701 return;
203702 }
203703 pParse = jsonParseCached(ctx, argv[0], ctx, argc>1);
203704 if( pParse==0 ) return;
203705 for(i=1; i<(u32)argc; i+=2){
203706 zPath = (const char*)sqlite3_value_text(argv[i]);
203707 pParse->useMod = 1;
203708 pNode = jsonLookup(pParse, zPath, 0, ctx);
203709 if( pParse->nErr ) goto replace_err;
203710 if( pNode ){
203711 jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]);
 
 
 
 
203712 }
203713 }
203714 jsonReturnJson(pParse, pParse->aNode, ctx, 1);
 
 
 
 
 
203715 replace_err:
203716 jsonDebugPrintParse(pParse);
203717 }
203718
203719
203720 /*
203721 ** json_set(JSON, PATH, VALUE, ...)
@@ -202836,11 +203732,11 @@
203732 static void jsonSetFunc(
203733 sqlite3_context *ctx,
203734 int argc,
203735 sqlite3_value **argv
203736 ){
203737 JsonParse *pParse; /* The parse */
203738 JsonNode *pNode;
203739 const char *zPath;
203740 u32 i;
203741 int bApnd;
203742 int bIsSet = sqlite3_user_data(ctx)!=0;
@@ -202848,37 +203744,31 @@
203744 if( argc<1 ) return;
203745 if( (argc&1)==0 ) {
203746 jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert");
203747 return;
203748 }
203749 pParse = jsonParseCached(ctx, argv[0], ctx, argc>1);
203750 if( pParse==0 ) return;
203751 for(i=1; i<(u32)argc; i+=2){
203752 zPath = (const char*)sqlite3_value_text(argv[i]);
203753 bApnd = 0;
203754 pParse->useMod = 1;
203755 pNode = jsonLookup(pParse, zPath, &bApnd, ctx);
203756 if( pParse->oom ){
203757 sqlite3_result_error_nomem(ctx);
203758 goto jsonSetDone;
203759 }else if( pParse->nErr ){
203760 goto jsonSetDone;
203761 }else if( pNode && (bApnd || bIsSet) ){
203762 jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]);
 
 
 
 
203763 }
203764 }
203765 jsonDebugPrintParse(pParse);
203766 jsonReturnJson(pParse, pParse->aNode, ctx, 1);
203767
 
 
 
203768 jsonSetDone:
203769 /* no cleanup required */;
203770 }
203771
203772 /*
203773 ** json_type(JSON)
203774 ** json_type(JSON, PATH)
@@ -202893,11 +203783,11 @@
203783 ){
203784 JsonParse *p; /* The parse */
203785 const char *zPath;
203786 JsonNode *pNode;
203787
203788 p = jsonParseCached(ctx, argv[0], ctx, 0);
203789 if( p==0 ) return;
203790 if( argc==2 ){
203791 zPath = (const char*)sqlite3_value_text(argv[1]);
203792 pNode = jsonLookup(p, zPath, 0, ctx);
203793 }else{
@@ -202920,16 +203810,16 @@
203810 sqlite3_value **argv
203811 ){
203812 JsonParse *p; /* The parse */
203813 UNUSED_PARAMETER(argc);
203814 if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
203815 p = jsonParseCached(ctx, argv[0], 0, 0);
203816 if( p==0 || p->oom ){
203817 sqlite3_result_error_nomem(ctx);
203818 sqlite3_free(p);
203819 }else{
203820 sqlite3_result_int(ctx, p->nErr==0 && (p->hasNonstd==0 || p->useMod));
203821 if( p->nErr ) jsonParseFree(p);
203822 }
203823 }
203824
203825 /*
@@ -202966,20 +203856,20 @@
203856 sqlite3_value **argv
203857 ){
203858 JsonParse *p; /* The parse */
203859 UNUSED_PARAMETER(argc);
203860 if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
203861 p = jsonParseCached(ctx, argv[0], 0, 0);
203862 if( p==0 || p->oom ){
203863 sqlite3_result_error_nomem(ctx);
203864 sqlite3_free(p);
203865 }else if( p->nErr==0 ){
203866 sqlite3_result_int(ctx, 0);
203867 }else{
203868 int n = 1;
203869 u32 i;
203870 const char *z = (const char*)sqlite3_value_text(argv[0]);
203871 for(i=0; i<p->iErr && ALWAYS(z[i]); i++){
203872 if( (z[i]&0xc0)!=0x80 ) n++;
203873 }
203874 sqlite3_result_int(ctx, n);
203875 jsonParseFree(p);
@@ -203023,11 +203913,12 @@
203913 if( pStr->bErr ){
203914 if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
203915 assert( pStr->bStatic );
203916 }else if( isFinal ){
203917 sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed,
203918 pStr->bStatic ? SQLITE_TRANSIENT :
203919 (void(*)(void*))sqlite3RCStrUnref);
203920 pStr->bStatic = 1;
203921 }else{
203922 sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT);
203923 pStr->nUsed--;
203924 }
@@ -203131,11 +204022,12 @@
204022 if( pStr->bErr ){
204023 if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
204024 assert( pStr->bStatic );
204025 }else if( isFinal ){
204026 sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed,
204027 pStr->bStatic ? SQLITE_TRANSIENT :
204028 (void(*)(void*))sqlite3RCStrUnref);
204029 pStr->bStatic = 1;
204030 }else{
204031 sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT);
204032 pStr->nUsed--;
204033 }
@@ -203242,11 +204134,10 @@
204134 }
204135
204136 /* Reset a JsonEachCursor back to its original state. Free any memory
204137 ** held. */
204138 static void jsonEachCursorReset(JsonEachCursor *p){
 
204139 sqlite3_free(p->zRoot);
204140 jsonParseReset(&p->sParse);
204141 p->iRowid = 0;
204142 p->i = 0;
204143 p->iEnd = 0;
@@ -203380,11 +204271,11 @@
204271 JsonNode *pThis = &p->sParse.aNode[p->i];
204272 switch( i ){
204273 case JEACH_KEY: {
204274 if( p->i==0 ) break;
204275 if( p->eType==JSON_OBJECT ){
204276 jsonReturn(&p->sParse, pThis, ctx);
204277 }else if( p->eType==JSON_ARRAY ){
204278 u32 iKey;
204279 if( p->bRecursive ){
204280 if( p->iRowid==0 ) break;
204281 assert( p->sParse.aNode[p->sParse.aUp[p->i]].eU==3 );
@@ -203396,11 +204287,11 @@
204287 }
204288 break;
204289 }
204290 case JEACH_VALUE: {
204291 if( pThis->jnFlags & JNODE_LABEL ) pThis++;
204292 jsonReturn(&p->sParse, pThis, ctx);
204293 break;
204294 }
204295 case JEACH_TYPE: {
204296 if( pThis->jnFlags & JNODE_LABEL ) pThis++;
204297 sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC);
@@ -203407,11 +204298,11 @@
204298 break;
204299 }
204300 case JEACH_ATOM: {
204301 if( pThis->jnFlags & JNODE_LABEL ) pThis++;
204302 if( pThis->eType>=JSON_ARRAY ) break;
204303 jsonReturn(&p->sParse, pThis, ctx);
204304 break;
204305 }
204306 case JEACH_ID: {
204307 sqlite3_result_int64(ctx,
204308 (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0));
@@ -203562,15 +204453,23 @@
204453 UNUSED_PARAMETER(argc);
204454 jsonEachCursorReset(p);
204455 if( idxNum==0 ) return SQLITE_OK;
204456 z = (const char*)sqlite3_value_text(argv[0]);
204457 if( z==0 ) return SQLITE_OK;
204458 memset(&p->sParse, 0, sizeof(p->sParse));
204459 p->sParse.nJPRef = 1;
204460 if( sqlite3ValueIsOfClass(argv[0], (void(*)(void*))sqlite3RCStrUnref) ){
204461 p->sParse.zJson = sqlite3RCStrRef((char*)z);
204462 }else{
204463 n = sqlite3_value_bytes(argv[0]);
204464 p->sParse.zJson = sqlite3RCStrNew( n+1 );
204465 if( p->sParse.zJson==0 ) return SQLITE_NOMEM;
204466 memcpy(p->sParse.zJson, z, (size_t)n+1);
204467 }
204468 p->sParse.bJsonIsRCStr = 1;
204469 p->zJson = p->sParse.zJson;
204470 if( jsonParse(&p->sParse, 0) ){
204471 int rc = SQLITE_NOMEM;
204472 if( p->sParse.oom==0 ){
204473 sqlite3_free(cur->pVtab->zErrMsg);
204474 cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON");
204475 if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR;
@@ -219306,10 +220205,11 @@
220205 }else{
220206 /* assert( db->pPreUpdate->pUnpacked ); */
220207 rc = pSession->hook.xOld(pSession->hook.pCtx, iCol, &pVal);
220208 }
220209 assert( rc==SQLITE_OK );
220210 (void)rc; /* Suppress warning about unused variable */
220211 if( sqlite3_value_type(pVal)!=eType ) return 0;
220212
220213 /* A SessionChange object never has a NULL value in a PK column */
220214 assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT
220215 || eType==SQLITE_BLOB || eType==SQLITE_TEXT
@@ -225188,10 +226088,14 @@
226088 ** nAutomerge:
226089 ** The minimum number of segments that an auto-merge operation should
226090 ** attempt to merge together. A value of 1 sets the object to use the
226091 ** compile time default. Zero disables auto-merge altogether.
226092 **
226093 ** bContentlessDelete:
226094 ** True if the contentless_delete option was present in the CREATE
226095 ** VIRTUAL TABLE statement.
226096 **
226097 ** zContent:
226098 **
226099 ** zContentRowid:
226100 ** The value of the content_rowid= option, if one was specified. Or
226101 ** the string "rowid" otherwise. This text is not quoted - if it is
@@ -225222,10 +226126,11 @@
226126 char **azCol; /* Column names */
226127 u8 *abUnindexed; /* True for unindexed columns */
226128 int nPrefix; /* Number of prefix indexes */
226129 int *aPrefix; /* Sizes in bytes of nPrefix prefix indexes */
226130 int eContent; /* An FTS5_CONTENT value */
226131 int bContentlessDelete; /* "contentless_delete=" option (dflt==0) */
226132 char *zContent; /* content table */
226133 char *zContentRowid; /* "content_rowid=" option value */
226134 int bColumnsize; /* "columnsize=" option value (dflt==1) */
226135 int eDetail; /* FTS5_DETAIL_XXX value */
226136 char *zContentExprlist;
@@ -225243,10 +226148,11 @@
226148 int nUsermerge; /* 'usermerge' setting */
226149 int nHashSize; /* Bytes of memory for in-memory hash */
226150 char *zRank; /* Name of rank function */
226151 char *zRankArgs; /* Arguments to rank function */
226152 int bSecureDelete; /* 'secure-delete' */
226153 int nDeleteMerge; /* 'deletemerge' */
226154
226155 /* If non-NULL, points to sqlite3_vtab.base.zErrmsg. Often NULL. */
226156 char **pzErrmsg;
226157
226158 #ifdef SQLITE_DEBUG
@@ -225565,10 +226471,13 @@
226471 static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge);
226472 static int sqlite3Fts5IndexReset(Fts5Index *p);
226473
226474 static int sqlite3Fts5IndexLoadConfig(Fts5Index *p);
226475
226476 static int sqlite3Fts5IndexGetOrigin(Fts5Index *p, i64 *piOrigin);
226477 static int sqlite3Fts5IndexContentlessDelete(Fts5Index *p, i64 iOrigin, i64 iRowid);
226478
226479 /*
226480 ** End of interface to code in fts5_index.c.
226481 **************************************************************************/
226482
226483 /**************************************************************************
@@ -225649,10 +226558,15 @@
226558 /*
226559 ** Empty (but do not delete) a hash table.
226560 */
226561 static void sqlite3Fts5HashClear(Fts5Hash*);
226562
226563 /*
226564 ** Return true if the hash is empty, false otherwise.
226565 */
226566 static int sqlite3Fts5HashIsEmpty(Fts5Hash*);
226567
226568 static int sqlite3Fts5HashQuery(
226569 Fts5Hash*, /* Hash table to query */
226570 int nPre,
226571 const char *pTerm, int nTerm, /* Query term */
226572 void **ppObj, /* OUT: Pointer to doclist for pTerm */
@@ -225668,10 +226582,11 @@
226582 static void sqlite3Fts5HashScanEntry(Fts5Hash *,
226583 const char **pzTerm, /* OUT: term (nul-terminated) */
226584 const u8 **ppDoclist, /* OUT: pointer to doclist */
226585 int *pnDoclist /* OUT: size of doclist in bytes */
226586 );
226587
226588
226589
226590 /*
226591 ** End of interface to code in fts5_hash.c.
226592 **************************************************************************/
@@ -228542,10 +229457,12 @@
229457 #define FTS5_DEFAULT_AUTOMERGE 4
229458 #define FTS5_DEFAULT_USERMERGE 4
229459 #define FTS5_DEFAULT_CRISISMERGE 16
229460 #define FTS5_DEFAULT_HASHSIZE (1024*1024)
229461
229462 #define FTS5_DEFAULT_DELETE_AUTOMERGE 10 /* default 10% */
229463
229464 /* Maximum allowed page size */
229465 #define FTS5_MAX_PAGE_SIZE (64*1024)
229466
229467 static int fts5_iswhitespace(char x){
229468 return (x==' ');
@@ -228871,10 +229788,20 @@
229788 pConfig->eContent = FTS5_CONTENT_NONE;
229789 }
229790 }
229791 return rc;
229792 }
229793
229794 if( sqlite3_strnicmp("contentless_delete", zCmd, nCmd)==0 ){
229795 if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){
229796 *pzErr = sqlite3_mprintf("malformed contentless_delete=... directive");
229797 rc = SQLITE_ERROR;
229798 }else{
229799 pConfig->bContentlessDelete = (zArg[0]=='1');
229800 }
229801 return rc;
229802 }
229803
229804 if( sqlite3_strnicmp("content_rowid", zCmd, nCmd)==0 ){
229805 if( pConfig->zContentRowid ){
229806 *pzErr = sqlite3_mprintf("multiple content_rowid=... directives");
229807 rc = SQLITE_ERROR;
@@ -229115,10 +230042,32 @@
230042 }
230043
230044 sqlite3_free(zOne);
230045 sqlite3_free(zTwo);
230046 }
230047
230048 /* We only allow contentless_delete=1 if the table is indeed contentless. */
230049 if( rc==SQLITE_OK
230050 && pRet->bContentlessDelete
230051 && pRet->eContent!=FTS5_CONTENT_NONE
230052 ){
230053 *pzErr = sqlite3_mprintf(
230054 "contentless_delete=1 requires a contentless table"
230055 );
230056 rc = SQLITE_ERROR;
230057 }
230058
230059 /* We only allow contentless_delete=1 if columnsize=0 is not present.
230060 **
230061 ** This restriction may be removed at some point.
230062 */
230063 if( rc==SQLITE_OK && pRet->bContentlessDelete && pRet->bColumnsize==0 ){
230064 *pzErr = sqlite3_mprintf(
230065 "contentless_delete=1 is incompatible with columnsize=0"
230066 );
230067 rc = SQLITE_ERROR;
230068 }
230069
230070 /* If a tokenizer= option was successfully parsed, the tokenizer has
230071 ** already been allocated. Otherwise, allocate an instance of the default
230072 ** tokenizer (unicode61) now. */
230073 if( rc==SQLITE_OK && pRet->pTok==0 ){
@@ -229409,10 +230358,22 @@
230358 if( nCrisisMerge<=1 ) nCrisisMerge = FTS5_DEFAULT_CRISISMERGE;
230359 if( nCrisisMerge>=FTS5_MAX_SEGMENT ) nCrisisMerge = FTS5_MAX_SEGMENT-1;
230360 pConfig->nCrisisMerge = nCrisisMerge;
230361 }
230362 }
230363
230364 else if( 0==sqlite3_stricmp(zKey, "deletemerge") ){
230365 int nVal = -1;
230366 if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
230367 nVal = sqlite3_value_int(pVal);
230368 }else{
230369 *pbBadkey = 1;
230370 }
230371 if( nVal<0 ) nVal = FTS5_DEFAULT_DELETE_AUTOMERGE;
230372 if( nVal>100 ) nVal = 0;
230373 pConfig->nDeleteMerge = nVal;
230374 }
230375
230376 else if( 0==sqlite3_stricmp(zKey, "rank") ){
230377 const char *zIn = (const char*)sqlite3_value_text(pVal);
230378 char *zRank;
230379 char *zRankArgs;
@@ -229458,10 +230419,11 @@
230419 pConfig->pgsz = FTS5_DEFAULT_PAGE_SIZE;
230420 pConfig->nAutomerge = FTS5_DEFAULT_AUTOMERGE;
230421 pConfig->nUsermerge = FTS5_DEFAULT_USERMERGE;
230422 pConfig->nCrisisMerge = FTS5_DEFAULT_CRISISMERGE;
230423 pConfig->nHashSize = FTS5_DEFAULT_HASHSIZE;
230424 pConfig->nDeleteMerge = FTS5_DEFAULT_DELETE_AUTOMERGE;
230425
230426 zSql = sqlite3Fts5Mprintf(&rc, zSelect, pConfig->zDb, pConfig->zName);
230427 if( zSql ){
230428 rc = sqlite3_prepare_v2(pConfig->db, zSql, -1, &p, 0);
230429 sqlite3_free(zSql);
@@ -231981,11 +232943,11 @@
232943 }
232944
232945 return pRet;
232946 }
232947
232948 #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
232949 static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){
232950 sqlite3_int64 nByte = 0;
232951 Fts5ExprTerm *p;
232952 char *zQuoted;
232953
@@ -232348,18 +233310,18 @@
233310 iCode = sqlite3_value_int(apVal[0]);
233311 if( nArg==2 ) bRemoveDiacritics = sqlite3_value_int(apVal[1]);
233312 sqlite3_result_int(pCtx, sqlite3Fts5UnicodeFold(iCode, bRemoveDiacritics));
233313 }
233314 }
233315 #endif /* if SQLITE_TEST || SQLITE_FTS5_DEBUG */
233316
233317 /*
233318 ** This is called during initialization to register the fts5_expr() scalar
233319 ** UDF with the SQLite handle passed as the only argument.
233320 */
233321 static int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){
233322 #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
233323 struct Fts5ExprFunc {
233324 const char *z;
233325 void (*x)(sqlite3_context*,int,sqlite3_value**);
233326 } aFunc[] = {
233327 { "fts5_expr", fts5ExprFunctionHr },
@@ -233115,11 +234077,10 @@
234077 pList = 0;
234078 for(i=0; i<nMergeSlot; i++){
234079 pList = fts5HashEntryMerge(pList, ap[i]);
234080 }
234081
 
234082 sqlite3_free(ap);
234083 *ppSorted = pList;
234084 return SQLITE_OK;
234085 }
234086
@@ -233168,10 +234129,32 @@
234129 Fts5Hash *p, /* Hash table to query */
234130 const char *pTerm, int nTerm /* Query prefix */
234131 ){
234132 return fts5HashEntrySort(p, pTerm, nTerm, &p->pScan);
234133 }
234134
234135 #ifdef SQLITE_DEBUG
234136 static int fts5HashCount(Fts5Hash *pHash){
234137 int nEntry = 0;
234138 int ii;
234139 for(ii=0; ii<pHash->nSlot; ii++){
234140 Fts5HashEntry *p = 0;
234141 for(p=pHash->aSlot[ii]; p; p=p->pHashNext){
234142 nEntry++;
234143 }
234144 }
234145 return nEntry;
234146 }
234147 #endif
234148
234149 /*
234150 ** Return true if the hash table is empty, false otherwise.
234151 */
234152 static int sqlite3Fts5HashIsEmpty(Fts5Hash *pHash){
234153 assert( pHash->nEntry==fts5HashCount(pHash) );
234154 return pHash->nEntry==0;
234155 }
234156
234157 static void sqlite3Fts5HashScanNext(Fts5Hash *p){
234158 assert( !sqlite3Fts5HashScanEof(p) );
234159 p->pScan = p->pScan->pScanNext;
234160 }
@@ -233257,32 +234240,50 @@
234240 # error "FTS5_MAX_PREFIX_INDEXES is too large"
234241 #endif
234242
234243 #define FTS5_MAX_LEVEL 64
234244
234245 /*
234246 ** There are two versions of the format used for the structure record:
234247 **
234248 ** 1. the legacy format, that may be read by all fts5 versions, and
234249 **
234250 ** 2. the V2 format, which is used by contentless_delete=1 databases.
234251 **
234252 ** Both begin with a 4-byte "configuration cookie" value. Then, a legacy
234253 ** format structure record contains a varint - the number of levels in
234254 ** the structure. Whereas a V2 structure record contains the constant
234255 ** 4 bytes [0xff 0x00 0x00 0x01]. This is unambiguous as the value of a
234256 ** varint has to be at least 16256 to begin with "0xFF". And the default
234257 ** maximum number of levels is 64.
234258 **
234259 ** See below for more on structure record formats.
234260 */
234261 #define FTS5_STRUCTURE_V2 "\xFF\x00\x00\x01"
234262
234263 /*
234264 ** Details:
234265 **
234266 ** The %_data table managed by this module,
234267 **
234268 ** CREATE TABLE %_data(id INTEGER PRIMARY KEY, block BLOB);
234269 **
234270 ** , contains the following 6 types of records. See the comments surrounding
234271 ** the FTS5_*_ROWID macros below for a description of how %_data rowids are
234272 ** assigned to each fo them.
234273 **
234274 ** 1. Structure Records:
234275 **
234276 ** The set of segments that make up an index - the index structure - are
234277 ** recorded in a single record within the %_data table. The record consists
234278 ** of a single 32-bit configuration cookie value followed by a list of
234279 ** SQLite varints.
 
 
234280 **
234281 ** If the structure record is a V2 record, the configuration cookie is
234282 ** followed by the following 4 bytes: [0xFF 0x00 0x00 0x01].
234283 **
234284 ** Next, the record continues with three varints:
234285 **
234286 ** + number of levels,
234287 ** + total number of segments on all levels,
234288 ** + value of write counter.
234289 **
@@ -233293,10 +234294,16 @@
234294 ** + for each segment from oldest to newest:
234295 ** + segment id (always > 0)
234296 ** + first leaf page number (often 1, always greater than 0)
234297 ** + final leaf page number
234298 **
234299 ** Then, for V2 structures only:
234300 **
234301 ** + lower origin counter value,
234302 ** + upper origin counter value,
234303 ** + the number of tombstone hash pages.
234304 **
234305 ** 2. The Averages Record:
234306 **
234307 ** A single record within the %_data table. The data is a list of varints.
234308 ** The first value is the number of rows in the index. Then, for each column
234309 ** from left to right, the total number of tokens in the column for all
@@ -233408,10 +234415,42 @@
234415 ** * Copy of first rowid on page indicated by previous field. As a varint.
234416 **
234417 ** * A list of delta-encoded varints - the first rowid on each subsequent
234418 ** child page.
234419 **
234420 ** 6. Tombstone Hash Page
234421 **
234422 ** These records are only ever present in contentless_delete=1 tables.
234423 ** There are zero or more of these associated with each segment. They
234424 ** are used to store the tombstone rowids for rows contained in the
234425 ** associated segments.
234426 **
234427 ** The set of nHashPg tombstone hash pages associated with a single
234428 ** segment together form a single hash table containing tombstone rowids.
234429 ** To find the page of the hash on which a key might be stored:
234430 **
234431 ** iPg = (rowid % nHashPg)
234432 **
234433 ** Then, within page iPg, which has nSlot slots:
234434 **
234435 ** iSlot = (rowid / nHashPg) % nSlot
234436 **
234437 ** Each tombstone hash page begins with an 8 byte header:
234438 **
234439 ** 1-byte: Key-size (the size in bytes of each slot). Either 4 or 8.
234440 ** 1-byte: rowid-0-tombstone flag. This flag is only valid on the
234441 ** first tombstone hash page for each segment (iPg=0). If set,
234442 ** the hash table contains rowid 0. If clear, it does not.
234443 ** Rowid 0 is handled specially.
234444 ** 2-bytes: unused.
234445 ** 4-bytes: Big-endian integer containing number of entries on page.
234446 **
234447 ** Following this are nSlot 4 or 8 byte slots (depending on the key-size
234448 ** in the first byte of the page header). The number of slots may be
234449 ** determined based on the size of the page record and the key-size:
234450 **
234451 ** nSlot = (nByte - 8) / key-size
234452 */
234453
234454 /*
234455 ** Rowids for the averages and structure records in the %_data table.
234456 */
@@ -233441,10 +234480,11 @@
234480 ((i64)(pgno)) \
234481 )
234482
234483 #define FTS5_SEGMENT_ROWID(segid, pgno) fts5_dri(segid, 0, 0, pgno)
234484 #define FTS5_DLIDX_ROWID(segid, height, pgno) fts5_dri(segid, 1, height, pgno)
234485 #define FTS5_TOMBSTONE_ROWID(segid,ipg) fts5_dri(segid+(1<<16), 0, 0, ipg)
234486
234487 #ifdef SQLITE_DEBUG
234488 static int sqlite3Fts5Corrupt() { return SQLITE_CORRUPT_VTAB; }
234489 #endif
234490
@@ -233476,10 +234516,16 @@
234516 int szLeaf; /* Size of leaf without page-index */
234517 };
234518
234519 /*
234520 ** One object per %_data table.
234521 **
234522 ** nContentlessDelete:
234523 ** The number of contentless delete operations since the most recent
234524 ** call to fts5IndexFlush() or fts5IndexDiscardData(). This is tracked
234525 ** so that extra auto-merge work can be done by fts5IndexFlush() to
234526 ** account for the delete operations.
234527 */
234528 struct Fts5Index {
234529 Fts5Config *pConfig; /* Virtual table configuration */
234530 char *zDataTbl; /* Name of %_data table */
234531 int nWorkUnit; /* Leaf pages in a "unit" of work */
@@ -233490,10 +234536,12 @@
234536 */
234537 Fts5Hash *pHash; /* Hash table for in-memory data */
234538 int nPendingData; /* Current bytes of pending data */
234539 i64 iWriteRowid; /* Rowid for current doc being written */
234540 int bDelete; /* Current write is a delete */
234541 int nContentlessDelete; /* Number of contentless delete ops */
234542 int nPendingRow; /* Number of INSERT in hash table */
234543
234544 /* Error state. */
234545 int rc; /* Current error code */
234546
234547 /* State used by the fts5DataXXX() functions. */
@@ -233524,24 +234572,37 @@
234572
234573 /*
234574 ** The contents of the "structure" record for each index are represented
234575 ** using an Fts5Structure record in memory. Which uses instances of the
234576 ** other Fts5StructureXXX types as components.
234577 **
234578 ** nOriginCntr:
234579 ** This value is set to non-zero for structure records created for
234580 ** contentlessdelete=1 tables only. In that case it represents the
234581 ** origin value to apply to the next top-level segment created.
234582 */
234583 struct Fts5StructureSegment {
234584 int iSegid; /* Segment id */
234585 int pgnoFirst; /* First leaf page number in segment */
234586 int pgnoLast; /* Last leaf page number in segment */
234587
234588 /* contentlessdelete=1 tables only: */
234589 u64 iOrigin1;
234590 u64 iOrigin2;
234591 int nPgTombstone; /* Number of tombstone hash table pages */
234592 u64 nEntryTombstone; /* Number of tombstone entries that "count" */
234593 u64 nEntry; /* Number of rows in this segment */
234594 };
234595 struct Fts5StructureLevel {
234596 int nMerge; /* Number of segments in incr-merge */
234597 int nSeg; /* Total number of segments on level */
234598 Fts5StructureSegment *aSeg; /* Array of segments. aSeg[0] is oldest. */
234599 };
234600 struct Fts5Structure {
234601 int nRef; /* Object reference count */
234602 u64 nWriteCounter; /* Total leaves written to level 0 */
234603 u64 nOriginCntr; /* Origin value for next top-level segment */
234604 int nSegment; /* Total segments in this structure */
234605 int nLevel; /* Number of levels in this index */
234606 Fts5StructureLevel aLevel[1]; /* Array of nLevel level objects */
234607 };
234608
@@ -233626,18 +234687,27 @@
234687 ** corresponding aRowidOffset[] entry is set to the byte offset of the
234688 ** start of the "position-list-size" field within the page.
234689 **
234690 ** iTermIdx:
234691 ** Index of current term on iTermLeafPgno.
234692 **
234693 ** apTombstone/nTombstone:
234694 ** These are used for contentless_delete=1 tables only. When the cursor
234695 ** is first allocated, the apTombstone[] array is allocated so that it
234696 ** is large enough for all tombstones hash pages associated with the
234697 ** segment. The pages themselves are loaded lazily from the database as
234698 ** they are required.
234699 */
234700 struct Fts5SegIter {
234701 Fts5StructureSegment *pSeg; /* Segment to iterate through */
234702 int flags; /* Mask of configuration flags */
234703 int iLeafPgno; /* Current leaf page number */
234704 Fts5Data *pLeaf; /* Current leaf data */
234705 Fts5Data *pNextLeaf; /* Leaf page (iLeafPgno+1) */
234706 i64 iLeafOffset; /* Byte offset within current leaf */
234707 Fts5Data **apTombstone; /* Array of tombstone pages */
234708 int nTombstone;
234709
234710 /* Next method */
234711 void (*xNext)(Fts5Index*, Fts5SegIter*, int*);
234712
234713 /* The page and offset from which the current term was read. The offset
@@ -233762,10 +234832,64 @@
234832 }
234833
234834 static u16 fts5GetU16(const u8 *aIn){
234835 return ((u16)aIn[0] << 8) + aIn[1];
234836 }
234837
234838 /*
234839 ** The only argument points to a buffer at least 8 bytes in size. This
234840 ** function interprets the first 8 bytes of the buffer as a 64-bit big-endian
234841 ** unsigned integer and returns the result.
234842 */
234843 static u64 fts5GetU64(u8 *a){
234844 return ((u64)a[0] << 56)
234845 + ((u64)a[1] << 48)
234846 + ((u64)a[2] << 40)
234847 + ((u64)a[3] << 32)
234848 + ((u64)a[4] << 24)
234849 + ((u64)a[5] << 16)
234850 + ((u64)a[6] << 8)
234851 + ((u64)a[7] << 0);
234852 }
234853
234854 /*
234855 ** The only argument points to a buffer at least 4 bytes in size. This
234856 ** function interprets the first 4 bytes of the buffer as a 32-bit big-endian
234857 ** unsigned integer and returns the result.
234858 */
234859 static u32 fts5GetU32(const u8 *a){
234860 return ((u32)a[0] << 24)
234861 + ((u32)a[1] << 16)
234862 + ((u32)a[2] << 8)
234863 + ((u32)a[3] << 0);
234864 }
234865
234866 /*
234867 ** Write iVal, formated as a 64-bit big-endian unsigned integer, to the
234868 ** buffer indicated by the first argument.
234869 */
234870 static void fts5PutU64(u8 *a, u64 iVal){
234871 a[0] = ((iVal >> 56) & 0xFF);
234872 a[1] = ((iVal >> 48) & 0xFF);
234873 a[2] = ((iVal >> 40) & 0xFF);
234874 a[3] = ((iVal >> 32) & 0xFF);
234875 a[4] = ((iVal >> 24) & 0xFF);
234876 a[5] = ((iVal >> 16) & 0xFF);
234877 a[6] = ((iVal >> 8) & 0xFF);
234878 a[7] = ((iVal >> 0) & 0xFF);
234879 }
234880
234881 /*
234882 ** Write iVal, formated as a 32-bit big-endian unsigned integer, to the
234883 ** buffer indicated by the first argument.
234884 */
234885 static void fts5PutU32(u8 *a, u32 iVal){
234886 a[0] = ((iVal >> 24) & 0xFF);
234887 a[1] = ((iVal >> 16) & 0xFF);
234888 a[2] = ((iVal >> 8) & 0xFF);
234889 a[3] = ((iVal >> 0) & 0xFF);
234890 }
234891
234892 /*
234893 ** Allocate and return a buffer at least nByte bytes in size.
234894 **
234895 ** If an OOM error is encountered, return NULL and set the error code in
@@ -233990,14 +235114,21 @@
235114 }
235115
235116 /*
235117 ** Remove all records associated with segment iSegid.
235118 */
235119 static void fts5DataRemoveSegment(Fts5Index *p, Fts5StructureSegment *pSeg){
235120 int iSegid = pSeg->iSegid;
235121 i64 iFirst = FTS5_SEGMENT_ROWID(iSegid, 0);
235122 i64 iLast = FTS5_SEGMENT_ROWID(iSegid+1, 0)-1;
235123 fts5DataDelete(p, iFirst, iLast);
235124
235125 if( pSeg->nPgTombstone ){
235126 i64 iTomb1 = FTS5_TOMBSTONE_ROWID(iSegid, 0);
235127 i64 iTomb2 = FTS5_TOMBSTONE_ROWID(iSegid, pSeg->nPgTombstone-1);
235128 fts5DataDelete(p, iTomb1, iTomb2);
235129 }
235130 if( p->pIdxDeleter==0 ){
235131 Fts5Config *pConfig = p->pConfig;
235132 fts5IndexPrepareStmt(p, &p->pIdxDeleter, sqlite3_mprintf(
235133 "DELETE FROM '%q'.'%q_idx' WHERE segid=?",
235134 pConfig->zDb, pConfig->zName
@@ -234104,14 +235235,22 @@
235235 int iLvl;
235236 int nLevel = 0;
235237 int nSegment = 0;
235238 sqlite3_int64 nByte; /* Bytes of space to allocate at pRet */
235239 Fts5Structure *pRet = 0; /* Structure object to return */
235240 int bStructureV2 = 0; /* True for FTS5_STRUCTURE_V2 */
235241 u64 nOriginCntr = 0; /* Largest origin value seen so far */
235242
235243 /* Grab the cookie value */
235244 if( piCookie ) *piCookie = sqlite3Fts5Get32(pData);
235245 i = 4;
235246
235247 /* Check if this is a V2 structure record. Set bStructureV2 if it is. */
235248 if( 0==memcmp(&pData[i], FTS5_STRUCTURE_V2, 4) ){
235249 i += 4;
235250 bStructureV2 = 1;
235251 }
235252
235253 /* Read the total number of levels and segments from the start of the
235254 ** structure record. */
235255 i += fts5GetVarint32(&pData[i], nLevel);
235256 i += fts5GetVarint32(&pData[i], nSegment);
@@ -234159,10 +235298,18 @@
235298 }
235299 assert( pSeg!=0 );
235300 i += fts5GetVarint32(&pData[i], pSeg->iSegid);
235301 i += fts5GetVarint32(&pData[i], pSeg->pgnoFirst);
235302 i += fts5GetVarint32(&pData[i], pSeg->pgnoLast);
235303 if( bStructureV2 ){
235304 i += fts5GetVarint(&pData[i], &pSeg->iOrigin1);
235305 i += fts5GetVarint(&pData[i], &pSeg->iOrigin2);
235306 i += fts5GetVarint32(&pData[i], pSeg->nPgTombstone);
235307 i += fts5GetVarint(&pData[i], &pSeg->nEntryTombstone);
235308 i += fts5GetVarint(&pData[i], &pSeg->nEntry);
235309 nOriginCntr = MAX(nOriginCntr, pSeg->iOrigin2);
235310 }
235311 if( pSeg->pgnoLast<pSeg->pgnoFirst ){
235312 rc = FTS5_CORRUPT;
235313 break;
235314 }
235315 }
@@ -234169,10 +235316,13 @@
235316 if( iLvl>0 && pLvl[-1].nMerge && nTotal==0 ) rc = FTS5_CORRUPT;
235317 if( iLvl==nLevel-1 && pLvl->nMerge ) rc = FTS5_CORRUPT;
235318 }
235319 }
235320 if( nSegment!=0 && rc==SQLITE_OK ) rc = FTS5_CORRUPT;
235321 if( bStructureV2 ){
235322 pRet->nOriginCntr = nOriginCntr+1;
235323 }
235324
235325 if( rc!=SQLITE_OK ){
235326 fts5StructureRelease(pRet);
235327 pRet = 0;
235328 }
@@ -234381,21 +235531,25 @@
235531 static void fts5StructureWrite(Fts5Index *p, Fts5Structure *pStruct){
235532 if( p->rc==SQLITE_OK ){
235533 Fts5Buffer buf; /* Buffer to serialize record into */
235534 int iLvl; /* Used to iterate through levels */
235535 int iCookie; /* Cookie value to store */
235536 int nHdr = (pStruct->nOriginCntr>0 ? (4+4+9+9+9) : (4+9+9));
235537
235538 assert( pStruct->nSegment==fts5StructureCountSegments(pStruct) );
235539 memset(&buf, 0, sizeof(Fts5Buffer));
235540
235541 /* Append the current configuration cookie */
235542 iCookie = p->pConfig->iCookie;
235543 if( iCookie<0 ) iCookie = 0;
235544
235545 if( 0==sqlite3Fts5BufferSize(&p->rc, &buf, nHdr) ){
235546 sqlite3Fts5Put32(buf.p, iCookie);
235547 buf.n = 4;
235548 if( pStruct->nOriginCntr>0 ){
235549 fts5BufferSafeAppendBlob(&buf, FTS5_STRUCTURE_V2, 4);
235550 }
235551 fts5BufferSafeAppendVarint(&buf, pStruct->nLevel);
235552 fts5BufferSafeAppendVarint(&buf, pStruct->nSegment);
235553 fts5BufferSafeAppendVarint(&buf, (i64)pStruct->nWriteCounter);
235554 }
235555
@@ -234405,13 +235559,21 @@
235559 fts5BufferAppendVarint(&p->rc, &buf, pLvl->nMerge);
235560 fts5BufferAppendVarint(&p->rc, &buf, pLvl->nSeg);
235561 assert( pLvl->nMerge<=pLvl->nSeg );
235562
235563 for(iSeg=0; iSeg<pLvl->nSeg; iSeg++){
235564 Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg];
235565 fts5BufferAppendVarint(&p->rc, &buf, pSeg->iSegid);
235566 fts5BufferAppendVarint(&p->rc, &buf, pSeg->pgnoFirst);
235567 fts5BufferAppendVarint(&p->rc, &buf, pSeg->pgnoLast);
235568 if( pStruct->nOriginCntr>0 ){
235569 fts5BufferAppendVarint(&p->rc, &buf, pSeg->iOrigin1);
235570 fts5BufferAppendVarint(&p->rc, &buf, pSeg->iOrigin2);
235571 fts5BufferAppendVarint(&p->rc, &buf, pSeg->nPgTombstone);
235572 fts5BufferAppendVarint(&p->rc, &buf, pSeg->nEntryTombstone);
235573 fts5BufferAppendVarint(&p->rc, &buf, pSeg->nEntry);
235574 }
235575 }
235576 }
235577
235578 fts5DataWrite(p, FTS5_STRUCTURE_ROWID, buf.p, buf.n);
235579 fts5BufferFree(&buf);
@@ -234929,10 +236091,27 @@
236091 pIter->xNext = fts5SegIterNext_None;
236092 }else{
236093 pIter->xNext = fts5SegIterNext;
236094 }
236095 }
236096
236097 /*
236098 ** Allocate a tombstone hash page array (pIter->apTombstone) for the
236099 ** iterator passed as the second argument. If an OOM error occurs, leave
236100 ** an error in the Fts5Index object.
236101 */
236102 static void fts5SegIterAllocTombstone(Fts5Index *p, Fts5SegIter *pIter){
236103 const int nTomb = pIter->pSeg->nPgTombstone;
236104 if( nTomb>0 ){
236105 Fts5Data **apTomb = 0;
236106 apTomb = (Fts5Data**)sqlite3Fts5MallocZero(&p->rc, sizeof(Fts5Data)*nTomb);
236107 if( apTomb ){
236108 pIter->apTombstone = apTomb;
236109 pIter->nTombstone = nTomb;
236110 }
236111 }
236112 }
236113
236114 /*
236115 ** Initialize the iterator object pIter to iterate through the entries in
236116 ** segment pSeg. The iterator is left pointing to the first entry when
236117 ** this function returns.
@@ -234971,10 +236150,11 @@
236150 assert_nc( pIter->pLeaf->nn>4 );
236151 assert_nc( fts5LeafFirstTermOff(pIter->pLeaf)==4 );
236152 pIter->iPgidxOff = pIter->pLeaf->szLeaf+1;
236153 fts5SegIterLoadTerm(p, pIter, 0);
236154 fts5SegIterLoadNPos(p, pIter);
236155 fts5SegIterAllocTombstone(p, pIter);
236156 }
236157 }
236158
236159 /*
236160 ** This function is only ever called on iterators created by calls to
@@ -235672,10 +236852,11 @@
236852 }
236853 }
236854 }
236855
236856 fts5SegIterSetNext(p, pIter);
236857 fts5SegIterAllocTombstone(p, pIter);
236858
236859 /* Either:
236860 **
236861 ** 1) an error has occurred, or
236862 ** 2) the iterator points to EOF, or
@@ -235751,18 +236932,33 @@
236932 }
236933 }
236934
236935 fts5SegIterSetNext(p, pIter);
236936 }
236937
236938 /*
236939 ** Array ap[] contains n elements. Release each of these elements using
236940 ** fts5DataRelease(). Then free the array itself using sqlite3_free().
236941 */
236942 static void fts5IndexFreeArray(Fts5Data **ap, int n){
236943 if( ap ){
236944 int ii;
236945 for(ii=0; ii<n; ii++){
236946 fts5DataRelease(ap[ii]);
236947 }
236948 sqlite3_free(ap);
236949 }
236950 }
236951
236952 /*
236953 ** Zero the iterator passed as the only argument.
236954 */
236955 static void fts5SegIterClear(Fts5SegIter *pIter){
236956 fts5BufferFree(&pIter->term);
236957 fts5DataRelease(pIter->pLeaf);
236958 fts5DataRelease(pIter->pNextLeaf);
236959 fts5IndexFreeArray(pIter->apTombstone, pIter->nTombstone);
236960 fts5DlidxIterFree(pIter->pDlidx);
236961 sqlite3_free(pIter->aRowidOffset);
236962 memset(pIter, 0, sizeof(Fts5SegIter));
236963 }
236964
@@ -236095,10 +237291,88 @@
237291 static void fts5MultiIterSetEof(Fts5Iter *pIter){
237292 Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
237293 pIter->base.bEof = pSeg->pLeaf==0;
237294 pIter->iSwitchRowid = pSeg->iRowid;
237295 }
237296
237297 /*
237298 ** The argument to this macro must be an Fts5Data structure containing a
237299 ** tombstone hash page. This macro returns the key-size of the hash-page.
237300 */
237301 #define TOMBSTONE_KEYSIZE(pPg) (pPg->p[0]==4 ? 4 : 8)
237302
237303 #define TOMBSTONE_NSLOT(pPg) \
237304 ((pPg->nn > 16) ? ((pPg->nn-8) / TOMBSTONE_KEYSIZE(pPg)) : 1)
237305
237306 /*
237307 ** Query a single tombstone hash table for rowid iRowid. Return true if
237308 ** it is found or false otherwise. The tombstone hash table is one of
237309 ** nHashTable tables.
237310 */
237311 static int fts5IndexTombstoneQuery(
237312 Fts5Data *pHash, /* Hash table page to query */
237313 int nHashTable, /* Number of pages attached to segment */
237314 u64 iRowid /* Rowid to query hash for */
237315 ){
237316 const int szKey = TOMBSTONE_KEYSIZE(pHash);
237317 const int nSlot = TOMBSTONE_NSLOT(pHash);
237318 int iSlot = (iRowid / nHashTable) % nSlot;
237319 int nCollide = nSlot;
237320
237321 if( iRowid==0 ){
237322 return pHash->p[1];
237323 }else if( szKey==4 ){
237324 u32 *aSlot = (u32*)&pHash->p[8];
237325 while( aSlot[iSlot] ){
237326 if( fts5GetU32((u8*)&aSlot[iSlot])==iRowid ) return 1;
237327 if( nCollide--==0 ) break;
237328 iSlot = (iSlot+1)%nSlot;
237329 }
237330 }else{
237331 u64 *aSlot = (u64*)&pHash->p[8];
237332 while( aSlot[iSlot] ){
237333 if( fts5GetU64((u8*)&aSlot[iSlot])==iRowid ) return 1;
237334 if( nCollide--==0 ) break;
237335 iSlot = (iSlot+1)%nSlot;
237336 }
237337 }
237338
237339 return 0;
237340 }
237341
237342 /*
237343 ** Return true if the iterator passed as the only argument points
237344 ** to an segment entry for which there is a tombstone. Return false
237345 ** if there is no tombstone or if the iterator is already at EOF.
237346 */
237347 static int fts5MultiIterIsDeleted(Fts5Iter *pIter){
237348 int iFirst = pIter->aFirst[1].iFirst;
237349 Fts5SegIter *pSeg = &pIter->aSeg[iFirst];
237350
237351 if( pSeg->pLeaf && pSeg->nTombstone ){
237352 /* Figure out which page the rowid might be present on. */
237353 int iPg = ((u64)pSeg->iRowid) % pSeg->nTombstone;
237354 assert( iPg>=0 );
237355
237356 /* If tombstone hash page iPg has not yet been loaded from the
237357 ** database, load it now. */
237358 if( pSeg->apTombstone[iPg]==0 ){
237359 pSeg->apTombstone[iPg] = fts5DataRead(pIter->pIndex,
237360 FTS5_TOMBSTONE_ROWID(pSeg->pSeg->iSegid, iPg)
237361 );
237362 if( pSeg->apTombstone[iPg]==0 ) return 0;
237363 }
237364
237365 return fts5IndexTombstoneQuery(
237366 pSeg->apTombstone[iPg],
237367 pSeg->nTombstone,
237368 pSeg->iRowid
237369 );
237370 }
237371
237372 return 0;
237373 }
237374
237375 /*
237376 ** Move the iterator to the next entry.
237377 **
237378 ** If an error occurs, an error code is left in Fts5Index.rc. It is not
@@ -236133,11 +237407,13 @@
237407 if( pSeg->pLeaf==0 ) return;
237408 }
237409
237410 fts5AssertMultiIterSetup(p, pIter);
237411 assert( pSeg==&pIter->aSeg[pIter->aFirst[1].iFirst] && pSeg->pLeaf );
237412 if( (pIter->bSkipEmpty==0 || pSeg->nPos)
237413 && 0==fts5MultiIterIsDeleted(pIter)
237414 ){
237415 pIter->xSetOutputs(pIter, pSeg);
237416 return;
237417 }
237418 bUseFrom = 0;
237419 }
@@ -236165,11 +237441,13 @@
237441 fts5MultiIterSetEof(pIter);
237442 *pbNewTerm = 1;
237443 }
237444 fts5AssertMultiIterSetup(p, pIter);
237445
237446 }while( (fts5MultiIterIsEmpty(p, pIter) || fts5MultiIterIsDeleted(pIter))
237447 && (p->rc==SQLITE_OK)
237448 );
237449 }
237450 }
237451
237452 static void fts5IterSetOutputs_Noop(Fts5Iter *pUnused1, Fts5SegIter *pUnused2){
237453 UNUSED_PARAM2(pUnused1, pUnused2);
@@ -236720,11 +237998,13 @@
237998 }
237999 }
238000 fts5MultiIterSetEof(pNew);
238001 fts5AssertMultiIterSetup(p, pNew);
238002
238003 if( (pNew->bSkipEmpty && fts5MultiIterIsEmpty(p, pNew))
238004 || fts5MultiIterIsDeleted(pNew)
238005 ){
238006 fts5MultiIterNext(p, pNew, 0, 0);
238007 }else if( pNew->base.bEof==0 ){
238008 Fts5SegIter *pSeg = &pNew->aSeg[pNew->aFirst[1].iFirst];
238009 pNew->xSetOutputs(pNew, pSeg);
238010 }
@@ -236898,11 +238178,13 @@
238178 static void fts5IndexDiscardData(Fts5Index *p){
238179 assert( p->pHash || p->nPendingData==0 );
238180 if( p->pHash ){
238181 sqlite3Fts5HashClear(p->pHash);
238182 p->nPendingData = 0;
238183 p->nPendingRow = 0;
238184 }
238185 p->nContentlessDelete = 0;
238186 }
238187
238188 /*
238189 ** Return the size of the prefix, in bytes, that buffer
238190 ** (pNew/<length-unknown>) shares with buffer (pOld/nOld).
@@ -237535,10 +238817,16 @@
238817 pSeg->iSegid = iSegid;
238818 pStruct->nSegment++;
238819
238820 /* Read input from all segments in the input level */
238821 nInput = pLvl->nSeg;
238822
238823 /* Set the range of origins that will go into the output segment. */
238824 if( pStruct->nOriginCntr>0 ){
238825 pSeg->iOrigin1 = pLvl->aSeg[0].iOrigin1;
238826 pSeg->iOrigin2 = pLvl->aSeg[pLvl->nSeg-1].iOrigin2;
238827 }
238828 }
238829 bOldest = (pLvlOut->nSeg==1 && pStruct->nLevel==iLvl+2);
238830
238831 assert( iLvl>=0 );
238832 for(fts5MultiIterNew(p, pStruct, flags, 0, 0, 0, iLvl, nInput, &pIter);
@@ -237594,12 +238882,15 @@
238882 assert( pIter!=0 || p->rc!=SQLITE_OK );
238883 if( fts5MultiIterEof(p, pIter) ){
238884 int i;
238885
238886 /* Remove the redundant segments from the %_data table */
238887 assert( pSeg->nEntry==0 );
238888 for(i=0; i<nInput; i++){
238889 Fts5StructureSegment *pOld = &pLvl->aSeg[i];
238890 pSeg->nEntry += (pOld->nEntry - pOld->nEntryTombstone);
238891 fts5DataRemoveSegment(p, pOld);
238892 }
238893
238894 /* Remove the redundant segments from the input level */
238895 if( pLvl->nSeg!=nInput ){
238896 int nMove = (pLvl->nSeg - nInput) * sizeof(Fts5StructureSegment);
@@ -237620,10 +238911,47 @@
238911
238912 fts5MultiIterFree(pIter);
238913 fts5BufferFree(&term);
238914 if( pnRem ) *pnRem -= writer.nLeafWritten;
238915 }
238916
238917 /*
238918 ** If this is not a contentless_delete=1 table, or if the 'deletemerge'
238919 ** configuration option is set to 0, then this function always returns -1.
238920 ** Otherwise, it searches the structure object passed as the second argument
238921 ** for a level suitable for merging due to having a large number of
238922 ** tombstones in the tombstone hash. If one is found, its index is returned.
238923 ** Otherwise, if there is no suitable level, -1.
238924 */
238925 static int fts5IndexFindDeleteMerge(Fts5Index *p, Fts5Structure *pStruct){
238926 Fts5Config *pConfig = p->pConfig;
238927 int iRet = -1;
238928 if( pConfig->bContentlessDelete && pConfig->nDeleteMerge>0 ){
238929 int ii;
238930 int nBest = 0;
238931
238932 for(ii=0; ii<pStruct->nLevel; ii++){
238933 Fts5StructureLevel *pLvl = &pStruct->aLevel[ii];
238934 i64 nEntry = 0;
238935 i64 nTomb = 0;
238936 int iSeg;
238937 for(iSeg=0; iSeg<pLvl->nSeg; iSeg++){
238938 nEntry += pLvl->aSeg[iSeg].nEntry;
238939 nTomb += pLvl->aSeg[iSeg].nEntryTombstone;
238940 }
238941 assert_nc( nEntry>0 || pLvl->nSeg==0 );
238942 if( nEntry>0 ){
238943 int nPercent = (nTomb * 100) / nEntry;
238944 if( nPercent>=pConfig->nDeleteMerge && nPercent>nBest ){
238945 iRet = ii;
238946 nBest = nPercent;
238947 }
238948 }
238949 }
238950 }
238951 return iRet;
238952 }
238953
238954 /*
238955 ** Do up to nPg pages of automerge work on the index.
238956 **
238957 ** Return true if any changes were actually made, or false otherwise.
@@ -237640,42 +238968,39 @@
238968 while( nRem>0 && p->rc==SQLITE_OK ){
238969 int iLvl; /* To iterate through levels */
238970 int iBestLvl = 0; /* Level offering the most input segments */
238971 int nBest = 0; /* Number of input segments on best level */
238972
238973 /* Set iBestLvl to the level to read input segments from. Or to -1 if
238974 ** there is no level suitable to merge segments from. */
238975 assert( pStruct->nLevel>0 );
238976 for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
238977 Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl];
238978 if( pLvl->nMerge ){
238979 if( pLvl->nMerge>nBest ){
238980 iBestLvl = iLvl;
238981 nBest = nMin;
238982 }
238983 break;
238984 }
238985 if( pLvl->nSeg>nBest ){
238986 nBest = pLvl->nSeg;
238987 iBestLvl = iLvl;
238988 }
238989 }
238990 if( nBest<nMin ){
238991 iBestLvl = fts5IndexFindDeleteMerge(p, pStruct);
238992 }
238993
238994 if( iBestLvl<0 ) break;
 
 
 
 
 
 
238995 bRet = 1;
238996 fts5IndexMergeLevel(p, &pStruct, iBestLvl, &nRem);
238997 if( p->rc==SQLITE_OK && pStruct->aLevel[iBestLvl].nMerge==0 ){
238998 fts5StructurePromote(p, iBestLvl+1, pStruct);
238999 }
239000
239001 if( nMin==1 ) nMin = 2;
239002 }
239003 *ppStruct = pStruct;
239004 return bRet;
239005 }
239006
@@ -237856,13 +239181,17 @@
239181 if( pLeaf->nn>pLeaf->szLeaf ){
239182 int iFirst = 0;
239183 int i1 = pLeaf->szLeaf;
239184 int i2 = 0;
239185
239186 i1 += fts5GetVarint32(&aPg[i1], iFirst);
239187 if( iFirst<iNext ){
239188 p->rc = FTS5_CORRUPT;
239189 break;
239190 }
239191 aIdx = sqlite3Fts5MallocZero(&p->rc, (pLeaf->nn-pLeaf->szLeaf)+2);
239192 if( aIdx==0 ) break;
 
239193 i2 = sqlite3Fts5PutVarint(aIdx, iFirst-nShift);
239194 if( i1<pLeaf->nn ){
239195 memcpy(&aIdx[i2], &aPg[i1], pLeaf->nn-i1);
239196 i2 += (pLeaf->nn-i1);
239197 }
@@ -238180,202 +239509,212 @@
239509 int pgnoLast = 0; /* Last leaf page number in segment */
239510
239511 /* Obtain a reference to the index structure and allocate a new segment-id
239512 ** for the new level-0 segment. */
239513 pStruct = fts5StructureRead(p);
239514 fts5StructureInvalidate(p);
239515
239516 if( sqlite3Fts5HashIsEmpty(pHash)==0 ){
239517 iSegid = fts5AllocateSegid(p, pStruct);
239518 if( iSegid ){
239519 const int pgsz = p->pConfig->pgsz;
239520 int eDetail = p->pConfig->eDetail;
239521 int bSecureDelete = p->pConfig->bSecureDelete;
239522 Fts5StructureSegment *pSeg; /* New segment within pStruct */
239523 Fts5Buffer *pBuf; /* Buffer in which to assemble leaf page */
239524 Fts5Buffer *pPgidx; /* Buffer in which to assemble pgidx */
239525
239526 Fts5SegWriter writer;
239527 fts5WriteInit(p, &writer, iSegid);
239528
239529 pBuf = &writer.writer.buf;
239530 pPgidx = &writer.writer.pgidx;
239531
239532 /* fts5WriteInit() should have initialized the buffers to (most likely)
239533 ** the maximum space required. */
239534 assert( p->rc || pBuf->nSpace>=(pgsz + FTS5_DATA_PADDING) );
239535 assert( p->rc || pPgidx->nSpace>=(pgsz + FTS5_DATA_PADDING) );
239536
239537 /* Begin scanning through hash table entries. This loop runs once for each
239538 ** term/doclist currently stored within the hash table. */
239539 if( p->rc==SQLITE_OK ){
239540 p->rc = sqlite3Fts5HashScanInit(pHash, 0, 0);
239541 }
239542 while( p->rc==SQLITE_OK && 0==sqlite3Fts5HashScanEof(pHash) ){
239543 const char *zTerm; /* Buffer containing term */
239544 int nTerm; /* Size of zTerm in bytes */
239545 const u8 *pDoclist; /* Pointer to doclist for this term */
239546 int nDoclist; /* Size of doclist in bytes */
239547
239548 /* Get the term and doclist for this entry. */
239549 sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist);
239550 nTerm = (int)strlen(zTerm);
239551 if( bSecureDelete==0 ){
239552 fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm);
239553 if( p->rc!=SQLITE_OK ) break;
239554 assert( writer.bFirstRowidInPage==0 );
239555 }
239556
239557 if( !bSecureDelete && pgsz>=(pBuf->n + pPgidx->n + nDoclist + 1) ){
239558 /* The entire doclist will fit on the current leaf. */
239559 fts5BufferSafeAppendBlob(pBuf, pDoclist, nDoclist);
239560 }else{
239561 int bTermWritten = !bSecureDelete;
239562 i64 iRowid = 0;
239563 i64 iPrev = 0;
239564 int iOff = 0;
239565
239566 /* The entire doclist will not fit on this leaf. The following
239567 ** loop iterates through the poslists that make up the current
239568 ** doclist. */
239569 while( p->rc==SQLITE_OK && iOff<nDoclist ){
239570 u64 iDelta = 0;
239571 iOff += fts5GetVarint(&pDoclist[iOff], &iDelta);
239572 iRowid += iDelta;
239573
239574 /* If in secure delete mode, and if this entry in the poslist is
239575 ** in fact a delete, then edit the existing segments directly
239576 ** using fts5FlushSecureDelete(). */
239577 if( bSecureDelete ){
239578 if( eDetail==FTS5_DETAIL_NONE ){
239579 if( iOff<nDoclist && pDoclist[iOff]==0x00 ){
239580 fts5FlushSecureDelete(p, pStruct, zTerm, iRowid);
239581 iOff++;
239582 if( iOff<nDoclist && pDoclist[iOff]==0x00 ){
239583 iOff++;
239584 nDoclist = 0;
239585 }else{
239586 continue;
239587 }
239588 }
239589 }else if( (pDoclist[iOff] & 0x01) ){
239590 fts5FlushSecureDelete(p, pStruct, zTerm, iRowid);
239591 if( p->rc!=SQLITE_OK || pDoclist[iOff]==0x01 ){
239592 iOff++;
239593 continue;
239594 }
239595 }
239596 }
239597
239598 if( p->rc==SQLITE_OK && bTermWritten==0 ){
239599 fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm);
239600 bTermWritten = 1;
239601 assert( p->rc!=SQLITE_OK || writer.bFirstRowidInPage==0 );
239602 }
239603
239604 if( writer.bFirstRowidInPage ){
239605 fts5PutU16(&pBuf->p[0], (u16)pBuf->n); /* first rowid on page */
239606 pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid);
239607 writer.bFirstRowidInPage = 0;
239608 fts5WriteDlidxAppend(p, &writer, iRowid);
239609 }else{
239610 pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid-iPrev);
239611 }
239612 if( p->rc!=SQLITE_OK ) break;
239613 assert( pBuf->n<=pBuf->nSpace );
239614 iPrev = iRowid;
239615
239616 if( eDetail==FTS5_DETAIL_NONE ){
239617 if( iOff<nDoclist && pDoclist[iOff]==0 ){
239618 pBuf->p[pBuf->n++] = 0;
239619 iOff++;
239620 if( iOff<nDoclist && pDoclist[iOff]==0 ){
239621 pBuf->p[pBuf->n++] = 0;
239622 iOff++;
239623 }
239624 }
239625 if( (pBuf->n + pPgidx->n)>=pgsz ){
239626 fts5WriteFlushLeaf(p, &writer);
239627 }
239628 }else{
239629 int bDummy;
239630 int nPos;
239631 int nCopy = fts5GetPoslistSize(&pDoclist[iOff], &nPos, &bDummy);
239632 nCopy += nPos;
239633 if( (pBuf->n + pPgidx->n + nCopy) <= pgsz ){
239634 /* The entire poslist will fit on the current leaf. So copy
239635 ** it in one go. */
239636 fts5BufferSafeAppendBlob(pBuf, &pDoclist[iOff], nCopy);
239637 }else{
239638 /* The entire poslist will not fit on this leaf. So it needs
239639 ** to be broken into sections. The only qualification being
239640 ** that each varint must be stored contiguously. */
239641 const u8 *pPoslist = &pDoclist[iOff];
239642 int iPos = 0;
239643 while( p->rc==SQLITE_OK ){
239644 int nSpace = pgsz - pBuf->n - pPgidx->n;
239645 int n = 0;
239646 if( (nCopy - iPos)<=nSpace ){
239647 n = nCopy - iPos;
239648 }else{
239649 n = fts5PoslistPrefix(&pPoslist[iPos], nSpace);
239650 }
239651 assert( n>0 );
239652 fts5BufferSafeAppendBlob(pBuf, &pPoslist[iPos], n);
239653 iPos += n;
239654 if( (pBuf->n + pPgidx->n)>=pgsz ){
239655 fts5WriteFlushLeaf(p, &writer);
239656 }
239657 if( iPos>=nCopy ) break;
239658 }
239659 }
239660 iOff += nCopy;
239661 }
239662 }
239663 }
239664
239665 /* TODO2: Doclist terminator written here. */
239666 /* pBuf->p[pBuf->n++] = '\0'; */
239667 assert( pBuf->n<=pBuf->nSpace );
239668 if( p->rc==SQLITE_OK ) sqlite3Fts5HashScanNext(pHash);
239669 }
239670 sqlite3Fts5HashClear(pHash);
239671 fts5WriteFinish(p, &writer, &pgnoLast);
239672
239673 assert( p->rc!=SQLITE_OK || bSecureDelete || pgnoLast>0 );
239674 if( pgnoLast>0 ){
239675 /* Update the Fts5Structure. It is written back to the database by the
239676 ** fts5StructureRelease() call below. */
239677 if( pStruct->nLevel==0 ){
239678 fts5StructureAddLevel(&p->rc, &pStruct);
239679 }
239680 fts5StructureExtendLevel(&p->rc, pStruct, 0, 1, 0);
239681 if( p->rc==SQLITE_OK ){
239682 pSeg = &pStruct->aLevel[0].aSeg[ pStruct->aLevel[0].nSeg++ ];
239683 pSeg->iSegid = iSegid;
239684 pSeg->pgnoFirst = 1;
239685 pSeg->pgnoLast = pgnoLast;
239686 if( pStruct->nOriginCntr>0 ){
239687 pSeg->iOrigin1 = pStruct->nOriginCntr;
239688 pSeg->iOrigin2 = pStruct->nOriginCntr;
239689 pSeg->nEntry = p->nPendingRow;
239690 pStruct->nOriginCntr++;
239691 }
239692 pStruct->nSegment++;
239693 }
239694 fts5StructurePromote(p, 0, pStruct);
239695 }
239696 }
239697 }
239698
239699 fts5IndexAutomerge(p, &pStruct, pgnoLast + p->nContentlessDelete);
239700 fts5IndexCrisismerge(p, &pStruct);
239701 fts5StructureWrite(p, pStruct);
239702 fts5StructureRelease(pStruct);
239703 p->nContentlessDelete = 0;
239704 }
239705
239706 /*
239707 ** Flush any data stored in the in-memory hash tables to the database.
239708 */
239709 static void fts5IndexFlush(Fts5Index *p){
239710 /* Unless it is empty, flush the hash table to disk */
239711 if( p->nPendingData || p->nContentlessDelete ){
239712 assert( p->pHash );
 
239713 fts5FlushOneHash(p);
239714 p->nPendingData = 0;
239715 p->nPendingRow = 0;
239716 }
239717 }
239718
239719 static Fts5Structure *fts5IndexOptimizeStruct(
239720 Fts5Index *p,
@@ -238387,21 +239726,26 @@
239726 int i;
239727
239728 /* Figure out if this structure requires optimization. A structure does
239729 ** not require optimization if either:
239730 **
239731 ** 1. it consists of fewer than two segments, or
239732 ** 2. all segments are on the same level, or
239733 ** 3. all segments except one are currently inputs to a merge operation.
239734 **
239735 ** In the first case, if there are no tombstone hash pages, return NULL. In
239736 ** the second, increment the ref-count on *pStruct and return a copy of the
239737 ** pointer to it.
239738 */
239739 if( nSeg==0 ) return 0;
239740 for(i=0; i<pStruct->nLevel; i++){
239741 int nThis = pStruct->aLevel[i].nSeg;
239742 int nMerge = pStruct->aLevel[i].nMerge;
239743 if( nThis>0 && (nThis==nSeg || (nThis==nSeg-1 && nMerge==nThis)) ){
239744 if( nSeg==1 && nThis==1 && pStruct->aLevel[i].aSeg[0].nPgTombstone==0 ){
239745 return 0;
239746 }
239747 fts5StructureRef(pStruct);
239748 return pStruct;
239749 }
239750 assert( pStruct->aLevel[i].nMerge<=nThis );
239751 }
@@ -238413,10 +239757,11 @@
239757 Fts5StructureLevel *pLvl;
239758 nByte = nSeg * sizeof(Fts5StructureSegment);
239759 pNew->nLevel = MIN(pStruct->nLevel+1, FTS5_MAX_LEVEL);
239760 pNew->nRef = 1;
239761 pNew->nWriteCounter = pStruct->nWriteCounter;
239762 pNew->nOriginCntr = pStruct->nOriginCntr;
239763 pLvl = &pNew->aLevel[pNew->nLevel-1];
239764 pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&p->rc, nByte);
239765 if( pLvl->aSeg ){
239766 int iLvl, iSeg;
239767 int iSegOut = 0;
@@ -238443,10 +239788,11 @@
239788 Fts5Structure *pStruct;
239789 Fts5Structure *pNew = 0;
239790
239791 assert( p->rc==SQLITE_OK );
239792 fts5IndexFlush(p);
239793 assert( p->nContentlessDelete==0 );
239794 pStruct = fts5StructureRead(p);
239795 fts5StructureInvalidate(p);
239796
239797 if( pStruct ){
239798 pNew = fts5IndexOptimizeStruct(p, pStruct);
@@ -238472,19 +239818,22 @@
239818 /*
239819 ** This is called to implement the special "VALUES('merge', $nMerge)"
239820 ** INSERT command.
239821 */
239822 static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){
239823 Fts5Structure *pStruct = 0;
239824
239825 fts5IndexFlush(p);
239826 pStruct = fts5StructureRead(p);
239827 if( pStruct ){
239828 int nMin = p->pConfig->nUsermerge;
239829 fts5StructureInvalidate(p);
239830 if( nMerge<0 ){
239831 Fts5Structure *pNew = fts5IndexOptimizeStruct(p, pStruct);
239832 fts5StructureRelease(pStruct);
239833 pStruct = pNew;
239834 nMin = 1;
239835 nMerge = nMerge*-1;
239836 }
239837 if( pStruct && pStruct->nLevel ){
239838 if( fts5IndexMerge(p, &pStruct, nMerge, nMin) ){
239839 fts5StructureWrite(p, pStruct);
@@ -238994,10 +240343,13 @@
240343 fts5IndexFlush(p);
240344 }
240345
240346 p->iWriteRowid = iRowid;
240347 p->bDelete = bDelete;
240348 if( bDelete==0 ){
240349 p->nPendingRow++;
240350 }
240351 return fts5IndexReturn(p);
240352 }
240353
240354 /*
240355 ** Commit data to disk.
@@ -239031,10 +240383,13 @@
240383 static int sqlite3Fts5IndexReinit(Fts5Index *p){
240384 Fts5Structure s;
240385 fts5StructureInvalidate(p);
240386 fts5IndexDiscardData(p);
240387 memset(&s, 0, sizeof(Fts5Structure));
240388 if( p->pConfig->bContentlessDelete ){
240389 s.nOriginCntr = 1;
240390 }
240391 fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0);
240392 fts5StructureWrite(p, &s);
240393 return fts5IndexReturn(p);
240394 }
240395
@@ -239422,10 +240777,351 @@
240777 pStruct = fts5StructureRead(p);
240778 fts5StructureRelease(pStruct);
240779 return fts5IndexReturn(p);
240780 }
240781
240782 /*
240783 ** Retrieve the origin value that will be used for the segment currently
240784 ** being accumulated in the in-memory hash table when it is flushed to
240785 ** disk. If successful, SQLITE_OK is returned and (*piOrigin) set to
240786 ** the queried value. Or, if an error occurs, an error code is returned
240787 ** and the final value of (*piOrigin) is undefined.
240788 */
240789 static int sqlite3Fts5IndexGetOrigin(Fts5Index *p, i64 *piOrigin){
240790 Fts5Structure *pStruct;
240791 pStruct = fts5StructureRead(p);
240792 if( pStruct ){
240793 *piOrigin = pStruct->nOriginCntr;
240794 fts5StructureRelease(pStruct);
240795 }
240796 return fts5IndexReturn(p);
240797 }
240798
240799 /*
240800 ** Buffer pPg contains a page of a tombstone hash table - one of nPg pages
240801 ** associated with the same segment. This function adds rowid iRowid to
240802 ** the hash table. The caller is required to guarantee that there is at
240803 ** least one free slot on the page.
240804 **
240805 ** If parameter bForce is false and the hash table is deemed to be full
240806 ** (more than half of the slots are occupied), then non-zero is returned
240807 ** and iRowid not inserted. Or, if bForce is true or if the hash table page
240808 ** is not full, iRowid is inserted and zero returned.
240809 */
240810 static int fts5IndexTombstoneAddToPage(
240811 Fts5Data *pPg,
240812 int bForce,
240813 int nPg,
240814 u64 iRowid
240815 ){
240816 const int szKey = TOMBSTONE_KEYSIZE(pPg);
240817 const int nSlot = TOMBSTONE_NSLOT(pPg);
240818 const int nElem = fts5GetU32(&pPg->p[4]);
240819 int iSlot = (iRowid / nPg) % nSlot;
240820 int nCollide = nSlot;
240821
240822 if( szKey==4 && iRowid>0xFFFFFFFF ) return 2;
240823 if( iRowid==0 ){
240824 pPg->p[1] = 0x01;
240825 return 0;
240826 }
240827
240828 if( bForce==0 && nElem>=(nSlot/2) ){
240829 return 1;
240830 }
240831
240832 fts5PutU32(&pPg->p[4], nElem+1);
240833 if( szKey==4 ){
240834 u32 *aSlot = (u32*)&pPg->p[8];
240835 while( aSlot[iSlot] ){
240836 iSlot = (iSlot + 1) % nSlot;
240837 if( nCollide--==0 ) return 0;
240838 }
240839 fts5PutU32((u8*)&aSlot[iSlot], (u32)iRowid);
240840 }else{
240841 u64 *aSlot = (u64*)&pPg->p[8];
240842 while( aSlot[iSlot] ){
240843 iSlot = (iSlot + 1) % nSlot;
240844 if( nCollide--==0 ) return 0;
240845 }
240846 fts5PutU64((u8*)&aSlot[iSlot], iRowid);
240847 }
240848
240849 return 0;
240850 }
240851
240852 /*
240853 ** This function attempts to build a new hash containing all the keys
240854 ** currently in the tombstone hash table for segment pSeg. The new
240855 ** hash will be stored in the nOut buffers passed in array apOut[].
240856 ** All pages of the new hash use key-size szKey (4 or 8).
240857 **
240858 ** Return 0 if the hash is successfully rebuilt into the nOut pages.
240859 ** Or non-zero if it is not (because one page became overfull). In this
240860 ** case the caller should retry with a larger nOut parameter.
240861 **
240862 ** Parameter pData1 is page iPg1 of the hash table being rebuilt.
240863 */
240864 static int fts5IndexTombstoneRehash(
240865 Fts5Index *p,
240866 Fts5StructureSegment *pSeg, /* Segment to rebuild hash of */
240867 Fts5Data *pData1, /* One page of current hash - or NULL */
240868 int iPg1, /* Which page of the current hash is pData1 */
240869 int szKey, /* 4 or 8, the keysize */
240870 int nOut, /* Number of output pages */
240871 Fts5Data **apOut /* Array of output hash pages */
240872 ){
240873 int ii;
240874 int res = 0;
240875
240876 /* Initialize the headers of all the output pages */
240877 for(ii=0; ii<nOut; ii++){
240878 apOut[ii]->p[0] = szKey;
240879 fts5PutU32(&apOut[ii]->p[4], 0);
240880 }
240881
240882 /* Loop through the current pages of the hash table. */
240883 for(ii=0; res==0 && ii<pSeg->nPgTombstone; ii++){
240884 Fts5Data *pData = 0; /* Page ii of the current hash table */
240885 Fts5Data *pFree = 0; /* Free this at the end of the loop */
240886
240887 if( iPg1==ii ){
240888 pData = pData1;
240889 }else{
240890 pFree = pData = fts5DataRead(p, FTS5_TOMBSTONE_ROWID(pSeg->iSegid, ii));
240891 }
240892
240893 if( pData ){
240894 int szKeyIn = TOMBSTONE_KEYSIZE(pData);
240895 int nSlotIn = (pData->nn - 8) / szKeyIn;
240896 int iIn;
240897 for(iIn=0; iIn<nSlotIn; iIn++){
240898 u64 iVal = 0;
240899
240900 /* Read the value from slot iIn of the input page into iVal. */
240901 if( szKeyIn==4 ){
240902 u32 *aSlot = (u32*)&pData->p[8];
240903 if( aSlot[iIn] ) iVal = fts5GetU32((u8*)&aSlot[iIn]);
240904 }else{
240905 u64 *aSlot = (u64*)&pData->p[8];
240906 if( aSlot[iIn] ) iVal = fts5GetU64((u8*)&aSlot[iIn]);
240907 }
240908
240909 /* If iVal is not 0 at this point, insert it into the new hash table */
240910 if( iVal ){
240911 Fts5Data *pPg = apOut[(iVal % nOut)];
240912 res = fts5IndexTombstoneAddToPage(pPg, 0, nOut, iVal);
240913 if( res ) break;
240914 }
240915 }
240916
240917 /* If this is page 0 of the old hash, copy the rowid-0-flag from the
240918 ** old hash to the new. */
240919 if( ii==0 ){
240920 apOut[0]->p[1] = pData->p[1];
240921 }
240922 }
240923 fts5DataRelease(pFree);
240924 }
240925
240926 return res;
240927 }
240928
240929 /*
240930 ** This is called to rebuild the hash table belonging to segment pSeg.
240931 ** If parameter pData1 is not NULL, then one page of the existing hash table
240932 ** has already been loaded - pData1, which is page iPg1. The key-size for
240933 ** the new hash table is szKey (4 or 8).
240934 **
240935 ** If successful, the new hash table is not written to disk. Instead,
240936 ** output parameter (*pnOut) is set to the number of pages in the new
240937 ** hash table, and (*papOut) to point to an array of buffers containing
240938 ** the new page data.
240939 **
240940 ** If an error occurs, an error code is left in the Fts5Index object and
240941 ** both output parameters set to 0 before returning.
240942 */
240943 static void fts5IndexTombstoneRebuild(
240944 Fts5Index *p,
240945 Fts5StructureSegment *pSeg, /* Segment to rebuild hash of */
240946 Fts5Data *pData1, /* One page of current hash - or NULL */
240947 int iPg1, /* Which page of the current hash is pData1 */
240948 int szKey, /* 4 or 8, the keysize */
240949 int *pnOut, /* OUT: Number of output pages */
240950 Fts5Data ***papOut /* OUT: Output hash pages */
240951 ){
240952 const int MINSLOT = 32;
240953 int nSlotPerPage = MAX(MINSLOT, (p->pConfig->pgsz - 8) / szKey);
240954 int nSlot = 0; /* Number of slots in each output page */
240955 int nOut = 0;
240956
240957 /* Figure out how many output pages (nOut) and how many slots per
240958 ** page (nSlot). There are three possibilities:
240959 **
240960 ** 1. The hash table does not yet exist. In this case the new hash
240961 ** table will consist of a single page with MINSLOT slots.
240962 **
240963 ** 2. The hash table exists but is currently a single page. In this
240964 ** case an attempt is made to grow the page to accommodate the new
240965 ** entry. The page is allowed to grow up to nSlotPerPage (see above)
240966 ** slots.
240967 **
240968 ** 3. The hash table already consists of more than one page, or of
240969 ** a single page already so large that it cannot be grown. In this
240970 ** case the new hash consists of (nPg*2+1) pages of nSlotPerPage
240971 ** slots each, where nPg is the current number of pages in the
240972 ** hash table.
240973 */
240974 if( pSeg->nPgTombstone==0 ){
240975 /* Case 1. */
240976 nOut = 1;
240977 nSlot = MINSLOT;
240978 }else if( pSeg->nPgTombstone==1 ){
240979 /* Case 2. */
240980 int nElem = (int)fts5GetU32(&pData1->p[4]);
240981 assert( pData1 && iPg1==0 );
240982 nOut = 1;
240983 nSlot = MAX(nElem*4, MINSLOT);
240984 if( nSlot>nSlotPerPage ) nOut = 0;
240985 }
240986 if( nOut==0 ){
240987 /* Case 3. */
240988 nOut = (pSeg->nPgTombstone * 2 + 1);
240989 nSlot = nSlotPerPage;
240990 }
240991
240992 /* Allocate the required array and output pages */
240993 while( 1 ){
240994 int res = 0;
240995 int ii = 0;
240996 int szPage = 0;
240997 Fts5Data **apOut = 0;
240998
240999 /* Allocate space for the new hash table */
241000 assert( nSlot>=MINSLOT );
241001 apOut = (Fts5Data**)sqlite3Fts5MallocZero(&p->rc, sizeof(Fts5Data*) * nOut);
241002 szPage = 8 + nSlot*szKey;
241003 for(ii=0; ii<nOut; ii++){
241004 Fts5Data *pNew = (Fts5Data*)sqlite3Fts5MallocZero(&p->rc,
241005 sizeof(Fts5Data)+szPage
241006 );
241007 if( pNew ){
241008 pNew->nn = szPage;
241009 pNew->p = (u8*)&pNew[1];
241010 apOut[ii] = pNew;
241011 }
241012 }
241013
241014 /* Rebuild the hash table. */
241015 if( p->rc==SQLITE_OK ){
241016 res = fts5IndexTombstoneRehash(p, pSeg, pData1, iPg1, szKey, nOut, apOut);
241017 }
241018 if( res==0 ){
241019 if( p->rc ){
241020 fts5IndexFreeArray(apOut, nOut);
241021 apOut = 0;
241022 nOut = 0;
241023 }
241024 *pnOut = nOut;
241025 *papOut = apOut;
241026 break;
241027 }
241028
241029 /* If control flows to here, it was not possible to rebuild the hash
241030 ** table. Free all buffers and then try again with more pages. */
241031 assert( p->rc==SQLITE_OK );
241032 fts5IndexFreeArray(apOut, nOut);
241033 nSlot = nSlotPerPage;
241034 nOut = nOut*2 + 1;
241035 }
241036 }
241037
241038
241039 /*
241040 ** Add a tombstone for rowid iRowid to segment pSeg.
241041 */
241042 static void fts5IndexTombstoneAdd(
241043 Fts5Index *p,
241044 Fts5StructureSegment *pSeg,
241045 u64 iRowid
241046 ){
241047 Fts5Data *pPg = 0;
241048 int iPg = -1;
241049 int szKey = 0;
241050 int nHash = 0;
241051 Fts5Data **apHash = 0;
241052
241053 p->nContentlessDelete++;
241054
241055 if( pSeg->nPgTombstone>0 ){
241056 iPg = iRowid % pSeg->nPgTombstone;
241057 pPg = fts5DataRead(p, FTS5_TOMBSTONE_ROWID(pSeg->iSegid,iPg));
241058 if( pPg==0 ){
241059 assert( p->rc!=SQLITE_OK );
241060 return;
241061 }
241062
241063 if( 0==fts5IndexTombstoneAddToPage(pPg, 0, pSeg->nPgTombstone, iRowid) ){
241064 fts5DataWrite(p, FTS5_TOMBSTONE_ROWID(pSeg->iSegid,iPg), pPg->p, pPg->nn);
241065 fts5DataRelease(pPg);
241066 return;
241067 }
241068 }
241069
241070 /* Have to rebuild the hash table. First figure out the key-size (4 or 8). */
241071 szKey = pPg ? TOMBSTONE_KEYSIZE(pPg) : 4;
241072 if( iRowid>0xFFFFFFFF ) szKey = 8;
241073
241074 /* Rebuild the hash table */
241075 fts5IndexTombstoneRebuild(p, pSeg, pPg, iPg, szKey, &nHash, &apHash);
241076 assert( p->rc==SQLITE_OK || (nHash==0 && apHash==0) );
241077
241078 /* If all has succeeded, write the new rowid into one of the new hash
241079 ** table pages, then write them all out to disk. */
241080 if( nHash ){
241081 int ii = 0;
241082 fts5IndexTombstoneAddToPage(apHash[iRowid % nHash], 1, nHash, iRowid);
241083 for(ii=0; ii<nHash; ii++){
241084 i64 iTombstoneRowid = FTS5_TOMBSTONE_ROWID(pSeg->iSegid, ii);
241085 fts5DataWrite(p, iTombstoneRowid, apHash[ii]->p, apHash[ii]->nn);
241086 }
241087 pSeg->nPgTombstone = nHash;
241088 fts5StructureWrite(p, p->pStruct);
241089 }
241090
241091 fts5DataRelease(pPg);
241092 fts5IndexFreeArray(apHash, nHash);
241093 }
241094
241095 /*
241096 ** Add iRowid to the tombstone list of the segment or segments that contain
241097 ** rows from origin iOrigin. Return SQLITE_OK if successful, or an SQLite
241098 ** error code otherwise.
241099 */
241100 static int sqlite3Fts5IndexContentlessDelete(Fts5Index *p, i64 iOrigin, i64 iRowid){
241101 Fts5Structure *pStruct;
241102 pStruct = fts5StructureRead(p);
241103 if( pStruct ){
241104 int bFound = 0; /* True after pSeg->nEntryTombstone incr. */
241105 int iLvl;
241106 for(iLvl=pStruct->nLevel-1; iLvl>=0; iLvl--){
241107 int iSeg;
241108 for(iSeg=pStruct->aLevel[iLvl].nSeg-1; iSeg>=0; iSeg--){
241109 Fts5StructureSegment *pSeg = &pStruct->aLevel[iLvl].aSeg[iSeg];
241110 if( pSeg->iOrigin1<=(u64)iOrigin && pSeg->iOrigin2>=(u64)iOrigin ){
241111 if( bFound==0 ){
241112 pSeg->nEntryTombstone++;
241113 bFound = 1;
241114 }
241115 fts5IndexTombstoneAdd(p, pSeg, iRowid);
241116 }
241117 }
241118 }
241119 fts5StructureRelease(pStruct);
241120 }
241121 return fts5IndexReturn(p);
241122 }
241123
241124 /*************************************************************************
241125 **************************************************************************
241126 ** Below this point is the implementation of the integrity-check
241127 ** functionality.
@@ -239973,17 +241669,18 @@
241669 **************************************************************************
241670 ** Below this point is the implementation of the fts5_decode() scalar
241671 ** function only.
241672 */
241673
241674 #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
241675 /*
241676 ** Decode a segment-data rowid from the %_data table. This function is
241677 ** the opposite of macro FTS5_SEGMENT_ROWID().
241678 */
241679 static void fts5DecodeRowid(
241680 i64 iRowid, /* Rowid from %_data table */
241681 int *pbTombstone, /* OUT: Tombstone hash flag */
241682 int *piSegid, /* OUT: Segment id */
241683 int *pbDlidx, /* OUT: Dlidx flag */
241684 int *piHeight, /* OUT: Height */
241685 int *piPgno /* OUT: Page number */
241686 ){
@@ -239995,34 +241692,39 @@
241692
241693 *pbDlidx = (int)(iRowid & 0x0001);
241694 iRowid >>= FTS5_DATA_DLI_B;
241695
241696 *piSegid = (int)(iRowid & (((i64)1 << FTS5_DATA_ID_B) - 1));
241697 iRowid >>= FTS5_DATA_ID_B;
241698
241699 *pbTombstone = (int)(iRowid & 0x0001);
241700 }
241701 #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
241702
241703 #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
241704 static void fts5DebugRowid(int *pRc, Fts5Buffer *pBuf, i64 iKey){
241705 int iSegid, iHeight, iPgno, bDlidx, bTomb; /* Rowid compenents */
241706 fts5DecodeRowid(iKey, &bTomb, &iSegid, &bDlidx, &iHeight, &iPgno);
241707
241708 if( iSegid==0 ){
241709 if( iKey==FTS5_AVERAGES_ROWID ){
241710 sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{averages} ");
241711 }else{
241712 sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{structure}");
241713 }
241714 }
241715 else{
241716 sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{%s%ssegid=%d h=%d pgno=%d}",
241717 bDlidx ? "dlidx " : "",
241718 bTomb ? "tombstone " : "",
241719 iSegid, iHeight, iPgno
241720 );
241721 }
241722 }
241723 #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
241724
241725 #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
241726 static void fts5DebugStructure(
241727 int *pRc, /* IN/OUT: error code */
241728 Fts5Buffer *pBuf,
241729 Fts5Structure *p
241730 ){
@@ -240033,20 +241735,26 @@
241735 sqlite3Fts5BufferAppendPrintf(pRc, pBuf,
241736 " {lvl=%d nMerge=%d nSeg=%d", iLvl, pLvl->nMerge, pLvl->nSeg
241737 );
241738 for(iSeg=0; iSeg<pLvl->nSeg; iSeg++){
241739 Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg];
241740 sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " {id=%d leaves=%d..%d",
241741 pSeg->iSegid, pSeg->pgnoFirst, pSeg->pgnoLast
241742 );
241743 if( pSeg->iOrigin1>0 ){
241744 sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " origin=%lld..%lld",
241745 pSeg->iOrigin1, pSeg->iOrigin2
241746 );
241747 }
241748 sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "}");
241749 }
241750 sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "}");
241751 }
241752 }
241753 #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
241754
241755 #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
241756 /*
241757 ** This is part of the fts5_decode() debugging aid.
241758 **
241759 ** Arguments pBlob/nBlob contain a serialized Fts5Structure object. This
241760 ** function appends a human-readable representation of the same object
@@ -240067,13 +241775,13 @@
241775 }
241776
241777 fts5DebugStructure(pRc, pBuf, p);
241778 fts5StructureRelease(p);
241779 }
241780 #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
241781
241782 #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
241783 /*
241784 ** This is part of the fts5_decode() debugging aid.
241785 **
241786 ** Arguments pBlob/nBlob contain an "averages" record. This function
241787 ** appends a human-readable representation of record to the buffer passed
@@ -240092,13 +241800,13 @@
241800 i += sqlite3Fts5GetVarint(&pBlob[i], &iVal);
241801 sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "%s%d", zSpace, (int)iVal);
241802 zSpace = " ";
241803 }
241804 }
241805 #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
241806
241807 #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
241808 /*
241809 ** Buffer (a/n) is assumed to contain a list of serialized varints. Read
241810 ** each varint and append its string representation to buffer pBuf. Return
241811 ** after either the input buffer is exhausted or a 0 value is read.
241812 **
@@ -240111,13 +241819,13 @@
241819 iOff += fts5GetVarint32(&a[iOff], iVal);
241820 sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " %d", iVal);
241821 }
241822 return iOff;
241823 }
241824 #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
241825
241826 #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
241827 /*
241828 ** The start of buffer (a/n) contains the start of a doclist. The doclist
241829 ** may or may not finish within the buffer. This function appends a text
241830 ** representation of the part of the doclist that is present to buffer
241831 ** pBuf.
@@ -240146,13 +241854,13 @@
241854 }
241855 }
241856
241857 return iOff;
241858 }
241859 #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
241860
241861 #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
241862 /*
241863 ** This function is part of the fts5_decode() debugging function. It is
241864 ** only ever used with detail=none tables.
241865 **
241866 ** Buffer (pData/nData) contains a doclist in the format used by detail=none
@@ -240189,13 +241897,13 @@
241897 }
241898
241899 sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " %lld%s", iRowid, zApp);
241900 }
241901 }
241902 #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
241903
241904 #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
241905 /*
241906 ** The implementation of user-defined scalar function fts5_decode().
241907 */
241908 static void fts5DecodeFunction(
241909 sqlite3_context *pCtx, /* Function call context */
@@ -240202,10 +241910,11 @@
241910 int nArg, /* Number of args (always 2) */
241911 sqlite3_value **apVal /* Function arguments */
241912 ){
241913 i64 iRowid; /* Rowid for record being decoded */
241914 int iSegid,iHeight,iPgno,bDlidx;/* Rowid components */
241915 int bTomb;
241916 const u8 *aBlob; int n; /* Record to decode */
241917 u8 *a = 0;
241918 Fts5Buffer s; /* Build up text to return here */
241919 int rc = SQLITE_OK; /* Return code */
241920 sqlite3_int64 nSpace = 0;
@@ -240224,11 +241933,11 @@
241933 nSpace = n + FTS5_DATA_ZERO_PADDING;
241934 a = (u8*)sqlite3Fts5MallocZero(&rc, nSpace);
241935 if( a==0 ) goto decode_out;
241936 if( n>0 ) memcpy(a, aBlob, n);
241937
241938 fts5DecodeRowid(iRowid, &bTomb, &iSegid, &bDlidx, &iHeight, &iPgno);
241939
241940 fts5DebugRowid(&rc, &s, iRowid);
241941 if( bDlidx ){
241942 Fts5Data dlidx;
241943 Fts5DlidxLvl lvl;
@@ -240242,10 +241951,32 @@
241951
241952 for(fts5DlidxLvlNext(&lvl); lvl.bEof==0; fts5DlidxLvlNext(&lvl)){
241953 sqlite3Fts5BufferAppendPrintf(&rc, &s,
241954 " %d(%lld)", lvl.iLeafPgno, lvl.iRowid
241955 );
241956 }
241957 }else if( bTomb ){
241958 u32 nElem = fts5GetU32(&a[4]);
241959 int szKey = (aBlob[0]==4 || aBlob[0]==8) ? aBlob[0] : 8;
241960 int nSlot = (n - 8) / szKey;
241961 int ii;
241962 sqlite3Fts5BufferAppendPrintf(&rc, &s, " nElem=%d", (int)nElem);
241963 if( aBlob[1] ){
241964 sqlite3Fts5BufferAppendPrintf(&rc, &s, " 0");
241965 }
241966 for(ii=0; ii<nSlot; ii++){
241967 u64 iVal = 0;
241968 if( szKey==4 ){
241969 u32 *aSlot = (u32*)&aBlob[8];
241970 if( aSlot[ii] ) iVal = fts5GetU32((u8*)&aSlot[ii]);
241971 }else{
241972 u64 *aSlot = (u64*)&aBlob[8];
241973 if( aSlot[ii] ) iVal = fts5GetU64((u8*)&aSlot[ii]);
241974 }
241975 if( iVal!=0 ){
241976 sqlite3Fts5BufferAppendPrintf(&rc, &s, " %lld", (i64)iVal);
241977 }
241978 }
241979 }else if( iSegid==0 ){
241980 if( iRowid==FTS5_AVERAGES_ROWID ){
241981 fts5DecodeAverages(&rc, &s, a, n);
241982 }else{
@@ -240400,13 +242131,13 @@
242131 }else{
242132 sqlite3_result_error_code(pCtx, rc);
242133 }
242134 fts5BufferFree(&s);
242135 }
242136 #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
242137
242138 #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
242139 /*
242140 ** The implementation of user-defined scalar function fts5_rowid().
242141 */
242142 static void fts5RowidFunction(
242143 sqlite3_context *pCtx, /* Function call context */
@@ -240436,11 +242167,239 @@
242167 "first arg to fts5_rowid() must be 'segment'" , -1
242168 );
242169 }
242170 }
242171 }
242172 #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
242173
242174 #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
242175
242176 typedef struct Fts5StructVtab Fts5StructVtab;
242177 struct Fts5StructVtab {
242178 sqlite3_vtab base;
242179 };
242180
242181 typedef struct Fts5StructVcsr Fts5StructVcsr;
242182 struct Fts5StructVcsr {
242183 sqlite3_vtab_cursor base;
242184 Fts5Structure *pStruct;
242185 int iLevel;
242186 int iSeg;
242187 int iRowid;
242188 };
242189
242190 /*
242191 ** Create a new fts5_structure() table-valued function.
242192 */
242193 static int fts5structConnectMethod(
242194 sqlite3 *db,
242195 void *pAux,
242196 int argc, const char *const*argv,
242197 sqlite3_vtab **ppVtab,
242198 char **pzErr
242199 ){
242200 Fts5StructVtab *pNew = 0;
242201 int rc = SQLITE_OK;
242202
242203 rc = sqlite3_declare_vtab(db,
242204 "CREATE TABLE xyz("
242205 "level, segment, merge, segid, leaf1, leaf2, loc1, loc2, "
242206 "npgtombstone, nentrytombstone, nentry, struct HIDDEN);"
242207 );
242208 if( rc==SQLITE_OK ){
242209 pNew = sqlite3Fts5MallocZero(&rc, sizeof(*pNew));
242210 }
242211
242212 *ppVtab = (sqlite3_vtab*)pNew;
242213 return rc;
242214 }
242215
242216 /*
242217 ** We must have a single struct=? constraint that will be passed through
242218 ** into the xFilter method. If there is no valid stmt=? constraint,
242219 ** then return an SQLITE_CONSTRAINT error.
242220 */
242221 static int fts5structBestIndexMethod(
242222 sqlite3_vtab *tab,
242223 sqlite3_index_info *pIdxInfo
242224 ){
242225 int i;
242226 int rc = SQLITE_CONSTRAINT;
242227 struct sqlite3_index_constraint *p;
242228 pIdxInfo->estimatedCost = (double)100;
242229 pIdxInfo->estimatedRows = 100;
242230 pIdxInfo->idxNum = 0;
242231 for(i=0, p=pIdxInfo->aConstraint; i<pIdxInfo->nConstraint; i++, p++){
242232 if( p->usable==0 ) continue;
242233 if( p->op==SQLITE_INDEX_CONSTRAINT_EQ && p->iColumn==11 ){
242234 rc = SQLITE_OK;
242235 pIdxInfo->aConstraintUsage[i].omit = 1;
242236 pIdxInfo->aConstraintUsage[i].argvIndex = 1;
242237 break;
242238 }
242239 }
242240 return rc;
242241 }
242242
242243 /*
242244 ** This method is the destructor for bytecodevtab objects.
242245 */
242246 static int fts5structDisconnectMethod(sqlite3_vtab *pVtab){
242247 Fts5StructVtab *p = (Fts5StructVtab*)pVtab;
242248 sqlite3_free(p);
242249 return SQLITE_OK;
242250 }
242251
242252 /*
242253 ** Constructor for a new bytecodevtab_cursor object.
242254 */
242255 static int fts5structOpenMethod(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCsr){
242256 int rc = SQLITE_OK;
242257 Fts5StructVcsr *pNew = 0;
242258
242259 pNew = sqlite3Fts5MallocZero(&rc, sizeof(*pNew));
242260 *ppCsr = (sqlite3_vtab_cursor*)pNew;
242261
242262 return SQLITE_OK;
242263 }
242264
242265 /*
242266 ** Destructor for a bytecodevtab_cursor.
242267 */
242268 static int fts5structCloseMethod(sqlite3_vtab_cursor *cur){
242269 Fts5StructVcsr *pCsr = (Fts5StructVcsr*)cur;
242270 fts5StructureRelease(pCsr->pStruct);
242271 sqlite3_free(pCsr);
242272 return SQLITE_OK;
242273 }
242274
242275
242276 /*
242277 ** Advance a bytecodevtab_cursor to its next row of output.
242278 */
242279 static int fts5structNextMethod(sqlite3_vtab_cursor *cur){
242280 Fts5StructVcsr *pCsr = (Fts5StructVcsr*)cur;
242281 Fts5Structure *p = pCsr->pStruct;
242282
242283 assert( pCsr->pStruct );
242284 pCsr->iSeg++;
242285 pCsr->iRowid++;
242286 while( pCsr->iLevel<p->nLevel && pCsr->iSeg>=p->aLevel[pCsr->iLevel].nSeg ){
242287 pCsr->iLevel++;
242288 pCsr->iSeg = 0;
242289 }
242290 if( pCsr->iLevel>=p->nLevel ){
242291 fts5StructureRelease(pCsr->pStruct);
242292 pCsr->pStruct = 0;
242293 }
242294 return SQLITE_OK;
242295 }
242296
242297 /*
242298 ** Return TRUE if the cursor has been moved off of the last
242299 ** row of output.
242300 */
242301 static int fts5structEofMethod(sqlite3_vtab_cursor *cur){
242302 Fts5StructVcsr *pCsr = (Fts5StructVcsr*)cur;
242303 return pCsr->pStruct==0;
242304 }
242305
242306 static int fts5structRowidMethod(
242307 sqlite3_vtab_cursor *cur,
242308 sqlite_int64 *piRowid
242309 ){
242310 Fts5StructVcsr *pCsr = (Fts5StructVcsr*)cur;
242311 *piRowid = pCsr->iRowid;
242312 return SQLITE_OK;
242313 }
242314
242315 /*
242316 ** Return values of columns for the row at which the bytecodevtab_cursor
242317 ** is currently pointing.
242318 */
242319 static int fts5structColumnMethod(
242320 sqlite3_vtab_cursor *cur, /* The cursor */
242321 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
242322 int i /* Which column to return */
242323 ){
242324 Fts5StructVcsr *pCsr = (Fts5StructVcsr*)cur;
242325 Fts5Structure *p = pCsr->pStruct;
242326 Fts5StructureSegment *pSeg = &p->aLevel[pCsr->iLevel].aSeg[pCsr->iSeg];
242327
242328 switch( i ){
242329 case 0: /* level */
242330 sqlite3_result_int(ctx, pCsr->iLevel);
242331 break;
242332 case 1: /* segment */
242333 sqlite3_result_int(ctx, pCsr->iSeg);
242334 break;
242335 case 2: /* merge */
242336 sqlite3_result_int(ctx, pCsr->iSeg < p->aLevel[pCsr->iLevel].nMerge);
242337 break;
242338 case 3: /* segid */
242339 sqlite3_result_int(ctx, pSeg->iSegid);
242340 break;
242341 case 4: /* leaf1 */
242342 sqlite3_result_int(ctx, pSeg->pgnoFirst);
242343 break;
242344 case 5: /* leaf2 */
242345 sqlite3_result_int(ctx, pSeg->pgnoLast);
242346 break;
242347 case 6: /* origin1 */
242348 sqlite3_result_int64(ctx, pSeg->iOrigin1);
242349 break;
242350 case 7: /* origin2 */
242351 sqlite3_result_int64(ctx, pSeg->iOrigin2);
242352 break;
242353 case 8: /* npgtombstone */
242354 sqlite3_result_int(ctx, pSeg->nPgTombstone);
242355 break;
242356 case 9: /* nentrytombstone */
242357 sqlite3_result_int64(ctx, pSeg->nEntryTombstone);
242358 break;
242359 case 10: /* nentry */
242360 sqlite3_result_int64(ctx, pSeg->nEntry);
242361 break;
242362 }
242363 return SQLITE_OK;
242364 }
242365
242366 /*
242367 ** Initialize a cursor.
242368 **
242369 ** idxNum==0 means show all subprograms
242370 ** idxNum==1 means show only the main bytecode and omit subprograms.
242371 */
242372 static int fts5structFilterMethod(
242373 sqlite3_vtab_cursor *pVtabCursor,
242374 int idxNum, const char *idxStr,
242375 int argc, sqlite3_value **argv
242376 ){
242377 Fts5StructVcsr *pCsr = (Fts5StructVcsr *)pVtabCursor;
242378 int rc = SQLITE_OK;
242379
242380 const u8 *aBlob = 0;
242381 int nBlob = 0;
242382
242383 assert( argc==1 );
242384 fts5StructureRelease(pCsr->pStruct);
242385 pCsr->pStruct = 0;
242386
242387 nBlob = sqlite3_value_bytes(argv[0]);
242388 aBlob = (const u8*)sqlite3_value_blob(argv[0]);
242389 rc = fts5StructureDecode(aBlob, nBlob, 0, &pCsr->pStruct);
242390 if( rc==SQLITE_OK ){
242391 pCsr->iLevel = 0;
242392 pCsr->iRowid = 0;
242393 pCsr->iSeg = -1;
242394 rc = fts5structNextMethod(pVtabCursor);
242395 }
242396
242397 return rc;
242398 }
242399
242400 #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
242401
242402 /*
242403 ** This is called as part of registering the FTS5 module with database
242404 ** connection db. It registers several user-defined scalar functions useful
242405 ** with FTS5.
@@ -240447,11 +242406,11 @@
242406 **
242407 ** If successful, SQLITE_OK is returned. If an error occurs, some other
242408 ** SQLite error code is returned instead.
242409 */
242410 static int sqlite3Fts5IndexInit(sqlite3 *db){
242411 #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
242412 int rc = sqlite3_create_function(
242413 db, "fts5_decode", 2, SQLITE_UTF8, 0, fts5DecodeFunction, 0, 0
242414 );
242415
242416 if( rc==SQLITE_OK ){
@@ -240464,10 +242423,40 @@
242423 if( rc==SQLITE_OK ){
242424 rc = sqlite3_create_function(
242425 db, "fts5_rowid", -1, SQLITE_UTF8, 0, fts5RowidFunction, 0, 0
242426 );
242427 }
242428
242429 if( rc==SQLITE_OK ){
242430 static const sqlite3_module fts5structure_module = {
242431 0, /* iVersion */
242432 0, /* xCreate */
242433 fts5structConnectMethod, /* xConnect */
242434 fts5structBestIndexMethod, /* xBestIndex */
242435 fts5structDisconnectMethod, /* xDisconnect */
242436 0, /* xDestroy */
242437 fts5structOpenMethod, /* xOpen */
242438 fts5structCloseMethod, /* xClose */
242439 fts5structFilterMethod, /* xFilter */
242440 fts5structNextMethod, /* xNext */
242441 fts5structEofMethod, /* xEof */
242442 fts5structColumnMethod, /* xColumn */
242443 fts5structRowidMethod, /* xRowid */
242444 0, /* xUpdate */
242445 0, /* xBegin */
242446 0, /* xSync */
242447 0, /* xCommit */
242448 0, /* xRollback */
242449 0, /* xFindFunction */
242450 0, /* xRename */
242451 0, /* xSavepoint */
242452 0, /* xRelease */
242453 0, /* xRollbackTo */
242454 0 /* xShadowName */
242455 };
242456 rc = sqlite3_create_module(db, "fts5_structure", &fts5structure_module, 0);
242457 }
242458 return rc;
242459 #else
242460 return SQLITE_OK;
242461 UNUSED_PARAM(db);
242462 #endif
@@ -242107,11 +244096,10 @@
244096 Fts5Config *pConfig = pTab->p.pConfig;
244097 int eType0; /* value_type() of apVal[0] */
244098 int rc = SQLITE_OK; /* Return code */
244099 int bUpdateOrDelete = 0;
244100
 
244101 /* A transaction must be open when this is called. */
244102 assert( pTab->ts.eState==1 || pTab->ts.eState==2 );
244103
244104 assert( pVtab->zErrMsg==0 );
244105 assert( nArg==1 || nArg==(2+pConfig->nCol+2) );
@@ -242136,11 +244124,18 @@
244124 /* A "special" INSERT op. These are handled separately. */
244125 const char *z = (const char*)sqlite3_value_text(apVal[2+pConfig->nCol]);
244126 if( pConfig->eContent!=FTS5_CONTENT_NORMAL
244127 && 0==sqlite3_stricmp("delete", z)
244128 ){
244129 if( pConfig->bContentlessDelete ){
244130 fts5SetVtabError(pTab,
244131 "'delete' may not be used with a contentless_delete=1 table"
244132 );
244133 rc = SQLITE_ERROR;
244134 }else{
244135 rc = fts5SpecialDelete(pTab, apVal);
244136 }
244137 }else{
244138 rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]);
244139 }
244140 }else{
244141 /* A regular INSERT, UPDATE or DELETE statement. The trick here is that
@@ -242153,20 +244148,24 @@
244148 ** 4) INSERT
244149 **
244150 ** Cases 3 and 4 may violate the rowid constraint.
244151 */
244152 int eConflict = SQLITE_ABORT;
244153 if( pConfig->eContent==FTS5_CONTENT_NORMAL || pConfig->bContentlessDelete ){
244154 eConflict = sqlite3_vtab_on_conflict(pConfig->db);
244155 }
244156
244157 assert( eType0==SQLITE_INTEGER || eType0==SQLITE_NULL );
244158 assert( nArg!=1 || eType0==SQLITE_INTEGER );
244159
244160 /* Filter out attempts to run UPDATE or DELETE on contentless tables.
244161 ** This is not suported. Except - DELETE is supported if the CREATE
244162 ** VIRTUAL TABLE statement contained "contentless_delete=1". */
244163 if( eType0==SQLITE_INTEGER
244164 && pConfig->eContent==FTS5_CONTENT_NONE
244165 && (nArg>1 || pConfig->bContentlessDelete==0)
244166 ){
244167 pTab->p.base.zErrMsg = sqlite3_mprintf(
244168 "cannot %s contentless fts5 table: %s",
244169 (nArg>1 ? "UPDATE" : "DELETE from"), pConfig->zName
244170 );
244171 rc = SQLITE_ERROR;
@@ -242249,12 +244248,11 @@
244248 static int fts5SyncMethod(sqlite3_vtab *pVtab){
244249 int rc;
244250 Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
244251 fts5CheckTransactionState(pTab, FTS5_SYNC, 0);
244252 pTab->p.pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
244253 rc = sqlite3Fts5FlushToDisk(&pTab->p);
 
244254 pTab->p.pConfig->pzErrmsg = 0;
244255 return rc;
244256 }
244257
244258 /*
@@ -243299,11 +245297,11 @@
245297 int nArg, /* Number of args */
245298 sqlite3_value **apUnused /* Function arguments */
245299 ){
245300 assert( nArg==0 );
245301 UNUSED_PARAM2(nArg, apUnused);
245302 sqlite3_result_text(pCtx, "fts5: 2023-08-01 11:03:06 aa55c83f35c2ab134e0842201e46e021079283f9c65595c86664060b3aa8d715", -1, SQLITE_TRANSIENT);
245303 }
245304
245305 /*
245306 ** Return true if zName is the extension on one of the shadow tables used
245307 ** by this module.
@@ -243512,14 +245510,14 @@
245510 "SELECT %s FROM %s T WHERE T.%Q=?", /* LOOKUP */
245511
245512 "INSERT INTO %Q.'%q_content' VALUES(%s)", /* INSERT_CONTENT */
245513 "REPLACE INTO %Q.'%q_content' VALUES(%s)", /* REPLACE_CONTENT */
245514 "DELETE FROM %Q.'%q_content' WHERE id=?", /* DELETE_CONTENT */
245515 "REPLACE INTO %Q.'%q_docsize' VALUES(?,?%s)", /* REPLACE_DOCSIZE */
245516 "DELETE FROM %Q.'%q_docsize' WHERE id=?", /* DELETE_DOCSIZE */
245517
245518 "SELECT sz%s FROM %Q.'%q_docsize' WHERE id=?", /* LOOKUP_DOCSIZE */
245519
245520 "REPLACE INTO %Q.'%q_config' VALUES(?,?)", /* REPLACE_CONFIG */
245521 "SELECT %s FROM %s AS T", /* SCAN */
245522 };
245523 Fts5Config *pC = p->pConfig;
@@ -243562,10 +245560,23 @@
245560 zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName, zBind);
245561 sqlite3_free(zBind);
245562 }
245563 break;
245564 }
245565
245566 case FTS5_STMT_REPLACE_DOCSIZE:
245567 zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName,
245568 (pC->bContentlessDelete ? ",?" : "")
245569 );
245570 break;
245571
245572 case FTS5_STMT_LOOKUP_DOCSIZE:
245573 zSql = sqlite3_mprintf(azStmt[eStmt],
245574 (pC->bContentlessDelete ? ",origin" : ""),
245575 pC->zDb, pC->zName
245576 );
245577 break;
245578
245579 default:
245580 zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName);
245581 break;
245582 }
@@ -243752,13 +245763,15 @@
245763 }
245764 sqlite3_free(zDefn);
245765 }
245766
245767 if( rc==SQLITE_OK && pConfig->bColumnsize ){
245768 const char *zCols = "id INTEGER PRIMARY KEY, sz BLOB";
245769 if( pConfig->bContentlessDelete ){
245770 zCols = "id INTEGER PRIMARY KEY, sz BLOB, origin INTEGER";
245771 }
245772 rc = sqlite3Fts5CreateTable(pConfig, "docsize", zCols, 0, pzErr);
245773 }
245774 if( rc==SQLITE_OK ){
245775 rc = sqlite3Fts5CreateTable(
245776 pConfig, "config", "k PRIMARY KEY, v", 1, pzErr
245777 );
@@ -243831,11 +245844,11 @@
245844 i64 iDel,
245845 sqlite3_value **apVal
245846 ){
245847 Fts5Config *pConfig = p->pConfig;
245848 sqlite3_stmt *pSeek = 0; /* SELECT to read row iDel from %_data */
245849 int rc = SQLITE_OK; /* Return code */
245850 int rc2; /* sqlite3_reset() return code */
245851 int iCol;
245852 Fts5InsertCtx ctx;
245853
245854 if( apVal==0 ){
@@ -243847,11 +245860,10 @@
245860 }
245861 }
245862
245863 ctx.pStorage = p;
245864 ctx.iCol = -1;
 
245865 for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){
245866 if( pConfig->abUnindexed[iCol-1]==0 ){
245867 const char *zText;
245868 int nText;
245869 assert( pSeek==0 || apVal==0 );
@@ -243884,10 +245896,41 @@
245896 rc2 = sqlite3_reset(pSeek);
245897 if( rc==SQLITE_OK ) rc = rc2;
245898 return rc;
245899 }
245900
245901 /*
245902 ** This function is called to process a DELETE on a contentless_delete=1
245903 ** table. It adds the tombstone required to delete the entry with rowid
245904 ** iDel. If successful, SQLITE_OK is returned. Or, if an error occurs,
245905 ** an SQLite error code.
245906 */
245907 static int fts5StorageContentlessDelete(Fts5Storage *p, i64 iDel){
245908 i64 iOrigin = 0;
245909 sqlite3_stmt *pLookup = 0;
245910 int rc = SQLITE_OK;
245911
245912 assert( p->pConfig->bContentlessDelete );
245913 assert( p->pConfig->eContent==FTS5_CONTENT_NONE );
245914
245915 /* Look up the origin of the document in the %_docsize table. Store
245916 ** this in stack variable iOrigin. */
245917 rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP_DOCSIZE, &pLookup, 0);
245918 if( rc==SQLITE_OK ){
245919 sqlite3_bind_int64(pLookup, 1, iDel);
245920 if( SQLITE_ROW==sqlite3_step(pLookup) ){
245921 iOrigin = sqlite3_column_int64(pLookup, 1);
245922 }
245923 rc = sqlite3_reset(pLookup);
245924 }
245925
245926 if( rc==SQLITE_OK && iOrigin!=0 ){
245927 rc = sqlite3Fts5IndexContentlessDelete(p->pIndex, iOrigin, iDel);
245928 }
245929
245930 return rc;
245931 }
245932
245933 /*
245934 ** Insert a record into the %_docsize table. Specifically, do:
245935 **
245936 ** INSERT OR REPLACE INTO %_docsize(id, sz) VALUES(iRowid, pBuf);
@@ -243904,14 +245947,21 @@
245947 if( p->pConfig->bColumnsize ){
245948 sqlite3_stmt *pReplace = 0;
245949 rc = fts5StorageGetStmt(p, FTS5_STMT_REPLACE_DOCSIZE, &pReplace, 0);
245950 if( rc==SQLITE_OK ){
245951 sqlite3_bind_int64(pReplace, 1, iRowid);
245952 if( p->pConfig->bContentlessDelete ){
245953 i64 iOrigin = 0;
245954 rc = sqlite3Fts5IndexGetOrigin(p->pIndex, &iOrigin);
245955 sqlite3_bind_int64(pReplace, 3, iOrigin);
245956 }
245957 if( rc==SQLITE_OK ){
245958 sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC);
245959 sqlite3_step(pReplace);
245960 rc = sqlite3_reset(pReplace);
245961 sqlite3_bind_null(pReplace, 2);
245962 }
245963 }
245964 }
245965 return rc;
245966 }
245967
@@ -243971,11 +246021,19 @@
246021 assert( pConfig->eContent!=FTS5_CONTENT_NORMAL || apVal==0 );
246022 rc = fts5StorageLoadTotals(p, 1);
246023
246024 /* Delete the index records */
246025 if( rc==SQLITE_OK ){
246026 rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel);
246027 }
246028
246029 if( rc==SQLITE_OK ){
246030 if( p->pConfig->bContentlessDelete ){
246031 rc = fts5StorageContentlessDelete(p, iDel);
246032 }else{
246033 rc = fts5StorageDeleteFromIndex(p, iDel, apVal);
246034 }
246035 }
246036
246037 /* Delete the %_docsize record */
246038 if( rc==SQLITE_OK && pConfig->bColumnsize ){
246039 rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_DOCSIZE, &pDel, 0);
246040
+36 -1
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,11 +146,11 @@
146146
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147147
** [sqlite_version()] and [sqlite_source_id()].
148148
*/
149149
#define SQLITE_VERSION "3.43.0"
150150
#define SQLITE_VERSION_NUMBER 3043000
151
-#define SQLITE_SOURCE_ID "2023-07-08 17:42:24 07d95ed60f0a17ea13b4bc19c2ab2ec9052fedd27c9e1e57a1ec6e3a6470e5b7"
151
+#define SQLITE_SOURCE_ID "2023-08-02 16:06:02 ea0b9aecbaca9a8e784fd2bcb50f78cbdcf4c5cfb45a7700bb222e4cc104c644"
152152
153153
/*
154154
** CAPI3REF: Run-Time Library Version Numbers
155155
** KEYWORDS: sqlite3_version sqlite3_sourceid
156156
**
@@ -4419,10 +4419,45 @@
44194419
** ^The sqlite3_stmt_isexplain(S) interface returns 0 if S is
44204420
** an ordinary statement or a NULL pointer.
44214421
*/
44224422
SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt);
44234423
4424
+/*
4425
+** CAPI3REF: Change The EXPLAIN Setting For A Prepared Statement
4426
+** METHOD: sqlite3_stmt
4427
+**
4428
+** The sqlite3_stmt_explain(S,E) interface changes the EXPLAIN
4429
+** setting for [prepared statement] S. If E is zero, then S becomes
4430
+** a normal prepared statement. If E is 1, then S behaves as if
4431
+** its SQL text began with "[EXPLAIN]". If E is 2, then S behaves as if
4432
+** its SQL text began with "[EXPLAIN QUERY PLAN]".
4433
+**
4434
+** Calling sqlite3_stmt_explain(S,E) might cause S to be reprepared.
4435
+** SQLite tries to avoid a reprepare, but a reprepare might be necessary
4436
+** on the first transition into EXPLAIN or EXPLAIN QUERY PLAN mode.
4437
+**
4438
+** Because of the potential need to reprepare, a call to
4439
+** sqlite3_stmt_explain(S,E) will fail with SQLITE_ERROR if S cannot be
4440
+** reprepared because it was created using [sqlite3_prepare()] instead of
4441
+** the newer [sqlite3_prepare_v2()] or [sqlite3_prepare_v3()] interfaces and
4442
+** hence has no saved SQL text with which to reprepare.
4443
+**
4444
+** Changing the explain setting for a prepared statement does not change
4445
+** the original SQL text for the statement. Hence, if the SQL text originally
4446
+** began with EXPLAIN or EXPLAIN QUERY PLAN, but sqlite3_stmt_explain(S,0)
4447
+** is called to convert the statement into an ordinary statement, the EXPLAIN
4448
+** or EXPLAIN QUERY PLAN keywords will still appear in the sqlite3_sql(S)
4449
+** output, even though the statement now acts like a normal SQL statement.
4450
+**
4451
+** This routine returns SQLITE_OK if the explain mode is successfully
4452
+** changed, or an error code if the explain mode could not be changed.
4453
+** The explain mode cannot be changed while a statement is active.
4454
+** Hence, it is good practice to call [sqlite3_reset(S)]
4455
+** immediately prior to calling sqlite3_stmt_explain(S,E).
4456
+*/
4457
+SQLITE_API int sqlite3_stmt_explain(sqlite3_stmt *pStmt, int eMode);
4458
+
44244459
/*
44254460
** CAPI3REF: Determine If A Prepared Statement Has Been Reset
44264461
** METHOD: sqlite3_stmt
44274462
**
44284463
** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the
44294464
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,11 +146,11 @@
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.43.0"
150 #define SQLITE_VERSION_NUMBER 3043000
151 #define SQLITE_SOURCE_ID "2023-07-08 17:42:24 07d95ed60f0a17ea13b4bc19c2ab2ec9052fedd27c9e1e57a1ec6e3a6470e5b7"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
@@ -4419,10 +4419,45 @@
4419 ** ^The sqlite3_stmt_isexplain(S) interface returns 0 if S is
4420 ** an ordinary statement or a NULL pointer.
4421 */
4422 SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt);
4423
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4424 /*
4425 ** CAPI3REF: Determine If A Prepared Statement Has Been Reset
4426 ** METHOD: sqlite3_stmt
4427 **
4428 ** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the
4429
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,11 +146,11 @@
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.43.0"
150 #define SQLITE_VERSION_NUMBER 3043000
151 #define SQLITE_SOURCE_ID "2023-08-02 16:06:02 ea0b9aecbaca9a8e784fd2bcb50f78cbdcf4c5cfb45a7700bb222e4cc104c644"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
@@ -4419,10 +4419,45 @@
4419 ** ^The sqlite3_stmt_isexplain(S) interface returns 0 if S is
4420 ** an ordinary statement or a NULL pointer.
4421 */
4422 SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt);
4423
4424 /*
4425 ** CAPI3REF: Change The EXPLAIN Setting For A Prepared Statement
4426 ** METHOD: sqlite3_stmt
4427 **
4428 ** The sqlite3_stmt_explain(S,E) interface changes the EXPLAIN
4429 ** setting for [prepared statement] S. If E is zero, then S becomes
4430 ** a normal prepared statement. If E is 1, then S behaves as if
4431 ** its SQL text began with "[EXPLAIN]". If E is 2, then S behaves as if
4432 ** its SQL text began with "[EXPLAIN QUERY PLAN]".
4433 **
4434 ** Calling sqlite3_stmt_explain(S,E) might cause S to be reprepared.
4435 ** SQLite tries to avoid a reprepare, but a reprepare might be necessary
4436 ** on the first transition into EXPLAIN or EXPLAIN QUERY PLAN mode.
4437 **
4438 ** Because of the potential need to reprepare, a call to
4439 ** sqlite3_stmt_explain(S,E) will fail with SQLITE_ERROR if S cannot be
4440 ** reprepared because it was created using [sqlite3_prepare()] instead of
4441 ** the newer [sqlite3_prepare_v2()] or [sqlite3_prepare_v3()] interfaces and
4442 ** hence has no saved SQL text with which to reprepare.
4443 **
4444 ** Changing the explain setting for a prepared statement does not change
4445 ** the original SQL text for the statement. Hence, if the SQL text originally
4446 ** began with EXPLAIN or EXPLAIN QUERY PLAN, but sqlite3_stmt_explain(S,0)
4447 ** is called to convert the statement into an ordinary statement, the EXPLAIN
4448 ** or EXPLAIN QUERY PLAN keywords will still appear in the sqlite3_sql(S)
4449 ** output, even though the statement now acts like a normal SQL statement.
4450 **
4451 ** This routine returns SQLITE_OK if the explain mode is successfully
4452 ** changed, or an error code if the explain mode could not be changed.
4453 ** The explain mode cannot be changed while a statement is active.
4454 ** Hence, it is good practice to call [sqlite3_reset(S)]
4455 ** immediately prior to calling sqlite3_stmt_explain(S,E).
4456 */
4457 SQLITE_API int sqlite3_stmt_explain(sqlite3_stmt *pStmt, int eMode);
4458
4459 /*
4460 ** CAPI3REF: Determine If A Prepared Statement Has Been Reset
4461 ** METHOD: sqlite3_stmt
4462 **
4463 ** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the
4464

Keyboard Shortcuts

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