Fossil SCM

Merged in trunk, resolved conflicts introduced via the parallel development of the markdown-footnotes branch.

stephan 2022-04-24 22:46 markdown-tagrefs merge
Commit 64af75b0702d8a9b145bf84f2ea51eb8802c285f37b5baee2b7ed8a9b214f392
+10
--- Makefile.in
+++ Makefile.in
@@ -47,10 +47,17 @@
4747
CFLAGS = @CFLAGS@
4848
CFLAGS_INCLUDE = @CFLAGS_INCLUDE@
4949
LIB = @LDFLAGS@ @EXTRA_LDFLAGS@ @LIBS@
5050
BCCFLAGS = @CPPFLAGS@ $(CFLAGS)
5151
TCCFLAGS = @EXTRA_CFLAGS@ @CPPFLAGS@ $(CFLAGS) -DHAVE_AUTOCONFIG_H -D_HAVE_SQLITE_CONFIG_H
52
+#
53
+# Fuzzing may be enable by appending -fsanitize=fuzzer -DFOSSIL_FUZZ
54
+# to the TCCFLAGS variable.
55
+# For more thorouth (but also slower) investigation
56
+# -fsanitize=fuzzer,undefined,address
57
+# might be more useful.
58
+
5259
INSTALLDIR = $(DESTDIR)@prefix@/bin
5360
USE_SYSTEM_SQLITE = @USE_SYSTEM_SQLITE@
5461
SQLITE3_SRC.2 = @SQLITE3_SRC.2@
5562
SQLITE3_OBJ.2 = @SQLITE3_OBJ.2@
5663
SQLITE3_SHELL_SRC.2 = @SQLITE3_SHELL_SRC.2@
@@ -62,10 +69,13 @@
6269
# 0=src/shell.c, 1=src/shell-see.c, 2=$(SQLITE3_SHELL_SRC.2)
6370
USE_LINENOISE = @USE_LINENOISE@
6471
USE_MMAN_H = @USE_MMAN_H@
6572
USE_SEE = @USE_SEE@
6673
APPNAME = fossil
74
+#
75
+# APPNAME = fossil-fuzz
76
+# may be more appropriate for fuzzing.
6777
6878
.PHONY: all tags
6979
7080
include $(SRCDIR)/main.mk
7181
7282
--- Makefile.in
+++ Makefile.in
@@ -47,10 +47,17 @@
47 CFLAGS = @CFLAGS@
48 CFLAGS_INCLUDE = @CFLAGS_INCLUDE@
49 LIB = @LDFLAGS@ @EXTRA_LDFLAGS@ @LIBS@
50 BCCFLAGS = @CPPFLAGS@ $(CFLAGS)
51 TCCFLAGS = @EXTRA_CFLAGS@ @CPPFLAGS@ $(CFLAGS) -DHAVE_AUTOCONFIG_H -D_HAVE_SQLITE_CONFIG_H
 
 
 
 
 
 
 
52 INSTALLDIR = $(DESTDIR)@prefix@/bin
53 USE_SYSTEM_SQLITE = @USE_SYSTEM_SQLITE@
54 SQLITE3_SRC.2 = @SQLITE3_SRC.2@
55 SQLITE3_OBJ.2 = @SQLITE3_OBJ.2@
56 SQLITE3_SHELL_SRC.2 = @SQLITE3_SHELL_SRC.2@
@@ -62,10 +69,13 @@
62 # 0=src/shell.c, 1=src/shell-see.c, 2=$(SQLITE3_SHELL_SRC.2)
63 USE_LINENOISE = @USE_LINENOISE@
64 USE_MMAN_H = @USE_MMAN_H@
65 USE_SEE = @USE_SEE@
66 APPNAME = fossil
 
 
 
67
68 .PHONY: all tags
69
70 include $(SRCDIR)/main.mk
71
72
--- Makefile.in
+++ Makefile.in
@@ -47,10 +47,17 @@
47 CFLAGS = @CFLAGS@
48 CFLAGS_INCLUDE = @CFLAGS_INCLUDE@
49 LIB = @LDFLAGS@ @EXTRA_LDFLAGS@ @LIBS@
50 BCCFLAGS = @CPPFLAGS@ $(CFLAGS)
51 TCCFLAGS = @EXTRA_CFLAGS@ @CPPFLAGS@ $(CFLAGS) -DHAVE_AUTOCONFIG_H -D_HAVE_SQLITE_CONFIG_H
52 #
53 # Fuzzing may be enable by appending -fsanitize=fuzzer -DFOSSIL_FUZZ
54 # to the TCCFLAGS variable.
55 # For more thorouth (but also slower) investigation
56 # -fsanitize=fuzzer,undefined,address
57 # might be more useful.
58
59 INSTALLDIR = $(DESTDIR)@prefix@/bin
60 USE_SYSTEM_SQLITE = @USE_SYSTEM_SQLITE@
61 SQLITE3_SRC.2 = @SQLITE3_SRC.2@
62 SQLITE3_OBJ.2 = @SQLITE3_OBJ.2@
63 SQLITE3_SHELL_SRC.2 = @SQLITE3_SHELL_SRC.2@
@@ -62,10 +69,13 @@
69 # 0=src/shell.c, 1=src/shell-see.c, 2=$(SQLITE3_SHELL_SRC.2)
70 USE_LINENOISE = @USE_LINENOISE@
71 USE_MMAN_H = @USE_MMAN_H@
72 USE_SEE = @USE_SEE@
73 APPNAME = fossil
74 #
75 # APPNAME = fossil-fuzz
76 # may be more appropriate for fuzzing.
77
78 .PHONY: all tags
79
80 include $(SRCDIR)/main.mk
81
82
+29 -13
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -14029,10 +14029,13 @@
1402914029
** The indenting rules are:
1403014030
**
1403114031
** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
1403214032
** all opcodes that occur between the p2 jump destination and the opcode
1403314033
** itself by 2 spaces.
14034
+**
14035
+** * Do the previous for "Return" instructions for when P2 is positive.
14036
+** See tag-20220407a in wherecode.c and vdbe.c.
1403414037
**
1403514038
** * For each "Goto", if the jump destination is earlier in the program
1403614039
** and ends on one of:
1403714040
** Yield SeekGt SeekLt RowSetRead Rewind
1403814041
** or if the P1 parameter is one instead of zero,
@@ -14044,11 +14047,12 @@
1404414047
const char *z; /* Used to check if this is an EXPLAIN */
1404514048
int *abYield = 0; /* True if op is an OP_Yield */
1404614049
int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
1404714050
int iOp; /* Index of operation in p->aiIndent[] */
1404814051
14049
- const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", 0 };
14052
+ const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
14053
+ "Return", 0 };
1405014054
const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
1405114055
"Rewind", 0 };
1405214056
const char *azGoto[] = { "Goto", 0 };
1405314057
1405414058
/* Try to figure out if this is really an EXPLAIN statement. If this
@@ -14102,11 +14106,11 @@
1410214106
}
1410314107
abYield[iOp] = str_in_array(zOp, azYield);
1410414108
p->aiIndent[iOp] = 0;
1410514109
p->nIndent = iOp+1;
1410614110
14107
- if( str_in_array(zOp, azNext) ){
14111
+ if( str_in_array(zOp, azNext) && p2op>0 ){
1410814112
for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
1410914113
}
1411014114
if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1411114115
&& (abYield[p2op] || sqlite3_column_int(pSql, 2))
1411214116
){
@@ -14128,11 +14132,11 @@
1412814132
p->nIndent = 0;
1412914133
p->iIndent = 0;
1413014134
}
1413114135
1413214136
/*
14133
-** Disable and restore .wheretrace and .selecttrace settings.
14137
+** Disable and restore .wheretrace and .treetrace/.selecttrace settings.
1413414138
*/
1413514139
static unsigned int savedSelectTrace;
1413614140
static unsigned int savedWhereTrace;
1413714141
static void disable_debug_trace_modes(void){
1413814142
unsigned int zero = 0;
@@ -14432,10 +14436,12 @@
1443214436
const char *rowSep = 0;
1443314437
const unsigned char **azNextLine = 0;
1443414438
int bNextLine = 0;
1443514439
int bMultiLineRowExists = 0;
1443614440
int bw = p->cmOpts.bWordWrap;
14441
+ const char *zEmpty = "";
14442
+ const char *zShowNull = p->nullValue;
1443714443
1443814444
rc = sqlite3_step(pStmt);
1443914445
if( rc!=SQLITE_ROW ) return;
1444014446
nColumn = sqlite3_column_count(pStmt);
1444114447
nAlloc = nColumn*4;
@@ -14493,16 +14499,18 @@
1449314499
wx = p->cmOpts.iWrap;
1449414500
}
1449514501
if( wx<0 ) wx = -wx;
1449614502
if( useNextLine ){
1449714503
uz = azNextLine[i];
14504
+ if( uz==0 ) uz = (u8*)zEmpty;
1449814505
}else if( p->cmOpts.bQuote ){
1449914506
sqlite3_free(azQuoted[i]);
1450014507
azQuoted[i] = quoted_column(pStmt,i);
1450114508
uz = (const unsigned char*)azQuoted[i];
1450214509
}else{
1450314510
uz = (const unsigned char*)sqlite3_column_text(pStmt,i);
14511
+ if( uz==0 ) uz = (u8*)zShowNull;
1450414512
}
1450514513
azData[nRow*nColumn + i]
1450614514
= translateForDisplayAndDup(uz, &azNextLine[i], wx, bw);
1450714515
if( azNextLine[i] ){
1450814516
bNextLine = 1;
@@ -14512,11 +14520,11 @@
1451214520
}
1451314521
}while( bNextLine || sqlite3_step(pStmt)==SQLITE_ROW );
1451414522
nTotal = nColumn*(nRow+1);
1451514523
for(i=0; i<nTotal; i++){
1451614524
z = azData[i];
14517
- if( z==0 ) z = p->nullValue;
14525
+ if( z==0 ) z = (char*)zEmpty;
1451814526
n = strlenChar(z);
1451914527
j = i%nColumn;
1452014528
if( n>p->actualWidth[j] ) p->actualWidth[j] = n;
1452114529
}
1452214530
if( seenInterrupt ) goto columnar_end;
@@ -14616,11 +14624,14 @@
1461614624
columnar_end:
1461714625
if( seenInterrupt ){
1461814626
utf8_printf(p->out, "Interrupt\n");
1461914627
}
1462014628
nData = (nRow+1)*nColumn;
14621
- for(i=0; i<nData; i++) free(azData[i]);
14629
+ for(i=0; i<nData; i++){
14630
+ z = azData[i];
14631
+ if( z!=zEmpty && z!=zShowNull ) free(azData[i]);
14632
+ }
1462214633
sqlite3_free(azData);
1462314634
sqlite3_free((void*)azNextLine);
1462414635
sqlite3_free(abRowDiv);
1462514636
if( azQuoted ){
1462614637
for(i=0; i<nColumn; i++) sqlite3_free(azQuoted[i]);
@@ -18915,11 +18926,11 @@
1891518926
return rc;
1891618927
}
1891718928
#endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
1891818929
1891918930
18920
-/*
18931
+/*
1892118932
* zAutoColumn(zCol, &db, ?) => Maybe init db, add column zCol to it.
1892218933
* zAutoColumn(0, &db, ?) => (db!=0) Form columns spec for CREATE TABLE,
1892318934
* close db and set it to 0, and return the columns spec, to later
1892418935
* be sqlite3_free()'ed by the caller.
1892518936
* The return is 0 when either:
@@ -18998,10 +19009,17 @@
1899819009
";
1899919010
#ifdef SQLITE_ENABLE_MATH_FUNCTIONS
1900019011
static const char * const zColDigits = "\
1900119012
SELECT CAST(ceil(log(count(*)+0.5)) AS INT) FROM ColNames \
1900219013
";
19014
+#else
19015
+ /* Counting on SQLITE_MAX_COLUMN < 100,000 here. (32767 is the hard limit.) */
19016
+ static const char * const zColDigits = "\
19017
+SELECT CASE WHEN (nc < 10) THEN 1 WHEN (nc < 100) THEN 2 \
19018
+ WHEN (nc < 1000) THEN 3 WHEN (nc < 10000) THEN 4 \
19019
+ ELSE 5 FROM (SELECT count(*) AS nc FROM ColNames) \
19020
+";
1900319021
#endif
1900419022
static const char * const zRenameRank =
1900519023
#ifdef SHELL_COLUMN_RENAME_CLEAN
1900619024
"UPDATE ColNames AS t SET suff="
1900719025
"iif(reps>1, printf('%c%0*d', '"AUTOCOLUMN_SEP"', $1, cpos), '')"
@@ -19044,16 +19062,16 @@
1904419062
|| group_concat(\
1904519063
cname||' TEXT',\
1904619064
','||iif((cpos-1)%4>0, ' ', x'0a'||' '))\
1904719065
||')' AS ColsSpec \
1904819066
FROM (\
19049
- SELECT cpos, printf('\"%w\"',printf('%.*s%s', nlen-chop,name,suff)) AS cname \
19067
+ SELECT cpos, printf('\"%w\"',printf('%!.*s%s', nlen-chop,name,suff)) AS cname \
1905019068
FROM ColNames ORDER BY cpos\
1905119069
)";
1905219070
static const char * const zRenamesDone =
1905319071
"SELECT group_concat("
19054
- " printf('\"%w\" to \"%w\"',name,printf('%.*s%s', nlen-chop, name, suff)),"
19072
+ " printf('\"%w\" to \"%w\"',name,printf('%!.*s%s', nlen-chop, name, suff)),"
1905519073
" ','||x'0a')"
1905619074
"FROM ColNames WHERE suff<>'' OR chop!=0"
1905719075
;
1905819076
int rc;
1905919077
sqlite3_stmt *pStmt = 0;
@@ -19083,15 +19101,11 @@
1908319101
return 0;
1908419102
}else{
1908519103
/* Formulate the columns spec, close the DB, zero *pDb. */
1908619104
char *zColsSpec = 0;
1908719105
int hasDupes = db_int(*pDb, zHasDupes);
19088
-#ifdef SQLITE_ENABLE_MATH_FUNCTIONS
1908919106
int nDigits = (hasDupes)? db_int(*pDb, zColDigits) : 0;
19090
-#else
19091
-# define nDigits 2
19092
-#endif
1909319107
if( hasDupes ){
1909419108
#ifdef SHELL_COLUMN_RENAME_CLEAN
1909519109
rc = sqlite3_exec(*pDb, zDedoctor, 0, 0, 0);
1909619110
rc_err_oom_die(rc);
1909719111
#endif
@@ -21199,11 +21213,13 @@
2119921213
}else{
2120021214
rc = 0;
2120121215
}
2120221216
}else
2120321217
21204
- if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
21218
+ if( (c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0)
21219
+ || (c=='t' && n==9 && strncmp(azArg[0], "treetrace", n)==0)
21220
+ ){
2120521221
unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff;
2120621222
sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &x);
2120721223
}else
2120821224
2120921225
#if defined(SQLITE_ENABLE_SESSION)
2121021226
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -14029,10 +14029,13 @@
14029 ** The indenting rules are:
14030 **
14031 ** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
14032 ** all opcodes that occur between the p2 jump destination and the opcode
14033 ** itself by 2 spaces.
 
 
 
14034 **
14035 ** * For each "Goto", if the jump destination is earlier in the program
14036 ** and ends on one of:
14037 ** Yield SeekGt SeekLt RowSetRead Rewind
14038 ** or if the P1 parameter is one instead of zero,
@@ -14044,11 +14047,12 @@
14044 const char *z; /* Used to check if this is an EXPLAIN */
14045 int *abYield = 0; /* True if op is an OP_Yield */
14046 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
14047 int iOp; /* Index of operation in p->aiIndent[] */
14048
14049 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", 0 };
 
14050 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
14051 "Rewind", 0 };
14052 const char *azGoto[] = { "Goto", 0 };
14053
14054 /* Try to figure out if this is really an EXPLAIN statement. If this
@@ -14102,11 +14106,11 @@
14102 }
14103 abYield[iOp] = str_in_array(zOp, azYield);
14104 p->aiIndent[iOp] = 0;
14105 p->nIndent = iOp+1;
14106
14107 if( str_in_array(zOp, azNext) ){
14108 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
14109 }
14110 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
14111 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
14112 ){
@@ -14128,11 +14132,11 @@
14128 p->nIndent = 0;
14129 p->iIndent = 0;
14130 }
14131
14132 /*
14133 ** Disable and restore .wheretrace and .selecttrace settings.
14134 */
14135 static unsigned int savedSelectTrace;
14136 static unsigned int savedWhereTrace;
14137 static void disable_debug_trace_modes(void){
14138 unsigned int zero = 0;
@@ -14432,10 +14436,12 @@
14432 const char *rowSep = 0;
14433 const unsigned char **azNextLine = 0;
14434 int bNextLine = 0;
14435 int bMultiLineRowExists = 0;
14436 int bw = p->cmOpts.bWordWrap;
 
 
14437
14438 rc = sqlite3_step(pStmt);
14439 if( rc!=SQLITE_ROW ) return;
14440 nColumn = sqlite3_column_count(pStmt);
14441 nAlloc = nColumn*4;
@@ -14493,16 +14499,18 @@
14493 wx = p->cmOpts.iWrap;
14494 }
14495 if( wx<0 ) wx = -wx;
14496 if( useNextLine ){
14497 uz = azNextLine[i];
 
14498 }else if( p->cmOpts.bQuote ){
14499 sqlite3_free(azQuoted[i]);
14500 azQuoted[i] = quoted_column(pStmt,i);
14501 uz = (const unsigned char*)azQuoted[i];
14502 }else{
14503 uz = (const unsigned char*)sqlite3_column_text(pStmt,i);
 
14504 }
14505 azData[nRow*nColumn + i]
14506 = translateForDisplayAndDup(uz, &azNextLine[i], wx, bw);
14507 if( azNextLine[i] ){
14508 bNextLine = 1;
@@ -14512,11 +14520,11 @@
14512 }
14513 }while( bNextLine || sqlite3_step(pStmt)==SQLITE_ROW );
14514 nTotal = nColumn*(nRow+1);
14515 for(i=0; i<nTotal; i++){
14516 z = azData[i];
14517 if( z==0 ) z = p->nullValue;
14518 n = strlenChar(z);
14519 j = i%nColumn;
14520 if( n>p->actualWidth[j] ) p->actualWidth[j] = n;
14521 }
14522 if( seenInterrupt ) goto columnar_end;
@@ -14616,11 +14624,14 @@
14616 columnar_end:
14617 if( seenInterrupt ){
14618 utf8_printf(p->out, "Interrupt\n");
14619 }
14620 nData = (nRow+1)*nColumn;
14621 for(i=0; i<nData; i++) free(azData[i]);
 
 
 
14622 sqlite3_free(azData);
14623 sqlite3_free((void*)azNextLine);
14624 sqlite3_free(abRowDiv);
14625 if( azQuoted ){
14626 for(i=0; i<nColumn; i++) sqlite3_free(azQuoted[i]);
@@ -18915,11 +18926,11 @@
18915 return rc;
18916 }
18917 #endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
18918
18919
18920 /*
18921 * zAutoColumn(zCol, &db, ?) => Maybe init db, add column zCol to it.
18922 * zAutoColumn(0, &db, ?) => (db!=0) Form columns spec for CREATE TABLE,
18923 * close db and set it to 0, and return the columns spec, to later
18924 * be sqlite3_free()'ed by the caller.
18925 * The return is 0 when either:
@@ -18998,10 +19009,17 @@
18998 ";
18999 #ifdef SQLITE_ENABLE_MATH_FUNCTIONS
19000 static const char * const zColDigits = "\
19001 SELECT CAST(ceil(log(count(*)+0.5)) AS INT) FROM ColNames \
19002 ";
 
 
 
 
 
 
 
19003 #endif
19004 static const char * const zRenameRank =
19005 #ifdef SHELL_COLUMN_RENAME_CLEAN
19006 "UPDATE ColNames AS t SET suff="
19007 "iif(reps>1, printf('%c%0*d', '"AUTOCOLUMN_SEP"', $1, cpos), '')"
@@ -19044,16 +19062,16 @@
19044 || group_concat(\
19045 cname||' TEXT',\
19046 ','||iif((cpos-1)%4>0, ' ', x'0a'||' '))\
19047 ||')' AS ColsSpec \
19048 FROM (\
19049 SELECT cpos, printf('\"%w\"',printf('%.*s%s', nlen-chop,name,suff)) AS cname \
19050 FROM ColNames ORDER BY cpos\
19051 )";
19052 static const char * const zRenamesDone =
19053 "SELECT group_concat("
19054 " printf('\"%w\" to \"%w\"',name,printf('%.*s%s', nlen-chop, name, suff)),"
19055 " ','||x'0a')"
19056 "FROM ColNames WHERE suff<>'' OR chop!=0"
19057 ;
19058 int rc;
19059 sqlite3_stmt *pStmt = 0;
@@ -19083,15 +19101,11 @@
19083 return 0;
19084 }else{
19085 /* Formulate the columns spec, close the DB, zero *pDb. */
19086 char *zColsSpec = 0;
19087 int hasDupes = db_int(*pDb, zHasDupes);
19088 #ifdef SQLITE_ENABLE_MATH_FUNCTIONS
19089 int nDigits = (hasDupes)? db_int(*pDb, zColDigits) : 0;
19090 #else
19091 # define nDigits 2
19092 #endif
19093 if( hasDupes ){
19094 #ifdef SHELL_COLUMN_RENAME_CLEAN
19095 rc = sqlite3_exec(*pDb, zDedoctor, 0, 0, 0);
19096 rc_err_oom_die(rc);
19097 #endif
@@ -21199,11 +21213,13 @@
21199 }else{
21200 rc = 0;
21201 }
21202 }else
21203
21204 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
 
 
21205 unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff;
21206 sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &x);
21207 }else
21208
21209 #if defined(SQLITE_ENABLE_SESSION)
21210
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -14029,10 +14029,13 @@
14029 ** The indenting rules are:
14030 **
14031 ** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
14032 ** all opcodes that occur between the p2 jump destination and the opcode
14033 ** itself by 2 spaces.
14034 **
14035 ** * Do the previous for "Return" instructions for when P2 is positive.
14036 ** See tag-20220407a in wherecode.c and vdbe.c.
14037 **
14038 ** * For each "Goto", if the jump destination is earlier in the program
14039 ** and ends on one of:
14040 ** Yield SeekGt SeekLt RowSetRead Rewind
14041 ** or if the P1 parameter is one instead of zero,
@@ -14044,11 +14047,12 @@
14047 const char *z; /* Used to check if this is an EXPLAIN */
14048 int *abYield = 0; /* True if op is an OP_Yield */
14049 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
14050 int iOp; /* Index of operation in p->aiIndent[] */
14051
14052 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
14053 "Return", 0 };
14054 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
14055 "Rewind", 0 };
14056 const char *azGoto[] = { "Goto", 0 };
14057
14058 /* Try to figure out if this is really an EXPLAIN statement. If this
@@ -14102,11 +14106,11 @@
14106 }
14107 abYield[iOp] = str_in_array(zOp, azYield);
14108 p->aiIndent[iOp] = 0;
14109 p->nIndent = iOp+1;
14110
14111 if( str_in_array(zOp, azNext) && p2op>0 ){
14112 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
14113 }
14114 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
14115 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
14116 ){
@@ -14128,11 +14132,11 @@
14132 p->nIndent = 0;
14133 p->iIndent = 0;
14134 }
14135
14136 /*
14137 ** Disable and restore .wheretrace and .treetrace/.selecttrace settings.
14138 */
14139 static unsigned int savedSelectTrace;
14140 static unsigned int savedWhereTrace;
14141 static void disable_debug_trace_modes(void){
14142 unsigned int zero = 0;
@@ -14432,10 +14436,12 @@
14436 const char *rowSep = 0;
14437 const unsigned char **azNextLine = 0;
14438 int bNextLine = 0;
14439 int bMultiLineRowExists = 0;
14440 int bw = p->cmOpts.bWordWrap;
14441 const char *zEmpty = "";
14442 const char *zShowNull = p->nullValue;
14443
14444 rc = sqlite3_step(pStmt);
14445 if( rc!=SQLITE_ROW ) return;
14446 nColumn = sqlite3_column_count(pStmt);
14447 nAlloc = nColumn*4;
@@ -14493,16 +14499,18 @@
14499 wx = p->cmOpts.iWrap;
14500 }
14501 if( wx<0 ) wx = -wx;
14502 if( useNextLine ){
14503 uz = azNextLine[i];
14504 if( uz==0 ) uz = (u8*)zEmpty;
14505 }else if( p->cmOpts.bQuote ){
14506 sqlite3_free(azQuoted[i]);
14507 azQuoted[i] = quoted_column(pStmt,i);
14508 uz = (const unsigned char*)azQuoted[i];
14509 }else{
14510 uz = (const unsigned char*)sqlite3_column_text(pStmt,i);
14511 if( uz==0 ) uz = (u8*)zShowNull;
14512 }
14513 azData[nRow*nColumn + i]
14514 = translateForDisplayAndDup(uz, &azNextLine[i], wx, bw);
14515 if( azNextLine[i] ){
14516 bNextLine = 1;
@@ -14512,11 +14520,11 @@
14520 }
14521 }while( bNextLine || sqlite3_step(pStmt)==SQLITE_ROW );
14522 nTotal = nColumn*(nRow+1);
14523 for(i=0; i<nTotal; i++){
14524 z = azData[i];
14525 if( z==0 ) z = (char*)zEmpty;
14526 n = strlenChar(z);
14527 j = i%nColumn;
14528 if( n>p->actualWidth[j] ) p->actualWidth[j] = n;
14529 }
14530 if( seenInterrupt ) goto columnar_end;
@@ -14616,11 +14624,14 @@
14624 columnar_end:
14625 if( seenInterrupt ){
14626 utf8_printf(p->out, "Interrupt\n");
14627 }
14628 nData = (nRow+1)*nColumn;
14629 for(i=0; i<nData; i++){
14630 z = azData[i];
14631 if( z!=zEmpty && z!=zShowNull ) free(azData[i]);
14632 }
14633 sqlite3_free(azData);
14634 sqlite3_free((void*)azNextLine);
14635 sqlite3_free(abRowDiv);
14636 if( azQuoted ){
14637 for(i=0; i<nColumn; i++) sqlite3_free(azQuoted[i]);
@@ -18915,11 +18926,11 @@
18926 return rc;
18927 }
18928 #endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
18929
18930
18931 /*
18932 * zAutoColumn(zCol, &db, ?) => Maybe init db, add column zCol to it.
18933 * zAutoColumn(0, &db, ?) => (db!=0) Form columns spec for CREATE TABLE,
18934 * close db and set it to 0, and return the columns spec, to later
18935 * be sqlite3_free()'ed by the caller.
18936 * The return is 0 when either:
@@ -18998,10 +19009,17 @@
19009 ";
19010 #ifdef SQLITE_ENABLE_MATH_FUNCTIONS
19011 static const char * const zColDigits = "\
19012 SELECT CAST(ceil(log(count(*)+0.5)) AS INT) FROM ColNames \
19013 ";
19014 #else
19015 /* Counting on SQLITE_MAX_COLUMN < 100,000 here. (32767 is the hard limit.) */
19016 static const char * const zColDigits = "\
19017 SELECT CASE WHEN (nc < 10) THEN 1 WHEN (nc < 100) THEN 2 \
19018 WHEN (nc < 1000) THEN 3 WHEN (nc < 10000) THEN 4 \
19019 ELSE 5 FROM (SELECT count(*) AS nc FROM ColNames) \
19020 ";
19021 #endif
19022 static const char * const zRenameRank =
19023 #ifdef SHELL_COLUMN_RENAME_CLEAN
19024 "UPDATE ColNames AS t SET suff="
19025 "iif(reps>1, printf('%c%0*d', '"AUTOCOLUMN_SEP"', $1, cpos), '')"
@@ -19044,16 +19062,16 @@
19062 || group_concat(\
19063 cname||' TEXT',\
19064 ','||iif((cpos-1)%4>0, ' ', x'0a'||' '))\
19065 ||')' AS ColsSpec \
19066 FROM (\
19067 SELECT cpos, printf('\"%w\"',printf('%!.*s%s', nlen-chop,name,suff)) AS cname \
19068 FROM ColNames ORDER BY cpos\
19069 )";
19070 static const char * const zRenamesDone =
19071 "SELECT group_concat("
19072 " printf('\"%w\" to \"%w\"',name,printf('%!.*s%s', nlen-chop, name, suff)),"
19073 " ','||x'0a')"
19074 "FROM ColNames WHERE suff<>'' OR chop!=0"
19075 ;
19076 int rc;
19077 sqlite3_stmt *pStmt = 0;
@@ -19083,15 +19101,11 @@
19101 return 0;
19102 }else{
19103 /* Formulate the columns spec, close the DB, zero *pDb. */
19104 char *zColsSpec = 0;
19105 int hasDupes = db_int(*pDb, zHasDupes);
 
19106 int nDigits = (hasDupes)? db_int(*pDb, zColDigits) : 0;
 
 
 
19107 if( hasDupes ){
19108 #ifdef SHELL_COLUMN_RENAME_CLEAN
19109 rc = sqlite3_exec(*pDb, zDedoctor, 0, 0, 0);
19110 rc_err_oom_die(rc);
19111 #endif
@@ -21199,11 +21213,13 @@
21213 }else{
21214 rc = 0;
21215 }
21216 }else
21217
21218 if( (c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0)
21219 || (c=='t' && n==9 && strncmp(azArg[0], "treetrace", n)==0)
21220 ){
21221 unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff;
21222 sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &x);
21223 }else
21224
21225 #if defined(SQLITE_ENABLE_SESSION)
21226
+2874 -1648
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -452,11 +452,11 @@
452452
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
453453
** [sqlite_version()] and [sqlite_source_id()].
454454
*/
455455
#define SQLITE_VERSION "3.39.0"
456456
#define SQLITE_VERSION_NUMBER 3039000
457
-#define SQLITE_SOURCE_ID "2022-04-01 17:23:17 a7d79560a0efd6221ba59ce84bcb4fa94024a901ac4a45e192ddecc6e1b5c78c"
457
+#define SQLITE_SOURCE_ID "2022-04-21 19:38:17 f766dff012af0ea3c28a8ce4db850cd0205729a8283bce1e442992aded7c734b"
458458
459459
/*
460460
** CAPI3REF: Run-Time Library Version Numbers
461461
** KEYWORDS: sqlite3_version sqlite3_sourceid
462462
**
@@ -14363,12 +14363,23 @@
1436314363
#define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)
1436414364
1436514365
/*
1436614366
** Round up a number to the next larger multiple of 8. This is used
1436714367
** to force 8-byte alignment on 64-bit architectures.
14368
+**
14369
+** ROUND8() always does the rounding, for any argument.
14370
+**
14371
+** ROUND8P() assumes that the argument is already an integer number of
14372
+** pointers in size, and so it is a no-op on systems where the pointer
14373
+** size is 8.
1436814374
*/
1436914375
#define ROUND8(x) (((x)+7)&~7)
14376
+#if SQLITE_PTRSIZE==8
14377
+# define ROUND8P(x) (x)
14378
+#else
14379
+# define ROUND8P(x) (((x)+7)&~7)
14380
+#endif
1437014381
1437114382
/*
1437214383
** Round down to the nearest multiple of 8
1437314384
*/
1437414385
#define ROUNDDOWN8(x) ((x)&~7)
@@ -14427,26 +14438,27 @@
1442714438
# undef SQLITE_DEFAULT_MMAP_SIZE
1442814439
# define SQLITE_DEFAULT_MMAP_SIZE SQLITE_MAX_MMAP_SIZE
1442914440
#endif
1443014441
1443114442
/*
14432
-** SELECTTRACE_ENABLED will be either 1 or 0 depending on whether or not
14433
-** the Select query generator tracing logic is turned on.
14443
+** TREETRACE_ENABLED will be either 1 or 0 depending on whether or not
14444
+** the Abstract Syntax Tree tracing logic is turned on.
1443414445
*/
1443514446
#if !defined(SQLITE_AMALGAMATION)
14436
-SQLITE_PRIVATE u32 sqlite3SelectTrace;
14447
+SQLITE_PRIVATE u32 sqlite3TreeTrace;
1443714448
#endif
1443814449
#if defined(SQLITE_DEBUG) \
14439
- && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_SELECTTRACE))
14440
-# define SELECTTRACE_ENABLED 1
14450
+ && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_SELECTTRACE) \
14451
+ || defined(SQLITE_ENABLE_TREETRACE))
14452
+# define TREETRACE_ENABLED 1
1444114453
# define SELECTTRACE(K,P,S,X) \
14442
- if(sqlite3SelectTrace&(K)) \
14454
+ if(sqlite3TreeTrace&(K)) \
1444314455
sqlite3DebugPrintf("%u/%d/%p: ",(S)->selId,(P)->addrExplain,(S)),\
1444414456
sqlite3DebugPrintf X
1444514457
#else
1444614458
# define SELECTTRACE(K,P,S,X)
14447
-# define SELECTTRACE_ENABLED 0
14459
+# define TREETRACE_ENABLED 0
1444814460
#endif
1444914461
1445014462
/*
1445114463
** Macros for "wheretrace"
1445214464
*/
@@ -14603,10 +14615,11 @@
1460314615
typedef struct KeyInfo KeyInfo;
1460414616
typedef struct Lookaside Lookaside;
1460514617
typedef struct LookasideSlot LookasideSlot;
1460614618
typedef struct Module Module;
1460714619
typedef struct NameContext NameContext;
14620
+typedef struct OnOrUsing OnOrUsing;
1460814621
typedef struct Parse Parse;
1460914622
typedef struct ParseCleanup ParseCleanup;
1461014623
typedef struct PreUpdate PreUpdate;
1461114624
typedef struct PrintfArguments PrintfArguments;
1461214625
typedef struct RenameToken RenameToken;
@@ -15581,14 +15594,14 @@
1558115594
#define OP_Function 66 /* synopsis: r[P3]=func(r[P2@NP]) */
1558215595
#define OP_Return 67
1558315596
#define OP_EndCoroutine 68
1558415597
#define OP_HaltIfNull 69 /* synopsis: if r[P3]=null halt */
1558515598
#define OP_Halt 70
15586
-#define OP_BeginSubrtn 71 /* synopsis: r[P2]=P1 */
15587
-#define OP_Integer 72 /* synopsis: r[P2]=P1 */
15588
-#define OP_Int64 73 /* synopsis: r[P2]=P4 */
15589
-#define OP_String 74 /* synopsis: r[P2]='P4' (len=P1) */
15599
+#define OP_Integer 71 /* synopsis: r[P2]=P1 */
15600
+#define OP_Int64 72 /* synopsis: r[P2]=P4 */
15601
+#define OP_String 73 /* synopsis: r[P2]='P4' (len=P1) */
15602
+#define OP_BeginSubrtn 74 /* synopsis: r[P2]=NULL */
1559015603
#define OP_Null 75 /* synopsis: r[P2..P3]=NULL */
1559115604
#define OP_SoftNull 76 /* synopsis: r[P1]=NULL */
1559215605
#define OP_Blob 77 /* synopsis: r[P2]=P4 (len=P1) */
1559315606
#define OP_Variable 78 /* synopsis: r[P2]=parameter(P1,P4) */
1559415607
#define OP_Move 79 /* synopsis: r[P2@P3]=r[P1@P3] */
@@ -15604,11 +15617,11 @@
1560415617
#define OP_Permutation 89
1560515618
#define OP_Compare 90 /* synopsis: r[P1@P3] <-> r[P2@P3] */
1560615619
#define OP_IsTrue 91 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */
1560715620
#define OP_ZeroOrNull 92 /* synopsis: r[P2] = 0 OR NULL */
1560815621
#define OP_Offset 93 /* synopsis: r[P3] = sqlite_offset(P1) */
15609
-#define OP_Column 94 /* synopsis: r[P3]=PX */
15622
+#define OP_Column 94 /* synopsis: r[P3]=PX cursor P1 column P2 */
1561015623
#define OP_TypeCheck 95 /* synopsis: typecheck(r[P1@P2]) */
1561115624
#define OP_Affinity 96 /* synopsis: affinity(r[P1@P2]) */
1561215625
#define OP_MakeRecord 97 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
1561315626
#define OP_Count 98 /* synopsis: r[P2]=count() */
1561415627
#define OP_ReadCookie 99
@@ -15645,11 +15658,11 @@
1564515658
#define OP_Delete 130
1564615659
#define OP_ResetCount 131
1564715660
#define OP_SorterCompare 132 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
1564815661
#define OP_SorterData 133 /* synopsis: r[P2]=data */
1564915662
#define OP_RowData 134 /* synopsis: r[P2]=data */
15650
-#define OP_Rowid 135 /* synopsis: r[P2]=rowid */
15663
+#define OP_Rowid 135 /* synopsis: r[P2]=PX rowid of P1 */
1565115664
#define OP_NullRow 136
1565215665
#define OP_SeekEnd 137
1565315666
#define OP_IdxInsert 138 /* synopsis: key=r[P2] */
1565415667
#define OP_SorterInsert 139 /* synopsis: key=r[P2] */
1565515668
#define OP_IdxDelete 140 /* synopsis: key=r[P2@P3] */
@@ -15716,12 +15729,12 @@
1571615729
/* 24 */ 0x01, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x01,\
1571715730
/* 32 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
1571815731
/* 40 */ 0x01, 0x01, 0x01, 0x26, 0x26, 0x23, 0x0b, 0x01,\
1571915732
/* 48 */ 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\
1572015733
/* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x01, 0x01,\
15721
-/* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x00,\
15722
-/* 72 */ 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00,\
15734
+/* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\
15735
+/* 72 */ 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10, 0x00,\
1572315736
/* 80 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02,\
1572415737
/* 88 */ 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20, 0x00, 0x00,\
1572515738
/* 96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x26, 0x26,\
1572615739
/* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\
1572715740
/* 112 */ 0x00, 0x00, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00,\
@@ -15823,11 +15836,10 @@
1582315836
SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
1582415837
SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Parse*);
1582515838
SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*);
1582615839
SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe*);
1582715840
SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*);
15828
-SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3*,Vdbe*);
1582915841
SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,Parse*);
1583015842
SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe*);
1583115843
SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int);
1583215844
SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe*);
1583315845
#ifdef SQLITE_DEBUG
@@ -17038,10 +17050,11 @@
1703817050
#define SQLITE_OmitOrderBy 0x00040000 /* Omit pointless ORDER BY */
1703917051
/* TH3 expects this value ^^^^^^^^^^ to be 0x40000. Coordinate any change */
1704017052
#define SQLITE_BloomFilter 0x00080000 /* Use a Bloom filter on searches */
1704117053
#define SQLITE_BloomPulldown 0x00100000 /* Run Bloom filters early */
1704217054
#define SQLITE_BalancedMerge 0x00200000 /* Balance multi-way merges */
17055
+#define SQLITE_ReleaseReg 0x00400000 /* Use OP_ReleaseReg for testing */
1704317056
#define SQLITE_AllOpts 0xffffffff /* All optimizations */
1704417057
1704517058
/*
1704617059
** Macros for testing whether or not optimizations are enabled or disabled.
1704717060
*/
@@ -18102,11 +18115,11 @@
1810218115
ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid.
1810318116
** TK_VARIABLE: variable number (always >= 1).
1810418117
** TK_SELECT_COLUMN: column of the result vector */
1810518118
i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
1810618119
union {
18107
- int iRightJoinTable; /* If EP_FromJoin, the right table of the join */
18120
+ int iJoin; /* If EP_FromJoin, the right table of the join */
1810818121
int iOfst; /* else: start of token from start of statement */
1810918122
} w;
1811018123
AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
1811118124
union {
1811218125
Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL
@@ -18145,11 +18158,11 @@
1814518158
#define EP_IfNullRow 0x020000 /* The TK_IF_NULL_ROW opcode */
1814618159
#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
1814718160
#define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
1814818161
#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
1814918162
#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
18150
- /* 0x400000 // Available */
18163
+#define EP_InnerJoin 0x400000 /* Originates in ON/USING of an inner join */
1815118164
#define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
1815218165
#define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
1815318166
#define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */
1815418167
#define EP_Quoted 0x4000000 /* TK_ID was originally quoted */
1815518168
#define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */
@@ -18262,10 +18275,11 @@
1826218275
unsigned eEName :2; /* Meaning of zEName */
1826318276
unsigned done :1; /* A flag to indicate when processing is finished */
1826418277
unsigned reusable :1; /* Constant expression is reusable */
1826518278
unsigned bSorterRef :1; /* Defer evaluation until after sorting */
1826618279
unsigned bNulls: 1; /* True if explicit "NULLS FIRST/LAST" */
18280
+ unsigned bUsed: 1; /* This column used in a SF_NestedFrom subquery */
1826718281
union {
1826818282
struct { /* Used by any ExprList other than Parse.pConsExpr */
1826918283
u16 iOrderByCol; /* For ORDER BY, column number in result set */
1827018284
u16 iAlias; /* Index into Parse.aAlias[] for zName */
1827118285
} x;
@@ -18296,17 +18310,29 @@
1829618310
** INSERT INTO t(a,b,c) ...
1829718311
**
1829818312
** If "a" is the k-th column of table "t", then IdList.a[0].idx==k.
1829918313
*/
1830018314
struct IdList {
18315
+ int nId; /* Number of identifiers on the list */
18316
+ u8 eU4; /* Which element of a.u4 is valid */
1830118317
struct IdList_item {
1830218318
char *zName; /* Name of the identifier */
18303
- int idx; /* Index in some Table.aCol[] of a column named zName */
18304
- } *a;
18305
- int nId; /* Number of identifiers on the list */
18319
+ union {
18320
+ int idx; /* Index in some Table.aCol[] of a column named zName */
18321
+ Expr *pExpr; /* Expr to implement a USING variable -- NOT USED */
18322
+ } u4;
18323
+ } a[1];
1830618324
};
1830718325
18326
+/*
18327
+** Allowed values for IdList.eType, which determines which value of the a.u4
18328
+** is valid.
18329
+*/
18330
+#define EU4_NONE 0 /* Does not use IdList.a.u4 */
18331
+#define EU4_IDX 1 /* Uses IdList.a.u4.idx */
18332
+#define EU4_EXPR 2 /* Uses IdList.a.u4.pExpr -- NOT CURRENTLY USED */
18333
+
1830818334
/*
1830918335
** The SrcItem object represents a single term in the FROM clause of a query.
1831018336
** The SrcList object is mostly an array of SrcItems.
1831118337
**
1831218338
** Union member validity:
@@ -18335,14 +18361,19 @@
1833518361
unsigned viaCoroutine :1; /* Implemented as a co-routine */
1833618362
unsigned isRecursive :1; /* True for recursive reference in WITH */
1833718363
unsigned fromDDL :1; /* Comes from sqlite_schema */
1833818364
unsigned isCte :1; /* This is a CTE */
1833918365
unsigned notCte :1; /* This item may not match a CTE */
18366
+ unsigned isUsing :1; /* u3.pUsing is valid */
18367
+ unsigned isSynthUsing :1; /* u3.pUsing is synthensized from NATURAL */
18368
+ unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */
1834018369
} fg;
1834118370
int iCursor; /* The VDBE cursor number used to access this table */
18342
- Expr *pOn; /* The ON clause of a join */
18343
- IdList *pUsing; /* The USING clause of a join */
18371
+ union {
18372
+ Expr *pOn; /* fg.isUsing==0 => The ON clause of a join */
18373
+ IdList *pUsing; /* fg.isUsing==1 => The USING clause of a join */
18374
+ } u3;
1834418375
Bitmask colUsed; /* Bit N (1<<N) set if column N of pTab is used */
1834518376
union {
1834618377
char *zIndexedBy; /* Identifier from "INDEXED BY <zIndex>" clause */
1834718378
ExprList *pFuncArg; /* Arguments to table-valued-function */
1834818379
} u1;
@@ -18349,10 +18380,19 @@
1834918380
union {
1835018381
Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */
1835118382
CteUse *pCteUse; /* CTE Usage info info fg.isCte is true */
1835218383
} u2;
1835318384
};
18385
+
18386
+/*
18387
+** The OnOrUsing object represents either an ON clause or a USING clause.
18388
+** It can never be both at the same time, but it can be neither.
18389
+*/
18390
+struct OnOrUsing {
18391
+ Expr *pOn; /* The ON clause of a join */
18392
+ IdList *pUsing; /* The USING clause of a join */
18393
+};
1835418394
1835518395
/*
1835618396
** The following structure describes the FROM clause of a SELECT statement.
1835718397
** Each table or subquery in the FROM clause is a separate element of
1835818398
** the SrcList.a[] array.
@@ -18378,18 +18418,19 @@
1837818418
};
1837918419
1838018420
/*
1838118421
** Permitted values of the SrcList.a.jointype field
1838218422
*/
18383
-#define JT_INNER 0x0001 /* Any kind of inner or cross join */
18384
-#define JT_CROSS 0x0002 /* Explicit use of the CROSS keyword */
18385
-#define JT_NATURAL 0x0004 /* True for a "natural" join */
18386
-#define JT_LEFT 0x0008 /* Left outer join */
18387
-#define JT_RIGHT 0x0010 /* Right outer join */
18388
-#define JT_OUTER 0x0020 /* The "OUTER" keyword is present */
18389
-#define JT_ERROR 0x0040 /* unknown or unsupported join type */
18390
-
18423
+#define JT_INNER 0x01 /* Any kind of inner or cross join */
18424
+#define JT_CROSS 0x02 /* Explicit use of the CROSS keyword */
18425
+#define JT_NATURAL 0x04 /* True for a "natural" join */
18426
+#define JT_LEFT 0x08 /* Left outer join */
18427
+#define JT_RIGHT 0x10 /* Right outer join */
18428
+#define JT_OUTER 0x20 /* The "OUTER" keyword is present */
18429
+#define JT_LTORJ 0x40 /* One of the LEFT operands of a RIGHT JOIN
18430
+ ** Mnemonic: Left Table Of Right Join */
18431
+#define JT_ERROR 0x80 /* unknown or unsupported join type */
1839118432
1839218433
/*
1839318434
** Flags appropriate for the wctrlFlags parameter of sqlite3WhereBegin()
1839418435
** and the WhereInfo.wctrlFlags member.
1839518436
**
@@ -18408,11 +18449,11 @@
1840818449
#define WHERE_DISTINCTBY 0x0080 /* pOrderby is really a DISTINCT clause */
1840918450
#define WHERE_WANT_DISTINCT 0x0100 /* All output needs to be distinct */
1841018451
#define WHERE_SORTBYGROUP 0x0200 /* Support sqlite3WhereIsSorted() */
1841118452
#define WHERE_AGG_DISTINCT 0x0400 /* Query is "SELECT agg(DISTINCT ...)" */
1841218453
#define WHERE_ORDERBY_LIMIT 0x0800 /* ORDERBY+LIMIT on the inner loop */
18413
- /* 0x1000 not currently used */
18454
+#define WHERE_RIGHT_JOIN 0x1000 /* Processing a RIGHT JOIN */
1841418455
/* 0x2000 not currently used */
1841518456
#define WHERE_USE_LIMIT 0x4000 /* Use the LIMIT in cost estimates */
1841618457
/* 0x8000 not currently used */
1841718458
1841818459
/* Allowed return values from sqlite3WhereIsDistinct()
@@ -18604,10 +18645,13 @@
1860418645
#define SF_PushDown 0x1000000 /* SELECT has be modified by push-down opt */
1860518646
#define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */
1860618647
#define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */
1860718648
#define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */
1860818649
18650
+/* True if S exists and has SF_NestedFrom */
18651
+#define IsNestedFrom(S) ((S)!=0 && ((S)->selFlags&SF_NestedFrom)!=0)
18652
+
1860918653
/*
1861018654
** The results of a SELECT can be distributed in several ways, as defined
1861118655
** by one of the following macros. The "SRT" prefix means "SELECT Result
1861218656
** Type".
1861318657
**
@@ -18815,10 +18859,11 @@
1881518859
u8 mayAbort; /* True if statement may throw an ABORT exception */
1881618860
u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */
1881718861
u8 okConstFactor; /* OK to factor out constants */
1881818862
u8 disableLookaside; /* Number of times lookaside has been disabled */
1881918863
u8 disableVtab; /* Disable all virtual tables for this parse */
18864
+ u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */
1882018865
#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
1882118866
u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */
1882218867
#endif
1882318868
int nRangeReg; /* Size of the temporary register block */
1882418869
int iRangeReg; /* First register in temporary register block */
@@ -18987,24 +19032,24 @@
1898719032
#define OPFLAG_AUXDELETE 0x04 /* OP_Delete: index in a DELETE op */
1898819033
#define OPFLAG_NOCHNG_MAGIC 0x6d /* OP_MakeRecord: serialtype 10 is ok */
1898919034
#define OPFLAG_PREFORMAT 0x80 /* OP_Insert uses preformatted cell */
1899019035
1899119036
/*
18992
- * Each trigger present in the database schema is stored as an instance of
18993
- * struct Trigger.
18994
- *
18995
- * Pointers to instances of struct Trigger are stored in two ways.
18996
- * 1. In the "trigHash" hash table (part of the sqlite3* that represents the
18997
- * database). This allows Trigger structures to be retrieved by name.
18998
- * 2. All triggers associated with a single table form a linked list, using the
18999
- * pNext member of struct Trigger. A pointer to the first element of the
19000
- * linked list is stored as the "pTrigger" member of the associated
19001
- * struct Table.
19002
- *
19003
- * The "step_list" member points to the first element of a linked list
19004
- * containing the SQL statements specified as the trigger program.
19005
- */
19037
+** Each trigger present in the database schema is stored as an instance of
19038
+** struct Trigger.
19039
+**
19040
+** Pointers to instances of struct Trigger are stored in two ways.
19041
+** 1. In the "trigHash" hash table (part of the sqlite3* that represents the
19042
+** database). This allows Trigger structures to be retrieved by name.
19043
+** 2. All triggers associated with a single table form a linked list, using the
19044
+** pNext member of struct Trigger. A pointer to the first element of the
19045
+** linked list is stored as the "pTrigger" member of the associated
19046
+** struct Table.
19047
+**
19048
+** The "step_list" member points to the first element of a linked list
19049
+** containing the SQL statements specified as the trigger program.
19050
+*/
1900619051
struct Trigger {
1900719052
char *zName; /* The name of the trigger */
1900819053
char *table; /* The table or view to which the trigger applies */
1900919054
u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT */
1901019055
u8 tr_tm; /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
@@ -19027,47 +19072,52 @@
1902719072
*/
1902819073
#define TRIGGER_BEFORE 1
1902919074
#define TRIGGER_AFTER 2
1903019075
1903119076
/*
19032
- * An instance of struct TriggerStep is used to store a single SQL statement
19033
- * that is a part of a trigger-program.
19034
- *
19035
- * Instances of struct TriggerStep are stored in a singly linked list (linked
19036
- * using the "pNext" member) referenced by the "step_list" member of the
19037
- * associated struct Trigger instance. The first element of the linked list is
19038
- * the first step of the trigger-program.
19039
- *
19040
- * The "op" member indicates whether this is a "DELETE", "INSERT", "UPDATE" or
19041
- * "SELECT" statement. The meanings of the other members is determined by the
19042
- * value of "op" as follows:
19043
- *
19044
- * (op == TK_INSERT)
19045
- * orconf -> stores the ON CONFLICT algorithm
19046
- * pSelect -> If this is an INSERT INTO ... SELECT ... statement, then
19047
- * this stores a pointer to the SELECT statement. Otherwise NULL.
19048
- * zTarget -> Dequoted name of the table to insert into.
19049
- * pExprList -> If this is an INSERT INTO ... VALUES ... statement, then
19050
- * this stores values to be inserted. Otherwise NULL.
19051
- * pIdList -> If this is an INSERT INTO ... (<column-names>) VALUES ...
19052
- * statement, then this stores the column-names to be
19053
- * inserted into.
19054
- *
19055
- * (op == TK_DELETE)
19056
- * zTarget -> Dequoted name of the table to delete from.
19057
- * pWhere -> The WHERE clause of the DELETE statement if one is specified.
19058
- * Otherwise NULL.
19059
- *
19060
- * (op == TK_UPDATE)
19061
- * zTarget -> Dequoted name of the table to update.
19062
- * pWhere -> The WHERE clause of the UPDATE statement if one is specified.
19063
- * Otherwise NULL.
19064
- * pExprList -> A list of the columns to update and the expressions to update
19065
- * them to. See sqlite3Update() documentation of "pChanges"
19066
- * argument.
19067
- *
19068
- */
19077
+** An instance of struct TriggerStep is used to store a single SQL statement
19078
+** that is a part of a trigger-program.
19079
+**
19080
+** Instances of struct TriggerStep are stored in a singly linked list (linked
19081
+** using the "pNext" member) referenced by the "step_list" member of the
19082
+** associated struct Trigger instance. The first element of the linked list is
19083
+** the first step of the trigger-program.
19084
+**
19085
+** The "op" member indicates whether this is a "DELETE", "INSERT", "UPDATE" or
19086
+** "SELECT" statement. The meanings of the other members is determined by the
19087
+** value of "op" as follows:
19088
+**
19089
+** (op == TK_INSERT)
19090
+** orconf -> stores the ON CONFLICT algorithm
19091
+** pSelect -> The content to be inserted - either a SELECT statement or
19092
+** a VALUES clause.
19093
+** zTarget -> Dequoted name of the table to insert into.
19094
+** pIdList -> If this is an INSERT INTO ... (<column-names>) VALUES ...
19095
+** statement, then this stores the column-names to be
19096
+** inserted into.
19097
+** pUpsert -> The ON CONFLICT clauses for an Upsert
19098
+**
19099
+** (op == TK_DELETE)
19100
+** zTarget -> Dequoted name of the table to delete from.
19101
+** pWhere -> The WHERE clause of the DELETE statement if one is specified.
19102
+** Otherwise NULL.
19103
+**
19104
+** (op == TK_UPDATE)
19105
+** zTarget -> Dequoted name of the table to update.
19106
+** pWhere -> The WHERE clause of the UPDATE statement if one is specified.
19107
+** Otherwise NULL.
19108
+** pExprList -> A list of the columns to update and the expressions to update
19109
+** them to. See sqlite3Update() documentation of "pChanges"
19110
+** argument.
19111
+**
19112
+** (op == TK_SELECT)
19113
+** pSelect -> The SELECT statement
19114
+**
19115
+** (op == TK_RETURNING)
19116
+** pExprList -> The list of expressions that follow the RETURNING keyword.
19117
+**
19118
+*/
1906919119
struct TriggerStep {
1907019120
u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT,
1907119121
** or TK_RETURNING */
1907219122
u8 orconf; /* OE_Rollback etc. */
1907319123
Trigger *pTrig; /* The trigger that this step is a part of */
@@ -19673,22 +19723,54 @@
1967319723
#if defined(SQLITE_TEST)
1967419724
SQLITE_PRIVATE void *sqlite3TestTextToPtr(const char*);
1967519725
#endif
1967619726
1967719727
#if defined(SQLITE_DEBUG)
19728
+SQLITE_PRIVATE void sqlite3TreeViewLine(TreeView*, const char *zFormat, ...);
1967819729
SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView*, const Expr*, u8);
1967919730
SQLITE_PRIVATE void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*);
1968019731
SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*);
19732
+SQLITE_PRIVATE void sqlite3TreeViewBareIdList(TreeView*, const IdList*, const char*);
19733
+SQLITE_PRIVATE void sqlite3TreeViewIdList(TreeView*, const IdList*, u8, const char*);
1968119734
SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView*, const SrcList*);
1968219735
SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8);
1968319736
SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView*, const With*, u8);
19737
+SQLITE_PRIVATE void sqlite3TreeViewUpsert(TreeView*, const Upsert*, u8);
19738
+SQLITE_PRIVATE void sqlite3TreeViewDelete(const With*, const SrcList*, const Expr*,
19739
+ const ExprList*,const Expr*, const Trigger*);
19740
+SQLITE_PRIVATE void sqlite3TreeViewInsert(const With*, const SrcList*,
19741
+ const IdList*, const Select*, const ExprList*,
19742
+ int, const Upsert*, const Trigger*);
19743
+SQLITE_PRIVATE void sqlite3TreeViewUpdate(const With*, const SrcList*, const ExprList*,
19744
+ const Expr*, int, const ExprList*, const Expr*,
19745
+ const Upsert*, const Trigger*);
19746
+#ifndef SQLITE_OMIT_TRIGGER
19747
+SQLITE_PRIVATE void sqlite3TreeViewTriggerStep(TreeView*, const TriggerStep*, u8, u8);
19748
+SQLITE_PRIVATE void sqlite3TreeViewTrigger(TreeView*, const Trigger*, u8, u8);
19749
+#endif
1968419750
#ifndef SQLITE_OMIT_WINDOWFUNC
1968519751
SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView*, const Window*, u8);
1968619752
SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8);
1968719753
#endif
19754
+SQLITE_PRIVATE void sqlite3ShowExpr(const Expr*);
19755
+SQLITE_PRIVATE void sqlite3ShowExprList(const ExprList*);
19756
+SQLITE_PRIVATE void sqlite3ShowIdList(const IdList*);
19757
+SQLITE_PRIVATE void sqlite3ShowSrcList(const SrcList*);
19758
+SQLITE_PRIVATE void sqlite3ShowSelect(const Select*);
19759
+SQLITE_PRIVATE void sqlite3ShowWith(const With*);
19760
+SQLITE_PRIVATE void sqlite3ShowUpsert(const Upsert*);
19761
+#ifndef SQLITE_OMIT_TRIGGER
19762
+SQLITE_PRIVATE void sqlite3ShowTriggerStep(const TriggerStep*);
19763
+SQLITE_PRIVATE void sqlite3ShowTriggerStepList(const TriggerStep*);
19764
+SQLITE_PRIVATE void sqlite3ShowTrigger(const Trigger*);
19765
+SQLITE_PRIVATE void sqlite3ShowTriggerList(const Trigger*);
1968819766
#endif
19689
-
19767
+#ifndef SQLITE_OMIT_WINDOWFUNC
19768
+SQLITE_PRIVATE void sqlite3ShowWindow(const Window*);
19769
+SQLITE_PRIVATE void sqlite3ShowWinFunc(const Window*);
19770
+#endif
19771
+#endif
1969019772
1969119773
SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*);
1969219774
SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...);
1969319775
SQLITE_PRIVATE int sqlite3ErrorToParser(sqlite3*,int);
1969419776
SQLITE_PRIVATE void sqlite3Dequote(char*);
@@ -19833,17 +19915,18 @@
1983319915
SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*);
1983419916
SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(Parse*, SrcList*, int, int);
1983519917
SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2);
1983619918
SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*);
1983719919
SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*,
19838
- Token*, Select*, Expr*, IdList*);
19920
+ Token*, Select*, OnOrUsing*);
1983919921
SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *);
1984019922
SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*);
1984119923
SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, SrcItem *);
19842
-SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList*);
19924
+SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(Parse*,SrcList*);
1984319925
SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*);
1984419926
SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*);
19927
+SQLITE_PRIVATE void sqlite3ClearOnOrUsing(sqlite3*, OnOrUsing*);
1984519928
SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*);
1984619929
SQLITE_PRIVATE Index *sqlite3AllocateIndexObject(sqlite3*,i16,int,char**);
1984719930
SQLITE_PRIVATE void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
1984819931
Expr*, int, int, u8);
1984919932
SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
@@ -20036,11 +20119,12 @@
2003620119
# define sqlite3TriggerStepSrc(A,B) 0
2003720120
#endif
2003820121
2003920122
SQLITE_PRIVATE int sqlite3JoinType(Parse*, Token*, Token*, Token*);
2004020123
SQLITE_PRIVATE int sqlite3ColumnIndex(Table *pTab, const char *zCol);
20041
-SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr*,int);
20124
+SQLITE_PRIVATE void sqlite3SrcItemColumnUsed(SrcItem*,int);
20125
+SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr*,int,u32);
2004220126
SQLITE_PRIVATE void sqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int);
2004320127
SQLITE_PRIVATE void sqlite3DeferForeignKey(Parse*, int);
2004420128
#ifndef SQLITE_OMIT_AUTHORIZATION
2004520129
SQLITE_PRIVATE void sqlite3AuthRead(Parse*,Expr*,Schema*,SrcList*);
2004620130
SQLITE_PRIVATE int sqlite3AuthCheck(Parse*,int, const char*, const char*, const char*);
@@ -20382,11 +20466,11 @@
2038220466
SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *);
2038320467
2038420468
SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
2038520469
#if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \
2038620470
&& !defined(SQLITE_OMIT_VIRTUALTABLE)
20387
-SQLITE_PRIVATE void sqlite3VtabWriteAll(sqlite3_index_info*);
20471
+SQLITE_PRIVATE void sqlite3VtabUsesAllSchemas(sqlite3_index_info*);
2038820472
#endif
2038920473
SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
2039020474
SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
2039120475
SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
2039220476
SQLITE_PRIVATE void sqlite3ParseObjectInit(Parse*,sqlite3*);
@@ -21130,13 +21214,10 @@
2113021214
"ENABLE_RBU",
2113121215
#endif
2113221216
#ifdef SQLITE_ENABLE_RTREE
2113321217
"ENABLE_RTREE",
2113421218
#endif
21135
-#ifdef SQLITE_ENABLE_SELECTTRACE
21136
- "ENABLE_SELECTTRACE",
21137
-#endif
2113821219
#ifdef SQLITE_ENABLE_SESSION
2113921220
"ENABLE_SESSION",
2114021221
#endif
2114121222
#ifdef SQLITE_ENABLE_SNAPSHOT
2114221223
"ENABLE_SNAPSHOT",
@@ -21153,10 +21234,13 @@
2115321234
#ifdef SQLITE_ENABLE_STMTVTAB
2115421235
"ENABLE_STMTVTAB",
2115521236
#endif
2115621237
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
2115721238
"ENABLE_STMT_SCANSTATUS",
21239
+#endif
21240
+#ifdef SQLITE_ENABLE_TREETRACE
21241
+ "ENABLE_TREETRACE",
2115821242
#endif
2115921243
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
2116021244
"ENABLE_UNKNOWN_SQL_FUNCTION",
2116121245
#endif
2116221246
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
@@ -21960,11 +22044,11 @@
2196022044
#endif
2196122045
2196222046
/*
2196322047
** Tracing flags set by SQLITE_TESTCTRL_TRACEFLAGS.
2196422048
*/
21965
-SQLITE_PRIVATE u32 sqlite3SelectTrace = 0;
22049
+SQLITE_PRIVATE u32 sqlite3TreeTrace = 0;
2196622050
SQLITE_PRIVATE u32 sqlite3WhereTrace = 0;
2196722051
2196822052
/* #include "opcodes.h" */
2196922053
/*
2197022054
** Properties of opcodes. The OPFLG_INITIALIZER macro is
@@ -22175,10 +22259,15 @@
2217522259
** static element declared in the structure. nField total array slots for
2217622260
** aType[] and nField+1 array slots for aOffset[] */
2217722261
u32 aType[1]; /* Type values record decode. MUST BE LAST */
2217822262
};
2217922263
22264
+/* Return true if P is a null-only cursor
22265
+*/
22266
+#define IsNullCursor(P) \
22267
+ ((P)->eCurType==CURTYPE_PSEUDO && (P)->nullRow && (P)->seekResult==0)
22268
+
2218022269
2218122270
/*
2218222271
** A value for VdbeCursor.cacheStatus that means the cache is always invalid.
2218322272
*/
2218422273
#define CACHE_STALE 0
@@ -22496,16 +22585,14 @@
2249622585
#endif
2249722586
u16 nResColumn; /* Number of columns in one row of the result set */
2249822587
u8 errorAction; /* Recovery action to do in case of an error */
2249922588
u8 minWriteFileFormat; /* Minimum file format for writable database files */
2250022589
u8 prepFlags; /* SQLITE_PREPARE_* flags */
22501
- u8 doingRerun; /* True if rerunning after an auto-reprepare */
2250222590
u8 eVdbeState; /* On of the VDBE_*_STATE values */
2250322591
bft expired:2; /* 1: recompile VM immediately 2: when convenient */
2250422592
bft explain:2; /* True if EXPLAIN present on SQL command */
2250522593
bft changeCntOn:1; /* True to update the change-counter */
22506
- bft runOnlyOnce:1; /* Automatically expire on reset */
2250722594
bft usesStmtJournal:1; /* True if uses a statement journal */
2250822595
bft readOnly:1; /* True for statements that do not write */
2250922596
bft bIsReader:1; /* True for statements that read */
2251022597
yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
2251122598
yDbMask lockMask; /* Subset of btreeMask that requires a lock */
@@ -22574,22 +22661,35 @@
2257422661
struct ValueList {
2257522662
BtCursor *pCsr; /* An ephemeral table holding all values */
2257622663
sqlite3_value *pOut; /* Register to hold each decoded output value */
2257722664
};
2257822665
22666
+/* Size of content associated with serial types that fit into a
22667
+** single-byte varint.
22668
+*/
22669
+#ifndef SQLITE_AMALGAMATION
22670
+SQLITE_PRIVATE const u8 sqlite3SmallTypeSizes[];
22671
+#endif
22672
+
2257922673
/*
2258022674
** Function prototypes
2258122675
*/
2258222676
SQLITE_PRIVATE void sqlite3VdbeError(Vdbe*, const char *, ...);
2258322677
SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
22678
+SQLITE_PRIVATE void sqlite3VdbeFreeCursorNN(Vdbe*,VdbeCursor*);
2258422679
void sqliteVdbePopStack(Vdbe*,int);
2258522680
SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeHandleMovedCursor(VdbeCursor *p);
2258622681
SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor*);
2258722682
SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
2258822683
SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
2258922684
SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8);
22590
-SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
22685
+#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
22686
+SQLITE_PRIVATE u64 sqlite3FloatSwap(u64 in);
22687
+# define swapMixedEndianFloat(X) X = sqlite3FloatSwap(X)
22688
+#else
22689
+# define swapMixedEndianFloat(X)
22690
+#endif
2259122691
SQLITE_PRIVATE void sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
2259222692
SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3*, AuxData**, int, int);
2259322693
2259422694
int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
2259522695
SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
@@ -23046,12 +23146,11 @@
2304623146
struct Vdbe *pVdbe; /* Used to iterate through VMs */
2304723147
int nByte = 0; /* Used to accumulate return value */
2304823148
2304923149
db->pnBytesFreed = &nByte;
2305023150
for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){
23051
- sqlite3VdbeClearObject(db, pVdbe);
23052
- sqlite3DbFree(db, pVdbe);
23151
+ sqlite3VdbeDelete(pVdbe);
2305323152
}
2305423153
db->pnBytesFreed = 0;
2305523154
2305623155
*pHighwater = 0; /* IMP: R-64479-57858 */
2305723156
*pCurrent = nByte;
@@ -29389,12 +29488,13 @@
2938929488
2939029489
/*
2939129490
** Free any prior content in *pz and replace it with a copy of zNew.
2939229491
*/
2939329492
SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){
29493
+ char *z = sqlite3DbStrDup(db, zNew);
2939429494
sqlite3DbFree(db, *pz);
29395
- *pz = sqlite3DbStrDup(db, zNew);
29495
+ *pz = z;
2939629496
}
2939729497
2939829498
/*
2939929499
** Call this routine to record the fact that an OOM (out-of-memory) error
2940029500
** has happened. This routine will set db->mallocFailed, and also
@@ -30886,37 +30986,41 @@
3088630986
3088730987
/*
3088830988
** Add a new subitem to the tree. The moreToFollow flag indicates that this
3088930989
** is not the last item in the tree.
3089030990
*/
30891
-static TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){
30991
+static void sqlite3TreeViewPush(TreeView **pp, u8 moreToFollow){
30992
+ TreeView *p = *pp;
3089230993
if( p==0 ){
30893
- p = sqlite3_malloc64( sizeof(*p) );
30894
- if( p==0 ) return 0;
30994
+ *pp = p = sqlite3_malloc64( sizeof(*p) );
30995
+ if( p==0 ) return;
3089530996
memset(p, 0, sizeof(*p));
3089630997
}else{
3089730998
p->iLevel++;
3089830999
}
3089931000
assert( moreToFollow==0 || moreToFollow==1 );
3090031001
if( p->iLevel<(int)sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow;
30901
- return p;
3090231002
}
3090331003
3090431004
/*
3090531005
** Finished with one layer of the tree
3090631006
*/
30907
-static void sqlite3TreeViewPop(TreeView *p){
31007
+static void sqlite3TreeViewPop(TreeView **pp){
31008
+ TreeView *p = *pp;
3090831009
if( p==0 ) return;
3090931010
p->iLevel--;
30910
- if( p->iLevel<0 ) sqlite3_free(p);
31011
+ if( p->iLevel<0 ){
31012
+ sqlite3_free(p);
31013
+ *pp = 0;
31014
+ }
3091131015
}
3091231016
3091331017
/*
3091431018
** Generate a single line of output for the tree, with a prefix that contains
3091531019
** all the appropriate tree lines
3091631020
*/
30917
-static void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
31021
+SQLITE_PRIVATE void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
3091831022
va_list ap;
3091931023
int i;
3092031024
StrAccum acc;
3092131025
char zBuf[500];
3092231026
sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
@@ -30940,11 +31044,11 @@
3094031044
3094131045
/*
3094231046
** Shorthand for starting a new tree item that consists of a single label
3094331047
*/
3094431048
static void sqlite3TreeViewItem(TreeView *p, const char *zLabel,u8 moreFollows){
30945
- p = sqlite3TreeViewPush(p, moreFollows);
31049
+ sqlite3TreeViewPush(&p, moreFollows);
3094631050
sqlite3TreeViewLine(p, "%s", zLabel);
3094731051
}
3094831052
3094931053
/*
3095031054
** Generate a human-readable description of a WITH clause.
@@ -30957,11 +31061,11 @@
3095731061
sqlite3TreeViewLine(pView, "WITH (0x%p, pOuter=0x%p)",pWith,pWith->pOuter);
3095831062
}else{
3095931063
sqlite3TreeViewLine(pView, "WITH (0x%p)", pWith);
3096031064
}
3096131065
if( pWith->nCte>0 ){
30962
- pView = sqlite3TreeViewPush(pView, 1);
31066
+ sqlite3TreeViewPush(&pView, moreToFollow);
3096331067
for(i=0; i<pWith->nCte; i++){
3096431068
StrAccum x;
3096531069
char zLine[1000];
3096631070
const struct Cte *pCte = &pWith->a[i];
3096731071
sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
@@ -30980,21 +31084,22 @@
3098031084
pCte->pUse->nUse);
3098131085
}
3098231086
sqlite3StrAccumFinish(&x);
3098331087
sqlite3TreeViewItem(pView, zLine, i<pWith->nCte-1);
3098431088
sqlite3TreeViewSelect(pView, pCte->pSelect, 0);
30985
- sqlite3TreeViewPop(pView);
31089
+ sqlite3TreeViewPop(&pView);
3098631090
}
30987
- sqlite3TreeViewPop(pView);
31091
+ sqlite3TreeViewPop(&pView);
3098831092
}
3098931093
}
3099031094
3099131095
/*
3099231096
** Generate a human-readable description of a SrcList object.
3099331097
*/
3099431098
SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){
3099531099
int i;
31100
+ if( pSrc==0 ) return;
3099631101
for(i=0; i<pSrc->nSrc; i++){
3099731102
const SrcItem *pItem = &pSrc->a[i];
3099831103
StrAccum x;
3099931104
char zLine[100];
3100031105
sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
@@ -31002,14 +31107,21 @@
3100231107
sqlite3_str_appendf(&x, "{%d:*} %!S", pItem->iCursor, pItem);
3100331108
if( pItem->pTab ){
3100431109
sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx",
3100531110
pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab, pItem->colUsed);
3100631111
}
31007
- if( pItem->fg.jointype & JT_LEFT ){
31112
+ if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==(JT_LEFT|JT_RIGHT) ){
31113
+ sqlite3_str_appendf(&x, " FULL-OUTER-JOIN");
31114
+ }else if( pItem->fg.jointype & JT_LEFT ){
3100831115
sqlite3_str_appendf(&x, " LEFT-JOIN");
31116
+ }else if( pItem->fg.jointype & JT_RIGHT ){
31117
+ sqlite3_str_appendf(&x, " RIGHT-JOIN");
3100931118
}else if( pItem->fg.jointype & JT_CROSS ){
3101031119
sqlite3_str_appendf(&x, " CROSS-JOIN");
31120
+ }
31121
+ if( pItem->fg.jointype & JT_LTORJ ){
31122
+ sqlite3_str_appendf(&x, " LTORJ");
3101131123
}
3101231124
if( pItem->fg.fromDDL ){
3101331125
sqlite3_str_appendf(&x, " DDL");
3101431126
}
3101531127
if( pItem->fg.isCte ){
@@ -31016,16 +31128,17 @@
3101631128
sqlite3_str_appendf(&x, " CteUse=0x%p", pItem->u2.pCteUse);
3101731129
}
3101831130
sqlite3StrAccumFinish(&x);
3101931131
sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1);
3102031132
if( pItem->pSelect ){
31133
+ assert( pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) );
3102131134
sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
3102231135
}
3102331136
if( pItem->fg.isTabFunc ){
3102431137
sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
3102531138
}
31026
- sqlite3TreeViewPop(pView);
31139
+ sqlite3TreeViewPop(&pView);
3102731140
}
3102831141
}
3102931142
3103031143
/*
3103131144
** Generate a human-readable description of a Select object.
@@ -31035,15 +31148,15 @@
3103531148
int cnt = 0;
3103631149
if( p==0 ){
3103731150
sqlite3TreeViewLine(pView, "nil-SELECT");
3103831151
return;
3103931152
}
31040
- pView = sqlite3TreeViewPush(pView, moreToFollow);
31153
+ sqlite3TreeViewPush(&pView, moreToFollow);
3104131154
if( p->pWith ){
3104231155
sqlite3TreeViewWith(pView, p->pWith, 1);
3104331156
cnt = 1;
31044
- sqlite3TreeViewPush(pView, 1);
31157
+ sqlite3TreeViewPush(&pView, 1);
3104531158
}
3104631159
do{
3104731160
if( p->selFlags & SF_WhereBegin ){
3104831161
sqlite3TreeViewLine(pView, "sqlite3WhereBegin()");
3104931162
}else{
@@ -31053,11 +31166,11 @@
3105331166
((p->selFlags & SF_Aggregate) ? " agg_flag" : ""),
3105431167
p->selId, p, p->selFlags,
3105531168
(int)p->nSelectRow
3105631169
);
3105731170
}
31058
- if( cnt++ ) sqlite3TreeViewPop(pView);
31171
+ if( cnt++ ) sqlite3TreeViewPop(&pView);
3105931172
if( p->pPrior ){
3106031173
n = 1000;
3106131174
}else{
3106231175
n = 0;
3106331176
if( p->pSrc && p->pSrc->nSrc ) n++;
@@ -31076,45 +31189,45 @@
3107631189
}
3107731190
n--;
3107831191
#ifndef SQLITE_OMIT_WINDOWFUNC
3107931192
if( p->pWin ){
3108031193
Window *pX;
31081
- pView = sqlite3TreeViewPush(pView, (n--)>0);
31194
+ sqlite3TreeViewPush(&pView, (n--)>0);
3108231195
sqlite3TreeViewLine(pView, "window-functions");
3108331196
for(pX=p->pWin; pX; pX=pX->pNextWin){
3108431197
sqlite3TreeViewWinFunc(pView, pX, pX->pNextWin!=0);
3108531198
}
31086
- sqlite3TreeViewPop(pView);
31199
+ sqlite3TreeViewPop(&pView);
3108731200
}
3108831201
#endif
3108931202
if( p->pSrc && p->pSrc->nSrc ){
31090
- pView = sqlite3TreeViewPush(pView, (n--)>0);
31203
+ sqlite3TreeViewPush(&pView, (n--)>0);
3109131204
sqlite3TreeViewLine(pView, "FROM");
3109231205
sqlite3TreeViewSrcList(pView, p->pSrc);
31093
- sqlite3TreeViewPop(pView);
31206
+ sqlite3TreeViewPop(&pView);
3109431207
}
3109531208
if( p->pWhere ){
3109631209
sqlite3TreeViewItem(pView, "WHERE", (n--)>0);
3109731210
sqlite3TreeViewExpr(pView, p->pWhere, 0);
31098
- sqlite3TreeViewPop(pView);
31211
+ sqlite3TreeViewPop(&pView);
3109931212
}
3110031213
if( p->pGroupBy ){
3110131214
sqlite3TreeViewExprList(pView, p->pGroupBy, (n--)>0, "GROUPBY");
3110231215
}
3110331216
if( p->pHaving ){
3110431217
sqlite3TreeViewItem(pView, "HAVING", (n--)>0);
3110531218
sqlite3TreeViewExpr(pView, p->pHaving, 0);
31106
- sqlite3TreeViewPop(pView);
31219
+ sqlite3TreeViewPop(&pView);
3110731220
}
3110831221
#ifndef SQLITE_OMIT_WINDOWFUNC
3110931222
if( p->pWinDefn ){
3111031223
Window *pX;
3111131224
sqlite3TreeViewItem(pView, "WINDOW", (n--)>0);
3111231225
for(pX=p->pWinDefn; pX; pX=pX->pNextWin){
3111331226
sqlite3TreeViewWindow(pView, pX, pX->pNextWin!=0);
3111431227
}
31115
- sqlite3TreeViewPop(pView);
31228
+ sqlite3TreeViewPop(&pView);
3111631229
}
3111731230
#endif
3111831231
if( p->pOrderBy ){
3111931232
sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY");
3112031233
}
@@ -31122,13 +31235,13 @@
3112231235
sqlite3TreeViewItem(pView, "LIMIT", (n--)>0);
3112331236
sqlite3TreeViewExpr(pView, p->pLimit->pLeft, p->pLimit->pRight!=0);
3112431237
if( p->pLimit->pRight ){
3112531238
sqlite3TreeViewItem(pView, "OFFSET", (n--)>0);
3112631239
sqlite3TreeViewExpr(pView, p->pLimit->pRight, 0);
31127
- sqlite3TreeViewPop(pView);
31240
+ sqlite3TreeViewPop(&pView);
3112831241
}
31129
- sqlite3TreeViewPop(pView);
31242
+ sqlite3TreeViewPop(&pView);
3113031243
}
3113131244
if( p->pPrior ){
3113231245
const char *zOp = "UNION";
3113331246
switch( p->op ){
3113431247
case TK_ALL: zOp = "UNION ALL"; break;
@@ -31137,11 +31250,11 @@
3113731250
}
3113831251
sqlite3TreeViewItem(pView, zOp, 1);
3113931252
}
3114031253
p = p->pPrior;
3114131254
}while( p!=0 );
31142
- sqlite3TreeViewPop(pView);
31255
+ sqlite3TreeViewPop(&pView);
3114331256
}
3114431257
3114531258
#ifndef SQLITE_OMIT_WINDOWFUNC
3114631259
/*
3114731260
** Generate a description of starting or stopping bounds
@@ -31153,28 +31266,28 @@
3115331266
u8 moreToFollow /* True if more to follow */
3115431267
){
3115531268
switch( eBound ){
3115631269
case TK_UNBOUNDED: {
3115731270
sqlite3TreeViewItem(pView, "UNBOUNDED", moreToFollow);
31158
- sqlite3TreeViewPop(pView);
31271
+ sqlite3TreeViewPop(&pView);
3115931272
break;
3116031273
}
3116131274
case TK_CURRENT: {
3116231275
sqlite3TreeViewItem(pView, "CURRENT", moreToFollow);
31163
- sqlite3TreeViewPop(pView);
31276
+ sqlite3TreeViewPop(&pView);
3116431277
break;
3116531278
}
3116631279
case TK_PRECEDING: {
3116731280
sqlite3TreeViewItem(pView, "PRECEDING", moreToFollow);
3116831281
sqlite3TreeViewExpr(pView, pExpr, 0);
31169
- sqlite3TreeViewPop(pView);
31282
+ sqlite3TreeViewPop(&pView);
3117031283
break;
3117131284
}
3117231285
case TK_FOLLOWING: {
3117331286
sqlite3TreeViewItem(pView, "FOLLOWING", moreToFollow);
3117431287
sqlite3TreeViewExpr(pView, pExpr, 0);
31175
- sqlite3TreeViewPop(pView);
31288
+ sqlite3TreeViewPop(&pView);
3117631289
break;
3117731290
}
3117831291
}
3117931292
}
3118031293
#endif /* SQLITE_OMIT_WINDOWFUNC */
@@ -31186,13 +31299,13 @@
3118631299
SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){
3118731300
int nElement = 0;
3118831301
if( pWin->pFilter ){
3118931302
sqlite3TreeViewItem(pView, "FILTER", 1);
3119031303
sqlite3TreeViewExpr(pView, pWin->pFilter, 0);
31191
- sqlite3TreeViewPop(pView);
31304
+ sqlite3TreeViewPop(&pView);
3119231305
}
31193
- pView = sqlite3TreeViewPush(pView, more);
31306
+ sqlite3TreeViewPush(&pView, more);
3119431307
if( pWin->zName ){
3119531308
sqlite3TreeViewLine(pView, "OVER %s (%p)", pWin->zName, pWin);
3119631309
}else{
3119731310
sqlite3TreeViewLine(pView, "OVER (%p)", pWin);
3119831311
}
@@ -31199,13 +31312,13 @@
3119931312
if( pWin->zBase ) nElement++;
3120031313
if( pWin->pOrderBy ) nElement++;
3120131314
if( pWin->eFrmType ) nElement++;
3120231315
if( pWin->eExclude ) nElement++;
3120331316
if( pWin->zBase ){
31204
- sqlite3TreeViewPush(pView, (--nElement)>0);
31317
+ sqlite3TreeViewPush(&pView, (--nElement)>0);
3120531318
sqlite3TreeViewLine(pView, "window: %s", pWin->zBase);
31206
- sqlite3TreeViewPop(pView);
31319
+ sqlite3TreeViewPop(&pView);
3120731320
}
3120831321
if( pWin->pPartition ){
3120931322
sqlite3TreeViewExprList(pView, pWin->pPartition, nElement>0,"PARTITION-BY");
3121031323
}
3121131324
if( pWin->pOrderBy ){
@@ -31219,11 +31332,11 @@
3121931332
sqlite3_snprintf(sizeof(zBuf),zBuf,"%s%s",zFrmType,
3122031333
pWin->bImplicitFrame ? " (implied)" : "");
3122131334
sqlite3TreeViewItem(pView, zBuf, (--nElement)>0);
3122231335
sqlite3TreeViewBound(pView, pWin->eStart, pWin->pStart, 1);
3122331336
sqlite3TreeViewBound(pView, pWin->eEnd, pWin->pEnd, 0);
31224
- sqlite3TreeViewPop(pView);
31337
+ sqlite3TreeViewPop(&pView);
3122531338
}
3122631339
if( pWin->eExclude ){
3122731340
char zBuf[30];
3122831341
const char *zExclude;
3122931342
switch( pWin->eExclude ){
@@ -31234,28 +31347,28 @@
3123431347
default:
3123531348
sqlite3_snprintf(sizeof(zBuf),zBuf,"invalid(%d)", pWin->eExclude);
3123631349
zExclude = zBuf;
3123731350
break;
3123831351
}
31239
- sqlite3TreeViewPush(pView, 0);
31352
+ sqlite3TreeViewPush(&pView, 0);
3124031353
sqlite3TreeViewLine(pView, "EXCLUDE %s", zExclude);
31241
- sqlite3TreeViewPop(pView);
31354
+ sqlite3TreeViewPop(&pView);
3124231355
}
31243
- sqlite3TreeViewPop(pView);
31356
+ sqlite3TreeViewPop(&pView);
3124431357
}
3124531358
#endif /* SQLITE_OMIT_WINDOWFUNC */
3124631359
3124731360
#ifndef SQLITE_OMIT_WINDOWFUNC
3124831361
/*
3124931362
** Generate a human-readable explanation for a Window Function object
3125031363
*/
3125131364
SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){
31252
- pView = sqlite3TreeViewPush(pView, more);
31365
+ sqlite3TreeViewPush(&pView, more);
3125331366
sqlite3TreeViewLine(pView, "WINFUNC %s(%d)",
3125431367
pWin->pWFunc->zName, pWin->pWFunc->nArg);
3125531368
sqlite3TreeViewWindow(pView, pWin, 0);
31256
- sqlite3TreeViewPop(pView);
31369
+ sqlite3TreeViewPop(&pView);
3125731370
}
3125831371
#endif /* SQLITE_OMIT_WINDOWFUNC */
3125931372
3126031373
/*
3126131374
** Generate a human-readable explanation of an expression tree.
@@ -31262,23 +31375,23 @@
3126231375
*/
3126331376
SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
3126431377
const char *zBinOp = 0; /* Binary operator */
3126531378
const char *zUniOp = 0; /* Unary operator */
3126631379
char zFlgs[200];
31267
- pView = sqlite3TreeViewPush(pView, moreToFollow);
31380
+ sqlite3TreeViewPush(&pView, moreToFollow);
3126831381
if( pExpr==0 ){
3126931382
sqlite3TreeViewLine(pView, "nil");
31270
- sqlite3TreeViewPop(pView);
31383
+ sqlite3TreeViewPop(&pView);
3127131384
return;
3127231385
}
3127331386
if( pExpr->flags || pExpr->affExpr || pExpr->vvaFlags ){
3127431387
StrAccum x;
3127531388
sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0);
3127631389
sqlite3_str_appendf(&x, " fg.af=%x.%c",
3127731390
pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n');
3127831391
if( ExprHasProperty(pExpr, EP_FromJoin) ){
31279
- sqlite3_str_appendf(&x, " iRJT=%d", pExpr->w.iRightJoinTable);
31392
+ sqlite3_str_appendf(&x, " iJoin=%d", pExpr->w.iJoin);
3128031393
}
3128131394
if( ExprHasProperty(pExpr, EP_FromDDL) ){
3128231395
sqlite3_str_appendf(&x, " DDL");
3128331396
}
3128431397
if( ExprHasVVAProperty(pExpr, EP_Immutable) ){
@@ -31622,11 +31735,11 @@
3162231735
sqlite3TreeViewExpr(pView, pExpr->pRight, 0);
3162331736
}else if( zUniOp ){
3162431737
sqlite3TreeViewLine(pView, "%s%s", zUniOp, zFlgs);
3162531738
sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
3162631739
}
31627
- sqlite3TreeViewPop(pView);
31740
+ sqlite3TreeViewPop(&pView);
3162831741
}
3162931742
3163031743
3163131744
/*
3163231745
** Generate a human-readable explanation of an expression list.
@@ -31644,27 +31757,37 @@
3164431757
sqlite3TreeViewLine(pView, "%s", zLabel);
3164531758
for(i=0; i<pList->nExpr; i++){
3164631759
int j = pList->a[i].u.x.iOrderByCol;
3164731760
char *zName = pList->a[i].zEName;
3164831761
int moreToFollow = i<pList->nExpr - 1;
31649
- if( pList->a[i].eEName!=ENAME_NAME ) zName = 0;
3165031762
if( j || zName ){
31651
- sqlite3TreeViewPush(pView, moreToFollow);
31763
+ sqlite3TreeViewPush(&pView, moreToFollow);
3165231764
moreToFollow = 0;
3165331765
sqlite3TreeViewLine(pView, 0);
3165431766
if( zName ){
31655
- fprintf(stdout, "AS %s ", zName);
31767
+ switch( pList->a[i].eEName ){
31768
+ default:
31769
+ fprintf(stdout, "AS %s ", zName);
31770
+ break;
31771
+ case ENAME_TAB:
31772
+ fprintf(stdout, "TABLE-ALIAS-NAME(\"%s\") ", zName);
31773
+ if( pList->a[i].bUsed==0 ) fprintf(stdout, "(unused) ");
31774
+ break;
31775
+ case ENAME_SPAN:
31776
+ fprintf(stdout, "SPAN(\"%s\") ", zName);
31777
+ break;
31778
+ }
3165631779
}
3165731780
if( j ){
3165831781
fprintf(stdout, "iOrderByCol=%d", j);
3165931782
}
3166031783
fprintf(stdout, "\n");
3166131784
fflush(stdout);
3166231785
}
3166331786
sqlite3TreeViewExpr(pView, pList->a[i].pExpr, moreToFollow);
3166431787
if( j || zName ){
31665
- sqlite3TreeViewPop(pView);
31788
+ sqlite3TreeViewPop(&pView);
3166631789
}
3166731790
}
3166831791
}
3166931792
}
3167031793
SQLITE_PRIVATE void sqlite3TreeViewExprList(
@@ -31671,15 +31794,376 @@
3167131794
TreeView *pView,
3167231795
const ExprList *pList,
3167331796
u8 moreToFollow,
3167431797
const char *zLabel
3167531798
){
31676
- pView = sqlite3TreeViewPush(pView, moreToFollow);
31799
+ sqlite3TreeViewPush(&pView, moreToFollow);
3167731800
sqlite3TreeViewBareExprList(pView, pList, zLabel);
31678
- sqlite3TreeViewPop(pView);
31801
+ sqlite3TreeViewPop(&pView);
3167931802
}
3168031803
31804
+/*
31805
+** Generate a human-readable explanation of an id-list.
31806
+*/
31807
+SQLITE_PRIVATE void sqlite3TreeViewBareIdList(
31808
+ TreeView *pView,
31809
+ const IdList *pList,
31810
+ const char *zLabel
31811
+){
31812
+ if( zLabel==0 || zLabel[0]==0 ) zLabel = "LIST";
31813
+ if( pList==0 ){
31814
+ sqlite3TreeViewLine(pView, "%s (empty)", zLabel);
31815
+ }else{
31816
+ int i;
31817
+ sqlite3TreeViewLine(pView, "%s", zLabel);
31818
+ for(i=0; i<pList->nId; i++){
31819
+ char *zName = pList->a[i].zName;
31820
+ int moreToFollow = i<pList->nId - 1;
31821
+ if( zName==0 ) zName = "(null)";
31822
+ sqlite3TreeViewPush(&pView, moreToFollow);
31823
+ sqlite3TreeViewLine(pView, 0);
31824
+ if( pList->eU4==EU4_NONE ){
31825
+ fprintf(stdout, "%s\n", zName);
31826
+ }else if( pList->eU4==EU4_IDX ){
31827
+ fprintf(stdout, "%s (%d)\n", zName, pList->a[i].u4.idx);
31828
+ }else{
31829
+ assert( pList->eU4==EU4_EXPR );
31830
+ if( pList->a[i].u4.pExpr==0 ){
31831
+ fprintf(stdout, "%s (pExpr=NULL)\n", zName);
31832
+ }else{
31833
+ fprintf(stdout, "%s\n", zName);
31834
+ sqlite3TreeViewPush(&pView, i<pList->nId-1);
31835
+ sqlite3TreeViewExpr(pView, pList->a[i].u4.pExpr, 0);
31836
+ sqlite3TreeViewPop(&pView);
31837
+ }
31838
+ }
31839
+ sqlite3TreeViewPop(&pView);
31840
+ }
31841
+ }
31842
+}
31843
+SQLITE_PRIVATE void sqlite3TreeViewIdList(
31844
+ TreeView *pView,
31845
+ const IdList *pList,
31846
+ u8 moreToFollow,
31847
+ const char *zLabel
31848
+){
31849
+ sqlite3TreeViewPush(&pView, moreToFollow);
31850
+ sqlite3TreeViewBareIdList(pView, pList, zLabel);
31851
+ sqlite3TreeViewPop(&pView);
31852
+}
31853
+
31854
+/*
31855
+** Generate a human-readable explanation of a list of Upsert objects
31856
+*/
31857
+SQLITE_PRIVATE void sqlite3TreeViewUpsert(
31858
+ TreeView *pView,
31859
+ const Upsert *pUpsert,
31860
+ u8 moreToFollow
31861
+){
31862
+ if( pUpsert==0 ) return;
31863
+ sqlite3TreeViewPush(&pView, moreToFollow);
31864
+ while( pUpsert ){
31865
+ int n;
31866
+ sqlite3TreeViewPush(&pView, pUpsert->pNextUpsert!=0 || moreToFollow);
31867
+ sqlite3TreeViewLine(pView, "ON CONFLICT DO %s",
31868
+ pUpsert->isDoUpdate ? "UPDATE" : "NOTHING");
31869
+ n = (pUpsert->pUpsertSet!=0) + (pUpsert->pUpsertWhere!=0);
31870
+ sqlite3TreeViewExprList(pView, pUpsert->pUpsertTarget, (n--)>0, "TARGET");
31871
+ sqlite3TreeViewExprList(pView, pUpsert->pUpsertSet, (n--)>0, "SET");
31872
+ if( pUpsert->pUpsertWhere ){
31873
+ sqlite3TreeViewItem(pView, "WHERE", (n--)>0);
31874
+ sqlite3TreeViewExpr(pView, pUpsert->pUpsertWhere, 0);
31875
+ sqlite3TreeViewPop(&pView);
31876
+ }
31877
+ sqlite3TreeViewPop(&pView);
31878
+ pUpsert = pUpsert->pNextUpsert;
31879
+ }
31880
+ sqlite3TreeViewPop(&pView);
31881
+}
31882
+
31883
+/*
31884
+** Generate a human-readable diagram of the data structure that go
31885
+** into generating an DELETE statement.
31886
+*/
31887
+SQLITE_PRIVATE void sqlite3TreeViewDelete(
31888
+ const With *pWith,
31889
+ const SrcList *pTabList,
31890
+ const Expr *pWhere,
31891
+ const ExprList *pOrderBy,
31892
+ const Expr *pLimit,
31893
+ const Trigger *pTrigger
31894
+){
31895
+ int n = 0;
31896
+ TreeView *pView = 0;
31897
+ sqlite3TreeViewPush(&pView, 0);
31898
+ sqlite3TreeViewLine(pView, "DELETE");
31899
+ if( pWith ) n++;
31900
+ if( pTabList ) n++;
31901
+ if( pWhere ) n++;
31902
+ if( pOrderBy ) n++;
31903
+ if( pLimit ) n++;
31904
+ if( pTrigger ) n++;
31905
+ if( pWith ){
31906
+ sqlite3TreeViewPush(&pView, (--n)>0);
31907
+ sqlite3TreeViewWith(pView, pWith, 0);
31908
+ sqlite3TreeViewPop(&pView);
31909
+ }
31910
+ if( pTabList ){
31911
+ sqlite3TreeViewPush(&pView, (--n)>0);
31912
+ sqlite3TreeViewLine(pView, "FROM");
31913
+ sqlite3TreeViewSrcList(pView, pTabList);
31914
+ sqlite3TreeViewPop(&pView);
31915
+ }
31916
+ if( pWhere ){
31917
+ sqlite3TreeViewPush(&pView, (--n)>0);
31918
+ sqlite3TreeViewLine(pView, "WHERE");
31919
+ sqlite3TreeViewExpr(pView, pWhere, 0);
31920
+ sqlite3TreeViewPop(&pView);
31921
+ }
31922
+ if( pOrderBy ){
31923
+ sqlite3TreeViewExprList(pView, pOrderBy, (--n)>0, "ORDER-BY");
31924
+ }
31925
+ if( pLimit ){
31926
+ sqlite3TreeViewPush(&pView, (--n)>0);
31927
+ sqlite3TreeViewLine(pView, "LIMIT");
31928
+ sqlite3TreeViewExpr(pView, pLimit, 0);
31929
+ sqlite3TreeViewPop(&pView);
31930
+ }
31931
+ if( pTrigger ){
31932
+ sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1);
31933
+ }
31934
+ sqlite3TreeViewPop(&pView);
31935
+}
31936
+
31937
+/*
31938
+** Generate a human-readable diagram of the data structure that go
31939
+** into generating an INSERT statement.
31940
+*/
31941
+SQLITE_PRIVATE void sqlite3TreeViewInsert(
31942
+ const With *pWith,
31943
+ const SrcList *pTabList,
31944
+ const IdList *pColumnList,
31945
+ const Select *pSelect,
31946
+ const ExprList *pExprList,
31947
+ int onError,
31948
+ const Upsert *pUpsert,
31949
+ const Trigger *pTrigger
31950
+){
31951
+ TreeView *pView = 0;
31952
+ int n = 0;
31953
+ const char *zLabel = "INSERT";
31954
+ switch( onError ){
31955
+ case OE_Replace: zLabel = "REPLACE"; break;
31956
+ case OE_Ignore: zLabel = "INSERT OR IGNORE"; break;
31957
+ case OE_Rollback: zLabel = "INSERT OR ROLLBACK"; break;
31958
+ case OE_Abort: zLabel = "INSERT OR ABORT"; break;
31959
+ case OE_Fail: zLabel = "INSERT OR FAIL"; break;
31960
+ }
31961
+ sqlite3TreeViewPush(&pView, 0);
31962
+ sqlite3TreeViewLine(pView, zLabel);
31963
+ if( pWith ) n++;
31964
+ if( pTabList ) n++;
31965
+ if( pColumnList ) n++;
31966
+ if( pSelect ) n++;
31967
+ if( pExprList ) n++;
31968
+ if( pUpsert ) n++;
31969
+ if( pTrigger ) n++;
31970
+ if( pWith ){
31971
+ sqlite3TreeViewPush(&pView, (--n)>0);
31972
+ sqlite3TreeViewWith(pView, pWith, 0);
31973
+ sqlite3TreeViewPop(&pView);
31974
+ }
31975
+ if( pTabList ){
31976
+ sqlite3TreeViewPush(&pView, (--n)>0);
31977
+ sqlite3TreeViewLine(pView, "INTO");
31978
+ sqlite3TreeViewSrcList(pView, pTabList);
31979
+ sqlite3TreeViewPop(&pView);
31980
+ }
31981
+ if( pColumnList ){
31982
+ sqlite3TreeViewIdList(pView, pColumnList, (--n)>0, "COLUMNS");
31983
+ }
31984
+ if( pSelect ){
31985
+ sqlite3TreeViewPush(&pView, (--n)>0);
31986
+ sqlite3TreeViewLine(pView, "DATA-SOURCE");
31987
+ sqlite3TreeViewSelect(pView, pSelect, 0);
31988
+ sqlite3TreeViewPop(&pView);
31989
+ }
31990
+ if( pExprList ){
31991
+ sqlite3TreeViewExprList(pView, pExprList, (--n)>0, "VALUES");
31992
+ }
31993
+ if( pUpsert ){
31994
+ sqlite3TreeViewPush(&pView, (--n)>0);
31995
+ sqlite3TreeViewLine(pView, "UPSERT");
31996
+ sqlite3TreeViewUpsert(pView, pUpsert, 0);
31997
+ sqlite3TreeViewPop(&pView);
31998
+ }
31999
+ if( pTrigger ){
32000
+ sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1);
32001
+ }
32002
+ sqlite3TreeViewPop(&pView);
32003
+}
32004
+
32005
+/*
32006
+** Generate a human-readable diagram of the data structure that go
32007
+** into generating an UPDATE statement.
32008
+*/
32009
+SQLITE_PRIVATE void sqlite3TreeViewUpdate(
32010
+ const With *pWith,
32011
+ const SrcList *pTabList,
32012
+ const ExprList *pChanges,
32013
+ const Expr *pWhere,
32014
+ int onError,
32015
+ const ExprList *pOrderBy,
32016
+ const Expr *pLimit,
32017
+ const Upsert *pUpsert,
32018
+ const Trigger *pTrigger
32019
+){
32020
+ int n = 0;
32021
+ TreeView *pView = 0;
32022
+ const char *zLabel = "UPDATE";
32023
+ switch( onError ){
32024
+ case OE_Replace: zLabel = "UPDATE OR REPLACE"; break;
32025
+ case OE_Ignore: zLabel = "UPDATE OR IGNORE"; break;
32026
+ case OE_Rollback: zLabel = "UPDATE OR ROLLBACK"; break;
32027
+ case OE_Abort: zLabel = "UPDATE OR ABORT"; break;
32028
+ case OE_Fail: zLabel = "UPDATE OR FAIL"; break;
32029
+ }
32030
+ sqlite3TreeViewPush(&pView, 0);
32031
+ sqlite3TreeViewLine(pView, zLabel);
32032
+ if( pWith ) n++;
32033
+ if( pTabList ) n++;
32034
+ if( pChanges ) n++;
32035
+ if( pWhere ) n++;
32036
+ if( pOrderBy ) n++;
32037
+ if( pLimit ) n++;
32038
+ if( pUpsert ) n++;
32039
+ if( pTrigger ) n++;
32040
+ if( pWith ){
32041
+ sqlite3TreeViewPush(&pView, (--n)>0);
32042
+ sqlite3TreeViewWith(pView, pWith, 0);
32043
+ sqlite3TreeViewPop(&pView);
32044
+ }
32045
+ if( pTabList ){
32046
+ sqlite3TreeViewPush(&pView, (--n)>0);
32047
+ sqlite3TreeViewLine(pView, "FROM");
32048
+ sqlite3TreeViewSrcList(pView, pTabList);
32049
+ sqlite3TreeViewPop(&pView);
32050
+ }
32051
+ if( pChanges ){
32052
+ sqlite3TreeViewExprList(pView, pChanges, (--n)>0, "SET");
32053
+ }
32054
+ if( pWhere ){
32055
+ sqlite3TreeViewPush(&pView, (--n)>0);
32056
+ sqlite3TreeViewLine(pView, "WHERE");
32057
+ sqlite3TreeViewExpr(pView, pWhere, 0);
32058
+ sqlite3TreeViewPop(&pView);
32059
+ }
32060
+ if( pOrderBy ){
32061
+ sqlite3TreeViewExprList(pView, pOrderBy, (--n)>0, "ORDER-BY");
32062
+ }
32063
+ if( pLimit ){
32064
+ sqlite3TreeViewPush(&pView, (--n)>0);
32065
+ sqlite3TreeViewLine(pView, "LIMIT");
32066
+ sqlite3TreeViewExpr(pView, pLimit, 0);
32067
+ sqlite3TreeViewPop(&pView);
32068
+ }
32069
+ if( pUpsert ){
32070
+ sqlite3TreeViewPush(&pView, (--n)>0);
32071
+ sqlite3TreeViewLine(pView, "UPSERT");
32072
+ sqlite3TreeViewUpsert(pView, pUpsert, 0);
32073
+ sqlite3TreeViewPop(&pView);
32074
+ }
32075
+ if( pTrigger ){
32076
+ sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1);
32077
+ }
32078
+ sqlite3TreeViewPop(&pView);
32079
+}
32080
+
32081
+#ifndef SQLITE_OMIT_TRIGGER
32082
+/*
32083
+** Show a human-readable graph of a TriggerStep
32084
+*/
32085
+SQLITE_PRIVATE void sqlite3TreeViewTriggerStep(
32086
+ TreeView *pView,
32087
+ const TriggerStep *pStep,
32088
+ u8 moreToFollow,
32089
+ u8 showFullList
32090
+){
32091
+ int cnt = 0;
32092
+ if( pStep==0 ) return;
32093
+ sqlite3TreeViewPush(&pView,
32094
+ moreToFollow || (showFullList && pStep->pNext!=0));
32095
+ do{
32096
+ if( cnt++ && pStep->pNext==0 ){
32097
+ sqlite3TreeViewPop(&pView);
32098
+ sqlite3TreeViewPush(&pView, 0);
32099
+ }
32100
+ sqlite3TreeViewLine(pView, "%s", pStep->zSpan ? pStep->zSpan : "RETURNING");
32101
+ }while( showFullList && (pStep = pStep->pNext)!=0 );
32102
+ sqlite3TreeViewPop(&pView);
32103
+}
32104
+
32105
+/*
32106
+** Show a human-readable graph of a Trigger
32107
+*/
32108
+SQLITE_PRIVATE void sqlite3TreeViewTrigger(
32109
+ TreeView *pView,
32110
+ const Trigger *pTrigger,
32111
+ u8 moreToFollow,
32112
+ u8 showFullList
32113
+){
32114
+ int cnt = 0;
32115
+ if( pTrigger==0 ) return;
32116
+ sqlite3TreeViewPush(&pView,
32117
+ moreToFollow || (showFullList && pTrigger->pNext!=0));
32118
+ do{
32119
+ if( cnt++ && pTrigger->pNext==0 ){
32120
+ sqlite3TreeViewPop(&pView);
32121
+ sqlite3TreeViewPush(&pView, 0);
32122
+ }
32123
+ sqlite3TreeViewLine(pView, "TRIGGER %s", pTrigger->zName);
32124
+ sqlite3TreeViewPush(&pView, 0);
32125
+ sqlite3TreeViewTriggerStep(pView, pTrigger->step_list, 0, 1);
32126
+ sqlite3TreeViewPop(&pView);
32127
+ }while( showFullList && (pTrigger = pTrigger->pNext)!=0 );
32128
+ sqlite3TreeViewPop(&pView);
32129
+}
32130
+#endif /* SQLITE_OMIT_TRIGGER */
32131
+
32132
+
32133
+/*
32134
+** These simplified versions of the tree-view routines omit unnecessary
32135
+** parameters. These variants are intended to be used from a symbolic
32136
+** debugger, such as "gdb", during interactive debugging sessions.
32137
+**
32138
+** This routines are given external linkage so that they will always be
32139
+** accessible to the debugging, and to avoid warnings about unused
32140
+** functions. But these routines only exist in debugging builds, so they
32141
+** do not contaminate the interface.
32142
+*/
32143
+SQLITE_PRIVATE void sqlite3ShowExpr(const Expr *p){ sqlite3TreeViewExpr(0,p,0); }
32144
+SQLITE_PRIVATE void sqlite3ShowExprList(const ExprList *p){ sqlite3TreeViewExprList(0,p,0,0);}
32145
+SQLITE_PRIVATE void sqlite3ShowIdList(const IdList *p){ sqlite3TreeViewIdList(0,p,0,0); }
32146
+SQLITE_PRIVATE void sqlite3ShowSrcList(const SrcList *p){ sqlite3TreeViewSrcList(0,p); }
32147
+SQLITE_PRIVATE void sqlite3ShowSelect(const Select *p){ sqlite3TreeViewSelect(0,p,0); }
32148
+SQLITE_PRIVATE void sqlite3ShowWith(const With *p){ sqlite3TreeViewWith(0,p,0); }
32149
+SQLITE_PRIVATE void sqlite3ShowUpsert(const Upsert *p){ sqlite3TreeViewUpsert(0,p,0); }
32150
+#ifndef SQLITE_OMIT_TRIGGER
32151
+SQLITE_PRIVATE void sqlite3ShowTriggerStep(const TriggerStep *p){
32152
+ sqlite3TreeViewTriggerStep(0,p,0,0);
32153
+}
32154
+SQLITE_PRIVATE void sqlite3ShowTriggerStepList(const TriggerStep *p){
32155
+ sqlite3TreeViewTriggerStep(0,p,0,1);
32156
+}
32157
+SQLITE_PRIVATE void sqlite3ShowTrigger(const Trigger *p){ sqlite3TreeViewTrigger(0,p,0,0); }
32158
+SQLITE_PRIVATE void sqlite3ShowTriggerList(const Trigger *p){ sqlite3TreeViewTrigger(0,p,0,1);}
32159
+#endif
32160
+#ifndef SQLITE_OMIT_WINDOWFUNC
32161
+SQLITE_PRIVATE void sqlite3ShowWindow(const Window *p){ sqlite3TreeViewWindow(0,p,0); }
32162
+SQLITE_PRIVATE void sqlite3ShowWinFunc(const Window *p){ sqlite3TreeViewWinFunc(0,p,0); }
32163
+#endif
32164
+
3168132165
#endif /* SQLITE_DEBUG */
3168232166
3168332167
/************** End of treeview.c ********************************************/
3168432168
/************** Begin file random.c ******************************************/
3168532169
/*
@@ -34710,14 +35194,14 @@
3471035194
/* 66 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"),
3471135195
/* 67 */ "Return" OpHelp(""),
3471235196
/* 68 */ "EndCoroutine" OpHelp(""),
3471335197
/* 69 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
3471435198
/* 70 */ "Halt" OpHelp(""),
34715
- /* 71 */ "BeginSubrtn" OpHelp("r[P2]=P1"),
34716
- /* 72 */ "Integer" OpHelp("r[P2]=P1"),
34717
- /* 73 */ "Int64" OpHelp("r[P2]=P4"),
34718
- /* 74 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
35199
+ /* 71 */ "Integer" OpHelp("r[P2]=P1"),
35200
+ /* 72 */ "Int64" OpHelp("r[P2]=P4"),
35201
+ /* 73 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
35202
+ /* 74 */ "BeginSubrtn" OpHelp("r[P2]=NULL"),
3471935203
/* 75 */ "Null" OpHelp("r[P2..P3]=NULL"),
3472035204
/* 76 */ "SoftNull" OpHelp("r[P1]=NULL"),
3472135205
/* 77 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
3472235206
/* 78 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
3472335207
/* 79 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
@@ -34733,11 +35217,11 @@
3473335217
/* 89 */ "Permutation" OpHelp(""),
3473435218
/* 90 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
3473535219
/* 91 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"),
3473635220
/* 92 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"),
3473735221
/* 93 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"),
34738
- /* 94 */ "Column" OpHelp("r[P3]=PX"),
35222
+ /* 94 */ "Column" OpHelp("r[P3]=PX cursor P1 column P2"),
3473935223
/* 95 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"),
3474035224
/* 96 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
3474135225
/* 97 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
3474235226
/* 98 */ "Count" OpHelp("r[P2]=count()"),
3474335227
/* 99 */ "ReadCookie" OpHelp(""),
@@ -34774,11 +35258,11 @@
3477435258
/* 130 */ "Delete" OpHelp(""),
3477535259
/* 131 */ "ResetCount" OpHelp(""),
3477635260
/* 132 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
3477735261
/* 133 */ "SorterData" OpHelp("r[P2]=data"),
3477835262
/* 134 */ "RowData" OpHelp("r[P2]=data"),
34779
- /* 135 */ "Rowid" OpHelp("r[P2]=rowid"),
35263
+ /* 135 */ "Rowid" OpHelp("r[P2]=PX rowid of P1"),
3478035264
/* 136 */ "NullRow" OpHelp(""),
3478135265
/* 137 */ "SeekEnd" OpHelp(""),
3478235266
/* 138 */ "IdxInsert" OpHelp("key=r[P2]"),
3478335267
/* 139 */ "SorterInsert" OpHelp("key=r[P2]"),
3478435268
/* 140 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
@@ -67869,10 +68353,12 @@
6786968353
6787068354
/* Remove the slot from the free-list. Update the number of
6787168355
** fragmented bytes within the page. */
6787268356
memcpy(&aData[iAddr], &aData[pc], 2);
6787368357
aData[hdr+7] += (u8)x;
68358
+ testcase( pc+x>maxPC );
68359
+ return &aData[pc];
6787468360
}else if( x+pc > maxPC ){
6787568361
/* This slot extends off the end of the usable part of the page */
6787668362
*pRc = SQLITE_CORRUPT_PAGE(pPg);
6787768363
return 0;
6787868364
}else{
@@ -72179,11 +72665,11 @@
7217972665
idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2 */
7218072666
}
7218172667
assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) );
7218272668
assert( pPage->isInit );
7218372669
if( pPage->leaf ){
72184
- assert( pCur->ix<pCur->pPage->nCell );
72670
+ assert( pCur->ix<pCur->pPage->nCell || CORRUPT_DB );
7218572671
pCur->ix = (u16)idx;
7218672672
*pRes = c;
7218772673
rc = SQLITE_OK;
7218872674
goto moveto_index_finish;
7218972675
}
@@ -74703,11 +75189,11 @@
7470375189
}
7470475190
}
7470575191
iOvflSpace += sz;
7470675192
assert( sz<=pBt->maxLocal+23 );
7470775193
assert( iOvflSpace <= (int)pBt->pageSize );
74708
- for(k=0; b.ixNx[k]<=i && ALWAYS(k<NB*2); k++){}
75194
+ for(k=0; b.ixNx[k]<=j && ALWAYS(k<NB*2); k++){}
7470975195
pSrcEnd = b.apEnd[k];
7471075196
if( SQLITE_WITHIN(pSrcEnd, pCell, pCell+sz) ){
7471175197
rc = SQLITE_CORRUPT_BKPT;
7471275198
goto balance_cleanup;
7471375199
}
@@ -75526,11 +76012,15 @@
7552676012
const u8 *aIn; /* Pointer to next input buffer */
7552776013
u32 nIn; /* Size of input buffer aIn[] */
7552876014
u32 nRem; /* Bytes of data still to copy */
7552976015
7553076016
getCellInfo(pSrc);
75531
- aOut += putVarint32(aOut, pSrc->info.nPayload);
76017
+ if( pSrc->info.nPayload<0x80 ){
76018
+ *(aOut++) = pSrc->info.nPayload;
76019
+ }else{
76020
+ aOut += sqlite3PutVarint(aOut, pSrc->info.nPayload);
76021
+ }
7553276022
if( pDest->pKeyInfo==0 ) aOut += putVarint(aOut, iKey);
7553376023
nIn = pSrc->info.nLocal;
7553476024
aIn = pSrc->info.pPayload;
7553576025
if( aIn+nIn>pSrc->pPage->aDataEnd ){
7553676026
return SQLITE_CORRUPT_BKPT;
@@ -78539,13 +79029,14 @@
7853979029
SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
7854079030
sqlite3_context ctx;
7854179031
Mem t;
7854279032
assert( pFunc!=0 );
7854379033
assert( pMem!=0 );
79034
+ assert( pMem->db!=0 );
7854479035
assert( pFunc->xFinalize!=0 );
7854579036
assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef );
78546
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
79037
+ assert( sqlite3_mutex_held(pMem->db->mutex) );
7854779038
memset(&ctx, 0, sizeof(ctx));
7854879039
memset(&t, 0, sizeof(t));
7854979040
t.flags = MEM_Null;
7855079041
t.db = pMem->db;
7855179042
ctx.pOut = &t;
@@ -78571,11 +79062,12 @@
7857179062
SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem *pAccum, Mem *pOut, FuncDef *pFunc){
7857279063
sqlite3_context ctx;
7857379064
assert( pFunc!=0 );
7857479065
assert( pFunc->xValue!=0 );
7857579066
assert( (pAccum->flags & MEM_Null)!=0 || pFunc==pAccum->u.pDef );
78576
- assert( pAccum->db==0 || sqlite3_mutex_held(pAccum->db->mutex) );
79067
+ assert( pAccum->db!=0 );
79068
+ assert( sqlite3_mutex_held(pAccum->db->mutex) );
7857779069
memset(&ctx, 0, sizeof(ctx));
7857879070
sqlite3VdbeMemSetNull(pOut);
7857979071
ctx.pOut = pOut;
7858079072
ctx.pMem = pAccum;
7858179073
ctx.pFunc = pFunc;
@@ -80639,18 +81131,24 @@
8063981131
8064081132
/*
8064181133
** Mark the VDBE as one that can only be run one time.
8064281134
*/
8064381135
SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe *p){
80644
- p->runOnlyOnce = 1;
81136
+ sqlite3VdbeAddOp2(p, OP_Expire, 1, 1);
8064581137
}
8064681138
8064781139
/*
8064881140
** Mark the VDBE as one that can only be run multiple times.
8064981141
*/
8065081142
SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe *p){
80651
- p->runOnlyOnce = 0;
81143
+ int i;
81144
+ for(i=1; ALWAYS(i<p->nOp); i++){
81145
+ if( ALWAYS(p->aOp[i].opcode==OP_Expire) ){
81146
+ p->aOp[1].opcode = OP_Noop;
81147
+ break;
81148
+ }
81149
+ }
8065281150
}
8065381151
8065481152
#ifdef SQLITE_DEBUG /* sqlite3AssertMayAbort() logic */
8065581153
8065681154
/*
@@ -81276,11 +81774,11 @@
8127681774
int iFirst, /* Index of first register to be released */
8127781775
int N, /* Number of registers to release */
8127881776
u32 mask, /* Mask of registers to NOT release */
8127981777
int bUndefine /* If true, mark registers as undefined */
8128081778
){
81281
- if( N==0 ) return;
81779
+ if( N==0 || OptimizationDisabled(pParse->db, SQLITE_ReleaseReg) ) return;
8128281780
assert( pParse->pVdbe );
8128381781
assert( iFirst>=1 );
8128481782
assert( iFirst+N-1<=pParse->nMem );
8128581783
if( N<=31 && mask!=0 ){
8128681784
while( N>0 && (mask&1)!=0 ){
@@ -81535,12 +82033,17 @@
8153582033
if( c=='P' ){
8153682034
c = zSynopsis[++ii];
8153782035
if( c=='4' ){
8153882036
sqlite3_str_appendall(&x, zP4);
8153982037
}else if( c=='X' ){
81540
- sqlite3_str_appendall(&x, pOp->zComment);
82038
+ if( pOp->zComment && pOp->zComment[0] ){
82039
+ sqlite3_str_appendall(&x, pOp->zComment);
82040
+ }else{
82041
+ sqlite3_str_appendall(&x, zSynopsis+1);
82042
+ }
8154182043
seenCom = 1;
82044
+ break;
8154282045
}else{
8154382046
int v1 = translateP(c, pOp);
8154482047
int v2;
8154582048
if( strncmp(zSynopsis+ii+1, "@P", 2)==0 ){
8154682049
ii += 3;
@@ -82131,11 +82634,11 @@
8213182634
int i;
8213282635
Mem *aMem = VdbeFrameMem(p);
8213382636
VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem];
8213482637
assert( sqlite3VdbeFrameIsValid(p) );
8213582638
for(i=0; i<p->nChildCsr; i++){
82136
- sqlite3VdbeFreeCursor(p->v, apCsr[i]);
82639
+ if( apCsr[i] ) sqlite3VdbeFreeCursorNN(p->v, apCsr[i]);
8213782640
}
8213882641
releaseMemArray(aMem, p->nChildMem);
8213982642
sqlite3VdbeDeleteAuxData(p->v->db, &p->pAuxData, -1, 0);
8214082643
sqlite3DbFree(p->v->db, p);
8214182644
}
@@ -82325,15 +82828,15 @@
8232582828
** statement.
8232682829
*/
8232782830
static void *allocSpace(
8232882831
struct ReusableSpace *p, /* Bulk memory available for allocation */
8232982832
void *pBuf, /* Pointer to a prior allocation */
82330
- sqlite3_int64 nByte /* Bytes of memory needed */
82833
+ sqlite3_int64 nByte /* Bytes of memory needed. */
8233182834
){
8233282835
assert( EIGHT_BYTE_ALIGNMENT(p->pSpace) );
8233382836
if( pBuf==0 ){
82334
- nByte = ROUND8(nByte);
82837
+ nByte = ROUND8P(nByte);
8233582838
if( nByte <= p->nFree ){
8233682839
p->nFree -= nByte;
8233782840
pBuf = &p->pSpace[p->nFree];
8233882841
}else{
8233982842
p->nNeeded += nByte;
@@ -82437,11 +82940,11 @@
8243782940
8243882941
/* Figure out how much reusable memory is available at the end of the
8243982942
** opcode array. This extra memory will be reallocated for other elements
8244082943
** of the prepared statement.
8244182944
*/
82442
- n = ROUND8(sizeof(Op)*p->nOp); /* Bytes of opcode memory used */
82945
+ n = ROUND8P(sizeof(Op)*p->nOp); /* Bytes of opcode memory used */
8244382946
x.pSpace = &((u8*)p->aOp)[n]; /* Unused opcode memory */
8244482947
assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) );
8244582948
x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes of unused memory */
8244682949
assert( x.nFree>=0 );
8244782950
assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) );
@@ -82525,13 +83028,13 @@
8252583028
/*
8252683029
** Close a VDBE cursor and release all the resources that cursor
8252783030
** happens to hold.
8252883031
*/
8252983032
SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
82530
- if( pCx==0 ){
82531
- return;
82532
- }
83033
+ if( pCx ) sqlite3VdbeFreeCursorNN(p,pCx);
83034
+}
83035
+SQLITE_PRIVATE void sqlite3VdbeFreeCursorNN(Vdbe *p, VdbeCursor *pCx){
8253383036
switch( pCx->eCurType ){
8253483037
case CURTYPE_SORTER: {
8253583038
sqlite3VdbeSorterClose(p->db, pCx);
8253683039
break;
8253783040
}
@@ -82559,11 +83062,11 @@
8255983062
static void closeCursorsInFrame(Vdbe *p){
8256083063
int i;
8256183064
for(i=0; i<p->nCursor; i++){
8256283065
VdbeCursor *pC = p->apCsr[i];
8256383066
if( pC ){
82564
- sqlite3VdbeFreeCursor(p, pC);
83067
+ sqlite3VdbeFreeCursorNN(p, pC);
8256583068
p->apCsr[i] = 0;
8256683069
}
8256783070
}
8256883071
}
8256983072
@@ -83089,13 +83592,11 @@
8308983592
** Then the internal cache might have been left in an inconsistent
8309083593
** state. We need to rollback the statement transaction, if there is
8309183594
** one, or the complete transaction if there is no statement transaction.
8309283595
*/
8309383596
83094
- if( p->eVdbeState!=VDBE_RUN_STATE ){
83095
- return SQLITE_OK;
83096
- }
83597
+ assert( p->eVdbeState==VDBE_RUN_STATE );
8309783598
if( db->mallocFailed ){
8309883599
p->rc = SQLITE_NOMEM_BKPT;
8309983600
}
8310083601
closeAllCursors(p);
8310183602
checkActiveVdbeCnt(db);
@@ -83351,11 +83852,11 @@
8335183852
8335283853
/* If the VM did not run to completion or if it encountered an
8335383854
** error, then it might not have been halted properly. So halt
8335483855
** it now.
8335583856
*/
83356
- sqlite3VdbeHalt(p);
83857
+ if( p->eVdbeState==VDBE_RUN_STATE ) sqlite3VdbeHalt(p);
8335783858
8335883859
/* If the VDBE has been run even partially, then transfer the error code
8335983860
** and error message from the VDBE into the main database structure. But
8336083861
** if the VDBE has just been set to run but has not actually executed any
8336183862
** instructions yet, leave the main database error information unchanged.
@@ -83365,11 +83866,10 @@
8336583866
if( db->pErr || p->zErrMsg ){
8336683867
sqlite3VdbeTransferError(p);
8336783868
}else{
8336883869
db->errCode = p->rc;
8336983870
}
83370
- if( p->runOnlyOnce ) p->expired = 1;
8337183871
}
8337283872
8337383873
/* Reset register contents and reclaim error message memory.
8337483874
*/
8337583875
#ifdef SQLITE_DEBUG
@@ -83486,11 +83986,11 @@
8348683986
**
8348783987
** The difference between this function and sqlite3VdbeDelete() is that
8348883988
** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with
8348983989
** the database connection and frees the object itself.
8349083990
*/
83491
-SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
83991
+static void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
8349283992
SubProgram *pSub, *pNext;
8349383993
assert( p->db==0 || p->db==db );
8349483994
if( p->aColName ){
8349583995
releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
8349683996
sqlite3DbFreeNN(db, p->aColName);
@@ -83536,18 +84036,20 @@
8353684036
8353784037
assert( p!=0 );
8353884038
db = p->db;
8353984039
assert( sqlite3_mutex_held(db->mutex) );
8354084040
sqlite3VdbeClearObject(db, p);
83541
- if( p->pPrev ){
83542
- p->pPrev->pNext = p->pNext;
83543
- }else{
83544
- assert( db->pVdbe==p );
83545
- db->pVdbe = p->pNext;
83546
- }
83547
- if( p->pNext ){
83548
- p->pNext->pPrev = p->pPrev;
84041
+ if( db->pnBytesFreed==0 ){
84042
+ if( p->pPrev ){
84043
+ p->pPrev->pNext = p->pNext;
84044
+ }else{
84045
+ assert( db->pVdbe==p );
84046
+ db->pVdbe = p->pNext;
84047
+ }
84048
+ if( p->pNext ){
84049
+ p->pNext->pPrev = p->pPrev;
84050
+ }
8354984051
}
8355084052
sqlite3DbFreeNN(db, p);
8355184053
}
8355284054
8355384055
/*
@@ -83595,11 +84097,11 @@
8359584097
/*
8359684098
** Check to ensure that the cursor is valid. Restore the cursor
8359784099
** if need be. Return any I/O error from the restore operation.
8359884100
*/
8359984101
SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){
83600
- assert( p->eCurType==CURTYPE_BTREE );
84102
+ assert( p->eCurType==CURTYPE_BTREE || IsNullCursor(p) );
8360184103
if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
8360284104
return sqlite3VdbeHandleMovedCursor(p);
8360384105
}
8360484106
return SQLITE_OK;
8360584107
}
@@ -83608,11 +84110,11 @@
8360884110
** The following functions:
8360984111
**
8361084112
** sqlite3VdbeSerialType()
8361184113
** sqlite3VdbeSerialTypeLen()
8361284114
** sqlite3VdbeSerialLen()
83613
-** sqlite3VdbeSerialPut()
84115
+** sqlite3VdbeSerialPut() <--- in-lined into OP_MakeRecord as of 2022-04-02
8361484116
** sqlite3VdbeSerialGet()
8361584117
**
8361684118
** encapsulate the code that serializes values for storage in SQLite
8361784119
** data and index records. Each serialized value consists of a
8361884120
** 'serial-type' and a blob of data. The serial type is an 8-byte unsigned
@@ -83720,11 +84222,11 @@
8372084222
#endif /* inlined into OP_MakeRecord */
8372184223
8372284224
/*
8372384225
** The sizes for serial types less than 128
8372484226
*/
83725
-static const u8 sqlite3SmallTypeSizes[] = {
84227
+SQLITE_PRIVATE const u8 sqlite3SmallTypeSizes[128] = {
8372684228
/* 0 1 2 3 4 5 6 7 8 9 */
8372784229
/* 0 */ 0, 1, 2, 3, 4, 6, 8, 8, 0, 0,
8372884230
/* 10 */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
8372984231
/* 20 */ 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
8373084232
/* 30 */ 9, 9, 10, 10, 11, 11, 12, 12, 13, 13,
@@ -83789,11 +84291,11 @@
8378984291
** works for him. We, the developers, have no way to independently
8379084292
** verify this, but Frank seems to know what he is talking about
8379184293
** so we trust him.
8379284294
*/
8379384295
#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
83794
-static u64 floatSwap(u64 in){
84296
+SQLITE_PRIVATE u64 sqlite3FloatSwap(u64 in){
8379584297
union {
8379684298
u64 r;
8379784299
u32 i[2];
8379884300
} u;
8379984301
u32 t;
@@ -83802,63 +84304,12 @@
8380284304
t = u.i[0];
8380384305
u.i[0] = u.i[1];
8380484306
u.i[1] = t;
8380584307
return u.r;
8380684308
}
83807
-# define swapMixedEndianFloat(X) X = floatSwap(X)
83808
-#else
83809
-# define swapMixedEndianFloat(X)
83810
-#endif
83811
-
83812
-/*
83813
-** Write the serialized data blob for the value stored in pMem into
83814
-** buf. It is assumed that the caller has allocated sufficient space.
83815
-** Return the number of bytes written.
83816
-**
83817
-** nBuf is the amount of space left in buf[]. The caller is responsible
83818
-** for allocating enough space to buf[] to hold the entire field, exclusive
83819
-** of the pMem->u.nZero bytes for a MEM_Zero value.
83820
-**
83821
-** Return the number of bytes actually written into buf[]. The number
83822
-** of bytes in the zero-filled tail is included in the return value only
83823
-** if those bytes were zeroed in buf[].
83824
-*/
83825
-SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){
83826
- u32 len;
83827
-
83828
- /* Integer and Real */
83829
- if( serial_type<=7 && serial_type>0 ){
83830
- u64 v;
83831
- u32 i;
83832
- if( serial_type==7 ){
83833
- assert( sizeof(v)==sizeof(pMem->u.r) );
83834
- memcpy(&v, &pMem->u.r, sizeof(v));
83835
- swapMixedEndianFloat(v);
83836
- }else{
83837
- v = pMem->u.i;
83838
- }
83839
- len = i = sqlite3SmallTypeSizes[serial_type];
83840
- assert( i>0 );
83841
- do{
83842
- buf[--i] = (u8)(v&0xFF);
83843
- v >>= 8;
83844
- }while( i );
83845
- return len;
83846
- }
83847
-
83848
- /* String or blob */
83849
- if( serial_type>=12 ){
83850
- assert( pMem->n + ((pMem->flags & MEM_Zero)?pMem->u.nZero:0)
83851
- == (int)sqlite3VdbeSerialTypeLen(serial_type) );
83852
- len = pMem->n;
83853
- if( len>0 ) memcpy(buf, pMem->z, len);
83854
- return len;
83855
- }
83856
-
83857
- /* NULL or constants 0 or 1 */
83858
- return 0;
83859
-}
84309
+#endif /* SQLITE_MIXED_ENDIAN_64BIT_FLOAT */
84310
+
8386084311
8386184312
/* Input "x" is a sequence of unsigned characters that represent a
8386284313
** big-endian integer. Return the equivalent native integer
8386384314
*/
8386484315
#define ONE_BYTE_INT(x) ((i8)(x)[0])
@@ -84020,14 +84471,14 @@
8402084471
SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(
8402184472
KeyInfo *pKeyInfo /* Description of the record */
8402284473
){
8402384474
UnpackedRecord *p; /* Unpacked record to return */
8402484475
int nByte; /* Number of bytes required for *p */
84025
- nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1);
84476
+ nByte = ROUND8P(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1);
8402684477
p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte);
8402784478
if( !p ) return 0;
84028
- p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))];
84479
+ p->aMem = (Mem*)&((char*)p)[ROUND8P(sizeof(UnpackedRecord))];
8402984480
assert( pKeyInfo->aSortFlags!=0 );
8403084481
p->pKeyInfo = pKeyInfo;
8403184482
p->nField = pKeyInfo->nKeyField + 1;
8403284483
return p;
8403384484
}
@@ -84521,18 +84972,26 @@
8452184972
8452284973
/* If bSkip is true, then the caller has already determined that the first
8452384974
** two elements in the keys are equal. Fix the various stack variables so
8452484975
** that this routine begins comparing at the second field. */
8452584976
if( bSkip ){
84526
- u32 s1;
84527
- idx1 = 1 + getVarint32(&aKey1[1], s1);
84977
+ u32 s1 = aKey1[1];
84978
+ if( s1<0x80 ){
84979
+ idx1 = 2;
84980
+ }else{
84981
+ idx1 = 1 + sqlite3GetVarint32(&aKey1[1], &s1);
84982
+ }
8452884983
szHdr1 = aKey1[0];
8452984984
d1 = szHdr1 + sqlite3VdbeSerialTypeLen(s1);
8453084985
i = 1;
8453184986
pRhs++;
8453284987
}else{
84533
- idx1 = getVarint32(aKey1, szHdr1);
84988
+ if( (szHdr1 = aKey1[0])<0x80 ){
84989
+ idx1 = 1;
84990
+ }else{
84991
+ idx1 = sqlite3GetVarint32(aKey1, &szHdr1);
84992
+ }
8453484993
d1 = szHdr1;
8453584994
i = 0;
8453684995
}
8453784996
if( d1>(unsigned)nKey1 ){
8453884997
pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
@@ -85932,18 +86391,12 @@
8593286391
*/
8593386392
static int sqlite3Step(Vdbe *p){
8593486393
sqlite3 *db;
8593586394
int rc;
8593686395
85937
- /* Check that malloc() has not failed. If it has, return early. */
85938
- db = p->db;
85939
- if( db->mallocFailed ){
85940
- p->rc = SQLITE_NOMEM;
85941
- return SQLITE_NOMEM_BKPT;
85942
- }
85943
-
8594486396
assert(p);
86397
+ db = p->db;
8594586398
if( p->eVdbeState!=VDBE_RUN_STATE ){
8594686399
restart_step:
8594786400
if( p->eVdbeState==VDBE_READY_STATE ){
8594886401
if( p->expired ){
8594986402
p->rc = SQLITE_SCHEMA;
@@ -86087,11 +86540,10 @@
8608786540
if( vdbeSafetyNotNull(v) ){
8608886541
return SQLITE_MISUSE_BKPT;
8608986542
}
8609086543
db = v->db;
8609186544
sqlite3_mutex_enter(db->mutex);
86092
- v->doingRerun = 0;
8609386545
while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
8609486546
&& cnt++ < SQLITE_MAX_SCHEMA_RETRY ){
8609586547
int savedPc = v->pc;
8609686548
rc = sqlite3Reprepare(v);
8609786549
if( rc!=SQLITE_OK ){
@@ -86113,11 +86565,17 @@
8611386565
v->rc = rc = SQLITE_NOMEM_BKPT;
8611486566
}
8611586567
break;
8611686568
}
8611786569
sqlite3_reset(pStmt);
86118
- if( savedPc>=0 ) v->doingRerun = 1;
86570
+ if( savedPc>=0 ){
86571
+ /* Setting minWriteFileFormat to 254 is a signal to the OP_Init and
86572
+ ** OP_Trace opcodes to *not* perform SQLITE_TRACE_STMT because one
86573
+ ** should output has already occurred due to SQLITE_SCHEMA.
86574
+ ** tag-20220401a */
86575
+ v->minWriteFileFormat = 254;
86576
+ }
8611986577
assert( v->expired==0 );
8612086578
}
8612186579
sqlite3_mutex_leave(db->mutex);
8612286580
return rc;
8612386581
}
@@ -87126,12 +87584,11 @@
8712687584
if( op==SQLITE_STMTSTATUS_MEMUSED ){
8712787585
sqlite3 *db = pVdbe->db;
8712887586
sqlite3_mutex_enter(db->mutex);
8712987587
v = 0;
8713087588
db->pnBytesFreed = (int*)&v;
87131
- sqlite3VdbeClearObject(db, pVdbe);
87132
- sqlite3DbFree(db, pVdbe);
87589
+ sqlite3VdbeDelete(pVdbe);
8713387590
db->pnBytesFreed = 0;
8713487591
sqlite3_mutex_leave(db->mutex);
8713587592
}else{
8713687593
v = pVdbe->aCounter[op];
8713787594
if( resetFlag ) pVdbe->aCounter[op] = 0;
@@ -87920,16 +88377,16 @@
8792088377
Mem *pMem = iCur>0 ? &p->aMem[p->nMem-iCur] : p->aMem;
8792188378
8792288379
int nByte;
8792388380
VdbeCursor *pCx = 0;
8792488381
nByte =
87925
- ROUND8(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField +
88382
+ ROUND8P(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField +
8792688383
(eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0);
8792788384
8792888385
assert( iCur>=0 && iCur<p->nCursor );
8792988386
if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/
87930
- sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
88387
+ sqlite3VdbeFreeCursorNN(p, p->apCsr[iCur]);
8793188388
p->apCsr[iCur] = 0;
8793288389
}
8793388390
8793488391
/* There used to be a call to sqlite3VdbeMemClearAndResize() to make sure
8793588392
** the pMem used to hold space for the cursor has enough storage available
@@ -87955,11 +88412,11 @@
8795588412
pCx->eCurType = eCurType;
8795688413
pCx->nField = nField;
8795788414
pCx->aOffset = &pCx->aType[nField];
8795888415
if( eCurType==CURTYPE_BTREE ){
8795988416
pCx->uc.pCursor = (BtCursor*)
87960
- &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField];
88417
+ &pMem->z[ROUND8P(sizeof(VdbeCursor))+2*sizeof(u32)*nField];
8796188418
sqlite3BtreeCursorZero(pCx->uc.pCursor);
8796288419
}
8796388420
return pCx;
8796488421
}
8796588422
@@ -88637,32 +89094,43 @@
8863789094
assert( VdbeMemDynamic(pIn1)==0 );
8863889095
memAboutToChange(p, pIn1);
8863989096
pIn1->flags = MEM_Int;
8864089097
pIn1->u.i = (int)(pOp-aOp);
8864189098
REGISTER_TRACE(pOp->p1, pIn1);
88642
-
88643
- /* Most jump operations do a goto to this spot in order to update
88644
- ** the pOp pointer. */
88645
-jump_to_p2:
88646
- pOp = &aOp[pOp->p2 - 1];
88647
- break;
88648
-}
88649
-
88650
-/* Opcode: Return P1 * P3 * *
88651
-**
88652
-** Jump to the next instruction after the address in register P1. After
88653
-** the jump, register P1 becomes undefined.
88654
-**
88655
-** P3 is not used by the byte-code engine. However, the code generator
88656
-** sets P3 to address of the associated OP_BeginSubrtn opcode, if there is
88657
-** one.
89099
+ goto jump_to_p2_and_check_for_interrupt;
89100
+}
89101
+
89102
+/* Opcode: Return P1 P2 P3 * *
89103
+**
89104
+** Jump to the address stored in register P1. If P1 is a return address
89105
+** register, then this accomplishes a return from a subroutine.
89106
+**
89107
+** If P3 is 1, then the jump is only taken if register P1 holds an integer
89108
+** values, otherwise execution falls through to the next opcode, and the
89109
+** OP_Return becomes a no-op. If P3 is 0, then register P1 must hold an
89110
+** integer or else an assert() is raised. P3 should be set to 1 when
89111
+** this opcode is used in combination with OP_BeginSubrtn, and set to 0
89112
+** otherwise.
89113
+**
89114
+** The value in register P1 is unchanged by this opcode.
89115
+**
89116
+** P2 is not used by the byte-code engine. However, if P2 is positive
89117
+** and also less than the current address, then the "EXPLAIN" output
89118
+** formatter in the CLI will indent all opcodes from the P2 opcode up
89119
+** to be not including the current Return. P2 should be the first opcode
89120
+** in the subroutine from which this opcode is returnning. Thus the P2
89121
+** value is a byte-code indentation hint. See tag-20220407a in
89122
+** wherecode.c and shell.c.
8865889123
*/
8865989124
case OP_Return: { /* in1 */
8866089125
pIn1 = &aMem[pOp->p1];
88661
- assert( pIn1->flags==MEM_Int );
88662
- pOp = &aOp[pIn1->u.i];
88663
- pIn1->flags = MEM_Undefined;
89126
+ if( pIn1->flags & MEM_Int ){
89127
+ if( pOp->p3 ){ VdbeBranchTaken(1, 2); }
89128
+ pOp = &aOp[pIn1->u.i];
89129
+ }else if( ALWAYS(pOp->p3) ){
89130
+ VdbeBranchTaken(0, 2);
89131
+ }
8866489132
break;
8866589133
}
8866689134
8866789135
/* Opcode: InitCoroutine P1 P2 P3 * *
8866889136
**
@@ -88681,11 +89149,16 @@
8868189149
assert( pOp->p3>=0 && pOp->p3<p->nOp );
8868289150
pOut = &aMem[pOp->p1];
8868389151
assert( !VdbeMemDynamic(pOut) );
8868489152
pOut->u.i = pOp->p3 - 1;
8868589153
pOut->flags = MEM_Int;
88686
- if( pOp->p2 ) goto jump_to_p2;
89154
+ if( pOp->p2==0 ) break;
89155
+
89156
+ /* Most jump operations do a goto to this spot in order to update
89157
+ ** the pOp pointer. */
89158
+jump_to_p2:
89159
+ pOp = &aOp[pOp->p2 - 1];
8868789160
break;
8868889161
}
8868989162
8869089163
/* Opcode: EndCoroutine P1 * * * *
8869189164
**
@@ -88783,15 +89256,14 @@
8878389256
*/
8878489257
case OP_Halt: {
8878589258
VdbeFrame *pFrame;
8878689259
int pcx;
8878789260
88788
- pcx = (int)(pOp - aOp);
8878989261
#ifdef SQLITE_DEBUG
8879089262
if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); }
8879189263
#endif
88792
- if( pOp->p1==SQLITE_OK && p->pFrame ){
89264
+ if( p->pFrame && pOp->p1==SQLITE_OK ){
8879389265
/* Halt the sub-program. Return control to the parent frame. */
8879489266
pFrame = p->pFrame;
8879589267
p->pFrame = pFrame->pParent;
8879689268
p->nFrame--;
8879789269
sqlite3VdbeSetChanges(db, p->nChange);
@@ -88809,11 +89281,10 @@
8880989281
pOp = &aOp[pcx];
8881089282
break;
8881189283
}
8881289284
p->rc = pOp->p1;
8881389285
p->errorAction = (u8)pOp->p2;
88814
- p->pc = pcx;
8881589286
assert( pOp->p5<=4 );
8881689287
if( p->rc ){
8881789288
if( pOp->p5 ){
8881889289
static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK",
8881989290
"FOREIGN KEY" };
@@ -88826,10 +89297,11 @@
8882689297
p->zErrMsg = sqlite3MPrintf(db, "%z: %s", p->zErrMsg, pOp->p4.z);
8882789298
}
8882889299
}else{
8882989300
sqlite3VdbeError(p, "%s", pOp->p4.z);
8883089301
}
89302
+ pcx = (int)(pOp - aOp);
8883189303
sqlite3_log(pOp->p1, "abort at %d in [%s]: %s", pcx, p->zSql, p->zErrMsg);
8883289304
}
8883389305
rc = sqlite3VdbeHalt(p);
8883489306
assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
8883589307
if( rc==SQLITE_BUSY ){
@@ -88840,26 +89312,15 @@
8884089312
rc = p->rc ? SQLITE_ERROR : SQLITE_DONE;
8884189313
}
8884289314
goto vdbe_return;
8884389315
}
8884489316
88845
-/* Opcode: BeginSubrtn P1 P2 * * *
88846
-** Synopsis: r[P2]=P1
88847
-**
88848
-** Mark the beginning of a subroutine by loading the integer value P1
88849
-** into register r[P2]. The P2 register is used to store the return
88850
-** address of the subroutine call.
88851
-**
88852
-** This opcode is identical to OP_Integer. It has a different name
88853
-** only to make the byte code easier to read and verify.
88854
-*/
8885589317
/* Opcode: Integer P1 P2 * * *
8885689318
** Synopsis: r[P2]=P1
8885789319
**
8885889320
** The 32-bit integer value P1 is written into register P2.
8885989321
*/
88860
-case OP_BeginSubrtn:
8886189322
case OP_Integer: { /* out2 */
8886289323
pOut = out2Prerelease(p, pOp);
8886389324
pOut->u.i = pOp->p1;
8886489325
break;
8886589326
}
@@ -88962,10 +89423,32 @@
8896289423
}
8896389424
#endif
8896489425
break;
8896589426
}
8896689427
89428
+/* Opcode: BeginSubrtn * P2 * * *
89429
+** Synopsis: r[P2]=NULL
89430
+**
89431
+** Mark the beginning of a subroutine that can be entered in-line
89432
+** or that can be called using OP_Gosub. The subroutine should
89433
+** be terminated by an OP_Return instruction that has a P1 operand that
89434
+** is the same as the P2 operand to this opcode and that has P3 set to 1.
89435
+** If the subroutine is entered in-line, then the OP_Return will simply
89436
+** fall through. But if the subroutine is entered using OP_Gosub, then
89437
+** the OP_Return will jump back to the first instruction after the OP_Gosub.
89438
+**
89439
+** This routine works by loading a NULL into the P2 register. When the
89440
+** return address register contains a NULL, the OP_Return instruction is
89441
+** a no-op that simply falls through to the next instruction (assuming that
89442
+** the OP_Return opcode has a P3 value of 1). Thus if the subroutine is
89443
+** entered in-line, then the OP_Return will cause in-line execution to
89444
+** continue. But if the subroutine is entered via OP_Gosub, then the
89445
+** OP_Return will cause a return to the address following the OP_Gosub.
89446
+**
89447
+** This opcode is identical to OP_Null. It has a different name
89448
+** only to make the byte code easier to read and verify.
89449
+*/
8896789450
/* Opcode: Null P1 P2 P3 * *
8896889451
** Synopsis: r[P2..P3]=NULL
8896989452
**
8897089453
** Write a NULL into registers P2. If P3 greater than P2, then also write
8897189454
** NULL into register P3 and every register in between P2 and P3. If P3
@@ -88974,10 +89457,11 @@
8897489457
**
8897589458
** If the P1 value is non-zero, then also set the MEM_Cleared flag so that
8897689459
** NULL values will not compare equal even if SQLITE_NULLEQ is set on
8897789460
** OP_Ne or OP_Eq.
8897889461
*/
89462
+case OP_BeginSubrtn:
8897989463
case OP_Null: { /* out2 */
8898089464
int cnt;
8898189465
u16 nullFlag;
8898289466
pOut = out2Prerelease(p, pOp);
8898389467
cnt = pOp->p3-pOp->p2;
@@ -89203,49 +89687,36 @@
8920389687
** with an SQLITE_ROW return code and it sets up the sqlite3_stmt
8920489688
** structure to provide access to the r(P1)..r(P1+P2-1) values as
8920589689
** the result row.
8920689690
*/
8920789691
case OP_ResultRow: {
89208
- Mem *pMem;
89209
- int i;
8921089692
assert( p->nResColumn==pOp->p2 );
8921189693
assert( pOp->p1>0 || CORRUPT_DB );
8921289694
assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 );
8921389695
89214
- /* Invalidate all ephemeral cursor row caches */
8921589696
p->cacheCtr = (p->cacheCtr + 2)|1;
89216
-
89217
- /* Make sure the results of the current row are \000 terminated
89218
- ** and have an assigned type. The results are de-ephemeralized as
89219
- ** a side effect.
89220
- */
89221
- pMem = p->pResultSet = &aMem[pOp->p1];
89222
- for(i=0; i<pOp->p2; i++){
89223
- assert( memIsValid(&pMem[i]) );
89224
- Deephemeralize(&pMem[i]);
89225
- assert( (pMem[i].flags & MEM_Ephem)==0
89226
- || (pMem[i].flags & (MEM_Str|MEM_Blob))==0 );
89227
- sqlite3VdbeMemNulTerminate(&pMem[i]);
89228
- REGISTER_TRACE(pOp->p1+i, &pMem[i]);
89697
+ p->pResultSet = &aMem[pOp->p1];
8922989698
#ifdef SQLITE_DEBUG
89230
- /* The registers in the result will not be used again when the
89231
- ** prepared statement restarts. This is because sqlite3_column()
89232
- ** APIs might have caused type conversions of made other changes to
89233
- ** the register values. Therefore, we can go ahead and break any
89234
- ** OP_SCopy dependencies. */
89235
- pMem[i].pScopyFrom = 0;
89699
+ {
89700
+ Mem *pMem = p->pResultSet;
89701
+ int i;
89702
+ for(i=0; i<pOp->p2; i++){
89703
+ assert( memIsValid(&pMem[i]) );
89704
+ REGISTER_TRACE(pOp->p1+i, &pMem[i]);
89705
+ /* The registers in the result will not be used again when the
89706
+ ** prepared statement restarts. This is because sqlite3_column()
89707
+ ** APIs might have caused type conversions of made other changes to
89708
+ ** the register values. Therefore, we can go ahead and break any
89709
+ ** OP_SCopy dependencies. */
89710
+ pMem[i].pScopyFrom = 0;
89711
+ }
89712
+ }
8923689713
#endif
89237
- }
8923889714
if( db->mallocFailed ) goto no_mem;
89239
-
8924089715
if( db->mTrace & SQLITE_TRACE_ROW ){
8924189716
db->trace.xV2(SQLITE_TRACE_ROW, db->pTraceArg, p, 0);
8924289717
}
89243
-
89244
-
89245
- /* Return SQLITE_ROW
89246
- */
8924789718
p->pc = (int)(pOp - aOp) + 1;
8924889719
rc = SQLITE_ROW;
8924989720
goto vdbe_return;
8925089721
}
8925189722
@@ -89755,27 +90226,27 @@
8975590226
flags3 = pIn3->flags;
8975690227
if( (flags1 & flags3 & MEM_Int)!=0 ){
8975790228
assert( (pOp->p5 & SQLITE_AFF_MASK)!=SQLITE_AFF_TEXT || CORRUPT_DB );
8975890229
/* Common case of comparison of two integers */
8975990230
if( pIn3->u.i > pIn1->u.i ){
89760
- iCompare = +1;
8976190231
if( sqlite3aGTb[pOp->opcode] ){
8976290232
VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3);
8976390233
goto jump_to_p2;
8976490234
}
90235
+ iCompare = +1;
8976590236
}else if( pIn3->u.i < pIn1->u.i ){
89766
- iCompare = -1;
8976790237
if( sqlite3aLTb[pOp->opcode] ){
8976890238
VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3);
8976990239
goto jump_to_p2;
8977090240
}
90241
+ iCompare = -1;
8977190242
}else{
89772
- iCompare = 0;
8977390243
if( sqlite3aEQb[pOp->opcode] ){
8977490244
VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3);
8977590245
goto jump_to_p2;
8977690246
}
90247
+ iCompare = 0;
8977790248
}
8977890249
VdbeBranchTaken(0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
8977990250
break;
8978090251
}
8978190252
if( (flags1 | flags3)&MEM_Null ){
@@ -89798,15 +90269,15 @@
8979890269
}else{
8979990270
/* SQLITE_NULLEQ is clear and at least one operand is NULL,
8980090271
** then the result is always NULL.
8980190272
** The jump is taken if the SQLITE_JUMPIFNULL bit is set.
8980290273
*/
89803
- iCompare = 1; /* Operands are not equal */
8980490274
VdbeBranchTaken(2,3);
8980590275
if( pOp->p5 & SQLITE_JUMPIFNULL ){
8980690276
goto jump_to_p2;
8980790277
}
90278
+ iCompare = 1; /* Operands are not equal */
8980890279
break;
8980990280
}
8981090281
}else{
8981190282
/* Neither operand is NULL and we couldn't do the special high-speed
8981290283
** integer comparison case. So do a general-case comparison. */
@@ -89908,13 +90379,12 @@
8990890379
/* Opcode: Permutation * * * P4 *
8990990380
**
8991090381
** Set the permutation used by the OP_Compare operator in the next
8991190382
** instruction. The permutation is stored in the P4 operand.
8991290383
**
89913
-** The permutation is only valid until the next OP_Compare that has
89914
-** the OPFLAG_PERMUTE bit set in P5. Typically the OP_Permutation should
89915
-** occur immediately prior to the OP_Compare.
90384
+** The permutation is only valid for the next opcode which must be
90385
+** an OP_Compare that has the OPFLAG_PERMUTE bit set in P5.
8991690386
**
8991790387
** The first integer in the P4 integer array is the length of the array
8991890388
** and does not become part of the permutation.
8991990389
*/
8992090390
case OP_Permutation: {
@@ -89942,10 +90412,12 @@
8994290412
** only. The KeyInfo elements are used sequentially.
8994390413
**
8994490414
** The comparison is a sort comparison, so NULLs compare equal,
8994590415
** NULLs are less than numbers, numbers are less than strings,
8994690416
** and strings are less than blobs.
90417
+**
90418
+** This opcode must be immediately followed by an OP_Jump opcode.
8994790419
*/
8994890420
case OP_Compare: {
8994990421
int n;
8995090422
int i;
8995190423
int p1;
@@ -90000,20 +90472,24 @@
9000090472
}
9000190473
if( bRev ) iCompare = -iCompare;
9000290474
break;
9000390475
}
9000490476
}
90477
+ assert( pOp[1].opcode==OP_Jump );
9000590478
break;
9000690479
}
9000790480
9000890481
/* Opcode: Jump P1 P2 P3 * *
9000990482
**
9001090483
** Jump to the instruction at address P1, P2, or P3 depending on whether
9001190484
** in the most recent OP_Compare instruction the P1 vector was less than
9001290485
** equal to, or greater than the P2 vector, respectively.
90486
+**
90487
+** This opcode must immediately follow an OP_Compare opcode.
9001390488
*/
9001490489
case OP_Jump: { /* jump */
90490
+ assert( pOp>aOp && pOp[-1].opcode==OP_Compare );
9001590491
if( iCompare<0 ){
9001690492
VdbeBranchTaken(0,4); pOp = &aOp[pOp->p1 - 1];
9001790493
}else if( iCompare==0 ){
9001890494
VdbeBranchTaken(1,4); pOp = &aOp[pOp->p2 - 1];
9001990495
}else{
@@ -90314,11 +90790,11 @@
9031490790
break;
9031590791
}
9031690792
#endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */
9031790793
9031890794
/* Opcode: Column P1 P2 P3 P4 P5
90319
-** Synopsis: r[P3]=PX
90795
+** Synopsis: r[P3]=PX cursor P1 column P2
9032090796
**
9032190797
** Interpret the data that cursor P1 points to as a structure built using
9032290798
** the MakeRecord instruction. (See the MakeRecord opcode for additional
9032390799
** information about the format of the data.) Extract the P2-th column
9032490800
** from this record. If there are less that (P2+1)
@@ -90356,23 +90832,23 @@
9035690832
pC = p->apCsr[pOp->p1];
9035790833
p2 = (u32)pOp->p2;
9035890834
9035990835
op_column_restart:
9036090836
assert( pC!=0 );
90361
- assert( p2<(u32)pC->nField );
90837
+ assert( p2<(u32)pC->nField
90838
+ || (pC->eCurType==CURTYPE_PSEUDO && pC->seekResult==0) );
9036290839
aOffset = pC->aOffset;
9036390840
assert( aOffset==pC->aType+pC->nField );
9036490841
assert( pC->eCurType!=CURTYPE_VTAB );
9036590842
assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow );
9036690843
assert( pC->eCurType!=CURTYPE_SORTER );
9036790844
9036890845
if( pC->cacheStatus!=p->cacheCtr ){ /*OPTIMIZATION-IF-FALSE*/
9036990846
if( pC->nullRow ){
90370
- if( pC->eCurType==CURTYPE_PSEUDO ){
90847
+ if( pC->eCurType==CURTYPE_PSEUDO && pC->seekResult>0 ){
9037190848
/* For the special case of as pseudo-cursor, the seekResult field
9037290849
** identifies the register that holds the record */
90373
- assert( pC->seekResult>0 );
9037490850
pReg = &aMem[pC->seekResult];
9037590851
assert( pReg->flags & MEM_Blob );
9037690852
assert( memIsValid(pReg) );
9037790853
pC->payloadSize = pC->szRow = pReg->n;
9037890854
pC->aRow = (u8*)pReg->z;
@@ -90406,11 +90882,15 @@
9040690882
pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &pC->szRow);
9040790883
assert( pC->szRow<=pC->payloadSize );
9040890884
assert( pC->szRow<=65536 ); /* Maximum page size is 64KiB */
9040990885
}
9041090886
pC->cacheStatus = p->cacheCtr;
90411
- pC->iHdrOffset = getVarint32(pC->aRow, aOffset[0]);
90887
+ if( (aOffset[0] = pC->aRow[0])<0x80 ){
90888
+ pC->iHdrOffset = 1;
90889
+ }else{
90890
+ pC->iHdrOffset = sqlite3GetVarint32(pC->aRow, aOffset);
90891
+ }
9041290892
pC->nHdrParsed = 0;
9041390893
9041490894
if( pC->szRow<aOffset[0] ){ /*OPTIMIZATION-IF-FALSE*/
9041590895
/* pC->aRow does not have to hold the entire row, but it does at least
9041690896
** need to cover the header of the record. If pC->aRow does not contain
@@ -91041,22 +91521,64 @@
9104191521
UPDATE_MAX_BLOBSIZE(pOut);
9104291522
zHdr = (u8 *)pOut->z;
9104391523
zPayload = zHdr + nHdr;
9104491524
9104591525
/* Write the record */
91046
- zHdr += putVarint32(zHdr, nHdr);
91526
+ if( nHdr<0x80 ){
91527
+ *(zHdr++) = nHdr;
91528
+ }else{
91529
+ zHdr += sqlite3PutVarint(zHdr,nHdr);
91530
+ }
9104791531
assert( pData0<=pLast );
9104891532
pRec = pData0;
91049
- do{
91533
+ while( 1 /*exit-by-break*/ ){
9105091534
serial_type = pRec->uTemp;
9105191535
/* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more
91052
- ** additional varints, one per column. */
91053
- zHdr += putVarint32(zHdr, serial_type); /* serial type */
91054
- /* EVIDENCE-OF: R-64536-51728 The values for each column in the record
91536
+ ** additional varints, one per column.
91537
+ ** EVIDENCE-OF: R-64536-51728 The values for each column in the record
9105591538
** immediately follow the header. */
91056
- zPayload += sqlite3VdbeSerialPut(zPayload, pRec, serial_type); /* content */
91057
- }while( (++pRec)<=pLast );
91539
+ if( serial_type<=7 ){
91540
+ *(zHdr++) = serial_type;
91541
+ if( serial_type==0 ){
91542
+ /* NULL value. No change in zPayload */
91543
+ }else{
91544
+ u64 v;
91545
+ u32 i;
91546
+ if( serial_type==7 ){
91547
+ assert( sizeof(v)==sizeof(pRec->u.r) );
91548
+ memcpy(&v, &pRec->u.r, sizeof(v));
91549
+ swapMixedEndianFloat(v);
91550
+ }else{
91551
+ v = pRec->u.i;
91552
+ }
91553
+ len = i = sqlite3SmallTypeSizes[serial_type];
91554
+ assert( i>0 );
91555
+ while( 1 /*exit-by-break*/ ){
91556
+ zPayload[--i] = (u8)(v&0xFF);
91557
+ if( i==0 ) break;
91558
+ v >>= 8;
91559
+ }
91560
+ zPayload += len;
91561
+ }
91562
+ }else if( serial_type<0x80 ){
91563
+ *(zHdr++) = serial_type;
91564
+ if( serial_type>=14 && pRec->n>0 ){
91565
+ assert( pRec->z!=0 );
91566
+ memcpy(zPayload, pRec->z, pRec->n);
91567
+ zPayload += pRec->n;
91568
+ }
91569
+ }else{
91570
+ zHdr += sqlite3PutVarint(zHdr, serial_type);
91571
+ if( pRec->n ){
91572
+ assert( pRec->z!=0 );
91573
+ memcpy(zPayload, pRec->z, pRec->n);
91574
+ zPayload += pRec->n;
91575
+ }
91576
+ }
91577
+ if( pRec==pLast ) break;
91578
+ pRec++;
91579
+ }
9105891580
assert( nHdr==(int)(zHdr - (u8*)pOut->z) );
9105991581
assert( nByte==(int)(zPayload - (u8*)pOut->z) );
9106091582
9106191583
assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
9106291584
REGISTER_TRACE(pOp->p3, pOut);
@@ -91271,11 +91793,14 @@
9127191793
if( rc!=SQLITE_OK ) goto abort_due_to_error;
9127291794
}
9127391795
}
9127491796
}
9127591797
if( rc ) goto abort_due_to_error;
91276
-
91798
+ if( p->eVdbeState==VDBE_HALT_STATE ){
91799
+ rc = SQLITE_DONE;
91800
+ goto vdbe_return;
91801
+ }
9127791802
break;
9127891803
}
9127991804
9128091805
/* Opcode: AutoCommit P1 P2 * * *
9128191806
**
@@ -91375,10 +91900,11 @@
9137591900
** halts. The sqlite3_step() wrapper function might then reprepare the
9137691901
** statement and rerun it from the beginning.
9137791902
*/
9137891903
case OP_Transaction: {
9137991904
Btree *pBt;
91905
+ Db *pDb;
9138091906
int iMeta = 0;
9138191907
9138291908
assert( p->bIsReader );
9138391909
assert( p->readOnly==0 || pOp->p2==0 );
9138491910
assert( pOp->p2>=0 && pOp->p2<=2 );
@@ -91394,11 +91920,12 @@
9139491920
** transaction */
9139591921
rc = SQLITE_CORRUPT;
9139691922
}
9139791923
goto abort_due_to_error;
9139891924
}
91399
- pBt = db->aDb[pOp->p1].pBt;
91925
+ pDb = &db->aDb[pOp->p1];
91926
+ pBt = pDb->pBt;
9140091927
9140191928
if( pBt ){
9140291929
rc = sqlite3BtreeBeginTrans(pBt, pOp->p2, &iMeta);
9140391930
testcase( rc==SQLITE_BUSY_SNAPSHOT );
9140491931
testcase( rc==SQLITE_BUSY_RECOVERY );
@@ -91435,12 +91962,11 @@
9143591962
}
9143691963
}
9143791964
assert( pOp->p5==0 || pOp->p4type==P4_INT32 );
9143891965
if( rc==SQLITE_OK
9143991966
&& pOp->p5
91440
- && (iMeta!=pOp->p3
91441
- || db->aDb[pOp->p1].pSchema->iGeneration!=pOp->p4.i)
91967
+ && (iMeta!=pOp->p3 || pDb->pSchema->iGeneration!=pOp->p4.i)
9144291968
){
9144391969
/*
9144491970
** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema
9144591971
** version is checked to ensure that the schema has not changed since the
9144691972
** SQL statement was prepared.
@@ -92579,15 +93105,12 @@
9257993105
}
9258093106
case OP_NoConflict: /* jump, in3 */
9258193107
case OP_NotFound: /* jump, in3 */
9258293108
case OP_Found: { /* jump, in3 */
9258393109
int alreadyExists;
92584
- int takeJump;
9258593110
int ii;
9258693111
VdbeCursor *pC;
92587
- int res;
92588
- UnpackedRecord *pFree;
9258993112
UnpackedRecord *pIdxKey;
9259093113
UnpackedRecord r;
9259193114
9259293115
#ifdef SQLITE_TEST
9259393116
if( pOp->opcode!=OP_NoConflict ) sqlite3_found_count++;
@@ -92598,66 +93121,71 @@
9259893121
pC = p->apCsr[pOp->p1];
9259993122
assert( pC!=0 );
9260093123
#ifdef SQLITE_DEBUG
9260193124
pC->seekOp = pOp->opcode;
9260293125
#endif
92603
- pIn3 = &aMem[pOp->p3];
93126
+ r.aMem = &aMem[pOp->p3];
9260493127
assert( pC->eCurType==CURTYPE_BTREE );
9260593128
assert( pC->uc.pCursor!=0 );
9260693129
assert( pC->isTable==0 );
92607
- if( pOp->p4.i>0 ){
93130
+ r.nField = (u16)pOp->p4.i;
93131
+ if( r.nField>0 ){
93132
+ /* Key values in an array of registers */
9260893133
r.pKeyInfo = pC->pKeyInfo;
92609
- r.nField = (u16)pOp->p4.i;
92610
- r.aMem = pIn3;
93134
+ r.default_rc = 0;
9261193135
#ifdef SQLITE_DEBUG
9261293136
for(ii=0; ii<r.nField; ii++){
9261393137
assert( memIsValid(&r.aMem[ii]) );
9261493138
assert( (r.aMem[ii].flags & MEM_Zero)==0 || r.aMem[ii].n==0 );
9261593139
if( ii ) REGISTER_TRACE(pOp->p3+ii, &r.aMem[ii]);
9261693140
}
9261793141
#endif
92618
- pIdxKey = &r;
92619
- pFree = 0;
93142
+ rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, &r, &pC->seekResult);
9262093143
}else{
92621
- assert( pIn3->flags & MEM_Blob );
92622
- rc = ExpandBlob(pIn3);
93144
+ /* Composite key generated by OP_MakeRecord */
93145
+ assert( r.aMem->flags & MEM_Blob );
93146
+ assert( pOp->opcode!=OP_NoConflict );
93147
+ rc = ExpandBlob(r.aMem);
9262393148
assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
9262493149
if( rc ) goto no_mem;
92625
- pFree = pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo);
93150
+ pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo);
9262693151
if( pIdxKey==0 ) goto no_mem;
92627
- sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey);
92628
- }
92629
- pIdxKey->default_rc = 0;
92630
- takeJump = 0;
92631
- if( pOp->opcode==OP_NoConflict ){
92632
- /* For the OP_NoConflict opcode, take the jump if any of the
92633
- ** input fields are NULL, since any key with a NULL will not
92634
- ** conflict */
92635
- for(ii=0; ii<pIdxKey->nField; ii++){
92636
- if( pIdxKey->aMem[ii].flags & MEM_Null ){
92637
- takeJump = 1;
92638
- break;
92639
- }
92640
- }
92641
- }
92642
- rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, pIdxKey, &res);
92643
- if( pFree ) sqlite3DbFreeNN(db, pFree);
93152
+ sqlite3VdbeRecordUnpack(pC->pKeyInfo, r.aMem->n, r.aMem->z, pIdxKey);
93153
+ pIdxKey->default_rc = 0;
93154
+ rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, pIdxKey, &pC->seekResult);
93155
+ sqlite3DbFreeNN(db, pIdxKey);
93156
+ }
9264493157
if( rc!=SQLITE_OK ){
9264593158
goto abort_due_to_error;
9264693159
}
92647
- pC->seekResult = res;
92648
- alreadyExists = (res==0);
93160
+ alreadyExists = (pC->seekResult==0);
9264993161
pC->nullRow = 1-alreadyExists;
9265093162
pC->deferredMoveto = 0;
9265193163
pC->cacheStatus = CACHE_STALE;
9265293164
if( pOp->opcode==OP_Found ){
9265393165
VdbeBranchTaken(alreadyExists!=0,2);
9265493166
if( alreadyExists ) goto jump_to_p2;
9265593167
}else{
92656
- VdbeBranchTaken(takeJump||alreadyExists==0,2);
92657
- if( takeJump || !alreadyExists ) goto jump_to_p2;
92658
- if( pOp->opcode==OP_IfNoHope ) pC->seekHit = pOp->p4.i;
93168
+ if( !alreadyExists ){
93169
+ VdbeBranchTaken(1,2);
93170
+ goto jump_to_p2;
93171
+ }
93172
+ if( pOp->opcode==OP_NoConflict ){
93173
+ /* For the OP_NoConflict opcode, take the jump if any of the
93174
+ ** input fields are NULL, since any key with a NULL will not
93175
+ ** conflict */
93176
+ for(ii=0; ii<r.nField; ii++){
93177
+ if( r.aMem[ii].flags & MEM_Null ){
93178
+ VdbeBranchTaken(1,2);
93179
+ goto jump_to_p2;
93180
+ }
93181
+ }
93182
+ }
93183
+ VdbeBranchTaken(0,2);
93184
+ if( pOp->opcode==OP_IfNoHope ){
93185
+ pC->seekHit = pOp->p4.i;
93186
+ }
9265993187
}
9266093188
break;
9266193189
}
9266293190
9266393191
/* Opcode: SeekRowid P1 P2 P3 * *
@@ -93344,11 +93872,11 @@
9334493872
REGISTER_TRACE(pOp->p2, pOut);
9334593873
break;
9334693874
}
9334793875
9334893876
/* Opcode: Rowid P1 P2 * * *
93349
-** Synopsis: r[P2]=rowid
93877
+** Synopsis: r[P2]=PX rowid of P1
9335093878
**
9335193879
** Store in register P2 an integer which is the key of the table entry that
9335293880
** P1 is currently point to.
9335393881
**
9335493882
** P1 can be either an ordinary table or a virtual table. There used to
@@ -93400,20 +93928,27 @@
9340093928
**
9340193929
** Move the cursor P1 to a null row. Any OP_Column operations
9340293930
** that occur while the cursor is on the null row will always
9340393931
** write a NULL.
9340493932
**
93405
-** Or, if P1 is a Pseudo-Cursor (a cursor opened using OP_OpenPseudo)
93406
-** just reset the cache for that cursor. This causes the row of
93407
-** content held by the pseudo-cursor to be reparsed.
93933
+** If cursor P1 is not previously opened, open it now to a special
93934
+** pseudo-cursor that always returns NULL for every column.
9340893935
*/
9340993936
case OP_NullRow: {
9341093937
VdbeCursor *pC;
9341193938
9341293939
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
9341393940
pC = p->apCsr[pOp->p1];
93414
- assert( pC!=0 );
93941
+ if( pC==0 ){
93942
+ /* If the cursor is not already open, create a special kind of
93943
+ ** pseudo-cursor that always gives null rows. */
93944
+ pC = allocateCursor(p, pOp->p1, 1, CURTYPE_PSEUDO);
93945
+ if( pC==0 ) goto no_mem;
93946
+ pC->seekResult = 0;
93947
+ pC->isTable = 1;
93948
+ pC->uc.pCursor = sqlite3BtreeFakeValidCursor();
93949
+ }
9341593950
pC->nullRow = 1;
9341693951
pC->cacheStatus = CACHE_STALE;
9341793952
if( pC->eCurType==CURTYPE_BTREE ){
9341893953
assert( pC->uc.pCursor!=0 );
9341993954
sqlite3BtreeClearCursor(pC->uc.pCursor);
@@ -93856,13 +94391,13 @@
9385694391
i64 rowid; /* Rowid that P1 current points to */
9385794392
9385894393
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
9385994394
pC = p->apCsr[pOp->p1];
9386094395
assert( pC!=0 );
93861
- assert( pC->eCurType==CURTYPE_BTREE );
94396
+ assert( pC->eCurType==CURTYPE_BTREE || IsNullCursor(pC) );
9386294397
assert( pC->uc.pCursor!=0 );
93863
- assert( pC->isTable==0 );
94398
+ assert( pC->isTable==0 || IsNullCursor(pC) );
9386494399
assert( pC->deferredMoveto==0 );
9386594400
assert( !pC->nullRow || pOp->opcode==OP_IdxRowid );
9386694401
9386794402
/* The IdxRowid and Seek opcodes are combined because of the commonality
9386894403
** of sqlite3VdbeCursorRestore() and sqlite3VdbeIdxRowid(). */
@@ -95994,11 +96529,11 @@
9599496529
/* OP_Init is always instruction 0 */
9599596530
assert( pOp==p->aOp || pOp->opcode==OP_Trace );
9599696531
9599796532
#ifndef SQLITE_OMIT_TRACE
9599896533
if( (db->mTrace & (SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0
95999
- && !p->doingRerun
96534
+ && p->minWriteFileFormat!=254 /* tag-20220401a */
9600096535
&& (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
9600196536
){
9600296537
#ifndef SQLITE_OMIT_DEPRECATED
9600396538
if( db->mTrace & SQLITE_TRACE_LEGACY ){
9600496539
char *z = sqlite3VdbeExpandSql(p, zTrace);
@@ -96223,11 +96758,11 @@
9622396758
p->rc = rc;
9622496759
sqlite3SystemError(db, rc);
9622596760
testcase( sqlite3GlobalConfig.xLog!=0 );
9622696761
sqlite3_log(rc, "statement aborts at %d: [%s] %s",
9622796762
(int)(pOp - aOp), p->zSql, p->zErrMsg);
96228
- sqlite3VdbeHalt(p);
96763
+ if( p->eVdbeState==VDBE_RUN_STATE ) sqlite3VdbeHalt(p);
9622996764
if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db);
9623096765
if( rc==SQLITE_CORRUPT && db->autoCommit==0 ){
9623196766
db->flags |= SQLITE_CorruptRdOnly;
9623296767
}
9623396768
rc = SQLITE_ERROR;
@@ -100815,27 +101350,10 @@
100815101350
}
100816101351
sqlite3DbFree(db, pDup);
100817101352
}
100818101353
}
100819101354
100820
-
100821
-/*
100822
-** Return TRUE if the name zCol occurs anywhere in the USING clause.
100823
-**
100824
-** Return FALSE if the USING clause is NULL or if it does not contain
100825
-** zCol.
100826
-*/
100827
-static int nameInUsingClause(IdList *pUsing, const char *zCol){
100828
- if( pUsing ){
100829
- int k;
100830
- for(k=0; k<pUsing->nId; k++){
100831
- if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ) return 1;
100832
- }
100833
- }
100834
- return 0;
100835
-}
100836
-
100837101355
/*
100838101356
** Subqueries stores the original database, table and column names for their
100839101357
** result sets in ExprList.a[].zSpan, in the form "DATABASE.TABLE.COLUMN".
100840101358
** Check to see if the zSpan given to this routine matches the zDb, zTab,
100841101359
** and zCol. If any of zDb, zTab, and zCol are NULL then those fields will
@@ -100907,10 +101425,33 @@
100907101425
testcase( n==BMS );
100908101426
if( n>=BMS ) n = BMS-1;
100909101427
return ((Bitmask)1)<<n;
100910101428
}
100911101429
}
101430
+
101431
+/*
101432
+** Create a new expression term for the column specified by pMatch and
101433
+** iColumn. Append this new expression term to the FULL JOIN Match set
101434
+** in *ppList. Create a new *ppList if this is the first term in the
101435
+** set.
101436
+*/
101437
+static void extendFJMatch(
101438
+ Parse *pParse, /* Parsing context */
101439
+ ExprList **ppList, /* ExprList to extend */
101440
+ SrcItem *pMatch, /* Source table containing the column */
101441
+ i16 iColumn /* The column number */
101442
+){
101443
+ Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0);
101444
+ if( pNew ){
101445
+ pNew->iTable = pMatch->iCursor;
101446
+ pNew->iColumn = iColumn;
101447
+ pNew->y.pTab = pMatch->pTab;
101448
+ assert( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 );
101449
+ ExprSetProperty(pNew, EP_CanBeNull);
101450
+ *ppList = sqlite3ExprListAppend(pParse, *ppList, pNew);
101451
+ }
101452
+}
100912101453
100913101454
/*
100914101455
** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
100915101456
** that name in the set of source tables in pSrcList and make the pExpr
100916101457
** expression node refer back to that source column. The following changes
@@ -100953,15 +101494,17 @@
100953101494
SrcItem *pItem; /* Use for looping over pSrcList items */
100954101495
SrcItem *pMatch = 0; /* The matching pSrcList item */
100955101496
NameContext *pTopNC = pNC; /* First namecontext in the list */
100956101497
Schema *pSchema = 0; /* Schema of the expression */
100957101498
int eNewExprOp = TK_COLUMN; /* New value for pExpr->op on success */
100958
- Table *pTab = 0; /* Table hold the row */
101499
+ Table *pTab = 0; /* Table holding the row */
100959101500
Column *pCol; /* A column of pTab */
101501
+ ExprList *pFJMatch = 0; /* Matches for FULL JOIN .. USING */
100960101502
100961101503
assert( pNC ); /* the name context cannot be NULL. */
100962101504
assert( zCol ); /* The Z in X.Y.Z cannot be NULL */
101505
+ assert( zDb==0 || zTab!=0 );
100963101506
assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
100964101507
100965101508
/* Initialize the node to no-match */
100966101509
pExpr->iTable = -1;
100967101510
ExprSetVVAProperty(pExpr, EP_NoReduce);
@@ -101006,30 +101549,68 @@
101006101549
for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
101007101550
u8 hCol;
101008101551
pTab = pItem->pTab;
101009101552
assert( pTab!=0 && pTab->zName!=0 );
101010101553
assert( pTab->nCol>0 || pParse->nErr );
101011
- if( pItem->pSelect && (pItem->pSelect->selFlags & SF_NestedFrom)!=0 ){
101554
+ assert( pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) );
101555
+ if( pItem->fg.isNestedFrom ){
101556
+ /* In this case, pItem is a subquery that has been formed from a
101557
+ ** parenthesized subset of the FROM clause terms. Example:
101558
+ ** .... FROM t1 LEFT JOIN (t2 RIGHT JOIN t3 USING(x)) USING(y) ...
101559
+ ** \_________________________/
101560
+ ** This pItem -------------^
101561
+ */
101012101562
int hit = 0;
101563
+ assert( pItem->pSelect!=0 );
101013101564
pEList = pItem->pSelect->pEList;
101565
+ assert( pEList!=0 );
101566
+ assert( pEList->nExpr==pTab->nCol );
101014101567
for(j=0; j<pEList->nExpr; j++){
101015
- if( sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb) ){
101016
- cnt++;
101017
- cntTab = 2;
101018
- pMatch = pItem;
101019
- pExpr->iColumn = j;
101020
- hit = 1;
101568
+ if( !sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb) ){
101569
+ continue;
101021101570
}
101571
+ if( cnt>0 ){
101572
+ if( pItem->fg.isUsing==0
101573
+ || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0
101574
+ ){
101575
+ /* Two or more tables have the same column name which is
101576
+ ** not joined by USING. This is an error. Signal as much
101577
+ ** by clearing pFJMatch and letting cnt go above 1. */
101578
+ sqlite3ExprListDelete(db, pFJMatch);
101579
+ pFJMatch = 0;
101580
+ }else
101581
+ if( (pItem->fg.jointype & JT_RIGHT)==0 ){
101582
+ /* An INNER or LEFT JOIN. Use the left-most table */
101583
+ continue;
101584
+ }else
101585
+ if( (pItem->fg.jointype & JT_LEFT)==0 ){
101586
+ /* A RIGHT JOIN. Use the right-most table */
101587
+ cnt = 0;
101588
+ sqlite3ExprListDelete(db, pFJMatch);
101589
+ pFJMatch = 0;
101590
+ }else{
101591
+ /* For a FULL JOIN, we must construct a coalesce() func */
101592
+ extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn);
101593
+ }
101594
+ }
101595
+ cnt++;
101596
+ cntTab = 2;
101597
+ pMatch = pItem;
101598
+ pExpr->iColumn = j;
101599
+ pEList->a[j].bUsed = 1;
101600
+ hit = 1;
101022101601
}
101023101602
if( hit || zTab==0 ) continue;
101024101603
}
101025
- if( zDb ){
101026
- if( pTab->pSchema!=pSchema ) continue;
101027
- if( pSchema==0 && strcmp(zDb,"*")!=0 ) continue;
101028
- }
101604
+ assert( zDb==0 || zTab!=0 );
101029101605
if( zTab ){
101030
- const char *zTabName = pItem->zAlias ? pItem->zAlias : pTab->zName;
101606
+ const char *zTabName;
101607
+ if( zDb ){
101608
+ if( pTab->pSchema!=pSchema ) continue;
101609
+ if( pSchema==0 && strcmp(zDb,"*")!=0 ) continue;
101610
+ }
101611
+ zTabName = pItem->zAlias ? pItem->zAlias : pTab->zName;
101031101612
assert( zTabName!=0 );
101032101613
if( sqlite3StrICmp(zTabName, zTab)!=0 ){
101033101614
continue;
101034101615
}
101035101616
assert( ExprUseYTab(pExpr) );
@@ -101040,22 +101621,41 @@
101040101621
hCol = sqlite3StrIHash(zCol);
101041101622
for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
101042101623
if( pCol->hName==hCol
101043101624
&& sqlite3StrICmp(pCol->zCnName, zCol)==0
101044101625
){
101045
- /* If there has been exactly one prior match and this match
101046
- ** is for the right-hand table of a NATURAL JOIN or is in a
101047
- ** USING clause, then skip this match.
101048
- */
101049
- if( cnt==1 ){
101050
- if( pItem->fg.jointype & JT_NATURAL ) continue;
101051
- if( nameInUsingClause(pItem->pUsing, zCol) ) continue;
101626
+ if( cnt>0 ){
101627
+ if( pItem->fg.isUsing==0
101628
+ || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0
101629
+ ){
101630
+ /* Two or more tables have the same column name which is
101631
+ ** not joined by USING. This is an error. Signal as much
101632
+ ** by clearing pFJMatch and letting cnt go above 1. */
101633
+ sqlite3ExprListDelete(db, pFJMatch);
101634
+ pFJMatch = 0;
101635
+ }else
101636
+ if( (pItem->fg.jointype & JT_RIGHT)==0 ){
101637
+ /* An INNER or LEFT JOIN. Use the left-most table */
101638
+ continue;
101639
+ }else
101640
+ if( (pItem->fg.jointype & JT_LEFT)==0 ){
101641
+ /* A RIGHT JOIN. Use the right-most table */
101642
+ cnt = 0;
101643
+ sqlite3ExprListDelete(db, pFJMatch);
101644
+ pFJMatch = 0;
101645
+ }else{
101646
+ /* For a FULL JOIN, we must construct a coalesce() func */
101647
+ extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn);
101648
+ }
101052101649
}
101053101650
cnt++;
101054101651
pMatch = pItem;
101055101652
/* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
101056101653
pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j;
101654
+ if( pItem->fg.isNestedFrom ){
101655
+ sqlite3SrcItemColumnUsed(pItem, j);
101656
+ }
101057101657
break;
101058101658
}
101059101659
}
101060101660
if( 0==cnt && VisibleRowid(pTab) ){
101061101661
cntTab++;
@@ -101064,13 +101664,11 @@
101064101664
}
101065101665
if( pMatch ){
101066101666
pExpr->iTable = pMatch->iCursor;
101067101667
assert( ExprUseYTab(pExpr) );
101068101668
pExpr->y.pTab = pMatch->pTab;
101069
- /* RIGHT JOIN not (yet) supported */
101070
- assert( (pMatch->fg.jointype & JT_RIGHT)==0 );
101071
- if( (pMatch->fg.jointype & JT_LEFT)!=0 ){
101669
+ if( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 ){
101072101670
ExprSetProperty(pExpr, EP_CanBeNull);
101073101671
}
101074101672
pSchema = pExpr->y.pTab->pSchema;
101075101673
}
101076101674
} /* if( pSrcList ) */
@@ -101307,15 +101905,41 @@
101307101905
return WRC_Prune;
101308101906
}
101309101907
}
101310101908
101311101909
/*
101312
- ** cnt==0 means there was not match. cnt>1 means there were two or
101313
- ** more matches. Either way, we have an error.
101910
+ ** cnt==0 means there was not match.
101911
+ ** cnt>1 means there were two or more matches.
101912
+ **
101913
+ ** cnt==0 is always an error. cnt>1 is often an error, but might
101914
+ ** be multiple matches for a NATURAL LEFT JOIN or a LEFT JOIN USING.
101314101915
*/
101916
+ assert( pFJMatch==0 || cnt>0 );
101917
+ assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) );
101315101918
if( cnt!=1 ){
101316101919
const char *zErr;
101920
+ if( pFJMatch ){
101921
+ if( pFJMatch->nExpr==cnt-1 ){
101922
+ if( ExprHasProperty(pExpr,EP_Leaf) ){
101923
+ ExprClearProperty(pExpr,EP_Leaf);
101924
+ }else{
101925
+ sqlite3ExprDelete(db, pExpr->pLeft);
101926
+ pExpr->pLeft = 0;
101927
+ sqlite3ExprDelete(db, pExpr->pRight);
101928
+ pExpr->pRight = 0;
101929
+ }
101930
+ extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn);
101931
+ pExpr->op = TK_FUNCTION;
101932
+ pExpr->u.zToken = "coalesce";
101933
+ pExpr->x.pList = pFJMatch;
101934
+ cnt = 1;
101935
+ goto lookupname_end;
101936
+ }else{
101937
+ sqlite3ExprListDelete(db, pFJMatch);
101938
+ pFJMatch = 0;
101939
+ }
101940
+ }
101317101941
zErr = cnt==0 ? "no such column" : "ambiguous column name";
101318101942
if( zDb ){
101319101943
sqlite3ErrorMsg(pParse, "%s: %s.%s.%s", zErr, zDb, zTab, zCol);
101320101944
}else if( zTab ){
101321101945
sqlite3ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol);
@@ -101324,10 +101948,20 @@
101324101948
}
101325101949
sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
101326101950
pParse->checkSchema = 1;
101327101951
pTopNC->nNcErr++;
101328101952
}
101953
+ assert( pFJMatch==0 );
101954
+
101955
+ /* Remove all substructure from pExpr */
101956
+ if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){
101957
+ sqlite3ExprDelete(db, pExpr->pLeft);
101958
+ pExpr->pLeft = 0;
101959
+ sqlite3ExprDelete(db, pExpr->pRight);
101960
+ pExpr->pRight = 0;
101961
+ ExprSetProperty(pExpr, EP_Leaf);
101962
+ }
101329101963
101330101964
/* If a column from a table in pSrcList is referenced, then record
101331101965
** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes
101332101966
** bit 0 to be set. Column 1 sets bit 1. And so forth. Bit 63 is
101333101967
** set if the 63rd or any subsequent column is used.
@@ -101343,20 +101977,11 @@
101343101977
*/
101344101978
if( pExpr->iColumn>=0 && pMatch!=0 ){
101345101979
pMatch->colUsed |= sqlite3ExprColUsed(pExpr);
101346101980
}
101347101981
101348
- /* Clean up and return
101349
- */
101350
- if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){
101351
- sqlite3ExprDelete(db, pExpr->pLeft);
101352
- pExpr->pLeft = 0;
101353
- sqlite3ExprDelete(db, pExpr->pRight);
101354
- pExpr->pRight = 0;
101355
- }
101356101982
pExpr->op = eNewExprOp;
101357
- ExprSetProperty(pExpr, EP_Leaf);
101358101983
lookupname_end:
101359101984
if( cnt==1 ){
101360101985
assert( pNC!=0 );
101361101986
#ifndef SQLITE_OMIT_AUTHORIZATION
101362101987
if( pParse->db->xAuth
@@ -104008,10 +104633,22 @@
104008104633
}
104009104634
SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
104010104635
if( p ) sqlite3ExprDeleteNN(db, p);
104011104636
}
104012104637
104638
+/*
104639
+** Clear both elements of an OnOrUsing object
104640
+*/
104641
+SQLITE_PRIVATE void sqlite3ClearOnOrUsing(sqlite3 *db, OnOrUsing *p){
104642
+ if( p==0 ){
104643
+ /* Nothing to clear */
104644
+ }else if( p->pOn ){
104645
+ sqlite3ExprDeleteNN(db, p->pOn);
104646
+ }else if( p->pUsing ){
104647
+ sqlite3IdListDelete(db, p->pUsing);
104648
+ }
104649
+}
104013104650
104014104651
/*
104015104652
** Arrange to cause pExpr to be deleted when the pParse is deleted.
104016104653
** This is similar to sqlite3ExprDelete() except that the delete is
104017104654
** deferred untilthe pParse is deleted.
@@ -104378,10 +105015,11 @@
104378105015
pItem->zEName = sqlite3DbStrDup(db, pOldItem->zEName);
104379105016
pItem->sortFlags = pOldItem->sortFlags;
104380105017
pItem->eEName = pOldItem->eEName;
104381105018
pItem->done = 0;
104382105019
pItem->bNulls = pOldItem->bNulls;
105020
+ pItem->bUsed = pOldItem->bUsed;
104383105021
pItem->bSorterRef = pOldItem->bSorterRef;
104384105022
pItem->u = pOldItem->u;
104385105023
}
104386105024
return pNew;
104387105025
}
@@ -104430,37 +105068,35 @@
104430105068
pTab = pNewItem->pTab = pOldItem->pTab;
104431105069
if( pTab ){
104432105070
pTab->nTabRef++;
104433105071
}
104434105072
pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags);
104435
- pNewItem->pOn = sqlite3ExprDup(db, pOldItem->pOn, flags);
104436
- pNewItem->pUsing = sqlite3IdListDup(db, pOldItem->pUsing);
105073
+ if( pOldItem->fg.isUsing ){
105074
+ assert( pNewItem->fg.isUsing );
105075
+ pNewItem->u3.pUsing = sqlite3IdListDup(db, pOldItem->u3.pUsing);
105076
+ }else{
105077
+ pNewItem->u3.pOn = sqlite3ExprDup(db, pOldItem->u3.pOn, flags);
105078
+ }
104437105079
pNewItem->colUsed = pOldItem->colUsed;
104438105080
}
104439105081
return pNew;
104440105082
}
104441105083
SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, const IdList *p){
104442105084
IdList *pNew;
104443105085
int i;
104444105086
assert( db!=0 );
104445105087
if( p==0 ) return 0;
104446
- pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) );
105088
+ assert( p->eU4!=EU4_EXPR );
105089
+ pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew)+(p->nId-1)*sizeof(p->a[0]) );
104447105090
if( pNew==0 ) return 0;
104448105091
pNew->nId = p->nId;
104449
- pNew->a = sqlite3DbMallocRawNN(db, p->nId*sizeof(p->a[0]) );
104450
- if( pNew->a==0 ){
104451
- sqlite3DbFreeNN(db, pNew);
104452
- return 0;
104453
- }
104454
- /* Note that because the size of the allocation for p->a[] is not
104455
- ** necessarily a power of two, sqlite3IdListAppend() may not be called
104456
- ** on the duplicate created by this function. */
105092
+ pNew->eU4 = p->eU4;
104457105093
for(i=0; i<p->nId; i++){
104458105094
struct IdList_item *pNewItem = &pNew->a[i];
104459
- struct IdList_item *pOldItem = &p->a[i];
105095
+ const struct IdList_item *pOldItem = &p->a[i];
104460105096
pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
104461
- pNewItem->idx = pOldItem->idx;
105097
+ pNewItem->u4 = pOldItem->u4;
104462105098
}
104463105099
return pNew;
104464105100
}
104465105101
SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *pDup, int flags){
104466105102
Select *pRet = 0;
@@ -104922,11 +105558,11 @@
104922105558
** malformed schema error.
104923105559
*/
104924105560
static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
104925105561
104926105562
/* If pWalker->eCode is 2 then any term of the expression that comes from
104927
- ** the ON or USING clauses of a left join disqualifies the expression
105563
+ ** the ON or USING clauses of an outer join disqualifies the expression
104928105564
** from being considered constant. */
104929105565
if( pWalker->eCode==2 && ExprHasProperty(pExpr, EP_FromJoin) ){
104930105566
pWalker->eCode = 0;
104931105567
return WRC_Abort;
104932105568
}
@@ -105924,13 +106560,13 @@
105924106560
sqlite3VdbeJumpHere(v, addrOnce);
105925106561
/* Subroutine return */
105926106562
assert( ExprUseYSub(pExpr) );
105927106563
assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn
105928106564
|| pParse->nErr );
105929
- sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, 0,
105930
- pExpr->y.sub.iAddr-1);
105931
- sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
106565
+ sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn,
106566
+ pExpr->y.sub.iAddr, 1);
106567
+ VdbeCoverage(v);
105932106568
sqlite3ClearTempRegCache(pParse);
105933106569
}
105934106570
}
105935106571
#endif /* SQLITE_OMIT_SUBQUERY */
105936106572
@@ -106055,13 +106691,13 @@
106055106691
106056106692
/* Subroutine return */
106057106693
assert( ExprUseYSub(pExpr) );
106058106694
assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn
106059106695
|| pParse->nErr );
106060
- sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, 0,
106061
- pExpr->y.sub.iAddr-1);
106062
- sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
106696
+ sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn,
106697
+ pExpr->y.sub.iAddr, 1);
106698
+ VdbeCoverage(v);
106063106699
sqlite3ClearTempRegCache(pParse);
106064106700
return rReg;
106065106701
}
106066106702
#endif /* SQLITE_OMIT_SUBQUERY */
106067106703
@@ -106491,10 +107127,11 @@
106491107127
sqlite3VdbeAddOp3(v, OP_Column, iTabCur, iCol, regOut);
106492107128
return;
106493107129
}
106494107130
if( iCol<0 || iCol==pTab->iPKey ){
106495107131
sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut);
107132
+ VdbeComment((v, "%s.rowid", pTab->zName));
106496107133
}else{
106497107134
int op;
106498107135
int x;
106499107136
if( IsVirtual(pTab) ){
106500107137
op = OP_VColumn;
@@ -107243,20 +107880,22 @@
107243107880
}
107244107881
break;
107245107882
}
107246107883
case TK_SELECT_COLUMN: {
107247107884
int n;
107248
- if( pExpr->pLeft->iTable==0 ){
107249
- pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft);
107885
+ Expr *pLeft = pExpr->pLeft;
107886
+ if( pLeft->iTable==0 || pParse->withinRJSubrtn > pLeft->op2 ){
107887
+ pLeft->iTable = sqlite3CodeSubselect(pParse, pLeft);
107888
+ pLeft->op2 = pParse->withinRJSubrtn;
107250107889
}
107251
- assert( pExpr->pLeft->op==TK_SELECT || pExpr->pLeft->op==TK_ERROR );
107252
- n = sqlite3ExprVectorSize(pExpr->pLeft);
107890
+ assert( pLeft->op==TK_SELECT || pLeft->op==TK_ERROR );
107891
+ n = sqlite3ExprVectorSize(pLeft);
107253107892
if( pExpr->iTable!=n ){
107254107893
sqlite3ErrorMsg(pParse, "%d columns assigned %d values",
107255107894
pExpr->iTable, n);
107256107895
}
107257
- return pExpr->pLeft->iTable + pExpr->iColumn;
107896
+ return pLeft->iTable + pExpr->iColumn;
107258107897
}
107259107898
case TK_IN: {
107260107899
int destIfFalse = sqlite3VdbeMakeLabel(pParse);
107261107900
int destIfNull = sqlite3VdbeMakeLabel(pParse);
107262107901
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
@@ -108560,11 +109199,11 @@
108560109199
**
108561109200
** False positives are not allowed, however. A false positive may result
108562109201
** in an incorrect answer.
108563109202
**
108564109203
** Terms of p that are marked with EP_FromJoin (and hence that come from
108565
-** the ON or USING clauses of LEFT JOINS) are excluded from the analysis.
109204
+** the ON or USING clauses of OUTER JOINS) are excluded from the analysis.
108566109205
**
108567109206
** This routine is used to check if a LEFT JOIN can be converted into
108568109207
** an ordinary JOIN. The p argument is the WHERE clause. If the WHERE
108569109208
** clause requires that some column of the right table of the LEFT JOIN
108570109209
** be non-NULL, then the LEFT JOIN can be safely converted into an
@@ -109974,15 +110613,14 @@
109974110613
*/
109975110614
static void unmapColumnIdlistNames(
109976110615
Parse *pParse,
109977110616
const IdList *pIdList
109978110617
){
109979
- if( pIdList ){
109980
- int ii;
109981
- for(ii=0; ii<pIdList->nId; ii++){
109982
- sqlite3RenameTokenRemap(pParse, 0, (const void*)pIdList->a[ii].zName);
109983
- }
110618
+ int ii;
110619
+ assert( pIdList!=0 );
110620
+ for(ii=0; ii<pIdList->nId; ii++){
110621
+ sqlite3RenameTokenRemap(pParse, 0, (const void*)pIdList->a[ii].zName);
109984110622
}
109985110623
}
109986110624
109987110625
/*
109988110626
** Walker callback used by sqlite3RenameExprUnmap().
@@ -110006,12 +110644,15 @@
110006110644
}
110007110645
if( ALWAYS(p->pSrc) ){ /* Every Select as a SrcList, even if it is empty */
110008110646
SrcList *pSrc = p->pSrc;
110009110647
for(i=0; i<pSrc->nSrc; i++){
110010110648
sqlite3RenameTokenRemap(pParse, 0, (void*)pSrc->a[i].zName);
110011
- sqlite3WalkExpr(pWalker, pSrc->a[i].pOn);
110012
- unmapColumnIdlistNames(pParse, pSrc->a[i].pUsing);
110649
+ if( pSrc->a[i].fg.isUsing==0 ){
110650
+ sqlite3WalkExpr(pWalker, pSrc->a[i].u3.pOn);
110651
+ }else{
110652
+ unmapColumnIdlistNames(pParse, pSrc->a[i].u3.pUsing);
110653
+ }
110013110654
}
110014110655
}
110015110656
110016110657
renameWalkWith(pWalker, p);
110017110658
return WRC_Continue;
@@ -113792,11 +114433,15 @@
113792114433
}
113793114434
pItem->pSchema = pFix->pSchema;
113794114435
pItem->fg.fromDDL = 1;
113795114436
}
113796114437
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
113797
- if( sqlite3WalkExpr(&pFix->w, pList->a[i].pOn) ) return WRC_Abort;
114438
+ if( pList->a[i].fg.isUsing==0
114439
+ && sqlite3WalkExpr(&pFix->w, pList->a[i].u3.pOn)
114440
+ ){
114441
+ return WRC_Abort;
114442
+ }
113798114443
#endif
113799114444
}
113800114445
if( pSelect->pWith ){
113801114446
for(i=0; i<pSelect->pWith->nCte; i++){
113802114447
if( sqlite3WalkSelect(p, pSelect->pWith->a[i].pSelect) ){
@@ -118856,22 +119501,21 @@
118856119501
sqlite3 *db = pParse->db;
118857119502
int i;
118858119503
if( pList==0 ){
118859119504
pList = sqlite3DbMallocZero(db, sizeof(IdList) );
118860119505
if( pList==0 ) return 0;
118861
- }
118862
- pList->a = sqlite3ArrayAllocate(
118863
- db,
118864
- pList->a,
118865
- sizeof(pList->a[0]),
118866
- &pList->nId,
118867
- &i
118868
- );
118869
- if( i<0 ){
118870
- sqlite3IdListDelete(db, pList);
118871
- return 0;
118872
- }
119506
+ }else{
119507
+ IdList *pNew;
119508
+ pNew = sqlite3DbRealloc(db, pList,
119509
+ sizeof(IdList) + pList->nId*sizeof(pList->a));
119510
+ if( pNew==0 ){
119511
+ sqlite3IdListDelete(db, pList);
119512
+ return 0;
119513
+ }
119514
+ pList = pNew;
119515
+ }
119516
+ i = pList->nId++;
118873119517
pList->a[i].zName = sqlite3NameFromToken(db, pToken);
118874119518
if( IN_RENAME_OBJECT && pList->a[i].zName ){
118875119519
sqlite3RenameTokenMap(pParse, (void*)pList->a[i].zName, pToken);
118876119520
}
118877119521
return pList;
@@ -118881,24 +119525,24 @@
118881119525
** Delete an IdList.
118882119526
*/
118883119527
SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3 *db, IdList *pList){
118884119528
int i;
118885119529
if( pList==0 ) return;
119530
+ assert( pList->eU4!=EU4_EXPR ); /* EU4_EXPR mode is not currently used */
118886119531
for(i=0; i<pList->nId; i++){
118887119532
sqlite3DbFree(db, pList->a[i].zName);
118888119533
}
118889
- sqlite3DbFree(db, pList->a);
118890119534
sqlite3DbFreeNN(db, pList);
118891119535
}
118892119536
118893119537
/*
118894119538
** Return the index in pList of the identifier named zId. Return -1
118895119539
** if not found.
118896119540
*/
118897119541
SQLITE_PRIVATE int sqlite3IdListIndex(IdList *pList, const char *zName){
118898119542
int i;
118899
- if( pList==0 ) return -1;
119543
+ assert( pList!=0 );
118900119544
for(i=0; i<pList->nId; i++){
118901119545
if( sqlite3StrICmp(pList->a[i].zName, zName)==0 ) return i;
118902119546
}
118903119547
return -1;
118904119548
}
@@ -119097,12 +119741,15 @@
119097119741
if( pItem->zAlias ) sqlite3DbFreeNN(db, pItem->zAlias);
119098119742
if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy);
119099119743
if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg);
119100119744
sqlite3DeleteTable(db, pItem->pTab);
119101119745
if( pItem->pSelect ) sqlite3SelectDelete(db, pItem->pSelect);
119102
- if( pItem->pOn ) sqlite3ExprDelete(db, pItem->pOn);
119103
- if( pItem->pUsing ) sqlite3IdListDelete(db, pItem->pUsing);
119746
+ if( pItem->fg.isUsing ){
119747
+ sqlite3IdListDelete(db, pItem->u3.pUsing);
119748
+ }else if( pItem->u3.pOn ){
119749
+ sqlite3ExprDelete(db, pItem->u3.pOn);
119750
+ }
119104119751
}
119105119752
sqlite3DbFreeNN(db, pList);
119106119753
}
119107119754
119108119755
/*
@@ -119126,18 +119773,17 @@
119126119773
SrcList *p, /* The left part of the FROM clause already seen */
119127119774
Token *pTable, /* Name of the table to add to the FROM clause */
119128119775
Token *pDatabase, /* Name of the database containing pTable */
119129119776
Token *pAlias, /* The right-hand side of the AS subexpression */
119130119777
Select *pSubquery, /* A subquery used in place of a table name */
119131
- Expr *pOn, /* The ON clause of a join */
119132
- IdList *pUsing /* The USING clause of a join */
119778
+ OnOrUsing *pOnUsing /* Either the ON clause or the USING clause */
119133119779
){
119134119780
SrcItem *pItem;
119135119781
sqlite3 *db = pParse->db;
119136
- if( !p && (pOn || pUsing) ){
119782
+ if( !p && pOnUsing!=0 && (pOnUsing->pOn || pOnUsing->pUsing) ){
119137119783
sqlite3ErrorMsg(pParse, "a JOIN clause is required before %s",
119138
- (pOn ? "ON" : "USING")
119784
+ (pOnUsing->pOn ? "ON" : "USING")
119139119785
);
119140119786
goto append_from_error;
119141119787
}
119142119788
p = sqlite3SrcListAppend(pParse, p, pTable, pDatabase);
119143119789
if( p==0 ){
@@ -119153,19 +119799,31 @@
119153119799
}
119154119800
assert( pAlias!=0 );
119155119801
if( pAlias->n ){
119156119802
pItem->zAlias = sqlite3NameFromToken(db, pAlias);
119157119803
}
119158
- pItem->pSelect = pSubquery;
119159
- pItem->pOn = pOn;
119160
- pItem->pUsing = pUsing;
119804
+ if( pSubquery ){
119805
+ pItem->pSelect = pSubquery;
119806
+ if( pSubquery->selFlags & SF_NestedFrom ){
119807
+ pItem->fg.isNestedFrom = 1;
119808
+ }
119809
+ }
119810
+ assert( pOnUsing==0 || pOnUsing->pOn==0 || pOnUsing->pUsing==0 );
119811
+ assert( pItem->fg.isUsing==0 );
119812
+ if( pOnUsing==0 ){
119813
+ pItem->u3.pOn = 0;
119814
+ }else if( pOnUsing->pUsing ){
119815
+ pItem->fg.isUsing = 1;
119816
+ pItem->u3.pUsing = pOnUsing->pUsing;
119817
+ }else{
119818
+ pItem->u3.pOn = pOnUsing->pOn;
119819
+ }
119161119820
return p;
119162119821
119163119822
append_from_error:
119164119823
assert( p==0 );
119165
- sqlite3ExprDelete(db, pOn);
119166
- sqlite3IdListDelete(db, pUsing);
119824
+ sqlite3ClearOnOrUsing(db, pOnUsing);
119167119825
sqlite3SelectDelete(db, pSubquery);
119168119826
return 0;
119169119827
}
119170119828
119171119829
/*
@@ -119206,10 +119864,11 @@
119206119864
sqlite3SrcListDelete(pParse->db, p2);
119207119865
}else{
119208119866
p1 = pNew;
119209119867
memcpy(&p1->a[1], p2->a, p2->nSrc*sizeof(SrcItem));
119210119868
sqlite3DbFree(pParse->db, p2);
119869
+ p1->a[0].fg.jointype |= (JT_LTORJ & p1->a[1].fg.jointype);
119211119870
}
119212119871
}
119213119872
return p1;
119214119873
}
119215119874
@@ -119242,18 +119901,38 @@
119242119901
** A natural cross join B
119243119902
**
119244119903
** The operator is "natural cross join". The A and B operands are stored
119245119904
** in p->a[0] and p->a[1], respectively. The parser initially stores the
119246119905
** operator with A. This routine shifts that operator over to B.
119906
+**
119907
+** Additional changes:
119908
+**
119909
+** * All tables to the left of the right-most RIGHT JOIN are tagged with
119910
+** JT_LTORJ (mnemonic: Left Table Of Right Join) so that the
119911
+** code generator can easily tell that the table is part of
119912
+** the left operand of at least one RIGHT JOIN.
119247119913
*/
119248
-SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList *p){
119249
- if( p ){
119250
- int i;
119251
- for(i=p->nSrc-1; i>0; i--){
119252
- p->a[i].fg.jointype = p->a[i-1].fg.jointype;
119253
- }
119914
+SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(Parse *pParse, SrcList *p){
119915
+ (void)pParse;
119916
+ if( p && p->nSrc>1 ){
119917
+ int i = p->nSrc-1;
119918
+ u8 allFlags = 0;
119919
+ do{
119920
+ allFlags |= p->a[i].fg.jointype = p->a[i-1].fg.jointype;
119921
+ }while( (--i)>0 );
119254119922
p->a[0].fg.jointype = 0;
119923
+
119924
+ /* All terms to the left of a RIGHT JOIN should be tagged with the
119925
+ ** JT_LTORJ flags */
119926
+ if( allFlags & JT_RIGHT ){
119927
+ for(i=p->nSrc-1; ALWAYS(i>0) && (p->a[i].fg.jointype&JT_RIGHT)==0; i--){}
119928
+ i--;
119929
+ assert( i>=0 );
119930
+ do{
119931
+ p->a[i].fg.jointype |= JT_LTORJ;
119932
+ }while( (--i)>=0 );
119933
+ }
119255119934
}
119256119935
}
119257119936
119258119937
/*
119259119938
** Generate VDBE code for a BEGIN statement.
@@ -120498,12 +121177,12 @@
120498121177
pFrom = sqlite3SrcListAppend(pParse, 0, 0, 0);
120499121178
if( pFrom ){
120500121179
assert( pFrom->nSrc==1 );
120501121180
pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName);
120502121181
pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName);
120503
- assert( pFrom->a[0].pOn==0 );
120504
- assert( pFrom->a[0].pUsing==0 );
121182
+ assert( pFrom->a[0].fg.isUsing==0 );
121183
+ assert( pFrom->a[0].u3.pOn==0 );
120505121184
}
120506121185
pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, pOrderBy,
120507121186
SF_IncludeHidden, pLimit);
120508121187
sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
120509121188
sqlite3Select(pParse, pSel, &dest);
@@ -120670,11 +121349,10 @@
120670121349
goto delete_from_cleanup;
120671121350
}
120672121351
assert( db->mallocFailed==0 );
120673121352
assert( pTabList->nSrc==1 );
120674121353
120675
-
120676121354
/* Locate the table which we want to delete. This table has to be
120677121355
** put in an SrcList structure because some of the subroutines we
120678121356
** will be calling are designed to work with multiple tables and expect
120679121357
** an SrcList* parameter instead of just a Table* parameter.
120680121358
*/
@@ -120694,10 +121372,18 @@
120694121372
bComplex = pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0);
120695121373
#ifdef SQLITE_OMIT_VIEW
120696121374
# undef isView
120697121375
# define isView 0
120698121376
#endif
121377
+
121378
+#if TREETRACE_ENABLED
121379
+ if( sqlite3TreeTrace & 0x10000 ){
121380
+ sqlite3TreeViewLine(0, "In sqlite3Delete() at %s:%d", __FILE__, __LINE__);
121381
+ sqlite3TreeViewDelete(pParse->pWith, pTabList, pWhere,
121382
+ pOrderBy, pLimit, pTrigger);
121383
+ }
121384
+#endif
120699121385
120700121386
#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
120701121387
if( !isView ){
120702121388
pWhere = sqlite3LimitWhere(
120703121389
pParse, pTabList, pWhere, pOrderBy, pLimit, "DELETE"
@@ -124132,11 +124818,10 @@
124132124818
sqlite3VdbeJumpHere(v, iMustBeInt);
124133124819
sqlite3ReleaseTempReg(pParse, regTemp);
124134124820
}else{
124135124821
int nCol = pFKey->nCol;
124136124822
int regTemp = sqlite3GetTempRange(pParse, nCol);
124137
- int regRec = sqlite3GetTempReg(pParse);
124138124823
124139124824
sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb);
124140124825
sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
124141124826
for(i=0; i<nCol; i++){
124142124827
sqlite3VdbeAddOp2(v, OP_Copy,
@@ -124172,15 +124857,14 @@
124172124857
sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
124173124858
}
124174124859
sqlite3VdbeGoto(v, iOk);
124175124860
}
124176124861
124177
- sqlite3VdbeAddOp4(v, OP_MakeRecord, regTemp, nCol, regRec,
124862
+ sqlite3VdbeAddOp4(v, OP_Affinity, regTemp, nCol, 0,
124178124863
sqlite3IndexAffinityStr(pParse->db,pIdx), nCol);
124179
- sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0); VdbeCoverage(v);
124180
-
124181
- sqlite3ReleaseTempReg(pParse, regRec);
124864
+ sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regTemp, nCol);
124865
+ VdbeCoverage(v);
124182124866
sqlite3ReleaseTempRange(pParse, regTemp, nCol);
124183124867
}
124184124868
}
124185124869
124186124870
if( !pFKey->isDeferred && !(pParse->db->flags & SQLITE_DeferFKs)
@@ -124278,18 +124962,14 @@
124278124962
** For each child row found, one of the following actions is taken:
124279124963
**
124280124964
** Operation | FK type | Action taken
124281124965
** --------------------------------------------------------------------------
124282124966
** DELETE immediate Increment the "immediate constraint counter".
124283
-** Or, if the ON (UPDATE|DELETE) action is RESTRICT,
124284
-** throw a "FOREIGN KEY constraint failed" exception.
124285124967
**
124286124968
** INSERT immediate Decrement the "immediate constraint counter".
124287124969
**
124288124970
** DELETE deferred Increment the "deferred constraint counter".
124289
-** Or, if the ON (UPDATE|DELETE) action is RESTRICT,
124290
-** throw a "FOREIGN KEY constraint failed" exception.
124291124971
**
124292124972
** INSERT deferred Decrement the "deferred constraint counter".
124293124973
**
124294124974
** These operations are identified in the comment at the top of this file
124295124975
** (fkey.c) as "I.2" and "D.2".
@@ -124933,13 +125613,13 @@
124933125613
** passed a pointer to the list of columns being modified. If it is a
124934125614
** DELETE, pChanges is passed a NULL pointer.
124935125615
**
124936125616
** It returns a pointer to a Trigger structure containing a trigger
124937125617
** equivalent to the ON UPDATE or ON DELETE action specified by pFKey.
124938
-** If the action is "NO ACTION" or "RESTRICT", then a NULL pointer is
124939
-** returned (these actions require no special handling by the triggers
124940
-** sub-system, code for them is created by fkScanChildren()).
125618
+** If the action is "NO ACTION" then a NULL pointer is returned (these actions
125619
+** require no special handling by the triggers sub-system, code for them is
125620
+** created by fkScanChildren()).
124941125621
**
124942125622
** For example, if pFKey is the foreign key and pTab is table "p" in
124943125623
** the following schema:
124944125624
**
124945125625
** CREATE TABLE p(pk PRIMARY KEY);
@@ -125064,22 +125744,27 @@
125064125744
125065125745
zFrom = pFKey->pFrom->zName;
125066125746
nFrom = sqlite3Strlen30(zFrom);
125067125747
125068125748
if( action==OE_Restrict ){
125749
+ int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
125069125750
Token tFrom;
125751
+ Token tDb;
125070125752
Expr *pRaise;
125071125753
125072125754
tFrom.z = zFrom;
125073125755
tFrom.n = nFrom;
125756
+ tDb.z = db->aDb[iDb].zDbSName;
125757
+ tDb.n = sqlite3Strlen30(tDb.z);
125758
+
125074125759
pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed");
125075125760
if( pRaise ){
125076125761
pRaise->affExpr = OE_Abort;
125077125762
}
125078125763
pSelect = sqlite3SelectNew(pParse,
125079125764
sqlite3ExprListAppend(pParse, 0, pRaise),
125080
- sqlite3SrcListAppend(pParse, 0, &tFrom, 0),
125765
+ sqlite3SrcListAppend(pParse, 0, &tDb, &tFrom),
125081125766
pWhere,
125082125767
0, 0, 0, 0, 0
125083125768
);
125084125769
pWhere = 0;
125085125770
}
@@ -125984,10 +126669,18 @@
125984126669
#ifdef SQLITE_OMIT_VIEW
125985126670
# undef isView
125986126671
# define isView 0
125987126672
#endif
125988126673
assert( (pTrigger && tmask) || (pTrigger==0 && tmask==0) );
126674
+
126675
+#if TREETRACE_ENABLED
126676
+ if( sqlite3TreeTrace & 0x10000 ){
126677
+ sqlite3TreeViewLine(0, "In sqlite3Insert() at %s:%d", __FILE__, __LINE__);
126678
+ sqlite3TreeViewInsert(pParse->pWith, pTabList, pColumn, pSelect, pList,
126679
+ onError, pUpsert, pTrigger);
126680
+ }
126681
+#endif
125989126682
125990126683
/* If pTab is really a view, make sure it has been initialized.
125991126684
** ViewGetColumnNames() is a no-op if pTab is not a view.
125992126685
*/
125993126686
if( sqlite3ViewGetColumnNames(pParse, pTab) ){
@@ -126063,17 +126756,19 @@
126063126756
** columns into storage order. False negatives are harmless,
126064126757
** but false positives will cause database corruption.
126065126758
*/
126066126759
bIdListInOrder = (pTab->tabFlags & (TF_OOOHidden|TF_HasStored))==0;
126067126760
if( pColumn ){
126761
+ assert( pColumn->eU4!=EU4_EXPR );
126762
+ pColumn->eU4 = EU4_IDX;
126068126763
for(i=0; i<pColumn->nId; i++){
126069
- pColumn->a[i].idx = -1;
126764
+ pColumn->a[i].u4.idx = -1;
126070126765
}
126071126766
for(i=0; i<pColumn->nId; i++){
126072126767
for(j=0; j<pTab->nCol; j++){
126073126768
if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zCnName)==0 ){
126074
- pColumn->a[i].idx = j;
126769
+ pColumn->a[i].u4.idx = j;
126075126770
if( i!=j ) bIdListInOrder = 0;
126076126771
if( j==pTab->iPKey ){
126077126772
ipkColumn = i; assert( !withoutRowid );
126078126773
}
126079126774
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
@@ -126371,11 +127066,12 @@
126371127066
iRegStore);
126372127067
continue;
126373127068
}
126374127069
}
126375127070
if( pColumn ){
126376
- for(j=0; j<pColumn->nId && pColumn->a[j].idx!=i; j++){}
127071
+ assert( pColumn->eU4==EU4_IDX );
127072
+ for(j=0; j<pColumn->nId && pColumn->a[j].u4.idx!=i; j++){}
126377127073
if( j>=pColumn->nId ){
126378127074
/* A column not named in the insert column list gets its
126379127075
** default value */
126380127076
sqlite3ExprCodeFactorable(pParse,
126381127077
sqlite3ColumnExpr(pTab, &pTab->aCol[i]),
@@ -132244,19 +132940,17 @@
132244132940
int i; /* Loop counter: Foreign key number for pTab */
132245132941
int j; /* Loop counter: Field of the foreign key */
132246132942
HashElem *k; /* Loop counter: Next table in schema */
132247132943
int x; /* result variable */
132248132944
int regResult; /* 3 registers to hold a result row */
132249
- int regKey; /* Register to hold key for checking the FK */
132250132945
int regRow; /* Registers to hold a row from pTab */
132251132946
int addrTop; /* Top of a loop checking foreign keys */
132252132947
int addrOk; /* Jump here if the key is OK */
132253132948
int *aiCols; /* child to parent column mapping */
132254132949
132255132950
regResult = pParse->nMem+1;
132256132951
pParse->nMem += 4;
132257
- regKey = ++pParse->nMem;
132258132952
regRow = ++pParse->nMem;
132259132953
k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash);
132260132954
while( k ){
132261132955
if( zRight ){
132262132956
pTab = sqlite3LocateTable(pParse, 0, zRight, zDb);
@@ -132319,13 +133013,13 @@
132319133013
}
132320133014
132321133015
/* Generate code to query the parent index for a matching parent
132322133016
** key. If a match is found, jump to addrOk. */
132323133017
if( pIdx ){
132324
- sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey,
133018
+ sqlite3VdbeAddOp4(v, OP_Affinity, regRow, pFK->nCol, 0,
132325133019
sqlite3IndexAffinityStr(db,pIdx), pFK->nCol);
132326
- sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0);
133020
+ sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regRow, pFK->nCol);
132327133021
VdbeCoverage(v);
132328133022
}else if( pParent ){
132329133023
int jmp = sqlite3VdbeCurrentAddr(v)+2;
132330133024
sqlite3VdbeAddOp3(v, OP_SeekRowid, i, jmp, regRow); VdbeCoverage(v);
132331133025
sqlite3VdbeGoto(v, addrOk);
@@ -134732,10 +135426,56 @@
134732135426
**
134733135427
** A full outer join is the combination of JT_LEFT and JT_RIGHT.
134734135428
**
134735135429
** If an illegal or unsupported join type is seen, then still return
134736135430
** a join type, but put an error in the pParse structure.
135431
+**
135432
+** These are the valid join types:
135433
+**
135434
+**
135435
+** pA pB pC Return Value
135436
+** ------- ----- ----- ------------
135437
+** CROSS - - JT_CROSS
135438
+** INNER - - JT_INNER
135439
+** LEFT - - JT_LEFT|JT_OUTER
135440
+** LEFT OUTER - JT_LEFT|JT_OUTER
135441
+** RIGHT - - JT_RIGHT|JT_OUTER
135442
+** RIGHT OUTER - JT_RIGHT|JT_OUTER
135443
+** FULL - - JT_LEFT|JT_RIGHT|JT_OUTER
135444
+** FULL OUTER - JT_LEFT|JT_RIGHT|JT_OUTER
135445
+** NATURAL INNER - JT_NATURAL|JT_INNER
135446
+** NATURAL LEFT - JT_NATURAL|JT_LEFT|JT_OUTER
135447
+** NATURAL LEFT OUTER JT_NATURAL|JT_LEFT|JT_OUTER
135448
+** NATURAL RIGHT - JT_NATURAL|JT_RIGHT|JT_OUTER
135449
+** NATURAL RIGHT OUTER JT_NATURAL|JT_RIGHT|JT_OUTER
135450
+** NATURAL FULL - JT_NATURAL|JT_LEFT|JT_RIGHT
135451
+** NATURAL FULL OUTER JT_NATRUAL|JT_LEFT|JT_RIGHT
135452
+**
135453
+** To preserve historical compatibly, SQLite also accepts a variety
135454
+** of other non-standard and in many cases non-sensical join types.
135455
+** This routine makes as much sense at it can from the nonsense join
135456
+** type and returns a result. Examples of accepted nonsense join types
135457
+** include but are not limited to:
135458
+**
135459
+** INNER CROSS JOIN -> same as JOIN
135460
+** NATURAL CROSS JOIN -> same as NATURAL JOIN
135461
+** OUTER LEFT JOIN -> same as LEFT JOIN
135462
+** LEFT NATURAL JOIN -> same as NATURAL LEFT JOIN
135463
+** LEFT RIGHT JOIN -> same as FULL JOIN
135464
+** RIGHT OUTER FULL JOIN -> same as FULL JOIN
135465
+** CROSS CROSS CROSS JOIN -> same as JOIN
135466
+**
135467
+** The only restrictions on the join type name are:
135468
+**
135469
+** * "INNER" cannot appear together with "OUTER", "LEFT", "RIGHT",
135470
+** or "FULL".
135471
+**
135472
+** * "CROSS" cannot appear together with "OUTER", "LEFT", "RIGHT,
135473
+** or "FULL".
135474
+**
135475
+** * If "OUTER" is present then there must also be one of
135476
+** "LEFT", "RIGHT", or "FULL"
134737135477
*/
134738135478
SQLITE_PRIVATE int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){
134739135479
int jointype = 0;
134740135480
Token *apAll[3];
134741135481
Token *p;
@@ -134744,17 +135484,17 @@
134744135484
static const struct {
134745135485
u8 i; /* Beginning of keyword text in zKeyText[] */
134746135486
u8 nChar; /* Length of the keyword in characters */
134747135487
u8 code; /* Join type mask */
134748135488
} aKeyword[] = {
134749
- /* natural */ { 0, 7, JT_NATURAL },
134750
- /* left */ { 6, 4, JT_LEFT|JT_OUTER },
134751
- /* outer */ { 10, 5, JT_OUTER },
134752
- /* right */ { 14, 5, JT_RIGHT|JT_OUTER },
134753
- /* full */ { 19, 4, JT_LEFT|JT_RIGHT|JT_OUTER },
134754
- /* inner */ { 23, 5, JT_INNER },
134755
- /* cross */ { 28, 5, JT_INNER|JT_CROSS },
135489
+ /* (0) natural */ { 0, 7, JT_NATURAL },
135490
+ /* (1) left */ { 6, 4, JT_LEFT|JT_OUTER },
135491
+ /* (2) outer */ { 10, 5, JT_OUTER },
135492
+ /* (3) right */ { 14, 5, JT_RIGHT|JT_OUTER },
135493
+ /* (4) full */ { 19, 4, JT_LEFT|JT_RIGHT|JT_OUTER },
135494
+ /* (5) inner */ { 23, 5, JT_INNER },
135495
+ /* (6) cross */ { 28, 5, JT_INNER|JT_CROSS },
134756135496
};
134757135497
int i, j;
134758135498
apAll[0] = pA;
134759135499
apAll[1] = pB;
134760135500
apAll[2] = pC;
@@ -134773,22 +135513,19 @@
134773135513
break;
134774135514
}
134775135515
}
134776135516
if(
134777135517
(jointype & (JT_INNER|JT_OUTER))==(JT_INNER|JT_OUTER) ||
134778
- (jointype & JT_ERROR)!=0
135518
+ (jointype & JT_ERROR)!=0 ||
135519
+ (jointype & (JT_OUTER|JT_LEFT|JT_RIGHT))==JT_OUTER
134779135520
){
134780
- const char *zSp = " ";
134781
- assert( pB!=0 );
134782
- if( pC==0 ){ zSp++; }
134783
- sqlite3ErrorMsg(pParse, "unknown or unsupported join type: "
134784
- "%T %T%s%T", pA, pB, zSp, pC);
134785
- jointype = JT_INNER;
134786
- }else if( (jointype & JT_OUTER)!=0
134787
- && (jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ){
134788
- sqlite3ErrorMsg(pParse,
134789
- "RIGHT and FULL OUTER JOINs are not currently supported");
135521
+ const char *zSp1 = " ";
135522
+ const char *zSp2 = " ";
135523
+ if( pB==0 ){ zSp1++; }
135524
+ if( pC==0 ){ zSp2++; }
135525
+ sqlite3ErrorMsg(pParse, "unknown join type: "
135526
+ "%T%s%T%s%T", pA, zSp1, pB, zSp2, pC);
134790135527
jointype = JT_INNER;
134791135528
}
134792135529
return jointype;
134793135530
}
134794135531
@@ -134805,106 +135542,81 @@
134805135542
}
134806135543
return -1;
134807135544
}
134808135545
134809135546
/*
134810
-** Search the first N tables in pSrc, from left to right, looking for a
134811
-** table that has a column named zCol.
135547
+** Mark a subquery result column as having been used.
135548
+*/
135549
+SQLITE_PRIVATE void sqlite3SrcItemColumnUsed(SrcItem *pItem, int iCol){
135550
+ assert( pItem!=0 );
135551
+ assert( pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) );
135552
+ if( pItem->fg.isNestedFrom ){
135553
+ ExprList *pResults;
135554
+ assert( pItem->pSelect!=0 );
135555
+ pResults = pItem->pSelect->pEList;
135556
+ assert( pResults!=0 );
135557
+ assert( iCol>=0 && iCol<pResults->nExpr );
135558
+ pResults->a[iCol].bUsed = 1;
135559
+ }
135560
+}
135561
+
135562
+/*
135563
+** Search the tables iStart..iEnd (inclusive) in pSrc, looking for a
135564
+** table that has a column named zCol. The search is left-to-right.
135565
+** The first match found is returned.
134812135566
**
134813135567
** When found, set *piTab and *piCol to the table index and column index
134814135568
** of the matching column and return TRUE.
134815135569
**
134816135570
** If not found, return FALSE.
134817135571
*/
134818135572
static int tableAndColumnIndex(
134819135573
SrcList *pSrc, /* Array of tables to search */
134820
- int N, /* Number of tables in pSrc->a[] to search */
135574
+ int iStart, /* First member of pSrc->a[] to check */
135575
+ int iEnd, /* Last member of pSrc->a[] to check */
134821135576
const char *zCol, /* Name of the column we are looking for */
134822135577
int *piTab, /* Write index of pSrc->a[] here */
134823135578
int *piCol, /* Write index of pSrc->a[*piTab].pTab->aCol[] here */
134824
- int bIgnoreHidden /* True to ignore hidden columns */
135579
+ int bIgnoreHidden /* Ignore hidden columns */
134825135580
){
134826135581
int i; /* For looping over tables in pSrc */
134827135582
int iCol; /* Index of column matching zCol */
134828135583
135584
+ assert( iEnd<pSrc->nSrc );
135585
+ assert( iStart>=0 );
134829135586
assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */
134830
- for(i=0; i<N; i++){
135587
+
135588
+ for(i=iStart; i<=iEnd; i++){
134831135589
iCol = sqlite3ColumnIndex(pSrc->a[i].pTab, zCol);
134832135590
if( iCol>=0
134833135591
&& (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pTab->aCol[iCol])==0)
134834135592
){
134835135593
if( piTab ){
135594
+ sqlite3SrcItemColumnUsed(&pSrc->a[i], iCol);
134836135595
*piTab = i;
134837135596
*piCol = iCol;
134838135597
}
134839135598
return 1;
134840135599
}
134841135600
}
134842135601
return 0;
134843135602
}
134844135603
134845
-/*
134846
-** This function is used to add terms implied by JOIN syntax to the
134847
-** WHERE clause expression of a SELECT statement. The new term, which
134848
-** is ANDed with the existing WHERE clause, is of the form:
134849
-**
134850
-** (tab1.col1 = tab2.col2)
134851
-**
134852
-** where tab1 is the iSrc'th table in SrcList pSrc and tab2 is the
134853
-** (iSrc+1)'th. Column col1 is column iColLeft of tab1, and col2 is
134854
-** column iColRight of tab2.
134855
-*/
134856
-static void addWhereTerm(
134857
- Parse *pParse, /* Parsing context */
134858
- SrcList *pSrc, /* List of tables in FROM clause */
134859
- int iLeft, /* Index of first table to join in pSrc */
134860
- int iColLeft, /* Index of column in first table */
134861
- int iRight, /* Index of second table in pSrc */
134862
- int iColRight, /* Index of column in second table */
134863
- int isOuterJoin, /* True if this is an OUTER join */
134864
- Expr **ppWhere /* IN/OUT: The WHERE clause to add to */
134865
-){
134866
- sqlite3 *db = pParse->db;
134867
- Expr *pE1;
134868
- Expr *pE2;
134869
- Expr *pEq;
134870
-
134871
- assert( iLeft<iRight );
134872
- assert( pSrc->nSrc>iRight );
134873
- assert( pSrc->a[iLeft].pTab );
134874
- assert( pSrc->a[iRight].pTab );
134875
-
134876
- pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iColLeft);
134877
- pE2 = sqlite3CreateColumnExpr(db, pSrc, iRight, iColRight);
134878
-
134879
- pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2);
134880
- assert( pE2!=0 || pEq==0 ); /* Due to db->mallocFailed test
134881
- ** in sqlite3DbMallocRawNN() called from
134882
- ** sqlite3PExpr(). */
134883
- if( pEq && isOuterJoin ){
134884
- ExprSetProperty(pEq, EP_FromJoin);
134885
- assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) );
134886
- ExprSetVVAProperty(pEq, EP_NoReduce);
134887
- pEq->w.iRightJoinTable = pE2->iTable;
134888
- }
134889
- *ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq);
134890
-}
134891
-
134892135604
/*
134893135605
** Set the EP_FromJoin property on all terms of the given expression.
134894
-** And set the Expr.w.iRightJoinTable to iTable for every term in the
135606
+** And set the Expr.w.iJoin to iTable for every term in the
134895135607
** expression.
134896135608
**
134897135609
** The EP_FromJoin property is used on terms of an expression to tell
134898
-** the LEFT OUTER JOIN processing logic that this term is part of the
135610
+** the OUTER JOIN processing logic that this term is part of the
134899135611
** join restriction specified in the ON or USING clause and not a part
134900135612
** of the more general WHERE clause. These terms are moved over to the
134901135613
** WHERE clause during join processing but we need to remember that they
134902135614
** originated in the ON or USING clause.
134903135615
**
134904
-** The Expr.w.iRightJoinTable tells the WHERE clause processing that the
134905
-** expression depends on table w.iRightJoinTable even if that table is not
135616
+** The Expr.w.iJoin tells the WHERE clause processing that the
135617
+** expression depends on table w.iJoin even if that table is not
134906135618
** explicitly mentioned in the expression. That information is needed
134907135619
** for cases like this:
134908135620
**
134909135621
** SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.b AND t1.x=5
134910135622
**
@@ -134913,41 +135625,43 @@
134913135625
** NULL t2 row will be inserted whenever t1.x!=5. If we do not
134914135626
** defer the handling of t1.x=5, it will be processed immediately
134915135627
** after the t1 loop and rows with t1.x!=5 will never appear in
134916135628
** the output, which is incorrect.
134917135629
*/
134918
-SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr *p, int iTable){
135630
+SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr *p, int iTable, u32 joinFlag){
135631
+ assert( joinFlag==EP_FromJoin || joinFlag==EP_InnerJoin );
134919135632
while( p ){
134920
- ExprSetProperty(p, EP_FromJoin);
135633
+ ExprSetProperty(p, joinFlag);
134921135634
assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
134922135635
ExprSetVVAProperty(p, EP_NoReduce);
134923
- p->w.iRightJoinTable = iTable;
135636
+ p->w.iJoin = iTable;
134924135637
if( p->op==TK_FUNCTION ){
134925135638
assert( ExprUseXList(p) );
134926135639
if( p->x.pList ){
134927135640
int i;
134928135641
for(i=0; i<p->x.pList->nExpr; i++){
134929
- sqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable);
135642
+ sqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable, joinFlag);
134930135643
}
134931135644
}
134932135645
}
134933
- sqlite3SetJoinExpr(p->pLeft, iTable);
135646
+ sqlite3SetJoinExpr(p->pLeft, iTable, joinFlag);
134934135647
p = p->pRight;
134935135648
}
134936135649
}
134937135650
134938135651
/* Undo the work of sqlite3SetJoinExpr(). In the expression p, convert every
134939
-** term that is marked with EP_FromJoin and w.iRightJoinTable==iTable into
135652
+** term that is marked with EP_FromJoin and w.iJoin==iTable into
134940135653
** an ordinary term that omits the EP_FromJoin mark.
134941135654
**
134942135655
** This happens when a LEFT JOIN is simplified into an ordinary JOIN.
134943135656
*/
134944135657
static void unsetJoinExpr(Expr *p, int iTable){
134945135658
while( p ){
134946135659
if( ExprHasProperty(p, EP_FromJoin)
134947
- && (iTable<0 || p->w.iRightJoinTable==iTable) ){
135660
+ && (iTable<0 || p->w.iJoin==iTable) ){
134948135661
ExprClearProperty(p, EP_FromJoin);
135662
+ ExprSetProperty(p, EP_InnerJoin);
134949135663
}
134950135664
if( p->op==TK_COLUMN && p->iTable==iTable ){
134951135665
ExprClearProperty(p, EP_CanBeNull);
134952135666
}
134953135667
if( p->op==TK_FUNCTION ){
@@ -134964,23 +135678,30 @@
134964135678
}
134965135679
}
134966135680
134967135681
/*
134968135682
** This routine processes the join information for a SELECT statement.
134969
-** ON and USING clauses are converted into extra terms of the WHERE clause.
134970
-** NATURAL joins also create extra WHERE clause terms.
135683
+**
135684
+** * A NATURAL join is converted into a USING join. After that, we
135685
+** do not need to be concerned with NATURAL joins and we only have
135686
+** think about USING joins.
135687
+**
135688
+** * ON and USING clauses result in extra terms being added to the
135689
+** WHERE clause to enforce the specified constraints. The extra
135690
+** WHERE clause terms will be tagged with EP_FromJoin or
135691
+** EP_InnerJoin so that we know that they originated in ON/USING.
134971135692
**
134972135693
** The terms of a FROM clause are contained in the Select.pSrc structure.
134973135694
** The left most table is the first entry in Select.pSrc. The right-most
134974135695
** table is the last entry. The join operator is held in the entry to
134975
-** the left. Thus entry 0 contains the join operator for the join between
135696
+** the right. Thus entry 1 contains the join operator for the join between
134976135697
** entries 0 and 1. Any ON or USING clauses associated with the join are
134977
-** also attached to the left entry.
135698
+** also attached to the right entry.
134978135699
**
134979135700
** This routine returns the number of errors encountered.
134980135701
*/
134981
-static int sqliteProcessJoin(Parse *pParse, Select *p){
135702
+static int sqlite3ProcessJoin(Parse *pParse, Select *p){
134982135703
SrcList *pSrc; /* All tables in the FROM clause */
134983135704
int i, j; /* Loop counters */
134984135705
SrcItem *pLeft; /* Left table being joined */
134985135706
SrcItem *pRight; /* Right table being joined */
134986135707
@@ -134987,83 +135708,135 @@
134987135708
pSrc = p->pSrc;
134988135709
pLeft = &pSrc->a[0];
134989135710
pRight = &pLeft[1];
134990135711
for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){
134991135712
Table *pRightTab = pRight->pTab;
134992
- int isOuter;
135713
+ u32 joinType;
134993135714
134994135715
if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue;
134995
- isOuter = (pRight->fg.jointype & JT_OUTER)!=0;
135716
+ joinType = (pRight->fg.jointype & JT_OUTER)!=0 ? EP_FromJoin : EP_InnerJoin;
134996135717
134997
- /* When the NATURAL keyword is present, add WHERE clause terms for
134998
- ** every column that the two tables have in common.
135718
+ /* If this is a NATURAL join, synthesize an approprate USING clause
135719
+ ** to specify which columns should be joined.
134999135720
*/
135000135721
if( pRight->fg.jointype & JT_NATURAL ){
135001
- if( pRight->pOn || pRight->pUsing ){
135722
+ IdList *pUsing = 0;
135723
+ if( pRight->fg.isUsing || pRight->u3.pOn ){
135002135724
sqlite3ErrorMsg(pParse, "a NATURAL join may not have "
135003135725
"an ON or USING clause", 0);
135004135726
return 1;
135005135727
}
135006135728
for(j=0; j<pRightTab->nCol; j++){
135007135729
char *zName; /* Name of column in the right table */
135008
- int iLeft; /* Matching left table */
135009
- int iLeftCol; /* Matching column in the left table */
135010135730
135011135731
if( IsHiddenColumn(&pRightTab->aCol[j]) ) continue;
135012135732
zName = pRightTab->aCol[j].zCnName;
135013
- if( tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, 1) ){
135014
- addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, j,
135015
- isOuter, &p->pWhere);
135016
- }
135017
- }
135018
- }
135019
-
135020
- /* Disallow both ON and USING clauses in the same join
135021
- */
135022
- if( pRight->pOn && pRight->pUsing ){
135023
- sqlite3ErrorMsg(pParse, "cannot have both ON and USING "
135024
- "clauses in the same join");
135025
- return 1;
135026
- }
135027
-
135028
- /* Add the ON clause to the end of the WHERE clause, connected by
135029
- ** an AND operator.
135030
- */
135031
- if( pRight->pOn ){
135032
- if( isOuter ) sqlite3SetJoinExpr(pRight->pOn, pRight->iCursor);
135033
- p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->pOn);
135034
- pRight->pOn = 0;
135733
+ if( tableAndColumnIndex(pSrc, 0, i, zName, 0, 0, 1) ){
135734
+ pUsing = sqlite3IdListAppend(pParse, pUsing, 0);
135735
+ if( pUsing ){
135736
+ assert( pUsing->nId>0 );
135737
+ assert( pUsing->a[pUsing->nId-1].zName==0 );
135738
+ pUsing->a[pUsing->nId-1].zName = sqlite3DbStrDup(pParse->db, zName);
135739
+ }
135740
+ }
135741
+ }
135742
+ if( pUsing ){
135743
+ pRight->fg.isUsing = 1;
135744
+ pRight->fg.isSynthUsing = 1;
135745
+ pRight->u3.pUsing = pUsing;
135746
+ }
135747
+ if( pParse->nErr ) return 1;
135035135748
}
135036135749
135037135750
/* Create extra terms on the WHERE clause for each column named
135038135751
** in the USING clause. Example: If the two tables to be joined are
135039135752
** A and B and the USING clause names X, Y, and Z, then add this
135040135753
** to the WHERE clause: A.X=B.X AND A.Y=B.Y AND A.Z=B.Z
135041135754
** Report an error if any column mentioned in the USING clause is
135042135755
** not contained in both tables to be joined.
135043135756
*/
135044
- if( pRight->pUsing ){
135045
- IdList *pList = pRight->pUsing;
135757
+ if( pRight->fg.isUsing ){
135758
+ IdList *pList = pRight->u3.pUsing;
135759
+ sqlite3 *db = pParse->db;
135760
+ assert( pList!=0 );
135046135761
for(j=0; j<pList->nId; j++){
135047135762
char *zName; /* Name of the term in the USING clause */
135048135763
int iLeft; /* Table on the left with matching column name */
135049135764
int iLeftCol; /* Column number of matching column on the left */
135050135765
int iRightCol; /* Column number of matching column on the right */
135766
+ Expr *pE1; /* Reference to the column on the LEFT of the join */
135767
+ Expr *pE2; /* Reference to the column on the RIGHT of the join */
135768
+ Expr *pEq; /* Equality constraint. pE1 == pE2 */
135051135769
135052135770
zName = pList->a[j].zName;
135053135771
iRightCol = sqlite3ColumnIndex(pRightTab, zName);
135054135772
if( iRightCol<0
135055
- || !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, 0)
135773
+ || tableAndColumnIndex(pSrc, 0, i, zName, &iLeft, &iLeftCol,
135774
+ pRight->fg.isSynthUsing)==0
135056135775
){
135057135776
sqlite3ErrorMsg(pParse, "cannot join using column %s - column "
135058135777
"not present in both tables", zName);
135059135778
return 1;
135060135779
}
135061
- addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, iRightCol,
135062
- isOuter, &p->pWhere);
135780
+ pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol);
135781
+ sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol);
135782
+ if( (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){
135783
+ /* This branch runs if the query contains one or more RIGHT or FULL
135784
+ ** JOINs. If only a single table on the left side of this join
135785
+ ** contains the zName column, then this branch is a no-op.
135786
+ ** But if there are two or more tables on the left side
135787
+ ** of the join, construct a coalesce() function that gathers all
135788
+ ** such tables. Raise an error if more than one of those references
135789
+ ** to zName is not also within a prior USING clause.
135790
+ **
135791
+ ** We really ought to raise an error if there are two or more
135792
+ ** non-USING references to zName on the left of an INNER or LEFT
135793
+ ** JOIN. But older versions of SQLite do not do that, so we avoid
135794
+ ** adding a new error so as to not break legacy applications.
135795
+ */
135796
+ ExprList *pFuncArgs = 0; /* Arguments to the coalesce() */
135797
+ static const Token tkCoalesce = { "coalesce", 8 };
135798
+ while( tableAndColumnIndex(pSrc, iLeft+1, i, zName, &iLeft, &iLeftCol,
135799
+ pRight->fg.isSynthUsing)!=0 ){
135800
+ if( pSrc->a[iLeft].fg.isUsing==0
135801
+ || sqlite3IdListIndex(pSrc->a[iLeft].u3.pUsing, zName)<0
135802
+ ){
135803
+ sqlite3ErrorMsg(pParse, "ambiguous reference to %s in USING()",
135804
+ zName);
135805
+ break;
135806
+ }
135807
+ pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1);
135808
+ pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol);
135809
+ sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol);
135810
+ }
135811
+ if( pFuncArgs ){
135812
+ pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1);
135813
+ pE1 = sqlite3ExprFunction(pParse, pFuncArgs, &tkCoalesce, 0);
135814
+ }
135815
+ }
135816
+ pE2 = sqlite3CreateColumnExpr(db, pSrc, i+1, iRightCol);
135817
+ sqlite3SrcItemColumnUsed(pRight, iRightCol);
135818
+ pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2);
135819
+ assert( pE2!=0 || pEq==0 );
135820
+ if( pEq ){
135821
+ ExprSetProperty(pEq, joinType);
135822
+ assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) );
135823
+ ExprSetVVAProperty(pEq, EP_NoReduce);
135824
+ pEq->w.iJoin = pE2->iTable;
135825
+ }
135826
+ p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pEq);
135063135827
}
135064135828
}
135829
+
135830
+ /* Add the ON clause to the end of the WHERE clause, connected by
135831
+ ** an AND operator.
135832
+ */
135833
+ else if( pRight->u3.pOn ){
135834
+ sqlite3SetJoinExpr(pRight->u3.pOn, pRight->iCursor, joinType);
135835
+ p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->u3.pOn);
135836
+ pRight->u3.pOn = 0;
135837
+ }
135065135838
}
135066135839
return 0;
135067135840
}
135068135841
135069135842
/*
@@ -136628,16 +137401,17 @@
136628137401
assert( nCol==(i16)nCol );
136629137402
*pnCol = nCol;
136630137403
*paCol = aCol;
136631137404
136632137405
for(i=0, pCol=aCol; i<nCol && !db->mallocFailed; i++, pCol++){
137406
+ struct ExprList_item *pX = &pEList->a[i];
136633137407
/* Get an appropriate name for the column
136634137408
*/
136635
- if( (zName = pEList->a[i].zEName)!=0 && pEList->a[i].eEName==ENAME_NAME ){
137409
+ if( (zName = pX->zEName)!=0 && pX->eEName==ENAME_NAME ){
136636137410
/* If the column contains an "AS <name>" phrase, use <name> as the name */
136637137411
}else{
136638
- Expr *pColExpr = sqlite3ExprSkipCollateAndLikely(pEList->a[i].pExpr);
137412
+ Expr *pColExpr = sqlite3ExprSkipCollateAndLikely(pX->pExpr);
136639137413
while( ALWAYS(pColExpr!=0) && pColExpr->op==TK_DOT ){
136640137414
pColExpr = pColExpr->pRight;
136641137415
assert( pColExpr!=0 );
136642137416
}
136643137417
if( pColExpr->op==TK_COLUMN
@@ -136651,11 +137425,11 @@
136651137425
}else if( pColExpr->op==TK_ID ){
136652137426
assert( !ExprHasProperty(pColExpr, EP_IntValue) );
136653137427
zName = pColExpr->u.zToken;
136654137428
}else{
136655137429
/* Use the original text of the column expression as its name */
136656
- zName = pEList->a[i].zEName;
137430
+ assert( zName==pX->zEName ); /* pointer comparison intended */
136657137431
}
136658137432
}
136659137433
if( zName && !sqlite3IsTrueOrFalse(zName) ){
136660137434
zName = sqlite3DbStrDup(db, zName);
136661137435
}else{
@@ -138144,16 +138918,44 @@
138144138918
/* An instance of the SubstContext object describes an substitution edit
138145138919
** to be performed on a parse tree.
138146138920
**
138147138921
** All references to columns in table iTable are to be replaced by corresponding
138148138922
** expressions in pEList.
138923
+**
138924
+** ## About "isOuterJoin":
138925
+**
138926
+** The isOuterJoin column indicates that the replacement will occur into a
138927
+** position in the parent that NULL-able due to an OUTER JOIN. Either the
138928
+** target slot in the parent is the right operand of a LEFT JOIN, or one of
138929
+** the left operands of a RIGHT JOIN. In either case, we need to potentially
138930
+** bypass the substituted expression with OP_IfNullRow.
138931
+**
138932
+** Suppose the original expression integer constant. Even though the table
138933
+** has the nullRow flag set, because the expression is an integer constant,
138934
+** it will not be NULLed out. So instead, we insert an OP_IfNullRow opcode
138935
+** that checks to see if the nullRow flag is set on the table. If the nullRow
138936
+** flag is set, then the value in the register is set to NULL and the original
138937
+** expression is bypassed. If the nullRow flag is not set, then the original
138938
+** expression runs to populate the register.
138939
+**
138940
+** Example where this is needed:
138941
+**
138942
+** CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT);
138943
+** CREATE TABLE t2(x INT UNIQUE);
138944
+**
138945
+** SELECT a,b,m,x FROM t1 LEFT JOIN (SELECT 59 AS m,x FROM t2) ON b=x;
138946
+**
138947
+** When the subquery on the right side of the LEFT JOIN is flattened, we
138948
+** have to add OP_IfNullRow in front of the OP_Integer that implements the
138949
+** "m" value of the subquery so that a NULL will be loaded instead of 59
138950
+** when processing a non-matched row of the left.
138149138951
*/
138150138952
typedef struct SubstContext {
138151138953
Parse *pParse; /* The parsing context */
138152138954
int iTable; /* Replace references to this table */
138153138955
int iNewTable; /* New table number */
138154
- int isLeftJoin; /* Add TK_IF_NULL_ROW opcodes on each replacement */
138956
+ int isOuterJoin; /* Add TK_IF_NULL_ROW opcodes on each replacement */
138155138957
ExprList *pEList; /* Replacement expressions */
138156138958
} SubstContext;
138157138959
138158138960
/* Forward Declarations */
138159138961
static void substExprList(SubstContext*, ExprList*);
@@ -138176,13 +138978,13 @@
138176138978
SubstContext *pSubst, /* Description of the substitution */
138177138979
Expr *pExpr /* Expr in which substitution occurs */
138178138980
){
138179138981
if( pExpr==0 ) return 0;
138180138982
if( ExprHasProperty(pExpr, EP_FromJoin)
138181
- && pExpr->w.iRightJoinTable==pSubst->iTable
138983
+ && pExpr->w.iJoin==pSubst->iTable
138182138984
){
138183
- pExpr->w.iRightJoinTable = pSubst->iNewTable;
138985
+ pExpr->w.iJoin = pSubst->iNewTable;
138184138986
}
138185138987
if( pExpr->op==TK_COLUMN
138186138988
&& pExpr->iTable==pSubst->iTable
138187138989
&& !ExprHasProperty(pExpr, EP_FixedCol)
138188138990
){
@@ -138199,11 +139001,11 @@
138199139001
assert( pExpr->pRight==0 );
138200139002
if( sqlite3ExprIsVector(pCopy) ){
138201139003
sqlite3VectorErrorMsg(pSubst->pParse, pCopy);
138202139004
}else{
138203139005
sqlite3 *db = pSubst->pParse->db;
138204
- if( pSubst->isLeftJoin && pCopy->op!=TK_COLUMN ){
139006
+ if( pSubst->isOuterJoin && pCopy->op!=TK_COLUMN ){
138205139007
memset(&ifNullRow, 0, sizeof(ifNullRow));
138206139008
ifNullRow.op = TK_IF_NULL_ROW;
138207139009
ifNullRow.pLeft = pCopy;
138208139010
ifNullRow.iTable = pSubst->iNewTable;
138209139011
ifNullRow.flags = EP_IfNullRow;
@@ -138213,15 +139015,16 @@
138213139015
pNew = sqlite3ExprDup(db, pCopy, 0);
138214139016
if( db->mallocFailed ){
138215139017
sqlite3ExprDelete(db, pNew);
138216139018
return pExpr;
138217139019
}
138218
- if( pSubst->isLeftJoin ){
139020
+ if( pSubst->isOuterJoin ){
138219139021
ExprSetProperty(pNew, EP_CanBeNull);
138220139022
}
138221
- if( ExprHasProperty(pExpr,EP_FromJoin) ){
138222
- sqlite3SetJoinExpr(pNew, pExpr->w.iRightJoinTable);
139023
+ if( ExprHasProperty(pExpr,EP_FromJoin|EP_InnerJoin) ){
139024
+ sqlite3SetJoinExpr(pNew, pExpr->w.iJoin,
139025
+ pExpr->flags & (EP_FromJoin|EP_InnerJoin));
138223139026
}
138224139027
sqlite3ExprDelete(db, pExpr);
138225139028
pExpr = pNew;
138226139029
138227139030
/* Ensure that the expression now has an implicit collation sequence,
@@ -138382,11 +139185,11 @@
138382139185
int op = pExpr->op;
138383139186
if( op==TK_COLUMN || op==TK_IF_NULL_ROW ){
138384139187
renumberCursorDoMapping(pWalker, &pExpr->iTable);
138385139188
}
138386139189
if( ExprHasProperty(pExpr, EP_FromJoin) ){
138387
- renumberCursorDoMapping(pWalker, &pExpr->w.iRightJoinTable);
139190
+ renumberCursorDoMapping(pWalker, &pExpr->w.iJoin);
138388139191
}
138389139192
return WRC_Continue;
138390139193
}
138391139194
138392139195
/*
@@ -138467,10 +139270,11 @@
138467139270
** (3a) the subquery may not be a join and
138468139271
** (3b) the FROM clause of the subquery may not contain a virtual
138469139272
** table and
138470139273
** (3c) the outer query may not be an aggregate.
138471139274
** (3d) the outer query may not be DISTINCT.
139275
+** See also (26) for restrictions on RIGHT JOIN.
138472139276
**
138473139277
** (4) The subquery can not be DISTINCT.
138474139278
**
138475139279
** (**) At one point restrictions (4) and (5) defined a subset of DISTINCT
138476139280
** sub-queries that were excluded from this optimization. Restriction
@@ -138565,10 +139369,16 @@
138565139369
**
138566139370
** (25) If either the subquery or the parent query contains a window
138567139371
** function in the select list or ORDER BY clause, flattening
138568139372
** is not attempted.
138569139373
**
139374
+** (26) The subquery may not be the right operand of a RIGHT JOIN.
139375
+** See also (3) for restrictions on LEFT JOIN.
139376
+**
139377
+** (27) The subquery may not contain a FULL or RIGHT JOIN unless it
139378
+** is the first element of the parent query.
139379
+**
138570139380
**
138571139381
** In this routine, the "p" parameter is a pointer to the outer query.
138572139382
** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query
138573139383
** uses aggregates.
138574139384
**
@@ -138590,11 +139400,11 @@
138590139400
Select *pSub1; /* Pointer to the rightmost select in sub-query */
138591139401
SrcList *pSrc; /* The FROM clause of the outer query */
138592139402
SrcList *pSubSrc; /* The FROM clause of the subquery */
138593139403
int iParent; /* VDBE cursor number of the pSub result set temp table */
138594139404
int iNewParent = -1;/* Replacement table for iParent */
138595
- int isLeftJoin = 0; /* True if pSub is the right side of a LEFT JOIN */
139405
+ int isOuterJoin = 0; /* True if pSub is the right side of a LEFT JOIN */
138596139406
int i; /* Loop counter */
138597139407
Expr *pWhere; /* The WHERE clause */
138598139408
SrcItem *pSubitem; /* The subquery */
138599139409
sqlite3 *db = pParse->db;
138600139410
Walker w; /* Walker to persist agginfo data */
@@ -138663,29 +139473,35 @@
138663139473
** aggregates are processed - there is no mechanism to determine if
138664139474
** the LEFT JOIN table should be all-NULL.
138665139475
**
138666139476
** See also tickets #306, #350, and #3300.
138667139477
*/
138668
- if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){
138669
- isLeftJoin = 1;
138670
- if( pSubSrc->nSrc>1 /* (3a) */
138671
- || isAgg /* (3b) */
138672
- || IsVirtual(pSubSrc->a[0].pTab) /* (3c) */
138673
- || (p->selFlags & SF_Distinct)!=0 /* (3d) */
139478
+ if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){
139479
+ if( pSubSrc->nSrc>1 /* (3a) */
139480
+ || isAgg /* (3b) */
139481
+ || IsVirtual(pSubSrc->a[0].pTab) /* (3c) */
139482
+ || (p->selFlags & SF_Distinct)!=0 /* (3d) */
139483
+ || (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */
138674139484
){
138675139485
return 0;
138676139486
}
139487
+ isOuterJoin = 1;
138677139488
}
138678139489
#ifdef SQLITE_EXTRA_IFNULLROW
138679139490
else if( iFrom>0 && !isAgg ){
138680
- /* Setting isLeftJoin to -1 causes OP_IfNullRow opcodes to be generated for
139491
+ /* Setting isOuterJoin to -1 causes OP_IfNullRow opcodes to be generated for
138681139492
** every reference to any result column from subquery in a join, even
138682139493
** though they are not necessary. This will stress-test the OP_IfNullRow
138683139494
** opcode. */
138684
- isLeftJoin = -1;
139495
+ isOuterJoin = -1;
138685139496
}
138686139497
#endif
139498
+
139499
+ assert( pSubSrc->nSrc>0 ); /* True by restriction (7) */
139500
+ if( iFrom>0 && (pSubSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){
139501
+ return 0; /* Restriction (27) */
139502
+ }
138687139503
138688139504
/* Restriction (17): If the sub-query is a compound SELECT, then it must
138689139505
** use only the UNION ALL operator. And none of the simple select queries
138690139506
** that make up the compound SELECT are allowed to be aggregate or distinct
138691139507
** queries.
@@ -138692,11 +139508,11 @@
138692139508
*/
138693139509
if( pSub->pPrior ){
138694139510
if( pSub->pOrderBy ){
138695139511
return 0; /* Restriction (20) */
138696139512
}
138697
- if( isAgg || (p->selFlags & SF_Distinct)!=0 || isLeftJoin>0 ){
139513
+ if( isAgg || (p->selFlags & SF_Distinct)!=0 || isOuterJoin>0 ){
138698139514
return 0; /* (17d1), (17d2), or (17f) */
138699139515
}
138700139516
for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){
138701139517
testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
138702139518
testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
@@ -138750,11 +139566,11 @@
138750139566
sqlite3DbFree(db, pSubitem->zAlias);
138751139567
pSubitem->zDatabase = 0;
138752139568
pSubitem->zName = 0;
138753139569
pSubitem->zAlias = 0;
138754139570
pSubitem->pSelect = 0;
138755
- assert( pSubitem->pOn==0 );
139571
+ assert( pSubitem->fg.isUsing!=0 || pSubitem->u3.pOn==0 );
138756139572
138757139573
/* If the sub-query is a compound SELECT statement, then (by restrictions
138758139574
** 17 and 18 above) it must be a UNION ALL and the parent query must
138759139575
** be of the form:
138760139576
**
@@ -138860,10 +139676,11 @@
138860139676
*/
138861139677
pSub = pSub1;
138862139678
for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){
138863139679
int nSubSrc;
138864139680
u8 jointype = 0;
139681
+ u8 ltorj = pSrc->a[iFrom].fg.jointype & JT_LTORJ;
138865139682
assert( pSub!=0 );
138866139683
pSubSrc = pSub->pSrc; /* FROM clause of subquery */
138867139684
nSubSrc = pSubSrc->nSrc; /* Number of terms in subquery FROM clause */
138868139685
pSrc = pParent->pSrc; /* FROM clause of the outer query */
138869139686
@@ -138894,17 +139711,20 @@
138894139711
138895139712
/* Transfer the FROM clause terms from the subquery into the
138896139713
** outer query.
138897139714
*/
138898139715
for(i=0; i<nSubSrc; i++){
138899
- sqlite3IdListDelete(db, pSrc->a[i+iFrom].pUsing);
138900
- assert( pSrc->a[i+iFrom].fg.isTabFunc==0 );
138901
- pSrc->a[i+iFrom] = pSubSrc->a[i];
139716
+ SrcItem *pItem = &pSrc->a[i+iFrom];
139717
+ if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing);
139718
+ assert( pItem->fg.isTabFunc==0 );
139719
+ *pItem = pSubSrc->a[i];
139720
+ pItem->fg.jointype |= ltorj;
138902139721
iNewParent = pSubSrc->a[i].iCursor;
138903139722
memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
138904139723
}
138905
- pSrc->a[iFrom].fg.jointype = jointype;
139724
+ pSrc->a[iFrom].fg.jointype &= JT_LTORJ;
139725
+ pSrc->a[iFrom].fg.jointype |= jointype | ltorj;
138906139726
138907139727
/* Now begin substituting subquery result set expressions for
138908139728
** references to the iParent in the outer query.
138909139729
**
138910139730
** Example:
@@ -138935,12 +139755,12 @@
138935139755
pParent->pOrderBy = pOrderBy;
138936139756
pSub->pOrderBy = 0;
138937139757
}
138938139758
pWhere = pSub->pWhere;
138939139759
pSub->pWhere = 0;
138940
- if( isLeftJoin>0 ){
138941
- sqlite3SetJoinExpr(pWhere, iNewParent);
139760
+ if( isOuterJoin>0 ){
139761
+ sqlite3SetJoinExpr(pWhere, iNewParent, EP_FromJoin);
138942139762
}
138943139763
if( pWhere ){
138944139764
if( pParent->pWhere ){
138945139765
pParent->pWhere = sqlite3PExpr(pParse, TK_AND, pWhere, pParent->pWhere);
138946139766
}else{
@@ -138950,11 +139770,11 @@
138950139770
if( db->mallocFailed==0 ){
138951139771
SubstContext x;
138952139772
x.pParse = pParse;
138953139773
x.iTable = iParent;
138954139774
x.iNewTable = iNewParent;
138955
- x.isLeftJoin = isLeftJoin;
139775
+ x.isOuterJoin = isOuterJoin;
138956139776
x.pEList = pSub->pEList;
138957139777
substSelect(&x, pParent, 0);
138958139778
}
138959139779
138960139780
/* The flattened query is a compound if either the inner or the
@@ -138985,12 +139805,12 @@
138985139805
*/
138986139806
sqlite3AggInfoPersistWalkerInit(&w, pParse);
138987139807
sqlite3WalkSelect(&w,pSub1);
138988139808
sqlite3SelectDelete(db, pSub1);
138989139809
138990
-#if SELECTTRACE_ENABLED
138991
- if( sqlite3SelectTrace & 0x100 ){
139810
+#if TREETRACE_ENABLED
139811
+ if( sqlite3TreeTrace & 0x100 ){
138992139812
SELECTTRACE(0x100,pParse,p,("After flattening:\n"));
138993139813
sqlite3TreeViewSelect(0, p, 0);
138994139814
}
138995139815
#endif
138996139816
@@ -139392,16 +140212,16 @@
139392140212
iCursor, isLeftJoin);
139393140213
pWhere = pWhere->pLeft;
139394140214
}
139395140215
if( isLeftJoin
139396140216
&& (ExprHasProperty(pWhere,EP_FromJoin)==0
139397
- || pWhere->w.iRightJoinTable!=iCursor)
140217
+ || pWhere->w.iJoin!=iCursor)
139398140218
){
139399140219
return 0; /* restriction (4) */
139400140220
}
139401140221
if( ExprHasProperty(pWhere,EP_FromJoin)
139402
- && pWhere->w.iRightJoinTable!=iCursor
140222
+ && pWhere->w.iJoin!=iCursor
139403140223
){
139404140224
return 0; /* restriction (5) */
139405140225
}
139406140226
if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){
139407140227
nChng++;
@@ -139411,11 +140231,11 @@
139411140231
pNew = sqlite3ExprDup(pParse->db, pWhere, 0);
139412140232
unsetJoinExpr(pNew, -1);
139413140233
x.pParse = pParse;
139414140234
x.iTable = iCursor;
139415140235
x.iNewTable = iCursor;
139416
- x.isLeftJoin = 0;
140236
+ x.isOuterJoin = 0;
139417140237
x.pEList = pSubq->pEList;
139418140238
pNew = substExpr(&x, pNew);
139419140239
#ifndef SQLITE_OMIT_WINDOWFUNC
139420140240
if( pSubq->pWin && 0==pushDownWindowCheck(pParse, pSubq, pNew) ){
139421140241
/* Restriction 6c has prevented push-down in this case */
@@ -139620,11 +140440,11 @@
139620140440
pParse = pWalker->pParse;
139621140441
db = pParse->db;
139622140442
pNew = sqlite3DbMallocZero(db, sizeof(*pNew) );
139623140443
if( pNew==0 ) return WRC_Abort;
139624140444
memset(&dummy, 0, sizeof(dummy));
139625
- pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0,0);
140445
+ pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0);
139626140446
if( pNewSrc==0 ) return WRC_Abort;
139627140447
*pNew = *p;
139628140448
p->pSrc = pNewSrc;
139629140449
p->pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ASTERISK, 0));
139630140450
p->op = TK_SELECT;
@@ -139965,14 +140785,38 @@
139965140785
/* The usual case - do not allow ROWID on a subquery */
139966140786
pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid;
139967140787
#else
139968140788
pTab->tabFlags |= TF_Ephemeral; /* Legacy compatibility mode */
139969140789
#endif
139970
-
139971
-
139972140790
return pParse->nErr ? SQLITE_ERROR : SQLITE_OK;
139973140791
}
140792
+
140793
+
140794
+/*
140795
+** Check the N SrcItem objects to the right of pBase. (N might be zero!)
140796
+** If any of those SrcItem objects have a USING clause containing zName
140797
+** then return true.
140798
+**
140799
+** If N is zero, or none of the N SrcItem objects to the right of pBase
140800
+** contains a USING clause, or if none of the USING clauses contain zName,
140801
+** then return false.
140802
+*/
140803
+static int inAnyUsingClause(
140804
+ const char *zName, /* Name we are looking for */
140805
+ SrcItem *pBase, /* The base SrcItem. Looking at pBase[1] and following */
140806
+ int N /* How many SrcItems to check */
140807
+){
140808
+ while( N>0 ){
140809
+ N--;
140810
+ pBase++;
140811
+ if( pBase->fg.isUsing==0 ) continue;
140812
+ if( NEVER(pBase->u3.pUsing==0) ) continue;
140813
+ if( sqlite3IdListIndex(pBase->u3.pUsing, zName)>=0 ) return 1;
140814
+ }
140815
+ return 0;
140816
+}
140817
+
139974140818
139975140819
/*
139976140820
** This routine is a Walker callback for "expanding" a SELECT statement.
139977140821
** "Expanding" means to do the following:
139978140822
**
@@ -140119,11 +140963,11 @@
140119140963
}
140120140964
140121140965
/* Process NATURAL keywords, and ON and USING clauses of joins.
140122140966
*/
140123140967
assert( db->mallocFailed==0 || pParse->nErr!=0 );
140124
- if( pParse->nErr || sqliteProcessJoin(pParse, p) ){
140968
+ if( pParse->nErr || sqlite3ProcessJoin(pParse, p) ){
140125140969
return WRC_Abort;
140126140970
}
140127140971
140128140972
/* For every "*" that occurs in the column list, insert the names of
140129140973
** all columns in all tables. And for every TABLE.* insert the names
@@ -140183,31 +141027,34 @@
140183141027
assert( !ExprHasProperty(pE->pLeft, EP_IntValue) );
140184141028
zTName = pE->pLeft->u.zToken;
140185141029
}
140186141030
for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
140187141031
Table *pTab = pFrom->pTab;
140188
- Select *pSub = pFrom->pSelect;
141032
+ Select *pSub;
140189141033
char *zTabName = pFrom->zAlias;
140190141034
const char *zSchemaName = 0;
140191141035
int iDb;
140192141036
if( zTabName==0 ){
140193141037
zTabName = pTab->zName;
140194141038
}
140195141039
if( db->mallocFailed ) break;
140196
- if( pSub==0 || (pSub->selFlags & SF_NestedFrom)==0 ){
141040
+ assert( pFrom->fg.isNestedFrom == IsNestedFrom(pFrom->pSelect) );
141041
+ if( pFrom->fg.isNestedFrom ){
141042
+ pSub = pFrom->pSelect;
141043
+ assert( pSub->pEList!=0 );
141044
+ assert( pSub->pEList->nExpr==pTab->nCol );
141045
+ }else{
140197141046
pSub = 0;
140198141047
if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
140199141048
continue;
140200141049
}
140201141050
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
140202141051
zSchemaName = iDb>=0 ? db->aDb[iDb].zDbSName : "*";
140203141052
}
140204141053
for(j=0; j<pTab->nCol; j++){
140205141054
char *zName = pTab->aCol[j].zCnName;
140206
- char *zColname; /* The computed column name */
140207
- char *zToFree; /* Malloced string that needs to be freed */
140208
- Token sColname; /* Computed column name as a token */
141055
+ struct ExprList_item *pX; /* Newly added ExprList term */
140209141056
140210141057
assert( zName );
140211141058
if( zTName && pSub
140212141059
&& sqlite3MatchEName(&pSub->pEList->a[j], 0, zTName, 0)==0
140213141060
){
@@ -140224,58 +141071,62 @@
140224141071
continue;
140225141072
}
140226141073
tableSeen = 1;
140227141074
140228141075
if( i>0 && zTName==0 ){
140229
- if( (pFrom->fg.jointype & JT_NATURAL)!=0
140230
- && tableAndColumnIndex(pTabList, i, zName, 0, 0, 1)
141076
+ if( pFrom->fg.isUsing
141077
+ && sqlite3IdListIndex(pFrom->u3.pUsing, zName)>=0
140231141078
){
140232
- /* In a NATURAL join, omit the join columns from the
140233
- ** table to the right of the join */
140234
- continue;
140235
- }
140236
- if( sqlite3IdListIndex(pFrom->pUsing, zName)>=0 ){
140237141079
/* In a join with a USING clause, omit columns in the
140238141080
** using clause from the table on the right. */
140239141081
continue;
140240141082
}
140241141083
}
140242141084
pRight = sqlite3Expr(db, TK_ID, zName);
140243
- zColname = zName;
140244
- zToFree = 0;
140245
- if( longNames || pTabList->nSrc>1 ){
141085
+ if( (pTabList->nSrc>1
141086
+ && ( (pFrom->fg.jointype & JT_LTORJ)==0
141087
+ || !inAnyUsingClause(zName,pFrom,pTabList->nSrc-i-1)
141088
+ )
141089
+ )
141090
+ || IN_RENAME_OBJECT
141091
+ ){
140246141092
Expr *pLeft;
140247141093
pLeft = sqlite3Expr(db, TK_ID, zTabName);
140248141094
pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
141095
+ if( IN_RENAME_OBJECT && pE->pLeft ){
141096
+ sqlite3RenameTokenRemap(pParse, pLeft, pE->pLeft);
141097
+ }
140249141098
if( zSchemaName ){
140250141099
pLeft = sqlite3Expr(db, TK_ID, zSchemaName);
140251141100
pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pExpr);
140252141101
}
140253
- if( longNames ){
140254
- zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName);
140255
- zToFree = zColname;
140256
- }
140257141102
}else{
140258141103
pExpr = pRight;
140259141104
}
140260141105
pNew = sqlite3ExprListAppend(pParse, pNew, pExpr);
140261
- sqlite3TokenInit(&sColname, zColname);
140262
- sqlite3ExprListSetName(pParse, pNew, &sColname, 0);
140263
- if( pNew && (p->selFlags & SF_NestedFrom)!=0 && !IN_RENAME_OBJECT ){
140264
- struct ExprList_item *pX = &pNew->a[pNew->nExpr-1];
140265
- sqlite3DbFree(db, pX->zEName);
141106
+ if( pNew==0 ){
141107
+ break; /* OOM */
141108
+ }
141109
+ pX = &pNew->a[pNew->nExpr-1];
141110
+ assert( pX->zEName==0 );
141111
+ if( (selFlags & SF_NestedFrom)!=0 && !IN_RENAME_OBJECT ){
140266141112
if( pSub ){
140267141113
pX->zEName = sqlite3DbStrDup(db, pSub->pEList->a[j].zEName);
140268141114
testcase( pX->zEName==0 );
140269141115
}else{
140270141116
pX->zEName = sqlite3MPrintf(db, "%s.%s.%s",
140271
- zSchemaName, zTabName, zColname);
141117
+ zSchemaName, zTabName, zName);
140272141118
testcase( pX->zEName==0 );
140273141119
}
140274141120
pX->eEName = ENAME_TAB;
141121
+ }else if( longNames ){
141122
+ pX->zEName = sqlite3MPrintf(db, "%s.%s", zTabName, zName);
141123
+ pX->eEName = ENAME_NAME;
141124
+ }else{
141125
+ pX->zEName = sqlite3DbStrDup(db, zName);
141126
+ pX->eEName = ENAME_NAME;
140275141127
}
140276
- sqlite3DbFree(db, zToFree);
140277141128
}
140278141129
}
140279141130
if( !tableSeen ){
140280141131
if( zTName ){
140281141132
sqlite3ErrorMsg(pParse, "no such table: %s", zTName);
@@ -140295,10 +141146,16 @@
140295141146
}
140296141147
if( (elistFlags & (EP_HasFunc|EP_Subquery))!=0 ){
140297141148
p->selFlags |= SF_ComplexResult;
140298141149
}
140299141150
}
141151
+#if TREETRACE_ENABLED
141152
+ if( sqlite3TreeTrace & 0x100 ){
141153
+ SELECTTRACE(0x100,pParse,p,("After result-set wildcard expansion:\n"));
141154
+ sqlite3TreeViewSelect(0, p, 0);
141155
+ }
141156
+#endif
140300141157
return WRC_Continue;
140301141158
}
140302141159
140303141160
#if SQLITE_DEBUG
140304141161
/*
@@ -140685,12 +141542,12 @@
140685141542
memset(&sWalker, 0, sizeof(sWalker));
140686141543
sWalker.pParse = pParse;
140687141544
sWalker.xExprCallback = havingToWhereExprCb;
140688141545
sWalker.u.pSelect = p;
140689141546
sqlite3WalkExpr(&sWalker, p->pHaving);
140690
-#if SELECTTRACE_ENABLED
140691
- if( sWalker.eCode && (sqlite3SelectTrace & 0x100)!=0 ){
141547
+#if TREETRACE_ENABLED
141548
+ if( sWalker.eCode && (sqlite3TreeTrace & 0x100)!=0 ){
140692141549
SELECTTRACE(0x100,pParse,p,("Move HAVING terms into WHERE:\n"));
140693141550
sqlite3TreeViewSelect(0, p, 0);
140694141551
}
140695141552
#endif
140696141553
}
@@ -140818,12 +141675,12 @@
140818141675
pSub = pPrior;
140819141676
}
140820141677
p->pEList->a[0].pExpr = pExpr;
140821141678
p->selFlags &= ~SF_Aggregate;
140822141679
140823
-#if SELECTTRACE_ENABLED
140824
- if( sqlite3SelectTrace & 0x400 ){
141680
+#if TREETRACE_ENABLED
141681
+ if( sqlite3TreeTrace & 0x400 ){
140825141682
SELECTTRACE(0x400,pParse,p,("After count-of-view optimization:\n"));
140826141683
sqlite3TreeViewSelect(0, p, 0);
140827141684
}
140828141685
#endif
140829141686
return 1;
@@ -140872,14 +141729,18 @@
140872141729
if( p==0 || pParse->nErr ){
140873141730
return 1;
140874141731
}
140875141732
assert( db->mallocFailed==0 );
140876141733
if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
140877
-#if SELECTTRACE_ENABLED
141734
+#if TREETRACE_ENABLED
140878141735
SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain));
140879
- if( sqlite3SelectTrace & 0x100 ){
140880
- sqlite3TreeViewSelect(0, p, 0);
141736
+ if( sqlite3TreeTrace & 0x10100 ){
141737
+ if( (sqlite3TreeTrace & 0x10001)==0x10000 ){
141738
+ sqlite3TreeViewLine(0, "In sqlite3Select() at %s:%d",
141739
+ __FILE__, __LINE__);
141740
+ }
141741
+ sqlite3ShowSelect(p);
140881141742
}
140882141743
#endif
140883141744
140884141745
assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo );
140885141746
assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo );
@@ -140889,13 +141750,13 @@
140889141750
assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union ||
140890141751
pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard ||
140891141752
pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_DistFifo );
140892141753
/* All of these destinations are also able to ignore the ORDER BY clause */
140893141754
if( p->pOrderBy ){
140894
-#if SELECTTRACE_ENABLED
141755
+#if TREETRACE_ENABLED
140895141756
SELECTTRACE(1,pParse,p, ("dropping superfluous ORDER BY:\n"));
140896
- if( sqlite3SelectTrace & 0x100 ){
141757
+ if( sqlite3TreeTrace & 0x100 ){
140897141758
sqlite3TreeViewExprList(0, p->pOrderBy, 0, "ORDERBY");
140898141759
}
140899141760
#endif
140900141761
sqlite3ParserAddCleanup(pParse,
140901141762
(void(*)(sqlite3*,void*))sqlite3ExprListDelete,
@@ -140910,12 +141771,12 @@
140910141771
if( pParse->nErr ){
140911141772
goto select_end;
140912141773
}
140913141774
assert( db->mallocFailed==0 );
140914141775
assert( p->pEList!=0 );
140915
-#if SELECTTRACE_ENABLED
140916
- if( sqlite3SelectTrace & 0x104 ){
141776
+#if TREETRACE_ENABLED
141777
+ if( sqlite3TreeTrace & 0x104 ){
140917141778
SELECTTRACE(0x104,pParse,p, ("after name resolution:\n"));
140918141779
sqlite3TreeViewSelect(0, p, 0);
140919141780
}
140920141781
#endif
140921141782
@@ -140955,12 +141816,12 @@
140955141816
#ifndef SQLITE_OMIT_WINDOWFUNC
140956141817
if( sqlite3WindowRewrite(pParse, p) ){
140957141818
assert( pParse->nErr );
140958141819
goto select_end;
140959141820
}
140960
-#if SELECTTRACE_ENABLED
140961
- if( p->pWin && (sqlite3SelectTrace & 0x108)!=0 ){
141821
+#if TREETRACE_ENABLED
141822
+ if( p->pWin && (sqlite3TreeTrace & 0x108)!=0 ){
140962141823
SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n"));
140963141824
sqlite3TreeViewSelect(0, p, 0);
140964141825
}
140965141826
#endif
140966141827
#endif /* SQLITE_OMIT_WINDOWFUNC */
@@ -140984,11 +141845,11 @@
140984141845
assert( pTab!=0 );
140985141846
140986141847
/* Convert LEFT JOIN into JOIN if there are terms of the right table
140987141848
** of the LEFT JOIN used in the WHERE clause.
140988141849
*/
140989
- if( (pItem->fg.jointype & JT_LEFT)!=0
141850
+ if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==JT_LEFT
140990141851
&& sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor)
140991141852
&& OptimizationEnabled(db, SQLITE_SimplifyJoin)
140992141853
){
140993141854
SELECTTRACE(0x100,pParse,p,
140994141855
("LEFT-JOIN simplifies to JOIN on term %d\n",i));
@@ -141070,11 +141931,11 @@
141070141931
*/
141071141932
if( pSub->pOrderBy!=0
141072141933
&& i==0
141073141934
&& (p->selFlags & SF_ComplexResult)!=0
141074141935
&& (pTabList->nSrc==1
141075
- || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0)
141936
+ || (pTabList->a[1].fg.jointype&(JT_OUTER|JT_CROSS))!=0)
141076141937
){
141077141938
continue;
141078141939
}
141079141940
141080141941
if( flattenSubquery(pParse, p, i, isAgg) ){
@@ -141094,13 +141955,13 @@
141094141955
/* Handle compound SELECT statements using the separate multiSelect()
141095141956
** procedure.
141096141957
*/
141097141958
if( p->pPrior ){
141098141959
rc = multiSelect(pParse, p, pDest);
141099
-#if SELECTTRACE_ENABLED
141960
+#if TREETRACE_ENABLED
141100141961
SELECTTRACE(0x1,pParse,p,("end compound-select processing\n"));
141101
- if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
141962
+ if( (sqlite3TreeTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
141102141963
sqlite3TreeViewSelect(0, p, 0);
141103141964
}
141104141965
#endif
141105141966
if( p->pNext==0 ) ExplainQueryPlanPop(pParse);
141106141967
return rc;
@@ -141115,12 +141976,12 @@
141115141976
if( p->pWhere!=0
141116141977
&& p->pWhere->op==TK_AND
141117141978
&& OptimizationEnabled(db, SQLITE_PropagateConst)
141118141979
&& propagateConstants(pParse, p)
141119141980
){
141120
-#if SELECTTRACE_ENABLED
141121
- if( sqlite3SelectTrace & 0x100 ){
141981
+#if TREETRACE_ENABLED
141982
+ if( sqlite3TreeTrace & 0x100 ){
141122141983
SELECTTRACE(0x100,pParse,p,("After constant propagation:\n"));
141123141984
sqlite3TreeViewSelect(0, p, 0);
141124141985
}
141125141986
#endif
141126141987
}else{
@@ -141192,15 +142053,16 @@
141192142053
** inside the subquery. This can help the subquery to run more efficiently.
141193142054
*/
141194142055
if( OptimizationEnabled(db, SQLITE_PushDown)
141195142056
&& (pItem->fg.isCte==0
141196142057
|| (pItem->u2.pCteUse->eM10d!=M10d_Yes && pItem->u2.pCteUse->nUse<2))
142058
+ && (pItem->fg.jointype & JT_RIGHT)==0
141197142059
&& pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor,
141198142060
(pItem->fg.jointype & JT_OUTER)!=0)
141199142061
){
141200
-#if SELECTTRACE_ENABLED
141201
- if( sqlite3SelectTrace & 0x100 ){
142062
+#if TREETRACE_ENABLED
142063
+ if( sqlite3TreeTrace & 0x100 ){
141202142064
SELECTTRACE(0x100,pParse,p,
141203142065
("After WHERE-clause push-down into subquery %d:\n", pSub->selId));
141204142066
sqlite3TreeViewSelect(0, p, 0);
141205142067
}
141206142068
#endif
@@ -141212,22 +142074,23 @@
141212142074
zSavedAuthContext = pParse->zAuthContext;
141213142075
pParse->zAuthContext = pItem->zName;
141214142076
141215142077
/* Generate code to implement the subquery
141216142078
**
141217
- ** The subquery is implemented as a co-routine if:
142079
+ ** The subquery is implemented as a co-routine all of the following are
142080
+ ** true:
142081
+ **
141218142082
** (1) the subquery is guaranteed to be the outer loop (so that
141219142083
** it does not need to be computed more than once), and
141220142084
** (2) the subquery is not a CTE that should be materialized
141221
- **
141222
- ** TODO: Are there other reasons beside (1) and (2) to use a co-routine
141223
- ** implementation?
142085
+ ** (3) the subquery is not part of a left operand for a RIGHT JOIN
141224142086
*/
141225142087
if( i==0
141226142088
&& (pTabList->nSrc==1
141227
- || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0) /* (1) */
141228
- && (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d!=M10d_Yes) /* (2) */
142089
+ || (pTabList->a[1].fg.jointype&(JT_OUTER|JT_CROSS))!=0) /* (1) */
142090
+ && (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d!=M10d_Yes) /* (2) */
142091
+ && (pTabList->a[0].fg.jointype & JT_LTORJ)==0 /* (3) */
141229142092
){
141230142093
/* Implement a co-routine that will return a single row of the result
141231142094
** set on each invocation.
141232142095
*/
141233142096
int addrTop = sqlite3VdbeCurrentAddr(v)+1;
@@ -141314,12 +142177,12 @@
141314142177
pWhere = p->pWhere;
141315142178
pGroupBy = p->pGroupBy;
141316142179
pHaving = p->pHaving;
141317142180
sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0;
141318142181
141319
-#if SELECTTRACE_ENABLED
141320
- if( sqlite3SelectTrace & 0x400 ){
142182
+#if TREETRACE_ENABLED
142183
+ if( sqlite3TreeTrace & 0x400 ){
141321142184
SELECTTRACE(0x400,pParse,p,("After all FROM-clause analysis:\n"));
141322142185
sqlite3TreeViewSelect(0, p, 0);
141323142186
}
141324142187
#endif
141325142188
@@ -141351,12 +142214,12 @@
141351142214
** the sDistinct.isTnct is still set. Hence, isTnct represents the
141352142215
** original setting of the SF_Distinct flag, not the current setting */
141353142216
assert( sDistinct.isTnct );
141354142217
sDistinct.isTnct = 2;
141355142218
141356
-#if SELECTTRACE_ENABLED
141357
- if( sqlite3SelectTrace & 0x400 ){
142219
+#if TREETRACE_ENABLED
142220
+ if( sqlite3TreeTrace & 0x400 ){
141358142221
SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n"));
141359142222
sqlite3TreeViewSelect(0, p, 0);
141360142223
}
141361142224
#endif
141362142225
}
@@ -141385,10 +142248,22 @@
141385142248
141386142249
/* If the output is destined for a temporary table, open that table.
141387142250
*/
141388142251
if( pDest->eDest==SRT_EphemTab ){
141389142252
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr);
142253
+ if( p->selFlags & SF_NestedFrom ){
142254
+ /* Delete or NULL-out result columns that will never be used */
142255
+ int ii;
142256
+ for(ii=pEList->nExpr-1; ii>0 && pEList->a[ii].bUsed==0; ii--){
142257
+ sqlite3ExprDelete(db, pEList->a[ii].pExpr);
142258
+ sqlite3DbFree(db, pEList->a[ii].zEName);
142259
+ pEList->nExpr--;
142260
+ }
142261
+ for(ii=0; ii<pEList->nExpr; ii++){
142262
+ if( pEList->a[ii].bUsed==0 ) pEList->a[ii].pExpr->op = TK_NULL;
142263
+ }
142264
+ }
141390142265
}
141391142266
141392142267
/* Set the limiter.
141393142268
*/
141394142269
iEnd = sqlite3VdbeMakeLabel(pParse);
@@ -141604,12 +142479,12 @@
141604142479
#endif
141605142480
sNC.ncFlags &= ~NC_InAggFunc;
141606142481
}
141607142482
pAggInfo->mxReg = pParse->nMem;
141608142483
if( db->mallocFailed ) goto select_end;
141609
-#if SELECTTRACE_ENABLED
141610
- if( sqlite3SelectTrace & 0x400 ){
142484
+#if TREETRACE_ENABLED
142485
+ if( sqlite3TreeTrace & 0x400 ){
141611142486
int ii;
141612142487
SELECTTRACE(0x400,pParse,p,("After aggregate analysis %p:\n", pAggInfo));
141613142488
sqlite3TreeViewSelect(0, p, 0);
141614142489
if( minMaxFlag ){
141615142490
sqlite3DebugPrintf("MIN/MAX Optimization (0x%02x) adds:\n", minMaxFlag);
@@ -142001,11 +142876,13 @@
142001142876
SELECTTRACE(1,pParse,p,("WhereBegin returns\n"));
142002142877
eDist = sqlite3WhereIsDistinct(pWInfo);
142003142878
updateAccumulator(pParse, regAcc, pAggInfo, eDist);
142004142879
if( eDist!=WHERE_DISTINCT_NOOP ){
142005142880
struct AggInfo_func *pF = &pAggInfo->aFunc[0];
142006
- fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr);
142881
+ if( pF ){
142882
+ fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr);
142883
+ }
142007142884
}
142008142885
142009142886
if( regAcc ) sqlite3VdbeAddOp2(v, OP_Integer, 1, regAcc);
142010142887
if( minMaxFlag ){
142011142888
sqlite3WhereMinMaxOptEarlyOut(v, pWInfo);
@@ -142068,13 +142945,13 @@
142068142945
assert( pExpr->iAgg==i );
142069142946
}
142070142947
}
142071142948
#endif
142072142949
142073
-#if SELECTTRACE_ENABLED
142950
+#if TREETRACE_ENABLED
142074142951
SELECTTRACE(0x1,pParse,p,("end processing\n"));
142075
- if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
142952
+ if( (sqlite3TreeTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
142076142953
sqlite3TreeViewSelect(0, p, 0);
142077142954
}
142078142955
#endif
142079142956
ExplainQueryPlanPop(pParse);
142080142957
return rc;
@@ -142335,13 +143212,11 @@
142335143212
SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){
142336143213
Schema *pTmpSchema; /* Schema of the pTab table */
142337143214
Trigger *pList; /* List of triggers to return */
142338143215
HashElem *p; /* Loop variable for TEMP triggers */
142339143216
142340
- if( pParse->disableTriggers ){
142341
- return 0;
142342
- }
143217
+ assert( pParse->disableTriggers==0 );
142343143218
pTmpSchema = pParse->db->aDb[1].pSchema;
142344143219
p = sqliteHashFirst(&pTmpSchema->trigHash);
142345143220
pList = pTab->pTrigger;
142346143221
while( p ){
142347143222
Trigger *pTrig = (Trigger *)sqliteHashData(p);
@@ -143011,18 +143886,27 @@
143011143886
for(e=0; e<pEList->nExpr; e++){
143012143887
if( sqlite3IdListIndex(pIdList, pEList->a[e].zEName)>=0 ) return 1;
143013143888
}
143014143889
return 0;
143015143890
}
143891
+
143892
+/*
143893
+** Return true if any TEMP triggers exist
143894
+*/
143895
+static int tempTriggersExist(sqlite3 *db){
143896
+ if( NEVER(db->aDb[1].pSchema==0) ) return 0;
143897
+ if( sqliteHashFirst(&db->aDb[1].pSchema->trigHash)==0 ) return 0;
143898
+ return 1;
143899
+}
143016143900
143017143901
/*
143018143902
** Return a list of all triggers on table pTab if there exists at least
143019143903
** one trigger that must be fired when an operation of type 'op' is
143020143904
** performed on the table, and, if that operation is an UPDATE, if at
143021143905
** least one of the columns in pChanges is being modified.
143022143906
*/
143023
-SQLITE_PRIVATE Trigger *sqlite3TriggersExist(
143907
+static SQLITE_NOINLINE Trigger *triggersReallyExist(
143024143908
Parse *pParse, /* Parse context */
143025143909
Table *pTab, /* The table the contains the triggers */
143026143910
int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */
143027143911
ExprList *pChanges, /* Columns that change in an UPDATE statement */
143028143912
int *pMask /* OUT: Mask of TRIGGER_BEFORE|TRIGGER_AFTER */
@@ -143081,10 +143965,26 @@
143081143965
if( pMask ){
143082143966
*pMask = mask;
143083143967
}
143084143968
return (mask ? pList : 0);
143085143969
}
143970
+SQLITE_PRIVATE Trigger *sqlite3TriggersExist(
143971
+ Parse *pParse, /* Parse context */
143972
+ Table *pTab, /* The table the contains the triggers */
143973
+ int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */
143974
+ ExprList *pChanges, /* Columns that change in an UPDATE statement */
143975
+ int *pMask /* OUT: Mask of TRIGGER_BEFORE|TRIGGER_AFTER */
143976
+){
143977
+ assert( pTab!=0 );
143978
+ if( (pTab->pTrigger==0 && !tempTriggersExist(pParse->db))
143979
+ || pParse->disableTriggers
143980
+ ){
143981
+ if( pMask ) *pMask = 0;
143982
+ return 0;
143983
+ }
143984
+ return triggersReallyExist(pParse,pTab,op,pChanges,pMask);
143985
+}
143086143986
143087143987
/*
143088143988
** Convert the pStep->zTarget string into a SrcList and return a pointer
143089143989
** to that SrcList.
143090143990
**
@@ -144088,10 +144988,18 @@
144088144988
#endif
144089144989
#ifdef SQLITE_OMIT_VIEW
144090144990
# undef isView
144091144991
# define isView 0
144092144992
#endif
144993
+
144994
+#if TREETRACE_ENABLED
144995
+ if( sqlite3TreeTrace & 0x10000 ){
144996
+ sqlite3TreeViewLine(0, "In sqlite3Update() at %s:%d", __FILE__, __LINE__);
144997
+ sqlite3TreeViewUpdate(pParse->pWith, pTabList, pChanges, pWhere,
144998
+ onError, pOrderBy, pLimit, pUpsert, pTrigger);
144999
+ }
145000
+#endif
144093145001
144094145002
/* If there was a FROM clause, set nChangeFrom to the number of expressions
144095145003
** in the change-list. Otherwise, set it to 0. There cannot be a FROM
144096145004
** clause if this function is being called to generate code for part of
144097145005
** an UPSERT statement. */
@@ -147181,10 +148089,31 @@
147181148089
typedef struct WhereTerm WhereTerm;
147182148090
typedef struct WhereLoopBuilder WhereLoopBuilder;
147183148091
typedef struct WhereScan WhereScan;
147184148092
typedef struct WhereOrCost WhereOrCost;
147185148093
typedef struct WhereOrSet WhereOrSet;
148094
+typedef struct WhereMemBlock WhereMemBlock;
148095
+typedef struct WhereRightJoin WhereRightJoin;
148096
+
148097
+/*
148098
+** This object is a header on a block of allocated memory that will be
148099
+** automatically freed when its WInfo oject is destructed.
148100
+*/
148101
+struct WhereMemBlock {
148102
+ WhereMemBlock *pNext; /* Next block in the chain */
148103
+ u8 sz; /* Bytes of space */
148104
+};
148105
+
148106
+/*
148107
+** Extra information attached to a WhereLevel that is a RIGHT JOIN.
148108
+*/
148109
+struct WhereRightJoin {
148110
+ int iMatch; /* Cursor used to determine prior matched rows */
148111
+ int regBloom; /* Bloom filter for iRJMatch */
148112
+ int regReturn; /* Return register for the interior subroutine */
148113
+ int addrSubrtn; /* Starting address for the interior subroutine */
148114
+};
147186148115
147187148116
/*
147188148117
** This object contains information needed to implement a single nested
147189148118
** loop in WHERE clause.
147190148119
**
@@ -147214,10 +148143,11 @@
147214148143
#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
147215148144
u32 iLikeRepCntr; /* LIKE range processing counter register (times 2) */
147216148145
int addrLikeRep; /* LIKE range processing address */
147217148146
#endif
147218148147
int regFilter; /* Bloom filter */
148148
+ WhereRightJoin *pRJ; /* Extra information for RIGHT JOIN */
147219148149
u8 iFrom; /* Which entry in the FROM clause */
147220148150
u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */
147221148151
int p1, p2; /* Operands of the opcode used to end the loop */
147222148152
union { /* Information that depends on pWLoop->wsFlags */
147223148153
struct {
@@ -147627,10 +148557,11 @@
147627148557
LogEst nRowOut; /* Estimated number of output rows */
147628148558
int iTop; /* The very beginning of the WHERE loop */
147629148559
int iEndWhere; /* End of the WHERE clause itself */
147630148560
WhereLoop *pLoops; /* List of all WhereLoop objects */
147631148561
WhereExprMod *pExprMods; /* Expression modifications */
148562
+ WhereMemBlock *pMemToFree;/* Memory to free when this object destroyed */
147632148563
Bitmask revMask; /* Mask of ORDER BY terms that need reversing */
147633148564
WhereClause sWC; /* Decomposition of the WHERE clause */
147634148565
WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */
147635148566
WhereLevel a[1]; /* Information about each nest loop in WHERE */
147636148567
};
@@ -147652,10 +148583,12 @@
147652148583
int iColumn, /* Column number of LHS */
147653148584
Bitmask notReady, /* RHS must not overlap with this mask */
147654148585
u32 op, /* Mask of WO_xx values describing operator */
147655148586
Index *pIdx /* Must be compatible with this index, if not NULL */
147656148587
);
148588
+SQLITE_PRIVATE void *sqlite3WhereMalloc(WhereInfo *pWInfo, u64 nByte);
148589
+SQLITE_PRIVATE void *sqlite3WhereRealloc(WhereInfo *pWInfo, void *pOld, u64 nByte);
147657148590
147658148591
/* wherecode.c: */
147659148592
#ifndef SQLITE_OMIT_EXPLAIN
147660148593
SQLITE_PRIVATE int sqlite3WhereExplainOneScan(
147661148594
Parse *pParse, /* Parse context */
@@ -147687,10 +148620,15 @@
147687148620
Vdbe *v, /* Prepared statement under construction */
147688148621
WhereInfo *pWInfo, /* Complete information about the WHERE clause */
147689148622
int iLevel, /* Which level of pWInfo->a[] should be coded */
147690148623
WhereLevel *pLevel, /* The current level pointer */
147691148624
Bitmask notReady /* Which tables are currently available */
148625
+);
148626
+SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop(
148627
+ WhereInfo *pWInfo,
148628
+ int iLevel,
148629
+ WhereLevel *pLevel
147692148630
);
147693148631
147694148632
/* whereexpr.c: */
147695148633
SQLITE_PRIVATE void sqlite3WhereClauseInit(WhereClause*,WhereInfo*);
147696148634
SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause*);
@@ -147955,10 +148893,13 @@
147955148893
else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
147956148894
sqlite3_str_appendf(&str, " VIRTUAL TABLE INDEX %d:%s",
147957148895
pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
147958148896
}
147959148897
#endif
148898
+ if( pItem->fg.jointype & JT_LEFT ){
148899
+ sqlite3_str_appendf(&str, " LEFT-JOIN");
148900
+ }
147960148901
#ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS
147961148902
if( pLoop->nOut>=10 ){
147962148903
sqlite3_str_appendf(&str, " (~%llu rows)",
147963148904
sqlite3LogEstToInt(pLoop->nOut));
147964148905
}else{
@@ -148391,12 +149332,13 @@
148391149332
}
148392149333
148393149334
i = pLevel->u.in.nIn;
148394149335
pLevel->u.in.nIn += nEq;
148395149336
pLevel->u.in.aInLoop =
148396
- sqlite3DbReallocOrFree(pParse->db, pLevel->u.in.aInLoop,
148397
- sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn);
149337
+ sqlite3WhereRealloc(pTerm->pWC->pWInfo,
149338
+ pLevel->u.in.aInLoop,
149339
+ sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn);
148398149340
pIn = pLevel->u.in.aInLoop;
148399149341
if( pIn ){
148400149342
int iMap = 0; /* Index in aiMap[] */
148401149343
pIn += i;
148402149344
for(i=iEq;i<pLoop->nLTerm; i++){
@@ -148814,11 +149756,11 @@
148814149756
** are also excluded. See codeCursorHintIsOrFunction() for details.
148815149757
*/
148816149758
if( pTabItem->fg.jointype & JT_LEFT ){
148817149759
Expr *pExpr = pTerm->pExpr;
148818149760
if( !ExprHasProperty(pExpr, EP_FromJoin)
148819
- || pExpr->w.iRightJoinTable!=pTabItem->iCursor
149761
+ || pExpr->w.iJoin!=pTabItem->iCursor
148820149762
){
148821149763
sWalker.eCode = 0;
148822149764
sWalker.xExprCallback = codeCursorHintIsOrFunction;
148823149765
sqlite3WalkExpr(&sWalker, pTerm->pExpr);
148824149766
if( sWalker.eCode ) continue;
@@ -148900,11 +149842,11 @@
148900149842
assert( iIdxCur>0 );
148901149843
assert( pIdx->aiColumn[pIdx->nColumn-1]==-1 );
148902149844
148903149845
pWInfo->bDeferredSeek = 1;
148904149846
sqlite3VdbeAddOp3(v, OP_DeferredSeek, iIdxCur, 0, iCur);
148905
- if( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)
149847
+ if( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))
148906149848
&& DbMaskAllZero(sqlite3ParseToplevel(pParse)->writeMask)
148907149849
){
148908149850
int i;
148909149851
Table *pTab = pIdx->pTable;
148910149852
u32 *ai = (u32*)sqlite3DbMallocZero(pParse->db, sizeof(u32)*(pTab->nCol+1));
@@ -149252,11 +150194,11 @@
149252150194
149253150195
/* If this is the right table of a LEFT OUTER JOIN, allocate and
149254150196
** initialize a memory cell that records if this table matches any
149255150197
** row of the left table of the join.
149256150198
*/
149257
- assert( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)
150199
+ assert( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))
149258150200
|| pLevel->iFrom>0 || (pTabItem[0].fg.jointype & JT_LEFT)==0
149259150201
);
149260150202
if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){
149261150203
pLevel->iLeftJoin = ++pParse->nMem;
149262150204
sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin);
@@ -149263,11 +150205,14 @@
149263150205
VdbeComment((v, "init LEFT JOIN no-match flag"));
149264150206
}
149265150207
149266150208
/* Compute a safe address to jump to if we discover that the table for
149267150209
** this loop is empty and can never contribute content. */
149268
- for(j=iLevel; j>0 && pWInfo->a[j].iLeftJoin==0; j--){}
150210
+ for(j=iLevel; j>0; j--){
150211
+ if( pWInfo->a[j].iLeftJoin ) break;
150212
+ if( pWInfo->a[j].pRJ ) break;
150213
+ }
149269150214
addrHalt = pWInfo->a[j].addrBrk;
149270150215
149271150216
/* Special case of a FROM clause subquery implemented as a co-routine */
149272150217
if( pTabItem->fg.viaCoroutine ){
149273150218
int regYield = pTabItem->regReturn;
@@ -149890,11 +150835,11 @@
149890150835
sqlite3VdbeAddOp3(v, OP_SeekHit, iIdxCur, nEq, nEq);
149891150836
}
149892150837
149893150838
/* Seek the table cursor, if required */
149894150839
omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0
149895
- && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0;
150840
+ && (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))==0;
149896150841
if( omitTable ){
149897150842
/* pIdx is a covering index. No need to access the main table. */
149898150843
}else if( HasRowid(pIdx->pTable) ){
149899150844
codeDeferredSeek(pWInfo, pIdx, iCur, iIdxCur);
149900150845
}else if( iCur!=iIdxCur ){
@@ -149924,11 +150869,11 @@
149924150869
** Also, do not do this when processing one index an a multi-index
149925150870
** OR clause, since the transformation will become invalid once we
149926150871
** move forward to the next index.
149927150872
** https://sqlite.org/src/info/4e8e4857d32d401f
149928150873
*/
149929
- if( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){
150874
+ if( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))==0 ){
149930150875
whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo);
149931150876
}
149932150877
149933150878
/* If a partial index is driving the loop, try to eliminate WHERE clause
149934150879
** terms from the query that must be true due to the WHERE clause of
@@ -149943,11 +150888,11 @@
149943150888
}else{
149944150889
testcase( pIdx->pPartIdxWhere );
149945150890
/* The following assert() is not a requirement, merely an observation:
149946150891
** The OR-optimization doesn't work for the right hand table of
149947150892
** a LEFT JOIN: */
149948
- assert( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 );
150893
+ assert( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))==0 );
149949150894
}
149950150895
149951150896
/* Record the instruction used to terminate the loop. */
149952150897
if( pLoop->wsFlags & WHERE_ONEROW ){
149953150898
pLevel->op = OP_Noop;
@@ -150284,10 +151229,18 @@
150284151229
sqlite3ExprDelete(db, pAndExpr);
150285151230
}
150286151231
sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
150287151232
sqlite3VdbeGoto(v, pLevel->addrBrk);
150288151233
sqlite3VdbeResolveLabel(v, iLoopBody);
151234
+
151235
+ /* Set the P2 operand of the OP_Return opcode that will end the current
151236
+ ** loop to point to this spot, which is the top of the next containing
151237
+ ** loop. The byte-code formatter will use that P2 value as a hint to
151238
+ ** indent everything in between the this point and the final OP_Return.
151239
+ ** See tag-20220407a in vdbe.c and shell.c */
151240
+ assert( pLevel->op==OP_Return );
151241
+ pLevel->p2 = sqlite3VdbeCurrentAddr(v);
150289151242
150290151243
if( pWInfo->nLevel>1 ){ sqlite3StackFree(db, pOrTab); }
150291151244
if( !untestedTerms ) disableTerm(pLevel, pTerm);
150292151245
}else
150293151246
#endif /* SQLITE_OMIT_OR_OPTIMIZATION */
@@ -150347,11 +151300,13 @@
150347151300
pWInfo->untestedTerms = 1;
150348151301
continue;
150349151302
}
150350151303
pE = pTerm->pExpr;
150351151304
assert( pE!=0 );
150352
- if( (pTabItem->fg.jointype&JT_LEFT) && !ExprHasProperty(pE,EP_FromJoin) ){
151305
+ if( (pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ))
151306
+ && !ExprHasProperty(pE,EP_FromJoin)
151307
+ ){
150353151308
continue;
150354151309
}
150355151310
150356151311
if( iLoop==1 && !sqlite3ExprCoveredByIndex(pE, pLevel->iTabCur, pIdx) ){
150357151312
iNext = 2;
@@ -150409,11 +151364,11 @@
150409151364
WhereTerm *pAlt;
150410151365
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
150411151366
if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue;
150412151367
if( (pTerm->eOperator & WO_EQUIV)==0 ) continue;
150413151368
if( pTerm->leftCursor!=iCur ) continue;
150414
- if( pTabItem->fg.jointype & JT_LEFT ) continue;
151369
+ if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ) ) continue;
150415151370
pE = pTerm->pExpr;
150416151371
#ifdef WHERETRACE_ENABLED /* 0x800 */
150417151372
if( sqlite3WhereTrace & 0x800 ){
150418151373
sqlite3DebugPrintf("Coding transitive constraint:\n");
150419151374
sqlite3WhereTermPrint(pTerm, pWC->nTerm-j);
@@ -150439,10 +151394,51 @@
150439151394
sEAlt = *pAlt->pExpr;
150440151395
sEAlt.pLeft = pE->pLeft;
150441151396
sqlite3ExprIfFalse(pParse, &sEAlt, addrCont, SQLITE_JUMPIFNULL);
150442151397
pAlt->wtFlags |= TERM_CODED;
150443151398
}
151399
+
151400
+ /* For a RIGHT OUTER JOIN, record the fact that the current row has
151401
+ ** been matched at least once.
151402
+ */
151403
+ if( pLevel->pRJ ){
151404
+ Table *pTab;
151405
+ int nPk;
151406
+ int r;
151407
+ int jmp1 = 0;
151408
+ WhereRightJoin *pRJ = pLevel->pRJ;
151409
+
151410
+ /* pTab is the right-hand table of the RIGHT JOIN. Generate code that
151411
+ ** will record that the current row of that table has been matched at
151412
+ ** least once. This is accomplished by storing the PK for the row in
151413
+ ** both the iMatch index and the regBloom Bloom filter.
151414
+ */
151415
+ pTab = pWInfo->pTabList->a[pLevel->iFrom].pTab;
151416
+ if( HasRowid(pTab) ){
151417
+ r = sqlite3GetTempRange(pParse, 2);
151418
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, pLevel->iTabCur, -1, r+1);
151419
+ nPk = 1;
151420
+ }else{
151421
+ int iPk;
151422
+ Index *pPk = sqlite3PrimaryKeyIndex(pTab);
151423
+ nPk = pPk->nKeyCol;
151424
+ r = sqlite3GetTempRange(pParse, nPk+1);
151425
+ for(iPk=0; iPk<nPk; iPk++){
151426
+ int iCol = pPk->aiColumn[iPk];
151427
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+1+iPk);
151428
+ }
151429
+ }
151430
+ jmp1 = sqlite3VdbeAddOp4Int(v, OP_Found, pRJ->iMatch, 0, r+1, nPk);
151431
+ VdbeCoverage(v);
151432
+ VdbeComment((v, "match against %s", pTab->zName));
151433
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, r+1, nPk, r);
151434
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pRJ->iMatch, r, r+1, nPk);
151435
+ sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pRJ->regBloom, 0, r+1, nPk);
151436
+ sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
151437
+ sqlite3VdbeJumpHere(v, jmp1);
151438
+ sqlite3ReleaseTempRange(pParse, r, nPk+1);
151439
+ }
150444151440
150445151441
/* For a LEFT OUTER JOIN, generate code that will record the fact that
150446151442
** at least one row of the right table has matched the left table.
150447151443
*/
150448151444
if( pLevel->iLeftJoin ){
@@ -150455,15 +151451,30 @@
150455151451
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
150456151452
if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
150457151453
assert( pWInfo->untestedTerms );
150458151454
continue;
150459151455
}
151456
+ if( pTabItem->fg.jointype & JT_LTORJ ) continue;
150460151457
assert( pTerm->pExpr );
150461151458
sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
150462151459
pTerm->wtFlags |= TERM_CODED;
150463151460
}
150464151461
}
151462
+
151463
+ if( pLevel->pRJ ){
151464
+ /* Create a subroutine used to process all interior loops and code
151465
+ ** of the RIGHT JOIN. During normal operation, the subroutine will
151466
+ ** be in-line with the rest of the code. But at the end, a separate
151467
+ ** loop will run that invokes this subroutine for unmatched rows
151468
+ ** of pTab, with all tables to left begin set to NULL.
151469
+ */
151470
+ WhereRightJoin *pRJ = pLevel->pRJ;
151471
+ sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pRJ->regReturn);
151472
+ pRJ->addrSubrtn = sqlite3VdbeCurrentAddr(v);
151473
+ assert( pParse->withinRJSubrtn < 255 );
151474
+ pParse->withinRJSubrtn++;
151475
+ }
150465151476
150466151477
#if WHERETRACE_ENABLED /* 0x20800 */
150467151478
if( sqlite3WhereTrace & 0x20000 ){
150468151479
sqlite3DebugPrintf("All WHERE-clause terms after coding level %d:\n",
150469151480
iLevel);
@@ -150474,10 +151485,94 @@
150474151485
iLevel, (u64)pLevel->notReady);
150475151486
}
150476151487
#endif
150477151488
return pLevel->notReady;
150478151489
}
151490
+
151491
+/*
151492
+** Generate the code for the loop that finds all non-matched terms
151493
+** for a RIGHT JOIN.
151494
+*/
151495
+SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop(
151496
+ WhereInfo *pWInfo,
151497
+ int iLevel,
151498
+ WhereLevel *pLevel
151499
+){
151500
+ Parse *pParse = pWInfo->pParse;
151501
+ Vdbe *v = pParse->pVdbe;
151502
+ WhereRightJoin *pRJ = pLevel->pRJ;
151503
+ Expr *pSubWhere = 0;
151504
+ WhereClause *pWC = &pWInfo->sWC;
151505
+ WhereInfo *pSubWInfo;
151506
+ WhereLoop *pLoop = pLevel->pWLoop;
151507
+ SrcItem *pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
151508
+ SrcList sFrom;
151509
+ Bitmask mAll = 0;
151510
+ int k;
151511
+
151512
+ ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pTab->zName));
151513
+ for(k=0; k<iLevel; k++){
151514
+ int iIdxCur;
151515
+ mAll |= pWInfo->a[k].pWLoop->maskSelf;
151516
+ sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur);
151517
+ iIdxCur = pWInfo->a[k].iIdxCur;
151518
+ if( iIdxCur ){
151519
+ sqlite3VdbeAddOp1(v, OP_NullRow, iIdxCur);
151520
+ }
151521
+ }
151522
+ if( (pTabItem->fg.jointype & JT_LTORJ)==0 ){
151523
+ mAll |= pLoop->maskSelf;
151524
+ for(k=0; k<pWC->nTerm; k++){
151525
+ WhereTerm *pTerm = &pWC->a[k];
151526
+ if( pTerm->wtFlags & TERM_VIRTUAL ) break;
151527
+ if( pTerm->prereqAll & ~mAll ) continue;
151528
+ if( ExprHasProperty(pTerm->pExpr, EP_FromJoin|EP_InnerJoin) ) continue;
151529
+ pSubWhere = sqlite3ExprAnd(pParse, pSubWhere,
151530
+ sqlite3ExprDup(pParse->db, pTerm->pExpr, 0));
151531
+ }
151532
+ }
151533
+ sFrom.nSrc = 1;
151534
+ sFrom.nAlloc = 1;
151535
+ memcpy(&sFrom.a[0], pTabItem, sizeof(SrcItem));
151536
+ sFrom.a[0].fg.jointype = 0;
151537
+ assert( pParse->withinRJSubrtn < 100 );
151538
+ pParse->withinRJSubrtn++;
151539
+ pSubWInfo = sqlite3WhereBegin(pParse, &sFrom, pSubWhere, 0, 0, 0,
151540
+ WHERE_RIGHT_JOIN, 0);
151541
+ if( pSubWInfo ){
151542
+ int iCur = pLevel->iTabCur;
151543
+ int r = ++pParse->nMem;
151544
+ int nPk;
151545
+ int jmp;
151546
+ int addrCont = sqlite3WhereContinueLabel(pSubWInfo);
151547
+ Table *pTab = pTabItem->pTab;
151548
+ if( HasRowid(pTab) ){
151549
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, r);
151550
+ nPk = 1;
151551
+ }else{
151552
+ int iPk;
151553
+ Index *pPk = sqlite3PrimaryKeyIndex(pTab);
151554
+ nPk = pPk->nKeyCol;
151555
+ pParse->nMem += nPk - 1;
151556
+ for(iPk=0; iPk<nPk; iPk++){
151557
+ int iCol = pPk->aiColumn[iPk];
151558
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+iPk);
151559
+ }
151560
+ }
151561
+ jmp = sqlite3VdbeAddOp4Int(v, OP_Filter, pRJ->regBloom, 0, r, nPk);
151562
+ VdbeCoverage(v);
151563
+ sqlite3VdbeAddOp4Int(v, OP_Found, pRJ->iMatch, addrCont, r, nPk);
151564
+ VdbeCoverage(v);
151565
+ sqlite3VdbeJumpHere(v, jmp);
151566
+ sqlite3VdbeAddOp2(v, OP_Gosub, pRJ->regReturn, pRJ->addrSubrtn);
151567
+ sqlite3WhereEnd(pSubWInfo);
151568
+ }
151569
+ sqlite3ExprDelete(pParse->db, pSubWhere);
151570
+ ExplainQueryPlanPop(pParse);
151571
+ assert( pParse->withinRJSubrtn>0 );
151572
+ pParse->withinRJSubrtn--;
151573
+}
150479151574
150480151575
/************** End of wherecode.c *******************************************/
150481151576
/************** Begin file whereexpr.c ***************************************/
150482151577
/*
150483151578
** 2015-06-08
@@ -150543,23 +151638,20 @@
150543151638
int idx;
150544151639
testcase( wtFlags & TERM_VIRTUAL );
150545151640
if( pWC->nTerm>=pWC->nSlot ){
150546151641
WhereTerm *pOld = pWC->a;
150547151642
sqlite3 *db = pWC->pWInfo->pParse->db;
150548
- pWC->a = sqlite3DbMallocRawNN(db, sizeof(pWC->a[0])*pWC->nSlot*2 );
151643
+ pWC->a = sqlite3WhereMalloc(pWC->pWInfo, sizeof(pWC->a[0])*pWC->nSlot*2 );
150549151644
if( pWC->a==0 ){
150550151645
if( wtFlags & TERM_DYNAMIC ){
150551151646
sqlite3ExprDelete(db, p);
150552151647
}
150553151648
pWC->a = pOld;
150554151649
return 0;
150555151650
}
150556151651
memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm);
150557
- if( pOld!=pWC->aStatic ){
150558
- sqlite3DbFree(db, pOld);
150559
- }
150560
- pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
151652
+ pWC->nSlot = pWC->nSlot*2;
150561151653
}
150562151654
pTerm = &pWC->a[idx = pWC->nTerm++];
150563151655
if( (wtFlags & TERM_VIRTUAL)==0 ) pWC->nBase = pWC->nTerm;
150564151656
if( p && ExprHasProperty(p, EP_Unlikely) ){
150565151657
pTerm->truthProb = sqlite3LogEst(p->iTable) - 270;
@@ -150945,11 +152037,11 @@
150945152037
** a join, then transfer the appropriate markings over to derived.
150946152038
*/
150947152039
static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
150948152040
if( pDerived ){
150949152041
pDerived->flags |= pBase->flags & EP_FromJoin;
150950
- pDerived->w.iRightJoinTable = pBase->w.iRightJoinTable;
152042
+ pDerived->w.iJoin = pBase->w.iJoin;
150951152043
}
150952152044
}
150953152045
150954152046
/*
150955152047
** Mark term iChild as being a child of term iParent
@@ -151430,11 +152522,13 @@
151430152522
mask |= sqlite3WhereExprUsage(pMaskSet, pS->pHaving);
151431152523
if( ALWAYS(pSrc!=0) ){
151432152524
int i;
151433152525
for(i=0; i<pSrc->nSrc; i++){
151434152526
mask |= exprSelectUsage(pMaskSet, pSrc->a[i].pSelect);
151435
- mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].pOn);
152527
+ if( pSrc->a[i].fg.isUsing==0 ){
152528
+ mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].u3.pOn);
152529
+ }
151436152530
if( pSrc->a[i].fg.isTabFunc ){
151437152531
mask |= sqlite3WhereExprListUsage(pMaskSet, pSrc->a[i].u1.pFuncArg);
151438152532
}
151439152533
}
151440152534
}
@@ -151590,11 +152684,11 @@
151590152684
abort();
151591152685
}
151592152686
#endif
151593152687
151594152688
if( ExprHasProperty(pExpr, EP_FromJoin) ){
151595
- Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->w.iRightJoinTable);
152689
+ Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->w.iJoin);
151596152690
prereqAll |= x;
151597152691
extraRight = x-1; /* ON clause terms may not be used with an index
151598152692
** on left table of a LEFT JOIN. Ticket #3015 */
151599152693
if( (prereqAll>>1)>=x ){
151600152694
sqlite3ErrorMsg(pParse, "ON clause references tables to its right");
@@ -151941,11 +153035,11 @@
151941153035
Expr *pNewExpr;
151942153036
pNewExpr = sqlite3PExpr(pParse, TK_MATCH,
151943153037
0, sqlite3ExprDup(db, pRight, 0));
151944153038
if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){
151945153039
ExprSetProperty(pNewExpr, EP_FromJoin);
151946
- pNewExpr->w.iRightJoinTable = pExpr->w.iRightJoinTable;
153040
+ pNewExpr->w.iJoin = pExpr->w.iJoin;
151947153041
}
151948153042
idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
151949153043
testcase( idxNew==0 );
151950153044
pNewTerm = &pWC->a[idxNew];
151951153045
pNewTerm->prereqRight = prereqExpr;
@@ -152163,13 +153257,10 @@
152163153257
}
152164153258
if( a==aLast ) break;
152165153259
a++;
152166153260
}
152167153261
}
152168
- if( pWC->a!=pWC->aStatic ){
152169
- sqlite3DbFree(db, pWC->a);
152170
- }
152171153262
}
152172153263
152173153264
152174153265
/*
152175153266
** These routines walk (recursively) an expression tree and generate
@@ -152292,10 +153383,11 @@
152292153383
assert( pTab!=0 );
152293153384
pArgs = pItem->u1.pFuncArg;
152294153385
if( pArgs==0 ) return;
152295153386
for(j=k=0; j<pArgs->nExpr; j++){
152296153387
Expr *pRhs;
153388
+ u32 joinType;
152297153389
while( k<pTab->nCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){k++;}
152298153390
if( k>=pTab->nCol ){
152299153391
sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d",
152300153392
pTab->zName, j);
152301153393
return;
@@ -152308,13 +153400,16 @@
152308153400
pColRef->y.pTab = pTab;
152309153401
pItem->colUsed |= sqlite3ExprColUsed(pColRef);
152310153402
pRhs = sqlite3PExpr(pParse, TK_UPLUS,
152311153403
sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
152312153404
pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs);
152313
- if( pItem->fg.jointype & JT_LEFT ){
152314
- sqlite3SetJoinExpr(pTerm, pItem->iCursor);
153405
+ if( pItem->fg.jointype & (JT_LEFT|JT_LTORJ) ){
153406
+ joinType = EP_FromJoin;
153407
+ }else{
153408
+ joinType = EP_InnerJoin;
152315153409
}
153410
+ sqlite3SetJoinExpr(pTerm, pItem->iCursor, joinType);
152316153411
whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);
152317153412
}
152318153413
}
152319153414
152320153415
/************** End of whereexpr.c *******************************************/
@@ -152571,10 +153666,34 @@
152571153666
return MASKBIT(i);
152572153667
}
152573153668
}
152574153669
return 0;
152575153670
}
153671
+
153672
+/* Allocate memory that is automatically freed when pWInfo is freed.
153673
+*/
153674
+SQLITE_PRIVATE void *sqlite3WhereMalloc(WhereInfo *pWInfo, u64 nByte){
153675
+ WhereMemBlock *pBlock;
153676
+ pBlock = sqlite3DbMallocRawNN(pWInfo->pParse->db, nByte+sizeof(*pBlock));
153677
+ if( pBlock ){
153678
+ pBlock->pNext = pWInfo->pMemToFree;
153679
+ pBlock->sz = nByte;
153680
+ pWInfo->pMemToFree = pBlock;
153681
+ pBlock++;
153682
+ }
153683
+ return (void*)pBlock;
153684
+}
153685
+SQLITE_PRIVATE void *sqlite3WhereRealloc(WhereInfo *pWInfo, void *pOld, u64 nByte){
153686
+ void *pNew = sqlite3WhereMalloc(pWInfo, nByte);
153687
+ if( pNew && pOld ){
153688
+ WhereMemBlock *pOldBlk = (WhereMemBlock*)pOld;
153689
+ pOldBlk--;
153690
+ assert( pOldBlk->sz<nByte );
153691
+ memcpy(pNew, pOld, pOldBlk->sz);
153692
+ }
153693
+ return pNew;
153694
+}
152576153695
152577153696
/*
152578153697
** Create a new mask for cursor iCursor.
152579153698
**
152580153699
** There is one cursor per table in the FROM clause. The number of
@@ -153051,17 +154170,17 @@
153051154170
const Bitmask notReady /* Tables in outer loops of the join */
153052154171
){
153053154172
char aff;
153054154173
if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
153055154174
if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0;
153056
- if( (pSrc->fg.jointype & JT_LEFT)
154175
+ if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ))!=0
153057154176
&& !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
153058154177
&& (pTerm->eOperator & WO_IS)
153059154178
){
153060154179
/* Cannot use an IS term from the WHERE clause as an index driver for
153061
- ** the RHS of a LEFT JOIN. Such a term can only be used if it is from
153062
- ** the ON clause. */
154180
+ ** the RHS of a LEFT JOIN or for the LHS of a RIGHT JOIN. Such a term
154181
+ ** can only be used if it is from the ON clause. */
153063154182
return 0;
153064154183
}
153065154184
if( (pTerm->prereqRight & notReady)!=0 ) return 0;
153066154185
assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
153067154186
if( pTerm->u.x.leftColumn<0 ) return 0;
@@ -153127,11 +154246,12 @@
153127154246
Expr *pExpr = pTerm->pExpr;
153128154247
/* Make the automatic index a partial index if there are terms in the
153129154248
** WHERE clause (or the ON clause of a LEFT join) that constrain which
153130154249
** rows of the target table (pSrc) that can be used. */
153131154250
if( (pTerm->wtFlags & TERM_VIRTUAL)==0
153132
- && ((pSrc->fg.jointype&JT_LEFT)==0 || ExprHasProperty(pExpr,EP_FromJoin))
154251
+ && ((pSrc->fg.jointype&(JT_LEFT|JT_LTORJ))==0
154252
+ || ExprHasProperty(pExpr,EP_FromJoin))
153133154253
&& sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor)
153134154254
){
153135154255
pPartial = sqlite3ExprAnd(pParse, pPartial,
153136154256
sqlite3ExprDup(pParse->db, pExpr, 0));
153137154257
}
@@ -153400,11 +154520,11 @@
153400154520
if( OptimizationDisabled(pParse->db, SQLITE_BloomPulldown) ) break;
153401154521
while( ++iLevel < pWInfo->nLevel ){
153402154522
const SrcItem *pTabItem;
153403154523
pLevel = &pWInfo->a[iLevel];
153404154524
pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
153405
- if( pTabItem->fg.jointype & JT_LEFT ) continue;
154525
+ if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ) ) continue;
153406154526
pLoop = pLevel->pWLoop;
153407154527
if( NEVER(pLoop==0) ) continue;
153408154528
if( pLoop->prereq & notReady ) continue;
153409154529
if( (pLoop->wsFlags & (WHERE_BLOOMFILTER|WHERE_COLUMN_IN))
153410154530
==WHERE_BLOOMFILTER
@@ -153473,13 +154593,14 @@
153473154593
assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
153474154594
assert( pTerm->u.x.leftColumn>=XN_ROWID );
153475154595
assert( pTerm->u.x.leftColumn<pTab->nCol );
153476154596
153477154597
/* tag-20191211-002: WHERE-clause constraints are not useful to the
153478
- ** right-hand table of a LEFT JOIN. See tag-20191211-001 for the
154598
+ ** right-hand table of a LEFT JOIN nor to the left-hand table of a
154599
+ ** RIGHT JOIN. See tag-20191211-001 for the
153479154600
** equivalent restriction for ordinary tables. */
153480
- if( (pSrc->fg.jointype & JT_LEFT)!=0
154601
+ if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ))!=0
153481154602
&& !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
153482154603
){
153483154604
continue;
153484154605
}
153485154606
nTerm++;
@@ -154535,26 +155656,23 @@
154535155656
154536155657
/*
154537155658
** Free a WhereInfo structure
154538155659
*/
154539155660
static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
154540
- int i;
154541155661
assert( pWInfo!=0 );
154542
- for(i=0; i<pWInfo->nLevel; i++){
154543
- WhereLevel *pLevel = &pWInfo->a[i];
154544
- if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE)!=0 ){
154545
- assert( (pLevel->pWLoop->wsFlags & WHERE_MULTI_OR)==0 );
154546
- sqlite3DbFree(db, pLevel->u.in.aInLoop);
154547
- }
154548
- }
154549155662
sqlite3WhereClauseClear(&pWInfo->sWC);
154550155663
while( pWInfo->pLoops ){
154551155664
WhereLoop *p = pWInfo->pLoops;
154552155665
pWInfo->pLoops = p->pNextLoop;
154553155666
whereLoopDelete(db, p);
154554155667
}
154555155668
assert( pWInfo->pExprMods==0 );
155669
+ while( pWInfo->pMemToFree ){
155670
+ WhereMemBlock *pNext = pWInfo->pMemToFree->pNext;
155671
+ sqlite3DbFreeNN(db, pWInfo->pMemToFree);
155672
+ pWInfo->pMemToFree = pNext;
155673
+ }
154556155674
sqlite3DbFreeNN(db, pWInfo);
154557155675
}
154558155676
154559155677
/* Undo all Expr node modifications
154560155678
*/
@@ -154919,14 +156037,15 @@
154919156037
** cause many rows to be omitted, then mark that table as
154920156038
** "self-culling".
154921156039
**
154922156040
** 2022-03-24: Self-culling only applies if either the extra terms
154923156041
** are straight comparison operators that are non-true with NULL
154924
- ** operand, or if the loop is not a LEFT JOIN.
156042
+ ** operand, or if the loop is not an OUTER JOIN.
154925156043
*/
154926156044
if( (pTerm->eOperator & 0x3f)!=0
154927
- || (pWC->pWInfo->pTabList->a[pLoop->iTab].fg.jointype & JT_LEFT)==0
156045
+ || (pWC->pWInfo->pTabList->a[pLoop->iTab].fg.jointype
156046
+ & (JT_LEFT|JT_LTORJ))==0
154928156047
){
154929156048
pLoop->wsFlags |= WHERE_SELFCULL;
154930156049
}
154931156050
}
154932156051
if( pTerm->truthProb<=0 ){
@@ -155129,13 +156248,14 @@
155129156248
/* Do not allow the upper bound of a LIKE optimization range constraint
155130156249
** to mix with a lower range bound from some other source */
155131156250
if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue;
155132156251
155133156252
/* tag-20191211-001: Do not allow constraints from the WHERE clause to
155134
- ** be used by the right table of a LEFT JOIN. Only constraints in the
156253
+ ** be used by the right table of a LEFT JOIN nor by the left table of a
156254
+ ** RIGHT JOIN. Only constraints in the
155135156255
** ON clause are allowed. See tag-20191211-002 for the vtab equivalent. */
155136
- if( (pSrc->fg.jointype & JT_LEFT)!=0
156256
+ if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ))!=0
155137156257
&& !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
155138156258
){
155139156259
continue;
155140156260
}
155141156261
@@ -155501,11 +156621,11 @@
155501156621
}
155502156622
if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0;
155503156623
for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
155504156624
Expr *pExpr;
155505156625
pExpr = pTerm->pExpr;
155506
- if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->w.iRightJoinTable==iTab)
156626
+ if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->w.iJoin==iTab)
155507156627
&& (isLeft==0 || ExprHasProperty(pExpr, EP_FromJoin))
155508156628
&& sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab)
155509156629
&& (pTerm->wtFlags & TERM_VNULL)==0
155510156630
){
155511156631
return 1;
@@ -155611,17 +156731,18 @@
155611156731
rSize = pTab->nRowLogEst;
155612156732
155613156733
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
155614156734
/* Automatic indexes */
155615156735
if( !pBuilder->pOrSet /* Not part of an OR optimization */
155616
- && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0
156736
+ && (pWInfo->wctrlFlags & (WHERE_RIGHT_JOIN|WHERE_OR_SUBCLAUSE))==0
155617156737
&& (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
155618156738
&& !pSrc->fg.isIndexedBy /* Has no INDEXED BY clause */
155619156739
&& !pSrc->fg.notIndexed /* Has no NOT INDEXED clause */
155620156740
&& HasRowid(pTab) /* Not WITHOUT ROWID table. (FIXME: Why not?) */
155621156741
&& !pSrc->fg.isCorrelated /* Not a correlated subquery */
155622156742
&& !pSrc->fg.isRecursive /* Not a recursive common table expression. */
156743
+ && (pSrc->fg.jointype & JT_RIGHT)==0 /* Not the right tab of a RIGHT JOIN */
155623156744
){
155624156745
/* Generate auto-index WhereLoops */
155625156746
LogEst rLogSize; /* Logarithm of the number of rows in the table */
155626156747
WhereTerm *pTerm;
155627156748
WhereTerm *pWCEnd = pWC->a + pWC->nTerm;
@@ -156107,19 +157228,30 @@
156107157228
156108157229
#if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \
156109157230
&& !defined(SQLITE_OMIT_VIRTUALTABLE)
156110157231
/*
156111157232
** Cause the prepared statement that is associated with a call to
156112
-** xBestIndex to open write transactions on all attached schemas.
157233
+** xBestIndex to potentiall use all schemas. If the statement being
157234
+** prepared is read-only, then just start read transactions on all
157235
+** schemas. But if this is a write operation, start writes on all
157236
+** schemas.
157237
+**
156113157238
** This is used by the (built-in) sqlite_dbpage virtual table.
156114157239
*/
156115
-SQLITE_PRIVATE void sqlite3VtabWriteAll(sqlite3_index_info *pIdxInfo){
157240
+SQLITE_PRIVATE void sqlite3VtabUsesAllSchemas(sqlite3_index_info *pIdxInfo){
156116157241
HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
156117157242
Parse *pParse = pHidden->pParse;
156118157243
int nDb = pParse->db->nDb;
156119157244
int i;
156120
- for(i=0; i<nDb; i++) sqlite3BeginWriteOperation(pParse, 0, i);
157245
+ for(i=0; i<nDb; i++){
157246
+ sqlite3CodeVerifySchema(pParse, i);
157247
+ }
157248
+ if( pParse->writeMask ){
157249
+ for(i=0; i<nDb; i++){
157250
+ sqlite3BeginWriteOperation(pParse, 0, i);
157251
+ }
157252
+ }
156121157253
}
156122157254
#endif
156123157255
156124157256
/*
156125157257
** Add all WhereLoop objects for a table of the join identified by
@@ -156297,10 +157429,13 @@
156297157429
pWCEnd = pWC->a + pWC->nTerm;
156298157430
pNew = pBuilder->pNew;
156299157431
memset(&sSum, 0, sizeof(sSum));
156300157432
pItem = pWInfo->pTabList->a + pNew->iTab;
156301157433
iCur = pItem->iCursor;
157434
+
157435
+ /* The multi-index OR optimization does not work for RIGHT and FULL JOIN */
157436
+ if( pItem->fg.jointype & JT_RIGHT ) return SQLITE_OK;
156302157437
156303157438
for(pTerm=pWC->a; pTerm<pWCEnd && rc==SQLITE_OK; pTerm++){
156304157439
if( (pTerm->eOperator & WO_OR)!=0
156305157440
&& (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0
156306157441
){
@@ -156422,22 +157557,22 @@
156422157557
for(iTab=0, pItem=pTabList->a; pItem<pEnd; iTab++, pItem++){
156423157558
Bitmask mUnusable = 0;
156424157559
pNew->iTab = iTab;
156425157560
pBuilder->iPlanLimit += SQLITE_QUERY_PLANNER_LIMIT_INCR;
156426157561
pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor);
156427
- if( (pItem->fg.jointype & (JT_LEFT|JT_CROSS))!=0 ){
157562
+ if( (pItem->fg.jointype & (JT_OUTER|JT_CROSS))!=0 ){
156428157563
/* This condition is true when pItem is the FROM clause term on the
156429
- ** right-hand-side of a LEFT or CROSS JOIN. */
157564
+ ** right-hand-side of a OUTER or CROSS JOIN. */
156430157565
mPrereq = mPrior;
156431157566
}else{
156432157567
mPrereq = 0;
156433157568
}
156434157569
#ifndef SQLITE_OMIT_VIRTUALTABLE
156435157570
if( IsVirtual(pItem->pTab) ){
156436157571
SrcItem *p;
156437157572
for(p=&pItem[1]; p<pEnd; p++){
156438
- if( mUnusable || (p->fg.jointype & (JT_LEFT|JT_CROSS)) ){
157573
+ if( mUnusable || (p->fg.jointype & (JT_OUTER|JT_CROSS)) ){
156439157574
mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor);
156440157575
}
156441157576
}
156442157577
rc = whereLoopAddVirtual(pBuilder, mPrereq, mUnusable);
156443157578
}else
@@ -157496,11 +158631,11 @@
157496158631
if( (tabUsed & pLoop->maskSelf)!=0 ) continue;
157497158632
pEnd = pWInfo->sWC.a + pWInfo->sWC.nTerm;
157498158633
for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){
157499158634
if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
157500158635
if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
157501
- || pTerm->pExpr->w.iRightJoinTable!=pItem->iCursor
158636
+ || pTerm->pExpr->w.iJoin!=pItem->iCursor
157502158637
){
157503158638
break;
157504158639
}
157505158640
}
157506158641
}
@@ -157727,11 +158862,11 @@
157727158862
** struct, the contents of WhereInfo.a[], the WhereClause structure
157728158863
** and the WhereMaskSet structure. Since WhereClause contains an 8-byte
157729158864
** field (type Bitmask) it must be aligned on an 8-byte boundary on
157730158865
** some architectures. Hence the ROUND8() below.
157731158866
*/
157732
- nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel));
158867
+ nByteWInfo = ROUND8P(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel));
157733158868
pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop));
157734158869
if( db->mallocFailed ){
157735158870
sqlite3DbFree(db, pWInfo);
157736158871
pWInfo = 0;
157737158872
goto whereBeginError;
@@ -158049,12 +159184,14 @@
158049159184
sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB);
158050159185
}else if( IsVirtual(pTab) ){
158051159186
/* noop */
158052159187
}else
158053159188
#endif
158054
- if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
158055
- && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){
159189
+ if( ((pLoop->wsFlags & WHERE_IDX_ONLY)==0
159190
+ && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0)
159191
+ || (pTabItem->fg.jointype & (JT_LTORJ|JT_RIGHT))!=0
159192
+ ){
158056159193
int op = OP_OpenRead;
158057159194
if( pWInfo->eOnePass!=ONEPASS_OFF ){
158058159195
op = OP_OpenWrite;
158059159196
pWInfo->aiCurOnePass[0] = pTabItem->iCursor;
158060159197
};
@@ -158152,10 +159289,41 @@
158152159289
}
158153159290
#endif /* SQLITE_ENABLE_COLUMN_USED_MASK */
158154159291
}
158155159292
}
158156159293
if( iDb>=0 ) sqlite3CodeVerifySchema(pParse, iDb);
159294
+ if( (pTabItem->fg.jointype & JT_RIGHT)!=0
159295
+ && (pLevel->pRJ = sqlite3WhereMalloc(pWInfo, sizeof(WhereRightJoin)))!=0
159296
+ ){
159297
+ WhereRightJoin *pRJ = pLevel->pRJ;
159298
+ pRJ->iMatch = pParse->nTab++;
159299
+ pRJ->regBloom = ++pParse->nMem;
159300
+ sqlite3VdbeAddOp2(v, OP_Blob, 65536, pRJ->regBloom);
159301
+ pRJ->regReturn = ++pParse->nMem;
159302
+ sqlite3VdbeAddOp2(v, OP_Null, 0, pRJ->regReturn);
159303
+ assert( pTab==pTabItem->pTab );
159304
+ if( HasRowid(pTab) ){
159305
+ KeyInfo *pInfo;
159306
+ sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRJ->iMatch, 1);
159307
+ pInfo = sqlite3KeyInfoAlloc(pParse->db, 1, 0);
159308
+ if( pInfo ){
159309
+ pInfo->aColl[0] = 0;
159310
+ pInfo->aSortFlags[0] = 0;
159311
+ sqlite3VdbeAppendP4(v, pInfo, P4_KEYINFO);
159312
+ }
159313
+ }else{
159314
+ Index *pPk = sqlite3PrimaryKeyIndex(pTab);
159315
+ sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRJ->iMatch, pPk->nKeyCol);
159316
+ sqlite3VdbeSetP4KeyInfo(pParse, pPk);
159317
+ }
159318
+ pLoop->wsFlags &= ~WHERE_IDX_ONLY;
159319
+ /* The nature of RIGHT JOIN processing is such that it messes up
159320
+ ** the output order. So omit any ORDER BY/GROUP BY elimination
159321
+ ** optimizations. We need to do an actual sort for RIGHT JOIN. */
159322
+ pWInfo->nOBSat = 0;
159323
+ pWInfo->eDistinct = WHERE_DISTINCT_UNORDERED;
159324
+ }
158157159325
}
158158159326
pWInfo->iTop = sqlite3VdbeCurrentAddr(v);
158159159327
if( db->mallocFailed ) goto whereBeginError;
158160159328
158161159329
/* Generate the code to do the search. Each iteration of the for
@@ -158264,10 +159432,21 @@
158264159432
*/
158265159433
VdbeModuleComment((v, "End WHERE-core"));
158266159434
for(i=pWInfo->nLevel-1; i>=0; i--){
158267159435
int addr;
158268159436
pLevel = &pWInfo->a[i];
159437
+ if( pLevel->pRJ ){
159438
+ /* Terminate the subroutine that forms the interior of the loop of
159439
+ ** the RIGHT JOIN table */
159440
+ WhereRightJoin *pRJ = pLevel->pRJ;
159441
+ sqlite3VdbeResolveLabel(v, pLevel->addrCont);
159442
+ pLevel->addrCont = 0;
159443
+ sqlite3VdbeAddOp3(v, OP_Return, pRJ->regReturn, pRJ->addrSubrtn, 1);
159444
+ VdbeCoverage(v);
159445
+ assert( pParse->withinRJSubrtn>0 );
159446
+ pParse->withinRJSubrtn--;
159447
+ }
158269159448
pLoop = pLevel->pWLoop;
158270159449
if( pLevel->op!=OP_Noop ){
158271159450
#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
158272159451
int addrSeek = 0;
158273159452
Index *pIdx;
@@ -158291,11 +159470,11 @@
158291159470
VdbeCoverageIf(v, op==OP_SeekGT);
158292159471
sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2);
158293159472
}
158294159473
#endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */
158295159474
/* The common case: Advance to the next row */
158296
- sqlite3VdbeResolveLabel(v, pLevel->addrCont);
159475
+ if( pLevel->addrCont ) sqlite3VdbeResolveLabel(v, pLevel->addrCont);
158297159476
sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3);
158298159477
sqlite3VdbeChangeP5(v, pLevel->p5);
158299159478
VdbeCoverage(v);
158300159479
VdbeCoverageIf(v, pLevel->op==OP_Next);
158301159480
VdbeCoverageIf(v, pLevel->op==OP_Prev);
@@ -158306,11 +159485,11 @@
158306159485
VdbeCoverage(v);
158307159486
}
158308159487
#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
158309159488
if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek);
158310159489
#endif
158311
- }else{
159490
+ }else if( pLevel->addrCont ){
158312159491
sqlite3VdbeResolveLabel(v, pLevel->addrCont);
158313159492
}
158314159493
if( (pLoop->wsFlags & WHERE_IN_ABLE)!=0 && pLevel->u.in.nIn>0 ){
158315159494
struct InLoop *pIn;
158316159495
int j;
@@ -158356,10 +159535,14 @@
158356159535
}
158357159536
sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
158358159537
}
158359159538
}
158360159539
sqlite3VdbeResolveLabel(v, pLevel->addrBrk);
159540
+ if( pLevel->pRJ ){
159541
+ sqlite3VdbeAddOp3(v, OP_Return, pLevel->pRJ->regReturn, 0, 1);
159542
+ VdbeCoverage(v);
159543
+ }
158361159544
if( pLevel->addrSkip ){
158362159545
sqlite3VdbeGoto(v, pLevel->addrSkip);
158363159546
VdbeComment((v, "next skip-scan on %s", pLoop->u.btree.pIndex->zName));
158364159547
sqlite3VdbeJumpHere(v, pLevel->addrSkip);
158365159548
sqlite3VdbeJumpHere(v, pLevel->addrSkip-2);
@@ -158399,24 +159582,28 @@
158399159582
}
158400159583
VdbeModuleComment((v, "End WHERE-loop%d: %s", i,
158401159584
pWInfo->pTabList->a[pLevel->iFrom].pTab->zName));
158402159585
}
158403159586
158404
- /* The "break" point is here, just past the end of the outer loop.
158405
- ** Set it.
158406
- */
158407
- sqlite3VdbeResolveLabel(v, pWInfo->iBreak);
158408
-
158409159587
assert( pWInfo->nLevel<=pTabList->nSrc );
158410159588
for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){
158411159589
int k, last;
158412159590
VdbeOp *pOp, *pLastOp;
158413159591
Index *pIdx = 0;
158414159592
SrcItem *pTabItem = &pTabList->a[pLevel->iFrom];
158415159593
Table *pTab = pTabItem->pTab;
158416159594
assert( pTab!=0 );
158417159595
pLoop = pLevel->pWLoop;
159596
+
159597
+ /* Do RIGHT JOIN processing. Generate code that will output the
159598
+ ** unmatched rows of the right operand of the RIGHT JOIN with
159599
+ ** all of the columns of the left operand set to NULL.
159600
+ */
159601
+ if( pLevel->pRJ ){
159602
+ sqlite3WhereRightJoinLoop(pWInfo, i, pLevel);
159603
+ continue;
159604
+ }
158418159605
158419159606
/* For a co-routine, change all OP_Column references to the table of
158420159607
** the co-routine into OP_Copy of result contained in a register.
158421159608
** OP_Rowid becomes OP_Null.
158422159609
*/
@@ -158425,33 +159612,10 @@
158425159612
translateColumnToCopy(pParse, pLevel->addrBody, pLevel->iTabCur,
158426159613
pTabItem->regResult, 0);
158427159614
continue;
158428159615
}
158429159616
158430
-#ifdef SQLITE_ENABLE_EARLY_CURSOR_CLOSE
158431
- /* Close all of the cursors that were opened by sqlite3WhereBegin.
158432
- ** Except, do not close cursors that will be reused by the OR optimization
158433
- ** (WHERE_OR_SUBCLAUSE). And do not close the OP_OpenWrite cursors
158434
- ** created for the ONEPASS optimization.
158435
- */
158436
- if( (pTab->tabFlags & TF_Ephemeral)==0
158437
- && !IsView(pTab)
158438
- && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0
158439
- ){
158440
- int ws = pLoop->wsFlags;
158441
- if( pWInfo->eOnePass==ONEPASS_OFF && (ws & WHERE_IDX_ONLY)==0 ){
158442
- sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor);
158443
- }
158444
- if( (ws & WHERE_INDEXED)!=0
158445
- && (ws & (WHERE_IPK|WHERE_AUTO_INDEX))==0
158446
- && pLevel->iIdxCur!=pWInfo->aiCurOnePass[1]
158447
- ){
158448
- sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur);
158449
- }
158450
- }
158451
-#endif
158452
-
158453159617
/* If this scan uses an index, make VDBE code substitutions to read data
158454159618
** from the index instead of from the table where possible. In some cases
158455159619
** this optimization prevents the table from ever being read, which can
158456159620
** yield a significant performance boost.
158457159621
**
@@ -158547,10 +159711,15 @@
158547159711
#ifdef SQLITE_DEBUG
158548159712
if( db->flags & SQLITE_VdbeAddopTrace ) printf("TRANSLATE complete\n");
158549159713
#endif
158550159714
}
158551159715
}
159716
+
159717
+ /* The "break" point is here, just past the end of the outer loop.
159718
+ ** Set it.
159719
+ */
159720
+ sqlite3VdbeResolveLabel(v, pWInfo->iBreak);
158552159721
158553159722
/* Final cleanup
158554159723
*/
158555159724
if( pWInfo->pExprMods ) whereUndoExprMods(pWInfo);
158556159725
pParse->nQueryLoop = pWInfo->savedNQueryLoop;
@@ -160289,11 +161458,11 @@
160289161458
regArg = sqlite3GetTempRange(pParse, nArg);
160290161459
sqlite3ExprCodeExprList(pParse, pWin->pOwner->x.pList, regArg, 0, 0);
160291161460
160292161461
for(iEnd=sqlite3VdbeCurrentAddr(v); iOp<iEnd; iOp++){
160293161462
VdbeOp *pOp = sqlite3VdbeGetOp(v, iOp);
160294
- if( pOp->opcode==OP_Column && pOp->p1==pWin->iEphCsr ){
161463
+ if( pOp->opcode==OP_Column && pOp->p1==pMWin->iEphCsr ){
160295161464
pOp->p1 = csr;
160296161465
}
160297161466
}
160298161467
}
160299161468
if( pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
@@ -161828,11 +162997,11 @@
161828162997
/* memset(p, 0, sizeof(Expr)); */
161829162998
p->op = (u8)op;
161830162999
p->affExpr = 0;
161831163000
p->flags = EP_Leaf;
161832163001
ExprClearVVAProperties(p);
161833
- p->iAgg = -1;
163002
+ /* p->iAgg = -1; // Not required */
161834163003
p->pLeft = p->pRight = 0;
161835163004
p->pAggInfo = 0;
161836163005
memset(&p->x, 0, sizeof(p->x));
161837163006
memset(&p->y, 0, sizeof(p->y));
161838163007
p->op2 = 0;
@@ -162161,10 +163330,11 @@
162161163330
Upsert* yy444;
162162163331
u8 yy516;
162163163332
With* yy521;
162164163333
const char* yy522;
162165163334
Expr* yy528;
163335
+ OnOrUsing yy561;
162166163336
struct FrameBound yy595;
162167163337
} YYMINORTYPE;
162168163338
#ifndef YYSTACKDEPTH
162169163339
#define YYSTACKDEPTH 100
162170163340
#endif
@@ -162177,21 +163347,21 @@
162177163347
#define sqlite3ParserCTX_PDECL ,Parse *pParse
162178163348
#define sqlite3ParserCTX_PARAM ,pParse
162179163349
#define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse;
162180163350
#define sqlite3ParserCTX_STORE yypParser->pParse=pParse;
162181163351
#define YYFALLBACK 1
162182
-#define YYNSTATE 574
162183
-#define YYNRULE 402
163352
+#define YYNSTATE 570
163353
+#define YYNRULE 403
162184163354
#define YYNRULE_WITH_ACTION 340
162185163355
#define YYNTOKEN 185
162186
-#define YY_MAX_SHIFT 573
162187
-#define YY_MIN_SHIFTREDUCE 831
162188
-#define YY_MAX_SHIFTREDUCE 1232
162189
-#define YY_ERROR_ACTION 1233
162190
-#define YY_ACCEPT_ACTION 1234
162191
-#define YY_NO_ACTION 1235
162192
-#define YY_MIN_REDUCE 1236
163356
+#define YY_MAX_SHIFT 569
163357
+#define YY_MIN_SHIFTREDUCE 829
163358
+#define YY_MAX_SHIFTREDUCE 1231
163359
+#define YY_ERROR_ACTION 1232
163360
+#define YY_ACCEPT_ACTION 1233
163361
+#define YY_NO_ACTION 1234
163362
+#define YY_MIN_REDUCE 1235
162193163363
#define YY_MAX_REDUCE 1637
162194163364
/************* End control #defines *******************************************/
162195163365
#define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])))
162196163366
162197163367
/* Define the yytestcase() macro to be a no-op if is not already defined
@@ -162255,428 +163425,428 @@
162255163425
** yy_reduce_ofst[] For each state, the offset into yy_action for
162256163426
** shifting non-terminals after a reduce.
162257163427
** yy_default[] Default action for each state.
162258163428
**
162259163429
*********** Begin parsing tables **********************************************/
162260
-#define YY_ACTTAB_COUNT (2070)
163430
+#define YY_ACTTAB_COUNT (2064)
162261163431
static const YYACTIONTYPE yy_action[] = {
162262
- /* 0 */ 566, 1307, 566, 1286, 201, 201, 566, 116, 112, 222,
162263
- /* 10 */ 566, 1307, 377, 566, 116, 112, 222, 397, 408, 409,
162264
- /* 20 */ 1260, 378, 1269, 41, 41, 41, 41, 1412, 1517, 71,
162265
- /* 30 */ 71, 967, 1258, 41, 41, 491, 71, 71, 272, 968,
162266
- /* 40 */ 298, 476, 298, 123, 124, 114, 1210, 1210, 1044, 1047,
162267
- /* 50 */ 1036, 1036, 121, 121, 122, 122, 122, 122, 543, 409,
162268
- /* 60 */ 1234, 1, 1, 573, 2, 1238, 548, 116, 112, 222,
162269
- /* 70 */ 309, 480, 142, 548, 1272, 524, 116, 112, 222, 1320,
162270
- /* 80 */ 417, 523, 547, 123, 124, 114, 1210, 1210, 1044, 1047,
162271
- /* 90 */ 1036, 1036, 121, 121, 122, 122, 122, 122, 424, 116,
162272
- /* 100 */ 112, 222, 120, 120, 120, 120, 119, 119, 118, 118,
162273
- /* 110 */ 118, 117, 113, 444, 277, 277, 277, 277, 560, 560,
162274
- /* 120 */ 560, 1558, 376, 1560, 1186, 375, 1157, 563, 1157, 563,
162275
- /* 130 */ 409, 1558, 537, 252, 219, 1553, 99, 141, 449, 6,
162276
- /* 140 */ 365, 233, 120, 120, 120, 120, 119, 119, 118, 118,
162277
- /* 150 */ 118, 117, 113, 444, 123, 124, 114, 1210, 1210, 1044,
162278
- /* 160 */ 1047, 1036, 1036, 121, 121, 122, 122, 122, 122, 138,
162279
- /* 170 */ 289, 1186, 1546, 448, 118, 118, 118, 117, 113, 444,
162280
- /* 180 */ 125, 1186, 1187, 1188, 144, 465, 334, 566, 150, 127,
162281
- /* 190 */ 444, 122, 122, 122, 122, 115, 120, 120, 120, 120,
162282
- /* 200 */ 119, 119, 118, 118, 118, 117, 113, 444, 454, 419,
162283
- /* 210 */ 13, 13, 215, 120, 120, 120, 120, 119, 119, 118,
162284
- /* 220 */ 118, 118, 117, 113, 444, 422, 308, 557, 1186, 1187,
162285
- /* 230 */ 1188, 441, 440, 409, 1271, 122, 122, 122, 122, 120,
163432
+ /* 0 */ 562, 204, 562, 116, 112, 225, 562, 116, 112, 225,
163433
+ /* 10 */ 562, 1306, 373, 1285, 404, 556, 556, 556, 562, 405,
163434
+ /* 20 */ 374, 1306, 1268, 41, 41, 41, 41, 204, 1516, 71,
163435
+ /* 30 */ 71, 965, 415, 41, 41, 487, 299, 275, 299, 966,
163436
+ /* 40 */ 393, 71, 71, 123, 124, 114, 1209, 1209, 1042, 1045,
163437
+ /* 50 */ 1034, 1034, 121, 121, 122, 122, 122, 122, 472, 405,
163438
+ /* 60 */ 1233, 1, 1, 569, 2, 1237, 544, 116, 112, 225,
163439
+ /* 70 */ 313, 476, 142, 476, 520, 116, 112, 225, 525, 1319,
163440
+ /* 80 */ 413, 519, 138, 123, 124, 114, 1209, 1209, 1042, 1045,
163441
+ /* 90 */ 1034, 1034, 121, 121, 122, 122, 122, 122, 116, 112,
163442
+ /* 100 */ 225, 323, 120, 120, 120, 120, 119, 119, 118, 118,
163443
+ /* 110 */ 118, 117, 113, 440, 280, 280, 280, 280, 438, 438,
163444
+ /* 120 */ 438, 1557, 372, 1559, 1184, 371, 1155, 559, 1155, 559,
163445
+ /* 130 */ 405, 1557, 533, 255, 222, 440, 99, 141, 445, 312,
163446
+ /* 140 */ 553, 236, 120, 120, 120, 120, 119, 119, 118, 118,
163447
+ /* 150 */ 118, 117, 113, 440, 123, 124, 114, 1209, 1209, 1042,
163448
+ /* 160 */ 1045, 1034, 1034, 121, 121, 122, 122, 122, 122, 138,
163449
+ /* 170 */ 290, 1184, 335, 444, 118, 118, 118, 117, 113, 440,
163450
+ /* 180 */ 125, 1184, 1185, 1186, 144, 437, 436, 562, 117, 113,
163451
+ /* 190 */ 440, 122, 122, 122, 122, 115, 120, 120, 120, 120,
163452
+ /* 200 */ 119, 119, 118, 118, 118, 117, 113, 440, 450, 110,
163453
+ /* 210 */ 13, 13, 542, 120, 120, 120, 120, 119, 119, 118,
163454
+ /* 220 */ 118, 118, 117, 113, 440, 418, 312, 553, 1184, 1185,
163455
+ /* 230 */ 1186, 145, 1216, 405, 1216, 122, 122, 122, 122, 120,
162286163456
/* 240 */ 120, 120, 120, 119, 119, 118, 118, 118, 117, 113,
162287
- /* 250 */ 444, 1543, 98, 1033, 1033, 1045, 1048, 123, 124, 114,
162288
- /* 260 */ 1210, 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122,
162289
- /* 270 */ 122, 122, 566, 406, 405, 1186, 566, 409, 1217, 319,
162290
- /* 280 */ 1217, 80, 81, 120, 120, 120, 120, 119, 119, 118,
162291
- /* 290 */ 118, 118, 117, 113, 444, 70, 70, 1186, 1604, 71,
162292
- /* 300 */ 71, 123, 124, 114, 1210, 1210, 1044, 1047, 1036, 1036,
163457
+ /* 250 */ 440, 461, 338, 1031, 1031, 1043, 1046, 123, 124, 114,
163458
+ /* 260 */ 1209, 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122,
163459
+ /* 270 */ 122, 122, 1271, 518, 218, 1184, 562, 405, 220, 510,
163460
+ /* 280 */ 171, 80, 81, 120, 120, 120, 120, 119, 119, 118,
163461
+ /* 290 */ 118, 118, 117, 113, 440, 1001, 16, 16, 1184, 55,
163462
+ /* 300 */ 55, 123, 124, 114, 1209, 1209, 1042, 1045, 1034, 1034,
162293163463
/* 310 */ 121, 121, 122, 122, 122, 122, 120, 120, 120, 120,
162294
- /* 320 */ 119, 119, 118, 118, 118, 117, 113, 444, 1037, 210,
162295
- /* 330 */ 1186, 365, 1186, 1187, 1188, 245, 548, 399, 504, 501,
162296
- /* 340 */ 500, 108, 558, 138, 4, 516, 933, 433, 499, 217,
162297
- /* 350 */ 514, 522, 352, 879, 1186, 1187, 1188, 383, 561, 566,
163464
+ /* 320 */ 119, 119, 118, 118, 118, 117, 113, 440, 1035, 542,
163465
+ /* 330 */ 1184, 369, 1184, 1185, 1186, 248, 1426, 395, 500, 497,
163466
+ /* 340 */ 496, 108, 554, 560, 4, 920, 920, 429, 495, 336,
163467
+ /* 350 */ 456, 324, 356, 390, 1229, 1184, 1185, 1186, 557, 562,
162298163468
/* 360 */ 120, 120, 120, 120, 119, 119, 118, 118, 118, 117,
162299
- /* 370 */ 113, 444, 277, 277, 16, 16, 1598, 441, 440, 153,
162300
- /* 380 */ 409, 445, 13, 13, 1279, 563, 1214, 1186, 1187, 1188,
162301
- /* 390 */ 1003, 1216, 264, 555, 1574, 186, 566, 427, 138, 1215,
162302
- /* 400 */ 308, 557, 472, 138, 123, 124, 114, 1210, 1210, 1044,
162303
- /* 410 */ 1047, 1036, 1036, 121, 121, 122, 122, 122, 122, 55,
162304
- /* 420 */ 55, 413, 1023, 507, 1217, 1186, 1217, 474, 106, 106,
162305
- /* 430 */ 1312, 1312, 1186, 171, 566, 384, 107, 380, 445, 568,
162306
- /* 440 */ 567, 430, 1543, 1013, 332, 549, 565, 263, 280, 360,
162307
- /* 450 */ 510, 355, 509, 250, 491, 308, 557, 71, 71, 351,
162308
- /* 460 */ 308, 557, 374, 120, 120, 120, 120, 119, 119, 118,
162309
- /* 470 */ 118, 118, 117, 113, 444, 1013, 1013, 1015, 1016, 27,
162310
- /* 480 */ 277, 277, 1186, 1187, 1188, 1152, 566, 528, 409, 1186,
162311
- /* 490 */ 1187, 1188, 348, 563, 548, 1260, 533, 517, 1152, 1516,
162312
- /* 500 */ 317, 1152, 285, 550, 485, 569, 566, 569, 482, 51,
162313
- /* 510 */ 51, 207, 123, 124, 114, 1210, 1210, 1044, 1047, 1036,
162314
- /* 520 */ 1036, 121, 121, 122, 122, 122, 122, 171, 1412, 13,
162315
- /* 530 */ 13, 409, 277, 277, 1186, 505, 119, 119, 118, 118,
162316
- /* 540 */ 118, 117, 113, 444, 429, 563, 518, 220, 515, 1552,
162317
- /* 550 */ 365, 546, 1186, 6, 532, 123, 124, 114, 1210, 1210,
162318
- /* 560 */ 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, 122,
162319
- /* 570 */ 145, 120, 120, 120, 120, 119, 119, 118, 118, 118,
162320
- /* 580 */ 117, 113, 444, 245, 566, 474, 504, 501, 500, 566,
162321
- /* 590 */ 1481, 1186, 1187, 1188, 1310, 1310, 499, 1186, 149, 425,
162322
- /* 600 */ 1186, 480, 409, 274, 365, 952, 872, 56, 56, 1186,
162323
- /* 610 */ 1187, 1188, 71, 71, 120, 120, 120, 120, 119, 119,
162324
- /* 620 */ 118, 118, 118, 117, 113, 444, 123, 124, 114, 1210,
162325
- /* 630 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122,
162326
- /* 640 */ 122, 409, 541, 1552, 83, 865, 98, 6, 928, 529,
162327
- /* 650 */ 848, 543, 151, 927, 1186, 1187, 1188, 1186, 1187, 1188,
162328
- /* 660 */ 290, 1543, 187, 1633, 395, 123, 124, 114, 1210, 1210,
162329
- /* 670 */ 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, 122,
162330
- /* 680 */ 566, 954, 566, 453, 953, 120, 120, 120, 120, 119,
162331
- /* 690 */ 119, 118, 118, 118, 117, 113, 444, 1152, 221, 1186,
162332
- /* 700 */ 331, 453, 452, 13, 13, 13, 13, 1003, 365, 463,
162333
- /* 710 */ 1152, 193, 409, 1152, 382, 1543, 1170, 32, 297, 474,
162334
- /* 720 */ 195, 1527, 5, 952, 120, 120, 120, 120, 119, 119,
162335
- /* 730 */ 118, 118, 118, 117, 113, 444, 123, 124, 114, 1210,
162336
- /* 740 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122,
162337
- /* 750 */ 122, 409, 1067, 419, 1186, 1024, 1186, 1187, 1188, 1186,
162338
- /* 760 */ 419, 332, 460, 320, 544, 1545, 442, 442, 442, 566,
162339
- /* 770 */ 3, 117, 113, 444, 453, 123, 124, 114, 1210, 1210,
162340
- /* 780 */ 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, 122,
162341
- /* 790 */ 1473, 566, 15, 15, 293, 120, 120, 120, 120, 119,
162342
- /* 800 */ 119, 118, 118, 118, 117, 113, 444, 1186, 566, 1486,
162343
- /* 810 */ 1412, 1186, 1187, 1188, 13, 13, 1186, 1187, 1188, 1544,
162344
- /* 820 */ 271, 271, 409, 286, 308, 557, 1008, 1486, 1488, 196,
162345
- /* 830 */ 288, 71, 71, 563, 120, 120, 120, 120, 119, 119,
162346
- /* 840 */ 118, 118, 118, 117, 113, 444, 123, 124, 114, 1210,
162347
- /* 850 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122,
162348
- /* 860 */ 122, 409, 201, 1087, 1186, 1187, 1188, 1324, 304, 1529,
162349
- /* 870 */ 388, 278, 278, 450, 564, 402, 922, 922, 566, 563,
162350
- /* 880 */ 566, 426, 491, 480, 563, 123, 124, 114, 1210, 1210,
162351
- /* 890 */ 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, 122,
162352
- /* 900 */ 1486, 71, 71, 13, 13, 120, 120, 120, 120, 119,
162353
- /* 910 */ 119, 118, 118, 118, 117, 113, 444, 566, 545, 566,
162354
- /* 920 */ 1577, 573, 2, 1238, 1092, 1092, 488, 1480, 309, 1525,
162355
- /* 930 */ 142, 324, 409, 836, 837, 838, 312, 1320, 305, 363,
162356
- /* 940 */ 43, 43, 57, 57, 120, 120, 120, 120, 119, 119,
162357
- /* 950 */ 118, 118, 118, 117, 113, 444, 123, 124, 114, 1210,
162358
- /* 960 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122,
162359
- /* 970 */ 122, 12, 277, 277, 566, 1152, 409, 572, 428, 1238,
162360
- /* 980 */ 465, 334, 296, 474, 309, 563, 142, 249, 1152, 308,
162361
- /* 990 */ 557, 1152, 321, 1320, 323, 491, 455, 71, 71, 233,
162362
- /* 1000 */ 283, 101, 114, 1210, 1210, 1044, 1047, 1036, 1036, 121,
163469
+ /* 370 */ 113, 440, 280, 280, 365, 1570, 1597, 437, 436, 150,
163470
+ /* 380 */ 405, 441, 71, 71, 1278, 559, 1213, 1184, 1185, 1186,
163471
+ /* 390 */ 83, 1215, 267, 551, 539, 511, 1551, 562, 96, 1214,
163472
+ /* 400 */ 6, 1270, 468, 138, 123, 124, 114, 1209, 1209, 1042,
163473
+ /* 410 */ 1045, 1034, 1034, 121, 121, 122, 122, 122, 122, 544,
163474
+ /* 420 */ 13, 13, 1021, 503, 1216, 1184, 1216, 543, 106, 106,
163475
+ /* 430 */ 218, 562, 1230, 171, 562, 423, 107, 193, 441, 564,
163476
+ /* 440 */ 563, 426, 1542, 1011, 321, 545, 1184, 266, 283, 364,
163477
+ /* 450 */ 506, 359, 505, 253, 71, 71, 539, 71, 71, 355,
163478
+ /* 460 */ 312, 553, 1603, 120, 120, 120, 120, 119, 119, 118,
163479
+ /* 470 */ 118, 118, 117, 113, 440, 1011, 1011, 1013, 1014, 27,
163480
+ /* 480 */ 280, 280, 1184, 1185, 1186, 1150, 562, 1602, 405, 895,
163481
+ /* 490 */ 186, 544, 352, 559, 544, 931, 529, 513, 1150, 512,
163482
+ /* 500 */ 409, 1150, 546, 1184, 1185, 1186, 562, 540, 1544, 51,
163483
+ /* 510 */ 51, 210, 123, 124, 114, 1209, 1209, 1042, 1045, 1034,
163484
+ /* 520 */ 1034, 121, 121, 122, 122, 122, 122, 1184, 470, 56,
163485
+ /* 530 */ 56, 405, 280, 280, 1480, 501, 119, 119, 118, 118,
163486
+ /* 540 */ 118, 117, 113, 440, 1001, 559, 514, 213, 537, 1551,
163487
+ /* 550 */ 312, 553, 138, 6, 528, 123, 124, 114, 1209, 1209,
163488
+ /* 560 */ 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122, 122,
163489
+ /* 570 */ 1545, 120, 120, 120, 120, 119, 119, 118, 118, 118,
163490
+ /* 580 */ 117, 113, 440, 481, 1184, 1185, 1186, 478, 277, 1259,
163491
+ /* 590 */ 951, 248, 1184, 369, 500, 497, 496, 1184, 336, 565,
163492
+ /* 600 */ 1184, 565, 405, 288, 495, 951, 870, 187, 476, 312,
163493
+ /* 610 */ 553, 380, 286, 376, 120, 120, 120, 120, 119, 119,
163494
+ /* 620 */ 118, 118, 118, 117, 113, 440, 123, 124, 114, 1209,
163495
+ /* 630 */ 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122,
163496
+ /* 640 */ 122, 405, 390, 1128, 1184, 863, 98, 280, 280, 1184,
163497
+ /* 650 */ 1185, 1186, 369, 1085, 1184, 1185, 1186, 1184, 1185, 1186,
163498
+ /* 660 */ 559, 451, 32, 369, 229, 123, 124, 114, 1209, 1209,
163499
+ /* 670 */ 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122, 122,
163500
+ /* 680 */ 1425, 953, 562, 224, 952, 120, 120, 120, 120, 119,
163501
+ /* 690 */ 119, 118, 118, 118, 117, 113, 440, 1150, 224, 1184,
163502
+ /* 700 */ 153, 1184, 1185, 1186, 1543, 13, 13, 297, 951, 1224,
163503
+ /* 710 */ 1150, 149, 405, 1150, 369, 1573, 1168, 5, 365, 1570,
163504
+ /* 720 */ 425, 1230, 3, 951, 120, 120, 120, 120, 119, 119,
163505
+ /* 730 */ 118, 118, 118, 117, 113, 440, 123, 124, 114, 1209,
163506
+ /* 740 */ 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122,
163507
+ /* 750 */ 122, 405, 204, 561, 1184, 1022, 1184, 1185, 1186, 1184,
163508
+ /* 760 */ 384, 846, 151, 1542, 282, 398, 1090, 1090, 484, 562,
163509
+ /* 770 */ 461, 338, 1311, 1311, 1542, 123, 124, 114, 1209, 1209,
163510
+ /* 780 */ 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122, 122,
163511
+ /* 790 */ 127, 562, 13, 13, 370, 120, 120, 120, 120, 119,
163512
+ /* 800 */ 119, 118, 118, 118, 117, 113, 440, 298, 562, 449,
163513
+ /* 810 */ 524, 1184, 1185, 1186, 13, 13, 1184, 1185, 1186, 1289,
163514
+ /* 820 */ 459, 1259, 405, 1309, 1309, 1542, 1006, 449, 448, 196,
163515
+ /* 830 */ 295, 71, 71, 1257, 120, 120, 120, 120, 119, 119,
163516
+ /* 840 */ 118, 118, 118, 117, 113, 440, 123, 124, 114, 1209,
163517
+ /* 850 */ 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122,
163518
+ /* 860 */ 122, 405, 223, 1065, 1150, 280, 280, 415, 308, 274,
163519
+ /* 870 */ 274, 281, 281, 1411, 402, 401, 378, 1150, 559, 562,
163520
+ /* 880 */ 1150, 1188, 559, 1590, 559, 123, 124, 114, 1209, 1209,
163521
+ /* 890 */ 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122, 122,
163522
+ /* 900 */ 449, 1472, 13, 13, 1526, 120, 120, 120, 120, 119,
163523
+ /* 910 */ 119, 118, 118, 118, 117, 113, 440, 197, 562, 350,
163524
+ /* 920 */ 1576, 569, 2, 1237, 834, 835, 836, 1552, 313, 1204,
163525
+ /* 930 */ 142, 6, 405, 251, 250, 249, 202, 1319, 9, 1188,
163526
+ /* 940 */ 258, 71, 71, 420, 120, 120, 120, 120, 119, 119,
163527
+ /* 950 */ 118, 118, 118, 117, 113, 440, 123, 124, 114, 1209,
163528
+ /* 960 */ 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122,
163529
+ /* 970 */ 122, 562, 280, 280, 562, 1205, 405, 568, 309, 1237,
163530
+ /* 980 */ 345, 1288, 348, 415, 313, 559, 142, 487, 521, 1633,
163531
+ /* 990 */ 391, 367, 487, 1319, 70, 70, 1287, 71, 71, 236,
163532
+ /* 1000 */ 1317, 101, 114, 1209, 1209, 1042, 1045, 1034, 1034, 121,
162363163533
/* 1010 */ 121, 122, 122, 122, 122, 120, 120, 120, 120, 119,
162364
- /* 1020 */ 119, 118, 118, 118, 117, 113, 444, 1108, 277, 277,
162365
- /* 1030 */ 1412, 448, 394, 1230, 439, 277, 277, 248, 247, 246,
162366
- /* 1040 */ 1319, 563, 1109, 313, 198, 294, 491, 1318, 563, 464,
162367
- /* 1050 */ 566, 1427, 394, 1130, 1023, 233, 414, 1110, 295, 120,
163534
+ /* 1020 */ 119, 118, 118, 118, 117, 113, 440, 1106, 280, 280,
163535
+ /* 1030 */ 424, 444, 1515, 1205, 435, 280, 280, 1479, 1344, 307,
163536
+ /* 1040 */ 470, 559, 1107, 965, 487, 487, 213, 1255, 559, 1528,
163537
+ /* 1050 */ 562, 966, 203, 562, 1021, 236, 379, 1108, 515, 120,
162368163538
/* 1060 */ 120, 120, 120, 119, 119, 118, 118, 118, 117, 113,
162369
- /* 1070 */ 444, 1014, 104, 71, 71, 1013, 322, 496, 908, 566,
162370
- /* 1080 */ 277, 277, 277, 277, 1108, 1261, 415, 448, 909, 361,
162371
- /* 1090 */ 1571, 1315, 409, 563, 952, 563, 9, 202, 255, 1109,
162372
- /* 1100 */ 316, 487, 44, 44, 249, 559, 415, 1013, 1013, 1015,
162373
- /* 1110 */ 443, 1231, 409, 1603, 1110, 897, 123, 124, 114, 1210,
162374
- /* 1120 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122,
162375
- /* 1130 */ 122, 1231, 409, 1207, 215, 554, 123, 124, 114, 1210,
162376
- /* 1140 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122,
162377
- /* 1150 */ 122, 1131, 1631, 470, 1631, 255, 123, 111, 114, 1210,
162378
- /* 1160 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122,
162379
- /* 1170 */ 122, 1131, 1632, 414, 1632, 120, 120, 120, 120, 119,
162380
- /* 1180 */ 119, 118, 118, 118, 117, 113, 444, 221, 209, 351,
162381
- /* 1190 */ 1207, 1207, 147, 1426, 491, 120, 120, 120, 120, 119,
162382
- /* 1200 */ 119, 118, 118, 118, 117, 113, 444, 1256, 539, 519,
162383
- /* 1210 */ 888, 551, 952, 12, 566, 120, 120, 120, 120, 119,
162384
- /* 1220 */ 119, 118, 118, 118, 117, 113, 444, 538, 566, 860,
162385
- /* 1230 */ 1129, 361, 1571, 346, 1356, 409, 1163, 58, 58, 339,
162386
- /* 1240 */ 1355, 508, 277, 277, 277, 277, 277, 277, 1207, 889,
162387
- /* 1250 */ 1129, 59, 59, 459, 363, 563, 566, 563, 96, 563,
162388
- /* 1260 */ 124, 114, 1210, 1210, 1044, 1047, 1036, 1036, 121, 121,
162389
- /* 1270 */ 122, 122, 122, 122, 566, 1412, 566, 281, 1186, 60,
162390
- /* 1280 */ 60, 110, 392, 392, 391, 266, 389, 860, 1163, 845,
162391
- /* 1290 */ 566, 481, 566, 436, 341, 1152, 344, 61, 61, 62,
162392
- /* 1300 */ 62, 967, 227, 1550, 315, 431, 540, 6, 1152, 968,
162393
- /* 1310 */ 566, 1152, 314, 45, 45, 46, 46, 512, 120, 120,
162394
- /* 1320 */ 120, 120, 119, 119, 118, 118, 118, 117, 113, 444,
162395
- /* 1330 */ 416, 173, 1532, 47, 47, 1186, 1187, 1188, 108, 558,
162396
- /* 1340 */ 325, 4, 229, 1551, 928, 566, 437, 6, 566, 927,
162397
- /* 1350 */ 164, 566, 1290, 137, 1190, 561, 566, 1549, 566, 1089,
162398
- /* 1360 */ 566, 6, 566, 1089, 531, 566, 868, 8, 49, 49,
162399
- /* 1370 */ 228, 50, 50, 566, 63, 63, 566, 457, 445, 64,
162400
- /* 1380 */ 64, 65, 65, 14, 14, 66, 66, 407, 129, 129,
162401
- /* 1390 */ 555, 566, 458, 566, 1505, 486, 67, 67, 566, 52,
162402
- /* 1400 */ 52, 546, 407, 467, 535, 410, 226, 1023, 566, 534,
162403
- /* 1410 */ 308, 557, 1190, 407, 68, 68, 69, 69, 566, 1023,
162404
- /* 1420 */ 566, 53, 53, 868, 1014, 106, 106, 525, 1013, 566,
162405
- /* 1430 */ 1504, 159, 159, 107, 451, 445, 568, 567, 471, 307,
162406
- /* 1440 */ 1013, 160, 160, 76, 76, 566, 1548, 466, 407, 407,
162407
- /* 1450 */ 6, 1225, 54, 54, 478, 276, 219, 566, 887, 886,
162408
- /* 1460 */ 1013, 1013, 1015, 84, 206, 1206, 230, 282, 72, 72,
162409
- /* 1470 */ 329, 483, 1013, 1013, 1015, 1016, 27, 1576, 1174, 447,
162410
- /* 1480 */ 130, 130, 281, 148, 105, 38, 103, 392, 392, 391,
162411
- /* 1490 */ 266, 389, 566, 1126, 845, 396, 566, 108, 558, 566,
162412
- /* 1500 */ 4, 311, 566, 30, 17, 566, 279, 227, 566, 315,
162413
- /* 1510 */ 108, 558, 468, 4, 561, 73, 73, 314, 566, 157,
162414
- /* 1520 */ 157, 566, 131, 131, 526, 132, 132, 561, 128, 128,
162415
- /* 1530 */ 566, 158, 158, 566, 31, 291, 566, 445, 330, 521,
162416
- /* 1540 */ 98, 152, 152, 420, 136, 136, 1005, 229, 254, 555,
162417
- /* 1550 */ 445, 479, 336, 135, 135, 164, 133, 133, 137, 134,
162418
- /* 1560 */ 134, 875, 555, 535, 566, 473, 566, 254, 536, 475,
162419
- /* 1570 */ 335, 254, 98, 894, 895, 228, 535, 566, 1023, 566,
162420
- /* 1580 */ 1074, 534, 210, 232, 106, 106, 1352, 75, 75, 77,
162421
- /* 1590 */ 77, 1023, 107, 340, 445, 568, 567, 106, 106, 1013,
162422
- /* 1600 */ 74, 74, 42, 42, 566, 107, 343, 445, 568, 567,
162423
- /* 1610 */ 410, 497, 1013, 251, 359, 308, 557, 1135, 349, 875,
162424
- /* 1620 */ 98, 1070, 345, 251, 358, 1591, 347, 48, 48, 1017,
162425
- /* 1630 */ 1303, 1013, 1013, 1015, 1016, 27, 1289, 1287, 1074, 451,
162426
- /* 1640 */ 961, 925, 254, 110, 1013, 1013, 1015, 1016, 27, 1174,
162427
- /* 1650 */ 447, 970, 971, 281, 108, 558, 1288, 4, 392, 392,
162428
- /* 1660 */ 391, 266, 389, 1343, 1086, 845, 1086, 1085, 858, 1085,
162429
- /* 1670 */ 146, 561, 926, 354, 110, 303, 364, 553, 227, 1364,
162430
- /* 1680 */ 315, 108, 558, 1411, 4, 1339, 492, 1017, 314, 1350,
162431
- /* 1690 */ 1565, 552, 1417, 1268, 445, 204, 1259, 1247, 561, 1246,
162432
- /* 1700 */ 1248, 1584, 269, 1336, 367, 369, 555, 371, 11, 212,
162433
- /* 1710 */ 393, 225, 1393, 284, 1398, 456, 287, 327, 229, 328,
162434
- /* 1720 */ 292, 445, 1386, 216, 333, 1403, 164, 477, 373, 137,
162435
- /* 1730 */ 1402, 400, 502, 555, 1286, 1023, 357, 1477, 199, 1587,
162436
- /* 1740 */ 211, 106, 106, 932, 1476, 1225, 228, 556, 175, 107,
162437
- /* 1750 */ 200, 445, 568, 567, 258, 387, 1013, 1524, 1522, 223,
162438
- /* 1760 */ 1222, 418, 1023, 83, 208, 79, 82, 184, 106, 106,
162439
- /* 1770 */ 1482, 169, 177, 461, 179, 462, 107, 1399, 445, 568,
162440
- /* 1780 */ 567, 410, 180, 1013, 495, 181, 308, 557, 1013, 1013,
162441
- /* 1790 */ 1015, 1016, 27, 182, 35, 235, 100, 558, 398, 4,
162442
- /* 1800 */ 96, 1405, 1404, 36, 484, 469, 1407, 188, 401, 1471,
162443
- /* 1810 */ 451, 89, 1493, 561, 239, 1013, 1013, 1015, 1016, 27,
162444
- /* 1820 */ 490, 338, 270, 241, 192, 342, 493, 242, 403, 1249,
162445
- /* 1830 */ 243, 511, 432, 1297, 1306, 91, 445, 1305, 1304, 879,
162446
- /* 1840 */ 217, 434, 435, 1570, 1276, 1602, 520, 1601, 555, 301,
162447
- /* 1850 */ 527, 404, 1275, 302, 356, 1274, 1600, 95, 1347, 366,
162448
- /* 1860 */ 1296, 362, 1348, 368, 256, 257, 1556, 1555, 438, 1346,
162449
- /* 1870 */ 370, 126, 1345, 10, 1371, 546, 381, 1023, 102, 1457,
162450
- /* 1880 */ 97, 530, 34, 106, 106, 570, 1180, 372, 265, 1329,
162451
- /* 1890 */ 379, 107, 203, 445, 568, 567, 1328, 385, 1013, 1370,
162452
- /* 1900 */ 386, 267, 268, 571, 1244, 161, 1239, 162, 1509, 1510,
162453
- /* 1910 */ 1508, 143, 1507, 299, 832, 213, 214, 78, 446, 205,
162454
- /* 1920 */ 310, 306, 163, 224, 1084, 140, 1082, 318, 165, 176,
162455
- /* 1930 */ 1013, 1013, 1015, 1016, 27, 178, 1206, 231, 911, 234,
162456
- /* 1940 */ 326, 1098, 183, 421, 166, 167, 411, 185, 85, 423,
162457
- /* 1950 */ 412, 86, 174, 87, 168, 88, 1101, 236, 1097, 237,
162458
- /* 1960 */ 154, 18, 238, 254, 337, 1219, 489, 1090, 240, 190,
162459
- /* 1970 */ 37, 847, 189, 494, 358, 244, 350, 506, 191, 877,
162460
- /* 1980 */ 90, 498, 19, 20, 503, 92, 353, 890, 300, 170,
162461
- /* 1990 */ 155, 93, 513, 94, 1168, 156, 1050, 1137, 39, 218,
162462
- /* 2000 */ 273, 275, 1136, 960, 194, 955, 110, 1154, 1158, 253,
162463
- /* 2010 */ 7, 1162, 1156, 21, 22, 1161, 1142, 23, 24, 25,
162464
- /* 2020 */ 33, 542, 26, 260, 197, 98, 1065, 1051, 1049, 1053,
162465
- /* 2030 */ 1107, 1054, 1106, 259, 28, 40, 562, 1018, 859, 109,
162466
- /* 2040 */ 29, 921, 390, 1176, 172, 139, 1175, 1235, 261, 1235,
162467
- /* 2050 */ 1235, 1235, 1235, 1235, 1235, 1235, 1235, 262, 1235, 1235,
162468
- /* 2060 */ 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1593, 1592,
163539
+ /* 1070 */ 440, 1012, 104, 71, 71, 1011, 13, 13, 906, 562,
163540
+ /* 1080 */ 1485, 562, 280, 280, 95, 522, 487, 444, 907, 1318,
163541
+ /* 1090 */ 1314, 541, 405, 280, 280, 559, 147, 205, 1485, 1487,
163542
+ /* 1100 */ 258, 446, 15, 15, 43, 43, 559, 1011, 1011, 1013,
163543
+ /* 1110 */ 439, 328, 405, 523, 12, 291, 123, 124, 114, 1209,
163544
+ /* 1120 */ 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122,
163545
+ /* 1130 */ 122, 343, 405, 858, 1524, 1205, 123, 124, 114, 1209,
163546
+ /* 1140 */ 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122,
163547
+ /* 1150 */ 122, 1129, 1631, 470, 1631, 367, 123, 111, 114, 1209,
163548
+ /* 1160 */ 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122,
163549
+ /* 1170 */ 122, 1485, 325, 470, 327, 120, 120, 120, 120, 119,
163550
+ /* 1180 */ 119, 118, 118, 118, 117, 113, 440, 199, 1411, 562,
163551
+ /* 1190 */ 1286, 858, 460, 1205, 432, 120, 120, 120, 120, 119,
163552
+ /* 1200 */ 119, 118, 118, 118, 117, 113, 440, 547, 1129, 1632,
163553
+ /* 1210 */ 535, 1632, 57, 57, 886, 120, 120, 120, 120, 119,
163554
+ /* 1220 */ 119, 118, 118, 118, 117, 113, 440, 562, 294, 534,
163555
+ /* 1230 */ 1127, 1411, 1549, 1550, 1323, 405, 6, 6, 1161, 1260,
163556
+ /* 1240 */ 411, 316, 280, 280, 1411, 504, 559, 521, 296, 453,
163557
+ /* 1250 */ 44, 44, 562, 887, 12, 559, 326, 474, 421, 403,
163558
+ /* 1260 */ 124, 114, 1209, 1209, 1042, 1045, 1034, 1034, 121, 121,
163559
+ /* 1270 */ 122, 122, 122, 122, 562, 58, 58, 284, 1184, 1411,
163560
+ /* 1280 */ 492, 454, 388, 388, 387, 269, 385, 1127, 1548, 843,
163561
+ /* 1290 */ 1161, 403, 6, 562, 317, 1150, 466, 59, 59, 1547,
163562
+ /* 1300 */ 1106, 422, 230, 6, 319, 252, 536, 252, 1150, 427,
163563
+ /* 1310 */ 562, 1150, 318, 17, 483, 1107, 60, 60, 120, 120,
163564
+ /* 1320 */ 120, 120, 119, 119, 118, 118, 118, 117, 113, 440,
163565
+ /* 1330 */ 1108, 212, 477, 61, 61, 1184, 1185, 1186, 108, 554,
163566
+ /* 1340 */ 320, 4, 232, 452, 522, 562, 233, 452, 562, 433,
163567
+ /* 1350 */ 164, 550, 416, 137, 475, 557, 562, 289, 562, 1087,
163568
+ /* 1360 */ 562, 289, 562, 1087, 527, 562, 866, 8, 62, 62,
163569
+ /* 1370 */ 231, 45, 45, 562, 410, 562, 410, 562, 441, 46,
163570
+ /* 1380 */ 46, 47, 47, 49, 49, 50, 50, 195, 63, 63,
163571
+ /* 1390 */ 551, 562, 355, 562, 98, 482, 64, 64, 65, 65,
163572
+ /* 1400 */ 14, 14, 555, 411, 531, 406, 562, 1021, 562, 530,
163573
+ /* 1410 */ 312, 553, 312, 553, 66, 66, 129, 129, 562, 1021,
163574
+ /* 1420 */ 562, 508, 926, 866, 1012, 106, 106, 925, 1011, 67,
163575
+ /* 1430 */ 67, 52, 52, 107, 447, 441, 564, 563, 412, 173,
163576
+ /* 1440 */ 1011, 68, 68, 69, 69, 562, 463, 562, 926, 467,
163577
+ /* 1450 */ 1356, 279, 222, 925, 311, 1355, 403, 562, 455, 403,
163578
+ /* 1460 */ 1011, 1011, 1013, 235, 403, 84, 209, 1342, 53, 53,
163579
+ /* 1470 */ 159, 159, 1011, 1011, 1013, 1014, 27, 1575, 1172, 443,
163580
+ /* 1480 */ 160, 160, 284, 95, 105, 1531, 103, 388, 388, 387,
163581
+ /* 1490 */ 269, 385, 562, 873, 843, 877, 562, 108, 554, 462,
163582
+ /* 1500 */ 4, 562, 148, 30, 38, 562, 1124, 230, 392, 319,
163583
+ /* 1510 */ 108, 554, 523, 4, 557, 76, 76, 318, 562, 54,
163584
+ /* 1520 */ 54, 562, 333, 464, 72, 72, 329, 557, 130, 130,
163585
+ /* 1530 */ 562, 285, 1504, 562, 31, 1503, 562, 441, 334, 479,
163586
+ /* 1540 */ 98, 73, 73, 340, 157, 157, 292, 232, 1072, 551,
163587
+ /* 1550 */ 441, 873, 1352, 131, 131, 164, 132, 132, 137, 128,
163588
+ /* 1560 */ 128, 1564, 551, 531, 562, 315, 562, 344, 532, 1003,
163589
+ /* 1570 */ 469, 257, 257, 885, 884, 231, 531, 562, 1021, 562,
163590
+ /* 1580 */ 471, 530, 257, 363, 106, 106, 517, 158, 158, 152,
163591
+ /* 1590 */ 152, 1021, 107, 362, 441, 564, 563, 106, 106, 1011,
163592
+ /* 1600 */ 136, 136, 135, 135, 562, 107, 1072, 441, 564, 563,
163593
+ /* 1610 */ 406, 347, 1011, 562, 349, 312, 553, 562, 339, 562,
163594
+ /* 1620 */ 98, 493, 353, 254, 98, 892, 893, 133, 133, 351,
163595
+ /* 1630 */ 1302, 1011, 1011, 1013, 1014, 27, 134, 134, 1015, 447,
163596
+ /* 1640 */ 75, 75, 77, 77, 1011, 1011, 1013, 1014, 27, 1172,
163597
+ /* 1650 */ 443, 562, 358, 284, 108, 554, 368, 4, 388, 388,
163598
+ /* 1660 */ 387, 269, 385, 562, 1133, 843, 562, 1068, 956, 254,
163599
+ /* 1670 */ 257, 557, 968, 969, 74, 74, 549, 923, 230, 110,
163600
+ /* 1680 */ 319, 108, 554, 1084, 4, 1084, 42, 42, 318, 48,
163601
+ /* 1690 */ 48, 1083, 1365, 1083, 441, 856, 1015, 146, 557, 924,
163602
+ /* 1700 */ 1410, 110, 1338, 1350, 548, 1416, 551, 1267, 207, 1258,
163603
+ /* 1710 */ 1246, 1245, 1247, 1583, 11, 488, 272, 215, 232, 1335,
163604
+ /* 1720 */ 304, 441, 305, 306, 389, 228, 164, 1397, 1392, 137,
163605
+ /* 1730 */ 287, 331, 332, 551, 293, 1021, 1385, 337, 473, 200,
163606
+ /* 1740 */ 361, 106, 106, 930, 498, 1402, 231, 1401, 1285, 107,
163607
+ /* 1750 */ 396, 441, 564, 563, 219, 1476, 1011, 1347, 1475, 1348,
163608
+ /* 1760 */ 1346, 1345, 1021, 1224, 552, 1586, 261, 1221, 106, 106,
163609
+ /* 1770 */ 1523, 201, 383, 1521, 214, 414, 107, 83, 441, 564,
163610
+ /* 1780 */ 563, 406, 211, 1011, 175, 1398, 312, 553, 1011, 1011,
163611
+ /* 1790 */ 1013, 1014, 27, 226, 184, 169, 100, 554, 79, 4,
163612
+ /* 1800 */ 82, 457, 35, 179, 458, 177, 491, 238, 96, 1481,
163613
+ /* 1810 */ 447, 180, 1404, 557, 181, 1011, 1011, 1013, 1014, 27,
163614
+ /* 1820 */ 182, 1403, 394, 36, 465, 1406, 397, 188, 1470, 480,
163615
+ /* 1830 */ 242, 89, 1492, 486, 342, 244, 441, 273, 192, 346,
163616
+ /* 1840 */ 489, 245, 399, 1248, 428, 246, 507, 1296, 551, 91,
163617
+ /* 1850 */ 877, 1305, 1304, 220, 1601, 1295, 1303, 430, 431, 516,
163618
+ /* 1860 */ 1569, 259, 400, 302, 1600, 1275, 303, 260, 360, 1274,
163619
+ /* 1870 */ 1273, 1599, 366, 1555, 434, 1554, 1370, 1021, 1369, 542,
163620
+ /* 1880 */ 126, 10, 1456, 106, 106, 377, 102, 97, 310, 526,
163621
+ /* 1890 */ 34, 107, 566, 441, 564, 563, 1178, 271, 1011, 268,
163622
+ /* 1900 */ 270, 567, 1243, 1238, 206, 1328, 375, 381, 1327, 382,
163623
+ /* 1910 */ 407, 161, 174, 408, 1508, 1509, 143, 300, 830, 162,
163624
+ /* 1920 */ 1507, 1506, 163, 442, 208, 314, 227, 216, 217, 78,
163625
+ /* 1930 */ 1011, 1011, 1013, 1014, 27, 140, 1082, 322, 1080, 165,
163626
+ /* 1940 */ 176, 1204, 234, 178, 909, 330, 237, 1096, 183, 166,
163627
+ /* 1950 */ 167, 417, 85, 86, 419, 185, 87, 88, 168, 1099,
163628
+ /* 1960 */ 239, 1095, 240, 154, 18, 241, 341, 1218, 257, 1088,
163629
+ /* 1970 */ 243, 485, 190, 189, 37, 845, 490, 362, 247, 494,
163630
+ /* 1980 */ 357, 191, 875, 90, 19, 502, 354, 20, 499, 92,
163631
+ /* 1990 */ 170, 155, 888, 93, 301, 509, 94, 1166, 156, 1048,
163632
+ /* 2000 */ 1135, 39, 221, 1134, 276, 278, 256, 194, 110, 960,
163633
+ /* 2010 */ 954, 1156, 21, 1152, 22, 1160, 1140, 1154, 23, 33,
163634
+ /* 2020 */ 24, 1159, 25, 538, 26, 198, 98, 1063, 1049, 1047,
163635
+ /* 2030 */ 1051, 7, 1105, 262, 1104, 263, 1052, 28, 40, 558,
163636
+ /* 2040 */ 1016, 857, 109, 29, 919, 386, 139, 172, 264, 265,
163637
+ /* 2050 */ 1174, 1592, 1173, 1234, 1234, 1234, 1234, 1234, 1234, 1234,
163638
+ /* 2060 */ 1234, 1234, 1234, 1591,
162469163639
};
162470163640
static const YYCODETYPE yy_lookahead[] = {
162471
- /* 0 */ 193, 223, 193, 225, 193, 193, 193, 274, 275, 276,
162472
- /* 10 */ 193, 233, 219, 193, 274, 275, 276, 206, 206, 19,
162473
- /* 20 */ 193, 219, 216, 216, 217, 216, 217, 193, 295, 216,
162474
- /* 30 */ 217, 31, 205, 216, 217, 193, 216, 217, 213, 39,
162475
- /* 40 */ 228, 193, 230, 43, 44, 45, 46, 47, 48, 49,
163641
+ /* 0 */ 193, 193, 193, 274, 275, 276, 193, 274, 275, 276,
163642
+ /* 10 */ 193, 223, 219, 225, 206, 210, 211, 212, 193, 19,
163643
+ /* 20 */ 219, 233, 216, 216, 217, 216, 217, 193, 295, 216,
163644
+ /* 30 */ 217, 31, 193, 216, 217, 193, 228, 213, 230, 39,
163645
+ /* 40 */ 206, 216, 217, 43, 44, 45, 46, 47, 48, 49,
162476163646
/* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 193, 19,
162477163647
/* 60 */ 185, 186, 187, 188, 189, 190, 253, 274, 275, 276,
162478
- /* 70 */ 195, 193, 197, 253, 216, 262, 274, 275, 276, 204,
162479
- /* 80 */ 238, 204, 262, 43, 44, 45, 46, 47, 48, 49,
162480
- /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 264, 274,
162481
- /* 100 */ 275, 276, 102, 103, 104, 105, 106, 107, 108, 109,
163648
+ /* 70 */ 195, 193, 197, 193, 261, 274, 275, 276, 253, 204,
163649
+ /* 80 */ 238, 204, 81, 43, 44, 45, 46, 47, 48, 49,
163650
+ /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 274, 275,
163651
+ /* 100 */ 276, 262, 102, 103, 104, 105, 106, 107, 108, 109,
162482163652
/* 110 */ 110, 111, 112, 113, 239, 240, 239, 240, 210, 211,
162483163653
/* 120 */ 212, 314, 315, 314, 59, 316, 86, 252, 88, 252,
162484
- /* 130 */ 19, 314, 315, 256, 257, 309, 25, 72, 296, 313,
162485
- /* 140 */ 193, 266, 102, 103, 104, 105, 106, 107, 108, 109,
163654
+ /* 130 */ 19, 314, 315, 256, 257, 113, 25, 72, 296, 138,
163655
+ /* 140 */ 139, 266, 102, 103, 104, 105, 106, 107, 108, 109,
162486163656
/* 150 */ 110, 111, 112, 113, 43, 44, 45, 46, 47, 48,
162487163657
/* 160 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 81,
162488
- /* 170 */ 292, 59, 307, 298, 108, 109, 110, 111, 112, 113,
162489
- /* 180 */ 69, 116, 117, 118, 72, 128, 129, 193, 241, 22,
163658
+ /* 170 */ 292, 59, 292, 298, 108, 109, 110, 111, 112, 113,
163659
+ /* 180 */ 69, 116, 117, 118, 72, 106, 107, 193, 111, 112,
162490163660
/* 190 */ 113, 54, 55, 56, 57, 58, 102, 103, 104, 105,
162491
- /* 200 */ 106, 107, 108, 109, 110, 111, 112, 113, 120, 193,
162492
- /* 210 */ 216, 217, 25, 102, 103, 104, 105, 106, 107, 108,
163661
+ /* 200 */ 106, 107, 108, 109, 110, 111, 112, 113, 120, 25,
163662
+ /* 210 */ 216, 217, 145, 102, 103, 104, 105, 106, 107, 108,
162493163663
/* 220 */ 109, 110, 111, 112, 113, 231, 138, 139, 116, 117,
162494
- /* 230 */ 118, 106, 107, 19, 216, 54, 55, 56, 57, 102,
163664
+ /* 230 */ 118, 164, 153, 19, 155, 54, 55, 56, 57, 102,
162495163665
/* 240 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
162496
- /* 250 */ 113, 304, 25, 46, 47, 48, 49, 43, 44, 45,
163666
+ /* 250 */ 113, 128, 129, 46, 47, 48, 49, 43, 44, 45,
162497163667
/* 260 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
162498
- /* 270 */ 56, 57, 193, 106, 107, 59, 193, 19, 153, 263,
162499
- /* 280 */ 155, 67, 24, 102, 103, 104, 105, 106, 107, 108,
162500
- /* 290 */ 109, 110, 111, 112, 113, 216, 217, 59, 230, 216,
163668
+ /* 270 */ 56, 57, 216, 193, 25, 59, 193, 19, 165, 166,
163669
+ /* 280 */ 193, 67, 24, 102, 103, 104, 105, 106, 107, 108,
163670
+ /* 290 */ 109, 110, 111, 112, 113, 73, 216, 217, 59, 216,
162501163671
/* 300 */ 217, 43, 44, 45, 46, 47, 48, 49, 50, 51,
162502163672
/* 310 */ 52, 53, 54, 55, 56, 57, 102, 103, 104, 105,
162503
- /* 320 */ 106, 107, 108, 109, 110, 111, 112, 113, 121, 142,
162504
- /* 330 */ 59, 193, 116, 117, 118, 119, 253, 204, 122, 123,
162505
- /* 340 */ 124, 19, 20, 81, 22, 262, 108, 19, 132, 165,
162506
- /* 350 */ 166, 193, 24, 126, 116, 117, 118, 278, 36, 193,
163673
+ /* 320 */ 106, 107, 108, 109, 110, 111, 112, 113, 121, 145,
163674
+ /* 330 */ 59, 193, 116, 117, 118, 119, 273, 204, 122, 123,
163675
+ /* 340 */ 124, 19, 20, 134, 22, 136, 137, 19, 132, 127,
163676
+ /* 350 */ 128, 129, 24, 22, 23, 116, 117, 118, 36, 193,
162507163677
/* 360 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
162508
- /* 370 */ 112, 113, 239, 240, 216, 217, 215, 106, 107, 241,
163678
+ /* 370 */ 112, 113, 239, 240, 311, 312, 215, 106, 107, 241,
162509163679
/* 380 */ 19, 59, 216, 217, 223, 252, 115, 116, 117, 118,
162510
- /* 390 */ 73, 120, 26, 71, 193, 22, 193, 231, 81, 128,
162511
- /* 400 */ 138, 139, 269, 81, 43, 44, 45, 46, 47, 48,
162512
- /* 410 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 216,
162513
- /* 420 */ 217, 198, 100, 95, 153, 59, 155, 193, 106, 107,
162514
- /* 430 */ 235, 236, 59, 193, 193, 249, 114, 251, 116, 117,
162515
- /* 440 */ 118, 113, 304, 121, 127, 204, 193, 119, 120, 121,
162516
- /* 450 */ 122, 123, 124, 125, 193, 138, 139, 216, 217, 131,
162517
- /* 460 */ 138, 139, 193, 102, 103, 104, 105, 106, 107, 108,
163680
+ /* 390 */ 151, 120, 26, 71, 193, 308, 309, 193, 149, 128,
163681
+ /* 400 */ 313, 216, 269, 81, 43, 44, 45, 46, 47, 48,
163682
+ /* 410 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 253,
163683
+ /* 420 */ 216, 217, 100, 95, 153, 59, 155, 261, 106, 107,
163684
+ /* 430 */ 25, 193, 101, 193, 193, 231, 114, 25, 116, 117,
163685
+ /* 440 */ 118, 113, 304, 121, 193, 204, 59, 119, 120, 121,
163686
+ /* 450 */ 122, 123, 124, 125, 216, 217, 193, 216, 217, 131,
163687
+ /* 460 */ 138, 139, 230, 102, 103, 104, 105, 106, 107, 108,
162518163688
/* 470 */ 109, 110, 111, 112, 113, 153, 154, 155, 156, 157,
162519
- /* 480 */ 239, 240, 116, 117, 118, 76, 193, 193, 19, 116,
162520
- /* 490 */ 117, 118, 23, 252, 253, 193, 87, 204, 89, 238,
162521
- /* 500 */ 193, 92, 268, 262, 281, 203, 193, 205, 285, 216,
163689
+ /* 480 */ 239, 240, 116, 117, 118, 76, 193, 23, 19, 25,
163690
+ /* 490 */ 22, 253, 23, 252, 253, 108, 87, 204, 89, 261,
163691
+ /* 500 */ 198, 92, 261, 116, 117, 118, 193, 306, 307, 216,
162522163692
/* 510 */ 217, 150, 43, 44, 45, 46, 47, 48, 49, 50,
162523
- /* 520 */ 51, 52, 53, 54, 55, 56, 57, 193, 193, 216,
162524
- /* 530 */ 217, 19, 239, 240, 59, 23, 106, 107, 108, 109,
162525
- /* 540 */ 110, 111, 112, 113, 231, 252, 253, 193, 308, 309,
162526
- /* 550 */ 193, 145, 59, 313, 145, 43, 44, 45, 46, 47,
163693
+ /* 520 */ 51, 52, 53, 54, 55, 56, 57, 59, 193, 216,
163694
+ /* 530 */ 217, 19, 239, 240, 283, 23, 106, 107, 108, 109,
163695
+ /* 540 */ 110, 111, 112, 113, 73, 252, 253, 142, 308, 309,
163696
+ /* 550 */ 138, 139, 81, 313, 145, 43, 44, 45, 46, 47,
162527163697
/* 560 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
162528
- /* 570 */ 164, 102, 103, 104, 105, 106, 107, 108, 109, 110,
162529
- /* 580 */ 111, 112, 113, 119, 193, 193, 122, 123, 124, 193,
162530
- /* 590 */ 283, 116, 117, 118, 235, 236, 132, 59, 241, 264,
162531
- /* 600 */ 59, 193, 19, 23, 193, 25, 23, 216, 217, 116,
162532
- /* 610 */ 117, 118, 216, 217, 102, 103, 104, 105, 106, 107,
163698
+ /* 570 */ 307, 102, 103, 104, 105, 106, 107, 108, 109, 110,
163699
+ /* 580 */ 111, 112, 113, 281, 116, 117, 118, 285, 23, 193,
163700
+ /* 590 */ 25, 119, 59, 193, 122, 123, 124, 59, 127, 203,
163701
+ /* 600 */ 59, 205, 19, 268, 132, 25, 23, 22, 193, 138,
163702
+ /* 610 */ 139, 249, 204, 251, 102, 103, 104, 105, 106, 107,
162533163703
/* 620 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46,
162534163704
/* 630 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
162535
- /* 640 */ 57, 19, 308, 309, 151, 23, 25, 313, 135, 253,
162536
- /* 650 */ 21, 193, 241, 140, 116, 117, 118, 116, 117, 118,
162537
- /* 660 */ 268, 304, 22, 301, 302, 43, 44, 45, 46, 47,
163705
+ /* 640 */ 57, 19, 22, 23, 59, 23, 25, 239, 240, 116,
163706
+ /* 650 */ 117, 118, 193, 11, 116, 117, 118, 116, 117, 118,
163707
+ /* 660 */ 252, 269, 22, 193, 15, 43, 44, 45, 46, 47,
162538163708
/* 670 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
162539
- /* 680 */ 193, 143, 193, 193, 143, 102, 103, 104, 105, 106,
163709
+ /* 680 */ 273, 143, 193, 118, 143, 102, 103, 104, 105, 106,
162540163710
/* 690 */ 107, 108, 109, 110, 111, 112, 113, 76, 118, 59,
162541
- /* 700 */ 292, 211, 212, 216, 217, 216, 217, 73, 193, 80,
162542
- /* 710 */ 89, 25, 19, 92, 193, 304, 23, 22, 231, 193,
162543
- /* 720 */ 231, 193, 22, 143, 102, 103, 104, 105, 106, 107,
163711
+ /* 700 */ 241, 116, 117, 118, 304, 216, 217, 292, 143, 60,
163712
+ /* 710 */ 89, 241, 19, 92, 193, 193, 23, 22, 311, 312,
163713
+ /* 720 */ 231, 101, 22, 143, 102, 103, 104, 105, 106, 107,
162544163714
/* 730 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46,
162545163715
/* 740 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
162546
- /* 750 */ 57, 19, 123, 193, 59, 23, 116, 117, 118, 59,
162547
- /* 760 */ 193, 127, 128, 129, 306, 307, 210, 211, 212, 193,
162548
- /* 770 */ 22, 111, 112, 113, 284, 43, 44, 45, 46, 47,
163716
+ /* 750 */ 57, 19, 193, 193, 59, 23, 116, 117, 118, 59,
163717
+ /* 760 */ 201, 21, 241, 304, 22, 206, 127, 128, 129, 193,
163718
+ /* 770 */ 128, 129, 235, 236, 304, 43, 44, 45, 46, 47,
162549163719
/* 780 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
162550
- /* 790 */ 161, 193, 216, 217, 268, 102, 103, 104, 105, 106,
162551
- /* 800 */ 107, 108, 109, 110, 111, 112, 113, 59, 193, 193,
162552
- /* 810 */ 193, 116, 117, 118, 216, 217, 116, 117, 118, 304,
162553
- /* 820 */ 239, 240, 19, 263, 138, 139, 23, 211, 212, 231,
162554
- /* 830 */ 263, 216, 217, 252, 102, 103, 104, 105, 106, 107,
163720
+ /* 790 */ 22, 193, 216, 217, 193, 102, 103, 104, 105, 106,
163721
+ /* 800 */ 107, 108, 109, 110, 111, 112, 113, 231, 193, 193,
163722
+ /* 810 */ 193, 116, 117, 118, 216, 217, 116, 117, 118, 226,
163723
+ /* 820 */ 80, 193, 19, 235, 236, 304, 23, 211, 212, 231,
163724
+ /* 830 */ 204, 216, 217, 205, 102, 103, 104, 105, 106, 107,
162555163725
/* 840 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46,
162556163726
/* 850 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
162557
- /* 860 */ 57, 19, 193, 11, 116, 117, 118, 240, 253, 193,
162558
- /* 870 */ 201, 239, 240, 193, 134, 206, 136, 137, 193, 252,
162559
- /* 880 */ 193, 264, 193, 193, 252, 43, 44, 45, 46, 47,
163727
+ /* 860 */ 57, 19, 193, 123, 76, 239, 240, 193, 253, 239,
163728
+ /* 870 */ 240, 239, 240, 193, 106, 107, 193, 89, 252, 193,
163729
+ /* 880 */ 92, 59, 252, 141, 252, 43, 44, 45, 46, 47,
162560163730
/* 890 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
162561
- /* 900 */ 284, 216, 217, 216, 217, 102, 103, 104, 105, 106,
162562
- /* 910 */ 107, 108, 109, 110, 111, 112, 113, 193, 231, 193,
162563
- /* 920 */ 187, 188, 189, 190, 127, 128, 129, 238, 195, 193,
162564
- /* 930 */ 197, 16, 19, 7, 8, 9, 193, 204, 253, 193,
162565
- /* 940 */ 216, 217, 216, 217, 102, 103, 104, 105, 106, 107,
163731
+ /* 900 */ 284, 161, 216, 217, 193, 102, 103, 104, 105, 106,
163732
+ /* 910 */ 107, 108, 109, 110, 111, 112, 113, 231, 193, 16,
163733
+ /* 920 */ 187, 188, 189, 190, 7, 8, 9, 309, 195, 25,
163734
+ /* 930 */ 197, 313, 19, 127, 128, 129, 262, 204, 22, 117,
163735
+ /* 940 */ 24, 216, 217, 263, 102, 103, 104, 105, 106, 107,
162566163736
/* 950 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46,
162567163737
/* 960 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
162568
- /* 970 */ 57, 213, 239, 240, 193, 76, 19, 188, 232, 190,
162569
- /* 980 */ 128, 129, 292, 193, 195, 252, 197, 46, 89, 138,
162570
- /* 990 */ 139, 92, 77, 204, 79, 193, 269, 216, 217, 266,
163738
+ /* 970 */ 57, 193, 239, 240, 193, 59, 19, 188, 253, 190,
163739
+ /* 980 */ 77, 226, 79, 193, 195, 252, 197, 193, 19, 301,
163740
+ /* 990 */ 302, 193, 193, 204, 216, 217, 226, 216, 217, 266,
162571163741
/* 1000 */ 204, 159, 45, 46, 47, 48, 49, 50, 51, 52,
162572163742
/* 1010 */ 53, 54, 55, 56, 57, 102, 103, 104, 105, 106,
162573163743
/* 1020 */ 107, 108, 109, 110, 111, 112, 113, 12, 239, 240,
162574
- /* 1030 */ 193, 298, 22, 23, 253, 239, 240, 127, 128, 129,
162575
- /* 1040 */ 238, 252, 27, 193, 286, 204, 193, 204, 252, 291,
162576
- /* 1050 */ 193, 273, 22, 23, 100, 266, 115, 42, 268, 102,
163744
+ /* 1030 */ 232, 298, 238, 117, 253, 239, 240, 238, 259, 260,
163745
+ /* 1040 */ 193, 252, 27, 31, 193, 193, 142, 204, 252, 193,
163746
+ /* 1050 */ 193, 39, 262, 193, 100, 266, 278, 42, 204, 102,
162577163747
/* 1060 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
162578
- /* 1070 */ 113, 117, 159, 216, 217, 121, 161, 19, 63, 193,
162579
- /* 1080 */ 239, 240, 239, 240, 12, 208, 209, 298, 73, 311,
162580
- /* 1090 */ 312, 238, 19, 252, 25, 252, 22, 24, 24, 27,
162581
- /* 1100 */ 193, 264, 216, 217, 46, 208, 209, 153, 154, 155,
162582
- /* 1110 */ 253, 101, 19, 23, 42, 25, 43, 44, 45, 46,
163748
+ /* 1070 */ 113, 117, 159, 216, 217, 121, 216, 217, 63, 193,
163749
+ /* 1080 */ 193, 193, 239, 240, 115, 116, 193, 298, 73, 238,
163750
+ /* 1090 */ 238, 231, 19, 239, 240, 252, 22, 24, 211, 212,
163751
+ /* 1100 */ 24, 193, 216, 217, 216, 217, 252, 153, 154, 155,
163752
+ /* 1110 */ 253, 16, 19, 144, 213, 268, 43, 44, 45, 46,
162583163753
/* 1120 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
162584
- /* 1130 */ 57, 101, 19, 59, 25, 63, 43, 44, 45, 46,
163754
+ /* 1130 */ 57, 238, 19, 59, 193, 59, 43, 44, 45, 46,
162585163755
/* 1140 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
162586
- /* 1150 */ 57, 22, 23, 115, 25, 24, 43, 44, 45, 46,
163756
+ /* 1150 */ 57, 22, 23, 193, 25, 193, 43, 44, 45, 46,
162587163757
/* 1160 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
162588
- /* 1170 */ 57, 22, 23, 115, 25, 102, 103, 104, 105, 106,
162589
- /* 1180 */ 107, 108, 109, 110, 111, 112, 113, 118, 150, 131,
162590
- /* 1190 */ 59, 117, 22, 273, 193, 102, 103, 104, 105, 106,
162591
- /* 1200 */ 107, 108, 109, 110, 111, 112, 113, 204, 66, 204,
162592
- /* 1210 */ 35, 204, 143, 213, 193, 102, 103, 104, 105, 106,
162593
- /* 1220 */ 107, 108, 109, 110, 111, 112, 113, 85, 193, 59,
162594
- /* 1230 */ 101, 311, 312, 16, 193, 19, 94, 216, 217, 238,
162595
- /* 1240 */ 193, 66, 239, 240, 239, 240, 239, 240, 117, 74,
162596
- /* 1250 */ 101, 216, 217, 193, 193, 252, 193, 252, 149, 252,
163758
+ /* 1170 */ 57, 284, 77, 193, 79, 102, 103, 104, 105, 106,
163759
+ /* 1180 */ 107, 108, 109, 110, 111, 112, 113, 286, 193, 193,
163760
+ /* 1190 */ 193, 117, 291, 117, 232, 102, 103, 104, 105, 106,
163761
+ /* 1200 */ 107, 108, 109, 110, 111, 112, 113, 204, 22, 23,
163762
+ /* 1210 */ 66, 25, 216, 217, 35, 102, 103, 104, 105, 106,
163763
+ /* 1220 */ 107, 108, 109, 110, 111, 112, 113, 193, 268, 85,
163764
+ /* 1230 */ 101, 193, 309, 309, 240, 19, 313, 313, 94, 208,
163765
+ /* 1240 */ 209, 193, 239, 240, 193, 66, 252, 19, 268, 244,
163766
+ /* 1250 */ 216, 217, 193, 74, 213, 252, 161, 19, 263, 254,
162597163767
/* 1260 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
162598
- /* 1270 */ 54, 55, 56, 57, 193, 193, 193, 5, 59, 216,
162599
- /* 1280 */ 217, 25, 10, 11, 12, 13, 14, 117, 146, 17,
162600
- /* 1290 */ 193, 291, 193, 232, 77, 76, 79, 216, 217, 216,
162601
- /* 1300 */ 217, 31, 30, 309, 32, 130, 87, 313, 89, 39,
162602
- /* 1310 */ 193, 92, 40, 216, 217, 216, 217, 108, 102, 103,
163768
+ /* 1270 */ 54, 55, 56, 57, 193, 216, 217, 5, 59, 193,
163769
+ /* 1280 */ 19, 244, 10, 11, 12, 13, 14, 101, 309, 17,
163770
+ /* 1290 */ 146, 254, 313, 193, 193, 76, 115, 216, 217, 309,
163771
+ /* 1300 */ 12, 263, 30, 313, 32, 46, 87, 46, 89, 130,
163772
+ /* 1310 */ 193, 92, 40, 22, 263, 27, 216, 217, 102, 103,
162603163773
/* 1320 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
162604
- /* 1330 */ 299, 300, 193, 216, 217, 116, 117, 118, 19, 20,
162605
- /* 1340 */ 193, 22, 70, 309, 135, 193, 264, 313, 193, 140,
162606
- /* 1350 */ 78, 193, 226, 81, 59, 36, 193, 309, 193, 29,
162607
- /* 1360 */ 193, 313, 193, 33, 145, 193, 59, 48, 216, 217,
162608
- /* 1370 */ 98, 216, 217, 193, 216, 217, 193, 244, 59, 216,
162609
- /* 1380 */ 217, 216, 217, 216, 217, 216, 217, 254, 216, 217,
162610
- /* 1390 */ 71, 193, 244, 193, 193, 65, 216, 217, 193, 216,
162611
- /* 1400 */ 217, 145, 254, 244, 85, 133, 15, 100, 193, 90,
162612
- /* 1410 */ 138, 139, 117, 254, 216, 217, 216, 217, 193, 100,
162613
- /* 1420 */ 193, 216, 217, 116, 117, 106, 107, 19, 121, 193,
162614
- /* 1430 */ 193, 216, 217, 114, 162, 116, 117, 118, 244, 244,
162615
- /* 1440 */ 121, 216, 217, 216, 217, 193, 309, 129, 254, 254,
162616
- /* 1450 */ 313, 60, 216, 217, 19, 256, 257, 193, 120, 121,
162617
- /* 1460 */ 153, 154, 155, 149, 150, 25, 24, 99, 216, 217,
162618
- /* 1470 */ 152, 193, 153, 154, 155, 156, 157, 0, 1, 2,
162619
- /* 1480 */ 216, 217, 5, 22, 158, 24, 160, 10, 11, 12,
162620
- /* 1490 */ 13, 14, 193, 23, 17, 25, 193, 19, 20, 193,
162621
- /* 1500 */ 22, 133, 193, 22, 22, 193, 22, 30, 193, 32,
162622
- /* 1510 */ 19, 20, 129, 22, 36, 216, 217, 40, 193, 216,
162623
- /* 1520 */ 217, 193, 216, 217, 116, 216, 217, 36, 216, 217,
162624
- /* 1530 */ 193, 216, 217, 193, 53, 152, 193, 59, 23, 19,
162625
- /* 1540 */ 25, 216, 217, 61, 216, 217, 23, 70, 25, 71,
162626
- /* 1550 */ 59, 116, 193, 216, 217, 78, 216, 217, 81, 216,
162627
- /* 1560 */ 217, 59, 71, 85, 193, 23, 193, 25, 90, 23,
162628
- /* 1570 */ 23, 25, 25, 7, 8, 98, 85, 193, 100, 193,
162629
- /* 1580 */ 59, 90, 142, 141, 106, 107, 193, 216, 217, 216,
162630
- /* 1590 */ 217, 100, 114, 193, 116, 117, 118, 106, 107, 121,
162631
- /* 1600 */ 216, 217, 216, 217, 193, 114, 193, 116, 117, 118,
162632
- /* 1610 */ 133, 23, 121, 25, 121, 138, 139, 97, 23, 117,
162633
- /* 1620 */ 25, 23, 193, 25, 131, 141, 193, 216, 217, 59,
162634
- /* 1630 */ 193, 153, 154, 155, 156, 157, 226, 193, 117, 162,
162635
- /* 1640 */ 23, 23, 25, 25, 153, 154, 155, 156, 157, 1,
162636
- /* 1650 */ 2, 83, 84, 5, 19, 20, 226, 22, 10, 11,
162637
- /* 1660 */ 12, 13, 14, 258, 153, 17, 155, 153, 23, 155,
162638
- /* 1670 */ 25, 36, 23, 193, 25, 255, 193, 236, 30, 193,
162639
- /* 1680 */ 32, 19, 20, 193, 22, 193, 288, 117, 40, 193,
162640
- /* 1690 */ 318, 193, 193, 193, 59, 242, 193, 193, 36, 193,
162641
- /* 1700 */ 193, 193, 287, 255, 255, 255, 71, 255, 243, 214,
162642
- /* 1710 */ 191, 297, 267, 245, 271, 259, 259, 293, 70, 246,
162643
- /* 1720 */ 246, 59, 267, 229, 245, 271, 78, 293, 259, 81,
162644
- /* 1730 */ 271, 271, 220, 71, 225, 100, 219, 219, 249, 196,
162645
- /* 1740 */ 243, 106, 107, 108, 219, 60, 98, 280, 297, 114,
162646
- /* 1750 */ 249, 116, 117, 118, 141, 245, 121, 200, 200, 297,
162647
- /* 1760 */ 38, 200, 100, 151, 150, 294, 294, 22, 106, 107,
162648
- /* 1770 */ 283, 43, 234, 18, 237, 200, 114, 272, 116, 117,
162649
- /* 1780 */ 118, 133, 237, 121, 18, 237, 138, 139, 153, 154,
162650
- /* 1790 */ 155, 156, 157, 237, 270, 199, 19, 20, 246, 22,
162651
- /* 1800 */ 149, 272, 272, 270, 200, 246, 234, 234, 246, 246,
162652
- /* 1810 */ 162, 158, 290, 36, 199, 153, 154, 155, 156, 157,
162653
- /* 1820 */ 62, 289, 200, 199, 22, 200, 221, 199, 221, 200,
162654
- /* 1830 */ 199, 115, 64, 227, 218, 22, 59, 218, 218, 126,
162655
- /* 1840 */ 165, 24, 113, 312, 218, 224, 305, 224, 71, 282,
162656
- /* 1850 */ 144, 221, 220, 282, 218, 218, 218, 115, 261, 260,
162657
- /* 1860 */ 227, 221, 261, 260, 200, 91, 317, 317, 82, 261,
162658
- /* 1870 */ 260, 148, 261, 22, 265, 145, 200, 100, 158, 277,
162659
- /* 1880 */ 147, 146, 25, 106, 107, 202, 13, 260, 194, 250,
162660
- /* 1890 */ 249, 114, 248, 116, 117, 118, 250, 247, 121, 265,
162661
- /* 1900 */ 246, 194, 6, 192, 192, 207, 192, 207, 213, 213,
162662
- /* 1910 */ 213, 222, 213, 222, 4, 214, 214, 213, 3, 22,
162663
- /* 1920 */ 163, 279, 207, 15, 23, 16, 23, 139, 130, 151,
162664
- /* 1930 */ 153, 154, 155, 156, 157, 142, 25, 24, 20, 144,
162665
- /* 1940 */ 16, 1, 142, 61, 130, 130, 303, 151, 53, 37,
162666
- /* 1950 */ 303, 53, 300, 53, 130, 53, 116, 34, 1, 141,
162667
- /* 1960 */ 5, 22, 115, 25, 161, 75, 41, 68, 141, 115,
162668
- /* 1970 */ 24, 20, 68, 19, 131, 125, 23, 96, 22, 59,
162669
- /* 1980 */ 22, 67, 22, 22, 67, 22, 24, 28, 67, 37,
162670
- /* 1990 */ 23, 149, 22, 25, 23, 23, 23, 23, 22, 141,
162671
- /* 2000 */ 23, 23, 97, 116, 22, 143, 25, 88, 75, 34,
162672
- /* 2010 */ 44, 75, 86, 34, 34, 93, 23, 34, 34, 34,
162673
- /* 2020 */ 22, 24, 34, 22, 25, 25, 23, 23, 23, 23,
162674
- /* 2030 */ 23, 11, 23, 25, 22, 22, 25, 23, 23, 22,
162675
- /* 2040 */ 22, 135, 15, 1, 25, 23, 1, 319, 141, 319,
162676
- /* 2050 */ 319, 319, 319, 319, 319, 319, 319, 141, 319, 319,
162677
- /* 2060 */ 319, 319, 319, 319, 319, 319, 319, 319, 141, 141,
163774
+ /* 1330 */ 42, 150, 291, 216, 217, 116, 117, 118, 19, 20,
163775
+ /* 1340 */ 193, 22, 70, 260, 116, 193, 24, 264, 193, 263,
163776
+ /* 1350 */ 78, 63, 61, 81, 116, 36, 193, 260, 193, 29,
163777
+ /* 1360 */ 193, 264, 193, 33, 145, 193, 59, 48, 216, 217,
163778
+ /* 1370 */ 98, 216, 217, 193, 115, 193, 115, 193, 59, 216,
163779
+ /* 1380 */ 217, 216, 217, 216, 217, 216, 217, 255, 216, 217,
163780
+ /* 1390 */ 71, 193, 131, 193, 25, 65, 216, 217, 216, 217,
163781
+ /* 1400 */ 216, 217, 208, 209, 85, 133, 193, 100, 193, 90,
163782
+ /* 1410 */ 138, 139, 138, 139, 216, 217, 216, 217, 193, 100,
163783
+ /* 1420 */ 193, 108, 135, 116, 117, 106, 107, 140, 121, 216,
163784
+ /* 1430 */ 217, 216, 217, 114, 162, 116, 117, 118, 299, 300,
163785
+ /* 1440 */ 121, 216, 217, 216, 217, 193, 244, 193, 135, 244,
163786
+ /* 1450 */ 193, 256, 257, 140, 244, 193, 254, 193, 193, 254,
163787
+ /* 1460 */ 153, 154, 155, 141, 254, 149, 150, 258, 216, 217,
163788
+ /* 1470 */ 216, 217, 153, 154, 155, 156, 157, 0, 1, 2,
163789
+ /* 1480 */ 216, 217, 5, 115, 158, 193, 160, 10, 11, 12,
163790
+ /* 1490 */ 13, 14, 193, 59, 17, 126, 193, 19, 20, 129,
163791
+ /* 1500 */ 22, 193, 22, 22, 24, 193, 23, 30, 25, 32,
163792
+ /* 1510 */ 19, 20, 144, 22, 36, 216, 217, 40, 193, 216,
163793
+ /* 1520 */ 217, 193, 152, 129, 216, 217, 193, 36, 216, 217,
163794
+ /* 1530 */ 193, 99, 193, 193, 53, 193, 193, 59, 23, 193,
163795
+ /* 1540 */ 25, 216, 217, 193, 216, 217, 152, 70, 59, 71,
163796
+ /* 1550 */ 59, 117, 193, 216, 217, 78, 216, 217, 81, 216,
163797
+ /* 1560 */ 217, 318, 71, 85, 193, 133, 193, 193, 90, 23,
163798
+ /* 1570 */ 23, 25, 25, 120, 121, 98, 85, 193, 100, 193,
163799
+ /* 1580 */ 23, 90, 25, 121, 106, 107, 19, 216, 217, 216,
163800
+ /* 1590 */ 217, 100, 114, 131, 116, 117, 118, 106, 107, 121,
163801
+ /* 1600 */ 216, 217, 216, 217, 193, 114, 117, 116, 117, 118,
163802
+ /* 1610 */ 133, 193, 121, 193, 193, 138, 139, 193, 23, 193,
163803
+ /* 1620 */ 25, 23, 23, 25, 25, 7, 8, 216, 217, 193,
163804
+ /* 1630 */ 193, 153, 154, 155, 156, 157, 216, 217, 59, 162,
163805
+ /* 1640 */ 216, 217, 216, 217, 153, 154, 155, 156, 157, 1,
163806
+ /* 1650 */ 2, 193, 193, 5, 19, 20, 193, 22, 10, 11,
163807
+ /* 1660 */ 12, 13, 14, 193, 97, 17, 193, 23, 23, 25,
163808
+ /* 1670 */ 25, 36, 83, 84, 216, 217, 236, 23, 30, 25,
163809
+ /* 1680 */ 32, 19, 20, 153, 22, 155, 216, 217, 40, 216,
163810
+ /* 1690 */ 217, 153, 193, 155, 59, 23, 117, 25, 36, 23,
163811
+ /* 1700 */ 193, 25, 193, 193, 193, 193, 71, 193, 242, 193,
163812
+ /* 1710 */ 193, 193, 193, 193, 243, 288, 287, 214, 70, 255,
163813
+ /* 1720 */ 255, 59, 255, 255, 191, 297, 78, 271, 267, 81,
163814
+ /* 1730 */ 245, 293, 246, 71, 246, 100, 267, 245, 293, 249,
163815
+ /* 1740 */ 219, 106, 107, 108, 220, 271, 98, 271, 225, 114,
163816
+ /* 1750 */ 271, 116, 117, 118, 229, 219, 121, 259, 219, 259,
163817
+ /* 1760 */ 259, 259, 100, 60, 280, 196, 141, 38, 106, 107,
163818
+ /* 1770 */ 200, 249, 245, 200, 243, 200, 114, 151, 116, 117,
163819
+ /* 1780 */ 118, 133, 150, 121, 297, 272, 138, 139, 153, 154,
163820
+ /* 1790 */ 155, 156, 157, 297, 22, 43, 19, 20, 294, 22,
163821
+ /* 1800 */ 294, 18, 270, 237, 200, 234, 18, 199, 149, 283,
163822
+ /* 1810 */ 162, 237, 272, 36, 237, 153, 154, 155, 156, 157,
163823
+ /* 1820 */ 237, 272, 246, 270, 246, 234, 246, 234, 246, 200,
163824
+ /* 1830 */ 199, 158, 290, 62, 289, 199, 59, 200, 22, 200,
163825
+ /* 1840 */ 221, 199, 221, 200, 64, 199, 115, 227, 71, 22,
163826
+ /* 1850 */ 126, 218, 218, 165, 224, 227, 218, 24, 113, 305,
163827
+ /* 1860 */ 312, 200, 221, 282, 224, 218, 282, 91, 218, 220,
163828
+ /* 1870 */ 218, 218, 221, 317, 82, 317, 265, 100, 265, 145,
163829
+ /* 1880 */ 148, 22, 277, 106, 107, 200, 158, 147, 279, 146,
163830
+ /* 1890 */ 25, 114, 202, 116, 117, 118, 13, 6, 121, 194,
163831
+ /* 1900 */ 194, 192, 192, 192, 248, 250, 249, 247, 250, 246,
163832
+ /* 1910 */ 303, 207, 300, 303, 213, 213, 222, 222, 4, 207,
163833
+ /* 1920 */ 213, 213, 207, 3, 22, 163, 15, 214, 214, 213,
163834
+ /* 1930 */ 153, 154, 155, 156, 157, 16, 23, 139, 23, 130,
163835
+ /* 1940 */ 151, 25, 24, 142, 20, 16, 144, 1, 142, 130,
163836
+ /* 1950 */ 130, 61, 53, 53, 37, 151, 53, 53, 130, 116,
163837
+ /* 1960 */ 34, 1, 141, 5, 22, 115, 161, 75, 25, 68,
163838
+ /* 1970 */ 141, 41, 115, 68, 24, 20, 19, 131, 125, 67,
163839
+ /* 1980 */ 24, 22, 59, 22, 22, 96, 23, 22, 67, 22,
163840
+ /* 1990 */ 37, 23, 28, 149, 67, 22, 25, 23, 23, 23,
163841
+ /* 2000 */ 23, 22, 141, 97, 23, 23, 34, 22, 25, 116,
163842
+ /* 2010 */ 143, 75, 34, 88, 34, 75, 23, 86, 34, 22,
163843
+ /* 2020 */ 34, 93, 34, 24, 34, 25, 25, 23, 23, 23,
163844
+ /* 2030 */ 23, 44, 23, 25, 23, 22, 11, 22, 22, 25,
163845
+ /* 2040 */ 23, 23, 22, 22, 135, 15, 23, 25, 141, 141,
163846
+ /* 2050 */ 1, 141, 1, 319, 319, 319, 319, 319, 319, 319,
163847
+ /* 2060 */ 319, 319, 319, 141, 319, 319, 319, 319, 319, 319,
162678163848
/* 2070 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
162679163849
/* 2080 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
162680163850
/* 2090 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
162681163851
/* 2100 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
162682163852
/* 2110 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
@@ -162690,181 +163860,178 @@
162690163860
/* 2190 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
162691163861
/* 2200 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
162692163862
/* 2210 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
162693163863
/* 2220 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
162694163864
/* 2230 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
162695
- /* 2240 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
162696
- /* 2250 */ 319, 319, 319, 319, 319,
163865
+ /* 2240 */ 319, 319, 319, 319, 319, 319, 319, 319, 319,
162697163866
};
162698
-#define YY_SHIFT_COUNT (573)
163867
+#define YY_SHIFT_COUNT (569)
162699163868
#define YY_SHIFT_MIN (0)
162700
-#define YY_SHIFT_MAX (2045)
163869
+#define YY_SHIFT_MAX (2051)
162701163870
static const unsigned short int yy_shift_ofst[] = {
162702
- /* 0 */ 1648, 1477, 1272, 322, 322, 262, 1319, 1478, 1491, 1662,
162703
- /* 10 */ 1662, 1662, 317, 0, 0, 214, 1093, 1662, 1662, 1662,
163871
+ /* 0 */ 1648, 1477, 1272, 322, 322, 1, 1319, 1478, 1491, 1662,
163872
+ /* 10 */ 1662, 1662, 471, 0, 0, 214, 1093, 1662, 1662, 1662,
162704163873
/* 20 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
162705
- /* 30 */ 271, 271, 1219, 1219, 216, 88, 262, 262, 262, 262,
162706
- /* 40 */ 262, 40, 111, 258, 361, 469, 512, 583, 622, 693,
163874
+ /* 30 */ 271, 271, 1219, 1219, 216, 88, 1, 1, 1, 1,
163875
+ /* 40 */ 1, 40, 111, 258, 361, 469, 512, 583, 622, 693,
162707163876
/* 50 */ 732, 803, 842, 913, 1073, 1093, 1093, 1093, 1093, 1093,
162708163877
/* 60 */ 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093,
162709163878
/* 70 */ 1093, 1093, 1093, 1113, 1093, 1216, 957, 957, 1635, 1662,
162710163879
/* 80 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
162711163880
/* 90 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
162712163881
/* 100 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
162713163882
/* 110 */ 1662, 1662, 1662, 1662, 1777, 1662, 1662, 1662, 1662, 1662,
162714163883
/* 120 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 137, 181,
162715163884
/* 130 */ 181, 181, 181, 181, 94, 430, 66, 65, 112, 366,
162716
- /* 140 */ 475, 475, 629, 1058, 475, 475, 125, 125, 475, 686,
162717
- /* 150 */ 686, 686, 660, 686, 57, 184, 184, 77, 77, 2070,
162718
- /* 160 */ 2070, 328, 328, 328, 493, 373, 373, 373, 373, 1015,
162719
- /* 170 */ 1015, 409, 366, 1129, 1149, 475, 475, 475, 475, 475,
162720
- /* 180 */ 475, 475, 475, 475, 475, 475, 475, 475, 475, 475,
162721
- /* 190 */ 475, 475, 475, 475, 475, 621, 621, 475, 852, 899,
162722
- /* 200 */ 899, 1295, 1295, 406, 851, 2070, 2070, 2070, 2070, 2070,
162723
- /* 210 */ 2070, 2070, 1307, 954, 954, 640, 464, 695, 238, 700,
162724
- /* 220 */ 538, 541, 748, 475, 475, 475, 475, 475, 475, 475,
162725
- /* 230 */ 475, 475, 475, 634, 475, 475, 475, 475, 475, 475,
162726
- /* 240 */ 475, 475, 475, 475, 475, 475, 1175, 1175, 1175, 475,
162727
- /* 250 */ 475, 475, 580, 475, 475, 475, 1074, 1142, 475, 475,
162728
- /* 260 */ 1072, 475, 475, 475, 475, 475, 475, 475, 475, 797,
162729
- /* 270 */ 1330, 740, 1131, 1131, 1131, 1131, 1069, 740, 740, 1209,
162730
- /* 280 */ 167, 926, 1391, 1038, 1314, 187, 1408, 1314, 1408, 1435,
162731
- /* 290 */ 1109, 1038, 1038, 1109, 1038, 187, 1435, 227, 1090, 941,
162732
- /* 300 */ 1270, 1270, 1270, 1408, 1256, 1256, 1326, 1440, 513, 1461,
162733
- /* 310 */ 1685, 1685, 1613, 1613, 1722, 1722, 1613, 1612, 1614, 1745,
162734
- /* 320 */ 1728, 1755, 1755, 1755, 1755, 1613, 1766, 1651, 1614, 1614,
162735
- /* 330 */ 1651, 1745, 1728, 1651, 1728, 1651, 1613, 1766, 1653, 1758,
162736
- /* 340 */ 1613, 1766, 1802, 1613, 1766, 1613, 1766, 1802, 1716, 1716,
162737
- /* 350 */ 1716, 1768, 1813, 1813, 1802, 1716, 1713, 1716, 1768, 1716,
162738
- /* 360 */ 1716, 1675, 1817, 1729, 1729, 1802, 1706, 1742, 1706, 1742,
162739
- /* 370 */ 1706, 1742, 1706, 1742, 1613, 1774, 1774, 1786, 1786, 1723,
162740
- /* 380 */ 1730, 1851, 1613, 1720, 1723, 1733, 1735, 1651, 1857, 1873,
162741
- /* 390 */ 1873, 1896, 1896, 1896, 2070, 2070, 2070, 2070, 2070, 2070,
162742
- /* 400 */ 2070, 2070, 2070, 2070, 2070, 2070, 2070, 2070, 2070, 207,
162743
- /* 410 */ 915, 1010, 1030, 1217, 910, 1170, 1470, 1368, 1481, 1442,
162744
- /* 420 */ 1318, 1383, 1515, 1482, 1523, 1542, 1546, 1547, 1588, 1595,
162745
- /* 430 */ 1502, 1338, 1566, 1493, 1520, 1521, 1598, 1617, 1568, 1618,
162746
- /* 440 */ 1511, 1514, 1645, 1649, 1570, 1484, 1910, 1915, 1897, 1757,
162747
- /* 450 */ 1908, 1909, 1901, 1903, 1788, 1778, 1798, 1911, 1911, 1913,
162748
- /* 460 */ 1793, 1918, 1795, 1924, 1940, 1800, 1814, 1911, 1815, 1882,
162749
- /* 470 */ 1912, 1911, 1796, 1895, 1898, 1900, 1902, 1824, 1840, 1923,
162750
- /* 480 */ 1818, 1957, 1955, 1939, 1847, 1803, 1899, 1938, 1904, 1890,
162751
- /* 490 */ 1925, 1827, 1854, 1946, 1951, 1954, 1843, 1850, 1956, 1914,
162752
- /* 500 */ 1958, 1960, 1953, 1961, 1917, 1920, 1962, 1881, 1959, 1963,
162753
- /* 510 */ 1921, 1952, 1967, 1842, 1970, 1971, 1972, 1973, 1968, 1974,
162754
- /* 520 */ 1976, 1905, 1858, 1977, 1978, 1887, 1975, 1982, 1862, 1981,
162755
- /* 530 */ 1979, 1980, 1983, 1984, 1919, 1933, 1926, 1966, 1936, 1922,
162756
- /* 540 */ 1985, 1993, 1998, 1997, 1999, 2000, 1988, 2003, 1981, 2004,
162757
- /* 550 */ 2005, 2006, 2007, 2008, 2009, 2001, 2020, 2012, 2013, 2014,
162758
- /* 560 */ 2015, 2017, 2018, 2011, 1906, 1907, 1916, 1927, 1928, 2019,
162759
- /* 570 */ 2022, 2027, 2042, 2045,
163885
+ /* 140 */ 533, 533, 740, 1261, 533, 533, 79, 79, 533, 412,
163886
+ /* 150 */ 412, 412, 77, 412, 123, 113, 113, 22, 22, 2064,
163887
+ /* 160 */ 2064, 328, 328, 328, 239, 468, 468, 468, 468, 1015,
163888
+ /* 170 */ 1015, 409, 366, 1129, 1186, 533, 533, 533, 533, 533,
163889
+ /* 180 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 533,
163890
+ /* 190 */ 533, 533, 533, 533, 533, 969, 621, 621, 533, 642,
163891
+ /* 200 */ 788, 788, 1228, 1228, 822, 822, 67, 1274, 2064, 2064,
163892
+ /* 210 */ 2064, 2064, 2064, 2064, 2064, 1307, 954, 954, 585, 472,
163893
+ /* 220 */ 640, 387, 695, 538, 541, 700, 533, 533, 533, 533,
163894
+ /* 230 */ 533, 533, 533, 533, 533, 533, 222, 533, 533, 533,
163895
+ /* 240 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 1179,
163896
+ /* 250 */ 1179, 1179, 533, 533, 533, 565, 533, 533, 533, 916,
163897
+ /* 260 */ 1144, 533, 533, 1288, 533, 533, 533, 533, 533, 533,
163898
+ /* 270 */ 533, 533, 639, 1330, 209, 1076, 1076, 1076, 1076, 580,
163899
+ /* 280 */ 209, 209, 1313, 768, 917, 649, 1181, 1316, 405, 1316,
163900
+ /* 290 */ 1238, 249, 1181, 1181, 249, 1181, 405, 1238, 1369, 464,
163901
+ /* 300 */ 1259, 1012, 1012, 1012, 1368, 1368, 1368, 1368, 184, 184,
163902
+ /* 310 */ 1326, 904, 1287, 1480, 1703, 1703, 1625, 1625, 1729, 1729,
163903
+ /* 320 */ 1625, 1626, 1632, 1772, 1752, 1783, 1783, 1783, 1783, 1625,
163904
+ /* 330 */ 1788, 1659, 1632, 1632, 1659, 1772, 1752, 1659, 1752, 1659,
163905
+ /* 340 */ 1625, 1788, 1673, 1771, 1625, 1788, 1816, 1625, 1788, 1625,
163906
+ /* 350 */ 1788, 1816, 1731, 1731, 1731, 1780, 1827, 1827, 1816, 1731,
163907
+ /* 360 */ 1724, 1731, 1780, 1731, 1731, 1688, 1833, 1745, 1745, 1816,
163908
+ /* 370 */ 1625, 1776, 1776, 1792, 1792, 1732, 1734, 1859, 1625, 1728,
163909
+ /* 380 */ 1732, 1740, 1743, 1659, 1865, 1883, 1883, 1891, 1891, 1891,
163910
+ /* 390 */ 2064, 2064, 2064, 2064, 2064, 2064, 2064, 2064, 2064, 2064,
163911
+ /* 400 */ 2064, 2064, 2064, 2064, 2064, 207, 1095, 331, 620, 903,
163912
+ /* 410 */ 806, 1074, 1483, 1432, 1481, 1322, 1370, 1394, 1515, 1291,
163913
+ /* 420 */ 1546, 1547, 1557, 1595, 1598, 1599, 1434, 1453, 1618, 1462,
163914
+ /* 430 */ 1567, 1489, 1644, 1645, 1589, 1654, 1530, 1538, 1672, 1676,
163915
+ /* 440 */ 1579, 742, 1914, 1920, 1902, 1762, 1911, 1919, 1913, 1915,
163916
+ /* 450 */ 1798, 1789, 1809, 1916, 1916, 1918, 1801, 1924, 1802, 1929,
163917
+ /* 460 */ 1946, 1806, 1819, 1916, 1820, 1890, 1917, 1916, 1804, 1899,
163918
+ /* 470 */ 1900, 1903, 1904, 1828, 1843, 1926, 1821, 1960, 1958, 1942,
163919
+ /* 480 */ 1850, 1805, 1901, 1943, 1905, 1892, 1930, 1829, 1857, 1950,
163920
+ /* 490 */ 1955, 1957, 1846, 1853, 1959, 1912, 1961, 1962, 1963, 1965,
163921
+ /* 500 */ 1921, 1923, 1956, 1889, 1964, 1967, 1927, 1953, 1968, 1844,
163922
+ /* 510 */ 1973, 1974, 1975, 1976, 1971, 1977, 1979, 1906, 1861, 1981,
163923
+ /* 520 */ 1982, 1893, 1972, 1985, 1867, 1983, 1978, 1980, 1984, 1986,
163924
+ /* 530 */ 1925, 1936, 1931, 1987, 1940, 1928, 1988, 1993, 1997, 1999,
163925
+ /* 540 */ 2000, 2001, 1990, 2004, 1983, 2005, 2006, 2007, 2009, 2008,
163926
+ /* 550 */ 2011, 2013, 2025, 2015, 2016, 2017, 2018, 2020, 2021, 2014,
163927
+ /* 560 */ 1909, 1907, 1908, 1910, 1922, 2022, 2023, 2030, 2049, 2051,
162760163928
};
162761
-#define YY_REDUCE_COUNT (408)
162762
-#define YY_REDUCE_MIN (-267)
162763
-#define YY_REDUCE_MAX (1715)
163929
+#define YY_REDUCE_COUNT (404)
163930
+#define YY_REDUCE_MIN (-271)
163931
+#define YY_REDUCE_MAX (1716)
162764163932
static const short yy_reduce_ofst[] = {
162765163933
/* 0 */ -125, 733, 789, 241, 293, -123, -193, -191, -183, -187,
162766
- /* 10 */ -180, 83, 133, -207, -198, -267, -175, -6, 166, 313,
162767
- /* 20 */ 487, 396, 489, 598, 615, 685, 687, 79, 781, 857,
162768
- /* 30 */ 490, 616, 240, 334, -188, 796, 841, 843, 1003, 1005,
162769
- /* 40 */ 1007, -260, -260, -260, -260, -260, -260, -260, -260, -260,
162770
- /* 50 */ -260, -260, -260, -260, -260, -260, -260, -260, -260, -260,
162771
- /* 60 */ -260, -260, -260, -260, -260, -260, -260, -260, -260, -260,
162772
- /* 70 */ -260, -260, -260, -260, -260, -260, -260, -260, 158, 203,
162773
- /* 80 */ 391, 576, 724, 726, 886, 1021, 1035, 1063, 1081, 1083,
162774
- /* 90 */ 1097, 1099, 1117, 1152, 1155, 1158, 1163, 1165, 1167, 1169,
162775
- /* 100 */ 1172, 1180, 1183, 1198, 1200, 1205, 1215, 1225, 1227, 1236,
162776
- /* 110 */ 1252, 1264, 1299, 1303, 1306, 1309, 1312, 1315, 1325, 1328,
162777
- /* 120 */ 1337, 1340, 1343, 1371, 1373, 1384, 1386, 1411, -260, -260,
162778
- /* 130 */ -260, -260, -260, -260, -260, -260, -260, -53, 138, 302,
162779
- /* 140 */ -158, 357, 223, -222, 411, 458, -92, 556, 669, 581,
162780
- /* 150 */ 632, 581, -260, 632, 758, 778, 920, -260, -260, -260,
162781
- /* 160 */ -260, 161, 161, 161, 307, 234, 392, 526, 790, 195,
162782
- /* 170 */ 359, -174, -173, 362, 362, -189, 16, 560, 567, 261,
162783
- /* 180 */ 689, 802, 853, -122, -166, 408, 335, 617, 690, 837,
162784
- /* 190 */ 1001, 746, 1061, 515, 1082, 994, 1034, -135, 1000, 1048,
162785
- /* 200 */ 1137, 877, 897, 186, 627, 1031, 1133, 1148, 1159, 1194,
162786
- /* 210 */ 1199, 1195, -194, -142, 18, -152, 68, 201, 253, 269,
162787
- /* 220 */ 294, 354, 521, 528, 676, 680, 736, 743, 850, 907,
162788
- /* 230 */ 1041, 1047, 1060, 727, 1139, 1147, 1201, 1237, 1278, 1359,
162789
- /* 240 */ 1393, 1400, 1413, 1429, 1433, 1437, 1126, 1410, 1430, 1444,
162790
- /* 250 */ 1480, 1483, 1405, 1486, 1490, 1492, 1420, 1372, 1496, 1498,
162791
- /* 260 */ 1441, 1499, 253, 1500, 1503, 1504, 1506, 1507, 1508, 1398,
162792
- /* 270 */ 1415, 1453, 1448, 1449, 1450, 1452, 1405, 1453, 1453, 1465,
162793
- /* 280 */ 1495, 1519, 1414, 1443, 1445, 1468, 1456, 1455, 1457, 1424,
162794
- /* 290 */ 1473, 1454, 1459, 1474, 1460, 1479, 1434, 1512, 1494, 1509,
162795
- /* 300 */ 1517, 1518, 1525, 1469, 1489, 1501, 1467, 1510, 1497, 1543,
162796
- /* 310 */ 1451, 1462, 1557, 1558, 1471, 1472, 1561, 1487, 1505, 1524,
162797
- /* 320 */ 1538, 1537, 1545, 1548, 1556, 1575, 1596, 1552, 1529, 1530,
162798
- /* 330 */ 1559, 1533, 1572, 1562, 1573, 1563, 1604, 1615, 1522, 1532,
162799
- /* 340 */ 1622, 1624, 1605, 1625, 1628, 1629, 1631, 1607, 1616, 1619,
162800
- /* 350 */ 1620, 1606, 1621, 1623, 1630, 1626, 1632, 1636, 1633, 1637,
162801
- /* 360 */ 1638, 1531, 1541, 1567, 1571, 1640, 1597, 1599, 1601, 1603,
162802
- /* 370 */ 1608, 1610, 1611, 1627, 1664, 1549, 1550, 1609, 1634, 1639,
162803
- /* 380 */ 1641, 1602, 1676, 1642, 1646, 1644, 1650, 1654, 1683, 1694,
162804
- /* 390 */ 1707, 1711, 1712, 1714, 1643, 1647, 1652, 1698, 1695, 1696,
162805
- /* 400 */ 1697, 1699, 1700, 1689, 1691, 1701, 1702, 1704, 1715,
163934
+ /* 10 */ 166, 238, 133, -207, -199, -267, -176, -6, 204, 489,
163935
+ /* 20 */ 576, -175, 598, 686, 615, 725, 860, 778, 781, 857,
163936
+ /* 30 */ 616, 887, 87, 240, -192, 408, 626, 796, 843, 854,
163937
+ /* 40 */ 1003, -271, -271, -271, -271, -271, -271, -271, -271, -271,
163938
+ /* 50 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, -271,
163939
+ /* 60 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, -271,
163940
+ /* 70 */ -271, -271, -271, -271, -271, -271, -271, -271, 80, 83,
163941
+ /* 80 */ 313, 886, 888, 996, 1034, 1059, 1081, 1100, 1117, 1152,
163942
+ /* 90 */ 1155, 1163, 1165, 1167, 1169, 1172, 1180, 1182, 1184, 1198,
163943
+ /* 100 */ 1200, 1213, 1215, 1225, 1227, 1252, 1254, 1264, 1299, 1303,
163944
+ /* 110 */ 1308, 1312, 1325, 1328, 1337, 1340, 1343, 1371, 1373, 1384,
163945
+ /* 120 */ 1386, 1411, 1420, 1424, 1426, 1458, 1470, 1473, -271, -271,
163946
+ /* 130 */ -271, -271, -271, -271, -271, -271, -271, 138, 459, 396,
163947
+ /* 140 */ -158, 470, 302, -212, 521, 201, -195, -92, 559, 630,
163948
+ /* 150 */ 632, 630, -271, 632, 901, 63, 407, -271, -271, -271,
163949
+ /* 160 */ -271, 161, 161, 161, 251, 335, 847, 960, 980, 537,
163950
+ /* 170 */ 588, 618, 628, 688, 688, -166, -161, 674, 790, 794,
163951
+ /* 180 */ 799, 851, 852, -122, 680, -120, 995, 1038, 415, 1051,
163952
+ /* 190 */ 893, 798, 962, 400, 1086, 779, 923, 924, 263, 1041,
163953
+ /* 200 */ 979, 990, 1083, 1097, 1031, 1194, 362, 994, 1139, 1005,
163954
+ /* 210 */ 1037, 1202, 1205, 1195, 1210, -194, 56, 185, -135, 232,
163955
+ /* 220 */ 522, 560, 601, 617, 669, 683, 711, 856, 908, 941,
163956
+ /* 230 */ 1048, 1101, 1147, 1257, 1262, 1265, 392, 1292, 1333, 1339,
163957
+ /* 240 */ 1342, 1346, 1350, 1359, 1374, 1418, 1421, 1436, 1437, 593,
163958
+ /* 250 */ 755, 770, 997, 1459, 1463, 1209, 1499, 1507, 1509, 1132,
163959
+ /* 260 */ 1243, 1510, 1511, 1440, 1512, 560, 1514, 1516, 1517, 1518,
163960
+ /* 270 */ 1519, 1520, 1427, 1429, 1466, 1464, 1465, 1467, 1468, 1209,
163961
+ /* 280 */ 1466, 1466, 1471, 1503, 1533, 1428, 1456, 1461, 1485, 1469,
163962
+ /* 290 */ 1438, 1486, 1474, 1476, 1488, 1479, 1492, 1445, 1524, 1525,
163963
+ /* 300 */ 1523, 1521, 1536, 1539, 1498, 1500, 1501, 1502, 1490, 1522,
163964
+ /* 310 */ 1484, 1527, 1531, 1569, 1487, 1496, 1570, 1573, 1504, 1506,
163965
+ /* 320 */ 1575, 1526, 1513, 1532, 1571, 1566, 1574, 1577, 1583, 1604,
163966
+ /* 330 */ 1608, 1576, 1540, 1549, 1578, 1553, 1591, 1580, 1593, 1582,
163967
+ /* 340 */ 1629, 1631, 1542, 1545, 1637, 1636, 1619, 1639, 1642, 1643,
163968
+ /* 350 */ 1646, 1621, 1633, 1634, 1638, 1620, 1630, 1640, 1641, 1647,
163969
+ /* 360 */ 1649, 1650, 1628, 1652, 1653, 1548, 1554, 1581, 1584, 1651,
163970
+ /* 370 */ 1661, 1556, 1558, 1611, 1613, 1655, 1657, 1605, 1685, 1609,
163971
+ /* 380 */ 1658, 1656, 1660, 1663, 1690, 1705, 1706, 1709, 1710, 1711,
163972
+ /* 390 */ 1607, 1610, 1612, 1704, 1701, 1702, 1707, 1708, 1712, 1694,
163973
+ /* 400 */ 1695, 1713, 1714, 1716, 1715,
162806163974
};
162807163975
static const YYACTIONTYPE yy_default[] = {
162808
- /* 0 */ 1637, 1637, 1637, 1466, 1233, 1344, 1233, 1233, 1233, 1466,
162809
- /* 10 */ 1466, 1466, 1233, 1374, 1374, 1519, 1266, 1233, 1233, 1233,
162810
- /* 20 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1465, 1233, 1233,
162811
- /* 30 */ 1233, 1233, 1554, 1554, 1233, 1233, 1233, 1233, 1233, 1233,
162812
- /* 40 */ 1233, 1233, 1383, 1233, 1390, 1233, 1233, 1233, 1233, 1233,
162813
- /* 50 */ 1467, 1468, 1233, 1233, 1233, 1518, 1520, 1483, 1397, 1396,
162814
- /* 60 */ 1395, 1394, 1501, 1361, 1388, 1381, 1385, 1461, 1462, 1460,
162815
- /* 70 */ 1464, 1468, 1467, 1233, 1384, 1431, 1445, 1430, 1233, 1233,
162816
- /* 80 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162817
- /* 90 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162818
- /* 100 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162819
- /* 110 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162820
- /* 120 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1439, 1444,
162821
- /* 130 */ 1451, 1443, 1440, 1433, 1432, 1434, 1435, 1233, 1233, 1257,
162822
- /* 140 */ 1233, 1233, 1254, 1308, 1233, 1233, 1233, 1233, 1233, 1538,
162823
- /* 150 */ 1537, 1233, 1436, 1233, 1266, 1425, 1424, 1448, 1437, 1447,
162824
- /* 160 */ 1446, 1526, 1590, 1589, 1484, 1233, 1233, 1233, 1233, 1233,
162825
- /* 170 */ 1233, 1554, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162826
- /* 180 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162827
- /* 190 */ 1233, 1233, 1233, 1233, 1233, 1554, 1554, 1233, 1266, 1554,
162828
- /* 200 */ 1554, 1262, 1262, 1368, 1233, 1533, 1335, 1335, 1335, 1335,
162829
- /* 210 */ 1344, 1335, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162830
- /* 220 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1523, 1521, 1233,
162831
- /* 230 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162832
- /* 240 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162833
- /* 250 */ 1233, 1233, 1233, 1233, 1233, 1233, 1340, 1233, 1233, 1233,
162834
- /* 260 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1583, 1233,
162835
- /* 270 */ 1496, 1322, 1340, 1340, 1340, 1340, 1342, 1323, 1321, 1334,
162836
- /* 280 */ 1267, 1240, 1629, 1400, 1389, 1341, 1363, 1389, 1363, 1626,
162837
- /* 290 */ 1387, 1400, 1400, 1387, 1400, 1341, 1626, 1283, 1606, 1278,
162838
- /* 300 */ 1374, 1374, 1374, 1363, 1368, 1368, 1463, 1341, 1334, 1233,
162839
- /* 310 */ 1629, 1629, 1349, 1349, 1628, 1628, 1349, 1484, 1613, 1409,
162840
- /* 320 */ 1311, 1317, 1317, 1317, 1317, 1349, 1251, 1387, 1613, 1613,
162841
- /* 330 */ 1387, 1409, 1311, 1387, 1311, 1387, 1349, 1251, 1500, 1623,
162842
- /* 340 */ 1349, 1251, 1474, 1349, 1251, 1349, 1251, 1474, 1309, 1309,
162843
- /* 350 */ 1309, 1298, 1233, 1233, 1474, 1309, 1283, 1309, 1298, 1309,
162844
- /* 360 */ 1309, 1572, 1233, 1478, 1478, 1474, 1367, 1362, 1367, 1362,
162845
- /* 370 */ 1367, 1362, 1367, 1362, 1349, 1564, 1564, 1377, 1377, 1382,
162846
- /* 380 */ 1368, 1469, 1349, 1233, 1382, 1380, 1378, 1387, 1301, 1586,
162847
- /* 390 */ 1586, 1582, 1582, 1582, 1634, 1634, 1533, 1599, 1266, 1266,
162848
- /* 400 */ 1266, 1266, 1599, 1285, 1285, 1267, 1267, 1266, 1599, 1233,
162849
- /* 410 */ 1233, 1233, 1233, 1233, 1233, 1594, 1233, 1528, 1485, 1353,
162850
- /* 420 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162851
- /* 430 */ 1233, 1233, 1233, 1233, 1539, 1233, 1233, 1233, 1233, 1233,
162852
- /* 440 */ 1233, 1233, 1233, 1233, 1233, 1414, 1233, 1236, 1530, 1233,
162853
- /* 450 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1391, 1392, 1354,
162854
- /* 460 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1406, 1233, 1233,
162855
- /* 470 */ 1233, 1401, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162856
- /* 480 */ 1625, 1233, 1233, 1233, 1233, 1233, 1233, 1499, 1498, 1233,
162857
- /* 490 */ 1233, 1351, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162858
- /* 500 */ 1233, 1233, 1233, 1233, 1233, 1281, 1233, 1233, 1233, 1233,
162859
- /* 510 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162860
- /* 520 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1379,
162861
- /* 530 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162862
- /* 540 */ 1233, 1233, 1233, 1233, 1569, 1369, 1233, 1233, 1616, 1233,
162863
- /* 550 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162864
- /* 560 */ 1233, 1233, 1233, 1610, 1325, 1416, 1233, 1415, 1419, 1255,
162865
- /* 570 */ 1233, 1245, 1233, 1233,
163976
+ /* 0 */ 1637, 1637, 1637, 1465, 1232, 1343, 1232, 1232, 1232, 1465,
163977
+ /* 10 */ 1465, 1465, 1232, 1373, 1373, 1518, 1265, 1232, 1232, 1232,
163978
+ /* 20 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1464, 1232, 1232,
163979
+ /* 30 */ 1232, 1232, 1553, 1553, 1232, 1232, 1232, 1232, 1232, 1232,
163980
+ /* 40 */ 1232, 1232, 1382, 1232, 1389, 1232, 1232, 1232, 1232, 1232,
163981
+ /* 50 */ 1466, 1467, 1232, 1232, 1232, 1517, 1519, 1482, 1396, 1395,
163982
+ /* 60 */ 1394, 1393, 1500, 1361, 1387, 1380, 1384, 1460, 1461, 1459,
163983
+ /* 70 */ 1463, 1467, 1466, 1232, 1383, 1430, 1444, 1429, 1232, 1232,
163984
+ /* 80 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
163985
+ /* 90 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
163986
+ /* 100 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
163987
+ /* 110 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
163988
+ /* 120 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1438, 1443,
163989
+ /* 130 */ 1450, 1442, 1439, 1432, 1431, 1433, 1434, 1232, 1232, 1256,
163990
+ /* 140 */ 1232, 1232, 1253, 1307, 1232, 1232, 1232, 1232, 1232, 1537,
163991
+ /* 150 */ 1536, 1232, 1435, 1232, 1265, 1424, 1423, 1447, 1436, 1446,
163992
+ /* 160 */ 1445, 1525, 1589, 1588, 1483, 1232, 1232, 1232, 1232, 1232,
163993
+ /* 170 */ 1232, 1553, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
163994
+ /* 180 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
163995
+ /* 190 */ 1232, 1232, 1232, 1232, 1232, 1363, 1553, 1553, 1232, 1265,
163996
+ /* 200 */ 1553, 1553, 1364, 1364, 1261, 1261, 1367, 1232, 1532, 1334,
163997
+ /* 210 */ 1334, 1334, 1334, 1343, 1334, 1232, 1232, 1232, 1232, 1232,
163998
+ /* 220 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
163999
+ /* 230 */ 1522, 1520, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164000
+ /* 240 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164001
+ /* 250 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1339,
164002
+ /* 260 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164003
+ /* 270 */ 1232, 1582, 1232, 1495, 1321, 1339, 1339, 1339, 1339, 1341,
164004
+ /* 280 */ 1322, 1320, 1333, 1266, 1239, 1629, 1399, 1388, 1340, 1388,
164005
+ /* 290 */ 1626, 1386, 1399, 1399, 1386, 1399, 1340, 1626, 1282, 1605,
164006
+ /* 300 */ 1277, 1373, 1373, 1373, 1363, 1363, 1363, 1363, 1367, 1367,
164007
+ /* 310 */ 1462, 1340, 1333, 1232, 1629, 1629, 1349, 1349, 1628, 1628,
164008
+ /* 320 */ 1349, 1483, 1613, 1408, 1310, 1316, 1316, 1316, 1316, 1349,
164009
+ /* 330 */ 1250, 1386, 1613, 1613, 1386, 1408, 1310, 1386, 1310, 1386,
164010
+ /* 340 */ 1349, 1250, 1499, 1623, 1349, 1250, 1473, 1349, 1250, 1349,
164011
+ /* 350 */ 1250, 1473, 1308, 1308, 1308, 1297, 1232, 1232, 1473, 1308,
164012
+ /* 360 */ 1282, 1308, 1297, 1308, 1308, 1571, 1232, 1477, 1477, 1473,
164013
+ /* 370 */ 1349, 1563, 1563, 1376, 1376, 1381, 1367, 1468, 1349, 1232,
164014
+ /* 380 */ 1381, 1379, 1377, 1386, 1300, 1585, 1585, 1581, 1581, 1581,
164015
+ /* 390 */ 1634, 1634, 1532, 1598, 1265, 1265, 1265, 1265, 1598, 1284,
164016
+ /* 400 */ 1284, 1266, 1266, 1265, 1598, 1232, 1232, 1232, 1232, 1232,
164017
+ /* 410 */ 1232, 1593, 1232, 1527, 1484, 1353, 1232, 1232, 1232, 1232,
164018
+ /* 420 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164019
+ /* 430 */ 1538, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164020
+ /* 440 */ 1232, 1413, 1232, 1235, 1529, 1232, 1232, 1232, 1232, 1232,
164021
+ /* 450 */ 1232, 1232, 1232, 1390, 1391, 1354, 1232, 1232, 1232, 1232,
164022
+ /* 460 */ 1232, 1232, 1232, 1405, 1232, 1232, 1232, 1400, 1232, 1232,
164023
+ /* 470 */ 1232, 1232, 1232, 1232, 1232, 1232, 1625, 1232, 1232, 1232,
164024
+ /* 480 */ 1232, 1232, 1232, 1498, 1497, 1232, 1232, 1351, 1232, 1232,
164025
+ /* 490 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164026
+ /* 500 */ 1232, 1280, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164027
+ /* 510 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164028
+ /* 520 */ 1232, 1232, 1232, 1232, 1232, 1378, 1232, 1232, 1232, 1232,
164029
+ /* 530 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164030
+ /* 540 */ 1568, 1368, 1232, 1232, 1616, 1232, 1232, 1232, 1232, 1232,
164031
+ /* 550 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1609,
164032
+ /* 560 */ 1324, 1415, 1232, 1414, 1418, 1254, 1232, 1244, 1232, 1232,
162866164033
};
162867164034
/********** End of lemon-generated parsing tables *****************************/
162868164035
162869164036
/* The next table maps tokens (terminal symbols) into fallback tokens.
162870164037
** If a construct like the following:
@@ -163412,16 +164579,16 @@
163412164579
/* 254 */ "sclp",
163413164580
/* 255 */ "as",
163414164581
/* 256 */ "seltablist",
163415164582
/* 257 */ "stl_prefix",
163416164583
/* 258 */ "joinop",
163417
- /* 259 */ "indexed_opt",
163418
- /* 260 */ "on_opt",
163419
- /* 261 */ "using_opt",
163420
- /* 262 */ "exprlist",
163421
- /* 263 */ "xfullname",
163422
- /* 264 */ "idlist",
164584
+ /* 259 */ "on_using",
164585
+ /* 260 */ "indexed_by",
164586
+ /* 261 */ "exprlist",
164587
+ /* 262 */ "xfullname",
164588
+ /* 263 */ "idlist",
164589
+ /* 264 */ "indexed_opt",
163423164590
/* 265 */ "nulls",
163424164591
/* 266 */ "with",
163425164592
/* 267 */ "where_opt_ret",
163426164593
/* 268 */ "setlist",
163427164594
/* 269 */ "insert_cmd",
@@ -163588,33 +164755,33 @@
163588164755
/* 104 */ "as ::=",
163589164756
/* 105 */ "from ::=",
163590164757
/* 106 */ "from ::= FROM seltablist",
163591164758
/* 107 */ "stl_prefix ::= seltablist joinop",
163592164759
/* 108 */ "stl_prefix ::=",
163593
- /* 109 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
163594
- /* 110 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt",
163595
- /* 111 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
163596
- /* 112 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
163597
- /* 113 */ "dbnm ::=",
163598
- /* 114 */ "dbnm ::= DOT nm",
163599
- /* 115 */ "fullname ::= nm",
163600
- /* 116 */ "fullname ::= nm DOT nm",
163601
- /* 117 */ "xfullname ::= nm",
163602
- /* 118 */ "xfullname ::= nm DOT nm",
163603
- /* 119 */ "xfullname ::= nm DOT nm AS nm",
163604
- /* 120 */ "xfullname ::= nm AS nm",
163605
- /* 121 */ "joinop ::= COMMA|JOIN",
163606
- /* 122 */ "joinop ::= JOIN_KW JOIN",
163607
- /* 123 */ "joinop ::= JOIN_KW nm JOIN",
163608
- /* 124 */ "joinop ::= JOIN_KW nm nm JOIN",
163609
- /* 125 */ "on_opt ::= ON expr",
163610
- /* 126 */ "on_opt ::=",
163611
- /* 127 */ "indexed_opt ::=",
163612
- /* 128 */ "indexed_opt ::= INDEXED BY nm",
163613
- /* 129 */ "indexed_opt ::= NOT INDEXED",
163614
- /* 130 */ "using_opt ::= USING LP idlist RP",
163615
- /* 131 */ "using_opt ::=",
164760
+ /* 109 */ "seltablist ::= stl_prefix nm dbnm as on_using",
164761
+ /* 110 */ "seltablist ::= stl_prefix nm dbnm as indexed_by on_using",
164762
+ /* 111 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using",
164763
+ /* 112 */ "seltablist ::= stl_prefix LP select RP as on_using",
164764
+ /* 113 */ "seltablist ::= stl_prefix LP seltablist RP as on_using",
164765
+ /* 114 */ "dbnm ::=",
164766
+ /* 115 */ "dbnm ::= DOT nm",
164767
+ /* 116 */ "fullname ::= nm",
164768
+ /* 117 */ "fullname ::= nm DOT nm",
164769
+ /* 118 */ "xfullname ::= nm",
164770
+ /* 119 */ "xfullname ::= nm DOT nm",
164771
+ /* 120 */ "xfullname ::= nm DOT nm AS nm",
164772
+ /* 121 */ "xfullname ::= nm AS nm",
164773
+ /* 122 */ "joinop ::= COMMA|JOIN",
164774
+ /* 123 */ "joinop ::= JOIN_KW JOIN",
164775
+ /* 124 */ "joinop ::= JOIN_KW nm JOIN",
164776
+ /* 125 */ "joinop ::= JOIN_KW nm nm JOIN",
164777
+ /* 126 */ "on_using ::= ON expr",
164778
+ /* 127 */ "on_using ::= USING LP idlist RP",
164779
+ /* 128 */ "on_using ::=",
164780
+ /* 129 */ "indexed_opt ::=",
164781
+ /* 130 */ "indexed_by ::= INDEXED BY nm",
164782
+ /* 131 */ "indexed_by ::= NOT INDEXED",
163616164783
/* 132 */ "orderby_opt ::=",
163617164784
/* 133 */ "orderby_opt ::= ORDER BY sortlist",
163618164785
/* 134 */ "sortlist ::= sortlist COMMA expr sortorder nulls",
163619164786
/* 135 */ "sortlist ::= expr sortorder nulls",
163620164787
/* 136 */ "sortorder ::= ASC",
@@ -163856,35 +165023,36 @@
163856165023
/* 372 */ "resolvetype ::= raisetype",
163857165024
/* 373 */ "selectnowith ::= oneselect",
163858165025
/* 374 */ "oneselect ::= values",
163859165026
/* 375 */ "sclp ::= selcollist COMMA",
163860165027
/* 376 */ "as ::= ID|STRING",
163861
- /* 377 */ "returning ::=",
163862
- /* 378 */ "expr ::= term",
163863
- /* 379 */ "likeop ::= LIKE_KW|MATCH",
163864
- /* 380 */ "exprlist ::= nexprlist",
163865
- /* 381 */ "nmnum ::= plus_num",
163866
- /* 382 */ "nmnum ::= nm",
163867
- /* 383 */ "nmnum ::= ON",
163868
- /* 384 */ "nmnum ::= DELETE",
163869
- /* 385 */ "nmnum ::= DEFAULT",
163870
- /* 386 */ "plus_num ::= INTEGER|FLOAT",
163871
- /* 387 */ "foreach_clause ::=",
163872
- /* 388 */ "foreach_clause ::= FOR EACH ROW",
163873
- /* 389 */ "trnm ::= nm",
163874
- /* 390 */ "tridxby ::=",
163875
- /* 391 */ "database_kw_opt ::= DATABASE",
163876
- /* 392 */ "database_kw_opt ::=",
163877
- /* 393 */ "kwcolumn_opt ::=",
163878
- /* 394 */ "kwcolumn_opt ::= COLUMNKW",
163879
- /* 395 */ "vtabarglist ::= vtabarg",
163880
- /* 396 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
163881
- /* 397 */ "vtabarg ::= vtabarg vtabargtoken",
163882
- /* 398 */ "anylist ::=",
163883
- /* 399 */ "anylist ::= anylist LP anylist RP",
163884
- /* 400 */ "anylist ::= anylist ANY",
163885
- /* 401 */ "with ::=",
165028
+ /* 377 */ "indexed_opt ::= indexed_by",
165029
+ /* 378 */ "returning ::=",
165030
+ /* 379 */ "expr ::= term",
165031
+ /* 380 */ "likeop ::= LIKE_KW|MATCH",
165032
+ /* 381 */ "exprlist ::= nexprlist",
165033
+ /* 382 */ "nmnum ::= plus_num",
165034
+ /* 383 */ "nmnum ::= nm",
165035
+ /* 384 */ "nmnum ::= ON",
165036
+ /* 385 */ "nmnum ::= DELETE",
165037
+ /* 386 */ "nmnum ::= DEFAULT",
165038
+ /* 387 */ "plus_num ::= INTEGER|FLOAT",
165039
+ /* 388 */ "foreach_clause ::=",
165040
+ /* 389 */ "foreach_clause ::= FOR EACH ROW",
165041
+ /* 390 */ "trnm ::= nm",
165042
+ /* 391 */ "tridxby ::=",
165043
+ /* 392 */ "database_kw_opt ::= DATABASE",
165044
+ /* 393 */ "database_kw_opt ::=",
165045
+ /* 394 */ "kwcolumn_opt ::=",
165046
+ /* 395 */ "kwcolumn_opt ::= COLUMNKW",
165047
+ /* 396 */ "vtabarglist ::= vtabarg",
165048
+ /* 397 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
165049
+ /* 398 */ "vtabarg ::= vtabarg vtabargtoken",
165050
+ /* 399 */ "anylist ::=",
165051
+ /* 400 */ "anylist ::= anylist LP anylist RP",
165052
+ /* 401 */ "anylist ::= anylist ANY",
165053
+ /* 402 */ "with ::=",
163886165054
};
163887165055
#endif /* NDEBUG */
163888165056
163889165057
163890165058
#if YYSTACKDEPTH<=0
@@ -164018,11 +165186,10 @@
164018165186
break;
164019165187
case 216: /* term */
164020165188
case 217: /* expr */
164021165189
case 246: /* where_opt */
164022165190
case 248: /* having_opt */
164023
- case 260: /* on_opt */
164024165191
case 267: /* where_opt_ret */
164025165192
case 278: /* case_operand */
164026165193
case 280: /* case_else */
164027165194
case 283: /* vinto */
164028165195
case 290: /* when_clause */
@@ -164038,11 +165205,11 @@
164038165205
case 244: /* selcollist */
164039165206
case 247: /* groupby_opt */
164040165207
case 249: /* orderby_opt */
164041165208
case 253: /* nexprlist */
164042165209
case 254: /* sclp */
164043
- case 262: /* exprlist */
165210
+ case 261: /* exprlist */
164044165211
case 268: /* setlist */
164045165212
case 277: /* paren_exprlist */
164046165213
case 279: /* case_exprlist */
164047165214
case 310: /* part_opt */
164048165215
{
@@ -164051,11 +165218,11 @@
164051165218
break;
164052165219
case 238: /* fullname */
164053165220
case 245: /* from */
164054165221
case 256: /* seltablist */
164055165222
case 257: /* stl_prefix */
164056
- case 263: /* xfullname */
165223
+ case 262: /* xfullname */
164057165224
{
164058165225
sqlite3SrcListDelete(pParse->db, (yypminor->yy131));
164059165226
}
164060165227
break;
164061165228
case 241: /* wqlist */
@@ -164067,12 +165234,11 @@
164067165234
case 306: /* windowdefn_list */
164068165235
{
164069165236
sqlite3WindowListDelete(pParse->db, (yypminor->yy41));
164070165237
}
164071165238
break;
164072
- case 261: /* using_opt */
164073
- case 264: /* idlist */
165239
+ case 263: /* idlist */
164074165240
case 270: /* idlist_opt */
164075165241
{
164076165242
sqlite3IdListDelete(pParse->db, (yypminor->yy254));
164077165243
}
164078165244
break;
@@ -164498,33 +165664,33 @@
164498165664
255, /* (104) as ::= */
164499165665
245, /* (105) from ::= */
164500165666
245, /* (106) from ::= FROM seltablist */
164501165667
257, /* (107) stl_prefix ::= seltablist joinop */
164502165668
257, /* (108) stl_prefix ::= */
164503
- 256, /* (109) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
164504
- 256, /* (110) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
164505
- 256, /* (111) seltablist ::= stl_prefix LP select RP as on_opt using_opt */
164506
- 256, /* (112) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
164507
- 200, /* (113) dbnm ::= */
164508
- 200, /* (114) dbnm ::= DOT nm */
164509
- 238, /* (115) fullname ::= nm */
164510
- 238, /* (116) fullname ::= nm DOT nm */
164511
- 263, /* (117) xfullname ::= nm */
164512
- 263, /* (118) xfullname ::= nm DOT nm */
164513
- 263, /* (119) xfullname ::= nm DOT nm AS nm */
164514
- 263, /* (120) xfullname ::= nm AS nm */
164515
- 258, /* (121) joinop ::= COMMA|JOIN */
164516
- 258, /* (122) joinop ::= JOIN_KW JOIN */
164517
- 258, /* (123) joinop ::= JOIN_KW nm JOIN */
164518
- 258, /* (124) joinop ::= JOIN_KW nm nm JOIN */
164519
- 260, /* (125) on_opt ::= ON expr */
164520
- 260, /* (126) on_opt ::= */
164521
- 259, /* (127) indexed_opt ::= */
164522
- 259, /* (128) indexed_opt ::= INDEXED BY nm */
164523
- 259, /* (129) indexed_opt ::= NOT INDEXED */
164524
- 261, /* (130) using_opt ::= USING LP idlist RP */
164525
- 261, /* (131) using_opt ::= */
165669
+ 256, /* (109) seltablist ::= stl_prefix nm dbnm as on_using */
165670
+ 256, /* (110) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */
165671
+ 256, /* (111) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */
165672
+ 256, /* (112) seltablist ::= stl_prefix LP select RP as on_using */
165673
+ 256, /* (113) seltablist ::= stl_prefix LP seltablist RP as on_using */
165674
+ 200, /* (114) dbnm ::= */
165675
+ 200, /* (115) dbnm ::= DOT nm */
165676
+ 238, /* (116) fullname ::= nm */
165677
+ 238, /* (117) fullname ::= nm DOT nm */
165678
+ 262, /* (118) xfullname ::= nm */
165679
+ 262, /* (119) xfullname ::= nm DOT nm */
165680
+ 262, /* (120) xfullname ::= nm DOT nm AS nm */
165681
+ 262, /* (121) xfullname ::= nm AS nm */
165682
+ 258, /* (122) joinop ::= COMMA|JOIN */
165683
+ 258, /* (123) joinop ::= JOIN_KW JOIN */
165684
+ 258, /* (124) joinop ::= JOIN_KW nm JOIN */
165685
+ 258, /* (125) joinop ::= JOIN_KW nm nm JOIN */
165686
+ 259, /* (126) on_using ::= ON expr */
165687
+ 259, /* (127) on_using ::= USING LP idlist RP */
165688
+ 259, /* (128) on_using ::= */
165689
+ 264, /* (129) indexed_opt ::= */
165690
+ 260, /* (130) indexed_by ::= INDEXED BY nm */
165691
+ 260, /* (131) indexed_by ::= NOT INDEXED */
164526165692
249, /* (132) orderby_opt ::= */
164527165693
249, /* (133) orderby_opt ::= ORDER BY sortlist */
164528165694
231, /* (134) sortlist ::= sortlist COMMA expr sortorder nulls */
164529165695
231, /* (135) sortlist ::= expr sortorder nulls */
164530165696
219, /* (136) sortorder ::= ASC */
@@ -164564,12 +165730,12 @@
164564165730
272, /* (170) returning ::= RETURNING selcollist */
164565165731
269, /* (171) insert_cmd ::= INSERT orconf */
164566165732
269, /* (172) insert_cmd ::= REPLACE */
164567165733
270, /* (173) idlist_opt ::= */
164568165734
270, /* (174) idlist_opt ::= LP idlist RP */
164569
- 264, /* (175) idlist ::= idlist COMMA nm */
164570
- 264, /* (176) idlist ::= nm */
165735
+ 263, /* (175) idlist ::= idlist COMMA nm */
165736
+ 263, /* (176) idlist ::= nm */
164571165737
217, /* (177) expr ::= LP expr RP */
164572165738
217, /* (178) expr ::= ID|INDEXED */
164573165739
217, /* (179) expr ::= JOIN_KW */
164574165740
217, /* (180) expr ::= nm DOT nm */
164575165741
217, /* (181) expr ::= nm DOT nm DOT nm */
@@ -164619,11 +165785,11 @@
164619165785
279, /* (225) case_exprlist ::= WHEN expr THEN expr */
164620165786
280, /* (226) case_else ::= ELSE expr */
164621165787
280, /* (227) case_else ::= */
164622165788
278, /* (228) case_operand ::= expr */
164623165789
278, /* (229) case_operand ::= */
164624
- 262, /* (230) exprlist ::= */
165790
+ 261, /* (230) exprlist ::= */
164625165791
253, /* (231) nexprlist ::= nexprlist COMMA expr */
164626165792
253, /* (232) nexprlist ::= expr */
164627165793
277, /* (233) paren_exprlist ::= */
164628165794
277, /* (234) paren_exprlist ::= LP exprlist RP */
164629165795
190, /* (235) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
@@ -164766,35 +165932,36 @@
164766165932
235, /* (372) resolvetype ::= raisetype */
164767165933
239, /* (373) selectnowith ::= oneselect */
164768165934
240, /* (374) oneselect ::= values */
164769165935
254, /* (375) sclp ::= selcollist COMMA */
164770165936
255, /* (376) as ::= ID|STRING */
164771
- 272, /* (377) returning ::= */
164772
- 217, /* (378) expr ::= term */
164773
- 274, /* (379) likeop ::= LIKE_KW|MATCH */
164774
- 262, /* (380) exprlist ::= nexprlist */
164775
- 284, /* (381) nmnum ::= plus_num */
164776
- 284, /* (382) nmnum ::= nm */
164777
- 284, /* (383) nmnum ::= ON */
164778
- 284, /* (384) nmnum ::= DELETE */
164779
- 284, /* (385) nmnum ::= DEFAULT */
164780
- 211, /* (386) plus_num ::= INTEGER|FLOAT */
164781
- 289, /* (387) foreach_clause ::= */
164782
- 289, /* (388) foreach_clause ::= FOR EACH ROW */
164783
- 292, /* (389) trnm ::= nm */
164784
- 293, /* (390) tridxby ::= */
164785
- 294, /* (391) database_kw_opt ::= DATABASE */
164786
- 294, /* (392) database_kw_opt ::= */
164787
- 297, /* (393) kwcolumn_opt ::= */
164788
- 297, /* (394) kwcolumn_opt ::= COLUMNKW */
164789
- 299, /* (395) vtabarglist ::= vtabarg */
164790
- 299, /* (396) vtabarglist ::= vtabarglist COMMA vtabarg */
164791
- 300, /* (397) vtabarg ::= vtabarg vtabargtoken */
164792
- 303, /* (398) anylist ::= */
164793
- 303, /* (399) anylist ::= anylist LP anylist RP */
164794
- 303, /* (400) anylist ::= anylist ANY */
164795
- 266, /* (401) with ::= */
165937
+ 264, /* (377) indexed_opt ::= indexed_by */
165938
+ 272, /* (378) returning ::= */
165939
+ 217, /* (379) expr ::= term */
165940
+ 274, /* (380) likeop ::= LIKE_KW|MATCH */
165941
+ 261, /* (381) exprlist ::= nexprlist */
165942
+ 284, /* (382) nmnum ::= plus_num */
165943
+ 284, /* (383) nmnum ::= nm */
165944
+ 284, /* (384) nmnum ::= ON */
165945
+ 284, /* (385) nmnum ::= DELETE */
165946
+ 284, /* (386) nmnum ::= DEFAULT */
165947
+ 211, /* (387) plus_num ::= INTEGER|FLOAT */
165948
+ 289, /* (388) foreach_clause ::= */
165949
+ 289, /* (389) foreach_clause ::= FOR EACH ROW */
165950
+ 292, /* (390) trnm ::= nm */
165951
+ 293, /* (391) tridxby ::= */
165952
+ 294, /* (392) database_kw_opt ::= DATABASE */
165953
+ 294, /* (393) database_kw_opt ::= */
165954
+ 297, /* (394) kwcolumn_opt ::= */
165955
+ 297, /* (395) kwcolumn_opt ::= COLUMNKW */
165956
+ 299, /* (396) vtabarglist ::= vtabarg */
165957
+ 299, /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */
165958
+ 300, /* (398) vtabarg ::= vtabarg vtabargtoken */
165959
+ 303, /* (399) anylist ::= */
165960
+ 303, /* (400) anylist ::= anylist LP anylist RP */
165961
+ 303, /* (401) anylist ::= anylist ANY */
165962
+ 266, /* (402) with ::= */
164796165963
};
164797165964
164798165965
/* For rule J, yyRuleInfoNRhs[J] contains the negative of the number
164799165966
** of symbols on the right-hand side of that rule. */
164800165967
static const signed char yyRuleInfoNRhs[] = {
@@ -164905,33 +166072,33 @@
164905166072
0, /* (104) as ::= */
164906166073
0, /* (105) from ::= */
164907166074
-2, /* (106) from ::= FROM seltablist */
164908166075
-2, /* (107) stl_prefix ::= seltablist joinop */
164909166076
0, /* (108) stl_prefix ::= */
164910
- -7, /* (109) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
164911
- -9, /* (110) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
164912
- -7, /* (111) seltablist ::= stl_prefix LP select RP as on_opt using_opt */
164913
- -7, /* (112) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
164914
- 0, /* (113) dbnm ::= */
164915
- -2, /* (114) dbnm ::= DOT nm */
164916
- -1, /* (115) fullname ::= nm */
164917
- -3, /* (116) fullname ::= nm DOT nm */
164918
- -1, /* (117) xfullname ::= nm */
164919
- -3, /* (118) xfullname ::= nm DOT nm */
164920
- -5, /* (119) xfullname ::= nm DOT nm AS nm */
164921
- -3, /* (120) xfullname ::= nm AS nm */
164922
- -1, /* (121) joinop ::= COMMA|JOIN */
164923
- -2, /* (122) joinop ::= JOIN_KW JOIN */
164924
- -3, /* (123) joinop ::= JOIN_KW nm JOIN */
164925
- -4, /* (124) joinop ::= JOIN_KW nm nm JOIN */
164926
- -2, /* (125) on_opt ::= ON expr */
164927
- 0, /* (126) on_opt ::= */
164928
- 0, /* (127) indexed_opt ::= */
164929
- -3, /* (128) indexed_opt ::= INDEXED BY nm */
164930
- -2, /* (129) indexed_opt ::= NOT INDEXED */
164931
- -4, /* (130) using_opt ::= USING LP idlist RP */
164932
- 0, /* (131) using_opt ::= */
166077
+ -5, /* (109) seltablist ::= stl_prefix nm dbnm as on_using */
166078
+ -6, /* (110) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */
166079
+ -8, /* (111) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */
166080
+ -6, /* (112) seltablist ::= stl_prefix LP select RP as on_using */
166081
+ -6, /* (113) seltablist ::= stl_prefix LP seltablist RP as on_using */
166082
+ 0, /* (114) dbnm ::= */
166083
+ -2, /* (115) dbnm ::= DOT nm */
166084
+ -1, /* (116) fullname ::= nm */
166085
+ -3, /* (117) fullname ::= nm DOT nm */
166086
+ -1, /* (118) xfullname ::= nm */
166087
+ -3, /* (119) xfullname ::= nm DOT nm */
166088
+ -5, /* (120) xfullname ::= nm DOT nm AS nm */
166089
+ -3, /* (121) xfullname ::= nm AS nm */
166090
+ -1, /* (122) joinop ::= COMMA|JOIN */
166091
+ -2, /* (123) joinop ::= JOIN_KW JOIN */
166092
+ -3, /* (124) joinop ::= JOIN_KW nm JOIN */
166093
+ -4, /* (125) joinop ::= JOIN_KW nm nm JOIN */
166094
+ -2, /* (126) on_using ::= ON expr */
166095
+ -4, /* (127) on_using ::= USING LP idlist RP */
166096
+ 0, /* (128) on_using ::= */
166097
+ 0, /* (129) indexed_opt ::= */
166098
+ -3, /* (130) indexed_by ::= INDEXED BY nm */
166099
+ -2, /* (131) indexed_by ::= NOT INDEXED */
164933166100
0, /* (132) orderby_opt ::= */
164934166101
-3, /* (133) orderby_opt ::= ORDER BY sortlist */
164935166102
-5, /* (134) sortlist ::= sortlist COMMA expr sortorder nulls */
164936166103
-3, /* (135) sortlist ::= expr sortorder nulls */
164937166104
-1, /* (136) sortorder ::= ASC */
@@ -165173,35 +166340,36 @@
165173166340
-1, /* (372) resolvetype ::= raisetype */
165174166341
-1, /* (373) selectnowith ::= oneselect */
165175166342
-1, /* (374) oneselect ::= values */
165176166343
-2, /* (375) sclp ::= selcollist COMMA */
165177166344
-1, /* (376) as ::= ID|STRING */
165178
- 0, /* (377) returning ::= */
165179
- -1, /* (378) expr ::= term */
165180
- -1, /* (379) likeop ::= LIKE_KW|MATCH */
165181
- -1, /* (380) exprlist ::= nexprlist */
165182
- -1, /* (381) nmnum ::= plus_num */
165183
- -1, /* (382) nmnum ::= nm */
165184
- -1, /* (383) nmnum ::= ON */
165185
- -1, /* (384) nmnum ::= DELETE */
165186
- -1, /* (385) nmnum ::= DEFAULT */
165187
- -1, /* (386) plus_num ::= INTEGER|FLOAT */
165188
- 0, /* (387) foreach_clause ::= */
165189
- -3, /* (388) foreach_clause ::= FOR EACH ROW */
165190
- -1, /* (389) trnm ::= nm */
165191
- 0, /* (390) tridxby ::= */
165192
- -1, /* (391) database_kw_opt ::= DATABASE */
165193
- 0, /* (392) database_kw_opt ::= */
165194
- 0, /* (393) kwcolumn_opt ::= */
165195
- -1, /* (394) kwcolumn_opt ::= COLUMNKW */
165196
- -1, /* (395) vtabarglist ::= vtabarg */
165197
- -3, /* (396) vtabarglist ::= vtabarglist COMMA vtabarg */
165198
- -2, /* (397) vtabarg ::= vtabarg vtabargtoken */
165199
- 0, /* (398) anylist ::= */
165200
- -4, /* (399) anylist ::= anylist LP anylist RP */
165201
- -2, /* (400) anylist ::= anylist ANY */
165202
- 0, /* (401) with ::= */
166345
+ -1, /* (377) indexed_opt ::= indexed_by */
166346
+ 0, /* (378) returning ::= */
166347
+ -1, /* (379) expr ::= term */
166348
+ -1, /* (380) likeop ::= LIKE_KW|MATCH */
166349
+ -1, /* (381) exprlist ::= nexprlist */
166350
+ -1, /* (382) nmnum ::= plus_num */
166351
+ -1, /* (383) nmnum ::= nm */
166352
+ -1, /* (384) nmnum ::= ON */
166353
+ -1, /* (385) nmnum ::= DELETE */
166354
+ -1, /* (386) nmnum ::= DEFAULT */
166355
+ -1, /* (387) plus_num ::= INTEGER|FLOAT */
166356
+ 0, /* (388) foreach_clause ::= */
166357
+ -3, /* (389) foreach_clause ::= FOR EACH ROW */
166358
+ -1, /* (390) trnm ::= nm */
166359
+ 0, /* (391) tridxby ::= */
166360
+ -1, /* (392) database_kw_opt ::= DATABASE */
166361
+ 0, /* (393) database_kw_opt ::= */
166362
+ 0, /* (394) kwcolumn_opt ::= */
166363
+ -1, /* (395) kwcolumn_opt ::= COLUMNKW */
166364
+ -1, /* (396) vtabarglist ::= vtabarg */
166365
+ -3, /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */
166366
+ -2, /* (398) vtabarg ::= vtabarg vtabargtoken */
166367
+ 0, /* (399) anylist ::= */
166368
+ -4, /* (400) anylist ::= anylist LP anylist RP */
166369
+ -2, /* (401) anylist ::= anylist ANY */
166370
+ 0, /* (402) with ::= */
165203166371
};
165204166372
165205166373
static void yy_accept(yyParser*); /* Forward Declaration */
165206166374
165207166375
/*
@@ -165565,11 +166733,11 @@
165565166733
if( pRhs && pRhs->pPrior ){
165566166734
SrcList *pFrom;
165567166735
Token x;
165568166736
x.n = 0;
165569166737
parserDoubleLinkSelect(pParse, pRhs);
165570
- pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0);
166738
+ pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0);
165571166739
pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0);
165572166740
}
165573166741
if( pRhs ){
165574166742
pRhs->op = (u8)yymsp[-1].minor.yy394;
165575166743
pRhs->pPrior = pLhs;
@@ -165657,11 +166825,11 @@
165657166825
Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
165658166826
yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, pDot);
165659166827
}
165660166828
break;
165661166829
case 103: /* as ::= AS nm */
165662
- case 114: /* dbnm ::= DOT nm */ yytestcase(yyruleno==114);
166830
+ case 115: /* dbnm ::= DOT nm */ yytestcase(yyruleno==115);
165663166831
case 254: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==254);
165664166832
case 255: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==255);
165665166833
{yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
165666166834
break;
165667166835
case 105: /* from ::= */
@@ -165669,144 +166837,136 @@
165669166837
{yymsp[1].minor.yy131 = 0;}
165670166838
break;
165671166839
case 106: /* from ::= FROM seltablist */
165672166840
{
165673166841
yymsp[-1].minor.yy131 = yymsp[0].minor.yy131;
165674
- sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy131);
166842
+ sqlite3SrcListShiftJoinType(pParse,yymsp[-1].minor.yy131);
165675166843
}
165676166844
break;
165677166845
case 107: /* stl_prefix ::= seltablist joinop */
165678166846
{
165679166847
if( ALWAYS(yymsp[-1].minor.yy131 && yymsp[-1].minor.yy131->nSrc>0) ) yymsp[-1].minor.yy131->a[yymsp[-1].minor.yy131->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy394;
165680166848
}
165681166849
break;
165682
- case 109: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
165683
-{
165684
- yymsp[-6].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy131,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy528,yymsp[0].minor.yy254);
165685
- sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy131, &yymsp[-2].minor.yy0);
165686
-}
165687
- break;
165688
- case 110: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
165689
-{
165690
- yymsp[-8].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy131,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy528,yymsp[0].minor.yy254);
165691
- sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy131, yymsp[-4].minor.yy322);
165692
-}
165693
- break;
165694
- case 111: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
165695
-{
165696
- yymsp[-6].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy131,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy47,yymsp[-1].minor.yy528,yymsp[0].minor.yy254);
165697
- }
165698
- break;
165699
- case 112: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
165700
-{
165701
- if( yymsp[-6].minor.yy131==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy528==0 && yymsp[0].minor.yy254==0 ){
165702
- yymsp[-6].minor.yy131 = yymsp[-4].minor.yy131;
165703
- }else if( yymsp[-4].minor.yy131->nSrc==1 ){
165704
- yymsp[-6].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy131,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy528,yymsp[0].minor.yy254);
165705
- if( yymsp[-6].minor.yy131 ){
165706
- SrcItem *pNew = &yymsp[-6].minor.yy131->a[yymsp[-6].minor.yy131->nSrc-1];
165707
- SrcItem *pOld = yymsp[-4].minor.yy131->a;
166850
+ case 109: /* seltablist ::= stl_prefix nm dbnm as on_using */
166851
+{
166852
+ yymsp[-4].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-4].minor.yy131,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561);
166853
+}
166854
+ break;
166855
+ case 110: /* seltablist ::= stl_prefix nm dbnm as indexed_by on_using */
166856
+{
166857
+ yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,0,&yymsp[0].minor.yy561);
166858
+ sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy131, &yymsp[-1].minor.yy0);
166859
+}
166860
+ break;
166861
+ case 111: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */
166862
+{
166863
+ yymsp[-7].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-7].minor.yy131,&yymsp[-6].minor.yy0,&yymsp[-5].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561);
166864
+ sqlite3SrcListFuncArgs(pParse, yymsp[-7].minor.yy131, yymsp[-3].minor.yy322);
166865
+}
166866
+ break;
166867
+ case 112: /* seltablist ::= stl_prefix LP select RP as on_using */
166868
+{
166869
+ yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,yymsp[-3].minor.yy47,&yymsp[0].minor.yy561);
166870
+ }
166871
+ break;
166872
+ case 113: /* seltablist ::= stl_prefix LP seltablist RP as on_using */
166873
+{
166874
+ if( yymsp[-5].minor.yy131==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy561.pOn==0 && yymsp[0].minor.yy561.pUsing==0 ){
166875
+ yymsp[-5].minor.yy131 = yymsp[-3].minor.yy131;
166876
+ }else if( yymsp[-3].minor.yy131->nSrc==1 ){
166877
+ yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561);
166878
+ if( yymsp[-5].minor.yy131 ){
166879
+ SrcItem *pNew = &yymsp[-5].minor.yy131->a[yymsp[-5].minor.yy131->nSrc-1];
166880
+ SrcItem *pOld = yymsp[-3].minor.yy131->a;
165708166881
pNew->zName = pOld->zName;
165709166882
pNew->zDatabase = pOld->zDatabase;
165710166883
pNew->pSelect = pOld->pSelect;
166884
+ if( pNew->pSelect && (pNew->pSelect->selFlags & SF_NestedFrom)!=0 ){
166885
+ pNew->fg.isNestedFrom = 1;
166886
+ }
165711166887
if( pOld->fg.isTabFunc ){
165712166888
pNew->u1.pFuncArg = pOld->u1.pFuncArg;
165713166889
pOld->u1.pFuncArg = 0;
165714166890
pOld->fg.isTabFunc = 0;
165715166891
pNew->fg.isTabFunc = 1;
165716166892
}
165717166893
pOld->zName = pOld->zDatabase = 0;
165718166894
pOld->pSelect = 0;
165719166895
}
165720
- sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy131);
166896
+ sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy131);
165721166897
}else{
165722166898
Select *pSubquery;
165723
- sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy131);
165724
- pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy131,0,0,0,0,SF_NestedFrom,0);
165725
- yymsp[-6].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy131,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy528,yymsp[0].minor.yy254);
166899
+ sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy131);
166900
+ pSubquery = sqlite3SelectNew(pParse,0,yymsp[-3].minor.yy131,0,0,0,0,SF_NestedFrom,0);
166901
+ yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,pSubquery,&yymsp[0].minor.yy561);
165726166902
}
165727166903
}
165728166904
break;
165729
- case 113: /* dbnm ::= */
165730
- case 127: /* indexed_opt ::= */ yytestcase(yyruleno==127);
166905
+ case 114: /* dbnm ::= */
166906
+ case 129: /* indexed_opt ::= */ yytestcase(yyruleno==129);
165731166907
{yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;}
165732166908
break;
165733
- case 115: /* fullname ::= nm */
166909
+ case 116: /* fullname ::= nm */
165734166910
{
165735166911
yylhsminor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0);
165736166912
if( IN_RENAME_OBJECT && yylhsminor.yy131 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy131->a[0].zName, &yymsp[0].minor.yy0);
165737166913
}
165738166914
yymsp[0].minor.yy131 = yylhsminor.yy131;
165739166915
break;
165740
- case 116: /* fullname ::= nm DOT nm */
166916
+ case 117: /* fullname ::= nm DOT nm */
165741166917
{
165742166918
yylhsminor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
165743166919
if( IN_RENAME_OBJECT && yylhsminor.yy131 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy131->a[0].zName, &yymsp[0].minor.yy0);
165744166920
}
165745166921
yymsp[-2].minor.yy131 = yylhsminor.yy131;
165746166922
break;
165747
- case 117: /* xfullname ::= nm */
166923
+ case 118: /* xfullname ::= nm */
165748166924
{yymsp[0].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/}
165749166925
break;
165750
- case 118: /* xfullname ::= nm DOT nm */
166926
+ case 119: /* xfullname ::= nm DOT nm */
165751166927
{yymsp[-2].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/}
165752166928
break;
165753
- case 119: /* xfullname ::= nm DOT nm AS nm */
166929
+ case 120: /* xfullname ::= nm DOT nm AS nm */
165754166930
{
165755166931
yymsp[-4].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/
165756166932
if( yymsp[-4].minor.yy131 ) yymsp[-4].minor.yy131->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
165757166933
}
165758166934
break;
165759
- case 120: /* xfullname ::= nm AS nm */
166935
+ case 121: /* xfullname ::= nm AS nm */
165760166936
{
165761166937
yymsp[-2].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/
165762166938
if( yymsp[-2].minor.yy131 ) yymsp[-2].minor.yy131->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
165763166939
}
165764166940
break;
165765
- case 121: /* joinop ::= COMMA|JOIN */
166941
+ case 122: /* joinop ::= COMMA|JOIN */
165766166942
{ yymsp[0].minor.yy394 = JT_INNER; }
165767166943
break;
165768
- case 122: /* joinop ::= JOIN_KW JOIN */
166944
+ case 123: /* joinop ::= JOIN_KW JOIN */
165769166945
{yymsp[-1].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/}
165770166946
break;
165771
- case 123: /* joinop ::= JOIN_KW nm JOIN */
166947
+ case 124: /* joinop ::= JOIN_KW nm JOIN */
165772166948
{yymsp[-2].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/}
165773166949
break;
165774
- case 124: /* joinop ::= JOIN_KW nm nm JOIN */
166950
+ case 125: /* joinop ::= JOIN_KW nm nm JOIN */
165775166951
{yymsp[-3].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
165776166952
break;
165777
- case 125: /* on_opt ::= ON expr */
165778
- case 145: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==145);
165779
- case 152: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==152);
165780
- case 154: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==154);
165781
- case 226: /* case_else ::= ELSE expr */ yytestcase(yyruleno==226);
165782
- case 247: /* vinto ::= INTO expr */ yytestcase(yyruleno==247);
165783
-{yymsp[-1].minor.yy528 = yymsp[0].minor.yy528;}
165784
- break;
165785
- case 126: /* on_opt ::= */
165786
- case 144: /* having_opt ::= */ yytestcase(yyruleno==144);
165787
- case 146: /* limit_opt ::= */ yytestcase(yyruleno==146);
165788
- case 151: /* where_opt ::= */ yytestcase(yyruleno==151);
165789
- case 153: /* where_opt_ret ::= */ yytestcase(yyruleno==153);
165790
- case 227: /* case_else ::= */ yytestcase(yyruleno==227);
165791
- case 229: /* case_operand ::= */ yytestcase(yyruleno==229);
165792
- case 248: /* vinto ::= */ yytestcase(yyruleno==248);
165793
-{yymsp[1].minor.yy528 = 0;}
165794
- break;
165795
- case 128: /* indexed_opt ::= INDEXED BY nm */
166953
+ case 126: /* on_using ::= ON expr */
166954
+{yymsp[-1].minor.yy561.pOn = yymsp[0].minor.yy528; yymsp[-1].minor.yy561.pUsing = 0;}
166955
+ break;
166956
+ case 127: /* on_using ::= USING LP idlist RP */
166957
+{yymsp[-3].minor.yy561.pOn = 0; yymsp[-3].minor.yy561.pUsing = yymsp[-1].minor.yy254;}
166958
+ break;
166959
+ case 128: /* on_using ::= */
166960
+{yymsp[1].minor.yy561.pOn = 0; yymsp[1].minor.yy561.pUsing = 0;}
166961
+ break;
166962
+ case 130: /* indexed_by ::= INDEXED BY nm */
165796166963
{yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;}
165797166964
break;
165798
- case 129: /* indexed_opt ::= NOT INDEXED */
166965
+ case 131: /* indexed_by ::= NOT INDEXED */
165799166966
{yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;}
165800166967
break;
165801
- case 130: /* using_opt ::= USING LP idlist RP */
165802
-{yymsp[-3].minor.yy254 = yymsp[-1].minor.yy254;}
165803
- break;
165804
- case 131: /* using_opt ::= */
165805
- case 173: /* idlist_opt ::= */ yytestcase(yyruleno==173);
165806
-{yymsp[1].minor.yy254 = 0;}
165807
- break;
165808166968
case 133: /* orderby_opt ::= ORDER BY sortlist */
165809166969
case 143: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==143);
165810166970
{yymsp[-2].minor.yy322 = yymsp[0].minor.yy322;}
165811166971
break;
165812166972
case 134: /* sortlist ::= sortlist COMMA expr sortorder nulls */
@@ -165835,10 +166995,26 @@
165835166995
{yymsp[-1].minor.yy394 = SQLITE_SO_ASC;}
165836166996
break;
165837166997
case 140: /* nulls ::= NULLS LAST */
165838166998
{yymsp[-1].minor.yy394 = SQLITE_SO_DESC;}
165839166999
break;
167000
+ case 144: /* having_opt ::= */
167001
+ case 146: /* limit_opt ::= */ yytestcase(yyruleno==146);
167002
+ case 151: /* where_opt ::= */ yytestcase(yyruleno==151);
167003
+ case 153: /* where_opt_ret ::= */ yytestcase(yyruleno==153);
167004
+ case 227: /* case_else ::= */ yytestcase(yyruleno==227);
167005
+ case 229: /* case_operand ::= */ yytestcase(yyruleno==229);
167006
+ case 248: /* vinto ::= */ yytestcase(yyruleno==248);
167007
+{yymsp[1].minor.yy528 = 0;}
167008
+ break;
167009
+ case 145: /* having_opt ::= HAVING expr */
167010
+ case 152: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==152);
167011
+ case 154: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==154);
167012
+ case 226: /* case_else ::= ELSE expr */ yytestcase(yyruleno==226);
167013
+ case 247: /* vinto ::= INTO expr */ yytestcase(yyruleno==247);
167014
+{yymsp[-1].minor.yy528 = yymsp[0].minor.yy528;}
167015
+ break;
165840167016
case 147: /* limit_opt ::= LIMIT expr */
165841167017
{yymsp[-1].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy528,0);}
165842167018
break;
165843167019
case 148: /* limit_opt ::= LIMIT expr OFFSET expr */
165844167020
{yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);}
@@ -165917,10 +167093,13 @@
165917167093
case 169: /* upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */
165918167094
{ yymsp[-7].minor.yy444 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528,0);}
165919167095
break;
165920167096
case 170: /* returning ::= RETURNING selcollist */
165921167097
{sqlite3AddReturning(pParse,yymsp[0].minor.yy322);}
167098
+ break;
167099
+ case 173: /* idlist_opt ::= */
167100
+{yymsp[1].minor.yy254 = 0;}
165922167101
break;
165923167102
case 174: /* idlist_opt ::= LP idlist RP */
165924167103
{yymsp[-2].minor.yy254 = yymsp[-1].minor.yy254;}
165925167104
break;
165926167105
case 175: /* idlist ::= idlist COMMA nm */
@@ -166693,35 +167872,36 @@
166693167872
/* (372) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=372);
166694167873
/* (373) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=373);
166695167874
/* (374) oneselect ::= values */ yytestcase(yyruleno==374);
166696167875
/* (375) sclp ::= selcollist COMMA */ yytestcase(yyruleno==375);
166697167876
/* (376) as ::= ID|STRING */ yytestcase(yyruleno==376);
166698
- /* (377) returning ::= */ yytestcase(yyruleno==377);
166699
- /* (378) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=378);
166700
- /* (379) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==379);
166701
- /* (380) exprlist ::= nexprlist */ yytestcase(yyruleno==380);
166702
- /* (381) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=381);
166703
- /* (382) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=382);
166704
- /* (383) nmnum ::= ON */ yytestcase(yyruleno==383);
166705
- /* (384) nmnum ::= DELETE */ yytestcase(yyruleno==384);
166706
- /* (385) nmnum ::= DEFAULT */ yytestcase(yyruleno==385);
166707
- /* (386) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==386);
166708
- /* (387) foreach_clause ::= */ yytestcase(yyruleno==387);
166709
- /* (388) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==388);
166710
- /* (389) trnm ::= nm */ yytestcase(yyruleno==389);
166711
- /* (390) tridxby ::= */ yytestcase(yyruleno==390);
166712
- /* (391) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==391);
166713
- /* (392) database_kw_opt ::= */ yytestcase(yyruleno==392);
166714
- /* (393) kwcolumn_opt ::= */ yytestcase(yyruleno==393);
166715
- /* (394) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==394);
166716
- /* (395) vtabarglist ::= vtabarg */ yytestcase(yyruleno==395);
166717
- /* (396) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==396);
166718
- /* (397) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==397);
166719
- /* (398) anylist ::= */ yytestcase(yyruleno==398);
166720
- /* (399) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==399);
166721
- /* (400) anylist ::= anylist ANY */ yytestcase(yyruleno==400);
166722
- /* (401) with ::= */ yytestcase(yyruleno==401);
167877
+ /* (377) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=377);
167878
+ /* (378) returning ::= */ yytestcase(yyruleno==378);
167879
+ /* (379) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=379);
167880
+ /* (380) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==380);
167881
+ /* (381) exprlist ::= nexprlist */ yytestcase(yyruleno==381);
167882
+ /* (382) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=382);
167883
+ /* (383) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=383);
167884
+ /* (384) nmnum ::= ON */ yytestcase(yyruleno==384);
167885
+ /* (385) nmnum ::= DELETE */ yytestcase(yyruleno==385);
167886
+ /* (386) nmnum ::= DEFAULT */ yytestcase(yyruleno==386);
167887
+ /* (387) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==387);
167888
+ /* (388) foreach_clause ::= */ yytestcase(yyruleno==388);
167889
+ /* (389) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==389);
167890
+ /* (390) trnm ::= nm */ yytestcase(yyruleno==390);
167891
+ /* (391) tridxby ::= */ yytestcase(yyruleno==391);
167892
+ /* (392) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==392);
167893
+ /* (393) database_kw_opt ::= */ yytestcase(yyruleno==393);
167894
+ /* (394) kwcolumn_opt ::= */ yytestcase(yyruleno==394);
167895
+ /* (395) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==395);
167896
+ /* (396) vtabarglist ::= vtabarg */ yytestcase(yyruleno==396);
167897
+ /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==397);
167898
+ /* (398) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==398);
167899
+ /* (399) anylist ::= */ yytestcase(yyruleno==399);
167900
+ /* (400) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==400);
167901
+ /* (401) anylist ::= anylist ANY */ yytestcase(yyruleno==401);
167902
+ /* (402) with ::= */ yytestcase(yyruleno==402);
166723167903
break;
166724167904
/********** End reduce actions ************************************************/
166725167905
};
166726167906
assert( yyruleno<sizeof(yyRuleInfoLhs)/sizeof(yyRuleInfoLhs[0]) );
166727167907
yygoto = yyRuleInfoLhs[yyruleno];
@@ -172889,10 +174069,29 @@
172889174069
*/
172890174070
case SQLITE_TESTCTRL_ASSERT: {
172891174071
volatile int x = 0;
172892174072
assert( /*side-effects-ok*/ (x = va_arg(ap,int))!=0 );
172893174073
rc = x;
174074
+#if defined(SQLITE_DEBUG)
174075
+ /* Invoke these debugging routines so that the compiler does not
174076
+ ** issue "defined but not used" warnings. */
174077
+ if( x==9999 ){
174078
+ sqlite3ShowExpr(0);
174079
+ sqlite3ShowExpr(0);
174080
+ sqlite3ShowExprList(0);
174081
+ sqlite3ShowIdList(0);
174082
+ sqlite3ShowSrcList(0);
174083
+ sqlite3ShowWith(0);
174084
+ sqlite3ShowUpsert(0);
174085
+ sqlite3ShowTriggerStep(0);
174086
+ sqlite3ShowTriggerStepList(0);
174087
+ sqlite3ShowTrigger(0);
174088
+ sqlite3ShowTriggerList(0);
174089
+ sqlite3ShowWindow(0);
174090
+ sqlite3ShowWinFunc(0);
174091
+ }
174092
+#endif
172894174093
break;
172895174094
}
172896174095
172897174096
172898174097
/*
@@ -173150,23 +174349,23 @@
173150174349
173151174350
/* sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, op, ptr)
173152174351
**
173153174352
** "ptr" is a pointer to a u32.
173154174353
**
173155
- ** op==0 Store the current sqlite3SelectTrace in *ptr
173156
- ** op==1 Set sqlite3SelectTrace to the value *ptr
174354
+ ** op==0 Store the current sqlite3TreeTrace in *ptr
174355
+ ** op==1 Set sqlite3TreeTrace to the value *ptr
173157174356
** op==3 Store the current sqlite3WhereTrace in *ptr
173158174357
** op==3 Set sqlite3WhereTrace to the value *ptr
173159174358
*/
173160174359
case SQLITE_TESTCTRL_TRACEFLAGS: {
173161174360
int opTrace = va_arg(ap, int);
173162174361
u32 *ptr = va_arg(ap, u32*);
173163174362
switch( opTrace ){
173164
- case 0: *ptr = sqlite3SelectTrace; break;
173165
- case 1: sqlite3SelectTrace = *ptr; break;
173166
- case 2: *ptr = sqlite3WhereTrace; break;
173167
- case 3: sqlite3WhereTrace = *ptr; break;
174363
+ case 0: *ptr = sqlite3TreeTrace; break;
174364
+ case 1: sqlite3TreeTrace = *ptr; break;
174365
+ case 2: *ptr = sqlite3WhereTrace; break;
174366
+ case 3: sqlite3WhereTrace = *ptr; break;
173168174367
}
173169174368
break;
173170174369
}
173171174370
173172174371
/* sqlite3_test_control(SQLITE_TESTCTRL_LOGEST,
@@ -194609,18 +195808,19 @@
194609195808
i++;
194610195809
}else{
194611195810
*pzErr = zPath;
194612195811
return 0;
194613195812
}
195813
+ testcase( nKey==0 );
194614195814
}else{
194615195815
zKey = zPath;
194616195816
for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
194617195817
nKey = i;
194618
- }
194619
- if( nKey==0 ){
194620
- *pzErr = zPath;
194621
- return 0;
195818
+ if( nKey==0 ){
195819
+ *pzErr = zPath;
195820
+ return 0;
195821
+ }
194622195822
}
194623195823
j = 1;
194624195824
for(;;){
194625195825
while( j<=pRoot->n ){
194626195826
if( jsonLabelCompare(pRoot+j, zKey, nKey) ){
@@ -195763,10 +196963,37 @@
195763196963
}
195764196964
}
195765196965
}
195766196966
return SQLITE_OK;
195767196967
}
196968
+
196969
+/* Append an object label to the JSON Path being constructed
196970
+** in pStr.
196971
+*/
196972
+static void jsonAppendObjectPathElement(
196973
+ JsonString *pStr,
196974
+ JsonNode *pNode
196975
+){
196976
+ int jj, nn;
196977
+ const char *z;
196978
+ assert( pNode->eType==JSON_STRING );
196979
+ assert( pNode->jnFlags & JNODE_LABEL );
196980
+ assert( pNode->eU==1 );
196981
+ z = pNode->u.zJContent;
196982
+ nn = pNode->n;
196983
+ assert( nn>=2 );
196984
+ assert( z[0]=='"' );
196985
+ assert( z[nn-1]=='"' );
196986
+ if( nn>2 && sqlite3Isalpha(z[1]) ){
196987
+ for(jj=2; jj<nn-1 && sqlite3Isalnum(z[jj]); jj++){}
196988
+ if( jj==nn-1 ){
196989
+ z++;
196990
+ nn -= 2;
196991
+ }
196992
+ }
196993
+ jsonPrintf(nn+2, pStr, ".%.*s", nn, z);
196994
+}
195768196995
195769196996
/* Append the name of the path for element i to pStr
195770196997
*/
195771196998
static void jsonEachComputePath(
195772196999
JsonEachCursor *p, /* The cursor */
@@ -195788,14 +197015,11 @@
195788197015
testcase( pUp->eU==0 );
195789197016
jsonPrintf(30, pStr, "[%d]", pUp->u.iKey);
195790197017
}else{
195791197018
assert( pUp->eType==JSON_OBJECT );
195792197019
if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--;
195793
- assert( pNode->eType==JSON_STRING );
195794
- assert( pNode->jnFlags & JNODE_LABEL );
195795
- assert( pNode->eU==1 );
195796
- jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1);
197020
+ jsonAppendObjectPathElement(pStr, pNode);
195797197021
}
195798197022
}
195799197023
195800197024
/* Return the value of a column */
195801197025
static int jsonEachColumn(
@@ -195862,12 +197086,11 @@
195862197086
jsonAppendChar(&x, '$');
195863197087
}
195864197088
if( p->eType==JSON_ARRAY ){
195865197089
jsonPrintf(30, &x, "[%d]", p->iRowid);
195866197090
}else if( p->eType==JSON_OBJECT ){
195867
- assert( pThis->eU==1 );
195868
- jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1);
197091
+ jsonAppendObjectPathElement(&x, pThis);
195869197092
}
195870197093
}
195871197094
jsonResult(&x);
195872197095
break;
195873197096
}
@@ -210410,11 +211633,11 @@
210410211633
&& pIdxInfo->aOrderBy[0].iColumn<=0
210411211634
&& pIdxInfo->aOrderBy[0].desc==0
210412211635
){
210413211636
pIdxInfo->orderByConsumed = 1;
210414211637
}
210415
- sqlite3VtabWriteAll(pIdxInfo);
211638
+ sqlite3VtabUsesAllSchemas(pIdxInfo);
210416211639
return SQLITE_OK;
210417211640
}
210418211641
210419211642
/*
210420211643
** Open a new dbpagevfs cursor.
@@ -223138,10 +224361,13 @@
223138224361
sqlite3Fts5ParseNearsetFree(pNear);
223139224362
sqlite3Fts5ParsePhraseFree(pPhrase);
223140224363
}else{
223141224364
if( pRet->nPhrase>0 ){
223142224365
Fts5ExprPhrase *pLast = pRet->apPhrase[pRet->nPhrase-1];
224366
+ assert( pParse!=0 );
224367
+ assert( pParse->apPhrase!=0 );
224368
+ assert( pParse->nPhrase>=2 );
223143224369
assert( pLast==pParse->apPhrase[pParse->nPhrase-2] );
223144224370
if( pPhrase->nTerm==0 ){
223145224371
fts5ExprPhraseFree(pPhrase);
223146224372
pRet->nPhrase--;
223147224373
pParse->nPhrase--;
@@ -234754,11 +235980,11 @@
234754235980
int nArg, /* Number of args */
234755235981
sqlite3_value **apUnused /* Function arguments */
234756235982
){
234757235983
assert( nArg==0 );
234758235984
UNUSED_PARAM2(nArg, apUnused);
234759
- sqlite3_result_text(pCtx, "fts5: 2022-03-31 11:12:56 f2d9262e4427ab37ba26c004fc7a4790c86c1856d695a6b4ec3e72732ea54c09", -1, SQLITE_TRANSIENT);
235985
+ sqlite3_result_text(pCtx, "fts5: 2022-04-19 15:56:03 b966d52437f08a6759a83a45cafb0d706a8933a8e55dee38ae78166d1a5b3ba4", -1, SQLITE_TRANSIENT);
234760235986
}
234761235987
234762235988
/*
234763235989
** Return true if zName is the extension on one of the shadow tables used
234764235990
** by this module.
234765235991
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -452,11 +452,11 @@
452 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
453 ** [sqlite_version()] and [sqlite_source_id()].
454 */
455 #define SQLITE_VERSION "3.39.0"
456 #define SQLITE_VERSION_NUMBER 3039000
457 #define SQLITE_SOURCE_ID "2022-04-01 17:23:17 a7d79560a0efd6221ba59ce84bcb4fa94024a901ac4a45e192ddecc6e1b5c78c"
458
459 /*
460 ** CAPI3REF: Run-Time Library Version Numbers
461 ** KEYWORDS: sqlite3_version sqlite3_sourceid
462 **
@@ -14363,12 +14363,23 @@
14363 #define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)
14364
14365 /*
14366 ** Round up a number to the next larger multiple of 8. This is used
14367 ** to force 8-byte alignment on 64-bit architectures.
 
 
 
 
 
 
14368 */
14369 #define ROUND8(x) (((x)+7)&~7)
 
 
 
 
 
14370
14371 /*
14372 ** Round down to the nearest multiple of 8
14373 */
14374 #define ROUNDDOWN8(x) ((x)&~7)
@@ -14427,26 +14438,27 @@
14427 # undef SQLITE_DEFAULT_MMAP_SIZE
14428 # define SQLITE_DEFAULT_MMAP_SIZE SQLITE_MAX_MMAP_SIZE
14429 #endif
14430
14431 /*
14432 ** SELECTTRACE_ENABLED will be either 1 or 0 depending on whether or not
14433 ** the Select query generator tracing logic is turned on.
14434 */
14435 #if !defined(SQLITE_AMALGAMATION)
14436 SQLITE_PRIVATE u32 sqlite3SelectTrace;
14437 #endif
14438 #if defined(SQLITE_DEBUG) \
14439 && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_SELECTTRACE))
14440 # define SELECTTRACE_ENABLED 1
 
14441 # define SELECTTRACE(K,P,S,X) \
14442 if(sqlite3SelectTrace&(K)) \
14443 sqlite3DebugPrintf("%u/%d/%p: ",(S)->selId,(P)->addrExplain,(S)),\
14444 sqlite3DebugPrintf X
14445 #else
14446 # define SELECTTRACE(K,P,S,X)
14447 # define SELECTTRACE_ENABLED 0
14448 #endif
14449
14450 /*
14451 ** Macros for "wheretrace"
14452 */
@@ -14603,10 +14615,11 @@
14603 typedef struct KeyInfo KeyInfo;
14604 typedef struct Lookaside Lookaside;
14605 typedef struct LookasideSlot LookasideSlot;
14606 typedef struct Module Module;
14607 typedef struct NameContext NameContext;
 
14608 typedef struct Parse Parse;
14609 typedef struct ParseCleanup ParseCleanup;
14610 typedef struct PreUpdate PreUpdate;
14611 typedef struct PrintfArguments PrintfArguments;
14612 typedef struct RenameToken RenameToken;
@@ -15581,14 +15594,14 @@
15581 #define OP_Function 66 /* synopsis: r[P3]=func(r[P2@NP]) */
15582 #define OP_Return 67
15583 #define OP_EndCoroutine 68
15584 #define OP_HaltIfNull 69 /* synopsis: if r[P3]=null halt */
15585 #define OP_Halt 70
15586 #define OP_BeginSubrtn 71 /* synopsis: r[P2]=P1 */
15587 #define OP_Integer 72 /* synopsis: r[P2]=P1 */
15588 #define OP_Int64 73 /* synopsis: r[P2]=P4 */
15589 #define OP_String 74 /* synopsis: r[P2]='P4' (len=P1) */
15590 #define OP_Null 75 /* synopsis: r[P2..P3]=NULL */
15591 #define OP_SoftNull 76 /* synopsis: r[P1]=NULL */
15592 #define OP_Blob 77 /* synopsis: r[P2]=P4 (len=P1) */
15593 #define OP_Variable 78 /* synopsis: r[P2]=parameter(P1,P4) */
15594 #define OP_Move 79 /* synopsis: r[P2@P3]=r[P1@P3] */
@@ -15604,11 +15617,11 @@
15604 #define OP_Permutation 89
15605 #define OP_Compare 90 /* synopsis: r[P1@P3] <-> r[P2@P3] */
15606 #define OP_IsTrue 91 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */
15607 #define OP_ZeroOrNull 92 /* synopsis: r[P2] = 0 OR NULL */
15608 #define OP_Offset 93 /* synopsis: r[P3] = sqlite_offset(P1) */
15609 #define OP_Column 94 /* synopsis: r[P3]=PX */
15610 #define OP_TypeCheck 95 /* synopsis: typecheck(r[P1@P2]) */
15611 #define OP_Affinity 96 /* synopsis: affinity(r[P1@P2]) */
15612 #define OP_MakeRecord 97 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
15613 #define OP_Count 98 /* synopsis: r[P2]=count() */
15614 #define OP_ReadCookie 99
@@ -15645,11 +15658,11 @@
15645 #define OP_Delete 130
15646 #define OP_ResetCount 131
15647 #define OP_SorterCompare 132 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
15648 #define OP_SorterData 133 /* synopsis: r[P2]=data */
15649 #define OP_RowData 134 /* synopsis: r[P2]=data */
15650 #define OP_Rowid 135 /* synopsis: r[P2]=rowid */
15651 #define OP_NullRow 136
15652 #define OP_SeekEnd 137
15653 #define OP_IdxInsert 138 /* synopsis: key=r[P2] */
15654 #define OP_SorterInsert 139 /* synopsis: key=r[P2] */
15655 #define OP_IdxDelete 140 /* synopsis: key=r[P2@P3] */
@@ -15716,12 +15729,12 @@
15716 /* 24 */ 0x01, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x01,\
15717 /* 32 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
15718 /* 40 */ 0x01, 0x01, 0x01, 0x26, 0x26, 0x23, 0x0b, 0x01,\
15719 /* 48 */ 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\
15720 /* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x01, 0x01,\
15721 /* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x00,\
15722 /* 72 */ 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00,\
15723 /* 80 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02,\
15724 /* 88 */ 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20, 0x00, 0x00,\
15725 /* 96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x26, 0x26,\
15726 /* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\
15727 /* 112 */ 0x00, 0x00, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00,\
@@ -15823,11 +15836,10 @@
15823 SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
15824 SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Parse*);
15825 SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*);
15826 SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe*);
15827 SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*);
15828 SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3*,Vdbe*);
15829 SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,Parse*);
15830 SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe*);
15831 SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int);
15832 SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe*);
15833 #ifdef SQLITE_DEBUG
@@ -17038,10 +17050,11 @@
17038 #define SQLITE_OmitOrderBy 0x00040000 /* Omit pointless ORDER BY */
17039 /* TH3 expects this value ^^^^^^^^^^ to be 0x40000. Coordinate any change */
17040 #define SQLITE_BloomFilter 0x00080000 /* Use a Bloom filter on searches */
17041 #define SQLITE_BloomPulldown 0x00100000 /* Run Bloom filters early */
17042 #define SQLITE_BalancedMerge 0x00200000 /* Balance multi-way merges */
 
17043 #define SQLITE_AllOpts 0xffffffff /* All optimizations */
17044
17045 /*
17046 ** Macros for testing whether or not optimizations are enabled or disabled.
17047 */
@@ -18102,11 +18115,11 @@
18102 ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid.
18103 ** TK_VARIABLE: variable number (always >= 1).
18104 ** TK_SELECT_COLUMN: column of the result vector */
18105 i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
18106 union {
18107 int iRightJoinTable; /* If EP_FromJoin, the right table of the join */
18108 int iOfst; /* else: start of token from start of statement */
18109 } w;
18110 AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
18111 union {
18112 Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL
@@ -18145,11 +18158,11 @@
18145 #define EP_IfNullRow 0x020000 /* The TK_IF_NULL_ROW opcode */
18146 #define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
18147 #define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
18148 #define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
18149 #define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
18150 /* 0x400000 // Available */
18151 #define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
18152 #define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
18153 #define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */
18154 #define EP_Quoted 0x4000000 /* TK_ID was originally quoted */
18155 #define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */
@@ -18262,10 +18275,11 @@
18262 unsigned eEName :2; /* Meaning of zEName */
18263 unsigned done :1; /* A flag to indicate when processing is finished */
18264 unsigned reusable :1; /* Constant expression is reusable */
18265 unsigned bSorterRef :1; /* Defer evaluation until after sorting */
18266 unsigned bNulls: 1; /* True if explicit "NULLS FIRST/LAST" */
 
18267 union {
18268 struct { /* Used by any ExprList other than Parse.pConsExpr */
18269 u16 iOrderByCol; /* For ORDER BY, column number in result set */
18270 u16 iAlias; /* Index into Parse.aAlias[] for zName */
18271 } x;
@@ -18296,17 +18310,29 @@
18296 ** INSERT INTO t(a,b,c) ...
18297 **
18298 ** If "a" is the k-th column of table "t", then IdList.a[0].idx==k.
18299 */
18300 struct IdList {
 
 
18301 struct IdList_item {
18302 char *zName; /* Name of the identifier */
18303 int idx; /* Index in some Table.aCol[] of a column named zName */
18304 } *a;
18305 int nId; /* Number of identifiers on the list */
 
 
18306 };
18307
 
 
 
 
 
 
 
 
18308 /*
18309 ** The SrcItem object represents a single term in the FROM clause of a query.
18310 ** The SrcList object is mostly an array of SrcItems.
18311 **
18312 ** Union member validity:
@@ -18335,14 +18361,19 @@
18335 unsigned viaCoroutine :1; /* Implemented as a co-routine */
18336 unsigned isRecursive :1; /* True for recursive reference in WITH */
18337 unsigned fromDDL :1; /* Comes from sqlite_schema */
18338 unsigned isCte :1; /* This is a CTE */
18339 unsigned notCte :1; /* This item may not match a CTE */
 
 
 
18340 } fg;
18341 int iCursor; /* The VDBE cursor number used to access this table */
18342 Expr *pOn; /* The ON clause of a join */
18343 IdList *pUsing; /* The USING clause of a join */
 
 
18344 Bitmask colUsed; /* Bit N (1<<N) set if column N of pTab is used */
18345 union {
18346 char *zIndexedBy; /* Identifier from "INDEXED BY <zIndex>" clause */
18347 ExprList *pFuncArg; /* Arguments to table-valued-function */
18348 } u1;
@@ -18349,10 +18380,19 @@
18349 union {
18350 Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */
18351 CteUse *pCteUse; /* CTE Usage info info fg.isCte is true */
18352 } u2;
18353 };
 
 
 
 
 
 
 
 
 
18354
18355 /*
18356 ** The following structure describes the FROM clause of a SELECT statement.
18357 ** Each table or subquery in the FROM clause is a separate element of
18358 ** the SrcList.a[] array.
@@ -18378,18 +18418,19 @@
18378 };
18379
18380 /*
18381 ** Permitted values of the SrcList.a.jointype field
18382 */
18383 #define JT_INNER 0x0001 /* Any kind of inner or cross join */
18384 #define JT_CROSS 0x0002 /* Explicit use of the CROSS keyword */
18385 #define JT_NATURAL 0x0004 /* True for a "natural" join */
18386 #define JT_LEFT 0x0008 /* Left outer join */
18387 #define JT_RIGHT 0x0010 /* Right outer join */
18388 #define JT_OUTER 0x0020 /* The "OUTER" keyword is present */
18389 #define JT_ERROR 0x0040 /* unknown or unsupported join type */
18390
 
18391
18392 /*
18393 ** Flags appropriate for the wctrlFlags parameter of sqlite3WhereBegin()
18394 ** and the WhereInfo.wctrlFlags member.
18395 **
@@ -18408,11 +18449,11 @@
18408 #define WHERE_DISTINCTBY 0x0080 /* pOrderby is really a DISTINCT clause */
18409 #define WHERE_WANT_DISTINCT 0x0100 /* All output needs to be distinct */
18410 #define WHERE_SORTBYGROUP 0x0200 /* Support sqlite3WhereIsSorted() */
18411 #define WHERE_AGG_DISTINCT 0x0400 /* Query is "SELECT agg(DISTINCT ...)" */
18412 #define WHERE_ORDERBY_LIMIT 0x0800 /* ORDERBY+LIMIT on the inner loop */
18413 /* 0x1000 not currently used */
18414 /* 0x2000 not currently used */
18415 #define WHERE_USE_LIMIT 0x4000 /* Use the LIMIT in cost estimates */
18416 /* 0x8000 not currently used */
18417
18418 /* Allowed return values from sqlite3WhereIsDistinct()
@@ -18604,10 +18645,13 @@
18604 #define SF_PushDown 0x1000000 /* SELECT has be modified by push-down opt */
18605 #define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */
18606 #define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */
18607 #define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */
18608
 
 
 
18609 /*
18610 ** The results of a SELECT can be distributed in several ways, as defined
18611 ** by one of the following macros. The "SRT" prefix means "SELECT Result
18612 ** Type".
18613 **
@@ -18815,10 +18859,11 @@
18815 u8 mayAbort; /* True if statement may throw an ABORT exception */
18816 u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */
18817 u8 okConstFactor; /* OK to factor out constants */
18818 u8 disableLookaside; /* Number of times lookaside has been disabled */
18819 u8 disableVtab; /* Disable all virtual tables for this parse */
 
18820 #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
18821 u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */
18822 #endif
18823 int nRangeReg; /* Size of the temporary register block */
18824 int iRangeReg; /* First register in temporary register block */
@@ -18987,24 +19032,24 @@
18987 #define OPFLAG_AUXDELETE 0x04 /* OP_Delete: index in a DELETE op */
18988 #define OPFLAG_NOCHNG_MAGIC 0x6d /* OP_MakeRecord: serialtype 10 is ok */
18989 #define OPFLAG_PREFORMAT 0x80 /* OP_Insert uses preformatted cell */
18990
18991 /*
18992 * Each trigger present in the database schema is stored as an instance of
18993 * struct Trigger.
18994 *
18995 * Pointers to instances of struct Trigger are stored in two ways.
18996 * 1. In the "trigHash" hash table (part of the sqlite3* that represents the
18997 * database). This allows Trigger structures to be retrieved by name.
18998 * 2. All triggers associated with a single table form a linked list, using the
18999 * pNext member of struct Trigger. A pointer to the first element of the
19000 * linked list is stored as the "pTrigger" member of the associated
19001 * struct Table.
19002 *
19003 * The "step_list" member points to the first element of a linked list
19004 * containing the SQL statements specified as the trigger program.
19005 */
19006 struct Trigger {
19007 char *zName; /* The name of the trigger */
19008 char *table; /* The table or view to which the trigger applies */
19009 u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT */
19010 u8 tr_tm; /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
@@ -19027,47 +19072,52 @@
19027 */
19028 #define TRIGGER_BEFORE 1
19029 #define TRIGGER_AFTER 2
19030
19031 /*
19032 * An instance of struct TriggerStep is used to store a single SQL statement
19033 * that is a part of a trigger-program.
19034 *
19035 * Instances of struct TriggerStep are stored in a singly linked list (linked
19036 * using the "pNext" member) referenced by the "step_list" member of the
19037 * associated struct Trigger instance. The first element of the linked list is
19038 * the first step of the trigger-program.
19039 *
19040 * The "op" member indicates whether this is a "DELETE", "INSERT", "UPDATE" or
19041 * "SELECT" statement. The meanings of the other members is determined by the
19042 * value of "op" as follows:
19043 *
19044 * (op == TK_INSERT)
19045 * orconf -> stores the ON CONFLICT algorithm
19046 * pSelect -> If this is an INSERT INTO ... SELECT ... statement, then
19047 * this stores a pointer to the SELECT statement. Otherwise NULL.
19048 * zTarget -> Dequoted name of the table to insert into.
19049 * pExprList -> If this is an INSERT INTO ... VALUES ... statement, then
19050 * this stores values to be inserted. Otherwise NULL.
19051 * pIdList -> If this is an INSERT INTO ... (<column-names>) VALUES ...
19052 * statement, then this stores the column-names to be
19053 * inserted into.
19054 *
19055 * (op == TK_DELETE)
19056 * zTarget -> Dequoted name of the table to delete from.
19057 * pWhere -> The WHERE clause of the DELETE statement if one is specified.
19058 * Otherwise NULL.
19059 *
19060 * (op == TK_UPDATE)
19061 * zTarget -> Dequoted name of the table to update.
19062 * pWhere -> The WHERE clause of the UPDATE statement if one is specified.
19063 * Otherwise NULL.
19064 * pExprList -> A list of the columns to update and the expressions to update
19065 * them to. See sqlite3Update() documentation of "pChanges"
19066 * argument.
19067 *
19068 */
 
 
 
 
 
19069 struct TriggerStep {
19070 u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT,
19071 ** or TK_RETURNING */
19072 u8 orconf; /* OE_Rollback etc. */
19073 Trigger *pTrig; /* The trigger that this step is a part of */
@@ -19673,22 +19723,54 @@
19673 #if defined(SQLITE_TEST)
19674 SQLITE_PRIVATE void *sqlite3TestTextToPtr(const char*);
19675 #endif
19676
19677 #if defined(SQLITE_DEBUG)
 
19678 SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView*, const Expr*, u8);
19679 SQLITE_PRIVATE void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*);
19680 SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*);
 
 
19681 SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView*, const SrcList*);
19682 SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8);
19683 SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView*, const With*, u8);
 
 
 
 
 
 
 
 
 
 
 
 
 
19684 #ifndef SQLITE_OMIT_WINDOWFUNC
19685 SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView*, const Window*, u8);
19686 SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8);
19687 #endif
 
 
 
 
 
 
 
 
 
 
 
 
19688 #endif
19689
 
 
 
 
19690
19691 SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*);
19692 SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...);
19693 SQLITE_PRIVATE int sqlite3ErrorToParser(sqlite3*,int);
19694 SQLITE_PRIVATE void sqlite3Dequote(char*);
@@ -19833,17 +19915,18 @@
19833 SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*);
19834 SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(Parse*, SrcList*, int, int);
19835 SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2);
19836 SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*);
19837 SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*,
19838 Token*, Select*, Expr*, IdList*);
19839 SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *);
19840 SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*);
19841 SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, SrcItem *);
19842 SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList*);
19843 SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*);
19844 SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*);
 
19845 SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*);
19846 SQLITE_PRIVATE Index *sqlite3AllocateIndexObject(sqlite3*,i16,int,char**);
19847 SQLITE_PRIVATE void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
19848 Expr*, int, int, u8);
19849 SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
@@ -20036,11 +20119,12 @@
20036 # define sqlite3TriggerStepSrc(A,B) 0
20037 #endif
20038
20039 SQLITE_PRIVATE int sqlite3JoinType(Parse*, Token*, Token*, Token*);
20040 SQLITE_PRIVATE int sqlite3ColumnIndex(Table *pTab, const char *zCol);
20041 SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr*,int);
 
20042 SQLITE_PRIVATE void sqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int);
20043 SQLITE_PRIVATE void sqlite3DeferForeignKey(Parse*, int);
20044 #ifndef SQLITE_OMIT_AUTHORIZATION
20045 SQLITE_PRIVATE void sqlite3AuthRead(Parse*,Expr*,Schema*,SrcList*);
20046 SQLITE_PRIVATE int sqlite3AuthCheck(Parse*,int, const char*, const char*, const char*);
@@ -20382,11 +20466,11 @@
20382 SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *);
20383
20384 SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
20385 #if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \
20386 && !defined(SQLITE_OMIT_VIRTUALTABLE)
20387 SQLITE_PRIVATE void sqlite3VtabWriteAll(sqlite3_index_info*);
20388 #endif
20389 SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
20390 SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
20391 SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
20392 SQLITE_PRIVATE void sqlite3ParseObjectInit(Parse*,sqlite3*);
@@ -21130,13 +21214,10 @@
21130 "ENABLE_RBU",
21131 #endif
21132 #ifdef SQLITE_ENABLE_RTREE
21133 "ENABLE_RTREE",
21134 #endif
21135 #ifdef SQLITE_ENABLE_SELECTTRACE
21136 "ENABLE_SELECTTRACE",
21137 #endif
21138 #ifdef SQLITE_ENABLE_SESSION
21139 "ENABLE_SESSION",
21140 #endif
21141 #ifdef SQLITE_ENABLE_SNAPSHOT
21142 "ENABLE_SNAPSHOT",
@@ -21153,10 +21234,13 @@
21153 #ifdef SQLITE_ENABLE_STMTVTAB
21154 "ENABLE_STMTVTAB",
21155 #endif
21156 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
21157 "ENABLE_STMT_SCANSTATUS",
 
 
 
21158 #endif
21159 #ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
21160 "ENABLE_UNKNOWN_SQL_FUNCTION",
21161 #endif
21162 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
@@ -21960,11 +22044,11 @@
21960 #endif
21961
21962 /*
21963 ** Tracing flags set by SQLITE_TESTCTRL_TRACEFLAGS.
21964 */
21965 SQLITE_PRIVATE u32 sqlite3SelectTrace = 0;
21966 SQLITE_PRIVATE u32 sqlite3WhereTrace = 0;
21967
21968 /* #include "opcodes.h" */
21969 /*
21970 ** Properties of opcodes. The OPFLG_INITIALIZER macro is
@@ -22175,10 +22259,15 @@
22175 ** static element declared in the structure. nField total array slots for
22176 ** aType[] and nField+1 array slots for aOffset[] */
22177 u32 aType[1]; /* Type values record decode. MUST BE LAST */
22178 };
22179
 
 
 
 
 
22180
22181 /*
22182 ** A value for VdbeCursor.cacheStatus that means the cache is always invalid.
22183 */
22184 #define CACHE_STALE 0
@@ -22496,16 +22585,14 @@
22496 #endif
22497 u16 nResColumn; /* Number of columns in one row of the result set */
22498 u8 errorAction; /* Recovery action to do in case of an error */
22499 u8 minWriteFileFormat; /* Minimum file format for writable database files */
22500 u8 prepFlags; /* SQLITE_PREPARE_* flags */
22501 u8 doingRerun; /* True if rerunning after an auto-reprepare */
22502 u8 eVdbeState; /* On of the VDBE_*_STATE values */
22503 bft expired:2; /* 1: recompile VM immediately 2: when convenient */
22504 bft explain:2; /* True if EXPLAIN present on SQL command */
22505 bft changeCntOn:1; /* True to update the change-counter */
22506 bft runOnlyOnce:1; /* Automatically expire on reset */
22507 bft usesStmtJournal:1; /* True if uses a statement journal */
22508 bft readOnly:1; /* True for statements that do not write */
22509 bft bIsReader:1; /* True for statements that read */
22510 yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
22511 yDbMask lockMask; /* Subset of btreeMask that requires a lock */
@@ -22574,22 +22661,35 @@
22574 struct ValueList {
22575 BtCursor *pCsr; /* An ephemeral table holding all values */
22576 sqlite3_value *pOut; /* Register to hold each decoded output value */
22577 };
22578
 
 
 
 
 
 
 
22579 /*
22580 ** Function prototypes
22581 */
22582 SQLITE_PRIVATE void sqlite3VdbeError(Vdbe*, const char *, ...);
22583 SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
 
22584 void sqliteVdbePopStack(Vdbe*,int);
22585 SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeHandleMovedCursor(VdbeCursor *p);
22586 SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor*);
22587 SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
22588 SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
22589 SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8);
22590 SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
 
 
 
 
 
22591 SQLITE_PRIVATE void sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
22592 SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3*, AuxData**, int, int);
22593
22594 int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
22595 SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
@@ -23046,12 +23146,11 @@
23046 struct Vdbe *pVdbe; /* Used to iterate through VMs */
23047 int nByte = 0; /* Used to accumulate return value */
23048
23049 db->pnBytesFreed = &nByte;
23050 for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){
23051 sqlite3VdbeClearObject(db, pVdbe);
23052 sqlite3DbFree(db, pVdbe);
23053 }
23054 db->pnBytesFreed = 0;
23055
23056 *pHighwater = 0; /* IMP: R-64479-57858 */
23057 *pCurrent = nByte;
@@ -29389,12 +29488,13 @@
29389
29390 /*
29391 ** Free any prior content in *pz and replace it with a copy of zNew.
29392 */
29393 SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){
 
29394 sqlite3DbFree(db, *pz);
29395 *pz = sqlite3DbStrDup(db, zNew);
29396 }
29397
29398 /*
29399 ** Call this routine to record the fact that an OOM (out-of-memory) error
29400 ** has happened. This routine will set db->mallocFailed, and also
@@ -30886,37 +30986,41 @@
30886
30887 /*
30888 ** Add a new subitem to the tree. The moreToFollow flag indicates that this
30889 ** is not the last item in the tree.
30890 */
30891 static TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){
 
30892 if( p==0 ){
30893 p = sqlite3_malloc64( sizeof(*p) );
30894 if( p==0 ) return 0;
30895 memset(p, 0, sizeof(*p));
30896 }else{
30897 p->iLevel++;
30898 }
30899 assert( moreToFollow==0 || moreToFollow==1 );
30900 if( p->iLevel<(int)sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow;
30901 return p;
30902 }
30903
30904 /*
30905 ** Finished with one layer of the tree
30906 */
30907 static void sqlite3TreeViewPop(TreeView *p){
 
30908 if( p==0 ) return;
30909 p->iLevel--;
30910 if( p->iLevel<0 ) sqlite3_free(p);
 
 
 
30911 }
30912
30913 /*
30914 ** Generate a single line of output for the tree, with a prefix that contains
30915 ** all the appropriate tree lines
30916 */
30917 static void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
30918 va_list ap;
30919 int i;
30920 StrAccum acc;
30921 char zBuf[500];
30922 sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
@@ -30940,11 +31044,11 @@
30940
30941 /*
30942 ** Shorthand for starting a new tree item that consists of a single label
30943 */
30944 static void sqlite3TreeViewItem(TreeView *p, const char *zLabel,u8 moreFollows){
30945 p = sqlite3TreeViewPush(p, moreFollows);
30946 sqlite3TreeViewLine(p, "%s", zLabel);
30947 }
30948
30949 /*
30950 ** Generate a human-readable description of a WITH clause.
@@ -30957,11 +31061,11 @@
30957 sqlite3TreeViewLine(pView, "WITH (0x%p, pOuter=0x%p)",pWith,pWith->pOuter);
30958 }else{
30959 sqlite3TreeViewLine(pView, "WITH (0x%p)", pWith);
30960 }
30961 if( pWith->nCte>0 ){
30962 pView = sqlite3TreeViewPush(pView, 1);
30963 for(i=0; i<pWith->nCte; i++){
30964 StrAccum x;
30965 char zLine[1000];
30966 const struct Cte *pCte = &pWith->a[i];
30967 sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
@@ -30980,21 +31084,22 @@
30980 pCte->pUse->nUse);
30981 }
30982 sqlite3StrAccumFinish(&x);
30983 sqlite3TreeViewItem(pView, zLine, i<pWith->nCte-1);
30984 sqlite3TreeViewSelect(pView, pCte->pSelect, 0);
30985 sqlite3TreeViewPop(pView);
30986 }
30987 sqlite3TreeViewPop(pView);
30988 }
30989 }
30990
30991 /*
30992 ** Generate a human-readable description of a SrcList object.
30993 */
30994 SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){
30995 int i;
 
30996 for(i=0; i<pSrc->nSrc; i++){
30997 const SrcItem *pItem = &pSrc->a[i];
30998 StrAccum x;
30999 char zLine[100];
31000 sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
@@ -31002,14 +31107,21 @@
31002 sqlite3_str_appendf(&x, "{%d:*} %!S", pItem->iCursor, pItem);
31003 if( pItem->pTab ){
31004 sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx",
31005 pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab, pItem->colUsed);
31006 }
31007 if( pItem->fg.jointype & JT_LEFT ){
 
 
31008 sqlite3_str_appendf(&x, " LEFT-JOIN");
 
 
31009 }else if( pItem->fg.jointype & JT_CROSS ){
31010 sqlite3_str_appendf(&x, " CROSS-JOIN");
 
 
 
31011 }
31012 if( pItem->fg.fromDDL ){
31013 sqlite3_str_appendf(&x, " DDL");
31014 }
31015 if( pItem->fg.isCte ){
@@ -31016,16 +31128,17 @@
31016 sqlite3_str_appendf(&x, " CteUse=0x%p", pItem->u2.pCteUse);
31017 }
31018 sqlite3StrAccumFinish(&x);
31019 sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1);
31020 if( pItem->pSelect ){
 
31021 sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
31022 }
31023 if( pItem->fg.isTabFunc ){
31024 sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
31025 }
31026 sqlite3TreeViewPop(pView);
31027 }
31028 }
31029
31030 /*
31031 ** Generate a human-readable description of a Select object.
@@ -31035,15 +31148,15 @@
31035 int cnt = 0;
31036 if( p==0 ){
31037 sqlite3TreeViewLine(pView, "nil-SELECT");
31038 return;
31039 }
31040 pView = sqlite3TreeViewPush(pView, moreToFollow);
31041 if( p->pWith ){
31042 sqlite3TreeViewWith(pView, p->pWith, 1);
31043 cnt = 1;
31044 sqlite3TreeViewPush(pView, 1);
31045 }
31046 do{
31047 if( p->selFlags & SF_WhereBegin ){
31048 sqlite3TreeViewLine(pView, "sqlite3WhereBegin()");
31049 }else{
@@ -31053,11 +31166,11 @@
31053 ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""),
31054 p->selId, p, p->selFlags,
31055 (int)p->nSelectRow
31056 );
31057 }
31058 if( cnt++ ) sqlite3TreeViewPop(pView);
31059 if( p->pPrior ){
31060 n = 1000;
31061 }else{
31062 n = 0;
31063 if( p->pSrc && p->pSrc->nSrc ) n++;
@@ -31076,45 +31189,45 @@
31076 }
31077 n--;
31078 #ifndef SQLITE_OMIT_WINDOWFUNC
31079 if( p->pWin ){
31080 Window *pX;
31081 pView = sqlite3TreeViewPush(pView, (n--)>0);
31082 sqlite3TreeViewLine(pView, "window-functions");
31083 for(pX=p->pWin; pX; pX=pX->pNextWin){
31084 sqlite3TreeViewWinFunc(pView, pX, pX->pNextWin!=0);
31085 }
31086 sqlite3TreeViewPop(pView);
31087 }
31088 #endif
31089 if( p->pSrc && p->pSrc->nSrc ){
31090 pView = sqlite3TreeViewPush(pView, (n--)>0);
31091 sqlite3TreeViewLine(pView, "FROM");
31092 sqlite3TreeViewSrcList(pView, p->pSrc);
31093 sqlite3TreeViewPop(pView);
31094 }
31095 if( p->pWhere ){
31096 sqlite3TreeViewItem(pView, "WHERE", (n--)>0);
31097 sqlite3TreeViewExpr(pView, p->pWhere, 0);
31098 sqlite3TreeViewPop(pView);
31099 }
31100 if( p->pGroupBy ){
31101 sqlite3TreeViewExprList(pView, p->pGroupBy, (n--)>0, "GROUPBY");
31102 }
31103 if( p->pHaving ){
31104 sqlite3TreeViewItem(pView, "HAVING", (n--)>0);
31105 sqlite3TreeViewExpr(pView, p->pHaving, 0);
31106 sqlite3TreeViewPop(pView);
31107 }
31108 #ifndef SQLITE_OMIT_WINDOWFUNC
31109 if( p->pWinDefn ){
31110 Window *pX;
31111 sqlite3TreeViewItem(pView, "WINDOW", (n--)>0);
31112 for(pX=p->pWinDefn; pX; pX=pX->pNextWin){
31113 sqlite3TreeViewWindow(pView, pX, pX->pNextWin!=0);
31114 }
31115 sqlite3TreeViewPop(pView);
31116 }
31117 #endif
31118 if( p->pOrderBy ){
31119 sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY");
31120 }
@@ -31122,13 +31235,13 @@
31122 sqlite3TreeViewItem(pView, "LIMIT", (n--)>0);
31123 sqlite3TreeViewExpr(pView, p->pLimit->pLeft, p->pLimit->pRight!=0);
31124 if( p->pLimit->pRight ){
31125 sqlite3TreeViewItem(pView, "OFFSET", (n--)>0);
31126 sqlite3TreeViewExpr(pView, p->pLimit->pRight, 0);
31127 sqlite3TreeViewPop(pView);
31128 }
31129 sqlite3TreeViewPop(pView);
31130 }
31131 if( p->pPrior ){
31132 const char *zOp = "UNION";
31133 switch( p->op ){
31134 case TK_ALL: zOp = "UNION ALL"; break;
@@ -31137,11 +31250,11 @@
31137 }
31138 sqlite3TreeViewItem(pView, zOp, 1);
31139 }
31140 p = p->pPrior;
31141 }while( p!=0 );
31142 sqlite3TreeViewPop(pView);
31143 }
31144
31145 #ifndef SQLITE_OMIT_WINDOWFUNC
31146 /*
31147 ** Generate a description of starting or stopping bounds
@@ -31153,28 +31266,28 @@
31153 u8 moreToFollow /* True if more to follow */
31154 ){
31155 switch( eBound ){
31156 case TK_UNBOUNDED: {
31157 sqlite3TreeViewItem(pView, "UNBOUNDED", moreToFollow);
31158 sqlite3TreeViewPop(pView);
31159 break;
31160 }
31161 case TK_CURRENT: {
31162 sqlite3TreeViewItem(pView, "CURRENT", moreToFollow);
31163 sqlite3TreeViewPop(pView);
31164 break;
31165 }
31166 case TK_PRECEDING: {
31167 sqlite3TreeViewItem(pView, "PRECEDING", moreToFollow);
31168 sqlite3TreeViewExpr(pView, pExpr, 0);
31169 sqlite3TreeViewPop(pView);
31170 break;
31171 }
31172 case TK_FOLLOWING: {
31173 sqlite3TreeViewItem(pView, "FOLLOWING", moreToFollow);
31174 sqlite3TreeViewExpr(pView, pExpr, 0);
31175 sqlite3TreeViewPop(pView);
31176 break;
31177 }
31178 }
31179 }
31180 #endif /* SQLITE_OMIT_WINDOWFUNC */
@@ -31186,13 +31299,13 @@
31186 SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){
31187 int nElement = 0;
31188 if( pWin->pFilter ){
31189 sqlite3TreeViewItem(pView, "FILTER", 1);
31190 sqlite3TreeViewExpr(pView, pWin->pFilter, 0);
31191 sqlite3TreeViewPop(pView);
31192 }
31193 pView = sqlite3TreeViewPush(pView, more);
31194 if( pWin->zName ){
31195 sqlite3TreeViewLine(pView, "OVER %s (%p)", pWin->zName, pWin);
31196 }else{
31197 sqlite3TreeViewLine(pView, "OVER (%p)", pWin);
31198 }
@@ -31199,13 +31312,13 @@
31199 if( pWin->zBase ) nElement++;
31200 if( pWin->pOrderBy ) nElement++;
31201 if( pWin->eFrmType ) nElement++;
31202 if( pWin->eExclude ) nElement++;
31203 if( pWin->zBase ){
31204 sqlite3TreeViewPush(pView, (--nElement)>0);
31205 sqlite3TreeViewLine(pView, "window: %s", pWin->zBase);
31206 sqlite3TreeViewPop(pView);
31207 }
31208 if( pWin->pPartition ){
31209 sqlite3TreeViewExprList(pView, pWin->pPartition, nElement>0,"PARTITION-BY");
31210 }
31211 if( pWin->pOrderBy ){
@@ -31219,11 +31332,11 @@
31219 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s%s",zFrmType,
31220 pWin->bImplicitFrame ? " (implied)" : "");
31221 sqlite3TreeViewItem(pView, zBuf, (--nElement)>0);
31222 sqlite3TreeViewBound(pView, pWin->eStart, pWin->pStart, 1);
31223 sqlite3TreeViewBound(pView, pWin->eEnd, pWin->pEnd, 0);
31224 sqlite3TreeViewPop(pView);
31225 }
31226 if( pWin->eExclude ){
31227 char zBuf[30];
31228 const char *zExclude;
31229 switch( pWin->eExclude ){
@@ -31234,28 +31347,28 @@
31234 default:
31235 sqlite3_snprintf(sizeof(zBuf),zBuf,"invalid(%d)", pWin->eExclude);
31236 zExclude = zBuf;
31237 break;
31238 }
31239 sqlite3TreeViewPush(pView, 0);
31240 sqlite3TreeViewLine(pView, "EXCLUDE %s", zExclude);
31241 sqlite3TreeViewPop(pView);
31242 }
31243 sqlite3TreeViewPop(pView);
31244 }
31245 #endif /* SQLITE_OMIT_WINDOWFUNC */
31246
31247 #ifndef SQLITE_OMIT_WINDOWFUNC
31248 /*
31249 ** Generate a human-readable explanation for a Window Function object
31250 */
31251 SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){
31252 pView = sqlite3TreeViewPush(pView, more);
31253 sqlite3TreeViewLine(pView, "WINFUNC %s(%d)",
31254 pWin->pWFunc->zName, pWin->pWFunc->nArg);
31255 sqlite3TreeViewWindow(pView, pWin, 0);
31256 sqlite3TreeViewPop(pView);
31257 }
31258 #endif /* SQLITE_OMIT_WINDOWFUNC */
31259
31260 /*
31261 ** Generate a human-readable explanation of an expression tree.
@@ -31262,23 +31375,23 @@
31262 */
31263 SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
31264 const char *zBinOp = 0; /* Binary operator */
31265 const char *zUniOp = 0; /* Unary operator */
31266 char zFlgs[200];
31267 pView = sqlite3TreeViewPush(pView, moreToFollow);
31268 if( pExpr==0 ){
31269 sqlite3TreeViewLine(pView, "nil");
31270 sqlite3TreeViewPop(pView);
31271 return;
31272 }
31273 if( pExpr->flags || pExpr->affExpr || pExpr->vvaFlags ){
31274 StrAccum x;
31275 sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0);
31276 sqlite3_str_appendf(&x, " fg.af=%x.%c",
31277 pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n');
31278 if( ExprHasProperty(pExpr, EP_FromJoin) ){
31279 sqlite3_str_appendf(&x, " iRJT=%d", pExpr->w.iRightJoinTable);
31280 }
31281 if( ExprHasProperty(pExpr, EP_FromDDL) ){
31282 sqlite3_str_appendf(&x, " DDL");
31283 }
31284 if( ExprHasVVAProperty(pExpr, EP_Immutable) ){
@@ -31622,11 +31735,11 @@
31622 sqlite3TreeViewExpr(pView, pExpr->pRight, 0);
31623 }else if( zUniOp ){
31624 sqlite3TreeViewLine(pView, "%s%s", zUniOp, zFlgs);
31625 sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
31626 }
31627 sqlite3TreeViewPop(pView);
31628 }
31629
31630
31631 /*
31632 ** Generate a human-readable explanation of an expression list.
@@ -31644,27 +31757,37 @@
31644 sqlite3TreeViewLine(pView, "%s", zLabel);
31645 for(i=0; i<pList->nExpr; i++){
31646 int j = pList->a[i].u.x.iOrderByCol;
31647 char *zName = pList->a[i].zEName;
31648 int moreToFollow = i<pList->nExpr - 1;
31649 if( pList->a[i].eEName!=ENAME_NAME ) zName = 0;
31650 if( j || zName ){
31651 sqlite3TreeViewPush(pView, moreToFollow);
31652 moreToFollow = 0;
31653 sqlite3TreeViewLine(pView, 0);
31654 if( zName ){
31655 fprintf(stdout, "AS %s ", zName);
 
 
 
 
 
 
 
 
 
 
 
31656 }
31657 if( j ){
31658 fprintf(stdout, "iOrderByCol=%d", j);
31659 }
31660 fprintf(stdout, "\n");
31661 fflush(stdout);
31662 }
31663 sqlite3TreeViewExpr(pView, pList->a[i].pExpr, moreToFollow);
31664 if( j || zName ){
31665 sqlite3TreeViewPop(pView);
31666 }
31667 }
31668 }
31669 }
31670 SQLITE_PRIVATE void sqlite3TreeViewExprList(
@@ -31671,15 +31794,376 @@
31671 TreeView *pView,
31672 const ExprList *pList,
31673 u8 moreToFollow,
31674 const char *zLabel
31675 ){
31676 pView = sqlite3TreeViewPush(pView, moreToFollow);
31677 sqlite3TreeViewBareExprList(pView, pList, zLabel);
31678 sqlite3TreeViewPop(pView);
31679 }
31680
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31681 #endif /* SQLITE_DEBUG */
31682
31683 /************** End of treeview.c ********************************************/
31684 /************** Begin file random.c ******************************************/
31685 /*
@@ -34710,14 +35194,14 @@
34710 /* 66 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"),
34711 /* 67 */ "Return" OpHelp(""),
34712 /* 68 */ "EndCoroutine" OpHelp(""),
34713 /* 69 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
34714 /* 70 */ "Halt" OpHelp(""),
34715 /* 71 */ "BeginSubrtn" OpHelp("r[P2]=P1"),
34716 /* 72 */ "Integer" OpHelp("r[P2]=P1"),
34717 /* 73 */ "Int64" OpHelp("r[P2]=P4"),
34718 /* 74 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
34719 /* 75 */ "Null" OpHelp("r[P2..P3]=NULL"),
34720 /* 76 */ "SoftNull" OpHelp("r[P1]=NULL"),
34721 /* 77 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
34722 /* 78 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
34723 /* 79 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
@@ -34733,11 +35217,11 @@
34733 /* 89 */ "Permutation" OpHelp(""),
34734 /* 90 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
34735 /* 91 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"),
34736 /* 92 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"),
34737 /* 93 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"),
34738 /* 94 */ "Column" OpHelp("r[P3]=PX"),
34739 /* 95 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"),
34740 /* 96 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
34741 /* 97 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
34742 /* 98 */ "Count" OpHelp("r[P2]=count()"),
34743 /* 99 */ "ReadCookie" OpHelp(""),
@@ -34774,11 +35258,11 @@
34774 /* 130 */ "Delete" OpHelp(""),
34775 /* 131 */ "ResetCount" OpHelp(""),
34776 /* 132 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
34777 /* 133 */ "SorterData" OpHelp("r[P2]=data"),
34778 /* 134 */ "RowData" OpHelp("r[P2]=data"),
34779 /* 135 */ "Rowid" OpHelp("r[P2]=rowid"),
34780 /* 136 */ "NullRow" OpHelp(""),
34781 /* 137 */ "SeekEnd" OpHelp(""),
34782 /* 138 */ "IdxInsert" OpHelp("key=r[P2]"),
34783 /* 139 */ "SorterInsert" OpHelp("key=r[P2]"),
34784 /* 140 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
@@ -67869,10 +68353,12 @@
67869
67870 /* Remove the slot from the free-list. Update the number of
67871 ** fragmented bytes within the page. */
67872 memcpy(&aData[iAddr], &aData[pc], 2);
67873 aData[hdr+7] += (u8)x;
 
 
67874 }else if( x+pc > maxPC ){
67875 /* This slot extends off the end of the usable part of the page */
67876 *pRc = SQLITE_CORRUPT_PAGE(pPg);
67877 return 0;
67878 }else{
@@ -72179,11 +72665,11 @@
72179 idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2 */
72180 }
72181 assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) );
72182 assert( pPage->isInit );
72183 if( pPage->leaf ){
72184 assert( pCur->ix<pCur->pPage->nCell );
72185 pCur->ix = (u16)idx;
72186 *pRes = c;
72187 rc = SQLITE_OK;
72188 goto moveto_index_finish;
72189 }
@@ -74703,11 +75189,11 @@
74703 }
74704 }
74705 iOvflSpace += sz;
74706 assert( sz<=pBt->maxLocal+23 );
74707 assert( iOvflSpace <= (int)pBt->pageSize );
74708 for(k=0; b.ixNx[k]<=i && ALWAYS(k<NB*2); k++){}
74709 pSrcEnd = b.apEnd[k];
74710 if( SQLITE_WITHIN(pSrcEnd, pCell, pCell+sz) ){
74711 rc = SQLITE_CORRUPT_BKPT;
74712 goto balance_cleanup;
74713 }
@@ -75526,11 +76012,15 @@
75526 const u8 *aIn; /* Pointer to next input buffer */
75527 u32 nIn; /* Size of input buffer aIn[] */
75528 u32 nRem; /* Bytes of data still to copy */
75529
75530 getCellInfo(pSrc);
75531 aOut += putVarint32(aOut, pSrc->info.nPayload);
 
 
 
 
75532 if( pDest->pKeyInfo==0 ) aOut += putVarint(aOut, iKey);
75533 nIn = pSrc->info.nLocal;
75534 aIn = pSrc->info.pPayload;
75535 if( aIn+nIn>pSrc->pPage->aDataEnd ){
75536 return SQLITE_CORRUPT_BKPT;
@@ -78539,13 +79029,14 @@
78539 SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
78540 sqlite3_context ctx;
78541 Mem t;
78542 assert( pFunc!=0 );
78543 assert( pMem!=0 );
 
78544 assert( pFunc->xFinalize!=0 );
78545 assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef );
78546 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
78547 memset(&ctx, 0, sizeof(ctx));
78548 memset(&t, 0, sizeof(t));
78549 t.flags = MEM_Null;
78550 t.db = pMem->db;
78551 ctx.pOut = &t;
@@ -78571,11 +79062,12 @@
78571 SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem *pAccum, Mem *pOut, FuncDef *pFunc){
78572 sqlite3_context ctx;
78573 assert( pFunc!=0 );
78574 assert( pFunc->xValue!=0 );
78575 assert( (pAccum->flags & MEM_Null)!=0 || pFunc==pAccum->u.pDef );
78576 assert( pAccum->db==0 || sqlite3_mutex_held(pAccum->db->mutex) );
 
78577 memset(&ctx, 0, sizeof(ctx));
78578 sqlite3VdbeMemSetNull(pOut);
78579 ctx.pOut = pOut;
78580 ctx.pMem = pAccum;
78581 ctx.pFunc = pFunc;
@@ -80639,18 +81131,24 @@
80639
80640 /*
80641 ** Mark the VDBE as one that can only be run one time.
80642 */
80643 SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe *p){
80644 p->runOnlyOnce = 1;
80645 }
80646
80647 /*
80648 ** Mark the VDBE as one that can only be run multiple times.
80649 */
80650 SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe *p){
80651 p->runOnlyOnce = 0;
 
 
 
 
 
 
80652 }
80653
80654 #ifdef SQLITE_DEBUG /* sqlite3AssertMayAbort() logic */
80655
80656 /*
@@ -81276,11 +81774,11 @@
81276 int iFirst, /* Index of first register to be released */
81277 int N, /* Number of registers to release */
81278 u32 mask, /* Mask of registers to NOT release */
81279 int bUndefine /* If true, mark registers as undefined */
81280 ){
81281 if( N==0 ) return;
81282 assert( pParse->pVdbe );
81283 assert( iFirst>=1 );
81284 assert( iFirst+N-1<=pParse->nMem );
81285 if( N<=31 && mask!=0 ){
81286 while( N>0 && (mask&1)!=0 ){
@@ -81535,12 +82033,17 @@
81535 if( c=='P' ){
81536 c = zSynopsis[++ii];
81537 if( c=='4' ){
81538 sqlite3_str_appendall(&x, zP4);
81539 }else if( c=='X' ){
81540 sqlite3_str_appendall(&x, pOp->zComment);
 
 
 
 
81541 seenCom = 1;
 
81542 }else{
81543 int v1 = translateP(c, pOp);
81544 int v2;
81545 if( strncmp(zSynopsis+ii+1, "@P", 2)==0 ){
81546 ii += 3;
@@ -82131,11 +82634,11 @@
82131 int i;
82132 Mem *aMem = VdbeFrameMem(p);
82133 VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem];
82134 assert( sqlite3VdbeFrameIsValid(p) );
82135 for(i=0; i<p->nChildCsr; i++){
82136 sqlite3VdbeFreeCursor(p->v, apCsr[i]);
82137 }
82138 releaseMemArray(aMem, p->nChildMem);
82139 sqlite3VdbeDeleteAuxData(p->v->db, &p->pAuxData, -1, 0);
82140 sqlite3DbFree(p->v->db, p);
82141 }
@@ -82325,15 +82828,15 @@
82325 ** statement.
82326 */
82327 static void *allocSpace(
82328 struct ReusableSpace *p, /* Bulk memory available for allocation */
82329 void *pBuf, /* Pointer to a prior allocation */
82330 sqlite3_int64 nByte /* Bytes of memory needed */
82331 ){
82332 assert( EIGHT_BYTE_ALIGNMENT(p->pSpace) );
82333 if( pBuf==0 ){
82334 nByte = ROUND8(nByte);
82335 if( nByte <= p->nFree ){
82336 p->nFree -= nByte;
82337 pBuf = &p->pSpace[p->nFree];
82338 }else{
82339 p->nNeeded += nByte;
@@ -82437,11 +82940,11 @@
82437
82438 /* Figure out how much reusable memory is available at the end of the
82439 ** opcode array. This extra memory will be reallocated for other elements
82440 ** of the prepared statement.
82441 */
82442 n = ROUND8(sizeof(Op)*p->nOp); /* Bytes of opcode memory used */
82443 x.pSpace = &((u8*)p->aOp)[n]; /* Unused opcode memory */
82444 assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) );
82445 x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes of unused memory */
82446 assert( x.nFree>=0 );
82447 assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) );
@@ -82525,13 +83028,13 @@
82525 /*
82526 ** Close a VDBE cursor and release all the resources that cursor
82527 ** happens to hold.
82528 */
82529 SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
82530 if( pCx==0 ){
82531 return;
82532 }
82533 switch( pCx->eCurType ){
82534 case CURTYPE_SORTER: {
82535 sqlite3VdbeSorterClose(p->db, pCx);
82536 break;
82537 }
@@ -82559,11 +83062,11 @@
82559 static void closeCursorsInFrame(Vdbe *p){
82560 int i;
82561 for(i=0; i<p->nCursor; i++){
82562 VdbeCursor *pC = p->apCsr[i];
82563 if( pC ){
82564 sqlite3VdbeFreeCursor(p, pC);
82565 p->apCsr[i] = 0;
82566 }
82567 }
82568 }
82569
@@ -83089,13 +83592,11 @@
83089 ** Then the internal cache might have been left in an inconsistent
83090 ** state. We need to rollback the statement transaction, if there is
83091 ** one, or the complete transaction if there is no statement transaction.
83092 */
83093
83094 if( p->eVdbeState!=VDBE_RUN_STATE ){
83095 return SQLITE_OK;
83096 }
83097 if( db->mallocFailed ){
83098 p->rc = SQLITE_NOMEM_BKPT;
83099 }
83100 closeAllCursors(p);
83101 checkActiveVdbeCnt(db);
@@ -83351,11 +83852,11 @@
83351
83352 /* If the VM did not run to completion or if it encountered an
83353 ** error, then it might not have been halted properly. So halt
83354 ** it now.
83355 */
83356 sqlite3VdbeHalt(p);
83357
83358 /* If the VDBE has been run even partially, then transfer the error code
83359 ** and error message from the VDBE into the main database structure. But
83360 ** if the VDBE has just been set to run but has not actually executed any
83361 ** instructions yet, leave the main database error information unchanged.
@@ -83365,11 +83866,10 @@
83365 if( db->pErr || p->zErrMsg ){
83366 sqlite3VdbeTransferError(p);
83367 }else{
83368 db->errCode = p->rc;
83369 }
83370 if( p->runOnlyOnce ) p->expired = 1;
83371 }
83372
83373 /* Reset register contents and reclaim error message memory.
83374 */
83375 #ifdef SQLITE_DEBUG
@@ -83486,11 +83986,11 @@
83486 **
83487 ** The difference between this function and sqlite3VdbeDelete() is that
83488 ** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with
83489 ** the database connection and frees the object itself.
83490 */
83491 SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
83492 SubProgram *pSub, *pNext;
83493 assert( p->db==0 || p->db==db );
83494 if( p->aColName ){
83495 releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
83496 sqlite3DbFreeNN(db, p->aColName);
@@ -83536,18 +84036,20 @@
83536
83537 assert( p!=0 );
83538 db = p->db;
83539 assert( sqlite3_mutex_held(db->mutex) );
83540 sqlite3VdbeClearObject(db, p);
83541 if( p->pPrev ){
83542 p->pPrev->pNext = p->pNext;
83543 }else{
83544 assert( db->pVdbe==p );
83545 db->pVdbe = p->pNext;
83546 }
83547 if( p->pNext ){
83548 p->pNext->pPrev = p->pPrev;
 
 
83549 }
83550 sqlite3DbFreeNN(db, p);
83551 }
83552
83553 /*
@@ -83595,11 +84097,11 @@
83595 /*
83596 ** Check to ensure that the cursor is valid. Restore the cursor
83597 ** if need be. Return any I/O error from the restore operation.
83598 */
83599 SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){
83600 assert( p->eCurType==CURTYPE_BTREE );
83601 if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
83602 return sqlite3VdbeHandleMovedCursor(p);
83603 }
83604 return SQLITE_OK;
83605 }
@@ -83608,11 +84110,11 @@
83608 ** The following functions:
83609 **
83610 ** sqlite3VdbeSerialType()
83611 ** sqlite3VdbeSerialTypeLen()
83612 ** sqlite3VdbeSerialLen()
83613 ** sqlite3VdbeSerialPut()
83614 ** sqlite3VdbeSerialGet()
83615 **
83616 ** encapsulate the code that serializes values for storage in SQLite
83617 ** data and index records. Each serialized value consists of a
83618 ** 'serial-type' and a blob of data. The serial type is an 8-byte unsigned
@@ -83720,11 +84222,11 @@
83720 #endif /* inlined into OP_MakeRecord */
83721
83722 /*
83723 ** The sizes for serial types less than 128
83724 */
83725 static const u8 sqlite3SmallTypeSizes[] = {
83726 /* 0 1 2 3 4 5 6 7 8 9 */
83727 /* 0 */ 0, 1, 2, 3, 4, 6, 8, 8, 0, 0,
83728 /* 10 */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
83729 /* 20 */ 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
83730 /* 30 */ 9, 9, 10, 10, 11, 11, 12, 12, 13, 13,
@@ -83789,11 +84291,11 @@
83789 ** works for him. We, the developers, have no way to independently
83790 ** verify this, but Frank seems to know what he is talking about
83791 ** so we trust him.
83792 */
83793 #ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
83794 static u64 floatSwap(u64 in){
83795 union {
83796 u64 r;
83797 u32 i[2];
83798 } u;
83799 u32 t;
@@ -83802,63 +84304,12 @@
83802 t = u.i[0];
83803 u.i[0] = u.i[1];
83804 u.i[1] = t;
83805 return u.r;
83806 }
83807 # define swapMixedEndianFloat(X) X = floatSwap(X)
83808 #else
83809 # define swapMixedEndianFloat(X)
83810 #endif
83811
83812 /*
83813 ** Write the serialized data blob for the value stored in pMem into
83814 ** buf. It is assumed that the caller has allocated sufficient space.
83815 ** Return the number of bytes written.
83816 **
83817 ** nBuf is the amount of space left in buf[]. The caller is responsible
83818 ** for allocating enough space to buf[] to hold the entire field, exclusive
83819 ** of the pMem->u.nZero bytes for a MEM_Zero value.
83820 **
83821 ** Return the number of bytes actually written into buf[]. The number
83822 ** of bytes in the zero-filled tail is included in the return value only
83823 ** if those bytes were zeroed in buf[].
83824 */
83825 SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){
83826 u32 len;
83827
83828 /* Integer and Real */
83829 if( serial_type<=7 && serial_type>0 ){
83830 u64 v;
83831 u32 i;
83832 if( serial_type==7 ){
83833 assert( sizeof(v)==sizeof(pMem->u.r) );
83834 memcpy(&v, &pMem->u.r, sizeof(v));
83835 swapMixedEndianFloat(v);
83836 }else{
83837 v = pMem->u.i;
83838 }
83839 len = i = sqlite3SmallTypeSizes[serial_type];
83840 assert( i>0 );
83841 do{
83842 buf[--i] = (u8)(v&0xFF);
83843 v >>= 8;
83844 }while( i );
83845 return len;
83846 }
83847
83848 /* String or blob */
83849 if( serial_type>=12 ){
83850 assert( pMem->n + ((pMem->flags & MEM_Zero)?pMem->u.nZero:0)
83851 == (int)sqlite3VdbeSerialTypeLen(serial_type) );
83852 len = pMem->n;
83853 if( len>0 ) memcpy(buf, pMem->z, len);
83854 return len;
83855 }
83856
83857 /* NULL or constants 0 or 1 */
83858 return 0;
83859 }
83860
83861 /* Input "x" is a sequence of unsigned characters that represent a
83862 ** big-endian integer. Return the equivalent native integer
83863 */
83864 #define ONE_BYTE_INT(x) ((i8)(x)[0])
@@ -84020,14 +84471,14 @@
84020 SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(
84021 KeyInfo *pKeyInfo /* Description of the record */
84022 ){
84023 UnpackedRecord *p; /* Unpacked record to return */
84024 int nByte; /* Number of bytes required for *p */
84025 nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1);
84026 p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte);
84027 if( !p ) return 0;
84028 p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))];
84029 assert( pKeyInfo->aSortFlags!=0 );
84030 p->pKeyInfo = pKeyInfo;
84031 p->nField = pKeyInfo->nKeyField + 1;
84032 return p;
84033 }
@@ -84521,18 +84972,26 @@
84521
84522 /* If bSkip is true, then the caller has already determined that the first
84523 ** two elements in the keys are equal. Fix the various stack variables so
84524 ** that this routine begins comparing at the second field. */
84525 if( bSkip ){
84526 u32 s1;
84527 idx1 = 1 + getVarint32(&aKey1[1], s1);
 
 
 
 
84528 szHdr1 = aKey1[0];
84529 d1 = szHdr1 + sqlite3VdbeSerialTypeLen(s1);
84530 i = 1;
84531 pRhs++;
84532 }else{
84533 idx1 = getVarint32(aKey1, szHdr1);
 
 
 
 
84534 d1 = szHdr1;
84535 i = 0;
84536 }
84537 if( d1>(unsigned)nKey1 ){
84538 pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
@@ -85932,18 +86391,12 @@
85932 */
85933 static int sqlite3Step(Vdbe *p){
85934 sqlite3 *db;
85935 int rc;
85936
85937 /* Check that malloc() has not failed. If it has, return early. */
85938 db = p->db;
85939 if( db->mallocFailed ){
85940 p->rc = SQLITE_NOMEM;
85941 return SQLITE_NOMEM_BKPT;
85942 }
85943
85944 assert(p);
 
85945 if( p->eVdbeState!=VDBE_RUN_STATE ){
85946 restart_step:
85947 if( p->eVdbeState==VDBE_READY_STATE ){
85948 if( p->expired ){
85949 p->rc = SQLITE_SCHEMA;
@@ -86087,11 +86540,10 @@
86087 if( vdbeSafetyNotNull(v) ){
86088 return SQLITE_MISUSE_BKPT;
86089 }
86090 db = v->db;
86091 sqlite3_mutex_enter(db->mutex);
86092 v->doingRerun = 0;
86093 while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
86094 && cnt++ < SQLITE_MAX_SCHEMA_RETRY ){
86095 int savedPc = v->pc;
86096 rc = sqlite3Reprepare(v);
86097 if( rc!=SQLITE_OK ){
@@ -86113,11 +86565,17 @@
86113 v->rc = rc = SQLITE_NOMEM_BKPT;
86114 }
86115 break;
86116 }
86117 sqlite3_reset(pStmt);
86118 if( savedPc>=0 ) v->doingRerun = 1;
 
 
 
 
 
 
86119 assert( v->expired==0 );
86120 }
86121 sqlite3_mutex_leave(db->mutex);
86122 return rc;
86123 }
@@ -87126,12 +87584,11 @@
87126 if( op==SQLITE_STMTSTATUS_MEMUSED ){
87127 sqlite3 *db = pVdbe->db;
87128 sqlite3_mutex_enter(db->mutex);
87129 v = 0;
87130 db->pnBytesFreed = (int*)&v;
87131 sqlite3VdbeClearObject(db, pVdbe);
87132 sqlite3DbFree(db, pVdbe);
87133 db->pnBytesFreed = 0;
87134 sqlite3_mutex_leave(db->mutex);
87135 }else{
87136 v = pVdbe->aCounter[op];
87137 if( resetFlag ) pVdbe->aCounter[op] = 0;
@@ -87920,16 +88377,16 @@
87920 Mem *pMem = iCur>0 ? &p->aMem[p->nMem-iCur] : p->aMem;
87921
87922 int nByte;
87923 VdbeCursor *pCx = 0;
87924 nByte =
87925 ROUND8(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField +
87926 (eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0);
87927
87928 assert( iCur>=0 && iCur<p->nCursor );
87929 if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/
87930 sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
87931 p->apCsr[iCur] = 0;
87932 }
87933
87934 /* There used to be a call to sqlite3VdbeMemClearAndResize() to make sure
87935 ** the pMem used to hold space for the cursor has enough storage available
@@ -87955,11 +88412,11 @@
87955 pCx->eCurType = eCurType;
87956 pCx->nField = nField;
87957 pCx->aOffset = &pCx->aType[nField];
87958 if( eCurType==CURTYPE_BTREE ){
87959 pCx->uc.pCursor = (BtCursor*)
87960 &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField];
87961 sqlite3BtreeCursorZero(pCx->uc.pCursor);
87962 }
87963 return pCx;
87964 }
87965
@@ -88637,32 +89094,43 @@
88637 assert( VdbeMemDynamic(pIn1)==0 );
88638 memAboutToChange(p, pIn1);
88639 pIn1->flags = MEM_Int;
88640 pIn1->u.i = (int)(pOp-aOp);
88641 REGISTER_TRACE(pOp->p1, pIn1);
88642
88643 /* Most jump operations do a goto to this spot in order to update
88644 ** the pOp pointer. */
88645 jump_to_p2:
88646 pOp = &aOp[pOp->p2 - 1];
88647 break;
88648 }
88649
88650 /* Opcode: Return P1 * P3 * *
88651 **
88652 ** Jump to the next instruction after the address in register P1. After
88653 ** the jump, register P1 becomes undefined.
88654 **
88655 ** P3 is not used by the byte-code engine. However, the code generator
88656 ** sets P3 to address of the associated OP_BeginSubrtn opcode, if there is
88657 ** one.
 
 
 
 
 
 
 
 
88658 */
88659 case OP_Return: { /* in1 */
88660 pIn1 = &aMem[pOp->p1];
88661 assert( pIn1->flags==MEM_Int );
88662 pOp = &aOp[pIn1->u.i];
88663 pIn1->flags = MEM_Undefined;
 
 
 
88664 break;
88665 }
88666
88667 /* Opcode: InitCoroutine P1 P2 P3 * *
88668 **
@@ -88681,11 +89149,16 @@
88681 assert( pOp->p3>=0 && pOp->p3<p->nOp );
88682 pOut = &aMem[pOp->p1];
88683 assert( !VdbeMemDynamic(pOut) );
88684 pOut->u.i = pOp->p3 - 1;
88685 pOut->flags = MEM_Int;
88686 if( pOp->p2 ) goto jump_to_p2;
 
 
 
 
 
88687 break;
88688 }
88689
88690 /* Opcode: EndCoroutine P1 * * * *
88691 **
@@ -88783,15 +89256,14 @@
88783 */
88784 case OP_Halt: {
88785 VdbeFrame *pFrame;
88786 int pcx;
88787
88788 pcx = (int)(pOp - aOp);
88789 #ifdef SQLITE_DEBUG
88790 if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); }
88791 #endif
88792 if( pOp->p1==SQLITE_OK && p->pFrame ){
88793 /* Halt the sub-program. Return control to the parent frame. */
88794 pFrame = p->pFrame;
88795 p->pFrame = pFrame->pParent;
88796 p->nFrame--;
88797 sqlite3VdbeSetChanges(db, p->nChange);
@@ -88809,11 +89281,10 @@
88809 pOp = &aOp[pcx];
88810 break;
88811 }
88812 p->rc = pOp->p1;
88813 p->errorAction = (u8)pOp->p2;
88814 p->pc = pcx;
88815 assert( pOp->p5<=4 );
88816 if( p->rc ){
88817 if( pOp->p5 ){
88818 static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK",
88819 "FOREIGN KEY" };
@@ -88826,10 +89297,11 @@
88826 p->zErrMsg = sqlite3MPrintf(db, "%z: %s", p->zErrMsg, pOp->p4.z);
88827 }
88828 }else{
88829 sqlite3VdbeError(p, "%s", pOp->p4.z);
88830 }
 
88831 sqlite3_log(pOp->p1, "abort at %d in [%s]: %s", pcx, p->zSql, p->zErrMsg);
88832 }
88833 rc = sqlite3VdbeHalt(p);
88834 assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
88835 if( rc==SQLITE_BUSY ){
@@ -88840,26 +89312,15 @@
88840 rc = p->rc ? SQLITE_ERROR : SQLITE_DONE;
88841 }
88842 goto vdbe_return;
88843 }
88844
88845 /* Opcode: BeginSubrtn P1 P2 * * *
88846 ** Synopsis: r[P2]=P1
88847 **
88848 ** Mark the beginning of a subroutine by loading the integer value P1
88849 ** into register r[P2]. The P2 register is used to store the return
88850 ** address of the subroutine call.
88851 **
88852 ** This opcode is identical to OP_Integer. It has a different name
88853 ** only to make the byte code easier to read and verify.
88854 */
88855 /* Opcode: Integer P1 P2 * * *
88856 ** Synopsis: r[P2]=P1
88857 **
88858 ** The 32-bit integer value P1 is written into register P2.
88859 */
88860 case OP_BeginSubrtn:
88861 case OP_Integer: { /* out2 */
88862 pOut = out2Prerelease(p, pOp);
88863 pOut->u.i = pOp->p1;
88864 break;
88865 }
@@ -88962,10 +89423,32 @@
88962 }
88963 #endif
88964 break;
88965 }
88966
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88967 /* Opcode: Null P1 P2 P3 * *
88968 ** Synopsis: r[P2..P3]=NULL
88969 **
88970 ** Write a NULL into registers P2. If P3 greater than P2, then also write
88971 ** NULL into register P3 and every register in between P2 and P3. If P3
@@ -88974,10 +89457,11 @@
88974 **
88975 ** If the P1 value is non-zero, then also set the MEM_Cleared flag so that
88976 ** NULL values will not compare equal even if SQLITE_NULLEQ is set on
88977 ** OP_Ne or OP_Eq.
88978 */
 
88979 case OP_Null: { /* out2 */
88980 int cnt;
88981 u16 nullFlag;
88982 pOut = out2Prerelease(p, pOp);
88983 cnt = pOp->p3-pOp->p2;
@@ -89203,49 +89687,36 @@
89203 ** with an SQLITE_ROW return code and it sets up the sqlite3_stmt
89204 ** structure to provide access to the r(P1)..r(P1+P2-1) values as
89205 ** the result row.
89206 */
89207 case OP_ResultRow: {
89208 Mem *pMem;
89209 int i;
89210 assert( p->nResColumn==pOp->p2 );
89211 assert( pOp->p1>0 || CORRUPT_DB );
89212 assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 );
89213
89214 /* Invalidate all ephemeral cursor row caches */
89215 p->cacheCtr = (p->cacheCtr + 2)|1;
89216
89217 /* Make sure the results of the current row are \000 terminated
89218 ** and have an assigned type. The results are de-ephemeralized as
89219 ** a side effect.
89220 */
89221 pMem = p->pResultSet = &aMem[pOp->p1];
89222 for(i=0; i<pOp->p2; i++){
89223 assert( memIsValid(&pMem[i]) );
89224 Deephemeralize(&pMem[i]);
89225 assert( (pMem[i].flags & MEM_Ephem)==0
89226 || (pMem[i].flags & (MEM_Str|MEM_Blob))==0 );
89227 sqlite3VdbeMemNulTerminate(&pMem[i]);
89228 REGISTER_TRACE(pOp->p1+i, &pMem[i]);
89229 #ifdef SQLITE_DEBUG
89230 /* The registers in the result will not be used again when the
89231 ** prepared statement restarts. This is because sqlite3_column()
89232 ** APIs might have caused type conversions of made other changes to
89233 ** the register values. Therefore, we can go ahead and break any
89234 ** OP_SCopy dependencies. */
89235 pMem[i].pScopyFrom = 0;
 
 
 
 
 
 
 
 
89236 #endif
89237 }
89238 if( db->mallocFailed ) goto no_mem;
89239
89240 if( db->mTrace & SQLITE_TRACE_ROW ){
89241 db->trace.xV2(SQLITE_TRACE_ROW, db->pTraceArg, p, 0);
89242 }
89243
89244
89245 /* Return SQLITE_ROW
89246 */
89247 p->pc = (int)(pOp - aOp) + 1;
89248 rc = SQLITE_ROW;
89249 goto vdbe_return;
89250 }
89251
@@ -89755,27 +90226,27 @@
89755 flags3 = pIn3->flags;
89756 if( (flags1 & flags3 & MEM_Int)!=0 ){
89757 assert( (pOp->p5 & SQLITE_AFF_MASK)!=SQLITE_AFF_TEXT || CORRUPT_DB );
89758 /* Common case of comparison of two integers */
89759 if( pIn3->u.i > pIn1->u.i ){
89760 iCompare = +1;
89761 if( sqlite3aGTb[pOp->opcode] ){
89762 VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3);
89763 goto jump_to_p2;
89764 }
 
89765 }else if( pIn3->u.i < pIn1->u.i ){
89766 iCompare = -1;
89767 if( sqlite3aLTb[pOp->opcode] ){
89768 VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3);
89769 goto jump_to_p2;
89770 }
 
89771 }else{
89772 iCompare = 0;
89773 if( sqlite3aEQb[pOp->opcode] ){
89774 VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3);
89775 goto jump_to_p2;
89776 }
 
89777 }
89778 VdbeBranchTaken(0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
89779 break;
89780 }
89781 if( (flags1 | flags3)&MEM_Null ){
@@ -89798,15 +90269,15 @@
89798 }else{
89799 /* SQLITE_NULLEQ is clear and at least one operand is NULL,
89800 ** then the result is always NULL.
89801 ** The jump is taken if the SQLITE_JUMPIFNULL bit is set.
89802 */
89803 iCompare = 1; /* Operands are not equal */
89804 VdbeBranchTaken(2,3);
89805 if( pOp->p5 & SQLITE_JUMPIFNULL ){
89806 goto jump_to_p2;
89807 }
 
89808 break;
89809 }
89810 }else{
89811 /* Neither operand is NULL and we couldn't do the special high-speed
89812 ** integer comparison case. So do a general-case comparison. */
@@ -89908,13 +90379,12 @@
89908 /* Opcode: Permutation * * * P4 *
89909 **
89910 ** Set the permutation used by the OP_Compare operator in the next
89911 ** instruction. The permutation is stored in the P4 operand.
89912 **
89913 ** The permutation is only valid until the next OP_Compare that has
89914 ** the OPFLAG_PERMUTE bit set in P5. Typically the OP_Permutation should
89915 ** occur immediately prior to the OP_Compare.
89916 **
89917 ** The first integer in the P4 integer array is the length of the array
89918 ** and does not become part of the permutation.
89919 */
89920 case OP_Permutation: {
@@ -89942,10 +90412,12 @@
89942 ** only. The KeyInfo elements are used sequentially.
89943 **
89944 ** The comparison is a sort comparison, so NULLs compare equal,
89945 ** NULLs are less than numbers, numbers are less than strings,
89946 ** and strings are less than blobs.
 
 
89947 */
89948 case OP_Compare: {
89949 int n;
89950 int i;
89951 int p1;
@@ -90000,20 +90472,24 @@
90000 }
90001 if( bRev ) iCompare = -iCompare;
90002 break;
90003 }
90004 }
 
90005 break;
90006 }
90007
90008 /* Opcode: Jump P1 P2 P3 * *
90009 **
90010 ** Jump to the instruction at address P1, P2, or P3 depending on whether
90011 ** in the most recent OP_Compare instruction the P1 vector was less than
90012 ** equal to, or greater than the P2 vector, respectively.
 
 
90013 */
90014 case OP_Jump: { /* jump */
 
90015 if( iCompare<0 ){
90016 VdbeBranchTaken(0,4); pOp = &aOp[pOp->p1 - 1];
90017 }else if( iCompare==0 ){
90018 VdbeBranchTaken(1,4); pOp = &aOp[pOp->p2 - 1];
90019 }else{
@@ -90314,11 +90790,11 @@
90314 break;
90315 }
90316 #endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */
90317
90318 /* Opcode: Column P1 P2 P3 P4 P5
90319 ** Synopsis: r[P3]=PX
90320 **
90321 ** Interpret the data that cursor P1 points to as a structure built using
90322 ** the MakeRecord instruction. (See the MakeRecord opcode for additional
90323 ** information about the format of the data.) Extract the P2-th column
90324 ** from this record. If there are less that (P2+1)
@@ -90356,23 +90832,23 @@
90356 pC = p->apCsr[pOp->p1];
90357 p2 = (u32)pOp->p2;
90358
90359 op_column_restart:
90360 assert( pC!=0 );
90361 assert( p2<(u32)pC->nField );
 
90362 aOffset = pC->aOffset;
90363 assert( aOffset==pC->aType+pC->nField );
90364 assert( pC->eCurType!=CURTYPE_VTAB );
90365 assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow );
90366 assert( pC->eCurType!=CURTYPE_SORTER );
90367
90368 if( pC->cacheStatus!=p->cacheCtr ){ /*OPTIMIZATION-IF-FALSE*/
90369 if( pC->nullRow ){
90370 if( pC->eCurType==CURTYPE_PSEUDO ){
90371 /* For the special case of as pseudo-cursor, the seekResult field
90372 ** identifies the register that holds the record */
90373 assert( pC->seekResult>0 );
90374 pReg = &aMem[pC->seekResult];
90375 assert( pReg->flags & MEM_Blob );
90376 assert( memIsValid(pReg) );
90377 pC->payloadSize = pC->szRow = pReg->n;
90378 pC->aRow = (u8*)pReg->z;
@@ -90406,11 +90882,15 @@
90406 pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &pC->szRow);
90407 assert( pC->szRow<=pC->payloadSize );
90408 assert( pC->szRow<=65536 ); /* Maximum page size is 64KiB */
90409 }
90410 pC->cacheStatus = p->cacheCtr;
90411 pC->iHdrOffset = getVarint32(pC->aRow, aOffset[0]);
 
 
 
 
90412 pC->nHdrParsed = 0;
90413
90414 if( pC->szRow<aOffset[0] ){ /*OPTIMIZATION-IF-FALSE*/
90415 /* pC->aRow does not have to hold the entire row, but it does at least
90416 ** need to cover the header of the record. If pC->aRow does not contain
@@ -91041,22 +91521,64 @@
91041 UPDATE_MAX_BLOBSIZE(pOut);
91042 zHdr = (u8 *)pOut->z;
91043 zPayload = zHdr + nHdr;
91044
91045 /* Write the record */
91046 zHdr += putVarint32(zHdr, nHdr);
 
 
 
 
91047 assert( pData0<=pLast );
91048 pRec = pData0;
91049 do{
91050 serial_type = pRec->uTemp;
91051 /* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more
91052 ** additional varints, one per column. */
91053 zHdr += putVarint32(zHdr, serial_type); /* serial type */
91054 /* EVIDENCE-OF: R-64536-51728 The values for each column in the record
91055 ** immediately follow the header. */
91056 zPayload += sqlite3VdbeSerialPut(zPayload, pRec, serial_type); /* content */
91057 }while( (++pRec)<=pLast );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91058 assert( nHdr==(int)(zHdr - (u8*)pOut->z) );
91059 assert( nByte==(int)(zPayload - (u8*)pOut->z) );
91060
91061 assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
91062 REGISTER_TRACE(pOp->p3, pOut);
@@ -91271,11 +91793,14 @@
91271 if( rc!=SQLITE_OK ) goto abort_due_to_error;
91272 }
91273 }
91274 }
91275 if( rc ) goto abort_due_to_error;
91276
 
 
 
91277 break;
91278 }
91279
91280 /* Opcode: AutoCommit P1 P2 * * *
91281 **
@@ -91375,10 +91900,11 @@
91375 ** halts. The sqlite3_step() wrapper function might then reprepare the
91376 ** statement and rerun it from the beginning.
91377 */
91378 case OP_Transaction: {
91379 Btree *pBt;
 
91380 int iMeta = 0;
91381
91382 assert( p->bIsReader );
91383 assert( p->readOnly==0 || pOp->p2==0 );
91384 assert( pOp->p2>=0 && pOp->p2<=2 );
@@ -91394,11 +91920,12 @@
91394 ** transaction */
91395 rc = SQLITE_CORRUPT;
91396 }
91397 goto abort_due_to_error;
91398 }
91399 pBt = db->aDb[pOp->p1].pBt;
 
91400
91401 if( pBt ){
91402 rc = sqlite3BtreeBeginTrans(pBt, pOp->p2, &iMeta);
91403 testcase( rc==SQLITE_BUSY_SNAPSHOT );
91404 testcase( rc==SQLITE_BUSY_RECOVERY );
@@ -91435,12 +91962,11 @@
91435 }
91436 }
91437 assert( pOp->p5==0 || pOp->p4type==P4_INT32 );
91438 if( rc==SQLITE_OK
91439 && pOp->p5
91440 && (iMeta!=pOp->p3
91441 || db->aDb[pOp->p1].pSchema->iGeneration!=pOp->p4.i)
91442 ){
91443 /*
91444 ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema
91445 ** version is checked to ensure that the schema has not changed since the
91446 ** SQL statement was prepared.
@@ -92579,15 +93105,12 @@
92579 }
92580 case OP_NoConflict: /* jump, in3 */
92581 case OP_NotFound: /* jump, in3 */
92582 case OP_Found: { /* jump, in3 */
92583 int alreadyExists;
92584 int takeJump;
92585 int ii;
92586 VdbeCursor *pC;
92587 int res;
92588 UnpackedRecord *pFree;
92589 UnpackedRecord *pIdxKey;
92590 UnpackedRecord r;
92591
92592 #ifdef SQLITE_TEST
92593 if( pOp->opcode!=OP_NoConflict ) sqlite3_found_count++;
@@ -92598,66 +93121,71 @@
92598 pC = p->apCsr[pOp->p1];
92599 assert( pC!=0 );
92600 #ifdef SQLITE_DEBUG
92601 pC->seekOp = pOp->opcode;
92602 #endif
92603 pIn3 = &aMem[pOp->p3];
92604 assert( pC->eCurType==CURTYPE_BTREE );
92605 assert( pC->uc.pCursor!=0 );
92606 assert( pC->isTable==0 );
92607 if( pOp->p4.i>0 ){
 
 
92608 r.pKeyInfo = pC->pKeyInfo;
92609 r.nField = (u16)pOp->p4.i;
92610 r.aMem = pIn3;
92611 #ifdef SQLITE_DEBUG
92612 for(ii=0; ii<r.nField; ii++){
92613 assert( memIsValid(&r.aMem[ii]) );
92614 assert( (r.aMem[ii].flags & MEM_Zero)==0 || r.aMem[ii].n==0 );
92615 if( ii ) REGISTER_TRACE(pOp->p3+ii, &r.aMem[ii]);
92616 }
92617 #endif
92618 pIdxKey = &r;
92619 pFree = 0;
92620 }else{
92621 assert( pIn3->flags & MEM_Blob );
92622 rc = ExpandBlob(pIn3);
 
 
92623 assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
92624 if( rc ) goto no_mem;
92625 pFree = pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo);
92626 if( pIdxKey==0 ) goto no_mem;
92627 sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey);
92628 }
92629 pIdxKey->default_rc = 0;
92630 takeJump = 0;
92631 if( pOp->opcode==OP_NoConflict ){
92632 /* For the OP_NoConflict opcode, take the jump if any of the
92633 ** input fields are NULL, since any key with a NULL will not
92634 ** conflict */
92635 for(ii=0; ii<pIdxKey->nField; ii++){
92636 if( pIdxKey->aMem[ii].flags & MEM_Null ){
92637 takeJump = 1;
92638 break;
92639 }
92640 }
92641 }
92642 rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, pIdxKey, &res);
92643 if( pFree ) sqlite3DbFreeNN(db, pFree);
92644 if( rc!=SQLITE_OK ){
92645 goto abort_due_to_error;
92646 }
92647 pC->seekResult = res;
92648 alreadyExists = (res==0);
92649 pC->nullRow = 1-alreadyExists;
92650 pC->deferredMoveto = 0;
92651 pC->cacheStatus = CACHE_STALE;
92652 if( pOp->opcode==OP_Found ){
92653 VdbeBranchTaken(alreadyExists!=0,2);
92654 if( alreadyExists ) goto jump_to_p2;
92655 }else{
92656 VdbeBranchTaken(takeJump||alreadyExists==0,2);
92657 if( takeJump || !alreadyExists ) goto jump_to_p2;
92658 if( pOp->opcode==OP_IfNoHope ) pC->seekHit = pOp->p4.i;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92659 }
92660 break;
92661 }
92662
92663 /* Opcode: SeekRowid P1 P2 P3 * *
@@ -93344,11 +93872,11 @@
93344 REGISTER_TRACE(pOp->p2, pOut);
93345 break;
93346 }
93347
93348 /* Opcode: Rowid P1 P2 * * *
93349 ** Synopsis: r[P2]=rowid
93350 **
93351 ** Store in register P2 an integer which is the key of the table entry that
93352 ** P1 is currently point to.
93353 **
93354 ** P1 can be either an ordinary table or a virtual table. There used to
@@ -93400,20 +93928,27 @@
93400 **
93401 ** Move the cursor P1 to a null row. Any OP_Column operations
93402 ** that occur while the cursor is on the null row will always
93403 ** write a NULL.
93404 **
93405 ** Or, if P1 is a Pseudo-Cursor (a cursor opened using OP_OpenPseudo)
93406 ** just reset the cache for that cursor. This causes the row of
93407 ** content held by the pseudo-cursor to be reparsed.
93408 */
93409 case OP_NullRow: {
93410 VdbeCursor *pC;
93411
93412 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
93413 pC = p->apCsr[pOp->p1];
93414 assert( pC!=0 );
 
 
 
 
 
 
 
 
93415 pC->nullRow = 1;
93416 pC->cacheStatus = CACHE_STALE;
93417 if( pC->eCurType==CURTYPE_BTREE ){
93418 assert( pC->uc.pCursor!=0 );
93419 sqlite3BtreeClearCursor(pC->uc.pCursor);
@@ -93856,13 +94391,13 @@
93856 i64 rowid; /* Rowid that P1 current points to */
93857
93858 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
93859 pC = p->apCsr[pOp->p1];
93860 assert( pC!=0 );
93861 assert( pC->eCurType==CURTYPE_BTREE );
93862 assert( pC->uc.pCursor!=0 );
93863 assert( pC->isTable==0 );
93864 assert( pC->deferredMoveto==0 );
93865 assert( !pC->nullRow || pOp->opcode==OP_IdxRowid );
93866
93867 /* The IdxRowid and Seek opcodes are combined because of the commonality
93868 ** of sqlite3VdbeCursorRestore() and sqlite3VdbeIdxRowid(). */
@@ -95994,11 +96529,11 @@
95994 /* OP_Init is always instruction 0 */
95995 assert( pOp==p->aOp || pOp->opcode==OP_Trace );
95996
95997 #ifndef SQLITE_OMIT_TRACE
95998 if( (db->mTrace & (SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0
95999 && !p->doingRerun
96000 && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
96001 ){
96002 #ifndef SQLITE_OMIT_DEPRECATED
96003 if( db->mTrace & SQLITE_TRACE_LEGACY ){
96004 char *z = sqlite3VdbeExpandSql(p, zTrace);
@@ -96223,11 +96758,11 @@
96223 p->rc = rc;
96224 sqlite3SystemError(db, rc);
96225 testcase( sqlite3GlobalConfig.xLog!=0 );
96226 sqlite3_log(rc, "statement aborts at %d: [%s] %s",
96227 (int)(pOp - aOp), p->zSql, p->zErrMsg);
96228 sqlite3VdbeHalt(p);
96229 if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db);
96230 if( rc==SQLITE_CORRUPT && db->autoCommit==0 ){
96231 db->flags |= SQLITE_CorruptRdOnly;
96232 }
96233 rc = SQLITE_ERROR;
@@ -100815,27 +101350,10 @@
100815 }
100816 sqlite3DbFree(db, pDup);
100817 }
100818 }
100819
100820
100821 /*
100822 ** Return TRUE if the name zCol occurs anywhere in the USING clause.
100823 **
100824 ** Return FALSE if the USING clause is NULL or if it does not contain
100825 ** zCol.
100826 */
100827 static int nameInUsingClause(IdList *pUsing, const char *zCol){
100828 if( pUsing ){
100829 int k;
100830 for(k=0; k<pUsing->nId; k++){
100831 if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ) return 1;
100832 }
100833 }
100834 return 0;
100835 }
100836
100837 /*
100838 ** Subqueries stores the original database, table and column names for their
100839 ** result sets in ExprList.a[].zSpan, in the form "DATABASE.TABLE.COLUMN".
100840 ** Check to see if the zSpan given to this routine matches the zDb, zTab,
100841 ** and zCol. If any of zDb, zTab, and zCol are NULL then those fields will
@@ -100907,10 +101425,33 @@
100907 testcase( n==BMS );
100908 if( n>=BMS ) n = BMS-1;
100909 return ((Bitmask)1)<<n;
100910 }
100911 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100912
100913 /*
100914 ** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
100915 ** that name in the set of source tables in pSrcList and make the pExpr
100916 ** expression node refer back to that source column. The following changes
@@ -100953,15 +101494,17 @@
100953 SrcItem *pItem; /* Use for looping over pSrcList items */
100954 SrcItem *pMatch = 0; /* The matching pSrcList item */
100955 NameContext *pTopNC = pNC; /* First namecontext in the list */
100956 Schema *pSchema = 0; /* Schema of the expression */
100957 int eNewExprOp = TK_COLUMN; /* New value for pExpr->op on success */
100958 Table *pTab = 0; /* Table hold the row */
100959 Column *pCol; /* A column of pTab */
 
100960
100961 assert( pNC ); /* the name context cannot be NULL. */
100962 assert( zCol ); /* The Z in X.Y.Z cannot be NULL */
 
100963 assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
100964
100965 /* Initialize the node to no-match */
100966 pExpr->iTable = -1;
100967 ExprSetVVAProperty(pExpr, EP_NoReduce);
@@ -101006,30 +101549,68 @@
101006 for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
101007 u8 hCol;
101008 pTab = pItem->pTab;
101009 assert( pTab!=0 && pTab->zName!=0 );
101010 assert( pTab->nCol>0 || pParse->nErr );
101011 if( pItem->pSelect && (pItem->pSelect->selFlags & SF_NestedFrom)!=0 ){
 
 
 
 
 
 
 
101012 int hit = 0;
 
101013 pEList = pItem->pSelect->pEList;
 
 
101014 for(j=0; j<pEList->nExpr; j++){
101015 if( sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb) ){
101016 cnt++;
101017 cntTab = 2;
101018 pMatch = pItem;
101019 pExpr->iColumn = j;
101020 hit = 1;
101021 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101022 }
101023 if( hit || zTab==0 ) continue;
101024 }
101025 if( zDb ){
101026 if( pTab->pSchema!=pSchema ) continue;
101027 if( pSchema==0 && strcmp(zDb,"*")!=0 ) continue;
101028 }
101029 if( zTab ){
101030 const char *zTabName = pItem->zAlias ? pItem->zAlias : pTab->zName;
 
 
 
 
 
101031 assert( zTabName!=0 );
101032 if( sqlite3StrICmp(zTabName, zTab)!=0 ){
101033 continue;
101034 }
101035 assert( ExprUseYTab(pExpr) );
@@ -101040,22 +101621,41 @@
101040 hCol = sqlite3StrIHash(zCol);
101041 for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
101042 if( pCol->hName==hCol
101043 && sqlite3StrICmp(pCol->zCnName, zCol)==0
101044 ){
101045 /* If there has been exactly one prior match and this match
101046 ** is for the right-hand table of a NATURAL JOIN or is in a
101047 ** USING clause, then skip this match.
101048 */
101049 if( cnt==1 ){
101050 if( pItem->fg.jointype & JT_NATURAL ) continue;
101051 if( nameInUsingClause(pItem->pUsing, zCol) ) continue;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101052 }
101053 cnt++;
101054 pMatch = pItem;
101055 /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
101056 pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j;
 
 
 
101057 break;
101058 }
101059 }
101060 if( 0==cnt && VisibleRowid(pTab) ){
101061 cntTab++;
@@ -101064,13 +101664,11 @@
101064 }
101065 if( pMatch ){
101066 pExpr->iTable = pMatch->iCursor;
101067 assert( ExprUseYTab(pExpr) );
101068 pExpr->y.pTab = pMatch->pTab;
101069 /* RIGHT JOIN not (yet) supported */
101070 assert( (pMatch->fg.jointype & JT_RIGHT)==0 );
101071 if( (pMatch->fg.jointype & JT_LEFT)!=0 ){
101072 ExprSetProperty(pExpr, EP_CanBeNull);
101073 }
101074 pSchema = pExpr->y.pTab->pSchema;
101075 }
101076 } /* if( pSrcList ) */
@@ -101307,15 +101905,41 @@
101307 return WRC_Prune;
101308 }
101309 }
101310
101311 /*
101312 ** cnt==0 means there was not match. cnt>1 means there were two or
101313 ** more matches. Either way, we have an error.
 
 
 
101314 */
 
 
101315 if( cnt!=1 ){
101316 const char *zErr;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101317 zErr = cnt==0 ? "no such column" : "ambiguous column name";
101318 if( zDb ){
101319 sqlite3ErrorMsg(pParse, "%s: %s.%s.%s", zErr, zDb, zTab, zCol);
101320 }else if( zTab ){
101321 sqlite3ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol);
@@ -101324,10 +101948,20 @@
101324 }
101325 sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
101326 pParse->checkSchema = 1;
101327 pTopNC->nNcErr++;
101328 }
 
 
 
 
 
 
 
 
 
 
101329
101330 /* If a column from a table in pSrcList is referenced, then record
101331 ** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes
101332 ** bit 0 to be set. Column 1 sets bit 1. And so forth. Bit 63 is
101333 ** set if the 63rd or any subsequent column is used.
@@ -101343,20 +101977,11 @@
101343 */
101344 if( pExpr->iColumn>=0 && pMatch!=0 ){
101345 pMatch->colUsed |= sqlite3ExprColUsed(pExpr);
101346 }
101347
101348 /* Clean up and return
101349 */
101350 if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){
101351 sqlite3ExprDelete(db, pExpr->pLeft);
101352 pExpr->pLeft = 0;
101353 sqlite3ExprDelete(db, pExpr->pRight);
101354 pExpr->pRight = 0;
101355 }
101356 pExpr->op = eNewExprOp;
101357 ExprSetProperty(pExpr, EP_Leaf);
101358 lookupname_end:
101359 if( cnt==1 ){
101360 assert( pNC!=0 );
101361 #ifndef SQLITE_OMIT_AUTHORIZATION
101362 if( pParse->db->xAuth
@@ -104008,10 +104633,22 @@
104008 }
104009 SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
104010 if( p ) sqlite3ExprDeleteNN(db, p);
104011 }
104012
 
 
 
 
 
 
 
 
 
 
 
 
104013
104014 /*
104015 ** Arrange to cause pExpr to be deleted when the pParse is deleted.
104016 ** This is similar to sqlite3ExprDelete() except that the delete is
104017 ** deferred untilthe pParse is deleted.
@@ -104378,10 +105015,11 @@
104378 pItem->zEName = sqlite3DbStrDup(db, pOldItem->zEName);
104379 pItem->sortFlags = pOldItem->sortFlags;
104380 pItem->eEName = pOldItem->eEName;
104381 pItem->done = 0;
104382 pItem->bNulls = pOldItem->bNulls;
 
104383 pItem->bSorterRef = pOldItem->bSorterRef;
104384 pItem->u = pOldItem->u;
104385 }
104386 return pNew;
104387 }
@@ -104430,37 +105068,35 @@
104430 pTab = pNewItem->pTab = pOldItem->pTab;
104431 if( pTab ){
104432 pTab->nTabRef++;
104433 }
104434 pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags);
104435 pNewItem->pOn = sqlite3ExprDup(db, pOldItem->pOn, flags);
104436 pNewItem->pUsing = sqlite3IdListDup(db, pOldItem->pUsing);
 
 
 
 
104437 pNewItem->colUsed = pOldItem->colUsed;
104438 }
104439 return pNew;
104440 }
104441 SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, const IdList *p){
104442 IdList *pNew;
104443 int i;
104444 assert( db!=0 );
104445 if( p==0 ) return 0;
104446 pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) );
 
104447 if( pNew==0 ) return 0;
104448 pNew->nId = p->nId;
104449 pNew->a = sqlite3DbMallocRawNN(db, p->nId*sizeof(p->a[0]) );
104450 if( pNew->a==0 ){
104451 sqlite3DbFreeNN(db, pNew);
104452 return 0;
104453 }
104454 /* Note that because the size of the allocation for p->a[] is not
104455 ** necessarily a power of two, sqlite3IdListAppend() may not be called
104456 ** on the duplicate created by this function. */
104457 for(i=0; i<p->nId; i++){
104458 struct IdList_item *pNewItem = &pNew->a[i];
104459 struct IdList_item *pOldItem = &p->a[i];
104460 pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
104461 pNewItem->idx = pOldItem->idx;
104462 }
104463 return pNew;
104464 }
104465 SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *pDup, int flags){
104466 Select *pRet = 0;
@@ -104922,11 +105558,11 @@
104922 ** malformed schema error.
104923 */
104924 static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
104925
104926 /* If pWalker->eCode is 2 then any term of the expression that comes from
104927 ** the ON or USING clauses of a left join disqualifies the expression
104928 ** from being considered constant. */
104929 if( pWalker->eCode==2 && ExprHasProperty(pExpr, EP_FromJoin) ){
104930 pWalker->eCode = 0;
104931 return WRC_Abort;
104932 }
@@ -105924,13 +106560,13 @@
105924 sqlite3VdbeJumpHere(v, addrOnce);
105925 /* Subroutine return */
105926 assert( ExprUseYSub(pExpr) );
105927 assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn
105928 || pParse->nErr );
105929 sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, 0,
105930 pExpr->y.sub.iAddr-1);
105931 sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
105932 sqlite3ClearTempRegCache(pParse);
105933 }
105934 }
105935 #endif /* SQLITE_OMIT_SUBQUERY */
105936
@@ -106055,13 +106691,13 @@
106055
106056 /* Subroutine return */
106057 assert( ExprUseYSub(pExpr) );
106058 assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn
106059 || pParse->nErr );
106060 sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, 0,
106061 pExpr->y.sub.iAddr-1);
106062 sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
106063 sqlite3ClearTempRegCache(pParse);
106064 return rReg;
106065 }
106066 #endif /* SQLITE_OMIT_SUBQUERY */
106067
@@ -106491,10 +107127,11 @@
106491 sqlite3VdbeAddOp3(v, OP_Column, iTabCur, iCol, regOut);
106492 return;
106493 }
106494 if( iCol<0 || iCol==pTab->iPKey ){
106495 sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut);
 
106496 }else{
106497 int op;
106498 int x;
106499 if( IsVirtual(pTab) ){
106500 op = OP_VColumn;
@@ -107243,20 +107880,22 @@
107243 }
107244 break;
107245 }
107246 case TK_SELECT_COLUMN: {
107247 int n;
107248 if( pExpr->pLeft->iTable==0 ){
107249 pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft);
 
 
107250 }
107251 assert( pExpr->pLeft->op==TK_SELECT || pExpr->pLeft->op==TK_ERROR );
107252 n = sqlite3ExprVectorSize(pExpr->pLeft);
107253 if( pExpr->iTable!=n ){
107254 sqlite3ErrorMsg(pParse, "%d columns assigned %d values",
107255 pExpr->iTable, n);
107256 }
107257 return pExpr->pLeft->iTable + pExpr->iColumn;
107258 }
107259 case TK_IN: {
107260 int destIfFalse = sqlite3VdbeMakeLabel(pParse);
107261 int destIfNull = sqlite3VdbeMakeLabel(pParse);
107262 sqlite3VdbeAddOp2(v, OP_Null, 0, target);
@@ -108560,11 +109199,11 @@
108560 **
108561 ** False positives are not allowed, however. A false positive may result
108562 ** in an incorrect answer.
108563 **
108564 ** Terms of p that are marked with EP_FromJoin (and hence that come from
108565 ** the ON or USING clauses of LEFT JOINS) are excluded from the analysis.
108566 **
108567 ** This routine is used to check if a LEFT JOIN can be converted into
108568 ** an ordinary JOIN. The p argument is the WHERE clause. If the WHERE
108569 ** clause requires that some column of the right table of the LEFT JOIN
108570 ** be non-NULL, then the LEFT JOIN can be safely converted into an
@@ -109974,15 +110613,14 @@
109974 */
109975 static void unmapColumnIdlistNames(
109976 Parse *pParse,
109977 const IdList *pIdList
109978 ){
109979 if( pIdList ){
109980 int ii;
109981 for(ii=0; ii<pIdList->nId; ii++){
109982 sqlite3RenameTokenRemap(pParse, 0, (const void*)pIdList->a[ii].zName);
109983 }
109984 }
109985 }
109986
109987 /*
109988 ** Walker callback used by sqlite3RenameExprUnmap().
@@ -110006,12 +110644,15 @@
110006 }
110007 if( ALWAYS(p->pSrc) ){ /* Every Select as a SrcList, even if it is empty */
110008 SrcList *pSrc = p->pSrc;
110009 for(i=0; i<pSrc->nSrc; i++){
110010 sqlite3RenameTokenRemap(pParse, 0, (void*)pSrc->a[i].zName);
110011 sqlite3WalkExpr(pWalker, pSrc->a[i].pOn);
110012 unmapColumnIdlistNames(pParse, pSrc->a[i].pUsing);
 
 
 
110013 }
110014 }
110015
110016 renameWalkWith(pWalker, p);
110017 return WRC_Continue;
@@ -113792,11 +114433,15 @@
113792 }
113793 pItem->pSchema = pFix->pSchema;
113794 pItem->fg.fromDDL = 1;
113795 }
113796 #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
113797 if( sqlite3WalkExpr(&pFix->w, pList->a[i].pOn) ) return WRC_Abort;
 
 
 
 
113798 #endif
113799 }
113800 if( pSelect->pWith ){
113801 for(i=0; i<pSelect->pWith->nCte; i++){
113802 if( sqlite3WalkSelect(p, pSelect->pWith->a[i].pSelect) ){
@@ -118856,22 +119501,21 @@
118856 sqlite3 *db = pParse->db;
118857 int i;
118858 if( pList==0 ){
118859 pList = sqlite3DbMallocZero(db, sizeof(IdList) );
118860 if( pList==0 ) return 0;
118861 }
118862 pList->a = sqlite3ArrayAllocate(
118863 db,
118864 pList->a,
118865 sizeof(pList->a[0]),
118866 &pList->nId,
118867 &i
118868 );
118869 if( i<0 ){
118870 sqlite3IdListDelete(db, pList);
118871 return 0;
118872 }
118873 pList->a[i].zName = sqlite3NameFromToken(db, pToken);
118874 if( IN_RENAME_OBJECT && pList->a[i].zName ){
118875 sqlite3RenameTokenMap(pParse, (void*)pList->a[i].zName, pToken);
118876 }
118877 return pList;
@@ -118881,24 +119525,24 @@
118881 ** Delete an IdList.
118882 */
118883 SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3 *db, IdList *pList){
118884 int i;
118885 if( pList==0 ) return;
 
118886 for(i=0; i<pList->nId; i++){
118887 sqlite3DbFree(db, pList->a[i].zName);
118888 }
118889 sqlite3DbFree(db, pList->a);
118890 sqlite3DbFreeNN(db, pList);
118891 }
118892
118893 /*
118894 ** Return the index in pList of the identifier named zId. Return -1
118895 ** if not found.
118896 */
118897 SQLITE_PRIVATE int sqlite3IdListIndex(IdList *pList, const char *zName){
118898 int i;
118899 if( pList==0 ) return -1;
118900 for(i=0; i<pList->nId; i++){
118901 if( sqlite3StrICmp(pList->a[i].zName, zName)==0 ) return i;
118902 }
118903 return -1;
118904 }
@@ -119097,12 +119741,15 @@
119097 if( pItem->zAlias ) sqlite3DbFreeNN(db, pItem->zAlias);
119098 if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy);
119099 if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg);
119100 sqlite3DeleteTable(db, pItem->pTab);
119101 if( pItem->pSelect ) sqlite3SelectDelete(db, pItem->pSelect);
119102 if( pItem->pOn ) sqlite3ExprDelete(db, pItem->pOn);
119103 if( pItem->pUsing ) sqlite3IdListDelete(db, pItem->pUsing);
 
 
 
119104 }
119105 sqlite3DbFreeNN(db, pList);
119106 }
119107
119108 /*
@@ -119126,18 +119773,17 @@
119126 SrcList *p, /* The left part of the FROM clause already seen */
119127 Token *pTable, /* Name of the table to add to the FROM clause */
119128 Token *pDatabase, /* Name of the database containing pTable */
119129 Token *pAlias, /* The right-hand side of the AS subexpression */
119130 Select *pSubquery, /* A subquery used in place of a table name */
119131 Expr *pOn, /* The ON clause of a join */
119132 IdList *pUsing /* The USING clause of a join */
119133 ){
119134 SrcItem *pItem;
119135 sqlite3 *db = pParse->db;
119136 if( !p && (pOn || pUsing) ){
119137 sqlite3ErrorMsg(pParse, "a JOIN clause is required before %s",
119138 (pOn ? "ON" : "USING")
119139 );
119140 goto append_from_error;
119141 }
119142 p = sqlite3SrcListAppend(pParse, p, pTable, pDatabase);
119143 if( p==0 ){
@@ -119153,19 +119799,31 @@
119153 }
119154 assert( pAlias!=0 );
119155 if( pAlias->n ){
119156 pItem->zAlias = sqlite3NameFromToken(db, pAlias);
119157 }
119158 pItem->pSelect = pSubquery;
119159 pItem->pOn = pOn;
119160 pItem->pUsing = pUsing;
 
 
 
 
 
 
 
 
 
 
 
 
 
119161 return p;
119162
119163 append_from_error:
119164 assert( p==0 );
119165 sqlite3ExprDelete(db, pOn);
119166 sqlite3IdListDelete(db, pUsing);
119167 sqlite3SelectDelete(db, pSubquery);
119168 return 0;
119169 }
119170
119171 /*
@@ -119206,10 +119864,11 @@
119206 sqlite3SrcListDelete(pParse->db, p2);
119207 }else{
119208 p1 = pNew;
119209 memcpy(&p1->a[1], p2->a, p2->nSrc*sizeof(SrcItem));
119210 sqlite3DbFree(pParse->db, p2);
 
119211 }
119212 }
119213 return p1;
119214 }
119215
@@ -119242,18 +119901,38 @@
119242 ** A natural cross join B
119243 **
119244 ** The operator is "natural cross join". The A and B operands are stored
119245 ** in p->a[0] and p->a[1], respectively. The parser initially stores the
119246 ** operator with A. This routine shifts that operator over to B.
 
 
 
 
 
 
 
119247 */
119248 SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList *p){
119249 if( p ){
119250 int i;
119251 for(i=p->nSrc-1; i>0; i--){
119252 p->a[i].fg.jointype = p->a[i-1].fg.jointype;
119253 }
 
 
119254 p->a[0].fg.jointype = 0;
 
 
 
 
 
 
 
 
 
 
 
119255 }
119256 }
119257
119258 /*
119259 ** Generate VDBE code for a BEGIN statement.
@@ -120498,12 +121177,12 @@
120498 pFrom = sqlite3SrcListAppend(pParse, 0, 0, 0);
120499 if( pFrom ){
120500 assert( pFrom->nSrc==1 );
120501 pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName);
120502 pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName);
120503 assert( pFrom->a[0].pOn==0 );
120504 assert( pFrom->a[0].pUsing==0 );
120505 }
120506 pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, pOrderBy,
120507 SF_IncludeHidden, pLimit);
120508 sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
120509 sqlite3Select(pParse, pSel, &dest);
@@ -120670,11 +121349,10 @@
120670 goto delete_from_cleanup;
120671 }
120672 assert( db->mallocFailed==0 );
120673 assert( pTabList->nSrc==1 );
120674
120675
120676 /* Locate the table which we want to delete. This table has to be
120677 ** put in an SrcList structure because some of the subroutines we
120678 ** will be calling are designed to work with multiple tables and expect
120679 ** an SrcList* parameter instead of just a Table* parameter.
120680 */
@@ -120694,10 +121372,18 @@
120694 bComplex = pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0);
120695 #ifdef SQLITE_OMIT_VIEW
120696 # undef isView
120697 # define isView 0
120698 #endif
 
 
 
 
 
 
 
 
120699
120700 #ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
120701 if( !isView ){
120702 pWhere = sqlite3LimitWhere(
120703 pParse, pTabList, pWhere, pOrderBy, pLimit, "DELETE"
@@ -124132,11 +124818,10 @@
124132 sqlite3VdbeJumpHere(v, iMustBeInt);
124133 sqlite3ReleaseTempReg(pParse, regTemp);
124134 }else{
124135 int nCol = pFKey->nCol;
124136 int regTemp = sqlite3GetTempRange(pParse, nCol);
124137 int regRec = sqlite3GetTempReg(pParse);
124138
124139 sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb);
124140 sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
124141 for(i=0; i<nCol; i++){
124142 sqlite3VdbeAddOp2(v, OP_Copy,
@@ -124172,15 +124857,14 @@
124172 sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
124173 }
124174 sqlite3VdbeGoto(v, iOk);
124175 }
124176
124177 sqlite3VdbeAddOp4(v, OP_MakeRecord, regTemp, nCol, regRec,
124178 sqlite3IndexAffinityStr(pParse->db,pIdx), nCol);
124179 sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0); VdbeCoverage(v);
124180
124181 sqlite3ReleaseTempReg(pParse, regRec);
124182 sqlite3ReleaseTempRange(pParse, regTemp, nCol);
124183 }
124184 }
124185
124186 if( !pFKey->isDeferred && !(pParse->db->flags & SQLITE_DeferFKs)
@@ -124278,18 +124962,14 @@
124278 ** For each child row found, one of the following actions is taken:
124279 **
124280 ** Operation | FK type | Action taken
124281 ** --------------------------------------------------------------------------
124282 ** DELETE immediate Increment the "immediate constraint counter".
124283 ** Or, if the ON (UPDATE|DELETE) action is RESTRICT,
124284 ** throw a "FOREIGN KEY constraint failed" exception.
124285 **
124286 ** INSERT immediate Decrement the "immediate constraint counter".
124287 **
124288 ** DELETE deferred Increment the "deferred constraint counter".
124289 ** Or, if the ON (UPDATE|DELETE) action is RESTRICT,
124290 ** throw a "FOREIGN KEY constraint failed" exception.
124291 **
124292 ** INSERT deferred Decrement the "deferred constraint counter".
124293 **
124294 ** These operations are identified in the comment at the top of this file
124295 ** (fkey.c) as "I.2" and "D.2".
@@ -124933,13 +125613,13 @@
124933 ** passed a pointer to the list of columns being modified. If it is a
124934 ** DELETE, pChanges is passed a NULL pointer.
124935 **
124936 ** It returns a pointer to a Trigger structure containing a trigger
124937 ** equivalent to the ON UPDATE or ON DELETE action specified by pFKey.
124938 ** If the action is "NO ACTION" or "RESTRICT", then a NULL pointer is
124939 ** returned (these actions require no special handling by the triggers
124940 ** sub-system, code for them is created by fkScanChildren()).
124941 **
124942 ** For example, if pFKey is the foreign key and pTab is table "p" in
124943 ** the following schema:
124944 **
124945 ** CREATE TABLE p(pk PRIMARY KEY);
@@ -125064,22 +125744,27 @@
125064
125065 zFrom = pFKey->pFrom->zName;
125066 nFrom = sqlite3Strlen30(zFrom);
125067
125068 if( action==OE_Restrict ){
 
125069 Token tFrom;
 
125070 Expr *pRaise;
125071
125072 tFrom.z = zFrom;
125073 tFrom.n = nFrom;
 
 
 
125074 pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed");
125075 if( pRaise ){
125076 pRaise->affExpr = OE_Abort;
125077 }
125078 pSelect = sqlite3SelectNew(pParse,
125079 sqlite3ExprListAppend(pParse, 0, pRaise),
125080 sqlite3SrcListAppend(pParse, 0, &tFrom, 0),
125081 pWhere,
125082 0, 0, 0, 0, 0
125083 );
125084 pWhere = 0;
125085 }
@@ -125984,10 +126669,18 @@
125984 #ifdef SQLITE_OMIT_VIEW
125985 # undef isView
125986 # define isView 0
125987 #endif
125988 assert( (pTrigger && tmask) || (pTrigger==0 && tmask==0) );
 
 
 
 
 
 
 
 
125989
125990 /* If pTab is really a view, make sure it has been initialized.
125991 ** ViewGetColumnNames() is a no-op if pTab is not a view.
125992 */
125993 if( sqlite3ViewGetColumnNames(pParse, pTab) ){
@@ -126063,17 +126756,19 @@
126063 ** columns into storage order. False negatives are harmless,
126064 ** but false positives will cause database corruption.
126065 */
126066 bIdListInOrder = (pTab->tabFlags & (TF_OOOHidden|TF_HasStored))==0;
126067 if( pColumn ){
 
 
126068 for(i=0; i<pColumn->nId; i++){
126069 pColumn->a[i].idx = -1;
126070 }
126071 for(i=0; i<pColumn->nId; i++){
126072 for(j=0; j<pTab->nCol; j++){
126073 if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zCnName)==0 ){
126074 pColumn->a[i].idx = j;
126075 if( i!=j ) bIdListInOrder = 0;
126076 if( j==pTab->iPKey ){
126077 ipkColumn = i; assert( !withoutRowid );
126078 }
126079 #ifndef SQLITE_OMIT_GENERATED_COLUMNS
@@ -126371,11 +127066,12 @@
126371 iRegStore);
126372 continue;
126373 }
126374 }
126375 if( pColumn ){
126376 for(j=0; j<pColumn->nId && pColumn->a[j].idx!=i; j++){}
 
126377 if( j>=pColumn->nId ){
126378 /* A column not named in the insert column list gets its
126379 ** default value */
126380 sqlite3ExprCodeFactorable(pParse,
126381 sqlite3ColumnExpr(pTab, &pTab->aCol[i]),
@@ -132244,19 +132940,17 @@
132244 int i; /* Loop counter: Foreign key number for pTab */
132245 int j; /* Loop counter: Field of the foreign key */
132246 HashElem *k; /* Loop counter: Next table in schema */
132247 int x; /* result variable */
132248 int regResult; /* 3 registers to hold a result row */
132249 int regKey; /* Register to hold key for checking the FK */
132250 int regRow; /* Registers to hold a row from pTab */
132251 int addrTop; /* Top of a loop checking foreign keys */
132252 int addrOk; /* Jump here if the key is OK */
132253 int *aiCols; /* child to parent column mapping */
132254
132255 regResult = pParse->nMem+1;
132256 pParse->nMem += 4;
132257 regKey = ++pParse->nMem;
132258 regRow = ++pParse->nMem;
132259 k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash);
132260 while( k ){
132261 if( zRight ){
132262 pTab = sqlite3LocateTable(pParse, 0, zRight, zDb);
@@ -132319,13 +133013,13 @@
132319 }
132320
132321 /* Generate code to query the parent index for a matching parent
132322 ** key. If a match is found, jump to addrOk. */
132323 if( pIdx ){
132324 sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey,
132325 sqlite3IndexAffinityStr(db,pIdx), pFK->nCol);
132326 sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0);
132327 VdbeCoverage(v);
132328 }else if( pParent ){
132329 int jmp = sqlite3VdbeCurrentAddr(v)+2;
132330 sqlite3VdbeAddOp3(v, OP_SeekRowid, i, jmp, regRow); VdbeCoverage(v);
132331 sqlite3VdbeGoto(v, addrOk);
@@ -134732,10 +135426,56 @@
134732 **
134733 ** A full outer join is the combination of JT_LEFT and JT_RIGHT.
134734 **
134735 ** If an illegal or unsupported join type is seen, then still return
134736 ** a join type, but put an error in the pParse structure.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134737 */
134738 SQLITE_PRIVATE int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){
134739 int jointype = 0;
134740 Token *apAll[3];
134741 Token *p;
@@ -134744,17 +135484,17 @@
134744 static const struct {
134745 u8 i; /* Beginning of keyword text in zKeyText[] */
134746 u8 nChar; /* Length of the keyword in characters */
134747 u8 code; /* Join type mask */
134748 } aKeyword[] = {
134749 /* natural */ { 0, 7, JT_NATURAL },
134750 /* left */ { 6, 4, JT_LEFT|JT_OUTER },
134751 /* outer */ { 10, 5, JT_OUTER },
134752 /* right */ { 14, 5, JT_RIGHT|JT_OUTER },
134753 /* full */ { 19, 4, JT_LEFT|JT_RIGHT|JT_OUTER },
134754 /* inner */ { 23, 5, JT_INNER },
134755 /* cross */ { 28, 5, JT_INNER|JT_CROSS },
134756 };
134757 int i, j;
134758 apAll[0] = pA;
134759 apAll[1] = pB;
134760 apAll[2] = pC;
@@ -134773,22 +135513,19 @@
134773 break;
134774 }
134775 }
134776 if(
134777 (jointype & (JT_INNER|JT_OUTER))==(JT_INNER|JT_OUTER) ||
134778 (jointype & JT_ERROR)!=0
 
134779 ){
134780 const char *zSp = " ";
134781 assert( pB!=0 );
134782 if( pC==0 ){ zSp++; }
134783 sqlite3ErrorMsg(pParse, "unknown or unsupported join type: "
134784 "%T %T%s%T", pA, pB, zSp, pC);
134785 jointype = JT_INNER;
134786 }else if( (jointype & JT_OUTER)!=0
134787 && (jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ){
134788 sqlite3ErrorMsg(pParse,
134789 "RIGHT and FULL OUTER JOINs are not currently supported");
134790 jointype = JT_INNER;
134791 }
134792 return jointype;
134793 }
134794
@@ -134805,106 +135542,81 @@
134805 }
134806 return -1;
134807 }
134808
134809 /*
134810 ** Search the first N tables in pSrc, from left to right, looking for a
134811 ** table that has a column named zCol.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134812 **
134813 ** When found, set *piTab and *piCol to the table index and column index
134814 ** of the matching column and return TRUE.
134815 **
134816 ** If not found, return FALSE.
134817 */
134818 static int tableAndColumnIndex(
134819 SrcList *pSrc, /* Array of tables to search */
134820 int N, /* Number of tables in pSrc->a[] to search */
 
134821 const char *zCol, /* Name of the column we are looking for */
134822 int *piTab, /* Write index of pSrc->a[] here */
134823 int *piCol, /* Write index of pSrc->a[*piTab].pTab->aCol[] here */
134824 int bIgnoreHidden /* True to ignore hidden columns */
134825 ){
134826 int i; /* For looping over tables in pSrc */
134827 int iCol; /* Index of column matching zCol */
134828
 
 
134829 assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */
134830 for(i=0; i<N; i++){
 
134831 iCol = sqlite3ColumnIndex(pSrc->a[i].pTab, zCol);
134832 if( iCol>=0
134833 && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pTab->aCol[iCol])==0)
134834 ){
134835 if( piTab ){
 
134836 *piTab = i;
134837 *piCol = iCol;
134838 }
134839 return 1;
134840 }
134841 }
134842 return 0;
134843 }
134844
134845 /*
134846 ** This function is used to add terms implied by JOIN syntax to the
134847 ** WHERE clause expression of a SELECT statement. The new term, which
134848 ** is ANDed with the existing WHERE clause, is of the form:
134849 **
134850 ** (tab1.col1 = tab2.col2)
134851 **
134852 ** where tab1 is the iSrc'th table in SrcList pSrc and tab2 is the
134853 ** (iSrc+1)'th. Column col1 is column iColLeft of tab1, and col2 is
134854 ** column iColRight of tab2.
134855 */
134856 static void addWhereTerm(
134857 Parse *pParse, /* Parsing context */
134858 SrcList *pSrc, /* List of tables in FROM clause */
134859 int iLeft, /* Index of first table to join in pSrc */
134860 int iColLeft, /* Index of column in first table */
134861 int iRight, /* Index of second table in pSrc */
134862 int iColRight, /* Index of column in second table */
134863 int isOuterJoin, /* True if this is an OUTER join */
134864 Expr **ppWhere /* IN/OUT: The WHERE clause to add to */
134865 ){
134866 sqlite3 *db = pParse->db;
134867 Expr *pE1;
134868 Expr *pE2;
134869 Expr *pEq;
134870
134871 assert( iLeft<iRight );
134872 assert( pSrc->nSrc>iRight );
134873 assert( pSrc->a[iLeft].pTab );
134874 assert( pSrc->a[iRight].pTab );
134875
134876 pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iColLeft);
134877 pE2 = sqlite3CreateColumnExpr(db, pSrc, iRight, iColRight);
134878
134879 pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2);
134880 assert( pE2!=0 || pEq==0 ); /* Due to db->mallocFailed test
134881 ** in sqlite3DbMallocRawNN() called from
134882 ** sqlite3PExpr(). */
134883 if( pEq && isOuterJoin ){
134884 ExprSetProperty(pEq, EP_FromJoin);
134885 assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) );
134886 ExprSetVVAProperty(pEq, EP_NoReduce);
134887 pEq->w.iRightJoinTable = pE2->iTable;
134888 }
134889 *ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq);
134890 }
134891
134892 /*
134893 ** Set the EP_FromJoin property on all terms of the given expression.
134894 ** And set the Expr.w.iRightJoinTable to iTable for every term in the
134895 ** expression.
134896 **
134897 ** The EP_FromJoin property is used on terms of an expression to tell
134898 ** the LEFT OUTER JOIN processing logic that this term is part of the
134899 ** join restriction specified in the ON or USING clause and not a part
134900 ** of the more general WHERE clause. These terms are moved over to the
134901 ** WHERE clause during join processing but we need to remember that they
134902 ** originated in the ON or USING clause.
134903 **
134904 ** The Expr.w.iRightJoinTable tells the WHERE clause processing that the
134905 ** expression depends on table w.iRightJoinTable even if that table is not
134906 ** explicitly mentioned in the expression. That information is needed
134907 ** for cases like this:
134908 **
134909 ** SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.b AND t1.x=5
134910 **
@@ -134913,41 +135625,43 @@
134913 ** NULL t2 row will be inserted whenever t1.x!=5. If we do not
134914 ** defer the handling of t1.x=5, it will be processed immediately
134915 ** after the t1 loop and rows with t1.x!=5 will never appear in
134916 ** the output, which is incorrect.
134917 */
134918 SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr *p, int iTable){
 
134919 while( p ){
134920 ExprSetProperty(p, EP_FromJoin);
134921 assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
134922 ExprSetVVAProperty(p, EP_NoReduce);
134923 p->w.iRightJoinTable = iTable;
134924 if( p->op==TK_FUNCTION ){
134925 assert( ExprUseXList(p) );
134926 if( p->x.pList ){
134927 int i;
134928 for(i=0; i<p->x.pList->nExpr; i++){
134929 sqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable);
134930 }
134931 }
134932 }
134933 sqlite3SetJoinExpr(p->pLeft, iTable);
134934 p = p->pRight;
134935 }
134936 }
134937
134938 /* Undo the work of sqlite3SetJoinExpr(). In the expression p, convert every
134939 ** term that is marked with EP_FromJoin and w.iRightJoinTable==iTable into
134940 ** an ordinary term that omits the EP_FromJoin mark.
134941 **
134942 ** This happens when a LEFT JOIN is simplified into an ordinary JOIN.
134943 */
134944 static void unsetJoinExpr(Expr *p, int iTable){
134945 while( p ){
134946 if( ExprHasProperty(p, EP_FromJoin)
134947 && (iTable<0 || p->w.iRightJoinTable==iTable) ){
134948 ExprClearProperty(p, EP_FromJoin);
 
134949 }
134950 if( p->op==TK_COLUMN && p->iTable==iTable ){
134951 ExprClearProperty(p, EP_CanBeNull);
134952 }
134953 if( p->op==TK_FUNCTION ){
@@ -134964,23 +135678,30 @@
134964 }
134965 }
134966
134967 /*
134968 ** This routine processes the join information for a SELECT statement.
134969 ** ON and USING clauses are converted into extra terms of the WHERE clause.
134970 ** NATURAL joins also create extra WHERE clause terms.
 
 
 
 
 
 
 
134971 **
134972 ** The terms of a FROM clause are contained in the Select.pSrc structure.
134973 ** The left most table is the first entry in Select.pSrc. The right-most
134974 ** table is the last entry. The join operator is held in the entry to
134975 ** the left. Thus entry 0 contains the join operator for the join between
134976 ** entries 0 and 1. Any ON or USING clauses associated with the join are
134977 ** also attached to the left entry.
134978 **
134979 ** This routine returns the number of errors encountered.
134980 */
134981 static int sqliteProcessJoin(Parse *pParse, Select *p){
134982 SrcList *pSrc; /* All tables in the FROM clause */
134983 int i, j; /* Loop counters */
134984 SrcItem *pLeft; /* Left table being joined */
134985 SrcItem *pRight; /* Right table being joined */
134986
@@ -134987,83 +135708,135 @@
134987 pSrc = p->pSrc;
134988 pLeft = &pSrc->a[0];
134989 pRight = &pLeft[1];
134990 for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){
134991 Table *pRightTab = pRight->pTab;
134992 int isOuter;
134993
134994 if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue;
134995 isOuter = (pRight->fg.jointype & JT_OUTER)!=0;
134996
134997 /* When the NATURAL keyword is present, add WHERE clause terms for
134998 ** every column that the two tables have in common.
134999 */
135000 if( pRight->fg.jointype & JT_NATURAL ){
135001 if( pRight->pOn || pRight->pUsing ){
 
135002 sqlite3ErrorMsg(pParse, "a NATURAL join may not have "
135003 "an ON or USING clause", 0);
135004 return 1;
135005 }
135006 for(j=0; j<pRightTab->nCol; j++){
135007 char *zName; /* Name of column in the right table */
135008 int iLeft; /* Matching left table */
135009 int iLeftCol; /* Matching column in the left table */
135010
135011 if( IsHiddenColumn(&pRightTab->aCol[j]) ) continue;
135012 zName = pRightTab->aCol[j].zCnName;
135013 if( tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, 1) ){
135014 addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, j,
135015 isOuter, &p->pWhere);
135016 }
135017 }
135018 }
135019
135020 /* Disallow both ON and USING clauses in the same join
135021 */
135022 if( pRight->pOn && pRight->pUsing ){
135023 sqlite3ErrorMsg(pParse, "cannot have both ON and USING "
135024 "clauses in the same join");
135025 return 1;
135026 }
135027
135028 /* Add the ON clause to the end of the WHERE clause, connected by
135029 ** an AND operator.
135030 */
135031 if( pRight->pOn ){
135032 if( isOuter ) sqlite3SetJoinExpr(pRight->pOn, pRight->iCursor);
135033 p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->pOn);
135034 pRight->pOn = 0;
135035 }
135036
135037 /* Create extra terms on the WHERE clause for each column named
135038 ** in the USING clause. Example: If the two tables to be joined are
135039 ** A and B and the USING clause names X, Y, and Z, then add this
135040 ** to the WHERE clause: A.X=B.X AND A.Y=B.Y AND A.Z=B.Z
135041 ** Report an error if any column mentioned in the USING clause is
135042 ** not contained in both tables to be joined.
135043 */
135044 if( pRight->pUsing ){
135045 IdList *pList = pRight->pUsing;
 
 
135046 for(j=0; j<pList->nId; j++){
135047 char *zName; /* Name of the term in the USING clause */
135048 int iLeft; /* Table on the left with matching column name */
135049 int iLeftCol; /* Column number of matching column on the left */
135050 int iRightCol; /* Column number of matching column on the right */
 
 
 
135051
135052 zName = pList->a[j].zName;
135053 iRightCol = sqlite3ColumnIndex(pRightTab, zName);
135054 if( iRightCol<0
135055 || !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, 0)
 
135056 ){
135057 sqlite3ErrorMsg(pParse, "cannot join using column %s - column "
135058 "not present in both tables", zName);
135059 return 1;
135060 }
135061 addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, iRightCol,
135062 isOuter, &p->pWhere);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135063 }
135064 }
 
 
 
 
 
 
 
 
 
135065 }
135066 return 0;
135067 }
135068
135069 /*
@@ -136628,16 +137401,17 @@
136628 assert( nCol==(i16)nCol );
136629 *pnCol = nCol;
136630 *paCol = aCol;
136631
136632 for(i=0, pCol=aCol; i<nCol && !db->mallocFailed; i++, pCol++){
 
136633 /* Get an appropriate name for the column
136634 */
136635 if( (zName = pEList->a[i].zEName)!=0 && pEList->a[i].eEName==ENAME_NAME ){
136636 /* If the column contains an "AS <name>" phrase, use <name> as the name */
136637 }else{
136638 Expr *pColExpr = sqlite3ExprSkipCollateAndLikely(pEList->a[i].pExpr);
136639 while( ALWAYS(pColExpr!=0) && pColExpr->op==TK_DOT ){
136640 pColExpr = pColExpr->pRight;
136641 assert( pColExpr!=0 );
136642 }
136643 if( pColExpr->op==TK_COLUMN
@@ -136651,11 +137425,11 @@
136651 }else if( pColExpr->op==TK_ID ){
136652 assert( !ExprHasProperty(pColExpr, EP_IntValue) );
136653 zName = pColExpr->u.zToken;
136654 }else{
136655 /* Use the original text of the column expression as its name */
136656 zName = pEList->a[i].zEName;
136657 }
136658 }
136659 if( zName && !sqlite3IsTrueOrFalse(zName) ){
136660 zName = sqlite3DbStrDup(db, zName);
136661 }else{
@@ -138144,16 +138918,44 @@
138144 /* An instance of the SubstContext object describes an substitution edit
138145 ** to be performed on a parse tree.
138146 **
138147 ** All references to columns in table iTable are to be replaced by corresponding
138148 ** expressions in pEList.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138149 */
138150 typedef struct SubstContext {
138151 Parse *pParse; /* The parsing context */
138152 int iTable; /* Replace references to this table */
138153 int iNewTable; /* New table number */
138154 int isLeftJoin; /* Add TK_IF_NULL_ROW opcodes on each replacement */
138155 ExprList *pEList; /* Replacement expressions */
138156 } SubstContext;
138157
138158 /* Forward Declarations */
138159 static void substExprList(SubstContext*, ExprList*);
@@ -138176,13 +138978,13 @@
138176 SubstContext *pSubst, /* Description of the substitution */
138177 Expr *pExpr /* Expr in which substitution occurs */
138178 ){
138179 if( pExpr==0 ) return 0;
138180 if( ExprHasProperty(pExpr, EP_FromJoin)
138181 && pExpr->w.iRightJoinTable==pSubst->iTable
138182 ){
138183 pExpr->w.iRightJoinTable = pSubst->iNewTable;
138184 }
138185 if( pExpr->op==TK_COLUMN
138186 && pExpr->iTable==pSubst->iTable
138187 && !ExprHasProperty(pExpr, EP_FixedCol)
138188 ){
@@ -138199,11 +139001,11 @@
138199 assert( pExpr->pRight==0 );
138200 if( sqlite3ExprIsVector(pCopy) ){
138201 sqlite3VectorErrorMsg(pSubst->pParse, pCopy);
138202 }else{
138203 sqlite3 *db = pSubst->pParse->db;
138204 if( pSubst->isLeftJoin && pCopy->op!=TK_COLUMN ){
138205 memset(&ifNullRow, 0, sizeof(ifNullRow));
138206 ifNullRow.op = TK_IF_NULL_ROW;
138207 ifNullRow.pLeft = pCopy;
138208 ifNullRow.iTable = pSubst->iNewTable;
138209 ifNullRow.flags = EP_IfNullRow;
@@ -138213,15 +139015,16 @@
138213 pNew = sqlite3ExprDup(db, pCopy, 0);
138214 if( db->mallocFailed ){
138215 sqlite3ExprDelete(db, pNew);
138216 return pExpr;
138217 }
138218 if( pSubst->isLeftJoin ){
138219 ExprSetProperty(pNew, EP_CanBeNull);
138220 }
138221 if( ExprHasProperty(pExpr,EP_FromJoin) ){
138222 sqlite3SetJoinExpr(pNew, pExpr->w.iRightJoinTable);
 
138223 }
138224 sqlite3ExprDelete(db, pExpr);
138225 pExpr = pNew;
138226
138227 /* Ensure that the expression now has an implicit collation sequence,
@@ -138382,11 +139185,11 @@
138382 int op = pExpr->op;
138383 if( op==TK_COLUMN || op==TK_IF_NULL_ROW ){
138384 renumberCursorDoMapping(pWalker, &pExpr->iTable);
138385 }
138386 if( ExprHasProperty(pExpr, EP_FromJoin) ){
138387 renumberCursorDoMapping(pWalker, &pExpr->w.iRightJoinTable);
138388 }
138389 return WRC_Continue;
138390 }
138391
138392 /*
@@ -138467,10 +139270,11 @@
138467 ** (3a) the subquery may not be a join and
138468 ** (3b) the FROM clause of the subquery may not contain a virtual
138469 ** table and
138470 ** (3c) the outer query may not be an aggregate.
138471 ** (3d) the outer query may not be DISTINCT.
 
138472 **
138473 ** (4) The subquery can not be DISTINCT.
138474 **
138475 ** (**) At one point restrictions (4) and (5) defined a subset of DISTINCT
138476 ** sub-queries that were excluded from this optimization. Restriction
@@ -138565,10 +139369,16 @@
138565 **
138566 ** (25) If either the subquery or the parent query contains a window
138567 ** function in the select list or ORDER BY clause, flattening
138568 ** is not attempted.
138569 **
 
 
 
 
 
 
138570 **
138571 ** In this routine, the "p" parameter is a pointer to the outer query.
138572 ** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query
138573 ** uses aggregates.
138574 **
@@ -138590,11 +139400,11 @@
138590 Select *pSub1; /* Pointer to the rightmost select in sub-query */
138591 SrcList *pSrc; /* The FROM clause of the outer query */
138592 SrcList *pSubSrc; /* The FROM clause of the subquery */
138593 int iParent; /* VDBE cursor number of the pSub result set temp table */
138594 int iNewParent = -1;/* Replacement table for iParent */
138595 int isLeftJoin = 0; /* True if pSub is the right side of a LEFT JOIN */
138596 int i; /* Loop counter */
138597 Expr *pWhere; /* The WHERE clause */
138598 SrcItem *pSubitem; /* The subquery */
138599 sqlite3 *db = pParse->db;
138600 Walker w; /* Walker to persist agginfo data */
@@ -138663,29 +139473,35 @@
138663 ** aggregates are processed - there is no mechanism to determine if
138664 ** the LEFT JOIN table should be all-NULL.
138665 **
138666 ** See also tickets #306, #350, and #3300.
138667 */
138668 if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){
138669 isLeftJoin = 1;
138670 if( pSubSrc->nSrc>1 /* (3a) */
138671 || isAgg /* (3b) */
138672 || IsVirtual(pSubSrc->a[0].pTab) /* (3c) */
138673 || (p->selFlags & SF_Distinct)!=0 /* (3d) */
138674 ){
138675 return 0;
138676 }
 
138677 }
138678 #ifdef SQLITE_EXTRA_IFNULLROW
138679 else if( iFrom>0 && !isAgg ){
138680 /* Setting isLeftJoin to -1 causes OP_IfNullRow opcodes to be generated for
138681 ** every reference to any result column from subquery in a join, even
138682 ** though they are not necessary. This will stress-test the OP_IfNullRow
138683 ** opcode. */
138684 isLeftJoin = -1;
138685 }
138686 #endif
 
 
 
 
 
138687
138688 /* Restriction (17): If the sub-query is a compound SELECT, then it must
138689 ** use only the UNION ALL operator. And none of the simple select queries
138690 ** that make up the compound SELECT are allowed to be aggregate or distinct
138691 ** queries.
@@ -138692,11 +139508,11 @@
138692 */
138693 if( pSub->pPrior ){
138694 if( pSub->pOrderBy ){
138695 return 0; /* Restriction (20) */
138696 }
138697 if( isAgg || (p->selFlags & SF_Distinct)!=0 || isLeftJoin>0 ){
138698 return 0; /* (17d1), (17d2), or (17f) */
138699 }
138700 for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){
138701 testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
138702 testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
@@ -138750,11 +139566,11 @@
138750 sqlite3DbFree(db, pSubitem->zAlias);
138751 pSubitem->zDatabase = 0;
138752 pSubitem->zName = 0;
138753 pSubitem->zAlias = 0;
138754 pSubitem->pSelect = 0;
138755 assert( pSubitem->pOn==0 );
138756
138757 /* If the sub-query is a compound SELECT statement, then (by restrictions
138758 ** 17 and 18 above) it must be a UNION ALL and the parent query must
138759 ** be of the form:
138760 **
@@ -138860,10 +139676,11 @@
138860 */
138861 pSub = pSub1;
138862 for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){
138863 int nSubSrc;
138864 u8 jointype = 0;
 
138865 assert( pSub!=0 );
138866 pSubSrc = pSub->pSrc; /* FROM clause of subquery */
138867 nSubSrc = pSubSrc->nSrc; /* Number of terms in subquery FROM clause */
138868 pSrc = pParent->pSrc; /* FROM clause of the outer query */
138869
@@ -138894,17 +139711,20 @@
138894
138895 /* Transfer the FROM clause terms from the subquery into the
138896 ** outer query.
138897 */
138898 for(i=0; i<nSubSrc; i++){
138899 sqlite3IdListDelete(db, pSrc->a[i+iFrom].pUsing);
138900 assert( pSrc->a[i+iFrom].fg.isTabFunc==0 );
138901 pSrc->a[i+iFrom] = pSubSrc->a[i];
 
 
138902 iNewParent = pSubSrc->a[i].iCursor;
138903 memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
138904 }
138905 pSrc->a[iFrom].fg.jointype = jointype;
 
138906
138907 /* Now begin substituting subquery result set expressions for
138908 ** references to the iParent in the outer query.
138909 **
138910 ** Example:
@@ -138935,12 +139755,12 @@
138935 pParent->pOrderBy = pOrderBy;
138936 pSub->pOrderBy = 0;
138937 }
138938 pWhere = pSub->pWhere;
138939 pSub->pWhere = 0;
138940 if( isLeftJoin>0 ){
138941 sqlite3SetJoinExpr(pWhere, iNewParent);
138942 }
138943 if( pWhere ){
138944 if( pParent->pWhere ){
138945 pParent->pWhere = sqlite3PExpr(pParse, TK_AND, pWhere, pParent->pWhere);
138946 }else{
@@ -138950,11 +139770,11 @@
138950 if( db->mallocFailed==0 ){
138951 SubstContext x;
138952 x.pParse = pParse;
138953 x.iTable = iParent;
138954 x.iNewTable = iNewParent;
138955 x.isLeftJoin = isLeftJoin;
138956 x.pEList = pSub->pEList;
138957 substSelect(&x, pParent, 0);
138958 }
138959
138960 /* The flattened query is a compound if either the inner or the
@@ -138985,12 +139805,12 @@
138985 */
138986 sqlite3AggInfoPersistWalkerInit(&w, pParse);
138987 sqlite3WalkSelect(&w,pSub1);
138988 sqlite3SelectDelete(db, pSub1);
138989
138990 #if SELECTTRACE_ENABLED
138991 if( sqlite3SelectTrace & 0x100 ){
138992 SELECTTRACE(0x100,pParse,p,("After flattening:\n"));
138993 sqlite3TreeViewSelect(0, p, 0);
138994 }
138995 #endif
138996
@@ -139392,16 +140212,16 @@
139392 iCursor, isLeftJoin);
139393 pWhere = pWhere->pLeft;
139394 }
139395 if( isLeftJoin
139396 && (ExprHasProperty(pWhere,EP_FromJoin)==0
139397 || pWhere->w.iRightJoinTable!=iCursor)
139398 ){
139399 return 0; /* restriction (4) */
139400 }
139401 if( ExprHasProperty(pWhere,EP_FromJoin)
139402 && pWhere->w.iRightJoinTable!=iCursor
139403 ){
139404 return 0; /* restriction (5) */
139405 }
139406 if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){
139407 nChng++;
@@ -139411,11 +140231,11 @@
139411 pNew = sqlite3ExprDup(pParse->db, pWhere, 0);
139412 unsetJoinExpr(pNew, -1);
139413 x.pParse = pParse;
139414 x.iTable = iCursor;
139415 x.iNewTable = iCursor;
139416 x.isLeftJoin = 0;
139417 x.pEList = pSubq->pEList;
139418 pNew = substExpr(&x, pNew);
139419 #ifndef SQLITE_OMIT_WINDOWFUNC
139420 if( pSubq->pWin && 0==pushDownWindowCheck(pParse, pSubq, pNew) ){
139421 /* Restriction 6c has prevented push-down in this case */
@@ -139620,11 +140440,11 @@
139620 pParse = pWalker->pParse;
139621 db = pParse->db;
139622 pNew = sqlite3DbMallocZero(db, sizeof(*pNew) );
139623 if( pNew==0 ) return WRC_Abort;
139624 memset(&dummy, 0, sizeof(dummy));
139625 pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0,0);
139626 if( pNewSrc==0 ) return WRC_Abort;
139627 *pNew = *p;
139628 p->pSrc = pNewSrc;
139629 p->pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ASTERISK, 0));
139630 p->op = TK_SELECT;
@@ -139965,14 +140785,38 @@
139965 /* The usual case - do not allow ROWID on a subquery */
139966 pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid;
139967 #else
139968 pTab->tabFlags |= TF_Ephemeral; /* Legacy compatibility mode */
139969 #endif
139970
139971
139972 return pParse->nErr ? SQLITE_ERROR : SQLITE_OK;
139973 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139974
139975 /*
139976 ** This routine is a Walker callback for "expanding" a SELECT statement.
139977 ** "Expanding" means to do the following:
139978 **
@@ -140119,11 +140963,11 @@
140119 }
140120
140121 /* Process NATURAL keywords, and ON and USING clauses of joins.
140122 */
140123 assert( db->mallocFailed==0 || pParse->nErr!=0 );
140124 if( pParse->nErr || sqliteProcessJoin(pParse, p) ){
140125 return WRC_Abort;
140126 }
140127
140128 /* For every "*" that occurs in the column list, insert the names of
140129 ** all columns in all tables. And for every TABLE.* insert the names
@@ -140183,31 +141027,34 @@
140183 assert( !ExprHasProperty(pE->pLeft, EP_IntValue) );
140184 zTName = pE->pLeft->u.zToken;
140185 }
140186 for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
140187 Table *pTab = pFrom->pTab;
140188 Select *pSub = pFrom->pSelect;
140189 char *zTabName = pFrom->zAlias;
140190 const char *zSchemaName = 0;
140191 int iDb;
140192 if( zTabName==0 ){
140193 zTabName = pTab->zName;
140194 }
140195 if( db->mallocFailed ) break;
140196 if( pSub==0 || (pSub->selFlags & SF_NestedFrom)==0 ){
 
 
 
 
 
140197 pSub = 0;
140198 if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
140199 continue;
140200 }
140201 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
140202 zSchemaName = iDb>=0 ? db->aDb[iDb].zDbSName : "*";
140203 }
140204 for(j=0; j<pTab->nCol; j++){
140205 char *zName = pTab->aCol[j].zCnName;
140206 char *zColname; /* The computed column name */
140207 char *zToFree; /* Malloced string that needs to be freed */
140208 Token sColname; /* Computed column name as a token */
140209
140210 assert( zName );
140211 if( zTName && pSub
140212 && sqlite3MatchEName(&pSub->pEList->a[j], 0, zTName, 0)==0
140213 ){
@@ -140224,58 +141071,62 @@
140224 continue;
140225 }
140226 tableSeen = 1;
140227
140228 if( i>0 && zTName==0 ){
140229 if( (pFrom->fg.jointype & JT_NATURAL)!=0
140230 && tableAndColumnIndex(pTabList, i, zName, 0, 0, 1)
140231 ){
140232 /* In a NATURAL join, omit the join columns from the
140233 ** table to the right of the join */
140234 continue;
140235 }
140236 if( sqlite3IdListIndex(pFrom->pUsing, zName)>=0 ){
140237 /* In a join with a USING clause, omit columns in the
140238 ** using clause from the table on the right. */
140239 continue;
140240 }
140241 }
140242 pRight = sqlite3Expr(db, TK_ID, zName);
140243 zColname = zName;
140244 zToFree = 0;
140245 if( longNames || pTabList->nSrc>1 ){
 
 
 
 
140246 Expr *pLeft;
140247 pLeft = sqlite3Expr(db, TK_ID, zTabName);
140248 pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
 
 
 
140249 if( zSchemaName ){
140250 pLeft = sqlite3Expr(db, TK_ID, zSchemaName);
140251 pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pExpr);
140252 }
140253 if( longNames ){
140254 zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName);
140255 zToFree = zColname;
140256 }
140257 }else{
140258 pExpr = pRight;
140259 }
140260 pNew = sqlite3ExprListAppend(pParse, pNew, pExpr);
140261 sqlite3TokenInit(&sColname, zColname);
140262 sqlite3ExprListSetName(pParse, pNew, &sColname, 0);
140263 if( pNew && (p->selFlags & SF_NestedFrom)!=0 && !IN_RENAME_OBJECT ){
140264 struct ExprList_item *pX = &pNew->a[pNew->nExpr-1];
140265 sqlite3DbFree(db, pX->zEName);
 
140266 if( pSub ){
140267 pX->zEName = sqlite3DbStrDup(db, pSub->pEList->a[j].zEName);
140268 testcase( pX->zEName==0 );
140269 }else{
140270 pX->zEName = sqlite3MPrintf(db, "%s.%s.%s",
140271 zSchemaName, zTabName, zColname);
140272 testcase( pX->zEName==0 );
140273 }
140274 pX->eEName = ENAME_TAB;
 
 
 
 
 
 
140275 }
140276 sqlite3DbFree(db, zToFree);
140277 }
140278 }
140279 if( !tableSeen ){
140280 if( zTName ){
140281 sqlite3ErrorMsg(pParse, "no such table: %s", zTName);
@@ -140295,10 +141146,16 @@
140295 }
140296 if( (elistFlags & (EP_HasFunc|EP_Subquery))!=0 ){
140297 p->selFlags |= SF_ComplexResult;
140298 }
140299 }
 
 
 
 
 
 
140300 return WRC_Continue;
140301 }
140302
140303 #if SQLITE_DEBUG
140304 /*
@@ -140685,12 +141542,12 @@
140685 memset(&sWalker, 0, sizeof(sWalker));
140686 sWalker.pParse = pParse;
140687 sWalker.xExprCallback = havingToWhereExprCb;
140688 sWalker.u.pSelect = p;
140689 sqlite3WalkExpr(&sWalker, p->pHaving);
140690 #if SELECTTRACE_ENABLED
140691 if( sWalker.eCode && (sqlite3SelectTrace & 0x100)!=0 ){
140692 SELECTTRACE(0x100,pParse,p,("Move HAVING terms into WHERE:\n"));
140693 sqlite3TreeViewSelect(0, p, 0);
140694 }
140695 #endif
140696 }
@@ -140818,12 +141675,12 @@
140818 pSub = pPrior;
140819 }
140820 p->pEList->a[0].pExpr = pExpr;
140821 p->selFlags &= ~SF_Aggregate;
140822
140823 #if SELECTTRACE_ENABLED
140824 if( sqlite3SelectTrace & 0x400 ){
140825 SELECTTRACE(0x400,pParse,p,("After count-of-view optimization:\n"));
140826 sqlite3TreeViewSelect(0, p, 0);
140827 }
140828 #endif
140829 return 1;
@@ -140872,14 +141729,18 @@
140872 if( p==0 || pParse->nErr ){
140873 return 1;
140874 }
140875 assert( db->mallocFailed==0 );
140876 if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
140877 #if SELECTTRACE_ENABLED
140878 SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain));
140879 if( sqlite3SelectTrace & 0x100 ){
140880 sqlite3TreeViewSelect(0, p, 0);
 
 
 
 
140881 }
140882 #endif
140883
140884 assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo );
140885 assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo );
@@ -140889,13 +141750,13 @@
140889 assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union ||
140890 pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard ||
140891 pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_DistFifo );
140892 /* All of these destinations are also able to ignore the ORDER BY clause */
140893 if( p->pOrderBy ){
140894 #if SELECTTRACE_ENABLED
140895 SELECTTRACE(1,pParse,p, ("dropping superfluous ORDER BY:\n"));
140896 if( sqlite3SelectTrace & 0x100 ){
140897 sqlite3TreeViewExprList(0, p->pOrderBy, 0, "ORDERBY");
140898 }
140899 #endif
140900 sqlite3ParserAddCleanup(pParse,
140901 (void(*)(sqlite3*,void*))sqlite3ExprListDelete,
@@ -140910,12 +141771,12 @@
140910 if( pParse->nErr ){
140911 goto select_end;
140912 }
140913 assert( db->mallocFailed==0 );
140914 assert( p->pEList!=0 );
140915 #if SELECTTRACE_ENABLED
140916 if( sqlite3SelectTrace & 0x104 ){
140917 SELECTTRACE(0x104,pParse,p, ("after name resolution:\n"));
140918 sqlite3TreeViewSelect(0, p, 0);
140919 }
140920 #endif
140921
@@ -140955,12 +141816,12 @@
140955 #ifndef SQLITE_OMIT_WINDOWFUNC
140956 if( sqlite3WindowRewrite(pParse, p) ){
140957 assert( pParse->nErr );
140958 goto select_end;
140959 }
140960 #if SELECTTRACE_ENABLED
140961 if( p->pWin && (sqlite3SelectTrace & 0x108)!=0 ){
140962 SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n"));
140963 sqlite3TreeViewSelect(0, p, 0);
140964 }
140965 #endif
140966 #endif /* SQLITE_OMIT_WINDOWFUNC */
@@ -140984,11 +141845,11 @@
140984 assert( pTab!=0 );
140985
140986 /* Convert LEFT JOIN into JOIN if there are terms of the right table
140987 ** of the LEFT JOIN used in the WHERE clause.
140988 */
140989 if( (pItem->fg.jointype & JT_LEFT)!=0
140990 && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor)
140991 && OptimizationEnabled(db, SQLITE_SimplifyJoin)
140992 ){
140993 SELECTTRACE(0x100,pParse,p,
140994 ("LEFT-JOIN simplifies to JOIN on term %d\n",i));
@@ -141070,11 +141931,11 @@
141070 */
141071 if( pSub->pOrderBy!=0
141072 && i==0
141073 && (p->selFlags & SF_ComplexResult)!=0
141074 && (pTabList->nSrc==1
141075 || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0)
141076 ){
141077 continue;
141078 }
141079
141080 if( flattenSubquery(pParse, p, i, isAgg) ){
@@ -141094,13 +141955,13 @@
141094 /* Handle compound SELECT statements using the separate multiSelect()
141095 ** procedure.
141096 */
141097 if( p->pPrior ){
141098 rc = multiSelect(pParse, p, pDest);
141099 #if SELECTTRACE_ENABLED
141100 SELECTTRACE(0x1,pParse,p,("end compound-select processing\n"));
141101 if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
141102 sqlite3TreeViewSelect(0, p, 0);
141103 }
141104 #endif
141105 if( p->pNext==0 ) ExplainQueryPlanPop(pParse);
141106 return rc;
@@ -141115,12 +141976,12 @@
141115 if( p->pWhere!=0
141116 && p->pWhere->op==TK_AND
141117 && OptimizationEnabled(db, SQLITE_PropagateConst)
141118 && propagateConstants(pParse, p)
141119 ){
141120 #if SELECTTRACE_ENABLED
141121 if( sqlite3SelectTrace & 0x100 ){
141122 SELECTTRACE(0x100,pParse,p,("After constant propagation:\n"));
141123 sqlite3TreeViewSelect(0, p, 0);
141124 }
141125 #endif
141126 }else{
@@ -141192,15 +142053,16 @@
141192 ** inside the subquery. This can help the subquery to run more efficiently.
141193 */
141194 if( OptimizationEnabled(db, SQLITE_PushDown)
141195 && (pItem->fg.isCte==0
141196 || (pItem->u2.pCteUse->eM10d!=M10d_Yes && pItem->u2.pCteUse->nUse<2))
 
141197 && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor,
141198 (pItem->fg.jointype & JT_OUTER)!=0)
141199 ){
141200 #if SELECTTRACE_ENABLED
141201 if( sqlite3SelectTrace & 0x100 ){
141202 SELECTTRACE(0x100,pParse,p,
141203 ("After WHERE-clause push-down into subquery %d:\n", pSub->selId));
141204 sqlite3TreeViewSelect(0, p, 0);
141205 }
141206 #endif
@@ -141212,22 +142074,23 @@
141212 zSavedAuthContext = pParse->zAuthContext;
141213 pParse->zAuthContext = pItem->zName;
141214
141215 /* Generate code to implement the subquery
141216 **
141217 ** The subquery is implemented as a co-routine if:
 
 
141218 ** (1) the subquery is guaranteed to be the outer loop (so that
141219 ** it does not need to be computed more than once), and
141220 ** (2) the subquery is not a CTE that should be materialized
141221 **
141222 ** TODO: Are there other reasons beside (1) and (2) to use a co-routine
141223 ** implementation?
141224 */
141225 if( i==0
141226 && (pTabList->nSrc==1
141227 || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0) /* (1) */
141228 && (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d!=M10d_Yes) /* (2) */
 
141229 ){
141230 /* Implement a co-routine that will return a single row of the result
141231 ** set on each invocation.
141232 */
141233 int addrTop = sqlite3VdbeCurrentAddr(v)+1;
@@ -141314,12 +142177,12 @@
141314 pWhere = p->pWhere;
141315 pGroupBy = p->pGroupBy;
141316 pHaving = p->pHaving;
141317 sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0;
141318
141319 #if SELECTTRACE_ENABLED
141320 if( sqlite3SelectTrace & 0x400 ){
141321 SELECTTRACE(0x400,pParse,p,("After all FROM-clause analysis:\n"));
141322 sqlite3TreeViewSelect(0, p, 0);
141323 }
141324 #endif
141325
@@ -141351,12 +142214,12 @@
141351 ** the sDistinct.isTnct is still set. Hence, isTnct represents the
141352 ** original setting of the SF_Distinct flag, not the current setting */
141353 assert( sDistinct.isTnct );
141354 sDistinct.isTnct = 2;
141355
141356 #if SELECTTRACE_ENABLED
141357 if( sqlite3SelectTrace & 0x400 ){
141358 SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n"));
141359 sqlite3TreeViewSelect(0, p, 0);
141360 }
141361 #endif
141362 }
@@ -141385,10 +142248,22 @@
141385
141386 /* If the output is destined for a temporary table, open that table.
141387 */
141388 if( pDest->eDest==SRT_EphemTab ){
141389 sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr);
 
 
 
 
 
 
 
 
 
 
 
 
141390 }
141391
141392 /* Set the limiter.
141393 */
141394 iEnd = sqlite3VdbeMakeLabel(pParse);
@@ -141604,12 +142479,12 @@
141604 #endif
141605 sNC.ncFlags &= ~NC_InAggFunc;
141606 }
141607 pAggInfo->mxReg = pParse->nMem;
141608 if( db->mallocFailed ) goto select_end;
141609 #if SELECTTRACE_ENABLED
141610 if( sqlite3SelectTrace & 0x400 ){
141611 int ii;
141612 SELECTTRACE(0x400,pParse,p,("After aggregate analysis %p:\n", pAggInfo));
141613 sqlite3TreeViewSelect(0, p, 0);
141614 if( minMaxFlag ){
141615 sqlite3DebugPrintf("MIN/MAX Optimization (0x%02x) adds:\n", minMaxFlag);
@@ -142001,11 +142876,13 @@
142001 SELECTTRACE(1,pParse,p,("WhereBegin returns\n"));
142002 eDist = sqlite3WhereIsDistinct(pWInfo);
142003 updateAccumulator(pParse, regAcc, pAggInfo, eDist);
142004 if( eDist!=WHERE_DISTINCT_NOOP ){
142005 struct AggInfo_func *pF = &pAggInfo->aFunc[0];
142006 fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr);
 
 
142007 }
142008
142009 if( regAcc ) sqlite3VdbeAddOp2(v, OP_Integer, 1, regAcc);
142010 if( minMaxFlag ){
142011 sqlite3WhereMinMaxOptEarlyOut(v, pWInfo);
@@ -142068,13 +142945,13 @@
142068 assert( pExpr->iAgg==i );
142069 }
142070 }
142071 #endif
142072
142073 #if SELECTTRACE_ENABLED
142074 SELECTTRACE(0x1,pParse,p,("end processing\n"));
142075 if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
142076 sqlite3TreeViewSelect(0, p, 0);
142077 }
142078 #endif
142079 ExplainQueryPlanPop(pParse);
142080 return rc;
@@ -142335,13 +143212,11 @@
142335 SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){
142336 Schema *pTmpSchema; /* Schema of the pTab table */
142337 Trigger *pList; /* List of triggers to return */
142338 HashElem *p; /* Loop variable for TEMP triggers */
142339
142340 if( pParse->disableTriggers ){
142341 return 0;
142342 }
142343 pTmpSchema = pParse->db->aDb[1].pSchema;
142344 p = sqliteHashFirst(&pTmpSchema->trigHash);
142345 pList = pTab->pTrigger;
142346 while( p ){
142347 Trigger *pTrig = (Trigger *)sqliteHashData(p);
@@ -143011,18 +143886,27 @@
143011 for(e=0; e<pEList->nExpr; e++){
143012 if( sqlite3IdListIndex(pIdList, pEList->a[e].zEName)>=0 ) return 1;
143013 }
143014 return 0;
143015 }
 
 
 
 
 
 
 
 
 
143016
143017 /*
143018 ** Return a list of all triggers on table pTab if there exists at least
143019 ** one trigger that must be fired when an operation of type 'op' is
143020 ** performed on the table, and, if that operation is an UPDATE, if at
143021 ** least one of the columns in pChanges is being modified.
143022 */
143023 SQLITE_PRIVATE Trigger *sqlite3TriggersExist(
143024 Parse *pParse, /* Parse context */
143025 Table *pTab, /* The table the contains the triggers */
143026 int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */
143027 ExprList *pChanges, /* Columns that change in an UPDATE statement */
143028 int *pMask /* OUT: Mask of TRIGGER_BEFORE|TRIGGER_AFTER */
@@ -143081,10 +143965,26 @@
143081 if( pMask ){
143082 *pMask = mask;
143083 }
143084 return (mask ? pList : 0);
143085 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143086
143087 /*
143088 ** Convert the pStep->zTarget string into a SrcList and return a pointer
143089 ** to that SrcList.
143090 **
@@ -144088,10 +144988,18 @@
144088 #endif
144089 #ifdef SQLITE_OMIT_VIEW
144090 # undef isView
144091 # define isView 0
144092 #endif
 
 
 
 
 
 
 
 
144093
144094 /* If there was a FROM clause, set nChangeFrom to the number of expressions
144095 ** in the change-list. Otherwise, set it to 0. There cannot be a FROM
144096 ** clause if this function is being called to generate code for part of
144097 ** an UPSERT statement. */
@@ -147181,10 +148089,31 @@
147181 typedef struct WhereTerm WhereTerm;
147182 typedef struct WhereLoopBuilder WhereLoopBuilder;
147183 typedef struct WhereScan WhereScan;
147184 typedef struct WhereOrCost WhereOrCost;
147185 typedef struct WhereOrSet WhereOrSet;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147186
147187 /*
147188 ** This object contains information needed to implement a single nested
147189 ** loop in WHERE clause.
147190 **
@@ -147214,10 +148143,11 @@
147214 #ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
147215 u32 iLikeRepCntr; /* LIKE range processing counter register (times 2) */
147216 int addrLikeRep; /* LIKE range processing address */
147217 #endif
147218 int regFilter; /* Bloom filter */
 
147219 u8 iFrom; /* Which entry in the FROM clause */
147220 u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */
147221 int p1, p2; /* Operands of the opcode used to end the loop */
147222 union { /* Information that depends on pWLoop->wsFlags */
147223 struct {
@@ -147627,10 +148557,11 @@
147627 LogEst nRowOut; /* Estimated number of output rows */
147628 int iTop; /* The very beginning of the WHERE loop */
147629 int iEndWhere; /* End of the WHERE clause itself */
147630 WhereLoop *pLoops; /* List of all WhereLoop objects */
147631 WhereExprMod *pExprMods; /* Expression modifications */
 
147632 Bitmask revMask; /* Mask of ORDER BY terms that need reversing */
147633 WhereClause sWC; /* Decomposition of the WHERE clause */
147634 WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */
147635 WhereLevel a[1]; /* Information about each nest loop in WHERE */
147636 };
@@ -147652,10 +148583,12 @@
147652 int iColumn, /* Column number of LHS */
147653 Bitmask notReady, /* RHS must not overlap with this mask */
147654 u32 op, /* Mask of WO_xx values describing operator */
147655 Index *pIdx /* Must be compatible with this index, if not NULL */
147656 );
 
 
147657
147658 /* wherecode.c: */
147659 #ifndef SQLITE_OMIT_EXPLAIN
147660 SQLITE_PRIVATE int sqlite3WhereExplainOneScan(
147661 Parse *pParse, /* Parse context */
@@ -147687,10 +148620,15 @@
147687 Vdbe *v, /* Prepared statement under construction */
147688 WhereInfo *pWInfo, /* Complete information about the WHERE clause */
147689 int iLevel, /* Which level of pWInfo->a[] should be coded */
147690 WhereLevel *pLevel, /* The current level pointer */
147691 Bitmask notReady /* Which tables are currently available */
 
 
 
 
 
147692 );
147693
147694 /* whereexpr.c: */
147695 SQLITE_PRIVATE void sqlite3WhereClauseInit(WhereClause*,WhereInfo*);
147696 SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause*);
@@ -147955,10 +148893,13 @@
147955 else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
147956 sqlite3_str_appendf(&str, " VIRTUAL TABLE INDEX %d:%s",
147957 pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
147958 }
147959 #endif
 
 
 
147960 #ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS
147961 if( pLoop->nOut>=10 ){
147962 sqlite3_str_appendf(&str, " (~%llu rows)",
147963 sqlite3LogEstToInt(pLoop->nOut));
147964 }else{
@@ -148391,12 +149332,13 @@
148391 }
148392
148393 i = pLevel->u.in.nIn;
148394 pLevel->u.in.nIn += nEq;
148395 pLevel->u.in.aInLoop =
148396 sqlite3DbReallocOrFree(pParse->db, pLevel->u.in.aInLoop,
148397 sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn);
 
148398 pIn = pLevel->u.in.aInLoop;
148399 if( pIn ){
148400 int iMap = 0; /* Index in aiMap[] */
148401 pIn += i;
148402 for(i=iEq;i<pLoop->nLTerm; i++){
@@ -148814,11 +149756,11 @@
148814 ** are also excluded. See codeCursorHintIsOrFunction() for details.
148815 */
148816 if( pTabItem->fg.jointype & JT_LEFT ){
148817 Expr *pExpr = pTerm->pExpr;
148818 if( !ExprHasProperty(pExpr, EP_FromJoin)
148819 || pExpr->w.iRightJoinTable!=pTabItem->iCursor
148820 ){
148821 sWalker.eCode = 0;
148822 sWalker.xExprCallback = codeCursorHintIsOrFunction;
148823 sqlite3WalkExpr(&sWalker, pTerm->pExpr);
148824 if( sWalker.eCode ) continue;
@@ -148900,11 +149842,11 @@
148900 assert( iIdxCur>0 );
148901 assert( pIdx->aiColumn[pIdx->nColumn-1]==-1 );
148902
148903 pWInfo->bDeferredSeek = 1;
148904 sqlite3VdbeAddOp3(v, OP_DeferredSeek, iIdxCur, 0, iCur);
148905 if( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)
148906 && DbMaskAllZero(sqlite3ParseToplevel(pParse)->writeMask)
148907 ){
148908 int i;
148909 Table *pTab = pIdx->pTable;
148910 u32 *ai = (u32*)sqlite3DbMallocZero(pParse->db, sizeof(u32)*(pTab->nCol+1));
@@ -149252,11 +150194,11 @@
149252
149253 /* If this is the right table of a LEFT OUTER JOIN, allocate and
149254 ** initialize a memory cell that records if this table matches any
149255 ** row of the left table of the join.
149256 */
149257 assert( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)
149258 || pLevel->iFrom>0 || (pTabItem[0].fg.jointype & JT_LEFT)==0
149259 );
149260 if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){
149261 pLevel->iLeftJoin = ++pParse->nMem;
149262 sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin);
@@ -149263,11 +150205,14 @@
149263 VdbeComment((v, "init LEFT JOIN no-match flag"));
149264 }
149265
149266 /* Compute a safe address to jump to if we discover that the table for
149267 ** this loop is empty and can never contribute content. */
149268 for(j=iLevel; j>0 && pWInfo->a[j].iLeftJoin==0; j--){}
 
 
 
149269 addrHalt = pWInfo->a[j].addrBrk;
149270
149271 /* Special case of a FROM clause subquery implemented as a co-routine */
149272 if( pTabItem->fg.viaCoroutine ){
149273 int regYield = pTabItem->regReturn;
@@ -149890,11 +150835,11 @@
149890 sqlite3VdbeAddOp3(v, OP_SeekHit, iIdxCur, nEq, nEq);
149891 }
149892
149893 /* Seek the table cursor, if required */
149894 omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0
149895 && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0;
149896 if( omitTable ){
149897 /* pIdx is a covering index. No need to access the main table. */
149898 }else if( HasRowid(pIdx->pTable) ){
149899 codeDeferredSeek(pWInfo, pIdx, iCur, iIdxCur);
149900 }else if( iCur!=iIdxCur ){
@@ -149924,11 +150869,11 @@
149924 ** Also, do not do this when processing one index an a multi-index
149925 ** OR clause, since the transformation will become invalid once we
149926 ** move forward to the next index.
149927 ** https://sqlite.org/src/info/4e8e4857d32d401f
149928 */
149929 if( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){
149930 whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo);
149931 }
149932
149933 /* If a partial index is driving the loop, try to eliminate WHERE clause
149934 ** terms from the query that must be true due to the WHERE clause of
@@ -149943,11 +150888,11 @@
149943 }else{
149944 testcase( pIdx->pPartIdxWhere );
149945 /* The following assert() is not a requirement, merely an observation:
149946 ** The OR-optimization doesn't work for the right hand table of
149947 ** a LEFT JOIN: */
149948 assert( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 );
149949 }
149950
149951 /* Record the instruction used to terminate the loop. */
149952 if( pLoop->wsFlags & WHERE_ONEROW ){
149953 pLevel->op = OP_Noop;
@@ -150284,10 +151229,18 @@
150284 sqlite3ExprDelete(db, pAndExpr);
150285 }
150286 sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
150287 sqlite3VdbeGoto(v, pLevel->addrBrk);
150288 sqlite3VdbeResolveLabel(v, iLoopBody);
 
 
 
 
 
 
 
 
150289
150290 if( pWInfo->nLevel>1 ){ sqlite3StackFree(db, pOrTab); }
150291 if( !untestedTerms ) disableTerm(pLevel, pTerm);
150292 }else
150293 #endif /* SQLITE_OMIT_OR_OPTIMIZATION */
@@ -150347,11 +151300,13 @@
150347 pWInfo->untestedTerms = 1;
150348 continue;
150349 }
150350 pE = pTerm->pExpr;
150351 assert( pE!=0 );
150352 if( (pTabItem->fg.jointype&JT_LEFT) && !ExprHasProperty(pE,EP_FromJoin) ){
 
 
150353 continue;
150354 }
150355
150356 if( iLoop==1 && !sqlite3ExprCoveredByIndex(pE, pLevel->iTabCur, pIdx) ){
150357 iNext = 2;
@@ -150409,11 +151364,11 @@
150409 WhereTerm *pAlt;
150410 if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
150411 if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue;
150412 if( (pTerm->eOperator & WO_EQUIV)==0 ) continue;
150413 if( pTerm->leftCursor!=iCur ) continue;
150414 if( pTabItem->fg.jointype & JT_LEFT ) continue;
150415 pE = pTerm->pExpr;
150416 #ifdef WHERETRACE_ENABLED /* 0x800 */
150417 if( sqlite3WhereTrace & 0x800 ){
150418 sqlite3DebugPrintf("Coding transitive constraint:\n");
150419 sqlite3WhereTermPrint(pTerm, pWC->nTerm-j);
@@ -150439,10 +151394,51 @@
150439 sEAlt = *pAlt->pExpr;
150440 sEAlt.pLeft = pE->pLeft;
150441 sqlite3ExprIfFalse(pParse, &sEAlt, addrCont, SQLITE_JUMPIFNULL);
150442 pAlt->wtFlags |= TERM_CODED;
150443 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150444
150445 /* For a LEFT OUTER JOIN, generate code that will record the fact that
150446 ** at least one row of the right table has matched the left table.
150447 */
150448 if( pLevel->iLeftJoin ){
@@ -150455,15 +151451,30 @@
150455 if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
150456 if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
150457 assert( pWInfo->untestedTerms );
150458 continue;
150459 }
 
150460 assert( pTerm->pExpr );
150461 sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
150462 pTerm->wtFlags |= TERM_CODED;
150463 }
150464 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150465
150466 #if WHERETRACE_ENABLED /* 0x20800 */
150467 if( sqlite3WhereTrace & 0x20000 ){
150468 sqlite3DebugPrintf("All WHERE-clause terms after coding level %d:\n",
150469 iLevel);
@@ -150474,10 +151485,94 @@
150474 iLevel, (u64)pLevel->notReady);
150475 }
150476 #endif
150477 return pLevel->notReady;
150478 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150479
150480 /************** End of wherecode.c *******************************************/
150481 /************** Begin file whereexpr.c ***************************************/
150482 /*
150483 ** 2015-06-08
@@ -150543,23 +151638,20 @@
150543 int idx;
150544 testcase( wtFlags & TERM_VIRTUAL );
150545 if( pWC->nTerm>=pWC->nSlot ){
150546 WhereTerm *pOld = pWC->a;
150547 sqlite3 *db = pWC->pWInfo->pParse->db;
150548 pWC->a = sqlite3DbMallocRawNN(db, sizeof(pWC->a[0])*pWC->nSlot*2 );
150549 if( pWC->a==0 ){
150550 if( wtFlags & TERM_DYNAMIC ){
150551 sqlite3ExprDelete(db, p);
150552 }
150553 pWC->a = pOld;
150554 return 0;
150555 }
150556 memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm);
150557 if( pOld!=pWC->aStatic ){
150558 sqlite3DbFree(db, pOld);
150559 }
150560 pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
150561 }
150562 pTerm = &pWC->a[idx = pWC->nTerm++];
150563 if( (wtFlags & TERM_VIRTUAL)==0 ) pWC->nBase = pWC->nTerm;
150564 if( p && ExprHasProperty(p, EP_Unlikely) ){
150565 pTerm->truthProb = sqlite3LogEst(p->iTable) - 270;
@@ -150945,11 +152037,11 @@
150945 ** a join, then transfer the appropriate markings over to derived.
150946 */
150947 static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
150948 if( pDerived ){
150949 pDerived->flags |= pBase->flags & EP_FromJoin;
150950 pDerived->w.iRightJoinTable = pBase->w.iRightJoinTable;
150951 }
150952 }
150953
150954 /*
150955 ** Mark term iChild as being a child of term iParent
@@ -151430,11 +152522,13 @@
151430 mask |= sqlite3WhereExprUsage(pMaskSet, pS->pHaving);
151431 if( ALWAYS(pSrc!=0) ){
151432 int i;
151433 for(i=0; i<pSrc->nSrc; i++){
151434 mask |= exprSelectUsage(pMaskSet, pSrc->a[i].pSelect);
151435 mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].pOn);
 
 
151436 if( pSrc->a[i].fg.isTabFunc ){
151437 mask |= sqlite3WhereExprListUsage(pMaskSet, pSrc->a[i].u1.pFuncArg);
151438 }
151439 }
151440 }
@@ -151590,11 +152684,11 @@
151590 abort();
151591 }
151592 #endif
151593
151594 if( ExprHasProperty(pExpr, EP_FromJoin) ){
151595 Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->w.iRightJoinTable);
151596 prereqAll |= x;
151597 extraRight = x-1; /* ON clause terms may not be used with an index
151598 ** on left table of a LEFT JOIN. Ticket #3015 */
151599 if( (prereqAll>>1)>=x ){
151600 sqlite3ErrorMsg(pParse, "ON clause references tables to its right");
@@ -151941,11 +153035,11 @@
151941 Expr *pNewExpr;
151942 pNewExpr = sqlite3PExpr(pParse, TK_MATCH,
151943 0, sqlite3ExprDup(db, pRight, 0));
151944 if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){
151945 ExprSetProperty(pNewExpr, EP_FromJoin);
151946 pNewExpr->w.iRightJoinTable = pExpr->w.iRightJoinTable;
151947 }
151948 idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
151949 testcase( idxNew==0 );
151950 pNewTerm = &pWC->a[idxNew];
151951 pNewTerm->prereqRight = prereqExpr;
@@ -152163,13 +153257,10 @@
152163 }
152164 if( a==aLast ) break;
152165 a++;
152166 }
152167 }
152168 if( pWC->a!=pWC->aStatic ){
152169 sqlite3DbFree(db, pWC->a);
152170 }
152171 }
152172
152173
152174 /*
152175 ** These routines walk (recursively) an expression tree and generate
@@ -152292,10 +153383,11 @@
152292 assert( pTab!=0 );
152293 pArgs = pItem->u1.pFuncArg;
152294 if( pArgs==0 ) return;
152295 for(j=k=0; j<pArgs->nExpr; j++){
152296 Expr *pRhs;
 
152297 while( k<pTab->nCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){k++;}
152298 if( k>=pTab->nCol ){
152299 sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d",
152300 pTab->zName, j);
152301 return;
@@ -152308,13 +153400,16 @@
152308 pColRef->y.pTab = pTab;
152309 pItem->colUsed |= sqlite3ExprColUsed(pColRef);
152310 pRhs = sqlite3PExpr(pParse, TK_UPLUS,
152311 sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
152312 pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs);
152313 if( pItem->fg.jointype & JT_LEFT ){
152314 sqlite3SetJoinExpr(pTerm, pItem->iCursor);
 
 
152315 }
 
152316 whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);
152317 }
152318 }
152319
152320 /************** End of whereexpr.c *******************************************/
@@ -152571,10 +153666,34 @@
152571 return MASKBIT(i);
152572 }
152573 }
152574 return 0;
152575 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152576
152577 /*
152578 ** Create a new mask for cursor iCursor.
152579 **
152580 ** There is one cursor per table in the FROM clause. The number of
@@ -153051,17 +154170,17 @@
153051 const Bitmask notReady /* Tables in outer loops of the join */
153052 ){
153053 char aff;
153054 if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
153055 if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0;
153056 if( (pSrc->fg.jointype & JT_LEFT)
153057 && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
153058 && (pTerm->eOperator & WO_IS)
153059 ){
153060 /* Cannot use an IS term from the WHERE clause as an index driver for
153061 ** the RHS of a LEFT JOIN. Such a term can only be used if it is from
153062 ** the ON clause. */
153063 return 0;
153064 }
153065 if( (pTerm->prereqRight & notReady)!=0 ) return 0;
153066 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
153067 if( pTerm->u.x.leftColumn<0 ) return 0;
@@ -153127,11 +154246,12 @@
153127 Expr *pExpr = pTerm->pExpr;
153128 /* Make the automatic index a partial index if there are terms in the
153129 ** WHERE clause (or the ON clause of a LEFT join) that constrain which
153130 ** rows of the target table (pSrc) that can be used. */
153131 if( (pTerm->wtFlags & TERM_VIRTUAL)==0
153132 && ((pSrc->fg.jointype&JT_LEFT)==0 || ExprHasProperty(pExpr,EP_FromJoin))
 
153133 && sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor)
153134 ){
153135 pPartial = sqlite3ExprAnd(pParse, pPartial,
153136 sqlite3ExprDup(pParse->db, pExpr, 0));
153137 }
@@ -153400,11 +154520,11 @@
153400 if( OptimizationDisabled(pParse->db, SQLITE_BloomPulldown) ) break;
153401 while( ++iLevel < pWInfo->nLevel ){
153402 const SrcItem *pTabItem;
153403 pLevel = &pWInfo->a[iLevel];
153404 pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
153405 if( pTabItem->fg.jointype & JT_LEFT ) continue;
153406 pLoop = pLevel->pWLoop;
153407 if( NEVER(pLoop==0) ) continue;
153408 if( pLoop->prereq & notReady ) continue;
153409 if( (pLoop->wsFlags & (WHERE_BLOOMFILTER|WHERE_COLUMN_IN))
153410 ==WHERE_BLOOMFILTER
@@ -153473,13 +154593,14 @@
153473 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
153474 assert( pTerm->u.x.leftColumn>=XN_ROWID );
153475 assert( pTerm->u.x.leftColumn<pTab->nCol );
153476
153477 /* tag-20191211-002: WHERE-clause constraints are not useful to the
153478 ** right-hand table of a LEFT JOIN. See tag-20191211-001 for the
 
153479 ** equivalent restriction for ordinary tables. */
153480 if( (pSrc->fg.jointype & JT_LEFT)!=0
153481 && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
153482 ){
153483 continue;
153484 }
153485 nTerm++;
@@ -154535,26 +155656,23 @@
154535
154536 /*
154537 ** Free a WhereInfo structure
154538 */
154539 static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
154540 int i;
154541 assert( pWInfo!=0 );
154542 for(i=0; i<pWInfo->nLevel; i++){
154543 WhereLevel *pLevel = &pWInfo->a[i];
154544 if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE)!=0 ){
154545 assert( (pLevel->pWLoop->wsFlags & WHERE_MULTI_OR)==0 );
154546 sqlite3DbFree(db, pLevel->u.in.aInLoop);
154547 }
154548 }
154549 sqlite3WhereClauseClear(&pWInfo->sWC);
154550 while( pWInfo->pLoops ){
154551 WhereLoop *p = pWInfo->pLoops;
154552 pWInfo->pLoops = p->pNextLoop;
154553 whereLoopDelete(db, p);
154554 }
154555 assert( pWInfo->pExprMods==0 );
 
 
 
 
 
154556 sqlite3DbFreeNN(db, pWInfo);
154557 }
154558
154559 /* Undo all Expr node modifications
154560 */
@@ -154919,14 +156037,15 @@
154919 ** cause many rows to be omitted, then mark that table as
154920 ** "self-culling".
154921 **
154922 ** 2022-03-24: Self-culling only applies if either the extra terms
154923 ** are straight comparison operators that are non-true with NULL
154924 ** operand, or if the loop is not a LEFT JOIN.
154925 */
154926 if( (pTerm->eOperator & 0x3f)!=0
154927 || (pWC->pWInfo->pTabList->a[pLoop->iTab].fg.jointype & JT_LEFT)==0
 
154928 ){
154929 pLoop->wsFlags |= WHERE_SELFCULL;
154930 }
154931 }
154932 if( pTerm->truthProb<=0 ){
@@ -155129,13 +156248,14 @@
155129 /* Do not allow the upper bound of a LIKE optimization range constraint
155130 ** to mix with a lower range bound from some other source */
155131 if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue;
155132
155133 /* tag-20191211-001: Do not allow constraints from the WHERE clause to
155134 ** be used by the right table of a LEFT JOIN. Only constraints in the
 
155135 ** ON clause are allowed. See tag-20191211-002 for the vtab equivalent. */
155136 if( (pSrc->fg.jointype & JT_LEFT)!=0
155137 && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
155138 ){
155139 continue;
155140 }
155141
@@ -155501,11 +156621,11 @@
155501 }
155502 if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0;
155503 for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
155504 Expr *pExpr;
155505 pExpr = pTerm->pExpr;
155506 if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->w.iRightJoinTable==iTab)
155507 && (isLeft==0 || ExprHasProperty(pExpr, EP_FromJoin))
155508 && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab)
155509 && (pTerm->wtFlags & TERM_VNULL)==0
155510 ){
155511 return 1;
@@ -155611,17 +156731,18 @@
155611 rSize = pTab->nRowLogEst;
155612
155613 #ifndef SQLITE_OMIT_AUTOMATIC_INDEX
155614 /* Automatic indexes */
155615 if( !pBuilder->pOrSet /* Not part of an OR optimization */
155616 && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0
155617 && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
155618 && !pSrc->fg.isIndexedBy /* Has no INDEXED BY clause */
155619 && !pSrc->fg.notIndexed /* Has no NOT INDEXED clause */
155620 && HasRowid(pTab) /* Not WITHOUT ROWID table. (FIXME: Why not?) */
155621 && !pSrc->fg.isCorrelated /* Not a correlated subquery */
155622 && !pSrc->fg.isRecursive /* Not a recursive common table expression. */
 
155623 ){
155624 /* Generate auto-index WhereLoops */
155625 LogEst rLogSize; /* Logarithm of the number of rows in the table */
155626 WhereTerm *pTerm;
155627 WhereTerm *pWCEnd = pWC->a + pWC->nTerm;
@@ -156107,19 +157228,30 @@
156107
156108 #if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \
156109 && !defined(SQLITE_OMIT_VIRTUALTABLE)
156110 /*
156111 ** Cause the prepared statement that is associated with a call to
156112 ** xBestIndex to open write transactions on all attached schemas.
 
 
 
 
156113 ** This is used by the (built-in) sqlite_dbpage virtual table.
156114 */
156115 SQLITE_PRIVATE void sqlite3VtabWriteAll(sqlite3_index_info *pIdxInfo){
156116 HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
156117 Parse *pParse = pHidden->pParse;
156118 int nDb = pParse->db->nDb;
156119 int i;
156120 for(i=0; i<nDb; i++) sqlite3BeginWriteOperation(pParse, 0, i);
 
 
 
 
 
 
 
156121 }
156122 #endif
156123
156124 /*
156125 ** Add all WhereLoop objects for a table of the join identified by
@@ -156297,10 +157429,13 @@
156297 pWCEnd = pWC->a + pWC->nTerm;
156298 pNew = pBuilder->pNew;
156299 memset(&sSum, 0, sizeof(sSum));
156300 pItem = pWInfo->pTabList->a + pNew->iTab;
156301 iCur = pItem->iCursor;
 
 
 
156302
156303 for(pTerm=pWC->a; pTerm<pWCEnd && rc==SQLITE_OK; pTerm++){
156304 if( (pTerm->eOperator & WO_OR)!=0
156305 && (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0
156306 ){
@@ -156422,22 +157557,22 @@
156422 for(iTab=0, pItem=pTabList->a; pItem<pEnd; iTab++, pItem++){
156423 Bitmask mUnusable = 0;
156424 pNew->iTab = iTab;
156425 pBuilder->iPlanLimit += SQLITE_QUERY_PLANNER_LIMIT_INCR;
156426 pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor);
156427 if( (pItem->fg.jointype & (JT_LEFT|JT_CROSS))!=0 ){
156428 /* This condition is true when pItem is the FROM clause term on the
156429 ** right-hand-side of a LEFT or CROSS JOIN. */
156430 mPrereq = mPrior;
156431 }else{
156432 mPrereq = 0;
156433 }
156434 #ifndef SQLITE_OMIT_VIRTUALTABLE
156435 if( IsVirtual(pItem->pTab) ){
156436 SrcItem *p;
156437 for(p=&pItem[1]; p<pEnd; p++){
156438 if( mUnusable || (p->fg.jointype & (JT_LEFT|JT_CROSS)) ){
156439 mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor);
156440 }
156441 }
156442 rc = whereLoopAddVirtual(pBuilder, mPrereq, mUnusable);
156443 }else
@@ -157496,11 +158631,11 @@
157496 if( (tabUsed & pLoop->maskSelf)!=0 ) continue;
157497 pEnd = pWInfo->sWC.a + pWInfo->sWC.nTerm;
157498 for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){
157499 if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
157500 if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
157501 || pTerm->pExpr->w.iRightJoinTable!=pItem->iCursor
157502 ){
157503 break;
157504 }
157505 }
157506 }
@@ -157727,11 +158862,11 @@
157727 ** struct, the contents of WhereInfo.a[], the WhereClause structure
157728 ** and the WhereMaskSet structure. Since WhereClause contains an 8-byte
157729 ** field (type Bitmask) it must be aligned on an 8-byte boundary on
157730 ** some architectures. Hence the ROUND8() below.
157731 */
157732 nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel));
157733 pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop));
157734 if( db->mallocFailed ){
157735 sqlite3DbFree(db, pWInfo);
157736 pWInfo = 0;
157737 goto whereBeginError;
@@ -158049,12 +159184,14 @@
158049 sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB);
158050 }else if( IsVirtual(pTab) ){
158051 /* noop */
158052 }else
158053 #endif
158054 if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
158055 && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){
 
 
158056 int op = OP_OpenRead;
158057 if( pWInfo->eOnePass!=ONEPASS_OFF ){
158058 op = OP_OpenWrite;
158059 pWInfo->aiCurOnePass[0] = pTabItem->iCursor;
158060 };
@@ -158152,10 +159289,41 @@
158152 }
158153 #endif /* SQLITE_ENABLE_COLUMN_USED_MASK */
158154 }
158155 }
158156 if( iDb>=0 ) sqlite3CodeVerifySchema(pParse, iDb);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158157 }
158158 pWInfo->iTop = sqlite3VdbeCurrentAddr(v);
158159 if( db->mallocFailed ) goto whereBeginError;
158160
158161 /* Generate the code to do the search. Each iteration of the for
@@ -158264,10 +159432,21 @@
158264 */
158265 VdbeModuleComment((v, "End WHERE-core"));
158266 for(i=pWInfo->nLevel-1; i>=0; i--){
158267 int addr;
158268 pLevel = &pWInfo->a[i];
 
 
 
 
 
 
 
 
 
 
 
158269 pLoop = pLevel->pWLoop;
158270 if( pLevel->op!=OP_Noop ){
158271 #ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
158272 int addrSeek = 0;
158273 Index *pIdx;
@@ -158291,11 +159470,11 @@
158291 VdbeCoverageIf(v, op==OP_SeekGT);
158292 sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2);
158293 }
158294 #endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */
158295 /* The common case: Advance to the next row */
158296 sqlite3VdbeResolveLabel(v, pLevel->addrCont);
158297 sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3);
158298 sqlite3VdbeChangeP5(v, pLevel->p5);
158299 VdbeCoverage(v);
158300 VdbeCoverageIf(v, pLevel->op==OP_Next);
158301 VdbeCoverageIf(v, pLevel->op==OP_Prev);
@@ -158306,11 +159485,11 @@
158306 VdbeCoverage(v);
158307 }
158308 #ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
158309 if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek);
158310 #endif
158311 }else{
158312 sqlite3VdbeResolveLabel(v, pLevel->addrCont);
158313 }
158314 if( (pLoop->wsFlags & WHERE_IN_ABLE)!=0 && pLevel->u.in.nIn>0 ){
158315 struct InLoop *pIn;
158316 int j;
@@ -158356,10 +159535,14 @@
158356 }
158357 sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
158358 }
158359 }
158360 sqlite3VdbeResolveLabel(v, pLevel->addrBrk);
 
 
 
 
158361 if( pLevel->addrSkip ){
158362 sqlite3VdbeGoto(v, pLevel->addrSkip);
158363 VdbeComment((v, "next skip-scan on %s", pLoop->u.btree.pIndex->zName));
158364 sqlite3VdbeJumpHere(v, pLevel->addrSkip);
158365 sqlite3VdbeJumpHere(v, pLevel->addrSkip-2);
@@ -158399,24 +159582,28 @@
158399 }
158400 VdbeModuleComment((v, "End WHERE-loop%d: %s", i,
158401 pWInfo->pTabList->a[pLevel->iFrom].pTab->zName));
158402 }
158403
158404 /* The "break" point is here, just past the end of the outer loop.
158405 ** Set it.
158406 */
158407 sqlite3VdbeResolveLabel(v, pWInfo->iBreak);
158408
158409 assert( pWInfo->nLevel<=pTabList->nSrc );
158410 for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){
158411 int k, last;
158412 VdbeOp *pOp, *pLastOp;
158413 Index *pIdx = 0;
158414 SrcItem *pTabItem = &pTabList->a[pLevel->iFrom];
158415 Table *pTab = pTabItem->pTab;
158416 assert( pTab!=0 );
158417 pLoop = pLevel->pWLoop;
 
 
 
 
 
 
 
 
 
158418
158419 /* For a co-routine, change all OP_Column references to the table of
158420 ** the co-routine into OP_Copy of result contained in a register.
158421 ** OP_Rowid becomes OP_Null.
158422 */
@@ -158425,33 +159612,10 @@
158425 translateColumnToCopy(pParse, pLevel->addrBody, pLevel->iTabCur,
158426 pTabItem->regResult, 0);
158427 continue;
158428 }
158429
158430 #ifdef SQLITE_ENABLE_EARLY_CURSOR_CLOSE
158431 /* Close all of the cursors that were opened by sqlite3WhereBegin.
158432 ** Except, do not close cursors that will be reused by the OR optimization
158433 ** (WHERE_OR_SUBCLAUSE). And do not close the OP_OpenWrite cursors
158434 ** created for the ONEPASS optimization.
158435 */
158436 if( (pTab->tabFlags & TF_Ephemeral)==0
158437 && !IsView(pTab)
158438 && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0
158439 ){
158440 int ws = pLoop->wsFlags;
158441 if( pWInfo->eOnePass==ONEPASS_OFF && (ws & WHERE_IDX_ONLY)==0 ){
158442 sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor);
158443 }
158444 if( (ws & WHERE_INDEXED)!=0
158445 && (ws & (WHERE_IPK|WHERE_AUTO_INDEX))==0
158446 && pLevel->iIdxCur!=pWInfo->aiCurOnePass[1]
158447 ){
158448 sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur);
158449 }
158450 }
158451 #endif
158452
158453 /* If this scan uses an index, make VDBE code substitutions to read data
158454 ** from the index instead of from the table where possible. In some cases
158455 ** this optimization prevents the table from ever being read, which can
158456 ** yield a significant performance boost.
158457 **
@@ -158547,10 +159711,15 @@
158547 #ifdef SQLITE_DEBUG
158548 if( db->flags & SQLITE_VdbeAddopTrace ) printf("TRANSLATE complete\n");
158549 #endif
158550 }
158551 }
 
 
 
 
 
158552
158553 /* Final cleanup
158554 */
158555 if( pWInfo->pExprMods ) whereUndoExprMods(pWInfo);
158556 pParse->nQueryLoop = pWInfo->savedNQueryLoop;
@@ -160289,11 +161458,11 @@
160289 regArg = sqlite3GetTempRange(pParse, nArg);
160290 sqlite3ExprCodeExprList(pParse, pWin->pOwner->x.pList, regArg, 0, 0);
160291
160292 for(iEnd=sqlite3VdbeCurrentAddr(v); iOp<iEnd; iOp++){
160293 VdbeOp *pOp = sqlite3VdbeGetOp(v, iOp);
160294 if( pOp->opcode==OP_Column && pOp->p1==pWin->iEphCsr ){
160295 pOp->p1 = csr;
160296 }
160297 }
160298 }
160299 if( pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
@@ -161828,11 +162997,11 @@
161828 /* memset(p, 0, sizeof(Expr)); */
161829 p->op = (u8)op;
161830 p->affExpr = 0;
161831 p->flags = EP_Leaf;
161832 ExprClearVVAProperties(p);
161833 p->iAgg = -1;
161834 p->pLeft = p->pRight = 0;
161835 p->pAggInfo = 0;
161836 memset(&p->x, 0, sizeof(p->x));
161837 memset(&p->y, 0, sizeof(p->y));
161838 p->op2 = 0;
@@ -162161,10 +163330,11 @@
162161 Upsert* yy444;
162162 u8 yy516;
162163 With* yy521;
162164 const char* yy522;
162165 Expr* yy528;
 
162166 struct FrameBound yy595;
162167 } YYMINORTYPE;
162168 #ifndef YYSTACKDEPTH
162169 #define YYSTACKDEPTH 100
162170 #endif
@@ -162177,21 +163347,21 @@
162177 #define sqlite3ParserCTX_PDECL ,Parse *pParse
162178 #define sqlite3ParserCTX_PARAM ,pParse
162179 #define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse;
162180 #define sqlite3ParserCTX_STORE yypParser->pParse=pParse;
162181 #define YYFALLBACK 1
162182 #define YYNSTATE 574
162183 #define YYNRULE 402
162184 #define YYNRULE_WITH_ACTION 340
162185 #define YYNTOKEN 185
162186 #define YY_MAX_SHIFT 573
162187 #define YY_MIN_SHIFTREDUCE 831
162188 #define YY_MAX_SHIFTREDUCE 1232
162189 #define YY_ERROR_ACTION 1233
162190 #define YY_ACCEPT_ACTION 1234
162191 #define YY_NO_ACTION 1235
162192 #define YY_MIN_REDUCE 1236
162193 #define YY_MAX_REDUCE 1637
162194 /************* End control #defines *******************************************/
162195 #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])))
162196
162197 /* Define the yytestcase() macro to be a no-op if is not already defined
@@ -162255,428 +163425,428 @@
162255 ** yy_reduce_ofst[] For each state, the offset into yy_action for
162256 ** shifting non-terminals after a reduce.
162257 ** yy_default[] Default action for each state.
162258 **
162259 *********** Begin parsing tables **********************************************/
162260 #define YY_ACTTAB_COUNT (2070)
162261 static const YYACTIONTYPE yy_action[] = {
162262 /* 0 */ 566, 1307, 566, 1286, 201, 201, 566, 116, 112, 222,
162263 /* 10 */ 566, 1307, 377, 566, 116, 112, 222, 397, 408, 409,
162264 /* 20 */ 1260, 378, 1269, 41, 41, 41, 41, 1412, 1517, 71,
162265 /* 30 */ 71, 967, 1258, 41, 41, 491, 71, 71, 272, 968,
162266 /* 40 */ 298, 476, 298, 123, 124, 114, 1210, 1210, 1044, 1047,
162267 /* 50 */ 1036, 1036, 121, 121, 122, 122, 122, 122, 543, 409,
162268 /* 60 */ 1234, 1, 1, 573, 2, 1238, 548, 116, 112, 222,
162269 /* 70 */ 309, 480, 142, 548, 1272, 524, 116, 112, 222, 1320,
162270 /* 80 */ 417, 523, 547, 123, 124, 114, 1210, 1210, 1044, 1047,
162271 /* 90 */ 1036, 1036, 121, 121, 122, 122, 122, 122, 424, 116,
162272 /* 100 */ 112, 222, 120, 120, 120, 120, 119, 119, 118, 118,
162273 /* 110 */ 118, 117, 113, 444, 277, 277, 277, 277, 560, 560,
162274 /* 120 */ 560, 1558, 376, 1560, 1186, 375, 1157, 563, 1157, 563,
162275 /* 130 */ 409, 1558, 537, 252, 219, 1553, 99, 141, 449, 6,
162276 /* 140 */ 365, 233, 120, 120, 120, 120, 119, 119, 118, 118,
162277 /* 150 */ 118, 117, 113, 444, 123, 124, 114, 1210, 1210, 1044,
162278 /* 160 */ 1047, 1036, 1036, 121, 121, 122, 122, 122, 122, 138,
162279 /* 170 */ 289, 1186, 1546, 448, 118, 118, 118, 117, 113, 444,
162280 /* 180 */ 125, 1186, 1187, 1188, 144, 465, 334, 566, 150, 127,
162281 /* 190 */ 444, 122, 122, 122, 122, 115, 120, 120, 120, 120,
162282 /* 200 */ 119, 119, 118, 118, 118, 117, 113, 444, 454, 419,
162283 /* 210 */ 13, 13, 215, 120, 120, 120, 120, 119, 119, 118,
162284 /* 220 */ 118, 118, 117, 113, 444, 422, 308, 557, 1186, 1187,
162285 /* 230 */ 1188, 441, 440, 409, 1271, 122, 122, 122, 122, 120,
162286 /* 240 */ 120, 120, 120, 119, 119, 118, 118, 118, 117, 113,
162287 /* 250 */ 444, 1543, 98, 1033, 1033, 1045, 1048, 123, 124, 114,
162288 /* 260 */ 1210, 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122,
162289 /* 270 */ 122, 122, 566, 406, 405, 1186, 566, 409, 1217, 319,
162290 /* 280 */ 1217, 80, 81, 120, 120, 120, 120, 119, 119, 118,
162291 /* 290 */ 118, 118, 117, 113, 444, 70, 70, 1186, 1604, 71,
162292 /* 300 */ 71, 123, 124, 114, 1210, 1210, 1044, 1047, 1036, 1036,
162293 /* 310 */ 121, 121, 122, 122, 122, 122, 120, 120, 120, 120,
162294 /* 320 */ 119, 119, 118, 118, 118, 117, 113, 444, 1037, 210,
162295 /* 330 */ 1186, 365, 1186, 1187, 1188, 245, 548, 399, 504, 501,
162296 /* 340 */ 500, 108, 558, 138, 4, 516, 933, 433, 499, 217,
162297 /* 350 */ 514, 522, 352, 879, 1186, 1187, 1188, 383, 561, 566,
162298 /* 360 */ 120, 120, 120, 120, 119, 119, 118, 118, 118, 117,
162299 /* 370 */ 113, 444, 277, 277, 16, 16, 1598, 441, 440, 153,
162300 /* 380 */ 409, 445, 13, 13, 1279, 563, 1214, 1186, 1187, 1188,
162301 /* 390 */ 1003, 1216, 264, 555, 1574, 186, 566, 427, 138, 1215,
162302 /* 400 */ 308, 557, 472, 138, 123, 124, 114, 1210, 1210, 1044,
162303 /* 410 */ 1047, 1036, 1036, 121, 121, 122, 122, 122, 122, 55,
162304 /* 420 */ 55, 413, 1023, 507, 1217, 1186, 1217, 474, 106, 106,
162305 /* 430 */ 1312, 1312, 1186, 171, 566, 384, 107, 380, 445, 568,
162306 /* 440 */ 567, 430, 1543, 1013, 332, 549, 565, 263, 280, 360,
162307 /* 450 */ 510, 355, 509, 250, 491, 308, 557, 71, 71, 351,
162308 /* 460 */ 308, 557, 374, 120, 120, 120, 120, 119, 119, 118,
162309 /* 470 */ 118, 118, 117, 113, 444, 1013, 1013, 1015, 1016, 27,
162310 /* 480 */ 277, 277, 1186, 1187, 1188, 1152, 566, 528, 409, 1186,
162311 /* 490 */ 1187, 1188, 348, 563, 548, 1260, 533, 517, 1152, 1516,
162312 /* 500 */ 317, 1152, 285, 550, 485, 569, 566, 569, 482, 51,
162313 /* 510 */ 51, 207, 123, 124, 114, 1210, 1210, 1044, 1047, 1036,
162314 /* 520 */ 1036, 121, 121, 122, 122, 122, 122, 171, 1412, 13,
162315 /* 530 */ 13, 409, 277, 277, 1186, 505, 119, 119, 118, 118,
162316 /* 540 */ 118, 117, 113, 444, 429, 563, 518, 220, 515, 1552,
162317 /* 550 */ 365, 546, 1186, 6, 532, 123, 124, 114, 1210, 1210,
162318 /* 560 */ 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, 122,
162319 /* 570 */ 145, 120, 120, 120, 120, 119, 119, 118, 118, 118,
162320 /* 580 */ 117, 113, 444, 245, 566, 474, 504, 501, 500, 566,
162321 /* 590 */ 1481, 1186, 1187, 1188, 1310, 1310, 499, 1186, 149, 425,
162322 /* 600 */ 1186, 480, 409, 274, 365, 952, 872, 56, 56, 1186,
162323 /* 610 */ 1187, 1188, 71, 71, 120, 120, 120, 120, 119, 119,
162324 /* 620 */ 118, 118, 118, 117, 113, 444, 123, 124, 114, 1210,
162325 /* 630 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122,
162326 /* 640 */ 122, 409, 541, 1552, 83, 865, 98, 6, 928, 529,
162327 /* 650 */ 848, 543, 151, 927, 1186, 1187, 1188, 1186, 1187, 1188,
162328 /* 660 */ 290, 1543, 187, 1633, 395, 123, 124, 114, 1210, 1210,
162329 /* 670 */ 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, 122,
162330 /* 680 */ 566, 954, 566, 453, 953, 120, 120, 120, 120, 119,
162331 /* 690 */ 119, 118, 118, 118, 117, 113, 444, 1152, 221, 1186,
162332 /* 700 */ 331, 453, 452, 13, 13, 13, 13, 1003, 365, 463,
162333 /* 710 */ 1152, 193, 409, 1152, 382, 1543, 1170, 32, 297, 474,
162334 /* 720 */ 195, 1527, 5, 952, 120, 120, 120, 120, 119, 119,
162335 /* 730 */ 118, 118, 118, 117, 113, 444, 123, 124, 114, 1210,
162336 /* 740 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122,
162337 /* 750 */ 122, 409, 1067, 419, 1186, 1024, 1186, 1187, 1188, 1186,
162338 /* 760 */ 419, 332, 460, 320, 544, 1545, 442, 442, 442, 566,
162339 /* 770 */ 3, 117, 113, 444, 453, 123, 124, 114, 1210, 1210,
162340 /* 780 */ 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, 122,
162341 /* 790 */ 1473, 566, 15, 15, 293, 120, 120, 120, 120, 119,
162342 /* 800 */ 119, 118, 118, 118, 117, 113, 444, 1186, 566, 1486,
162343 /* 810 */ 1412, 1186, 1187, 1188, 13, 13, 1186, 1187, 1188, 1544,
162344 /* 820 */ 271, 271, 409, 286, 308, 557, 1008, 1486, 1488, 196,
162345 /* 830 */ 288, 71, 71, 563, 120, 120, 120, 120, 119, 119,
162346 /* 840 */ 118, 118, 118, 117, 113, 444, 123, 124, 114, 1210,
162347 /* 850 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122,
162348 /* 860 */ 122, 409, 201, 1087, 1186, 1187, 1188, 1324, 304, 1529,
162349 /* 870 */ 388, 278, 278, 450, 564, 402, 922, 922, 566, 563,
162350 /* 880 */ 566, 426, 491, 480, 563, 123, 124, 114, 1210, 1210,
162351 /* 890 */ 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, 122,
162352 /* 900 */ 1486, 71, 71, 13, 13, 120, 120, 120, 120, 119,
162353 /* 910 */ 119, 118, 118, 118, 117, 113, 444, 566, 545, 566,
162354 /* 920 */ 1577, 573, 2, 1238, 1092, 1092, 488, 1480, 309, 1525,
162355 /* 930 */ 142, 324, 409, 836, 837, 838, 312, 1320, 305, 363,
162356 /* 940 */ 43, 43, 57, 57, 120, 120, 120, 120, 119, 119,
162357 /* 950 */ 118, 118, 118, 117, 113, 444, 123, 124, 114, 1210,
162358 /* 960 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122,
162359 /* 970 */ 122, 12, 277, 277, 566, 1152, 409, 572, 428, 1238,
162360 /* 980 */ 465, 334, 296, 474, 309, 563, 142, 249, 1152, 308,
162361 /* 990 */ 557, 1152, 321, 1320, 323, 491, 455, 71, 71, 233,
162362 /* 1000 */ 283, 101, 114, 1210, 1210, 1044, 1047, 1036, 1036, 121,
162363 /* 1010 */ 121, 122, 122, 122, 122, 120, 120, 120, 120, 119,
162364 /* 1020 */ 119, 118, 118, 118, 117, 113, 444, 1108, 277, 277,
162365 /* 1030 */ 1412, 448, 394, 1230, 439, 277, 277, 248, 247, 246,
162366 /* 1040 */ 1319, 563, 1109, 313, 198, 294, 491, 1318, 563, 464,
162367 /* 1050 */ 566, 1427, 394, 1130, 1023, 233, 414, 1110, 295, 120,
162368 /* 1060 */ 120, 120, 120, 119, 119, 118, 118, 118, 117, 113,
162369 /* 1070 */ 444, 1014, 104, 71, 71, 1013, 322, 496, 908, 566,
162370 /* 1080 */ 277, 277, 277, 277, 1108, 1261, 415, 448, 909, 361,
162371 /* 1090 */ 1571, 1315, 409, 563, 952, 563, 9, 202, 255, 1109,
162372 /* 1100 */ 316, 487, 44, 44, 249, 559, 415, 1013, 1013, 1015,
162373 /* 1110 */ 443, 1231, 409, 1603, 1110, 897, 123, 124, 114, 1210,
162374 /* 1120 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122,
162375 /* 1130 */ 122, 1231, 409, 1207, 215, 554, 123, 124, 114, 1210,
162376 /* 1140 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122,
162377 /* 1150 */ 122, 1131, 1631, 470, 1631, 255, 123, 111, 114, 1210,
162378 /* 1160 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122,
162379 /* 1170 */ 122, 1131, 1632, 414, 1632, 120, 120, 120, 120, 119,
162380 /* 1180 */ 119, 118, 118, 118, 117, 113, 444, 221, 209, 351,
162381 /* 1190 */ 1207, 1207, 147, 1426, 491, 120, 120, 120, 120, 119,
162382 /* 1200 */ 119, 118, 118, 118, 117, 113, 444, 1256, 539, 519,
162383 /* 1210 */ 888, 551, 952, 12, 566, 120, 120, 120, 120, 119,
162384 /* 1220 */ 119, 118, 118, 118, 117, 113, 444, 538, 566, 860,
162385 /* 1230 */ 1129, 361, 1571, 346, 1356, 409, 1163, 58, 58, 339,
162386 /* 1240 */ 1355, 508, 277, 277, 277, 277, 277, 277, 1207, 889,
162387 /* 1250 */ 1129, 59, 59, 459, 363, 563, 566, 563, 96, 563,
162388 /* 1260 */ 124, 114, 1210, 1210, 1044, 1047, 1036, 1036, 121, 121,
162389 /* 1270 */ 122, 122, 122, 122, 566, 1412, 566, 281, 1186, 60,
162390 /* 1280 */ 60, 110, 392, 392, 391, 266, 389, 860, 1163, 845,
162391 /* 1290 */ 566, 481, 566, 436, 341, 1152, 344, 61, 61, 62,
162392 /* 1300 */ 62, 967, 227, 1550, 315, 431, 540, 6, 1152, 968,
162393 /* 1310 */ 566, 1152, 314, 45, 45, 46, 46, 512, 120, 120,
162394 /* 1320 */ 120, 120, 119, 119, 118, 118, 118, 117, 113, 444,
162395 /* 1330 */ 416, 173, 1532, 47, 47, 1186, 1187, 1188, 108, 558,
162396 /* 1340 */ 325, 4, 229, 1551, 928, 566, 437, 6, 566, 927,
162397 /* 1350 */ 164, 566, 1290, 137, 1190, 561, 566, 1549, 566, 1089,
162398 /* 1360 */ 566, 6, 566, 1089, 531, 566, 868, 8, 49, 49,
162399 /* 1370 */ 228, 50, 50, 566, 63, 63, 566, 457, 445, 64,
162400 /* 1380 */ 64, 65, 65, 14, 14, 66, 66, 407, 129, 129,
162401 /* 1390 */ 555, 566, 458, 566, 1505, 486, 67, 67, 566, 52,
162402 /* 1400 */ 52, 546, 407, 467, 535, 410, 226, 1023, 566, 534,
162403 /* 1410 */ 308, 557, 1190, 407, 68, 68, 69, 69, 566, 1023,
162404 /* 1420 */ 566, 53, 53, 868, 1014, 106, 106, 525, 1013, 566,
162405 /* 1430 */ 1504, 159, 159, 107, 451, 445, 568, 567, 471, 307,
162406 /* 1440 */ 1013, 160, 160, 76, 76, 566, 1548, 466, 407, 407,
162407 /* 1450 */ 6, 1225, 54, 54, 478, 276, 219, 566, 887, 886,
162408 /* 1460 */ 1013, 1013, 1015, 84, 206, 1206, 230, 282, 72, 72,
162409 /* 1470 */ 329, 483, 1013, 1013, 1015, 1016, 27, 1576, 1174, 447,
162410 /* 1480 */ 130, 130, 281, 148, 105, 38, 103, 392, 392, 391,
162411 /* 1490 */ 266, 389, 566, 1126, 845, 396, 566, 108, 558, 566,
162412 /* 1500 */ 4, 311, 566, 30, 17, 566, 279, 227, 566, 315,
162413 /* 1510 */ 108, 558, 468, 4, 561, 73, 73, 314, 566, 157,
162414 /* 1520 */ 157, 566, 131, 131, 526, 132, 132, 561, 128, 128,
162415 /* 1530 */ 566, 158, 158, 566, 31, 291, 566, 445, 330, 521,
162416 /* 1540 */ 98, 152, 152, 420, 136, 136, 1005, 229, 254, 555,
162417 /* 1550 */ 445, 479, 336, 135, 135, 164, 133, 133, 137, 134,
162418 /* 1560 */ 134, 875, 555, 535, 566, 473, 566, 254, 536, 475,
162419 /* 1570 */ 335, 254, 98, 894, 895, 228, 535, 566, 1023, 566,
162420 /* 1580 */ 1074, 534, 210, 232, 106, 106, 1352, 75, 75, 77,
162421 /* 1590 */ 77, 1023, 107, 340, 445, 568, 567, 106, 106, 1013,
162422 /* 1600 */ 74, 74, 42, 42, 566, 107, 343, 445, 568, 567,
162423 /* 1610 */ 410, 497, 1013, 251, 359, 308, 557, 1135, 349, 875,
162424 /* 1620 */ 98, 1070, 345, 251, 358, 1591, 347, 48, 48, 1017,
162425 /* 1630 */ 1303, 1013, 1013, 1015, 1016, 27, 1289, 1287, 1074, 451,
162426 /* 1640 */ 961, 925, 254, 110, 1013, 1013, 1015, 1016, 27, 1174,
162427 /* 1650 */ 447, 970, 971, 281, 108, 558, 1288, 4, 392, 392,
162428 /* 1660 */ 391, 266, 389, 1343, 1086, 845, 1086, 1085, 858, 1085,
162429 /* 1670 */ 146, 561, 926, 354, 110, 303, 364, 553, 227, 1364,
162430 /* 1680 */ 315, 108, 558, 1411, 4, 1339, 492, 1017, 314, 1350,
162431 /* 1690 */ 1565, 552, 1417, 1268, 445, 204, 1259, 1247, 561, 1246,
162432 /* 1700 */ 1248, 1584, 269, 1336, 367, 369, 555, 371, 11, 212,
162433 /* 1710 */ 393, 225, 1393, 284, 1398, 456, 287, 327, 229, 328,
162434 /* 1720 */ 292, 445, 1386, 216, 333, 1403, 164, 477, 373, 137,
162435 /* 1730 */ 1402, 400, 502, 555, 1286, 1023, 357, 1477, 199, 1587,
162436 /* 1740 */ 211, 106, 106, 932, 1476, 1225, 228, 556, 175, 107,
162437 /* 1750 */ 200, 445, 568, 567, 258, 387, 1013, 1524, 1522, 223,
162438 /* 1760 */ 1222, 418, 1023, 83, 208, 79, 82, 184, 106, 106,
162439 /* 1770 */ 1482, 169, 177, 461, 179, 462, 107, 1399, 445, 568,
162440 /* 1780 */ 567, 410, 180, 1013, 495, 181, 308, 557, 1013, 1013,
162441 /* 1790 */ 1015, 1016, 27, 182, 35, 235, 100, 558, 398, 4,
162442 /* 1800 */ 96, 1405, 1404, 36, 484, 469, 1407, 188, 401, 1471,
162443 /* 1810 */ 451, 89, 1493, 561, 239, 1013, 1013, 1015, 1016, 27,
162444 /* 1820 */ 490, 338, 270, 241, 192, 342, 493, 242, 403, 1249,
162445 /* 1830 */ 243, 511, 432, 1297, 1306, 91, 445, 1305, 1304, 879,
162446 /* 1840 */ 217, 434, 435, 1570, 1276, 1602, 520, 1601, 555, 301,
162447 /* 1850 */ 527, 404, 1275, 302, 356, 1274, 1600, 95, 1347, 366,
162448 /* 1860 */ 1296, 362, 1348, 368, 256, 257, 1556, 1555, 438, 1346,
162449 /* 1870 */ 370, 126, 1345, 10, 1371, 546, 381, 1023, 102, 1457,
162450 /* 1880 */ 97, 530, 34, 106, 106, 570, 1180, 372, 265, 1329,
162451 /* 1890 */ 379, 107, 203, 445, 568, 567, 1328, 385, 1013, 1370,
162452 /* 1900 */ 386, 267, 268, 571, 1244, 161, 1239, 162, 1509, 1510,
162453 /* 1910 */ 1508, 143, 1507, 299, 832, 213, 214, 78, 446, 205,
162454 /* 1920 */ 310, 306, 163, 224, 1084, 140, 1082, 318, 165, 176,
162455 /* 1930 */ 1013, 1013, 1015, 1016, 27, 178, 1206, 231, 911, 234,
162456 /* 1940 */ 326, 1098, 183, 421, 166, 167, 411, 185, 85, 423,
162457 /* 1950 */ 412, 86, 174, 87, 168, 88, 1101, 236, 1097, 237,
162458 /* 1960 */ 154, 18, 238, 254, 337, 1219, 489, 1090, 240, 190,
162459 /* 1970 */ 37, 847, 189, 494, 358, 244, 350, 506, 191, 877,
162460 /* 1980 */ 90, 498, 19, 20, 503, 92, 353, 890, 300, 170,
162461 /* 1990 */ 155, 93, 513, 94, 1168, 156, 1050, 1137, 39, 218,
162462 /* 2000 */ 273, 275, 1136, 960, 194, 955, 110, 1154, 1158, 253,
162463 /* 2010 */ 7, 1162, 1156, 21, 22, 1161, 1142, 23, 24, 25,
162464 /* 2020 */ 33, 542, 26, 260, 197, 98, 1065, 1051, 1049, 1053,
162465 /* 2030 */ 1107, 1054, 1106, 259, 28, 40, 562, 1018, 859, 109,
162466 /* 2040 */ 29, 921, 390, 1176, 172, 139, 1175, 1235, 261, 1235,
162467 /* 2050 */ 1235, 1235, 1235, 1235, 1235, 1235, 1235, 262, 1235, 1235,
162468 /* 2060 */ 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1593, 1592,
162469 };
162470 static const YYCODETYPE yy_lookahead[] = {
162471 /* 0 */ 193, 223, 193, 225, 193, 193, 193, 274, 275, 276,
162472 /* 10 */ 193, 233, 219, 193, 274, 275, 276, 206, 206, 19,
162473 /* 20 */ 193, 219, 216, 216, 217, 216, 217, 193, 295, 216,
162474 /* 30 */ 217, 31, 205, 216, 217, 193, 216, 217, 213, 39,
162475 /* 40 */ 228, 193, 230, 43, 44, 45, 46, 47, 48, 49,
162476 /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 193, 19,
162477 /* 60 */ 185, 186, 187, 188, 189, 190, 253, 274, 275, 276,
162478 /* 70 */ 195, 193, 197, 253, 216, 262, 274, 275, 276, 204,
162479 /* 80 */ 238, 204, 262, 43, 44, 45, 46, 47, 48, 49,
162480 /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 264, 274,
162481 /* 100 */ 275, 276, 102, 103, 104, 105, 106, 107, 108, 109,
162482 /* 110 */ 110, 111, 112, 113, 239, 240, 239, 240, 210, 211,
162483 /* 120 */ 212, 314, 315, 314, 59, 316, 86, 252, 88, 252,
162484 /* 130 */ 19, 314, 315, 256, 257, 309, 25, 72, 296, 313,
162485 /* 140 */ 193, 266, 102, 103, 104, 105, 106, 107, 108, 109,
162486 /* 150 */ 110, 111, 112, 113, 43, 44, 45, 46, 47, 48,
162487 /* 160 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 81,
162488 /* 170 */ 292, 59, 307, 298, 108, 109, 110, 111, 112, 113,
162489 /* 180 */ 69, 116, 117, 118, 72, 128, 129, 193, 241, 22,
162490 /* 190 */ 113, 54, 55, 56, 57, 58, 102, 103, 104, 105,
162491 /* 200 */ 106, 107, 108, 109, 110, 111, 112, 113, 120, 193,
162492 /* 210 */ 216, 217, 25, 102, 103, 104, 105, 106, 107, 108,
162493 /* 220 */ 109, 110, 111, 112, 113, 231, 138, 139, 116, 117,
162494 /* 230 */ 118, 106, 107, 19, 216, 54, 55, 56, 57, 102,
162495 /* 240 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
162496 /* 250 */ 113, 304, 25, 46, 47, 48, 49, 43, 44, 45,
162497 /* 260 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
162498 /* 270 */ 56, 57, 193, 106, 107, 59, 193, 19, 153, 263,
162499 /* 280 */ 155, 67, 24, 102, 103, 104, 105, 106, 107, 108,
162500 /* 290 */ 109, 110, 111, 112, 113, 216, 217, 59, 230, 216,
162501 /* 300 */ 217, 43, 44, 45, 46, 47, 48, 49, 50, 51,
162502 /* 310 */ 52, 53, 54, 55, 56, 57, 102, 103, 104, 105,
162503 /* 320 */ 106, 107, 108, 109, 110, 111, 112, 113, 121, 142,
162504 /* 330 */ 59, 193, 116, 117, 118, 119, 253, 204, 122, 123,
162505 /* 340 */ 124, 19, 20, 81, 22, 262, 108, 19, 132, 165,
162506 /* 350 */ 166, 193, 24, 126, 116, 117, 118, 278, 36, 193,
162507 /* 360 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
162508 /* 370 */ 112, 113, 239, 240, 216, 217, 215, 106, 107, 241,
162509 /* 380 */ 19, 59, 216, 217, 223, 252, 115, 116, 117, 118,
162510 /* 390 */ 73, 120, 26, 71, 193, 22, 193, 231, 81, 128,
162511 /* 400 */ 138, 139, 269, 81, 43, 44, 45, 46, 47, 48,
162512 /* 410 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 216,
162513 /* 420 */ 217, 198, 100, 95, 153, 59, 155, 193, 106, 107,
162514 /* 430 */ 235, 236, 59, 193, 193, 249, 114, 251, 116, 117,
162515 /* 440 */ 118, 113, 304, 121, 127, 204, 193, 119, 120, 121,
162516 /* 450 */ 122, 123, 124, 125, 193, 138, 139, 216, 217, 131,
162517 /* 460 */ 138, 139, 193, 102, 103, 104, 105, 106, 107, 108,
162518 /* 470 */ 109, 110, 111, 112, 113, 153, 154, 155, 156, 157,
162519 /* 480 */ 239, 240, 116, 117, 118, 76, 193, 193, 19, 116,
162520 /* 490 */ 117, 118, 23, 252, 253, 193, 87, 204, 89, 238,
162521 /* 500 */ 193, 92, 268, 262, 281, 203, 193, 205, 285, 216,
162522 /* 510 */ 217, 150, 43, 44, 45, 46, 47, 48, 49, 50,
162523 /* 520 */ 51, 52, 53, 54, 55, 56, 57, 193, 193, 216,
162524 /* 530 */ 217, 19, 239, 240, 59, 23, 106, 107, 108, 109,
162525 /* 540 */ 110, 111, 112, 113, 231, 252, 253, 193, 308, 309,
162526 /* 550 */ 193, 145, 59, 313, 145, 43, 44, 45, 46, 47,
162527 /* 560 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
162528 /* 570 */ 164, 102, 103, 104, 105, 106, 107, 108, 109, 110,
162529 /* 580 */ 111, 112, 113, 119, 193, 193, 122, 123, 124, 193,
162530 /* 590 */ 283, 116, 117, 118, 235, 236, 132, 59, 241, 264,
162531 /* 600 */ 59, 193, 19, 23, 193, 25, 23, 216, 217, 116,
162532 /* 610 */ 117, 118, 216, 217, 102, 103, 104, 105, 106, 107,
162533 /* 620 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46,
162534 /* 630 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
162535 /* 640 */ 57, 19, 308, 309, 151, 23, 25, 313, 135, 253,
162536 /* 650 */ 21, 193, 241, 140, 116, 117, 118, 116, 117, 118,
162537 /* 660 */ 268, 304, 22, 301, 302, 43, 44, 45, 46, 47,
162538 /* 670 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
162539 /* 680 */ 193, 143, 193, 193, 143, 102, 103, 104, 105, 106,
162540 /* 690 */ 107, 108, 109, 110, 111, 112, 113, 76, 118, 59,
162541 /* 700 */ 292, 211, 212, 216, 217, 216, 217, 73, 193, 80,
162542 /* 710 */ 89, 25, 19, 92, 193, 304, 23, 22, 231, 193,
162543 /* 720 */ 231, 193, 22, 143, 102, 103, 104, 105, 106, 107,
162544 /* 730 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46,
162545 /* 740 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
162546 /* 750 */ 57, 19, 123, 193, 59, 23, 116, 117, 118, 59,
162547 /* 760 */ 193, 127, 128, 129, 306, 307, 210, 211, 212, 193,
162548 /* 770 */ 22, 111, 112, 113, 284, 43, 44, 45, 46, 47,
162549 /* 780 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
162550 /* 790 */ 161, 193, 216, 217, 268, 102, 103, 104, 105, 106,
162551 /* 800 */ 107, 108, 109, 110, 111, 112, 113, 59, 193, 193,
162552 /* 810 */ 193, 116, 117, 118, 216, 217, 116, 117, 118, 304,
162553 /* 820 */ 239, 240, 19, 263, 138, 139, 23, 211, 212, 231,
162554 /* 830 */ 263, 216, 217, 252, 102, 103, 104, 105, 106, 107,
162555 /* 840 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46,
162556 /* 850 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
162557 /* 860 */ 57, 19, 193, 11, 116, 117, 118, 240, 253, 193,
162558 /* 870 */ 201, 239, 240, 193, 134, 206, 136, 137, 193, 252,
162559 /* 880 */ 193, 264, 193, 193, 252, 43, 44, 45, 46, 47,
162560 /* 890 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
162561 /* 900 */ 284, 216, 217, 216, 217, 102, 103, 104, 105, 106,
162562 /* 910 */ 107, 108, 109, 110, 111, 112, 113, 193, 231, 193,
162563 /* 920 */ 187, 188, 189, 190, 127, 128, 129, 238, 195, 193,
162564 /* 930 */ 197, 16, 19, 7, 8, 9, 193, 204, 253, 193,
162565 /* 940 */ 216, 217, 216, 217, 102, 103, 104, 105, 106, 107,
162566 /* 950 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46,
162567 /* 960 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
162568 /* 970 */ 57, 213, 239, 240, 193, 76, 19, 188, 232, 190,
162569 /* 980 */ 128, 129, 292, 193, 195, 252, 197, 46, 89, 138,
162570 /* 990 */ 139, 92, 77, 204, 79, 193, 269, 216, 217, 266,
162571 /* 1000 */ 204, 159, 45, 46, 47, 48, 49, 50, 51, 52,
162572 /* 1010 */ 53, 54, 55, 56, 57, 102, 103, 104, 105, 106,
162573 /* 1020 */ 107, 108, 109, 110, 111, 112, 113, 12, 239, 240,
162574 /* 1030 */ 193, 298, 22, 23, 253, 239, 240, 127, 128, 129,
162575 /* 1040 */ 238, 252, 27, 193, 286, 204, 193, 204, 252, 291,
162576 /* 1050 */ 193, 273, 22, 23, 100, 266, 115, 42, 268, 102,
162577 /* 1060 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
162578 /* 1070 */ 113, 117, 159, 216, 217, 121, 161, 19, 63, 193,
162579 /* 1080 */ 239, 240, 239, 240, 12, 208, 209, 298, 73, 311,
162580 /* 1090 */ 312, 238, 19, 252, 25, 252, 22, 24, 24, 27,
162581 /* 1100 */ 193, 264, 216, 217, 46, 208, 209, 153, 154, 155,
162582 /* 1110 */ 253, 101, 19, 23, 42, 25, 43, 44, 45, 46,
162583 /* 1120 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
162584 /* 1130 */ 57, 101, 19, 59, 25, 63, 43, 44, 45, 46,
162585 /* 1140 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
162586 /* 1150 */ 57, 22, 23, 115, 25, 24, 43, 44, 45, 46,
162587 /* 1160 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
162588 /* 1170 */ 57, 22, 23, 115, 25, 102, 103, 104, 105, 106,
162589 /* 1180 */ 107, 108, 109, 110, 111, 112, 113, 118, 150, 131,
162590 /* 1190 */ 59, 117, 22, 273, 193, 102, 103, 104, 105, 106,
162591 /* 1200 */ 107, 108, 109, 110, 111, 112, 113, 204, 66, 204,
162592 /* 1210 */ 35, 204, 143, 213, 193, 102, 103, 104, 105, 106,
162593 /* 1220 */ 107, 108, 109, 110, 111, 112, 113, 85, 193, 59,
162594 /* 1230 */ 101, 311, 312, 16, 193, 19, 94, 216, 217, 238,
162595 /* 1240 */ 193, 66, 239, 240, 239, 240, 239, 240, 117, 74,
162596 /* 1250 */ 101, 216, 217, 193, 193, 252, 193, 252, 149, 252,
162597 /* 1260 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
162598 /* 1270 */ 54, 55, 56, 57, 193, 193, 193, 5, 59, 216,
162599 /* 1280 */ 217, 25, 10, 11, 12, 13, 14, 117, 146, 17,
162600 /* 1290 */ 193, 291, 193, 232, 77, 76, 79, 216, 217, 216,
162601 /* 1300 */ 217, 31, 30, 309, 32, 130, 87, 313, 89, 39,
162602 /* 1310 */ 193, 92, 40, 216, 217, 216, 217, 108, 102, 103,
162603 /* 1320 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
162604 /* 1330 */ 299, 300, 193, 216, 217, 116, 117, 118, 19, 20,
162605 /* 1340 */ 193, 22, 70, 309, 135, 193, 264, 313, 193, 140,
162606 /* 1350 */ 78, 193, 226, 81, 59, 36, 193, 309, 193, 29,
162607 /* 1360 */ 193, 313, 193, 33, 145, 193, 59, 48, 216, 217,
162608 /* 1370 */ 98, 216, 217, 193, 216, 217, 193, 244, 59, 216,
162609 /* 1380 */ 217, 216, 217, 216, 217, 216, 217, 254, 216, 217,
162610 /* 1390 */ 71, 193, 244, 193, 193, 65, 216, 217, 193, 216,
162611 /* 1400 */ 217, 145, 254, 244, 85, 133, 15, 100, 193, 90,
162612 /* 1410 */ 138, 139, 117, 254, 216, 217, 216, 217, 193, 100,
162613 /* 1420 */ 193, 216, 217, 116, 117, 106, 107, 19, 121, 193,
162614 /* 1430 */ 193, 216, 217, 114, 162, 116, 117, 118, 244, 244,
162615 /* 1440 */ 121, 216, 217, 216, 217, 193, 309, 129, 254, 254,
162616 /* 1450 */ 313, 60, 216, 217, 19, 256, 257, 193, 120, 121,
162617 /* 1460 */ 153, 154, 155, 149, 150, 25, 24, 99, 216, 217,
162618 /* 1470 */ 152, 193, 153, 154, 155, 156, 157, 0, 1, 2,
162619 /* 1480 */ 216, 217, 5, 22, 158, 24, 160, 10, 11, 12,
162620 /* 1490 */ 13, 14, 193, 23, 17, 25, 193, 19, 20, 193,
162621 /* 1500 */ 22, 133, 193, 22, 22, 193, 22, 30, 193, 32,
162622 /* 1510 */ 19, 20, 129, 22, 36, 216, 217, 40, 193, 216,
162623 /* 1520 */ 217, 193, 216, 217, 116, 216, 217, 36, 216, 217,
162624 /* 1530 */ 193, 216, 217, 193, 53, 152, 193, 59, 23, 19,
162625 /* 1540 */ 25, 216, 217, 61, 216, 217, 23, 70, 25, 71,
162626 /* 1550 */ 59, 116, 193, 216, 217, 78, 216, 217, 81, 216,
162627 /* 1560 */ 217, 59, 71, 85, 193, 23, 193, 25, 90, 23,
162628 /* 1570 */ 23, 25, 25, 7, 8, 98, 85, 193, 100, 193,
162629 /* 1580 */ 59, 90, 142, 141, 106, 107, 193, 216, 217, 216,
162630 /* 1590 */ 217, 100, 114, 193, 116, 117, 118, 106, 107, 121,
162631 /* 1600 */ 216, 217, 216, 217, 193, 114, 193, 116, 117, 118,
162632 /* 1610 */ 133, 23, 121, 25, 121, 138, 139, 97, 23, 117,
162633 /* 1620 */ 25, 23, 193, 25, 131, 141, 193, 216, 217, 59,
162634 /* 1630 */ 193, 153, 154, 155, 156, 157, 226, 193, 117, 162,
162635 /* 1640 */ 23, 23, 25, 25, 153, 154, 155, 156, 157, 1,
162636 /* 1650 */ 2, 83, 84, 5, 19, 20, 226, 22, 10, 11,
162637 /* 1660 */ 12, 13, 14, 258, 153, 17, 155, 153, 23, 155,
162638 /* 1670 */ 25, 36, 23, 193, 25, 255, 193, 236, 30, 193,
162639 /* 1680 */ 32, 19, 20, 193, 22, 193, 288, 117, 40, 193,
162640 /* 1690 */ 318, 193, 193, 193, 59, 242, 193, 193, 36, 193,
162641 /* 1700 */ 193, 193, 287, 255, 255, 255, 71, 255, 243, 214,
162642 /* 1710 */ 191, 297, 267, 245, 271, 259, 259, 293, 70, 246,
162643 /* 1720 */ 246, 59, 267, 229, 245, 271, 78, 293, 259, 81,
162644 /* 1730 */ 271, 271, 220, 71, 225, 100, 219, 219, 249, 196,
162645 /* 1740 */ 243, 106, 107, 108, 219, 60, 98, 280, 297, 114,
162646 /* 1750 */ 249, 116, 117, 118, 141, 245, 121, 200, 200, 297,
162647 /* 1760 */ 38, 200, 100, 151, 150, 294, 294, 22, 106, 107,
162648 /* 1770 */ 283, 43, 234, 18, 237, 200, 114, 272, 116, 117,
162649 /* 1780 */ 118, 133, 237, 121, 18, 237, 138, 139, 153, 154,
162650 /* 1790 */ 155, 156, 157, 237, 270, 199, 19, 20, 246, 22,
162651 /* 1800 */ 149, 272, 272, 270, 200, 246, 234, 234, 246, 246,
162652 /* 1810 */ 162, 158, 290, 36, 199, 153, 154, 155, 156, 157,
162653 /* 1820 */ 62, 289, 200, 199, 22, 200, 221, 199, 221, 200,
162654 /* 1830 */ 199, 115, 64, 227, 218, 22, 59, 218, 218, 126,
162655 /* 1840 */ 165, 24, 113, 312, 218, 224, 305, 224, 71, 282,
162656 /* 1850 */ 144, 221, 220, 282, 218, 218, 218, 115, 261, 260,
162657 /* 1860 */ 227, 221, 261, 260, 200, 91, 317, 317, 82, 261,
162658 /* 1870 */ 260, 148, 261, 22, 265, 145, 200, 100, 158, 277,
162659 /* 1880 */ 147, 146, 25, 106, 107, 202, 13, 260, 194, 250,
162660 /* 1890 */ 249, 114, 248, 116, 117, 118, 250, 247, 121, 265,
162661 /* 1900 */ 246, 194, 6, 192, 192, 207, 192, 207, 213, 213,
162662 /* 1910 */ 213, 222, 213, 222, 4, 214, 214, 213, 3, 22,
162663 /* 1920 */ 163, 279, 207, 15, 23, 16, 23, 139, 130, 151,
162664 /* 1930 */ 153, 154, 155, 156, 157, 142, 25, 24, 20, 144,
162665 /* 1940 */ 16, 1, 142, 61, 130, 130, 303, 151, 53, 37,
162666 /* 1950 */ 303, 53, 300, 53, 130, 53, 116, 34, 1, 141,
162667 /* 1960 */ 5, 22, 115, 25, 161, 75, 41, 68, 141, 115,
162668 /* 1970 */ 24, 20, 68, 19, 131, 125, 23, 96, 22, 59,
162669 /* 1980 */ 22, 67, 22, 22, 67, 22, 24, 28, 67, 37,
162670 /* 1990 */ 23, 149, 22, 25, 23, 23, 23, 23, 22, 141,
162671 /* 2000 */ 23, 23, 97, 116, 22, 143, 25, 88, 75, 34,
162672 /* 2010 */ 44, 75, 86, 34, 34, 93, 23, 34, 34, 34,
162673 /* 2020 */ 22, 24, 34, 22, 25, 25, 23, 23, 23, 23,
162674 /* 2030 */ 23, 11, 23, 25, 22, 22, 25, 23, 23, 22,
162675 /* 2040 */ 22, 135, 15, 1, 25, 23, 1, 319, 141, 319,
162676 /* 2050 */ 319, 319, 319, 319, 319, 319, 319, 141, 319, 319,
162677 /* 2060 */ 319, 319, 319, 319, 319, 319, 319, 319, 141, 141,
162678 /* 2070 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
162679 /* 2080 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
162680 /* 2090 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
162681 /* 2100 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
162682 /* 2110 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
@@ -162690,181 +163860,178 @@
162690 /* 2190 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
162691 /* 2200 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
162692 /* 2210 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
162693 /* 2220 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
162694 /* 2230 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
162695 /* 2240 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
162696 /* 2250 */ 319, 319, 319, 319, 319,
162697 };
162698 #define YY_SHIFT_COUNT (573)
162699 #define YY_SHIFT_MIN (0)
162700 #define YY_SHIFT_MAX (2045)
162701 static const unsigned short int yy_shift_ofst[] = {
162702 /* 0 */ 1648, 1477, 1272, 322, 322, 262, 1319, 1478, 1491, 1662,
162703 /* 10 */ 1662, 1662, 317, 0, 0, 214, 1093, 1662, 1662, 1662,
162704 /* 20 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
162705 /* 30 */ 271, 271, 1219, 1219, 216, 88, 262, 262, 262, 262,
162706 /* 40 */ 262, 40, 111, 258, 361, 469, 512, 583, 622, 693,
162707 /* 50 */ 732, 803, 842, 913, 1073, 1093, 1093, 1093, 1093, 1093,
162708 /* 60 */ 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093,
162709 /* 70 */ 1093, 1093, 1093, 1113, 1093, 1216, 957, 957, 1635, 1662,
162710 /* 80 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
162711 /* 90 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
162712 /* 100 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
162713 /* 110 */ 1662, 1662, 1662, 1662, 1777, 1662, 1662, 1662, 1662, 1662,
162714 /* 120 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 137, 181,
162715 /* 130 */ 181, 181, 181, 181, 94, 430, 66, 65, 112, 366,
162716 /* 140 */ 475, 475, 629, 1058, 475, 475, 125, 125, 475, 686,
162717 /* 150 */ 686, 686, 660, 686, 57, 184, 184, 77, 77, 2070,
162718 /* 160 */ 2070, 328, 328, 328, 493, 373, 373, 373, 373, 1015,
162719 /* 170 */ 1015, 409, 366, 1129, 1149, 475, 475, 475, 475, 475,
162720 /* 180 */ 475, 475, 475, 475, 475, 475, 475, 475, 475, 475,
162721 /* 190 */ 475, 475, 475, 475, 475, 621, 621, 475, 852, 899,
162722 /* 200 */ 899, 1295, 1295, 406, 851, 2070, 2070, 2070, 2070, 2070,
162723 /* 210 */ 2070, 2070, 1307, 954, 954, 640, 464, 695, 238, 700,
162724 /* 220 */ 538, 541, 748, 475, 475, 475, 475, 475, 475, 475,
162725 /* 230 */ 475, 475, 475, 634, 475, 475, 475, 475, 475, 475,
162726 /* 240 */ 475, 475, 475, 475, 475, 475, 1175, 1175, 1175, 475,
162727 /* 250 */ 475, 475, 580, 475, 475, 475, 1074, 1142, 475, 475,
162728 /* 260 */ 1072, 475, 475, 475, 475, 475, 475, 475, 475, 797,
162729 /* 270 */ 1330, 740, 1131, 1131, 1131, 1131, 1069, 740, 740, 1209,
162730 /* 280 */ 167, 926, 1391, 1038, 1314, 187, 1408, 1314, 1408, 1435,
162731 /* 290 */ 1109, 1038, 1038, 1109, 1038, 187, 1435, 227, 1090, 941,
162732 /* 300 */ 1270, 1270, 1270, 1408, 1256, 1256, 1326, 1440, 513, 1461,
162733 /* 310 */ 1685, 1685, 1613, 1613, 1722, 1722, 1613, 1612, 1614, 1745,
162734 /* 320 */ 1728, 1755, 1755, 1755, 1755, 1613, 1766, 1651, 1614, 1614,
162735 /* 330 */ 1651, 1745, 1728, 1651, 1728, 1651, 1613, 1766, 1653, 1758,
162736 /* 340 */ 1613, 1766, 1802, 1613, 1766, 1613, 1766, 1802, 1716, 1716,
162737 /* 350 */ 1716, 1768, 1813, 1813, 1802, 1716, 1713, 1716, 1768, 1716,
162738 /* 360 */ 1716, 1675, 1817, 1729, 1729, 1802, 1706, 1742, 1706, 1742,
162739 /* 370 */ 1706, 1742, 1706, 1742, 1613, 1774, 1774, 1786, 1786, 1723,
162740 /* 380 */ 1730, 1851, 1613, 1720, 1723, 1733, 1735, 1651, 1857, 1873,
162741 /* 390 */ 1873, 1896, 1896, 1896, 2070, 2070, 2070, 2070, 2070, 2070,
162742 /* 400 */ 2070, 2070, 2070, 2070, 2070, 2070, 2070, 2070, 2070, 207,
162743 /* 410 */ 915, 1010, 1030, 1217, 910, 1170, 1470, 1368, 1481, 1442,
162744 /* 420 */ 1318, 1383, 1515, 1482, 1523, 1542, 1546, 1547, 1588, 1595,
162745 /* 430 */ 1502, 1338, 1566, 1493, 1520, 1521, 1598, 1617, 1568, 1618,
162746 /* 440 */ 1511, 1514, 1645, 1649, 1570, 1484, 1910, 1915, 1897, 1757,
162747 /* 450 */ 1908, 1909, 1901, 1903, 1788, 1778, 1798, 1911, 1911, 1913,
162748 /* 460 */ 1793, 1918, 1795, 1924, 1940, 1800, 1814, 1911, 1815, 1882,
162749 /* 470 */ 1912, 1911, 1796, 1895, 1898, 1900, 1902, 1824, 1840, 1923,
162750 /* 480 */ 1818, 1957, 1955, 1939, 1847, 1803, 1899, 1938, 1904, 1890,
162751 /* 490 */ 1925, 1827, 1854, 1946, 1951, 1954, 1843, 1850, 1956, 1914,
162752 /* 500 */ 1958, 1960, 1953, 1961, 1917, 1920, 1962, 1881, 1959, 1963,
162753 /* 510 */ 1921, 1952, 1967, 1842, 1970, 1971, 1972, 1973, 1968, 1974,
162754 /* 520 */ 1976, 1905, 1858, 1977, 1978, 1887, 1975, 1982, 1862, 1981,
162755 /* 530 */ 1979, 1980, 1983, 1984, 1919, 1933, 1926, 1966, 1936, 1922,
162756 /* 540 */ 1985, 1993, 1998, 1997, 1999, 2000, 1988, 2003, 1981, 2004,
162757 /* 550 */ 2005, 2006, 2007, 2008, 2009, 2001, 2020, 2012, 2013, 2014,
162758 /* 560 */ 2015, 2017, 2018, 2011, 1906, 1907, 1916, 1927, 1928, 2019,
162759 /* 570 */ 2022, 2027, 2042, 2045,
162760 };
162761 #define YY_REDUCE_COUNT (408)
162762 #define YY_REDUCE_MIN (-267)
162763 #define YY_REDUCE_MAX (1715)
162764 static const short yy_reduce_ofst[] = {
162765 /* 0 */ -125, 733, 789, 241, 293, -123, -193, -191, -183, -187,
162766 /* 10 */ -180, 83, 133, -207, -198, -267, -175, -6, 166, 313,
162767 /* 20 */ 487, 396, 489, 598, 615, 685, 687, 79, 781, 857,
162768 /* 30 */ 490, 616, 240, 334, -188, 796, 841, 843, 1003, 1005,
162769 /* 40 */ 1007, -260, -260, -260, -260, -260, -260, -260, -260, -260,
162770 /* 50 */ -260, -260, -260, -260, -260, -260, -260, -260, -260, -260,
162771 /* 60 */ -260, -260, -260, -260, -260, -260, -260, -260, -260, -260,
162772 /* 70 */ -260, -260, -260, -260, -260, -260, -260, -260, 158, 203,
162773 /* 80 */ 391, 576, 724, 726, 886, 1021, 1035, 1063, 1081, 1083,
162774 /* 90 */ 1097, 1099, 1117, 1152, 1155, 1158, 1163, 1165, 1167, 1169,
162775 /* 100 */ 1172, 1180, 1183, 1198, 1200, 1205, 1215, 1225, 1227, 1236,
162776 /* 110 */ 1252, 1264, 1299, 1303, 1306, 1309, 1312, 1315, 1325, 1328,
162777 /* 120 */ 1337, 1340, 1343, 1371, 1373, 1384, 1386, 1411, -260, -260,
162778 /* 130 */ -260, -260, -260, -260, -260, -260, -260, -53, 138, 302,
162779 /* 140 */ -158, 357, 223, -222, 411, 458, -92, 556, 669, 581,
162780 /* 150 */ 632, 581, -260, 632, 758, 778, 920, -260, -260, -260,
162781 /* 160 */ -260, 161, 161, 161, 307, 234, 392, 526, 790, 195,
162782 /* 170 */ 359, -174, -173, 362, 362, -189, 16, 560, 567, 261,
162783 /* 180 */ 689, 802, 853, -122, -166, 408, 335, 617, 690, 837,
162784 /* 190 */ 1001, 746, 1061, 515, 1082, 994, 1034, -135, 1000, 1048,
162785 /* 200 */ 1137, 877, 897, 186, 627, 1031, 1133, 1148, 1159, 1194,
162786 /* 210 */ 1199, 1195, -194, -142, 18, -152, 68, 201, 253, 269,
162787 /* 220 */ 294, 354, 521, 528, 676, 680, 736, 743, 850, 907,
162788 /* 230 */ 1041, 1047, 1060, 727, 1139, 1147, 1201, 1237, 1278, 1359,
162789 /* 240 */ 1393, 1400, 1413, 1429, 1433, 1437, 1126, 1410, 1430, 1444,
162790 /* 250 */ 1480, 1483, 1405, 1486, 1490, 1492, 1420, 1372, 1496, 1498,
162791 /* 260 */ 1441, 1499, 253, 1500, 1503, 1504, 1506, 1507, 1508, 1398,
162792 /* 270 */ 1415, 1453, 1448, 1449, 1450, 1452, 1405, 1453, 1453, 1465,
162793 /* 280 */ 1495, 1519, 1414, 1443, 1445, 1468, 1456, 1455, 1457, 1424,
162794 /* 290 */ 1473, 1454, 1459, 1474, 1460, 1479, 1434, 1512, 1494, 1509,
162795 /* 300 */ 1517, 1518, 1525, 1469, 1489, 1501, 1467, 1510, 1497, 1543,
162796 /* 310 */ 1451, 1462, 1557, 1558, 1471, 1472, 1561, 1487, 1505, 1524,
162797 /* 320 */ 1538, 1537, 1545, 1548, 1556, 1575, 1596, 1552, 1529, 1530,
162798 /* 330 */ 1559, 1533, 1572, 1562, 1573, 1563, 1604, 1615, 1522, 1532,
162799 /* 340 */ 1622, 1624, 1605, 1625, 1628, 1629, 1631, 1607, 1616, 1619,
162800 /* 350 */ 1620, 1606, 1621, 1623, 1630, 1626, 1632, 1636, 1633, 1637,
162801 /* 360 */ 1638, 1531, 1541, 1567, 1571, 1640, 1597, 1599, 1601, 1603,
162802 /* 370 */ 1608, 1610, 1611, 1627, 1664, 1549, 1550, 1609, 1634, 1639,
162803 /* 380 */ 1641, 1602, 1676, 1642, 1646, 1644, 1650, 1654, 1683, 1694,
162804 /* 390 */ 1707, 1711, 1712, 1714, 1643, 1647, 1652, 1698, 1695, 1696,
162805 /* 400 */ 1697, 1699, 1700, 1689, 1691, 1701, 1702, 1704, 1715,
162806 };
162807 static const YYACTIONTYPE yy_default[] = {
162808 /* 0 */ 1637, 1637, 1637, 1466, 1233, 1344, 1233, 1233, 1233, 1466,
162809 /* 10 */ 1466, 1466, 1233, 1374, 1374, 1519, 1266, 1233, 1233, 1233,
162810 /* 20 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1465, 1233, 1233,
162811 /* 30 */ 1233, 1233, 1554, 1554, 1233, 1233, 1233, 1233, 1233, 1233,
162812 /* 40 */ 1233, 1233, 1383, 1233, 1390, 1233, 1233, 1233, 1233, 1233,
162813 /* 50 */ 1467, 1468, 1233, 1233, 1233, 1518, 1520, 1483, 1397, 1396,
162814 /* 60 */ 1395, 1394, 1501, 1361, 1388, 1381, 1385, 1461, 1462, 1460,
162815 /* 70 */ 1464, 1468, 1467, 1233, 1384, 1431, 1445, 1430, 1233, 1233,
162816 /* 80 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162817 /* 90 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162818 /* 100 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162819 /* 110 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162820 /* 120 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1439, 1444,
162821 /* 130 */ 1451, 1443, 1440, 1433, 1432, 1434, 1435, 1233, 1233, 1257,
162822 /* 140 */ 1233, 1233, 1254, 1308, 1233, 1233, 1233, 1233, 1233, 1538,
162823 /* 150 */ 1537, 1233, 1436, 1233, 1266, 1425, 1424, 1448, 1437, 1447,
162824 /* 160 */ 1446, 1526, 1590, 1589, 1484, 1233, 1233, 1233, 1233, 1233,
162825 /* 170 */ 1233, 1554, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162826 /* 180 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162827 /* 190 */ 1233, 1233, 1233, 1233, 1233, 1554, 1554, 1233, 1266, 1554,
162828 /* 200 */ 1554, 1262, 1262, 1368, 1233, 1533, 1335, 1335, 1335, 1335,
162829 /* 210 */ 1344, 1335, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162830 /* 220 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1523, 1521, 1233,
162831 /* 230 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162832 /* 240 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162833 /* 250 */ 1233, 1233, 1233, 1233, 1233, 1233, 1340, 1233, 1233, 1233,
162834 /* 260 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1583, 1233,
162835 /* 270 */ 1496, 1322, 1340, 1340, 1340, 1340, 1342, 1323, 1321, 1334,
162836 /* 280 */ 1267, 1240, 1629, 1400, 1389, 1341, 1363, 1389, 1363, 1626,
162837 /* 290 */ 1387, 1400, 1400, 1387, 1400, 1341, 1626, 1283, 1606, 1278,
162838 /* 300 */ 1374, 1374, 1374, 1363, 1368, 1368, 1463, 1341, 1334, 1233,
162839 /* 310 */ 1629, 1629, 1349, 1349, 1628, 1628, 1349, 1484, 1613, 1409,
162840 /* 320 */ 1311, 1317, 1317, 1317, 1317, 1349, 1251, 1387, 1613, 1613,
162841 /* 330 */ 1387, 1409, 1311, 1387, 1311, 1387, 1349, 1251, 1500, 1623,
162842 /* 340 */ 1349, 1251, 1474, 1349, 1251, 1349, 1251, 1474, 1309, 1309,
162843 /* 350 */ 1309, 1298, 1233, 1233, 1474, 1309, 1283, 1309, 1298, 1309,
162844 /* 360 */ 1309, 1572, 1233, 1478, 1478, 1474, 1367, 1362, 1367, 1362,
162845 /* 370 */ 1367, 1362, 1367, 1362, 1349, 1564, 1564, 1377, 1377, 1382,
162846 /* 380 */ 1368, 1469, 1349, 1233, 1382, 1380, 1378, 1387, 1301, 1586,
162847 /* 390 */ 1586, 1582, 1582, 1582, 1634, 1634, 1533, 1599, 1266, 1266,
162848 /* 400 */ 1266, 1266, 1599, 1285, 1285, 1267, 1267, 1266, 1599, 1233,
162849 /* 410 */ 1233, 1233, 1233, 1233, 1233, 1594, 1233, 1528, 1485, 1353,
162850 /* 420 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162851 /* 430 */ 1233, 1233, 1233, 1233, 1539, 1233, 1233, 1233, 1233, 1233,
162852 /* 440 */ 1233, 1233, 1233, 1233, 1233, 1414, 1233, 1236, 1530, 1233,
162853 /* 450 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1391, 1392, 1354,
162854 /* 460 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1406, 1233, 1233,
162855 /* 470 */ 1233, 1401, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162856 /* 480 */ 1625, 1233, 1233, 1233, 1233, 1233, 1233, 1499, 1498, 1233,
162857 /* 490 */ 1233, 1351, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162858 /* 500 */ 1233, 1233, 1233, 1233, 1233, 1281, 1233, 1233, 1233, 1233,
162859 /* 510 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162860 /* 520 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1379,
162861 /* 530 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162862 /* 540 */ 1233, 1233, 1233, 1233, 1569, 1369, 1233, 1233, 1616, 1233,
162863 /* 550 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
162864 /* 560 */ 1233, 1233, 1233, 1610, 1325, 1416, 1233, 1415, 1419, 1255,
162865 /* 570 */ 1233, 1245, 1233, 1233,
162866 };
162867 /********** End of lemon-generated parsing tables *****************************/
162868
162869 /* The next table maps tokens (terminal symbols) into fallback tokens.
162870 ** If a construct like the following:
@@ -163412,16 +164579,16 @@
163412 /* 254 */ "sclp",
163413 /* 255 */ "as",
163414 /* 256 */ "seltablist",
163415 /* 257 */ "stl_prefix",
163416 /* 258 */ "joinop",
163417 /* 259 */ "indexed_opt",
163418 /* 260 */ "on_opt",
163419 /* 261 */ "using_opt",
163420 /* 262 */ "exprlist",
163421 /* 263 */ "xfullname",
163422 /* 264 */ "idlist",
163423 /* 265 */ "nulls",
163424 /* 266 */ "with",
163425 /* 267 */ "where_opt_ret",
163426 /* 268 */ "setlist",
163427 /* 269 */ "insert_cmd",
@@ -163588,33 +164755,33 @@
163588 /* 104 */ "as ::=",
163589 /* 105 */ "from ::=",
163590 /* 106 */ "from ::= FROM seltablist",
163591 /* 107 */ "stl_prefix ::= seltablist joinop",
163592 /* 108 */ "stl_prefix ::=",
163593 /* 109 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
163594 /* 110 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt",
163595 /* 111 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
163596 /* 112 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
163597 /* 113 */ "dbnm ::=",
163598 /* 114 */ "dbnm ::= DOT nm",
163599 /* 115 */ "fullname ::= nm",
163600 /* 116 */ "fullname ::= nm DOT nm",
163601 /* 117 */ "xfullname ::= nm",
163602 /* 118 */ "xfullname ::= nm DOT nm",
163603 /* 119 */ "xfullname ::= nm DOT nm AS nm",
163604 /* 120 */ "xfullname ::= nm AS nm",
163605 /* 121 */ "joinop ::= COMMA|JOIN",
163606 /* 122 */ "joinop ::= JOIN_KW JOIN",
163607 /* 123 */ "joinop ::= JOIN_KW nm JOIN",
163608 /* 124 */ "joinop ::= JOIN_KW nm nm JOIN",
163609 /* 125 */ "on_opt ::= ON expr",
163610 /* 126 */ "on_opt ::=",
163611 /* 127 */ "indexed_opt ::=",
163612 /* 128 */ "indexed_opt ::= INDEXED BY nm",
163613 /* 129 */ "indexed_opt ::= NOT INDEXED",
163614 /* 130 */ "using_opt ::= USING LP idlist RP",
163615 /* 131 */ "using_opt ::=",
163616 /* 132 */ "orderby_opt ::=",
163617 /* 133 */ "orderby_opt ::= ORDER BY sortlist",
163618 /* 134 */ "sortlist ::= sortlist COMMA expr sortorder nulls",
163619 /* 135 */ "sortlist ::= expr sortorder nulls",
163620 /* 136 */ "sortorder ::= ASC",
@@ -163856,35 +165023,36 @@
163856 /* 372 */ "resolvetype ::= raisetype",
163857 /* 373 */ "selectnowith ::= oneselect",
163858 /* 374 */ "oneselect ::= values",
163859 /* 375 */ "sclp ::= selcollist COMMA",
163860 /* 376 */ "as ::= ID|STRING",
163861 /* 377 */ "returning ::=",
163862 /* 378 */ "expr ::= term",
163863 /* 379 */ "likeop ::= LIKE_KW|MATCH",
163864 /* 380 */ "exprlist ::= nexprlist",
163865 /* 381 */ "nmnum ::= plus_num",
163866 /* 382 */ "nmnum ::= nm",
163867 /* 383 */ "nmnum ::= ON",
163868 /* 384 */ "nmnum ::= DELETE",
163869 /* 385 */ "nmnum ::= DEFAULT",
163870 /* 386 */ "plus_num ::= INTEGER|FLOAT",
163871 /* 387 */ "foreach_clause ::=",
163872 /* 388 */ "foreach_clause ::= FOR EACH ROW",
163873 /* 389 */ "trnm ::= nm",
163874 /* 390 */ "tridxby ::=",
163875 /* 391 */ "database_kw_opt ::= DATABASE",
163876 /* 392 */ "database_kw_opt ::=",
163877 /* 393 */ "kwcolumn_opt ::=",
163878 /* 394 */ "kwcolumn_opt ::= COLUMNKW",
163879 /* 395 */ "vtabarglist ::= vtabarg",
163880 /* 396 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
163881 /* 397 */ "vtabarg ::= vtabarg vtabargtoken",
163882 /* 398 */ "anylist ::=",
163883 /* 399 */ "anylist ::= anylist LP anylist RP",
163884 /* 400 */ "anylist ::= anylist ANY",
163885 /* 401 */ "with ::=",
 
163886 };
163887 #endif /* NDEBUG */
163888
163889
163890 #if YYSTACKDEPTH<=0
@@ -164018,11 +165186,10 @@
164018 break;
164019 case 216: /* term */
164020 case 217: /* expr */
164021 case 246: /* where_opt */
164022 case 248: /* having_opt */
164023 case 260: /* on_opt */
164024 case 267: /* where_opt_ret */
164025 case 278: /* case_operand */
164026 case 280: /* case_else */
164027 case 283: /* vinto */
164028 case 290: /* when_clause */
@@ -164038,11 +165205,11 @@
164038 case 244: /* selcollist */
164039 case 247: /* groupby_opt */
164040 case 249: /* orderby_opt */
164041 case 253: /* nexprlist */
164042 case 254: /* sclp */
164043 case 262: /* exprlist */
164044 case 268: /* setlist */
164045 case 277: /* paren_exprlist */
164046 case 279: /* case_exprlist */
164047 case 310: /* part_opt */
164048 {
@@ -164051,11 +165218,11 @@
164051 break;
164052 case 238: /* fullname */
164053 case 245: /* from */
164054 case 256: /* seltablist */
164055 case 257: /* stl_prefix */
164056 case 263: /* xfullname */
164057 {
164058 sqlite3SrcListDelete(pParse->db, (yypminor->yy131));
164059 }
164060 break;
164061 case 241: /* wqlist */
@@ -164067,12 +165234,11 @@
164067 case 306: /* windowdefn_list */
164068 {
164069 sqlite3WindowListDelete(pParse->db, (yypminor->yy41));
164070 }
164071 break;
164072 case 261: /* using_opt */
164073 case 264: /* idlist */
164074 case 270: /* idlist_opt */
164075 {
164076 sqlite3IdListDelete(pParse->db, (yypminor->yy254));
164077 }
164078 break;
@@ -164498,33 +165664,33 @@
164498 255, /* (104) as ::= */
164499 245, /* (105) from ::= */
164500 245, /* (106) from ::= FROM seltablist */
164501 257, /* (107) stl_prefix ::= seltablist joinop */
164502 257, /* (108) stl_prefix ::= */
164503 256, /* (109) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
164504 256, /* (110) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
164505 256, /* (111) seltablist ::= stl_prefix LP select RP as on_opt using_opt */
164506 256, /* (112) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
164507 200, /* (113) dbnm ::= */
164508 200, /* (114) dbnm ::= DOT nm */
164509 238, /* (115) fullname ::= nm */
164510 238, /* (116) fullname ::= nm DOT nm */
164511 263, /* (117) xfullname ::= nm */
164512 263, /* (118) xfullname ::= nm DOT nm */
164513 263, /* (119) xfullname ::= nm DOT nm AS nm */
164514 263, /* (120) xfullname ::= nm AS nm */
164515 258, /* (121) joinop ::= COMMA|JOIN */
164516 258, /* (122) joinop ::= JOIN_KW JOIN */
164517 258, /* (123) joinop ::= JOIN_KW nm JOIN */
164518 258, /* (124) joinop ::= JOIN_KW nm nm JOIN */
164519 260, /* (125) on_opt ::= ON expr */
164520 260, /* (126) on_opt ::= */
164521 259, /* (127) indexed_opt ::= */
164522 259, /* (128) indexed_opt ::= INDEXED BY nm */
164523 259, /* (129) indexed_opt ::= NOT INDEXED */
164524 261, /* (130) using_opt ::= USING LP idlist RP */
164525 261, /* (131) using_opt ::= */
164526 249, /* (132) orderby_opt ::= */
164527 249, /* (133) orderby_opt ::= ORDER BY sortlist */
164528 231, /* (134) sortlist ::= sortlist COMMA expr sortorder nulls */
164529 231, /* (135) sortlist ::= expr sortorder nulls */
164530 219, /* (136) sortorder ::= ASC */
@@ -164564,12 +165730,12 @@
164564 272, /* (170) returning ::= RETURNING selcollist */
164565 269, /* (171) insert_cmd ::= INSERT orconf */
164566 269, /* (172) insert_cmd ::= REPLACE */
164567 270, /* (173) idlist_opt ::= */
164568 270, /* (174) idlist_opt ::= LP idlist RP */
164569 264, /* (175) idlist ::= idlist COMMA nm */
164570 264, /* (176) idlist ::= nm */
164571 217, /* (177) expr ::= LP expr RP */
164572 217, /* (178) expr ::= ID|INDEXED */
164573 217, /* (179) expr ::= JOIN_KW */
164574 217, /* (180) expr ::= nm DOT nm */
164575 217, /* (181) expr ::= nm DOT nm DOT nm */
@@ -164619,11 +165785,11 @@
164619 279, /* (225) case_exprlist ::= WHEN expr THEN expr */
164620 280, /* (226) case_else ::= ELSE expr */
164621 280, /* (227) case_else ::= */
164622 278, /* (228) case_operand ::= expr */
164623 278, /* (229) case_operand ::= */
164624 262, /* (230) exprlist ::= */
164625 253, /* (231) nexprlist ::= nexprlist COMMA expr */
164626 253, /* (232) nexprlist ::= expr */
164627 277, /* (233) paren_exprlist ::= */
164628 277, /* (234) paren_exprlist ::= LP exprlist RP */
164629 190, /* (235) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
@@ -164766,35 +165932,36 @@
164766 235, /* (372) resolvetype ::= raisetype */
164767 239, /* (373) selectnowith ::= oneselect */
164768 240, /* (374) oneselect ::= values */
164769 254, /* (375) sclp ::= selcollist COMMA */
164770 255, /* (376) as ::= ID|STRING */
164771 272, /* (377) returning ::= */
164772 217, /* (378) expr ::= term */
164773 274, /* (379) likeop ::= LIKE_KW|MATCH */
164774 262, /* (380) exprlist ::= nexprlist */
164775 284, /* (381) nmnum ::= plus_num */
164776 284, /* (382) nmnum ::= nm */
164777 284, /* (383) nmnum ::= ON */
164778 284, /* (384) nmnum ::= DELETE */
164779 284, /* (385) nmnum ::= DEFAULT */
164780 211, /* (386) plus_num ::= INTEGER|FLOAT */
164781 289, /* (387) foreach_clause ::= */
164782 289, /* (388) foreach_clause ::= FOR EACH ROW */
164783 292, /* (389) trnm ::= nm */
164784 293, /* (390) tridxby ::= */
164785 294, /* (391) database_kw_opt ::= DATABASE */
164786 294, /* (392) database_kw_opt ::= */
164787 297, /* (393) kwcolumn_opt ::= */
164788 297, /* (394) kwcolumn_opt ::= COLUMNKW */
164789 299, /* (395) vtabarglist ::= vtabarg */
164790 299, /* (396) vtabarglist ::= vtabarglist COMMA vtabarg */
164791 300, /* (397) vtabarg ::= vtabarg vtabargtoken */
164792 303, /* (398) anylist ::= */
164793 303, /* (399) anylist ::= anylist LP anylist RP */
164794 303, /* (400) anylist ::= anylist ANY */
164795 266, /* (401) with ::= */
 
164796 };
164797
164798 /* For rule J, yyRuleInfoNRhs[J] contains the negative of the number
164799 ** of symbols on the right-hand side of that rule. */
164800 static const signed char yyRuleInfoNRhs[] = {
@@ -164905,33 +166072,33 @@
164905 0, /* (104) as ::= */
164906 0, /* (105) from ::= */
164907 -2, /* (106) from ::= FROM seltablist */
164908 -2, /* (107) stl_prefix ::= seltablist joinop */
164909 0, /* (108) stl_prefix ::= */
164910 -7, /* (109) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
164911 -9, /* (110) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
164912 -7, /* (111) seltablist ::= stl_prefix LP select RP as on_opt using_opt */
164913 -7, /* (112) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
164914 0, /* (113) dbnm ::= */
164915 -2, /* (114) dbnm ::= DOT nm */
164916 -1, /* (115) fullname ::= nm */
164917 -3, /* (116) fullname ::= nm DOT nm */
164918 -1, /* (117) xfullname ::= nm */
164919 -3, /* (118) xfullname ::= nm DOT nm */
164920 -5, /* (119) xfullname ::= nm DOT nm AS nm */
164921 -3, /* (120) xfullname ::= nm AS nm */
164922 -1, /* (121) joinop ::= COMMA|JOIN */
164923 -2, /* (122) joinop ::= JOIN_KW JOIN */
164924 -3, /* (123) joinop ::= JOIN_KW nm JOIN */
164925 -4, /* (124) joinop ::= JOIN_KW nm nm JOIN */
164926 -2, /* (125) on_opt ::= ON expr */
164927 0, /* (126) on_opt ::= */
164928 0, /* (127) indexed_opt ::= */
164929 -3, /* (128) indexed_opt ::= INDEXED BY nm */
164930 -2, /* (129) indexed_opt ::= NOT INDEXED */
164931 -4, /* (130) using_opt ::= USING LP idlist RP */
164932 0, /* (131) using_opt ::= */
164933 0, /* (132) orderby_opt ::= */
164934 -3, /* (133) orderby_opt ::= ORDER BY sortlist */
164935 -5, /* (134) sortlist ::= sortlist COMMA expr sortorder nulls */
164936 -3, /* (135) sortlist ::= expr sortorder nulls */
164937 -1, /* (136) sortorder ::= ASC */
@@ -165173,35 +166340,36 @@
165173 -1, /* (372) resolvetype ::= raisetype */
165174 -1, /* (373) selectnowith ::= oneselect */
165175 -1, /* (374) oneselect ::= values */
165176 -2, /* (375) sclp ::= selcollist COMMA */
165177 -1, /* (376) as ::= ID|STRING */
165178 0, /* (377) returning ::= */
165179 -1, /* (378) expr ::= term */
165180 -1, /* (379) likeop ::= LIKE_KW|MATCH */
165181 -1, /* (380) exprlist ::= nexprlist */
165182 -1, /* (381) nmnum ::= plus_num */
165183 -1, /* (382) nmnum ::= nm */
165184 -1, /* (383) nmnum ::= ON */
165185 -1, /* (384) nmnum ::= DELETE */
165186 -1, /* (385) nmnum ::= DEFAULT */
165187 -1, /* (386) plus_num ::= INTEGER|FLOAT */
165188 0, /* (387) foreach_clause ::= */
165189 -3, /* (388) foreach_clause ::= FOR EACH ROW */
165190 -1, /* (389) trnm ::= nm */
165191 0, /* (390) tridxby ::= */
165192 -1, /* (391) database_kw_opt ::= DATABASE */
165193 0, /* (392) database_kw_opt ::= */
165194 0, /* (393) kwcolumn_opt ::= */
165195 -1, /* (394) kwcolumn_opt ::= COLUMNKW */
165196 -1, /* (395) vtabarglist ::= vtabarg */
165197 -3, /* (396) vtabarglist ::= vtabarglist COMMA vtabarg */
165198 -2, /* (397) vtabarg ::= vtabarg vtabargtoken */
165199 0, /* (398) anylist ::= */
165200 -4, /* (399) anylist ::= anylist LP anylist RP */
165201 -2, /* (400) anylist ::= anylist ANY */
165202 0, /* (401) with ::= */
 
165203 };
165204
165205 static void yy_accept(yyParser*); /* Forward Declaration */
165206
165207 /*
@@ -165565,11 +166733,11 @@
165565 if( pRhs && pRhs->pPrior ){
165566 SrcList *pFrom;
165567 Token x;
165568 x.n = 0;
165569 parserDoubleLinkSelect(pParse, pRhs);
165570 pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0);
165571 pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0);
165572 }
165573 if( pRhs ){
165574 pRhs->op = (u8)yymsp[-1].minor.yy394;
165575 pRhs->pPrior = pLhs;
@@ -165657,11 +166825,11 @@
165657 Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
165658 yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, pDot);
165659 }
165660 break;
165661 case 103: /* as ::= AS nm */
165662 case 114: /* dbnm ::= DOT nm */ yytestcase(yyruleno==114);
165663 case 254: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==254);
165664 case 255: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==255);
165665 {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
165666 break;
165667 case 105: /* from ::= */
@@ -165669,144 +166837,136 @@
165669 {yymsp[1].minor.yy131 = 0;}
165670 break;
165671 case 106: /* from ::= FROM seltablist */
165672 {
165673 yymsp[-1].minor.yy131 = yymsp[0].minor.yy131;
165674 sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy131);
165675 }
165676 break;
165677 case 107: /* stl_prefix ::= seltablist joinop */
165678 {
165679 if( ALWAYS(yymsp[-1].minor.yy131 && yymsp[-1].minor.yy131->nSrc>0) ) yymsp[-1].minor.yy131->a[yymsp[-1].minor.yy131->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy394;
165680 }
165681 break;
165682 case 109: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
165683 {
165684 yymsp[-6].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy131,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy528,yymsp[0].minor.yy254);
165685 sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy131, &yymsp[-2].minor.yy0);
165686 }
165687 break;
165688 case 110: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
165689 {
165690 yymsp[-8].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy131,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy528,yymsp[0].minor.yy254);
165691 sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy131, yymsp[-4].minor.yy322);
165692 }
165693 break;
165694 case 111: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
165695 {
165696 yymsp[-6].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy131,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy47,yymsp[-1].minor.yy528,yymsp[0].minor.yy254);
165697 }
165698 break;
165699 case 112: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
165700 {
165701 if( yymsp[-6].minor.yy131==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy528==0 && yymsp[0].minor.yy254==0 ){
165702 yymsp[-6].minor.yy131 = yymsp[-4].minor.yy131;
165703 }else if( yymsp[-4].minor.yy131->nSrc==1 ){
165704 yymsp[-6].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy131,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy528,yymsp[0].minor.yy254);
165705 if( yymsp[-6].minor.yy131 ){
165706 SrcItem *pNew = &yymsp[-6].minor.yy131->a[yymsp[-6].minor.yy131->nSrc-1];
165707 SrcItem *pOld = yymsp[-4].minor.yy131->a;
 
 
 
 
 
165708 pNew->zName = pOld->zName;
165709 pNew->zDatabase = pOld->zDatabase;
165710 pNew->pSelect = pOld->pSelect;
 
 
 
165711 if( pOld->fg.isTabFunc ){
165712 pNew->u1.pFuncArg = pOld->u1.pFuncArg;
165713 pOld->u1.pFuncArg = 0;
165714 pOld->fg.isTabFunc = 0;
165715 pNew->fg.isTabFunc = 1;
165716 }
165717 pOld->zName = pOld->zDatabase = 0;
165718 pOld->pSelect = 0;
165719 }
165720 sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy131);
165721 }else{
165722 Select *pSubquery;
165723 sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy131);
165724 pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy131,0,0,0,0,SF_NestedFrom,0);
165725 yymsp[-6].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy131,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy528,yymsp[0].minor.yy254);
165726 }
165727 }
165728 break;
165729 case 113: /* dbnm ::= */
165730 case 127: /* indexed_opt ::= */ yytestcase(yyruleno==127);
165731 {yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;}
165732 break;
165733 case 115: /* fullname ::= nm */
165734 {
165735 yylhsminor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0);
165736 if( IN_RENAME_OBJECT && yylhsminor.yy131 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy131->a[0].zName, &yymsp[0].minor.yy0);
165737 }
165738 yymsp[0].minor.yy131 = yylhsminor.yy131;
165739 break;
165740 case 116: /* fullname ::= nm DOT nm */
165741 {
165742 yylhsminor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
165743 if( IN_RENAME_OBJECT && yylhsminor.yy131 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy131->a[0].zName, &yymsp[0].minor.yy0);
165744 }
165745 yymsp[-2].minor.yy131 = yylhsminor.yy131;
165746 break;
165747 case 117: /* xfullname ::= nm */
165748 {yymsp[0].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/}
165749 break;
165750 case 118: /* xfullname ::= nm DOT nm */
165751 {yymsp[-2].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/}
165752 break;
165753 case 119: /* xfullname ::= nm DOT nm AS nm */
165754 {
165755 yymsp[-4].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/
165756 if( yymsp[-4].minor.yy131 ) yymsp[-4].minor.yy131->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
165757 }
165758 break;
165759 case 120: /* xfullname ::= nm AS nm */
165760 {
165761 yymsp[-2].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/
165762 if( yymsp[-2].minor.yy131 ) yymsp[-2].minor.yy131->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
165763 }
165764 break;
165765 case 121: /* joinop ::= COMMA|JOIN */
165766 { yymsp[0].minor.yy394 = JT_INNER; }
165767 break;
165768 case 122: /* joinop ::= JOIN_KW JOIN */
165769 {yymsp[-1].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/}
165770 break;
165771 case 123: /* joinop ::= JOIN_KW nm JOIN */
165772 {yymsp[-2].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/}
165773 break;
165774 case 124: /* joinop ::= JOIN_KW nm nm JOIN */
165775 {yymsp[-3].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
165776 break;
165777 case 125: /* on_opt ::= ON expr */
165778 case 145: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==145);
165779 case 152: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==152);
165780 case 154: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==154);
165781 case 226: /* case_else ::= ELSE expr */ yytestcase(yyruleno==226);
165782 case 247: /* vinto ::= INTO expr */ yytestcase(yyruleno==247);
165783 {yymsp[-1].minor.yy528 = yymsp[0].minor.yy528;}
165784 break;
165785 case 126: /* on_opt ::= */
165786 case 144: /* having_opt ::= */ yytestcase(yyruleno==144);
165787 case 146: /* limit_opt ::= */ yytestcase(yyruleno==146);
165788 case 151: /* where_opt ::= */ yytestcase(yyruleno==151);
165789 case 153: /* where_opt_ret ::= */ yytestcase(yyruleno==153);
165790 case 227: /* case_else ::= */ yytestcase(yyruleno==227);
165791 case 229: /* case_operand ::= */ yytestcase(yyruleno==229);
165792 case 248: /* vinto ::= */ yytestcase(yyruleno==248);
165793 {yymsp[1].minor.yy528 = 0;}
165794 break;
165795 case 128: /* indexed_opt ::= INDEXED BY nm */
165796 {yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;}
165797 break;
165798 case 129: /* indexed_opt ::= NOT INDEXED */
165799 {yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;}
165800 break;
165801 case 130: /* using_opt ::= USING LP idlist RP */
165802 {yymsp[-3].minor.yy254 = yymsp[-1].minor.yy254;}
165803 break;
165804 case 131: /* using_opt ::= */
165805 case 173: /* idlist_opt ::= */ yytestcase(yyruleno==173);
165806 {yymsp[1].minor.yy254 = 0;}
165807 break;
165808 case 133: /* orderby_opt ::= ORDER BY sortlist */
165809 case 143: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==143);
165810 {yymsp[-2].minor.yy322 = yymsp[0].minor.yy322;}
165811 break;
165812 case 134: /* sortlist ::= sortlist COMMA expr sortorder nulls */
@@ -165835,10 +166995,26 @@
165835 {yymsp[-1].minor.yy394 = SQLITE_SO_ASC;}
165836 break;
165837 case 140: /* nulls ::= NULLS LAST */
165838 {yymsp[-1].minor.yy394 = SQLITE_SO_DESC;}
165839 break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165840 case 147: /* limit_opt ::= LIMIT expr */
165841 {yymsp[-1].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy528,0);}
165842 break;
165843 case 148: /* limit_opt ::= LIMIT expr OFFSET expr */
165844 {yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);}
@@ -165917,10 +167093,13 @@
165917 case 169: /* upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */
165918 { yymsp[-7].minor.yy444 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528,0);}
165919 break;
165920 case 170: /* returning ::= RETURNING selcollist */
165921 {sqlite3AddReturning(pParse,yymsp[0].minor.yy322);}
 
 
 
165922 break;
165923 case 174: /* idlist_opt ::= LP idlist RP */
165924 {yymsp[-2].minor.yy254 = yymsp[-1].minor.yy254;}
165925 break;
165926 case 175: /* idlist ::= idlist COMMA nm */
@@ -166693,35 +167872,36 @@
166693 /* (372) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=372);
166694 /* (373) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=373);
166695 /* (374) oneselect ::= values */ yytestcase(yyruleno==374);
166696 /* (375) sclp ::= selcollist COMMA */ yytestcase(yyruleno==375);
166697 /* (376) as ::= ID|STRING */ yytestcase(yyruleno==376);
166698 /* (377) returning ::= */ yytestcase(yyruleno==377);
166699 /* (378) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=378);
166700 /* (379) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==379);
166701 /* (380) exprlist ::= nexprlist */ yytestcase(yyruleno==380);
166702 /* (381) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=381);
166703 /* (382) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=382);
166704 /* (383) nmnum ::= ON */ yytestcase(yyruleno==383);
166705 /* (384) nmnum ::= DELETE */ yytestcase(yyruleno==384);
166706 /* (385) nmnum ::= DEFAULT */ yytestcase(yyruleno==385);
166707 /* (386) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==386);
166708 /* (387) foreach_clause ::= */ yytestcase(yyruleno==387);
166709 /* (388) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==388);
166710 /* (389) trnm ::= nm */ yytestcase(yyruleno==389);
166711 /* (390) tridxby ::= */ yytestcase(yyruleno==390);
166712 /* (391) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==391);
166713 /* (392) database_kw_opt ::= */ yytestcase(yyruleno==392);
166714 /* (393) kwcolumn_opt ::= */ yytestcase(yyruleno==393);
166715 /* (394) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==394);
166716 /* (395) vtabarglist ::= vtabarg */ yytestcase(yyruleno==395);
166717 /* (396) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==396);
166718 /* (397) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==397);
166719 /* (398) anylist ::= */ yytestcase(yyruleno==398);
166720 /* (399) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==399);
166721 /* (400) anylist ::= anylist ANY */ yytestcase(yyruleno==400);
166722 /* (401) with ::= */ yytestcase(yyruleno==401);
 
166723 break;
166724 /********** End reduce actions ************************************************/
166725 };
166726 assert( yyruleno<sizeof(yyRuleInfoLhs)/sizeof(yyRuleInfoLhs[0]) );
166727 yygoto = yyRuleInfoLhs[yyruleno];
@@ -172889,10 +174069,29 @@
172889 */
172890 case SQLITE_TESTCTRL_ASSERT: {
172891 volatile int x = 0;
172892 assert( /*side-effects-ok*/ (x = va_arg(ap,int))!=0 );
172893 rc = x;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172894 break;
172895 }
172896
172897
172898 /*
@@ -173150,23 +174349,23 @@
173150
173151 /* sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, op, ptr)
173152 **
173153 ** "ptr" is a pointer to a u32.
173154 **
173155 ** op==0 Store the current sqlite3SelectTrace in *ptr
173156 ** op==1 Set sqlite3SelectTrace to the value *ptr
173157 ** op==3 Store the current sqlite3WhereTrace in *ptr
173158 ** op==3 Set sqlite3WhereTrace to the value *ptr
173159 */
173160 case SQLITE_TESTCTRL_TRACEFLAGS: {
173161 int opTrace = va_arg(ap, int);
173162 u32 *ptr = va_arg(ap, u32*);
173163 switch( opTrace ){
173164 case 0: *ptr = sqlite3SelectTrace; break;
173165 case 1: sqlite3SelectTrace = *ptr; break;
173166 case 2: *ptr = sqlite3WhereTrace; break;
173167 case 3: sqlite3WhereTrace = *ptr; break;
173168 }
173169 break;
173170 }
173171
173172 /* sqlite3_test_control(SQLITE_TESTCTRL_LOGEST,
@@ -194609,18 +195808,19 @@
194609 i++;
194610 }else{
194611 *pzErr = zPath;
194612 return 0;
194613 }
 
194614 }else{
194615 zKey = zPath;
194616 for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
194617 nKey = i;
194618 }
194619 if( nKey==0 ){
194620 *pzErr = zPath;
194621 return 0;
194622 }
194623 j = 1;
194624 for(;;){
194625 while( j<=pRoot->n ){
194626 if( jsonLabelCompare(pRoot+j, zKey, nKey) ){
@@ -195763,10 +196963,37 @@
195763 }
195764 }
195765 }
195766 return SQLITE_OK;
195767 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195768
195769 /* Append the name of the path for element i to pStr
195770 */
195771 static void jsonEachComputePath(
195772 JsonEachCursor *p, /* The cursor */
@@ -195788,14 +197015,11 @@
195788 testcase( pUp->eU==0 );
195789 jsonPrintf(30, pStr, "[%d]", pUp->u.iKey);
195790 }else{
195791 assert( pUp->eType==JSON_OBJECT );
195792 if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--;
195793 assert( pNode->eType==JSON_STRING );
195794 assert( pNode->jnFlags & JNODE_LABEL );
195795 assert( pNode->eU==1 );
195796 jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1);
195797 }
195798 }
195799
195800 /* Return the value of a column */
195801 static int jsonEachColumn(
@@ -195862,12 +197086,11 @@
195862 jsonAppendChar(&x, '$');
195863 }
195864 if( p->eType==JSON_ARRAY ){
195865 jsonPrintf(30, &x, "[%d]", p->iRowid);
195866 }else if( p->eType==JSON_OBJECT ){
195867 assert( pThis->eU==1 );
195868 jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1);
195869 }
195870 }
195871 jsonResult(&x);
195872 break;
195873 }
@@ -210410,11 +211633,11 @@
210410 && pIdxInfo->aOrderBy[0].iColumn<=0
210411 && pIdxInfo->aOrderBy[0].desc==0
210412 ){
210413 pIdxInfo->orderByConsumed = 1;
210414 }
210415 sqlite3VtabWriteAll(pIdxInfo);
210416 return SQLITE_OK;
210417 }
210418
210419 /*
210420 ** Open a new dbpagevfs cursor.
@@ -223138,10 +224361,13 @@
223138 sqlite3Fts5ParseNearsetFree(pNear);
223139 sqlite3Fts5ParsePhraseFree(pPhrase);
223140 }else{
223141 if( pRet->nPhrase>0 ){
223142 Fts5ExprPhrase *pLast = pRet->apPhrase[pRet->nPhrase-1];
 
 
 
223143 assert( pLast==pParse->apPhrase[pParse->nPhrase-2] );
223144 if( pPhrase->nTerm==0 ){
223145 fts5ExprPhraseFree(pPhrase);
223146 pRet->nPhrase--;
223147 pParse->nPhrase--;
@@ -234754,11 +235980,11 @@
234754 int nArg, /* Number of args */
234755 sqlite3_value **apUnused /* Function arguments */
234756 ){
234757 assert( nArg==0 );
234758 UNUSED_PARAM2(nArg, apUnused);
234759 sqlite3_result_text(pCtx, "fts5: 2022-03-31 11:12:56 f2d9262e4427ab37ba26c004fc7a4790c86c1856d695a6b4ec3e72732ea54c09", -1, SQLITE_TRANSIENT);
234760 }
234761
234762 /*
234763 ** Return true if zName is the extension on one of the shadow tables used
234764 ** by this module.
234765
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -452,11 +452,11 @@
452 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
453 ** [sqlite_version()] and [sqlite_source_id()].
454 */
455 #define SQLITE_VERSION "3.39.0"
456 #define SQLITE_VERSION_NUMBER 3039000
457 #define SQLITE_SOURCE_ID "2022-04-21 19:38:17 f766dff012af0ea3c28a8ce4db850cd0205729a8283bce1e442992aded7c734b"
458
459 /*
460 ** CAPI3REF: Run-Time Library Version Numbers
461 ** KEYWORDS: sqlite3_version sqlite3_sourceid
462 **
@@ -14363,12 +14363,23 @@
14363 #define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)
14364
14365 /*
14366 ** Round up a number to the next larger multiple of 8. This is used
14367 ** to force 8-byte alignment on 64-bit architectures.
14368 **
14369 ** ROUND8() always does the rounding, for any argument.
14370 **
14371 ** ROUND8P() assumes that the argument is already an integer number of
14372 ** pointers in size, and so it is a no-op on systems where the pointer
14373 ** size is 8.
14374 */
14375 #define ROUND8(x) (((x)+7)&~7)
14376 #if SQLITE_PTRSIZE==8
14377 # define ROUND8P(x) (x)
14378 #else
14379 # define ROUND8P(x) (((x)+7)&~7)
14380 #endif
14381
14382 /*
14383 ** Round down to the nearest multiple of 8
14384 */
14385 #define ROUNDDOWN8(x) ((x)&~7)
@@ -14427,26 +14438,27 @@
14438 # undef SQLITE_DEFAULT_MMAP_SIZE
14439 # define SQLITE_DEFAULT_MMAP_SIZE SQLITE_MAX_MMAP_SIZE
14440 #endif
14441
14442 /*
14443 ** TREETRACE_ENABLED will be either 1 or 0 depending on whether or not
14444 ** the Abstract Syntax Tree tracing logic is turned on.
14445 */
14446 #if !defined(SQLITE_AMALGAMATION)
14447 SQLITE_PRIVATE u32 sqlite3TreeTrace;
14448 #endif
14449 #if defined(SQLITE_DEBUG) \
14450 && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_SELECTTRACE) \
14451 || defined(SQLITE_ENABLE_TREETRACE))
14452 # define TREETRACE_ENABLED 1
14453 # define SELECTTRACE(K,P,S,X) \
14454 if(sqlite3TreeTrace&(K)) \
14455 sqlite3DebugPrintf("%u/%d/%p: ",(S)->selId,(P)->addrExplain,(S)),\
14456 sqlite3DebugPrintf X
14457 #else
14458 # define SELECTTRACE(K,P,S,X)
14459 # define TREETRACE_ENABLED 0
14460 #endif
14461
14462 /*
14463 ** Macros for "wheretrace"
14464 */
@@ -14603,10 +14615,11 @@
14615 typedef struct KeyInfo KeyInfo;
14616 typedef struct Lookaside Lookaside;
14617 typedef struct LookasideSlot LookasideSlot;
14618 typedef struct Module Module;
14619 typedef struct NameContext NameContext;
14620 typedef struct OnOrUsing OnOrUsing;
14621 typedef struct Parse Parse;
14622 typedef struct ParseCleanup ParseCleanup;
14623 typedef struct PreUpdate PreUpdate;
14624 typedef struct PrintfArguments PrintfArguments;
14625 typedef struct RenameToken RenameToken;
@@ -15581,14 +15594,14 @@
15594 #define OP_Function 66 /* synopsis: r[P3]=func(r[P2@NP]) */
15595 #define OP_Return 67
15596 #define OP_EndCoroutine 68
15597 #define OP_HaltIfNull 69 /* synopsis: if r[P3]=null halt */
15598 #define OP_Halt 70
15599 #define OP_Integer 71 /* synopsis: r[P2]=P1 */
15600 #define OP_Int64 72 /* synopsis: r[P2]=P4 */
15601 #define OP_String 73 /* synopsis: r[P2]='P4' (len=P1) */
15602 #define OP_BeginSubrtn 74 /* synopsis: r[P2]=NULL */
15603 #define OP_Null 75 /* synopsis: r[P2..P3]=NULL */
15604 #define OP_SoftNull 76 /* synopsis: r[P1]=NULL */
15605 #define OP_Blob 77 /* synopsis: r[P2]=P4 (len=P1) */
15606 #define OP_Variable 78 /* synopsis: r[P2]=parameter(P1,P4) */
15607 #define OP_Move 79 /* synopsis: r[P2@P3]=r[P1@P3] */
@@ -15604,11 +15617,11 @@
15617 #define OP_Permutation 89
15618 #define OP_Compare 90 /* synopsis: r[P1@P3] <-> r[P2@P3] */
15619 #define OP_IsTrue 91 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */
15620 #define OP_ZeroOrNull 92 /* synopsis: r[P2] = 0 OR NULL */
15621 #define OP_Offset 93 /* synopsis: r[P3] = sqlite_offset(P1) */
15622 #define OP_Column 94 /* synopsis: r[P3]=PX cursor P1 column P2 */
15623 #define OP_TypeCheck 95 /* synopsis: typecheck(r[P1@P2]) */
15624 #define OP_Affinity 96 /* synopsis: affinity(r[P1@P2]) */
15625 #define OP_MakeRecord 97 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
15626 #define OP_Count 98 /* synopsis: r[P2]=count() */
15627 #define OP_ReadCookie 99
@@ -15645,11 +15658,11 @@
15658 #define OP_Delete 130
15659 #define OP_ResetCount 131
15660 #define OP_SorterCompare 132 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
15661 #define OP_SorterData 133 /* synopsis: r[P2]=data */
15662 #define OP_RowData 134 /* synopsis: r[P2]=data */
15663 #define OP_Rowid 135 /* synopsis: r[P2]=PX rowid of P1 */
15664 #define OP_NullRow 136
15665 #define OP_SeekEnd 137
15666 #define OP_IdxInsert 138 /* synopsis: key=r[P2] */
15667 #define OP_SorterInsert 139 /* synopsis: key=r[P2] */
15668 #define OP_IdxDelete 140 /* synopsis: key=r[P2@P3] */
@@ -15716,12 +15729,12 @@
15729 /* 24 */ 0x01, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x01,\
15730 /* 32 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
15731 /* 40 */ 0x01, 0x01, 0x01, 0x26, 0x26, 0x23, 0x0b, 0x01,\
15732 /* 48 */ 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\
15733 /* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x01, 0x01,\
15734 /* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\
15735 /* 72 */ 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10, 0x00,\
15736 /* 80 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02,\
15737 /* 88 */ 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20, 0x00, 0x00,\
15738 /* 96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x26, 0x26,\
15739 /* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\
15740 /* 112 */ 0x00, 0x00, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00,\
@@ -15823,11 +15836,10 @@
15836 SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
15837 SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Parse*);
15838 SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*);
15839 SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe*);
15840 SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*);
 
15841 SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,Parse*);
15842 SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe*);
15843 SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int);
15844 SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe*);
15845 #ifdef SQLITE_DEBUG
@@ -17038,10 +17050,11 @@
17050 #define SQLITE_OmitOrderBy 0x00040000 /* Omit pointless ORDER BY */
17051 /* TH3 expects this value ^^^^^^^^^^ to be 0x40000. Coordinate any change */
17052 #define SQLITE_BloomFilter 0x00080000 /* Use a Bloom filter on searches */
17053 #define SQLITE_BloomPulldown 0x00100000 /* Run Bloom filters early */
17054 #define SQLITE_BalancedMerge 0x00200000 /* Balance multi-way merges */
17055 #define SQLITE_ReleaseReg 0x00400000 /* Use OP_ReleaseReg for testing */
17056 #define SQLITE_AllOpts 0xffffffff /* All optimizations */
17057
17058 /*
17059 ** Macros for testing whether or not optimizations are enabled or disabled.
17060 */
@@ -18102,11 +18115,11 @@
18115 ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid.
18116 ** TK_VARIABLE: variable number (always >= 1).
18117 ** TK_SELECT_COLUMN: column of the result vector */
18118 i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
18119 union {
18120 int iJoin; /* If EP_FromJoin, the right table of the join */
18121 int iOfst; /* else: start of token from start of statement */
18122 } w;
18123 AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
18124 union {
18125 Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL
@@ -18145,11 +18158,11 @@
18158 #define EP_IfNullRow 0x020000 /* The TK_IF_NULL_ROW opcode */
18159 #define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
18160 #define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
18161 #define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
18162 #define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
18163 #define EP_InnerJoin 0x400000 /* Originates in ON/USING of an inner join */
18164 #define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
18165 #define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
18166 #define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */
18167 #define EP_Quoted 0x4000000 /* TK_ID was originally quoted */
18168 #define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */
@@ -18262,10 +18275,11 @@
18275 unsigned eEName :2; /* Meaning of zEName */
18276 unsigned done :1; /* A flag to indicate when processing is finished */
18277 unsigned reusable :1; /* Constant expression is reusable */
18278 unsigned bSorterRef :1; /* Defer evaluation until after sorting */
18279 unsigned bNulls: 1; /* True if explicit "NULLS FIRST/LAST" */
18280 unsigned bUsed: 1; /* This column used in a SF_NestedFrom subquery */
18281 union {
18282 struct { /* Used by any ExprList other than Parse.pConsExpr */
18283 u16 iOrderByCol; /* For ORDER BY, column number in result set */
18284 u16 iAlias; /* Index into Parse.aAlias[] for zName */
18285 } x;
@@ -18296,17 +18310,29 @@
18310 ** INSERT INTO t(a,b,c) ...
18311 **
18312 ** If "a" is the k-th column of table "t", then IdList.a[0].idx==k.
18313 */
18314 struct IdList {
18315 int nId; /* Number of identifiers on the list */
18316 u8 eU4; /* Which element of a.u4 is valid */
18317 struct IdList_item {
18318 char *zName; /* Name of the identifier */
18319 union {
18320 int idx; /* Index in some Table.aCol[] of a column named zName */
18321 Expr *pExpr; /* Expr to implement a USING variable -- NOT USED */
18322 } u4;
18323 } a[1];
18324 };
18325
18326 /*
18327 ** Allowed values for IdList.eType, which determines which value of the a.u4
18328 ** is valid.
18329 */
18330 #define EU4_NONE 0 /* Does not use IdList.a.u4 */
18331 #define EU4_IDX 1 /* Uses IdList.a.u4.idx */
18332 #define EU4_EXPR 2 /* Uses IdList.a.u4.pExpr -- NOT CURRENTLY USED */
18333
18334 /*
18335 ** The SrcItem object represents a single term in the FROM clause of a query.
18336 ** The SrcList object is mostly an array of SrcItems.
18337 **
18338 ** Union member validity:
@@ -18335,14 +18361,19 @@
18361 unsigned viaCoroutine :1; /* Implemented as a co-routine */
18362 unsigned isRecursive :1; /* True for recursive reference in WITH */
18363 unsigned fromDDL :1; /* Comes from sqlite_schema */
18364 unsigned isCte :1; /* This is a CTE */
18365 unsigned notCte :1; /* This item may not match a CTE */
18366 unsigned isUsing :1; /* u3.pUsing is valid */
18367 unsigned isSynthUsing :1; /* u3.pUsing is synthensized from NATURAL */
18368 unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */
18369 } fg;
18370 int iCursor; /* The VDBE cursor number used to access this table */
18371 union {
18372 Expr *pOn; /* fg.isUsing==0 => The ON clause of a join */
18373 IdList *pUsing; /* fg.isUsing==1 => The USING clause of a join */
18374 } u3;
18375 Bitmask colUsed; /* Bit N (1<<N) set if column N of pTab is used */
18376 union {
18377 char *zIndexedBy; /* Identifier from "INDEXED BY <zIndex>" clause */
18378 ExprList *pFuncArg; /* Arguments to table-valued-function */
18379 } u1;
@@ -18349,10 +18380,19 @@
18380 union {
18381 Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */
18382 CteUse *pCteUse; /* CTE Usage info info fg.isCte is true */
18383 } u2;
18384 };
18385
18386 /*
18387 ** The OnOrUsing object represents either an ON clause or a USING clause.
18388 ** It can never be both at the same time, but it can be neither.
18389 */
18390 struct OnOrUsing {
18391 Expr *pOn; /* The ON clause of a join */
18392 IdList *pUsing; /* The USING clause of a join */
18393 };
18394
18395 /*
18396 ** The following structure describes the FROM clause of a SELECT statement.
18397 ** Each table or subquery in the FROM clause is a separate element of
18398 ** the SrcList.a[] array.
@@ -18378,18 +18418,19 @@
18418 };
18419
18420 /*
18421 ** Permitted values of the SrcList.a.jointype field
18422 */
18423 #define JT_INNER 0x01 /* Any kind of inner or cross join */
18424 #define JT_CROSS 0x02 /* Explicit use of the CROSS keyword */
18425 #define JT_NATURAL 0x04 /* True for a "natural" join */
18426 #define JT_LEFT 0x08 /* Left outer join */
18427 #define JT_RIGHT 0x10 /* Right outer join */
18428 #define JT_OUTER 0x20 /* The "OUTER" keyword is present */
18429 #define JT_LTORJ 0x40 /* One of the LEFT operands of a RIGHT JOIN
18430 ** Mnemonic: Left Table Of Right Join */
18431 #define JT_ERROR 0x80 /* unknown or unsupported join type */
18432
18433 /*
18434 ** Flags appropriate for the wctrlFlags parameter of sqlite3WhereBegin()
18435 ** and the WhereInfo.wctrlFlags member.
18436 **
@@ -18408,11 +18449,11 @@
18449 #define WHERE_DISTINCTBY 0x0080 /* pOrderby is really a DISTINCT clause */
18450 #define WHERE_WANT_DISTINCT 0x0100 /* All output needs to be distinct */
18451 #define WHERE_SORTBYGROUP 0x0200 /* Support sqlite3WhereIsSorted() */
18452 #define WHERE_AGG_DISTINCT 0x0400 /* Query is "SELECT agg(DISTINCT ...)" */
18453 #define WHERE_ORDERBY_LIMIT 0x0800 /* ORDERBY+LIMIT on the inner loop */
18454 #define WHERE_RIGHT_JOIN 0x1000 /* Processing a RIGHT JOIN */
18455 /* 0x2000 not currently used */
18456 #define WHERE_USE_LIMIT 0x4000 /* Use the LIMIT in cost estimates */
18457 /* 0x8000 not currently used */
18458
18459 /* Allowed return values from sqlite3WhereIsDistinct()
@@ -18604,10 +18645,13 @@
18645 #define SF_PushDown 0x1000000 /* SELECT has be modified by push-down opt */
18646 #define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */
18647 #define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */
18648 #define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */
18649
18650 /* True if S exists and has SF_NestedFrom */
18651 #define IsNestedFrom(S) ((S)!=0 && ((S)->selFlags&SF_NestedFrom)!=0)
18652
18653 /*
18654 ** The results of a SELECT can be distributed in several ways, as defined
18655 ** by one of the following macros. The "SRT" prefix means "SELECT Result
18656 ** Type".
18657 **
@@ -18815,10 +18859,11 @@
18859 u8 mayAbort; /* True if statement may throw an ABORT exception */
18860 u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */
18861 u8 okConstFactor; /* OK to factor out constants */
18862 u8 disableLookaside; /* Number of times lookaside has been disabled */
18863 u8 disableVtab; /* Disable all virtual tables for this parse */
18864 u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */
18865 #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
18866 u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */
18867 #endif
18868 int nRangeReg; /* Size of the temporary register block */
18869 int iRangeReg; /* First register in temporary register block */
@@ -18987,24 +19032,24 @@
19032 #define OPFLAG_AUXDELETE 0x04 /* OP_Delete: index in a DELETE op */
19033 #define OPFLAG_NOCHNG_MAGIC 0x6d /* OP_MakeRecord: serialtype 10 is ok */
19034 #define OPFLAG_PREFORMAT 0x80 /* OP_Insert uses preformatted cell */
19035
19036 /*
19037 ** Each trigger present in the database schema is stored as an instance of
19038 ** struct Trigger.
19039 **
19040 ** Pointers to instances of struct Trigger are stored in two ways.
19041 ** 1. In the "trigHash" hash table (part of the sqlite3* that represents the
19042 ** database). This allows Trigger structures to be retrieved by name.
19043 ** 2. All triggers associated with a single table form a linked list, using the
19044 ** pNext member of struct Trigger. A pointer to the first element of the
19045 ** linked list is stored as the "pTrigger" member of the associated
19046 ** struct Table.
19047 **
19048 ** The "step_list" member points to the first element of a linked list
19049 ** containing the SQL statements specified as the trigger program.
19050 */
19051 struct Trigger {
19052 char *zName; /* The name of the trigger */
19053 char *table; /* The table or view to which the trigger applies */
19054 u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT */
19055 u8 tr_tm; /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
@@ -19027,47 +19072,52 @@
19072 */
19073 #define TRIGGER_BEFORE 1
19074 #define TRIGGER_AFTER 2
19075
19076 /*
19077 ** An instance of struct TriggerStep is used to store a single SQL statement
19078 ** that is a part of a trigger-program.
19079 **
19080 ** Instances of struct TriggerStep are stored in a singly linked list (linked
19081 ** using the "pNext" member) referenced by the "step_list" member of the
19082 ** associated struct Trigger instance. The first element of the linked list is
19083 ** the first step of the trigger-program.
19084 **
19085 ** The "op" member indicates whether this is a "DELETE", "INSERT", "UPDATE" or
19086 ** "SELECT" statement. The meanings of the other members is determined by the
19087 ** value of "op" as follows:
19088 **
19089 ** (op == TK_INSERT)
19090 ** orconf -> stores the ON CONFLICT algorithm
19091 ** pSelect -> The content to be inserted - either a SELECT statement or
19092 ** a VALUES clause.
19093 ** zTarget -> Dequoted name of the table to insert into.
19094 ** pIdList -> If this is an INSERT INTO ... (<column-names>) VALUES ...
19095 ** statement, then this stores the column-names to be
19096 ** inserted into.
19097 ** pUpsert -> The ON CONFLICT clauses for an Upsert
19098 **
19099 ** (op == TK_DELETE)
19100 ** zTarget -> Dequoted name of the table to delete from.
19101 ** pWhere -> The WHERE clause of the DELETE statement if one is specified.
19102 ** Otherwise NULL.
19103 **
19104 ** (op == TK_UPDATE)
19105 ** zTarget -> Dequoted name of the table to update.
19106 ** pWhere -> The WHERE clause of the UPDATE statement if one is specified.
19107 ** Otherwise NULL.
19108 ** pExprList -> A list of the columns to update and the expressions to update
19109 ** them to. See sqlite3Update() documentation of "pChanges"
19110 ** argument.
19111 **
19112 ** (op == TK_SELECT)
19113 ** pSelect -> The SELECT statement
19114 **
19115 ** (op == TK_RETURNING)
19116 ** pExprList -> The list of expressions that follow the RETURNING keyword.
19117 **
19118 */
19119 struct TriggerStep {
19120 u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT,
19121 ** or TK_RETURNING */
19122 u8 orconf; /* OE_Rollback etc. */
19123 Trigger *pTrig; /* The trigger that this step is a part of */
@@ -19673,22 +19723,54 @@
19723 #if defined(SQLITE_TEST)
19724 SQLITE_PRIVATE void *sqlite3TestTextToPtr(const char*);
19725 #endif
19726
19727 #if defined(SQLITE_DEBUG)
19728 SQLITE_PRIVATE void sqlite3TreeViewLine(TreeView*, const char *zFormat, ...);
19729 SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView*, const Expr*, u8);
19730 SQLITE_PRIVATE void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*);
19731 SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*);
19732 SQLITE_PRIVATE void sqlite3TreeViewBareIdList(TreeView*, const IdList*, const char*);
19733 SQLITE_PRIVATE void sqlite3TreeViewIdList(TreeView*, const IdList*, u8, const char*);
19734 SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView*, const SrcList*);
19735 SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8);
19736 SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView*, const With*, u8);
19737 SQLITE_PRIVATE void sqlite3TreeViewUpsert(TreeView*, const Upsert*, u8);
19738 SQLITE_PRIVATE void sqlite3TreeViewDelete(const With*, const SrcList*, const Expr*,
19739 const ExprList*,const Expr*, const Trigger*);
19740 SQLITE_PRIVATE void sqlite3TreeViewInsert(const With*, const SrcList*,
19741 const IdList*, const Select*, const ExprList*,
19742 int, const Upsert*, const Trigger*);
19743 SQLITE_PRIVATE void sqlite3TreeViewUpdate(const With*, const SrcList*, const ExprList*,
19744 const Expr*, int, const ExprList*, const Expr*,
19745 const Upsert*, const Trigger*);
19746 #ifndef SQLITE_OMIT_TRIGGER
19747 SQLITE_PRIVATE void sqlite3TreeViewTriggerStep(TreeView*, const TriggerStep*, u8, u8);
19748 SQLITE_PRIVATE void sqlite3TreeViewTrigger(TreeView*, const Trigger*, u8, u8);
19749 #endif
19750 #ifndef SQLITE_OMIT_WINDOWFUNC
19751 SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView*, const Window*, u8);
19752 SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8);
19753 #endif
19754 SQLITE_PRIVATE void sqlite3ShowExpr(const Expr*);
19755 SQLITE_PRIVATE void sqlite3ShowExprList(const ExprList*);
19756 SQLITE_PRIVATE void sqlite3ShowIdList(const IdList*);
19757 SQLITE_PRIVATE void sqlite3ShowSrcList(const SrcList*);
19758 SQLITE_PRIVATE void sqlite3ShowSelect(const Select*);
19759 SQLITE_PRIVATE void sqlite3ShowWith(const With*);
19760 SQLITE_PRIVATE void sqlite3ShowUpsert(const Upsert*);
19761 #ifndef SQLITE_OMIT_TRIGGER
19762 SQLITE_PRIVATE void sqlite3ShowTriggerStep(const TriggerStep*);
19763 SQLITE_PRIVATE void sqlite3ShowTriggerStepList(const TriggerStep*);
19764 SQLITE_PRIVATE void sqlite3ShowTrigger(const Trigger*);
19765 SQLITE_PRIVATE void sqlite3ShowTriggerList(const Trigger*);
19766 #endif
19767 #ifndef SQLITE_OMIT_WINDOWFUNC
19768 SQLITE_PRIVATE void sqlite3ShowWindow(const Window*);
19769 SQLITE_PRIVATE void sqlite3ShowWinFunc(const Window*);
19770 #endif
19771 #endif
19772
19773 SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*);
19774 SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...);
19775 SQLITE_PRIVATE int sqlite3ErrorToParser(sqlite3*,int);
19776 SQLITE_PRIVATE void sqlite3Dequote(char*);
@@ -19833,17 +19915,18 @@
19915 SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*);
19916 SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(Parse*, SrcList*, int, int);
19917 SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2);
19918 SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*);
19919 SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*,
19920 Token*, Select*, OnOrUsing*);
19921 SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *);
19922 SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*);
19923 SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, SrcItem *);
19924 SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(Parse*,SrcList*);
19925 SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*);
19926 SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*);
19927 SQLITE_PRIVATE void sqlite3ClearOnOrUsing(sqlite3*, OnOrUsing*);
19928 SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*);
19929 SQLITE_PRIVATE Index *sqlite3AllocateIndexObject(sqlite3*,i16,int,char**);
19930 SQLITE_PRIVATE void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
19931 Expr*, int, int, u8);
19932 SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
@@ -20036,11 +20119,12 @@
20119 # define sqlite3TriggerStepSrc(A,B) 0
20120 #endif
20121
20122 SQLITE_PRIVATE int sqlite3JoinType(Parse*, Token*, Token*, Token*);
20123 SQLITE_PRIVATE int sqlite3ColumnIndex(Table *pTab, const char *zCol);
20124 SQLITE_PRIVATE void sqlite3SrcItemColumnUsed(SrcItem*,int);
20125 SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr*,int,u32);
20126 SQLITE_PRIVATE void sqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int);
20127 SQLITE_PRIVATE void sqlite3DeferForeignKey(Parse*, int);
20128 #ifndef SQLITE_OMIT_AUTHORIZATION
20129 SQLITE_PRIVATE void sqlite3AuthRead(Parse*,Expr*,Schema*,SrcList*);
20130 SQLITE_PRIVATE int sqlite3AuthCheck(Parse*,int, const char*, const char*, const char*);
@@ -20382,11 +20466,11 @@
20466 SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *);
20467
20468 SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
20469 #if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \
20470 && !defined(SQLITE_OMIT_VIRTUALTABLE)
20471 SQLITE_PRIVATE void sqlite3VtabUsesAllSchemas(sqlite3_index_info*);
20472 #endif
20473 SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
20474 SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
20475 SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
20476 SQLITE_PRIVATE void sqlite3ParseObjectInit(Parse*,sqlite3*);
@@ -21130,13 +21214,10 @@
21214 "ENABLE_RBU",
21215 #endif
21216 #ifdef SQLITE_ENABLE_RTREE
21217 "ENABLE_RTREE",
21218 #endif
 
 
 
21219 #ifdef SQLITE_ENABLE_SESSION
21220 "ENABLE_SESSION",
21221 #endif
21222 #ifdef SQLITE_ENABLE_SNAPSHOT
21223 "ENABLE_SNAPSHOT",
@@ -21153,10 +21234,13 @@
21234 #ifdef SQLITE_ENABLE_STMTVTAB
21235 "ENABLE_STMTVTAB",
21236 #endif
21237 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
21238 "ENABLE_STMT_SCANSTATUS",
21239 #endif
21240 #ifdef SQLITE_ENABLE_TREETRACE
21241 "ENABLE_TREETRACE",
21242 #endif
21243 #ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
21244 "ENABLE_UNKNOWN_SQL_FUNCTION",
21245 #endif
21246 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
@@ -21960,11 +22044,11 @@
22044 #endif
22045
22046 /*
22047 ** Tracing flags set by SQLITE_TESTCTRL_TRACEFLAGS.
22048 */
22049 SQLITE_PRIVATE u32 sqlite3TreeTrace = 0;
22050 SQLITE_PRIVATE u32 sqlite3WhereTrace = 0;
22051
22052 /* #include "opcodes.h" */
22053 /*
22054 ** Properties of opcodes. The OPFLG_INITIALIZER macro is
@@ -22175,10 +22259,15 @@
22259 ** static element declared in the structure. nField total array slots for
22260 ** aType[] and nField+1 array slots for aOffset[] */
22261 u32 aType[1]; /* Type values record decode. MUST BE LAST */
22262 };
22263
22264 /* Return true if P is a null-only cursor
22265 */
22266 #define IsNullCursor(P) \
22267 ((P)->eCurType==CURTYPE_PSEUDO && (P)->nullRow && (P)->seekResult==0)
22268
22269
22270 /*
22271 ** A value for VdbeCursor.cacheStatus that means the cache is always invalid.
22272 */
22273 #define CACHE_STALE 0
@@ -22496,16 +22585,14 @@
22585 #endif
22586 u16 nResColumn; /* Number of columns in one row of the result set */
22587 u8 errorAction; /* Recovery action to do in case of an error */
22588 u8 minWriteFileFormat; /* Minimum file format for writable database files */
22589 u8 prepFlags; /* SQLITE_PREPARE_* flags */
 
22590 u8 eVdbeState; /* On of the VDBE_*_STATE values */
22591 bft expired:2; /* 1: recompile VM immediately 2: when convenient */
22592 bft explain:2; /* True if EXPLAIN present on SQL command */
22593 bft changeCntOn:1; /* True to update the change-counter */
 
22594 bft usesStmtJournal:1; /* True if uses a statement journal */
22595 bft readOnly:1; /* True for statements that do not write */
22596 bft bIsReader:1; /* True for statements that read */
22597 yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
22598 yDbMask lockMask; /* Subset of btreeMask that requires a lock */
@@ -22574,22 +22661,35 @@
22661 struct ValueList {
22662 BtCursor *pCsr; /* An ephemeral table holding all values */
22663 sqlite3_value *pOut; /* Register to hold each decoded output value */
22664 };
22665
22666 /* Size of content associated with serial types that fit into a
22667 ** single-byte varint.
22668 */
22669 #ifndef SQLITE_AMALGAMATION
22670 SQLITE_PRIVATE const u8 sqlite3SmallTypeSizes[];
22671 #endif
22672
22673 /*
22674 ** Function prototypes
22675 */
22676 SQLITE_PRIVATE void sqlite3VdbeError(Vdbe*, const char *, ...);
22677 SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
22678 SQLITE_PRIVATE void sqlite3VdbeFreeCursorNN(Vdbe*,VdbeCursor*);
22679 void sqliteVdbePopStack(Vdbe*,int);
22680 SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeHandleMovedCursor(VdbeCursor *p);
22681 SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor*);
22682 SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
22683 SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
22684 SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8);
22685 #ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
22686 SQLITE_PRIVATE u64 sqlite3FloatSwap(u64 in);
22687 # define swapMixedEndianFloat(X) X = sqlite3FloatSwap(X)
22688 #else
22689 # define swapMixedEndianFloat(X)
22690 #endif
22691 SQLITE_PRIVATE void sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
22692 SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3*, AuxData**, int, int);
22693
22694 int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
22695 SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
@@ -23046,12 +23146,11 @@
23146 struct Vdbe *pVdbe; /* Used to iterate through VMs */
23147 int nByte = 0; /* Used to accumulate return value */
23148
23149 db->pnBytesFreed = &nByte;
23150 for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){
23151 sqlite3VdbeDelete(pVdbe);
 
23152 }
23153 db->pnBytesFreed = 0;
23154
23155 *pHighwater = 0; /* IMP: R-64479-57858 */
23156 *pCurrent = nByte;
@@ -29389,12 +29488,13 @@
29488
29489 /*
29490 ** Free any prior content in *pz and replace it with a copy of zNew.
29491 */
29492 SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){
29493 char *z = sqlite3DbStrDup(db, zNew);
29494 sqlite3DbFree(db, *pz);
29495 *pz = z;
29496 }
29497
29498 /*
29499 ** Call this routine to record the fact that an OOM (out-of-memory) error
29500 ** has happened. This routine will set db->mallocFailed, and also
@@ -30886,37 +30986,41 @@
30986
30987 /*
30988 ** Add a new subitem to the tree. The moreToFollow flag indicates that this
30989 ** is not the last item in the tree.
30990 */
30991 static void sqlite3TreeViewPush(TreeView **pp, u8 moreToFollow){
30992 TreeView *p = *pp;
30993 if( p==0 ){
30994 *pp = p = sqlite3_malloc64( sizeof(*p) );
30995 if( p==0 ) return;
30996 memset(p, 0, sizeof(*p));
30997 }else{
30998 p->iLevel++;
30999 }
31000 assert( moreToFollow==0 || moreToFollow==1 );
31001 if( p->iLevel<(int)sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow;
 
31002 }
31003
31004 /*
31005 ** Finished with one layer of the tree
31006 */
31007 static void sqlite3TreeViewPop(TreeView **pp){
31008 TreeView *p = *pp;
31009 if( p==0 ) return;
31010 p->iLevel--;
31011 if( p->iLevel<0 ){
31012 sqlite3_free(p);
31013 *pp = 0;
31014 }
31015 }
31016
31017 /*
31018 ** Generate a single line of output for the tree, with a prefix that contains
31019 ** all the appropriate tree lines
31020 */
31021 SQLITE_PRIVATE void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
31022 va_list ap;
31023 int i;
31024 StrAccum acc;
31025 char zBuf[500];
31026 sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
@@ -30940,11 +31044,11 @@
31044
31045 /*
31046 ** Shorthand for starting a new tree item that consists of a single label
31047 */
31048 static void sqlite3TreeViewItem(TreeView *p, const char *zLabel,u8 moreFollows){
31049 sqlite3TreeViewPush(&p, moreFollows);
31050 sqlite3TreeViewLine(p, "%s", zLabel);
31051 }
31052
31053 /*
31054 ** Generate a human-readable description of a WITH clause.
@@ -30957,11 +31061,11 @@
31061 sqlite3TreeViewLine(pView, "WITH (0x%p, pOuter=0x%p)",pWith,pWith->pOuter);
31062 }else{
31063 sqlite3TreeViewLine(pView, "WITH (0x%p)", pWith);
31064 }
31065 if( pWith->nCte>0 ){
31066 sqlite3TreeViewPush(&pView, moreToFollow);
31067 for(i=0; i<pWith->nCte; i++){
31068 StrAccum x;
31069 char zLine[1000];
31070 const struct Cte *pCte = &pWith->a[i];
31071 sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
@@ -30980,21 +31084,22 @@
31084 pCte->pUse->nUse);
31085 }
31086 sqlite3StrAccumFinish(&x);
31087 sqlite3TreeViewItem(pView, zLine, i<pWith->nCte-1);
31088 sqlite3TreeViewSelect(pView, pCte->pSelect, 0);
31089 sqlite3TreeViewPop(&pView);
31090 }
31091 sqlite3TreeViewPop(&pView);
31092 }
31093 }
31094
31095 /*
31096 ** Generate a human-readable description of a SrcList object.
31097 */
31098 SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){
31099 int i;
31100 if( pSrc==0 ) return;
31101 for(i=0; i<pSrc->nSrc; i++){
31102 const SrcItem *pItem = &pSrc->a[i];
31103 StrAccum x;
31104 char zLine[100];
31105 sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
@@ -31002,14 +31107,21 @@
31107 sqlite3_str_appendf(&x, "{%d:*} %!S", pItem->iCursor, pItem);
31108 if( pItem->pTab ){
31109 sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx",
31110 pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab, pItem->colUsed);
31111 }
31112 if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==(JT_LEFT|JT_RIGHT) ){
31113 sqlite3_str_appendf(&x, " FULL-OUTER-JOIN");
31114 }else if( pItem->fg.jointype & JT_LEFT ){
31115 sqlite3_str_appendf(&x, " LEFT-JOIN");
31116 }else if( pItem->fg.jointype & JT_RIGHT ){
31117 sqlite3_str_appendf(&x, " RIGHT-JOIN");
31118 }else if( pItem->fg.jointype & JT_CROSS ){
31119 sqlite3_str_appendf(&x, " CROSS-JOIN");
31120 }
31121 if( pItem->fg.jointype & JT_LTORJ ){
31122 sqlite3_str_appendf(&x, " LTORJ");
31123 }
31124 if( pItem->fg.fromDDL ){
31125 sqlite3_str_appendf(&x, " DDL");
31126 }
31127 if( pItem->fg.isCte ){
@@ -31016,16 +31128,17 @@
31128 sqlite3_str_appendf(&x, " CteUse=0x%p", pItem->u2.pCteUse);
31129 }
31130 sqlite3StrAccumFinish(&x);
31131 sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1);
31132 if( pItem->pSelect ){
31133 assert( pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) );
31134 sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
31135 }
31136 if( pItem->fg.isTabFunc ){
31137 sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
31138 }
31139 sqlite3TreeViewPop(&pView);
31140 }
31141 }
31142
31143 /*
31144 ** Generate a human-readable description of a Select object.
@@ -31035,15 +31148,15 @@
31148 int cnt = 0;
31149 if( p==0 ){
31150 sqlite3TreeViewLine(pView, "nil-SELECT");
31151 return;
31152 }
31153 sqlite3TreeViewPush(&pView, moreToFollow);
31154 if( p->pWith ){
31155 sqlite3TreeViewWith(pView, p->pWith, 1);
31156 cnt = 1;
31157 sqlite3TreeViewPush(&pView, 1);
31158 }
31159 do{
31160 if( p->selFlags & SF_WhereBegin ){
31161 sqlite3TreeViewLine(pView, "sqlite3WhereBegin()");
31162 }else{
@@ -31053,11 +31166,11 @@
31166 ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""),
31167 p->selId, p, p->selFlags,
31168 (int)p->nSelectRow
31169 );
31170 }
31171 if( cnt++ ) sqlite3TreeViewPop(&pView);
31172 if( p->pPrior ){
31173 n = 1000;
31174 }else{
31175 n = 0;
31176 if( p->pSrc && p->pSrc->nSrc ) n++;
@@ -31076,45 +31189,45 @@
31189 }
31190 n--;
31191 #ifndef SQLITE_OMIT_WINDOWFUNC
31192 if( p->pWin ){
31193 Window *pX;
31194 sqlite3TreeViewPush(&pView, (n--)>0);
31195 sqlite3TreeViewLine(pView, "window-functions");
31196 for(pX=p->pWin; pX; pX=pX->pNextWin){
31197 sqlite3TreeViewWinFunc(pView, pX, pX->pNextWin!=0);
31198 }
31199 sqlite3TreeViewPop(&pView);
31200 }
31201 #endif
31202 if( p->pSrc && p->pSrc->nSrc ){
31203 sqlite3TreeViewPush(&pView, (n--)>0);
31204 sqlite3TreeViewLine(pView, "FROM");
31205 sqlite3TreeViewSrcList(pView, p->pSrc);
31206 sqlite3TreeViewPop(&pView);
31207 }
31208 if( p->pWhere ){
31209 sqlite3TreeViewItem(pView, "WHERE", (n--)>0);
31210 sqlite3TreeViewExpr(pView, p->pWhere, 0);
31211 sqlite3TreeViewPop(&pView);
31212 }
31213 if( p->pGroupBy ){
31214 sqlite3TreeViewExprList(pView, p->pGroupBy, (n--)>0, "GROUPBY");
31215 }
31216 if( p->pHaving ){
31217 sqlite3TreeViewItem(pView, "HAVING", (n--)>0);
31218 sqlite3TreeViewExpr(pView, p->pHaving, 0);
31219 sqlite3TreeViewPop(&pView);
31220 }
31221 #ifndef SQLITE_OMIT_WINDOWFUNC
31222 if( p->pWinDefn ){
31223 Window *pX;
31224 sqlite3TreeViewItem(pView, "WINDOW", (n--)>0);
31225 for(pX=p->pWinDefn; pX; pX=pX->pNextWin){
31226 sqlite3TreeViewWindow(pView, pX, pX->pNextWin!=0);
31227 }
31228 sqlite3TreeViewPop(&pView);
31229 }
31230 #endif
31231 if( p->pOrderBy ){
31232 sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY");
31233 }
@@ -31122,13 +31235,13 @@
31235 sqlite3TreeViewItem(pView, "LIMIT", (n--)>0);
31236 sqlite3TreeViewExpr(pView, p->pLimit->pLeft, p->pLimit->pRight!=0);
31237 if( p->pLimit->pRight ){
31238 sqlite3TreeViewItem(pView, "OFFSET", (n--)>0);
31239 sqlite3TreeViewExpr(pView, p->pLimit->pRight, 0);
31240 sqlite3TreeViewPop(&pView);
31241 }
31242 sqlite3TreeViewPop(&pView);
31243 }
31244 if( p->pPrior ){
31245 const char *zOp = "UNION";
31246 switch( p->op ){
31247 case TK_ALL: zOp = "UNION ALL"; break;
@@ -31137,11 +31250,11 @@
31250 }
31251 sqlite3TreeViewItem(pView, zOp, 1);
31252 }
31253 p = p->pPrior;
31254 }while( p!=0 );
31255 sqlite3TreeViewPop(&pView);
31256 }
31257
31258 #ifndef SQLITE_OMIT_WINDOWFUNC
31259 /*
31260 ** Generate a description of starting or stopping bounds
@@ -31153,28 +31266,28 @@
31266 u8 moreToFollow /* True if more to follow */
31267 ){
31268 switch( eBound ){
31269 case TK_UNBOUNDED: {
31270 sqlite3TreeViewItem(pView, "UNBOUNDED", moreToFollow);
31271 sqlite3TreeViewPop(&pView);
31272 break;
31273 }
31274 case TK_CURRENT: {
31275 sqlite3TreeViewItem(pView, "CURRENT", moreToFollow);
31276 sqlite3TreeViewPop(&pView);
31277 break;
31278 }
31279 case TK_PRECEDING: {
31280 sqlite3TreeViewItem(pView, "PRECEDING", moreToFollow);
31281 sqlite3TreeViewExpr(pView, pExpr, 0);
31282 sqlite3TreeViewPop(&pView);
31283 break;
31284 }
31285 case TK_FOLLOWING: {
31286 sqlite3TreeViewItem(pView, "FOLLOWING", moreToFollow);
31287 sqlite3TreeViewExpr(pView, pExpr, 0);
31288 sqlite3TreeViewPop(&pView);
31289 break;
31290 }
31291 }
31292 }
31293 #endif /* SQLITE_OMIT_WINDOWFUNC */
@@ -31186,13 +31299,13 @@
31299 SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){
31300 int nElement = 0;
31301 if( pWin->pFilter ){
31302 sqlite3TreeViewItem(pView, "FILTER", 1);
31303 sqlite3TreeViewExpr(pView, pWin->pFilter, 0);
31304 sqlite3TreeViewPop(&pView);
31305 }
31306 sqlite3TreeViewPush(&pView, more);
31307 if( pWin->zName ){
31308 sqlite3TreeViewLine(pView, "OVER %s (%p)", pWin->zName, pWin);
31309 }else{
31310 sqlite3TreeViewLine(pView, "OVER (%p)", pWin);
31311 }
@@ -31199,13 +31312,13 @@
31312 if( pWin->zBase ) nElement++;
31313 if( pWin->pOrderBy ) nElement++;
31314 if( pWin->eFrmType ) nElement++;
31315 if( pWin->eExclude ) nElement++;
31316 if( pWin->zBase ){
31317 sqlite3TreeViewPush(&pView, (--nElement)>0);
31318 sqlite3TreeViewLine(pView, "window: %s", pWin->zBase);
31319 sqlite3TreeViewPop(&pView);
31320 }
31321 if( pWin->pPartition ){
31322 sqlite3TreeViewExprList(pView, pWin->pPartition, nElement>0,"PARTITION-BY");
31323 }
31324 if( pWin->pOrderBy ){
@@ -31219,11 +31332,11 @@
31332 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s%s",zFrmType,
31333 pWin->bImplicitFrame ? " (implied)" : "");
31334 sqlite3TreeViewItem(pView, zBuf, (--nElement)>0);
31335 sqlite3TreeViewBound(pView, pWin->eStart, pWin->pStart, 1);
31336 sqlite3TreeViewBound(pView, pWin->eEnd, pWin->pEnd, 0);
31337 sqlite3TreeViewPop(&pView);
31338 }
31339 if( pWin->eExclude ){
31340 char zBuf[30];
31341 const char *zExclude;
31342 switch( pWin->eExclude ){
@@ -31234,28 +31347,28 @@
31347 default:
31348 sqlite3_snprintf(sizeof(zBuf),zBuf,"invalid(%d)", pWin->eExclude);
31349 zExclude = zBuf;
31350 break;
31351 }
31352 sqlite3TreeViewPush(&pView, 0);
31353 sqlite3TreeViewLine(pView, "EXCLUDE %s", zExclude);
31354 sqlite3TreeViewPop(&pView);
31355 }
31356 sqlite3TreeViewPop(&pView);
31357 }
31358 #endif /* SQLITE_OMIT_WINDOWFUNC */
31359
31360 #ifndef SQLITE_OMIT_WINDOWFUNC
31361 /*
31362 ** Generate a human-readable explanation for a Window Function object
31363 */
31364 SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){
31365 sqlite3TreeViewPush(&pView, more);
31366 sqlite3TreeViewLine(pView, "WINFUNC %s(%d)",
31367 pWin->pWFunc->zName, pWin->pWFunc->nArg);
31368 sqlite3TreeViewWindow(pView, pWin, 0);
31369 sqlite3TreeViewPop(&pView);
31370 }
31371 #endif /* SQLITE_OMIT_WINDOWFUNC */
31372
31373 /*
31374 ** Generate a human-readable explanation of an expression tree.
@@ -31262,23 +31375,23 @@
31375 */
31376 SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
31377 const char *zBinOp = 0; /* Binary operator */
31378 const char *zUniOp = 0; /* Unary operator */
31379 char zFlgs[200];
31380 sqlite3TreeViewPush(&pView, moreToFollow);
31381 if( pExpr==0 ){
31382 sqlite3TreeViewLine(pView, "nil");
31383 sqlite3TreeViewPop(&pView);
31384 return;
31385 }
31386 if( pExpr->flags || pExpr->affExpr || pExpr->vvaFlags ){
31387 StrAccum x;
31388 sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0);
31389 sqlite3_str_appendf(&x, " fg.af=%x.%c",
31390 pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n');
31391 if( ExprHasProperty(pExpr, EP_FromJoin) ){
31392 sqlite3_str_appendf(&x, " iJoin=%d", pExpr->w.iJoin);
31393 }
31394 if( ExprHasProperty(pExpr, EP_FromDDL) ){
31395 sqlite3_str_appendf(&x, " DDL");
31396 }
31397 if( ExprHasVVAProperty(pExpr, EP_Immutable) ){
@@ -31622,11 +31735,11 @@
31735 sqlite3TreeViewExpr(pView, pExpr->pRight, 0);
31736 }else if( zUniOp ){
31737 sqlite3TreeViewLine(pView, "%s%s", zUniOp, zFlgs);
31738 sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
31739 }
31740 sqlite3TreeViewPop(&pView);
31741 }
31742
31743
31744 /*
31745 ** Generate a human-readable explanation of an expression list.
@@ -31644,27 +31757,37 @@
31757 sqlite3TreeViewLine(pView, "%s", zLabel);
31758 for(i=0; i<pList->nExpr; i++){
31759 int j = pList->a[i].u.x.iOrderByCol;
31760 char *zName = pList->a[i].zEName;
31761 int moreToFollow = i<pList->nExpr - 1;
 
31762 if( j || zName ){
31763 sqlite3TreeViewPush(&pView, moreToFollow);
31764 moreToFollow = 0;
31765 sqlite3TreeViewLine(pView, 0);
31766 if( zName ){
31767 switch( pList->a[i].eEName ){
31768 default:
31769 fprintf(stdout, "AS %s ", zName);
31770 break;
31771 case ENAME_TAB:
31772 fprintf(stdout, "TABLE-ALIAS-NAME(\"%s\") ", zName);
31773 if( pList->a[i].bUsed==0 ) fprintf(stdout, "(unused) ");
31774 break;
31775 case ENAME_SPAN:
31776 fprintf(stdout, "SPAN(\"%s\") ", zName);
31777 break;
31778 }
31779 }
31780 if( j ){
31781 fprintf(stdout, "iOrderByCol=%d", j);
31782 }
31783 fprintf(stdout, "\n");
31784 fflush(stdout);
31785 }
31786 sqlite3TreeViewExpr(pView, pList->a[i].pExpr, moreToFollow);
31787 if( j || zName ){
31788 sqlite3TreeViewPop(&pView);
31789 }
31790 }
31791 }
31792 }
31793 SQLITE_PRIVATE void sqlite3TreeViewExprList(
@@ -31671,15 +31794,376 @@
31794 TreeView *pView,
31795 const ExprList *pList,
31796 u8 moreToFollow,
31797 const char *zLabel
31798 ){
31799 sqlite3TreeViewPush(&pView, moreToFollow);
31800 sqlite3TreeViewBareExprList(pView, pList, zLabel);
31801 sqlite3TreeViewPop(&pView);
31802 }
31803
31804 /*
31805 ** Generate a human-readable explanation of an id-list.
31806 */
31807 SQLITE_PRIVATE void sqlite3TreeViewBareIdList(
31808 TreeView *pView,
31809 const IdList *pList,
31810 const char *zLabel
31811 ){
31812 if( zLabel==0 || zLabel[0]==0 ) zLabel = "LIST";
31813 if( pList==0 ){
31814 sqlite3TreeViewLine(pView, "%s (empty)", zLabel);
31815 }else{
31816 int i;
31817 sqlite3TreeViewLine(pView, "%s", zLabel);
31818 for(i=0; i<pList->nId; i++){
31819 char *zName = pList->a[i].zName;
31820 int moreToFollow = i<pList->nId - 1;
31821 if( zName==0 ) zName = "(null)";
31822 sqlite3TreeViewPush(&pView, moreToFollow);
31823 sqlite3TreeViewLine(pView, 0);
31824 if( pList->eU4==EU4_NONE ){
31825 fprintf(stdout, "%s\n", zName);
31826 }else if( pList->eU4==EU4_IDX ){
31827 fprintf(stdout, "%s (%d)\n", zName, pList->a[i].u4.idx);
31828 }else{
31829 assert( pList->eU4==EU4_EXPR );
31830 if( pList->a[i].u4.pExpr==0 ){
31831 fprintf(stdout, "%s (pExpr=NULL)\n", zName);
31832 }else{
31833 fprintf(stdout, "%s\n", zName);
31834 sqlite3TreeViewPush(&pView, i<pList->nId-1);
31835 sqlite3TreeViewExpr(pView, pList->a[i].u4.pExpr, 0);
31836 sqlite3TreeViewPop(&pView);
31837 }
31838 }
31839 sqlite3TreeViewPop(&pView);
31840 }
31841 }
31842 }
31843 SQLITE_PRIVATE void sqlite3TreeViewIdList(
31844 TreeView *pView,
31845 const IdList *pList,
31846 u8 moreToFollow,
31847 const char *zLabel
31848 ){
31849 sqlite3TreeViewPush(&pView, moreToFollow);
31850 sqlite3TreeViewBareIdList(pView, pList, zLabel);
31851 sqlite3TreeViewPop(&pView);
31852 }
31853
31854 /*
31855 ** Generate a human-readable explanation of a list of Upsert objects
31856 */
31857 SQLITE_PRIVATE void sqlite3TreeViewUpsert(
31858 TreeView *pView,
31859 const Upsert *pUpsert,
31860 u8 moreToFollow
31861 ){
31862 if( pUpsert==0 ) return;
31863 sqlite3TreeViewPush(&pView, moreToFollow);
31864 while( pUpsert ){
31865 int n;
31866 sqlite3TreeViewPush(&pView, pUpsert->pNextUpsert!=0 || moreToFollow);
31867 sqlite3TreeViewLine(pView, "ON CONFLICT DO %s",
31868 pUpsert->isDoUpdate ? "UPDATE" : "NOTHING");
31869 n = (pUpsert->pUpsertSet!=0) + (pUpsert->pUpsertWhere!=0);
31870 sqlite3TreeViewExprList(pView, pUpsert->pUpsertTarget, (n--)>0, "TARGET");
31871 sqlite3TreeViewExprList(pView, pUpsert->pUpsertSet, (n--)>0, "SET");
31872 if( pUpsert->pUpsertWhere ){
31873 sqlite3TreeViewItem(pView, "WHERE", (n--)>0);
31874 sqlite3TreeViewExpr(pView, pUpsert->pUpsertWhere, 0);
31875 sqlite3TreeViewPop(&pView);
31876 }
31877 sqlite3TreeViewPop(&pView);
31878 pUpsert = pUpsert->pNextUpsert;
31879 }
31880 sqlite3TreeViewPop(&pView);
31881 }
31882
31883 /*
31884 ** Generate a human-readable diagram of the data structure that go
31885 ** into generating an DELETE statement.
31886 */
31887 SQLITE_PRIVATE void sqlite3TreeViewDelete(
31888 const With *pWith,
31889 const SrcList *pTabList,
31890 const Expr *pWhere,
31891 const ExprList *pOrderBy,
31892 const Expr *pLimit,
31893 const Trigger *pTrigger
31894 ){
31895 int n = 0;
31896 TreeView *pView = 0;
31897 sqlite3TreeViewPush(&pView, 0);
31898 sqlite3TreeViewLine(pView, "DELETE");
31899 if( pWith ) n++;
31900 if( pTabList ) n++;
31901 if( pWhere ) n++;
31902 if( pOrderBy ) n++;
31903 if( pLimit ) n++;
31904 if( pTrigger ) n++;
31905 if( pWith ){
31906 sqlite3TreeViewPush(&pView, (--n)>0);
31907 sqlite3TreeViewWith(pView, pWith, 0);
31908 sqlite3TreeViewPop(&pView);
31909 }
31910 if( pTabList ){
31911 sqlite3TreeViewPush(&pView, (--n)>0);
31912 sqlite3TreeViewLine(pView, "FROM");
31913 sqlite3TreeViewSrcList(pView, pTabList);
31914 sqlite3TreeViewPop(&pView);
31915 }
31916 if( pWhere ){
31917 sqlite3TreeViewPush(&pView, (--n)>0);
31918 sqlite3TreeViewLine(pView, "WHERE");
31919 sqlite3TreeViewExpr(pView, pWhere, 0);
31920 sqlite3TreeViewPop(&pView);
31921 }
31922 if( pOrderBy ){
31923 sqlite3TreeViewExprList(pView, pOrderBy, (--n)>0, "ORDER-BY");
31924 }
31925 if( pLimit ){
31926 sqlite3TreeViewPush(&pView, (--n)>0);
31927 sqlite3TreeViewLine(pView, "LIMIT");
31928 sqlite3TreeViewExpr(pView, pLimit, 0);
31929 sqlite3TreeViewPop(&pView);
31930 }
31931 if( pTrigger ){
31932 sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1);
31933 }
31934 sqlite3TreeViewPop(&pView);
31935 }
31936
31937 /*
31938 ** Generate a human-readable diagram of the data structure that go
31939 ** into generating an INSERT statement.
31940 */
31941 SQLITE_PRIVATE void sqlite3TreeViewInsert(
31942 const With *pWith,
31943 const SrcList *pTabList,
31944 const IdList *pColumnList,
31945 const Select *pSelect,
31946 const ExprList *pExprList,
31947 int onError,
31948 const Upsert *pUpsert,
31949 const Trigger *pTrigger
31950 ){
31951 TreeView *pView = 0;
31952 int n = 0;
31953 const char *zLabel = "INSERT";
31954 switch( onError ){
31955 case OE_Replace: zLabel = "REPLACE"; break;
31956 case OE_Ignore: zLabel = "INSERT OR IGNORE"; break;
31957 case OE_Rollback: zLabel = "INSERT OR ROLLBACK"; break;
31958 case OE_Abort: zLabel = "INSERT OR ABORT"; break;
31959 case OE_Fail: zLabel = "INSERT OR FAIL"; break;
31960 }
31961 sqlite3TreeViewPush(&pView, 0);
31962 sqlite3TreeViewLine(pView, zLabel);
31963 if( pWith ) n++;
31964 if( pTabList ) n++;
31965 if( pColumnList ) n++;
31966 if( pSelect ) n++;
31967 if( pExprList ) n++;
31968 if( pUpsert ) n++;
31969 if( pTrigger ) n++;
31970 if( pWith ){
31971 sqlite3TreeViewPush(&pView, (--n)>0);
31972 sqlite3TreeViewWith(pView, pWith, 0);
31973 sqlite3TreeViewPop(&pView);
31974 }
31975 if( pTabList ){
31976 sqlite3TreeViewPush(&pView, (--n)>0);
31977 sqlite3TreeViewLine(pView, "INTO");
31978 sqlite3TreeViewSrcList(pView, pTabList);
31979 sqlite3TreeViewPop(&pView);
31980 }
31981 if( pColumnList ){
31982 sqlite3TreeViewIdList(pView, pColumnList, (--n)>0, "COLUMNS");
31983 }
31984 if( pSelect ){
31985 sqlite3TreeViewPush(&pView, (--n)>0);
31986 sqlite3TreeViewLine(pView, "DATA-SOURCE");
31987 sqlite3TreeViewSelect(pView, pSelect, 0);
31988 sqlite3TreeViewPop(&pView);
31989 }
31990 if( pExprList ){
31991 sqlite3TreeViewExprList(pView, pExprList, (--n)>0, "VALUES");
31992 }
31993 if( pUpsert ){
31994 sqlite3TreeViewPush(&pView, (--n)>0);
31995 sqlite3TreeViewLine(pView, "UPSERT");
31996 sqlite3TreeViewUpsert(pView, pUpsert, 0);
31997 sqlite3TreeViewPop(&pView);
31998 }
31999 if( pTrigger ){
32000 sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1);
32001 }
32002 sqlite3TreeViewPop(&pView);
32003 }
32004
32005 /*
32006 ** Generate a human-readable diagram of the data structure that go
32007 ** into generating an UPDATE statement.
32008 */
32009 SQLITE_PRIVATE void sqlite3TreeViewUpdate(
32010 const With *pWith,
32011 const SrcList *pTabList,
32012 const ExprList *pChanges,
32013 const Expr *pWhere,
32014 int onError,
32015 const ExprList *pOrderBy,
32016 const Expr *pLimit,
32017 const Upsert *pUpsert,
32018 const Trigger *pTrigger
32019 ){
32020 int n = 0;
32021 TreeView *pView = 0;
32022 const char *zLabel = "UPDATE";
32023 switch( onError ){
32024 case OE_Replace: zLabel = "UPDATE OR REPLACE"; break;
32025 case OE_Ignore: zLabel = "UPDATE OR IGNORE"; break;
32026 case OE_Rollback: zLabel = "UPDATE OR ROLLBACK"; break;
32027 case OE_Abort: zLabel = "UPDATE OR ABORT"; break;
32028 case OE_Fail: zLabel = "UPDATE OR FAIL"; break;
32029 }
32030 sqlite3TreeViewPush(&pView, 0);
32031 sqlite3TreeViewLine(pView, zLabel);
32032 if( pWith ) n++;
32033 if( pTabList ) n++;
32034 if( pChanges ) n++;
32035 if( pWhere ) n++;
32036 if( pOrderBy ) n++;
32037 if( pLimit ) n++;
32038 if( pUpsert ) n++;
32039 if( pTrigger ) n++;
32040 if( pWith ){
32041 sqlite3TreeViewPush(&pView, (--n)>0);
32042 sqlite3TreeViewWith(pView, pWith, 0);
32043 sqlite3TreeViewPop(&pView);
32044 }
32045 if( pTabList ){
32046 sqlite3TreeViewPush(&pView, (--n)>0);
32047 sqlite3TreeViewLine(pView, "FROM");
32048 sqlite3TreeViewSrcList(pView, pTabList);
32049 sqlite3TreeViewPop(&pView);
32050 }
32051 if( pChanges ){
32052 sqlite3TreeViewExprList(pView, pChanges, (--n)>0, "SET");
32053 }
32054 if( pWhere ){
32055 sqlite3TreeViewPush(&pView, (--n)>0);
32056 sqlite3TreeViewLine(pView, "WHERE");
32057 sqlite3TreeViewExpr(pView, pWhere, 0);
32058 sqlite3TreeViewPop(&pView);
32059 }
32060 if( pOrderBy ){
32061 sqlite3TreeViewExprList(pView, pOrderBy, (--n)>0, "ORDER-BY");
32062 }
32063 if( pLimit ){
32064 sqlite3TreeViewPush(&pView, (--n)>0);
32065 sqlite3TreeViewLine(pView, "LIMIT");
32066 sqlite3TreeViewExpr(pView, pLimit, 0);
32067 sqlite3TreeViewPop(&pView);
32068 }
32069 if( pUpsert ){
32070 sqlite3TreeViewPush(&pView, (--n)>0);
32071 sqlite3TreeViewLine(pView, "UPSERT");
32072 sqlite3TreeViewUpsert(pView, pUpsert, 0);
32073 sqlite3TreeViewPop(&pView);
32074 }
32075 if( pTrigger ){
32076 sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1);
32077 }
32078 sqlite3TreeViewPop(&pView);
32079 }
32080
32081 #ifndef SQLITE_OMIT_TRIGGER
32082 /*
32083 ** Show a human-readable graph of a TriggerStep
32084 */
32085 SQLITE_PRIVATE void sqlite3TreeViewTriggerStep(
32086 TreeView *pView,
32087 const TriggerStep *pStep,
32088 u8 moreToFollow,
32089 u8 showFullList
32090 ){
32091 int cnt = 0;
32092 if( pStep==0 ) return;
32093 sqlite3TreeViewPush(&pView,
32094 moreToFollow || (showFullList && pStep->pNext!=0));
32095 do{
32096 if( cnt++ && pStep->pNext==0 ){
32097 sqlite3TreeViewPop(&pView);
32098 sqlite3TreeViewPush(&pView, 0);
32099 }
32100 sqlite3TreeViewLine(pView, "%s", pStep->zSpan ? pStep->zSpan : "RETURNING");
32101 }while( showFullList && (pStep = pStep->pNext)!=0 );
32102 sqlite3TreeViewPop(&pView);
32103 }
32104
32105 /*
32106 ** Show a human-readable graph of a Trigger
32107 */
32108 SQLITE_PRIVATE void sqlite3TreeViewTrigger(
32109 TreeView *pView,
32110 const Trigger *pTrigger,
32111 u8 moreToFollow,
32112 u8 showFullList
32113 ){
32114 int cnt = 0;
32115 if( pTrigger==0 ) return;
32116 sqlite3TreeViewPush(&pView,
32117 moreToFollow || (showFullList && pTrigger->pNext!=0));
32118 do{
32119 if( cnt++ && pTrigger->pNext==0 ){
32120 sqlite3TreeViewPop(&pView);
32121 sqlite3TreeViewPush(&pView, 0);
32122 }
32123 sqlite3TreeViewLine(pView, "TRIGGER %s", pTrigger->zName);
32124 sqlite3TreeViewPush(&pView, 0);
32125 sqlite3TreeViewTriggerStep(pView, pTrigger->step_list, 0, 1);
32126 sqlite3TreeViewPop(&pView);
32127 }while( showFullList && (pTrigger = pTrigger->pNext)!=0 );
32128 sqlite3TreeViewPop(&pView);
32129 }
32130 #endif /* SQLITE_OMIT_TRIGGER */
32131
32132
32133 /*
32134 ** These simplified versions of the tree-view routines omit unnecessary
32135 ** parameters. These variants are intended to be used from a symbolic
32136 ** debugger, such as "gdb", during interactive debugging sessions.
32137 **
32138 ** This routines are given external linkage so that they will always be
32139 ** accessible to the debugging, and to avoid warnings about unused
32140 ** functions. But these routines only exist in debugging builds, so they
32141 ** do not contaminate the interface.
32142 */
32143 SQLITE_PRIVATE void sqlite3ShowExpr(const Expr *p){ sqlite3TreeViewExpr(0,p,0); }
32144 SQLITE_PRIVATE void sqlite3ShowExprList(const ExprList *p){ sqlite3TreeViewExprList(0,p,0,0);}
32145 SQLITE_PRIVATE void sqlite3ShowIdList(const IdList *p){ sqlite3TreeViewIdList(0,p,0,0); }
32146 SQLITE_PRIVATE void sqlite3ShowSrcList(const SrcList *p){ sqlite3TreeViewSrcList(0,p); }
32147 SQLITE_PRIVATE void sqlite3ShowSelect(const Select *p){ sqlite3TreeViewSelect(0,p,0); }
32148 SQLITE_PRIVATE void sqlite3ShowWith(const With *p){ sqlite3TreeViewWith(0,p,0); }
32149 SQLITE_PRIVATE void sqlite3ShowUpsert(const Upsert *p){ sqlite3TreeViewUpsert(0,p,0); }
32150 #ifndef SQLITE_OMIT_TRIGGER
32151 SQLITE_PRIVATE void sqlite3ShowTriggerStep(const TriggerStep *p){
32152 sqlite3TreeViewTriggerStep(0,p,0,0);
32153 }
32154 SQLITE_PRIVATE void sqlite3ShowTriggerStepList(const TriggerStep *p){
32155 sqlite3TreeViewTriggerStep(0,p,0,1);
32156 }
32157 SQLITE_PRIVATE void sqlite3ShowTrigger(const Trigger *p){ sqlite3TreeViewTrigger(0,p,0,0); }
32158 SQLITE_PRIVATE void sqlite3ShowTriggerList(const Trigger *p){ sqlite3TreeViewTrigger(0,p,0,1);}
32159 #endif
32160 #ifndef SQLITE_OMIT_WINDOWFUNC
32161 SQLITE_PRIVATE void sqlite3ShowWindow(const Window *p){ sqlite3TreeViewWindow(0,p,0); }
32162 SQLITE_PRIVATE void sqlite3ShowWinFunc(const Window *p){ sqlite3TreeViewWinFunc(0,p,0); }
32163 #endif
32164
32165 #endif /* SQLITE_DEBUG */
32166
32167 /************** End of treeview.c ********************************************/
32168 /************** Begin file random.c ******************************************/
32169 /*
@@ -34710,14 +35194,14 @@
35194 /* 66 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"),
35195 /* 67 */ "Return" OpHelp(""),
35196 /* 68 */ "EndCoroutine" OpHelp(""),
35197 /* 69 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
35198 /* 70 */ "Halt" OpHelp(""),
35199 /* 71 */ "Integer" OpHelp("r[P2]=P1"),
35200 /* 72 */ "Int64" OpHelp("r[P2]=P4"),
35201 /* 73 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
35202 /* 74 */ "BeginSubrtn" OpHelp("r[P2]=NULL"),
35203 /* 75 */ "Null" OpHelp("r[P2..P3]=NULL"),
35204 /* 76 */ "SoftNull" OpHelp("r[P1]=NULL"),
35205 /* 77 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
35206 /* 78 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
35207 /* 79 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
@@ -34733,11 +35217,11 @@
35217 /* 89 */ "Permutation" OpHelp(""),
35218 /* 90 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
35219 /* 91 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"),
35220 /* 92 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"),
35221 /* 93 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"),
35222 /* 94 */ "Column" OpHelp("r[P3]=PX cursor P1 column P2"),
35223 /* 95 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"),
35224 /* 96 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
35225 /* 97 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
35226 /* 98 */ "Count" OpHelp("r[P2]=count()"),
35227 /* 99 */ "ReadCookie" OpHelp(""),
@@ -34774,11 +35258,11 @@
35258 /* 130 */ "Delete" OpHelp(""),
35259 /* 131 */ "ResetCount" OpHelp(""),
35260 /* 132 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
35261 /* 133 */ "SorterData" OpHelp("r[P2]=data"),
35262 /* 134 */ "RowData" OpHelp("r[P2]=data"),
35263 /* 135 */ "Rowid" OpHelp("r[P2]=PX rowid of P1"),
35264 /* 136 */ "NullRow" OpHelp(""),
35265 /* 137 */ "SeekEnd" OpHelp(""),
35266 /* 138 */ "IdxInsert" OpHelp("key=r[P2]"),
35267 /* 139 */ "SorterInsert" OpHelp("key=r[P2]"),
35268 /* 140 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
@@ -67869,10 +68353,12 @@
68353
68354 /* Remove the slot from the free-list. Update the number of
68355 ** fragmented bytes within the page. */
68356 memcpy(&aData[iAddr], &aData[pc], 2);
68357 aData[hdr+7] += (u8)x;
68358 testcase( pc+x>maxPC );
68359 return &aData[pc];
68360 }else if( x+pc > maxPC ){
68361 /* This slot extends off the end of the usable part of the page */
68362 *pRc = SQLITE_CORRUPT_PAGE(pPg);
68363 return 0;
68364 }else{
@@ -72179,11 +72665,11 @@
72665 idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2 */
72666 }
72667 assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) );
72668 assert( pPage->isInit );
72669 if( pPage->leaf ){
72670 assert( pCur->ix<pCur->pPage->nCell || CORRUPT_DB );
72671 pCur->ix = (u16)idx;
72672 *pRes = c;
72673 rc = SQLITE_OK;
72674 goto moveto_index_finish;
72675 }
@@ -74703,11 +75189,11 @@
75189 }
75190 }
75191 iOvflSpace += sz;
75192 assert( sz<=pBt->maxLocal+23 );
75193 assert( iOvflSpace <= (int)pBt->pageSize );
75194 for(k=0; b.ixNx[k]<=j && ALWAYS(k<NB*2); k++){}
75195 pSrcEnd = b.apEnd[k];
75196 if( SQLITE_WITHIN(pSrcEnd, pCell, pCell+sz) ){
75197 rc = SQLITE_CORRUPT_BKPT;
75198 goto balance_cleanup;
75199 }
@@ -75526,11 +76012,15 @@
76012 const u8 *aIn; /* Pointer to next input buffer */
76013 u32 nIn; /* Size of input buffer aIn[] */
76014 u32 nRem; /* Bytes of data still to copy */
76015
76016 getCellInfo(pSrc);
76017 if( pSrc->info.nPayload<0x80 ){
76018 *(aOut++) = pSrc->info.nPayload;
76019 }else{
76020 aOut += sqlite3PutVarint(aOut, pSrc->info.nPayload);
76021 }
76022 if( pDest->pKeyInfo==0 ) aOut += putVarint(aOut, iKey);
76023 nIn = pSrc->info.nLocal;
76024 aIn = pSrc->info.pPayload;
76025 if( aIn+nIn>pSrc->pPage->aDataEnd ){
76026 return SQLITE_CORRUPT_BKPT;
@@ -78539,13 +79029,14 @@
79029 SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
79030 sqlite3_context ctx;
79031 Mem t;
79032 assert( pFunc!=0 );
79033 assert( pMem!=0 );
79034 assert( pMem->db!=0 );
79035 assert( pFunc->xFinalize!=0 );
79036 assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef );
79037 assert( sqlite3_mutex_held(pMem->db->mutex) );
79038 memset(&ctx, 0, sizeof(ctx));
79039 memset(&t, 0, sizeof(t));
79040 t.flags = MEM_Null;
79041 t.db = pMem->db;
79042 ctx.pOut = &t;
@@ -78571,11 +79062,12 @@
79062 SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem *pAccum, Mem *pOut, FuncDef *pFunc){
79063 sqlite3_context ctx;
79064 assert( pFunc!=0 );
79065 assert( pFunc->xValue!=0 );
79066 assert( (pAccum->flags & MEM_Null)!=0 || pFunc==pAccum->u.pDef );
79067 assert( pAccum->db!=0 );
79068 assert( sqlite3_mutex_held(pAccum->db->mutex) );
79069 memset(&ctx, 0, sizeof(ctx));
79070 sqlite3VdbeMemSetNull(pOut);
79071 ctx.pOut = pOut;
79072 ctx.pMem = pAccum;
79073 ctx.pFunc = pFunc;
@@ -80639,18 +81131,24 @@
81131
81132 /*
81133 ** Mark the VDBE as one that can only be run one time.
81134 */
81135 SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe *p){
81136 sqlite3VdbeAddOp2(p, OP_Expire, 1, 1);
81137 }
81138
81139 /*
81140 ** Mark the VDBE as one that can only be run multiple times.
81141 */
81142 SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe *p){
81143 int i;
81144 for(i=1; ALWAYS(i<p->nOp); i++){
81145 if( ALWAYS(p->aOp[i].opcode==OP_Expire) ){
81146 p->aOp[1].opcode = OP_Noop;
81147 break;
81148 }
81149 }
81150 }
81151
81152 #ifdef SQLITE_DEBUG /* sqlite3AssertMayAbort() logic */
81153
81154 /*
@@ -81276,11 +81774,11 @@
81774 int iFirst, /* Index of first register to be released */
81775 int N, /* Number of registers to release */
81776 u32 mask, /* Mask of registers to NOT release */
81777 int bUndefine /* If true, mark registers as undefined */
81778 ){
81779 if( N==0 || OptimizationDisabled(pParse->db, SQLITE_ReleaseReg) ) return;
81780 assert( pParse->pVdbe );
81781 assert( iFirst>=1 );
81782 assert( iFirst+N-1<=pParse->nMem );
81783 if( N<=31 && mask!=0 ){
81784 while( N>0 && (mask&1)!=0 ){
@@ -81535,12 +82033,17 @@
82033 if( c=='P' ){
82034 c = zSynopsis[++ii];
82035 if( c=='4' ){
82036 sqlite3_str_appendall(&x, zP4);
82037 }else if( c=='X' ){
82038 if( pOp->zComment && pOp->zComment[0] ){
82039 sqlite3_str_appendall(&x, pOp->zComment);
82040 }else{
82041 sqlite3_str_appendall(&x, zSynopsis+1);
82042 }
82043 seenCom = 1;
82044 break;
82045 }else{
82046 int v1 = translateP(c, pOp);
82047 int v2;
82048 if( strncmp(zSynopsis+ii+1, "@P", 2)==0 ){
82049 ii += 3;
@@ -82131,11 +82634,11 @@
82634 int i;
82635 Mem *aMem = VdbeFrameMem(p);
82636 VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem];
82637 assert( sqlite3VdbeFrameIsValid(p) );
82638 for(i=0; i<p->nChildCsr; i++){
82639 if( apCsr[i] ) sqlite3VdbeFreeCursorNN(p->v, apCsr[i]);
82640 }
82641 releaseMemArray(aMem, p->nChildMem);
82642 sqlite3VdbeDeleteAuxData(p->v->db, &p->pAuxData, -1, 0);
82643 sqlite3DbFree(p->v->db, p);
82644 }
@@ -82325,15 +82828,15 @@
82828 ** statement.
82829 */
82830 static void *allocSpace(
82831 struct ReusableSpace *p, /* Bulk memory available for allocation */
82832 void *pBuf, /* Pointer to a prior allocation */
82833 sqlite3_int64 nByte /* Bytes of memory needed. */
82834 ){
82835 assert( EIGHT_BYTE_ALIGNMENT(p->pSpace) );
82836 if( pBuf==0 ){
82837 nByte = ROUND8P(nByte);
82838 if( nByte <= p->nFree ){
82839 p->nFree -= nByte;
82840 pBuf = &p->pSpace[p->nFree];
82841 }else{
82842 p->nNeeded += nByte;
@@ -82437,11 +82940,11 @@
82940
82941 /* Figure out how much reusable memory is available at the end of the
82942 ** opcode array. This extra memory will be reallocated for other elements
82943 ** of the prepared statement.
82944 */
82945 n = ROUND8P(sizeof(Op)*p->nOp); /* Bytes of opcode memory used */
82946 x.pSpace = &((u8*)p->aOp)[n]; /* Unused opcode memory */
82947 assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) );
82948 x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes of unused memory */
82949 assert( x.nFree>=0 );
82950 assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) );
@@ -82525,13 +83028,13 @@
83028 /*
83029 ** Close a VDBE cursor and release all the resources that cursor
83030 ** happens to hold.
83031 */
83032 SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
83033 if( pCx ) sqlite3VdbeFreeCursorNN(p,pCx);
83034 }
83035 SQLITE_PRIVATE void sqlite3VdbeFreeCursorNN(Vdbe *p, VdbeCursor *pCx){
83036 switch( pCx->eCurType ){
83037 case CURTYPE_SORTER: {
83038 sqlite3VdbeSorterClose(p->db, pCx);
83039 break;
83040 }
@@ -82559,11 +83062,11 @@
83062 static void closeCursorsInFrame(Vdbe *p){
83063 int i;
83064 for(i=0; i<p->nCursor; i++){
83065 VdbeCursor *pC = p->apCsr[i];
83066 if( pC ){
83067 sqlite3VdbeFreeCursorNN(p, pC);
83068 p->apCsr[i] = 0;
83069 }
83070 }
83071 }
83072
@@ -83089,13 +83592,11 @@
83592 ** Then the internal cache might have been left in an inconsistent
83593 ** state. We need to rollback the statement transaction, if there is
83594 ** one, or the complete transaction if there is no statement transaction.
83595 */
83596
83597 assert( p->eVdbeState==VDBE_RUN_STATE );
 
 
83598 if( db->mallocFailed ){
83599 p->rc = SQLITE_NOMEM_BKPT;
83600 }
83601 closeAllCursors(p);
83602 checkActiveVdbeCnt(db);
@@ -83351,11 +83852,11 @@
83852
83853 /* If the VM did not run to completion or if it encountered an
83854 ** error, then it might not have been halted properly. So halt
83855 ** it now.
83856 */
83857 if( p->eVdbeState==VDBE_RUN_STATE ) sqlite3VdbeHalt(p);
83858
83859 /* If the VDBE has been run even partially, then transfer the error code
83860 ** and error message from the VDBE into the main database structure. But
83861 ** if the VDBE has just been set to run but has not actually executed any
83862 ** instructions yet, leave the main database error information unchanged.
@@ -83365,11 +83866,10 @@
83866 if( db->pErr || p->zErrMsg ){
83867 sqlite3VdbeTransferError(p);
83868 }else{
83869 db->errCode = p->rc;
83870 }
 
83871 }
83872
83873 /* Reset register contents and reclaim error message memory.
83874 */
83875 #ifdef SQLITE_DEBUG
@@ -83486,11 +83986,11 @@
83986 **
83987 ** The difference between this function and sqlite3VdbeDelete() is that
83988 ** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with
83989 ** the database connection and frees the object itself.
83990 */
83991 static void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
83992 SubProgram *pSub, *pNext;
83993 assert( p->db==0 || p->db==db );
83994 if( p->aColName ){
83995 releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
83996 sqlite3DbFreeNN(db, p->aColName);
@@ -83536,18 +84036,20 @@
84036
84037 assert( p!=0 );
84038 db = p->db;
84039 assert( sqlite3_mutex_held(db->mutex) );
84040 sqlite3VdbeClearObject(db, p);
84041 if( db->pnBytesFreed==0 ){
84042 if( p->pPrev ){
84043 p->pPrev->pNext = p->pNext;
84044 }else{
84045 assert( db->pVdbe==p );
84046 db->pVdbe = p->pNext;
84047 }
84048 if( p->pNext ){
84049 p->pNext->pPrev = p->pPrev;
84050 }
84051 }
84052 sqlite3DbFreeNN(db, p);
84053 }
84054
84055 /*
@@ -83595,11 +84097,11 @@
84097 /*
84098 ** Check to ensure that the cursor is valid. Restore the cursor
84099 ** if need be. Return any I/O error from the restore operation.
84100 */
84101 SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){
84102 assert( p->eCurType==CURTYPE_BTREE || IsNullCursor(p) );
84103 if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
84104 return sqlite3VdbeHandleMovedCursor(p);
84105 }
84106 return SQLITE_OK;
84107 }
@@ -83608,11 +84110,11 @@
84110 ** The following functions:
84111 **
84112 ** sqlite3VdbeSerialType()
84113 ** sqlite3VdbeSerialTypeLen()
84114 ** sqlite3VdbeSerialLen()
84115 ** sqlite3VdbeSerialPut() <--- in-lined into OP_MakeRecord as of 2022-04-02
84116 ** sqlite3VdbeSerialGet()
84117 **
84118 ** encapsulate the code that serializes values for storage in SQLite
84119 ** data and index records. Each serialized value consists of a
84120 ** 'serial-type' and a blob of data. The serial type is an 8-byte unsigned
@@ -83720,11 +84222,11 @@
84222 #endif /* inlined into OP_MakeRecord */
84223
84224 /*
84225 ** The sizes for serial types less than 128
84226 */
84227 SQLITE_PRIVATE const u8 sqlite3SmallTypeSizes[128] = {
84228 /* 0 1 2 3 4 5 6 7 8 9 */
84229 /* 0 */ 0, 1, 2, 3, 4, 6, 8, 8, 0, 0,
84230 /* 10 */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
84231 /* 20 */ 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
84232 /* 30 */ 9, 9, 10, 10, 11, 11, 12, 12, 13, 13,
@@ -83789,11 +84291,11 @@
84291 ** works for him. We, the developers, have no way to independently
84292 ** verify this, but Frank seems to know what he is talking about
84293 ** so we trust him.
84294 */
84295 #ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
84296 SQLITE_PRIVATE u64 sqlite3FloatSwap(u64 in){
84297 union {
84298 u64 r;
84299 u32 i[2];
84300 } u;
84301 u32 t;
@@ -83802,63 +84304,12 @@
84304 t = u.i[0];
84305 u.i[0] = u.i[1];
84306 u.i[1] = t;
84307 return u.r;
84308 }
84309 #endif /* SQLITE_MIXED_ENDIAN_64BIT_FLOAT */
84310
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84311
84312 /* Input "x" is a sequence of unsigned characters that represent a
84313 ** big-endian integer. Return the equivalent native integer
84314 */
84315 #define ONE_BYTE_INT(x) ((i8)(x)[0])
@@ -84020,14 +84471,14 @@
84471 SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(
84472 KeyInfo *pKeyInfo /* Description of the record */
84473 ){
84474 UnpackedRecord *p; /* Unpacked record to return */
84475 int nByte; /* Number of bytes required for *p */
84476 nByte = ROUND8P(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1);
84477 p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte);
84478 if( !p ) return 0;
84479 p->aMem = (Mem*)&((char*)p)[ROUND8P(sizeof(UnpackedRecord))];
84480 assert( pKeyInfo->aSortFlags!=0 );
84481 p->pKeyInfo = pKeyInfo;
84482 p->nField = pKeyInfo->nKeyField + 1;
84483 return p;
84484 }
@@ -84521,18 +84972,26 @@
84972
84973 /* If bSkip is true, then the caller has already determined that the first
84974 ** two elements in the keys are equal. Fix the various stack variables so
84975 ** that this routine begins comparing at the second field. */
84976 if( bSkip ){
84977 u32 s1 = aKey1[1];
84978 if( s1<0x80 ){
84979 idx1 = 2;
84980 }else{
84981 idx1 = 1 + sqlite3GetVarint32(&aKey1[1], &s1);
84982 }
84983 szHdr1 = aKey1[0];
84984 d1 = szHdr1 + sqlite3VdbeSerialTypeLen(s1);
84985 i = 1;
84986 pRhs++;
84987 }else{
84988 if( (szHdr1 = aKey1[0])<0x80 ){
84989 idx1 = 1;
84990 }else{
84991 idx1 = sqlite3GetVarint32(aKey1, &szHdr1);
84992 }
84993 d1 = szHdr1;
84994 i = 0;
84995 }
84996 if( d1>(unsigned)nKey1 ){
84997 pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
@@ -85932,18 +86391,12 @@
86391 */
86392 static int sqlite3Step(Vdbe *p){
86393 sqlite3 *db;
86394 int rc;
86395
 
 
 
 
 
 
 
86396 assert(p);
86397 db = p->db;
86398 if( p->eVdbeState!=VDBE_RUN_STATE ){
86399 restart_step:
86400 if( p->eVdbeState==VDBE_READY_STATE ){
86401 if( p->expired ){
86402 p->rc = SQLITE_SCHEMA;
@@ -86087,11 +86540,10 @@
86540 if( vdbeSafetyNotNull(v) ){
86541 return SQLITE_MISUSE_BKPT;
86542 }
86543 db = v->db;
86544 sqlite3_mutex_enter(db->mutex);
 
86545 while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
86546 && cnt++ < SQLITE_MAX_SCHEMA_RETRY ){
86547 int savedPc = v->pc;
86548 rc = sqlite3Reprepare(v);
86549 if( rc!=SQLITE_OK ){
@@ -86113,11 +86565,17 @@
86565 v->rc = rc = SQLITE_NOMEM_BKPT;
86566 }
86567 break;
86568 }
86569 sqlite3_reset(pStmt);
86570 if( savedPc>=0 ){
86571 /* Setting minWriteFileFormat to 254 is a signal to the OP_Init and
86572 ** OP_Trace opcodes to *not* perform SQLITE_TRACE_STMT because one
86573 ** should output has already occurred due to SQLITE_SCHEMA.
86574 ** tag-20220401a */
86575 v->minWriteFileFormat = 254;
86576 }
86577 assert( v->expired==0 );
86578 }
86579 sqlite3_mutex_leave(db->mutex);
86580 return rc;
86581 }
@@ -87126,12 +87584,11 @@
87584 if( op==SQLITE_STMTSTATUS_MEMUSED ){
87585 sqlite3 *db = pVdbe->db;
87586 sqlite3_mutex_enter(db->mutex);
87587 v = 0;
87588 db->pnBytesFreed = (int*)&v;
87589 sqlite3VdbeDelete(pVdbe);
 
87590 db->pnBytesFreed = 0;
87591 sqlite3_mutex_leave(db->mutex);
87592 }else{
87593 v = pVdbe->aCounter[op];
87594 if( resetFlag ) pVdbe->aCounter[op] = 0;
@@ -87920,16 +88377,16 @@
88377 Mem *pMem = iCur>0 ? &p->aMem[p->nMem-iCur] : p->aMem;
88378
88379 int nByte;
88380 VdbeCursor *pCx = 0;
88381 nByte =
88382 ROUND8P(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField +
88383 (eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0);
88384
88385 assert( iCur>=0 && iCur<p->nCursor );
88386 if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/
88387 sqlite3VdbeFreeCursorNN(p, p->apCsr[iCur]);
88388 p->apCsr[iCur] = 0;
88389 }
88390
88391 /* There used to be a call to sqlite3VdbeMemClearAndResize() to make sure
88392 ** the pMem used to hold space for the cursor has enough storage available
@@ -87955,11 +88412,11 @@
88412 pCx->eCurType = eCurType;
88413 pCx->nField = nField;
88414 pCx->aOffset = &pCx->aType[nField];
88415 if( eCurType==CURTYPE_BTREE ){
88416 pCx->uc.pCursor = (BtCursor*)
88417 &pMem->z[ROUND8P(sizeof(VdbeCursor))+2*sizeof(u32)*nField];
88418 sqlite3BtreeCursorZero(pCx->uc.pCursor);
88419 }
88420 return pCx;
88421 }
88422
@@ -88637,32 +89094,43 @@
89094 assert( VdbeMemDynamic(pIn1)==0 );
89095 memAboutToChange(p, pIn1);
89096 pIn1->flags = MEM_Int;
89097 pIn1->u.i = (int)(pOp-aOp);
89098 REGISTER_TRACE(pOp->p1, pIn1);
89099 goto jump_to_p2_and_check_for_interrupt;
89100 }
89101
89102 /* Opcode: Return P1 P2 P3 * *
89103 **
89104 ** Jump to the address stored in register P1. If P1 is a return address
89105 ** register, then this accomplishes a return from a subroutine.
89106 **
89107 ** If P3 is 1, then the jump is only taken if register P1 holds an integer
89108 ** values, otherwise execution falls through to the next opcode, and the
89109 ** OP_Return becomes a no-op. If P3 is 0, then register P1 must hold an
89110 ** integer or else an assert() is raised. P3 should be set to 1 when
89111 ** this opcode is used in combination with OP_BeginSubrtn, and set to 0
89112 ** otherwise.
89113 **
89114 ** The value in register P1 is unchanged by this opcode.
89115 **
89116 ** P2 is not used by the byte-code engine. However, if P2 is positive
89117 ** and also less than the current address, then the "EXPLAIN" output
89118 ** formatter in the CLI will indent all opcodes from the P2 opcode up
89119 ** to be not including the current Return. P2 should be the first opcode
89120 ** in the subroutine from which this opcode is returnning. Thus the P2
89121 ** value is a byte-code indentation hint. See tag-20220407a in
89122 ** wherecode.c and shell.c.
89123 */
89124 case OP_Return: { /* in1 */
89125 pIn1 = &aMem[pOp->p1];
89126 if( pIn1->flags & MEM_Int ){
89127 if( pOp->p3 ){ VdbeBranchTaken(1, 2); }
89128 pOp = &aOp[pIn1->u.i];
89129 }else if( ALWAYS(pOp->p3) ){
89130 VdbeBranchTaken(0, 2);
89131 }
89132 break;
89133 }
89134
89135 /* Opcode: InitCoroutine P1 P2 P3 * *
89136 **
@@ -88681,11 +89149,16 @@
89149 assert( pOp->p3>=0 && pOp->p3<p->nOp );
89150 pOut = &aMem[pOp->p1];
89151 assert( !VdbeMemDynamic(pOut) );
89152 pOut->u.i = pOp->p3 - 1;
89153 pOut->flags = MEM_Int;
89154 if( pOp->p2==0 ) break;
89155
89156 /* Most jump operations do a goto to this spot in order to update
89157 ** the pOp pointer. */
89158 jump_to_p2:
89159 pOp = &aOp[pOp->p2 - 1];
89160 break;
89161 }
89162
89163 /* Opcode: EndCoroutine P1 * * * *
89164 **
@@ -88783,15 +89256,14 @@
89256 */
89257 case OP_Halt: {
89258 VdbeFrame *pFrame;
89259 int pcx;
89260
 
89261 #ifdef SQLITE_DEBUG
89262 if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); }
89263 #endif
89264 if( p->pFrame && pOp->p1==SQLITE_OK ){
89265 /* Halt the sub-program. Return control to the parent frame. */
89266 pFrame = p->pFrame;
89267 p->pFrame = pFrame->pParent;
89268 p->nFrame--;
89269 sqlite3VdbeSetChanges(db, p->nChange);
@@ -88809,11 +89281,10 @@
89281 pOp = &aOp[pcx];
89282 break;
89283 }
89284 p->rc = pOp->p1;
89285 p->errorAction = (u8)pOp->p2;
 
89286 assert( pOp->p5<=4 );
89287 if( p->rc ){
89288 if( pOp->p5 ){
89289 static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK",
89290 "FOREIGN KEY" };
@@ -88826,10 +89297,11 @@
89297 p->zErrMsg = sqlite3MPrintf(db, "%z: %s", p->zErrMsg, pOp->p4.z);
89298 }
89299 }else{
89300 sqlite3VdbeError(p, "%s", pOp->p4.z);
89301 }
89302 pcx = (int)(pOp - aOp);
89303 sqlite3_log(pOp->p1, "abort at %d in [%s]: %s", pcx, p->zSql, p->zErrMsg);
89304 }
89305 rc = sqlite3VdbeHalt(p);
89306 assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
89307 if( rc==SQLITE_BUSY ){
@@ -88840,26 +89312,15 @@
89312 rc = p->rc ? SQLITE_ERROR : SQLITE_DONE;
89313 }
89314 goto vdbe_return;
89315 }
89316
 
 
 
 
 
 
 
 
 
 
89317 /* Opcode: Integer P1 P2 * * *
89318 ** Synopsis: r[P2]=P1
89319 **
89320 ** The 32-bit integer value P1 is written into register P2.
89321 */
 
89322 case OP_Integer: { /* out2 */
89323 pOut = out2Prerelease(p, pOp);
89324 pOut->u.i = pOp->p1;
89325 break;
89326 }
@@ -88962,10 +89423,32 @@
89423 }
89424 #endif
89425 break;
89426 }
89427
89428 /* Opcode: BeginSubrtn * P2 * * *
89429 ** Synopsis: r[P2]=NULL
89430 **
89431 ** Mark the beginning of a subroutine that can be entered in-line
89432 ** or that can be called using OP_Gosub. The subroutine should
89433 ** be terminated by an OP_Return instruction that has a P1 operand that
89434 ** is the same as the P2 operand to this opcode and that has P3 set to 1.
89435 ** If the subroutine is entered in-line, then the OP_Return will simply
89436 ** fall through. But if the subroutine is entered using OP_Gosub, then
89437 ** the OP_Return will jump back to the first instruction after the OP_Gosub.
89438 **
89439 ** This routine works by loading a NULL into the P2 register. When the
89440 ** return address register contains a NULL, the OP_Return instruction is
89441 ** a no-op that simply falls through to the next instruction (assuming that
89442 ** the OP_Return opcode has a P3 value of 1). Thus if the subroutine is
89443 ** entered in-line, then the OP_Return will cause in-line execution to
89444 ** continue. But if the subroutine is entered via OP_Gosub, then the
89445 ** OP_Return will cause a return to the address following the OP_Gosub.
89446 **
89447 ** This opcode is identical to OP_Null. It has a different name
89448 ** only to make the byte code easier to read and verify.
89449 */
89450 /* Opcode: Null P1 P2 P3 * *
89451 ** Synopsis: r[P2..P3]=NULL
89452 **
89453 ** Write a NULL into registers P2. If P3 greater than P2, then also write
89454 ** NULL into register P3 and every register in between P2 and P3. If P3
@@ -88974,10 +89457,11 @@
89457 **
89458 ** If the P1 value is non-zero, then also set the MEM_Cleared flag so that
89459 ** NULL values will not compare equal even if SQLITE_NULLEQ is set on
89460 ** OP_Ne or OP_Eq.
89461 */
89462 case OP_BeginSubrtn:
89463 case OP_Null: { /* out2 */
89464 int cnt;
89465 u16 nullFlag;
89466 pOut = out2Prerelease(p, pOp);
89467 cnt = pOp->p3-pOp->p2;
@@ -89203,49 +89687,36 @@
89687 ** with an SQLITE_ROW return code and it sets up the sqlite3_stmt
89688 ** structure to provide access to the r(P1)..r(P1+P2-1) values as
89689 ** the result row.
89690 */
89691 case OP_ResultRow: {
 
 
89692 assert( p->nResColumn==pOp->p2 );
89693 assert( pOp->p1>0 || CORRUPT_DB );
89694 assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 );
89695
 
89696 p->cacheCtr = (p->cacheCtr + 2)|1;
89697 p->pResultSet = &aMem[pOp->p1];
 
 
 
 
 
 
 
 
 
 
 
 
89698 #ifdef SQLITE_DEBUG
89699 {
89700 Mem *pMem = p->pResultSet;
89701 int i;
89702 for(i=0; i<pOp->p2; i++){
89703 assert( memIsValid(&pMem[i]) );
89704 REGISTER_TRACE(pOp->p1+i, &pMem[i]);
89705 /* The registers in the result will not be used again when the
89706 ** prepared statement restarts. This is because sqlite3_column()
89707 ** APIs might have caused type conversions of made other changes to
89708 ** the register values. Therefore, we can go ahead and break any
89709 ** OP_SCopy dependencies. */
89710 pMem[i].pScopyFrom = 0;
89711 }
89712 }
89713 #endif
 
89714 if( db->mallocFailed ) goto no_mem;
 
89715 if( db->mTrace & SQLITE_TRACE_ROW ){
89716 db->trace.xV2(SQLITE_TRACE_ROW, db->pTraceArg, p, 0);
89717 }
 
 
 
 
89718 p->pc = (int)(pOp - aOp) + 1;
89719 rc = SQLITE_ROW;
89720 goto vdbe_return;
89721 }
89722
@@ -89755,27 +90226,27 @@
90226 flags3 = pIn3->flags;
90227 if( (flags1 & flags3 & MEM_Int)!=0 ){
90228 assert( (pOp->p5 & SQLITE_AFF_MASK)!=SQLITE_AFF_TEXT || CORRUPT_DB );
90229 /* Common case of comparison of two integers */
90230 if( pIn3->u.i > pIn1->u.i ){
 
90231 if( sqlite3aGTb[pOp->opcode] ){
90232 VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3);
90233 goto jump_to_p2;
90234 }
90235 iCompare = +1;
90236 }else if( pIn3->u.i < pIn1->u.i ){
 
90237 if( sqlite3aLTb[pOp->opcode] ){
90238 VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3);
90239 goto jump_to_p2;
90240 }
90241 iCompare = -1;
90242 }else{
 
90243 if( sqlite3aEQb[pOp->opcode] ){
90244 VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3);
90245 goto jump_to_p2;
90246 }
90247 iCompare = 0;
90248 }
90249 VdbeBranchTaken(0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
90250 break;
90251 }
90252 if( (flags1 | flags3)&MEM_Null ){
@@ -89798,15 +90269,15 @@
90269 }else{
90270 /* SQLITE_NULLEQ is clear and at least one operand is NULL,
90271 ** then the result is always NULL.
90272 ** The jump is taken if the SQLITE_JUMPIFNULL bit is set.
90273 */
 
90274 VdbeBranchTaken(2,3);
90275 if( pOp->p5 & SQLITE_JUMPIFNULL ){
90276 goto jump_to_p2;
90277 }
90278 iCompare = 1; /* Operands are not equal */
90279 break;
90280 }
90281 }else{
90282 /* Neither operand is NULL and we couldn't do the special high-speed
90283 ** integer comparison case. So do a general-case comparison. */
@@ -89908,13 +90379,12 @@
90379 /* Opcode: Permutation * * * P4 *
90380 **
90381 ** Set the permutation used by the OP_Compare operator in the next
90382 ** instruction. The permutation is stored in the P4 operand.
90383 **
90384 ** The permutation is only valid for the next opcode which must be
90385 ** an OP_Compare that has the OPFLAG_PERMUTE bit set in P5.
 
90386 **
90387 ** The first integer in the P4 integer array is the length of the array
90388 ** and does not become part of the permutation.
90389 */
90390 case OP_Permutation: {
@@ -89942,10 +90412,12 @@
90412 ** only. The KeyInfo elements are used sequentially.
90413 **
90414 ** The comparison is a sort comparison, so NULLs compare equal,
90415 ** NULLs are less than numbers, numbers are less than strings,
90416 ** and strings are less than blobs.
90417 **
90418 ** This opcode must be immediately followed by an OP_Jump opcode.
90419 */
90420 case OP_Compare: {
90421 int n;
90422 int i;
90423 int p1;
@@ -90000,20 +90472,24 @@
90472 }
90473 if( bRev ) iCompare = -iCompare;
90474 break;
90475 }
90476 }
90477 assert( pOp[1].opcode==OP_Jump );
90478 break;
90479 }
90480
90481 /* Opcode: Jump P1 P2 P3 * *
90482 **
90483 ** Jump to the instruction at address P1, P2, or P3 depending on whether
90484 ** in the most recent OP_Compare instruction the P1 vector was less than
90485 ** equal to, or greater than the P2 vector, respectively.
90486 **
90487 ** This opcode must immediately follow an OP_Compare opcode.
90488 */
90489 case OP_Jump: { /* jump */
90490 assert( pOp>aOp && pOp[-1].opcode==OP_Compare );
90491 if( iCompare<0 ){
90492 VdbeBranchTaken(0,4); pOp = &aOp[pOp->p1 - 1];
90493 }else if( iCompare==0 ){
90494 VdbeBranchTaken(1,4); pOp = &aOp[pOp->p2 - 1];
90495 }else{
@@ -90314,11 +90790,11 @@
90790 break;
90791 }
90792 #endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */
90793
90794 /* Opcode: Column P1 P2 P3 P4 P5
90795 ** Synopsis: r[P3]=PX cursor P1 column P2
90796 **
90797 ** Interpret the data that cursor P1 points to as a structure built using
90798 ** the MakeRecord instruction. (See the MakeRecord opcode for additional
90799 ** information about the format of the data.) Extract the P2-th column
90800 ** from this record. If there are less that (P2+1)
@@ -90356,23 +90832,23 @@
90832 pC = p->apCsr[pOp->p1];
90833 p2 = (u32)pOp->p2;
90834
90835 op_column_restart:
90836 assert( pC!=0 );
90837 assert( p2<(u32)pC->nField
90838 || (pC->eCurType==CURTYPE_PSEUDO && pC->seekResult==0) );
90839 aOffset = pC->aOffset;
90840 assert( aOffset==pC->aType+pC->nField );
90841 assert( pC->eCurType!=CURTYPE_VTAB );
90842 assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow );
90843 assert( pC->eCurType!=CURTYPE_SORTER );
90844
90845 if( pC->cacheStatus!=p->cacheCtr ){ /*OPTIMIZATION-IF-FALSE*/
90846 if( pC->nullRow ){
90847 if( pC->eCurType==CURTYPE_PSEUDO && pC->seekResult>0 ){
90848 /* For the special case of as pseudo-cursor, the seekResult field
90849 ** identifies the register that holds the record */
 
90850 pReg = &aMem[pC->seekResult];
90851 assert( pReg->flags & MEM_Blob );
90852 assert( memIsValid(pReg) );
90853 pC->payloadSize = pC->szRow = pReg->n;
90854 pC->aRow = (u8*)pReg->z;
@@ -90406,11 +90882,15 @@
90882 pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &pC->szRow);
90883 assert( pC->szRow<=pC->payloadSize );
90884 assert( pC->szRow<=65536 ); /* Maximum page size is 64KiB */
90885 }
90886 pC->cacheStatus = p->cacheCtr;
90887 if( (aOffset[0] = pC->aRow[0])<0x80 ){
90888 pC->iHdrOffset = 1;
90889 }else{
90890 pC->iHdrOffset = sqlite3GetVarint32(pC->aRow, aOffset);
90891 }
90892 pC->nHdrParsed = 0;
90893
90894 if( pC->szRow<aOffset[0] ){ /*OPTIMIZATION-IF-FALSE*/
90895 /* pC->aRow does not have to hold the entire row, but it does at least
90896 ** need to cover the header of the record. If pC->aRow does not contain
@@ -91041,22 +91521,64 @@
91521 UPDATE_MAX_BLOBSIZE(pOut);
91522 zHdr = (u8 *)pOut->z;
91523 zPayload = zHdr + nHdr;
91524
91525 /* Write the record */
91526 if( nHdr<0x80 ){
91527 *(zHdr++) = nHdr;
91528 }else{
91529 zHdr += sqlite3PutVarint(zHdr,nHdr);
91530 }
91531 assert( pData0<=pLast );
91532 pRec = pData0;
91533 while( 1 /*exit-by-break*/ ){
91534 serial_type = pRec->uTemp;
91535 /* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more
91536 ** additional varints, one per column.
91537 ** EVIDENCE-OF: R-64536-51728 The values for each column in the record
 
91538 ** immediately follow the header. */
91539 if( serial_type<=7 ){
91540 *(zHdr++) = serial_type;
91541 if( serial_type==0 ){
91542 /* NULL value. No change in zPayload */
91543 }else{
91544 u64 v;
91545 u32 i;
91546 if( serial_type==7 ){
91547 assert( sizeof(v)==sizeof(pRec->u.r) );
91548 memcpy(&v, &pRec->u.r, sizeof(v));
91549 swapMixedEndianFloat(v);
91550 }else{
91551 v = pRec->u.i;
91552 }
91553 len = i = sqlite3SmallTypeSizes[serial_type];
91554 assert( i>0 );
91555 while( 1 /*exit-by-break*/ ){
91556 zPayload[--i] = (u8)(v&0xFF);
91557 if( i==0 ) break;
91558 v >>= 8;
91559 }
91560 zPayload += len;
91561 }
91562 }else if( serial_type<0x80 ){
91563 *(zHdr++) = serial_type;
91564 if( serial_type>=14 && pRec->n>0 ){
91565 assert( pRec->z!=0 );
91566 memcpy(zPayload, pRec->z, pRec->n);
91567 zPayload += pRec->n;
91568 }
91569 }else{
91570 zHdr += sqlite3PutVarint(zHdr, serial_type);
91571 if( pRec->n ){
91572 assert( pRec->z!=0 );
91573 memcpy(zPayload, pRec->z, pRec->n);
91574 zPayload += pRec->n;
91575 }
91576 }
91577 if( pRec==pLast ) break;
91578 pRec++;
91579 }
91580 assert( nHdr==(int)(zHdr - (u8*)pOut->z) );
91581 assert( nByte==(int)(zPayload - (u8*)pOut->z) );
91582
91583 assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
91584 REGISTER_TRACE(pOp->p3, pOut);
@@ -91271,11 +91793,14 @@
91793 if( rc!=SQLITE_OK ) goto abort_due_to_error;
91794 }
91795 }
91796 }
91797 if( rc ) goto abort_due_to_error;
91798 if( p->eVdbeState==VDBE_HALT_STATE ){
91799 rc = SQLITE_DONE;
91800 goto vdbe_return;
91801 }
91802 break;
91803 }
91804
91805 /* Opcode: AutoCommit P1 P2 * * *
91806 **
@@ -91375,10 +91900,11 @@
91900 ** halts. The sqlite3_step() wrapper function might then reprepare the
91901 ** statement and rerun it from the beginning.
91902 */
91903 case OP_Transaction: {
91904 Btree *pBt;
91905 Db *pDb;
91906 int iMeta = 0;
91907
91908 assert( p->bIsReader );
91909 assert( p->readOnly==0 || pOp->p2==0 );
91910 assert( pOp->p2>=0 && pOp->p2<=2 );
@@ -91394,11 +91920,12 @@
91920 ** transaction */
91921 rc = SQLITE_CORRUPT;
91922 }
91923 goto abort_due_to_error;
91924 }
91925 pDb = &db->aDb[pOp->p1];
91926 pBt = pDb->pBt;
91927
91928 if( pBt ){
91929 rc = sqlite3BtreeBeginTrans(pBt, pOp->p2, &iMeta);
91930 testcase( rc==SQLITE_BUSY_SNAPSHOT );
91931 testcase( rc==SQLITE_BUSY_RECOVERY );
@@ -91435,12 +91962,11 @@
91962 }
91963 }
91964 assert( pOp->p5==0 || pOp->p4type==P4_INT32 );
91965 if( rc==SQLITE_OK
91966 && pOp->p5
91967 && (iMeta!=pOp->p3 || pDb->pSchema->iGeneration!=pOp->p4.i)
 
91968 ){
91969 /*
91970 ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema
91971 ** version is checked to ensure that the schema has not changed since the
91972 ** SQL statement was prepared.
@@ -92579,15 +93105,12 @@
93105 }
93106 case OP_NoConflict: /* jump, in3 */
93107 case OP_NotFound: /* jump, in3 */
93108 case OP_Found: { /* jump, in3 */
93109 int alreadyExists;
 
93110 int ii;
93111 VdbeCursor *pC;
 
 
93112 UnpackedRecord *pIdxKey;
93113 UnpackedRecord r;
93114
93115 #ifdef SQLITE_TEST
93116 if( pOp->opcode!=OP_NoConflict ) sqlite3_found_count++;
@@ -92598,66 +93121,71 @@
93121 pC = p->apCsr[pOp->p1];
93122 assert( pC!=0 );
93123 #ifdef SQLITE_DEBUG
93124 pC->seekOp = pOp->opcode;
93125 #endif
93126 r.aMem = &aMem[pOp->p3];
93127 assert( pC->eCurType==CURTYPE_BTREE );
93128 assert( pC->uc.pCursor!=0 );
93129 assert( pC->isTable==0 );
93130 r.nField = (u16)pOp->p4.i;
93131 if( r.nField>0 ){
93132 /* Key values in an array of registers */
93133 r.pKeyInfo = pC->pKeyInfo;
93134 r.default_rc = 0;
 
93135 #ifdef SQLITE_DEBUG
93136 for(ii=0; ii<r.nField; ii++){
93137 assert( memIsValid(&r.aMem[ii]) );
93138 assert( (r.aMem[ii].flags & MEM_Zero)==0 || r.aMem[ii].n==0 );
93139 if( ii ) REGISTER_TRACE(pOp->p3+ii, &r.aMem[ii]);
93140 }
93141 #endif
93142 rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, &r, &pC->seekResult);
 
93143 }else{
93144 /* Composite key generated by OP_MakeRecord */
93145 assert( r.aMem->flags & MEM_Blob );
93146 assert( pOp->opcode!=OP_NoConflict );
93147 rc = ExpandBlob(r.aMem);
93148 assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
93149 if( rc ) goto no_mem;
93150 pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo);
93151 if( pIdxKey==0 ) goto no_mem;
93152 sqlite3VdbeRecordUnpack(pC->pKeyInfo, r.aMem->n, r.aMem->z, pIdxKey);
93153 pIdxKey->default_rc = 0;
93154 rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, pIdxKey, &pC->seekResult);
93155 sqlite3DbFreeNN(db, pIdxKey);
93156 }
 
 
 
 
 
 
 
 
 
 
 
 
93157 if( rc!=SQLITE_OK ){
93158 goto abort_due_to_error;
93159 }
93160 alreadyExists = (pC->seekResult==0);
 
93161 pC->nullRow = 1-alreadyExists;
93162 pC->deferredMoveto = 0;
93163 pC->cacheStatus = CACHE_STALE;
93164 if( pOp->opcode==OP_Found ){
93165 VdbeBranchTaken(alreadyExists!=0,2);
93166 if( alreadyExists ) goto jump_to_p2;
93167 }else{
93168 if( !alreadyExists ){
93169 VdbeBranchTaken(1,2);
93170 goto jump_to_p2;
93171 }
93172 if( pOp->opcode==OP_NoConflict ){
93173 /* For the OP_NoConflict opcode, take the jump if any of the
93174 ** input fields are NULL, since any key with a NULL will not
93175 ** conflict */
93176 for(ii=0; ii<r.nField; ii++){
93177 if( r.aMem[ii].flags & MEM_Null ){
93178 VdbeBranchTaken(1,2);
93179 goto jump_to_p2;
93180 }
93181 }
93182 }
93183 VdbeBranchTaken(0,2);
93184 if( pOp->opcode==OP_IfNoHope ){
93185 pC->seekHit = pOp->p4.i;
93186 }
93187 }
93188 break;
93189 }
93190
93191 /* Opcode: SeekRowid P1 P2 P3 * *
@@ -93344,11 +93872,11 @@
93872 REGISTER_TRACE(pOp->p2, pOut);
93873 break;
93874 }
93875
93876 /* Opcode: Rowid P1 P2 * * *
93877 ** Synopsis: r[P2]=PX rowid of P1
93878 **
93879 ** Store in register P2 an integer which is the key of the table entry that
93880 ** P1 is currently point to.
93881 **
93882 ** P1 can be either an ordinary table or a virtual table. There used to
@@ -93400,20 +93928,27 @@
93928 **
93929 ** Move the cursor P1 to a null row. Any OP_Column operations
93930 ** that occur while the cursor is on the null row will always
93931 ** write a NULL.
93932 **
93933 ** If cursor P1 is not previously opened, open it now to a special
93934 ** pseudo-cursor that always returns NULL for every column.
 
93935 */
93936 case OP_NullRow: {
93937 VdbeCursor *pC;
93938
93939 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
93940 pC = p->apCsr[pOp->p1];
93941 if( pC==0 ){
93942 /* If the cursor is not already open, create a special kind of
93943 ** pseudo-cursor that always gives null rows. */
93944 pC = allocateCursor(p, pOp->p1, 1, CURTYPE_PSEUDO);
93945 if( pC==0 ) goto no_mem;
93946 pC->seekResult = 0;
93947 pC->isTable = 1;
93948 pC->uc.pCursor = sqlite3BtreeFakeValidCursor();
93949 }
93950 pC->nullRow = 1;
93951 pC->cacheStatus = CACHE_STALE;
93952 if( pC->eCurType==CURTYPE_BTREE ){
93953 assert( pC->uc.pCursor!=0 );
93954 sqlite3BtreeClearCursor(pC->uc.pCursor);
@@ -93856,13 +94391,13 @@
94391 i64 rowid; /* Rowid that P1 current points to */
94392
94393 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
94394 pC = p->apCsr[pOp->p1];
94395 assert( pC!=0 );
94396 assert( pC->eCurType==CURTYPE_BTREE || IsNullCursor(pC) );
94397 assert( pC->uc.pCursor!=0 );
94398 assert( pC->isTable==0 || IsNullCursor(pC) );
94399 assert( pC->deferredMoveto==0 );
94400 assert( !pC->nullRow || pOp->opcode==OP_IdxRowid );
94401
94402 /* The IdxRowid and Seek opcodes are combined because of the commonality
94403 ** of sqlite3VdbeCursorRestore() and sqlite3VdbeIdxRowid(). */
@@ -95994,11 +96529,11 @@
96529 /* OP_Init is always instruction 0 */
96530 assert( pOp==p->aOp || pOp->opcode==OP_Trace );
96531
96532 #ifndef SQLITE_OMIT_TRACE
96533 if( (db->mTrace & (SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0
96534 && p->minWriteFileFormat!=254 /* tag-20220401a */
96535 && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
96536 ){
96537 #ifndef SQLITE_OMIT_DEPRECATED
96538 if( db->mTrace & SQLITE_TRACE_LEGACY ){
96539 char *z = sqlite3VdbeExpandSql(p, zTrace);
@@ -96223,11 +96758,11 @@
96758 p->rc = rc;
96759 sqlite3SystemError(db, rc);
96760 testcase( sqlite3GlobalConfig.xLog!=0 );
96761 sqlite3_log(rc, "statement aborts at %d: [%s] %s",
96762 (int)(pOp - aOp), p->zSql, p->zErrMsg);
96763 if( p->eVdbeState==VDBE_RUN_STATE ) sqlite3VdbeHalt(p);
96764 if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db);
96765 if( rc==SQLITE_CORRUPT && db->autoCommit==0 ){
96766 db->flags |= SQLITE_CorruptRdOnly;
96767 }
96768 rc = SQLITE_ERROR;
@@ -100815,27 +101350,10 @@
101350 }
101351 sqlite3DbFree(db, pDup);
101352 }
101353 }
101354
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101355 /*
101356 ** Subqueries stores the original database, table and column names for their
101357 ** result sets in ExprList.a[].zSpan, in the form "DATABASE.TABLE.COLUMN".
101358 ** Check to see if the zSpan given to this routine matches the zDb, zTab,
101359 ** and zCol. If any of zDb, zTab, and zCol are NULL then those fields will
@@ -100907,10 +101425,33 @@
101425 testcase( n==BMS );
101426 if( n>=BMS ) n = BMS-1;
101427 return ((Bitmask)1)<<n;
101428 }
101429 }
101430
101431 /*
101432 ** Create a new expression term for the column specified by pMatch and
101433 ** iColumn. Append this new expression term to the FULL JOIN Match set
101434 ** in *ppList. Create a new *ppList if this is the first term in the
101435 ** set.
101436 */
101437 static void extendFJMatch(
101438 Parse *pParse, /* Parsing context */
101439 ExprList **ppList, /* ExprList to extend */
101440 SrcItem *pMatch, /* Source table containing the column */
101441 i16 iColumn /* The column number */
101442 ){
101443 Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0);
101444 if( pNew ){
101445 pNew->iTable = pMatch->iCursor;
101446 pNew->iColumn = iColumn;
101447 pNew->y.pTab = pMatch->pTab;
101448 assert( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 );
101449 ExprSetProperty(pNew, EP_CanBeNull);
101450 *ppList = sqlite3ExprListAppend(pParse, *ppList, pNew);
101451 }
101452 }
101453
101454 /*
101455 ** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
101456 ** that name in the set of source tables in pSrcList and make the pExpr
101457 ** expression node refer back to that source column. The following changes
@@ -100953,15 +101494,17 @@
101494 SrcItem *pItem; /* Use for looping over pSrcList items */
101495 SrcItem *pMatch = 0; /* The matching pSrcList item */
101496 NameContext *pTopNC = pNC; /* First namecontext in the list */
101497 Schema *pSchema = 0; /* Schema of the expression */
101498 int eNewExprOp = TK_COLUMN; /* New value for pExpr->op on success */
101499 Table *pTab = 0; /* Table holding the row */
101500 Column *pCol; /* A column of pTab */
101501 ExprList *pFJMatch = 0; /* Matches for FULL JOIN .. USING */
101502
101503 assert( pNC ); /* the name context cannot be NULL. */
101504 assert( zCol ); /* The Z in X.Y.Z cannot be NULL */
101505 assert( zDb==0 || zTab!=0 );
101506 assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
101507
101508 /* Initialize the node to no-match */
101509 pExpr->iTable = -1;
101510 ExprSetVVAProperty(pExpr, EP_NoReduce);
@@ -101006,30 +101549,68 @@
101549 for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
101550 u8 hCol;
101551 pTab = pItem->pTab;
101552 assert( pTab!=0 && pTab->zName!=0 );
101553 assert( pTab->nCol>0 || pParse->nErr );
101554 assert( pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) );
101555 if( pItem->fg.isNestedFrom ){
101556 /* In this case, pItem is a subquery that has been formed from a
101557 ** parenthesized subset of the FROM clause terms. Example:
101558 ** .... FROM t1 LEFT JOIN (t2 RIGHT JOIN t3 USING(x)) USING(y) ...
101559 ** \_________________________/
101560 ** This pItem -------------^
101561 */
101562 int hit = 0;
101563 assert( pItem->pSelect!=0 );
101564 pEList = pItem->pSelect->pEList;
101565 assert( pEList!=0 );
101566 assert( pEList->nExpr==pTab->nCol );
101567 for(j=0; j<pEList->nExpr; j++){
101568 if( !sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb) ){
101569 continue;
 
 
 
 
101570 }
101571 if( cnt>0 ){
101572 if( pItem->fg.isUsing==0
101573 || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0
101574 ){
101575 /* Two or more tables have the same column name which is
101576 ** not joined by USING. This is an error. Signal as much
101577 ** by clearing pFJMatch and letting cnt go above 1. */
101578 sqlite3ExprListDelete(db, pFJMatch);
101579 pFJMatch = 0;
101580 }else
101581 if( (pItem->fg.jointype & JT_RIGHT)==0 ){
101582 /* An INNER or LEFT JOIN. Use the left-most table */
101583 continue;
101584 }else
101585 if( (pItem->fg.jointype & JT_LEFT)==0 ){
101586 /* A RIGHT JOIN. Use the right-most table */
101587 cnt = 0;
101588 sqlite3ExprListDelete(db, pFJMatch);
101589 pFJMatch = 0;
101590 }else{
101591 /* For a FULL JOIN, we must construct a coalesce() func */
101592 extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn);
101593 }
101594 }
101595 cnt++;
101596 cntTab = 2;
101597 pMatch = pItem;
101598 pExpr->iColumn = j;
101599 pEList->a[j].bUsed = 1;
101600 hit = 1;
101601 }
101602 if( hit || zTab==0 ) continue;
101603 }
101604 assert( zDb==0 || zTab!=0 );
 
 
 
101605 if( zTab ){
101606 const char *zTabName;
101607 if( zDb ){
101608 if( pTab->pSchema!=pSchema ) continue;
101609 if( pSchema==0 && strcmp(zDb,"*")!=0 ) continue;
101610 }
101611 zTabName = pItem->zAlias ? pItem->zAlias : pTab->zName;
101612 assert( zTabName!=0 );
101613 if( sqlite3StrICmp(zTabName, zTab)!=0 ){
101614 continue;
101615 }
101616 assert( ExprUseYTab(pExpr) );
@@ -101040,22 +101621,41 @@
101621 hCol = sqlite3StrIHash(zCol);
101622 for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
101623 if( pCol->hName==hCol
101624 && sqlite3StrICmp(pCol->zCnName, zCol)==0
101625 ){
101626 if( cnt>0 ){
101627 if( pItem->fg.isUsing==0
101628 || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0
101629 ){
101630 /* Two or more tables have the same column name which is
101631 ** not joined by USING. This is an error. Signal as much
101632 ** by clearing pFJMatch and letting cnt go above 1. */
101633 sqlite3ExprListDelete(db, pFJMatch);
101634 pFJMatch = 0;
101635 }else
101636 if( (pItem->fg.jointype & JT_RIGHT)==0 ){
101637 /* An INNER or LEFT JOIN. Use the left-most table */
101638 continue;
101639 }else
101640 if( (pItem->fg.jointype & JT_LEFT)==0 ){
101641 /* A RIGHT JOIN. Use the right-most table */
101642 cnt = 0;
101643 sqlite3ExprListDelete(db, pFJMatch);
101644 pFJMatch = 0;
101645 }else{
101646 /* For a FULL JOIN, we must construct a coalesce() func */
101647 extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn);
101648 }
101649 }
101650 cnt++;
101651 pMatch = pItem;
101652 /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
101653 pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j;
101654 if( pItem->fg.isNestedFrom ){
101655 sqlite3SrcItemColumnUsed(pItem, j);
101656 }
101657 break;
101658 }
101659 }
101660 if( 0==cnt && VisibleRowid(pTab) ){
101661 cntTab++;
@@ -101064,13 +101664,11 @@
101664 }
101665 if( pMatch ){
101666 pExpr->iTable = pMatch->iCursor;
101667 assert( ExprUseYTab(pExpr) );
101668 pExpr->y.pTab = pMatch->pTab;
101669 if( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 ){
 
 
101670 ExprSetProperty(pExpr, EP_CanBeNull);
101671 }
101672 pSchema = pExpr->y.pTab->pSchema;
101673 }
101674 } /* if( pSrcList ) */
@@ -101307,15 +101905,41 @@
101905 return WRC_Prune;
101906 }
101907 }
101908
101909 /*
101910 ** cnt==0 means there was not match.
101911 ** cnt>1 means there were two or more matches.
101912 **
101913 ** cnt==0 is always an error. cnt>1 is often an error, but might
101914 ** be multiple matches for a NATURAL LEFT JOIN or a LEFT JOIN USING.
101915 */
101916 assert( pFJMatch==0 || cnt>0 );
101917 assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) );
101918 if( cnt!=1 ){
101919 const char *zErr;
101920 if( pFJMatch ){
101921 if( pFJMatch->nExpr==cnt-1 ){
101922 if( ExprHasProperty(pExpr,EP_Leaf) ){
101923 ExprClearProperty(pExpr,EP_Leaf);
101924 }else{
101925 sqlite3ExprDelete(db, pExpr->pLeft);
101926 pExpr->pLeft = 0;
101927 sqlite3ExprDelete(db, pExpr->pRight);
101928 pExpr->pRight = 0;
101929 }
101930 extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn);
101931 pExpr->op = TK_FUNCTION;
101932 pExpr->u.zToken = "coalesce";
101933 pExpr->x.pList = pFJMatch;
101934 cnt = 1;
101935 goto lookupname_end;
101936 }else{
101937 sqlite3ExprListDelete(db, pFJMatch);
101938 pFJMatch = 0;
101939 }
101940 }
101941 zErr = cnt==0 ? "no such column" : "ambiguous column name";
101942 if( zDb ){
101943 sqlite3ErrorMsg(pParse, "%s: %s.%s.%s", zErr, zDb, zTab, zCol);
101944 }else if( zTab ){
101945 sqlite3ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol);
@@ -101324,10 +101948,20 @@
101948 }
101949 sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
101950 pParse->checkSchema = 1;
101951 pTopNC->nNcErr++;
101952 }
101953 assert( pFJMatch==0 );
101954
101955 /* Remove all substructure from pExpr */
101956 if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){
101957 sqlite3ExprDelete(db, pExpr->pLeft);
101958 pExpr->pLeft = 0;
101959 sqlite3ExprDelete(db, pExpr->pRight);
101960 pExpr->pRight = 0;
101961 ExprSetProperty(pExpr, EP_Leaf);
101962 }
101963
101964 /* If a column from a table in pSrcList is referenced, then record
101965 ** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes
101966 ** bit 0 to be set. Column 1 sets bit 1. And so forth. Bit 63 is
101967 ** set if the 63rd or any subsequent column is used.
@@ -101343,20 +101977,11 @@
101977 */
101978 if( pExpr->iColumn>=0 && pMatch!=0 ){
101979 pMatch->colUsed |= sqlite3ExprColUsed(pExpr);
101980 }
101981
 
 
 
 
 
 
 
 
101982 pExpr->op = eNewExprOp;
 
101983 lookupname_end:
101984 if( cnt==1 ){
101985 assert( pNC!=0 );
101986 #ifndef SQLITE_OMIT_AUTHORIZATION
101987 if( pParse->db->xAuth
@@ -104008,10 +104633,22 @@
104633 }
104634 SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
104635 if( p ) sqlite3ExprDeleteNN(db, p);
104636 }
104637
104638 /*
104639 ** Clear both elements of an OnOrUsing object
104640 */
104641 SQLITE_PRIVATE void sqlite3ClearOnOrUsing(sqlite3 *db, OnOrUsing *p){
104642 if( p==0 ){
104643 /* Nothing to clear */
104644 }else if( p->pOn ){
104645 sqlite3ExprDeleteNN(db, p->pOn);
104646 }else if( p->pUsing ){
104647 sqlite3IdListDelete(db, p->pUsing);
104648 }
104649 }
104650
104651 /*
104652 ** Arrange to cause pExpr to be deleted when the pParse is deleted.
104653 ** This is similar to sqlite3ExprDelete() except that the delete is
104654 ** deferred untilthe pParse is deleted.
@@ -104378,10 +105015,11 @@
105015 pItem->zEName = sqlite3DbStrDup(db, pOldItem->zEName);
105016 pItem->sortFlags = pOldItem->sortFlags;
105017 pItem->eEName = pOldItem->eEName;
105018 pItem->done = 0;
105019 pItem->bNulls = pOldItem->bNulls;
105020 pItem->bUsed = pOldItem->bUsed;
105021 pItem->bSorterRef = pOldItem->bSorterRef;
105022 pItem->u = pOldItem->u;
105023 }
105024 return pNew;
105025 }
@@ -104430,37 +105068,35 @@
105068 pTab = pNewItem->pTab = pOldItem->pTab;
105069 if( pTab ){
105070 pTab->nTabRef++;
105071 }
105072 pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags);
105073 if( pOldItem->fg.isUsing ){
105074 assert( pNewItem->fg.isUsing );
105075 pNewItem->u3.pUsing = sqlite3IdListDup(db, pOldItem->u3.pUsing);
105076 }else{
105077 pNewItem->u3.pOn = sqlite3ExprDup(db, pOldItem->u3.pOn, flags);
105078 }
105079 pNewItem->colUsed = pOldItem->colUsed;
105080 }
105081 return pNew;
105082 }
105083 SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, const IdList *p){
105084 IdList *pNew;
105085 int i;
105086 assert( db!=0 );
105087 if( p==0 ) return 0;
105088 assert( p->eU4!=EU4_EXPR );
105089 pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew)+(p->nId-1)*sizeof(p->a[0]) );
105090 if( pNew==0 ) return 0;
105091 pNew->nId = p->nId;
105092 pNew->eU4 = p->eU4;
 
 
 
 
 
 
 
105093 for(i=0; i<p->nId; i++){
105094 struct IdList_item *pNewItem = &pNew->a[i];
105095 const struct IdList_item *pOldItem = &p->a[i];
105096 pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
105097 pNewItem->u4 = pOldItem->u4;
105098 }
105099 return pNew;
105100 }
105101 SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *pDup, int flags){
105102 Select *pRet = 0;
@@ -104922,11 +105558,11 @@
105558 ** malformed schema error.
105559 */
105560 static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
105561
105562 /* If pWalker->eCode is 2 then any term of the expression that comes from
105563 ** the ON or USING clauses of an outer join disqualifies the expression
105564 ** from being considered constant. */
105565 if( pWalker->eCode==2 && ExprHasProperty(pExpr, EP_FromJoin) ){
105566 pWalker->eCode = 0;
105567 return WRC_Abort;
105568 }
@@ -105924,13 +106560,13 @@
106560 sqlite3VdbeJumpHere(v, addrOnce);
106561 /* Subroutine return */
106562 assert( ExprUseYSub(pExpr) );
106563 assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn
106564 || pParse->nErr );
106565 sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn,
106566 pExpr->y.sub.iAddr, 1);
106567 VdbeCoverage(v);
106568 sqlite3ClearTempRegCache(pParse);
106569 }
106570 }
106571 #endif /* SQLITE_OMIT_SUBQUERY */
106572
@@ -106055,13 +106691,13 @@
106691
106692 /* Subroutine return */
106693 assert( ExprUseYSub(pExpr) );
106694 assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn
106695 || pParse->nErr );
106696 sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn,
106697 pExpr->y.sub.iAddr, 1);
106698 VdbeCoverage(v);
106699 sqlite3ClearTempRegCache(pParse);
106700 return rReg;
106701 }
106702 #endif /* SQLITE_OMIT_SUBQUERY */
106703
@@ -106491,10 +107127,11 @@
107127 sqlite3VdbeAddOp3(v, OP_Column, iTabCur, iCol, regOut);
107128 return;
107129 }
107130 if( iCol<0 || iCol==pTab->iPKey ){
107131 sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut);
107132 VdbeComment((v, "%s.rowid", pTab->zName));
107133 }else{
107134 int op;
107135 int x;
107136 if( IsVirtual(pTab) ){
107137 op = OP_VColumn;
@@ -107243,20 +107880,22 @@
107880 }
107881 break;
107882 }
107883 case TK_SELECT_COLUMN: {
107884 int n;
107885 Expr *pLeft = pExpr->pLeft;
107886 if( pLeft->iTable==0 || pParse->withinRJSubrtn > pLeft->op2 ){
107887 pLeft->iTable = sqlite3CodeSubselect(pParse, pLeft);
107888 pLeft->op2 = pParse->withinRJSubrtn;
107889 }
107890 assert( pLeft->op==TK_SELECT || pLeft->op==TK_ERROR );
107891 n = sqlite3ExprVectorSize(pLeft);
107892 if( pExpr->iTable!=n ){
107893 sqlite3ErrorMsg(pParse, "%d columns assigned %d values",
107894 pExpr->iTable, n);
107895 }
107896 return pLeft->iTable + pExpr->iColumn;
107897 }
107898 case TK_IN: {
107899 int destIfFalse = sqlite3VdbeMakeLabel(pParse);
107900 int destIfNull = sqlite3VdbeMakeLabel(pParse);
107901 sqlite3VdbeAddOp2(v, OP_Null, 0, target);
@@ -108560,11 +109199,11 @@
109199 **
109200 ** False positives are not allowed, however. A false positive may result
109201 ** in an incorrect answer.
109202 **
109203 ** Terms of p that are marked with EP_FromJoin (and hence that come from
109204 ** the ON or USING clauses of OUTER JOINS) are excluded from the analysis.
109205 **
109206 ** This routine is used to check if a LEFT JOIN can be converted into
109207 ** an ordinary JOIN. The p argument is the WHERE clause. If the WHERE
109208 ** clause requires that some column of the right table of the LEFT JOIN
109209 ** be non-NULL, then the LEFT JOIN can be safely converted into an
@@ -109974,15 +110613,14 @@
110613 */
110614 static void unmapColumnIdlistNames(
110615 Parse *pParse,
110616 const IdList *pIdList
110617 ){
110618 int ii;
110619 assert( pIdList!=0 );
110620 for(ii=0; ii<pIdList->nId; ii++){
110621 sqlite3RenameTokenRemap(pParse, 0, (const void*)pIdList->a[ii].zName);
 
110622 }
110623 }
110624
110625 /*
110626 ** Walker callback used by sqlite3RenameExprUnmap().
@@ -110006,12 +110644,15 @@
110644 }
110645 if( ALWAYS(p->pSrc) ){ /* Every Select as a SrcList, even if it is empty */
110646 SrcList *pSrc = p->pSrc;
110647 for(i=0; i<pSrc->nSrc; i++){
110648 sqlite3RenameTokenRemap(pParse, 0, (void*)pSrc->a[i].zName);
110649 if( pSrc->a[i].fg.isUsing==0 ){
110650 sqlite3WalkExpr(pWalker, pSrc->a[i].u3.pOn);
110651 }else{
110652 unmapColumnIdlistNames(pParse, pSrc->a[i].u3.pUsing);
110653 }
110654 }
110655 }
110656
110657 renameWalkWith(pWalker, p);
110658 return WRC_Continue;
@@ -113792,11 +114433,15 @@
114433 }
114434 pItem->pSchema = pFix->pSchema;
114435 pItem->fg.fromDDL = 1;
114436 }
114437 #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
114438 if( pList->a[i].fg.isUsing==0
114439 && sqlite3WalkExpr(&pFix->w, pList->a[i].u3.pOn)
114440 ){
114441 return WRC_Abort;
114442 }
114443 #endif
114444 }
114445 if( pSelect->pWith ){
114446 for(i=0; i<pSelect->pWith->nCte; i++){
114447 if( sqlite3WalkSelect(p, pSelect->pWith->a[i].pSelect) ){
@@ -118856,22 +119501,21 @@
119501 sqlite3 *db = pParse->db;
119502 int i;
119503 if( pList==0 ){
119504 pList = sqlite3DbMallocZero(db, sizeof(IdList) );
119505 if( pList==0 ) return 0;
119506 }else{
119507 IdList *pNew;
119508 pNew = sqlite3DbRealloc(db, pList,
119509 sizeof(IdList) + pList->nId*sizeof(pList->a));
119510 if( pNew==0 ){
119511 sqlite3IdListDelete(db, pList);
119512 return 0;
119513 }
119514 pList = pNew;
119515 }
119516 i = pList->nId++;
 
119517 pList->a[i].zName = sqlite3NameFromToken(db, pToken);
119518 if( IN_RENAME_OBJECT && pList->a[i].zName ){
119519 sqlite3RenameTokenMap(pParse, (void*)pList->a[i].zName, pToken);
119520 }
119521 return pList;
@@ -118881,24 +119525,24 @@
119525 ** Delete an IdList.
119526 */
119527 SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3 *db, IdList *pList){
119528 int i;
119529 if( pList==0 ) return;
119530 assert( pList->eU4!=EU4_EXPR ); /* EU4_EXPR mode is not currently used */
119531 for(i=0; i<pList->nId; i++){
119532 sqlite3DbFree(db, pList->a[i].zName);
119533 }
 
119534 sqlite3DbFreeNN(db, pList);
119535 }
119536
119537 /*
119538 ** Return the index in pList of the identifier named zId. Return -1
119539 ** if not found.
119540 */
119541 SQLITE_PRIVATE int sqlite3IdListIndex(IdList *pList, const char *zName){
119542 int i;
119543 assert( pList!=0 );
119544 for(i=0; i<pList->nId; i++){
119545 if( sqlite3StrICmp(pList->a[i].zName, zName)==0 ) return i;
119546 }
119547 return -1;
119548 }
@@ -119097,12 +119741,15 @@
119741 if( pItem->zAlias ) sqlite3DbFreeNN(db, pItem->zAlias);
119742 if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy);
119743 if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg);
119744 sqlite3DeleteTable(db, pItem->pTab);
119745 if( pItem->pSelect ) sqlite3SelectDelete(db, pItem->pSelect);
119746 if( pItem->fg.isUsing ){
119747 sqlite3IdListDelete(db, pItem->u3.pUsing);
119748 }else if( pItem->u3.pOn ){
119749 sqlite3ExprDelete(db, pItem->u3.pOn);
119750 }
119751 }
119752 sqlite3DbFreeNN(db, pList);
119753 }
119754
119755 /*
@@ -119126,18 +119773,17 @@
119773 SrcList *p, /* The left part of the FROM clause already seen */
119774 Token *pTable, /* Name of the table to add to the FROM clause */
119775 Token *pDatabase, /* Name of the database containing pTable */
119776 Token *pAlias, /* The right-hand side of the AS subexpression */
119777 Select *pSubquery, /* A subquery used in place of a table name */
119778 OnOrUsing *pOnUsing /* Either the ON clause or the USING clause */
 
119779 ){
119780 SrcItem *pItem;
119781 sqlite3 *db = pParse->db;
119782 if( !p && pOnUsing!=0 && (pOnUsing->pOn || pOnUsing->pUsing) ){
119783 sqlite3ErrorMsg(pParse, "a JOIN clause is required before %s",
119784 (pOnUsing->pOn ? "ON" : "USING")
119785 );
119786 goto append_from_error;
119787 }
119788 p = sqlite3SrcListAppend(pParse, p, pTable, pDatabase);
119789 if( p==0 ){
@@ -119153,19 +119799,31 @@
119799 }
119800 assert( pAlias!=0 );
119801 if( pAlias->n ){
119802 pItem->zAlias = sqlite3NameFromToken(db, pAlias);
119803 }
119804 if( pSubquery ){
119805 pItem->pSelect = pSubquery;
119806 if( pSubquery->selFlags & SF_NestedFrom ){
119807 pItem->fg.isNestedFrom = 1;
119808 }
119809 }
119810 assert( pOnUsing==0 || pOnUsing->pOn==0 || pOnUsing->pUsing==0 );
119811 assert( pItem->fg.isUsing==0 );
119812 if( pOnUsing==0 ){
119813 pItem->u3.pOn = 0;
119814 }else if( pOnUsing->pUsing ){
119815 pItem->fg.isUsing = 1;
119816 pItem->u3.pUsing = pOnUsing->pUsing;
119817 }else{
119818 pItem->u3.pOn = pOnUsing->pOn;
119819 }
119820 return p;
119821
119822 append_from_error:
119823 assert( p==0 );
119824 sqlite3ClearOnOrUsing(db, pOnUsing);
 
119825 sqlite3SelectDelete(db, pSubquery);
119826 return 0;
119827 }
119828
119829 /*
@@ -119206,10 +119864,11 @@
119864 sqlite3SrcListDelete(pParse->db, p2);
119865 }else{
119866 p1 = pNew;
119867 memcpy(&p1->a[1], p2->a, p2->nSrc*sizeof(SrcItem));
119868 sqlite3DbFree(pParse->db, p2);
119869 p1->a[0].fg.jointype |= (JT_LTORJ & p1->a[1].fg.jointype);
119870 }
119871 }
119872 return p1;
119873 }
119874
@@ -119242,18 +119901,38 @@
119901 ** A natural cross join B
119902 **
119903 ** The operator is "natural cross join". The A and B operands are stored
119904 ** in p->a[0] and p->a[1], respectively. The parser initially stores the
119905 ** operator with A. This routine shifts that operator over to B.
119906 **
119907 ** Additional changes:
119908 **
119909 ** * All tables to the left of the right-most RIGHT JOIN are tagged with
119910 ** JT_LTORJ (mnemonic: Left Table Of Right Join) so that the
119911 ** code generator can easily tell that the table is part of
119912 ** the left operand of at least one RIGHT JOIN.
119913 */
119914 SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(Parse *pParse, SrcList *p){
119915 (void)pParse;
119916 if( p && p->nSrc>1 ){
119917 int i = p->nSrc-1;
119918 u8 allFlags = 0;
119919 do{
119920 allFlags |= p->a[i].fg.jointype = p->a[i-1].fg.jointype;
119921 }while( (--i)>0 );
119922 p->a[0].fg.jointype = 0;
119923
119924 /* All terms to the left of a RIGHT JOIN should be tagged with the
119925 ** JT_LTORJ flags */
119926 if( allFlags & JT_RIGHT ){
119927 for(i=p->nSrc-1; ALWAYS(i>0) && (p->a[i].fg.jointype&JT_RIGHT)==0; i--){}
119928 i--;
119929 assert( i>=0 );
119930 do{
119931 p->a[i].fg.jointype |= JT_LTORJ;
119932 }while( (--i)>=0 );
119933 }
119934 }
119935 }
119936
119937 /*
119938 ** Generate VDBE code for a BEGIN statement.
@@ -120498,12 +121177,12 @@
121177 pFrom = sqlite3SrcListAppend(pParse, 0, 0, 0);
121178 if( pFrom ){
121179 assert( pFrom->nSrc==1 );
121180 pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName);
121181 pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName);
121182 assert( pFrom->a[0].fg.isUsing==0 );
121183 assert( pFrom->a[0].u3.pOn==0 );
121184 }
121185 pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, pOrderBy,
121186 SF_IncludeHidden, pLimit);
121187 sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
121188 sqlite3Select(pParse, pSel, &dest);
@@ -120670,11 +121349,10 @@
121349 goto delete_from_cleanup;
121350 }
121351 assert( db->mallocFailed==0 );
121352 assert( pTabList->nSrc==1 );
121353
 
121354 /* Locate the table which we want to delete. This table has to be
121355 ** put in an SrcList structure because some of the subroutines we
121356 ** will be calling are designed to work with multiple tables and expect
121357 ** an SrcList* parameter instead of just a Table* parameter.
121358 */
@@ -120694,10 +121372,18 @@
121372 bComplex = pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0);
121373 #ifdef SQLITE_OMIT_VIEW
121374 # undef isView
121375 # define isView 0
121376 #endif
121377
121378 #if TREETRACE_ENABLED
121379 if( sqlite3TreeTrace & 0x10000 ){
121380 sqlite3TreeViewLine(0, "In sqlite3Delete() at %s:%d", __FILE__, __LINE__);
121381 sqlite3TreeViewDelete(pParse->pWith, pTabList, pWhere,
121382 pOrderBy, pLimit, pTrigger);
121383 }
121384 #endif
121385
121386 #ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
121387 if( !isView ){
121388 pWhere = sqlite3LimitWhere(
121389 pParse, pTabList, pWhere, pOrderBy, pLimit, "DELETE"
@@ -124132,11 +124818,10 @@
124818 sqlite3VdbeJumpHere(v, iMustBeInt);
124819 sqlite3ReleaseTempReg(pParse, regTemp);
124820 }else{
124821 int nCol = pFKey->nCol;
124822 int regTemp = sqlite3GetTempRange(pParse, nCol);
 
124823
124824 sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb);
124825 sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
124826 for(i=0; i<nCol; i++){
124827 sqlite3VdbeAddOp2(v, OP_Copy,
@@ -124172,15 +124857,14 @@
124857 sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
124858 }
124859 sqlite3VdbeGoto(v, iOk);
124860 }
124861
124862 sqlite3VdbeAddOp4(v, OP_Affinity, regTemp, nCol, 0,
124863 sqlite3IndexAffinityStr(pParse->db,pIdx), nCol);
124864 sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regTemp, nCol);
124865 VdbeCoverage(v);
 
124866 sqlite3ReleaseTempRange(pParse, regTemp, nCol);
124867 }
124868 }
124869
124870 if( !pFKey->isDeferred && !(pParse->db->flags & SQLITE_DeferFKs)
@@ -124278,18 +124962,14 @@
124962 ** For each child row found, one of the following actions is taken:
124963 **
124964 ** Operation | FK type | Action taken
124965 ** --------------------------------------------------------------------------
124966 ** DELETE immediate Increment the "immediate constraint counter".
 
 
124967 **
124968 ** INSERT immediate Decrement the "immediate constraint counter".
124969 **
124970 ** DELETE deferred Increment the "deferred constraint counter".
 
 
124971 **
124972 ** INSERT deferred Decrement the "deferred constraint counter".
124973 **
124974 ** These operations are identified in the comment at the top of this file
124975 ** (fkey.c) as "I.2" and "D.2".
@@ -124933,13 +125613,13 @@
125613 ** passed a pointer to the list of columns being modified. If it is a
125614 ** DELETE, pChanges is passed a NULL pointer.
125615 **
125616 ** It returns a pointer to a Trigger structure containing a trigger
125617 ** equivalent to the ON UPDATE or ON DELETE action specified by pFKey.
125618 ** If the action is "NO ACTION" then a NULL pointer is returned (these actions
125619 ** require no special handling by the triggers sub-system, code for them is
125620 ** created by fkScanChildren()).
125621 **
125622 ** For example, if pFKey is the foreign key and pTab is table "p" in
125623 ** the following schema:
125624 **
125625 ** CREATE TABLE p(pk PRIMARY KEY);
@@ -125064,22 +125744,27 @@
125744
125745 zFrom = pFKey->pFrom->zName;
125746 nFrom = sqlite3Strlen30(zFrom);
125747
125748 if( action==OE_Restrict ){
125749 int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
125750 Token tFrom;
125751 Token tDb;
125752 Expr *pRaise;
125753
125754 tFrom.z = zFrom;
125755 tFrom.n = nFrom;
125756 tDb.z = db->aDb[iDb].zDbSName;
125757 tDb.n = sqlite3Strlen30(tDb.z);
125758
125759 pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed");
125760 if( pRaise ){
125761 pRaise->affExpr = OE_Abort;
125762 }
125763 pSelect = sqlite3SelectNew(pParse,
125764 sqlite3ExprListAppend(pParse, 0, pRaise),
125765 sqlite3SrcListAppend(pParse, 0, &tDb, &tFrom),
125766 pWhere,
125767 0, 0, 0, 0, 0
125768 );
125769 pWhere = 0;
125770 }
@@ -125984,10 +126669,18 @@
126669 #ifdef SQLITE_OMIT_VIEW
126670 # undef isView
126671 # define isView 0
126672 #endif
126673 assert( (pTrigger && tmask) || (pTrigger==0 && tmask==0) );
126674
126675 #if TREETRACE_ENABLED
126676 if( sqlite3TreeTrace & 0x10000 ){
126677 sqlite3TreeViewLine(0, "In sqlite3Insert() at %s:%d", __FILE__, __LINE__);
126678 sqlite3TreeViewInsert(pParse->pWith, pTabList, pColumn, pSelect, pList,
126679 onError, pUpsert, pTrigger);
126680 }
126681 #endif
126682
126683 /* If pTab is really a view, make sure it has been initialized.
126684 ** ViewGetColumnNames() is a no-op if pTab is not a view.
126685 */
126686 if( sqlite3ViewGetColumnNames(pParse, pTab) ){
@@ -126063,17 +126756,19 @@
126756 ** columns into storage order. False negatives are harmless,
126757 ** but false positives will cause database corruption.
126758 */
126759 bIdListInOrder = (pTab->tabFlags & (TF_OOOHidden|TF_HasStored))==0;
126760 if( pColumn ){
126761 assert( pColumn->eU4!=EU4_EXPR );
126762 pColumn->eU4 = EU4_IDX;
126763 for(i=0; i<pColumn->nId; i++){
126764 pColumn->a[i].u4.idx = -1;
126765 }
126766 for(i=0; i<pColumn->nId; i++){
126767 for(j=0; j<pTab->nCol; j++){
126768 if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zCnName)==0 ){
126769 pColumn->a[i].u4.idx = j;
126770 if( i!=j ) bIdListInOrder = 0;
126771 if( j==pTab->iPKey ){
126772 ipkColumn = i; assert( !withoutRowid );
126773 }
126774 #ifndef SQLITE_OMIT_GENERATED_COLUMNS
@@ -126371,11 +127066,12 @@
127066 iRegStore);
127067 continue;
127068 }
127069 }
127070 if( pColumn ){
127071 assert( pColumn->eU4==EU4_IDX );
127072 for(j=0; j<pColumn->nId && pColumn->a[j].u4.idx!=i; j++){}
127073 if( j>=pColumn->nId ){
127074 /* A column not named in the insert column list gets its
127075 ** default value */
127076 sqlite3ExprCodeFactorable(pParse,
127077 sqlite3ColumnExpr(pTab, &pTab->aCol[i]),
@@ -132244,19 +132940,17 @@
132940 int i; /* Loop counter: Foreign key number for pTab */
132941 int j; /* Loop counter: Field of the foreign key */
132942 HashElem *k; /* Loop counter: Next table in schema */
132943 int x; /* result variable */
132944 int regResult; /* 3 registers to hold a result row */
 
132945 int regRow; /* Registers to hold a row from pTab */
132946 int addrTop; /* Top of a loop checking foreign keys */
132947 int addrOk; /* Jump here if the key is OK */
132948 int *aiCols; /* child to parent column mapping */
132949
132950 regResult = pParse->nMem+1;
132951 pParse->nMem += 4;
 
132952 regRow = ++pParse->nMem;
132953 k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash);
132954 while( k ){
132955 if( zRight ){
132956 pTab = sqlite3LocateTable(pParse, 0, zRight, zDb);
@@ -132319,13 +133013,13 @@
133013 }
133014
133015 /* Generate code to query the parent index for a matching parent
133016 ** key. If a match is found, jump to addrOk. */
133017 if( pIdx ){
133018 sqlite3VdbeAddOp4(v, OP_Affinity, regRow, pFK->nCol, 0,
133019 sqlite3IndexAffinityStr(db,pIdx), pFK->nCol);
133020 sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regRow, pFK->nCol);
133021 VdbeCoverage(v);
133022 }else if( pParent ){
133023 int jmp = sqlite3VdbeCurrentAddr(v)+2;
133024 sqlite3VdbeAddOp3(v, OP_SeekRowid, i, jmp, regRow); VdbeCoverage(v);
133025 sqlite3VdbeGoto(v, addrOk);
@@ -134732,10 +135426,56 @@
135426 **
135427 ** A full outer join is the combination of JT_LEFT and JT_RIGHT.
135428 **
135429 ** If an illegal or unsupported join type is seen, then still return
135430 ** a join type, but put an error in the pParse structure.
135431 **
135432 ** These are the valid join types:
135433 **
135434 **
135435 ** pA pB pC Return Value
135436 ** ------- ----- ----- ------------
135437 ** CROSS - - JT_CROSS
135438 ** INNER - - JT_INNER
135439 ** LEFT - - JT_LEFT|JT_OUTER
135440 ** LEFT OUTER - JT_LEFT|JT_OUTER
135441 ** RIGHT - - JT_RIGHT|JT_OUTER
135442 ** RIGHT OUTER - JT_RIGHT|JT_OUTER
135443 ** FULL - - JT_LEFT|JT_RIGHT|JT_OUTER
135444 ** FULL OUTER - JT_LEFT|JT_RIGHT|JT_OUTER
135445 ** NATURAL INNER - JT_NATURAL|JT_INNER
135446 ** NATURAL LEFT - JT_NATURAL|JT_LEFT|JT_OUTER
135447 ** NATURAL LEFT OUTER JT_NATURAL|JT_LEFT|JT_OUTER
135448 ** NATURAL RIGHT - JT_NATURAL|JT_RIGHT|JT_OUTER
135449 ** NATURAL RIGHT OUTER JT_NATURAL|JT_RIGHT|JT_OUTER
135450 ** NATURAL FULL - JT_NATURAL|JT_LEFT|JT_RIGHT
135451 ** NATURAL FULL OUTER JT_NATRUAL|JT_LEFT|JT_RIGHT
135452 **
135453 ** To preserve historical compatibly, SQLite also accepts a variety
135454 ** of other non-standard and in many cases non-sensical join types.
135455 ** This routine makes as much sense at it can from the nonsense join
135456 ** type and returns a result. Examples of accepted nonsense join types
135457 ** include but are not limited to:
135458 **
135459 ** INNER CROSS JOIN -> same as JOIN
135460 ** NATURAL CROSS JOIN -> same as NATURAL JOIN
135461 ** OUTER LEFT JOIN -> same as LEFT JOIN
135462 ** LEFT NATURAL JOIN -> same as NATURAL LEFT JOIN
135463 ** LEFT RIGHT JOIN -> same as FULL JOIN
135464 ** RIGHT OUTER FULL JOIN -> same as FULL JOIN
135465 ** CROSS CROSS CROSS JOIN -> same as JOIN
135466 **
135467 ** The only restrictions on the join type name are:
135468 **
135469 ** * "INNER" cannot appear together with "OUTER", "LEFT", "RIGHT",
135470 ** or "FULL".
135471 **
135472 ** * "CROSS" cannot appear together with "OUTER", "LEFT", "RIGHT,
135473 ** or "FULL".
135474 **
135475 ** * If "OUTER" is present then there must also be one of
135476 ** "LEFT", "RIGHT", or "FULL"
135477 */
135478 SQLITE_PRIVATE int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){
135479 int jointype = 0;
135480 Token *apAll[3];
135481 Token *p;
@@ -134744,17 +135484,17 @@
135484 static const struct {
135485 u8 i; /* Beginning of keyword text in zKeyText[] */
135486 u8 nChar; /* Length of the keyword in characters */
135487 u8 code; /* Join type mask */
135488 } aKeyword[] = {
135489 /* (0) natural */ { 0, 7, JT_NATURAL },
135490 /* (1) left */ { 6, 4, JT_LEFT|JT_OUTER },
135491 /* (2) outer */ { 10, 5, JT_OUTER },
135492 /* (3) right */ { 14, 5, JT_RIGHT|JT_OUTER },
135493 /* (4) full */ { 19, 4, JT_LEFT|JT_RIGHT|JT_OUTER },
135494 /* (5) inner */ { 23, 5, JT_INNER },
135495 /* (6) cross */ { 28, 5, JT_INNER|JT_CROSS },
135496 };
135497 int i, j;
135498 apAll[0] = pA;
135499 apAll[1] = pB;
135500 apAll[2] = pC;
@@ -134773,22 +135513,19 @@
135513 break;
135514 }
135515 }
135516 if(
135517 (jointype & (JT_INNER|JT_OUTER))==(JT_INNER|JT_OUTER) ||
135518 (jointype & JT_ERROR)!=0 ||
135519 (jointype & (JT_OUTER|JT_LEFT|JT_RIGHT))==JT_OUTER
135520 ){
135521 const char *zSp1 = " ";
135522 const char *zSp2 = " ";
135523 if( pB==0 ){ zSp1++; }
135524 if( pC==0 ){ zSp2++; }
135525 sqlite3ErrorMsg(pParse, "unknown join type: "
135526 "%T%s%T%s%T", pA, zSp1, pB, zSp2, pC);
 
 
 
 
135527 jointype = JT_INNER;
135528 }
135529 return jointype;
135530 }
135531
@@ -134805,106 +135542,81 @@
135542 }
135543 return -1;
135544 }
135545
135546 /*
135547 ** Mark a subquery result column as having been used.
135548 */
135549 SQLITE_PRIVATE void sqlite3SrcItemColumnUsed(SrcItem *pItem, int iCol){
135550 assert( pItem!=0 );
135551 assert( pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) );
135552 if( pItem->fg.isNestedFrom ){
135553 ExprList *pResults;
135554 assert( pItem->pSelect!=0 );
135555 pResults = pItem->pSelect->pEList;
135556 assert( pResults!=0 );
135557 assert( iCol>=0 && iCol<pResults->nExpr );
135558 pResults->a[iCol].bUsed = 1;
135559 }
135560 }
135561
135562 /*
135563 ** Search the tables iStart..iEnd (inclusive) in pSrc, looking for a
135564 ** table that has a column named zCol. The search is left-to-right.
135565 ** The first match found is returned.
135566 **
135567 ** When found, set *piTab and *piCol to the table index and column index
135568 ** of the matching column and return TRUE.
135569 **
135570 ** If not found, return FALSE.
135571 */
135572 static int tableAndColumnIndex(
135573 SrcList *pSrc, /* Array of tables to search */
135574 int iStart, /* First member of pSrc->a[] to check */
135575 int iEnd, /* Last member of pSrc->a[] to check */
135576 const char *zCol, /* Name of the column we are looking for */
135577 int *piTab, /* Write index of pSrc->a[] here */
135578 int *piCol, /* Write index of pSrc->a[*piTab].pTab->aCol[] here */
135579 int bIgnoreHidden /* Ignore hidden columns */
135580 ){
135581 int i; /* For looping over tables in pSrc */
135582 int iCol; /* Index of column matching zCol */
135583
135584 assert( iEnd<pSrc->nSrc );
135585 assert( iStart>=0 );
135586 assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */
135587
135588 for(i=iStart; i<=iEnd; i++){
135589 iCol = sqlite3ColumnIndex(pSrc->a[i].pTab, zCol);
135590 if( iCol>=0
135591 && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pTab->aCol[iCol])==0)
135592 ){
135593 if( piTab ){
135594 sqlite3SrcItemColumnUsed(&pSrc->a[i], iCol);
135595 *piTab = i;
135596 *piCol = iCol;
135597 }
135598 return 1;
135599 }
135600 }
135601 return 0;
135602 }
135603
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135604 /*
135605 ** Set the EP_FromJoin property on all terms of the given expression.
135606 ** And set the Expr.w.iJoin to iTable for every term in the
135607 ** expression.
135608 **
135609 ** The EP_FromJoin property is used on terms of an expression to tell
135610 ** the OUTER JOIN processing logic that this term is part of the
135611 ** join restriction specified in the ON or USING clause and not a part
135612 ** of the more general WHERE clause. These terms are moved over to the
135613 ** WHERE clause during join processing but we need to remember that they
135614 ** originated in the ON or USING clause.
135615 **
135616 ** The Expr.w.iJoin tells the WHERE clause processing that the
135617 ** expression depends on table w.iJoin even if that table is not
135618 ** explicitly mentioned in the expression. That information is needed
135619 ** for cases like this:
135620 **
135621 ** SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.b AND t1.x=5
135622 **
@@ -134913,41 +135625,43 @@
135625 ** NULL t2 row will be inserted whenever t1.x!=5. If we do not
135626 ** defer the handling of t1.x=5, it will be processed immediately
135627 ** after the t1 loop and rows with t1.x!=5 will never appear in
135628 ** the output, which is incorrect.
135629 */
135630 SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr *p, int iTable, u32 joinFlag){
135631 assert( joinFlag==EP_FromJoin || joinFlag==EP_InnerJoin );
135632 while( p ){
135633 ExprSetProperty(p, joinFlag);
135634 assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
135635 ExprSetVVAProperty(p, EP_NoReduce);
135636 p->w.iJoin = iTable;
135637 if( p->op==TK_FUNCTION ){
135638 assert( ExprUseXList(p) );
135639 if( p->x.pList ){
135640 int i;
135641 for(i=0; i<p->x.pList->nExpr; i++){
135642 sqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable, joinFlag);
135643 }
135644 }
135645 }
135646 sqlite3SetJoinExpr(p->pLeft, iTable, joinFlag);
135647 p = p->pRight;
135648 }
135649 }
135650
135651 /* Undo the work of sqlite3SetJoinExpr(). In the expression p, convert every
135652 ** term that is marked with EP_FromJoin and w.iJoin==iTable into
135653 ** an ordinary term that omits the EP_FromJoin mark.
135654 **
135655 ** This happens when a LEFT JOIN is simplified into an ordinary JOIN.
135656 */
135657 static void unsetJoinExpr(Expr *p, int iTable){
135658 while( p ){
135659 if( ExprHasProperty(p, EP_FromJoin)
135660 && (iTable<0 || p->w.iJoin==iTable) ){
135661 ExprClearProperty(p, EP_FromJoin);
135662 ExprSetProperty(p, EP_InnerJoin);
135663 }
135664 if( p->op==TK_COLUMN && p->iTable==iTable ){
135665 ExprClearProperty(p, EP_CanBeNull);
135666 }
135667 if( p->op==TK_FUNCTION ){
@@ -134964,23 +135678,30 @@
135678 }
135679 }
135680
135681 /*
135682 ** This routine processes the join information for a SELECT statement.
135683 **
135684 ** * A NATURAL join is converted into a USING join. After that, we
135685 ** do not need to be concerned with NATURAL joins and we only have
135686 ** think about USING joins.
135687 **
135688 ** * ON and USING clauses result in extra terms being added to the
135689 ** WHERE clause to enforce the specified constraints. The extra
135690 ** WHERE clause terms will be tagged with EP_FromJoin or
135691 ** EP_InnerJoin so that we know that they originated in ON/USING.
135692 **
135693 ** The terms of a FROM clause are contained in the Select.pSrc structure.
135694 ** The left most table is the first entry in Select.pSrc. The right-most
135695 ** table is the last entry. The join operator is held in the entry to
135696 ** the right. Thus entry 1 contains the join operator for the join between
135697 ** entries 0 and 1. Any ON or USING clauses associated with the join are
135698 ** also attached to the right entry.
135699 **
135700 ** This routine returns the number of errors encountered.
135701 */
135702 static int sqlite3ProcessJoin(Parse *pParse, Select *p){
135703 SrcList *pSrc; /* All tables in the FROM clause */
135704 int i, j; /* Loop counters */
135705 SrcItem *pLeft; /* Left table being joined */
135706 SrcItem *pRight; /* Right table being joined */
135707
@@ -134987,83 +135708,135 @@
135708 pSrc = p->pSrc;
135709 pLeft = &pSrc->a[0];
135710 pRight = &pLeft[1];
135711 for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){
135712 Table *pRightTab = pRight->pTab;
135713 u32 joinType;
135714
135715 if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue;
135716 joinType = (pRight->fg.jointype & JT_OUTER)!=0 ? EP_FromJoin : EP_InnerJoin;
135717
135718 /* If this is a NATURAL join, synthesize an approprate USING clause
135719 ** to specify which columns should be joined.
135720 */
135721 if( pRight->fg.jointype & JT_NATURAL ){
135722 IdList *pUsing = 0;
135723 if( pRight->fg.isUsing || pRight->u3.pOn ){
135724 sqlite3ErrorMsg(pParse, "a NATURAL join may not have "
135725 "an ON or USING clause", 0);
135726 return 1;
135727 }
135728 for(j=0; j<pRightTab->nCol; j++){
135729 char *zName; /* Name of column in the right table */
 
 
135730
135731 if( IsHiddenColumn(&pRightTab->aCol[j]) ) continue;
135732 zName = pRightTab->aCol[j].zCnName;
135733 if( tableAndColumnIndex(pSrc, 0, i, zName, 0, 0, 1) ){
135734 pUsing = sqlite3IdListAppend(pParse, pUsing, 0);
135735 if( pUsing ){
135736 assert( pUsing->nId>0 );
135737 assert( pUsing->a[pUsing->nId-1].zName==0 );
135738 pUsing->a[pUsing->nId-1].zName = sqlite3DbStrDup(pParse->db, zName);
135739 }
135740 }
135741 }
135742 if( pUsing ){
135743 pRight->fg.isUsing = 1;
135744 pRight->fg.isSynthUsing = 1;
135745 pRight->u3.pUsing = pUsing;
135746 }
135747 if( pParse->nErr ) return 1;
 
 
 
 
 
 
 
135748 }
135749
135750 /* Create extra terms on the WHERE clause for each column named
135751 ** in the USING clause. Example: If the two tables to be joined are
135752 ** A and B and the USING clause names X, Y, and Z, then add this
135753 ** to the WHERE clause: A.X=B.X AND A.Y=B.Y AND A.Z=B.Z
135754 ** Report an error if any column mentioned in the USING clause is
135755 ** not contained in both tables to be joined.
135756 */
135757 if( pRight->fg.isUsing ){
135758 IdList *pList = pRight->u3.pUsing;
135759 sqlite3 *db = pParse->db;
135760 assert( pList!=0 );
135761 for(j=0; j<pList->nId; j++){
135762 char *zName; /* Name of the term in the USING clause */
135763 int iLeft; /* Table on the left with matching column name */
135764 int iLeftCol; /* Column number of matching column on the left */
135765 int iRightCol; /* Column number of matching column on the right */
135766 Expr *pE1; /* Reference to the column on the LEFT of the join */
135767 Expr *pE2; /* Reference to the column on the RIGHT of the join */
135768 Expr *pEq; /* Equality constraint. pE1 == pE2 */
135769
135770 zName = pList->a[j].zName;
135771 iRightCol = sqlite3ColumnIndex(pRightTab, zName);
135772 if( iRightCol<0
135773 || tableAndColumnIndex(pSrc, 0, i, zName, &iLeft, &iLeftCol,
135774 pRight->fg.isSynthUsing)==0
135775 ){
135776 sqlite3ErrorMsg(pParse, "cannot join using column %s - column "
135777 "not present in both tables", zName);
135778 return 1;
135779 }
135780 pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol);
135781 sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol);
135782 if( (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){
135783 /* This branch runs if the query contains one or more RIGHT or FULL
135784 ** JOINs. If only a single table on the left side of this join
135785 ** contains the zName column, then this branch is a no-op.
135786 ** But if there are two or more tables on the left side
135787 ** of the join, construct a coalesce() function that gathers all
135788 ** such tables. Raise an error if more than one of those references
135789 ** to zName is not also within a prior USING clause.
135790 **
135791 ** We really ought to raise an error if there are two or more
135792 ** non-USING references to zName on the left of an INNER or LEFT
135793 ** JOIN. But older versions of SQLite do not do that, so we avoid
135794 ** adding a new error so as to not break legacy applications.
135795 */
135796 ExprList *pFuncArgs = 0; /* Arguments to the coalesce() */
135797 static const Token tkCoalesce = { "coalesce", 8 };
135798 while( tableAndColumnIndex(pSrc, iLeft+1, i, zName, &iLeft, &iLeftCol,
135799 pRight->fg.isSynthUsing)!=0 ){
135800 if( pSrc->a[iLeft].fg.isUsing==0
135801 || sqlite3IdListIndex(pSrc->a[iLeft].u3.pUsing, zName)<0
135802 ){
135803 sqlite3ErrorMsg(pParse, "ambiguous reference to %s in USING()",
135804 zName);
135805 break;
135806 }
135807 pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1);
135808 pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol);
135809 sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol);
135810 }
135811 if( pFuncArgs ){
135812 pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1);
135813 pE1 = sqlite3ExprFunction(pParse, pFuncArgs, &tkCoalesce, 0);
135814 }
135815 }
135816 pE2 = sqlite3CreateColumnExpr(db, pSrc, i+1, iRightCol);
135817 sqlite3SrcItemColumnUsed(pRight, iRightCol);
135818 pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2);
135819 assert( pE2!=0 || pEq==0 );
135820 if( pEq ){
135821 ExprSetProperty(pEq, joinType);
135822 assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) );
135823 ExprSetVVAProperty(pEq, EP_NoReduce);
135824 pEq->w.iJoin = pE2->iTable;
135825 }
135826 p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pEq);
135827 }
135828 }
135829
135830 /* Add the ON clause to the end of the WHERE clause, connected by
135831 ** an AND operator.
135832 */
135833 else if( pRight->u3.pOn ){
135834 sqlite3SetJoinExpr(pRight->u3.pOn, pRight->iCursor, joinType);
135835 p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->u3.pOn);
135836 pRight->u3.pOn = 0;
135837 }
135838 }
135839 return 0;
135840 }
135841
135842 /*
@@ -136628,16 +137401,17 @@
137401 assert( nCol==(i16)nCol );
137402 *pnCol = nCol;
137403 *paCol = aCol;
137404
137405 for(i=0, pCol=aCol; i<nCol && !db->mallocFailed; i++, pCol++){
137406 struct ExprList_item *pX = &pEList->a[i];
137407 /* Get an appropriate name for the column
137408 */
137409 if( (zName = pX->zEName)!=0 && pX->eEName==ENAME_NAME ){
137410 /* If the column contains an "AS <name>" phrase, use <name> as the name */
137411 }else{
137412 Expr *pColExpr = sqlite3ExprSkipCollateAndLikely(pX->pExpr);
137413 while( ALWAYS(pColExpr!=0) && pColExpr->op==TK_DOT ){
137414 pColExpr = pColExpr->pRight;
137415 assert( pColExpr!=0 );
137416 }
137417 if( pColExpr->op==TK_COLUMN
@@ -136651,11 +137425,11 @@
137425 }else if( pColExpr->op==TK_ID ){
137426 assert( !ExprHasProperty(pColExpr, EP_IntValue) );
137427 zName = pColExpr->u.zToken;
137428 }else{
137429 /* Use the original text of the column expression as its name */
137430 assert( zName==pX->zEName ); /* pointer comparison intended */
137431 }
137432 }
137433 if( zName && !sqlite3IsTrueOrFalse(zName) ){
137434 zName = sqlite3DbStrDup(db, zName);
137435 }else{
@@ -138144,16 +138918,44 @@
138918 /* An instance of the SubstContext object describes an substitution edit
138919 ** to be performed on a parse tree.
138920 **
138921 ** All references to columns in table iTable are to be replaced by corresponding
138922 ** expressions in pEList.
138923 **
138924 ** ## About "isOuterJoin":
138925 **
138926 ** The isOuterJoin column indicates that the replacement will occur into a
138927 ** position in the parent that NULL-able due to an OUTER JOIN. Either the
138928 ** target slot in the parent is the right operand of a LEFT JOIN, or one of
138929 ** the left operands of a RIGHT JOIN. In either case, we need to potentially
138930 ** bypass the substituted expression with OP_IfNullRow.
138931 **
138932 ** Suppose the original expression integer constant. Even though the table
138933 ** has the nullRow flag set, because the expression is an integer constant,
138934 ** it will not be NULLed out. So instead, we insert an OP_IfNullRow opcode
138935 ** that checks to see if the nullRow flag is set on the table. If the nullRow
138936 ** flag is set, then the value in the register is set to NULL and the original
138937 ** expression is bypassed. If the nullRow flag is not set, then the original
138938 ** expression runs to populate the register.
138939 **
138940 ** Example where this is needed:
138941 **
138942 ** CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT);
138943 ** CREATE TABLE t2(x INT UNIQUE);
138944 **
138945 ** SELECT a,b,m,x FROM t1 LEFT JOIN (SELECT 59 AS m,x FROM t2) ON b=x;
138946 **
138947 ** When the subquery on the right side of the LEFT JOIN is flattened, we
138948 ** have to add OP_IfNullRow in front of the OP_Integer that implements the
138949 ** "m" value of the subquery so that a NULL will be loaded instead of 59
138950 ** when processing a non-matched row of the left.
138951 */
138952 typedef struct SubstContext {
138953 Parse *pParse; /* The parsing context */
138954 int iTable; /* Replace references to this table */
138955 int iNewTable; /* New table number */
138956 int isOuterJoin; /* Add TK_IF_NULL_ROW opcodes on each replacement */
138957 ExprList *pEList; /* Replacement expressions */
138958 } SubstContext;
138959
138960 /* Forward Declarations */
138961 static void substExprList(SubstContext*, ExprList*);
@@ -138176,13 +138978,13 @@
138978 SubstContext *pSubst, /* Description of the substitution */
138979 Expr *pExpr /* Expr in which substitution occurs */
138980 ){
138981 if( pExpr==0 ) return 0;
138982 if( ExprHasProperty(pExpr, EP_FromJoin)
138983 && pExpr->w.iJoin==pSubst->iTable
138984 ){
138985 pExpr->w.iJoin = pSubst->iNewTable;
138986 }
138987 if( pExpr->op==TK_COLUMN
138988 && pExpr->iTable==pSubst->iTable
138989 && !ExprHasProperty(pExpr, EP_FixedCol)
138990 ){
@@ -138199,11 +139001,11 @@
139001 assert( pExpr->pRight==0 );
139002 if( sqlite3ExprIsVector(pCopy) ){
139003 sqlite3VectorErrorMsg(pSubst->pParse, pCopy);
139004 }else{
139005 sqlite3 *db = pSubst->pParse->db;
139006 if( pSubst->isOuterJoin && pCopy->op!=TK_COLUMN ){
139007 memset(&ifNullRow, 0, sizeof(ifNullRow));
139008 ifNullRow.op = TK_IF_NULL_ROW;
139009 ifNullRow.pLeft = pCopy;
139010 ifNullRow.iTable = pSubst->iNewTable;
139011 ifNullRow.flags = EP_IfNullRow;
@@ -138213,15 +139015,16 @@
139015 pNew = sqlite3ExprDup(db, pCopy, 0);
139016 if( db->mallocFailed ){
139017 sqlite3ExprDelete(db, pNew);
139018 return pExpr;
139019 }
139020 if( pSubst->isOuterJoin ){
139021 ExprSetProperty(pNew, EP_CanBeNull);
139022 }
139023 if( ExprHasProperty(pExpr,EP_FromJoin|EP_InnerJoin) ){
139024 sqlite3SetJoinExpr(pNew, pExpr->w.iJoin,
139025 pExpr->flags & (EP_FromJoin|EP_InnerJoin));
139026 }
139027 sqlite3ExprDelete(db, pExpr);
139028 pExpr = pNew;
139029
139030 /* Ensure that the expression now has an implicit collation sequence,
@@ -138382,11 +139185,11 @@
139185 int op = pExpr->op;
139186 if( op==TK_COLUMN || op==TK_IF_NULL_ROW ){
139187 renumberCursorDoMapping(pWalker, &pExpr->iTable);
139188 }
139189 if( ExprHasProperty(pExpr, EP_FromJoin) ){
139190 renumberCursorDoMapping(pWalker, &pExpr->w.iJoin);
139191 }
139192 return WRC_Continue;
139193 }
139194
139195 /*
@@ -138467,10 +139270,11 @@
139270 ** (3a) the subquery may not be a join and
139271 ** (3b) the FROM clause of the subquery may not contain a virtual
139272 ** table and
139273 ** (3c) the outer query may not be an aggregate.
139274 ** (3d) the outer query may not be DISTINCT.
139275 ** See also (26) for restrictions on RIGHT JOIN.
139276 **
139277 ** (4) The subquery can not be DISTINCT.
139278 **
139279 ** (**) At one point restrictions (4) and (5) defined a subset of DISTINCT
139280 ** sub-queries that were excluded from this optimization. Restriction
@@ -138565,10 +139369,16 @@
139369 **
139370 ** (25) If either the subquery or the parent query contains a window
139371 ** function in the select list or ORDER BY clause, flattening
139372 ** is not attempted.
139373 **
139374 ** (26) The subquery may not be the right operand of a RIGHT JOIN.
139375 ** See also (3) for restrictions on LEFT JOIN.
139376 **
139377 ** (27) The subquery may not contain a FULL or RIGHT JOIN unless it
139378 ** is the first element of the parent query.
139379 **
139380 **
139381 ** In this routine, the "p" parameter is a pointer to the outer query.
139382 ** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query
139383 ** uses aggregates.
139384 **
@@ -138590,11 +139400,11 @@
139400 Select *pSub1; /* Pointer to the rightmost select in sub-query */
139401 SrcList *pSrc; /* The FROM clause of the outer query */
139402 SrcList *pSubSrc; /* The FROM clause of the subquery */
139403 int iParent; /* VDBE cursor number of the pSub result set temp table */
139404 int iNewParent = -1;/* Replacement table for iParent */
139405 int isOuterJoin = 0; /* True if pSub is the right side of a LEFT JOIN */
139406 int i; /* Loop counter */
139407 Expr *pWhere; /* The WHERE clause */
139408 SrcItem *pSubitem; /* The subquery */
139409 sqlite3 *db = pParse->db;
139410 Walker w; /* Walker to persist agginfo data */
@@ -138663,29 +139473,35 @@
139473 ** aggregates are processed - there is no mechanism to determine if
139474 ** the LEFT JOIN table should be all-NULL.
139475 **
139476 ** See also tickets #306, #350, and #3300.
139477 */
139478 if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){
139479 if( pSubSrc->nSrc>1 /* (3a) */
139480 || isAgg /* (3b) */
139481 || IsVirtual(pSubSrc->a[0].pTab) /* (3c) */
139482 || (p->selFlags & SF_Distinct)!=0 /* (3d) */
139483 || (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */
139484 ){
139485 return 0;
139486 }
139487 isOuterJoin = 1;
139488 }
139489 #ifdef SQLITE_EXTRA_IFNULLROW
139490 else if( iFrom>0 && !isAgg ){
139491 /* Setting isOuterJoin to -1 causes OP_IfNullRow opcodes to be generated for
139492 ** every reference to any result column from subquery in a join, even
139493 ** though they are not necessary. This will stress-test the OP_IfNullRow
139494 ** opcode. */
139495 isOuterJoin = -1;
139496 }
139497 #endif
139498
139499 assert( pSubSrc->nSrc>0 ); /* True by restriction (7) */
139500 if( iFrom>0 && (pSubSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){
139501 return 0; /* Restriction (27) */
139502 }
139503
139504 /* Restriction (17): If the sub-query is a compound SELECT, then it must
139505 ** use only the UNION ALL operator. And none of the simple select queries
139506 ** that make up the compound SELECT are allowed to be aggregate or distinct
139507 ** queries.
@@ -138692,11 +139508,11 @@
139508 */
139509 if( pSub->pPrior ){
139510 if( pSub->pOrderBy ){
139511 return 0; /* Restriction (20) */
139512 }
139513 if( isAgg || (p->selFlags & SF_Distinct)!=0 || isOuterJoin>0 ){
139514 return 0; /* (17d1), (17d2), or (17f) */
139515 }
139516 for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){
139517 testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
139518 testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
@@ -138750,11 +139566,11 @@
139566 sqlite3DbFree(db, pSubitem->zAlias);
139567 pSubitem->zDatabase = 0;
139568 pSubitem->zName = 0;
139569 pSubitem->zAlias = 0;
139570 pSubitem->pSelect = 0;
139571 assert( pSubitem->fg.isUsing!=0 || pSubitem->u3.pOn==0 );
139572
139573 /* If the sub-query is a compound SELECT statement, then (by restrictions
139574 ** 17 and 18 above) it must be a UNION ALL and the parent query must
139575 ** be of the form:
139576 **
@@ -138860,10 +139676,11 @@
139676 */
139677 pSub = pSub1;
139678 for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){
139679 int nSubSrc;
139680 u8 jointype = 0;
139681 u8 ltorj = pSrc->a[iFrom].fg.jointype & JT_LTORJ;
139682 assert( pSub!=0 );
139683 pSubSrc = pSub->pSrc; /* FROM clause of subquery */
139684 nSubSrc = pSubSrc->nSrc; /* Number of terms in subquery FROM clause */
139685 pSrc = pParent->pSrc; /* FROM clause of the outer query */
139686
@@ -138894,17 +139711,20 @@
139711
139712 /* Transfer the FROM clause terms from the subquery into the
139713 ** outer query.
139714 */
139715 for(i=0; i<nSubSrc; i++){
139716 SrcItem *pItem = &pSrc->a[i+iFrom];
139717 if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing);
139718 assert( pItem->fg.isTabFunc==0 );
139719 *pItem = pSubSrc->a[i];
139720 pItem->fg.jointype |= ltorj;
139721 iNewParent = pSubSrc->a[i].iCursor;
139722 memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
139723 }
139724 pSrc->a[iFrom].fg.jointype &= JT_LTORJ;
139725 pSrc->a[iFrom].fg.jointype |= jointype | ltorj;
139726
139727 /* Now begin substituting subquery result set expressions for
139728 ** references to the iParent in the outer query.
139729 **
139730 ** Example:
@@ -138935,12 +139755,12 @@
139755 pParent->pOrderBy = pOrderBy;
139756 pSub->pOrderBy = 0;
139757 }
139758 pWhere = pSub->pWhere;
139759 pSub->pWhere = 0;
139760 if( isOuterJoin>0 ){
139761 sqlite3SetJoinExpr(pWhere, iNewParent, EP_FromJoin);
139762 }
139763 if( pWhere ){
139764 if( pParent->pWhere ){
139765 pParent->pWhere = sqlite3PExpr(pParse, TK_AND, pWhere, pParent->pWhere);
139766 }else{
@@ -138950,11 +139770,11 @@
139770 if( db->mallocFailed==0 ){
139771 SubstContext x;
139772 x.pParse = pParse;
139773 x.iTable = iParent;
139774 x.iNewTable = iNewParent;
139775 x.isOuterJoin = isOuterJoin;
139776 x.pEList = pSub->pEList;
139777 substSelect(&x, pParent, 0);
139778 }
139779
139780 /* The flattened query is a compound if either the inner or the
@@ -138985,12 +139805,12 @@
139805 */
139806 sqlite3AggInfoPersistWalkerInit(&w, pParse);
139807 sqlite3WalkSelect(&w,pSub1);
139808 sqlite3SelectDelete(db, pSub1);
139809
139810 #if TREETRACE_ENABLED
139811 if( sqlite3TreeTrace & 0x100 ){
139812 SELECTTRACE(0x100,pParse,p,("After flattening:\n"));
139813 sqlite3TreeViewSelect(0, p, 0);
139814 }
139815 #endif
139816
@@ -139392,16 +140212,16 @@
140212 iCursor, isLeftJoin);
140213 pWhere = pWhere->pLeft;
140214 }
140215 if( isLeftJoin
140216 && (ExprHasProperty(pWhere,EP_FromJoin)==0
140217 || pWhere->w.iJoin!=iCursor)
140218 ){
140219 return 0; /* restriction (4) */
140220 }
140221 if( ExprHasProperty(pWhere,EP_FromJoin)
140222 && pWhere->w.iJoin!=iCursor
140223 ){
140224 return 0; /* restriction (5) */
140225 }
140226 if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){
140227 nChng++;
@@ -139411,11 +140231,11 @@
140231 pNew = sqlite3ExprDup(pParse->db, pWhere, 0);
140232 unsetJoinExpr(pNew, -1);
140233 x.pParse = pParse;
140234 x.iTable = iCursor;
140235 x.iNewTable = iCursor;
140236 x.isOuterJoin = 0;
140237 x.pEList = pSubq->pEList;
140238 pNew = substExpr(&x, pNew);
140239 #ifndef SQLITE_OMIT_WINDOWFUNC
140240 if( pSubq->pWin && 0==pushDownWindowCheck(pParse, pSubq, pNew) ){
140241 /* Restriction 6c has prevented push-down in this case */
@@ -139620,11 +140440,11 @@
140440 pParse = pWalker->pParse;
140441 db = pParse->db;
140442 pNew = sqlite3DbMallocZero(db, sizeof(*pNew) );
140443 if( pNew==0 ) return WRC_Abort;
140444 memset(&dummy, 0, sizeof(dummy));
140445 pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0);
140446 if( pNewSrc==0 ) return WRC_Abort;
140447 *pNew = *p;
140448 p->pSrc = pNewSrc;
140449 p->pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ASTERISK, 0));
140450 p->op = TK_SELECT;
@@ -139965,14 +140785,38 @@
140785 /* The usual case - do not allow ROWID on a subquery */
140786 pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid;
140787 #else
140788 pTab->tabFlags |= TF_Ephemeral; /* Legacy compatibility mode */
140789 #endif
 
 
140790 return pParse->nErr ? SQLITE_ERROR : SQLITE_OK;
140791 }
140792
140793
140794 /*
140795 ** Check the N SrcItem objects to the right of pBase. (N might be zero!)
140796 ** If any of those SrcItem objects have a USING clause containing zName
140797 ** then return true.
140798 **
140799 ** If N is zero, or none of the N SrcItem objects to the right of pBase
140800 ** contains a USING clause, or if none of the USING clauses contain zName,
140801 ** then return false.
140802 */
140803 static int inAnyUsingClause(
140804 const char *zName, /* Name we are looking for */
140805 SrcItem *pBase, /* The base SrcItem. Looking at pBase[1] and following */
140806 int N /* How many SrcItems to check */
140807 ){
140808 while( N>0 ){
140809 N--;
140810 pBase++;
140811 if( pBase->fg.isUsing==0 ) continue;
140812 if( NEVER(pBase->u3.pUsing==0) ) continue;
140813 if( sqlite3IdListIndex(pBase->u3.pUsing, zName)>=0 ) return 1;
140814 }
140815 return 0;
140816 }
140817
140818
140819 /*
140820 ** This routine is a Walker callback for "expanding" a SELECT statement.
140821 ** "Expanding" means to do the following:
140822 **
@@ -140119,11 +140963,11 @@
140963 }
140964
140965 /* Process NATURAL keywords, and ON and USING clauses of joins.
140966 */
140967 assert( db->mallocFailed==0 || pParse->nErr!=0 );
140968 if( pParse->nErr || sqlite3ProcessJoin(pParse, p) ){
140969 return WRC_Abort;
140970 }
140971
140972 /* For every "*" that occurs in the column list, insert the names of
140973 ** all columns in all tables. And for every TABLE.* insert the names
@@ -140183,31 +141027,34 @@
141027 assert( !ExprHasProperty(pE->pLeft, EP_IntValue) );
141028 zTName = pE->pLeft->u.zToken;
141029 }
141030 for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
141031 Table *pTab = pFrom->pTab;
141032 Select *pSub;
141033 char *zTabName = pFrom->zAlias;
141034 const char *zSchemaName = 0;
141035 int iDb;
141036 if( zTabName==0 ){
141037 zTabName = pTab->zName;
141038 }
141039 if( db->mallocFailed ) break;
141040 assert( pFrom->fg.isNestedFrom == IsNestedFrom(pFrom->pSelect) );
141041 if( pFrom->fg.isNestedFrom ){
141042 pSub = pFrom->pSelect;
141043 assert( pSub->pEList!=0 );
141044 assert( pSub->pEList->nExpr==pTab->nCol );
141045 }else{
141046 pSub = 0;
141047 if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
141048 continue;
141049 }
141050 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
141051 zSchemaName = iDb>=0 ? db->aDb[iDb].zDbSName : "*";
141052 }
141053 for(j=0; j<pTab->nCol; j++){
141054 char *zName = pTab->aCol[j].zCnName;
141055 struct ExprList_item *pX; /* Newly added ExprList term */
 
 
141056
141057 assert( zName );
141058 if( zTName && pSub
141059 && sqlite3MatchEName(&pSub->pEList->a[j], 0, zTName, 0)==0
141060 ){
@@ -140224,58 +141071,62 @@
141071 continue;
141072 }
141073 tableSeen = 1;
141074
141075 if( i>0 && zTName==0 ){
141076 if( pFrom->fg.isUsing
141077 && sqlite3IdListIndex(pFrom->u3.pUsing, zName)>=0
141078 ){
 
 
 
 
 
141079 /* In a join with a USING clause, omit columns in the
141080 ** using clause from the table on the right. */
141081 continue;
141082 }
141083 }
141084 pRight = sqlite3Expr(db, TK_ID, zName);
141085 if( (pTabList->nSrc>1
141086 && ( (pFrom->fg.jointype & JT_LTORJ)==0
141087 || !inAnyUsingClause(zName,pFrom,pTabList->nSrc-i-1)
141088 )
141089 )
141090 || IN_RENAME_OBJECT
141091 ){
141092 Expr *pLeft;
141093 pLeft = sqlite3Expr(db, TK_ID, zTabName);
141094 pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
141095 if( IN_RENAME_OBJECT && pE->pLeft ){
141096 sqlite3RenameTokenRemap(pParse, pLeft, pE->pLeft);
141097 }
141098 if( zSchemaName ){
141099 pLeft = sqlite3Expr(db, TK_ID, zSchemaName);
141100 pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pExpr);
141101 }
 
 
 
 
141102 }else{
141103 pExpr = pRight;
141104 }
141105 pNew = sqlite3ExprListAppend(pParse, pNew, pExpr);
141106 if( pNew==0 ){
141107 break; /* OOM */
141108 }
141109 pX = &pNew->a[pNew->nExpr-1];
141110 assert( pX->zEName==0 );
141111 if( (selFlags & SF_NestedFrom)!=0 && !IN_RENAME_OBJECT ){
141112 if( pSub ){
141113 pX->zEName = sqlite3DbStrDup(db, pSub->pEList->a[j].zEName);
141114 testcase( pX->zEName==0 );
141115 }else{
141116 pX->zEName = sqlite3MPrintf(db, "%s.%s.%s",
141117 zSchemaName, zTabName, zName);
141118 testcase( pX->zEName==0 );
141119 }
141120 pX->eEName = ENAME_TAB;
141121 }else if( longNames ){
141122 pX->zEName = sqlite3MPrintf(db, "%s.%s", zTabName, zName);
141123 pX->eEName = ENAME_NAME;
141124 }else{
141125 pX->zEName = sqlite3DbStrDup(db, zName);
141126 pX->eEName = ENAME_NAME;
141127 }
 
141128 }
141129 }
141130 if( !tableSeen ){
141131 if( zTName ){
141132 sqlite3ErrorMsg(pParse, "no such table: %s", zTName);
@@ -140295,10 +141146,16 @@
141146 }
141147 if( (elistFlags & (EP_HasFunc|EP_Subquery))!=0 ){
141148 p->selFlags |= SF_ComplexResult;
141149 }
141150 }
141151 #if TREETRACE_ENABLED
141152 if( sqlite3TreeTrace & 0x100 ){
141153 SELECTTRACE(0x100,pParse,p,("After result-set wildcard expansion:\n"));
141154 sqlite3TreeViewSelect(0, p, 0);
141155 }
141156 #endif
141157 return WRC_Continue;
141158 }
141159
141160 #if SQLITE_DEBUG
141161 /*
@@ -140685,12 +141542,12 @@
141542 memset(&sWalker, 0, sizeof(sWalker));
141543 sWalker.pParse = pParse;
141544 sWalker.xExprCallback = havingToWhereExprCb;
141545 sWalker.u.pSelect = p;
141546 sqlite3WalkExpr(&sWalker, p->pHaving);
141547 #if TREETRACE_ENABLED
141548 if( sWalker.eCode && (sqlite3TreeTrace & 0x100)!=0 ){
141549 SELECTTRACE(0x100,pParse,p,("Move HAVING terms into WHERE:\n"));
141550 sqlite3TreeViewSelect(0, p, 0);
141551 }
141552 #endif
141553 }
@@ -140818,12 +141675,12 @@
141675 pSub = pPrior;
141676 }
141677 p->pEList->a[0].pExpr = pExpr;
141678 p->selFlags &= ~SF_Aggregate;
141679
141680 #if TREETRACE_ENABLED
141681 if( sqlite3TreeTrace & 0x400 ){
141682 SELECTTRACE(0x400,pParse,p,("After count-of-view optimization:\n"));
141683 sqlite3TreeViewSelect(0, p, 0);
141684 }
141685 #endif
141686 return 1;
@@ -140872,14 +141729,18 @@
141729 if( p==0 || pParse->nErr ){
141730 return 1;
141731 }
141732 assert( db->mallocFailed==0 );
141733 if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
141734 #if TREETRACE_ENABLED
141735 SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain));
141736 if( sqlite3TreeTrace & 0x10100 ){
141737 if( (sqlite3TreeTrace & 0x10001)==0x10000 ){
141738 sqlite3TreeViewLine(0, "In sqlite3Select() at %s:%d",
141739 __FILE__, __LINE__);
141740 }
141741 sqlite3ShowSelect(p);
141742 }
141743 #endif
141744
141745 assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo );
141746 assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo );
@@ -140889,13 +141750,13 @@
141750 assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union ||
141751 pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard ||
141752 pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_DistFifo );
141753 /* All of these destinations are also able to ignore the ORDER BY clause */
141754 if( p->pOrderBy ){
141755 #if TREETRACE_ENABLED
141756 SELECTTRACE(1,pParse,p, ("dropping superfluous ORDER BY:\n"));
141757 if( sqlite3TreeTrace & 0x100 ){
141758 sqlite3TreeViewExprList(0, p->pOrderBy, 0, "ORDERBY");
141759 }
141760 #endif
141761 sqlite3ParserAddCleanup(pParse,
141762 (void(*)(sqlite3*,void*))sqlite3ExprListDelete,
@@ -140910,12 +141771,12 @@
141771 if( pParse->nErr ){
141772 goto select_end;
141773 }
141774 assert( db->mallocFailed==0 );
141775 assert( p->pEList!=0 );
141776 #if TREETRACE_ENABLED
141777 if( sqlite3TreeTrace & 0x104 ){
141778 SELECTTRACE(0x104,pParse,p, ("after name resolution:\n"));
141779 sqlite3TreeViewSelect(0, p, 0);
141780 }
141781 #endif
141782
@@ -140955,12 +141816,12 @@
141816 #ifndef SQLITE_OMIT_WINDOWFUNC
141817 if( sqlite3WindowRewrite(pParse, p) ){
141818 assert( pParse->nErr );
141819 goto select_end;
141820 }
141821 #if TREETRACE_ENABLED
141822 if( p->pWin && (sqlite3TreeTrace & 0x108)!=0 ){
141823 SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n"));
141824 sqlite3TreeViewSelect(0, p, 0);
141825 }
141826 #endif
141827 #endif /* SQLITE_OMIT_WINDOWFUNC */
@@ -140984,11 +141845,11 @@
141845 assert( pTab!=0 );
141846
141847 /* Convert LEFT JOIN into JOIN if there are terms of the right table
141848 ** of the LEFT JOIN used in the WHERE clause.
141849 */
141850 if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==JT_LEFT
141851 && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor)
141852 && OptimizationEnabled(db, SQLITE_SimplifyJoin)
141853 ){
141854 SELECTTRACE(0x100,pParse,p,
141855 ("LEFT-JOIN simplifies to JOIN on term %d\n",i));
@@ -141070,11 +141931,11 @@
141931 */
141932 if( pSub->pOrderBy!=0
141933 && i==0
141934 && (p->selFlags & SF_ComplexResult)!=0
141935 && (pTabList->nSrc==1
141936 || (pTabList->a[1].fg.jointype&(JT_OUTER|JT_CROSS))!=0)
141937 ){
141938 continue;
141939 }
141940
141941 if( flattenSubquery(pParse, p, i, isAgg) ){
@@ -141094,13 +141955,13 @@
141955 /* Handle compound SELECT statements using the separate multiSelect()
141956 ** procedure.
141957 */
141958 if( p->pPrior ){
141959 rc = multiSelect(pParse, p, pDest);
141960 #if TREETRACE_ENABLED
141961 SELECTTRACE(0x1,pParse,p,("end compound-select processing\n"));
141962 if( (sqlite3TreeTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
141963 sqlite3TreeViewSelect(0, p, 0);
141964 }
141965 #endif
141966 if( p->pNext==0 ) ExplainQueryPlanPop(pParse);
141967 return rc;
@@ -141115,12 +141976,12 @@
141976 if( p->pWhere!=0
141977 && p->pWhere->op==TK_AND
141978 && OptimizationEnabled(db, SQLITE_PropagateConst)
141979 && propagateConstants(pParse, p)
141980 ){
141981 #if TREETRACE_ENABLED
141982 if( sqlite3TreeTrace & 0x100 ){
141983 SELECTTRACE(0x100,pParse,p,("After constant propagation:\n"));
141984 sqlite3TreeViewSelect(0, p, 0);
141985 }
141986 #endif
141987 }else{
@@ -141192,15 +142053,16 @@
142053 ** inside the subquery. This can help the subquery to run more efficiently.
142054 */
142055 if( OptimizationEnabled(db, SQLITE_PushDown)
142056 && (pItem->fg.isCte==0
142057 || (pItem->u2.pCteUse->eM10d!=M10d_Yes && pItem->u2.pCteUse->nUse<2))
142058 && (pItem->fg.jointype & JT_RIGHT)==0
142059 && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor,
142060 (pItem->fg.jointype & JT_OUTER)!=0)
142061 ){
142062 #if TREETRACE_ENABLED
142063 if( sqlite3TreeTrace & 0x100 ){
142064 SELECTTRACE(0x100,pParse,p,
142065 ("After WHERE-clause push-down into subquery %d:\n", pSub->selId));
142066 sqlite3TreeViewSelect(0, p, 0);
142067 }
142068 #endif
@@ -141212,22 +142074,23 @@
142074 zSavedAuthContext = pParse->zAuthContext;
142075 pParse->zAuthContext = pItem->zName;
142076
142077 /* Generate code to implement the subquery
142078 **
142079 ** The subquery is implemented as a co-routine all of the following are
142080 ** true:
142081 **
142082 ** (1) the subquery is guaranteed to be the outer loop (so that
142083 ** it does not need to be computed more than once), and
142084 ** (2) the subquery is not a CTE that should be materialized
142085 ** (3) the subquery is not part of a left operand for a RIGHT JOIN
 
 
142086 */
142087 if( i==0
142088 && (pTabList->nSrc==1
142089 || (pTabList->a[1].fg.jointype&(JT_OUTER|JT_CROSS))!=0) /* (1) */
142090 && (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d!=M10d_Yes) /* (2) */
142091 && (pTabList->a[0].fg.jointype & JT_LTORJ)==0 /* (3) */
142092 ){
142093 /* Implement a co-routine that will return a single row of the result
142094 ** set on each invocation.
142095 */
142096 int addrTop = sqlite3VdbeCurrentAddr(v)+1;
@@ -141314,12 +142177,12 @@
142177 pWhere = p->pWhere;
142178 pGroupBy = p->pGroupBy;
142179 pHaving = p->pHaving;
142180 sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0;
142181
142182 #if TREETRACE_ENABLED
142183 if( sqlite3TreeTrace & 0x400 ){
142184 SELECTTRACE(0x400,pParse,p,("After all FROM-clause analysis:\n"));
142185 sqlite3TreeViewSelect(0, p, 0);
142186 }
142187 #endif
142188
@@ -141351,12 +142214,12 @@
142214 ** the sDistinct.isTnct is still set. Hence, isTnct represents the
142215 ** original setting of the SF_Distinct flag, not the current setting */
142216 assert( sDistinct.isTnct );
142217 sDistinct.isTnct = 2;
142218
142219 #if TREETRACE_ENABLED
142220 if( sqlite3TreeTrace & 0x400 ){
142221 SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n"));
142222 sqlite3TreeViewSelect(0, p, 0);
142223 }
142224 #endif
142225 }
@@ -141385,10 +142248,22 @@
142248
142249 /* If the output is destined for a temporary table, open that table.
142250 */
142251 if( pDest->eDest==SRT_EphemTab ){
142252 sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr);
142253 if( p->selFlags & SF_NestedFrom ){
142254 /* Delete or NULL-out result columns that will never be used */
142255 int ii;
142256 for(ii=pEList->nExpr-1; ii>0 && pEList->a[ii].bUsed==0; ii--){
142257 sqlite3ExprDelete(db, pEList->a[ii].pExpr);
142258 sqlite3DbFree(db, pEList->a[ii].zEName);
142259 pEList->nExpr--;
142260 }
142261 for(ii=0; ii<pEList->nExpr; ii++){
142262 if( pEList->a[ii].bUsed==0 ) pEList->a[ii].pExpr->op = TK_NULL;
142263 }
142264 }
142265 }
142266
142267 /* Set the limiter.
142268 */
142269 iEnd = sqlite3VdbeMakeLabel(pParse);
@@ -141604,12 +142479,12 @@
142479 #endif
142480 sNC.ncFlags &= ~NC_InAggFunc;
142481 }
142482 pAggInfo->mxReg = pParse->nMem;
142483 if( db->mallocFailed ) goto select_end;
142484 #if TREETRACE_ENABLED
142485 if( sqlite3TreeTrace & 0x400 ){
142486 int ii;
142487 SELECTTRACE(0x400,pParse,p,("After aggregate analysis %p:\n", pAggInfo));
142488 sqlite3TreeViewSelect(0, p, 0);
142489 if( minMaxFlag ){
142490 sqlite3DebugPrintf("MIN/MAX Optimization (0x%02x) adds:\n", minMaxFlag);
@@ -142001,11 +142876,13 @@
142876 SELECTTRACE(1,pParse,p,("WhereBegin returns\n"));
142877 eDist = sqlite3WhereIsDistinct(pWInfo);
142878 updateAccumulator(pParse, regAcc, pAggInfo, eDist);
142879 if( eDist!=WHERE_DISTINCT_NOOP ){
142880 struct AggInfo_func *pF = &pAggInfo->aFunc[0];
142881 if( pF ){
142882 fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr);
142883 }
142884 }
142885
142886 if( regAcc ) sqlite3VdbeAddOp2(v, OP_Integer, 1, regAcc);
142887 if( minMaxFlag ){
142888 sqlite3WhereMinMaxOptEarlyOut(v, pWInfo);
@@ -142068,13 +142945,13 @@
142945 assert( pExpr->iAgg==i );
142946 }
142947 }
142948 #endif
142949
142950 #if TREETRACE_ENABLED
142951 SELECTTRACE(0x1,pParse,p,("end processing\n"));
142952 if( (sqlite3TreeTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
142953 sqlite3TreeViewSelect(0, p, 0);
142954 }
142955 #endif
142956 ExplainQueryPlanPop(pParse);
142957 return rc;
@@ -142335,13 +143212,11 @@
143212 SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){
143213 Schema *pTmpSchema; /* Schema of the pTab table */
143214 Trigger *pList; /* List of triggers to return */
143215 HashElem *p; /* Loop variable for TEMP triggers */
143216
143217 assert( pParse->disableTriggers==0 );
 
 
143218 pTmpSchema = pParse->db->aDb[1].pSchema;
143219 p = sqliteHashFirst(&pTmpSchema->trigHash);
143220 pList = pTab->pTrigger;
143221 while( p ){
143222 Trigger *pTrig = (Trigger *)sqliteHashData(p);
@@ -143011,18 +143886,27 @@
143886 for(e=0; e<pEList->nExpr; e++){
143887 if( sqlite3IdListIndex(pIdList, pEList->a[e].zEName)>=0 ) return 1;
143888 }
143889 return 0;
143890 }
143891
143892 /*
143893 ** Return true if any TEMP triggers exist
143894 */
143895 static int tempTriggersExist(sqlite3 *db){
143896 if( NEVER(db->aDb[1].pSchema==0) ) return 0;
143897 if( sqliteHashFirst(&db->aDb[1].pSchema->trigHash)==0 ) return 0;
143898 return 1;
143899 }
143900
143901 /*
143902 ** Return a list of all triggers on table pTab if there exists at least
143903 ** one trigger that must be fired when an operation of type 'op' is
143904 ** performed on the table, and, if that operation is an UPDATE, if at
143905 ** least one of the columns in pChanges is being modified.
143906 */
143907 static SQLITE_NOINLINE Trigger *triggersReallyExist(
143908 Parse *pParse, /* Parse context */
143909 Table *pTab, /* The table the contains the triggers */
143910 int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */
143911 ExprList *pChanges, /* Columns that change in an UPDATE statement */
143912 int *pMask /* OUT: Mask of TRIGGER_BEFORE|TRIGGER_AFTER */
@@ -143081,10 +143965,26 @@
143965 if( pMask ){
143966 *pMask = mask;
143967 }
143968 return (mask ? pList : 0);
143969 }
143970 SQLITE_PRIVATE Trigger *sqlite3TriggersExist(
143971 Parse *pParse, /* Parse context */
143972 Table *pTab, /* The table the contains the triggers */
143973 int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */
143974 ExprList *pChanges, /* Columns that change in an UPDATE statement */
143975 int *pMask /* OUT: Mask of TRIGGER_BEFORE|TRIGGER_AFTER */
143976 ){
143977 assert( pTab!=0 );
143978 if( (pTab->pTrigger==0 && !tempTriggersExist(pParse->db))
143979 || pParse->disableTriggers
143980 ){
143981 if( pMask ) *pMask = 0;
143982 return 0;
143983 }
143984 return triggersReallyExist(pParse,pTab,op,pChanges,pMask);
143985 }
143986
143987 /*
143988 ** Convert the pStep->zTarget string into a SrcList and return a pointer
143989 ** to that SrcList.
143990 **
@@ -144088,10 +144988,18 @@
144988 #endif
144989 #ifdef SQLITE_OMIT_VIEW
144990 # undef isView
144991 # define isView 0
144992 #endif
144993
144994 #if TREETRACE_ENABLED
144995 if( sqlite3TreeTrace & 0x10000 ){
144996 sqlite3TreeViewLine(0, "In sqlite3Update() at %s:%d", __FILE__, __LINE__);
144997 sqlite3TreeViewUpdate(pParse->pWith, pTabList, pChanges, pWhere,
144998 onError, pOrderBy, pLimit, pUpsert, pTrigger);
144999 }
145000 #endif
145001
145002 /* If there was a FROM clause, set nChangeFrom to the number of expressions
145003 ** in the change-list. Otherwise, set it to 0. There cannot be a FROM
145004 ** clause if this function is being called to generate code for part of
145005 ** an UPSERT statement. */
@@ -147181,10 +148089,31 @@
148089 typedef struct WhereTerm WhereTerm;
148090 typedef struct WhereLoopBuilder WhereLoopBuilder;
148091 typedef struct WhereScan WhereScan;
148092 typedef struct WhereOrCost WhereOrCost;
148093 typedef struct WhereOrSet WhereOrSet;
148094 typedef struct WhereMemBlock WhereMemBlock;
148095 typedef struct WhereRightJoin WhereRightJoin;
148096
148097 /*
148098 ** This object is a header on a block of allocated memory that will be
148099 ** automatically freed when its WInfo oject is destructed.
148100 */
148101 struct WhereMemBlock {
148102 WhereMemBlock *pNext; /* Next block in the chain */
148103 u8 sz; /* Bytes of space */
148104 };
148105
148106 /*
148107 ** Extra information attached to a WhereLevel that is a RIGHT JOIN.
148108 */
148109 struct WhereRightJoin {
148110 int iMatch; /* Cursor used to determine prior matched rows */
148111 int regBloom; /* Bloom filter for iRJMatch */
148112 int regReturn; /* Return register for the interior subroutine */
148113 int addrSubrtn; /* Starting address for the interior subroutine */
148114 };
148115
148116 /*
148117 ** This object contains information needed to implement a single nested
148118 ** loop in WHERE clause.
148119 **
@@ -147214,10 +148143,11 @@
148143 #ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
148144 u32 iLikeRepCntr; /* LIKE range processing counter register (times 2) */
148145 int addrLikeRep; /* LIKE range processing address */
148146 #endif
148147 int regFilter; /* Bloom filter */
148148 WhereRightJoin *pRJ; /* Extra information for RIGHT JOIN */
148149 u8 iFrom; /* Which entry in the FROM clause */
148150 u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */
148151 int p1, p2; /* Operands of the opcode used to end the loop */
148152 union { /* Information that depends on pWLoop->wsFlags */
148153 struct {
@@ -147627,10 +148557,11 @@
148557 LogEst nRowOut; /* Estimated number of output rows */
148558 int iTop; /* The very beginning of the WHERE loop */
148559 int iEndWhere; /* End of the WHERE clause itself */
148560 WhereLoop *pLoops; /* List of all WhereLoop objects */
148561 WhereExprMod *pExprMods; /* Expression modifications */
148562 WhereMemBlock *pMemToFree;/* Memory to free when this object destroyed */
148563 Bitmask revMask; /* Mask of ORDER BY terms that need reversing */
148564 WhereClause sWC; /* Decomposition of the WHERE clause */
148565 WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */
148566 WhereLevel a[1]; /* Information about each nest loop in WHERE */
148567 };
@@ -147652,10 +148583,12 @@
148583 int iColumn, /* Column number of LHS */
148584 Bitmask notReady, /* RHS must not overlap with this mask */
148585 u32 op, /* Mask of WO_xx values describing operator */
148586 Index *pIdx /* Must be compatible with this index, if not NULL */
148587 );
148588 SQLITE_PRIVATE void *sqlite3WhereMalloc(WhereInfo *pWInfo, u64 nByte);
148589 SQLITE_PRIVATE void *sqlite3WhereRealloc(WhereInfo *pWInfo, void *pOld, u64 nByte);
148590
148591 /* wherecode.c: */
148592 #ifndef SQLITE_OMIT_EXPLAIN
148593 SQLITE_PRIVATE int sqlite3WhereExplainOneScan(
148594 Parse *pParse, /* Parse context */
@@ -147687,10 +148620,15 @@
148620 Vdbe *v, /* Prepared statement under construction */
148621 WhereInfo *pWInfo, /* Complete information about the WHERE clause */
148622 int iLevel, /* Which level of pWInfo->a[] should be coded */
148623 WhereLevel *pLevel, /* The current level pointer */
148624 Bitmask notReady /* Which tables are currently available */
148625 );
148626 SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop(
148627 WhereInfo *pWInfo,
148628 int iLevel,
148629 WhereLevel *pLevel
148630 );
148631
148632 /* whereexpr.c: */
148633 SQLITE_PRIVATE void sqlite3WhereClauseInit(WhereClause*,WhereInfo*);
148634 SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause*);
@@ -147955,10 +148893,13 @@
148893 else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
148894 sqlite3_str_appendf(&str, " VIRTUAL TABLE INDEX %d:%s",
148895 pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
148896 }
148897 #endif
148898 if( pItem->fg.jointype & JT_LEFT ){
148899 sqlite3_str_appendf(&str, " LEFT-JOIN");
148900 }
148901 #ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS
148902 if( pLoop->nOut>=10 ){
148903 sqlite3_str_appendf(&str, " (~%llu rows)",
148904 sqlite3LogEstToInt(pLoop->nOut));
148905 }else{
@@ -148391,12 +149332,13 @@
149332 }
149333
149334 i = pLevel->u.in.nIn;
149335 pLevel->u.in.nIn += nEq;
149336 pLevel->u.in.aInLoop =
149337 sqlite3WhereRealloc(pTerm->pWC->pWInfo,
149338 pLevel->u.in.aInLoop,
149339 sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn);
149340 pIn = pLevel->u.in.aInLoop;
149341 if( pIn ){
149342 int iMap = 0; /* Index in aiMap[] */
149343 pIn += i;
149344 for(i=iEq;i<pLoop->nLTerm; i++){
@@ -148814,11 +149756,11 @@
149756 ** are also excluded. See codeCursorHintIsOrFunction() for details.
149757 */
149758 if( pTabItem->fg.jointype & JT_LEFT ){
149759 Expr *pExpr = pTerm->pExpr;
149760 if( !ExprHasProperty(pExpr, EP_FromJoin)
149761 || pExpr->w.iJoin!=pTabItem->iCursor
149762 ){
149763 sWalker.eCode = 0;
149764 sWalker.xExprCallback = codeCursorHintIsOrFunction;
149765 sqlite3WalkExpr(&sWalker, pTerm->pExpr);
149766 if( sWalker.eCode ) continue;
@@ -148900,11 +149842,11 @@
149842 assert( iIdxCur>0 );
149843 assert( pIdx->aiColumn[pIdx->nColumn-1]==-1 );
149844
149845 pWInfo->bDeferredSeek = 1;
149846 sqlite3VdbeAddOp3(v, OP_DeferredSeek, iIdxCur, 0, iCur);
149847 if( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))
149848 && DbMaskAllZero(sqlite3ParseToplevel(pParse)->writeMask)
149849 ){
149850 int i;
149851 Table *pTab = pIdx->pTable;
149852 u32 *ai = (u32*)sqlite3DbMallocZero(pParse->db, sizeof(u32)*(pTab->nCol+1));
@@ -149252,11 +150194,11 @@
150194
150195 /* If this is the right table of a LEFT OUTER JOIN, allocate and
150196 ** initialize a memory cell that records if this table matches any
150197 ** row of the left table of the join.
150198 */
150199 assert( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))
150200 || pLevel->iFrom>0 || (pTabItem[0].fg.jointype & JT_LEFT)==0
150201 );
150202 if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){
150203 pLevel->iLeftJoin = ++pParse->nMem;
150204 sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin);
@@ -149263,11 +150205,14 @@
150205 VdbeComment((v, "init LEFT JOIN no-match flag"));
150206 }
150207
150208 /* Compute a safe address to jump to if we discover that the table for
150209 ** this loop is empty and can never contribute content. */
150210 for(j=iLevel; j>0; j--){
150211 if( pWInfo->a[j].iLeftJoin ) break;
150212 if( pWInfo->a[j].pRJ ) break;
150213 }
150214 addrHalt = pWInfo->a[j].addrBrk;
150215
150216 /* Special case of a FROM clause subquery implemented as a co-routine */
150217 if( pTabItem->fg.viaCoroutine ){
150218 int regYield = pTabItem->regReturn;
@@ -149890,11 +150835,11 @@
150835 sqlite3VdbeAddOp3(v, OP_SeekHit, iIdxCur, nEq, nEq);
150836 }
150837
150838 /* Seek the table cursor, if required */
150839 omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0
150840 && (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))==0;
150841 if( omitTable ){
150842 /* pIdx is a covering index. No need to access the main table. */
150843 }else if( HasRowid(pIdx->pTable) ){
150844 codeDeferredSeek(pWInfo, pIdx, iCur, iIdxCur);
150845 }else if( iCur!=iIdxCur ){
@@ -149924,11 +150869,11 @@
150869 ** Also, do not do this when processing one index an a multi-index
150870 ** OR clause, since the transformation will become invalid once we
150871 ** move forward to the next index.
150872 ** https://sqlite.org/src/info/4e8e4857d32d401f
150873 */
150874 if( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))==0 ){
150875 whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo);
150876 }
150877
150878 /* If a partial index is driving the loop, try to eliminate WHERE clause
150879 ** terms from the query that must be true due to the WHERE clause of
@@ -149943,11 +150888,11 @@
150888 }else{
150889 testcase( pIdx->pPartIdxWhere );
150890 /* The following assert() is not a requirement, merely an observation:
150891 ** The OR-optimization doesn't work for the right hand table of
150892 ** a LEFT JOIN: */
150893 assert( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))==0 );
150894 }
150895
150896 /* Record the instruction used to terminate the loop. */
150897 if( pLoop->wsFlags & WHERE_ONEROW ){
150898 pLevel->op = OP_Noop;
@@ -150284,10 +151229,18 @@
151229 sqlite3ExprDelete(db, pAndExpr);
151230 }
151231 sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
151232 sqlite3VdbeGoto(v, pLevel->addrBrk);
151233 sqlite3VdbeResolveLabel(v, iLoopBody);
151234
151235 /* Set the P2 operand of the OP_Return opcode that will end the current
151236 ** loop to point to this spot, which is the top of the next containing
151237 ** loop. The byte-code formatter will use that P2 value as a hint to
151238 ** indent everything in between the this point and the final OP_Return.
151239 ** See tag-20220407a in vdbe.c and shell.c */
151240 assert( pLevel->op==OP_Return );
151241 pLevel->p2 = sqlite3VdbeCurrentAddr(v);
151242
151243 if( pWInfo->nLevel>1 ){ sqlite3StackFree(db, pOrTab); }
151244 if( !untestedTerms ) disableTerm(pLevel, pTerm);
151245 }else
151246 #endif /* SQLITE_OMIT_OR_OPTIMIZATION */
@@ -150347,11 +151300,13 @@
151300 pWInfo->untestedTerms = 1;
151301 continue;
151302 }
151303 pE = pTerm->pExpr;
151304 assert( pE!=0 );
151305 if( (pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ))
151306 && !ExprHasProperty(pE,EP_FromJoin)
151307 ){
151308 continue;
151309 }
151310
151311 if( iLoop==1 && !sqlite3ExprCoveredByIndex(pE, pLevel->iTabCur, pIdx) ){
151312 iNext = 2;
@@ -150409,11 +151364,11 @@
151364 WhereTerm *pAlt;
151365 if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
151366 if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue;
151367 if( (pTerm->eOperator & WO_EQUIV)==0 ) continue;
151368 if( pTerm->leftCursor!=iCur ) continue;
151369 if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ) ) continue;
151370 pE = pTerm->pExpr;
151371 #ifdef WHERETRACE_ENABLED /* 0x800 */
151372 if( sqlite3WhereTrace & 0x800 ){
151373 sqlite3DebugPrintf("Coding transitive constraint:\n");
151374 sqlite3WhereTermPrint(pTerm, pWC->nTerm-j);
@@ -150439,10 +151394,51 @@
151394 sEAlt = *pAlt->pExpr;
151395 sEAlt.pLeft = pE->pLeft;
151396 sqlite3ExprIfFalse(pParse, &sEAlt, addrCont, SQLITE_JUMPIFNULL);
151397 pAlt->wtFlags |= TERM_CODED;
151398 }
151399
151400 /* For a RIGHT OUTER JOIN, record the fact that the current row has
151401 ** been matched at least once.
151402 */
151403 if( pLevel->pRJ ){
151404 Table *pTab;
151405 int nPk;
151406 int r;
151407 int jmp1 = 0;
151408 WhereRightJoin *pRJ = pLevel->pRJ;
151409
151410 /* pTab is the right-hand table of the RIGHT JOIN. Generate code that
151411 ** will record that the current row of that table has been matched at
151412 ** least once. This is accomplished by storing the PK for the row in
151413 ** both the iMatch index and the regBloom Bloom filter.
151414 */
151415 pTab = pWInfo->pTabList->a[pLevel->iFrom].pTab;
151416 if( HasRowid(pTab) ){
151417 r = sqlite3GetTempRange(pParse, 2);
151418 sqlite3ExprCodeGetColumnOfTable(v, pTab, pLevel->iTabCur, -1, r+1);
151419 nPk = 1;
151420 }else{
151421 int iPk;
151422 Index *pPk = sqlite3PrimaryKeyIndex(pTab);
151423 nPk = pPk->nKeyCol;
151424 r = sqlite3GetTempRange(pParse, nPk+1);
151425 for(iPk=0; iPk<nPk; iPk++){
151426 int iCol = pPk->aiColumn[iPk];
151427 sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+1+iPk);
151428 }
151429 }
151430 jmp1 = sqlite3VdbeAddOp4Int(v, OP_Found, pRJ->iMatch, 0, r+1, nPk);
151431 VdbeCoverage(v);
151432 VdbeComment((v, "match against %s", pTab->zName));
151433 sqlite3VdbeAddOp3(v, OP_MakeRecord, r+1, nPk, r);
151434 sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pRJ->iMatch, r, r+1, nPk);
151435 sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pRJ->regBloom, 0, r+1, nPk);
151436 sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
151437 sqlite3VdbeJumpHere(v, jmp1);
151438 sqlite3ReleaseTempRange(pParse, r, nPk+1);
151439 }
151440
151441 /* For a LEFT OUTER JOIN, generate code that will record the fact that
151442 ** at least one row of the right table has matched the left table.
151443 */
151444 if( pLevel->iLeftJoin ){
@@ -150455,15 +151451,30 @@
151451 if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
151452 if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
151453 assert( pWInfo->untestedTerms );
151454 continue;
151455 }
151456 if( pTabItem->fg.jointype & JT_LTORJ ) continue;
151457 assert( pTerm->pExpr );
151458 sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
151459 pTerm->wtFlags |= TERM_CODED;
151460 }
151461 }
151462
151463 if( pLevel->pRJ ){
151464 /* Create a subroutine used to process all interior loops and code
151465 ** of the RIGHT JOIN. During normal operation, the subroutine will
151466 ** be in-line with the rest of the code. But at the end, a separate
151467 ** loop will run that invokes this subroutine for unmatched rows
151468 ** of pTab, with all tables to left begin set to NULL.
151469 */
151470 WhereRightJoin *pRJ = pLevel->pRJ;
151471 sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pRJ->regReturn);
151472 pRJ->addrSubrtn = sqlite3VdbeCurrentAddr(v);
151473 assert( pParse->withinRJSubrtn < 255 );
151474 pParse->withinRJSubrtn++;
151475 }
151476
151477 #if WHERETRACE_ENABLED /* 0x20800 */
151478 if( sqlite3WhereTrace & 0x20000 ){
151479 sqlite3DebugPrintf("All WHERE-clause terms after coding level %d:\n",
151480 iLevel);
@@ -150474,10 +151485,94 @@
151485 iLevel, (u64)pLevel->notReady);
151486 }
151487 #endif
151488 return pLevel->notReady;
151489 }
151490
151491 /*
151492 ** Generate the code for the loop that finds all non-matched terms
151493 ** for a RIGHT JOIN.
151494 */
151495 SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop(
151496 WhereInfo *pWInfo,
151497 int iLevel,
151498 WhereLevel *pLevel
151499 ){
151500 Parse *pParse = pWInfo->pParse;
151501 Vdbe *v = pParse->pVdbe;
151502 WhereRightJoin *pRJ = pLevel->pRJ;
151503 Expr *pSubWhere = 0;
151504 WhereClause *pWC = &pWInfo->sWC;
151505 WhereInfo *pSubWInfo;
151506 WhereLoop *pLoop = pLevel->pWLoop;
151507 SrcItem *pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
151508 SrcList sFrom;
151509 Bitmask mAll = 0;
151510 int k;
151511
151512 ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pTab->zName));
151513 for(k=0; k<iLevel; k++){
151514 int iIdxCur;
151515 mAll |= pWInfo->a[k].pWLoop->maskSelf;
151516 sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur);
151517 iIdxCur = pWInfo->a[k].iIdxCur;
151518 if( iIdxCur ){
151519 sqlite3VdbeAddOp1(v, OP_NullRow, iIdxCur);
151520 }
151521 }
151522 if( (pTabItem->fg.jointype & JT_LTORJ)==0 ){
151523 mAll |= pLoop->maskSelf;
151524 for(k=0; k<pWC->nTerm; k++){
151525 WhereTerm *pTerm = &pWC->a[k];
151526 if( pTerm->wtFlags & TERM_VIRTUAL ) break;
151527 if( pTerm->prereqAll & ~mAll ) continue;
151528 if( ExprHasProperty(pTerm->pExpr, EP_FromJoin|EP_InnerJoin) ) continue;
151529 pSubWhere = sqlite3ExprAnd(pParse, pSubWhere,
151530 sqlite3ExprDup(pParse->db, pTerm->pExpr, 0));
151531 }
151532 }
151533 sFrom.nSrc = 1;
151534 sFrom.nAlloc = 1;
151535 memcpy(&sFrom.a[0], pTabItem, sizeof(SrcItem));
151536 sFrom.a[0].fg.jointype = 0;
151537 assert( pParse->withinRJSubrtn < 100 );
151538 pParse->withinRJSubrtn++;
151539 pSubWInfo = sqlite3WhereBegin(pParse, &sFrom, pSubWhere, 0, 0, 0,
151540 WHERE_RIGHT_JOIN, 0);
151541 if( pSubWInfo ){
151542 int iCur = pLevel->iTabCur;
151543 int r = ++pParse->nMem;
151544 int nPk;
151545 int jmp;
151546 int addrCont = sqlite3WhereContinueLabel(pSubWInfo);
151547 Table *pTab = pTabItem->pTab;
151548 if( HasRowid(pTab) ){
151549 sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, r);
151550 nPk = 1;
151551 }else{
151552 int iPk;
151553 Index *pPk = sqlite3PrimaryKeyIndex(pTab);
151554 nPk = pPk->nKeyCol;
151555 pParse->nMem += nPk - 1;
151556 for(iPk=0; iPk<nPk; iPk++){
151557 int iCol = pPk->aiColumn[iPk];
151558 sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+iPk);
151559 }
151560 }
151561 jmp = sqlite3VdbeAddOp4Int(v, OP_Filter, pRJ->regBloom, 0, r, nPk);
151562 VdbeCoverage(v);
151563 sqlite3VdbeAddOp4Int(v, OP_Found, pRJ->iMatch, addrCont, r, nPk);
151564 VdbeCoverage(v);
151565 sqlite3VdbeJumpHere(v, jmp);
151566 sqlite3VdbeAddOp2(v, OP_Gosub, pRJ->regReturn, pRJ->addrSubrtn);
151567 sqlite3WhereEnd(pSubWInfo);
151568 }
151569 sqlite3ExprDelete(pParse->db, pSubWhere);
151570 ExplainQueryPlanPop(pParse);
151571 assert( pParse->withinRJSubrtn>0 );
151572 pParse->withinRJSubrtn--;
151573 }
151574
151575 /************** End of wherecode.c *******************************************/
151576 /************** Begin file whereexpr.c ***************************************/
151577 /*
151578 ** 2015-06-08
@@ -150543,23 +151638,20 @@
151638 int idx;
151639 testcase( wtFlags & TERM_VIRTUAL );
151640 if( pWC->nTerm>=pWC->nSlot ){
151641 WhereTerm *pOld = pWC->a;
151642 sqlite3 *db = pWC->pWInfo->pParse->db;
151643 pWC->a = sqlite3WhereMalloc(pWC->pWInfo, sizeof(pWC->a[0])*pWC->nSlot*2 );
151644 if( pWC->a==0 ){
151645 if( wtFlags & TERM_DYNAMIC ){
151646 sqlite3ExprDelete(db, p);
151647 }
151648 pWC->a = pOld;
151649 return 0;
151650 }
151651 memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm);
151652 pWC->nSlot = pWC->nSlot*2;
 
 
 
151653 }
151654 pTerm = &pWC->a[idx = pWC->nTerm++];
151655 if( (wtFlags & TERM_VIRTUAL)==0 ) pWC->nBase = pWC->nTerm;
151656 if( p && ExprHasProperty(p, EP_Unlikely) ){
151657 pTerm->truthProb = sqlite3LogEst(p->iTable) - 270;
@@ -150945,11 +152037,11 @@
152037 ** a join, then transfer the appropriate markings over to derived.
152038 */
152039 static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
152040 if( pDerived ){
152041 pDerived->flags |= pBase->flags & EP_FromJoin;
152042 pDerived->w.iJoin = pBase->w.iJoin;
152043 }
152044 }
152045
152046 /*
152047 ** Mark term iChild as being a child of term iParent
@@ -151430,11 +152522,13 @@
152522 mask |= sqlite3WhereExprUsage(pMaskSet, pS->pHaving);
152523 if( ALWAYS(pSrc!=0) ){
152524 int i;
152525 for(i=0; i<pSrc->nSrc; i++){
152526 mask |= exprSelectUsage(pMaskSet, pSrc->a[i].pSelect);
152527 if( pSrc->a[i].fg.isUsing==0 ){
152528 mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].u3.pOn);
152529 }
152530 if( pSrc->a[i].fg.isTabFunc ){
152531 mask |= sqlite3WhereExprListUsage(pMaskSet, pSrc->a[i].u1.pFuncArg);
152532 }
152533 }
152534 }
@@ -151590,11 +152684,11 @@
152684 abort();
152685 }
152686 #endif
152687
152688 if( ExprHasProperty(pExpr, EP_FromJoin) ){
152689 Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->w.iJoin);
152690 prereqAll |= x;
152691 extraRight = x-1; /* ON clause terms may not be used with an index
152692 ** on left table of a LEFT JOIN. Ticket #3015 */
152693 if( (prereqAll>>1)>=x ){
152694 sqlite3ErrorMsg(pParse, "ON clause references tables to its right");
@@ -151941,11 +153035,11 @@
153035 Expr *pNewExpr;
153036 pNewExpr = sqlite3PExpr(pParse, TK_MATCH,
153037 0, sqlite3ExprDup(db, pRight, 0));
153038 if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){
153039 ExprSetProperty(pNewExpr, EP_FromJoin);
153040 pNewExpr->w.iJoin = pExpr->w.iJoin;
153041 }
153042 idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
153043 testcase( idxNew==0 );
153044 pNewTerm = &pWC->a[idxNew];
153045 pNewTerm->prereqRight = prereqExpr;
@@ -152163,13 +153257,10 @@
153257 }
153258 if( a==aLast ) break;
153259 a++;
153260 }
153261 }
 
 
 
153262 }
153263
153264
153265 /*
153266 ** These routines walk (recursively) an expression tree and generate
@@ -152292,10 +153383,11 @@
153383 assert( pTab!=0 );
153384 pArgs = pItem->u1.pFuncArg;
153385 if( pArgs==0 ) return;
153386 for(j=k=0; j<pArgs->nExpr; j++){
153387 Expr *pRhs;
153388 u32 joinType;
153389 while( k<pTab->nCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){k++;}
153390 if( k>=pTab->nCol ){
153391 sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d",
153392 pTab->zName, j);
153393 return;
@@ -152308,13 +153400,16 @@
153400 pColRef->y.pTab = pTab;
153401 pItem->colUsed |= sqlite3ExprColUsed(pColRef);
153402 pRhs = sqlite3PExpr(pParse, TK_UPLUS,
153403 sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
153404 pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs);
153405 if( pItem->fg.jointype & (JT_LEFT|JT_LTORJ) ){
153406 joinType = EP_FromJoin;
153407 }else{
153408 joinType = EP_InnerJoin;
153409 }
153410 sqlite3SetJoinExpr(pTerm, pItem->iCursor, joinType);
153411 whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);
153412 }
153413 }
153414
153415 /************** End of whereexpr.c *******************************************/
@@ -152571,10 +153666,34 @@
153666 return MASKBIT(i);
153667 }
153668 }
153669 return 0;
153670 }
153671
153672 /* Allocate memory that is automatically freed when pWInfo is freed.
153673 */
153674 SQLITE_PRIVATE void *sqlite3WhereMalloc(WhereInfo *pWInfo, u64 nByte){
153675 WhereMemBlock *pBlock;
153676 pBlock = sqlite3DbMallocRawNN(pWInfo->pParse->db, nByte+sizeof(*pBlock));
153677 if( pBlock ){
153678 pBlock->pNext = pWInfo->pMemToFree;
153679 pBlock->sz = nByte;
153680 pWInfo->pMemToFree = pBlock;
153681 pBlock++;
153682 }
153683 return (void*)pBlock;
153684 }
153685 SQLITE_PRIVATE void *sqlite3WhereRealloc(WhereInfo *pWInfo, void *pOld, u64 nByte){
153686 void *pNew = sqlite3WhereMalloc(pWInfo, nByte);
153687 if( pNew && pOld ){
153688 WhereMemBlock *pOldBlk = (WhereMemBlock*)pOld;
153689 pOldBlk--;
153690 assert( pOldBlk->sz<nByte );
153691 memcpy(pNew, pOld, pOldBlk->sz);
153692 }
153693 return pNew;
153694 }
153695
153696 /*
153697 ** Create a new mask for cursor iCursor.
153698 **
153699 ** There is one cursor per table in the FROM clause. The number of
@@ -153051,17 +154170,17 @@
154170 const Bitmask notReady /* Tables in outer loops of the join */
154171 ){
154172 char aff;
154173 if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
154174 if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0;
154175 if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ))!=0
154176 && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
154177 && (pTerm->eOperator & WO_IS)
154178 ){
154179 /* Cannot use an IS term from the WHERE clause as an index driver for
154180 ** the RHS of a LEFT JOIN or for the LHS of a RIGHT JOIN. Such a term
154181 ** can only be used if it is from the ON clause. */
154182 return 0;
154183 }
154184 if( (pTerm->prereqRight & notReady)!=0 ) return 0;
154185 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
154186 if( pTerm->u.x.leftColumn<0 ) return 0;
@@ -153127,11 +154246,12 @@
154246 Expr *pExpr = pTerm->pExpr;
154247 /* Make the automatic index a partial index if there are terms in the
154248 ** WHERE clause (or the ON clause of a LEFT join) that constrain which
154249 ** rows of the target table (pSrc) that can be used. */
154250 if( (pTerm->wtFlags & TERM_VIRTUAL)==0
154251 && ((pSrc->fg.jointype&(JT_LEFT|JT_LTORJ))==0
154252 || ExprHasProperty(pExpr,EP_FromJoin))
154253 && sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor)
154254 ){
154255 pPartial = sqlite3ExprAnd(pParse, pPartial,
154256 sqlite3ExprDup(pParse->db, pExpr, 0));
154257 }
@@ -153400,11 +154520,11 @@
154520 if( OptimizationDisabled(pParse->db, SQLITE_BloomPulldown) ) break;
154521 while( ++iLevel < pWInfo->nLevel ){
154522 const SrcItem *pTabItem;
154523 pLevel = &pWInfo->a[iLevel];
154524 pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
154525 if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ) ) continue;
154526 pLoop = pLevel->pWLoop;
154527 if( NEVER(pLoop==0) ) continue;
154528 if( pLoop->prereq & notReady ) continue;
154529 if( (pLoop->wsFlags & (WHERE_BLOOMFILTER|WHERE_COLUMN_IN))
154530 ==WHERE_BLOOMFILTER
@@ -153473,13 +154593,14 @@
154593 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
154594 assert( pTerm->u.x.leftColumn>=XN_ROWID );
154595 assert( pTerm->u.x.leftColumn<pTab->nCol );
154596
154597 /* tag-20191211-002: WHERE-clause constraints are not useful to the
154598 ** right-hand table of a LEFT JOIN nor to the left-hand table of a
154599 ** RIGHT JOIN. See tag-20191211-001 for the
154600 ** equivalent restriction for ordinary tables. */
154601 if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ))!=0
154602 && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
154603 ){
154604 continue;
154605 }
154606 nTerm++;
@@ -154535,26 +155656,23 @@
155656
155657 /*
155658 ** Free a WhereInfo structure
155659 */
155660 static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
 
155661 assert( pWInfo!=0 );
 
 
 
 
 
 
 
155662 sqlite3WhereClauseClear(&pWInfo->sWC);
155663 while( pWInfo->pLoops ){
155664 WhereLoop *p = pWInfo->pLoops;
155665 pWInfo->pLoops = p->pNextLoop;
155666 whereLoopDelete(db, p);
155667 }
155668 assert( pWInfo->pExprMods==0 );
155669 while( pWInfo->pMemToFree ){
155670 WhereMemBlock *pNext = pWInfo->pMemToFree->pNext;
155671 sqlite3DbFreeNN(db, pWInfo->pMemToFree);
155672 pWInfo->pMemToFree = pNext;
155673 }
155674 sqlite3DbFreeNN(db, pWInfo);
155675 }
155676
155677 /* Undo all Expr node modifications
155678 */
@@ -154919,14 +156037,15 @@
156037 ** cause many rows to be omitted, then mark that table as
156038 ** "self-culling".
156039 **
156040 ** 2022-03-24: Self-culling only applies if either the extra terms
156041 ** are straight comparison operators that are non-true with NULL
156042 ** operand, or if the loop is not an OUTER JOIN.
156043 */
156044 if( (pTerm->eOperator & 0x3f)!=0
156045 || (pWC->pWInfo->pTabList->a[pLoop->iTab].fg.jointype
156046 & (JT_LEFT|JT_LTORJ))==0
156047 ){
156048 pLoop->wsFlags |= WHERE_SELFCULL;
156049 }
156050 }
156051 if( pTerm->truthProb<=0 ){
@@ -155129,13 +156248,14 @@
156248 /* Do not allow the upper bound of a LIKE optimization range constraint
156249 ** to mix with a lower range bound from some other source */
156250 if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue;
156251
156252 /* tag-20191211-001: Do not allow constraints from the WHERE clause to
156253 ** be used by the right table of a LEFT JOIN nor by the left table of a
156254 ** RIGHT JOIN. Only constraints in the
156255 ** ON clause are allowed. See tag-20191211-002 for the vtab equivalent. */
156256 if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ))!=0
156257 && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
156258 ){
156259 continue;
156260 }
156261
@@ -155501,11 +156621,11 @@
156621 }
156622 if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0;
156623 for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
156624 Expr *pExpr;
156625 pExpr = pTerm->pExpr;
156626 if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->w.iJoin==iTab)
156627 && (isLeft==0 || ExprHasProperty(pExpr, EP_FromJoin))
156628 && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab)
156629 && (pTerm->wtFlags & TERM_VNULL)==0
156630 ){
156631 return 1;
@@ -155611,17 +156731,18 @@
156731 rSize = pTab->nRowLogEst;
156732
156733 #ifndef SQLITE_OMIT_AUTOMATIC_INDEX
156734 /* Automatic indexes */
156735 if( !pBuilder->pOrSet /* Not part of an OR optimization */
156736 && (pWInfo->wctrlFlags & (WHERE_RIGHT_JOIN|WHERE_OR_SUBCLAUSE))==0
156737 && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
156738 && !pSrc->fg.isIndexedBy /* Has no INDEXED BY clause */
156739 && !pSrc->fg.notIndexed /* Has no NOT INDEXED clause */
156740 && HasRowid(pTab) /* Not WITHOUT ROWID table. (FIXME: Why not?) */
156741 && !pSrc->fg.isCorrelated /* Not a correlated subquery */
156742 && !pSrc->fg.isRecursive /* Not a recursive common table expression. */
156743 && (pSrc->fg.jointype & JT_RIGHT)==0 /* Not the right tab of a RIGHT JOIN */
156744 ){
156745 /* Generate auto-index WhereLoops */
156746 LogEst rLogSize; /* Logarithm of the number of rows in the table */
156747 WhereTerm *pTerm;
156748 WhereTerm *pWCEnd = pWC->a + pWC->nTerm;
@@ -156107,19 +157228,30 @@
157228
157229 #if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \
157230 && !defined(SQLITE_OMIT_VIRTUALTABLE)
157231 /*
157232 ** Cause the prepared statement that is associated with a call to
157233 ** xBestIndex to potentiall use all schemas. If the statement being
157234 ** prepared is read-only, then just start read transactions on all
157235 ** schemas. But if this is a write operation, start writes on all
157236 ** schemas.
157237 **
157238 ** This is used by the (built-in) sqlite_dbpage virtual table.
157239 */
157240 SQLITE_PRIVATE void sqlite3VtabUsesAllSchemas(sqlite3_index_info *pIdxInfo){
157241 HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
157242 Parse *pParse = pHidden->pParse;
157243 int nDb = pParse->db->nDb;
157244 int i;
157245 for(i=0; i<nDb; i++){
157246 sqlite3CodeVerifySchema(pParse, i);
157247 }
157248 if( pParse->writeMask ){
157249 for(i=0; i<nDb; i++){
157250 sqlite3BeginWriteOperation(pParse, 0, i);
157251 }
157252 }
157253 }
157254 #endif
157255
157256 /*
157257 ** Add all WhereLoop objects for a table of the join identified by
@@ -156297,10 +157429,13 @@
157429 pWCEnd = pWC->a + pWC->nTerm;
157430 pNew = pBuilder->pNew;
157431 memset(&sSum, 0, sizeof(sSum));
157432 pItem = pWInfo->pTabList->a + pNew->iTab;
157433 iCur = pItem->iCursor;
157434
157435 /* The multi-index OR optimization does not work for RIGHT and FULL JOIN */
157436 if( pItem->fg.jointype & JT_RIGHT ) return SQLITE_OK;
157437
157438 for(pTerm=pWC->a; pTerm<pWCEnd && rc==SQLITE_OK; pTerm++){
157439 if( (pTerm->eOperator & WO_OR)!=0
157440 && (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0
157441 ){
@@ -156422,22 +157557,22 @@
157557 for(iTab=0, pItem=pTabList->a; pItem<pEnd; iTab++, pItem++){
157558 Bitmask mUnusable = 0;
157559 pNew->iTab = iTab;
157560 pBuilder->iPlanLimit += SQLITE_QUERY_PLANNER_LIMIT_INCR;
157561 pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor);
157562 if( (pItem->fg.jointype & (JT_OUTER|JT_CROSS))!=0 ){
157563 /* This condition is true when pItem is the FROM clause term on the
157564 ** right-hand-side of a OUTER or CROSS JOIN. */
157565 mPrereq = mPrior;
157566 }else{
157567 mPrereq = 0;
157568 }
157569 #ifndef SQLITE_OMIT_VIRTUALTABLE
157570 if( IsVirtual(pItem->pTab) ){
157571 SrcItem *p;
157572 for(p=&pItem[1]; p<pEnd; p++){
157573 if( mUnusable || (p->fg.jointype & (JT_OUTER|JT_CROSS)) ){
157574 mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor);
157575 }
157576 }
157577 rc = whereLoopAddVirtual(pBuilder, mPrereq, mUnusable);
157578 }else
@@ -157496,11 +158631,11 @@
158631 if( (tabUsed & pLoop->maskSelf)!=0 ) continue;
158632 pEnd = pWInfo->sWC.a + pWInfo->sWC.nTerm;
158633 for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){
158634 if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
158635 if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
158636 || pTerm->pExpr->w.iJoin!=pItem->iCursor
158637 ){
158638 break;
158639 }
158640 }
158641 }
@@ -157727,11 +158862,11 @@
158862 ** struct, the contents of WhereInfo.a[], the WhereClause structure
158863 ** and the WhereMaskSet structure. Since WhereClause contains an 8-byte
158864 ** field (type Bitmask) it must be aligned on an 8-byte boundary on
158865 ** some architectures. Hence the ROUND8() below.
158866 */
158867 nByteWInfo = ROUND8P(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel));
158868 pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop));
158869 if( db->mallocFailed ){
158870 sqlite3DbFree(db, pWInfo);
158871 pWInfo = 0;
158872 goto whereBeginError;
@@ -158049,12 +159184,14 @@
159184 sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB);
159185 }else if( IsVirtual(pTab) ){
159186 /* noop */
159187 }else
159188 #endif
159189 if( ((pLoop->wsFlags & WHERE_IDX_ONLY)==0
159190 && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0)
159191 || (pTabItem->fg.jointype & (JT_LTORJ|JT_RIGHT))!=0
159192 ){
159193 int op = OP_OpenRead;
159194 if( pWInfo->eOnePass!=ONEPASS_OFF ){
159195 op = OP_OpenWrite;
159196 pWInfo->aiCurOnePass[0] = pTabItem->iCursor;
159197 };
@@ -158152,10 +159289,41 @@
159289 }
159290 #endif /* SQLITE_ENABLE_COLUMN_USED_MASK */
159291 }
159292 }
159293 if( iDb>=0 ) sqlite3CodeVerifySchema(pParse, iDb);
159294 if( (pTabItem->fg.jointype & JT_RIGHT)!=0
159295 && (pLevel->pRJ = sqlite3WhereMalloc(pWInfo, sizeof(WhereRightJoin)))!=0
159296 ){
159297 WhereRightJoin *pRJ = pLevel->pRJ;
159298 pRJ->iMatch = pParse->nTab++;
159299 pRJ->regBloom = ++pParse->nMem;
159300 sqlite3VdbeAddOp2(v, OP_Blob, 65536, pRJ->regBloom);
159301 pRJ->regReturn = ++pParse->nMem;
159302 sqlite3VdbeAddOp2(v, OP_Null, 0, pRJ->regReturn);
159303 assert( pTab==pTabItem->pTab );
159304 if( HasRowid(pTab) ){
159305 KeyInfo *pInfo;
159306 sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRJ->iMatch, 1);
159307 pInfo = sqlite3KeyInfoAlloc(pParse->db, 1, 0);
159308 if( pInfo ){
159309 pInfo->aColl[0] = 0;
159310 pInfo->aSortFlags[0] = 0;
159311 sqlite3VdbeAppendP4(v, pInfo, P4_KEYINFO);
159312 }
159313 }else{
159314 Index *pPk = sqlite3PrimaryKeyIndex(pTab);
159315 sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRJ->iMatch, pPk->nKeyCol);
159316 sqlite3VdbeSetP4KeyInfo(pParse, pPk);
159317 }
159318 pLoop->wsFlags &= ~WHERE_IDX_ONLY;
159319 /* The nature of RIGHT JOIN processing is such that it messes up
159320 ** the output order. So omit any ORDER BY/GROUP BY elimination
159321 ** optimizations. We need to do an actual sort for RIGHT JOIN. */
159322 pWInfo->nOBSat = 0;
159323 pWInfo->eDistinct = WHERE_DISTINCT_UNORDERED;
159324 }
159325 }
159326 pWInfo->iTop = sqlite3VdbeCurrentAddr(v);
159327 if( db->mallocFailed ) goto whereBeginError;
159328
159329 /* Generate the code to do the search. Each iteration of the for
@@ -158264,10 +159432,21 @@
159432 */
159433 VdbeModuleComment((v, "End WHERE-core"));
159434 for(i=pWInfo->nLevel-1; i>=0; i--){
159435 int addr;
159436 pLevel = &pWInfo->a[i];
159437 if( pLevel->pRJ ){
159438 /* Terminate the subroutine that forms the interior of the loop of
159439 ** the RIGHT JOIN table */
159440 WhereRightJoin *pRJ = pLevel->pRJ;
159441 sqlite3VdbeResolveLabel(v, pLevel->addrCont);
159442 pLevel->addrCont = 0;
159443 sqlite3VdbeAddOp3(v, OP_Return, pRJ->regReturn, pRJ->addrSubrtn, 1);
159444 VdbeCoverage(v);
159445 assert( pParse->withinRJSubrtn>0 );
159446 pParse->withinRJSubrtn--;
159447 }
159448 pLoop = pLevel->pWLoop;
159449 if( pLevel->op!=OP_Noop ){
159450 #ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
159451 int addrSeek = 0;
159452 Index *pIdx;
@@ -158291,11 +159470,11 @@
159470 VdbeCoverageIf(v, op==OP_SeekGT);
159471 sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2);
159472 }
159473 #endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */
159474 /* The common case: Advance to the next row */
159475 if( pLevel->addrCont ) sqlite3VdbeResolveLabel(v, pLevel->addrCont);
159476 sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3);
159477 sqlite3VdbeChangeP5(v, pLevel->p5);
159478 VdbeCoverage(v);
159479 VdbeCoverageIf(v, pLevel->op==OP_Next);
159480 VdbeCoverageIf(v, pLevel->op==OP_Prev);
@@ -158306,11 +159485,11 @@
159485 VdbeCoverage(v);
159486 }
159487 #ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
159488 if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek);
159489 #endif
159490 }else if( pLevel->addrCont ){
159491 sqlite3VdbeResolveLabel(v, pLevel->addrCont);
159492 }
159493 if( (pLoop->wsFlags & WHERE_IN_ABLE)!=0 && pLevel->u.in.nIn>0 ){
159494 struct InLoop *pIn;
159495 int j;
@@ -158356,10 +159535,14 @@
159535 }
159536 sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
159537 }
159538 }
159539 sqlite3VdbeResolveLabel(v, pLevel->addrBrk);
159540 if( pLevel->pRJ ){
159541 sqlite3VdbeAddOp3(v, OP_Return, pLevel->pRJ->regReturn, 0, 1);
159542 VdbeCoverage(v);
159543 }
159544 if( pLevel->addrSkip ){
159545 sqlite3VdbeGoto(v, pLevel->addrSkip);
159546 VdbeComment((v, "next skip-scan on %s", pLoop->u.btree.pIndex->zName));
159547 sqlite3VdbeJumpHere(v, pLevel->addrSkip);
159548 sqlite3VdbeJumpHere(v, pLevel->addrSkip-2);
@@ -158399,24 +159582,28 @@
159582 }
159583 VdbeModuleComment((v, "End WHERE-loop%d: %s", i,
159584 pWInfo->pTabList->a[pLevel->iFrom].pTab->zName));
159585 }
159586
 
 
 
 
 
159587 assert( pWInfo->nLevel<=pTabList->nSrc );
159588 for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){
159589 int k, last;
159590 VdbeOp *pOp, *pLastOp;
159591 Index *pIdx = 0;
159592 SrcItem *pTabItem = &pTabList->a[pLevel->iFrom];
159593 Table *pTab = pTabItem->pTab;
159594 assert( pTab!=0 );
159595 pLoop = pLevel->pWLoop;
159596
159597 /* Do RIGHT JOIN processing. Generate code that will output the
159598 ** unmatched rows of the right operand of the RIGHT JOIN with
159599 ** all of the columns of the left operand set to NULL.
159600 */
159601 if( pLevel->pRJ ){
159602 sqlite3WhereRightJoinLoop(pWInfo, i, pLevel);
159603 continue;
159604 }
159605
159606 /* For a co-routine, change all OP_Column references to the table of
159607 ** the co-routine into OP_Copy of result contained in a register.
159608 ** OP_Rowid becomes OP_Null.
159609 */
@@ -158425,33 +159612,10 @@
159612 translateColumnToCopy(pParse, pLevel->addrBody, pLevel->iTabCur,
159613 pTabItem->regResult, 0);
159614 continue;
159615 }
159616
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159617 /* If this scan uses an index, make VDBE code substitutions to read data
159618 ** from the index instead of from the table where possible. In some cases
159619 ** this optimization prevents the table from ever being read, which can
159620 ** yield a significant performance boost.
159621 **
@@ -158547,10 +159711,15 @@
159711 #ifdef SQLITE_DEBUG
159712 if( db->flags & SQLITE_VdbeAddopTrace ) printf("TRANSLATE complete\n");
159713 #endif
159714 }
159715 }
159716
159717 /* The "break" point is here, just past the end of the outer loop.
159718 ** Set it.
159719 */
159720 sqlite3VdbeResolveLabel(v, pWInfo->iBreak);
159721
159722 /* Final cleanup
159723 */
159724 if( pWInfo->pExprMods ) whereUndoExprMods(pWInfo);
159725 pParse->nQueryLoop = pWInfo->savedNQueryLoop;
@@ -160289,11 +161458,11 @@
161458 regArg = sqlite3GetTempRange(pParse, nArg);
161459 sqlite3ExprCodeExprList(pParse, pWin->pOwner->x.pList, regArg, 0, 0);
161460
161461 for(iEnd=sqlite3VdbeCurrentAddr(v); iOp<iEnd; iOp++){
161462 VdbeOp *pOp = sqlite3VdbeGetOp(v, iOp);
161463 if( pOp->opcode==OP_Column && pOp->p1==pMWin->iEphCsr ){
161464 pOp->p1 = csr;
161465 }
161466 }
161467 }
161468 if( pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
@@ -161828,11 +162997,11 @@
162997 /* memset(p, 0, sizeof(Expr)); */
162998 p->op = (u8)op;
162999 p->affExpr = 0;
163000 p->flags = EP_Leaf;
163001 ExprClearVVAProperties(p);
163002 /* p->iAgg = -1; // Not required */
163003 p->pLeft = p->pRight = 0;
163004 p->pAggInfo = 0;
163005 memset(&p->x, 0, sizeof(p->x));
163006 memset(&p->y, 0, sizeof(p->y));
163007 p->op2 = 0;
@@ -162161,10 +163330,11 @@
163330 Upsert* yy444;
163331 u8 yy516;
163332 With* yy521;
163333 const char* yy522;
163334 Expr* yy528;
163335 OnOrUsing yy561;
163336 struct FrameBound yy595;
163337 } YYMINORTYPE;
163338 #ifndef YYSTACKDEPTH
163339 #define YYSTACKDEPTH 100
163340 #endif
@@ -162177,21 +163347,21 @@
163347 #define sqlite3ParserCTX_PDECL ,Parse *pParse
163348 #define sqlite3ParserCTX_PARAM ,pParse
163349 #define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse;
163350 #define sqlite3ParserCTX_STORE yypParser->pParse=pParse;
163351 #define YYFALLBACK 1
163352 #define YYNSTATE 570
163353 #define YYNRULE 403
163354 #define YYNRULE_WITH_ACTION 340
163355 #define YYNTOKEN 185
163356 #define YY_MAX_SHIFT 569
163357 #define YY_MIN_SHIFTREDUCE 829
163358 #define YY_MAX_SHIFTREDUCE 1231
163359 #define YY_ERROR_ACTION 1232
163360 #define YY_ACCEPT_ACTION 1233
163361 #define YY_NO_ACTION 1234
163362 #define YY_MIN_REDUCE 1235
163363 #define YY_MAX_REDUCE 1637
163364 /************* End control #defines *******************************************/
163365 #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])))
163366
163367 /* Define the yytestcase() macro to be a no-op if is not already defined
@@ -162255,428 +163425,428 @@
163425 ** yy_reduce_ofst[] For each state, the offset into yy_action for
163426 ** shifting non-terminals after a reduce.
163427 ** yy_default[] Default action for each state.
163428 **
163429 *********** Begin parsing tables **********************************************/
163430 #define YY_ACTTAB_COUNT (2064)
163431 static const YYACTIONTYPE yy_action[] = {
163432 /* 0 */ 562, 204, 562, 116, 112, 225, 562, 116, 112, 225,
163433 /* 10 */ 562, 1306, 373, 1285, 404, 556, 556, 556, 562, 405,
163434 /* 20 */ 374, 1306, 1268, 41, 41, 41, 41, 204, 1516, 71,
163435 /* 30 */ 71, 965, 415, 41, 41, 487, 299, 275, 299, 966,
163436 /* 40 */ 393, 71, 71, 123, 124, 114, 1209, 1209, 1042, 1045,
163437 /* 50 */ 1034, 1034, 121, 121, 122, 122, 122, 122, 472, 405,
163438 /* 60 */ 1233, 1, 1, 569, 2, 1237, 544, 116, 112, 225,
163439 /* 70 */ 313, 476, 142, 476, 520, 116, 112, 225, 525, 1319,
163440 /* 80 */ 413, 519, 138, 123, 124, 114, 1209, 1209, 1042, 1045,
163441 /* 90 */ 1034, 1034, 121, 121, 122, 122, 122, 122, 116, 112,
163442 /* 100 */ 225, 323, 120, 120, 120, 120, 119, 119, 118, 118,
163443 /* 110 */ 118, 117, 113, 440, 280, 280, 280, 280, 438, 438,
163444 /* 120 */ 438, 1557, 372, 1559, 1184, 371, 1155, 559, 1155, 559,
163445 /* 130 */ 405, 1557, 533, 255, 222, 440, 99, 141, 445, 312,
163446 /* 140 */ 553, 236, 120, 120, 120, 120, 119, 119, 118, 118,
163447 /* 150 */ 118, 117, 113, 440, 123, 124, 114, 1209, 1209, 1042,
163448 /* 160 */ 1045, 1034, 1034, 121, 121, 122, 122, 122, 122, 138,
163449 /* 170 */ 290, 1184, 335, 444, 118, 118, 118, 117, 113, 440,
163450 /* 180 */ 125, 1184, 1185, 1186, 144, 437, 436, 562, 117, 113,
163451 /* 190 */ 440, 122, 122, 122, 122, 115, 120, 120, 120, 120,
163452 /* 200 */ 119, 119, 118, 118, 118, 117, 113, 440, 450, 110,
163453 /* 210 */ 13, 13, 542, 120, 120, 120, 120, 119, 119, 118,
163454 /* 220 */ 118, 118, 117, 113, 440, 418, 312, 553, 1184, 1185,
163455 /* 230 */ 1186, 145, 1216, 405, 1216, 122, 122, 122, 122, 120,
163456 /* 240 */ 120, 120, 120, 119, 119, 118, 118, 118, 117, 113,
163457 /* 250 */ 440, 461, 338, 1031, 1031, 1043, 1046, 123, 124, 114,
163458 /* 260 */ 1209, 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122,
163459 /* 270 */ 122, 122, 1271, 518, 218, 1184, 562, 405, 220, 510,
163460 /* 280 */ 171, 80, 81, 120, 120, 120, 120, 119, 119, 118,
163461 /* 290 */ 118, 118, 117, 113, 440, 1001, 16, 16, 1184, 55,
163462 /* 300 */ 55, 123, 124, 114, 1209, 1209, 1042, 1045, 1034, 1034,
163463 /* 310 */ 121, 121, 122, 122, 122, 122, 120, 120, 120, 120,
163464 /* 320 */ 119, 119, 118, 118, 118, 117, 113, 440, 1035, 542,
163465 /* 330 */ 1184, 369, 1184, 1185, 1186, 248, 1426, 395, 500, 497,
163466 /* 340 */ 496, 108, 554, 560, 4, 920, 920, 429, 495, 336,
163467 /* 350 */ 456, 324, 356, 390, 1229, 1184, 1185, 1186, 557, 562,
163468 /* 360 */ 120, 120, 120, 120, 119, 119, 118, 118, 118, 117,
163469 /* 370 */ 113, 440, 280, 280, 365, 1570, 1597, 437, 436, 150,
163470 /* 380 */ 405, 441, 71, 71, 1278, 559, 1213, 1184, 1185, 1186,
163471 /* 390 */ 83, 1215, 267, 551, 539, 511, 1551, 562, 96, 1214,
163472 /* 400 */ 6, 1270, 468, 138, 123, 124, 114, 1209, 1209, 1042,
163473 /* 410 */ 1045, 1034, 1034, 121, 121, 122, 122, 122, 122, 544,
163474 /* 420 */ 13, 13, 1021, 503, 1216, 1184, 1216, 543, 106, 106,
163475 /* 430 */ 218, 562, 1230, 171, 562, 423, 107, 193, 441, 564,
163476 /* 440 */ 563, 426, 1542, 1011, 321, 545, 1184, 266, 283, 364,
163477 /* 450 */ 506, 359, 505, 253, 71, 71, 539, 71, 71, 355,
163478 /* 460 */ 312, 553, 1603, 120, 120, 120, 120, 119, 119, 118,
163479 /* 470 */ 118, 118, 117, 113, 440, 1011, 1011, 1013, 1014, 27,
163480 /* 480 */ 280, 280, 1184, 1185, 1186, 1150, 562, 1602, 405, 895,
163481 /* 490 */ 186, 544, 352, 559, 544, 931, 529, 513, 1150, 512,
163482 /* 500 */ 409, 1150, 546, 1184, 1185, 1186, 562, 540, 1544, 51,
163483 /* 510 */ 51, 210, 123, 124, 114, 1209, 1209, 1042, 1045, 1034,
163484 /* 520 */ 1034, 121, 121, 122, 122, 122, 122, 1184, 470, 56,
163485 /* 530 */ 56, 405, 280, 280, 1480, 501, 119, 119, 118, 118,
163486 /* 540 */ 118, 117, 113, 440, 1001, 559, 514, 213, 537, 1551,
163487 /* 550 */ 312, 553, 138, 6, 528, 123, 124, 114, 1209, 1209,
163488 /* 560 */ 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122, 122,
163489 /* 570 */ 1545, 120, 120, 120, 120, 119, 119, 118, 118, 118,
163490 /* 580 */ 117, 113, 440, 481, 1184, 1185, 1186, 478, 277, 1259,
163491 /* 590 */ 951, 248, 1184, 369, 500, 497, 496, 1184, 336, 565,
163492 /* 600 */ 1184, 565, 405, 288, 495, 951, 870, 187, 476, 312,
163493 /* 610 */ 553, 380, 286, 376, 120, 120, 120, 120, 119, 119,
163494 /* 620 */ 118, 118, 118, 117, 113, 440, 123, 124, 114, 1209,
163495 /* 630 */ 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122,
163496 /* 640 */ 122, 405, 390, 1128, 1184, 863, 98, 280, 280, 1184,
163497 /* 650 */ 1185, 1186, 369, 1085, 1184, 1185, 1186, 1184, 1185, 1186,
163498 /* 660 */ 559, 451, 32, 369, 229, 123, 124, 114, 1209, 1209,
163499 /* 670 */ 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122, 122,
163500 /* 680 */ 1425, 953, 562, 224, 952, 120, 120, 120, 120, 119,
163501 /* 690 */ 119, 118, 118, 118, 117, 113, 440, 1150, 224, 1184,
163502 /* 700 */ 153, 1184, 1185, 1186, 1543, 13, 13, 297, 951, 1224,
163503 /* 710 */ 1150, 149, 405, 1150, 369, 1573, 1168, 5, 365, 1570,
163504 /* 720 */ 425, 1230, 3, 951, 120, 120, 120, 120, 119, 119,
163505 /* 730 */ 118, 118, 118, 117, 113, 440, 123, 124, 114, 1209,
163506 /* 740 */ 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122,
163507 /* 750 */ 122, 405, 204, 561, 1184, 1022, 1184, 1185, 1186, 1184,
163508 /* 760 */ 384, 846, 151, 1542, 282, 398, 1090, 1090, 484, 562,
163509 /* 770 */ 461, 338, 1311, 1311, 1542, 123, 124, 114, 1209, 1209,
163510 /* 780 */ 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122, 122,
163511 /* 790 */ 127, 562, 13, 13, 370, 120, 120, 120, 120, 119,
163512 /* 800 */ 119, 118, 118, 118, 117, 113, 440, 298, 562, 449,
163513 /* 810 */ 524, 1184, 1185, 1186, 13, 13, 1184, 1185, 1186, 1289,
163514 /* 820 */ 459, 1259, 405, 1309, 1309, 1542, 1006, 449, 448, 196,
163515 /* 830 */ 295, 71, 71, 1257, 120, 120, 120, 120, 119, 119,
163516 /* 840 */ 118, 118, 118, 117, 113, 440, 123, 124, 114, 1209,
163517 /* 850 */ 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122,
163518 /* 860 */ 122, 405, 223, 1065, 1150, 280, 280, 415, 308, 274,
163519 /* 870 */ 274, 281, 281, 1411, 402, 401, 378, 1150, 559, 562,
163520 /* 880 */ 1150, 1188, 559, 1590, 559, 123, 124, 114, 1209, 1209,
163521 /* 890 */ 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122, 122,
163522 /* 900 */ 449, 1472, 13, 13, 1526, 120, 120, 120, 120, 119,
163523 /* 910 */ 119, 118, 118, 118, 117, 113, 440, 197, 562, 350,
163524 /* 920 */ 1576, 569, 2, 1237, 834, 835, 836, 1552, 313, 1204,
163525 /* 930 */ 142, 6, 405, 251, 250, 249, 202, 1319, 9, 1188,
163526 /* 940 */ 258, 71, 71, 420, 120, 120, 120, 120, 119, 119,
163527 /* 950 */ 118, 118, 118, 117, 113, 440, 123, 124, 114, 1209,
163528 /* 960 */ 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122,
163529 /* 970 */ 122, 562, 280, 280, 562, 1205, 405, 568, 309, 1237,
163530 /* 980 */ 345, 1288, 348, 415, 313, 559, 142, 487, 521, 1633,
163531 /* 990 */ 391, 367, 487, 1319, 70, 70, 1287, 71, 71, 236,
163532 /* 1000 */ 1317, 101, 114, 1209, 1209, 1042, 1045, 1034, 1034, 121,
163533 /* 1010 */ 121, 122, 122, 122, 122, 120, 120, 120, 120, 119,
163534 /* 1020 */ 119, 118, 118, 118, 117, 113, 440, 1106, 280, 280,
163535 /* 1030 */ 424, 444, 1515, 1205, 435, 280, 280, 1479, 1344, 307,
163536 /* 1040 */ 470, 559, 1107, 965, 487, 487, 213, 1255, 559, 1528,
163537 /* 1050 */ 562, 966, 203, 562, 1021, 236, 379, 1108, 515, 120,
163538 /* 1060 */ 120, 120, 120, 119, 119, 118, 118, 118, 117, 113,
163539 /* 1070 */ 440, 1012, 104, 71, 71, 1011, 13, 13, 906, 562,
163540 /* 1080 */ 1485, 562, 280, 280, 95, 522, 487, 444, 907, 1318,
163541 /* 1090 */ 1314, 541, 405, 280, 280, 559, 147, 205, 1485, 1487,
163542 /* 1100 */ 258, 446, 15, 15, 43, 43, 559, 1011, 1011, 1013,
163543 /* 1110 */ 439, 328, 405, 523, 12, 291, 123, 124, 114, 1209,
163544 /* 1120 */ 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122,
163545 /* 1130 */ 122, 343, 405, 858, 1524, 1205, 123, 124, 114, 1209,
163546 /* 1140 */ 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122,
163547 /* 1150 */ 122, 1129, 1631, 470, 1631, 367, 123, 111, 114, 1209,
163548 /* 1160 */ 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122,
163549 /* 1170 */ 122, 1485, 325, 470, 327, 120, 120, 120, 120, 119,
163550 /* 1180 */ 119, 118, 118, 118, 117, 113, 440, 199, 1411, 562,
163551 /* 1190 */ 1286, 858, 460, 1205, 432, 120, 120, 120, 120, 119,
163552 /* 1200 */ 119, 118, 118, 118, 117, 113, 440, 547, 1129, 1632,
163553 /* 1210 */ 535, 1632, 57, 57, 886, 120, 120, 120, 120, 119,
163554 /* 1220 */ 119, 118, 118, 118, 117, 113, 440, 562, 294, 534,
163555 /* 1230 */ 1127, 1411, 1549, 1550, 1323, 405, 6, 6, 1161, 1260,
163556 /* 1240 */ 411, 316, 280, 280, 1411, 504, 559, 521, 296, 453,
163557 /* 1250 */ 44, 44, 562, 887, 12, 559, 326, 474, 421, 403,
163558 /* 1260 */ 124, 114, 1209, 1209, 1042, 1045, 1034, 1034, 121, 121,
163559 /* 1270 */ 122, 122, 122, 122, 562, 58, 58, 284, 1184, 1411,
163560 /* 1280 */ 492, 454, 388, 388, 387, 269, 385, 1127, 1548, 843,
163561 /* 1290 */ 1161, 403, 6, 562, 317, 1150, 466, 59, 59, 1547,
163562 /* 1300 */ 1106, 422, 230, 6, 319, 252, 536, 252, 1150, 427,
163563 /* 1310 */ 562, 1150, 318, 17, 483, 1107, 60, 60, 120, 120,
163564 /* 1320 */ 120, 120, 119, 119, 118, 118, 118, 117, 113, 440,
163565 /* 1330 */ 1108, 212, 477, 61, 61, 1184, 1185, 1186, 108, 554,
163566 /* 1340 */ 320, 4, 232, 452, 522, 562, 233, 452, 562, 433,
163567 /* 1350 */ 164, 550, 416, 137, 475, 557, 562, 289, 562, 1087,
163568 /* 1360 */ 562, 289, 562, 1087, 527, 562, 866, 8, 62, 62,
163569 /* 1370 */ 231, 45, 45, 562, 410, 562, 410, 562, 441, 46,
163570 /* 1380 */ 46, 47, 47, 49, 49, 50, 50, 195, 63, 63,
163571 /* 1390 */ 551, 562, 355, 562, 98, 482, 64, 64, 65, 65,
163572 /* 1400 */ 14, 14, 555, 411, 531, 406, 562, 1021, 562, 530,
163573 /* 1410 */ 312, 553, 312, 553, 66, 66, 129, 129, 562, 1021,
163574 /* 1420 */ 562, 508, 926, 866, 1012, 106, 106, 925, 1011, 67,
163575 /* 1430 */ 67, 52, 52, 107, 447, 441, 564, 563, 412, 173,
163576 /* 1440 */ 1011, 68, 68, 69, 69, 562, 463, 562, 926, 467,
163577 /* 1450 */ 1356, 279, 222, 925, 311, 1355, 403, 562, 455, 403,
163578 /* 1460 */ 1011, 1011, 1013, 235, 403, 84, 209, 1342, 53, 53,
163579 /* 1470 */ 159, 159, 1011, 1011, 1013, 1014, 27, 1575, 1172, 443,
163580 /* 1480 */ 160, 160, 284, 95, 105, 1531, 103, 388, 388, 387,
163581 /* 1490 */ 269, 385, 562, 873, 843, 877, 562, 108, 554, 462,
163582 /* 1500 */ 4, 562, 148, 30, 38, 562, 1124, 230, 392, 319,
163583 /* 1510 */ 108, 554, 523, 4, 557, 76, 76, 318, 562, 54,
163584 /* 1520 */ 54, 562, 333, 464, 72, 72, 329, 557, 130, 130,
163585 /* 1530 */ 562, 285, 1504, 562, 31, 1503, 562, 441, 334, 479,
163586 /* 1540 */ 98, 73, 73, 340, 157, 157, 292, 232, 1072, 551,
163587 /* 1550 */ 441, 873, 1352, 131, 131, 164, 132, 132, 137, 128,
163588 /* 1560 */ 128, 1564, 551, 531, 562, 315, 562, 344, 532, 1003,
163589 /* 1570 */ 469, 257, 257, 885, 884, 231, 531, 562, 1021, 562,
163590 /* 1580 */ 471, 530, 257, 363, 106, 106, 517, 158, 158, 152,
163591 /* 1590 */ 152, 1021, 107, 362, 441, 564, 563, 106, 106, 1011,
163592 /* 1600 */ 136, 136, 135, 135, 562, 107, 1072, 441, 564, 563,
163593 /* 1610 */ 406, 347, 1011, 562, 349, 312, 553, 562, 339, 562,
163594 /* 1620 */ 98, 493, 353, 254, 98, 892, 893, 133, 133, 351,
163595 /* 1630 */ 1302, 1011, 1011, 1013, 1014, 27, 134, 134, 1015, 447,
163596 /* 1640 */ 75, 75, 77, 77, 1011, 1011, 1013, 1014, 27, 1172,
163597 /* 1650 */ 443, 562, 358, 284, 108, 554, 368, 4, 388, 388,
163598 /* 1660 */ 387, 269, 385, 562, 1133, 843, 562, 1068, 956, 254,
163599 /* 1670 */ 257, 557, 968, 969, 74, 74, 549, 923, 230, 110,
163600 /* 1680 */ 319, 108, 554, 1084, 4, 1084, 42, 42, 318, 48,
163601 /* 1690 */ 48, 1083, 1365, 1083, 441, 856, 1015, 146, 557, 924,
163602 /* 1700 */ 1410, 110, 1338, 1350, 548, 1416, 551, 1267, 207, 1258,
163603 /* 1710 */ 1246, 1245, 1247, 1583, 11, 488, 272, 215, 232, 1335,
163604 /* 1720 */ 304, 441, 305, 306, 389, 228, 164, 1397, 1392, 137,
163605 /* 1730 */ 287, 331, 332, 551, 293, 1021, 1385, 337, 473, 200,
163606 /* 1740 */ 361, 106, 106, 930, 498, 1402, 231, 1401, 1285, 107,
163607 /* 1750 */ 396, 441, 564, 563, 219, 1476, 1011, 1347, 1475, 1348,
163608 /* 1760 */ 1346, 1345, 1021, 1224, 552, 1586, 261, 1221, 106, 106,
163609 /* 1770 */ 1523, 201, 383, 1521, 214, 414, 107, 83, 441, 564,
163610 /* 1780 */ 563, 406, 211, 1011, 175, 1398, 312, 553, 1011, 1011,
163611 /* 1790 */ 1013, 1014, 27, 226, 184, 169, 100, 554, 79, 4,
163612 /* 1800 */ 82, 457, 35, 179, 458, 177, 491, 238, 96, 1481,
163613 /* 1810 */ 447, 180, 1404, 557, 181, 1011, 1011, 1013, 1014, 27,
163614 /* 1820 */ 182, 1403, 394, 36, 465, 1406, 397, 188, 1470, 480,
163615 /* 1830 */ 242, 89, 1492, 486, 342, 244, 441, 273, 192, 346,
163616 /* 1840 */ 489, 245, 399, 1248, 428, 246, 507, 1296, 551, 91,
163617 /* 1850 */ 877, 1305, 1304, 220, 1601, 1295, 1303, 430, 431, 516,
163618 /* 1860 */ 1569, 259, 400, 302, 1600, 1275, 303, 260, 360, 1274,
163619 /* 1870 */ 1273, 1599, 366, 1555, 434, 1554, 1370, 1021, 1369, 542,
163620 /* 1880 */ 126, 10, 1456, 106, 106, 377, 102, 97, 310, 526,
163621 /* 1890 */ 34, 107, 566, 441, 564, 563, 1178, 271, 1011, 268,
163622 /* 1900 */ 270, 567, 1243, 1238, 206, 1328, 375, 381, 1327, 382,
163623 /* 1910 */ 407, 161, 174, 408, 1508, 1509, 143, 300, 830, 162,
163624 /* 1920 */ 1507, 1506, 163, 442, 208, 314, 227, 216, 217, 78,
163625 /* 1930 */ 1011, 1011, 1013, 1014, 27, 140, 1082, 322, 1080, 165,
163626 /* 1940 */ 176, 1204, 234, 178, 909, 330, 237, 1096, 183, 166,
163627 /* 1950 */ 167, 417, 85, 86, 419, 185, 87, 88, 168, 1099,
163628 /* 1960 */ 239, 1095, 240, 154, 18, 241, 341, 1218, 257, 1088,
163629 /* 1970 */ 243, 485, 190, 189, 37, 845, 490, 362, 247, 494,
163630 /* 1980 */ 357, 191, 875, 90, 19, 502, 354, 20, 499, 92,
163631 /* 1990 */ 170, 155, 888, 93, 301, 509, 94, 1166, 156, 1048,
163632 /* 2000 */ 1135, 39, 221, 1134, 276, 278, 256, 194, 110, 960,
163633 /* 2010 */ 954, 1156, 21, 1152, 22, 1160, 1140, 1154, 23, 33,
163634 /* 2020 */ 24, 1159, 25, 538, 26, 198, 98, 1063, 1049, 1047,
163635 /* 2030 */ 1051, 7, 1105, 262, 1104, 263, 1052, 28, 40, 558,
163636 /* 2040 */ 1016, 857, 109, 29, 919, 386, 139, 172, 264, 265,
163637 /* 2050 */ 1174, 1592, 1173, 1234, 1234, 1234, 1234, 1234, 1234, 1234,
163638 /* 2060 */ 1234, 1234, 1234, 1591,
163639 };
163640 static const YYCODETYPE yy_lookahead[] = {
163641 /* 0 */ 193, 193, 193, 274, 275, 276, 193, 274, 275, 276,
163642 /* 10 */ 193, 223, 219, 225, 206, 210, 211, 212, 193, 19,
163643 /* 20 */ 219, 233, 216, 216, 217, 216, 217, 193, 295, 216,
163644 /* 30 */ 217, 31, 193, 216, 217, 193, 228, 213, 230, 39,
163645 /* 40 */ 206, 216, 217, 43, 44, 45, 46, 47, 48, 49,
163646 /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 193, 19,
163647 /* 60 */ 185, 186, 187, 188, 189, 190, 253, 274, 275, 276,
163648 /* 70 */ 195, 193, 197, 193, 261, 274, 275, 276, 253, 204,
163649 /* 80 */ 238, 204, 81, 43, 44, 45, 46, 47, 48, 49,
163650 /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 274, 275,
163651 /* 100 */ 276, 262, 102, 103, 104, 105, 106, 107, 108, 109,
163652 /* 110 */ 110, 111, 112, 113, 239, 240, 239, 240, 210, 211,
163653 /* 120 */ 212, 314, 315, 314, 59, 316, 86, 252, 88, 252,
163654 /* 130 */ 19, 314, 315, 256, 257, 113, 25, 72, 296, 138,
163655 /* 140 */ 139, 266, 102, 103, 104, 105, 106, 107, 108, 109,
163656 /* 150 */ 110, 111, 112, 113, 43, 44, 45, 46, 47, 48,
163657 /* 160 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 81,
163658 /* 170 */ 292, 59, 292, 298, 108, 109, 110, 111, 112, 113,
163659 /* 180 */ 69, 116, 117, 118, 72, 106, 107, 193, 111, 112,
163660 /* 190 */ 113, 54, 55, 56, 57, 58, 102, 103, 104, 105,
163661 /* 200 */ 106, 107, 108, 109, 110, 111, 112, 113, 120, 25,
163662 /* 210 */ 216, 217, 145, 102, 103, 104, 105, 106, 107, 108,
163663 /* 220 */ 109, 110, 111, 112, 113, 231, 138, 139, 116, 117,
163664 /* 230 */ 118, 164, 153, 19, 155, 54, 55, 56, 57, 102,
163665 /* 240 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
163666 /* 250 */ 113, 128, 129, 46, 47, 48, 49, 43, 44, 45,
163667 /* 260 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
163668 /* 270 */ 56, 57, 216, 193, 25, 59, 193, 19, 165, 166,
163669 /* 280 */ 193, 67, 24, 102, 103, 104, 105, 106, 107, 108,
163670 /* 290 */ 109, 110, 111, 112, 113, 73, 216, 217, 59, 216,
163671 /* 300 */ 217, 43, 44, 45, 46, 47, 48, 49, 50, 51,
163672 /* 310 */ 52, 53, 54, 55, 56, 57, 102, 103, 104, 105,
163673 /* 320 */ 106, 107, 108, 109, 110, 111, 112, 113, 121, 145,
163674 /* 330 */ 59, 193, 116, 117, 118, 119, 273, 204, 122, 123,
163675 /* 340 */ 124, 19, 20, 134, 22, 136, 137, 19, 132, 127,
163676 /* 350 */ 128, 129, 24, 22, 23, 116, 117, 118, 36, 193,
163677 /* 360 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
163678 /* 370 */ 112, 113, 239, 240, 311, 312, 215, 106, 107, 241,
163679 /* 380 */ 19, 59, 216, 217, 223, 252, 115, 116, 117, 118,
163680 /* 390 */ 151, 120, 26, 71, 193, 308, 309, 193, 149, 128,
163681 /* 400 */ 313, 216, 269, 81, 43, 44, 45, 46, 47, 48,
163682 /* 410 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 253,
163683 /* 420 */ 216, 217, 100, 95, 153, 59, 155, 261, 106, 107,
163684 /* 430 */ 25, 193, 101, 193, 193, 231, 114, 25, 116, 117,
163685 /* 440 */ 118, 113, 304, 121, 193, 204, 59, 119, 120, 121,
163686 /* 450 */ 122, 123, 124, 125, 216, 217, 193, 216, 217, 131,
163687 /* 460 */ 138, 139, 230, 102, 103, 104, 105, 106, 107, 108,
163688 /* 470 */ 109, 110, 111, 112, 113, 153, 154, 155, 156, 157,
163689 /* 480 */ 239, 240, 116, 117, 118, 76, 193, 23, 19, 25,
163690 /* 490 */ 22, 253, 23, 252, 253, 108, 87, 204, 89, 261,
163691 /* 500 */ 198, 92, 261, 116, 117, 118, 193, 306, 307, 216,
163692 /* 510 */ 217, 150, 43, 44, 45, 46, 47, 48, 49, 50,
163693 /* 520 */ 51, 52, 53, 54, 55, 56, 57, 59, 193, 216,
163694 /* 530 */ 217, 19, 239, 240, 283, 23, 106, 107, 108, 109,
163695 /* 540 */ 110, 111, 112, 113, 73, 252, 253, 142, 308, 309,
163696 /* 550 */ 138, 139, 81, 313, 145, 43, 44, 45, 46, 47,
163697 /* 560 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
163698 /* 570 */ 307, 102, 103, 104, 105, 106, 107, 108, 109, 110,
163699 /* 580 */ 111, 112, 113, 281, 116, 117, 118, 285, 23, 193,
163700 /* 590 */ 25, 119, 59, 193, 122, 123, 124, 59, 127, 203,
163701 /* 600 */ 59, 205, 19, 268, 132, 25, 23, 22, 193, 138,
163702 /* 610 */ 139, 249, 204, 251, 102, 103, 104, 105, 106, 107,
163703 /* 620 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46,
163704 /* 630 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
163705 /* 640 */ 57, 19, 22, 23, 59, 23, 25, 239, 240, 116,
163706 /* 650 */ 117, 118, 193, 11, 116, 117, 118, 116, 117, 118,
163707 /* 660 */ 252, 269, 22, 193, 15, 43, 44, 45, 46, 47,
163708 /* 670 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
163709 /* 680 */ 273, 143, 193, 118, 143, 102, 103, 104, 105, 106,
163710 /* 690 */ 107, 108, 109, 110, 111, 112, 113, 76, 118, 59,
163711 /* 700 */ 241, 116, 117, 118, 304, 216, 217, 292, 143, 60,
163712 /* 710 */ 89, 241, 19, 92, 193, 193, 23, 22, 311, 312,
163713 /* 720 */ 231, 101, 22, 143, 102, 103, 104, 105, 106, 107,
163714 /* 730 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46,
163715 /* 740 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
163716 /* 750 */ 57, 19, 193, 193, 59, 23, 116, 117, 118, 59,
163717 /* 760 */ 201, 21, 241, 304, 22, 206, 127, 128, 129, 193,
163718 /* 770 */ 128, 129, 235, 236, 304, 43, 44, 45, 46, 47,
163719 /* 780 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
163720 /* 790 */ 22, 193, 216, 217, 193, 102, 103, 104, 105, 106,
163721 /* 800 */ 107, 108, 109, 110, 111, 112, 113, 231, 193, 193,
163722 /* 810 */ 193, 116, 117, 118, 216, 217, 116, 117, 118, 226,
163723 /* 820 */ 80, 193, 19, 235, 236, 304, 23, 211, 212, 231,
163724 /* 830 */ 204, 216, 217, 205, 102, 103, 104, 105, 106, 107,
163725 /* 840 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46,
163726 /* 850 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
163727 /* 860 */ 57, 19, 193, 123, 76, 239, 240, 193, 253, 239,
163728 /* 870 */ 240, 239, 240, 193, 106, 107, 193, 89, 252, 193,
163729 /* 880 */ 92, 59, 252, 141, 252, 43, 44, 45, 46, 47,
163730 /* 890 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
163731 /* 900 */ 284, 161, 216, 217, 193, 102, 103, 104, 105, 106,
163732 /* 910 */ 107, 108, 109, 110, 111, 112, 113, 231, 193, 16,
163733 /* 920 */ 187, 188, 189, 190, 7, 8, 9, 309, 195, 25,
163734 /* 930 */ 197, 313, 19, 127, 128, 129, 262, 204, 22, 117,
163735 /* 940 */ 24, 216, 217, 263, 102, 103, 104, 105, 106, 107,
163736 /* 950 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46,
163737 /* 960 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
163738 /* 970 */ 57, 193, 239, 240, 193, 59, 19, 188, 253, 190,
163739 /* 980 */ 77, 226, 79, 193, 195, 252, 197, 193, 19, 301,
163740 /* 990 */ 302, 193, 193, 204, 216, 217, 226, 216, 217, 266,
163741 /* 1000 */ 204, 159, 45, 46, 47, 48, 49, 50, 51, 52,
163742 /* 1010 */ 53, 54, 55, 56, 57, 102, 103, 104, 105, 106,
163743 /* 1020 */ 107, 108, 109, 110, 111, 112, 113, 12, 239, 240,
163744 /* 1030 */ 232, 298, 238, 117, 253, 239, 240, 238, 259, 260,
163745 /* 1040 */ 193, 252, 27, 31, 193, 193, 142, 204, 252, 193,
163746 /* 1050 */ 193, 39, 262, 193, 100, 266, 278, 42, 204, 102,
163747 /* 1060 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
163748 /* 1070 */ 113, 117, 159, 216, 217, 121, 216, 217, 63, 193,
163749 /* 1080 */ 193, 193, 239, 240, 115, 116, 193, 298, 73, 238,
163750 /* 1090 */ 238, 231, 19, 239, 240, 252, 22, 24, 211, 212,
163751 /* 1100 */ 24, 193, 216, 217, 216, 217, 252, 153, 154, 155,
163752 /* 1110 */ 253, 16, 19, 144, 213, 268, 43, 44, 45, 46,
163753 /* 1120 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
163754 /* 1130 */ 57, 238, 19, 59, 193, 59, 43, 44, 45, 46,
163755 /* 1140 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
163756 /* 1150 */ 57, 22, 23, 193, 25, 193, 43, 44, 45, 46,
163757 /* 1160 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
163758 /* 1170 */ 57, 284, 77, 193, 79, 102, 103, 104, 105, 106,
163759 /* 1180 */ 107, 108, 109, 110, 111, 112, 113, 286, 193, 193,
163760 /* 1190 */ 193, 117, 291, 117, 232, 102, 103, 104, 105, 106,
163761 /* 1200 */ 107, 108, 109, 110, 111, 112, 113, 204, 22, 23,
163762 /* 1210 */ 66, 25, 216, 217, 35, 102, 103, 104, 105, 106,
163763 /* 1220 */ 107, 108, 109, 110, 111, 112, 113, 193, 268, 85,
163764 /* 1230 */ 101, 193, 309, 309, 240, 19, 313, 313, 94, 208,
163765 /* 1240 */ 209, 193, 239, 240, 193, 66, 252, 19, 268, 244,
163766 /* 1250 */ 216, 217, 193, 74, 213, 252, 161, 19, 263, 254,
163767 /* 1260 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
163768 /* 1270 */ 54, 55, 56, 57, 193, 216, 217, 5, 59, 193,
163769 /* 1280 */ 19, 244, 10, 11, 12, 13, 14, 101, 309, 17,
163770 /* 1290 */ 146, 254, 313, 193, 193, 76, 115, 216, 217, 309,
163771 /* 1300 */ 12, 263, 30, 313, 32, 46, 87, 46, 89, 130,
163772 /* 1310 */ 193, 92, 40, 22, 263, 27, 216, 217, 102, 103,
163773 /* 1320 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
163774 /* 1330 */ 42, 150, 291, 216, 217, 116, 117, 118, 19, 20,
163775 /* 1340 */ 193, 22, 70, 260, 116, 193, 24, 264, 193, 263,
163776 /* 1350 */ 78, 63, 61, 81, 116, 36, 193, 260, 193, 29,
163777 /* 1360 */ 193, 264, 193, 33, 145, 193, 59, 48, 216, 217,
163778 /* 1370 */ 98, 216, 217, 193, 115, 193, 115, 193, 59, 216,
163779 /* 1380 */ 217, 216, 217, 216, 217, 216, 217, 255, 216, 217,
163780 /* 1390 */ 71, 193, 131, 193, 25, 65, 216, 217, 216, 217,
163781 /* 1400 */ 216, 217, 208, 209, 85, 133, 193, 100, 193, 90,
163782 /* 1410 */ 138, 139, 138, 139, 216, 217, 216, 217, 193, 100,
163783 /* 1420 */ 193, 108, 135, 116, 117, 106, 107, 140, 121, 216,
163784 /* 1430 */ 217, 216, 217, 114, 162, 116, 117, 118, 299, 300,
163785 /* 1440 */ 121, 216, 217, 216, 217, 193, 244, 193, 135, 244,
163786 /* 1450 */ 193, 256, 257, 140, 244, 193, 254, 193, 193, 254,
163787 /* 1460 */ 153, 154, 155, 141, 254, 149, 150, 258, 216, 217,
163788 /* 1470 */ 216, 217, 153, 154, 155, 156, 157, 0, 1, 2,
163789 /* 1480 */ 216, 217, 5, 115, 158, 193, 160, 10, 11, 12,
163790 /* 1490 */ 13, 14, 193, 59, 17, 126, 193, 19, 20, 129,
163791 /* 1500 */ 22, 193, 22, 22, 24, 193, 23, 30, 25, 32,
163792 /* 1510 */ 19, 20, 144, 22, 36, 216, 217, 40, 193, 216,
163793 /* 1520 */ 217, 193, 152, 129, 216, 217, 193, 36, 216, 217,
163794 /* 1530 */ 193, 99, 193, 193, 53, 193, 193, 59, 23, 193,
163795 /* 1540 */ 25, 216, 217, 193, 216, 217, 152, 70, 59, 71,
163796 /* 1550 */ 59, 117, 193, 216, 217, 78, 216, 217, 81, 216,
163797 /* 1560 */ 217, 318, 71, 85, 193, 133, 193, 193, 90, 23,
163798 /* 1570 */ 23, 25, 25, 120, 121, 98, 85, 193, 100, 193,
163799 /* 1580 */ 23, 90, 25, 121, 106, 107, 19, 216, 217, 216,
163800 /* 1590 */ 217, 100, 114, 131, 116, 117, 118, 106, 107, 121,
163801 /* 1600 */ 216, 217, 216, 217, 193, 114, 117, 116, 117, 118,
163802 /* 1610 */ 133, 193, 121, 193, 193, 138, 139, 193, 23, 193,
163803 /* 1620 */ 25, 23, 23, 25, 25, 7, 8, 216, 217, 193,
163804 /* 1630 */ 193, 153, 154, 155, 156, 157, 216, 217, 59, 162,
163805 /* 1640 */ 216, 217, 216, 217, 153, 154, 155, 156, 157, 1,
163806 /* 1650 */ 2, 193, 193, 5, 19, 20, 193, 22, 10, 11,
163807 /* 1660 */ 12, 13, 14, 193, 97, 17, 193, 23, 23, 25,
163808 /* 1670 */ 25, 36, 83, 84, 216, 217, 236, 23, 30, 25,
163809 /* 1680 */ 32, 19, 20, 153, 22, 155, 216, 217, 40, 216,
163810 /* 1690 */ 217, 153, 193, 155, 59, 23, 117, 25, 36, 23,
163811 /* 1700 */ 193, 25, 193, 193, 193, 193, 71, 193, 242, 193,
163812 /* 1710 */ 193, 193, 193, 193, 243, 288, 287, 214, 70, 255,
163813 /* 1720 */ 255, 59, 255, 255, 191, 297, 78, 271, 267, 81,
163814 /* 1730 */ 245, 293, 246, 71, 246, 100, 267, 245, 293, 249,
163815 /* 1740 */ 219, 106, 107, 108, 220, 271, 98, 271, 225, 114,
163816 /* 1750 */ 271, 116, 117, 118, 229, 219, 121, 259, 219, 259,
163817 /* 1760 */ 259, 259, 100, 60, 280, 196, 141, 38, 106, 107,
163818 /* 1770 */ 200, 249, 245, 200, 243, 200, 114, 151, 116, 117,
163819 /* 1780 */ 118, 133, 150, 121, 297, 272, 138, 139, 153, 154,
163820 /* 1790 */ 155, 156, 157, 297, 22, 43, 19, 20, 294, 22,
163821 /* 1800 */ 294, 18, 270, 237, 200, 234, 18, 199, 149, 283,
163822 /* 1810 */ 162, 237, 272, 36, 237, 153, 154, 155, 156, 157,
163823 /* 1820 */ 237, 272, 246, 270, 246, 234, 246, 234, 246, 200,
163824 /* 1830 */ 199, 158, 290, 62, 289, 199, 59, 200, 22, 200,
163825 /* 1840 */ 221, 199, 221, 200, 64, 199, 115, 227, 71, 22,
163826 /* 1850 */ 126, 218, 218, 165, 224, 227, 218, 24, 113, 305,
163827 /* 1860 */ 312, 200, 221, 282, 224, 218, 282, 91, 218, 220,
163828 /* 1870 */ 218, 218, 221, 317, 82, 317, 265, 100, 265, 145,
163829 /* 1880 */ 148, 22, 277, 106, 107, 200, 158, 147, 279, 146,
163830 /* 1890 */ 25, 114, 202, 116, 117, 118, 13, 6, 121, 194,
163831 /* 1900 */ 194, 192, 192, 192, 248, 250, 249, 247, 250, 246,
163832 /* 1910 */ 303, 207, 300, 303, 213, 213, 222, 222, 4, 207,
163833 /* 1920 */ 213, 213, 207, 3, 22, 163, 15, 214, 214, 213,
163834 /* 1930 */ 153, 154, 155, 156, 157, 16, 23, 139, 23, 130,
163835 /* 1940 */ 151, 25, 24, 142, 20, 16, 144, 1, 142, 130,
163836 /* 1950 */ 130, 61, 53, 53, 37, 151, 53, 53, 130, 116,
163837 /* 1960 */ 34, 1, 141, 5, 22, 115, 161, 75, 25, 68,
163838 /* 1970 */ 141, 41, 115, 68, 24, 20, 19, 131, 125, 67,
163839 /* 1980 */ 24, 22, 59, 22, 22, 96, 23, 22, 67, 22,
163840 /* 1990 */ 37, 23, 28, 149, 67, 22, 25, 23, 23, 23,
163841 /* 2000 */ 23, 22, 141, 97, 23, 23, 34, 22, 25, 116,
163842 /* 2010 */ 143, 75, 34, 88, 34, 75, 23, 86, 34, 22,
163843 /* 2020 */ 34, 93, 34, 24, 34, 25, 25, 23, 23, 23,
163844 /* 2030 */ 23, 44, 23, 25, 23, 22, 11, 22, 22, 25,
163845 /* 2040 */ 23, 23, 22, 22, 135, 15, 23, 25, 141, 141,
163846 /* 2050 */ 1, 141, 1, 319, 319, 319, 319, 319, 319, 319,
163847 /* 2060 */ 319, 319, 319, 141, 319, 319, 319, 319, 319, 319,
163848 /* 2070 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
163849 /* 2080 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
163850 /* 2090 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
163851 /* 2100 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
163852 /* 2110 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
@@ -162690,181 +163860,178 @@
163860 /* 2190 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
163861 /* 2200 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
163862 /* 2210 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
163863 /* 2220 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
163864 /* 2230 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
163865 /* 2240 */ 319, 319, 319, 319, 319, 319, 319, 319, 319,
 
163866 };
163867 #define YY_SHIFT_COUNT (569)
163868 #define YY_SHIFT_MIN (0)
163869 #define YY_SHIFT_MAX (2051)
163870 static const unsigned short int yy_shift_ofst[] = {
163871 /* 0 */ 1648, 1477, 1272, 322, 322, 1, 1319, 1478, 1491, 1662,
163872 /* 10 */ 1662, 1662, 471, 0, 0, 214, 1093, 1662, 1662, 1662,
163873 /* 20 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
163874 /* 30 */ 271, 271, 1219, 1219, 216, 88, 1, 1, 1, 1,
163875 /* 40 */ 1, 40, 111, 258, 361, 469, 512, 583, 622, 693,
163876 /* 50 */ 732, 803, 842, 913, 1073, 1093, 1093, 1093, 1093, 1093,
163877 /* 60 */ 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093,
163878 /* 70 */ 1093, 1093, 1093, 1113, 1093, 1216, 957, 957, 1635, 1662,
163879 /* 80 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
163880 /* 90 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
163881 /* 100 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
163882 /* 110 */ 1662, 1662, 1662, 1662, 1777, 1662, 1662, 1662, 1662, 1662,
163883 /* 120 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 137, 181,
163884 /* 130 */ 181, 181, 181, 181, 94, 430, 66, 65, 112, 366,
163885 /* 140 */ 533, 533, 740, 1261, 533, 533, 79, 79, 533, 412,
163886 /* 150 */ 412, 412, 77, 412, 123, 113, 113, 22, 22, 2064,
163887 /* 160 */ 2064, 328, 328, 328, 239, 468, 468, 468, 468, 1015,
163888 /* 170 */ 1015, 409, 366, 1129, 1186, 533, 533, 533, 533, 533,
163889 /* 180 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 533,
163890 /* 190 */ 533, 533, 533, 533, 533, 969, 621, 621, 533, 642,
163891 /* 200 */ 788, 788, 1228, 1228, 822, 822, 67, 1274, 2064, 2064,
163892 /* 210 */ 2064, 2064, 2064, 2064, 2064, 1307, 954, 954, 585, 472,
163893 /* 220 */ 640, 387, 695, 538, 541, 700, 533, 533, 533, 533,
163894 /* 230 */ 533, 533, 533, 533, 533, 533, 222, 533, 533, 533,
163895 /* 240 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 1179,
163896 /* 250 */ 1179, 1179, 533, 533, 533, 565, 533, 533, 533, 916,
163897 /* 260 */ 1144, 533, 533, 1288, 533, 533, 533, 533, 533, 533,
163898 /* 270 */ 533, 533, 639, 1330, 209, 1076, 1076, 1076, 1076, 580,
163899 /* 280 */ 209, 209, 1313, 768, 917, 649, 1181, 1316, 405, 1316,
163900 /* 290 */ 1238, 249, 1181, 1181, 249, 1181, 405, 1238, 1369, 464,
163901 /* 300 */ 1259, 1012, 1012, 1012, 1368, 1368, 1368, 1368, 184, 184,
163902 /* 310 */ 1326, 904, 1287, 1480, 1703, 1703, 1625, 1625, 1729, 1729,
163903 /* 320 */ 1625, 1626, 1632, 1772, 1752, 1783, 1783, 1783, 1783, 1625,
163904 /* 330 */ 1788, 1659, 1632, 1632, 1659, 1772, 1752, 1659, 1752, 1659,
163905 /* 340 */ 1625, 1788, 1673, 1771, 1625, 1788, 1816, 1625, 1788, 1625,
163906 /* 350 */ 1788, 1816, 1731, 1731, 1731, 1780, 1827, 1827, 1816, 1731,
163907 /* 360 */ 1724, 1731, 1780, 1731, 1731, 1688, 1833, 1745, 1745, 1816,
163908 /* 370 */ 1625, 1776, 1776, 1792, 1792, 1732, 1734, 1859, 1625, 1728,
163909 /* 380 */ 1732, 1740, 1743, 1659, 1865, 1883, 1883, 1891, 1891, 1891,
163910 /* 390 */ 2064, 2064, 2064, 2064, 2064, 2064, 2064, 2064, 2064, 2064,
163911 /* 400 */ 2064, 2064, 2064, 2064, 2064, 207, 1095, 331, 620, 903,
163912 /* 410 */ 806, 1074, 1483, 1432, 1481, 1322, 1370, 1394, 1515, 1291,
163913 /* 420 */ 1546, 1547, 1557, 1595, 1598, 1599, 1434, 1453, 1618, 1462,
163914 /* 430 */ 1567, 1489, 1644, 1645, 1589, 1654, 1530, 1538, 1672, 1676,
163915 /* 440 */ 1579, 742, 1914, 1920, 1902, 1762, 1911, 1919, 1913, 1915,
163916 /* 450 */ 1798, 1789, 1809, 1916, 1916, 1918, 1801, 1924, 1802, 1929,
163917 /* 460 */ 1946, 1806, 1819, 1916, 1820, 1890, 1917, 1916, 1804, 1899,
163918 /* 470 */ 1900, 1903, 1904, 1828, 1843, 1926, 1821, 1960, 1958, 1942,
163919 /* 480 */ 1850, 1805, 1901, 1943, 1905, 1892, 1930, 1829, 1857, 1950,
163920 /* 490 */ 1955, 1957, 1846, 1853, 1959, 1912, 1961, 1962, 1963, 1965,
163921 /* 500 */ 1921, 1923, 1956, 1889, 1964, 1967, 1927, 1953, 1968, 1844,
163922 /* 510 */ 1973, 1974, 1975, 1976, 1971, 1977, 1979, 1906, 1861, 1981,
163923 /* 520 */ 1982, 1893, 1972, 1985, 1867, 1983, 1978, 1980, 1984, 1986,
163924 /* 530 */ 1925, 1936, 1931, 1987, 1940, 1928, 1988, 1993, 1997, 1999,
163925 /* 540 */ 2000, 2001, 1990, 2004, 1983, 2005, 2006, 2007, 2009, 2008,
163926 /* 550 */ 2011, 2013, 2025, 2015, 2016, 2017, 2018, 2020, 2021, 2014,
163927 /* 560 */ 1909, 1907, 1908, 1910, 1922, 2022, 2023, 2030, 2049, 2051,
 
163928 };
163929 #define YY_REDUCE_COUNT (404)
163930 #define YY_REDUCE_MIN (-271)
163931 #define YY_REDUCE_MAX (1716)
163932 static const short yy_reduce_ofst[] = {
163933 /* 0 */ -125, 733, 789, 241, 293, -123, -193, -191, -183, -187,
163934 /* 10 */ 166, 238, 133, -207, -199, -267, -176, -6, 204, 489,
163935 /* 20 */ 576, -175, 598, 686, 615, 725, 860, 778, 781, 857,
163936 /* 30 */ 616, 887, 87, 240, -192, 408, 626, 796, 843, 854,
163937 /* 40 */ 1003, -271, -271, -271, -271, -271, -271, -271, -271, -271,
163938 /* 50 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, -271,
163939 /* 60 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, -271,
163940 /* 70 */ -271, -271, -271, -271, -271, -271, -271, -271, 80, 83,
163941 /* 80 */ 313, 886, 888, 996, 1034, 1059, 1081, 1100, 1117, 1152,
163942 /* 90 */ 1155, 1163, 1165, 1167, 1169, 1172, 1180, 1182, 1184, 1198,
163943 /* 100 */ 1200, 1213, 1215, 1225, 1227, 1252, 1254, 1264, 1299, 1303,
163944 /* 110 */ 1308, 1312, 1325, 1328, 1337, 1340, 1343, 1371, 1373, 1384,
163945 /* 120 */ 1386, 1411, 1420, 1424, 1426, 1458, 1470, 1473, -271, -271,
163946 /* 130 */ -271, -271, -271, -271, -271, -271, -271, 138, 459, 396,
163947 /* 140 */ -158, 470, 302, -212, 521, 201, -195, -92, 559, 630,
163948 /* 150 */ 632, 630, -271, 632, 901, 63, 407, -271, -271, -271,
163949 /* 160 */ -271, 161, 161, 161, 251, 335, 847, 960, 980, 537,
163950 /* 170 */ 588, 618, 628, 688, 688, -166, -161, 674, 790, 794,
163951 /* 180 */ 799, 851, 852, -122, 680, -120, 995, 1038, 415, 1051,
163952 /* 190 */ 893, 798, 962, 400, 1086, 779, 923, 924, 263, 1041,
163953 /* 200 */ 979, 990, 1083, 1097, 1031, 1194, 362, 994, 1139, 1005,
163954 /* 210 */ 1037, 1202, 1205, 1195, 1210, -194, 56, 185, -135, 232,
163955 /* 220 */ 522, 560, 601, 617, 669, 683, 711, 856, 908, 941,
163956 /* 230 */ 1048, 1101, 1147, 1257, 1262, 1265, 392, 1292, 1333, 1339,
163957 /* 240 */ 1342, 1346, 1350, 1359, 1374, 1418, 1421, 1436, 1437, 593,
163958 /* 250 */ 755, 770, 997, 1459, 1463, 1209, 1499, 1507, 1509, 1132,
163959 /* 260 */ 1243, 1510, 1511, 1440, 1512, 560, 1514, 1516, 1517, 1518,
163960 /* 270 */ 1519, 1520, 1427, 1429, 1466, 1464, 1465, 1467, 1468, 1209,
163961 /* 280 */ 1466, 1466, 1471, 1503, 1533, 1428, 1456, 1461, 1485, 1469,
163962 /* 290 */ 1438, 1486, 1474, 1476, 1488, 1479, 1492, 1445, 1524, 1525,
163963 /* 300 */ 1523, 1521, 1536, 1539, 1498, 1500, 1501, 1502, 1490, 1522,
163964 /* 310 */ 1484, 1527, 1531, 1569, 1487, 1496, 1570, 1573, 1504, 1506,
163965 /* 320 */ 1575, 1526, 1513, 1532, 1571, 1566, 1574, 1577, 1583, 1604,
163966 /* 330 */ 1608, 1576, 1540, 1549, 1578, 1553, 1591, 1580, 1593, 1582,
163967 /* 340 */ 1629, 1631, 1542, 1545, 1637, 1636, 1619, 1639, 1642, 1643,
163968 /* 350 */ 1646, 1621, 1633, 1634, 1638, 1620, 1630, 1640, 1641, 1647,
163969 /* 360 */ 1649, 1650, 1628, 1652, 1653, 1548, 1554, 1581, 1584, 1651,
163970 /* 370 */ 1661, 1556, 1558, 1611, 1613, 1655, 1657, 1605, 1685, 1609,
163971 /* 380 */ 1658, 1656, 1660, 1663, 1690, 1705, 1706, 1709, 1710, 1711,
163972 /* 390 */ 1607, 1610, 1612, 1704, 1701, 1702, 1707, 1708, 1712, 1694,
163973 /* 400 */ 1695, 1713, 1714, 1716, 1715,
163974 };
163975 static const YYACTIONTYPE yy_default[] = {
163976 /* 0 */ 1637, 1637, 1637, 1465, 1232, 1343, 1232, 1232, 1232, 1465,
163977 /* 10 */ 1465, 1465, 1232, 1373, 1373, 1518, 1265, 1232, 1232, 1232,
163978 /* 20 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1464, 1232, 1232,
163979 /* 30 */ 1232, 1232, 1553, 1553, 1232, 1232, 1232, 1232, 1232, 1232,
163980 /* 40 */ 1232, 1232, 1382, 1232, 1389, 1232, 1232, 1232, 1232, 1232,
163981 /* 50 */ 1466, 1467, 1232, 1232, 1232, 1517, 1519, 1482, 1396, 1395,
163982 /* 60 */ 1394, 1393, 1500, 1361, 1387, 1380, 1384, 1460, 1461, 1459,
163983 /* 70 */ 1463, 1467, 1466, 1232, 1383, 1430, 1444, 1429, 1232, 1232,
163984 /* 80 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
163985 /* 90 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
163986 /* 100 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
163987 /* 110 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
163988 /* 120 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1438, 1443,
163989 /* 130 */ 1450, 1442, 1439, 1432, 1431, 1433, 1434, 1232, 1232, 1256,
163990 /* 140 */ 1232, 1232, 1253, 1307, 1232, 1232, 1232, 1232, 1232, 1537,
163991 /* 150 */ 1536, 1232, 1435, 1232, 1265, 1424, 1423, 1447, 1436, 1446,
163992 /* 160 */ 1445, 1525, 1589, 1588, 1483, 1232, 1232, 1232, 1232, 1232,
163993 /* 170 */ 1232, 1553, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
163994 /* 180 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
163995 /* 190 */ 1232, 1232, 1232, 1232, 1232, 1363, 1553, 1553, 1232, 1265,
163996 /* 200 */ 1553, 1553, 1364, 1364, 1261, 1261, 1367, 1232, 1532, 1334,
163997 /* 210 */ 1334, 1334, 1334, 1343, 1334, 1232, 1232, 1232, 1232, 1232,
163998 /* 220 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
163999 /* 230 */ 1522, 1520, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164000 /* 240 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164001 /* 250 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1339,
164002 /* 260 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164003 /* 270 */ 1232, 1582, 1232, 1495, 1321, 1339, 1339, 1339, 1339, 1341,
164004 /* 280 */ 1322, 1320, 1333, 1266, 1239, 1629, 1399, 1388, 1340, 1388,
164005 /* 290 */ 1626, 1386, 1399, 1399, 1386, 1399, 1340, 1626, 1282, 1605,
164006 /* 300 */ 1277, 1373, 1373, 1373, 1363, 1363, 1363, 1363, 1367, 1367,
164007 /* 310 */ 1462, 1340, 1333, 1232, 1629, 1629, 1349, 1349, 1628, 1628,
164008 /* 320 */ 1349, 1483, 1613, 1408, 1310, 1316, 1316, 1316, 1316, 1349,
164009 /* 330 */ 1250, 1386, 1613, 1613, 1386, 1408, 1310, 1386, 1310, 1386,
164010 /* 340 */ 1349, 1250, 1499, 1623, 1349, 1250, 1473, 1349, 1250, 1349,
164011 /* 350 */ 1250, 1473, 1308, 1308, 1308, 1297, 1232, 1232, 1473, 1308,
164012 /* 360 */ 1282, 1308, 1297, 1308, 1308, 1571, 1232, 1477, 1477, 1473,
164013 /* 370 */ 1349, 1563, 1563, 1376, 1376, 1381, 1367, 1468, 1349, 1232,
164014 /* 380 */ 1381, 1379, 1377, 1386, 1300, 1585, 1585, 1581, 1581, 1581,
164015 /* 390 */ 1634, 1634, 1532, 1598, 1265, 1265, 1265, 1265, 1598, 1284,
164016 /* 400 */ 1284, 1266, 1266, 1265, 1598, 1232, 1232, 1232, 1232, 1232,
164017 /* 410 */ 1232, 1593, 1232, 1527, 1484, 1353, 1232, 1232, 1232, 1232,
164018 /* 420 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164019 /* 430 */ 1538, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164020 /* 440 */ 1232, 1413, 1232, 1235, 1529, 1232, 1232, 1232, 1232, 1232,
164021 /* 450 */ 1232, 1232, 1232, 1390, 1391, 1354, 1232, 1232, 1232, 1232,
164022 /* 460 */ 1232, 1232, 1232, 1405, 1232, 1232, 1232, 1400, 1232, 1232,
164023 /* 470 */ 1232, 1232, 1232, 1232, 1232, 1232, 1625, 1232, 1232, 1232,
164024 /* 480 */ 1232, 1232, 1232, 1498, 1497, 1232, 1232, 1351, 1232, 1232,
164025 /* 490 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164026 /* 500 */ 1232, 1280, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164027 /* 510 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164028 /* 520 */ 1232, 1232, 1232, 1232, 1232, 1378, 1232, 1232, 1232, 1232,
164029 /* 530 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164030 /* 540 */ 1568, 1368, 1232, 1232, 1616, 1232, 1232, 1232, 1232, 1232,
164031 /* 550 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1609,
164032 /* 560 */ 1324, 1415, 1232, 1414, 1418, 1254, 1232, 1244, 1232, 1232,
 
164033 };
164034 /********** End of lemon-generated parsing tables *****************************/
164035
164036 /* The next table maps tokens (terminal symbols) into fallback tokens.
164037 ** If a construct like the following:
@@ -163412,16 +164579,16 @@
164579 /* 254 */ "sclp",
164580 /* 255 */ "as",
164581 /* 256 */ "seltablist",
164582 /* 257 */ "stl_prefix",
164583 /* 258 */ "joinop",
164584 /* 259 */ "on_using",
164585 /* 260 */ "indexed_by",
164586 /* 261 */ "exprlist",
164587 /* 262 */ "xfullname",
164588 /* 263 */ "idlist",
164589 /* 264 */ "indexed_opt",
164590 /* 265 */ "nulls",
164591 /* 266 */ "with",
164592 /* 267 */ "where_opt_ret",
164593 /* 268 */ "setlist",
164594 /* 269 */ "insert_cmd",
@@ -163588,33 +164755,33 @@
164755 /* 104 */ "as ::=",
164756 /* 105 */ "from ::=",
164757 /* 106 */ "from ::= FROM seltablist",
164758 /* 107 */ "stl_prefix ::= seltablist joinop",
164759 /* 108 */ "stl_prefix ::=",
164760 /* 109 */ "seltablist ::= stl_prefix nm dbnm as on_using",
164761 /* 110 */ "seltablist ::= stl_prefix nm dbnm as indexed_by on_using",
164762 /* 111 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using",
164763 /* 112 */ "seltablist ::= stl_prefix LP select RP as on_using",
164764 /* 113 */ "seltablist ::= stl_prefix LP seltablist RP as on_using",
164765 /* 114 */ "dbnm ::=",
164766 /* 115 */ "dbnm ::= DOT nm",
164767 /* 116 */ "fullname ::= nm",
164768 /* 117 */ "fullname ::= nm DOT nm",
164769 /* 118 */ "xfullname ::= nm",
164770 /* 119 */ "xfullname ::= nm DOT nm",
164771 /* 120 */ "xfullname ::= nm DOT nm AS nm",
164772 /* 121 */ "xfullname ::= nm AS nm",
164773 /* 122 */ "joinop ::= COMMA|JOIN",
164774 /* 123 */ "joinop ::= JOIN_KW JOIN",
164775 /* 124 */ "joinop ::= JOIN_KW nm JOIN",
164776 /* 125 */ "joinop ::= JOIN_KW nm nm JOIN",
164777 /* 126 */ "on_using ::= ON expr",
164778 /* 127 */ "on_using ::= USING LP idlist RP",
164779 /* 128 */ "on_using ::=",
164780 /* 129 */ "indexed_opt ::=",
164781 /* 130 */ "indexed_by ::= INDEXED BY nm",
164782 /* 131 */ "indexed_by ::= NOT INDEXED",
164783 /* 132 */ "orderby_opt ::=",
164784 /* 133 */ "orderby_opt ::= ORDER BY sortlist",
164785 /* 134 */ "sortlist ::= sortlist COMMA expr sortorder nulls",
164786 /* 135 */ "sortlist ::= expr sortorder nulls",
164787 /* 136 */ "sortorder ::= ASC",
@@ -163856,35 +165023,36 @@
165023 /* 372 */ "resolvetype ::= raisetype",
165024 /* 373 */ "selectnowith ::= oneselect",
165025 /* 374 */ "oneselect ::= values",
165026 /* 375 */ "sclp ::= selcollist COMMA",
165027 /* 376 */ "as ::= ID|STRING",
165028 /* 377 */ "indexed_opt ::= indexed_by",
165029 /* 378 */ "returning ::=",
165030 /* 379 */ "expr ::= term",
165031 /* 380 */ "likeop ::= LIKE_KW|MATCH",
165032 /* 381 */ "exprlist ::= nexprlist",
165033 /* 382 */ "nmnum ::= plus_num",
165034 /* 383 */ "nmnum ::= nm",
165035 /* 384 */ "nmnum ::= ON",
165036 /* 385 */ "nmnum ::= DELETE",
165037 /* 386 */ "nmnum ::= DEFAULT",
165038 /* 387 */ "plus_num ::= INTEGER|FLOAT",
165039 /* 388 */ "foreach_clause ::=",
165040 /* 389 */ "foreach_clause ::= FOR EACH ROW",
165041 /* 390 */ "trnm ::= nm",
165042 /* 391 */ "tridxby ::=",
165043 /* 392 */ "database_kw_opt ::= DATABASE",
165044 /* 393 */ "database_kw_opt ::=",
165045 /* 394 */ "kwcolumn_opt ::=",
165046 /* 395 */ "kwcolumn_opt ::= COLUMNKW",
165047 /* 396 */ "vtabarglist ::= vtabarg",
165048 /* 397 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
165049 /* 398 */ "vtabarg ::= vtabarg vtabargtoken",
165050 /* 399 */ "anylist ::=",
165051 /* 400 */ "anylist ::= anylist LP anylist RP",
165052 /* 401 */ "anylist ::= anylist ANY",
165053 /* 402 */ "with ::=",
165054 };
165055 #endif /* NDEBUG */
165056
165057
165058 #if YYSTACKDEPTH<=0
@@ -164018,11 +165186,10 @@
165186 break;
165187 case 216: /* term */
165188 case 217: /* expr */
165189 case 246: /* where_opt */
165190 case 248: /* having_opt */
 
165191 case 267: /* where_opt_ret */
165192 case 278: /* case_operand */
165193 case 280: /* case_else */
165194 case 283: /* vinto */
165195 case 290: /* when_clause */
@@ -164038,11 +165205,11 @@
165205 case 244: /* selcollist */
165206 case 247: /* groupby_opt */
165207 case 249: /* orderby_opt */
165208 case 253: /* nexprlist */
165209 case 254: /* sclp */
165210 case 261: /* exprlist */
165211 case 268: /* setlist */
165212 case 277: /* paren_exprlist */
165213 case 279: /* case_exprlist */
165214 case 310: /* part_opt */
165215 {
@@ -164051,11 +165218,11 @@
165218 break;
165219 case 238: /* fullname */
165220 case 245: /* from */
165221 case 256: /* seltablist */
165222 case 257: /* stl_prefix */
165223 case 262: /* xfullname */
165224 {
165225 sqlite3SrcListDelete(pParse->db, (yypminor->yy131));
165226 }
165227 break;
165228 case 241: /* wqlist */
@@ -164067,12 +165234,11 @@
165234 case 306: /* windowdefn_list */
165235 {
165236 sqlite3WindowListDelete(pParse->db, (yypminor->yy41));
165237 }
165238 break;
165239 case 263: /* idlist */
 
165240 case 270: /* idlist_opt */
165241 {
165242 sqlite3IdListDelete(pParse->db, (yypminor->yy254));
165243 }
165244 break;
@@ -164498,33 +165664,33 @@
165664 255, /* (104) as ::= */
165665 245, /* (105) from ::= */
165666 245, /* (106) from ::= FROM seltablist */
165667 257, /* (107) stl_prefix ::= seltablist joinop */
165668 257, /* (108) stl_prefix ::= */
165669 256, /* (109) seltablist ::= stl_prefix nm dbnm as on_using */
165670 256, /* (110) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */
165671 256, /* (111) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */
165672 256, /* (112) seltablist ::= stl_prefix LP select RP as on_using */
165673 256, /* (113) seltablist ::= stl_prefix LP seltablist RP as on_using */
165674 200, /* (114) dbnm ::= */
165675 200, /* (115) dbnm ::= DOT nm */
165676 238, /* (116) fullname ::= nm */
165677 238, /* (117) fullname ::= nm DOT nm */
165678 262, /* (118) xfullname ::= nm */
165679 262, /* (119) xfullname ::= nm DOT nm */
165680 262, /* (120) xfullname ::= nm DOT nm AS nm */
165681 262, /* (121) xfullname ::= nm AS nm */
165682 258, /* (122) joinop ::= COMMA|JOIN */
165683 258, /* (123) joinop ::= JOIN_KW JOIN */
165684 258, /* (124) joinop ::= JOIN_KW nm JOIN */
165685 258, /* (125) joinop ::= JOIN_KW nm nm JOIN */
165686 259, /* (126) on_using ::= ON expr */
165687 259, /* (127) on_using ::= USING LP idlist RP */
165688 259, /* (128) on_using ::= */
165689 264, /* (129) indexed_opt ::= */
165690 260, /* (130) indexed_by ::= INDEXED BY nm */
165691 260, /* (131) indexed_by ::= NOT INDEXED */
165692 249, /* (132) orderby_opt ::= */
165693 249, /* (133) orderby_opt ::= ORDER BY sortlist */
165694 231, /* (134) sortlist ::= sortlist COMMA expr sortorder nulls */
165695 231, /* (135) sortlist ::= expr sortorder nulls */
165696 219, /* (136) sortorder ::= ASC */
@@ -164564,12 +165730,12 @@
165730 272, /* (170) returning ::= RETURNING selcollist */
165731 269, /* (171) insert_cmd ::= INSERT orconf */
165732 269, /* (172) insert_cmd ::= REPLACE */
165733 270, /* (173) idlist_opt ::= */
165734 270, /* (174) idlist_opt ::= LP idlist RP */
165735 263, /* (175) idlist ::= idlist COMMA nm */
165736 263, /* (176) idlist ::= nm */
165737 217, /* (177) expr ::= LP expr RP */
165738 217, /* (178) expr ::= ID|INDEXED */
165739 217, /* (179) expr ::= JOIN_KW */
165740 217, /* (180) expr ::= nm DOT nm */
165741 217, /* (181) expr ::= nm DOT nm DOT nm */
@@ -164619,11 +165785,11 @@
165785 279, /* (225) case_exprlist ::= WHEN expr THEN expr */
165786 280, /* (226) case_else ::= ELSE expr */
165787 280, /* (227) case_else ::= */
165788 278, /* (228) case_operand ::= expr */
165789 278, /* (229) case_operand ::= */
165790 261, /* (230) exprlist ::= */
165791 253, /* (231) nexprlist ::= nexprlist COMMA expr */
165792 253, /* (232) nexprlist ::= expr */
165793 277, /* (233) paren_exprlist ::= */
165794 277, /* (234) paren_exprlist ::= LP exprlist RP */
165795 190, /* (235) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
@@ -164766,35 +165932,36 @@
165932 235, /* (372) resolvetype ::= raisetype */
165933 239, /* (373) selectnowith ::= oneselect */
165934 240, /* (374) oneselect ::= values */
165935 254, /* (375) sclp ::= selcollist COMMA */
165936 255, /* (376) as ::= ID|STRING */
165937 264, /* (377) indexed_opt ::= indexed_by */
165938 272, /* (378) returning ::= */
165939 217, /* (379) expr ::= term */
165940 274, /* (380) likeop ::= LIKE_KW|MATCH */
165941 261, /* (381) exprlist ::= nexprlist */
165942 284, /* (382) nmnum ::= plus_num */
165943 284, /* (383) nmnum ::= nm */
165944 284, /* (384) nmnum ::= ON */
165945 284, /* (385) nmnum ::= DELETE */
165946 284, /* (386) nmnum ::= DEFAULT */
165947 211, /* (387) plus_num ::= INTEGER|FLOAT */
165948 289, /* (388) foreach_clause ::= */
165949 289, /* (389) foreach_clause ::= FOR EACH ROW */
165950 292, /* (390) trnm ::= nm */
165951 293, /* (391) tridxby ::= */
165952 294, /* (392) database_kw_opt ::= DATABASE */
165953 294, /* (393) database_kw_opt ::= */
165954 297, /* (394) kwcolumn_opt ::= */
165955 297, /* (395) kwcolumn_opt ::= COLUMNKW */
165956 299, /* (396) vtabarglist ::= vtabarg */
165957 299, /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */
165958 300, /* (398) vtabarg ::= vtabarg vtabargtoken */
165959 303, /* (399) anylist ::= */
165960 303, /* (400) anylist ::= anylist LP anylist RP */
165961 303, /* (401) anylist ::= anylist ANY */
165962 266, /* (402) with ::= */
165963 };
165964
165965 /* For rule J, yyRuleInfoNRhs[J] contains the negative of the number
165966 ** of symbols on the right-hand side of that rule. */
165967 static const signed char yyRuleInfoNRhs[] = {
@@ -164905,33 +166072,33 @@
166072 0, /* (104) as ::= */
166073 0, /* (105) from ::= */
166074 -2, /* (106) from ::= FROM seltablist */
166075 -2, /* (107) stl_prefix ::= seltablist joinop */
166076 0, /* (108) stl_prefix ::= */
166077 -5, /* (109) seltablist ::= stl_prefix nm dbnm as on_using */
166078 -6, /* (110) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */
166079 -8, /* (111) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */
166080 -6, /* (112) seltablist ::= stl_prefix LP select RP as on_using */
166081 -6, /* (113) seltablist ::= stl_prefix LP seltablist RP as on_using */
166082 0, /* (114) dbnm ::= */
166083 -2, /* (115) dbnm ::= DOT nm */
166084 -1, /* (116) fullname ::= nm */
166085 -3, /* (117) fullname ::= nm DOT nm */
166086 -1, /* (118) xfullname ::= nm */
166087 -3, /* (119) xfullname ::= nm DOT nm */
166088 -5, /* (120) xfullname ::= nm DOT nm AS nm */
166089 -3, /* (121) xfullname ::= nm AS nm */
166090 -1, /* (122) joinop ::= COMMA|JOIN */
166091 -2, /* (123) joinop ::= JOIN_KW JOIN */
166092 -3, /* (124) joinop ::= JOIN_KW nm JOIN */
166093 -4, /* (125) joinop ::= JOIN_KW nm nm JOIN */
166094 -2, /* (126) on_using ::= ON expr */
166095 -4, /* (127) on_using ::= USING LP idlist RP */
166096 0, /* (128) on_using ::= */
166097 0, /* (129) indexed_opt ::= */
166098 -3, /* (130) indexed_by ::= INDEXED BY nm */
166099 -2, /* (131) indexed_by ::= NOT INDEXED */
166100 0, /* (132) orderby_opt ::= */
166101 -3, /* (133) orderby_opt ::= ORDER BY sortlist */
166102 -5, /* (134) sortlist ::= sortlist COMMA expr sortorder nulls */
166103 -3, /* (135) sortlist ::= expr sortorder nulls */
166104 -1, /* (136) sortorder ::= ASC */
@@ -165173,35 +166340,36 @@
166340 -1, /* (372) resolvetype ::= raisetype */
166341 -1, /* (373) selectnowith ::= oneselect */
166342 -1, /* (374) oneselect ::= values */
166343 -2, /* (375) sclp ::= selcollist COMMA */
166344 -1, /* (376) as ::= ID|STRING */
166345 -1, /* (377) indexed_opt ::= indexed_by */
166346 0, /* (378) returning ::= */
166347 -1, /* (379) expr ::= term */
166348 -1, /* (380) likeop ::= LIKE_KW|MATCH */
166349 -1, /* (381) exprlist ::= nexprlist */
166350 -1, /* (382) nmnum ::= plus_num */
166351 -1, /* (383) nmnum ::= nm */
166352 -1, /* (384) nmnum ::= ON */
166353 -1, /* (385) nmnum ::= DELETE */
166354 -1, /* (386) nmnum ::= DEFAULT */
166355 -1, /* (387) plus_num ::= INTEGER|FLOAT */
166356 0, /* (388) foreach_clause ::= */
166357 -3, /* (389) foreach_clause ::= FOR EACH ROW */
166358 -1, /* (390) trnm ::= nm */
166359 0, /* (391) tridxby ::= */
166360 -1, /* (392) database_kw_opt ::= DATABASE */
166361 0, /* (393) database_kw_opt ::= */
166362 0, /* (394) kwcolumn_opt ::= */
166363 -1, /* (395) kwcolumn_opt ::= COLUMNKW */
166364 -1, /* (396) vtabarglist ::= vtabarg */
166365 -3, /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */
166366 -2, /* (398) vtabarg ::= vtabarg vtabargtoken */
166367 0, /* (399) anylist ::= */
166368 -4, /* (400) anylist ::= anylist LP anylist RP */
166369 -2, /* (401) anylist ::= anylist ANY */
166370 0, /* (402) with ::= */
166371 };
166372
166373 static void yy_accept(yyParser*); /* Forward Declaration */
166374
166375 /*
@@ -165565,11 +166733,11 @@
166733 if( pRhs && pRhs->pPrior ){
166734 SrcList *pFrom;
166735 Token x;
166736 x.n = 0;
166737 parserDoubleLinkSelect(pParse, pRhs);
166738 pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0);
166739 pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0);
166740 }
166741 if( pRhs ){
166742 pRhs->op = (u8)yymsp[-1].minor.yy394;
166743 pRhs->pPrior = pLhs;
@@ -165657,11 +166825,11 @@
166825 Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
166826 yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, pDot);
166827 }
166828 break;
166829 case 103: /* as ::= AS nm */
166830 case 115: /* dbnm ::= DOT nm */ yytestcase(yyruleno==115);
166831 case 254: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==254);
166832 case 255: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==255);
166833 {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
166834 break;
166835 case 105: /* from ::= */
@@ -165669,144 +166837,136 @@
166837 {yymsp[1].minor.yy131 = 0;}
166838 break;
166839 case 106: /* from ::= FROM seltablist */
166840 {
166841 yymsp[-1].minor.yy131 = yymsp[0].minor.yy131;
166842 sqlite3SrcListShiftJoinType(pParse,yymsp[-1].minor.yy131);
166843 }
166844 break;
166845 case 107: /* stl_prefix ::= seltablist joinop */
166846 {
166847 if( ALWAYS(yymsp[-1].minor.yy131 && yymsp[-1].minor.yy131->nSrc>0) ) yymsp[-1].minor.yy131->a[yymsp[-1].minor.yy131->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy394;
166848 }
166849 break;
166850 case 109: /* seltablist ::= stl_prefix nm dbnm as on_using */
166851 {
166852 yymsp[-4].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-4].minor.yy131,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561);
166853 }
166854 break;
166855 case 110: /* seltablist ::= stl_prefix nm dbnm as indexed_by on_using */
166856 {
166857 yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,0,&yymsp[0].minor.yy561);
166858 sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy131, &yymsp[-1].minor.yy0);
166859 }
166860 break;
166861 case 111: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */
166862 {
166863 yymsp[-7].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-7].minor.yy131,&yymsp[-6].minor.yy0,&yymsp[-5].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561);
166864 sqlite3SrcListFuncArgs(pParse, yymsp[-7].minor.yy131, yymsp[-3].minor.yy322);
166865 }
166866 break;
166867 case 112: /* seltablist ::= stl_prefix LP select RP as on_using */
166868 {
166869 yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,yymsp[-3].minor.yy47,&yymsp[0].minor.yy561);
166870 }
166871 break;
166872 case 113: /* seltablist ::= stl_prefix LP seltablist RP as on_using */
166873 {
166874 if( yymsp[-5].minor.yy131==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy561.pOn==0 && yymsp[0].minor.yy561.pUsing==0 ){
166875 yymsp[-5].minor.yy131 = yymsp[-3].minor.yy131;
166876 }else if( yymsp[-3].minor.yy131->nSrc==1 ){
166877 yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561);
166878 if( yymsp[-5].minor.yy131 ){
166879 SrcItem *pNew = &yymsp[-5].minor.yy131->a[yymsp[-5].minor.yy131->nSrc-1];
166880 SrcItem *pOld = yymsp[-3].minor.yy131->a;
166881 pNew->zName = pOld->zName;
166882 pNew->zDatabase = pOld->zDatabase;
166883 pNew->pSelect = pOld->pSelect;
166884 if( pNew->pSelect && (pNew->pSelect->selFlags & SF_NestedFrom)!=0 ){
166885 pNew->fg.isNestedFrom = 1;
166886 }
166887 if( pOld->fg.isTabFunc ){
166888 pNew->u1.pFuncArg = pOld->u1.pFuncArg;
166889 pOld->u1.pFuncArg = 0;
166890 pOld->fg.isTabFunc = 0;
166891 pNew->fg.isTabFunc = 1;
166892 }
166893 pOld->zName = pOld->zDatabase = 0;
166894 pOld->pSelect = 0;
166895 }
166896 sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy131);
166897 }else{
166898 Select *pSubquery;
166899 sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy131);
166900 pSubquery = sqlite3SelectNew(pParse,0,yymsp[-3].minor.yy131,0,0,0,0,SF_NestedFrom,0);
166901 yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,pSubquery,&yymsp[0].minor.yy561);
166902 }
166903 }
166904 break;
166905 case 114: /* dbnm ::= */
166906 case 129: /* indexed_opt ::= */ yytestcase(yyruleno==129);
166907 {yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;}
166908 break;
166909 case 116: /* fullname ::= nm */
166910 {
166911 yylhsminor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0);
166912 if( IN_RENAME_OBJECT && yylhsminor.yy131 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy131->a[0].zName, &yymsp[0].minor.yy0);
166913 }
166914 yymsp[0].minor.yy131 = yylhsminor.yy131;
166915 break;
166916 case 117: /* fullname ::= nm DOT nm */
166917 {
166918 yylhsminor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
166919 if( IN_RENAME_OBJECT && yylhsminor.yy131 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy131->a[0].zName, &yymsp[0].minor.yy0);
166920 }
166921 yymsp[-2].minor.yy131 = yylhsminor.yy131;
166922 break;
166923 case 118: /* xfullname ::= nm */
166924 {yymsp[0].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/}
166925 break;
166926 case 119: /* xfullname ::= nm DOT nm */
166927 {yymsp[-2].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/}
166928 break;
166929 case 120: /* xfullname ::= nm DOT nm AS nm */
166930 {
166931 yymsp[-4].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/
166932 if( yymsp[-4].minor.yy131 ) yymsp[-4].minor.yy131->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
166933 }
166934 break;
166935 case 121: /* xfullname ::= nm AS nm */
166936 {
166937 yymsp[-2].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/
166938 if( yymsp[-2].minor.yy131 ) yymsp[-2].minor.yy131->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
166939 }
166940 break;
166941 case 122: /* joinop ::= COMMA|JOIN */
166942 { yymsp[0].minor.yy394 = JT_INNER; }
166943 break;
166944 case 123: /* joinop ::= JOIN_KW JOIN */
166945 {yymsp[-1].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/}
166946 break;
166947 case 124: /* joinop ::= JOIN_KW nm JOIN */
166948 {yymsp[-2].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/}
166949 break;
166950 case 125: /* joinop ::= JOIN_KW nm nm JOIN */
166951 {yymsp[-3].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
166952 break;
166953 case 126: /* on_using ::= ON expr */
166954 {yymsp[-1].minor.yy561.pOn = yymsp[0].minor.yy528; yymsp[-1].minor.yy561.pUsing = 0;}
166955 break;
166956 case 127: /* on_using ::= USING LP idlist RP */
166957 {yymsp[-3].minor.yy561.pOn = 0; yymsp[-3].minor.yy561.pUsing = yymsp[-1].minor.yy254;}
166958 break;
166959 case 128: /* on_using ::= */
166960 {yymsp[1].minor.yy561.pOn = 0; yymsp[1].minor.yy561.pUsing = 0;}
166961 break;
166962 case 130: /* indexed_by ::= INDEXED BY nm */
 
 
 
 
 
 
 
 
 
166963 {yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;}
166964 break;
166965 case 131: /* indexed_by ::= NOT INDEXED */
166966 {yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;}
166967 break;
 
 
 
 
 
 
 
166968 case 133: /* orderby_opt ::= ORDER BY sortlist */
166969 case 143: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==143);
166970 {yymsp[-2].minor.yy322 = yymsp[0].minor.yy322;}
166971 break;
166972 case 134: /* sortlist ::= sortlist COMMA expr sortorder nulls */
@@ -165835,10 +166995,26 @@
166995 {yymsp[-1].minor.yy394 = SQLITE_SO_ASC;}
166996 break;
166997 case 140: /* nulls ::= NULLS LAST */
166998 {yymsp[-1].minor.yy394 = SQLITE_SO_DESC;}
166999 break;
167000 case 144: /* having_opt ::= */
167001 case 146: /* limit_opt ::= */ yytestcase(yyruleno==146);
167002 case 151: /* where_opt ::= */ yytestcase(yyruleno==151);
167003 case 153: /* where_opt_ret ::= */ yytestcase(yyruleno==153);
167004 case 227: /* case_else ::= */ yytestcase(yyruleno==227);
167005 case 229: /* case_operand ::= */ yytestcase(yyruleno==229);
167006 case 248: /* vinto ::= */ yytestcase(yyruleno==248);
167007 {yymsp[1].minor.yy528 = 0;}
167008 break;
167009 case 145: /* having_opt ::= HAVING expr */
167010 case 152: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==152);
167011 case 154: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==154);
167012 case 226: /* case_else ::= ELSE expr */ yytestcase(yyruleno==226);
167013 case 247: /* vinto ::= INTO expr */ yytestcase(yyruleno==247);
167014 {yymsp[-1].minor.yy528 = yymsp[0].minor.yy528;}
167015 break;
167016 case 147: /* limit_opt ::= LIMIT expr */
167017 {yymsp[-1].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy528,0);}
167018 break;
167019 case 148: /* limit_opt ::= LIMIT expr OFFSET expr */
167020 {yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);}
@@ -165917,10 +167093,13 @@
167093 case 169: /* upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */
167094 { yymsp[-7].minor.yy444 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528,0);}
167095 break;
167096 case 170: /* returning ::= RETURNING selcollist */
167097 {sqlite3AddReturning(pParse,yymsp[0].minor.yy322);}
167098 break;
167099 case 173: /* idlist_opt ::= */
167100 {yymsp[1].minor.yy254 = 0;}
167101 break;
167102 case 174: /* idlist_opt ::= LP idlist RP */
167103 {yymsp[-2].minor.yy254 = yymsp[-1].minor.yy254;}
167104 break;
167105 case 175: /* idlist ::= idlist COMMA nm */
@@ -166693,35 +167872,36 @@
167872 /* (372) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=372);
167873 /* (373) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=373);
167874 /* (374) oneselect ::= values */ yytestcase(yyruleno==374);
167875 /* (375) sclp ::= selcollist COMMA */ yytestcase(yyruleno==375);
167876 /* (376) as ::= ID|STRING */ yytestcase(yyruleno==376);
167877 /* (377) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=377);
167878 /* (378) returning ::= */ yytestcase(yyruleno==378);
167879 /* (379) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=379);
167880 /* (380) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==380);
167881 /* (381) exprlist ::= nexprlist */ yytestcase(yyruleno==381);
167882 /* (382) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=382);
167883 /* (383) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=383);
167884 /* (384) nmnum ::= ON */ yytestcase(yyruleno==384);
167885 /* (385) nmnum ::= DELETE */ yytestcase(yyruleno==385);
167886 /* (386) nmnum ::= DEFAULT */ yytestcase(yyruleno==386);
167887 /* (387) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==387);
167888 /* (388) foreach_clause ::= */ yytestcase(yyruleno==388);
167889 /* (389) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==389);
167890 /* (390) trnm ::= nm */ yytestcase(yyruleno==390);
167891 /* (391) tridxby ::= */ yytestcase(yyruleno==391);
167892 /* (392) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==392);
167893 /* (393) database_kw_opt ::= */ yytestcase(yyruleno==393);
167894 /* (394) kwcolumn_opt ::= */ yytestcase(yyruleno==394);
167895 /* (395) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==395);
167896 /* (396) vtabarglist ::= vtabarg */ yytestcase(yyruleno==396);
167897 /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==397);
167898 /* (398) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==398);
167899 /* (399) anylist ::= */ yytestcase(yyruleno==399);
167900 /* (400) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==400);
167901 /* (401) anylist ::= anylist ANY */ yytestcase(yyruleno==401);
167902 /* (402) with ::= */ yytestcase(yyruleno==402);
167903 break;
167904 /********** End reduce actions ************************************************/
167905 };
167906 assert( yyruleno<sizeof(yyRuleInfoLhs)/sizeof(yyRuleInfoLhs[0]) );
167907 yygoto = yyRuleInfoLhs[yyruleno];
@@ -172889,10 +174069,29 @@
174069 */
174070 case SQLITE_TESTCTRL_ASSERT: {
174071 volatile int x = 0;
174072 assert( /*side-effects-ok*/ (x = va_arg(ap,int))!=0 );
174073 rc = x;
174074 #if defined(SQLITE_DEBUG)
174075 /* Invoke these debugging routines so that the compiler does not
174076 ** issue "defined but not used" warnings. */
174077 if( x==9999 ){
174078 sqlite3ShowExpr(0);
174079 sqlite3ShowExpr(0);
174080 sqlite3ShowExprList(0);
174081 sqlite3ShowIdList(0);
174082 sqlite3ShowSrcList(0);
174083 sqlite3ShowWith(0);
174084 sqlite3ShowUpsert(0);
174085 sqlite3ShowTriggerStep(0);
174086 sqlite3ShowTriggerStepList(0);
174087 sqlite3ShowTrigger(0);
174088 sqlite3ShowTriggerList(0);
174089 sqlite3ShowWindow(0);
174090 sqlite3ShowWinFunc(0);
174091 }
174092 #endif
174093 break;
174094 }
174095
174096
174097 /*
@@ -173150,23 +174349,23 @@
174349
174350 /* sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, op, ptr)
174351 **
174352 ** "ptr" is a pointer to a u32.
174353 **
174354 ** op==0 Store the current sqlite3TreeTrace in *ptr
174355 ** op==1 Set sqlite3TreeTrace to the value *ptr
174356 ** op==3 Store the current sqlite3WhereTrace in *ptr
174357 ** op==3 Set sqlite3WhereTrace to the value *ptr
174358 */
174359 case SQLITE_TESTCTRL_TRACEFLAGS: {
174360 int opTrace = va_arg(ap, int);
174361 u32 *ptr = va_arg(ap, u32*);
174362 switch( opTrace ){
174363 case 0: *ptr = sqlite3TreeTrace; break;
174364 case 1: sqlite3TreeTrace = *ptr; break;
174365 case 2: *ptr = sqlite3WhereTrace; break;
174366 case 3: sqlite3WhereTrace = *ptr; break;
174367 }
174368 break;
174369 }
174370
174371 /* sqlite3_test_control(SQLITE_TESTCTRL_LOGEST,
@@ -194609,18 +195808,19 @@
195808 i++;
195809 }else{
195810 *pzErr = zPath;
195811 return 0;
195812 }
195813 testcase( nKey==0 );
195814 }else{
195815 zKey = zPath;
195816 for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
195817 nKey = i;
195818 if( nKey==0 ){
195819 *pzErr = zPath;
195820 return 0;
195821 }
195822 }
195823 j = 1;
195824 for(;;){
195825 while( j<=pRoot->n ){
195826 if( jsonLabelCompare(pRoot+j, zKey, nKey) ){
@@ -195763,10 +196963,37 @@
196963 }
196964 }
196965 }
196966 return SQLITE_OK;
196967 }
196968
196969 /* Append an object label to the JSON Path being constructed
196970 ** in pStr.
196971 */
196972 static void jsonAppendObjectPathElement(
196973 JsonString *pStr,
196974 JsonNode *pNode
196975 ){
196976 int jj, nn;
196977 const char *z;
196978 assert( pNode->eType==JSON_STRING );
196979 assert( pNode->jnFlags & JNODE_LABEL );
196980 assert( pNode->eU==1 );
196981 z = pNode->u.zJContent;
196982 nn = pNode->n;
196983 assert( nn>=2 );
196984 assert( z[0]=='"' );
196985 assert( z[nn-1]=='"' );
196986 if( nn>2 && sqlite3Isalpha(z[1]) ){
196987 for(jj=2; jj<nn-1 && sqlite3Isalnum(z[jj]); jj++){}
196988 if( jj==nn-1 ){
196989 z++;
196990 nn -= 2;
196991 }
196992 }
196993 jsonPrintf(nn+2, pStr, ".%.*s", nn, z);
196994 }
196995
196996 /* Append the name of the path for element i to pStr
196997 */
196998 static void jsonEachComputePath(
196999 JsonEachCursor *p, /* The cursor */
@@ -195788,14 +197015,11 @@
197015 testcase( pUp->eU==0 );
197016 jsonPrintf(30, pStr, "[%d]", pUp->u.iKey);
197017 }else{
197018 assert( pUp->eType==JSON_OBJECT );
197019 if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--;
197020 jsonAppendObjectPathElement(pStr, pNode);
 
 
 
197021 }
197022 }
197023
197024 /* Return the value of a column */
197025 static int jsonEachColumn(
@@ -195862,12 +197086,11 @@
197086 jsonAppendChar(&x, '$');
197087 }
197088 if( p->eType==JSON_ARRAY ){
197089 jsonPrintf(30, &x, "[%d]", p->iRowid);
197090 }else if( p->eType==JSON_OBJECT ){
197091 jsonAppendObjectPathElement(&x, pThis);
 
197092 }
197093 }
197094 jsonResult(&x);
197095 break;
197096 }
@@ -210410,11 +211633,11 @@
211633 && pIdxInfo->aOrderBy[0].iColumn<=0
211634 && pIdxInfo->aOrderBy[0].desc==0
211635 ){
211636 pIdxInfo->orderByConsumed = 1;
211637 }
211638 sqlite3VtabUsesAllSchemas(pIdxInfo);
211639 return SQLITE_OK;
211640 }
211641
211642 /*
211643 ** Open a new dbpagevfs cursor.
@@ -223138,10 +224361,13 @@
224361 sqlite3Fts5ParseNearsetFree(pNear);
224362 sqlite3Fts5ParsePhraseFree(pPhrase);
224363 }else{
224364 if( pRet->nPhrase>0 ){
224365 Fts5ExprPhrase *pLast = pRet->apPhrase[pRet->nPhrase-1];
224366 assert( pParse!=0 );
224367 assert( pParse->apPhrase!=0 );
224368 assert( pParse->nPhrase>=2 );
224369 assert( pLast==pParse->apPhrase[pParse->nPhrase-2] );
224370 if( pPhrase->nTerm==0 ){
224371 fts5ExprPhraseFree(pPhrase);
224372 pRet->nPhrase--;
224373 pParse->nPhrase--;
@@ -234754,11 +235980,11 @@
235980 int nArg, /* Number of args */
235981 sqlite3_value **apUnused /* Function arguments */
235982 ){
235983 assert( nArg==0 );
235984 UNUSED_PARAM2(nArg, apUnused);
235985 sqlite3_result_text(pCtx, "fts5: 2022-04-19 15:56:03 b966d52437f08a6759a83a45cafb0d706a8933a8e55dee38ae78166d1a5b3ba4", -1, SQLITE_TRANSIENT);
235986 }
235987
235988 /*
235989 ** Return true if zName is the extension on one of the shadow tables used
235990 ** by this module.
235991
--- 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.39.0"
150150
#define SQLITE_VERSION_NUMBER 3039000
151
-#define SQLITE_SOURCE_ID "2022-04-01 17:23:17 a7d79560a0efd6221ba59ce84bcb4fa94024a901ac4a45e192ddecc6e1b5c78c"
151
+#define SQLITE_SOURCE_ID "2022-04-21 19:38:17 f766dff012af0ea3c28a8ce4db850cd0205729a8283bce1e442992aded7c734b"
152152
153153
/*
154154
** CAPI3REF: Run-Time Library Version Numbers
155155
** KEYWORDS: sqlite3_version sqlite3_sourceid
156156
**
157157
--- 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.39.0"
150 #define SQLITE_VERSION_NUMBER 3039000
151 #define SQLITE_SOURCE_ID "2022-04-01 17:23:17 a7d79560a0efd6221ba59ce84bcb4fa94024a901ac4a45e192ddecc6e1b5c78c"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
157
--- 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.39.0"
150 #define SQLITE_VERSION_NUMBER 3039000
151 #define SQLITE_SOURCE_ID "2022-04-21 19:38:17 f766dff012af0ea3c28a8ce4db850cd0205729a8283bce1e442992aded7c734b"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
157
--- src/backlink.c
+++ src/backlink.c
@@ -255,10 +255,12 @@
255255
Backlink *p
256256
){
257257
struct mkd_renderer html_renderer = {
258258
/* prolog */ (void(*)(Blob*,void*))mkdn_noop0,
259259
/* epilog */ (void(*)(Blob*,void*))mkdn_noop0,
260
+ /* footnotes */ (void(*)(Blob*,const Blob*, void*))mkdn_noop0,
261
+
260262
/* blockcode */ (void(*)(Blob*,Blob*,void*))mkdn_noop0,
261263
/* blockquote */ (void(*)(Blob*,Blob*,void*))mkdn_noop0,
262264
/* blockhtml */ (void(*)(Blob*,Blob*,void*))mkdn_noop0,
263265
/* header */ (void(*)(Blob*,Blob*,int,void*))mkdn_noop0,
264266
/* hrule */ (void(*)(Blob*,void*))mkdn_noop0,
@@ -266,10 +268,12 @@
266268
/* listitem */ (void(*)(Blob*,Blob*,int,void*))mkdn_noop0,
267269
/* paragraph */ (void(*)(Blob*,Blob*,void*))mkdn_noop0,
268270
/* table */ (void(*)(Blob*,Blob*,Blob*,void*))mkdn_noop0,
269271
/* table_cell */ (void(*)(Blob*,Blob*,int,void*))mkdn_noop0,
270272
/* table_row */ (void(*)(Blob*,Blob*,int,void*))mkdn_noop0,
273
+ /* footnoteitm*/ (void(*)(Blob*,const Blob*,int,int,void*))mkdn_noop0,
274
+
271275
/* autolink */ (int(*)(Blob*,Blob*,enum mkd_autolink,void*))mkdn_noop1,
272276
/* codespan */ (int(*)(Blob*,Blob*,int,void*))mkdn_noop1,
273277
/* dbl_emphas */ (int(*)(Blob*,Blob*,char,void*))mkdn_noop1,
274278
/* emphasis */ (int(*)(Blob*,Blob*,char,void*))mkdn_noop1,
275279
/* image */ (int(*)(Blob*,Blob*,Blob*,Blob*,void*))mkdn_noop1,
@@ -276,10 +280,12 @@
276280
/* linebreak */ (int(*)(Blob*,void*))mkdn_noop1,
277281
/* link */ backlink_md_link,
278282
/* r_html_tag */ (int(*)(Blob*,Blob*,void*))mkdn_noop1,
279283
/* @/#tags */ (int(*)(Blob*,Blob*,enum mkd_tagspan,void*))mkdn_noop1,
280284
/* tri_emphas */ (int(*)(Blob*,Blob*,char,void*))mkdn_noop1,
285
+ /* footnoteref*/ (int(*)(Blob*,const Blob*,const Blob*,int,int,void*))mkdn_noop1,
286
+
281287
0, /* entity */
282288
0, /* normal_text */
283289
"*_", /* emphasis characters */
284290
0 /* client data */
285291
};
286292
--- src/backlink.c
+++ src/backlink.c
@@ -255,10 +255,12 @@
255 Backlink *p
256 ){
257 struct mkd_renderer html_renderer = {
258 /* prolog */ (void(*)(Blob*,void*))mkdn_noop0,
259 /* epilog */ (void(*)(Blob*,void*))mkdn_noop0,
 
 
260 /* blockcode */ (void(*)(Blob*,Blob*,void*))mkdn_noop0,
261 /* blockquote */ (void(*)(Blob*,Blob*,void*))mkdn_noop0,
262 /* blockhtml */ (void(*)(Blob*,Blob*,void*))mkdn_noop0,
263 /* header */ (void(*)(Blob*,Blob*,int,void*))mkdn_noop0,
264 /* hrule */ (void(*)(Blob*,void*))mkdn_noop0,
@@ -266,10 +268,12 @@
266 /* listitem */ (void(*)(Blob*,Blob*,int,void*))mkdn_noop0,
267 /* paragraph */ (void(*)(Blob*,Blob*,void*))mkdn_noop0,
268 /* table */ (void(*)(Blob*,Blob*,Blob*,void*))mkdn_noop0,
269 /* table_cell */ (void(*)(Blob*,Blob*,int,void*))mkdn_noop0,
270 /* table_row */ (void(*)(Blob*,Blob*,int,void*))mkdn_noop0,
 
 
271 /* autolink */ (int(*)(Blob*,Blob*,enum mkd_autolink,void*))mkdn_noop1,
272 /* codespan */ (int(*)(Blob*,Blob*,int,void*))mkdn_noop1,
273 /* dbl_emphas */ (int(*)(Blob*,Blob*,char,void*))mkdn_noop1,
274 /* emphasis */ (int(*)(Blob*,Blob*,char,void*))mkdn_noop1,
275 /* image */ (int(*)(Blob*,Blob*,Blob*,Blob*,void*))mkdn_noop1,
@@ -276,10 +280,12 @@
276 /* linebreak */ (int(*)(Blob*,void*))mkdn_noop1,
277 /* link */ backlink_md_link,
278 /* r_html_tag */ (int(*)(Blob*,Blob*,void*))mkdn_noop1,
279 /* @/#tags */ (int(*)(Blob*,Blob*,enum mkd_tagspan,void*))mkdn_noop1,
280 /* tri_emphas */ (int(*)(Blob*,Blob*,char,void*))mkdn_noop1,
 
 
281 0, /* entity */
282 0, /* normal_text */
283 "*_", /* emphasis characters */
284 0 /* client data */
285 };
286
--- src/backlink.c
+++ src/backlink.c
@@ -255,10 +255,12 @@
255 Backlink *p
256 ){
257 struct mkd_renderer html_renderer = {
258 /* prolog */ (void(*)(Blob*,void*))mkdn_noop0,
259 /* epilog */ (void(*)(Blob*,void*))mkdn_noop0,
260 /* footnotes */ (void(*)(Blob*,const Blob*, void*))mkdn_noop0,
261
262 /* blockcode */ (void(*)(Blob*,Blob*,void*))mkdn_noop0,
263 /* blockquote */ (void(*)(Blob*,Blob*,void*))mkdn_noop0,
264 /* blockhtml */ (void(*)(Blob*,Blob*,void*))mkdn_noop0,
265 /* header */ (void(*)(Blob*,Blob*,int,void*))mkdn_noop0,
266 /* hrule */ (void(*)(Blob*,void*))mkdn_noop0,
@@ -266,10 +268,12 @@
268 /* listitem */ (void(*)(Blob*,Blob*,int,void*))mkdn_noop0,
269 /* paragraph */ (void(*)(Blob*,Blob*,void*))mkdn_noop0,
270 /* table */ (void(*)(Blob*,Blob*,Blob*,void*))mkdn_noop0,
271 /* table_cell */ (void(*)(Blob*,Blob*,int,void*))mkdn_noop0,
272 /* table_row */ (void(*)(Blob*,Blob*,int,void*))mkdn_noop0,
273 /* footnoteitm*/ (void(*)(Blob*,const Blob*,int,int,void*))mkdn_noop0,
274
275 /* autolink */ (int(*)(Blob*,Blob*,enum mkd_autolink,void*))mkdn_noop1,
276 /* codespan */ (int(*)(Blob*,Blob*,int,void*))mkdn_noop1,
277 /* dbl_emphas */ (int(*)(Blob*,Blob*,char,void*))mkdn_noop1,
278 /* emphasis */ (int(*)(Blob*,Blob*,char,void*))mkdn_noop1,
279 /* image */ (int(*)(Blob*,Blob*,Blob*,Blob*,void*))mkdn_noop1,
@@ -276,10 +280,12 @@
280 /* linebreak */ (int(*)(Blob*,void*))mkdn_noop1,
281 /* link */ backlink_md_link,
282 /* r_html_tag */ (int(*)(Blob*,Blob*,void*))mkdn_noop1,
283 /* @/#tags */ (int(*)(Blob*,Blob*,enum mkd_tagspan,void*))mkdn_noop1,
284 /* tri_emphas */ (int(*)(Blob*,Blob*,char,void*))mkdn_noop1,
285 /* footnoteref*/ (int(*)(Blob*,const Blob*,const Blob*,int,int,void*))mkdn_noop1,
286
287 0, /* entity */
288 0, /* normal_text */
289 "*_", /* emphasis characters */
290 0 /* client data */
291 };
292
--- src/backlink.c
+++ src/backlink.c
@@ -255,10 +255,12 @@
255255
Backlink *p
256256
){
257257
struct mkd_renderer html_renderer = {
258258
/* prolog */ (void(*)(Blob*,void*))mkdn_noop0,
259259
/* epilog */ (void(*)(Blob*,void*))mkdn_noop0,
260
+ /* footnotes */ (void(*)(Blob*,const Blob*, void*))mkdn_noop0,
261
+
260262
/* blockcode */ (void(*)(Blob*,Blob*,void*))mkdn_noop0,
261263
/* blockquote */ (void(*)(Blob*,Blob*,void*))mkdn_noop0,
262264
/* blockhtml */ (void(*)(Blob*,Blob*,void*))mkdn_noop0,
263265
/* header */ (void(*)(Blob*,Blob*,int,void*))mkdn_noop0,
264266
/* hrule */ (void(*)(Blob*,void*))mkdn_noop0,
@@ -266,10 +268,12 @@
266268
/* listitem */ (void(*)(Blob*,Blob*,int,void*))mkdn_noop0,
267269
/* paragraph */ (void(*)(Blob*,Blob*,void*))mkdn_noop0,
268270
/* table */ (void(*)(Blob*,Blob*,Blob*,void*))mkdn_noop0,
269271
/* table_cell */ (void(*)(Blob*,Blob*,int,void*))mkdn_noop0,
270272
/* table_row */ (void(*)(Blob*,Blob*,int,void*))mkdn_noop0,
273
+ /* footnoteitm*/ (void(*)(Blob*,const Blob*,int,int,void*))mkdn_noop0,
274
+
271275
/* autolink */ (int(*)(Blob*,Blob*,enum mkd_autolink,void*))mkdn_noop1,
272276
/* codespan */ (int(*)(Blob*,Blob*,int,void*))mkdn_noop1,
273277
/* dbl_emphas */ (int(*)(Blob*,Blob*,char,void*))mkdn_noop1,
274278
/* emphasis */ (int(*)(Blob*,Blob*,char,void*))mkdn_noop1,
275279
/* image */ (int(*)(Blob*,Blob*,Blob*,Blob*,void*))mkdn_noop1,
@@ -276,10 +280,12 @@
276280
/* linebreak */ (int(*)(Blob*,void*))mkdn_noop1,
277281
/* link */ backlink_md_link,
278282
/* r_html_tag */ (int(*)(Blob*,Blob*,void*))mkdn_noop1,
279283
/* @/#tags */ (int(*)(Blob*,Blob*,enum mkd_tagspan,void*))mkdn_noop1,
280284
/* tri_emphas */ (int(*)(Blob*,Blob*,char,void*))mkdn_noop1,
285
+ /* footnoteref*/ (int(*)(Blob*,const Blob*,const Blob*,int,int,void*))mkdn_noop1,
286
+
281287
0, /* entity */
282288
0, /* normal_text */
283289
"*_", /* emphasis characters */
284290
0 /* client data */
285291
};
286292
--- src/backlink.c
+++ src/backlink.c
@@ -255,10 +255,12 @@
255 Backlink *p
256 ){
257 struct mkd_renderer html_renderer = {
258 /* prolog */ (void(*)(Blob*,void*))mkdn_noop0,
259 /* epilog */ (void(*)(Blob*,void*))mkdn_noop0,
 
 
260 /* blockcode */ (void(*)(Blob*,Blob*,void*))mkdn_noop0,
261 /* blockquote */ (void(*)(Blob*,Blob*,void*))mkdn_noop0,
262 /* blockhtml */ (void(*)(Blob*,Blob*,void*))mkdn_noop0,
263 /* header */ (void(*)(Blob*,Blob*,int,void*))mkdn_noop0,
264 /* hrule */ (void(*)(Blob*,void*))mkdn_noop0,
@@ -266,10 +268,12 @@
266 /* listitem */ (void(*)(Blob*,Blob*,int,void*))mkdn_noop0,
267 /* paragraph */ (void(*)(Blob*,Blob*,void*))mkdn_noop0,
268 /* table */ (void(*)(Blob*,Blob*,Blob*,void*))mkdn_noop0,
269 /* table_cell */ (void(*)(Blob*,Blob*,int,void*))mkdn_noop0,
270 /* table_row */ (void(*)(Blob*,Blob*,int,void*))mkdn_noop0,
 
 
271 /* autolink */ (int(*)(Blob*,Blob*,enum mkd_autolink,void*))mkdn_noop1,
272 /* codespan */ (int(*)(Blob*,Blob*,int,void*))mkdn_noop1,
273 /* dbl_emphas */ (int(*)(Blob*,Blob*,char,void*))mkdn_noop1,
274 /* emphasis */ (int(*)(Blob*,Blob*,char,void*))mkdn_noop1,
275 /* image */ (int(*)(Blob*,Blob*,Blob*,Blob*,void*))mkdn_noop1,
@@ -276,10 +280,12 @@
276 /* linebreak */ (int(*)(Blob*,void*))mkdn_noop1,
277 /* link */ backlink_md_link,
278 /* r_html_tag */ (int(*)(Blob*,Blob*,void*))mkdn_noop1,
279 /* @/#tags */ (int(*)(Blob*,Blob*,enum mkd_tagspan,void*))mkdn_noop1,
280 /* tri_emphas */ (int(*)(Blob*,Blob*,char,void*))mkdn_noop1,
 
 
281 0, /* entity */
282 0, /* normal_text */
283 "*_", /* emphasis characters */
284 0 /* client data */
285 };
286
--- src/backlink.c
+++ src/backlink.c
@@ -255,10 +255,12 @@
255 Backlink *p
256 ){
257 struct mkd_renderer html_renderer = {
258 /* prolog */ (void(*)(Blob*,void*))mkdn_noop0,
259 /* epilog */ (void(*)(Blob*,void*))mkdn_noop0,
260 /* footnotes */ (void(*)(Blob*,const Blob*, void*))mkdn_noop0,
261
262 /* blockcode */ (void(*)(Blob*,Blob*,void*))mkdn_noop0,
263 /* blockquote */ (void(*)(Blob*,Blob*,void*))mkdn_noop0,
264 /* blockhtml */ (void(*)(Blob*,Blob*,void*))mkdn_noop0,
265 /* header */ (void(*)(Blob*,Blob*,int,void*))mkdn_noop0,
266 /* hrule */ (void(*)(Blob*,void*))mkdn_noop0,
@@ -266,10 +268,12 @@
268 /* listitem */ (void(*)(Blob*,Blob*,int,void*))mkdn_noop0,
269 /* paragraph */ (void(*)(Blob*,Blob*,void*))mkdn_noop0,
270 /* table */ (void(*)(Blob*,Blob*,Blob*,void*))mkdn_noop0,
271 /* table_cell */ (void(*)(Blob*,Blob*,int,void*))mkdn_noop0,
272 /* table_row */ (void(*)(Blob*,Blob*,int,void*))mkdn_noop0,
273 /* footnoteitm*/ (void(*)(Blob*,const Blob*,int,int,void*))mkdn_noop0,
274
275 /* autolink */ (int(*)(Blob*,Blob*,enum mkd_autolink,void*))mkdn_noop1,
276 /* codespan */ (int(*)(Blob*,Blob*,int,void*))mkdn_noop1,
277 /* dbl_emphas */ (int(*)(Blob*,Blob*,char,void*))mkdn_noop1,
278 /* emphasis */ (int(*)(Blob*,Blob*,char,void*))mkdn_noop1,
279 /* image */ (int(*)(Blob*,Blob*,Blob*,Blob*,void*))mkdn_noop1,
@@ -276,10 +280,12 @@
280 /* linebreak */ (int(*)(Blob*,void*))mkdn_noop1,
281 /* link */ backlink_md_link,
282 /* r_html_tag */ (int(*)(Blob*,Blob*,void*))mkdn_noop1,
283 /* @/#tags */ (int(*)(Blob*,Blob*,enum mkd_tagspan,void*))mkdn_noop1,
284 /* tri_emphas */ (int(*)(Blob*,Blob*,char,void*))mkdn_noop1,
285 /* footnoteref*/ (int(*)(Blob*,const Blob*,const Blob*,int,int,void*))mkdn_noop1,
286
287 0, /* entity */
288 0, /* normal_text */
289 "*_", /* emphasis characters */
290 0 /* client data */
291 };
292
+24 -8
--- src/blob.c
+++ src/blob.c
@@ -53,10 +53,33 @@
5353
/*
5454
** The buffer holding the blob data
5555
*/
5656
#define blob_buffer(X) ((X)->aData)
5757
58
+/*
59
+** Append blob contents to another
60
+*/
61
+#define blob_appendb(dest, src) \
62
+ blob_append((dest), blob_buffer(src), blob_size(src))
63
+
64
+/*
65
+** Append a string literal to a blob
66
+** TODO: Consider renaming to blob_appendl()
67
+*/
68
+#define blob_append_literal(blob, literal) \
69
+ blob_append((blob), "" literal, (sizeof literal)-1)
70
+ /*
71
+ * The empty string in the second argument leads to a syntax error
72
+ * when the macro is not used with a string literal. Unfortunately
73
+ * the error is not overly explicit.
74
+ */
75
+
76
+/*
77
+** TODO: Suggested for removal because the name seems misleading.
78
+*/
79
+#define blob_append_string blob_append_literal
80
+
5881
/*
5982
** Seek whence parameter values
6083
*/
6184
#define BLOB_SEEK_SET 1
6285
#define BLOB_SEEK_CUR 2
@@ -325,17 +348,10 @@
325348
pBlob->nUsed += nData;
326349
pBlob->aData[pBlob->nUsed] = 0;
327350
memcpy(&pBlob->aData[nUsed], aData, nData);
328351
}
329352
330
-/*
331
-** Append a string literal to a blob.
332
-*/
333
-#if INTERFACE
334
-#define blob_append_string(BLOB,STR) blob_append(BLOB,STR,sizeof(STR)-1)
335
-#endif
336
-
337353
/*
338354
** Append a single character to the blob. If pBlob is zero then the
339355
** character is written directly to stdout.
340356
*/
341357
void blob_append_char(Blob *pBlob, char c){
@@ -503,11 +519,11 @@
503519
504520
/*
505521
** Compare two blobs. Return negative, zero, or positive if the first
506522
** blob is less then, equal to, or greater than the second.
507523
*/
508
-int blob_compare(Blob *pA, Blob *pB){
524
+int blob_compare(const Blob *pA, const Blob *pB){
509525
int szA, szB, sz, rc;
510526
blob_is_init(pA);
511527
blob_is_init(pB);
512528
szA = blob_size(pA);
513529
szB = blob_size(pB);
514530
--- src/blob.c
+++ src/blob.c
@@ -53,10 +53,33 @@
53 /*
54 ** The buffer holding the blob data
55 */
56 #define blob_buffer(X) ((X)->aData)
57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58 /*
59 ** Seek whence parameter values
60 */
61 #define BLOB_SEEK_SET 1
62 #define BLOB_SEEK_CUR 2
@@ -325,17 +348,10 @@
325 pBlob->nUsed += nData;
326 pBlob->aData[pBlob->nUsed] = 0;
327 memcpy(&pBlob->aData[nUsed], aData, nData);
328 }
329
330 /*
331 ** Append a string literal to a blob.
332 */
333 #if INTERFACE
334 #define blob_append_string(BLOB,STR) blob_append(BLOB,STR,sizeof(STR)-1)
335 #endif
336
337 /*
338 ** Append a single character to the blob. If pBlob is zero then the
339 ** character is written directly to stdout.
340 */
341 void blob_append_char(Blob *pBlob, char c){
@@ -503,11 +519,11 @@
503
504 /*
505 ** Compare two blobs. Return negative, zero, or positive if the first
506 ** blob is less then, equal to, or greater than the second.
507 */
508 int blob_compare(Blob *pA, Blob *pB){
509 int szA, szB, sz, rc;
510 blob_is_init(pA);
511 blob_is_init(pB);
512 szA = blob_size(pA);
513 szB = blob_size(pB);
514
--- src/blob.c
+++ src/blob.c
@@ -53,10 +53,33 @@
53 /*
54 ** The buffer holding the blob data
55 */
56 #define blob_buffer(X) ((X)->aData)
57
58 /*
59 ** Append blob contents to another
60 */
61 #define blob_appendb(dest, src) \
62 blob_append((dest), blob_buffer(src), blob_size(src))
63
64 /*
65 ** Append a string literal to a blob
66 ** TODO: Consider renaming to blob_appendl()
67 */
68 #define blob_append_literal(blob, literal) \
69 blob_append((blob), "" literal, (sizeof literal)-1)
70 /*
71 * The empty string in the second argument leads to a syntax error
72 * when the macro is not used with a string literal. Unfortunately
73 * the error is not overly explicit.
74 */
75
76 /*
77 ** TODO: Suggested for removal because the name seems misleading.
78 */
79 #define blob_append_string blob_append_literal
80
81 /*
82 ** Seek whence parameter values
83 */
84 #define BLOB_SEEK_SET 1
85 #define BLOB_SEEK_CUR 2
@@ -325,17 +348,10 @@
348 pBlob->nUsed += nData;
349 pBlob->aData[pBlob->nUsed] = 0;
350 memcpy(&pBlob->aData[nUsed], aData, nData);
351 }
352
 
 
 
 
 
 
 
353 /*
354 ** Append a single character to the blob. If pBlob is zero then the
355 ** character is written directly to stdout.
356 */
357 void blob_append_char(Blob *pBlob, char c){
@@ -503,11 +519,11 @@
519
520 /*
521 ** Compare two blobs. Return negative, zero, or positive if the first
522 ** blob is less then, equal to, or greater than the second.
523 */
524 int blob_compare(const Blob *pA, const Blob *pB){
525 int szA, szB, sz, rc;
526 blob_is_init(pA);
527 blob_is_init(pB);
528 szA = blob_size(pA);
529 szB = blob_size(pB);
530
+1 -1
--- src/branch.c
+++ src/branch.c
@@ -221,11 +221,11 @@
221221
222222
/* Commit */
223223
db_end_transaction(0);
224224
225225
/* Do an autosync push, if requested */
226
- if( !isPrivate ) autosync_loop(SYNC_PUSH, db_get_int("autosync-tries",1),0);
226
+ if( !isPrivate ) autosync_loop(SYNC_PUSH, 0, "branch");
227227
}
228228
229229
/*
230230
** Create a TEMP table named "tmp_brlist" with 7 columns:
231231
**
232232
--- src/branch.c
+++ src/branch.c
@@ -221,11 +221,11 @@
221
222 /* Commit */
223 db_end_transaction(0);
224
225 /* Do an autosync push, if requested */
226 if( !isPrivate ) autosync_loop(SYNC_PUSH, db_get_int("autosync-tries",1),0);
227 }
228
229 /*
230 ** Create a TEMP table named "tmp_brlist" with 7 columns:
231 **
232
--- src/branch.c
+++ src/branch.c
@@ -221,11 +221,11 @@
221
222 /* Commit */
223 db_end_transaction(0);
224
225 /* Do an autosync push, if requested */
226 if( !isPrivate ) autosync_loop(SYNC_PUSH, 0, "branch");
227 }
228
229 /*
230 ** Create a TEMP table named "tmp_brlist" with 7 columns:
231 **
232
+1 -1
--- src/builtin.c
+++ src/builtin.c
@@ -156,11 +156,11 @@
156156
}
157157
return;
158158
}
159159
160160
/*
161
-** WEBPAGE: builtin
161
+** WEBPAGE: builtin loadavg-exempt
162162
**
163163
** Return one of many built-in content files. Query parameters:
164164
**
165165
** name=FILENAME Return the single file whose name is FILENAME.
166166
** mimetype=TYPE Override the mimetype in the returned file to
167167
--- src/builtin.c
+++ src/builtin.c
@@ -156,11 +156,11 @@
156 }
157 return;
158 }
159
160 /*
161 ** WEBPAGE: builtin
162 **
163 ** Return one of many built-in content files. Query parameters:
164 **
165 ** name=FILENAME Return the single file whose name is FILENAME.
166 ** mimetype=TYPE Override the mimetype in the returned file to
167
--- src/builtin.c
+++ src/builtin.c
@@ -156,11 +156,11 @@
156 }
157 return;
158 }
159
160 /*
161 ** WEBPAGE: builtin loadavg-exempt
162 **
163 ** Return one of many built-in content files. Query parameters:
164 **
165 ** name=FILENAME Return the single file whose name is FILENAME.
166 ** mimetype=TYPE Override the mimetype in the returned file to
167
+6 -6
--- src/chat.c
+++ src/chat.c
@@ -128,11 +128,11 @@
128128
**
129129
** This is the name of the builtin sound file to use for the alert tone.
130130
** The value must be the name of a builtin WAV file.
131131
*/
132132
/*
133
-** WEBPAGE: chat
133
+** WEBPAGE: chat loadavg-exempt
134134
**
135135
** Start up a browser-based chat session.
136136
**
137137
** This is the main page that humans use to access the chatroom. Simply
138138
** point a web-browser at /chat and the screen fills with the latest
@@ -343,11 +343,11 @@
343343
}
344344
fossil_free(zTime);
345345
}
346346
347347
/*
348
-** WEBPAGE: chat-send hidden
348
+** WEBPAGE: chat-send hidden loadavg-exempt
349349
**
350350
** This page receives (via XHR) a new chat-message and/or a new file
351351
** to be entered into the chat history.
352352
**
353353
** On success it responds with an empty response: the new message
@@ -449,11 +449,11 @@
449449
fossil_free(zOut);
450450
}
451451
}
452452
453453
/*
454
-** WEBPAGE: chat-poll hidden
454
+** WEBPAGE: chat-poll hidden loadavg-exempt
455455
**
456456
** The chat page generated by /chat using an XHR to this page to
457457
** request new chat content. A typical invocation is:
458458
**
459459
** /chat-poll/N
@@ -668,11 +668,11 @@
668668
cgi_set_content(&json);
669669
return;
670670
}
671671
672672
/*
673
-** WEBPAGE: chat-fetch-one hidden
673
+** WEBPAGE: chat-fetch-one hidden loadavg-exempt
674674
**
675675
** /chat-fetch-one/N
676676
**
677677
** Fetches a single message with the given ID, if available.
678678
**
@@ -745,11 +745,11 @@
745745
}
746746
db_finalize(&q);
747747
}
748748
749749
/*
750
-** WEBPAGE: chat-download hidden
750
+** WEBPAGE: chat-download hidden loadavg-exempt
751751
**
752752
** Download the CHAT.FILE attachment associated with a single chat
753753
** entry. The "name" query parameter begins with an integer that
754754
** identifies the particular chat message. The integer may be followed
755755
** by a / and a filename, which will indicate to the browser to use
@@ -778,11 +778,11 @@
778778
cgi_set_content(&r);
779779
}
780780
781781
782782
/*
783
-** WEBPAGE: chat-delete hidden
783
+** WEBPAGE: chat-delete hidden loadavg-exempt
784784
**
785785
** Delete the chat entry identified by the name query parameter.
786786
** Invoking fetch("chat-delete/"+msgid) from javascript in the client
787787
** will delete a chat entry from the CHAT table.
788788
**
789789
--- src/chat.c
+++ src/chat.c
@@ -128,11 +128,11 @@
128 **
129 ** This is the name of the builtin sound file to use for the alert tone.
130 ** The value must be the name of a builtin WAV file.
131 */
132 /*
133 ** WEBPAGE: chat
134 **
135 ** Start up a browser-based chat session.
136 **
137 ** This is the main page that humans use to access the chatroom. Simply
138 ** point a web-browser at /chat and the screen fills with the latest
@@ -343,11 +343,11 @@
343 }
344 fossil_free(zTime);
345 }
346
347 /*
348 ** WEBPAGE: chat-send hidden
349 **
350 ** This page receives (via XHR) a new chat-message and/or a new file
351 ** to be entered into the chat history.
352 **
353 ** On success it responds with an empty response: the new message
@@ -449,11 +449,11 @@
449 fossil_free(zOut);
450 }
451 }
452
453 /*
454 ** WEBPAGE: chat-poll hidden
455 **
456 ** The chat page generated by /chat using an XHR to this page to
457 ** request new chat content. A typical invocation is:
458 **
459 ** /chat-poll/N
@@ -668,11 +668,11 @@
668 cgi_set_content(&json);
669 return;
670 }
671
672 /*
673 ** WEBPAGE: chat-fetch-one hidden
674 **
675 ** /chat-fetch-one/N
676 **
677 ** Fetches a single message with the given ID, if available.
678 **
@@ -745,11 +745,11 @@
745 }
746 db_finalize(&q);
747 }
748
749 /*
750 ** WEBPAGE: chat-download hidden
751 **
752 ** Download the CHAT.FILE attachment associated with a single chat
753 ** entry. The "name" query parameter begins with an integer that
754 ** identifies the particular chat message. The integer may be followed
755 ** by a / and a filename, which will indicate to the browser to use
@@ -778,11 +778,11 @@
778 cgi_set_content(&r);
779 }
780
781
782 /*
783 ** WEBPAGE: chat-delete hidden
784 **
785 ** Delete the chat entry identified by the name query parameter.
786 ** Invoking fetch("chat-delete/"+msgid) from javascript in the client
787 ** will delete a chat entry from the CHAT table.
788 **
789
--- src/chat.c
+++ src/chat.c
@@ -128,11 +128,11 @@
128 **
129 ** This is the name of the builtin sound file to use for the alert tone.
130 ** The value must be the name of a builtin WAV file.
131 */
132 /*
133 ** WEBPAGE: chat loadavg-exempt
134 **
135 ** Start up a browser-based chat session.
136 **
137 ** This is the main page that humans use to access the chatroom. Simply
138 ** point a web-browser at /chat and the screen fills with the latest
@@ -343,11 +343,11 @@
343 }
344 fossil_free(zTime);
345 }
346
347 /*
348 ** WEBPAGE: chat-send hidden loadavg-exempt
349 **
350 ** This page receives (via XHR) a new chat-message and/or a new file
351 ** to be entered into the chat history.
352 **
353 ** On success it responds with an empty response: the new message
@@ -449,11 +449,11 @@
449 fossil_free(zOut);
450 }
451 }
452
453 /*
454 ** WEBPAGE: chat-poll hidden loadavg-exempt
455 **
456 ** The chat page generated by /chat using an XHR to this page to
457 ** request new chat content. A typical invocation is:
458 **
459 ** /chat-poll/N
@@ -668,11 +668,11 @@
668 cgi_set_content(&json);
669 return;
670 }
671
672 /*
673 ** WEBPAGE: chat-fetch-one hidden loadavg-exempt
674 **
675 ** /chat-fetch-one/N
676 **
677 ** Fetches a single message with the given ID, if available.
678 **
@@ -745,11 +745,11 @@
745 }
746 db_finalize(&q);
747 }
748
749 /*
750 ** WEBPAGE: chat-download hidden loadavg-exempt
751 **
752 ** Download the CHAT.FILE attachment associated with a single chat
753 ** entry. The "name" query parameter begins with an integer that
754 ** identifies the particular chat message. The integer may be followed
755 ** by a / and a filename, which will indicate to the browser to use
@@ -778,11 +778,11 @@
778 cgi_set_content(&r);
779 }
780
781
782 /*
783 ** WEBPAGE: chat-delete hidden loadavg-exempt
784 **
785 ** Delete the chat entry identified by the name query parameter.
786 ** Invoking fetch("chat-delete/"+msgid) from javascript in the client
787 ** will delete a chat entry from the CHAT table.
788 **
789
+6 -6
--- src/chat.c
+++ src/chat.c
@@ -128,11 +128,11 @@
128128
**
129129
** This is the name of the builtin sound file to use for the alert tone.
130130
** The value must be the name of a builtin WAV file.
131131
*/
132132
/*
133
-** WEBPAGE: chat
133
+** WEBPAGE: chat loadavg-exempt
134134
**
135135
** Start up a browser-based chat session.
136136
**
137137
** This is the main page that humans use to access the chatroom. Simply
138138
** point a web-browser at /chat and the screen fills with the latest
@@ -343,11 +343,11 @@
343343
}
344344
fossil_free(zTime);
345345
}
346346
347347
/*
348
-** WEBPAGE: chat-send hidden
348
+** WEBPAGE: chat-send hidden loadavg-exempt
349349
**
350350
** This page receives (via XHR) a new chat-message and/or a new file
351351
** to be entered into the chat history.
352352
**
353353
** On success it responds with an empty response: the new message
@@ -449,11 +449,11 @@
449449
fossil_free(zOut);
450450
}
451451
}
452452
453453
/*
454
-** WEBPAGE: chat-poll hidden
454
+** WEBPAGE: chat-poll hidden loadavg-exempt
455455
**
456456
** The chat page generated by /chat using an XHR to this page to
457457
** request new chat content. A typical invocation is:
458458
**
459459
** /chat-poll/N
@@ -668,11 +668,11 @@
668668
cgi_set_content(&json);
669669
return;
670670
}
671671
672672
/*
673
-** WEBPAGE: chat-fetch-one hidden
673
+** WEBPAGE: chat-fetch-one hidden loadavg-exempt
674674
**
675675
** /chat-fetch-one/N
676676
**
677677
** Fetches a single message with the given ID, if available.
678678
**
@@ -745,11 +745,11 @@
745745
}
746746
db_finalize(&q);
747747
}
748748
749749
/*
750
-** WEBPAGE: chat-download hidden
750
+** WEBPAGE: chat-download hidden loadavg-exempt
751751
**
752752
** Download the CHAT.FILE attachment associated with a single chat
753753
** entry. The "name" query parameter begins with an integer that
754754
** identifies the particular chat message. The integer may be followed
755755
** by a / and a filename, which will indicate to the browser to use
@@ -778,11 +778,11 @@
778778
cgi_set_content(&r);
779779
}
780780
781781
782782
/*
783
-** WEBPAGE: chat-delete hidden
783
+** WEBPAGE: chat-delete hidden loadavg-exempt
784784
**
785785
** Delete the chat entry identified by the name query parameter.
786786
** Invoking fetch("chat-delete/"+msgid) from javascript in the client
787787
** will delete a chat entry from the CHAT table.
788788
**
789789
--- src/chat.c
+++ src/chat.c
@@ -128,11 +128,11 @@
128 **
129 ** This is the name of the builtin sound file to use for the alert tone.
130 ** The value must be the name of a builtin WAV file.
131 */
132 /*
133 ** WEBPAGE: chat
134 **
135 ** Start up a browser-based chat session.
136 **
137 ** This is the main page that humans use to access the chatroom. Simply
138 ** point a web-browser at /chat and the screen fills with the latest
@@ -343,11 +343,11 @@
343 }
344 fossil_free(zTime);
345 }
346
347 /*
348 ** WEBPAGE: chat-send hidden
349 **
350 ** This page receives (via XHR) a new chat-message and/or a new file
351 ** to be entered into the chat history.
352 **
353 ** On success it responds with an empty response: the new message
@@ -449,11 +449,11 @@
449 fossil_free(zOut);
450 }
451 }
452
453 /*
454 ** WEBPAGE: chat-poll hidden
455 **
456 ** The chat page generated by /chat using an XHR to this page to
457 ** request new chat content. A typical invocation is:
458 **
459 ** /chat-poll/N
@@ -668,11 +668,11 @@
668 cgi_set_content(&json);
669 return;
670 }
671
672 /*
673 ** WEBPAGE: chat-fetch-one hidden
674 **
675 ** /chat-fetch-one/N
676 **
677 ** Fetches a single message with the given ID, if available.
678 **
@@ -745,11 +745,11 @@
745 }
746 db_finalize(&q);
747 }
748
749 /*
750 ** WEBPAGE: chat-download hidden
751 **
752 ** Download the CHAT.FILE attachment associated with a single chat
753 ** entry. The "name" query parameter begins with an integer that
754 ** identifies the particular chat message. The integer may be followed
755 ** by a / and a filename, which will indicate to the browser to use
@@ -778,11 +778,11 @@
778 cgi_set_content(&r);
779 }
780
781
782 /*
783 ** WEBPAGE: chat-delete hidden
784 **
785 ** Delete the chat entry identified by the name query parameter.
786 ** Invoking fetch("chat-delete/"+msgid) from javascript in the client
787 ** will delete a chat entry from the CHAT table.
788 **
789
--- src/chat.c
+++ src/chat.c
@@ -128,11 +128,11 @@
128 **
129 ** This is the name of the builtin sound file to use for the alert tone.
130 ** The value must be the name of a builtin WAV file.
131 */
132 /*
133 ** WEBPAGE: chat loadavg-exempt
134 **
135 ** Start up a browser-based chat session.
136 **
137 ** This is the main page that humans use to access the chatroom. Simply
138 ** point a web-browser at /chat and the screen fills with the latest
@@ -343,11 +343,11 @@
343 }
344 fossil_free(zTime);
345 }
346
347 /*
348 ** WEBPAGE: chat-send hidden loadavg-exempt
349 **
350 ** This page receives (via XHR) a new chat-message and/or a new file
351 ** to be entered into the chat history.
352 **
353 ** On success it responds with an empty response: the new message
@@ -449,11 +449,11 @@
449 fossil_free(zOut);
450 }
451 }
452
453 /*
454 ** WEBPAGE: chat-poll hidden loadavg-exempt
455 **
456 ** The chat page generated by /chat using an XHR to this page to
457 ** request new chat content. A typical invocation is:
458 **
459 ** /chat-poll/N
@@ -668,11 +668,11 @@
668 cgi_set_content(&json);
669 return;
670 }
671
672 /*
673 ** WEBPAGE: chat-fetch-one hidden loadavg-exempt
674 **
675 ** /chat-fetch-one/N
676 **
677 ** Fetches a single message with the given ID, if available.
678 **
@@ -745,11 +745,11 @@
745 }
746 db_finalize(&q);
747 }
748
749 /*
750 ** WEBPAGE: chat-download hidden loadavg-exempt
751 **
752 ** Download the CHAT.FILE attachment associated with a single chat
753 ** entry. The "name" query parameter begins with an integer that
754 ** identifies the particular chat message. The integer may be followed
755 ** by a / and a filename, which will indicate to the browser to use
@@ -778,11 +778,11 @@
778 cgi_set_content(&r);
779 }
780
781
782 /*
783 ** WEBPAGE: chat-delete hidden loadavg-exempt
784 **
785 ** Delete the chat entry identified by the name query parameter.
786 ** Invoking fetch("chat-delete/"+msgid) from javascript in the client
787 ** will delete a chat entry from the CHAT table.
788 **
789
+3 -4
--- src/checkin.c
+++ src/checkin.c
@@ -2346,11 +2346,11 @@
23462346
if( !g.markPrivate ){
23472347
int syncFlags = SYNC_PULL;
23482348
if( vid!=0 && !allowFork && !forceFlag ){
23492349
syncFlags |= SYNC_CKIN_LOCK;
23502350
}
2351
- if( autosync_loop(syncFlags, db_get_int("autosync-tries", 1), 1) ){
2351
+ if( autosync_loop(syncFlags, 1, "commit") ){
23522352
fossil_exit(1);
23532353
}
23542354
}
23552355
23562356
/* So that older versions of Fossil (that do not understand delta-
@@ -2552,11 +2552,11 @@
25522552
if( !g.markPrivate && vid!=0 && !allowFork && !forceFlag ){
25532553
/* Do another auto-pull, renewing the check-in lock. Then set
25542554
** bRecheck so that we loop back above to verify that the check-in
25552555
** is still not against a closed branch and still won't fork. */
25562556
int syncFlags = SYNC_PULL|SYNC_CKIN_LOCK;
2557
- if( autosync_loop(syncFlags, db_get_int("autosync-tries", 1), 1) ){
2557
+ if( autosync_loop(syncFlags, 1, "commit") ){
25582558
fossil_fatal("Auto-pull failed. Commit aborted.");
25592559
}
25602560
bRecheck = 1;
25612561
}
25622562
}else{
@@ -2865,14 +2865,13 @@
28652865
free(zManifestFile);
28662866
}
28672867
28682868
if( !g.markPrivate ){
28692869
int syncFlags = SYNC_PUSH | SYNC_PULL | SYNC_IFABLE;
2870
- int nTries = db_get_int("autosync-tries",1);
2871
- autosync_loop(syncFlags, nTries, 0);
2870
+ autosync_loop(syncFlags, 0, "commit");
28722871
}
28732872
if( count_nonbranch_children(vid)>1 ){
28742873
fossil_print("**** warning: a fork has occurred *****\n");
28752874
}else{
28762875
leaf_ambiguity_warning(nvid,nvid);
28772876
}
28782877
}
28792878
--- src/checkin.c
+++ src/checkin.c
@@ -2346,11 +2346,11 @@
2346 if( !g.markPrivate ){
2347 int syncFlags = SYNC_PULL;
2348 if( vid!=0 && !allowFork && !forceFlag ){
2349 syncFlags |= SYNC_CKIN_LOCK;
2350 }
2351 if( autosync_loop(syncFlags, db_get_int("autosync-tries", 1), 1) ){
2352 fossil_exit(1);
2353 }
2354 }
2355
2356 /* So that older versions of Fossil (that do not understand delta-
@@ -2552,11 +2552,11 @@
2552 if( !g.markPrivate && vid!=0 && !allowFork && !forceFlag ){
2553 /* Do another auto-pull, renewing the check-in lock. Then set
2554 ** bRecheck so that we loop back above to verify that the check-in
2555 ** is still not against a closed branch and still won't fork. */
2556 int syncFlags = SYNC_PULL|SYNC_CKIN_LOCK;
2557 if( autosync_loop(syncFlags, db_get_int("autosync-tries", 1), 1) ){
2558 fossil_fatal("Auto-pull failed. Commit aborted.");
2559 }
2560 bRecheck = 1;
2561 }
2562 }else{
@@ -2865,14 +2865,13 @@
2865 free(zManifestFile);
2866 }
2867
2868 if( !g.markPrivate ){
2869 int syncFlags = SYNC_PUSH | SYNC_PULL | SYNC_IFABLE;
2870 int nTries = db_get_int("autosync-tries",1);
2871 autosync_loop(syncFlags, nTries, 0);
2872 }
2873 if( count_nonbranch_children(vid)>1 ){
2874 fossil_print("**** warning: a fork has occurred *****\n");
2875 }else{
2876 leaf_ambiguity_warning(nvid,nvid);
2877 }
2878 }
2879
--- src/checkin.c
+++ src/checkin.c
@@ -2346,11 +2346,11 @@
2346 if( !g.markPrivate ){
2347 int syncFlags = SYNC_PULL;
2348 if( vid!=0 && !allowFork && !forceFlag ){
2349 syncFlags |= SYNC_CKIN_LOCK;
2350 }
2351 if( autosync_loop(syncFlags, 1, "commit") ){
2352 fossil_exit(1);
2353 }
2354 }
2355
2356 /* So that older versions of Fossil (that do not understand delta-
@@ -2552,11 +2552,11 @@
2552 if( !g.markPrivate && vid!=0 && !allowFork && !forceFlag ){
2553 /* Do another auto-pull, renewing the check-in lock. Then set
2554 ** bRecheck so that we loop back above to verify that the check-in
2555 ** is still not against a closed branch and still won't fork. */
2556 int syncFlags = SYNC_PULL|SYNC_CKIN_LOCK;
2557 if( autosync_loop(syncFlags, 1, "commit") ){
2558 fossil_fatal("Auto-pull failed. Commit aborted.");
2559 }
2560 bRecheck = 1;
2561 }
2562 }else{
@@ -2865,14 +2865,13 @@
2865 free(zManifestFile);
2866 }
2867
2868 if( !g.markPrivate ){
2869 int syncFlags = SYNC_PUSH | SYNC_PULL | SYNC_IFABLE;
2870 autosync_loop(syncFlags, 0, "commit");
 
2871 }
2872 if( count_nonbranch_children(vid)>1 ){
2873 fossil_print("**** warning: a fork has occurred *****\n");
2874 }else{
2875 leaf_ambiguity_warning(nvid,nvid);
2876 }
2877 }
2878
+93 -22
--- src/db.c
+++ src/db.c
@@ -3478,11 +3478,58 @@
34783478
va_end(ap);
34793479
db_unset(zName/*works-like:"x"*/, iGlobal);
34803480
fossil_free(zName);
34813481
}
34823482
3483
-
3483
+/*
3484
+** Get a setting that is tailored to subsystem. The return value is
3485
+** NULL if the setting does not exist, or a string obtained from mprintf()
3486
+** if the setting is available.
3487
+**
3488
+** The actual setting can be a comma-separated list of values of the form:
3489
+**
3490
+** * VALUE
3491
+** * SUBSYSTEM=VALUE
3492
+**
3493
+** A VALUE without the SUBSYSTEM= prefix is the default. This routine
3494
+** returns the VALUE that with the matching SUBSYSTEM, or the default
3495
+** VALUE if there is no match.
3496
+*/
3497
+char *db_get_for_subsystem(const char *zName, const char *zSubsys){
3498
+ int nSubsys;
3499
+ char *zToFree = 0;
3500
+ char *zCopy;
3501
+ char *zNext;
3502
+ char *zResult = 0;
3503
+ const char *zSetting = db_get(zName, 0);
3504
+ if( zSetting==0 ) return 0;
3505
+ zCopy = zToFree = fossil_strdup(zSetting);
3506
+ if( zSubsys==0 ) zSubsys = "";
3507
+ nSubsys = (int)strlen(zSubsys);
3508
+ while( zCopy ){
3509
+ zNext = strchr(zCopy, ',');
3510
+ if( zNext ){
3511
+ zNext[0] = 0;
3512
+ do{ zNext++; }while( fossil_isspace(zNext[0]) );
3513
+ if( zNext[0]==0 ) zNext = 0;
3514
+ }
3515
+ if( strchr(zCopy,'=')==0 ){
3516
+ if( zResult==0 ) zResult = zCopy;
3517
+ }else
3518
+ if( nSubsys
3519
+ && strncmp(zCopy, zSubsys, nSubsys)==0
3520
+ && zCopy[nSubsys]=='='
3521
+ ){
3522
+ zResult = &zCopy[nSubsys+1];
3523
+ break;
3524
+ }
3525
+ zCopy = zNext;
3526
+ }
3527
+ if( zResult ) zResult = fossil_strdup(zResult);
3528
+ fossil_free(zToFree);
3529
+ return zResult;
3530
+}
34843531
34853532
#if INTERFACE
34863533
/* Manifest generation flags */
34873534
#define MFESTFLG_RAW 0x01
34883535
#define MFESTFLG_UUID 0x02
@@ -3624,16 +3671,19 @@
36243671
** -f|--force Continue with the open even if the working directory is
36253672
** not empty.
36263673
** --force-missing Force opening a repository with missing content
36273674
** -k|--keep Only modify the manifest and manifest.uuid files
36283675
** --nested Allow opening a repository inside an opened checkout
3629
-** --nosync Do not auto-sync the repository prior to opening
3676
+** --nosync Do not auto-sync the repository prior to opening even
3677
+** if the autosync setting is on.
36303678
** --repodir DIR If REPOSITORY is a URI that will be cloned, store
36313679
** the clone in DIR rather than in "."
36323680
** --setmtime Set timestamps of all files to match their SCM-side
36333681
** times (the timestamp of the last checkin which modified
36343682
** them).
3683
+** --sync Auto-sync prior to opening even if the autosync setting
3684
+** is off.
36353685
** --verbose If passed a URI then this flag is passed on to the clone
36363686
** operation, otherwise it has no effect.
36373687
** --workdir DIR Use DIR as the working directory instead of ".". The DIR
36383688
** directory is created if it does not exist.
36393689
**
@@ -3651,11 +3701,10 @@
36513701
const char *zRepo = 0; /* Name of the repository file */
36523702
const char *zRepoDir = 0; /* --repodir value */
36533703
char *zPwd; /* Initial working directory */
36543704
int isUri = 0; /* True if REPOSITORY is a URI */
36553705
int nLocal; /* Number of preexisting files in cwd */
3656
- int bNosync = 0; /* --nosync. Omit auto-sync */
36573706
int bVerbose = 0; /* --verbose option for clone */
36583707
36593708
url_proxy_options();
36603709
emptyFlag = find_option("empty",0,0)!=0;
36613710
keepFlag = find_option("keep","k",0)!=0;
@@ -3662,15 +3711,14 @@
36623711
forceMissingFlag = find_option("force-missing",0,0)!=0;
36633712
allowNested = find_option("nested",0,0)!=0;
36643713
setmtimeFlag = find_option("setmtime",0,0)!=0;
36653714
zWorkDir = find_option("workdir",0,1);
36663715
zRepoDir = find_option("repodir",0,1);
3667
- bForce = find_option("force","f",0)!=0;
3668
- bNosync = find_option("nosync",0,0)!=0;
3716
+ bForce = find_option("force","f",0)!=0;
3717
+ if( find_option("nosync",0,0) ) g.fNoSync = 1;
36693718
bVerbose = find_option("verbose",0,0)!=0;
36703719
zPwd = file_getcwd(0,0);
3671
-
36723720
36733721
/* We should be done with options.. */
36743722
verify_all_options();
36753723
36763724
if( g.argc!=3 && g.argc!=4 ){
@@ -3756,23 +3804,21 @@
37563804
fossil_fatal("the --repodir option only makes sense if the REPOSITORY "
37573805
"argument is a URI that begins with http:, https:, ssh:, "
37583806
"or file:");
37593807
}
37603808
3809
+ db_open_config(0,0);
37613810
db_open_repository(zRepo);
37623811
37633812
/* Figure out which revision to open. */
37643813
if( !emptyFlag ){
37653814
if( g.argc==4 ){
37663815
g.zOpenRevision = g.argv[3];
37673816
}else if( db_exists("SELECT 1 FROM event WHERE type='ci'") ){
37683817
g.zOpenRevision = db_get("main-branch", 0);
37693818
}
3770
- if( !bNosync
3771
- && autosync_loop(SYNC_PULL, db_get_int("autosync-tries", 1), 1)
3772
- && !bForce
3773
- ){
3819
+ if( autosync_loop(SYNC_PULL, !bForce, "open") && !bForce ){
37743820
fossil_fatal("unable to auto-sync the repository");
37753821
}
37763822
}
37773823
37783824
@@ -3949,17 +3995,19 @@
39493995
** However, a value of 1 causes the visited/unvisited colors of hyperlinks
39503996
** to stop working on Safari-derived web browsers. When this setting is 2,
39513997
** the hyperlinks work better on Safari, but more robots are able to sneak
39523998
** in.
39533999
*/
3954
-/* SETTING: auto-hyperlink-delay width=16 default=0
4000
+/*
4001
+** SETTING: auto-hyperlink-delay width=16 default=0
39554002
**
39564003
** When the auto-hyperlink setting is 1, the javascript that runs to set
39574004
** the href= attributes of hyperlinks delays by this many milliseconds
39584005
** after the page load. Suggested values: 50 to 200.
39594006
*/
3960
-/* Setting: auto-hyperlink-mouseover boolean default=off
4007
+/*
4008
+** SETTING: auto-hyperlink-mouseover boolean default=off
39614009
**
39624010
** When the auto-hyperlink setting is 1 and this setting is on, the
39634011
** javascript that runs to set the href= attributes of hyperlinks waits
39644012
** until either a mousedown or mousemove event is seen. This helps
39654013
** to distinguish real users from robots. For maximum robot defense,
@@ -3970,20 +4018,30 @@
39704018
** If enabled, automatically pull the shunning list
39714019
** from a server to which the client autosyncs.
39724020
*/
39734021
/*
39744022
** SETTING: autosync width=16 default=on
3975
-** This setting can be a boolean value (0, 1, on, off, true, false)
3976
-** or "pullonly" or "all".
4023
+** This setting determines when autosync occurs. The setting is a
4024
+** string that provides a lot of flexibility for determining when and
4025
+** when not to autosync. Examples:
4026
+**
4027
+** on Always autosync for command where autosync
4028
+** makes sense ("commit", "merge", "open", "update")
4029
+**
4030
+** off Never autosync.
4031
+**
4032
+** pullonly Only to pull autosyncs
4033
+**
4034
+** on,open=off Autosync for most commands, but not for "open"
4035
+**
4036
+** off,commit=pullonly Do not autosync, except do a pull before each
4037
+** "commit", presumably to avoid undesirable
4038
+** forks.
39774039
**
3978
-** If not false, automatically pull prior to commit
3979
-** or update and automatically push after commit or
3980
-** tag or branch creation. Except, if the value is
3981
-** "pullonly" then only pull operations occur automatically.
3982
-** Normally, only the default remote is used, but if the
3983
-** value is "all" then push/pull operations occur on all
3984
-** remotes.
4040
+** The syntax is a comma-separated list of VALUE and COMMAND=VALUE entries.
4041
+** A plain VALUE entry is the default that is used if no COMMAND matches.
4042
+** Otherwise, the VALUE of the matching command is used.
39854043
*/
39864044
/*
39874045
** SETTING: autosync-tries width=16 default=1
39884046
** If autosync is enabled setting this to a value greater
39894047
** than zero will cause autosync to try no more than this
@@ -4558,10 +4616,13 @@
45584616
*/
45594617
void setting_cmd(void){
45604618
int i;
45614619
int globalFlag = find_option("global","g",0)!=0;
45624620
int exactFlag = find_option("exact",0,0)!=0;
4621
+ /* Undocumented "--test-for-subsystem SUBSYS" option used to test
4622
+ ** the db_get_for_subsystem() interface: */
4623
+ const char *zSubsys = find_option("test-for-subsystem",0,1);
45634624
int unsetFlag = g.argv[1][0]=='u';
45644625
int nSetting;
45654626
const Setting *aSetting = setting_info(&nSetting);
45664627
find_repository_option();
45674628
verify_all_options();
@@ -4622,11 +4683,21 @@
46224683
if( exactFlag ){
46234684
if( fossil_strcmp(pSetting->name,zName)!=0 ) break;
46244685
}else{
46254686
if( fossil_strncmp(pSetting->name,zName,n)!=0 ) break;
46264687
}
4627
- print_setting(pSetting);
4688
+ if( zSubsys ){
4689
+ char *zValue = db_get_for_subsystem(pSetting->name, zSubsys);
4690
+ fossil_print("%s (subsystem %s) ->", pSetting->name, zSubsys);
4691
+ if( zValue ){
4692
+ fossil_print(" [%s]", zValue);
4693
+ fossil_free(zValue);
4694
+ }
4695
+ fossil_print("\n");
4696
+ }else{
4697
+ print_setting(pSetting);
4698
+ }
46284699
pSetting++;
46294700
}
46304701
}
46314702
}else{
46324703
usage("?PROPERTY? ?VALUE? ?-global?");
46334704
--- src/db.c
+++ src/db.c
@@ -3478,11 +3478,58 @@
3478 va_end(ap);
3479 db_unset(zName/*works-like:"x"*/, iGlobal);
3480 fossil_free(zName);
3481 }
3482
3483
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3484
3485 #if INTERFACE
3486 /* Manifest generation flags */
3487 #define MFESTFLG_RAW 0x01
3488 #define MFESTFLG_UUID 0x02
@@ -3624,16 +3671,19 @@
3624 ** -f|--force Continue with the open even if the working directory is
3625 ** not empty.
3626 ** --force-missing Force opening a repository with missing content
3627 ** -k|--keep Only modify the manifest and manifest.uuid files
3628 ** --nested Allow opening a repository inside an opened checkout
3629 ** --nosync Do not auto-sync the repository prior to opening
 
3630 ** --repodir DIR If REPOSITORY is a URI that will be cloned, store
3631 ** the clone in DIR rather than in "."
3632 ** --setmtime Set timestamps of all files to match their SCM-side
3633 ** times (the timestamp of the last checkin which modified
3634 ** them).
 
 
3635 ** --verbose If passed a URI then this flag is passed on to the clone
3636 ** operation, otherwise it has no effect.
3637 ** --workdir DIR Use DIR as the working directory instead of ".". The DIR
3638 ** directory is created if it does not exist.
3639 **
@@ -3651,11 +3701,10 @@
3651 const char *zRepo = 0; /* Name of the repository file */
3652 const char *zRepoDir = 0; /* --repodir value */
3653 char *zPwd; /* Initial working directory */
3654 int isUri = 0; /* True if REPOSITORY is a URI */
3655 int nLocal; /* Number of preexisting files in cwd */
3656 int bNosync = 0; /* --nosync. Omit auto-sync */
3657 int bVerbose = 0; /* --verbose option for clone */
3658
3659 url_proxy_options();
3660 emptyFlag = find_option("empty",0,0)!=0;
3661 keepFlag = find_option("keep","k",0)!=0;
@@ -3662,15 +3711,14 @@
3662 forceMissingFlag = find_option("force-missing",0,0)!=0;
3663 allowNested = find_option("nested",0,0)!=0;
3664 setmtimeFlag = find_option("setmtime",0,0)!=0;
3665 zWorkDir = find_option("workdir",0,1);
3666 zRepoDir = find_option("repodir",0,1);
3667 bForce = find_option("force","f",0)!=0;
3668 bNosync = find_option("nosync",0,0)!=0;
3669 bVerbose = find_option("verbose",0,0)!=0;
3670 zPwd = file_getcwd(0,0);
3671
3672
3673 /* We should be done with options.. */
3674 verify_all_options();
3675
3676 if( g.argc!=3 && g.argc!=4 ){
@@ -3756,23 +3804,21 @@
3756 fossil_fatal("the --repodir option only makes sense if the REPOSITORY "
3757 "argument is a URI that begins with http:, https:, ssh:, "
3758 "or file:");
3759 }
3760
 
3761 db_open_repository(zRepo);
3762
3763 /* Figure out which revision to open. */
3764 if( !emptyFlag ){
3765 if( g.argc==4 ){
3766 g.zOpenRevision = g.argv[3];
3767 }else if( db_exists("SELECT 1 FROM event WHERE type='ci'") ){
3768 g.zOpenRevision = db_get("main-branch", 0);
3769 }
3770 if( !bNosync
3771 && autosync_loop(SYNC_PULL, db_get_int("autosync-tries", 1), 1)
3772 && !bForce
3773 ){
3774 fossil_fatal("unable to auto-sync the repository");
3775 }
3776 }
3777
3778
@@ -3949,17 +3995,19 @@
3949 ** However, a value of 1 causes the visited/unvisited colors of hyperlinks
3950 ** to stop working on Safari-derived web browsers. When this setting is 2,
3951 ** the hyperlinks work better on Safari, but more robots are able to sneak
3952 ** in.
3953 */
3954 /* SETTING: auto-hyperlink-delay width=16 default=0
 
3955 **
3956 ** When the auto-hyperlink setting is 1, the javascript that runs to set
3957 ** the href= attributes of hyperlinks delays by this many milliseconds
3958 ** after the page load. Suggested values: 50 to 200.
3959 */
3960 /* Setting: auto-hyperlink-mouseover boolean default=off
 
3961 **
3962 ** When the auto-hyperlink setting is 1 and this setting is on, the
3963 ** javascript that runs to set the href= attributes of hyperlinks waits
3964 ** until either a mousedown or mousemove event is seen. This helps
3965 ** to distinguish real users from robots. For maximum robot defense,
@@ -3970,20 +4018,30 @@
3970 ** If enabled, automatically pull the shunning list
3971 ** from a server to which the client autosyncs.
3972 */
3973 /*
3974 ** SETTING: autosync width=16 default=on
3975 ** This setting can be a boolean value (0, 1, on, off, true, false)
3976 ** or "pullonly" or "all".
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3977 **
3978 ** If not false, automatically pull prior to commit
3979 ** or update and automatically push after commit or
3980 ** tag or branch creation. Except, if the value is
3981 ** "pullonly" then only pull operations occur automatically.
3982 ** Normally, only the default remote is used, but if the
3983 ** value is "all" then push/pull operations occur on all
3984 ** remotes.
3985 */
3986 /*
3987 ** SETTING: autosync-tries width=16 default=1
3988 ** If autosync is enabled setting this to a value greater
3989 ** than zero will cause autosync to try no more than this
@@ -4558,10 +4616,13 @@
4558 */
4559 void setting_cmd(void){
4560 int i;
4561 int globalFlag = find_option("global","g",0)!=0;
4562 int exactFlag = find_option("exact",0,0)!=0;
 
 
 
4563 int unsetFlag = g.argv[1][0]=='u';
4564 int nSetting;
4565 const Setting *aSetting = setting_info(&nSetting);
4566 find_repository_option();
4567 verify_all_options();
@@ -4622,11 +4683,21 @@
4622 if( exactFlag ){
4623 if( fossil_strcmp(pSetting->name,zName)!=0 ) break;
4624 }else{
4625 if( fossil_strncmp(pSetting->name,zName,n)!=0 ) break;
4626 }
4627 print_setting(pSetting);
 
 
 
 
 
 
 
 
 
 
4628 pSetting++;
4629 }
4630 }
4631 }else{
4632 usage("?PROPERTY? ?VALUE? ?-global?");
4633
--- src/db.c
+++ src/db.c
@@ -3478,11 +3478,58 @@
3478 va_end(ap);
3479 db_unset(zName/*works-like:"x"*/, iGlobal);
3480 fossil_free(zName);
3481 }
3482
3483 /*
3484 ** Get a setting that is tailored to subsystem. The return value is
3485 ** NULL if the setting does not exist, or a string obtained from mprintf()
3486 ** if the setting is available.
3487 **
3488 ** The actual setting can be a comma-separated list of values of the form:
3489 **
3490 ** * VALUE
3491 ** * SUBSYSTEM=VALUE
3492 **
3493 ** A VALUE without the SUBSYSTEM= prefix is the default. This routine
3494 ** returns the VALUE that with the matching SUBSYSTEM, or the default
3495 ** VALUE if there is no match.
3496 */
3497 char *db_get_for_subsystem(const char *zName, const char *zSubsys){
3498 int nSubsys;
3499 char *zToFree = 0;
3500 char *zCopy;
3501 char *zNext;
3502 char *zResult = 0;
3503 const char *zSetting = db_get(zName, 0);
3504 if( zSetting==0 ) return 0;
3505 zCopy = zToFree = fossil_strdup(zSetting);
3506 if( zSubsys==0 ) zSubsys = "";
3507 nSubsys = (int)strlen(zSubsys);
3508 while( zCopy ){
3509 zNext = strchr(zCopy, ',');
3510 if( zNext ){
3511 zNext[0] = 0;
3512 do{ zNext++; }while( fossil_isspace(zNext[0]) );
3513 if( zNext[0]==0 ) zNext = 0;
3514 }
3515 if( strchr(zCopy,'=')==0 ){
3516 if( zResult==0 ) zResult = zCopy;
3517 }else
3518 if( nSubsys
3519 && strncmp(zCopy, zSubsys, nSubsys)==0
3520 && zCopy[nSubsys]=='='
3521 ){
3522 zResult = &zCopy[nSubsys+1];
3523 break;
3524 }
3525 zCopy = zNext;
3526 }
3527 if( zResult ) zResult = fossil_strdup(zResult);
3528 fossil_free(zToFree);
3529 return zResult;
3530 }
3531
3532 #if INTERFACE
3533 /* Manifest generation flags */
3534 #define MFESTFLG_RAW 0x01
3535 #define MFESTFLG_UUID 0x02
@@ -3624,16 +3671,19 @@
3671 ** -f|--force Continue with the open even if the working directory is
3672 ** not empty.
3673 ** --force-missing Force opening a repository with missing content
3674 ** -k|--keep Only modify the manifest and manifest.uuid files
3675 ** --nested Allow opening a repository inside an opened checkout
3676 ** --nosync Do not auto-sync the repository prior to opening even
3677 ** if the autosync setting is on.
3678 ** --repodir DIR If REPOSITORY is a URI that will be cloned, store
3679 ** the clone in DIR rather than in "."
3680 ** --setmtime Set timestamps of all files to match their SCM-side
3681 ** times (the timestamp of the last checkin which modified
3682 ** them).
3683 ** --sync Auto-sync prior to opening even if the autosync setting
3684 ** is off.
3685 ** --verbose If passed a URI then this flag is passed on to the clone
3686 ** operation, otherwise it has no effect.
3687 ** --workdir DIR Use DIR as the working directory instead of ".". The DIR
3688 ** directory is created if it does not exist.
3689 **
@@ -3651,11 +3701,10 @@
3701 const char *zRepo = 0; /* Name of the repository file */
3702 const char *zRepoDir = 0; /* --repodir value */
3703 char *zPwd; /* Initial working directory */
3704 int isUri = 0; /* True if REPOSITORY is a URI */
3705 int nLocal; /* Number of preexisting files in cwd */
 
3706 int bVerbose = 0; /* --verbose option for clone */
3707
3708 url_proxy_options();
3709 emptyFlag = find_option("empty",0,0)!=0;
3710 keepFlag = find_option("keep","k",0)!=0;
@@ -3662,15 +3711,14 @@
3711 forceMissingFlag = find_option("force-missing",0,0)!=0;
3712 allowNested = find_option("nested",0,0)!=0;
3713 setmtimeFlag = find_option("setmtime",0,0)!=0;
3714 zWorkDir = find_option("workdir",0,1);
3715 zRepoDir = find_option("repodir",0,1);
3716 bForce = find_option("force","f",0)!=0;
3717 if( find_option("nosync",0,0) ) g.fNoSync = 1;
3718 bVerbose = find_option("verbose",0,0)!=0;
3719 zPwd = file_getcwd(0,0);
 
3720
3721 /* We should be done with options.. */
3722 verify_all_options();
3723
3724 if( g.argc!=3 && g.argc!=4 ){
@@ -3756,23 +3804,21 @@
3804 fossil_fatal("the --repodir option only makes sense if the REPOSITORY "
3805 "argument is a URI that begins with http:, https:, ssh:, "
3806 "or file:");
3807 }
3808
3809 db_open_config(0,0);
3810 db_open_repository(zRepo);
3811
3812 /* Figure out which revision to open. */
3813 if( !emptyFlag ){
3814 if( g.argc==4 ){
3815 g.zOpenRevision = g.argv[3];
3816 }else if( db_exists("SELECT 1 FROM event WHERE type='ci'") ){
3817 g.zOpenRevision = db_get("main-branch", 0);
3818 }
3819 if( autosync_loop(SYNC_PULL, !bForce, "open") && !bForce ){
 
 
 
3820 fossil_fatal("unable to auto-sync the repository");
3821 }
3822 }
3823
3824
@@ -3949,17 +3995,19 @@
3995 ** However, a value of 1 causes the visited/unvisited colors of hyperlinks
3996 ** to stop working on Safari-derived web browsers. When this setting is 2,
3997 ** the hyperlinks work better on Safari, but more robots are able to sneak
3998 ** in.
3999 */
4000 /*
4001 ** SETTING: auto-hyperlink-delay width=16 default=0
4002 **
4003 ** When the auto-hyperlink setting is 1, the javascript that runs to set
4004 ** the href= attributes of hyperlinks delays by this many milliseconds
4005 ** after the page load. Suggested values: 50 to 200.
4006 */
4007 /*
4008 ** SETTING: auto-hyperlink-mouseover boolean default=off
4009 **
4010 ** When the auto-hyperlink setting is 1 and this setting is on, the
4011 ** javascript that runs to set the href= attributes of hyperlinks waits
4012 ** until either a mousedown or mousemove event is seen. This helps
4013 ** to distinguish real users from robots. For maximum robot defense,
@@ -3970,20 +4018,30 @@
4018 ** If enabled, automatically pull the shunning list
4019 ** from a server to which the client autosyncs.
4020 */
4021 /*
4022 ** SETTING: autosync width=16 default=on
4023 ** This setting determines when autosync occurs. The setting is a
4024 ** string that provides a lot of flexibility for determining when and
4025 ** when not to autosync. Examples:
4026 **
4027 ** on Always autosync for command where autosync
4028 ** makes sense ("commit", "merge", "open", "update")
4029 **
4030 ** off Never autosync.
4031 **
4032 ** pullonly Only to pull autosyncs
4033 **
4034 ** on,open=off Autosync for most commands, but not for "open"
4035 **
4036 ** off,commit=pullonly Do not autosync, except do a pull before each
4037 ** "commit", presumably to avoid undesirable
4038 ** forks.
4039 **
4040 ** The syntax is a comma-separated list of VALUE and COMMAND=VALUE entries.
4041 ** A plain VALUE entry is the default that is used if no COMMAND matches.
4042 ** Otherwise, the VALUE of the matching command is used.
 
 
 
 
4043 */
4044 /*
4045 ** SETTING: autosync-tries width=16 default=1
4046 ** If autosync is enabled setting this to a value greater
4047 ** than zero will cause autosync to try no more than this
@@ -4558,10 +4616,13 @@
4616 */
4617 void setting_cmd(void){
4618 int i;
4619 int globalFlag = find_option("global","g",0)!=0;
4620 int exactFlag = find_option("exact",0,0)!=0;
4621 /* Undocumented "--test-for-subsystem SUBSYS" option used to test
4622 ** the db_get_for_subsystem() interface: */
4623 const char *zSubsys = find_option("test-for-subsystem",0,1);
4624 int unsetFlag = g.argv[1][0]=='u';
4625 int nSetting;
4626 const Setting *aSetting = setting_info(&nSetting);
4627 find_repository_option();
4628 verify_all_options();
@@ -4622,11 +4683,21 @@
4683 if( exactFlag ){
4684 if( fossil_strcmp(pSetting->name,zName)!=0 ) break;
4685 }else{
4686 if( fossil_strncmp(pSetting->name,zName,n)!=0 ) break;
4687 }
4688 if( zSubsys ){
4689 char *zValue = db_get_for_subsystem(pSetting->name, zSubsys);
4690 fossil_print("%s (subsystem %s) ->", pSetting->name, zSubsys);
4691 if( zValue ){
4692 fossil_print(" [%s]", zValue);
4693 fossil_free(zValue);
4694 }
4695 fossil_print("\n");
4696 }else{
4697 print_setting(pSetting);
4698 }
4699 pSetting++;
4700 }
4701 }
4702 }else{
4703 usage("?PROPERTY? ?VALUE? ?-global?");
4704
--- src/default.css
+++ src/default.css
@@ -1665,10 +1665,86 @@
16651665
}
16661666
16671667
.monospace {
16681668
font-family: monospace;
16691669
}
1670
+
1671
+div.markdown > ol.footnotes {
1672
+ font-size: 90%;
1673
+}
1674
+div.markdown > ol.footnotes > li {
1675
+ margin-bottom: 0.5em;
1676
+}
1677
+div.markdown ol.footnotes > li.fn-joined > sup.fn-joined {
1678
+ color: gray;
1679
+ font-family: monospace;
1680
+}
1681
+div.markdown ol.footnotes > li.fn-joined > sup.fn-joined::after {
1682
+ content: "(joined from multiple locations) ";
1683
+}
1684
+div.markdown ol.footnotes > li.fn-misreference {
1685
+ margin-top: 0.75em;
1686
+ margin-bottom: 0.75em;
1687
+}
1688
+div.markdown ol.footnotes > li.fn-toodeep > i,
1689
+div.markdown ol.footnotes > li.fn-misreference,
1690
+div.markdown ol.footnotes > li.fn-unreferenced {
1691
+ color: gray;
1692
+}
1693
+div.markdown ol.footnotes > li.fn-misreference > span {
1694
+ color: red;
1695
+}
1696
+div.markdown ol.footnotes > li.fn-misreference > span::after {
1697
+ content: " (use of undefined label).";
1698
+}
1699
+div.markdown ol.footnotes > li.fn-unreferenced {
1700
+ padding-left: 0.5em;
1701
+}
1702
+div.markdown ol.footnotes > li.fn-unreferenced > code {
1703
+ color: red;
1704
+}
1705
+div.markdown ol.footnotes > li.fn-unreferenced > i::after {
1706
+ content: " was defined but is not referenced";
1707
+}
1708
+div.markdown ol.footnotes > li.fn-toodeep > i::after {
1709
+ content: " depth of nesting of inline footnotes exceeded the limit";
1710
+}
1711
+div.markdown ol.footnotes > li.fn-toodeep > pre,
1712
+div.markdown ol.footnotes > li.fn-unreferenced > pre {
1713
+ color: gray;
1714
+ font-size: 85%;
1715
+ padding-left: 0.5em;
1716
+ margin-top: 0.25em;
1717
+ border-left: 2px solid red;
1718
+}
1719
+div.markdown ol.footnotes > li.fn-toodeep > pre {
1720
+ margin-left: 0.5em;
1721
+}
1722
+div.markdown > ol.footnotes > li > .fn-backrefs {
1723
+ margin-right: 0.5em;
1724
+ font-weight: bold;
1725
+}
1726
+div.markdown > ol.footnotes > li > .fn-backrefs > a,
1727
+div.markdown sup.noteref > a {
1728
+ padding-left: 2px;
1729
+ padding-right: 2px;
1730
+}
1731
+div.markdown sup.noteref.misref,
1732
+div.markdown sup.noteref.misref > a {
1733
+ color: red;
1734
+ font-size: 90%;
1735
+}
1736
+div.markdown sup.noteref > a:target,
1737
+div.markdown span.notescope:target > sup.noteref > a,
1738
+div.markdown span.notescope:hover > sup.noteref > a,
1739
+div.markdown > ol.footnotes > li > .fn-backrefs > a:target {
1740
+ background: gold;
1741
+}
1742
+div.markdown span.notescope:hover,
1743
+div.markdown span.notescope:target {
1744
+ border-bottom: 2px solid gold;
1745
+}
16701746
16711747
/* Objects in the "desktoponly" class are invisible on mobile */
16721748
@media screen and (max-width: 600px) {
16731749
.desktoponly {
16741750
display: none;
16751751
--- src/default.css
+++ src/default.css
@@ -1665,10 +1665,86 @@
1665 }
1666
1667 .monospace {
1668 font-family: monospace;
1669 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1670
1671 /* Objects in the "desktoponly" class are invisible on mobile */
1672 @media screen and (max-width: 600px) {
1673 .desktoponly {
1674 display: none;
1675
--- src/default.css
+++ src/default.css
@@ -1665,10 +1665,86 @@
1665 }
1666
1667 .monospace {
1668 font-family: monospace;
1669 }
1670
1671 div.markdown > ol.footnotes {
1672 font-size: 90%;
1673 }
1674 div.markdown > ol.footnotes > li {
1675 margin-bottom: 0.5em;
1676 }
1677 div.markdown ol.footnotes > li.fn-joined > sup.fn-joined {
1678 color: gray;
1679 font-family: monospace;
1680 }
1681 div.markdown ol.footnotes > li.fn-joined > sup.fn-joined::after {
1682 content: "(joined from multiple locations) ";
1683 }
1684 div.markdown ol.footnotes > li.fn-misreference {
1685 margin-top: 0.75em;
1686 margin-bottom: 0.75em;
1687 }
1688 div.markdown ol.footnotes > li.fn-toodeep > i,
1689 div.markdown ol.footnotes > li.fn-misreference,
1690 div.markdown ol.footnotes > li.fn-unreferenced {
1691 color: gray;
1692 }
1693 div.markdown ol.footnotes > li.fn-misreference > span {
1694 color: red;
1695 }
1696 div.markdown ol.footnotes > li.fn-misreference > span::after {
1697 content: " (use of undefined label).";
1698 }
1699 div.markdown ol.footnotes > li.fn-unreferenced {
1700 padding-left: 0.5em;
1701 }
1702 div.markdown ol.footnotes > li.fn-unreferenced > code {
1703 color: red;
1704 }
1705 div.markdown ol.footnotes > li.fn-unreferenced > i::after {
1706 content: " was defined but is not referenced";
1707 }
1708 div.markdown ol.footnotes > li.fn-toodeep > i::after {
1709 content: " depth of nesting of inline footnotes exceeded the limit";
1710 }
1711 div.markdown ol.footnotes > li.fn-toodeep > pre,
1712 div.markdown ol.footnotes > li.fn-unreferenced > pre {
1713 color: gray;
1714 font-size: 85%;
1715 padding-left: 0.5em;
1716 margin-top: 0.25em;
1717 border-left: 2px solid red;
1718 }
1719 div.markdown ol.footnotes > li.fn-toodeep > pre {
1720 margin-left: 0.5em;
1721 }
1722 div.markdown > ol.footnotes > li > .fn-backrefs {
1723 margin-right: 0.5em;
1724 font-weight: bold;
1725 }
1726 div.markdown > ol.footnotes > li > .fn-backrefs > a,
1727 div.markdown sup.noteref > a {
1728 padding-left: 2px;
1729 padding-right: 2px;
1730 }
1731 div.markdown sup.noteref.misref,
1732 div.markdown sup.noteref.misref > a {
1733 color: red;
1734 font-size: 90%;
1735 }
1736 div.markdown sup.noteref > a:target,
1737 div.markdown span.notescope:target > sup.noteref > a,
1738 div.markdown span.notescope:hover > sup.noteref > a,
1739 div.markdown > ol.footnotes > li > .fn-backrefs > a:target {
1740 background: gold;
1741 }
1742 div.markdown span.notescope:hover,
1743 div.markdown span.notescope:target {
1744 border-bottom: 2px solid gold;
1745 }
1746
1747 /* Objects in the "desktoponly" class are invisible on mobile */
1748 @media screen and (max-width: 600px) {
1749 .desktoponly {
1750 display: none;
1751
+1 -1
--- src/diff.c
+++ src/diff.c
@@ -3594,11 +3594,11 @@
35943594
35953595
/* Gather query parameters */
35963596
login_check_credentials();
35973597
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
35983598
if( exclude_spiders() ) return;
3599
- load_control();
3599
+ fossil_nice_default();
36003600
zFilename = P("filename");
36013601
zRevision = PD("checkin",0);
36023602
zOrigin = P("origin");
36033603
zLimit = P("limit");
36043604
showLog = PB("log");
36053605
--- src/diff.c
+++ src/diff.c
@@ -3594,11 +3594,11 @@
3594
3595 /* Gather query parameters */
3596 login_check_credentials();
3597 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
3598 if( exclude_spiders() ) return;
3599 load_control();
3600 zFilename = P("filename");
3601 zRevision = PD("checkin",0);
3602 zOrigin = P("origin");
3603 zLimit = P("limit");
3604 showLog = PB("log");
3605
--- src/diff.c
+++ src/diff.c
@@ -3594,11 +3594,11 @@
3594
3595 /* Gather query parameters */
3596 login_check_credentials();
3597 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
3598 if( exclude_spiders() ) return;
3599 fossil_nice_default();
3600 zFilename = P("filename");
3601 zRevision = PD("checkin",0);
3602 zOrigin = P("origin");
3603 zLimit = P("limit");
3604 showLog = PB("log");
3605
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1182,9 +1182,10 @@
11821182
DiffConfig DCfg;
11831183
login_check_credentials();
11841184
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
11851185
if( zFrom==0 || zTo==0 ) fossil_redirect_home();
11861186
1187
+ fossil_nice_default();
11871188
cgi_set_content_type("text/plain");
11881189
diff_config_init(&DCfg, DIFF_VERBOSE);
11891190
diff_two_versions(zFrom, zTo, &DCfg, 0);
11901191
}
11911192
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1182,9 +1182,10 @@
1182 DiffConfig DCfg;
1183 login_check_credentials();
1184 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
1185 if( zFrom==0 || zTo==0 ) fossil_redirect_home();
1186
 
1187 cgi_set_content_type("text/plain");
1188 diff_config_init(&DCfg, DIFF_VERBOSE);
1189 diff_two_versions(zFrom, zTo, &DCfg, 0);
1190 }
1191
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1182,9 +1182,10 @@
1182 DiffConfig DCfg;
1183 login_check_credentials();
1184 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
1185 if( zFrom==0 || zTo==0 ) fossil_redirect_home();
1186
1187 fossil_nice_default();
1188 cgi_set_content_type("text/plain");
1189 diff_config_init(&DCfg, DIFF_VERBOSE);
1190 diff_two_versions(zFrom, zTo, &DCfg, 0);
1191 }
1192
+13 -12
--- src/dispatch.c
+++ src/dispatch.c
@@ -38,22 +38,23 @@
3838
3939
/***************************************************************************
4040
** These macros must match similar macros in mkindex.c
4141
** Allowed values for CmdOrPage.eCmdFlags.
4242
*/
43
-#define CMDFLAG_1ST_TIER 0x0001 /* Most important commands */
44
-#define CMDFLAG_2ND_TIER 0x0002 /* Obscure and seldom used commands */
45
-#define CMDFLAG_TEST 0x0004 /* Commands for testing only */
46
-#define CMDFLAG_WEBPAGE 0x0008 /* Web pages */
47
-#define CMDFLAG_COMMAND 0x0010 /* A command */
48
-#define CMDFLAG_SETTING 0x0020 /* A setting */
49
-#define CMDFLAG_VERSIONABLE 0x0040 /* A versionable setting */
50
-#define CMDFLAG_BLOCKTEXT 0x0080 /* Multi-line text setting */
51
-#define CMDFLAG_BOOLEAN 0x0100 /* A boolean setting */
52
-#define CMDFLAG_RAWCONTENT 0x0200 /* Do not interpret POST content */
53
-/* NOTE: 0x0400 = CMDFLAG_SENSITIVE in mkindex.c! */
54
-#define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */
43
+#define CMDFLAG_1ST_TIER 0x0001 /* Most important commands */
44
+#define CMDFLAG_2ND_TIER 0x0002 /* Obscure and seldom used commands */
45
+#define CMDFLAG_TEST 0x0004 /* Commands for testing only */
46
+#define CMDFLAG_WEBPAGE 0x0008 /* Web pages */
47
+#define CMDFLAG_COMMAND 0x0010 /* A command */
48
+#define CMDFLAG_SETTING 0x0020 /* A setting */
49
+#define CMDFLAG_VERSIONABLE 0x0040 /* A versionable setting */
50
+#define CMDFLAG_BLOCKTEXT 0x0080 /* Multi-line text setting */
51
+#define CMDFLAG_BOOLEAN 0x0100 /* A boolean setting */
52
+#define CMDFLAG_RAWCONTENT 0x0200 /* Do not interpret POST content */
53
+/* NOTE: 0x0400 = CMDFLAG_SENSITIVE in mkindex.c! */
54
+#define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */
55
+#define CMDFLAG_LDAVG_EXEMPT 0x1000 /* Exempt from load_control() */
5556
/**************************************************************************/
5657
5758
/* Values for the 2nd parameter to dispatch_name_search() */
5859
#define CMDFLAG_ANY 0x0038 /* Match anything */
5960
#define CMDFLAG_PREFIX 0x0200 /* Prefix match is ok */
6061
--- src/dispatch.c
+++ src/dispatch.c
@@ -38,22 +38,23 @@
38
39 /***************************************************************************
40 ** These macros must match similar macros in mkindex.c
41 ** Allowed values for CmdOrPage.eCmdFlags.
42 */
43 #define CMDFLAG_1ST_TIER 0x0001 /* Most important commands */
44 #define CMDFLAG_2ND_TIER 0x0002 /* Obscure and seldom used commands */
45 #define CMDFLAG_TEST 0x0004 /* Commands for testing only */
46 #define CMDFLAG_WEBPAGE 0x0008 /* Web pages */
47 #define CMDFLAG_COMMAND 0x0010 /* A command */
48 #define CMDFLAG_SETTING 0x0020 /* A setting */
49 #define CMDFLAG_VERSIONABLE 0x0040 /* A versionable setting */
50 #define CMDFLAG_BLOCKTEXT 0x0080 /* Multi-line text setting */
51 #define CMDFLAG_BOOLEAN 0x0100 /* A boolean setting */
52 #define CMDFLAG_RAWCONTENT 0x0200 /* Do not interpret POST content */
53 /* NOTE: 0x0400 = CMDFLAG_SENSITIVE in mkindex.c! */
54 #define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */
 
55 /**************************************************************************/
56
57 /* Values for the 2nd parameter to dispatch_name_search() */
58 #define CMDFLAG_ANY 0x0038 /* Match anything */
59 #define CMDFLAG_PREFIX 0x0200 /* Prefix match is ok */
60
--- src/dispatch.c
+++ src/dispatch.c
@@ -38,22 +38,23 @@
38
39 /***************************************************************************
40 ** These macros must match similar macros in mkindex.c
41 ** Allowed values for CmdOrPage.eCmdFlags.
42 */
43 #define CMDFLAG_1ST_TIER 0x0001 /* Most important commands */
44 #define CMDFLAG_2ND_TIER 0x0002 /* Obscure and seldom used commands */
45 #define CMDFLAG_TEST 0x0004 /* Commands for testing only */
46 #define CMDFLAG_WEBPAGE 0x0008 /* Web pages */
47 #define CMDFLAG_COMMAND 0x0010 /* A command */
48 #define CMDFLAG_SETTING 0x0020 /* A setting */
49 #define CMDFLAG_VERSIONABLE 0x0040 /* A versionable setting */
50 #define CMDFLAG_BLOCKTEXT 0x0080 /* Multi-line text setting */
51 #define CMDFLAG_BOOLEAN 0x0100 /* A boolean setting */
52 #define CMDFLAG_RAWCONTENT 0x0200 /* Do not interpret POST content */
53 /* NOTE: 0x0400 = CMDFLAG_SENSITIVE in mkindex.c! */
54 #define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */
55 #define CMDFLAG_LDAVG_EXEMPT 0x1000 /* Exempt from load_control() */
56 /**************************************************************************/
57
58 /* Values for the 2nd parameter to dispatch_name_search() */
59 #define CMDFLAG_ANY 0x0038 /* Match anything */
60 #define CMDFLAG_PREFIX 0x0200 /* Prefix match is ok */
61
+30
--- src/encode.c
+++ src/encode.c
@@ -205,10 +205,40 @@
205205
** by this routine.
206206
*/
207207
char *urlize(const char *z, int n){
208208
return EncodeHttp(z, n, 0);
209209
}
210
+
211
+/*
212
+** If input string does not contain quotes (niether ' nor ")
213
+** then return the argument itself. Otherwise return a newly allocated
214
+** copy of input with all quotes %-escaped.
215
+*/
216
+const char* escape_quotes(const char *zIn){
217
+ char *zRet, *zOut;
218
+ size_t i, n = 0;
219
+ for(i=0; zIn[i]; i++){
220
+ if( zIn[i]== '"' || zIn[i]== '\'' ) n++;
221
+ }
222
+ if( !n ) return zIn;
223
+ zRet = zOut = fossil_malloc( i + 2*n + 1 );
224
+ for(i=0; zIn[i]; i++){
225
+ if( zIn[i]=='"' ){
226
+ *(zOut++) = '%';
227
+ *(zOut++) = '2';
228
+ *(zOut++) = '2';
229
+ }else if( zIn[i]=='\'' ){
230
+ *(zOut++) = '%';
231
+ *(zOut++) = '2';
232
+ *(zOut++) = '7';
233
+ }else{
234
+ *(zOut++) = zIn[i];
235
+ }
236
+ }
237
+ *zOut = 0;
238
+ return zRet;
239
+}
210240
211241
/*
212242
** Convert a single HEX digit to an integer
213243
*/
214244
static int AsciiToHex(int c){
215245
--- src/encode.c
+++ src/encode.c
@@ -205,10 +205,40 @@
205 ** by this routine.
206 */
207 char *urlize(const char *z, int n){
208 return EncodeHttp(z, n, 0);
209 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
210
211 /*
212 ** Convert a single HEX digit to an integer
213 */
214 static int AsciiToHex(int c){
215
--- src/encode.c
+++ src/encode.c
@@ -205,10 +205,40 @@
205 ** by this routine.
206 */
207 char *urlize(const char *z, int n){
208 return EncodeHttp(z, n, 0);
209 }
210
211 /*
212 ** If input string does not contain quotes (niether ' nor ")
213 ** then return the argument itself. Otherwise return a newly allocated
214 ** copy of input with all quotes %-escaped.
215 */
216 const char* escape_quotes(const char *zIn){
217 char *zRet, *zOut;
218 size_t i, n = 0;
219 for(i=0; zIn[i]; i++){
220 if( zIn[i]== '"' || zIn[i]== '\'' ) n++;
221 }
222 if( !n ) return zIn;
223 zRet = zOut = fossil_malloc( i + 2*n + 1 );
224 for(i=0; zIn[i]; i++){
225 if( zIn[i]=='"' ){
226 *(zOut++) = '%';
227 *(zOut++) = '2';
228 *(zOut++) = '2';
229 }else if( zIn[i]=='\'' ){
230 *(zOut++) = '%';
231 *(zOut++) = '2';
232 *(zOut++) = '7';
233 }else{
234 *(zOut++) = zIn[i];
235 }
236 }
237 *zOut = 0;
238 return zRet;
239 }
240
241 /*
242 ** Convert a single HEX digit to an integer
243 */
244 static int AsciiToHex(int c){
245
+20 -1
--- src/fuzz.c
+++ src/fuzz.c
@@ -59,10 +59,11 @@
5959
** Type of fuzzing:
6060
*/
6161
#define FUZZ_WIKI 0 /* The Fossil-Wiki formatter */
6262
#define FUZZ_MARKDOWN 1 /* The Markdown formatter */
6363
#define FUZZ_ARTIFACT 2 /* Fuzz the artifact parser */
64
+#define FUZZ_WIKI2 3 /* FOSSIL_WIKI and FOSSIL_MARKDOWN */
6465
#endif
6566
6667
/* The type of fuzzing to do */
6768
static int eFuzzType = FUZZ_WIKI;
6869
@@ -73,17 +74,32 @@
7374
blob_init(&in, 0, 0);
7475
blob_append(&in, (char*)aData, (int)nByte);
7576
blob_zero(&out);
7677
switch( eFuzzType ){
7778
case FUZZ_WIKI: {
79
+ wiki_convert(&in, &out, 0);
80
+ blob_reset(&out);
81
+ break;
82
+ }
83
+ case FUZZ_MARKDOWN: {
84
+ Blob title = BLOB_INITIALIZER;
85
+ blob_reset(&out);
86
+ markdown_to_html(&in, &title, &out);
87
+ blob_reset(&title);
88
+ break;
89
+ }
90
+ case FUZZ_WIKI2: {
7891
Blob title = BLOB_INITIALIZER;
7992
wiki_convert(&in, &out, 0);
8093
blob_reset(&out);
8194
markdown_to_html(&in, &title, &out);
8295
blob_reset(&title);
8396
break;
8497
}
98
+ case FUZZ_ARTIFACT:
99
+ fossil_fatal("FUZZ_ARTIFACT is not implemented.");
100
+ break;
85101
}
86102
blob_reset(&in);
87103
blob_reset(&out);
88104
return 0;
89105
}
@@ -98,10 +114,12 @@
98114
zType = find_option("fuzztype",0,1);
99115
if( zType==0 || fossil_strcmp(zType,"wiki")==0 ){
100116
eFuzzType = FUZZ_WIKI;
101117
}else if( fossil_strcmp(zType,"markdown")==0 ){
102118
eFuzzType = FUZZ_MARKDOWN;
119
+ }else if( fossil_strcmp(zType,"wiki2")==0 ){
120
+ eFuzzType = FUZZ_WIKI2;
103121
}else{
104122
fossil_fatal("unknown fuzz type: \"%s\"", zType);
105123
}
106124
}
107125
@@ -117,17 +135,18 @@
117135
}
118136
119137
/*
120138
** COMMAND: test-fuzz
121139
**
122
-** Usage: %fossil test-fuzz [-type TYPE] INPUTFILE...
140
+** Usage: %fossil test-fuzz [-fuzztype TYPE] INPUTFILE...
123141
**
124142
** Run a fuzz test using INPUTFILE as the test data. TYPE can be one of:
125143
**
126144
** wiki Fuzz the Fossil-wiki translator
127145
** markdown Fuzz the markdown translator
128146
** artifact Fuzz the artifact parser
147
+** wiki2 Fuzz the Fossil-wiki and markdown translator
129148
*/
130149
void fuzz_command(void){
131150
Blob in;
132151
int i;
133152
fuzzer_options();
134153
--- src/fuzz.c
+++ src/fuzz.c
@@ -59,10 +59,11 @@
59 ** Type of fuzzing:
60 */
61 #define FUZZ_WIKI 0 /* The Fossil-Wiki formatter */
62 #define FUZZ_MARKDOWN 1 /* The Markdown formatter */
63 #define FUZZ_ARTIFACT 2 /* Fuzz the artifact parser */
 
64 #endif
65
66 /* The type of fuzzing to do */
67 static int eFuzzType = FUZZ_WIKI;
68
@@ -73,17 +74,32 @@
73 blob_init(&in, 0, 0);
74 blob_append(&in, (char*)aData, (int)nByte);
75 blob_zero(&out);
76 switch( eFuzzType ){
77 case FUZZ_WIKI: {
 
 
 
 
 
 
 
 
 
 
 
 
78 Blob title = BLOB_INITIALIZER;
79 wiki_convert(&in, &out, 0);
80 blob_reset(&out);
81 markdown_to_html(&in, &title, &out);
82 blob_reset(&title);
83 break;
84 }
 
 
 
85 }
86 blob_reset(&in);
87 blob_reset(&out);
88 return 0;
89 }
@@ -98,10 +114,12 @@
98 zType = find_option("fuzztype",0,1);
99 if( zType==0 || fossil_strcmp(zType,"wiki")==0 ){
100 eFuzzType = FUZZ_WIKI;
101 }else if( fossil_strcmp(zType,"markdown")==0 ){
102 eFuzzType = FUZZ_MARKDOWN;
 
 
103 }else{
104 fossil_fatal("unknown fuzz type: \"%s\"", zType);
105 }
106 }
107
@@ -117,17 +135,18 @@
117 }
118
119 /*
120 ** COMMAND: test-fuzz
121 **
122 ** Usage: %fossil test-fuzz [-type TYPE] INPUTFILE...
123 **
124 ** Run a fuzz test using INPUTFILE as the test data. TYPE can be one of:
125 **
126 ** wiki Fuzz the Fossil-wiki translator
127 ** markdown Fuzz the markdown translator
128 ** artifact Fuzz the artifact parser
 
129 */
130 void fuzz_command(void){
131 Blob in;
132 int i;
133 fuzzer_options();
134
--- src/fuzz.c
+++ src/fuzz.c
@@ -59,10 +59,11 @@
59 ** Type of fuzzing:
60 */
61 #define FUZZ_WIKI 0 /* The Fossil-Wiki formatter */
62 #define FUZZ_MARKDOWN 1 /* The Markdown formatter */
63 #define FUZZ_ARTIFACT 2 /* Fuzz the artifact parser */
64 #define FUZZ_WIKI2 3 /* FOSSIL_WIKI and FOSSIL_MARKDOWN */
65 #endif
66
67 /* The type of fuzzing to do */
68 static int eFuzzType = FUZZ_WIKI;
69
@@ -73,17 +74,32 @@
74 blob_init(&in, 0, 0);
75 blob_append(&in, (char*)aData, (int)nByte);
76 blob_zero(&out);
77 switch( eFuzzType ){
78 case FUZZ_WIKI: {
79 wiki_convert(&in, &out, 0);
80 blob_reset(&out);
81 break;
82 }
83 case FUZZ_MARKDOWN: {
84 Blob title = BLOB_INITIALIZER;
85 blob_reset(&out);
86 markdown_to_html(&in, &title, &out);
87 blob_reset(&title);
88 break;
89 }
90 case FUZZ_WIKI2: {
91 Blob title = BLOB_INITIALIZER;
92 wiki_convert(&in, &out, 0);
93 blob_reset(&out);
94 markdown_to_html(&in, &title, &out);
95 blob_reset(&title);
96 break;
97 }
98 case FUZZ_ARTIFACT:
99 fossil_fatal("FUZZ_ARTIFACT is not implemented.");
100 break;
101 }
102 blob_reset(&in);
103 blob_reset(&out);
104 return 0;
105 }
@@ -98,10 +114,12 @@
114 zType = find_option("fuzztype",0,1);
115 if( zType==0 || fossil_strcmp(zType,"wiki")==0 ){
116 eFuzzType = FUZZ_WIKI;
117 }else if( fossil_strcmp(zType,"markdown")==0 ){
118 eFuzzType = FUZZ_MARKDOWN;
119 }else if( fossil_strcmp(zType,"wiki2")==0 ){
120 eFuzzType = FUZZ_WIKI2;
121 }else{
122 fossil_fatal("unknown fuzz type: \"%s\"", zType);
123 }
124 }
125
@@ -117,17 +135,18 @@
135 }
136
137 /*
138 ** COMMAND: test-fuzz
139 **
140 ** Usage: %fossil test-fuzz [-fuzztype TYPE] INPUTFILE...
141 **
142 ** Run a fuzz test using INPUTFILE as the test data. TYPE can be one of:
143 **
144 ** wiki Fuzz the Fossil-wiki translator
145 ** markdown Fuzz the markdown translator
146 ** artifact Fuzz the artifact parser
147 ** wiki2 Fuzz the Fossil-wiki and markdown translator
148 */
149 void fuzz_command(void){
150 Blob in;
151 int i;
152 fuzzer_options();
153
+1 -1
--- src/gzip.c
+++ src/gzip.c
@@ -29,11 +29,11 @@
2929
/*
3030
** State information for the GZIP file under construction.
3131
*/
3232
struct gzip_state {
3333
int eState; /* 0: idle 1: header 2: compressing */
34
- int iCRC; /* The checksum */
34
+ unsigned long iCRC; /* The checksum */
3535
z_stream stream; /* The working compressor */
3636
Blob out; /* Results stored here */
3737
} gzip;
3838
3939
/*
4040
--- src/gzip.c
+++ src/gzip.c
@@ -29,11 +29,11 @@
29 /*
30 ** State information for the GZIP file under construction.
31 */
32 struct gzip_state {
33 int eState; /* 0: idle 1: header 2: compressing */
34 int iCRC; /* The checksum */
35 z_stream stream; /* The working compressor */
36 Blob out; /* Results stored here */
37 } gzip;
38
39 /*
40
--- src/gzip.c
+++ src/gzip.c
@@ -29,11 +29,11 @@
29 /*
30 ** State information for the GZIP file under construction.
31 */
32 struct gzip_state {
33 int eState; /* 0: idle 1: header 2: compressing */
34 unsigned long iCRC; /* The checksum */
35 z_stream stream; /* The working compressor */
36 Blob out; /* Results stored here */
37 } gzip;
38
39 /*
40
+5 -2
--- src/info.c
+++ src/info.c
@@ -735,11 +735,14 @@
735735
style_copy_button(1, "name-br", 0, 0, "%z%h</a>",
736736
href("%R/timeline?r=%T&unhide",zTagName), zTagName);
737737
cgi_printf("\n");
738738
if( wiki_tagid2("branch",zTagName)!=0 ){
739739
blob_appendf(&wiki_read_links, " | %z%h</a>",
740
- href("%R/wiki?name=branch/%h",zTagName), zTagName);
740
+ href("%R/%s?name=branch/%h",
741
+ (g.perm.Write && g.perm.WrWiki)
742
+ ? "wikiedit" : "wiki",
743
+ zTagName), zTagName);
741744
}else if( g.perm.Write && g.perm.WrWiki ){
742745
blob_appendf(&wiki_add_links, " | %z%h</a>",
743746
href("%R/wikiedit?name=branch/%h",zTagName), zTagName);
744747
}
745748
}else{
@@ -1179,11 +1182,11 @@
11791182
int bInvert = PB("inv");
11801183
11811184
login_check_credentials();
11821185
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
11831186
login_anonymous_available();
1184
- load_control();
1187
+ fossil_nice_default();
11851188
blob_init(&qp, 0, 0);
11861189
diffType = preferred_diff_type();
11871190
zRe = P("regex");
11881191
if( zRe ) re_compile(&pRe, zRe, 0);
11891192
zBranch = P("branch");
11901193
--- src/info.c
+++ src/info.c
@@ -735,11 +735,14 @@
735 style_copy_button(1, "name-br", 0, 0, "%z%h</a>",
736 href("%R/timeline?r=%T&unhide",zTagName), zTagName);
737 cgi_printf("\n");
738 if( wiki_tagid2("branch",zTagName)!=0 ){
739 blob_appendf(&wiki_read_links, " | %z%h</a>",
740 href("%R/wiki?name=branch/%h",zTagName), zTagName);
 
 
 
741 }else if( g.perm.Write && g.perm.WrWiki ){
742 blob_appendf(&wiki_add_links, " | %z%h</a>",
743 href("%R/wikiedit?name=branch/%h",zTagName), zTagName);
744 }
745 }else{
@@ -1179,11 +1182,11 @@
1179 int bInvert = PB("inv");
1180
1181 login_check_credentials();
1182 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
1183 login_anonymous_available();
1184 load_control();
1185 blob_init(&qp, 0, 0);
1186 diffType = preferred_diff_type();
1187 zRe = P("regex");
1188 if( zRe ) re_compile(&pRe, zRe, 0);
1189 zBranch = P("branch");
1190
--- src/info.c
+++ src/info.c
@@ -735,11 +735,14 @@
735 style_copy_button(1, "name-br", 0, 0, "%z%h</a>",
736 href("%R/timeline?r=%T&unhide",zTagName), zTagName);
737 cgi_printf("\n");
738 if( wiki_tagid2("branch",zTagName)!=0 ){
739 blob_appendf(&wiki_read_links, " | %z%h</a>",
740 href("%R/%s?name=branch/%h",
741 (g.perm.Write && g.perm.WrWiki)
742 ? "wikiedit" : "wiki",
743 zTagName), zTagName);
744 }else if( g.perm.Write && g.perm.WrWiki ){
745 blob_appendf(&wiki_add_links, " | %z%h</a>",
746 href("%R/wikiedit?name=branch/%h",zTagName), zTagName);
747 }
748 }else{
@@ -1179,11 +1182,11 @@
1182 int bInvert = PB("inv");
1183
1184 login_check_credentials();
1185 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
1186 login_anonymous_available();
1187 fossil_nice_default();
1188 blob_init(&qp, 0, 0);
1189 diffType = preferred_diff_type();
1190 zRe = P("regex");
1191 if( zRe ) re_compile(&pRe, zRe, 0);
1192 zBranch = P("branch");
1193
+2 -2
--- src/json.c
+++ src/json.c
@@ -739,11 +739,11 @@
739739
** been called. In general, this function should be used sparingly,
740740
** e.g. from low-level support functions like fossil_warning() where
741741
** there is genuine uncertainty about whether (or not) the JSON setup
742742
** has already been called.
743743
*/
744
-int json_is_bootstrapped_early(){
744
+int json_is_bootstrapped_early(void){
745745
return ((g.json.gc.v != NULL) && (g.json.gc.a != NULL));
746746
}
747747
748748
/*
749749
** Initializes some JSON bits which need to be initialized relatively
@@ -758,11 +758,11 @@
758758
** up. e.g. it must not use cgi_parameter() and friends because this
759759
** must be called before those data are initialized.
760760
**
761761
** If called multiple times, calls after the first are a no-op.
762762
*/
763
-void json_bootstrap_early(){
763
+void json_bootstrap_early(void){
764764
cson_value * v;
765765
766766
if(g.json.gc.v!=NULL){
767767
/* Avoid multiple bootstrappings. */
768768
return;
769769
--- src/json.c
+++ src/json.c
@@ -739,11 +739,11 @@
739 ** been called. In general, this function should be used sparingly,
740 ** e.g. from low-level support functions like fossil_warning() where
741 ** there is genuine uncertainty about whether (or not) the JSON setup
742 ** has already been called.
743 */
744 int json_is_bootstrapped_early(){
745 return ((g.json.gc.v != NULL) && (g.json.gc.a != NULL));
746 }
747
748 /*
749 ** Initializes some JSON bits which need to be initialized relatively
@@ -758,11 +758,11 @@
758 ** up. e.g. it must not use cgi_parameter() and friends because this
759 ** must be called before those data are initialized.
760 **
761 ** If called multiple times, calls after the first are a no-op.
762 */
763 void json_bootstrap_early(){
764 cson_value * v;
765
766 if(g.json.gc.v!=NULL){
767 /* Avoid multiple bootstrappings. */
768 return;
769
--- src/json.c
+++ src/json.c
@@ -739,11 +739,11 @@
739 ** been called. In general, this function should be used sparingly,
740 ** e.g. from low-level support functions like fossil_warning() where
741 ** there is genuine uncertainty about whether (or not) the JSON setup
742 ** has already been called.
743 */
744 int json_is_bootstrapped_early(void){
745 return ((g.json.gc.v != NULL) && (g.json.gc.a != NULL));
746 }
747
748 /*
749 ** Initializes some JSON bits which need to be initialized relatively
@@ -758,11 +758,11 @@
758 ** up. e.g. it must not use cgi_parameter() and friends because this
759 ** must be called before those data are initialized.
760 **
761 ** If called multiple times, calls after the first are a no-op.
762 */
763 void json_bootstrap_early(void){
764 cson_value * v;
765
766 if(g.json.gc.v!=NULL){
767 /* Avoid multiple bootstrappings. */
768 return;
769
--- src/json_branch.c
+++ src/json_branch.c
@@ -306,14 +306,10 @@
306306
}
307307
308308
/* Commit */
309309
db_end_transaction(0);
310310
311
-#if 0 /* Do an autosync push, if requested */
312
- /* arugable for JSON mode? */
313
- if( !g.isHTTP && !isPrivate ) autosync(SYNC_PUSH);
314
-#endif
315311
return 0;
316312
}
317313
318314
319315
/*
320316
--- src/json_branch.c
+++ src/json_branch.c
@@ -306,14 +306,10 @@
306 }
307
308 /* Commit */
309 db_end_transaction(0);
310
311 #if 0 /* Do an autosync push, if requested */
312 /* arugable for JSON mode? */
313 if( !g.isHTTP && !isPrivate ) autosync(SYNC_PUSH);
314 #endif
315 return 0;
316 }
317
318
319 /*
320
--- src/json_branch.c
+++ src/json_branch.c
@@ -306,14 +306,10 @@
306 }
307
308 /* Commit */
309 db_end_transaction(0);
310
 
 
 
 
311 return 0;
312 }
313
314
315 /*
316
+11 -2
--- src/loadctrl.c
+++ src/loadctrl.c
@@ -45,16 +45,25 @@
4545
void loadavg_test_cmd(void){
4646
fossil_print("load-average: %f\n", load_average());
4747
}
4848
4949
/*
50
-** Abort the current operation of the load average of the host computer
51
-** is too high.
50
+** Abort the current page request if the load average of the host
51
+** computer is too high. Admin and Setup users are exempt from this
52
+** restriction.
5253
*/
5354
void load_control(void){
5455
double mxLoad = atof(db_get("max-loadavg", 0));
56
+#if 1
57
+ /* Disable this block only to test load restrictions */
5558
if( mxLoad<=0.0 || mxLoad>=load_average() ) return;
59
+
60
+ login_check_credentials();
61
+ if(g.perm.Admin || g.perm.Setup){
62
+ return;
63
+ }
64
+#endif
5665
5766
style_set_current_feature("test");
5867
style_header("Server Overload");
5968
@ <h2>The server load is currently too high.
6069
@ Please try again later.</h2>
6170
--- src/loadctrl.c
+++ src/loadctrl.c
@@ -45,16 +45,25 @@
45 void loadavg_test_cmd(void){
46 fossil_print("load-average: %f\n", load_average());
47 }
48
49 /*
50 ** Abort the current operation of the load average of the host computer
51 ** is too high.
 
52 */
53 void load_control(void){
54 double mxLoad = atof(db_get("max-loadavg", 0));
 
 
55 if( mxLoad<=0.0 || mxLoad>=load_average() ) return;
 
 
 
 
 
 
56
57 style_set_current_feature("test");
58 style_header("Server Overload");
59 @ <h2>The server load is currently too high.
60 @ Please try again later.</h2>
61
--- src/loadctrl.c
+++ src/loadctrl.c
@@ -45,16 +45,25 @@
45 void loadavg_test_cmd(void){
46 fossil_print("load-average: %f\n", load_average());
47 }
48
49 /*
50 ** Abort the current page request if the load average of the host
51 ** computer is too high. Admin and Setup users are exempt from this
52 ** restriction.
53 */
54 void load_control(void){
55 double mxLoad = atof(db_get("max-loadavg", 0));
56 #if 1
57 /* Disable this block only to test load restrictions */
58 if( mxLoad<=0.0 || mxLoad>=load_average() ) return;
59
60 login_check_credentials();
61 if(g.perm.Admin || g.perm.Setup){
62 return;
63 }
64 #endif
65
66 style_set_current_feature("test");
67 style_header("Server Overload");
68 @ <h2>The server load is currently too high.
69 @ Please try again later.</h2>
70
--- src/login.c
+++ src/login.c
@@ -985,10 +985,11 @@
985985
** g.userUid Database USER.UID value. Might be -1 for "nobody"
986986
** g.zLogin Database USER.LOGIN value. NULL for user "nobody"
987987
** g.perm Permissions granted to this user
988988
** g.anon Permissions that would be available to anonymous
989989
** g.isHuman True if the user is human, not a spider or robot
990
+** g.perm Populated based on user account's capabilities
990991
**
991992
*/
992993
void login_check_credentials(void){
993994
int uid = 0; /* User id */
994995
const char *zCookie; /* Text of the login cookie */
995996
--- src/login.c
+++ src/login.c
@@ -985,10 +985,11 @@
985 ** g.userUid Database USER.UID value. Might be -1 for "nobody"
986 ** g.zLogin Database USER.LOGIN value. NULL for user "nobody"
987 ** g.perm Permissions granted to this user
988 ** g.anon Permissions that would be available to anonymous
989 ** g.isHuman True if the user is human, not a spider or robot
 
990 **
991 */
992 void login_check_credentials(void){
993 int uid = 0; /* User id */
994 const char *zCookie; /* Text of the login cookie */
995
--- src/login.c
+++ src/login.c
@@ -985,10 +985,11 @@
985 ** g.userUid Database USER.UID value. Might be -1 for "nobody"
986 ** g.zLogin Database USER.LOGIN value. NULL for user "nobody"
987 ** g.perm Permissions granted to this user
988 ** g.anon Permissions that would be available to anonymous
989 ** g.isHuman True if the user is human, not a spider or robot
990 ** g.perm Populated based on user account's capabilities
991 **
992 */
993 void login_check_credentials(void){
994 int uid = 0; /* User id */
995 const char *zCookie; /* Text of the login cookie */
996
+11 -6
--- src/main.c
+++ src/main.c
@@ -324,10 +324,11 @@
324324
} reqPayload; /* request payload object (if any) */
325325
cson_array *warnings; /* response warnings */
326326
int timerId; /* fetched from fossil_timer_start() */
327327
} json;
328328
#endif /* FOSSIL_ENABLE_JSON */
329
+ int ftntsIssues[4]; /* Counts for misref, strayed, joined, overnested */
329330
int diffCnt[3]; /* Counts for DIFF_NUMSTAT: files, ins, del */
330331
};
331332
332333
/*
333334
** Macro for debugging:
@@ -1873,11 +1874,10 @@
18731874
18741875
/* At this point, the appropriate repository database file will have
18751876
** been opened.
18761877
*/
18771878
1878
-
18791879
/*
18801880
** Check to see if the first term of PATH_INFO specifies an
18811881
** alternative skin. This will be the case if the first term of
18821882
** PATH_INFO begins with "draftN/" where N is an integer between 1
18831883
** and 9. If so, activate the skin associated with that draft.
@@ -2016,16 +2016,21 @@
20162016
@ <h1>Server Configuration Error</h1>
20172017
@ <p>The database schema on the server is out-of-date. Please ask
20182018
@ the administrator to run <b>fossil rebuild</b>.</p>
20192019
}
20202020
}else{
2021
+ if(0==(CMDFLAG_LDAVG_EXEMPT & pCmd->eCmdFlags)){
2022
+ load_control();
2023
+ }
20212024
#ifdef FOSSIL_ENABLE_JSON
2022
- static int jsonOnce = 0;
2023
- if( jsonOnce==0 && g.json.isJsonMode!=0 ){
2024
- assert(json_is_bootstrapped_early());
2025
- json_bootstrap_late();
2026
- jsonOnce = 1;
2025
+ {
2026
+ static int jsonOnce = 0;
2027
+ if( jsonOnce==0 && g.json.isJsonMode!=0 ){
2028
+ assert(json_is_bootstrapped_early());
2029
+ json_bootstrap_late();
2030
+ jsonOnce = 1;
2031
+ }
20272032
}
20282033
#endif
20292034
if( (pCmd->eCmdFlags & CMDFLAG_RAWCONTENT)==0 ){
20302035
cgi_decode_post_parameters();
20312036
}
20322037
--- src/main.c
+++ src/main.c
@@ -324,10 +324,11 @@
324 } reqPayload; /* request payload object (if any) */
325 cson_array *warnings; /* response warnings */
326 int timerId; /* fetched from fossil_timer_start() */
327 } json;
328 #endif /* FOSSIL_ENABLE_JSON */
 
329 int diffCnt[3]; /* Counts for DIFF_NUMSTAT: files, ins, del */
330 };
331
332 /*
333 ** Macro for debugging:
@@ -1873,11 +1874,10 @@
1873
1874 /* At this point, the appropriate repository database file will have
1875 ** been opened.
1876 */
1877
1878
1879 /*
1880 ** Check to see if the first term of PATH_INFO specifies an
1881 ** alternative skin. This will be the case if the first term of
1882 ** PATH_INFO begins with "draftN/" where N is an integer between 1
1883 ** and 9. If so, activate the skin associated with that draft.
@@ -2016,16 +2016,21 @@
2016 @ <h1>Server Configuration Error</h1>
2017 @ <p>The database schema on the server is out-of-date. Please ask
2018 @ the administrator to run <b>fossil rebuild</b>.</p>
2019 }
2020 }else{
 
 
 
2021 #ifdef FOSSIL_ENABLE_JSON
2022 static int jsonOnce = 0;
2023 if( jsonOnce==0 && g.json.isJsonMode!=0 ){
2024 assert(json_is_bootstrapped_early());
2025 json_bootstrap_late();
2026 jsonOnce = 1;
 
 
2027 }
2028 #endif
2029 if( (pCmd->eCmdFlags & CMDFLAG_RAWCONTENT)==0 ){
2030 cgi_decode_post_parameters();
2031 }
2032
--- src/main.c
+++ src/main.c
@@ -324,10 +324,11 @@
324 } reqPayload; /* request payload object (if any) */
325 cson_array *warnings; /* response warnings */
326 int timerId; /* fetched from fossil_timer_start() */
327 } json;
328 #endif /* FOSSIL_ENABLE_JSON */
329 int ftntsIssues[4]; /* Counts for misref, strayed, joined, overnested */
330 int diffCnt[3]; /* Counts for DIFF_NUMSTAT: files, ins, del */
331 };
332
333 /*
334 ** Macro for debugging:
@@ -1873,11 +1874,10 @@
1874
1875 /* At this point, the appropriate repository database file will have
1876 ** been opened.
1877 */
1878
 
1879 /*
1880 ** Check to see if the first term of PATH_INFO specifies an
1881 ** alternative skin. This will be the case if the first term of
1882 ** PATH_INFO begins with "draftN/" where N is an integer between 1
1883 ** and 9. If so, activate the skin associated with that draft.
@@ -2016,16 +2016,21 @@
2016 @ <h1>Server Configuration Error</h1>
2017 @ <p>The database schema on the server is out-of-date. Please ask
2018 @ the administrator to run <b>fossil rebuild</b>.</p>
2019 }
2020 }else{
2021 if(0==(CMDFLAG_LDAVG_EXEMPT & pCmd->eCmdFlags)){
2022 load_control();
2023 }
2024 #ifdef FOSSIL_ENABLE_JSON
2025 {
2026 static int jsonOnce = 0;
2027 if( jsonOnce==0 && g.json.isJsonMode!=0 ){
2028 assert(json_is_bootstrapped_early());
2029 json_bootstrap_late();
2030 jsonOnce = 1;
2031 }
2032 }
2033 #endif
2034 if( (pCmd->eCmdFlags & CMDFLAG_RAWCONTENT)==0 ){
2035 cgi_decode_post_parameters();
2036 }
2037
+730 -135
--- src/markdown.c
+++ src/markdown.c
@@ -52,10 +52,11 @@
5252
/* mkd_renderer -- functions for rendering parsed data */
5353
struct mkd_renderer {
5454
/* document level callbacks */
5555
void (*prolog)(struct Blob *ob, void *opaque);
5656
void (*epilog)(struct Blob *ob, void *opaque);
57
+ void (*footnotes)(struct Blob *ob, const struct Blob *items, void *opaque);
5758
5859
/* block level callbacks - NULL skips the block */
5960
void (*blockcode)(struct Blob *ob, struct Blob *text, void *opaque);
6061
void (*blockquote)(struct Blob *ob, struct Blob *text, void *opaque);
6162
void (*blockhtml)(struct Blob *ob, struct Blob *text, void *opaque);
@@ -70,10 +71,12 @@
7071
void *opaque);
7172
void (*table_cell)(struct Blob *ob, struct Blob *text, int flags,
7273
void *opaque);
7374
void (*table_row)(struct Blob *ob, struct Blob *cells, int flags,
7475
void *opaque);
76
+ void (*footnote_item)(struct Blob *ob, const struct Blob *text,
77
+ int index, int nUsed, void *opaque);
7578
7679
/* span level callbacks - NULL or return 0 prints the span verbatim */
7780
int (*autolink)(struct Blob *ob, struct Blob *link,
7881
enum mkd_autolink type, void *opaque);
7982
int (*codespan)(struct Blob *ob, struct Blob *text, int nSep, void *opaque);
@@ -88,10 +91,12 @@
8891
int (*raw_html_tag)(struct Blob *ob, struct Blob *tag, void *opaque);
8992
int (*tagspan)(struct Blob *ob, struct Blob *ref, enum mkd_tagspan type,
9093
void *opaque);
9194
int (*triple_emphasis)(struct Blob *ob, struct Blob *text,
9295
char c, void *opaque);
96
+ int (*footnote_ref)(struct Blob *ob, const struct Blob *span,
97
+ const struct Blob *upc, int index, int locus, void *opaque);
9398
9499
/* low level callbacks - NULL copies input directly into the output */
95100
void (*entity)(struct Blob *ob, struct Blob *entity, void *opaque);
96101
void (*normal_text)(struct Blob *ob, struct Blob *text, void *opaque);
97102
@@ -122,31 +127,54 @@
122127
123128
/**********************
124129
* EXPORTED FUNCTIONS *
125130
**********************/
126131
127
-/* markdown -- parses the input buffer and renders it into the output buffer */
132
+/*
133
+** markdown -- parses the input buffer and renders it into the output buffer.
134
+*/
128135
void markdown(
129136
struct Blob *ob,
130
- struct Blob *ib,
137
+ const struct Blob *ib,
131138
const struct mkd_renderer *rndr);
132139
133140
134141
#endif /* INTERFACE */
135142
143
+#define BLOB_COUNT(pBlob,el_type) (blob_size(pBlob)/sizeof(el_type))
144
+#define COUNT_FOOTNOTES(pBlob) BLOB_COUNT(pBlob,struct footnote)
145
+#define CAST_AS_FOOTNOTES(pBlob) ((struct footnote*)blob_buffer(pBlob))
136146
137147
/***************
138148
* LOCAL TYPES *
139149
***************/
140150
141
-/* link_ref -- reference to a link */
151
+/*
152
+** link_ref -- reference to a link.
153
+*/
142154
struct link_ref {
143
- struct Blob id;
155
+ struct Blob id; /* must be the first field as in footnote struct */
144156
struct Blob link;
145157
struct Blob title;
146158
};
147159
160
+/*
161
+** A footnote's data.
162
+** id, text, and upc fields must be in that particular order.
163
+*/
164
+struct footnote {
165
+ struct Blob id; /* must be the first field as in link_ref struct */
166
+ struct Blob text; /* footnote's content that is rendered at the end */
167
+ struct Blob upc; /* user-provided classes .ASCII-alnum.or-hypen: */
168
+ int bRndred; /* indicates if `text` holds a rendered content */
169
+
170
+ int defno; /* serial number of definition, set during the first pass */
171
+ int index; /* set to the index within array after ordering by id */
172
+ int iMark; /* user-visible numeric marker, assigned upon the first use*/
173
+ int nUsed; /* counts references to this note, increments upon each use*/
174
+};
175
+#define FOOTNOTE_INITIALIZER {empty_blob,empty_blob,empty_blob, 0,0,0,0,0}
148176
149177
/* char_trigger -- function pointer to render active chars */
150178
/* returns the number of chars taken care of */
151179
/* data is the pointer of the beginning of the span */
152180
/* offset is the number of valid chars before data */
@@ -165,12 +193,19 @@
165193
struct Blob refs;
166194
char_trigger active_char[256];
167195
int iDepth; /* Depth of recursion */
168196
int nBlobCache; /* Number of entries in aBlobCache */
169197
struct Blob *aBlobCache[20]; /* Cache of Blobs available for reuse */
198
+
199
+ struct {
200
+ Blob all; /* Buffer that holds array of footnotes. Its underline
201
+ memory may be reallocated when a new footnote is added. */
202
+ int nLbled; /* number of labeled footnotes found during the first pass */
203
+ int nMarks; /* counts distinct indices found during the second pass */
204
+ struct footnote misref; /* nUsed counts misreferences, iMark must be -1 */
205
+ } notes;
170206
};
171
-
172207
173208
/* html_tag -- structure for quick HTML tag search (inspired from discount) */
174209
struct html_tag {
175210
const char *text;
176211
int size;
@@ -192,16 +227,18 @@
192227
{ "html", 4 },
193228
{ "pre", 3 },
194229
{ "script", 6 },
195230
};
196231
197
-
198232
/***************************
199233
* STATIC HELPER FUNCTIONS *
200234
***************************/
201235
202
-/* build_ref_id -- collapse whitespace from input text to make it a ref id */
236
+/*
237
+** build_ref_id -- collapse whitespace from input text to make it a ref id.
238
+** Potential TODO: maybe also handle CR+LF line endings?
239
+*/
203240
static int build_ref_id(struct Blob *id, const char *data, size_t size){
204241
size_t beg, i;
205242
char *id_data;
206243
207244
/* skip leading whitespace */
@@ -256,10 +293,58 @@
256293
struct link_ref *lra = (void *)a;
257294
struct link_ref *lrb = (void *)b;
258295
return blob_compare(&lra->id, &lrb->id);
259296
}
260297
298
+/*
299
+** cmp_footnote_id -- comparison function for footnotes qsort.
300
+** Empty IDs sort last (in undetermined order).
301
+** Equal IDs are sorted in the order of definition in the source.
302
+*/
303
+static int cmp_footnote_id(const void *fna, const void *fnb){
304
+ const struct footnote *a = fna, *b = fnb;
305
+ const int szA = blob_size(&a->id), szB = blob_size(&b->id);
306
+ if( szA ){
307
+ if( szB ){
308
+ int cmp = blob_compare(&a->id, &b->id);
309
+ if( cmp ) return cmp;
310
+ }else return -1;
311
+ }else return szB ? 1 : 0;
312
+ /* IDs are equal and non-empty */
313
+ if( a->defno < b->defno ) return -1;
314
+ if( a->defno > b->defno ) return 1;
315
+ assert(!"reachable");
316
+ return 0; /* should never reach here */
317
+}
318
+
319
+/*
320
+** cmp_footnote_sort -- comparison function for footnotes qsort.
321
+** Unreferenced footnotes (when nUsed == 0) sort last and
322
+** are sorted in the order of definition in the source.
323
+*/
324
+static int cmp_footnote_sort(const void *fna, const void *fnb){
325
+ const struct footnote *a = fna, *b = fnb;
326
+ int i, j;
327
+ assert( a->nUsed >= 0 );
328
+ assert( b->nUsed >= 0 );
329
+ assert( a->defno >= 0 );
330
+ assert( b->defno >= 0 );
331
+ if( a->nUsed ){
332
+ assert( a->iMark > 0 );
333
+ if( !b->nUsed ) return -1;
334
+ assert( b->iMark > 0 );
335
+ i = a->iMark;
336
+ j = b->iMark;
337
+ }else{
338
+ if( b->nUsed ) return 1;
339
+ i = a->defno;
340
+ j = b->defno;
341
+ }
342
+ if( i < j ) return -1;
343
+ if( i > j ) return 1;
344
+ return 0;
345
+}
261346
262347
/* cmp_html_tag -- comparison function for bsearch() (stolen from discount) */
263348
static int cmp_html_tag(const void *a, const void *b){
264349
const struct html_tag *hta = a;
265350
const struct html_tag *htb = b;
@@ -588,12 +673,14 @@
588673
if( fossil_isalnum(after) ) return 0;
589674
return 1;
590675
}
591676
592677
593
-/* parse_emph1 -- parsing single emphasis */
594
-/* closed by a symbol not preceded by whitespace and not followed by symbol */
678
+/*
679
+** parse_emph1 -- parsing single emphasis.
680
+** closed by a symbol not preceded by whitespace and not followed by symbol.
681
+*/
595682
static size_t parse_emph1(
596683
struct Blob *ob,
597684
struct render *rndr,
598685
char *data,
599686
size_t size,
@@ -633,12 +720,13 @@
633720
}
634721
}
635722
return 0;
636723
}
637724
638
-
639
-/* parse_emph2 -- parsing single emphasis */
725
+/*
726
+** parse_emph2 -- parsing single emphasis.
727
+*/
640728
static size_t parse_emph2(
641729
struct Blob *ob,
642730
struct render *rndr,
643731
char *data,
644732
size_t size,
@@ -672,13 +760,14 @@
672760
i++;
673761
}
674762
return 0;
675763
}
676764
677
-
678
-/* parse_emph3 -- parsing single emphasis */
679
-/* finds the first closing tag, and delegates to the other emph */
765
+/*
766
+** parse_emph3 -- parsing single emphasis.
767
+** finds the first closing tag, and delegates to the other emph.
768
+*/
680769
static size_t parse_emph3(
681770
struct Blob *ob,
682771
struct render *rndr,
683772
char *data,
684773
size_t size,
@@ -720,12 +809,13 @@
720809
}
721810
}
722811
return 0;
723812
}
724813
725
-
726
-/* char_emphasis -- single and double emphasis parsing */
814
+/*
815
+** char_emphasis -- single and double emphasis parsing.
816
+*/
727817
static size_t char_emphasis(
728818
struct Blob *ob,
729819
struct render *rndr,
730820
char *data,
731821
size_t offset,
@@ -765,12 +855,13 @@
765855
return ret+3;
766856
}
767857
return 0;
768858
}
769859
770
-
771
-/* char_linebreak -- '\n' preceded by two spaces (assuming linebreak != 0) */
860
+/*
861
+** char_linebreak -- '\n' preceded by two spaces (assuming linebreak != 0).
862
+*/
772863
static size_t char_linebreak(
773864
struct Blob *ob,
774865
struct render *rndr,
775866
char *data,
776867
size_t offset,
@@ -780,12 +871,13 @@
780871
/* removing the last space from ob and rendering */
781872
if( blob_size(ob)>0 && blob_buffer(ob)[blob_size(ob)-1]==' ' ) ob->nUsed--;
782873
return rndr->make.linebreak(ob, rndr->make.opaque) ? 1 : 0;
783874
}
784875
785
-
786
-/* char_codespan -- '`' parsing a code span (assuming codespan != 0) */
876
+/*
877
+** char_codespan -- '`' parsing a code span (assuming codespan != 0).
878
+*/
787879
static size_t char_codespan(
788880
struct Blob *ob,
789881
struct render *rndr,
790882
char *data,
791883
size_t offset,
@@ -822,11 +914,13 @@
822914
}
823915
return end;
824916
}
825917
826918
827
-/* char_escape -- '\\' backslash escape */
919
+/*
920
+** char_escape -- '\\' backslash escape.
921
+*/
828922
static size_t char_escape(
829923
struct Blob *ob,
830924
struct render *rndr,
831925
char *data,
832926
size_t offset,
@@ -842,13 +936,14 @@
842936
}
843937
}
844938
return 2;
845939
}
846940
847
-
848
-/* char_entity -- '&' escaped when it doesn't belong to an entity */
849
-/* valid entities are assumed to be anything matching &#?[A-Za-z0-9]+; */
941
+/*
942
+** char_entity -- '&' escaped when it doesn't belong to an entity.
943
+** valid entities are assumed to be anything matching &#?[A-Za-z0-9]+;
944
+*/
850945
static size_t char_entity(
851946
struct Blob *ob,
852947
struct render *rndr,
853948
char *data,
854949
size_t offset,
@@ -877,11 +972,10 @@
877972
}else{
878973
blob_append(ob, data, end);
879974
}
880975
return end;
881976
}
882
-
883977
884978
/* char_atref_tag -- '@' followed by "word" characters to tag
885979
* at-references */
886980
static size_t char_atref_tag(
887981
struct Blob *ob,
@@ -938,13 +1032,10 @@
9381032
** or what appears to be the end or separator of a logical
9391033
** natural-language construct, e.g. period, colon, etc.
9401034
**
9411035
** Current limitations of this implementation:
9421036
**
943
-** - ASCII only. Support for non-ASCII characters might be
944
-** interesting.
945
-**
9461037
** - Currently requires starting alpha and trailing
9471038
** alphanumeric or underscores. "Should" be extended to
9481039
** handle #X[.Y], where X and optional Y are integer
9491040
** values, for forum post references.
9501041
*/
@@ -1073,12 +1164,13 @@
10731164
#endif
10741165
#undef HASHTAG_LEGAL_END
10751166
return 0;
10761167
}
10771168
1078
-
1079
-/* char_langle_tag -- '<' when tags or autolinks are allowed */
1169
+/*
1170
+** char_langle_tag -- '<' when tags or autolinks are allowed.
1171
+*/
10801172
static size_t char_langle_tag(
10811173
struct Blob *ob,
10821174
struct render *rndr,
10831175
char *data,
10841176
size_t offset,
@@ -1103,12 +1195,12 @@
11031195
}else{
11041196
return end;
11051197
}
11061198
}
11071199
1108
-
1109
-/* get_link_inline -- extract inline-style link and title from
1200
+/*
1201
+** get_link_inline -- extract inline-style link and title from
11101202
** parenthesed data
11111203
*/
11121204
static int get_link_inline(
11131205
struct Blob *link,
11141206
struct Blob *title,
@@ -1158,11 +1250,11 @@
11581250
link_e--;
11591251
}
11601252
11611253
/* remove optional angle brackets around the link */
11621254
if( data[link_b]=='<' ) link_b += 1;
1163
- if( data[link_e-1]=='>' ) link_e -= 1;
1255
+ if( link_e && data[link_e-1]=='>' ) link_e -= 1;
11641256
11651257
/* escape backslashed character from link */
11661258
blob_reset(link);
11671259
i = link_b;
11681260
while( i<link_e ){
@@ -1179,145 +1271,353 @@
11791271
/* this function always succeed */
11801272
return 0;
11811273
}
11821274
11831275
1184
-/* get_link_ref -- extract referenced link and title from id */
1276
+/*
1277
+** get_link_ref -- extract referenced link and title from id.
1278
+*/
11851279
static int get_link_ref(
11861280
struct render *rndr,
11871281
struct Blob *link,
11881282
struct Blob *title,
11891283
char *data,
11901284
size_t size
11911285
){
11921286
struct link_ref *lr;
1287
+ const size_t sz = blob_size(&rndr->refs);
11931288
11941289
/* find the link from its id (stored temporarily in link) */
11951290
blob_reset(link);
1196
- if( build_ref_id(link, data, size)<0 ) return -1;
1291
+ if( !sz || build_ref_id(link, data, size)<0 ) return -1;
11971292
lr = bsearch(link,
11981293
blob_buffer(&rndr->refs),
1199
- blob_size(&rndr->refs)/sizeof(struct link_ref),
1294
+ sz/sizeof(struct link_ref),
12001295
sizeof (struct link_ref),
12011296
cmp_link_ref);
12021297
if( !lr ) return -1;
12031298
12041299
/* fill the output buffers */
12051300
blob_reset(link);
12061301
blob_reset(title);
1207
- blob_append(link, blob_buffer(&lr->link), blob_size(&lr->link));
1208
- blob_append(title, blob_buffer(&lr->title), blob_size(&lr->title));
1302
+ blob_appendb(link, &lr->link);
1303
+ blob_appendb(title, &lr->title);
1304
+ return 0;
1305
+}
1306
+
1307
+/*
1308
+** get_footnote() -- find a footnote by label, invoked during the 2nd pass.
1309
+** If found then return a shallow copy of the corresponding footnote;
1310
+** otherwise return a shallow copy of rndr->notes.misref.
1311
+** In both cases corresponding `nUsed` field is incremented before return.
1312
+*/
1313
+static struct footnote get_footnote(
1314
+ struct render *rndr,
1315
+ const char *data,
1316
+ size_t size
1317
+){
1318
+ struct footnote *fn = 0;
1319
+ struct Blob *id;
1320
+ if( !rndr->notes.nLbled ) goto fallback;
1321
+ id = new_work_buffer(rndr);
1322
+ if( build_ref_id(id, data, size)<0 ) goto cleanup;
1323
+ fn = bsearch(id, blob_buffer(&rndr->notes.all),
1324
+ rndr->notes.nLbled,
1325
+ sizeof (struct footnote),
1326
+ cmp_link_ref);
1327
+ if( !fn ) goto cleanup;
1328
+
1329
+ if( fn->nUsed == 0 ){ /* the first reference to the footnote */
1330
+ assert( fn->iMark == 0 );
1331
+ fn->iMark = ++(rndr->notes.nMarks);
1332
+ }
1333
+ assert( fn->iMark > 0 );
1334
+cleanup:
1335
+ release_work_buffer( rndr, id );
1336
+fallback:
1337
+ if( !fn ) fn = &rndr->notes.misref;
1338
+ fn->nUsed++;
1339
+ assert( fn->nUsed > 0 );
1340
+ return *fn;
1341
+}
1342
+
1343
+/*
1344
+** Counts characters in the blank prefix within at most nHalfLines.
1345
+** A sequence of spaces and tabs counts as odd halfline,
1346
+** a newline counts as even halfline.
1347
+** If nHalfLines < 0 then proceed without constraints.
1348
+*/
1349
+static inline size_t sizeof_blank_prefix(
1350
+ const char *data, size_t size, int nHalfLines
1351
+){
1352
+ const char *p = data;
1353
+ const char * const end = data+size;
1354
+ if( nHalfLines < 0 ){
1355
+ while( p!=end && fossil_isspace(*p) ){
1356
+ p++;
1357
+ }
1358
+ }else while( nHalfLines > 0 ){
1359
+ while( p!=end && (*p==' ' || *p=='\t' ) ){ p++; }
1360
+ if( p==end || --nHalfLines == 0 ) break;
1361
+ if( *p=='\n' || *p=='\r' ){
1362
+ p++;
1363
+ if( p==end ) break;
1364
+ if( *p=='\n' && p[-1]=='\r' ){
1365
+ p++;
1366
+ }
1367
+ }
1368
+ nHalfLines--;
1369
+ }
1370
+ return p-data;
1371
+}
1372
+
1373
+/*
1374
+** Check if the data starts with a classlist token of the special form.
1375
+** If so then return the length of that token, otherwise return 0.
1376
+**
1377
+** The token must start with a dot and must end with a colon;
1378
+** in between of these it must be a dot-separated list of words;
1379
+** each word may contain only alphanumeric characters and hyphens.
1380
+**
1381
+** If `bBlank` is non-zero then a blank character must follow
1382
+** the token's ending colon: otherwise function returns 0
1383
+** despite the well-formed token.
1384
+*/
1385
+static size_t is_footnote_classlist(const char * const data, size_t size,
1386
+ int bBlank){
1387
+ const char *p;
1388
+ const char * const end = data+size;
1389
+ if( data==end || *data != '.' ) return 0;
1390
+ for(p=data+1; p!=end; p++){
1391
+ if( fossil_isalnum(*p) || *p=='-' ) continue;
1392
+ if( p[-1]=='.' ) break;
1393
+ if( *p==':' ){
1394
+ p++;
1395
+ if( bBlank ){
1396
+ if( p==end || !fossil_isspace(*p) ) break;
1397
+ }
1398
+ return p-data;
1399
+ }
1400
+ if( *p!='.' ) break;
1401
+ }
1402
+ return 0;
1403
+}
1404
+
1405
+/*
1406
+** Adds unlabeled footnote to the rndr->notes.all.
1407
+** On success puts a shallow copy of the constructed footnote into pFN
1408
+** and returns 1, otherwise pFN is unchanged and 0 is returned.
1409
+*/
1410
+static inline int add_inline_footnote(
1411
+ struct render *rndr,
1412
+ const char *text,
1413
+ size_t size,
1414
+ struct footnote* pFN
1415
+){
1416
+ struct footnote fn = FOOTNOTE_INITIALIZER, *last;
1417
+ const char *zUPC = 0;
1418
+ size_t nUPC = 0, n = sizeof_blank_prefix(text, size, 3);
1419
+ if( n >= size ) return 0;
1420
+ text += n;
1421
+ size -= n;
1422
+ nUPC = is_footnote_classlist(text, size, 1);
1423
+ if( nUPC ){
1424
+ assert( nUPC<size );
1425
+ zUPC = text;
1426
+ text += nUPC;
1427
+ size -= nUPC;
1428
+ }
1429
+ if( sizeof_blank_prefix(text,size,-1)==size ){
1430
+ if( !nUPC ) return 0; /* empty inline footnote */
1431
+ text = zUPC;
1432
+ size = nUPC; /* bare classlist is treated */
1433
+ nUPC = 0; /* as plain text */
1434
+ }
1435
+ fn.iMark = ++(rndr->notes.nMarks);
1436
+ fn.nUsed = 1;
1437
+ fn.index = COUNT_FOOTNOTES(&rndr->notes.all);
1438
+ assert( fn.iMark > 0 );
1439
+ blob_append(&fn.text, text, size);
1440
+ if(nUPC) blob_append(&fn.upc, zUPC, nUPC);
1441
+ blob_append(&rndr->notes.all, (char *)&fn, sizeof fn);
1442
+ last = (struct footnote*)( blob_buffer(&rndr->notes.all)
1443
+ +( blob_size(&rndr->notes.all)-sizeof fn ));
1444
+ assert( pFN );
1445
+ memcpy( pFN, last, sizeof fn );
1446
+ return 1;
1447
+}
1448
+
1449
+/*
1450
+** Return the byte offset of the matching closing bracket or 0 if not
1451
+** found. begin[0] must be either '[' or '('.
1452
+**
1453
+** TODO: It seems that things like "\\(" are not handled correctly.
1454
+** That is historical behavior for a corner-case,
1455
+** so it's left as it is until somebody complains.
1456
+*/
1457
+static inline size_t matching_bracket_offset(
1458
+ const char* begin,
1459
+ const char* end
1460
+){
1461
+ const char *i;
1462
+ int level;
1463
+ const char bra = *begin;
1464
+ const char ket = bra=='[' ? ']' : ')';
1465
+ assert( bra=='[' || bra=='(' );
1466
+ for(i=begin+1,level=1; i!=end; i++){
1467
+ if( *i=='\n' ) /* do nothing */;
1468
+ else if( i[-1]=='\\' ) continue;
1469
+ else if( *i==bra ) level++;
1470
+ else if( *i==ket ){
1471
+ if( --level<=0 ) return i-begin;
1472
+ }
1473
+ }
12091474
return 0;
12101475
}
12111476
1477
+/*
1478
+** char_footnote -- '(': parsing a standalone inline footnote.
1479
+*/
1480
+static size_t char_footnote(
1481
+ struct Blob *ob,
1482
+ struct render *rndr,
1483
+ char *data,
1484
+ size_t offset,
1485
+ size_t size
1486
+){
1487
+ size_t end;
1488
+ struct footnote fn;
12121489
1213
-/* char_link -- '[': parsing a link or an image */
1490
+ if( size<4 || data[1]!='^' ) return 0;
1491
+ end = matching_bracket_offset(data, data+size);
1492
+ if( !end ) return 0;
1493
+ if( !add_inline_footnote(rndr, data+2, end-2, &fn) ) return 0;
1494
+ if( rndr->make.footnote_ref ){
1495
+ rndr->make.footnote_ref(ob,0,&fn.upc,fn.iMark,1,rndr->make.opaque);
1496
+ }
1497
+ return end+1;
1498
+}
1499
+
1500
+/*
1501
+** char_link -- '[': parsing a link or an image.
1502
+*/
12141503
static size_t char_link(
12151504
struct Blob *ob,
12161505
struct render *rndr,
12171506
char *data,
12181507
size_t offset,
1219
- size_t size
1508
+ size_t size /* parse_inline() ensures that size > 0 */
12201509
){
1221
- int is_img = (offset && data[-1] == '!'), level;
1510
+ const int is_img = (offset && data[-1] == '!');
12221511
size_t i = 1, txt_e;
12231512
struct Blob *content = 0;
12241513
struct Blob *link = 0;
12251514
struct Blob *title = 0;
1515
+ struct footnote fn;
12261516
int ret;
12271517
12281518
/* checking whether the correct renderer exists */
12291519
if( (is_img && !rndr->make.image) || (!is_img && !rndr->make.link) ){
12301520
return 0;
12311521
}
12321522
12331523
/* looking for the matching closing bracket */
1234
- for(level=1; i<size; i++){
1235
- if( data[i]=='\n' ) /* do nothing */;
1236
- else if( data[i-1]=='\\' ) continue;
1237
- else if( data[i]=='[' ) level += 1;
1238
- else if( data[i]==']' ){
1239
- level--;
1240
- if( level<=0 ) break;
1241
- }
1242
- }
1243
- if( i>=size ) return 0;
1244
- txt_e = i;
1245
- i++;
1246
-
1247
- /* skip any amount of whitespace or newline */
1248
- /* (this is much more laxist than original markdown syntax) */
1249
- while( i<size && (data[i]==' ' || data[i]=='\t' || data[i]=='\n') ){ i++; }
1250
-
1251
- /* allocate temporary buffers to store content, link and title */
1252
- title = new_work_buffer(rndr);
1253
- content = new_work_buffer(rndr);
1254
- link = new_work_buffer(rndr);
1524
+ txt_e = matching_bracket_offset(data, data+size);
1525
+ if( !txt_e ) return 0;
1526
+ i = txt_e + 1;
12551527
ret = 0; /* error if we don't get to the callback */
1256
-
1257
- /* inline style link */
1258
- if( i<size && data[i]=='(' ){
1259
- size_t span_end = i;
1260
- while( span_end<size
1261
- && !(data[span_end]==')' && (span_end==i || data[span_end-1]!='\\'))
1262
- ){
1263
- span_end++;
1264
- }
1265
-
1266
- if( span_end>=size
1267
- || get_link_inline(link, title, data+i+1, span_end-(i+1))<0
1268
- ){
1269
- goto char_link_cleanup;
1270
- }
1271
-
1272
- i = span_end+1;
1273
-
1274
- /* reference style link */
1275
- }else if( i<size && data[i]=='[' ){
1276
- char *id_data;
1277
- size_t id_size, id_end = i;
1278
-
1279
- while( id_end<size && data[id_end]!=']' ){ id_end++; }
1280
-
1281
- if( id_end>=size ) goto char_link_cleanup;
1282
-
1283
- if( i+1==id_end ){
1284
- /* implicit id - use the contents */
1285
- id_data = data+1;
1286
- id_size = txt_e-1;
1287
- }else{
1288
- /* explicit id - between brackets */
1289
- id_data = data+i+1;
1290
- id_size = id_end-(i+1);
1291
- }
1292
-
1293
- if( get_link_ref(rndr, link, title, id_data, id_size)<0 ){
1294
- goto char_link_cleanup;
1295
- }
1296
-
1297
- i = id_end+1;
1298
-
1299
- /* shortcut reference style link */
1300
- }else{
1301
- if( get_link_ref(rndr, link, title, data+1, txt_e-1)<0 ){
1302
- goto char_link_cleanup;
1303
- }
1304
-
1305
- /* rewinding the whitespace */
1306
- i = txt_e+1;
1307
- }
1308
-
1528
+ fn.nUsed = 0;
1529
+
1530
+ /* free-standing footnote refernece */
1531
+ if(!is_img && size>3 && data[1]=='^'){
1532
+ fn = get_footnote(rndr, data+2, txt_e-2);
1533
+ }else{
1534
+
1535
+ /* skip "inter-bracket-whitespace" - any amount of whitespace or newline */
1536
+ /* (this is much more lax than original markdown syntax) */
1537
+ while( i<size && (data[i]==' ' || data[i]=='\t' || data[i]=='\n') ){ i++; }
1538
+
1539
+ /* allocate temporary buffers to store content, link and title */
1540
+ title = new_work_buffer(rndr);
1541
+ content = new_work_buffer(rndr);
1542
+ link = new_work_buffer(rndr);
1543
+
1544
+ if( i<size && data[i]=='(' ){
1545
+
1546
+ if( i+2<size && data[i+1]=='^' ){ /* span-bounded inline footnote */
1547
+
1548
+ const size_t k = matching_bracket_offset(data+i, data+size);
1549
+ if( !k ) goto char_link_cleanup;
1550
+ add_inline_footnote(rndr, data+(i+2), k-2, &fn);
1551
+ i += k+1;
1552
+ }else{ /* inline style link */
1553
+ size_t span_end = i;
1554
+ while( span_end<size
1555
+ && !(data[span_end]==')'
1556
+ && (span_end==i || data[span_end-1]!='\\')) ){
1557
+ span_end++;
1558
+ }
1559
+ if( span_end>=size
1560
+ || get_link_inline(link, title, data+i+1, span_end-(i+1))<0 ){
1561
+ goto char_link_cleanup;
1562
+ }
1563
+ i = span_end+1;
1564
+ }
1565
+ /* reference style link or span-bounded footnote reference */
1566
+ }else if( i<size && data[i]=='[' ){
1567
+ char *id_data;
1568
+ size_t id_size, id_end = i;
1569
+ int bFootnote;
1570
+
1571
+ while( id_end<size && data[id_end]!=']' ){ id_end++; }
1572
+ if( id_end>=size ) goto char_link_cleanup;
1573
+ bFootnote = data[i+1]=='^';
1574
+ if( i+1==id_end || (bFootnote && i+2==id_end) ){
1575
+ /* implicit id - use the contents */
1576
+ id_data = data+1;
1577
+ id_size = txt_e-1;
1578
+ }else{
1579
+ /* explicit id - between brackets */
1580
+ id_data = data+i+1;
1581
+ id_size = id_end-(i+1);
1582
+ if( bFootnote ){
1583
+ id_data++;
1584
+ id_size--;
1585
+ }
1586
+ }
1587
+ if( bFootnote ){
1588
+ fn = get_footnote(rndr, id_data, id_size);
1589
+ }else if( get_link_ref(rndr, link, title, id_data, id_size)<0 ){
1590
+ goto char_link_cleanup;
1591
+ }
1592
+ i = id_end+1;
1593
+ /* shortcut reference style link */
1594
+ }else{
1595
+ if( get_link_ref(rndr, link, title, data+1, txt_e-1)<0 ){
1596
+ goto char_link_cleanup;
1597
+ }
1598
+ /* rewinding an "inter-bracket-whitespace" */
1599
+ i = txt_e+1;
1600
+ }
1601
+ }
13091602
/* building content: img alt is escaped, link content is parsed */
1310
- if( txt_e>1 ){
1603
+ if( txt_e>1 && content ){
13111604
if( is_img ) blob_append(content, data+1, txt_e-1);
13121605
else parse_inline(content, rndr, data+1, txt_e-1);
13131606
}
13141607
13151608
/* calling the relevant rendering function */
13161609
if( is_img ){
1317
- if( blob_size(ob)>0 && blob_buffer(ob)[blob_size(ob)-1]=='!' ) ob->nUsed--;
1610
+ if( blob_size(ob)>0 && blob_buffer(ob)[blob_size(ob)-1]=='!' ){
1611
+ ob->nUsed--;
1612
+ }
13181613
ret = rndr->make.image(ob, link, title, content, rndr->make.opaque);
1614
+ }else if( fn.nUsed ){
1615
+ if( rndr->make.footnote_ref ){
1616
+ ret = rndr->make.footnote_ref(ob, content, &fn.upc, fn.iMark,
1617
+ fn.nUsed, rndr->make.opaque);
1618
+ }
13191619
}else{
13201620
ret = rndr->make.link(ob, link, title, content, rndr->make.opaque);
13211621
}
13221622
13231623
/* cleanup */
@@ -1325,11 +1625,10 @@
13251625
release_work_buffer(rndr, title);
13261626
release_work_buffer(rndr, link);
13271627
release_work_buffer(rndr, content);
13281628
return ret ? i : 0;
13291629
}
1330
-
13311630
13321631
13331632
/*********************************
13341633
* BLOCK-LEVEL PARSING FUNCTIONS *
13351634
*********************************/
@@ -2010,11 +2309,12 @@
20102309
/* the end of the block has been found */
20112310
if( strcmp(curtag->text,"html")==0 ){
20122311
/* Omit <html> tags */
20132312
enum mkd_autolink dummy;
20142313
int k = tag_length(data, size, &dummy);
2015
- blob_init(&work, data+k, i-(j+k));
2314
+ int sz = i - (j+k);
2315
+ if( sz>0 ) blob_init(&work, data+k, sz);
20162316
}else{
20172317
blob_init(&work, data, i);
20182318
}
20192319
if( rndr->make.blockhtml ){
20202320
rndr->make.blockhtml(ob, &work, rndr->make.opaque);
@@ -2217,11 +2517,13 @@
22172517
char *data, /* input text */
22182518
size_t size /* input text size */
22192519
){
22202520
size_t beg, end, i;
22212521
char *txt_data;
2222
- int has_table = (rndr->make.table
2522
+ int has_table;
2523
+ if( !size ) return;
2524
+ has_table = (rndr->make.table
22232525
&& rndr->make.table_row
22242526
&& rndr->make.table_cell
22252527
&& memchr(data, '|', size)!=0);
22262528
22272529
beg = 0;
@@ -2267,11 +2569,11 @@
22672569
* REFERENCE PARSING *
22682570
*********************/
22692571
22702572
/* is_ref -- returns whether a line is a reference or not */
22712573
static int is_ref(
2272
- char *data, /* input text */
2574
+ const char *data, /* input text */
22732575
size_t beg, /* offset of the beginning of the line */
22742576
size_t end, /* offset of the end of the text */
22752577
size_t *last, /* last character of the link */
22762578
struct Blob *refs /* array of link references */
22772579
){
@@ -2301,10 +2603,12 @@
23012603
i += beg;
23022604
23032605
/* id part: anything but a newline between brackets */
23042606
if( data[i]!='[' ) return 0;
23052607
i++;
2608
+ if( i>=end || data[i]=='^' ) return 0; /* see is_footnote() */
2609
+
23062610
id_offset = i;
23072611
while( i<end && data[i]!='\n' && data[i]!='\r' && data[i]!=']' ){ i++; }
23082612
if( i>=end || data[i]!=']' ) return 0;
23092613
id_end = i;
23102614
@@ -2329,10 +2633,11 @@
23292633
&& data[i]!='\n'
23302634
&& data[i]!='\r'
23312635
){
23322636
i += 1;
23332637
}
2638
+ /* TODO: maybe require both data[i-1]=='>' && data[link_offset-1]=='<' ? */
23342639
if( data[i-1]=='>' ) link_end = i-1; else link_end = i;
23352640
23362641
/* optional spacer: (space | tab)* (newline | '\'' | '"' | '(' ) */
23372642
while( i<end && (data[i]==' ' || data[i]=='\t') ){ i++; }
23382643
if( i<end
@@ -2388,34 +2693,168 @@
23882693
}
23892694
blob_append(refs, (char *)&lr, sizeof lr);
23902695
return 1;
23912696
}
23922697
2698
+/*********************
2699
+ * FOOTNOTE PARSING *
2700
+ *********************/
2701
+
2702
+/* is_footnote -- check if data holds a definition of a labeled footnote.
2703
+ * If so then append the corresponding element to `footnotes` array */
2704
+static int is_footnote(
2705
+ const char *data, /* input text */
2706
+ size_t beg, /* offset of the beginning of the line */
2707
+ size_t end, /* offset of the end of the text */
2708
+ size_t *last, /* last character of the link */
2709
+ struct Blob * footnotes
2710
+){
2711
+ size_t i, id_offset, id_end, upc_offset, upc_size;
2712
+ struct footnote fn = FOOTNOTE_INITIALIZER;
2713
+
2714
+ /* failfast if data is too short */
2715
+ if( beg+5>=end ) return 0;
2716
+ i = beg;
2717
+
2718
+ /* footnote definition must start at the begining of a line */
2719
+ if( data[i]!='[' ) return 0;
2720
+ i++;
2721
+ if( data[i]!='^' ) return 0;
2722
+ id_offset = ++i;
2723
+
2724
+ /* id part: anything but a newline between brackets */
2725
+ while( i<end && data[i]!=']' && data[i]!='\n' && data[i]!='\r' ){ i++; }
2726
+ if( i>=end || data[i]!=']' ) return 0;
2727
+ id_end = i++;
2728
+
2729
+ /* spacer: colon (space | tab)* */
2730
+ if( i>=end || data[i]!=':' ) return 0;
2731
+ i++;
2732
+ while( i<end && (data[i]==' ' || data[i]=='\t') ){ i++; }
2733
+
2734
+ /* passthrough truncated footnote definition */
2735
+ if( i>=end ) return 0;
2736
+
2737
+ if( build_ref_id(&fn.id, data+id_offset, id_end-id_offset)<0 ) return 0;
2738
+
2739
+ /* footnote's text may start on the same line after [^id]: */
2740
+ upc_offset = upc_size = 0;
2741
+ if( data[i]!='\n' && data[i]!='\r' ){
2742
+ size_t j;
2743
+ upc_size = is_footnote_classlist(data+i, end-i, 1);
2744
+ upc_offset = i; /* prevent further checks for a classlist */
2745
+ i += upc_size;
2746
+ j = i;
2747
+ while( i<end && data[i]!='\n' && data[i]!='\r' ){ i++; };
2748
+ if( i!=j )blob_append(&fn.text, data+j, i-j);
2749
+ if( i<end ){
2750
+ blob_append_char(&fn.text, data[i]);
2751
+ i++;
2752
+ if( i<end && data[i]=='\n' && data[i-1]=='\r' ){
2753
+ blob_append_char(&fn.text, data[i]);
2754
+ i++;
2755
+ }
2756
+ }
2757
+ }else{
2758
+ i++;
2759
+ if( i<end && data[i]=='\n' && data[i-1]=='\r' ) i++;
2760
+ }
2761
+ if( i<end ){
2762
+
2763
+ /* compute the indentation from the 2nd line */
2764
+ size_t indent = i;
2765
+ const char *spaces = data+i;
2766
+ while( indent<end && data[indent]==' ' ){ indent++; }
2767
+ if( indent>=end ) goto footnote_finish;
2768
+ indent -= i;
2769
+ if( indent<2 ) goto footnote_finish;
23932770
2771
+ /* process the 2nd and subsequent lines */
2772
+ while( i+indent<end && memcmp(data+i,spaces,indent)==0 ){
2773
+ size_t j;
2774
+ i += indent;
2775
+ if( !upc_offset ){
2776
+ /* a classlist must be provided no later than at the 2nd line */
2777
+ upc_offset = i + sizeof_blank_prefix(data+i, end-i, 1);
2778
+ upc_size = is_footnote_classlist(data+upc_offset,
2779
+ end-upc_offset, 1);
2780
+ if( upc_size ){
2781
+ i = upc_offset + upc_size;
2782
+ }
2783
+ }
2784
+ j = i;
2785
+ while( i<end && data[i]!='\n' && data[i]!='\r' ){ i++; }
2786
+ if( i!=j ) blob_append(&fn.text, data+j, i-j);
2787
+ if( i>=end ) break;
2788
+ blob_append_char(&fn.text, data[i]);
2789
+ i++;
2790
+ if( i<end && data[i]=='\n' && data[i-1]=='\r' ){
2791
+ blob_append_char(&fn.text, data[i]);
2792
+ i++;
2793
+ }
2794
+ }
2795
+ }
2796
+footnote_finish:
2797
+ if( !blob_size(&fn.text) ){
2798
+ blob_reset(&fn.id);
2799
+ return 0;
2800
+ }
2801
+ if( !blob_trim(&fn.text) ){ /* if the content is all-blank */
2802
+ if( upc_size ){ /* interpret UPC as plain text */
2803
+ blob_append(&fn.text, data+upc_offset, upc_size);
2804
+ upc_size = 0;
2805
+ }else{
2806
+ blob_reset(&fn.id); /* or clean up and fail */
2807
+ blob_reset(&fn.text);
2808
+ return 0;
2809
+ }
2810
+ }
2811
+ /* a valid note has been found */
2812
+ if( last ) *last = i;
2813
+ if( footnotes ){
2814
+ fn.defno = COUNT_FOOTNOTES( footnotes );
2815
+ if( upc_size ){
2816
+ assert( upc_offset && upc_offset+upc_size<end );
2817
+ blob_append(&fn.upc, data+upc_offset, upc_size);
2818
+ }
2819
+ blob_append(footnotes, (char *)&fn, sizeof fn);
2820
+ }
2821
+ return 1;
2822
+}
23942823
23952824
/**********************
23962825
* EXPORTED FUNCTIONS *
23972826
**********************/
23982827
23992828
/* markdown -- parses the input buffer and renders it into the output buffer */
24002829
void markdown(
24012830
struct Blob *ob, /* output blob for rendered text */
2402
- struct Blob *ib, /* input blob in markdown */
2831
+ const struct Blob *ib, /* input blob in markdown */
24032832
const struct mkd_renderer *rndrer /* renderer descriptor (callbacks) */
24042833
){
24052834
struct link_ref *lr;
2835
+ struct footnote *fn;
24062836
size_t i, beg, end = 0;
24072837
struct render rndr;
2408
- char *ib_data;
2409
- Blob text = BLOB_INITIALIZER;
2838
+ Blob text = BLOB_INITIALIZER; /* input after the first pass */
2839
+ Blob * const allNotes = &rndr.notes.all;
24102840
24112841
/* filling the render structure */
24122842
if( !rndrer ) return;
24132843
rndr.make = *rndrer;
24142844
rndr.nBlobCache = 0;
24152845
rndr.iDepth = 0;
2416
- rndr.refs = empty_blob;
2846
+ rndr.refs = empty_blob;
2847
+ rndr.notes.all = empty_blob;
2848
+ rndr.notes.nMarks = 0;
2849
+ rndr.notes.misref.id = empty_blob;
2850
+ rndr.notes.misref.text = empty_blob;
2851
+ rndr.notes.misref.upc = empty_blob;
2852
+ rndr.notes.misref.bRndred = 0;
2853
+ rndr.notes.misref.nUsed = 0;
2854
+ rndr.notes.misref.iMark = -1;
2855
+
24172856
for(i=0; i<256; i++) rndr.active_char[i] = 0;
24182857
if( (rndr.make.emphasis
24192858
|| rndr.make.double_emphasis
24202859
|| rndr.make.triple_emphasis)
24212860
&& rndr.make.emph_chars
@@ -2427,32 +2866,34 @@
24272866
if( rndr.make.codespan ) rndr.active_char['`'] = char_codespan;
24282867
if( rndr.make.linebreak ) rndr.active_char['\n'] = char_linebreak;
24292868
if( rndr.make.image || rndr.make.link ) rndr.active_char['['] = char_link;
24302869
rndr.active_char['@'] = char_atref_tag;
24312870
rndr.active_char['#'] = char_hashref_tag;
2871
+ if( rndr.make.footnote_ref ) rndr.active_char['('] = char_footnote;
24322872
rndr.active_char['<'] = char_langle_tag;
24332873
rndr.active_char['\\'] = char_escape;
24342874
rndr.active_char['&'] = char_entity;
24352875
2436
- /* first pass: looking for references, copying everything else */
2876
+ /* first pass: iterate over lines looking for references,
2877
+ * copying everything else into "text" */
24372878
beg = 0;
2438
- ib_data = blob_buffer(ib);
2439
- while( beg<blob_size(ib) ){ /* iterating over lines */
2440
- if( is_ref(ib_data, beg, blob_size(ib), &end, &rndr.refs) ){
2879
+ for(const size_t size = blob_size(ib); beg<size ;){
2880
+ const char* const data = blob_buffer(ib);
2881
+ if( is_ref(data, beg, size, &end, &rndr.refs) ){
2882
+ beg = end;
2883
+ }else if(is_footnote(data, beg, size, &end, &rndr.notes.all)){
24412884
beg = end;
24422885
}else{ /* skipping to the next line */
24432886
end = beg;
2444
- while( end<blob_size(ib) && ib_data[end]!='\n' && ib_data[end]!='\r' ){
2887
+ while( end<size && data[end]!='\n' && data[end]!='\r' ){
24452888
end += 1;
24462889
}
24472890
/* adding the line body if present */
2448
- if( end>beg ) blob_append(&text, ib_data + beg, end - beg);
2449
- while( end<blob_size(ib) && (ib_data[end]=='\n' || ib_data[end]=='\r') ){
2891
+ if( end>beg ) blob_append(&text, data + beg, end - beg);
2892
+ while( end<size && (data[end]=='\n' || data[end]=='\r') ){
24502893
/* add one \n per newline */
2451
- if( ib_data[end]=='\n'
2452
- || (end+1<blob_size(ib) && ib_data[end+1]!='\n')
2453
- ){
2894
+ if( data[end]=='\n' || (end+1<size && data[end+1]!='\n') ){
24542895
blob_append_char(&text, '\n');
24552896
}
24562897
end += 1;
24572898
}
24582899
beg = end;
@@ -2464,14 +2905,160 @@
24642905
qsort(blob_buffer(&rndr.refs),
24652906
blob_size(&rndr.refs)/sizeof(struct link_ref),
24662907
sizeof(struct link_ref),
24672908
cmp_link_ref_sort);
24682909
}
2910
+ rndr.notes.nLbled = COUNT_FOOTNOTES( allNotes );
2911
+
2912
+ /* sort footnotes by ID and join duplicates */
2913
+ if( rndr.notes.nLbled > 1 ){
2914
+ int nDups = 0;
2915
+ fn = CAST_AS_FOOTNOTES( allNotes );
2916
+ qsort(fn, rndr.notes.nLbled, sizeof(struct footnote), cmp_footnote_id);
2917
+
2918
+ /* concatenate footnotes with equal labels */
2919
+ for(i=0; i<rndr.notes.nLbled ;){
2920
+ struct footnote *x = fn + i;
2921
+ size_t j = i+1, k = blob_size(&x->text) + 64 + blob_size(&x->upc);
2922
+ while(j<rndr.notes.nLbled && !blob_compare(&x->id, &fn[j].id)){
2923
+ k += blob_size(&fn[j].text) + 10 + blob_size(&fn[j].upc);
2924
+ j++;
2925
+ nDups++;
2926
+ }
2927
+ if( i+1<j ){
2928
+ Blob list = empty_blob;
2929
+ blob_reserve(&list, k);
2930
+ /* must match _joined_footnote_indicator in html_footnote_item() */
2931
+ blob_append_literal(&list, "<ul class='fn-joined'>\n");
2932
+ for(k=i; k<j; k++){
2933
+ struct footnote *y = fn + k;
2934
+ blob_append_literal(&list, "<li>");
2935
+ if( blob_size(&y->upc) ){
2936
+ blob_appendb(&list, &y->upc);
2937
+ blob_reset(&y->upc);
2938
+ }
2939
+ blob_appendb(&list, &y->text);
2940
+ blob_append_literal(&list, "</li>\n");
2941
+
2942
+ /* free memory buffer */
2943
+ blob_reset(&y->text);
2944
+ if( k!=i ) blob_reset(&y->id);
2945
+ }
2946
+ blob_append_literal(&list, "</ul>\n");
2947
+ x->text = list;
2948
+ g.ftntsIssues[2]++;
2949
+ }
2950
+ i = j;
2951
+ }
2952
+ if( nDups ){ /* clean rndr.notes.all from invalidated footnotes */
2953
+ const int n = rndr.notes.nLbled - nDups;
2954
+ struct Blob filtered = empty_blob;
2955
+ blob_reserve(&filtered, n*sizeof(struct footnote));
2956
+ for(i=0; i<rndr.notes.nLbled; i++){
2957
+ if( blob_size(&fn[i].id) ){
2958
+ blob_append(&filtered, (char*)(fn+i), sizeof(struct footnote));
2959
+ }
2960
+ }
2961
+ blob_reset( allNotes );
2962
+ rndr.notes.all = filtered;
2963
+ rndr.notes.nLbled = n;
2964
+ assert( COUNT_FOOTNOTES(allNotes) == rndr.notes.nLbled );
2965
+ }
2966
+ }
2967
+ fn = CAST_AS_FOOTNOTES( allNotes );
2968
+ for(i=0; i<rndr.notes.nLbled; i++){
2969
+ fn[i].index = i;
2970
+ }
2971
+ assert( rndr.notes.nMarks==0 );
24692972
24702973
/* second pass: actual rendering */
24712974
if( rndr.make.prolog ) rndr.make.prolog(ob, rndr.make.opaque);
24722975
parse_block(ob, &rndr, blob_buffer(&text), blob_size(&text));
2976
+
2977
+ if( blob_size(allNotes) || rndr.notes.misref.nUsed ){
2978
+
2979
+ /* Footnotes must be parsed for the correct discovery of (back)links */
2980
+ Blob *notes = new_work_buffer( &rndr );
2981
+ if( blob_size(allNotes) ){
2982
+ Blob *tmp = new_work_buffer( &rndr );
2983
+ int nMarks = -1, maxDepth = 5;
2984
+
2985
+ /* inline notes may get appended to rndr.notes.all while rendering */
2986
+ while(1){
2987
+ struct footnote *aNotes;
2988
+ const int N = COUNT_FOOTNOTES( allNotes );
2989
+
2990
+ /* make a shallow copy of `allNotes` */
2991
+ blob_truncate(notes,0);
2992
+ blob_appendb(notes, allNotes);
2993
+ aNotes = CAST_AS_FOOTNOTES(notes);
2994
+ qsort(aNotes, N, sizeof(struct footnote), cmp_footnote_sort);
2995
+
2996
+ if( --maxDepth < 0 || nMarks == rndr.notes.nMarks ) break;
2997
+ nMarks = rndr.notes.nMarks;
2998
+
2999
+ for(i=0; i<N; i++){
3000
+ const int j = aNotes[i].index;
3001
+ struct footnote *x = CAST_AS_FOOTNOTES(allNotes) + j;
3002
+ assert( 0<=j && j<N );
3003
+ if( x->bRndred || !x->nUsed ) continue;
3004
+ assert( x->iMark > 0 );
3005
+ assert( blob_size(&x->text) );
3006
+ blob_truncate(tmp,0);
3007
+
3008
+ /* `allNotes` may be altered and extended through this call */
3009
+ parse_inline(tmp, &rndr, blob_buffer(&x->text), blob_size(&x->text));
3010
+
3011
+ x = CAST_AS_FOOTNOTES(allNotes) + j;
3012
+ blob_truncate(&x->text,0);
3013
+ blob_appendb(&x->text, tmp);
3014
+ x->bRndred = 1;
3015
+ }
3016
+ }
3017
+ release_work_buffer(&rndr,tmp);
3018
+ }
3019
+
3020
+ /* footnotes rendering */
3021
+ if( rndr.make.footnote_item && rndr.make.footnotes ){
3022
+ Blob *all_items = new_work_buffer(&rndr);
3023
+ int j = -1;
3024
+
3025
+ /* Assert that the in-memory layout of id, text and upc within
3026
+ ** footnote struct matches the expectations of html_footnote_item()
3027
+ ** If it doesn't then a compiler has done something very weird.
3028
+ */
3029
+ assert( &(rndr.notes.misref.id) == &(rndr.notes.misref.text) - 1 );
3030
+ assert( &(rndr.notes.misref.upc) == &(rndr.notes.misref.text) + 1 );
3031
+
3032
+ for(i=0; i<COUNT_FOOTNOTES(notes); i++){
3033
+ const struct footnote* x = CAST_AS_FOOTNOTES(notes) + i;
3034
+ const int xUsed = x->bRndred ? x->nUsed : 0;
3035
+ if( !x->iMark ) break;
3036
+ assert( x->nUsed );
3037
+ rndr.make.footnote_item(all_items, &x->text, x->iMark,
3038
+ xUsed, rndr.make.opaque);
3039
+ if( !xUsed ) g.ftntsIssues[3]++; /* an overnested footnote */
3040
+ j = i;
3041
+ }
3042
+ if( rndr.notes.misref.nUsed ){
3043
+ rndr.make.footnote_item(all_items, 0, -1,
3044
+ rndr.notes.misref.nUsed, rndr.make.opaque);
3045
+ g.ftntsIssues[0] += rndr.notes.misref.nUsed;
3046
+ }
3047
+ while( ++j < COUNT_FOOTNOTES(notes) ){
3048
+ const struct footnote* x = CAST_AS_FOOTNOTES(notes) + j;
3049
+ assert( !x->iMark );
3050
+ assert( !x->nUsed );
3051
+ assert( !x->bRndred );
3052
+ rndr.make.footnote_item(all_items,&x->text,0,0,rndr.make.opaque);
3053
+ g.ftntsIssues[1]++;
3054
+ }
3055
+ rndr.make.footnotes(ob, all_items, rndr.make.opaque);
3056
+ release_work_buffer(&rndr, all_items);
3057
+ }
3058
+ release_work_buffer(&rndr, notes);
3059
+ }
24733060
if( rndr.make.epilog ) rndr.make.epilog(ob, rndr.make.opaque);
24743061
24753062
/* clean-up */
24763063
assert( rndr.iDepth==0 );
24773064
blob_reset(&text);
@@ -2481,9 +3068,17 @@
24813068
blob_reset(&lr[i].id);
24823069
blob_reset(&lr[i].link);
24833070
blob_reset(&lr[i].title);
24843071
}
24853072
blob_reset(&rndr.refs);
3073
+ fn = CAST_AS_FOOTNOTES( allNotes );
3074
+ end = COUNT_FOOTNOTES( allNotes );
3075
+ for(i=0; i<end; i++){
3076
+ if(blob_size(&fn[i].id)) blob_reset(&fn[i].id);
3077
+ if(blob_size(&fn[i].upc)) blob_reset(&fn[i].upc);
3078
+ blob_reset(&fn[i].text);
3079
+ }
3080
+ blob_reset(&rndr.notes.all);
24863081
for(i=0; i<rndr.nBlobCache; i++){
24873082
fossil_free(rndr.aBlobCache[i]);
24883083
}
24893084
}
24903085
--- src/markdown.c
+++ src/markdown.c
@@ -52,10 +52,11 @@
52 /* mkd_renderer -- functions for rendering parsed data */
53 struct mkd_renderer {
54 /* document level callbacks */
55 void (*prolog)(struct Blob *ob, void *opaque);
56 void (*epilog)(struct Blob *ob, void *opaque);
 
57
58 /* block level callbacks - NULL skips the block */
59 void (*blockcode)(struct Blob *ob, struct Blob *text, void *opaque);
60 void (*blockquote)(struct Blob *ob, struct Blob *text, void *opaque);
61 void (*blockhtml)(struct Blob *ob, struct Blob *text, void *opaque);
@@ -70,10 +71,12 @@
70 void *opaque);
71 void (*table_cell)(struct Blob *ob, struct Blob *text, int flags,
72 void *opaque);
73 void (*table_row)(struct Blob *ob, struct Blob *cells, int flags,
74 void *opaque);
 
 
75
76 /* span level callbacks - NULL or return 0 prints the span verbatim */
77 int (*autolink)(struct Blob *ob, struct Blob *link,
78 enum mkd_autolink type, void *opaque);
79 int (*codespan)(struct Blob *ob, struct Blob *text, int nSep, void *opaque);
@@ -88,10 +91,12 @@
88 int (*raw_html_tag)(struct Blob *ob, struct Blob *tag, void *opaque);
89 int (*tagspan)(struct Blob *ob, struct Blob *ref, enum mkd_tagspan type,
90 void *opaque);
91 int (*triple_emphasis)(struct Blob *ob, struct Blob *text,
92 char c, void *opaque);
 
 
93
94 /* low level callbacks - NULL copies input directly into the output */
95 void (*entity)(struct Blob *ob, struct Blob *entity, void *opaque);
96 void (*normal_text)(struct Blob *ob, struct Blob *text, void *opaque);
97
@@ -122,31 +127,54 @@
122
123 /**********************
124 * EXPORTED FUNCTIONS *
125 **********************/
126
127 /* markdown -- parses the input buffer and renders it into the output buffer */
 
 
128 void markdown(
129 struct Blob *ob,
130 struct Blob *ib,
131 const struct mkd_renderer *rndr);
132
133
134 #endif /* INTERFACE */
135
 
 
 
136
137 /***************
138 * LOCAL TYPES *
139 ***************/
140
141 /* link_ref -- reference to a link */
 
 
142 struct link_ref {
143 struct Blob id;
144 struct Blob link;
145 struct Blob title;
146 };
147
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
149 /* char_trigger -- function pointer to render active chars */
150 /* returns the number of chars taken care of */
151 /* data is the pointer of the beginning of the span */
152 /* offset is the number of valid chars before data */
@@ -165,12 +193,19 @@
165 struct Blob refs;
166 char_trigger active_char[256];
167 int iDepth; /* Depth of recursion */
168 int nBlobCache; /* Number of entries in aBlobCache */
169 struct Blob *aBlobCache[20]; /* Cache of Blobs available for reuse */
 
 
 
 
 
 
 
 
170 };
171
172
173 /* html_tag -- structure for quick HTML tag search (inspired from discount) */
174 struct html_tag {
175 const char *text;
176 int size;
@@ -192,16 +227,18 @@
192 { "html", 4 },
193 { "pre", 3 },
194 { "script", 6 },
195 };
196
197
198 /***************************
199 * STATIC HELPER FUNCTIONS *
200 ***************************/
201
202 /* build_ref_id -- collapse whitespace from input text to make it a ref id */
 
 
 
203 static int build_ref_id(struct Blob *id, const char *data, size_t size){
204 size_t beg, i;
205 char *id_data;
206
207 /* skip leading whitespace */
@@ -256,10 +293,58 @@
256 struct link_ref *lra = (void *)a;
257 struct link_ref *lrb = (void *)b;
258 return blob_compare(&lra->id, &lrb->id);
259 }
260
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
262 /* cmp_html_tag -- comparison function for bsearch() (stolen from discount) */
263 static int cmp_html_tag(const void *a, const void *b){
264 const struct html_tag *hta = a;
265 const struct html_tag *htb = b;
@@ -588,12 +673,14 @@
588 if( fossil_isalnum(after) ) return 0;
589 return 1;
590 }
591
592
593 /* parse_emph1 -- parsing single emphasis */
594 /* closed by a symbol not preceded by whitespace and not followed by symbol */
 
 
595 static size_t parse_emph1(
596 struct Blob *ob,
597 struct render *rndr,
598 char *data,
599 size_t size,
@@ -633,12 +720,13 @@
633 }
634 }
635 return 0;
636 }
637
638
639 /* parse_emph2 -- parsing single emphasis */
 
640 static size_t parse_emph2(
641 struct Blob *ob,
642 struct render *rndr,
643 char *data,
644 size_t size,
@@ -672,13 +760,14 @@
672 i++;
673 }
674 return 0;
675 }
676
677
678 /* parse_emph3 -- parsing single emphasis */
679 /* finds the first closing tag, and delegates to the other emph */
 
680 static size_t parse_emph3(
681 struct Blob *ob,
682 struct render *rndr,
683 char *data,
684 size_t size,
@@ -720,12 +809,13 @@
720 }
721 }
722 return 0;
723 }
724
725
726 /* char_emphasis -- single and double emphasis parsing */
 
727 static size_t char_emphasis(
728 struct Blob *ob,
729 struct render *rndr,
730 char *data,
731 size_t offset,
@@ -765,12 +855,13 @@
765 return ret+3;
766 }
767 return 0;
768 }
769
770
771 /* char_linebreak -- '\n' preceded by two spaces (assuming linebreak != 0) */
 
772 static size_t char_linebreak(
773 struct Blob *ob,
774 struct render *rndr,
775 char *data,
776 size_t offset,
@@ -780,12 +871,13 @@
780 /* removing the last space from ob and rendering */
781 if( blob_size(ob)>0 && blob_buffer(ob)[blob_size(ob)-1]==' ' ) ob->nUsed--;
782 return rndr->make.linebreak(ob, rndr->make.opaque) ? 1 : 0;
783 }
784
785
786 /* char_codespan -- '`' parsing a code span (assuming codespan != 0) */
 
787 static size_t char_codespan(
788 struct Blob *ob,
789 struct render *rndr,
790 char *data,
791 size_t offset,
@@ -822,11 +914,13 @@
822 }
823 return end;
824 }
825
826
827 /* char_escape -- '\\' backslash escape */
 
 
828 static size_t char_escape(
829 struct Blob *ob,
830 struct render *rndr,
831 char *data,
832 size_t offset,
@@ -842,13 +936,14 @@
842 }
843 }
844 return 2;
845 }
846
847
848 /* char_entity -- '&' escaped when it doesn't belong to an entity */
849 /* valid entities are assumed to be anything matching &#?[A-Za-z0-9]+; */
 
850 static size_t char_entity(
851 struct Blob *ob,
852 struct render *rndr,
853 char *data,
854 size_t offset,
@@ -877,11 +972,10 @@
877 }else{
878 blob_append(ob, data, end);
879 }
880 return end;
881 }
882
883
884 /* char_atref_tag -- '@' followed by "word" characters to tag
885 * at-references */
886 static size_t char_atref_tag(
887 struct Blob *ob,
@@ -938,13 +1032,10 @@
938 ** or what appears to be the end or separator of a logical
939 ** natural-language construct, e.g. period, colon, etc.
940 **
941 ** Current limitations of this implementation:
942 **
943 ** - ASCII only. Support for non-ASCII characters might be
944 ** interesting.
945 **
946 ** - Currently requires starting alpha and trailing
947 ** alphanumeric or underscores. "Should" be extended to
948 ** handle #X[.Y], where X and optional Y are integer
949 ** values, for forum post references.
950 */
@@ -1073,12 +1164,13 @@
1073 #endif
1074 #undef HASHTAG_LEGAL_END
1075 return 0;
1076 }
1077
1078
1079 /* char_langle_tag -- '<' when tags or autolinks are allowed */
 
1080 static size_t char_langle_tag(
1081 struct Blob *ob,
1082 struct render *rndr,
1083 char *data,
1084 size_t offset,
@@ -1103,12 +1195,12 @@
1103 }else{
1104 return end;
1105 }
1106 }
1107
1108
1109 /* get_link_inline -- extract inline-style link and title from
1110 ** parenthesed data
1111 */
1112 static int get_link_inline(
1113 struct Blob *link,
1114 struct Blob *title,
@@ -1158,11 +1250,11 @@
1158 link_e--;
1159 }
1160
1161 /* remove optional angle brackets around the link */
1162 if( data[link_b]=='<' ) link_b += 1;
1163 if( data[link_e-1]=='>' ) link_e -= 1;
1164
1165 /* escape backslashed character from link */
1166 blob_reset(link);
1167 i = link_b;
1168 while( i<link_e ){
@@ -1179,145 +1271,353 @@
1179 /* this function always succeed */
1180 return 0;
1181 }
1182
1183
1184 /* get_link_ref -- extract referenced link and title from id */
 
 
1185 static int get_link_ref(
1186 struct render *rndr,
1187 struct Blob *link,
1188 struct Blob *title,
1189 char *data,
1190 size_t size
1191 ){
1192 struct link_ref *lr;
 
1193
1194 /* find the link from its id (stored temporarily in link) */
1195 blob_reset(link);
1196 if( build_ref_id(link, data, size)<0 ) return -1;
1197 lr = bsearch(link,
1198 blob_buffer(&rndr->refs),
1199 blob_size(&rndr->refs)/sizeof(struct link_ref),
1200 sizeof (struct link_ref),
1201 cmp_link_ref);
1202 if( !lr ) return -1;
1203
1204 /* fill the output buffers */
1205 blob_reset(link);
1206 blob_reset(title);
1207 blob_append(link, blob_buffer(&lr->link), blob_size(&lr->link));
1208 blob_append(title, blob_buffer(&lr->title), blob_size(&lr->title));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1209 return 0;
1210 }
1211
 
 
 
 
 
 
 
 
 
 
 
 
1212
1213 /* char_link -- '[': parsing a link or an image */
 
 
 
 
 
 
 
 
 
 
 
 
1214 static size_t char_link(
1215 struct Blob *ob,
1216 struct render *rndr,
1217 char *data,
1218 size_t offset,
1219 size_t size
1220 ){
1221 int is_img = (offset && data[-1] == '!'), level;
1222 size_t i = 1, txt_e;
1223 struct Blob *content = 0;
1224 struct Blob *link = 0;
1225 struct Blob *title = 0;
 
1226 int ret;
1227
1228 /* checking whether the correct renderer exists */
1229 if( (is_img && !rndr->make.image) || (!is_img && !rndr->make.link) ){
1230 return 0;
1231 }
1232
1233 /* looking for the matching closing bracket */
1234 for(level=1; i<size; i++){
1235 if( data[i]=='\n' ) /* do nothing */;
1236 else if( data[i-1]=='\\' ) continue;
1237 else if( data[i]=='[' ) level += 1;
1238 else if( data[i]==']' ){
1239 level--;
1240 if( level<=0 ) break;
1241 }
1242 }
1243 if( i>=size ) return 0;
1244 txt_e = i;
1245 i++;
1246
1247 /* skip any amount of whitespace or newline */
1248 /* (this is much more laxist than original markdown syntax) */
1249 while( i<size && (data[i]==' ' || data[i]=='\t' || data[i]=='\n') ){ i++; }
1250
1251 /* allocate temporary buffers to store content, link and title */
1252 title = new_work_buffer(rndr);
1253 content = new_work_buffer(rndr);
1254 link = new_work_buffer(rndr);
1255 ret = 0; /* error if we don't get to the callback */
1256
1257 /* inline style link */
1258 if( i<size && data[i]=='(' ){
1259 size_t span_end = i;
1260 while( span_end<size
1261 && !(data[span_end]==')' && (span_end==i || data[span_end-1]!='\\'))
1262 ){
1263 span_end++;
1264 }
1265
1266 if( span_end>=size
1267 || get_link_inline(link, title, data+i+1, span_end-(i+1))<0
1268 ){
1269 goto char_link_cleanup;
1270 }
1271
1272 i = span_end+1;
1273
1274 /* reference style link */
1275 }else if( i<size && data[i]=='[' ){
1276 char *id_data;
1277 size_t id_size, id_end = i;
1278
1279 while( id_end<size && data[id_end]!=']' ){ id_end++; }
1280
1281 if( id_end>=size ) goto char_link_cleanup;
1282
1283 if( i+1==id_end ){
1284 /* implicit id - use the contents */
1285 id_data = data+1;
1286 id_size = txt_e-1;
1287 }else{
1288 /* explicit id - between brackets */
1289 id_data = data+i+1;
1290 id_size = id_end-(i+1);
1291 }
1292
1293 if( get_link_ref(rndr, link, title, id_data, id_size)<0 ){
1294 goto char_link_cleanup;
1295 }
1296
1297 i = id_end+1;
1298
1299 /* shortcut reference style link */
1300 }else{
1301 if( get_link_ref(rndr, link, title, data+1, txt_e-1)<0 ){
1302 goto char_link_cleanup;
1303 }
1304
1305 /* rewinding the whitespace */
1306 i = txt_e+1;
1307 }
1308
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1309 /* building content: img alt is escaped, link content is parsed */
1310 if( txt_e>1 ){
1311 if( is_img ) blob_append(content, data+1, txt_e-1);
1312 else parse_inline(content, rndr, data+1, txt_e-1);
1313 }
1314
1315 /* calling the relevant rendering function */
1316 if( is_img ){
1317 if( blob_size(ob)>0 && blob_buffer(ob)[blob_size(ob)-1]=='!' ) ob->nUsed--;
 
 
1318 ret = rndr->make.image(ob, link, title, content, rndr->make.opaque);
 
 
 
 
 
1319 }else{
1320 ret = rndr->make.link(ob, link, title, content, rndr->make.opaque);
1321 }
1322
1323 /* cleanup */
@@ -1325,11 +1625,10 @@
1325 release_work_buffer(rndr, title);
1326 release_work_buffer(rndr, link);
1327 release_work_buffer(rndr, content);
1328 return ret ? i : 0;
1329 }
1330
1331
1332
1333 /*********************************
1334 * BLOCK-LEVEL PARSING FUNCTIONS *
1335 *********************************/
@@ -2010,11 +2309,12 @@
2010 /* the end of the block has been found */
2011 if( strcmp(curtag->text,"html")==0 ){
2012 /* Omit <html> tags */
2013 enum mkd_autolink dummy;
2014 int k = tag_length(data, size, &dummy);
2015 blob_init(&work, data+k, i-(j+k));
 
2016 }else{
2017 blob_init(&work, data, i);
2018 }
2019 if( rndr->make.blockhtml ){
2020 rndr->make.blockhtml(ob, &work, rndr->make.opaque);
@@ -2217,11 +2517,13 @@
2217 char *data, /* input text */
2218 size_t size /* input text size */
2219 ){
2220 size_t beg, end, i;
2221 char *txt_data;
2222 int has_table = (rndr->make.table
 
 
2223 && rndr->make.table_row
2224 && rndr->make.table_cell
2225 && memchr(data, '|', size)!=0);
2226
2227 beg = 0;
@@ -2267,11 +2569,11 @@
2267 * REFERENCE PARSING *
2268 *********************/
2269
2270 /* is_ref -- returns whether a line is a reference or not */
2271 static int is_ref(
2272 char *data, /* input text */
2273 size_t beg, /* offset of the beginning of the line */
2274 size_t end, /* offset of the end of the text */
2275 size_t *last, /* last character of the link */
2276 struct Blob *refs /* array of link references */
2277 ){
@@ -2301,10 +2603,12 @@
2301 i += beg;
2302
2303 /* id part: anything but a newline between brackets */
2304 if( data[i]!='[' ) return 0;
2305 i++;
 
 
2306 id_offset = i;
2307 while( i<end && data[i]!='\n' && data[i]!='\r' && data[i]!=']' ){ i++; }
2308 if( i>=end || data[i]!=']' ) return 0;
2309 id_end = i;
2310
@@ -2329,10 +2633,11 @@
2329 && data[i]!='\n'
2330 && data[i]!='\r'
2331 ){
2332 i += 1;
2333 }
 
2334 if( data[i-1]=='>' ) link_end = i-1; else link_end = i;
2335
2336 /* optional spacer: (space | tab)* (newline | '\'' | '"' | '(' ) */
2337 while( i<end && (data[i]==' ' || data[i]=='\t') ){ i++; }
2338 if( i<end
@@ -2388,34 +2693,168 @@
2388 }
2389 blob_append(refs, (char *)&lr, sizeof lr);
2390 return 1;
2391 }
2392
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2393
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2394
2395 /**********************
2396 * EXPORTED FUNCTIONS *
2397 **********************/
2398
2399 /* markdown -- parses the input buffer and renders it into the output buffer */
2400 void markdown(
2401 struct Blob *ob, /* output blob for rendered text */
2402 struct Blob *ib, /* input blob in markdown */
2403 const struct mkd_renderer *rndrer /* renderer descriptor (callbacks) */
2404 ){
2405 struct link_ref *lr;
 
2406 size_t i, beg, end = 0;
2407 struct render rndr;
2408 char *ib_data;
2409 Blob text = BLOB_INITIALIZER;
2410
2411 /* filling the render structure */
2412 if( !rndrer ) return;
2413 rndr.make = *rndrer;
2414 rndr.nBlobCache = 0;
2415 rndr.iDepth = 0;
2416 rndr.refs = empty_blob;
 
 
 
 
 
 
 
 
 
2417 for(i=0; i<256; i++) rndr.active_char[i] = 0;
2418 if( (rndr.make.emphasis
2419 || rndr.make.double_emphasis
2420 || rndr.make.triple_emphasis)
2421 && rndr.make.emph_chars
@@ -2427,32 +2866,34 @@
2427 if( rndr.make.codespan ) rndr.active_char['`'] = char_codespan;
2428 if( rndr.make.linebreak ) rndr.active_char['\n'] = char_linebreak;
2429 if( rndr.make.image || rndr.make.link ) rndr.active_char['['] = char_link;
2430 rndr.active_char['@'] = char_atref_tag;
2431 rndr.active_char['#'] = char_hashref_tag;
 
2432 rndr.active_char['<'] = char_langle_tag;
2433 rndr.active_char['\\'] = char_escape;
2434 rndr.active_char['&'] = char_entity;
2435
2436 /* first pass: looking for references, copying everything else */
 
2437 beg = 0;
2438 ib_data = blob_buffer(ib);
2439 while( beg<blob_size(ib) ){ /* iterating over lines */
2440 if( is_ref(ib_data, beg, blob_size(ib), &end, &rndr.refs) ){
 
 
2441 beg = end;
2442 }else{ /* skipping to the next line */
2443 end = beg;
2444 while( end<blob_size(ib) && ib_data[end]!='\n' && ib_data[end]!='\r' ){
2445 end += 1;
2446 }
2447 /* adding the line body if present */
2448 if( end>beg ) blob_append(&text, ib_data + beg, end - beg);
2449 while( end<blob_size(ib) && (ib_data[end]=='\n' || ib_data[end]=='\r') ){
2450 /* add one \n per newline */
2451 if( ib_data[end]=='\n'
2452 || (end+1<blob_size(ib) && ib_data[end+1]!='\n')
2453 ){
2454 blob_append_char(&text, '\n');
2455 }
2456 end += 1;
2457 }
2458 beg = end;
@@ -2464,14 +2905,160 @@
2464 qsort(blob_buffer(&rndr.refs),
2465 blob_size(&rndr.refs)/sizeof(struct link_ref),
2466 sizeof(struct link_ref),
2467 cmp_link_ref_sort);
2468 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2469
2470 /* second pass: actual rendering */
2471 if( rndr.make.prolog ) rndr.make.prolog(ob, rndr.make.opaque);
2472 parse_block(ob, &rndr, blob_buffer(&text), blob_size(&text));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2473 if( rndr.make.epilog ) rndr.make.epilog(ob, rndr.make.opaque);
2474
2475 /* clean-up */
2476 assert( rndr.iDepth==0 );
2477 blob_reset(&text);
@@ -2481,9 +3068,17 @@
2481 blob_reset(&lr[i].id);
2482 blob_reset(&lr[i].link);
2483 blob_reset(&lr[i].title);
2484 }
2485 blob_reset(&rndr.refs);
 
 
 
 
 
 
 
 
2486 for(i=0; i<rndr.nBlobCache; i++){
2487 fossil_free(rndr.aBlobCache[i]);
2488 }
2489 }
2490
--- src/markdown.c
+++ src/markdown.c
@@ -52,10 +52,11 @@
52 /* mkd_renderer -- functions for rendering parsed data */
53 struct mkd_renderer {
54 /* document level callbacks */
55 void (*prolog)(struct Blob *ob, void *opaque);
56 void (*epilog)(struct Blob *ob, void *opaque);
57 void (*footnotes)(struct Blob *ob, const struct Blob *items, void *opaque);
58
59 /* block level callbacks - NULL skips the block */
60 void (*blockcode)(struct Blob *ob, struct Blob *text, void *opaque);
61 void (*blockquote)(struct Blob *ob, struct Blob *text, void *opaque);
62 void (*blockhtml)(struct Blob *ob, struct Blob *text, void *opaque);
@@ -70,10 +71,12 @@
71 void *opaque);
72 void (*table_cell)(struct Blob *ob, struct Blob *text, int flags,
73 void *opaque);
74 void (*table_row)(struct Blob *ob, struct Blob *cells, int flags,
75 void *opaque);
76 void (*footnote_item)(struct Blob *ob, const struct Blob *text,
77 int index, int nUsed, void *opaque);
78
79 /* span level callbacks - NULL or return 0 prints the span verbatim */
80 int (*autolink)(struct Blob *ob, struct Blob *link,
81 enum mkd_autolink type, void *opaque);
82 int (*codespan)(struct Blob *ob, struct Blob *text, int nSep, void *opaque);
@@ -88,10 +91,12 @@
91 int (*raw_html_tag)(struct Blob *ob, struct Blob *tag, void *opaque);
92 int (*tagspan)(struct Blob *ob, struct Blob *ref, enum mkd_tagspan type,
93 void *opaque);
94 int (*triple_emphasis)(struct Blob *ob, struct Blob *text,
95 char c, void *opaque);
96 int (*footnote_ref)(struct Blob *ob, const struct Blob *span,
97 const struct Blob *upc, int index, int locus, void *opaque);
98
99 /* low level callbacks - NULL copies input directly into the output */
100 void (*entity)(struct Blob *ob, struct Blob *entity, void *opaque);
101 void (*normal_text)(struct Blob *ob, struct Blob *text, void *opaque);
102
@@ -122,31 +127,54 @@
127
128 /**********************
129 * EXPORTED FUNCTIONS *
130 **********************/
131
132 /*
133 ** markdown -- parses the input buffer and renders it into the output buffer.
134 */
135 void markdown(
136 struct Blob *ob,
137 const struct Blob *ib,
138 const struct mkd_renderer *rndr);
139
140
141 #endif /* INTERFACE */
142
143 #define BLOB_COUNT(pBlob,el_type) (blob_size(pBlob)/sizeof(el_type))
144 #define COUNT_FOOTNOTES(pBlob) BLOB_COUNT(pBlob,struct footnote)
145 #define CAST_AS_FOOTNOTES(pBlob) ((struct footnote*)blob_buffer(pBlob))
146
147 /***************
148 * LOCAL TYPES *
149 ***************/
150
151 /*
152 ** link_ref -- reference to a link.
153 */
154 struct link_ref {
155 struct Blob id; /* must be the first field as in footnote struct */
156 struct Blob link;
157 struct Blob title;
158 };
159
160 /*
161 ** A footnote's data.
162 ** id, text, and upc fields must be in that particular order.
163 */
164 struct footnote {
165 struct Blob id; /* must be the first field as in link_ref struct */
166 struct Blob text; /* footnote's content that is rendered at the end */
167 struct Blob upc; /* user-provided classes .ASCII-alnum.or-hypen: */
168 int bRndred; /* indicates if `text` holds a rendered content */
169
170 int defno; /* serial number of definition, set during the first pass */
171 int index; /* set to the index within array after ordering by id */
172 int iMark; /* user-visible numeric marker, assigned upon the first use*/
173 int nUsed; /* counts references to this note, increments upon each use*/
174 };
175 #define FOOTNOTE_INITIALIZER {empty_blob,empty_blob,empty_blob, 0,0,0,0,0}
176
177 /* char_trigger -- function pointer to render active chars */
178 /* returns the number of chars taken care of */
179 /* data is the pointer of the beginning of the span */
180 /* offset is the number of valid chars before data */
@@ -165,12 +193,19 @@
193 struct Blob refs;
194 char_trigger active_char[256];
195 int iDepth; /* Depth of recursion */
196 int nBlobCache; /* Number of entries in aBlobCache */
197 struct Blob *aBlobCache[20]; /* Cache of Blobs available for reuse */
198
199 struct {
200 Blob all; /* Buffer that holds array of footnotes. Its underline
201 memory may be reallocated when a new footnote is added. */
202 int nLbled; /* number of labeled footnotes found during the first pass */
203 int nMarks; /* counts distinct indices found during the second pass */
204 struct footnote misref; /* nUsed counts misreferences, iMark must be -1 */
205 } notes;
206 };
 
207
208 /* html_tag -- structure for quick HTML tag search (inspired from discount) */
209 struct html_tag {
210 const char *text;
211 int size;
@@ -192,16 +227,18 @@
227 { "html", 4 },
228 { "pre", 3 },
229 { "script", 6 },
230 };
231
 
232 /***************************
233 * STATIC HELPER FUNCTIONS *
234 ***************************/
235
236 /*
237 ** build_ref_id -- collapse whitespace from input text to make it a ref id.
238 ** Potential TODO: maybe also handle CR+LF line endings?
239 */
240 static int build_ref_id(struct Blob *id, const char *data, size_t size){
241 size_t beg, i;
242 char *id_data;
243
244 /* skip leading whitespace */
@@ -256,10 +293,58 @@
293 struct link_ref *lra = (void *)a;
294 struct link_ref *lrb = (void *)b;
295 return blob_compare(&lra->id, &lrb->id);
296 }
297
298 /*
299 ** cmp_footnote_id -- comparison function for footnotes qsort.
300 ** Empty IDs sort last (in undetermined order).
301 ** Equal IDs are sorted in the order of definition in the source.
302 */
303 static int cmp_footnote_id(const void *fna, const void *fnb){
304 const struct footnote *a = fna, *b = fnb;
305 const int szA = blob_size(&a->id), szB = blob_size(&b->id);
306 if( szA ){
307 if( szB ){
308 int cmp = blob_compare(&a->id, &b->id);
309 if( cmp ) return cmp;
310 }else return -1;
311 }else return szB ? 1 : 0;
312 /* IDs are equal and non-empty */
313 if( a->defno < b->defno ) return -1;
314 if( a->defno > b->defno ) return 1;
315 assert(!"reachable");
316 return 0; /* should never reach here */
317 }
318
319 /*
320 ** cmp_footnote_sort -- comparison function for footnotes qsort.
321 ** Unreferenced footnotes (when nUsed == 0) sort last and
322 ** are sorted in the order of definition in the source.
323 */
324 static int cmp_footnote_sort(const void *fna, const void *fnb){
325 const struct footnote *a = fna, *b = fnb;
326 int i, j;
327 assert( a->nUsed >= 0 );
328 assert( b->nUsed >= 0 );
329 assert( a->defno >= 0 );
330 assert( b->defno >= 0 );
331 if( a->nUsed ){
332 assert( a->iMark > 0 );
333 if( !b->nUsed ) return -1;
334 assert( b->iMark > 0 );
335 i = a->iMark;
336 j = b->iMark;
337 }else{
338 if( b->nUsed ) return 1;
339 i = a->defno;
340 j = b->defno;
341 }
342 if( i < j ) return -1;
343 if( i > j ) return 1;
344 return 0;
345 }
346
347 /* cmp_html_tag -- comparison function for bsearch() (stolen from discount) */
348 static int cmp_html_tag(const void *a, const void *b){
349 const struct html_tag *hta = a;
350 const struct html_tag *htb = b;
@@ -588,12 +673,14 @@
673 if( fossil_isalnum(after) ) return 0;
674 return 1;
675 }
676
677
678 /*
679 ** parse_emph1 -- parsing single emphasis.
680 ** closed by a symbol not preceded by whitespace and not followed by symbol.
681 */
682 static size_t parse_emph1(
683 struct Blob *ob,
684 struct render *rndr,
685 char *data,
686 size_t size,
@@ -633,12 +720,13 @@
720 }
721 }
722 return 0;
723 }
724
725 /*
726 ** parse_emph2 -- parsing single emphasis.
727 */
728 static size_t parse_emph2(
729 struct Blob *ob,
730 struct render *rndr,
731 char *data,
732 size_t size,
@@ -672,13 +760,14 @@
760 i++;
761 }
762 return 0;
763 }
764
765 /*
766 ** parse_emph3 -- parsing single emphasis.
767 ** finds the first closing tag, and delegates to the other emph.
768 */
769 static size_t parse_emph3(
770 struct Blob *ob,
771 struct render *rndr,
772 char *data,
773 size_t size,
@@ -720,12 +809,13 @@
809 }
810 }
811 return 0;
812 }
813
814 /*
815 ** char_emphasis -- single and double emphasis parsing.
816 */
817 static size_t char_emphasis(
818 struct Blob *ob,
819 struct render *rndr,
820 char *data,
821 size_t offset,
@@ -765,12 +855,13 @@
855 return ret+3;
856 }
857 return 0;
858 }
859
860 /*
861 ** char_linebreak -- '\n' preceded by two spaces (assuming linebreak != 0).
862 */
863 static size_t char_linebreak(
864 struct Blob *ob,
865 struct render *rndr,
866 char *data,
867 size_t offset,
@@ -780,12 +871,13 @@
871 /* removing the last space from ob and rendering */
872 if( blob_size(ob)>0 && blob_buffer(ob)[blob_size(ob)-1]==' ' ) ob->nUsed--;
873 return rndr->make.linebreak(ob, rndr->make.opaque) ? 1 : 0;
874 }
875
876 /*
877 ** char_codespan -- '`' parsing a code span (assuming codespan != 0).
878 */
879 static size_t char_codespan(
880 struct Blob *ob,
881 struct render *rndr,
882 char *data,
883 size_t offset,
@@ -822,11 +914,13 @@
914 }
915 return end;
916 }
917
918
919 /*
920 ** char_escape -- '\\' backslash escape.
921 */
922 static size_t char_escape(
923 struct Blob *ob,
924 struct render *rndr,
925 char *data,
926 size_t offset,
@@ -842,13 +936,14 @@
936 }
937 }
938 return 2;
939 }
940
941 /*
942 ** char_entity -- '&' escaped when it doesn't belong to an entity.
943 ** valid entities are assumed to be anything matching &#?[A-Za-z0-9]+;
944 */
945 static size_t char_entity(
946 struct Blob *ob,
947 struct render *rndr,
948 char *data,
949 size_t offset,
@@ -877,11 +972,10 @@
972 }else{
973 blob_append(ob, data, end);
974 }
975 return end;
976 }
 
977
978 /* char_atref_tag -- '@' followed by "word" characters to tag
979 * at-references */
980 static size_t char_atref_tag(
981 struct Blob *ob,
@@ -938,13 +1032,10 @@
1032 ** or what appears to be the end or separator of a logical
1033 ** natural-language construct, e.g. period, colon, etc.
1034 **
1035 ** Current limitations of this implementation:
1036 **
 
 
 
1037 ** - Currently requires starting alpha and trailing
1038 ** alphanumeric or underscores. "Should" be extended to
1039 ** handle #X[.Y], where X and optional Y are integer
1040 ** values, for forum post references.
1041 */
@@ -1073,12 +1164,13 @@
1164 #endif
1165 #undef HASHTAG_LEGAL_END
1166 return 0;
1167 }
1168
1169 /*
1170 ** char_langle_tag -- '<' when tags or autolinks are allowed.
1171 */
1172 static size_t char_langle_tag(
1173 struct Blob *ob,
1174 struct render *rndr,
1175 char *data,
1176 size_t offset,
@@ -1103,12 +1195,12 @@
1195 }else{
1196 return end;
1197 }
1198 }
1199
1200 /*
1201 ** get_link_inline -- extract inline-style link and title from
1202 ** parenthesed data
1203 */
1204 static int get_link_inline(
1205 struct Blob *link,
1206 struct Blob *title,
@@ -1158,11 +1250,11 @@
1250 link_e--;
1251 }
1252
1253 /* remove optional angle brackets around the link */
1254 if( data[link_b]=='<' ) link_b += 1;
1255 if( link_e && data[link_e-1]=='>' ) link_e -= 1;
1256
1257 /* escape backslashed character from link */
1258 blob_reset(link);
1259 i = link_b;
1260 while( i<link_e ){
@@ -1179,145 +1271,353 @@
1271 /* this function always succeed */
1272 return 0;
1273 }
1274
1275
1276 /*
1277 ** get_link_ref -- extract referenced link and title from id.
1278 */
1279 static int get_link_ref(
1280 struct render *rndr,
1281 struct Blob *link,
1282 struct Blob *title,
1283 char *data,
1284 size_t size
1285 ){
1286 struct link_ref *lr;
1287 const size_t sz = blob_size(&rndr->refs);
1288
1289 /* find the link from its id (stored temporarily in link) */
1290 blob_reset(link);
1291 if( !sz || build_ref_id(link, data, size)<0 ) return -1;
1292 lr = bsearch(link,
1293 blob_buffer(&rndr->refs),
1294 sz/sizeof(struct link_ref),
1295 sizeof (struct link_ref),
1296 cmp_link_ref);
1297 if( !lr ) return -1;
1298
1299 /* fill the output buffers */
1300 blob_reset(link);
1301 blob_reset(title);
1302 blob_appendb(link, &lr->link);
1303 blob_appendb(title, &lr->title);
1304 return 0;
1305 }
1306
1307 /*
1308 ** get_footnote() -- find a footnote by label, invoked during the 2nd pass.
1309 ** If found then return a shallow copy of the corresponding footnote;
1310 ** otherwise return a shallow copy of rndr->notes.misref.
1311 ** In both cases corresponding `nUsed` field is incremented before return.
1312 */
1313 static struct footnote get_footnote(
1314 struct render *rndr,
1315 const char *data,
1316 size_t size
1317 ){
1318 struct footnote *fn = 0;
1319 struct Blob *id;
1320 if( !rndr->notes.nLbled ) goto fallback;
1321 id = new_work_buffer(rndr);
1322 if( build_ref_id(id, data, size)<0 ) goto cleanup;
1323 fn = bsearch(id, blob_buffer(&rndr->notes.all),
1324 rndr->notes.nLbled,
1325 sizeof (struct footnote),
1326 cmp_link_ref);
1327 if( !fn ) goto cleanup;
1328
1329 if( fn->nUsed == 0 ){ /* the first reference to the footnote */
1330 assert( fn->iMark == 0 );
1331 fn->iMark = ++(rndr->notes.nMarks);
1332 }
1333 assert( fn->iMark > 0 );
1334 cleanup:
1335 release_work_buffer( rndr, id );
1336 fallback:
1337 if( !fn ) fn = &rndr->notes.misref;
1338 fn->nUsed++;
1339 assert( fn->nUsed > 0 );
1340 return *fn;
1341 }
1342
1343 /*
1344 ** Counts characters in the blank prefix within at most nHalfLines.
1345 ** A sequence of spaces and tabs counts as odd halfline,
1346 ** a newline counts as even halfline.
1347 ** If nHalfLines < 0 then proceed without constraints.
1348 */
1349 static inline size_t sizeof_blank_prefix(
1350 const char *data, size_t size, int nHalfLines
1351 ){
1352 const char *p = data;
1353 const char * const end = data+size;
1354 if( nHalfLines < 0 ){
1355 while( p!=end && fossil_isspace(*p) ){
1356 p++;
1357 }
1358 }else while( nHalfLines > 0 ){
1359 while( p!=end && (*p==' ' || *p=='\t' ) ){ p++; }
1360 if( p==end || --nHalfLines == 0 ) break;
1361 if( *p=='\n' || *p=='\r' ){
1362 p++;
1363 if( p==end ) break;
1364 if( *p=='\n' && p[-1]=='\r' ){
1365 p++;
1366 }
1367 }
1368 nHalfLines--;
1369 }
1370 return p-data;
1371 }
1372
1373 /*
1374 ** Check if the data starts with a classlist token of the special form.
1375 ** If so then return the length of that token, otherwise return 0.
1376 **
1377 ** The token must start with a dot and must end with a colon;
1378 ** in between of these it must be a dot-separated list of words;
1379 ** each word may contain only alphanumeric characters and hyphens.
1380 **
1381 ** If `bBlank` is non-zero then a blank character must follow
1382 ** the token's ending colon: otherwise function returns 0
1383 ** despite the well-formed token.
1384 */
1385 static size_t is_footnote_classlist(const char * const data, size_t size,
1386 int bBlank){
1387 const char *p;
1388 const char * const end = data+size;
1389 if( data==end || *data != '.' ) return 0;
1390 for(p=data+1; p!=end; p++){
1391 if( fossil_isalnum(*p) || *p=='-' ) continue;
1392 if( p[-1]=='.' ) break;
1393 if( *p==':' ){
1394 p++;
1395 if( bBlank ){
1396 if( p==end || !fossil_isspace(*p) ) break;
1397 }
1398 return p-data;
1399 }
1400 if( *p!='.' ) break;
1401 }
1402 return 0;
1403 }
1404
1405 /*
1406 ** Adds unlabeled footnote to the rndr->notes.all.
1407 ** On success puts a shallow copy of the constructed footnote into pFN
1408 ** and returns 1, otherwise pFN is unchanged and 0 is returned.
1409 */
1410 static inline int add_inline_footnote(
1411 struct render *rndr,
1412 const char *text,
1413 size_t size,
1414 struct footnote* pFN
1415 ){
1416 struct footnote fn = FOOTNOTE_INITIALIZER, *last;
1417 const char *zUPC = 0;
1418 size_t nUPC = 0, n = sizeof_blank_prefix(text, size, 3);
1419 if( n >= size ) return 0;
1420 text += n;
1421 size -= n;
1422 nUPC = is_footnote_classlist(text, size, 1);
1423 if( nUPC ){
1424 assert( nUPC<size );
1425 zUPC = text;
1426 text += nUPC;
1427 size -= nUPC;
1428 }
1429 if( sizeof_blank_prefix(text,size,-1)==size ){
1430 if( !nUPC ) return 0; /* empty inline footnote */
1431 text = zUPC;
1432 size = nUPC; /* bare classlist is treated */
1433 nUPC = 0; /* as plain text */
1434 }
1435 fn.iMark = ++(rndr->notes.nMarks);
1436 fn.nUsed = 1;
1437 fn.index = COUNT_FOOTNOTES(&rndr->notes.all);
1438 assert( fn.iMark > 0 );
1439 blob_append(&fn.text, text, size);
1440 if(nUPC) blob_append(&fn.upc, zUPC, nUPC);
1441 blob_append(&rndr->notes.all, (char *)&fn, sizeof fn);
1442 last = (struct footnote*)( blob_buffer(&rndr->notes.all)
1443 +( blob_size(&rndr->notes.all)-sizeof fn ));
1444 assert( pFN );
1445 memcpy( pFN, last, sizeof fn );
1446 return 1;
1447 }
1448
1449 /*
1450 ** Return the byte offset of the matching closing bracket or 0 if not
1451 ** found. begin[0] must be either '[' or '('.
1452 **
1453 ** TODO: It seems that things like "\\(" are not handled correctly.
1454 ** That is historical behavior for a corner-case,
1455 ** so it's left as it is until somebody complains.
1456 */
1457 static inline size_t matching_bracket_offset(
1458 const char* begin,
1459 const char* end
1460 ){
1461 const char *i;
1462 int level;
1463 const char bra = *begin;
1464 const char ket = bra=='[' ? ']' : ')';
1465 assert( bra=='[' || bra=='(' );
1466 for(i=begin+1,level=1; i!=end; i++){
1467 if( *i=='\n' ) /* do nothing */;
1468 else if( i[-1]=='\\' ) continue;
1469 else if( *i==bra ) level++;
1470 else if( *i==ket ){
1471 if( --level<=0 ) return i-begin;
1472 }
1473 }
1474 return 0;
1475 }
1476
1477 /*
1478 ** char_footnote -- '(': parsing a standalone inline footnote.
1479 */
1480 static size_t char_footnote(
1481 struct Blob *ob,
1482 struct render *rndr,
1483 char *data,
1484 size_t offset,
1485 size_t size
1486 ){
1487 size_t end;
1488 struct footnote fn;
1489
1490 if( size<4 || data[1]!='^' ) return 0;
1491 end = matching_bracket_offset(data, data+size);
1492 if( !end ) return 0;
1493 if( !add_inline_footnote(rndr, data+2, end-2, &fn) ) return 0;
1494 if( rndr->make.footnote_ref ){
1495 rndr->make.footnote_ref(ob,0,&fn.upc,fn.iMark,1,rndr->make.opaque);
1496 }
1497 return end+1;
1498 }
1499
1500 /*
1501 ** char_link -- '[': parsing a link or an image.
1502 */
1503 static size_t char_link(
1504 struct Blob *ob,
1505 struct render *rndr,
1506 char *data,
1507 size_t offset,
1508 size_t size /* parse_inline() ensures that size > 0 */
1509 ){
1510 const int is_img = (offset && data[-1] == '!');
1511 size_t i = 1, txt_e;
1512 struct Blob *content = 0;
1513 struct Blob *link = 0;
1514 struct Blob *title = 0;
1515 struct footnote fn;
1516 int ret;
1517
1518 /* checking whether the correct renderer exists */
1519 if( (is_img && !rndr->make.image) || (!is_img && !rndr->make.link) ){
1520 return 0;
1521 }
1522
1523 /* looking for the matching closing bracket */
1524 txt_e = matching_bracket_offset(data, data+size);
1525 if( !txt_e ) return 0;
1526 i = txt_e + 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1527 ret = 0; /* error if we don't get to the callback */
1528 fn.nUsed = 0;
1529
1530 /* free-standing footnote refernece */
1531 if(!is_img && size>3 && data[1]=='^'){
1532 fn = get_footnote(rndr, data+2, txt_e-2);
1533 }else{
1534
1535 /* skip "inter-bracket-whitespace" - any amount of whitespace or newline */
1536 /* (this is much more lax than original markdown syntax) */
1537 while( i<size && (data[i]==' ' || data[i]=='\t' || data[i]=='\n') ){ i++; }
1538
1539 /* allocate temporary buffers to store content, link and title */
1540 title = new_work_buffer(rndr);
1541 content = new_work_buffer(rndr);
1542 link = new_work_buffer(rndr);
1543
1544 if( i<size && data[i]=='(' ){
1545
1546 if( i+2<size && data[i+1]=='^' ){ /* span-bounded inline footnote */
1547
1548 const size_t k = matching_bracket_offset(data+i, data+size);
1549 if( !k ) goto char_link_cleanup;
1550 add_inline_footnote(rndr, data+(i+2), k-2, &fn);
1551 i += k+1;
1552 }else{ /* inline style link */
1553 size_t span_end = i;
1554 while( span_end<size
1555 && !(data[span_end]==')'
1556 && (span_end==i || data[span_end-1]!='\\')) ){
1557 span_end++;
1558 }
1559 if( span_end>=size
1560 || get_link_inline(link, title, data+i+1, span_end-(i+1))<0 ){
1561 goto char_link_cleanup;
1562 }
1563 i = span_end+1;
1564 }
1565 /* reference style link or span-bounded footnote reference */
1566 }else if( i<size && data[i]=='[' ){
1567 char *id_data;
1568 size_t id_size, id_end = i;
1569 int bFootnote;
1570
1571 while( id_end<size && data[id_end]!=']' ){ id_end++; }
1572 if( id_end>=size ) goto char_link_cleanup;
1573 bFootnote = data[i+1]=='^';
1574 if( i+1==id_end || (bFootnote && i+2==id_end) ){
1575 /* implicit id - use the contents */
1576 id_data = data+1;
1577 id_size = txt_e-1;
1578 }else{
1579 /* explicit id - between brackets */
1580 id_data = data+i+1;
1581 id_size = id_end-(i+1);
1582 if( bFootnote ){
1583 id_data++;
1584 id_size--;
1585 }
1586 }
1587 if( bFootnote ){
1588 fn = get_footnote(rndr, id_data, id_size);
1589 }else if( get_link_ref(rndr, link, title, id_data, id_size)<0 ){
1590 goto char_link_cleanup;
1591 }
1592 i = id_end+1;
1593 /* shortcut reference style link */
1594 }else{
1595 if( get_link_ref(rndr, link, title, data+1, txt_e-1)<0 ){
1596 goto char_link_cleanup;
1597 }
1598 /* rewinding an "inter-bracket-whitespace" */
1599 i = txt_e+1;
1600 }
1601 }
1602 /* building content: img alt is escaped, link content is parsed */
1603 if( txt_e>1 && content ){
1604 if( is_img ) blob_append(content, data+1, txt_e-1);
1605 else parse_inline(content, rndr, data+1, txt_e-1);
1606 }
1607
1608 /* calling the relevant rendering function */
1609 if( is_img ){
1610 if( blob_size(ob)>0 && blob_buffer(ob)[blob_size(ob)-1]=='!' ){
1611 ob->nUsed--;
1612 }
1613 ret = rndr->make.image(ob, link, title, content, rndr->make.opaque);
1614 }else if( fn.nUsed ){
1615 if( rndr->make.footnote_ref ){
1616 ret = rndr->make.footnote_ref(ob, content, &fn.upc, fn.iMark,
1617 fn.nUsed, rndr->make.opaque);
1618 }
1619 }else{
1620 ret = rndr->make.link(ob, link, title, content, rndr->make.opaque);
1621 }
1622
1623 /* cleanup */
@@ -1325,11 +1625,10 @@
1625 release_work_buffer(rndr, title);
1626 release_work_buffer(rndr, link);
1627 release_work_buffer(rndr, content);
1628 return ret ? i : 0;
1629 }
 
1630
1631
1632 /*********************************
1633 * BLOCK-LEVEL PARSING FUNCTIONS *
1634 *********************************/
@@ -2010,11 +2309,12 @@
2309 /* the end of the block has been found */
2310 if( strcmp(curtag->text,"html")==0 ){
2311 /* Omit <html> tags */
2312 enum mkd_autolink dummy;
2313 int k = tag_length(data, size, &dummy);
2314 int sz = i - (j+k);
2315 if( sz>0 ) blob_init(&work, data+k, sz);
2316 }else{
2317 blob_init(&work, data, i);
2318 }
2319 if( rndr->make.blockhtml ){
2320 rndr->make.blockhtml(ob, &work, rndr->make.opaque);
@@ -2217,11 +2517,13 @@
2517 char *data, /* input text */
2518 size_t size /* input text size */
2519 ){
2520 size_t beg, end, i;
2521 char *txt_data;
2522 int has_table;
2523 if( !size ) return;
2524 has_table = (rndr->make.table
2525 && rndr->make.table_row
2526 && rndr->make.table_cell
2527 && memchr(data, '|', size)!=0);
2528
2529 beg = 0;
@@ -2267,11 +2569,11 @@
2569 * REFERENCE PARSING *
2570 *********************/
2571
2572 /* is_ref -- returns whether a line is a reference or not */
2573 static int is_ref(
2574 const char *data, /* input text */
2575 size_t beg, /* offset of the beginning of the line */
2576 size_t end, /* offset of the end of the text */
2577 size_t *last, /* last character of the link */
2578 struct Blob *refs /* array of link references */
2579 ){
@@ -2301,10 +2603,12 @@
2603 i += beg;
2604
2605 /* id part: anything but a newline between brackets */
2606 if( data[i]!='[' ) return 0;
2607 i++;
2608 if( i>=end || data[i]=='^' ) return 0; /* see is_footnote() */
2609
2610 id_offset = i;
2611 while( i<end && data[i]!='\n' && data[i]!='\r' && data[i]!=']' ){ i++; }
2612 if( i>=end || data[i]!=']' ) return 0;
2613 id_end = i;
2614
@@ -2329,10 +2633,11 @@
2633 && data[i]!='\n'
2634 && data[i]!='\r'
2635 ){
2636 i += 1;
2637 }
2638 /* TODO: maybe require both data[i-1]=='>' && data[link_offset-1]=='<' ? */
2639 if( data[i-1]=='>' ) link_end = i-1; else link_end = i;
2640
2641 /* optional spacer: (space | tab)* (newline | '\'' | '"' | '(' ) */
2642 while( i<end && (data[i]==' ' || data[i]=='\t') ){ i++; }
2643 if( i<end
@@ -2388,34 +2693,168 @@
2693 }
2694 blob_append(refs, (char *)&lr, sizeof lr);
2695 return 1;
2696 }
2697
2698 /*********************
2699 * FOOTNOTE PARSING *
2700 *********************/
2701
2702 /* is_footnote -- check if data holds a definition of a labeled footnote.
2703 * If so then append the corresponding element to `footnotes` array */
2704 static int is_footnote(
2705 const char *data, /* input text */
2706 size_t beg, /* offset of the beginning of the line */
2707 size_t end, /* offset of the end of the text */
2708 size_t *last, /* last character of the link */
2709 struct Blob * footnotes
2710 ){
2711 size_t i, id_offset, id_end, upc_offset, upc_size;
2712 struct footnote fn = FOOTNOTE_INITIALIZER;
2713
2714 /* failfast if data is too short */
2715 if( beg+5>=end ) return 0;
2716 i = beg;
2717
2718 /* footnote definition must start at the begining of a line */
2719 if( data[i]!='[' ) return 0;
2720 i++;
2721 if( data[i]!='^' ) return 0;
2722 id_offset = ++i;
2723
2724 /* id part: anything but a newline between brackets */
2725 while( i<end && data[i]!=']' && data[i]!='\n' && data[i]!='\r' ){ i++; }
2726 if( i>=end || data[i]!=']' ) return 0;
2727 id_end = i++;
2728
2729 /* spacer: colon (space | tab)* */
2730 if( i>=end || data[i]!=':' ) return 0;
2731 i++;
2732 while( i<end && (data[i]==' ' || data[i]=='\t') ){ i++; }
2733
2734 /* passthrough truncated footnote definition */
2735 if( i>=end ) return 0;
2736
2737 if( build_ref_id(&fn.id, data+id_offset, id_end-id_offset)<0 ) return 0;
2738
2739 /* footnote's text may start on the same line after [^id]: */
2740 upc_offset = upc_size = 0;
2741 if( data[i]!='\n' && data[i]!='\r' ){
2742 size_t j;
2743 upc_size = is_footnote_classlist(data+i, end-i, 1);
2744 upc_offset = i; /* prevent further checks for a classlist */
2745 i += upc_size;
2746 j = i;
2747 while( i<end && data[i]!='\n' && data[i]!='\r' ){ i++; };
2748 if( i!=j )blob_append(&fn.text, data+j, i-j);
2749 if( i<end ){
2750 blob_append_char(&fn.text, data[i]);
2751 i++;
2752 if( i<end && data[i]=='\n' && data[i-1]=='\r' ){
2753 blob_append_char(&fn.text, data[i]);
2754 i++;
2755 }
2756 }
2757 }else{
2758 i++;
2759 if( i<end && data[i]=='\n' && data[i-1]=='\r' ) i++;
2760 }
2761 if( i<end ){
2762
2763 /* compute the indentation from the 2nd line */
2764 size_t indent = i;
2765 const char *spaces = data+i;
2766 while( indent<end && data[indent]==' ' ){ indent++; }
2767 if( indent>=end ) goto footnote_finish;
2768 indent -= i;
2769 if( indent<2 ) goto footnote_finish;
2770
2771 /* process the 2nd and subsequent lines */
2772 while( i+indent<end && memcmp(data+i,spaces,indent)==0 ){
2773 size_t j;
2774 i += indent;
2775 if( !upc_offset ){
2776 /* a classlist must be provided no later than at the 2nd line */
2777 upc_offset = i + sizeof_blank_prefix(data+i, end-i, 1);
2778 upc_size = is_footnote_classlist(data+upc_offset,
2779 end-upc_offset, 1);
2780 if( upc_size ){
2781 i = upc_offset + upc_size;
2782 }
2783 }
2784 j = i;
2785 while( i<end && data[i]!='\n' && data[i]!='\r' ){ i++; }
2786 if( i!=j ) blob_append(&fn.text, data+j, i-j);
2787 if( i>=end ) break;
2788 blob_append_char(&fn.text, data[i]);
2789 i++;
2790 if( i<end && data[i]=='\n' && data[i-1]=='\r' ){
2791 blob_append_char(&fn.text, data[i]);
2792 i++;
2793 }
2794 }
2795 }
2796 footnote_finish:
2797 if( !blob_size(&fn.text) ){
2798 blob_reset(&fn.id);
2799 return 0;
2800 }
2801 if( !blob_trim(&fn.text) ){ /* if the content is all-blank */
2802 if( upc_size ){ /* interpret UPC as plain text */
2803 blob_append(&fn.text, data+upc_offset, upc_size);
2804 upc_size = 0;
2805 }else{
2806 blob_reset(&fn.id); /* or clean up and fail */
2807 blob_reset(&fn.text);
2808 return 0;
2809 }
2810 }
2811 /* a valid note has been found */
2812 if( last ) *last = i;
2813 if( footnotes ){
2814 fn.defno = COUNT_FOOTNOTES( footnotes );
2815 if( upc_size ){
2816 assert( upc_offset && upc_offset+upc_size<end );
2817 blob_append(&fn.upc, data+upc_offset, upc_size);
2818 }
2819 blob_append(footnotes, (char *)&fn, sizeof fn);
2820 }
2821 return 1;
2822 }
2823
2824 /**********************
2825 * EXPORTED FUNCTIONS *
2826 **********************/
2827
2828 /* markdown -- parses the input buffer and renders it into the output buffer */
2829 void markdown(
2830 struct Blob *ob, /* output blob for rendered text */
2831 const struct Blob *ib, /* input blob in markdown */
2832 const struct mkd_renderer *rndrer /* renderer descriptor (callbacks) */
2833 ){
2834 struct link_ref *lr;
2835 struct footnote *fn;
2836 size_t i, beg, end = 0;
2837 struct render rndr;
2838 Blob text = BLOB_INITIALIZER; /* input after the first pass */
2839 Blob * const allNotes = &rndr.notes.all;
2840
2841 /* filling the render structure */
2842 if( !rndrer ) return;
2843 rndr.make = *rndrer;
2844 rndr.nBlobCache = 0;
2845 rndr.iDepth = 0;
2846 rndr.refs = empty_blob;
2847 rndr.notes.all = empty_blob;
2848 rndr.notes.nMarks = 0;
2849 rndr.notes.misref.id = empty_blob;
2850 rndr.notes.misref.text = empty_blob;
2851 rndr.notes.misref.upc = empty_blob;
2852 rndr.notes.misref.bRndred = 0;
2853 rndr.notes.misref.nUsed = 0;
2854 rndr.notes.misref.iMark = -1;
2855
2856 for(i=0; i<256; i++) rndr.active_char[i] = 0;
2857 if( (rndr.make.emphasis
2858 || rndr.make.double_emphasis
2859 || rndr.make.triple_emphasis)
2860 && rndr.make.emph_chars
@@ -2427,32 +2866,34 @@
2866 if( rndr.make.codespan ) rndr.active_char['`'] = char_codespan;
2867 if( rndr.make.linebreak ) rndr.active_char['\n'] = char_linebreak;
2868 if( rndr.make.image || rndr.make.link ) rndr.active_char['['] = char_link;
2869 rndr.active_char['@'] = char_atref_tag;
2870 rndr.active_char['#'] = char_hashref_tag;
2871 if( rndr.make.footnote_ref ) rndr.active_char['('] = char_footnote;
2872 rndr.active_char['<'] = char_langle_tag;
2873 rndr.active_char['\\'] = char_escape;
2874 rndr.active_char['&'] = char_entity;
2875
2876 /* first pass: iterate over lines looking for references,
2877 * copying everything else into "text" */
2878 beg = 0;
2879 for(const size_t size = blob_size(ib); beg<size ;){
2880 const char* const data = blob_buffer(ib);
2881 if( is_ref(data, beg, size, &end, &rndr.refs) ){
2882 beg = end;
2883 }else if(is_footnote(data, beg, size, &end, &rndr.notes.all)){
2884 beg = end;
2885 }else{ /* skipping to the next line */
2886 end = beg;
2887 while( end<size && data[end]!='\n' && data[end]!='\r' ){
2888 end += 1;
2889 }
2890 /* adding the line body if present */
2891 if( end>beg ) blob_append(&text, data + beg, end - beg);
2892 while( end<size && (data[end]=='\n' || data[end]=='\r') ){
2893 /* add one \n per newline */
2894 if( data[end]=='\n' || (end+1<size && data[end+1]!='\n') ){
 
 
2895 blob_append_char(&text, '\n');
2896 }
2897 end += 1;
2898 }
2899 beg = end;
@@ -2464,14 +2905,160 @@
2905 qsort(blob_buffer(&rndr.refs),
2906 blob_size(&rndr.refs)/sizeof(struct link_ref),
2907 sizeof(struct link_ref),
2908 cmp_link_ref_sort);
2909 }
2910 rndr.notes.nLbled = COUNT_FOOTNOTES( allNotes );
2911
2912 /* sort footnotes by ID and join duplicates */
2913 if( rndr.notes.nLbled > 1 ){
2914 int nDups = 0;
2915 fn = CAST_AS_FOOTNOTES( allNotes );
2916 qsort(fn, rndr.notes.nLbled, sizeof(struct footnote), cmp_footnote_id);
2917
2918 /* concatenate footnotes with equal labels */
2919 for(i=0; i<rndr.notes.nLbled ;){
2920 struct footnote *x = fn + i;
2921 size_t j = i+1, k = blob_size(&x->text) + 64 + blob_size(&x->upc);
2922 while(j<rndr.notes.nLbled && !blob_compare(&x->id, &fn[j].id)){
2923 k += blob_size(&fn[j].text) + 10 + blob_size(&fn[j].upc);
2924 j++;
2925 nDups++;
2926 }
2927 if( i+1<j ){
2928 Blob list = empty_blob;
2929 blob_reserve(&list, k);
2930 /* must match _joined_footnote_indicator in html_footnote_item() */
2931 blob_append_literal(&list, "<ul class='fn-joined'>\n");
2932 for(k=i; k<j; k++){
2933 struct footnote *y = fn + k;
2934 blob_append_literal(&list, "<li>");
2935 if( blob_size(&y->upc) ){
2936 blob_appendb(&list, &y->upc);
2937 blob_reset(&y->upc);
2938 }
2939 blob_appendb(&list, &y->text);
2940 blob_append_literal(&list, "</li>\n");
2941
2942 /* free memory buffer */
2943 blob_reset(&y->text);
2944 if( k!=i ) blob_reset(&y->id);
2945 }
2946 blob_append_literal(&list, "</ul>\n");
2947 x->text = list;
2948 g.ftntsIssues[2]++;
2949 }
2950 i = j;
2951 }
2952 if( nDups ){ /* clean rndr.notes.all from invalidated footnotes */
2953 const int n = rndr.notes.nLbled - nDups;
2954 struct Blob filtered = empty_blob;
2955 blob_reserve(&filtered, n*sizeof(struct footnote));
2956 for(i=0; i<rndr.notes.nLbled; i++){
2957 if( blob_size(&fn[i].id) ){
2958 blob_append(&filtered, (char*)(fn+i), sizeof(struct footnote));
2959 }
2960 }
2961 blob_reset( allNotes );
2962 rndr.notes.all = filtered;
2963 rndr.notes.nLbled = n;
2964 assert( COUNT_FOOTNOTES(allNotes) == rndr.notes.nLbled );
2965 }
2966 }
2967 fn = CAST_AS_FOOTNOTES( allNotes );
2968 for(i=0; i<rndr.notes.nLbled; i++){
2969 fn[i].index = i;
2970 }
2971 assert( rndr.notes.nMarks==0 );
2972
2973 /* second pass: actual rendering */
2974 if( rndr.make.prolog ) rndr.make.prolog(ob, rndr.make.opaque);
2975 parse_block(ob, &rndr, blob_buffer(&text), blob_size(&text));
2976
2977 if( blob_size(allNotes) || rndr.notes.misref.nUsed ){
2978
2979 /* Footnotes must be parsed for the correct discovery of (back)links */
2980 Blob *notes = new_work_buffer( &rndr );
2981 if( blob_size(allNotes) ){
2982 Blob *tmp = new_work_buffer( &rndr );
2983 int nMarks = -1, maxDepth = 5;
2984
2985 /* inline notes may get appended to rndr.notes.all while rendering */
2986 while(1){
2987 struct footnote *aNotes;
2988 const int N = COUNT_FOOTNOTES( allNotes );
2989
2990 /* make a shallow copy of `allNotes` */
2991 blob_truncate(notes,0);
2992 blob_appendb(notes, allNotes);
2993 aNotes = CAST_AS_FOOTNOTES(notes);
2994 qsort(aNotes, N, sizeof(struct footnote), cmp_footnote_sort);
2995
2996 if( --maxDepth < 0 || nMarks == rndr.notes.nMarks ) break;
2997 nMarks = rndr.notes.nMarks;
2998
2999 for(i=0; i<N; i++){
3000 const int j = aNotes[i].index;
3001 struct footnote *x = CAST_AS_FOOTNOTES(allNotes) + j;
3002 assert( 0<=j && j<N );
3003 if( x->bRndred || !x->nUsed ) continue;
3004 assert( x->iMark > 0 );
3005 assert( blob_size(&x->text) );
3006 blob_truncate(tmp,0);
3007
3008 /* `allNotes` may be altered and extended through this call */
3009 parse_inline(tmp, &rndr, blob_buffer(&x->text), blob_size(&x->text));
3010
3011 x = CAST_AS_FOOTNOTES(allNotes) + j;
3012 blob_truncate(&x->text,0);
3013 blob_appendb(&x->text, tmp);
3014 x->bRndred = 1;
3015 }
3016 }
3017 release_work_buffer(&rndr,tmp);
3018 }
3019
3020 /* footnotes rendering */
3021 if( rndr.make.footnote_item && rndr.make.footnotes ){
3022 Blob *all_items = new_work_buffer(&rndr);
3023 int j = -1;
3024
3025 /* Assert that the in-memory layout of id, text and upc within
3026 ** footnote struct matches the expectations of html_footnote_item()
3027 ** If it doesn't then a compiler has done something very weird.
3028 */
3029 assert( &(rndr.notes.misref.id) == &(rndr.notes.misref.text) - 1 );
3030 assert( &(rndr.notes.misref.upc) == &(rndr.notes.misref.text) + 1 );
3031
3032 for(i=0; i<COUNT_FOOTNOTES(notes); i++){
3033 const struct footnote* x = CAST_AS_FOOTNOTES(notes) + i;
3034 const int xUsed = x->bRndred ? x->nUsed : 0;
3035 if( !x->iMark ) break;
3036 assert( x->nUsed );
3037 rndr.make.footnote_item(all_items, &x->text, x->iMark,
3038 xUsed, rndr.make.opaque);
3039 if( !xUsed ) g.ftntsIssues[3]++; /* an overnested footnote */
3040 j = i;
3041 }
3042 if( rndr.notes.misref.nUsed ){
3043 rndr.make.footnote_item(all_items, 0, -1,
3044 rndr.notes.misref.nUsed, rndr.make.opaque);
3045 g.ftntsIssues[0] += rndr.notes.misref.nUsed;
3046 }
3047 while( ++j < COUNT_FOOTNOTES(notes) ){
3048 const struct footnote* x = CAST_AS_FOOTNOTES(notes) + j;
3049 assert( !x->iMark );
3050 assert( !x->nUsed );
3051 assert( !x->bRndred );
3052 rndr.make.footnote_item(all_items,&x->text,0,0,rndr.make.opaque);
3053 g.ftntsIssues[1]++;
3054 }
3055 rndr.make.footnotes(ob, all_items, rndr.make.opaque);
3056 release_work_buffer(&rndr, all_items);
3057 }
3058 release_work_buffer(&rndr, notes);
3059 }
3060 if( rndr.make.epilog ) rndr.make.epilog(ob, rndr.make.opaque);
3061
3062 /* clean-up */
3063 assert( rndr.iDepth==0 );
3064 blob_reset(&text);
@@ -2481,9 +3068,17 @@
3068 blob_reset(&lr[i].id);
3069 blob_reset(&lr[i].link);
3070 blob_reset(&lr[i].title);
3071 }
3072 blob_reset(&rndr.refs);
3073 fn = CAST_AS_FOOTNOTES( allNotes );
3074 end = COUNT_FOOTNOTES( allNotes );
3075 for(i=0; i<end; i++){
3076 if(blob_size(&fn[i].id)) blob_reset(&fn[i].id);
3077 if(blob_size(&fn[i].upc)) blob_reset(&fn[i].upc);
3078 blob_reset(&fn[i].text);
3079 }
3080 blob_reset(&rndr.notes.all);
3081 for(i=0; i<rndr.nBlobCache; i++){
3082 fossil_free(rndr.aBlobCache[i]);
3083 }
3084 }
3085
+730 -135
--- src/markdown.c
+++ src/markdown.c
@@ -52,10 +52,11 @@
5252
/* mkd_renderer -- functions for rendering parsed data */
5353
struct mkd_renderer {
5454
/* document level callbacks */
5555
void (*prolog)(struct Blob *ob, void *opaque);
5656
void (*epilog)(struct Blob *ob, void *opaque);
57
+ void (*footnotes)(struct Blob *ob, const struct Blob *items, void *opaque);
5758
5859
/* block level callbacks - NULL skips the block */
5960
void (*blockcode)(struct Blob *ob, struct Blob *text, void *opaque);
6061
void (*blockquote)(struct Blob *ob, struct Blob *text, void *opaque);
6162
void (*blockhtml)(struct Blob *ob, struct Blob *text, void *opaque);
@@ -70,10 +71,12 @@
7071
void *opaque);
7172
void (*table_cell)(struct Blob *ob, struct Blob *text, int flags,
7273
void *opaque);
7374
void (*table_row)(struct Blob *ob, struct Blob *cells, int flags,
7475
void *opaque);
76
+ void (*footnote_item)(struct Blob *ob, const struct Blob *text,
77
+ int index, int nUsed, void *opaque);
7578
7679
/* span level callbacks - NULL or return 0 prints the span verbatim */
7780
int (*autolink)(struct Blob *ob, struct Blob *link,
7881
enum mkd_autolink type, void *opaque);
7982
int (*codespan)(struct Blob *ob, struct Blob *text, int nSep, void *opaque);
@@ -88,10 +91,12 @@
8891
int (*raw_html_tag)(struct Blob *ob, struct Blob *tag, void *opaque);
8992
int (*tagspan)(struct Blob *ob, struct Blob *ref, enum mkd_tagspan type,
9093
void *opaque);
9194
int (*triple_emphasis)(struct Blob *ob, struct Blob *text,
9295
char c, void *opaque);
96
+ int (*footnote_ref)(struct Blob *ob, const struct Blob *span,
97
+ const struct Blob *upc, int index, int locus, void *opaque);
9398
9499
/* low level callbacks - NULL copies input directly into the output */
95100
void (*entity)(struct Blob *ob, struct Blob *entity, void *opaque);
96101
void (*normal_text)(struct Blob *ob, struct Blob *text, void *opaque);
97102
@@ -122,31 +127,54 @@
122127
123128
/**********************
124129
* EXPORTED FUNCTIONS *
125130
**********************/
126131
127
-/* markdown -- parses the input buffer and renders it into the output buffer */
132
+/*
133
+** markdown -- parses the input buffer and renders it into the output buffer.
134
+*/
128135
void markdown(
129136
struct Blob *ob,
130
- struct Blob *ib,
137
+ const struct Blob *ib,
131138
const struct mkd_renderer *rndr);
132139
133140
134141
#endif /* INTERFACE */
135142
143
+#define BLOB_COUNT(pBlob,el_type) (blob_size(pBlob)/sizeof(el_type))
144
+#define COUNT_FOOTNOTES(pBlob) BLOB_COUNT(pBlob,struct footnote)
145
+#define CAST_AS_FOOTNOTES(pBlob) ((struct footnote*)blob_buffer(pBlob))
136146
137147
/***************
138148
* LOCAL TYPES *
139149
***************/
140150
141
-/* link_ref -- reference to a link */
151
+/*
152
+** link_ref -- reference to a link.
153
+*/
142154
struct link_ref {
143
- struct Blob id;
155
+ struct Blob id; /* must be the first field as in footnote struct */
144156
struct Blob link;
145157
struct Blob title;
146158
};
147159
160
+/*
161
+** A footnote's data.
162
+** id, text, and upc fields must be in that particular order.
163
+*/
164
+struct footnote {
165
+ struct Blob id; /* must be the first field as in link_ref struct */
166
+ struct Blob text; /* footnote's content that is rendered at the end */
167
+ struct Blob upc; /* user-provided classes .ASCII-alnum.or-hypen: */
168
+ int bRndred; /* indicates if `text` holds a rendered content */
169
+
170
+ int defno; /* serial number of definition, set during the first pass */
171
+ int index; /* set to the index within array after ordering by id */
172
+ int iMark; /* user-visible numeric marker, assigned upon the first use*/
173
+ int nUsed; /* counts references to this note, increments upon each use*/
174
+};
175
+#define FOOTNOTE_INITIALIZER {empty_blob,empty_blob,empty_blob, 0,0,0,0,0}
148176
149177
/* char_trigger -- function pointer to render active chars */
150178
/* returns the number of chars taken care of */
151179
/* data is the pointer of the beginning of the span */
152180
/* offset is the number of valid chars before data */
@@ -165,12 +193,19 @@
165193
struct Blob refs;
166194
char_trigger active_char[256];
167195
int iDepth; /* Depth of recursion */
168196
int nBlobCache; /* Number of entries in aBlobCache */
169197
struct Blob *aBlobCache[20]; /* Cache of Blobs available for reuse */
198
+
199
+ struct {
200
+ Blob all; /* Buffer that holds array of footnotes. Its underline
201
+ memory may be reallocated when a new footnote is added. */
202
+ int nLbled; /* number of labeled footnotes found during the first pass */
203
+ int nMarks; /* counts distinct indices found during the second pass */
204
+ struct footnote misref; /* nUsed counts misreferences, iMark must be -1 */
205
+ } notes;
170206
};
171
-
172207
173208
/* html_tag -- structure for quick HTML tag search (inspired from discount) */
174209
struct html_tag {
175210
const char *text;
176211
int size;
@@ -192,16 +227,18 @@
192227
{ "html", 4 },
193228
{ "pre", 3 },
194229
{ "script", 6 },
195230
};
196231
197
-
198232
/***************************
199233
* STATIC HELPER FUNCTIONS *
200234
***************************/
201235
202
-/* build_ref_id -- collapse whitespace from input text to make it a ref id */
236
+/*
237
+** build_ref_id -- collapse whitespace from input text to make it a ref id.
238
+** Potential TODO: maybe also handle CR+LF line endings?
239
+*/
203240
static int build_ref_id(struct Blob *id, const char *data, size_t size){
204241
size_t beg, i;
205242
char *id_data;
206243
207244
/* skip leading whitespace */
@@ -256,10 +293,58 @@
256293
struct link_ref *lra = (void *)a;
257294
struct link_ref *lrb = (void *)b;
258295
return blob_compare(&lra->id, &lrb->id);
259296
}
260297
298
+/*
299
+** cmp_footnote_id -- comparison function for footnotes qsort.
300
+** Empty IDs sort last (in undetermined order).
301
+** Equal IDs are sorted in the order of definition in the source.
302
+*/
303
+static int cmp_footnote_id(const void *fna, const void *fnb){
304
+ const struct footnote *a = fna, *b = fnb;
305
+ const int szA = blob_size(&a->id), szB = blob_size(&b->id);
306
+ if( szA ){
307
+ if( szB ){
308
+ int cmp = blob_compare(&a->id, &b->id);
309
+ if( cmp ) return cmp;
310
+ }else return -1;
311
+ }else return szB ? 1 : 0;
312
+ /* IDs are equal and non-empty */
313
+ if( a->defno < b->defno ) return -1;
314
+ if( a->defno > b->defno ) return 1;
315
+ assert(!"reachable");
316
+ return 0; /* should never reach here */
317
+}
318
+
319
+/*
320
+** cmp_footnote_sort -- comparison function for footnotes qsort.
321
+** Unreferenced footnotes (when nUsed == 0) sort last and
322
+** are sorted in the order of definition in the source.
323
+*/
324
+static int cmp_footnote_sort(const void *fna, const void *fnb){
325
+ const struct footnote *a = fna, *b = fnb;
326
+ int i, j;
327
+ assert( a->nUsed >= 0 );
328
+ assert( b->nUsed >= 0 );
329
+ assert( a->defno >= 0 );
330
+ assert( b->defno >= 0 );
331
+ if( a->nUsed ){
332
+ assert( a->iMark > 0 );
333
+ if( !b->nUsed ) return -1;
334
+ assert( b->iMark > 0 );
335
+ i = a->iMark;
336
+ j = b->iMark;
337
+ }else{
338
+ if( b->nUsed ) return 1;
339
+ i = a->defno;
340
+ j = b->defno;
341
+ }
342
+ if( i < j ) return -1;
343
+ if( i > j ) return 1;
344
+ return 0;
345
+}
261346
262347
/* cmp_html_tag -- comparison function for bsearch() (stolen from discount) */
263348
static int cmp_html_tag(const void *a, const void *b){
264349
const struct html_tag *hta = a;
265350
const struct html_tag *htb = b;
@@ -588,12 +673,14 @@
588673
if( fossil_isalnum(after) ) return 0;
589674
return 1;
590675
}
591676
592677
593
-/* parse_emph1 -- parsing single emphasis */
594
-/* closed by a symbol not preceded by whitespace and not followed by symbol */
678
+/*
679
+** parse_emph1 -- parsing single emphasis.
680
+** closed by a symbol not preceded by whitespace and not followed by symbol.
681
+*/
595682
static size_t parse_emph1(
596683
struct Blob *ob,
597684
struct render *rndr,
598685
char *data,
599686
size_t size,
@@ -633,12 +720,13 @@
633720
}
634721
}
635722
return 0;
636723
}
637724
638
-
639
-/* parse_emph2 -- parsing single emphasis */
725
+/*
726
+** parse_emph2 -- parsing single emphasis.
727
+*/
640728
static size_t parse_emph2(
641729
struct Blob *ob,
642730
struct render *rndr,
643731
char *data,
644732
size_t size,
@@ -672,13 +760,14 @@
672760
i++;
673761
}
674762
return 0;
675763
}
676764
677
-
678
-/* parse_emph3 -- parsing single emphasis */
679
-/* finds the first closing tag, and delegates to the other emph */
765
+/*
766
+** parse_emph3 -- parsing single emphasis.
767
+** finds the first closing tag, and delegates to the other emph.
768
+*/
680769
static size_t parse_emph3(
681770
struct Blob *ob,
682771
struct render *rndr,
683772
char *data,
684773
size_t size,
@@ -720,12 +809,13 @@
720809
}
721810
}
722811
return 0;
723812
}
724813
725
-
726
-/* char_emphasis -- single and double emphasis parsing */
814
+/*
815
+** char_emphasis -- single and double emphasis parsing.
816
+*/
727817
static size_t char_emphasis(
728818
struct Blob *ob,
729819
struct render *rndr,
730820
char *data,
731821
size_t offset,
@@ -765,12 +855,13 @@
765855
return ret+3;
766856
}
767857
return 0;
768858
}
769859
770
-
771
-/* char_linebreak -- '\n' preceded by two spaces (assuming linebreak != 0) */
860
+/*
861
+** char_linebreak -- '\n' preceded by two spaces (assuming linebreak != 0).
862
+*/
772863
static size_t char_linebreak(
773864
struct Blob *ob,
774865
struct render *rndr,
775866
char *data,
776867
size_t offset,
@@ -780,12 +871,13 @@
780871
/* removing the last space from ob and rendering */
781872
if( blob_size(ob)>0 && blob_buffer(ob)[blob_size(ob)-1]==' ' ) ob->nUsed--;
782873
return rndr->make.linebreak(ob, rndr->make.opaque) ? 1 : 0;
783874
}
784875
785
-
786
-/* char_codespan -- '`' parsing a code span (assuming codespan != 0) */
876
+/*
877
+** char_codespan -- '`' parsing a code span (assuming codespan != 0).
878
+*/
787879
static size_t char_codespan(
788880
struct Blob *ob,
789881
struct render *rndr,
790882
char *data,
791883
size_t offset,
@@ -822,11 +914,13 @@
822914
}
823915
return end;
824916
}
825917
826918
827
-/* char_escape -- '\\' backslash escape */
919
+/*
920
+** char_escape -- '\\' backslash escape.
921
+*/
828922
static size_t char_escape(
829923
struct Blob *ob,
830924
struct render *rndr,
831925
char *data,
832926
size_t offset,
@@ -842,13 +936,14 @@
842936
}
843937
}
844938
return 2;
845939
}
846940
847
-
848
-/* char_entity -- '&' escaped when it doesn't belong to an entity */
849
-/* valid entities are assumed to be anything matching &#?[A-Za-z0-9]+; */
941
+/*
942
+** char_entity -- '&' escaped when it doesn't belong to an entity.
943
+** valid entities are assumed to be anything matching &#?[A-Za-z0-9]+;
944
+*/
850945
static size_t char_entity(
851946
struct Blob *ob,
852947
struct render *rndr,
853948
char *data,
854949
size_t offset,
@@ -877,11 +972,10 @@
877972
}else{
878973
blob_append(ob, data, end);
879974
}
880975
return end;
881976
}
882
-
883977
884978
/* char_atref_tag -- '@' followed by "word" characters to tag
885979
* at-references */
886980
static size_t char_atref_tag(
887981
struct Blob *ob,
@@ -938,13 +1032,10 @@
9381032
** or what appears to be the end or separator of a logical
9391033
** natural-language construct, e.g. period, colon, etc.
9401034
**
9411035
** Current limitations of this implementation:
9421036
**
943
-** - ASCII only. Support for non-ASCII characters might be
944
-** interesting.
945
-**
9461037
** - Currently requires starting alpha and trailing
9471038
** alphanumeric or underscores. "Should" be extended to
9481039
** handle #X[.Y], where X and optional Y are integer
9491040
** values, for forum post references.
9501041
*/
@@ -1073,12 +1164,13 @@
10731164
#endif
10741165
#undef HASHTAG_LEGAL_END
10751166
return 0;
10761167
}
10771168
1078
-
1079
-/* char_langle_tag -- '<' when tags or autolinks are allowed */
1169
+/*
1170
+** char_langle_tag -- '<' when tags or autolinks are allowed.
1171
+*/
10801172
static size_t char_langle_tag(
10811173
struct Blob *ob,
10821174
struct render *rndr,
10831175
char *data,
10841176
size_t offset,
@@ -1103,12 +1195,12 @@
11031195
}else{
11041196
return end;
11051197
}
11061198
}
11071199
1108
-
1109
-/* get_link_inline -- extract inline-style link and title from
1200
+/*
1201
+** get_link_inline -- extract inline-style link and title from
11101202
** parenthesed data
11111203
*/
11121204
static int get_link_inline(
11131205
struct Blob *link,
11141206
struct Blob *title,
@@ -1158,11 +1250,11 @@
11581250
link_e--;
11591251
}
11601252
11611253
/* remove optional angle brackets around the link */
11621254
if( data[link_b]=='<' ) link_b += 1;
1163
- if( data[link_e-1]=='>' ) link_e -= 1;
1255
+ if( link_e && data[link_e-1]=='>' ) link_e -= 1;
11641256
11651257
/* escape backslashed character from link */
11661258
blob_reset(link);
11671259
i = link_b;
11681260
while( i<link_e ){
@@ -1179,145 +1271,353 @@
11791271
/* this function always succeed */
11801272
return 0;
11811273
}
11821274
11831275
1184
-/* get_link_ref -- extract referenced link and title from id */
1276
+/*
1277
+** get_link_ref -- extract referenced link and title from id.
1278
+*/
11851279
static int get_link_ref(
11861280
struct render *rndr,
11871281
struct Blob *link,
11881282
struct Blob *title,
11891283
char *data,
11901284
size_t size
11911285
){
11921286
struct link_ref *lr;
1287
+ const size_t sz = blob_size(&rndr->refs);
11931288
11941289
/* find the link from its id (stored temporarily in link) */
11951290
blob_reset(link);
1196
- if( build_ref_id(link, data, size)<0 ) return -1;
1291
+ if( !sz || build_ref_id(link, data, size)<0 ) return -1;
11971292
lr = bsearch(link,
11981293
blob_buffer(&rndr->refs),
1199
- blob_size(&rndr->refs)/sizeof(struct link_ref),
1294
+ sz/sizeof(struct link_ref),
12001295
sizeof (struct link_ref),
12011296
cmp_link_ref);
12021297
if( !lr ) return -1;
12031298
12041299
/* fill the output buffers */
12051300
blob_reset(link);
12061301
blob_reset(title);
1207
- blob_append(link, blob_buffer(&lr->link), blob_size(&lr->link));
1208
- blob_append(title, blob_buffer(&lr->title), blob_size(&lr->title));
1302
+ blob_appendb(link, &lr->link);
1303
+ blob_appendb(title, &lr->title);
1304
+ return 0;
1305
+}
1306
+
1307
+/*
1308
+** get_footnote() -- find a footnote by label, invoked during the 2nd pass.
1309
+** If found then return a shallow copy of the corresponding footnote;
1310
+** otherwise return a shallow copy of rndr->notes.misref.
1311
+** In both cases corresponding `nUsed` field is incremented before return.
1312
+*/
1313
+static struct footnote get_footnote(
1314
+ struct render *rndr,
1315
+ const char *data,
1316
+ size_t size
1317
+){
1318
+ struct footnote *fn = 0;
1319
+ struct Blob *id;
1320
+ if( !rndr->notes.nLbled ) goto fallback;
1321
+ id = new_work_buffer(rndr);
1322
+ if( build_ref_id(id, data, size)<0 ) goto cleanup;
1323
+ fn = bsearch(id, blob_buffer(&rndr->notes.all),
1324
+ rndr->notes.nLbled,
1325
+ sizeof (struct footnote),
1326
+ cmp_link_ref);
1327
+ if( !fn ) goto cleanup;
1328
+
1329
+ if( fn->nUsed == 0 ){ /* the first reference to the footnote */
1330
+ assert( fn->iMark == 0 );
1331
+ fn->iMark = ++(rndr->notes.nMarks);
1332
+ }
1333
+ assert( fn->iMark > 0 );
1334
+cleanup:
1335
+ release_work_buffer( rndr, id );
1336
+fallback:
1337
+ if( !fn ) fn = &rndr->notes.misref;
1338
+ fn->nUsed++;
1339
+ assert( fn->nUsed > 0 );
1340
+ return *fn;
1341
+}
1342
+
1343
+/*
1344
+** Counts characters in the blank prefix within at most nHalfLines.
1345
+** A sequence of spaces and tabs counts as odd halfline,
1346
+** a newline counts as even halfline.
1347
+** If nHalfLines < 0 then proceed without constraints.
1348
+*/
1349
+static inline size_t sizeof_blank_prefix(
1350
+ const char *data, size_t size, int nHalfLines
1351
+){
1352
+ const char *p = data;
1353
+ const char * const end = data+size;
1354
+ if( nHalfLines < 0 ){
1355
+ while( p!=end && fossil_isspace(*p) ){
1356
+ p++;
1357
+ }
1358
+ }else while( nHalfLines > 0 ){
1359
+ while( p!=end && (*p==' ' || *p=='\t' ) ){ p++; }
1360
+ if( p==end || --nHalfLines == 0 ) break;
1361
+ if( *p=='\n' || *p=='\r' ){
1362
+ p++;
1363
+ if( p==end ) break;
1364
+ if( *p=='\n' && p[-1]=='\r' ){
1365
+ p++;
1366
+ }
1367
+ }
1368
+ nHalfLines--;
1369
+ }
1370
+ return p-data;
1371
+}
1372
+
1373
+/*
1374
+** Check if the data starts with a classlist token of the special form.
1375
+** If so then return the length of that token, otherwise return 0.
1376
+**
1377
+** The token must start with a dot and must end with a colon;
1378
+** in between of these it must be a dot-separated list of words;
1379
+** each word may contain only alphanumeric characters and hyphens.
1380
+**
1381
+** If `bBlank` is non-zero then a blank character must follow
1382
+** the token's ending colon: otherwise function returns 0
1383
+** despite the well-formed token.
1384
+*/
1385
+static size_t is_footnote_classlist(const char * const data, size_t size,
1386
+ int bBlank){
1387
+ const char *p;
1388
+ const char * const end = data+size;
1389
+ if( data==end || *data != '.' ) return 0;
1390
+ for(p=data+1; p!=end; p++){
1391
+ if( fossil_isalnum(*p) || *p=='-' ) continue;
1392
+ if( p[-1]=='.' ) break;
1393
+ if( *p==':' ){
1394
+ p++;
1395
+ if( bBlank ){
1396
+ if( p==end || !fossil_isspace(*p) ) break;
1397
+ }
1398
+ return p-data;
1399
+ }
1400
+ if( *p!='.' ) break;
1401
+ }
1402
+ return 0;
1403
+}
1404
+
1405
+/*
1406
+** Adds unlabeled footnote to the rndr->notes.all.
1407
+** On success puts a shallow copy of the constructed footnote into pFN
1408
+** and returns 1, otherwise pFN is unchanged and 0 is returned.
1409
+*/
1410
+static inline int add_inline_footnote(
1411
+ struct render *rndr,
1412
+ const char *text,
1413
+ size_t size,
1414
+ struct footnote* pFN
1415
+){
1416
+ struct footnote fn = FOOTNOTE_INITIALIZER, *last;
1417
+ const char *zUPC = 0;
1418
+ size_t nUPC = 0, n = sizeof_blank_prefix(text, size, 3);
1419
+ if( n >= size ) return 0;
1420
+ text += n;
1421
+ size -= n;
1422
+ nUPC = is_footnote_classlist(text, size, 1);
1423
+ if( nUPC ){
1424
+ assert( nUPC<size );
1425
+ zUPC = text;
1426
+ text += nUPC;
1427
+ size -= nUPC;
1428
+ }
1429
+ if( sizeof_blank_prefix(text,size,-1)==size ){
1430
+ if( !nUPC ) return 0; /* empty inline footnote */
1431
+ text = zUPC;
1432
+ size = nUPC; /* bare classlist is treated */
1433
+ nUPC = 0; /* as plain text */
1434
+ }
1435
+ fn.iMark = ++(rndr->notes.nMarks);
1436
+ fn.nUsed = 1;
1437
+ fn.index = COUNT_FOOTNOTES(&rndr->notes.all);
1438
+ assert( fn.iMark > 0 );
1439
+ blob_append(&fn.text, text, size);
1440
+ if(nUPC) blob_append(&fn.upc, zUPC, nUPC);
1441
+ blob_append(&rndr->notes.all, (char *)&fn, sizeof fn);
1442
+ last = (struct footnote*)( blob_buffer(&rndr->notes.all)
1443
+ +( blob_size(&rndr->notes.all)-sizeof fn ));
1444
+ assert( pFN );
1445
+ memcpy( pFN, last, sizeof fn );
1446
+ return 1;
1447
+}
1448
+
1449
+/*
1450
+** Return the byte offset of the matching closing bracket or 0 if not
1451
+** found. begin[0] must be either '[' or '('.
1452
+**
1453
+** TODO: It seems that things like "\\(" are not handled correctly.
1454
+** That is historical behavior for a corner-case,
1455
+** so it's left as it is until somebody complains.
1456
+*/
1457
+static inline size_t matching_bracket_offset(
1458
+ const char* begin,
1459
+ const char* end
1460
+){
1461
+ const char *i;
1462
+ int level;
1463
+ const char bra = *begin;
1464
+ const char ket = bra=='[' ? ']' : ')';
1465
+ assert( bra=='[' || bra=='(' );
1466
+ for(i=begin+1,level=1; i!=end; i++){
1467
+ if( *i=='\n' ) /* do nothing */;
1468
+ else if( i[-1]=='\\' ) continue;
1469
+ else if( *i==bra ) level++;
1470
+ else if( *i==ket ){
1471
+ if( --level<=0 ) return i-begin;
1472
+ }
1473
+ }
12091474
return 0;
12101475
}
12111476
1477
+/*
1478
+** char_footnote -- '(': parsing a standalone inline footnote.
1479
+*/
1480
+static size_t char_footnote(
1481
+ struct Blob *ob,
1482
+ struct render *rndr,
1483
+ char *data,
1484
+ size_t offset,
1485
+ size_t size
1486
+){
1487
+ size_t end;
1488
+ struct footnote fn;
12121489
1213
-/* char_link -- '[': parsing a link or an image */
1490
+ if( size<4 || data[1]!='^' ) return 0;
1491
+ end = matching_bracket_offset(data, data+size);
1492
+ if( !end ) return 0;
1493
+ if( !add_inline_footnote(rndr, data+2, end-2, &fn) ) return 0;
1494
+ if( rndr->make.footnote_ref ){
1495
+ rndr->make.footnote_ref(ob,0,&fn.upc,fn.iMark,1,rndr->make.opaque);
1496
+ }
1497
+ return end+1;
1498
+}
1499
+
1500
+/*
1501
+** char_link -- '[': parsing a link or an image.
1502
+*/
12141503
static size_t char_link(
12151504
struct Blob *ob,
12161505
struct render *rndr,
12171506
char *data,
12181507
size_t offset,
1219
- size_t size
1508
+ size_t size /* parse_inline() ensures that size > 0 */
12201509
){
1221
- int is_img = (offset && data[-1] == '!'), level;
1510
+ const int is_img = (offset && data[-1] == '!');
12221511
size_t i = 1, txt_e;
12231512
struct Blob *content = 0;
12241513
struct Blob *link = 0;
12251514
struct Blob *title = 0;
1515
+ struct footnote fn;
12261516
int ret;
12271517
12281518
/* checking whether the correct renderer exists */
12291519
if( (is_img && !rndr->make.image) || (!is_img && !rndr->make.link) ){
12301520
return 0;
12311521
}
12321522
12331523
/* looking for the matching closing bracket */
1234
- for(level=1; i<size; i++){
1235
- if( data[i]=='\n' ) /* do nothing */;
1236
- else if( data[i-1]=='\\' ) continue;
1237
- else if( data[i]=='[' ) level += 1;
1238
- else if( data[i]==']' ){
1239
- level--;
1240
- if( level<=0 ) break;
1241
- }
1242
- }
1243
- if( i>=size ) return 0;
1244
- txt_e = i;
1245
- i++;
1246
-
1247
- /* skip any amount of whitespace or newline */
1248
- /* (this is much more laxist than original markdown syntax) */
1249
- while( i<size && (data[i]==' ' || data[i]=='\t' || data[i]=='\n') ){ i++; }
1250
-
1251
- /* allocate temporary buffers to store content, link and title */
1252
- title = new_work_buffer(rndr);
1253
- content = new_work_buffer(rndr);
1254
- link = new_work_buffer(rndr);
1524
+ txt_e = matching_bracket_offset(data, data+size);
1525
+ if( !txt_e ) return 0;
1526
+ i = txt_e + 1;
12551527
ret = 0; /* error if we don't get to the callback */
1256
-
1257
- /* inline style link */
1258
- if( i<size && data[i]=='(' ){
1259
- size_t span_end = i;
1260
- while( span_end<size
1261
- && !(data[span_end]==')' && (span_end==i || data[span_end-1]!='\\'))
1262
- ){
1263
- span_end++;
1264
- }
1265
-
1266
- if( span_end>=size
1267
- || get_link_inline(link, title, data+i+1, span_end-(i+1))<0
1268
- ){
1269
- goto char_link_cleanup;
1270
- }
1271
-
1272
- i = span_end+1;
1273
-
1274
- /* reference style link */
1275
- }else if( i<size && data[i]=='[' ){
1276
- char *id_data;
1277
- size_t id_size, id_end = i;
1278
-
1279
- while( id_end<size && data[id_end]!=']' ){ id_end++; }
1280
-
1281
- if( id_end>=size ) goto char_link_cleanup;
1282
-
1283
- if( i+1==id_end ){
1284
- /* implicit id - use the contents */
1285
- id_data = data+1;
1286
- id_size = txt_e-1;
1287
- }else{
1288
- /* explicit id - between brackets */
1289
- id_data = data+i+1;
1290
- id_size = id_end-(i+1);
1291
- }
1292
-
1293
- if( get_link_ref(rndr, link, title, id_data, id_size)<0 ){
1294
- goto char_link_cleanup;
1295
- }
1296
-
1297
- i = id_end+1;
1298
-
1299
- /* shortcut reference style link */
1300
- }else{
1301
- if( get_link_ref(rndr, link, title, data+1, txt_e-1)<0 ){
1302
- goto char_link_cleanup;
1303
- }
1304
-
1305
- /* rewinding the whitespace */
1306
- i = txt_e+1;
1307
- }
1308
-
1528
+ fn.nUsed = 0;
1529
+
1530
+ /* free-standing footnote refernece */
1531
+ if(!is_img && size>3 && data[1]=='^'){
1532
+ fn = get_footnote(rndr, data+2, txt_e-2);
1533
+ }else{
1534
+
1535
+ /* skip "inter-bracket-whitespace" - any amount of whitespace or newline */
1536
+ /* (this is much more lax than original markdown syntax) */
1537
+ while( i<size && (data[i]==' ' || data[i]=='\t' || data[i]=='\n') ){ i++; }
1538
+
1539
+ /* allocate temporary buffers to store content, link and title */
1540
+ title = new_work_buffer(rndr);
1541
+ content = new_work_buffer(rndr);
1542
+ link = new_work_buffer(rndr);
1543
+
1544
+ if( i<size && data[i]=='(' ){
1545
+
1546
+ if( i+2<size && data[i+1]=='^' ){ /* span-bounded inline footnote */
1547
+
1548
+ const size_t k = matching_bracket_offset(data+i, data+size);
1549
+ if( !k ) goto char_link_cleanup;
1550
+ add_inline_footnote(rndr, data+(i+2), k-2, &fn);
1551
+ i += k+1;
1552
+ }else{ /* inline style link */
1553
+ size_t span_end = i;
1554
+ while( span_end<size
1555
+ && !(data[span_end]==')'
1556
+ && (span_end==i || data[span_end-1]!='\\')) ){
1557
+ span_end++;
1558
+ }
1559
+ if( span_end>=size
1560
+ || get_link_inline(link, title, data+i+1, span_end-(i+1))<0 ){
1561
+ goto char_link_cleanup;
1562
+ }
1563
+ i = span_end+1;
1564
+ }
1565
+ /* reference style link or span-bounded footnote reference */
1566
+ }else if( i<size && data[i]=='[' ){
1567
+ char *id_data;
1568
+ size_t id_size, id_end = i;
1569
+ int bFootnote;
1570
+
1571
+ while( id_end<size && data[id_end]!=']' ){ id_end++; }
1572
+ if( id_end>=size ) goto char_link_cleanup;
1573
+ bFootnote = data[i+1]=='^';
1574
+ if( i+1==id_end || (bFootnote && i+2==id_end) ){
1575
+ /* implicit id - use the contents */
1576
+ id_data = data+1;
1577
+ id_size = txt_e-1;
1578
+ }else{
1579
+ /* explicit id - between brackets */
1580
+ id_data = data+i+1;
1581
+ id_size = id_end-(i+1);
1582
+ if( bFootnote ){
1583
+ id_data++;
1584
+ id_size--;
1585
+ }
1586
+ }
1587
+ if( bFootnote ){
1588
+ fn = get_footnote(rndr, id_data, id_size);
1589
+ }else if( get_link_ref(rndr, link, title, id_data, id_size)<0 ){
1590
+ goto char_link_cleanup;
1591
+ }
1592
+ i = id_end+1;
1593
+ /* shortcut reference style link */
1594
+ }else{
1595
+ if( get_link_ref(rndr, link, title, data+1, txt_e-1)<0 ){
1596
+ goto char_link_cleanup;
1597
+ }
1598
+ /* rewinding an "inter-bracket-whitespace" */
1599
+ i = txt_e+1;
1600
+ }
1601
+ }
13091602
/* building content: img alt is escaped, link content is parsed */
1310
- if( txt_e>1 ){
1603
+ if( txt_e>1 && content ){
13111604
if( is_img ) blob_append(content, data+1, txt_e-1);
13121605
else parse_inline(content, rndr, data+1, txt_e-1);
13131606
}
13141607
13151608
/* calling the relevant rendering function */
13161609
if( is_img ){
1317
- if( blob_size(ob)>0 && blob_buffer(ob)[blob_size(ob)-1]=='!' ) ob->nUsed--;
1610
+ if( blob_size(ob)>0 && blob_buffer(ob)[blob_size(ob)-1]=='!' ){
1611
+ ob->nUsed--;
1612
+ }
13181613
ret = rndr->make.image(ob, link, title, content, rndr->make.opaque);
1614
+ }else if( fn.nUsed ){
1615
+ if( rndr->make.footnote_ref ){
1616
+ ret = rndr->make.footnote_ref(ob, content, &fn.upc, fn.iMark,
1617
+ fn.nUsed, rndr->make.opaque);
1618
+ }
13191619
}else{
13201620
ret = rndr->make.link(ob, link, title, content, rndr->make.opaque);
13211621
}
13221622
13231623
/* cleanup */
@@ -1325,11 +1625,10 @@
13251625
release_work_buffer(rndr, title);
13261626
release_work_buffer(rndr, link);
13271627
release_work_buffer(rndr, content);
13281628
return ret ? i : 0;
13291629
}
1330
-
13311630
13321631
13331632
/*********************************
13341633
* BLOCK-LEVEL PARSING FUNCTIONS *
13351634
*********************************/
@@ -2010,11 +2309,12 @@
20102309
/* the end of the block has been found */
20112310
if( strcmp(curtag->text,"html")==0 ){
20122311
/* Omit <html> tags */
20132312
enum mkd_autolink dummy;
20142313
int k = tag_length(data, size, &dummy);
2015
- blob_init(&work, data+k, i-(j+k));
2314
+ int sz = i - (j+k);
2315
+ if( sz>0 ) blob_init(&work, data+k, sz);
20162316
}else{
20172317
blob_init(&work, data, i);
20182318
}
20192319
if( rndr->make.blockhtml ){
20202320
rndr->make.blockhtml(ob, &work, rndr->make.opaque);
@@ -2217,11 +2517,13 @@
22172517
char *data, /* input text */
22182518
size_t size /* input text size */
22192519
){
22202520
size_t beg, end, i;
22212521
char *txt_data;
2222
- int has_table = (rndr->make.table
2522
+ int has_table;
2523
+ if( !size ) return;
2524
+ has_table = (rndr->make.table
22232525
&& rndr->make.table_row
22242526
&& rndr->make.table_cell
22252527
&& memchr(data, '|', size)!=0);
22262528
22272529
beg = 0;
@@ -2267,11 +2569,11 @@
22672569
* REFERENCE PARSING *
22682570
*********************/
22692571
22702572
/* is_ref -- returns whether a line is a reference or not */
22712573
static int is_ref(
2272
- char *data, /* input text */
2574
+ const char *data, /* input text */
22732575
size_t beg, /* offset of the beginning of the line */
22742576
size_t end, /* offset of the end of the text */
22752577
size_t *last, /* last character of the link */
22762578
struct Blob *refs /* array of link references */
22772579
){
@@ -2301,10 +2603,12 @@
23012603
i += beg;
23022604
23032605
/* id part: anything but a newline between brackets */
23042606
if( data[i]!='[' ) return 0;
23052607
i++;
2608
+ if( i>=end || data[i]=='^' ) return 0; /* see is_footnote() */
2609
+
23062610
id_offset = i;
23072611
while( i<end && data[i]!='\n' && data[i]!='\r' && data[i]!=']' ){ i++; }
23082612
if( i>=end || data[i]!=']' ) return 0;
23092613
id_end = i;
23102614
@@ -2329,10 +2633,11 @@
23292633
&& data[i]!='\n'
23302634
&& data[i]!='\r'
23312635
){
23322636
i += 1;
23332637
}
2638
+ /* TODO: maybe require both data[i-1]=='>' && data[link_offset-1]=='<' ? */
23342639
if( data[i-1]=='>' ) link_end = i-1; else link_end = i;
23352640
23362641
/* optional spacer: (space | tab)* (newline | '\'' | '"' | '(' ) */
23372642
while( i<end && (data[i]==' ' || data[i]=='\t') ){ i++; }
23382643
if( i<end
@@ -2388,34 +2693,168 @@
23882693
}
23892694
blob_append(refs, (char *)&lr, sizeof lr);
23902695
return 1;
23912696
}
23922697
2698
+/*********************
2699
+ * FOOTNOTE PARSING *
2700
+ *********************/
2701
+
2702
+/* is_footnote -- check if data holds a definition of a labeled footnote.
2703
+ * If so then append the corresponding element to `footnotes` array */
2704
+static int is_footnote(
2705
+ const char *data, /* input text */
2706
+ size_t beg, /* offset of the beginning of the line */
2707
+ size_t end, /* offset of the end of the text */
2708
+ size_t *last, /* last character of the link */
2709
+ struct Blob * footnotes
2710
+){
2711
+ size_t i, id_offset, id_end, upc_offset, upc_size;
2712
+ struct footnote fn = FOOTNOTE_INITIALIZER;
2713
+
2714
+ /* failfast if data is too short */
2715
+ if( beg+5>=end ) return 0;
2716
+ i = beg;
2717
+
2718
+ /* footnote definition must start at the begining of a line */
2719
+ if( data[i]!='[' ) return 0;
2720
+ i++;
2721
+ if( data[i]!='^' ) return 0;
2722
+ id_offset = ++i;
2723
+
2724
+ /* id part: anything but a newline between brackets */
2725
+ while( i<end && data[i]!=']' && data[i]!='\n' && data[i]!='\r' ){ i++; }
2726
+ if( i>=end || data[i]!=']' ) return 0;
2727
+ id_end = i++;
2728
+
2729
+ /* spacer: colon (space | tab)* */
2730
+ if( i>=end || data[i]!=':' ) return 0;
2731
+ i++;
2732
+ while( i<end && (data[i]==' ' || data[i]=='\t') ){ i++; }
2733
+
2734
+ /* passthrough truncated footnote definition */
2735
+ if( i>=end ) return 0;
2736
+
2737
+ if( build_ref_id(&fn.id, data+id_offset, id_end-id_offset)<0 ) return 0;
2738
+
2739
+ /* footnote's text may start on the same line after [^id]: */
2740
+ upc_offset = upc_size = 0;
2741
+ if( data[i]!='\n' && data[i]!='\r' ){
2742
+ size_t j;
2743
+ upc_size = is_footnote_classlist(data+i, end-i, 1);
2744
+ upc_offset = i; /* prevent further checks for a classlist */
2745
+ i += upc_size;
2746
+ j = i;
2747
+ while( i<end && data[i]!='\n' && data[i]!='\r' ){ i++; };
2748
+ if( i!=j )blob_append(&fn.text, data+j, i-j);
2749
+ if( i<end ){
2750
+ blob_append_char(&fn.text, data[i]);
2751
+ i++;
2752
+ if( i<end && data[i]=='\n' && data[i-1]=='\r' ){
2753
+ blob_append_char(&fn.text, data[i]);
2754
+ i++;
2755
+ }
2756
+ }
2757
+ }else{
2758
+ i++;
2759
+ if( i<end && data[i]=='\n' && data[i-1]=='\r' ) i++;
2760
+ }
2761
+ if( i<end ){
2762
+
2763
+ /* compute the indentation from the 2nd line */
2764
+ size_t indent = i;
2765
+ const char *spaces = data+i;
2766
+ while( indent<end && data[indent]==' ' ){ indent++; }
2767
+ if( indent>=end ) goto footnote_finish;
2768
+ indent -= i;
2769
+ if( indent<2 ) goto footnote_finish;
23932770
2771
+ /* process the 2nd and subsequent lines */
2772
+ while( i+indent<end && memcmp(data+i,spaces,indent)==0 ){
2773
+ size_t j;
2774
+ i += indent;
2775
+ if( !upc_offset ){
2776
+ /* a classlist must be provided no later than at the 2nd line */
2777
+ upc_offset = i + sizeof_blank_prefix(data+i, end-i, 1);
2778
+ upc_size = is_footnote_classlist(data+upc_offset,
2779
+ end-upc_offset, 1);
2780
+ if( upc_size ){
2781
+ i = upc_offset + upc_size;
2782
+ }
2783
+ }
2784
+ j = i;
2785
+ while( i<end && data[i]!='\n' && data[i]!='\r' ){ i++; }
2786
+ if( i!=j ) blob_append(&fn.text, data+j, i-j);
2787
+ if( i>=end ) break;
2788
+ blob_append_char(&fn.text, data[i]);
2789
+ i++;
2790
+ if( i<end && data[i]=='\n' && data[i-1]=='\r' ){
2791
+ blob_append_char(&fn.text, data[i]);
2792
+ i++;
2793
+ }
2794
+ }
2795
+ }
2796
+footnote_finish:
2797
+ if( !blob_size(&fn.text) ){
2798
+ blob_reset(&fn.id);
2799
+ return 0;
2800
+ }
2801
+ if( !blob_trim(&fn.text) ){ /* if the content is all-blank */
2802
+ if( upc_size ){ /* interpret UPC as plain text */
2803
+ blob_append(&fn.text, data+upc_offset, upc_size);
2804
+ upc_size = 0;
2805
+ }else{
2806
+ blob_reset(&fn.id); /* or clean up and fail */
2807
+ blob_reset(&fn.text);
2808
+ return 0;
2809
+ }
2810
+ }
2811
+ /* a valid note has been found */
2812
+ if( last ) *last = i;
2813
+ if( footnotes ){
2814
+ fn.defno = COUNT_FOOTNOTES( footnotes );
2815
+ if( upc_size ){
2816
+ assert( upc_offset && upc_offset+upc_size<end );
2817
+ blob_append(&fn.upc, data+upc_offset, upc_size);
2818
+ }
2819
+ blob_append(footnotes, (char *)&fn, sizeof fn);
2820
+ }
2821
+ return 1;
2822
+}
23942823
23952824
/**********************
23962825
* EXPORTED FUNCTIONS *
23972826
**********************/
23982827
23992828
/* markdown -- parses the input buffer and renders it into the output buffer */
24002829
void markdown(
24012830
struct Blob *ob, /* output blob for rendered text */
2402
- struct Blob *ib, /* input blob in markdown */
2831
+ const struct Blob *ib, /* input blob in markdown */
24032832
const struct mkd_renderer *rndrer /* renderer descriptor (callbacks) */
24042833
){
24052834
struct link_ref *lr;
2835
+ struct footnote *fn;
24062836
size_t i, beg, end = 0;
24072837
struct render rndr;
2408
- char *ib_data;
2409
- Blob text = BLOB_INITIALIZER;
2838
+ Blob text = BLOB_INITIALIZER; /* input after the first pass */
2839
+ Blob * const allNotes = &rndr.notes.all;
24102840
24112841
/* filling the render structure */
24122842
if( !rndrer ) return;
24132843
rndr.make = *rndrer;
24142844
rndr.nBlobCache = 0;
24152845
rndr.iDepth = 0;
2416
- rndr.refs = empty_blob;
2846
+ rndr.refs = empty_blob;
2847
+ rndr.notes.all = empty_blob;
2848
+ rndr.notes.nMarks = 0;
2849
+ rndr.notes.misref.id = empty_blob;
2850
+ rndr.notes.misref.text = empty_blob;
2851
+ rndr.notes.misref.upc = empty_blob;
2852
+ rndr.notes.misref.bRndred = 0;
2853
+ rndr.notes.misref.nUsed = 0;
2854
+ rndr.notes.misref.iMark = -1;
2855
+
24172856
for(i=0; i<256; i++) rndr.active_char[i] = 0;
24182857
if( (rndr.make.emphasis
24192858
|| rndr.make.double_emphasis
24202859
|| rndr.make.triple_emphasis)
24212860
&& rndr.make.emph_chars
@@ -2427,32 +2866,34 @@
24272866
if( rndr.make.codespan ) rndr.active_char['`'] = char_codespan;
24282867
if( rndr.make.linebreak ) rndr.active_char['\n'] = char_linebreak;
24292868
if( rndr.make.image || rndr.make.link ) rndr.active_char['['] = char_link;
24302869
rndr.active_char['@'] = char_atref_tag;
24312870
rndr.active_char['#'] = char_hashref_tag;
2871
+ if( rndr.make.footnote_ref ) rndr.active_char['('] = char_footnote;
24322872
rndr.active_char['<'] = char_langle_tag;
24332873
rndr.active_char['\\'] = char_escape;
24342874
rndr.active_char['&'] = char_entity;
24352875
2436
- /* first pass: looking for references, copying everything else */
2876
+ /* first pass: iterate over lines looking for references,
2877
+ * copying everything else into "text" */
24372878
beg = 0;
2438
- ib_data = blob_buffer(ib);
2439
- while( beg<blob_size(ib) ){ /* iterating over lines */
2440
- if( is_ref(ib_data, beg, blob_size(ib), &end, &rndr.refs) ){
2879
+ for(const size_t size = blob_size(ib); beg<size ;){
2880
+ const char* const data = blob_buffer(ib);
2881
+ if( is_ref(data, beg, size, &end, &rndr.refs) ){
2882
+ beg = end;
2883
+ }else if(is_footnote(data, beg, size, &end, &rndr.notes.all)){
24412884
beg = end;
24422885
}else{ /* skipping to the next line */
24432886
end = beg;
2444
- while( end<blob_size(ib) && ib_data[end]!='\n' && ib_data[end]!='\r' ){
2887
+ while( end<size && data[end]!='\n' && data[end]!='\r' ){
24452888
end += 1;
24462889
}
24472890
/* adding the line body if present */
2448
- if( end>beg ) blob_append(&text, ib_data + beg, end - beg);
2449
- while( end<blob_size(ib) && (ib_data[end]=='\n' || ib_data[end]=='\r') ){
2891
+ if( end>beg ) blob_append(&text, data + beg, end - beg);
2892
+ while( end<size && (data[end]=='\n' || data[end]=='\r') ){
24502893
/* add one \n per newline */
2451
- if( ib_data[end]=='\n'
2452
- || (end+1<blob_size(ib) && ib_data[end+1]!='\n')
2453
- ){
2894
+ if( data[end]=='\n' || (end+1<size && data[end+1]!='\n') ){
24542895
blob_append_char(&text, '\n');
24552896
}
24562897
end += 1;
24572898
}
24582899
beg = end;
@@ -2464,14 +2905,160 @@
24642905
qsort(blob_buffer(&rndr.refs),
24652906
blob_size(&rndr.refs)/sizeof(struct link_ref),
24662907
sizeof(struct link_ref),
24672908
cmp_link_ref_sort);
24682909
}
2910
+ rndr.notes.nLbled = COUNT_FOOTNOTES( allNotes );
2911
+
2912
+ /* sort footnotes by ID and join duplicates */
2913
+ if( rndr.notes.nLbled > 1 ){
2914
+ int nDups = 0;
2915
+ fn = CAST_AS_FOOTNOTES( allNotes );
2916
+ qsort(fn, rndr.notes.nLbled, sizeof(struct footnote), cmp_footnote_id);
2917
+
2918
+ /* concatenate footnotes with equal labels */
2919
+ for(i=0; i<rndr.notes.nLbled ;){
2920
+ struct footnote *x = fn + i;
2921
+ size_t j = i+1, k = blob_size(&x->text) + 64 + blob_size(&x->upc);
2922
+ while(j<rndr.notes.nLbled && !blob_compare(&x->id, &fn[j].id)){
2923
+ k += blob_size(&fn[j].text) + 10 + blob_size(&fn[j].upc);
2924
+ j++;
2925
+ nDups++;
2926
+ }
2927
+ if( i+1<j ){
2928
+ Blob list = empty_blob;
2929
+ blob_reserve(&list, k);
2930
+ /* must match _joined_footnote_indicator in html_footnote_item() */
2931
+ blob_append_literal(&list, "<ul class='fn-joined'>\n");
2932
+ for(k=i; k<j; k++){
2933
+ struct footnote *y = fn + k;
2934
+ blob_append_literal(&list, "<li>");
2935
+ if( blob_size(&y->upc) ){
2936
+ blob_appendb(&list, &y->upc);
2937
+ blob_reset(&y->upc);
2938
+ }
2939
+ blob_appendb(&list, &y->text);
2940
+ blob_append_literal(&list, "</li>\n");
2941
+
2942
+ /* free memory buffer */
2943
+ blob_reset(&y->text);
2944
+ if( k!=i ) blob_reset(&y->id);
2945
+ }
2946
+ blob_append_literal(&list, "</ul>\n");
2947
+ x->text = list;
2948
+ g.ftntsIssues[2]++;
2949
+ }
2950
+ i = j;
2951
+ }
2952
+ if( nDups ){ /* clean rndr.notes.all from invalidated footnotes */
2953
+ const int n = rndr.notes.nLbled - nDups;
2954
+ struct Blob filtered = empty_blob;
2955
+ blob_reserve(&filtered, n*sizeof(struct footnote));
2956
+ for(i=0; i<rndr.notes.nLbled; i++){
2957
+ if( blob_size(&fn[i].id) ){
2958
+ blob_append(&filtered, (char*)(fn+i), sizeof(struct footnote));
2959
+ }
2960
+ }
2961
+ blob_reset( allNotes );
2962
+ rndr.notes.all = filtered;
2963
+ rndr.notes.nLbled = n;
2964
+ assert( COUNT_FOOTNOTES(allNotes) == rndr.notes.nLbled );
2965
+ }
2966
+ }
2967
+ fn = CAST_AS_FOOTNOTES( allNotes );
2968
+ for(i=0; i<rndr.notes.nLbled; i++){
2969
+ fn[i].index = i;
2970
+ }
2971
+ assert( rndr.notes.nMarks==0 );
24692972
24702973
/* second pass: actual rendering */
24712974
if( rndr.make.prolog ) rndr.make.prolog(ob, rndr.make.opaque);
24722975
parse_block(ob, &rndr, blob_buffer(&text), blob_size(&text));
2976
+
2977
+ if( blob_size(allNotes) || rndr.notes.misref.nUsed ){
2978
+
2979
+ /* Footnotes must be parsed for the correct discovery of (back)links */
2980
+ Blob *notes = new_work_buffer( &rndr );
2981
+ if( blob_size(allNotes) ){
2982
+ Blob *tmp = new_work_buffer( &rndr );
2983
+ int nMarks = -1, maxDepth = 5;
2984
+
2985
+ /* inline notes may get appended to rndr.notes.all while rendering */
2986
+ while(1){
2987
+ struct footnote *aNotes;
2988
+ const int N = COUNT_FOOTNOTES( allNotes );
2989
+
2990
+ /* make a shallow copy of `allNotes` */
2991
+ blob_truncate(notes,0);
2992
+ blob_appendb(notes, allNotes);
2993
+ aNotes = CAST_AS_FOOTNOTES(notes);
2994
+ qsort(aNotes, N, sizeof(struct footnote), cmp_footnote_sort);
2995
+
2996
+ if( --maxDepth < 0 || nMarks == rndr.notes.nMarks ) break;
2997
+ nMarks = rndr.notes.nMarks;
2998
+
2999
+ for(i=0; i<N; i++){
3000
+ const int j = aNotes[i].index;
3001
+ struct footnote *x = CAST_AS_FOOTNOTES(allNotes) + j;
3002
+ assert( 0<=j && j<N );
3003
+ if( x->bRndred || !x->nUsed ) continue;
3004
+ assert( x->iMark > 0 );
3005
+ assert( blob_size(&x->text) );
3006
+ blob_truncate(tmp,0);
3007
+
3008
+ /* `allNotes` may be altered and extended through this call */
3009
+ parse_inline(tmp, &rndr, blob_buffer(&x->text), blob_size(&x->text));
3010
+
3011
+ x = CAST_AS_FOOTNOTES(allNotes) + j;
3012
+ blob_truncate(&x->text,0);
3013
+ blob_appendb(&x->text, tmp);
3014
+ x->bRndred = 1;
3015
+ }
3016
+ }
3017
+ release_work_buffer(&rndr,tmp);
3018
+ }
3019
+
3020
+ /* footnotes rendering */
3021
+ if( rndr.make.footnote_item && rndr.make.footnotes ){
3022
+ Blob *all_items = new_work_buffer(&rndr);
3023
+ int j = -1;
3024
+
3025
+ /* Assert that the in-memory layout of id, text and upc within
3026
+ ** footnote struct matches the expectations of html_footnote_item()
3027
+ ** If it doesn't then a compiler has done something very weird.
3028
+ */
3029
+ assert( &(rndr.notes.misref.id) == &(rndr.notes.misref.text) - 1 );
3030
+ assert( &(rndr.notes.misref.upc) == &(rndr.notes.misref.text) + 1 );
3031
+
3032
+ for(i=0; i<COUNT_FOOTNOTES(notes); i++){
3033
+ const struct footnote* x = CAST_AS_FOOTNOTES(notes) + i;
3034
+ const int xUsed = x->bRndred ? x->nUsed : 0;
3035
+ if( !x->iMark ) break;
3036
+ assert( x->nUsed );
3037
+ rndr.make.footnote_item(all_items, &x->text, x->iMark,
3038
+ xUsed, rndr.make.opaque);
3039
+ if( !xUsed ) g.ftntsIssues[3]++; /* an overnested footnote */
3040
+ j = i;
3041
+ }
3042
+ if( rndr.notes.misref.nUsed ){
3043
+ rndr.make.footnote_item(all_items, 0, -1,
3044
+ rndr.notes.misref.nUsed, rndr.make.opaque);
3045
+ g.ftntsIssues[0] += rndr.notes.misref.nUsed;
3046
+ }
3047
+ while( ++j < COUNT_FOOTNOTES(notes) ){
3048
+ const struct footnote* x = CAST_AS_FOOTNOTES(notes) + j;
3049
+ assert( !x->iMark );
3050
+ assert( !x->nUsed );
3051
+ assert( !x->bRndred );
3052
+ rndr.make.footnote_item(all_items,&x->text,0,0,rndr.make.opaque);
3053
+ g.ftntsIssues[1]++;
3054
+ }
3055
+ rndr.make.footnotes(ob, all_items, rndr.make.opaque);
3056
+ release_work_buffer(&rndr, all_items);
3057
+ }
3058
+ release_work_buffer(&rndr, notes);
3059
+ }
24733060
if( rndr.make.epilog ) rndr.make.epilog(ob, rndr.make.opaque);
24743061
24753062
/* clean-up */
24763063
assert( rndr.iDepth==0 );
24773064
blob_reset(&text);
@@ -2481,9 +3068,17 @@
24813068
blob_reset(&lr[i].id);
24823069
blob_reset(&lr[i].link);
24833070
blob_reset(&lr[i].title);
24843071
}
24853072
blob_reset(&rndr.refs);
3073
+ fn = CAST_AS_FOOTNOTES( allNotes );
3074
+ end = COUNT_FOOTNOTES( allNotes );
3075
+ for(i=0; i<end; i++){
3076
+ if(blob_size(&fn[i].id)) blob_reset(&fn[i].id);
3077
+ if(blob_size(&fn[i].upc)) blob_reset(&fn[i].upc);
3078
+ blob_reset(&fn[i].text);
3079
+ }
3080
+ blob_reset(&rndr.notes.all);
24863081
for(i=0; i<rndr.nBlobCache; i++){
24873082
fossil_free(rndr.aBlobCache[i]);
24883083
}
24893084
}
24903085
--- src/markdown.c
+++ src/markdown.c
@@ -52,10 +52,11 @@
52 /* mkd_renderer -- functions for rendering parsed data */
53 struct mkd_renderer {
54 /* document level callbacks */
55 void (*prolog)(struct Blob *ob, void *opaque);
56 void (*epilog)(struct Blob *ob, void *opaque);
 
57
58 /* block level callbacks - NULL skips the block */
59 void (*blockcode)(struct Blob *ob, struct Blob *text, void *opaque);
60 void (*blockquote)(struct Blob *ob, struct Blob *text, void *opaque);
61 void (*blockhtml)(struct Blob *ob, struct Blob *text, void *opaque);
@@ -70,10 +71,12 @@
70 void *opaque);
71 void (*table_cell)(struct Blob *ob, struct Blob *text, int flags,
72 void *opaque);
73 void (*table_row)(struct Blob *ob, struct Blob *cells, int flags,
74 void *opaque);
 
 
75
76 /* span level callbacks - NULL or return 0 prints the span verbatim */
77 int (*autolink)(struct Blob *ob, struct Blob *link,
78 enum mkd_autolink type, void *opaque);
79 int (*codespan)(struct Blob *ob, struct Blob *text, int nSep, void *opaque);
@@ -88,10 +91,12 @@
88 int (*raw_html_tag)(struct Blob *ob, struct Blob *tag, void *opaque);
89 int (*tagspan)(struct Blob *ob, struct Blob *ref, enum mkd_tagspan type,
90 void *opaque);
91 int (*triple_emphasis)(struct Blob *ob, struct Blob *text,
92 char c, void *opaque);
 
 
93
94 /* low level callbacks - NULL copies input directly into the output */
95 void (*entity)(struct Blob *ob, struct Blob *entity, void *opaque);
96 void (*normal_text)(struct Blob *ob, struct Blob *text, void *opaque);
97
@@ -122,31 +127,54 @@
122
123 /**********************
124 * EXPORTED FUNCTIONS *
125 **********************/
126
127 /* markdown -- parses the input buffer and renders it into the output buffer */
 
 
128 void markdown(
129 struct Blob *ob,
130 struct Blob *ib,
131 const struct mkd_renderer *rndr);
132
133
134 #endif /* INTERFACE */
135
 
 
 
136
137 /***************
138 * LOCAL TYPES *
139 ***************/
140
141 /* link_ref -- reference to a link */
 
 
142 struct link_ref {
143 struct Blob id;
144 struct Blob link;
145 struct Blob title;
146 };
147
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
149 /* char_trigger -- function pointer to render active chars */
150 /* returns the number of chars taken care of */
151 /* data is the pointer of the beginning of the span */
152 /* offset is the number of valid chars before data */
@@ -165,12 +193,19 @@
165 struct Blob refs;
166 char_trigger active_char[256];
167 int iDepth; /* Depth of recursion */
168 int nBlobCache; /* Number of entries in aBlobCache */
169 struct Blob *aBlobCache[20]; /* Cache of Blobs available for reuse */
 
 
 
 
 
 
 
 
170 };
171
172
173 /* html_tag -- structure for quick HTML tag search (inspired from discount) */
174 struct html_tag {
175 const char *text;
176 int size;
@@ -192,16 +227,18 @@
192 { "html", 4 },
193 { "pre", 3 },
194 { "script", 6 },
195 };
196
197
198 /***************************
199 * STATIC HELPER FUNCTIONS *
200 ***************************/
201
202 /* build_ref_id -- collapse whitespace from input text to make it a ref id */
 
 
 
203 static int build_ref_id(struct Blob *id, const char *data, size_t size){
204 size_t beg, i;
205 char *id_data;
206
207 /* skip leading whitespace */
@@ -256,10 +293,58 @@
256 struct link_ref *lra = (void *)a;
257 struct link_ref *lrb = (void *)b;
258 return blob_compare(&lra->id, &lrb->id);
259 }
260
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
262 /* cmp_html_tag -- comparison function for bsearch() (stolen from discount) */
263 static int cmp_html_tag(const void *a, const void *b){
264 const struct html_tag *hta = a;
265 const struct html_tag *htb = b;
@@ -588,12 +673,14 @@
588 if( fossil_isalnum(after) ) return 0;
589 return 1;
590 }
591
592
593 /* parse_emph1 -- parsing single emphasis */
594 /* closed by a symbol not preceded by whitespace and not followed by symbol */
 
 
595 static size_t parse_emph1(
596 struct Blob *ob,
597 struct render *rndr,
598 char *data,
599 size_t size,
@@ -633,12 +720,13 @@
633 }
634 }
635 return 0;
636 }
637
638
639 /* parse_emph2 -- parsing single emphasis */
 
640 static size_t parse_emph2(
641 struct Blob *ob,
642 struct render *rndr,
643 char *data,
644 size_t size,
@@ -672,13 +760,14 @@
672 i++;
673 }
674 return 0;
675 }
676
677
678 /* parse_emph3 -- parsing single emphasis */
679 /* finds the first closing tag, and delegates to the other emph */
 
680 static size_t parse_emph3(
681 struct Blob *ob,
682 struct render *rndr,
683 char *data,
684 size_t size,
@@ -720,12 +809,13 @@
720 }
721 }
722 return 0;
723 }
724
725
726 /* char_emphasis -- single and double emphasis parsing */
 
727 static size_t char_emphasis(
728 struct Blob *ob,
729 struct render *rndr,
730 char *data,
731 size_t offset,
@@ -765,12 +855,13 @@
765 return ret+3;
766 }
767 return 0;
768 }
769
770
771 /* char_linebreak -- '\n' preceded by two spaces (assuming linebreak != 0) */
 
772 static size_t char_linebreak(
773 struct Blob *ob,
774 struct render *rndr,
775 char *data,
776 size_t offset,
@@ -780,12 +871,13 @@
780 /* removing the last space from ob and rendering */
781 if( blob_size(ob)>0 && blob_buffer(ob)[blob_size(ob)-1]==' ' ) ob->nUsed--;
782 return rndr->make.linebreak(ob, rndr->make.opaque) ? 1 : 0;
783 }
784
785
786 /* char_codespan -- '`' parsing a code span (assuming codespan != 0) */
 
787 static size_t char_codespan(
788 struct Blob *ob,
789 struct render *rndr,
790 char *data,
791 size_t offset,
@@ -822,11 +914,13 @@
822 }
823 return end;
824 }
825
826
827 /* char_escape -- '\\' backslash escape */
 
 
828 static size_t char_escape(
829 struct Blob *ob,
830 struct render *rndr,
831 char *data,
832 size_t offset,
@@ -842,13 +936,14 @@
842 }
843 }
844 return 2;
845 }
846
847
848 /* char_entity -- '&' escaped when it doesn't belong to an entity */
849 /* valid entities are assumed to be anything matching &#?[A-Za-z0-9]+; */
 
850 static size_t char_entity(
851 struct Blob *ob,
852 struct render *rndr,
853 char *data,
854 size_t offset,
@@ -877,11 +972,10 @@
877 }else{
878 blob_append(ob, data, end);
879 }
880 return end;
881 }
882
883
884 /* char_atref_tag -- '@' followed by "word" characters to tag
885 * at-references */
886 static size_t char_atref_tag(
887 struct Blob *ob,
@@ -938,13 +1032,10 @@
938 ** or what appears to be the end or separator of a logical
939 ** natural-language construct, e.g. period, colon, etc.
940 **
941 ** Current limitations of this implementation:
942 **
943 ** - ASCII only. Support for non-ASCII characters might be
944 ** interesting.
945 **
946 ** - Currently requires starting alpha and trailing
947 ** alphanumeric or underscores. "Should" be extended to
948 ** handle #X[.Y], where X and optional Y are integer
949 ** values, for forum post references.
950 */
@@ -1073,12 +1164,13 @@
1073 #endif
1074 #undef HASHTAG_LEGAL_END
1075 return 0;
1076 }
1077
1078
1079 /* char_langle_tag -- '<' when tags or autolinks are allowed */
 
1080 static size_t char_langle_tag(
1081 struct Blob *ob,
1082 struct render *rndr,
1083 char *data,
1084 size_t offset,
@@ -1103,12 +1195,12 @@
1103 }else{
1104 return end;
1105 }
1106 }
1107
1108
1109 /* get_link_inline -- extract inline-style link and title from
1110 ** parenthesed data
1111 */
1112 static int get_link_inline(
1113 struct Blob *link,
1114 struct Blob *title,
@@ -1158,11 +1250,11 @@
1158 link_e--;
1159 }
1160
1161 /* remove optional angle brackets around the link */
1162 if( data[link_b]=='<' ) link_b += 1;
1163 if( data[link_e-1]=='>' ) link_e -= 1;
1164
1165 /* escape backslashed character from link */
1166 blob_reset(link);
1167 i = link_b;
1168 while( i<link_e ){
@@ -1179,145 +1271,353 @@
1179 /* this function always succeed */
1180 return 0;
1181 }
1182
1183
1184 /* get_link_ref -- extract referenced link and title from id */
 
 
1185 static int get_link_ref(
1186 struct render *rndr,
1187 struct Blob *link,
1188 struct Blob *title,
1189 char *data,
1190 size_t size
1191 ){
1192 struct link_ref *lr;
 
1193
1194 /* find the link from its id (stored temporarily in link) */
1195 blob_reset(link);
1196 if( build_ref_id(link, data, size)<0 ) return -1;
1197 lr = bsearch(link,
1198 blob_buffer(&rndr->refs),
1199 blob_size(&rndr->refs)/sizeof(struct link_ref),
1200 sizeof (struct link_ref),
1201 cmp_link_ref);
1202 if( !lr ) return -1;
1203
1204 /* fill the output buffers */
1205 blob_reset(link);
1206 blob_reset(title);
1207 blob_append(link, blob_buffer(&lr->link), blob_size(&lr->link));
1208 blob_append(title, blob_buffer(&lr->title), blob_size(&lr->title));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1209 return 0;
1210 }
1211
 
 
 
 
 
 
 
 
 
 
 
 
1212
1213 /* char_link -- '[': parsing a link or an image */
 
 
 
 
 
 
 
 
 
 
 
 
1214 static size_t char_link(
1215 struct Blob *ob,
1216 struct render *rndr,
1217 char *data,
1218 size_t offset,
1219 size_t size
1220 ){
1221 int is_img = (offset && data[-1] == '!'), level;
1222 size_t i = 1, txt_e;
1223 struct Blob *content = 0;
1224 struct Blob *link = 0;
1225 struct Blob *title = 0;
 
1226 int ret;
1227
1228 /* checking whether the correct renderer exists */
1229 if( (is_img && !rndr->make.image) || (!is_img && !rndr->make.link) ){
1230 return 0;
1231 }
1232
1233 /* looking for the matching closing bracket */
1234 for(level=1; i<size; i++){
1235 if( data[i]=='\n' ) /* do nothing */;
1236 else if( data[i-1]=='\\' ) continue;
1237 else if( data[i]=='[' ) level += 1;
1238 else if( data[i]==']' ){
1239 level--;
1240 if( level<=0 ) break;
1241 }
1242 }
1243 if( i>=size ) return 0;
1244 txt_e = i;
1245 i++;
1246
1247 /* skip any amount of whitespace or newline */
1248 /* (this is much more laxist than original markdown syntax) */
1249 while( i<size && (data[i]==' ' || data[i]=='\t' || data[i]=='\n') ){ i++; }
1250
1251 /* allocate temporary buffers to store content, link and title */
1252 title = new_work_buffer(rndr);
1253 content = new_work_buffer(rndr);
1254 link = new_work_buffer(rndr);
1255 ret = 0; /* error if we don't get to the callback */
1256
1257 /* inline style link */
1258 if( i<size && data[i]=='(' ){
1259 size_t span_end = i;
1260 while( span_end<size
1261 && !(data[span_end]==')' && (span_end==i || data[span_end-1]!='\\'))
1262 ){
1263 span_end++;
1264 }
1265
1266 if( span_end>=size
1267 || get_link_inline(link, title, data+i+1, span_end-(i+1))<0
1268 ){
1269 goto char_link_cleanup;
1270 }
1271
1272 i = span_end+1;
1273
1274 /* reference style link */
1275 }else if( i<size && data[i]=='[' ){
1276 char *id_data;
1277 size_t id_size, id_end = i;
1278
1279 while( id_end<size && data[id_end]!=']' ){ id_end++; }
1280
1281 if( id_end>=size ) goto char_link_cleanup;
1282
1283 if( i+1==id_end ){
1284 /* implicit id - use the contents */
1285 id_data = data+1;
1286 id_size = txt_e-1;
1287 }else{
1288 /* explicit id - between brackets */
1289 id_data = data+i+1;
1290 id_size = id_end-(i+1);
1291 }
1292
1293 if( get_link_ref(rndr, link, title, id_data, id_size)<0 ){
1294 goto char_link_cleanup;
1295 }
1296
1297 i = id_end+1;
1298
1299 /* shortcut reference style link */
1300 }else{
1301 if( get_link_ref(rndr, link, title, data+1, txt_e-1)<0 ){
1302 goto char_link_cleanup;
1303 }
1304
1305 /* rewinding the whitespace */
1306 i = txt_e+1;
1307 }
1308
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1309 /* building content: img alt is escaped, link content is parsed */
1310 if( txt_e>1 ){
1311 if( is_img ) blob_append(content, data+1, txt_e-1);
1312 else parse_inline(content, rndr, data+1, txt_e-1);
1313 }
1314
1315 /* calling the relevant rendering function */
1316 if( is_img ){
1317 if( blob_size(ob)>0 && blob_buffer(ob)[blob_size(ob)-1]=='!' ) ob->nUsed--;
 
 
1318 ret = rndr->make.image(ob, link, title, content, rndr->make.opaque);
 
 
 
 
 
1319 }else{
1320 ret = rndr->make.link(ob, link, title, content, rndr->make.opaque);
1321 }
1322
1323 /* cleanup */
@@ -1325,11 +1625,10 @@
1325 release_work_buffer(rndr, title);
1326 release_work_buffer(rndr, link);
1327 release_work_buffer(rndr, content);
1328 return ret ? i : 0;
1329 }
1330
1331
1332
1333 /*********************************
1334 * BLOCK-LEVEL PARSING FUNCTIONS *
1335 *********************************/
@@ -2010,11 +2309,12 @@
2010 /* the end of the block has been found */
2011 if( strcmp(curtag->text,"html")==0 ){
2012 /* Omit <html> tags */
2013 enum mkd_autolink dummy;
2014 int k = tag_length(data, size, &dummy);
2015 blob_init(&work, data+k, i-(j+k));
 
2016 }else{
2017 blob_init(&work, data, i);
2018 }
2019 if( rndr->make.blockhtml ){
2020 rndr->make.blockhtml(ob, &work, rndr->make.opaque);
@@ -2217,11 +2517,13 @@
2217 char *data, /* input text */
2218 size_t size /* input text size */
2219 ){
2220 size_t beg, end, i;
2221 char *txt_data;
2222 int has_table = (rndr->make.table
 
 
2223 && rndr->make.table_row
2224 && rndr->make.table_cell
2225 && memchr(data, '|', size)!=0);
2226
2227 beg = 0;
@@ -2267,11 +2569,11 @@
2267 * REFERENCE PARSING *
2268 *********************/
2269
2270 /* is_ref -- returns whether a line is a reference or not */
2271 static int is_ref(
2272 char *data, /* input text */
2273 size_t beg, /* offset of the beginning of the line */
2274 size_t end, /* offset of the end of the text */
2275 size_t *last, /* last character of the link */
2276 struct Blob *refs /* array of link references */
2277 ){
@@ -2301,10 +2603,12 @@
2301 i += beg;
2302
2303 /* id part: anything but a newline between brackets */
2304 if( data[i]!='[' ) return 0;
2305 i++;
 
 
2306 id_offset = i;
2307 while( i<end && data[i]!='\n' && data[i]!='\r' && data[i]!=']' ){ i++; }
2308 if( i>=end || data[i]!=']' ) return 0;
2309 id_end = i;
2310
@@ -2329,10 +2633,11 @@
2329 && data[i]!='\n'
2330 && data[i]!='\r'
2331 ){
2332 i += 1;
2333 }
 
2334 if( data[i-1]=='>' ) link_end = i-1; else link_end = i;
2335
2336 /* optional spacer: (space | tab)* (newline | '\'' | '"' | '(' ) */
2337 while( i<end && (data[i]==' ' || data[i]=='\t') ){ i++; }
2338 if( i<end
@@ -2388,34 +2693,168 @@
2388 }
2389 blob_append(refs, (char *)&lr, sizeof lr);
2390 return 1;
2391 }
2392
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2393
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2394
2395 /**********************
2396 * EXPORTED FUNCTIONS *
2397 **********************/
2398
2399 /* markdown -- parses the input buffer and renders it into the output buffer */
2400 void markdown(
2401 struct Blob *ob, /* output blob for rendered text */
2402 struct Blob *ib, /* input blob in markdown */
2403 const struct mkd_renderer *rndrer /* renderer descriptor (callbacks) */
2404 ){
2405 struct link_ref *lr;
 
2406 size_t i, beg, end = 0;
2407 struct render rndr;
2408 char *ib_data;
2409 Blob text = BLOB_INITIALIZER;
2410
2411 /* filling the render structure */
2412 if( !rndrer ) return;
2413 rndr.make = *rndrer;
2414 rndr.nBlobCache = 0;
2415 rndr.iDepth = 0;
2416 rndr.refs = empty_blob;
 
 
 
 
 
 
 
 
 
2417 for(i=0; i<256; i++) rndr.active_char[i] = 0;
2418 if( (rndr.make.emphasis
2419 || rndr.make.double_emphasis
2420 || rndr.make.triple_emphasis)
2421 && rndr.make.emph_chars
@@ -2427,32 +2866,34 @@
2427 if( rndr.make.codespan ) rndr.active_char['`'] = char_codespan;
2428 if( rndr.make.linebreak ) rndr.active_char['\n'] = char_linebreak;
2429 if( rndr.make.image || rndr.make.link ) rndr.active_char['['] = char_link;
2430 rndr.active_char['@'] = char_atref_tag;
2431 rndr.active_char['#'] = char_hashref_tag;
 
2432 rndr.active_char['<'] = char_langle_tag;
2433 rndr.active_char['\\'] = char_escape;
2434 rndr.active_char['&'] = char_entity;
2435
2436 /* first pass: looking for references, copying everything else */
 
2437 beg = 0;
2438 ib_data = blob_buffer(ib);
2439 while( beg<blob_size(ib) ){ /* iterating over lines */
2440 if( is_ref(ib_data, beg, blob_size(ib), &end, &rndr.refs) ){
 
 
2441 beg = end;
2442 }else{ /* skipping to the next line */
2443 end = beg;
2444 while( end<blob_size(ib) && ib_data[end]!='\n' && ib_data[end]!='\r' ){
2445 end += 1;
2446 }
2447 /* adding the line body if present */
2448 if( end>beg ) blob_append(&text, ib_data + beg, end - beg);
2449 while( end<blob_size(ib) && (ib_data[end]=='\n' || ib_data[end]=='\r') ){
2450 /* add one \n per newline */
2451 if( ib_data[end]=='\n'
2452 || (end+1<blob_size(ib) && ib_data[end+1]!='\n')
2453 ){
2454 blob_append_char(&text, '\n');
2455 }
2456 end += 1;
2457 }
2458 beg = end;
@@ -2464,14 +2905,160 @@
2464 qsort(blob_buffer(&rndr.refs),
2465 blob_size(&rndr.refs)/sizeof(struct link_ref),
2466 sizeof(struct link_ref),
2467 cmp_link_ref_sort);
2468 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2469
2470 /* second pass: actual rendering */
2471 if( rndr.make.prolog ) rndr.make.prolog(ob, rndr.make.opaque);
2472 parse_block(ob, &rndr, blob_buffer(&text), blob_size(&text));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2473 if( rndr.make.epilog ) rndr.make.epilog(ob, rndr.make.opaque);
2474
2475 /* clean-up */
2476 assert( rndr.iDepth==0 );
2477 blob_reset(&text);
@@ -2481,9 +3068,17 @@
2481 blob_reset(&lr[i].id);
2482 blob_reset(&lr[i].link);
2483 blob_reset(&lr[i].title);
2484 }
2485 blob_reset(&rndr.refs);
 
 
 
 
 
 
 
 
2486 for(i=0; i<rndr.nBlobCache; i++){
2487 fossil_free(rndr.aBlobCache[i]);
2488 }
2489 }
2490
--- src/markdown.c
+++ src/markdown.c
@@ -52,10 +52,11 @@
52 /* mkd_renderer -- functions for rendering parsed data */
53 struct mkd_renderer {
54 /* document level callbacks */
55 void (*prolog)(struct Blob *ob, void *opaque);
56 void (*epilog)(struct Blob *ob, void *opaque);
57 void (*footnotes)(struct Blob *ob, const struct Blob *items, void *opaque);
58
59 /* block level callbacks - NULL skips the block */
60 void (*blockcode)(struct Blob *ob, struct Blob *text, void *opaque);
61 void (*blockquote)(struct Blob *ob, struct Blob *text, void *opaque);
62 void (*blockhtml)(struct Blob *ob, struct Blob *text, void *opaque);
@@ -70,10 +71,12 @@
71 void *opaque);
72 void (*table_cell)(struct Blob *ob, struct Blob *text, int flags,
73 void *opaque);
74 void (*table_row)(struct Blob *ob, struct Blob *cells, int flags,
75 void *opaque);
76 void (*footnote_item)(struct Blob *ob, const struct Blob *text,
77 int index, int nUsed, void *opaque);
78
79 /* span level callbacks - NULL or return 0 prints the span verbatim */
80 int (*autolink)(struct Blob *ob, struct Blob *link,
81 enum mkd_autolink type, void *opaque);
82 int (*codespan)(struct Blob *ob, struct Blob *text, int nSep, void *opaque);
@@ -88,10 +91,12 @@
91 int (*raw_html_tag)(struct Blob *ob, struct Blob *tag, void *opaque);
92 int (*tagspan)(struct Blob *ob, struct Blob *ref, enum mkd_tagspan type,
93 void *opaque);
94 int (*triple_emphasis)(struct Blob *ob, struct Blob *text,
95 char c, void *opaque);
96 int (*footnote_ref)(struct Blob *ob, const struct Blob *span,
97 const struct Blob *upc, int index, int locus, void *opaque);
98
99 /* low level callbacks - NULL copies input directly into the output */
100 void (*entity)(struct Blob *ob, struct Blob *entity, void *opaque);
101 void (*normal_text)(struct Blob *ob, struct Blob *text, void *opaque);
102
@@ -122,31 +127,54 @@
127
128 /**********************
129 * EXPORTED FUNCTIONS *
130 **********************/
131
132 /*
133 ** markdown -- parses the input buffer and renders it into the output buffer.
134 */
135 void markdown(
136 struct Blob *ob,
137 const struct Blob *ib,
138 const struct mkd_renderer *rndr);
139
140
141 #endif /* INTERFACE */
142
143 #define BLOB_COUNT(pBlob,el_type) (blob_size(pBlob)/sizeof(el_type))
144 #define COUNT_FOOTNOTES(pBlob) BLOB_COUNT(pBlob,struct footnote)
145 #define CAST_AS_FOOTNOTES(pBlob) ((struct footnote*)blob_buffer(pBlob))
146
147 /***************
148 * LOCAL TYPES *
149 ***************/
150
151 /*
152 ** link_ref -- reference to a link.
153 */
154 struct link_ref {
155 struct Blob id; /* must be the first field as in footnote struct */
156 struct Blob link;
157 struct Blob title;
158 };
159
160 /*
161 ** A footnote's data.
162 ** id, text, and upc fields must be in that particular order.
163 */
164 struct footnote {
165 struct Blob id; /* must be the first field as in link_ref struct */
166 struct Blob text; /* footnote's content that is rendered at the end */
167 struct Blob upc; /* user-provided classes .ASCII-alnum.or-hypen: */
168 int bRndred; /* indicates if `text` holds a rendered content */
169
170 int defno; /* serial number of definition, set during the first pass */
171 int index; /* set to the index within array after ordering by id */
172 int iMark; /* user-visible numeric marker, assigned upon the first use*/
173 int nUsed; /* counts references to this note, increments upon each use*/
174 };
175 #define FOOTNOTE_INITIALIZER {empty_blob,empty_blob,empty_blob, 0,0,0,0,0}
176
177 /* char_trigger -- function pointer to render active chars */
178 /* returns the number of chars taken care of */
179 /* data is the pointer of the beginning of the span */
180 /* offset is the number of valid chars before data */
@@ -165,12 +193,19 @@
193 struct Blob refs;
194 char_trigger active_char[256];
195 int iDepth; /* Depth of recursion */
196 int nBlobCache; /* Number of entries in aBlobCache */
197 struct Blob *aBlobCache[20]; /* Cache of Blobs available for reuse */
198
199 struct {
200 Blob all; /* Buffer that holds array of footnotes. Its underline
201 memory may be reallocated when a new footnote is added. */
202 int nLbled; /* number of labeled footnotes found during the first pass */
203 int nMarks; /* counts distinct indices found during the second pass */
204 struct footnote misref; /* nUsed counts misreferences, iMark must be -1 */
205 } notes;
206 };
 
207
208 /* html_tag -- structure for quick HTML tag search (inspired from discount) */
209 struct html_tag {
210 const char *text;
211 int size;
@@ -192,16 +227,18 @@
227 { "html", 4 },
228 { "pre", 3 },
229 { "script", 6 },
230 };
231
 
232 /***************************
233 * STATIC HELPER FUNCTIONS *
234 ***************************/
235
236 /*
237 ** build_ref_id -- collapse whitespace from input text to make it a ref id.
238 ** Potential TODO: maybe also handle CR+LF line endings?
239 */
240 static int build_ref_id(struct Blob *id, const char *data, size_t size){
241 size_t beg, i;
242 char *id_data;
243
244 /* skip leading whitespace */
@@ -256,10 +293,58 @@
293 struct link_ref *lra = (void *)a;
294 struct link_ref *lrb = (void *)b;
295 return blob_compare(&lra->id, &lrb->id);
296 }
297
298 /*
299 ** cmp_footnote_id -- comparison function for footnotes qsort.
300 ** Empty IDs sort last (in undetermined order).
301 ** Equal IDs are sorted in the order of definition in the source.
302 */
303 static int cmp_footnote_id(const void *fna, const void *fnb){
304 const struct footnote *a = fna, *b = fnb;
305 const int szA = blob_size(&a->id), szB = blob_size(&b->id);
306 if( szA ){
307 if( szB ){
308 int cmp = blob_compare(&a->id, &b->id);
309 if( cmp ) return cmp;
310 }else return -1;
311 }else return szB ? 1 : 0;
312 /* IDs are equal and non-empty */
313 if( a->defno < b->defno ) return -1;
314 if( a->defno > b->defno ) return 1;
315 assert(!"reachable");
316 return 0; /* should never reach here */
317 }
318
319 /*
320 ** cmp_footnote_sort -- comparison function for footnotes qsort.
321 ** Unreferenced footnotes (when nUsed == 0) sort last and
322 ** are sorted in the order of definition in the source.
323 */
324 static int cmp_footnote_sort(const void *fna, const void *fnb){
325 const struct footnote *a = fna, *b = fnb;
326 int i, j;
327 assert( a->nUsed >= 0 );
328 assert( b->nUsed >= 0 );
329 assert( a->defno >= 0 );
330 assert( b->defno >= 0 );
331 if( a->nUsed ){
332 assert( a->iMark > 0 );
333 if( !b->nUsed ) return -1;
334 assert( b->iMark > 0 );
335 i = a->iMark;
336 j = b->iMark;
337 }else{
338 if( b->nUsed ) return 1;
339 i = a->defno;
340 j = b->defno;
341 }
342 if( i < j ) return -1;
343 if( i > j ) return 1;
344 return 0;
345 }
346
347 /* cmp_html_tag -- comparison function for bsearch() (stolen from discount) */
348 static int cmp_html_tag(const void *a, const void *b){
349 const struct html_tag *hta = a;
350 const struct html_tag *htb = b;
@@ -588,12 +673,14 @@
673 if( fossil_isalnum(after) ) return 0;
674 return 1;
675 }
676
677
678 /*
679 ** parse_emph1 -- parsing single emphasis.
680 ** closed by a symbol not preceded by whitespace and not followed by symbol.
681 */
682 static size_t parse_emph1(
683 struct Blob *ob,
684 struct render *rndr,
685 char *data,
686 size_t size,
@@ -633,12 +720,13 @@
720 }
721 }
722 return 0;
723 }
724
725 /*
726 ** parse_emph2 -- parsing single emphasis.
727 */
728 static size_t parse_emph2(
729 struct Blob *ob,
730 struct render *rndr,
731 char *data,
732 size_t size,
@@ -672,13 +760,14 @@
760 i++;
761 }
762 return 0;
763 }
764
765 /*
766 ** parse_emph3 -- parsing single emphasis.
767 ** finds the first closing tag, and delegates to the other emph.
768 */
769 static size_t parse_emph3(
770 struct Blob *ob,
771 struct render *rndr,
772 char *data,
773 size_t size,
@@ -720,12 +809,13 @@
809 }
810 }
811 return 0;
812 }
813
814 /*
815 ** char_emphasis -- single and double emphasis parsing.
816 */
817 static size_t char_emphasis(
818 struct Blob *ob,
819 struct render *rndr,
820 char *data,
821 size_t offset,
@@ -765,12 +855,13 @@
855 return ret+3;
856 }
857 return 0;
858 }
859
860 /*
861 ** char_linebreak -- '\n' preceded by two spaces (assuming linebreak != 0).
862 */
863 static size_t char_linebreak(
864 struct Blob *ob,
865 struct render *rndr,
866 char *data,
867 size_t offset,
@@ -780,12 +871,13 @@
871 /* removing the last space from ob and rendering */
872 if( blob_size(ob)>0 && blob_buffer(ob)[blob_size(ob)-1]==' ' ) ob->nUsed--;
873 return rndr->make.linebreak(ob, rndr->make.opaque) ? 1 : 0;
874 }
875
876 /*
877 ** char_codespan -- '`' parsing a code span (assuming codespan != 0).
878 */
879 static size_t char_codespan(
880 struct Blob *ob,
881 struct render *rndr,
882 char *data,
883 size_t offset,
@@ -822,11 +914,13 @@
914 }
915 return end;
916 }
917
918
919 /*
920 ** char_escape -- '\\' backslash escape.
921 */
922 static size_t char_escape(
923 struct Blob *ob,
924 struct render *rndr,
925 char *data,
926 size_t offset,
@@ -842,13 +936,14 @@
936 }
937 }
938 return 2;
939 }
940
941 /*
942 ** char_entity -- '&' escaped when it doesn't belong to an entity.
943 ** valid entities are assumed to be anything matching &#?[A-Za-z0-9]+;
944 */
945 static size_t char_entity(
946 struct Blob *ob,
947 struct render *rndr,
948 char *data,
949 size_t offset,
@@ -877,11 +972,10 @@
972 }else{
973 blob_append(ob, data, end);
974 }
975 return end;
976 }
 
977
978 /* char_atref_tag -- '@' followed by "word" characters to tag
979 * at-references */
980 static size_t char_atref_tag(
981 struct Blob *ob,
@@ -938,13 +1032,10 @@
1032 ** or what appears to be the end or separator of a logical
1033 ** natural-language construct, e.g. period, colon, etc.
1034 **
1035 ** Current limitations of this implementation:
1036 **
 
 
 
1037 ** - Currently requires starting alpha and trailing
1038 ** alphanumeric or underscores. "Should" be extended to
1039 ** handle #X[.Y], where X and optional Y are integer
1040 ** values, for forum post references.
1041 */
@@ -1073,12 +1164,13 @@
1164 #endif
1165 #undef HASHTAG_LEGAL_END
1166 return 0;
1167 }
1168
1169 /*
1170 ** char_langle_tag -- '<' when tags or autolinks are allowed.
1171 */
1172 static size_t char_langle_tag(
1173 struct Blob *ob,
1174 struct render *rndr,
1175 char *data,
1176 size_t offset,
@@ -1103,12 +1195,12 @@
1195 }else{
1196 return end;
1197 }
1198 }
1199
1200 /*
1201 ** get_link_inline -- extract inline-style link and title from
1202 ** parenthesed data
1203 */
1204 static int get_link_inline(
1205 struct Blob *link,
1206 struct Blob *title,
@@ -1158,11 +1250,11 @@
1250 link_e--;
1251 }
1252
1253 /* remove optional angle brackets around the link */
1254 if( data[link_b]=='<' ) link_b += 1;
1255 if( link_e && data[link_e-1]=='>' ) link_e -= 1;
1256
1257 /* escape backslashed character from link */
1258 blob_reset(link);
1259 i = link_b;
1260 while( i<link_e ){
@@ -1179,145 +1271,353 @@
1271 /* this function always succeed */
1272 return 0;
1273 }
1274
1275
1276 /*
1277 ** get_link_ref -- extract referenced link and title from id.
1278 */
1279 static int get_link_ref(
1280 struct render *rndr,
1281 struct Blob *link,
1282 struct Blob *title,
1283 char *data,
1284 size_t size
1285 ){
1286 struct link_ref *lr;
1287 const size_t sz = blob_size(&rndr->refs);
1288
1289 /* find the link from its id (stored temporarily in link) */
1290 blob_reset(link);
1291 if( !sz || build_ref_id(link, data, size)<0 ) return -1;
1292 lr = bsearch(link,
1293 blob_buffer(&rndr->refs),
1294 sz/sizeof(struct link_ref),
1295 sizeof (struct link_ref),
1296 cmp_link_ref);
1297 if( !lr ) return -1;
1298
1299 /* fill the output buffers */
1300 blob_reset(link);
1301 blob_reset(title);
1302 blob_appendb(link, &lr->link);
1303 blob_appendb(title, &lr->title);
1304 return 0;
1305 }
1306
1307 /*
1308 ** get_footnote() -- find a footnote by label, invoked during the 2nd pass.
1309 ** If found then return a shallow copy of the corresponding footnote;
1310 ** otherwise return a shallow copy of rndr->notes.misref.
1311 ** In both cases corresponding `nUsed` field is incremented before return.
1312 */
1313 static struct footnote get_footnote(
1314 struct render *rndr,
1315 const char *data,
1316 size_t size
1317 ){
1318 struct footnote *fn = 0;
1319 struct Blob *id;
1320 if( !rndr->notes.nLbled ) goto fallback;
1321 id = new_work_buffer(rndr);
1322 if( build_ref_id(id, data, size)<0 ) goto cleanup;
1323 fn = bsearch(id, blob_buffer(&rndr->notes.all),
1324 rndr->notes.nLbled,
1325 sizeof (struct footnote),
1326 cmp_link_ref);
1327 if( !fn ) goto cleanup;
1328
1329 if( fn->nUsed == 0 ){ /* the first reference to the footnote */
1330 assert( fn->iMark == 0 );
1331 fn->iMark = ++(rndr->notes.nMarks);
1332 }
1333 assert( fn->iMark > 0 );
1334 cleanup:
1335 release_work_buffer( rndr, id );
1336 fallback:
1337 if( !fn ) fn = &rndr->notes.misref;
1338 fn->nUsed++;
1339 assert( fn->nUsed > 0 );
1340 return *fn;
1341 }
1342
1343 /*
1344 ** Counts characters in the blank prefix within at most nHalfLines.
1345 ** A sequence of spaces and tabs counts as odd halfline,
1346 ** a newline counts as even halfline.
1347 ** If nHalfLines < 0 then proceed without constraints.
1348 */
1349 static inline size_t sizeof_blank_prefix(
1350 const char *data, size_t size, int nHalfLines
1351 ){
1352 const char *p = data;
1353 const char * const end = data+size;
1354 if( nHalfLines < 0 ){
1355 while( p!=end && fossil_isspace(*p) ){
1356 p++;
1357 }
1358 }else while( nHalfLines > 0 ){
1359 while( p!=end && (*p==' ' || *p=='\t' ) ){ p++; }
1360 if( p==end || --nHalfLines == 0 ) break;
1361 if( *p=='\n' || *p=='\r' ){
1362 p++;
1363 if( p==end ) break;
1364 if( *p=='\n' && p[-1]=='\r' ){
1365 p++;
1366 }
1367 }
1368 nHalfLines--;
1369 }
1370 return p-data;
1371 }
1372
1373 /*
1374 ** Check if the data starts with a classlist token of the special form.
1375 ** If so then return the length of that token, otherwise return 0.
1376 **
1377 ** The token must start with a dot and must end with a colon;
1378 ** in between of these it must be a dot-separated list of words;
1379 ** each word may contain only alphanumeric characters and hyphens.
1380 **
1381 ** If `bBlank` is non-zero then a blank character must follow
1382 ** the token's ending colon: otherwise function returns 0
1383 ** despite the well-formed token.
1384 */
1385 static size_t is_footnote_classlist(const char * const data, size_t size,
1386 int bBlank){
1387 const char *p;
1388 const char * const end = data+size;
1389 if( data==end || *data != '.' ) return 0;
1390 for(p=data+1; p!=end; p++){
1391 if( fossil_isalnum(*p) || *p=='-' ) continue;
1392 if( p[-1]=='.' ) break;
1393 if( *p==':' ){
1394 p++;
1395 if( bBlank ){
1396 if( p==end || !fossil_isspace(*p) ) break;
1397 }
1398 return p-data;
1399 }
1400 if( *p!='.' ) break;
1401 }
1402 return 0;
1403 }
1404
1405 /*
1406 ** Adds unlabeled footnote to the rndr->notes.all.
1407 ** On success puts a shallow copy of the constructed footnote into pFN
1408 ** and returns 1, otherwise pFN is unchanged and 0 is returned.
1409 */
1410 static inline int add_inline_footnote(
1411 struct render *rndr,
1412 const char *text,
1413 size_t size,
1414 struct footnote* pFN
1415 ){
1416 struct footnote fn = FOOTNOTE_INITIALIZER, *last;
1417 const char *zUPC = 0;
1418 size_t nUPC = 0, n = sizeof_blank_prefix(text, size, 3);
1419 if( n >= size ) return 0;
1420 text += n;
1421 size -= n;
1422 nUPC = is_footnote_classlist(text, size, 1);
1423 if( nUPC ){
1424 assert( nUPC<size );
1425 zUPC = text;
1426 text += nUPC;
1427 size -= nUPC;
1428 }
1429 if( sizeof_blank_prefix(text,size,-1)==size ){
1430 if( !nUPC ) return 0; /* empty inline footnote */
1431 text = zUPC;
1432 size = nUPC; /* bare classlist is treated */
1433 nUPC = 0; /* as plain text */
1434 }
1435 fn.iMark = ++(rndr->notes.nMarks);
1436 fn.nUsed = 1;
1437 fn.index = COUNT_FOOTNOTES(&rndr->notes.all);
1438 assert( fn.iMark > 0 );
1439 blob_append(&fn.text, text, size);
1440 if(nUPC) blob_append(&fn.upc, zUPC, nUPC);
1441 blob_append(&rndr->notes.all, (char *)&fn, sizeof fn);
1442 last = (struct footnote*)( blob_buffer(&rndr->notes.all)
1443 +( blob_size(&rndr->notes.all)-sizeof fn ));
1444 assert( pFN );
1445 memcpy( pFN, last, sizeof fn );
1446 return 1;
1447 }
1448
1449 /*
1450 ** Return the byte offset of the matching closing bracket or 0 if not
1451 ** found. begin[0] must be either '[' or '('.
1452 **
1453 ** TODO: It seems that things like "\\(" are not handled correctly.
1454 ** That is historical behavior for a corner-case,
1455 ** so it's left as it is until somebody complains.
1456 */
1457 static inline size_t matching_bracket_offset(
1458 const char* begin,
1459 const char* end
1460 ){
1461 const char *i;
1462 int level;
1463 const char bra = *begin;
1464 const char ket = bra=='[' ? ']' : ')';
1465 assert( bra=='[' || bra=='(' );
1466 for(i=begin+1,level=1; i!=end; i++){
1467 if( *i=='\n' ) /* do nothing */;
1468 else if( i[-1]=='\\' ) continue;
1469 else if( *i==bra ) level++;
1470 else if( *i==ket ){
1471 if( --level<=0 ) return i-begin;
1472 }
1473 }
1474 return 0;
1475 }
1476
1477 /*
1478 ** char_footnote -- '(': parsing a standalone inline footnote.
1479 */
1480 static size_t char_footnote(
1481 struct Blob *ob,
1482 struct render *rndr,
1483 char *data,
1484 size_t offset,
1485 size_t size
1486 ){
1487 size_t end;
1488 struct footnote fn;
1489
1490 if( size<4 || data[1]!='^' ) return 0;
1491 end = matching_bracket_offset(data, data+size);
1492 if( !end ) return 0;
1493 if( !add_inline_footnote(rndr, data+2, end-2, &fn) ) return 0;
1494 if( rndr->make.footnote_ref ){
1495 rndr->make.footnote_ref(ob,0,&fn.upc,fn.iMark,1,rndr->make.opaque);
1496 }
1497 return end+1;
1498 }
1499
1500 /*
1501 ** char_link -- '[': parsing a link or an image.
1502 */
1503 static size_t char_link(
1504 struct Blob *ob,
1505 struct render *rndr,
1506 char *data,
1507 size_t offset,
1508 size_t size /* parse_inline() ensures that size > 0 */
1509 ){
1510 const int is_img = (offset && data[-1] == '!');
1511 size_t i = 1, txt_e;
1512 struct Blob *content = 0;
1513 struct Blob *link = 0;
1514 struct Blob *title = 0;
1515 struct footnote fn;
1516 int ret;
1517
1518 /* checking whether the correct renderer exists */
1519 if( (is_img && !rndr->make.image) || (!is_img && !rndr->make.link) ){
1520 return 0;
1521 }
1522
1523 /* looking for the matching closing bracket */
1524 txt_e = matching_bracket_offset(data, data+size);
1525 if( !txt_e ) return 0;
1526 i = txt_e + 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1527 ret = 0; /* error if we don't get to the callback */
1528 fn.nUsed = 0;
1529
1530 /* free-standing footnote refernece */
1531 if(!is_img && size>3 && data[1]=='^'){
1532 fn = get_footnote(rndr, data+2, txt_e-2);
1533 }else{
1534
1535 /* skip "inter-bracket-whitespace" - any amount of whitespace or newline */
1536 /* (this is much more lax than original markdown syntax) */
1537 while( i<size && (data[i]==' ' || data[i]=='\t' || data[i]=='\n') ){ i++; }
1538
1539 /* allocate temporary buffers to store content, link and title */
1540 title = new_work_buffer(rndr);
1541 content = new_work_buffer(rndr);
1542 link = new_work_buffer(rndr);
1543
1544 if( i<size && data[i]=='(' ){
1545
1546 if( i+2<size && data[i+1]=='^' ){ /* span-bounded inline footnote */
1547
1548 const size_t k = matching_bracket_offset(data+i, data+size);
1549 if( !k ) goto char_link_cleanup;
1550 add_inline_footnote(rndr, data+(i+2), k-2, &fn);
1551 i += k+1;
1552 }else{ /* inline style link */
1553 size_t span_end = i;
1554 while( span_end<size
1555 && !(data[span_end]==')'
1556 && (span_end==i || data[span_end-1]!='\\')) ){
1557 span_end++;
1558 }
1559 if( span_end>=size
1560 || get_link_inline(link, title, data+i+1, span_end-(i+1))<0 ){
1561 goto char_link_cleanup;
1562 }
1563 i = span_end+1;
1564 }
1565 /* reference style link or span-bounded footnote reference */
1566 }else if( i<size && data[i]=='[' ){
1567 char *id_data;
1568 size_t id_size, id_end = i;
1569 int bFootnote;
1570
1571 while( id_end<size && data[id_end]!=']' ){ id_end++; }
1572 if( id_end>=size ) goto char_link_cleanup;
1573 bFootnote = data[i+1]=='^';
1574 if( i+1==id_end || (bFootnote && i+2==id_end) ){
1575 /* implicit id - use the contents */
1576 id_data = data+1;
1577 id_size = txt_e-1;
1578 }else{
1579 /* explicit id - between brackets */
1580 id_data = data+i+1;
1581 id_size = id_end-(i+1);
1582 if( bFootnote ){
1583 id_data++;
1584 id_size--;
1585 }
1586 }
1587 if( bFootnote ){
1588 fn = get_footnote(rndr, id_data, id_size);
1589 }else if( get_link_ref(rndr, link, title, id_data, id_size)<0 ){
1590 goto char_link_cleanup;
1591 }
1592 i = id_end+1;
1593 /* shortcut reference style link */
1594 }else{
1595 if( get_link_ref(rndr, link, title, data+1, txt_e-1)<0 ){
1596 goto char_link_cleanup;
1597 }
1598 /* rewinding an "inter-bracket-whitespace" */
1599 i = txt_e+1;
1600 }
1601 }
1602 /* building content: img alt is escaped, link content is parsed */
1603 if( txt_e>1 && content ){
1604 if( is_img ) blob_append(content, data+1, txt_e-1);
1605 else parse_inline(content, rndr, data+1, txt_e-1);
1606 }
1607
1608 /* calling the relevant rendering function */
1609 if( is_img ){
1610 if( blob_size(ob)>0 && blob_buffer(ob)[blob_size(ob)-1]=='!' ){
1611 ob->nUsed--;
1612 }
1613 ret = rndr->make.image(ob, link, title, content, rndr->make.opaque);
1614 }else if( fn.nUsed ){
1615 if( rndr->make.footnote_ref ){
1616 ret = rndr->make.footnote_ref(ob, content, &fn.upc, fn.iMark,
1617 fn.nUsed, rndr->make.opaque);
1618 }
1619 }else{
1620 ret = rndr->make.link(ob, link, title, content, rndr->make.opaque);
1621 }
1622
1623 /* cleanup */
@@ -1325,11 +1625,10 @@
1625 release_work_buffer(rndr, title);
1626 release_work_buffer(rndr, link);
1627 release_work_buffer(rndr, content);
1628 return ret ? i : 0;
1629 }
 
1630
1631
1632 /*********************************
1633 * BLOCK-LEVEL PARSING FUNCTIONS *
1634 *********************************/
@@ -2010,11 +2309,12 @@
2309 /* the end of the block has been found */
2310 if( strcmp(curtag->text,"html")==0 ){
2311 /* Omit <html> tags */
2312 enum mkd_autolink dummy;
2313 int k = tag_length(data, size, &dummy);
2314 int sz = i - (j+k);
2315 if( sz>0 ) blob_init(&work, data+k, sz);
2316 }else{
2317 blob_init(&work, data, i);
2318 }
2319 if( rndr->make.blockhtml ){
2320 rndr->make.blockhtml(ob, &work, rndr->make.opaque);
@@ -2217,11 +2517,13 @@
2517 char *data, /* input text */
2518 size_t size /* input text size */
2519 ){
2520 size_t beg, end, i;
2521 char *txt_data;
2522 int has_table;
2523 if( !size ) return;
2524 has_table = (rndr->make.table
2525 && rndr->make.table_row
2526 && rndr->make.table_cell
2527 && memchr(data, '|', size)!=0);
2528
2529 beg = 0;
@@ -2267,11 +2569,11 @@
2569 * REFERENCE PARSING *
2570 *********************/
2571
2572 /* is_ref -- returns whether a line is a reference or not */
2573 static int is_ref(
2574 const char *data, /* input text */
2575 size_t beg, /* offset of the beginning of the line */
2576 size_t end, /* offset of the end of the text */
2577 size_t *last, /* last character of the link */
2578 struct Blob *refs /* array of link references */
2579 ){
@@ -2301,10 +2603,12 @@
2603 i += beg;
2604
2605 /* id part: anything but a newline between brackets */
2606 if( data[i]!='[' ) return 0;
2607 i++;
2608 if( i>=end || data[i]=='^' ) return 0; /* see is_footnote() */
2609
2610 id_offset = i;
2611 while( i<end && data[i]!='\n' && data[i]!='\r' && data[i]!=']' ){ i++; }
2612 if( i>=end || data[i]!=']' ) return 0;
2613 id_end = i;
2614
@@ -2329,10 +2633,11 @@
2633 && data[i]!='\n'
2634 && data[i]!='\r'
2635 ){
2636 i += 1;
2637 }
2638 /* TODO: maybe require both data[i-1]=='>' && data[link_offset-1]=='<' ? */
2639 if( data[i-1]=='>' ) link_end = i-1; else link_end = i;
2640
2641 /* optional spacer: (space | tab)* (newline | '\'' | '"' | '(' ) */
2642 while( i<end && (data[i]==' ' || data[i]=='\t') ){ i++; }
2643 if( i<end
@@ -2388,34 +2693,168 @@
2693 }
2694 blob_append(refs, (char *)&lr, sizeof lr);
2695 return 1;
2696 }
2697
2698 /*********************
2699 * FOOTNOTE PARSING *
2700 *********************/
2701
2702 /* is_footnote -- check if data holds a definition of a labeled footnote.
2703 * If so then append the corresponding element to `footnotes` array */
2704 static int is_footnote(
2705 const char *data, /* input text */
2706 size_t beg, /* offset of the beginning of the line */
2707 size_t end, /* offset of the end of the text */
2708 size_t *last, /* last character of the link */
2709 struct Blob * footnotes
2710 ){
2711 size_t i, id_offset, id_end, upc_offset, upc_size;
2712 struct footnote fn = FOOTNOTE_INITIALIZER;
2713
2714 /* failfast if data is too short */
2715 if( beg+5>=end ) return 0;
2716 i = beg;
2717
2718 /* footnote definition must start at the begining of a line */
2719 if( data[i]!='[' ) return 0;
2720 i++;
2721 if( data[i]!='^' ) return 0;
2722 id_offset = ++i;
2723
2724 /* id part: anything but a newline between brackets */
2725 while( i<end && data[i]!=']' && data[i]!='\n' && data[i]!='\r' ){ i++; }
2726 if( i>=end || data[i]!=']' ) return 0;
2727 id_end = i++;
2728
2729 /* spacer: colon (space | tab)* */
2730 if( i>=end || data[i]!=':' ) return 0;
2731 i++;
2732 while( i<end && (data[i]==' ' || data[i]=='\t') ){ i++; }
2733
2734 /* passthrough truncated footnote definition */
2735 if( i>=end ) return 0;
2736
2737 if( build_ref_id(&fn.id, data+id_offset, id_end-id_offset)<0 ) return 0;
2738
2739 /* footnote's text may start on the same line after [^id]: */
2740 upc_offset = upc_size = 0;
2741 if( data[i]!='\n' && data[i]!='\r' ){
2742 size_t j;
2743 upc_size = is_footnote_classlist(data+i, end-i, 1);
2744 upc_offset = i; /* prevent further checks for a classlist */
2745 i += upc_size;
2746 j = i;
2747 while( i<end && data[i]!='\n' && data[i]!='\r' ){ i++; };
2748 if( i!=j )blob_append(&fn.text, data+j, i-j);
2749 if( i<end ){
2750 blob_append_char(&fn.text, data[i]);
2751 i++;
2752 if( i<end && data[i]=='\n' && data[i-1]=='\r' ){
2753 blob_append_char(&fn.text, data[i]);
2754 i++;
2755 }
2756 }
2757 }else{
2758 i++;
2759 if( i<end && data[i]=='\n' && data[i-1]=='\r' ) i++;
2760 }
2761 if( i<end ){
2762
2763 /* compute the indentation from the 2nd line */
2764 size_t indent = i;
2765 const char *spaces = data+i;
2766 while( indent<end && data[indent]==' ' ){ indent++; }
2767 if( indent>=end ) goto footnote_finish;
2768 indent -= i;
2769 if( indent<2 ) goto footnote_finish;
2770
2771 /* process the 2nd and subsequent lines */
2772 while( i+indent<end && memcmp(data+i,spaces,indent)==0 ){
2773 size_t j;
2774 i += indent;
2775 if( !upc_offset ){
2776 /* a classlist must be provided no later than at the 2nd line */
2777 upc_offset = i + sizeof_blank_prefix(data+i, end-i, 1);
2778 upc_size = is_footnote_classlist(data+upc_offset,
2779 end-upc_offset, 1);
2780 if( upc_size ){
2781 i = upc_offset + upc_size;
2782 }
2783 }
2784 j = i;
2785 while( i<end && data[i]!='\n' && data[i]!='\r' ){ i++; }
2786 if( i!=j ) blob_append(&fn.text, data+j, i-j);
2787 if( i>=end ) break;
2788 blob_append_char(&fn.text, data[i]);
2789 i++;
2790 if( i<end && data[i]=='\n' && data[i-1]=='\r' ){
2791 blob_append_char(&fn.text, data[i]);
2792 i++;
2793 }
2794 }
2795 }
2796 footnote_finish:
2797 if( !blob_size(&fn.text) ){
2798 blob_reset(&fn.id);
2799 return 0;
2800 }
2801 if( !blob_trim(&fn.text) ){ /* if the content is all-blank */
2802 if( upc_size ){ /* interpret UPC as plain text */
2803 blob_append(&fn.text, data+upc_offset, upc_size);
2804 upc_size = 0;
2805 }else{
2806 blob_reset(&fn.id); /* or clean up and fail */
2807 blob_reset(&fn.text);
2808 return 0;
2809 }
2810 }
2811 /* a valid note has been found */
2812 if( last ) *last = i;
2813 if( footnotes ){
2814 fn.defno = COUNT_FOOTNOTES( footnotes );
2815 if( upc_size ){
2816 assert( upc_offset && upc_offset+upc_size<end );
2817 blob_append(&fn.upc, data+upc_offset, upc_size);
2818 }
2819 blob_append(footnotes, (char *)&fn, sizeof fn);
2820 }
2821 return 1;
2822 }
2823
2824 /**********************
2825 * EXPORTED FUNCTIONS *
2826 **********************/
2827
2828 /* markdown -- parses the input buffer and renders it into the output buffer */
2829 void markdown(
2830 struct Blob *ob, /* output blob for rendered text */
2831 const struct Blob *ib, /* input blob in markdown */
2832 const struct mkd_renderer *rndrer /* renderer descriptor (callbacks) */
2833 ){
2834 struct link_ref *lr;
2835 struct footnote *fn;
2836 size_t i, beg, end = 0;
2837 struct render rndr;
2838 Blob text = BLOB_INITIALIZER; /* input after the first pass */
2839 Blob * const allNotes = &rndr.notes.all;
2840
2841 /* filling the render structure */
2842 if( !rndrer ) return;
2843 rndr.make = *rndrer;
2844 rndr.nBlobCache = 0;
2845 rndr.iDepth = 0;
2846 rndr.refs = empty_blob;
2847 rndr.notes.all = empty_blob;
2848 rndr.notes.nMarks = 0;
2849 rndr.notes.misref.id = empty_blob;
2850 rndr.notes.misref.text = empty_blob;
2851 rndr.notes.misref.upc = empty_blob;
2852 rndr.notes.misref.bRndred = 0;
2853 rndr.notes.misref.nUsed = 0;
2854 rndr.notes.misref.iMark = -1;
2855
2856 for(i=0; i<256; i++) rndr.active_char[i] = 0;
2857 if( (rndr.make.emphasis
2858 || rndr.make.double_emphasis
2859 || rndr.make.triple_emphasis)
2860 && rndr.make.emph_chars
@@ -2427,32 +2866,34 @@
2866 if( rndr.make.codespan ) rndr.active_char['`'] = char_codespan;
2867 if( rndr.make.linebreak ) rndr.active_char['\n'] = char_linebreak;
2868 if( rndr.make.image || rndr.make.link ) rndr.active_char['['] = char_link;
2869 rndr.active_char['@'] = char_atref_tag;
2870 rndr.active_char['#'] = char_hashref_tag;
2871 if( rndr.make.footnote_ref ) rndr.active_char['('] = char_footnote;
2872 rndr.active_char['<'] = char_langle_tag;
2873 rndr.active_char['\\'] = char_escape;
2874 rndr.active_char['&'] = char_entity;
2875
2876 /* first pass: iterate over lines looking for references,
2877 * copying everything else into "text" */
2878 beg = 0;
2879 for(const size_t size = blob_size(ib); beg<size ;){
2880 const char* const data = blob_buffer(ib);
2881 if( is_ref(data, beg, size, &end, &rndr.refs) ){
2882 beg = end;
2883 }else if(is_footnote(data, beg, size, &end, &rndr.notes.all)){
2884 beg = end;
2885 }else{ /* skipping to the next line */
2886 end = beg;
2887 while( end<size && data[end]!='\n' && data[end]!='\r' ){
2888 end += 1;
2889 }
2890 /* adding the line body if present */
2891 if( end>beg ) blob_append(&text, data + beg, end - beg);
2892 while( end<size && (data[end]=='\n' || data[end]=='\r') ){
2893 /* add one \n per newline */
2894 if( data[end]=='\n' || (end+1<size && data[end+1]!='\n') ){
 
 
2895 blob_append_char(&text, '\n');
2896 }
2897 end += 1;
2898 }
2899 beg = end;
@@ -2464,14 +2905,160 @@
2905 qsort(blob_buffer(&rndr.refs),
2906 blob_size(&rndr.refs)/sizeof(struct link_ref),
2907 sizeof(struct link_ref),
2908 cmp_link_ref_sort);
2909 }
2910 rndr.notes.nLbled = COUNT_FOOTNOTES( allNotes );
2911
2912 /* sort footnotes by ID and join duplicates */
2913 if( rndr.notes.nLbled > 1 ){
2914 int nDups = 0;
2915 fn = CAST_AS_FOOTNOTES( allNotes );
2916 qsort(fn, rndr.notes.nLbled, sizeof(struct footnote), cmp_footnote_id);
2917
2918 /* concatenate footnotes with equal labels */
2919 for(i=0; i<rndr.notes.nLbled ;){
2920 struct footnote *x = fn + i;
2921 size_t j = i+1, k = blob_size(&x->text) + 64 + blob_size(&x->upc);
2922 while(j<rndr.notes.nLbled && !blob_compare(&x->id, &fn[j].id)){
2923 k += blob_size(&fn[j].text) + 10 + blob_size(&fn[j].upc);
2924 j++;
2925 nDups++;
2926 }
2927 if( i+1<j ){
2928 Blob list = empty_blob;
2929 blob_reserve(&list, k);
2930 /* must match _joined_footnote_indicator in html_footnote_item() */
2931 blob_append_literal(&list, "<ul class='fn-joined'>\n");
2932 for(k=i; k<j; k++){
2933 struct footnote *y = fn + k;
2934 blob_append_literal(&list, "<li>");
2935 if( blob_size(&y->upc) ){
2936 blob_appendb(&list, &y->upc);
2937 blob_reset(&y->upc);
2938 }
2939 blob_appendb(&list, &y->text);
2940 blob_append_literal(&list, "</li>\n");
2941
2942 /* free memory buffer */
2943 blob_reset(&y->text);
2944 if( k!=i ) blob_reset(&y->id);
2945 }
2946 blob_append_literal(&list, "</ul>\n");
2947 x->text = list;
2948 g.ftntsIssues[2]++;
2949 }
2950 i = j;
2951 }
2952 if( nDups ){ /* clean rndr.notes.all from invalidated footnotes */
2953 const int n = rndr.notes.nLbled - nDups;
2954 struct Blob filtered = empty_blob;
2955 blob_reserve(&filtered, n*sizeof(struct footnote));
2956 for(i=0; i<rndr.notes.nLbled; i++){
2957 if( blob_size(&fn[i].id) ){
2958 blob_append(&filtered, (char*)(fn+i), sizeof(struct footnote));
2959 }
2960 }
2961 blob_reset( allNotes );
2962 rndr.notes.all = filtered;
2963 rndr.notes.nLbled = n;
2964 assert( COUNT_FOOTNOTES(allNotes) == rndr.notes.nLbled );
2965 }
2966 }
2967 fn = CAST_AS_FOOTNOTES( allNotes );
2968 for(i=0; i<rndr.notes.nLbled; i++){
2969 fn[i].index = i;
2970 }
2971 assert( rndr.notes.nMarks==0 );
2972
2973 /* second pass: actual rendering */
2974 if( rndr.make.prolog ) rndr.make.prolog(ob, rndr.make.opaque);
2975 parse_block(ob, &rndr, blob_buffer(&text), blob_size(&text));
2976
2977 if( blob_size(allNotes) || rndr.notes.misref.nUsed ){
2978
2979 /* Footnotes must be parsed for the correct discovery of (back)links */
2980 Blob *notes = new_work_buffer( &rndr );
2981 if( blob_size(allNotes) ){
2982 Blob *tmp = new_work_buffer( &rndr );
2983 int nMarks = -1, maxDepth = 5;
2984
2985 /* inline notes may get appended to rndr.notes.all while rendering */
2986 while(1){
2987 struct footnote *aNotes;
2988 const int N = COUNT_FOOTNOTES( allNotes );
2989
2990 /* make a shallow copy of `allNotes` */
2991 blob_truncate(notes,0);
2992 blob_appendb(notes, allNotes);
2993 aNotes = CAST_AS_FOOTNOTES(notes);
2994 qsort(aNotes, N, sizeof(struct footnote), cmp_footnote_sort);
2995
2996 if( --maxDepth < 0 || nMarks == rndr.notes.nMarks ) break;
2997 nMarks = rndr.notes.nMarks;
2998
2999 for(i=0; i<N; i++){
3000 const int j = aNotes[i].index;
3001 struct footnote *x = CAST_AS_FOOTNOTES(allNotes) + j;
3002 assert( 0<=j && j<N );
3003 if( x->bRndred || !x->nUsed ) continue;
3004 assert( x->iMark > 0 );
3005 assert( blob_size(&x->text) );
3006 blob_truncate(tmp,0);
3007
3008 /* `allNotes` may be altered and extended through this call */
3009 parse_inline(tmp, &rndr, blob_buffer(&x->text), blob_size(&x->text));
3010
3011 x = CAST_AS_FOOTNOTES(allNotes) + j;
3012 blob_truncate(&x->text,0);
3013 blob_appendb(&x->text, tmp);
3014 x->bRndred = 1;
3015 }
3016 }
3017 release_work_buffer(&rndr,tmp);
3018 }
3019
3020 /* footnotes rendering */
3021 if( rndr.make.footnote_item && rndr.make.footnotes ){
3022 Blob *all_items = new_work_buffer(&rndr);
3023 int j = -1;
3024
3025 /* Assert that the in-memory layout of id, text and upc within
3026 ** footnote struct matches the expectations of html_footnote_item()
3027 ** If it doesn't then a compiler has done something very weird.
3028 */
3029 assert( &(rndr.notes.misref.id) == &(rndr.notes.misref.text) - 1 );
3030 assert( &(rndr.notes.misref.upc) == &(rndr.notes.misref.text) + 1 );
3031
3032 for(i=0; i<COUNT_FOOTNOTES(notes); i++){
3033 const struct footnote* x = CAST_AS_FOOTNOTES(notes) + i;
3034 const int xUsed = x->bRndred ? x->nUsed : 0;
3035 if( !x->iMark ) break;
3036 assert( x->nUsed );
3037 rndr.make.footnote_item(all_items, &x->text, x->iMark,
3038 xUsed, rndr.make.opaque);
3039 if( !xUsed ) g.ftntsIssues[3]++; /* an overnested footnote */
3040 j = i;
3041 }
3042 if( rndr.notes.misref.nUsed ){
3043 rndr.make.footnote_item(all_items, 0, -1,
3044 rndr.notes.misref.nUsed, rndr.make.opaque);
3045 g.ftntsIssues[0] += rndr.notes.misref.nUsed;
3046 }
3047 while( ++j < COUNT_FOOTNOTES(notes) ){
3048 const struct footnote* x = CAST_AS_FOOTNOTES(notes) + j;
3049 assert( !x->iMark );
3050 assert( !x->nUsed );
3051 assert( !x->bRndred );
3052 rndr.make.footnote_item(all_items,&x->text,0,0,rndr.make.opaque);
3053 g.ftntsIssues[1]++;
3054 }
3055 rndr.make.footnotes(ob, all_items, rndr.make.opaque);
3056 release_work_buffer(&rndr, all_items);
3057 }
3058 release_work_buffer(&rndr, notes);
3059 }
3060 if( rndr.make.epilog ) rndr.make.epilog(ob, rndr.make.opaque);
3061
3062 /* clean-up */
3063 assert( rndr.iDepth==0 );
3064 blob_reset(&text);
@@ -2481,9 +3068,17 @@
3068 blob_reset(&lr[i].id);
3069 blob_reset(&lr[i].link);
3070 blob_reset(&lr[i].title);
3071 }
3072 blob_reset(&rndr.refs);
3073 fn = CAST_AS_FOOTNOTES( allNotes );
3074 end = COUNT_FOOTNOTES( allNotes );
3075 for(i=0; i<end; i++){
3076 if(blob_size(&fn[i].id)) blob_reset(&fn[i].id);
3077 if(blob_size(&fn[i].upc)) blob_reset(&fn[i].upc);
3078 blob_reset(&fn[i].text);
3079 }
3080 blob_reset(&rndr.notes.all);
3081 for(i=0; i<rndr.nBlobCache; i++){
3082 fossil_free(rndr.aBlobCache[i]);
3083 }
3084 }
3085
--- src/markdown.md
+++ src/markdown.md
@@ -152,10 +152,42 @@
152152
>
153153
~~~ pikchr
154154
oval "Start" fit; arrow; box "Hello, World!" fit; arrow; oval "Done" fit
155155
~~~
156156
157
+<a id="ftnts"></a>
158
+## Footnotes ##
159
+
160
+> Footnotes (or "endnotes") is a Fossil's extention of classical Markdown.
161
+> Fossil's syntax for footnotes is similar to links and
162
+> is distinguished by the use of character **^**
163
+> that *immediately* follows an opening bracket.
164
+
165
+> 1. **\(^** footnote's text **)**
166
+> 2. **\[** fragment of text **]\(^** a comment about that fragment **\)**
167
+> 3. **\[^**&nbsp;label&nbsp;**\]**
168
+> 4. **\[** fragment of text **\]\[^**&nbsp;label&nbsp;**\]**
169
+> 5. **\[** fragment of text **\]\[^\]**
170
+
171
+> With formats 1 and 2 ("inline footnotes") text of a footnote is provided
172
+> in the place where the corresponding numeric mark will be rendered.
173
+> With formats 3, 4, and 5 ("reference footnotes") text of a footnote
174
+> is supplied elsewhere in the document, as shown below.
175
+> Formats 2, 4 and 5 ("span-specific footnotes") mark a specific fragment
176
+> that is being commented in the footnote.
177
+> Format 5 reuses a fragment of text as a label.
178
+> Labels are case-insensitive.
179
+
180
+> ```
181
+> [^label]: Footnote definition must start on the first column.
182
+> The second line (if any) must be indented by two or more spaces.
183
+> Definition continues until indentation drops below that of the 2nd line.
184
+>```
185
+> Character **^** is not part of a label, it is part of the syntax.
186
+> Both a footnote's text and a fragment to which a footnote applies
187
+> are subject to further interpretation as Markdown sources.
188
+
157189
## Miscellaneous ##
158190
159191
> * In-line images are made using **\!\[alt-text\]\(image-URL\)**.
160192
> * Use HTML for advanced formatting such as forms.
161193
> * **\<!--** HTML-style comments **-->** are supported.
162194
--- src/markdown.md
+++ src/markdown.md
@@ -152,10 +152,42 @@
152 >
153 ~~~ pikchr
154 oval "Start" fit; arrow; box "Hello, World!" fit; arrow; oval "Done" fit
155 ~~~
156
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157 ## Miscellaneous ##
158
159 > * In-line images are made using **\!\[alt-text\]\(image-URL\)**.
160 > * Use HTML for advanced formatting such as forms.
161 > * **\<!--** HTML-style comments **-->** are supported.
162
--- src/markdown.md
+++ src/markdown.md
@@ -152,10 +152,42 @@
152 >
153 ~~~ pikchr
154 oval "Start" fit; arrow; box "Hello, World!" fit; arrow; oval "Done" fit
155 ~~~
156
157 <a id="ftnts"></a>
158 ## Footnotes ##
159
160 > Footnotes (or "endnotes") is a Fossil's extention of classical Markdown.
161 > Fossil's syntax for footnotes is similar to links and
162 > is distinguished by the use of character **^**
163 > that *immediately* follows an opening bracket.
164
165 > 1. **\(^** footnote's text **)**
166 > 2. **\[** fragment of text **]\(^** a comment about that fragment **\)**
167 > 3. **\[^**&nbsp;label&nbsp;**\]**
168 > 4. **\[** fragment of text **\]\[^**&nbsp;label&nbsp;**\]**
169 > 5. **\[** fragment of text **\]\[^\]**
170
171 > With formats 1 and 2 ("inline footnotes") text of a footnote is provided
172 > in the place where the corresponding numeric mark will be rendered.
173 > With formats 3, 4, and 5 ("reference footnotes") text of a footnote
174 > is supplied elsewhere in the document, as shown below.
175 > Formats 2, 4 and 5 ("span-specific footnotes") mark a specific fragment
176 > that is being commented in the footnote.
177 > Format 5 reuses a fragment of text as a label.
178 > Labels are case-insensitive.
179
180 > ```
181 > [^label]: Footnote definition must start on the first column.
182 > The second line (if any) must be indented by two or more spaces.
183 > Definition continues until indentation drops below that of the 2nd line.
184 >```
185 > Character **^** is not part of a label, it is part of the syntax.
186 > Both a footnote's text and a fragment to which a footnote applies
187 > are subject to further interpretation as Markdown sources.
188
189 ## Miscellaneous ##
190
191 > * In-line images are made using **\!\[alt-text\]\(image-URL\)**.
192 > * Use HTML for advanced formatting such as forms.
193 > * **\<!--** HTML-style comments **-->** are supported.
194
+362 -87
--- src/markdown_html.c
+++ src/markdown_html.c
@@ -29,37 +29,72 @@
2929
struct Blob *output_title,
3030
struct Blob *output_body);
3131
3232
#endif /* INTERFACE */
3333
34
+/*
35
+** Markdown-internal helper for generating unique link reference IDs.
36
+** Fields provide typed interpretation of the underline memory buffer.
37
+*/
38
+typedef union bitfield64_t bitfield64_t;
39
+union bitfield64_t{
40
+ char c[8]; /* interpret as the array of signed characters */
41
+ unsigned char b[8]; /* interpret as the array of unsigned characters */
42
+};
43
+
3444
/*
3545
** An instance of the following structure is passed through the
3646
** "opaque" pointer.
3747
*/
3848
typedef struct MarkdownToHtml MarkdownToHtml;
3949
struct MarkdownToHtml {
4050
Blob *output_title; /* Store the title here */
51
+ bitfield64_t unique; /* Enables construction of unique #id elements */
52
+
53
+ #ifndef FOOTNOTES_WITHOUT_URI
54
+ Blob reqURI; /* REQUEST_URI with escaped quotes */
55
+ #endif
4156
};
4257
4358
4459
/* INTER_BLOCK -- skip a line between block level elements */
4560
#define INTER_BLOCK(ob) \
4661
do { if( blob_size(ob)>0 ) blob_append_char(ob, '\n'); } while (0)
4762
48
-/* BLOB_APPEND_LITERAL -- append a string literal to a blob */
49
-#define BLOB_APPEND_LITERAL(blob, literal) \
50
- blob_append((blob), "" literal, (sizeof literal)-1)
51
- /*
52
- * The empty string in the second argument leads to a syntax error
53
- * when the macro is not used with a string literal. Unfortunately
54
- * the error is not overly explicit.
55
- */
56
-
57
-/* BLOB_APPEND_BLOB -- append blob contents to another */
58
-#define BLOB_APPEND_BLOB(dest, src) \
59
- blob_append((dest), blob_buffer(src), blob_size(src))
60
-
63
+/*
64
+** FOOTNOTES_WITHOUT_URI macro was introduced by [2c1f8f3592ef00e0]
65
+** to enable flexibility in rendering of footnote-specific hyperlinks.
66
+** It may be defined for a particular build in order to omit
67
+** full REQUEST_URIs within footnote-specific (and page-local) hyperlinks.
68
+** This *is* used for the builds that incorporate 'base-href-fix' branch
69
+** (which in turn fixes footnotes on the preview tab of /wikiedit page).
70
+*/
71
+#ifndef FOOTNOTES_WITHOUT_URI
72
+ #define BLOB_APPEND_URI(dest,ctx) blob_appendb(dest,&((ctx)->reqURI))
73
+#else
74
+ #define BLOB_APPEND_URI(dest,ctx)
75
+#endif
76
+
77
+/* Converts an integer to a textual base26 representation
78
+** with proper null-termination.
79
+ * Return empty string if that integer is negative. */
80
+static bitfield64_t to_base26(int i, int uppercase){
81
+ bitfield64_t x;
82
+ int j;
83
+ memset( &x, 0, sizeof(x) );
84
+ if( i >= 0 ){
85
+ for(j=7; j >= 0; j--){
86
+ x.b[j] = (unsigned char)(uppercase?'A':'a') + i%26;
87
+ if( (i /= 26) == 0 ) break;
88
+ }
89
+ assert( j > 0 ); /* because 2^32 < 26^7 */
90
+ for(i=0; i<8-j; i++) x.b[i] = x.b[i+j];
91
+ for( ; i<8 ; i++) x.b[i] = 0;
92
+ }
93
+ assert( x.c[7] == 0 );
94
+ return x;
95
+}
6196
6297
/* HTML escapes
6398
**
6499
** html_escape() converts < to &lt;, > to &gt;, and & to &amp;.
65100
** html_quote() goes further and converts " into &quot; and ' in &#39;.
@@ -78,19 +113,19 @@
78113
i++;
79114
}
80115
blob_append(ob, data+beg, i-beg);
81116
while( i<size ){
82117
if( data[i]=='<' ){
83
- BLOB_APPEND_LITERAL(ob, "&lt;");
118
+ blob_append_literal(ob, "&lt;");
84119
}else if( data[i]=='>' ){
85
- BLOB_APPEND_LITERAL(ob, "&gt;");
120
+ blob_append_literal(ob, "&gt;");
86121
}else if( data[i]=='&' ){
87
- BLOB_APPEND_LITERAL(ob, "&amp;");
122
+ blob_append_literal(ob, "&amp;");
88123
}else if( data[i]=='"' ){
89
- BLOB_APPEND_LITERAL(ob, "&quot;");
124
+ blob_append_literal(ob, "&quot;");
90125
}else if( data[i]=='\'' ){
91
- BLOB_APPEND_LITERAL(ob, "&#39;");
126
+ blob_append_literal(ob, "&#39;");
92127
}else{
93128
break;
94129
}
95130
i++;
96131
}
@@ -108,15 +143,15 @@
108143
i++;
109144
}
110145
blob_append(ob, data+beg, i-beg);
111146
while( i<size ){
112147
if( data[i]=='<' ){
113
- BLOB_APPEND_LITERAL(ob, "&lt;");
148
+ blob_append_literal(ob, "&lt;");
114149
}else if( data[i]=='>' ){
115
- BLOB_APPEND_LITERAL(ob, "&gt;");
150
+ blob_append_literal(ob, "&gt;");
116151
}else if( data[i]=='&' ){
117
- BLOB_APPEND_LITERAL(ob, "&amp;");
152
+ blob_append_literal(ob, "&amp;");
118153
}else{
119154
break;
120155
}
121156
i++;
122157
}
@@ -129,17 +164,17 @@
129164
/* Size of the prolog: "<div class='markdown'>\n" */
130165
#define PROLOG_SIZE 23
131166
132167
static void html_prolog(struct Blob *ob, void *opaque){
133168
INTER_BLOCK(ob);
134
- BLOB_APPEND_LITERAL(ob, "<div class=\"markdown\">\n");
169
+ blob_append_literal(ob, "<div class=\"markdown\">\n");
135170
assert( blob_size(ob)==PROLOG_SIZE );
136171
}
137172
138173
static void html_epilog(struct Blob *ob, void *opaque){
139174
INTER_BLOCK(ob);
140
- BLOB_APPEND_LITERAL(ob, "</div>\n");
175
+ blob_append_literal(ob, "</div>\n");
141176
}
142177
143178
static void html_blockhtml(struct Blob *ob, struct Blob *text, void *opaque){
144179
char *data = blob_buffer(text);
145180
size_t size = blob_size(text);
@@ -157,25 +192,25 @@
157192
blob_append(title, data+nTag, size - nTag - 5);
158193
return;
159194
}
160195
INTER_BLOCK(ob);
161196
blob_append(ob, data, size);
162
- BLOB_APPEND_LITERAL(ob, "\n");
197
+ blob_append_literal(ob, "\n");
163198
}
164199
165200
static void html_blockcode(struct Blob *ob, struct Blob *text, void *opaque){
166201
INTER_BLOCK(ob);
167
- BLOB_APPEND_LITERAL(ob, "<pre><code>");
202
+ blob_append_literal(ob, "<pre><code>");
168203
html_escape(ob, blob_buffer(text), blob_size(text));
169
- BLOB_APPEND_LITERAL(ob, "</code></pre>\n");
204
+ blob_append_literal(ob, "</code></pre>\n");
170205
}
171206
172207
static void html_blockquote(struct Blob *ob, struct Blob *text, void *opaque){
173208
INTER_BLOCK(ob);
174
- BLOB_APPEND_LITERAL(ob, "<blockquote>\n");
175
- BLOB_APPEND_BLOB(ob, text);
176
- BLOB_APPEND_LITERAL(ob, "</blockquote>\n");
209
+ blob_append_literal(ob, "<blockquote>\n");
210
+ blob_appendb(ob, text);
211
+ blob_append_literal(ob, "</blockquote>\n");
177212
}
178213
179214
static void html_header(
180215
struct Blob *ob,
181216
struct Blob *text,
@@ -184,22 +219,22 @@
184219
){
185220
struct Blob *title = ((MarkdownToHtml*)opaque)->output_title;
186221
/* The first header at the beginning of a text is considered as
187222
* a title and not output. */
188223
if( blob_size(ob)<=PROLOG_SIZE && title!=0 && blob_size(title)==0 ){
189
- BLOB_APPEND_BLOB(title, text);
224
+ blob_appendb(title, text);
190225
return;
191226
}
192227
INTER_BLOCK(ob);
193228
blob_appendf(ob, "<h%d>", level);
194
- BLOB_APPEND_BLOB(ob, text);
229
+ blob_appendb(ob, text);
195230
blob_appendf(ob, "</h%d>", level);
196231
}
197232
198233
static void html_hrule(struct Blob *ob, void *opaque){
199234
INTER_BLOCK(ob);
200
- BLOB_APPEND_LITERAL(ob, "<hr />\n");
235
+ blob_append_literal(ob, "<hr />\n");
201236
}
202237
203238
204239
static void html_list(
205240
struct Blob *ob,
@@ -210,11 +245,11 @@
210245
char ol[] = "ol";
211246
char ul[] = "ul";
212247
char *tag = (flags & MKD_LIST_ORDERED) ? ol : ul;
213248
INTER_BLOCK(ob);
214249
blob_appendf(ob, "<%s>\n", tag);
215
- BLOB_APPEND_BLOB(ob, text);
250
+ blob_appendb(ob, text);
216251
blob_appendf(ob, "</%s>\n", tag);
217252
}
218253
219254
static void html_list_item(
220255
struct Blob *ob,
@@ -223,20 +258,20 @@
223258
void *opaque
224259
){
225260
char *text_data = blob_buffer(text);
226261
size_t text_size = blob_size(text);
227262
while( text_size>0 && text_data[text_size-1]=='\n' ) text_size--;
228
- BLOB_APPEND_LITERAL(ob, "<li>");
263
+ blob_append_literal(ob, "<li>");
229264
blob_append(ob, text_data, text_size);
230
- BLOB_APPEND_LITERAL(ob, "</li>\n");
265
+ blob_append_literal(ob, "</li>\n");
231266
}
232267
233268
static void html_paragraph(struct Blob *ob, struct Blob *text, void *opaque){
234269
INTER_BLOCK(ob);
235
- BLOB_APPEND_LITERAL(ob, "<p>");
236
- BLOB_APPEND_BLOB(ob, text);
237
- BLOB_APPEND_LITERAL(ob, "</p>\n");
270
+ blob_append_literal(ob, "<p>");
271
+ blob_appendb(ob, text);
272
+ blob_append_literal(ob, "</p>\n");
238273
}
239274
240275
241276
static void html_table(
242277
struct Blob *ob,
@@ -243,71 +278,301 @@
243278
struct Blob *head_row,
244279
struct Blob *rows,
245280
void *opaque
246281
){
247282
INTER_BLOCK(ob);
248
- BLOB_APPEND_LITERAL(ob, "<table>\n");
283
+ blob_append_literal(ob, "<table>\n");
249284
if( head_row && blob_size(head_row)>0 ){
250
- BLOB_APPEND_LITERAL(ob, "<thead>\n");
251
- BLOB_APPEND_BLOB(ob, head_row);
252
- BLOB_APPEND_LITERAL(ob, "</thead>\n<tbody>\n");
285
+ blob_append_literal(ob, "<thead>\n");
286
+ blob_appendb(ob, head_row);
287
+ blob_append_literal(ob, "</thead>\n<tbody>\n");
253288
}
254289
if( rows ){
255
- BLOB_APPEND_BLOB(ob, rows);
290
+ blob_appendb(ob, rows);
256291
}
257292
if( head_row && blob_size(head_row)>0 ){
258
- BLOB_APPEND_LITERAL(ob, "</tbody>\n");
293
+ blob_append_literal(ob, "</tbody>\n");
259294
}
260
- BLOB_APPEND_LITERAL(ob, "</table>\n");
295
+ blob_append_literal(ob, "</table>\n");
261296
}
262297
263298
static void html_table_cell(
264299
struct Blob *ob,
265300
struct Blob *text,
266301
int flags,
267302
void *opaque
268303
){
269304
if( flags & MKD_CELL_HEAD ){
270
- BLOB_APPEND_LITERAL(ob, " <th");
305
+ blob_append_literal(ob, " <th");
271306
}else{
272
- BLOB_APPEND_LITERAL(ob, " <td");
307
+ blob_append_literal(ob, " <td");
273308
}
274309
switch( flags & MKD_CELL_ALIGN_MASK ){
275310
case MKD_CELL_ALIGN_LEFT: {
276
- BLOB_APPEND_LITERAL(ob, " align=\"left\"");
311
+ blob_append_literal(ob, " align=\"left\"");
277312
break;
278313
}
279314
case MKD_CELL_ALIGN_RIGHT: {
280
- BLOB_APPEND_LITERAL(ob, " align=\"right\"");
315
+ blob_append_literal(ob, " align=\"right\"");
281316
break;
282317
}
283318
case MKD_CELL_ALIGN_CENTER: {
284
- BLOB_APPEND_LITERAL(ob, " align=\"center\"");
319
+ blob_append_literal(ob, " align=\"center\"");
285320
break;
286321
}
287322
}
288
- BLOB_APPEND_LITERAL(ob, ">");
289
- BLOB_APPEND_BLOB(ob, text);
323
+ blob_append_literal(ob, ">");
324
+ blob_appendb(ob, text);
290325
if( flags & MKD_CELL_HEAD ){
291
- BLOB_APPEND_LITERAL(ob, "</th>\n");
326
+ blob_append_literal(ob, "</th>\n");
292327
}else{
293
- BLOB_APPEND_LITERAL(ob, "</td>\n");
328
+ blob_append_literal(ob, "</td>\n");
294329
}
295330
}
296331
297332
static void html_table_row(
298333
struct Blob *ob,
299334
struct Blob *cells,
300335
int flags,
301336
void *opaque
302337
){
303
- BLOB_APPEND_LITERAL(ob, " <tr>\n");
304
- BLOB_APPEND_BLOB(ob, cells);
305
- BLOB_APPEND_LITERAL(ob, " </tr>\n");
338
+ blob_append_literal(ob, " <tr>\n");
339
+ blob_appendb(ob, cells);
340
+ blob_append_literal(ob, " </tr>\n");
341
+}
342
+
343
+/*
344
+** Render a token of user provided classes.
345
+** If bHTML is true then render HTML for (presumably) visible text,
346
+** otherwise just a space-separated list of the derived classes.
347
+*/
348
+static void append_footnote_upc(
349
+ struct Blob *ob,
350
+ const struct Blob *upc, /* token of user-provided classes */
351
+ int bHTML
352
+){
353
+ const char *z = blob_buffer(upc);
354
+ int i, n = blob_size(upc);
355
+
356
+ if( n<3 ) return;
357
+ assert( z[0]=='.' && z[n-1] == ':' );
358
+ if( bHTML ){
359
+ blob_append_literal(ob, "<span class='fn-upc'>"
360
+ "<span class='fn-upcDot'>.</span>");
361
+ }
362
+ n = 0;
363
+ do{
364
+ z++;
365
+ if( *z!='.' && *z!=':' ){
366
+ assert( fossil_isalnum(*z) || *z=='-' );
367
+ n++;
368
+ continue;
369
+ }
370
+ assert( n );
371
+ if( bHTML ) blob_append_literal(ob, "<span class='");
372
+ blob_append_literal(ob, "fn-upc-");
373
+
374
+ for(i=-n; i<0; i++){
375
+ blob_append_char(ob, fossil_tolower(z[i]) );
376
+ }
377
+ if( bHTML ){
378
+ blob_append_literal(ob, "'>");
379
+ blob_append(ob, z-n, n);
380
+ blob_append_literal(ob, "</span>");
381
+ }else{
382
+ blob_append_char(ob, ' ');
383
+ }
384
+ n = 0;
385
+ if( bHTML ){
386
+ if( *z==':' ){
387
+ blob_append_literal(ob,"<span class='fn-upcColon'>:</span>");
388
+ }else{
389
+ blob_append_literal(ob,"<span class='fn-upcDot'>.</span>");
390
+ }
391
+ }
392
+ }while( *z != ':' );
393
+ if( bHTML ) blob_append_literal(ob,"</span>\n");
394
+}
395
+
396
+static int html_footnote_ref(
397
+ struct Blob *ob, const struct Blob *span, const struct Blob *upc,
398
+ int iMark, int locus, void *opaque
399
+){
400
+ const struct MarkdownToHtml* ctx = (struct MarkdownToHtml*)opaque;
401
+ const bitfield64_t l = to_base26(locus-1,0);
402
+ char pos[32];
403
+ memset(pos,0,32);
404
+ assert( locus > 0 );
405
+ /* expect BUGs if the following yields compiler warnings */
406
+ if( iMark > 0 ){ /* a regular reference to a footnote */
407
+ sprintf(pos, "%s-%d-%s", ctx->unique.c, iMark, l.c);
408
+ if(span && blob_size(span)) {
409
+ blob_append_literal(ob,"<span class='");
410
+ append_footnote_upc(ob, upc, 0);
411
+ blob_append_literal(ob,"notescope' id='noteref");
412
+ blob_appendf(ob,"%s'>",pos);
413
+ blob_appendb(ob, span);
414
+ blob_trim(ob);
415
+ blob_append_literal(ob,"<sup class='noteref'><a href='");
416
+ BLOB_APPEND_URI(ob, ctx);
417
+ blob_appendf(ob,"#footnote%s'>%d</a></sup></span>", pos, iMark);
418
+ }else{
419
+ blob_trim(ob);
420
+ blob_append_literal(ob,"<sup class='");
421
+ append_footnote_upc(ob, upc, 0);
422
+ blob_append_literal(ob,"noteref'><a href='");
423
+ BLOB_APPEND_URI(ob, ctx);
424
+ blob_appendf(ob,"#footnote%s' id='noteref%s'>%d</a></sup>",
425
+ pos, pos, iMark);
426
+ }
427
+ }else{ /* misreference */
428
+ assert( iMark == -1 );
429
+
430
+ sprintf(pos, "%s-%s", ctx->unique.c, l.c);
431
+ if(span && blob_size(span)) {
432
+ blob_appendf(ob, "<span class='notescope' id='misref%s'>", pos);
433
+ blob_appendb(ob, span);
434
+ blob_trim(ob);
435
+ blob_append_literal(ob, "<sup class='noteref misref'><a href='");
436
+ BLOB_APPEND_URI(ob, ctx);
437
+ blob_appendf(ob, "#misreference%s'>misref</a></sup></span>", pos);
438
+ }else{
439
+ blob_trim(ob);
440
+ blob_append_literal(ob, "<sup class='noteref misref'><a href='");
441
+ BLOB_APPEND_URI(ob, ctx);
442
+ blob_appendf(ob, "#misreference%s' id='misref%s'>", pos, pos);
443
+ blob_append_literal(ob, "misref</a></sup>");
444
+ }
445
+ }
446
+ return 1;
447
+}
448
+
449
+/* Render a single item of the footnotes list.
450
+ * Each backref gets a unique id to enable dynamic styling. */
451
+static void html_footnote_item(
452
+ struct Blob *ob, const struct Blob *text, int iMark, int nUsed, void *opaque
453
+){
454
+ const struct MarkdownToHtml* ctx = (struct MarkdownToHtml*)opaque;
455
+ const char * const unique = ctx->unique.c;
456
+ assert( nUsed >= 0 );
457
+ /* expect BUGs if the following yields compiler warnings */
458
+
459
+ if( iMark < 0 ){ /* misreferences */
460
+ assert( iMark == -1 );
461
+ assert( nUsed );
462
+ blob_append_literal(ob,"<li class='fn-misreference'>"
463
+ "<sup class='fn-backrefs'>");
464
+ if( nUsed == 1 ){
465
+ blob_appendf(ob,"<a id='misreference%s-a' href='", unique);
466
+ BLOB_APPEND_URI(ob, ctx);
467
+ blob_appendf(ob,"#misref%s-a'>^</a>", unique);
468
+ }else{
469
+ int i;
470
+ blob_append_char(ob, '^');
471
+ for(i=0; i<nUsed && i<26; i++){
472
+ const int c = i + (unsigned)'a';
473
+ blob_appendf(ob," <a id='misreference%s-%c' href='", unique,c);
474
+ BLOB_APPEND_URI(ob, ctx);
475
+ blob_appendf(ob,"#misref%s-%c'>%c</a>", unique,c, c);
476
+ }
477
+ if( i < nUsed ) blob_append_literal(ob," &hellip;");
478
+ }
479
+ blob_append_literal(ob,"</sup>\n<span>Misreference</span>");
480
+ }else if( iMark > 0 ){ /* regular, joined and overnested footnotes */
481
+ char pos[24];
482
+ int bJoin = 0;
483
+ #define _joined_footnote_indicator "<ul class='fn-joined'>"
484
+ #define _jfi_sz (sizeof(_joined_footnote_indicator)-1)
485
+ /* make.footnote_item() invocations should pass args accordingly */
486
+ const struct Blob *upc = text+1;
487
+ assert( text );
488
+ /* allow blob_size(text)==0 for constructs like [...](^ [] ()) */
489
+ memset(pos,0,24);
490
+ sprintf(pos, "%s-%d", unique, iMark);
491
+ blob_appendf(ob, "<li id='footnote%s' class='", pos);
492
+ if( nUsed ){
493
+ if( blob_size(text)>=_jfi_sz &&
494
+ !memcmp(blob_buffer(text),_joined_footnote_indicator,_jfi_sz)){
495
+ bJoin = 1;
496
+ blob_append_literal(ob, "fn-joined ");
497
+ }
498
+ append_footnote_upc(ob, upc, 0);
499
+ }else{
500
+ blob_append_literal(ob, "fn-toodeep ");
501
+ }
502
+ if( nUsed <= 1 ){
503
+ blob_append_literal(ob, "fn-monoref'><sup class='fn-backrefs'>");
504
+ blob_appendf(ob,"<a id='footnote%s-a' href='", pos);
505
+ BLOB_APPEND_URI(ob, ctx);
506
+ blob_appendf(ob,"#noteref%s-a'>^</a>", pos);
507
+ }else{
508
+ int i;
509
+ blob_append_literal(ob, "fn-polyref'><sup class='fn-backrefs'>^");
510
+ for(i=0; i<nUsed && i<26; i++){
511
+ const int c = i + (unsigned)'a';
512
+ blob_appendf(ob," <a id='footnote%s-%c' href='", pos,c);
513
+ BLOB_APPEND_URI(ob, ctx);
514
+ blob_appendf(ob,"#noteref%s-%c'>%c</a>", pos,c, c);
515
+ }
516
+ /* It's unlikely that so many backrefs will be usefull */
517
+ /* but maybe for some machine generated documents... */
518
+ for(; i<nUsed && i<676; i++){
519
+ const bitfield64_t l = to_base26(i,0);
520
+ blob_appendf(ob," <a id='footnote%s-%s' href='", pos, l.c);
521
+ BLOB_APPEND_URI(ob, ctx);
522
+ blob_appendf(ob,"#noteref%s-%s'>%s</a>", pos,l.c, l.c);
523
+ }
524
+ if( i < nUsed ) blob_append_literal(ob," &hellip;");
525
+ }
526
+ blob_append_literal(ob,"</sup>\n");
527
+ if( bJoin ){
528
+ blob_append_literal(ob,"<sup class='fn-joined'></sup><ul>");
529
+ blob_append(ob,blob_buffer(text)+_jfi_sz,blob_size(text)-_jfi_sz);
530
+ }else if( nUsed ){
531
+ append_footnote_upc(ob, upc, 1);
532
+ blob_appendb(ob, text);
533
+ }else{
534
+ blob_append_literal(ob,"<i></i>\n"
535
+ "<pre><code class='language-markdown'>");
536
+ if( blob_size(upc) ){
537
+ blob_appendb(ob, upc);
538
+ }
539
+ html_escape(ob, blob_buffer(text), blob_size(text));
540
+ blob_append_literal(ob,"</code></pre>");
541
+ }
542
+ #undef _joined_footnote_indicator
543
+ #undef _jfi_sz
544
+ }else{ /* a footnote was defined but wasn't referenced */
545
+ /* make.footnote_item() invocations should pass args accordingly */
546
+ const struct Blob *id = text-1, *upc = text+1;
547
+ assert( !nUsed );
548
+ assert( text );
549
+ assert( blob_size(text) );
550
+ assert( blob_size(id) );
551
+ blob_append_literal(ob,"<li class='fn-unreferenced'>\n[^&nbsp;<code>");
552
+ html_escape(ob, blob_buffer(id), blob_size(id));
553
+ blob_append_literal(ob, "</code>&nbsp;]<i></i>\n"
554
+ "<pre><code class='language-markdown'>");
555
+ if( blob_size(upc) ){
556
+ blob_appendb(ob, upc);
557
+ }
558
+ html_escape(ob, blob_buffer(text), blob_size(text));
559
+ blob_append_literal(ob,"</code></pre>");
560
+ }
561
+ blob_append_literal(ob, "\n</li>\n");
306562
}
307563
308
-
564
+static void html_footnotes(
565
+ struct Blob *ob, const struct Blob *items, void *opaque
566
+){
567
+ if( items && blob_size(items) ){
568
+ blob_append_literal(ob,
569
+ "\n<hr class='footnotes-separator'/>\n<ol class='footnotes'>\n");
570
+ blob_appendb(ob, items);
571
+ blob_append_literal(ob, "</ol>\n");
572
+ }
573
+}
309574
310575
/* HTML span tags */
311576
312577
static int html_raw_html_tag(struct Blob *ob, struct Blob *text, void *opaque){
313578
blob_append(ob, blob_buffer(text), blob_size(text));
@@ -319,21 +584,21 @@
319584
struct Blob *link,
320585
enum mkd_autolink type,
321586
void *opaque
322587
){
323588
if( !link || blob_size(link)<=0 ) return 0;
324
- BLOB_APPEND_LITERAL(ob, "<a href=\"");
325
- if( type==MKDA_IMPLICIT_EMAIL ) BLOB_APPEND_LITERAL(ob, "mailto:");
589
+ blob_append_literal(ob, "<a href=\"");
590
+ if( type==MKDA_IMPLICIT_EMAIL ) blob_append_literal(ob, "mailto:");
326591
html_quote(ob, blob_buffer(link), blob_size(link));
327
- BLOB_APPEND_LITERAL(ob, "\">");
592
+ blob_append_literal(ob, "\">");
328593
if( type==MKDA_EXPLICIT_EMAIL && blob_size(link)>7 ){
329594
/* remove "mailto:" from displayed text */
330595
html_escape(ob, blob_buffer(link)+7, blob_size(link)-7);
331596
}else{
332597
html_escape(ob, blob_buffer(link), blob_size(link));
333598
}
334
- BLOB_APPEND_LITERAL(ob, "</a>");
599
+ blob_append_literal(ob, "</a>");
335600
return 1;
336601
}
337602
338603
/*
339604
** The nSrc bytes at zSrc[] are Pikchr input text (allegedly). Process that
@@ -422,13 +687,13 @@
422687
){
423688
if( text==0 ){
424689
/* no-op */
425690
}else if( nSep<=2 ){
426691
/* One or two graves: an in-line code span */
427
- BLOB_APPEND_LITERAL(ob, "<code>");
692
+ blob_append_literal(ob, "<code>");
428693
html_escape(ob, blob_buffer(text), blob_size(text));
429
- BLOB_APPEND_LITERAL(ob, "</code>");
694
+ blob_append_literal(ob, "</code>");
430695
}else{
431696
/* Three or more graves: a fenced code block */
432697
int n = blob_size(text);
433698
const char *z = blob_buffer(text);
434699
int i;
@@ -460,25 +725,25 @@
460725
struct Blob *ob,
461726
struct Blob *text,
462727
char c,
463728
void *opaque
464729
){
465
- BLOB_APPEND_LITERAL(ob, "<strong>");
466
- BLOB_APPEND_BLOB(ob, text);
467
- BLOB_APPEND_LITERAL(ob, "</strong>");
730
+ blob_append_literal(ob, "<strong>");
731
+ blob_appendb(ob, text);
732
+ blob_append_literal(ob, "</strong>");
468733
return 1;
469734
}
470735
471736
static int html_emphasis(
472737
struct Blob *ob,
473738
struct Blob *text,
474739
char c,
475740
void *opaque
476741
){
477
- BLOB_APPEND_LITERAL(ob, "<em>");
478
- BLOB_APPEND_BLOB(ob, text);
479
- BLOB_APPEND_LITERAL(ob, "</em>");
742
+ blob_append_literal(ob, "<em>");
743
+ blob_appendb(ob, text);
744
+ blob_append_literal(ob, "</em>");
480745
return 1;
481746
}
482747
483748
static int html_image(
484749
struct Blob *ob,
@@ -485,24 +750,24 @@
485750
struct Blob *link,
486751
struct Blob *title,
487752
struct Blob *alt,
488753
void *opaque
489754
){
490
- BLOB_APPEND_LITERAL(ob, "<img src=\"");
755
+ blob_append_literal(ob, "<img src=\"");
491756
html_quote(ob, blob_buffer(link), blob_size(link));
492
- BLOB_APPEND_LITERAL(ob, "\" alt=\"");
757
+ blob_append_literal(ob, "\" alt=\"");
493758
html_quote(ob, blob_buffer(alt), blob_size(alt));
494759
if( title && blob_size(title)>0 ){
495
- BLOB_APPEND_LITERAL(ob, "\" title=\"");
760
+ blob_append_literal(ob, "\" title=\"");
496761
html_quote(ob, blob_buffer(title), blob_size(title));
497762
}
498
- BLOB_APPEND_LITERAL(ob, "\" />");
763
+ blob_append_literal(ob, "\" />");
499764
return 1;
500765
}
501766
502767
static int html_linebreak(struct Blob *ob, void *opaque){
503
- BLOB_APPEND_LITERAL(ob, "<br />\n");
768
+ blob_append_literal(ob, "<br />\n");
504769
return 1;
505770
}
506771
507772
static int html_link(
508773
struct Blob *ob,
@@ -523,23 +788,23 @@
523788
WIKI_MARKDOWNLINKS
524789
;
525790
wiki_resolve_hyperlink(ob, flags, zLink, zClose, sizeof(zClose), 0, zTitle);
526791
}
527792
if( blob_size(content)==0 ){
528
- if( link ) BLOB_APPEND_BLOB(ob, link);
793
+ if( link ) blob_appendb(ob, link);
529794
}else{
530
- BLOB_APPEND_BLOB(ob, content);
795
+ blob_appendb(ob, content);
531796
}
532797
blob_append(ob, zClose, -1);
533798
return 1;
534799
}
535800
536801
/* Invoked for @name and #tag tagged words, marked up in the
537802
** output text in a way that JS and CSS can do something
538803
** interesting with them. This isn't standard Markdown, so
539804
** it's implementation-specific what occurs here. More, each
540
-** Fossil feature using Markdown is free to apply markup and
805
+** Fossil feature using Markdown is free to apply styling and
541806
** behavior to these in feature-specific ways.
542807
*/
543808
static int html_tagspan(
544809
struct Blob *ob, /* Write the output here */
545810
struct Blob *text, /* The word after the tag character */
@@ -548,22 +813,22 @@
548813
){
549814
if( text==0 ){
550815
/* no-op */
551816
}else{
552817
char cPrefix = '!';
553
- BLOB_APPEND_LITERAL(ob, "<span data-");
818
+ blob_append_literal(ob, "<span data-");
554819
switch (type) {
555820
case MKDT_ATREF:
556
- cPrefix = '@'; BLOB_APPEND_LITERAL(ob, "atref"); break;
821
+ cPrefix = '@'; blob_append_literal(ob, "atref"); break;
557822
case MKDT_HASHTAG:
558
- cPrefix = '#'; BLOB_APPEND_LITERAL(ob, "hashtag"); break;
823
+ cPrefix = '#'; blob_append_literal(ob, "hashtag"); break;
559824
case MKDT_NUMTAG:
560
- cPrefix = '#'; BLOB_APPEND_LITERAL(ob, "numtag"); break;
825
+ cPrefix = '#'; blob_append_literal(ob, "numtag"); break;
561826
}
562
- BLOB_APPEND_LITERAL(ob, "=\"");
827
+ blob_append_literal(ob, "=\"");
563828
html_quote(ob, blob_buffer(text), blob_size(text));
564
- BLOB_APPEND_LITERAL(ob, "\"");
829
+ blob_append_literal(ob, "\"");
565830
blob_appendf(ob, ">%c%b</span>", cPrefix,text);
566831
}
567832
return 1;
568833
}
569834
@@ -571,13 +836,13 @@
571836
struct Blob *ob,
572837
struct Blob *text,
573838
char c,
574839
void *opaque
575840
){
576
- BLOB_APPEND_LITERAL(ob, "<strong><em>");
577
- BLOB_APPEND_BLOB(ob, text);
578
- BLOB_APPEND_LITERAL(ob, "</em></strong>");
841
+ blob_append_literal(ob, "<strong><em>");
842
+ blob_appendb(ob, text);
843
+ blob_append_literal(ob, "</em></strong>");
579844
return 1;
580845
}
581846
582847
583848
static void html_normal_text(struct Blob *ob, struct Blob *text, void *opaque){
@@ -597,10 +862,11 @@
597862
){
598863
struct mkd_renderer html_renderer = {
599864
/* prolog and epilog */
600865
html_prolog,
601866
html_epilog,
867
+ html_footnotes,
602868
603869
/* block level elements */
604870
html_blockcode,
605871
html_blockquote,
606872
html_blockhtml,
@@ -610,10 +876,11 @@
610876
html_list_item,
611877
html_paragraph,
612878
html_table,
613879
html_table_cell,
614880
html_table_row,
881
+ html_footnote_item,
615882
616883
/* span level elements */
617884
html_autolink,
618885
html_codespan,
619886
html_double_emphasis,
@@ -622,22 +889,30 @@
622889
html_linebreak,
623890
html_link,
624891
html_raw_html_tag,
625892
html_tagspan,
626893
html_triple_emphasis,
894
+ html_footnote_ref,
627895
628896
/* low level elements */
629897
0, /* entity */
630898
html_normal_text,
631899
632900
/* misc. parameters */
633901
"*_", /* emph_chars */
634902
0 /* opaque */
635903
};
904
+ static int invocation = -1; /* no marker for the first document */
905
+ static const char* zRU = 0; /* REQUEST_URI with escaped quotes */
636906
MarkdownToHtml context;
637907
memset(&context, 0, sizeof(context));
638908
context.output_title = output_title;
909
+ context.unique = to_base26(invocation++,1);
910
+ if( !zRU ) zRU = escape_quotes(PD("REQUEST_URI",""));
911
+ #ifndef FOOTNOTES_WITHOUT_URI
912
+ blob_set( &context.reqURI, zRU );
913
+ #endif
639914
html_renderer.opaque = &context;
640915
if( output_title ) blob_reset(output_title);
641916
blob_reset(output_body);
642917
markdown(output_body, input_markdown, &html_renderer);
643918
}
644919
--- src/markdown_html.c
+++ src/markdown_html.c
@@ -29,37 +29,72 @@
29 struct Blob *output_title,
30 struct Blob *output_body);
31
32 #endif /* INTERFACE */
33
 
 
 
 
 
 
 
 
 
 
34 /*
35 ** An instance of the following structure is passed through the
36 ** "opaque" pointer.
37 */
38 typedef struct MarkdownToHtml MarkdownToHtml;
39 struct MarkdownToHtml {
40 Blob *output_title; /* Store the title here */
 
 
 
 
 
41 };
42
43
44 /* INTER_BLOCK -- skip a line between block level elements */
45 #define INTER_BLOCK(ob) \
46 do { if( blob_size(ob)>0 ) blob_append_char(ob, '\n'); } while (0)
47
48 /* BLOB_APPEND_LITERAL -- append a string literal to a blob */
49 #define BLOB_APPEND_LITERAL(blob, literal) \
50 blob_append((blob), "" literal, (sizeof literal)-1)
51 /*
52 * The empty string in the second argument leads to a syntax error
53 * when the macro is not used with a string literal. Unfortunately
54 * the error is not overly explicit.
55 */
56
57 /* BLOB_APPEND_BLOB -- append blob contents to another */
58 #define BLOB_APPEND_BLOB(dest, src) \
59 blob_append((dest), blob_buffer(src), blob_size(src))
60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
62 /* HTML escapes
63 **
64 ** html_escape() converts < to &lt;, > to &gt;, and & to &amp;.
65 ** html_quote() goes further and converts " into &quot; and ' in &#39;.
@@ -78,19 +113,19 @@
78 i++;
79 }
80 blob_append(ob, data+beg, i-beg);
81 while( i<size ){
82 if( data[i]=='<' ){
83 BLOB_APPEND_LITERAL(ob, "&lt;");
84 }else if( data[i]=='>' ){
85 BLOB_APPEND_LITERAL(ob, "&gt;");
86 }else if( data[i]=='&' ){
87 BLOB_APPEND_LITERAL(ob, "&amp;");
88 }else if( data[i]=='"' ){
89 BLOB_APPEND_LITERAL(ob, "&quot;");
90 }else if( data[i]=='\'' ){
91 BLOB_APPEND_LITERAL(ob, "&#39;");
92 }else{
93 break;
94 }
95 i++;
96 }
@@ -108,15 +143,15 @@
108 i++;
109 }
110 blob_append(ob, data+beg, i-beg);
111 while( i<size ){
112 if( data[i]=='<' ){
113 BLOB_APPEND_LITERAL(ob, "&lt;");
114 }else if( data[i]=='>' ){
115 BLOB_APPEND_LITERAL(ob, "&gt;");
116 }else if( data[i]=='&' ){
117 BLOB_APPEND_LITERAL(ob, "&amp;");
118 }else{
119 break;
120 }
121 i++;
122 }
@@ -129,17 +164,17 @@
129 /* Size of the prolog: "<div class='markdown'>\n" */
130 #define PROLOG_SIZE 23
131
132 static void html_prolog(struct Blob *ob, void *opaque){
133 INTER_BLOCK(ob);
134 BLOB_APPEND_LITERAL(ob, "<div class=\"markdown\">\n");
135 assert( blob_size(ob)==PROLOG_SIZE );
136 }
137
138 static void html_epilog(struct Blob *ob, void *opaque){
139 INTER_BLOCK(ob);
140 BLOB_APPEND_LITERAL(ob, "</div>\n");
141 }
142
143 static void html_blockhtml(struct Blob *ob, struct Blob *text, void *opaque){
144 char *data = blob_buffer(text);
145 size_t size = blob_size(text);
@@ -157,25 +192,25 @@
157 blob_append(title, data+nTag, size - nTag - 5);
158 return;
159 }
160 INTER_BLOCK(ob);
161 blob_append(ob, data, size);
162 BLOB_APPEND_LITERAL(ob, "\n");
163 }
164
165 static void html_blockcode(struct Blob *ob, struct Blob *text, void *opaque){
166 INTER_BLOCK(ob);
167 BLOB_APPEND_LITERAL(ob, "<pre><code>");
168 html_escape(ob, blob_buffer(text), blob_size(text));
169 BLOB_APPEND_LITERAL(ob, "</code></pre>\n");
170 }
171
172 static void html_blockquote(struct Blob *ob, struct Blob *text, void *opaque){
173 INTER_BLOCK(ob);
174 BLOB_APPEND_LITERAL(ob, "<blockquote>\n");
175 BLOB_APPEND_BLOB(ob, text);
176 BLOB_APPEND_LITERAL(ob, "</blockquote>\n");
177 }
178
179 static void html_header(
180 struct Blob *ob,
181 struct Blob *text,
@@ -184,22 +219,22 @@
184 ){
185 struct Blob *title = ((MarkdownToHtml*)opaque)->output_title;
186 /* The first header at the beginning of a text is considered as
187 * a title and not output. */
188 if( blob_size(ob)<=PROLOG_SIZE && title!=0 && blob_size(title)==0 ){
189 BLOB_APPEND_BLOB(title, text);
190 return;
191 }
192 INTER_BLOCK(ob);
193 blob_appendf(ob, "<h%d>", level);
194 BLOB_APPEND_BLOB(ob, text);
195 blob_appendf(ob, "</h%d>", level);
196 }
197
198 static void html_hrule(struct Blob *ob, void *opaque){
199 INTER_BLOCK(ob);
200 BLOB_APPEND_LITERAL(ob, "<hr />\n");
201 }
202
203
204 static void html_list(
205 struct Blob *ob,
@@ -210,11 +245,11 @@
210 char ol[] = "ol";
211 char ul[] = "ul";
212 char *tag = (flags & MKD_LIST_ORDERED) ? ol : ul;
213 INTER_BLOCK(ob);
214 blob_appendf(ob, "<%s>\n", tag);
215 BLOB_APPEND_BLOB(ob, text);
216 blob_appendf(ob, "</%s>\n", tag);
217 }
218
219 static void html_list_item(
220 struct Blob *ob,
@@ -223,20 +258,20 @@
223 void *opaque
224 ){
225 char *text_data = blob_buffer(text);
226 size_t text_size = blob_size(text);
227 while( text_size>0 && text_data[text_size-1]=='\n' ) text_size--;
228 BLOB_APPEND_LITERAL(ob, "<li>");
229 blob_append(ob, text_data, text_size);
230 BLOB_APPEND_LITERAL(ob, "</li>\n");
231 }
232
233 static void html_paragraph(struct Blob *ob, struct Blob *text, void *opaque){
234 INTER_BLOCK(ob);
235 BLOB_APPEND_LITERAL(ob, "<p>");
236 BLOB_APPEND_BLOB(ob, text);
237 BLOB_APPEND_LITERAL(ob, "</p>\n");
238 }
239
240
241 static void html_table(
242 struct Blob *ob,
@@ -243,71 +278,301 @@
243 struct Blob *head_row,
244 struct Blob *rows,
245 void *opaque
246 ){
247 INTER_BLOCK(ob);
248 BLOB_APPEND_LITERAL(ob, "<table>\n");
249 if( head_row && blob_size(head_row)>0 ){
250 BLOB_APPEND_LITERAL(ob, "<thead>\n");
251 BLOB_APPEND_BLOB(ob, head_row);
252 BLOB_APPEND_LITERAL(ob, "</thead>\n<tbody>\n");
253 }
254 if( rows ){
255 BLOB_APPEND_BLOB(ob, rows);
256 }
257 if( head_row && blob_size(head_row)>0 ){
258 BLOB_APPEND_LITERAL(ob, "</tbody>\n");
259 }
260 BLOB_APPEND_LITERAL(ob, "</table>\n");
261 }
262
263 static void html_table_cell(
264 struct Blob *ob,
265 struct Blob *text,
266 int flags,
267 void *opaque
268 ){
269 if( flags & MKD_CELL_HEAD ){
270 BLOB_APPEND_LITERAL(ob, " <th");
271 }else{
272 BLOB_APPEND_LITERAL(ob, " <td");
273 }
274 switch( flags & MKD_CELL_ALIGN_MASK ){
275 case MKD_CELL_ALIGN_LEFT: {
276 BLOB_APPEND_LITERAL(ob, " align=\"left\"");
277 break;
278 }
279 case MKD_CELL_ALIGN_RIGHT: {
280 BLOB_APPEND_LITERAL(ob, " align=\"right\"");
281 break;
282 }
283 case MKD_CELL_ALIGN_CENTER: {
284 BLOB_APPEND_LITERAL(ob, " align=\"center\"");
285 break;
286 }
287 }
288 BLOB_APPEND_LITERAL(ob, ">");
289 BLOB_APPEND_BLOB(ob, text);
290 if( flags & MKD_CELL_HEAD ){
291 BLOB_APPEND_LITERAL(ob, "</th>\n");
292 }else{
293 BLOB_APPEND_LITERAL(ob, "</td>\n");
294 }
295 }
296
297 static void html_table_row(
298 struct Blob *ob,
299 struct Blob *cells,
300 int flags,
301 void *opaque
302 ){
303 BLOB_APPEND_LITERAL(ob, " <tr>\n");
304 BLOB_APPEND_BLOB(ob, cells);
305 BLOB_APPEND_LITERAL(ob, " </tr>\n");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
306 }
307
308
 
 
 
 
 
 
 
 
 
309
310 /* HTML span tags */
311
312 static int html_raw_html_tag(struct Blob *ob, struct Blob *text, void *opaque){
313 blob_append(ob, blob_buffer(text), blob_size(text));
@@ -319,21 +584,21 @@
319 struct Blob *link,
320 enum mkd_autolink type,
321 void *opaque
322 ){
323 if( !link || blob_size(link)<=0 ) return 0;
324 BLOB_APPEND_LITERAL(ob, "<a href=\"");
325 if( type==MKDA_IMPLICIT_EMAIL ) BLOB_APPEND_LITERAL(ob, "mailto:");
326 html_quote(ob, blob_buffer(link), blob_size(link));
327 BLOB_APPEND_LITERAL(ob, "\">");
328 if( type==MKDA_EXPLICIT_EMAIL && blob_size(link)>7 ){
329 /* remove "mailto:" from displayed text */
330 html_escape(ob, blob_buffer(link)+7, blob_size(link)-7);
331 }else{
332 html_escape(ob, blob_buffer(link), blob_size(link));
333 }
334 BLOB_APPEND_LITERAL(ob, "</a>");
335 return 1;
336 }
337
338 /*
339 ** The nSrc bytes at zSrc[] are Pikchr input text (allegedly). Process that
@@ -422,13 +687,13 @@
422 ){
423 if( text==0 ){
424 /* no-op */
425 }else if( nSep<=2 ){
426 /* One or two graves: an in-line code span */
427 BLOB_APPEND_LITERAL(ob, "<code>");
428 html_escape(ob, blob_buffer(text), blob_size(text));
429 BLOB_APPEND_LITERAL(ob, "</code>");
430 }else{
431 /* Three or more graves: a fenced code block */
432 int n = blob_size(text);
433 const char *z = blob_buffer(text);
434 int i;
@@ -460,25 +725,25 @@
460 struct Blob *ob,
461 struct Blob *text,
462 char c,
463 void *opaque
464 ){
465 BLOB_APPEND_LITERAL(ob, "<strong>");
466 BLOB_APPEND_BLOB(ob, text);
467 BLOB_APPEND_LITERAL(ob, "</strong>");
468 return 1;
469 }
470
471 static int html_emphasis(
472 struct Blob *ob,
473 struct Blob *text,
474 char c,
475 void *opaque
476 ){
477 BLOB_APPEND_LITERAL(ob, "<em>");
478 BLOB_APPEND_BLOB(ob, text);
479 BLOB_APPEND_LITERAL(ob, "</em>");
480 return 1;
481 }
482
483 static int html_image(
484 struct Blob *ob,
@@ -485,24 +750,24 @@
485 struct Blob *link,
486 struct Blob *title,
487 struct Blob *alt,
488 void *opaque
489 ){
490 BLOB_APPEND_LITERAL(ob, "<img src=\"");
491 html_quote(ob, blob_buffer(link), blob_size(link));
492 BLOB_APPEND_LITERAL(ob, "\" alt=\"");
493 html_quote(ob, blob_buffer(alt), blob_size(alt));
494 if( title && blob_size(title)>0 ){
495 BLOB_APPEND_LITERAL(ob, "\" title=\"");
496 html_quote(ob, blob_buffer(title), blob_size(title));
497 }
498 BLOB_APPEND_LITERAL(ob, "\" />");
499 return 1;
500 }
501
502 static int html_linebreak(struct Blob *ob, void *opaque){
503 BLOB_APPEND_LITERAL(ob, "<br />\n");
504 return 1;
505 }
506
507 static int html_link(
508 struct Blob *ob,
@@ -523,23 +788,23 @@
523 WIKI_MARKDOWNLINKS
524 ;
525 wiki_resolve_hyperlink(ob, flags, zLink, zClose, sizeof(zClose), 0, zTitle);
526 }
527 if( blob_size(content)==0 ){
528 if( link ) BLOB_APPEND_BLOB(ob, link);
529 }else{
530 BLOB_APPEND_BLOB(ob, content);
531 }
532 blob_append(ob, zClose, -1);
533 return 1;
534 }
535
536 /* Invoked for @name and #tag tagged words, marked up in the
537 ** output text in a way that JS and CSS can do something
538 ** interesting with them. This isn't standard Markdown, so
539 ** it's implementation-specific what occurs here. More, each
540 ** Fossil feature using Markdown is free to apply markup and
541 ** behavior to these in feature-specific ways.
542 */
543 static int html_tagspan(
544 struct Blob *ob, /* Write the output here */
545 struct Blob *text, /* The word after the tag character */
@@ -548,22 +813,22 @@
548 ){
549 if( text==0 ){
550 /* no-op */
551 }else{
552 char cPrefix = '!';
553 BLOB_APPEND_LITERAL(ob, "<span data-");
554 switch (type) {
555 case MKDT_ATREF:
556 cPrefix = '@'; BLOB_APPEND_LITERAL(ob, "atref"); break;
557 case MKDT_HASHTAG:
558 cPrefix = '#'; BLOB_APPEND_LITERAL(ob, "hashtag"); break;
559 case MKDT_NUMTAG:
560 cPrefix = '#'; BLOB_APPEND_LITERAL(ob, "numtag"); break;
561 }
562 BLOB_APPEND_LITERAL(ob, "=\"");
563 html_quote(ob, blob_buffer(text), blob_size(text));
564 BLOB_APPEND_LITERAL(ob, "\"");
565 blob_appendf(ob, ">%c%b</span>", cPrefix,text);
566 }
567 return 1;
568 }
569
@@ -571,13 +836,13 @@
571 struct Blob *ob,
572 struct Blob *text,
573 char c,
574 void *opaque
575 ){
576 BLOB_APPEND_LITERAL(ob, "<strong><em>");
577 BLOB_APPEND_BLOB(ob, text);
578 BLOB_APPEND_LITERAL(ob, "</em></strong>");
579 return 1;
580 }
581
582
583 static void html_normal_text(struct Blob *ob, struct Blob *text, void *opaque){
@@ -597,10 +862,11 @@
597 ){
598 struct mkd_renderer html_renderer = {
599 /* prolog and epilog */
600 html_prolog,
601 html_epilog,
 
602
603 /* block level elements */
604 html_blockcode,
605 html_blockquote,
606 html_blockhtml,
@@ -610,10 +876,11 @@
610 html_list_item,
611 html_paragraph,
612 html_table,
613 html_table_cell,
614 html_table_row,
 
615
616 /* span level elements */
617 html_autolink,
618 html_codespan,
619 html_double_emphasis,
@@ -622,22 +889,30 @@
622 html_linebreak,
623 html_link,
624 html_raw_html_tag,
625 html_tagspan,
626 html_triple_emphasis,
 
627
628 /* low level elements */
629 0, /* entity */
630 html_normal_text,
631
632 /* misc. parameters */
633 "*_", /* emph_chars */
634 0 /* opaque */
635 };
 
 
636 MarkdownToHtml context;
637 memset(&context, 0, sizeof(context));
638 context.output_title = output_title;
 
 
 
 
 
639 html_renderer.opaque = &context;
640 if( output_title ) blob_reset(output_title);
641 blob_reset(output_body);
642 markdown(output_body, input_markdown, &html_renderer);
643 }
644
--- src/markdown_html.c
+++ src/markdown_html.c
@@ -29,37 +29,72 @@
29 struct Blob *output_title,
30 struct Blob *output_body);
31
32 #endif /* INTERFACE */
33
34 /*
35 ** Markdown-internal helper for generating unique link reference IDs.
36 ** Fields provide typed interpretation of the underline memory buffer.
37 */
38 typedef union bitfield64_t bitfield64_t;
39 union bitfield64_t{
40 char c[8]; /* interpret as the array of signed characters */
41 unsigned char b[8]; /* interpret as the array of unsigned characters */
42 };
43
44 /*
45 ** An instance of the following structure is passed through the
46 ** "opaque" pointer.
47 */
48 typedef struct MarkdownToHtml MarkdownToHtml;
49 struct MarkdownToHtml {
50 Blob *output_title; /* Store the title here */
51 bitfield64_t unique; /* Enables construction of unique #id elements */
52
53 #ifndef FOOTNOTES_WITHOUT_URI
54 Blob reqURI; /* REQUEST_URI with escaped quotes */
55 #endif
56 };
57
58
59 /* INTER_BLOCK -- skip a line between block level elements */
60 #define INTER_BLOCK(ob) \
61 do { if( blob_size(ob)>0 ) blob_append_char(ob, '\n'); } while (0)
62
63 /*
64 ** FOOTNOTES_WITHOUT_URI macro was introduced by [2c1f8f3592ef00e0]
65 ** to enable flexibility in rendering of footnote-specific hyperlinks.
66 ** It may be defined for a particular build in order to omit
67 ** full REQUEST_URIs within footnote-specific (and page-local) hyperlinks.
68 ** This *is* used for the builds that incorporate 'base-href-fix' branch
69 ** (which in turn fixes footnotes on the preview tab of /wikiedit page).
70 */
71 #ifndef FOOTNOTES_WITHOUT_URI
72 #define BLOB_APPEND_URI(dest,ctx) blob_appendb(dest,&((ctx)->reqURI))
73 #else
74 #define BLOB_APPEND_URI(dest,ctx)
75 #endif
76
77 /* Converts an integer to a textual base26 representation
78 ** with proper null-termination.
79 * Return empty string if that integer is negative. */
80 static bitfield64_t to_base26(int i, int uppercase){
81 bitfield64_t x;
82 int j;
83 memset( &x, 0, sizeof(x) );
84 if( i >= 0 ){
85 for(j=7; j >= 0; j--){
86 x.b[j] = (unsigned char)(uppercase?'A':'a') + i%26;
87 if( (i /= 26) == 0 ) break;
88 }
89 assert( j > 0 ); /* because 2^32 < 26^7 */
90 for(i=0; i<8-j; i++) x.b[i] = x.b[i+j];
91 for( ; i<8 ; i++) x.b[i] = 0;
92 }
93 assert( x.c[7] == 0 );
94 return x;
95 }
96
97 /* HTML escapes
98 **
99 ** html_escape() converts < to &lt;, > to &gt;, and & to &amp;.
100 ** html_quote() goes further and converts " into &quot; and ' in &#39;.
@@ -78,19 +113,19 @@
113 i++;
114 }
115 blob_append(ob, data+beg, i-beg);
116 while( i<size ){
117 if( data[i]=='<' ){
118 blob_append_literal(ob, "&lt;");
119 }else if( data[i]=='>' ){
120 blob_append_literal(ob, "&gt;");
121 }else if( data[i]=='&' ){
122 blob_append_literal(ob, "&amp;");
123 }else if( data[i]=='"' ){
124 blob_append_literal(ob, "&quot;");
125 }else if( data[i]=='\'' ){
126 blob_append_literal(ob, "&#39;");
127 }else{
128 break;
129 }
130 i++;
131 }
@@ -108,15 +143,15 @@
143 i++;
144 }
145 blob_append(ob, data+beg, i-beg);
146 while( i<size ){
147 if( data[i]=='<' ){
148 blob_append_literal(ob, "&lt;");
149 }else if( data[i]=='>' ){
150 blob_append_literal(ob, "&gt;");
151 }else if( data[i]=='&' ){
152 blob_append_literal(ob, "&amp;");
153 }else{
154 break;
155 }
156 i++;
157 }
@@ -129,17 +164,17 @@
164 /* Size of the prolog: "<div class='markdown'>\n" */
165 #define PROLOG_SIZE 23
166
167 static void html_prolog(struct Blob *ob, void *opaque){
168 INTER_BLOCK(ob);
169 blob_append_literal(ob, "<div class=\"markdown\">\n");
170 assert( blob_size(ob)==PROLOG_SIZE );
171 }
172
173 static void html_epilog(struct Blob *ob, void *opaque){
174 INTER_BLOCK(ob);
175 blob_append_literal(ob, "</div>\n");
176 }
177
178 static void html_blockhtml(struct Blob *ob, struct Blob *text, void *opaque){
179 char *data = blob_buffer(text);
180 size_t size = blob_size(text);
@@ -157,25 +192,25 @@
192 blob_append(title, data+nTag, size - nTag - 5);
193 return;
194 }
195 INTER_BLOCK(ob);
196 blob_append(ob, data, size);
197 blob_append_literal(ob, "\n");
198 }
199
200 static void html_blockcode(struct Blob *ob, struct Blob *text, void *opaque){
201 INTER_BLOCK(ob);
202 blob_append_literal(ob, "<pre><code>");
203 html_escape(ob, blob_buffer(text), blob_size(text));
204 blob_append_literal(ob, "</code></pre>\n");
205 }
206
207 static void html_blockquote(struct Blob *ob, struct Blob *text, void *opaque){
208 INTER_BLOCK(ob);
209 blob_append_literal(ob, "<blockquote>\n");
210 blob_appendb(ob, text);
211 blob_append_literal(ob, "</blockquote>\n");
212 }
213
214 static void html_header(
215 struct Blob *ob,
216 struct Blob *text,
@@ -184,22 +219,22 @@
219 ){
220 struct Blob *title = ((MarkdownToHtml*)opaque)->output_title;
221 /* The first header at the beginning of a text is considered as
222 * a title and not output. */
223 if( blob_size(ob)<=PROLOG_SIZE && title!=0 && blob_size(title)==0 ){
224 blob_appendb(title, text);
225 return;
226 }
227 INTER_BLOCK(ob);
228 blob_appendf(ob, "<h%d>", level);
229 blob_appendb(ob, text);
230 blob_appendf(ob, "</h%d>", level);
231 }
232
233 static void html_hrule(struct Blob *ob, void *opaque){
234 INTER_BLOCK(ob);
235 blob_append_literal(ob, "<hr />\n");
236 }
237
238
239 static void html_list(
240 struct Blob *ob,
@@ -210,11 +245,11 @@
245 char ol[] = "ol";
246 char ul[] = "ul";
247 char *tag = (flags & MKD_LIST_ORDERED) ? ol : ul;
248 INTER_BLOCK(ob);
249 blob_appendf(ob, "<%s>\n", tag);
250 blob_appendb(ob, text);
251 blob_appendf(ob, "</%s>\n", tag);
252 }
253
254 static void html_list_item(
255 struct Blob *ob,
@@ -223,20 +258,20 @@
258 void *opaque
259 ){
260 char *text_data = blob_buffer(text);
261 size_t text_size = blob_size(text);
262 while( text_size>0 && text_data[text_size-1]=='\n' ) text_size--;
263 blob_append_literal(ob, "<li>");
264 blob_append(ob, text_data, text_size);
265 blob_append_literal(ob, "</li>\n");
266 }
267
268 static void html_paragraph(struct Blob *ob, struct Blob *text, void *opaque){
269 INTER_BLOCK(ob);
270 blob_append_literal(ob, "<p>");
271 blob_appendb(ob, text);
272 blob_append_literal(ob, "</p>\n");
273 }
274
275
276 static void html_table(
277 struct Blob *ob,
@@ -243,71 +278,301 @@
278 struct Blob *head_row,
279 struct Blob *rows,
280 void *opaque
281 ){
282 INTER_BLOCK(ob);
283 blob_append_literal(ob, "<table>\n");
284 if( head_row && blob_size(head_row)>0 ){
285 blob_append_literal(ob, "<thead>\n");
286 blob_appendb(ob, head_row);
287 blob_append_literal(ob, "</thead>\n<tbody>\n");
288 }
289 if( rows ){
290 blob_appendb(ob, rows);
291 }
292 if( head_row && blob_size(head_row)>0 ){
293 blob_append_literal(ob, "</tbody>\n");
294 }
295 blob_append_literal(ob, "</table>\n");
296 }
297
298 static void html_table_cell(
299 struct Blob *ob,
300 struct Blob *text,
301 int flags,
302 void *opaque
303 ){
304 if( flags & MKD_CELL_HEAD ){
305 blob_append_literal(ob, " <th");
306 }else{
307 blob_append_literal(ob, " <td");
308 }
309 switch( flags & MKD_CELL_ALIGN_MASK ){
310 case MKD_CELL_ALIGN_LEFT: {
311 blob_append_literal(ob, " align=\"left\"");
312 break;
313 }
314 case MKD_CELL_ALIGN_RIGHT: {
315 blob_append_literal(ob, " align=\"right\"");
316 break;
317 }
318 case MKD_CELL_ALIGN_CENTER: {
319 blob_append_literal(ob, " align=\"center\"");
320 break;
321 }
322 }
323 blob_append_literal(ob, ">");
324 blob_appendb(ob, text);
325 if( flags & MKD_CELL_HEAD ){
326 blob_append_literal(ob, "</th>\n");
327 }else{
328 blob_append_literal(ob, "</td>\n");
329 }
330 }
331
332 static void html_table_row(
333 struct Blob *ob,
334 struct Blob *cells,
335 int flags,
336 void *opaque
337 ){
338 blob_append_literal(ob, " <tr>\n");
339 blob_appendb(ob, cells);
340 blob_append_literal(ob, " </tr>\n");
341 }
342
343 /*
344 ** Render a token of user provided classes.
345 ** If bHTML is true then render HTML for (presumably) visible text,
346 ** otherwise just a space-separated list of the derived classes.
347 */
348 static void append_footnote_upc(
349 struct Blob *ob,
350 const struct Blob *upc, /* token of user-provided classes */
351 int bHTML
352 ){
353 const char *z = blob_buffer(upc);
354 int i, n = blob_size(upc);
355
356 if( n<3 ) return;
357 assert( z[0]=='.' && z[n-1] == ':' );
358 if( bHTML ){
359 blob_append_literal(ob, "<span class='fn-upc'>"
360 "<span class='fn-upcDot'>.</span>");
361 }
362 n = 0;
363 do{
364 z++;
365 if( *z!='.' && *z!=':' ){
366 assert( fossil_isalnum(*z) || *z=='-' );
367 n++;
368 continue;
369 }
370 assert( n );
371 if( bHTML ) blob_append_literal(ob, "<span class='");
372 blob_append_literal(ob, "fn-upc-");
373
374 for(i=-n; i<0; i++){
375 blob_append_char(ob, fossil_tolower(z[i]) );
376 }
377 if( bHTML ){
378 blob_append_literal(ob, "'>");
379 blob_append(ob, z-n, n);
380 blob_append_literal(ob, "</span>");
381 }else{
382 blob_append_char(ob, ' ');
383 }
384 n = 0;
385 if( bHTML ){
386 if( *z==':' ){
387 blob_append_literal(ob,"<span class='fn-upcColon'>:</span>");
388 }else{
389 blob_append_literal(ob,"<span class='fn-upcDot'>.</span>");
390 }
391 }
392 }while( *z != ':' );
393 if( bHTML ) blob_append_literal(ob,"</span>\n");
394 }
395
396 static int html_footnote_ref(
397 struct Blob *ob, const struct Blob *span, const struct Blob *upc,
398 int iMark, int locus, void *opaque
399 ){
400 const struct MarkdownToHtml* ctx = (struct MarkdownToHtml*)opaque;
401 const bitfield64_t l = to_base26(locus-1,0);
402 char pos[32];
403 memset(pos,0,32);
404 assert( locus > 0 );
405 /* expect BUGs if the following yields compiler warnings */
406 if( iMark > 0 ){ /* a regular reference to a footnote */
407 sprintf(pos, "%s-%d-%s", ctx->unique.c, iMark, l.c);
408 if(span && blob_size(span)) {
409 blob_append_literal(ob,"<span class='");
410 append_footnote_upc(ob, upc, 0);
411 blob_append_literal(ob,"notescope' id='noteref");
412 blob_appendf(ob,"%s'>",pos);
413 blob_appendb(ob, span);
414 blob_trim(ob);
415 blob_append_literal(ob,"<sup class='noteref'><a href='");
416 BLOB_APPEND_URI(ob, ctx);
417 blob_appendf(ob,"#footnote%s'>%d</a></sup></span>", pos, iMark);
418 }else{
419 blob_trim(ob);
420 blob_append_literal(ob,"<sup class='");
421 append_footnote_upc(ob, upc, 0);
422 blob_append_literal(ob,"noteref'><a href='");
423 BLOB_APPEND_URI(ob, ctx);
424 blob_appendf(ob,"#footnote%s' id='noteref%s'>%d</a></sup>",
425 pos, pos, iMark);
426 }
427 }else{ /* misreference */
428 assert( iMark == -1 );
429
430 sprintf(pos, "%s-%s", ctx->unique.c, l.c);
431 if(span && blob_size(span)) {
432 blob_appendf(ob, "<span class='notescope' id='misref%s'>", pos);
433 blob_appendb(ob, span);
434 blob_trim(ob);
435 blob_append_literal(ob, "<sup class='noteref misref'><a href='");
436 BLOB_APPEND_URI(ob, ctx);
437 blob_appendf(ob, "#misreference%s'>misref</a></sup></span>", pos);
438 }else{
439 blob_trim(ob);
440 blob_append_literal(ob, "<sup class='noteref misref'><a href='");
441 BLOB_APPEND_URI(ob, ctx);
442 blob_appendf(ob, "#misreference%s' id='misref%s'>", pos, pos);
443 blob_append_literal(ob, "misref</a></sup>");
444 }
445 }
446 return 1;
447 }
448
449 /* Render a single item of the footnotes list.
450 * Each backref gets a unique id to enable dynamic styling. */
451 static void html_footnote_item(
452 struct Blob *ob, const struct Blob *text, int iMark, int nUsed, void *opaque
453 ){
454 const struct MarkdownToHtml* ctx = (struct MarkdownToHtml*)opaque;
455 const char * const unique = ctx->unique.c;
456 assert( nUsed >= 0 );
457 /* expect BUGs if the following yields compiler warnings */
458
459 if( iMark < 0 ){ /* misreferences */
460 assert( iMark == -1 );
461 assert( nUsed );
462 blob_append_literal(ob,"<li class='fn-misreference'>"
463 "<sup class='fn-backrefs'>");
464 if( nUsed == 1 ){
465 blob_appendf(ob,"<a id='misreference%s-a' href='", unique);
466 BLOB_APPEND_URI(ob, ctx);
467 blob_appendf(ob,"#misref%s-a'>^</a>", unique);
468 }else{
469 int i;
470 blob_append_char(ob, '^');
471 for(i=0; i<nUsed && i<26; i++){
472 const int c = i + (unsigned)'a';
473 blob_appendf(ob," <a id='misreference%s-%c' href='", unique,c);
474 BLOB_APPEND_URI(ob, ctx);
475 blob_appendf(ob,"#misref%s-%c'>%c</a>", unique,c, c);
476 }
477 if( i < nUsed ) blob_append_literal(ob," &hellip;");
478 }
479 blob_append_literal(ob,"</sup>\n<span>Misreference</span>");
480 }else if( iMark > 0 ){ /* regular, joined and overnested footnotes */
481 char pos[24];
482 int bJoin = 0;
483 #define _joined_footnote_indicator "<ul class='fn-joined'>"
484 #define _jfi_sz (sizeof(_joined_footnote_indicator)-1)
485 /* make.footnote_item() invocations should pass args accordingly */
486 const struct Blob *upc = text+1;
487 assert( text );
488 /* allow blob_size(text)==0 for constructs like [...](^ [] ()) */
489 memset(pos,0,24);
490 sprintf(pos, "%s-%d", unique, iMark);
491 blob_appendf(ob, "<li id='footnote%s' class='", pos);
492 if( nUsed ){
493 if( blob_size(text)>=_jfi_sz &&
494 !memcmp(blob_buffer(text),_joined_footnote_indicator,_jfi_sz)){
495 bJoin = 1;
496 blob_append_literal(ob, "fn-joined ");
497 }
498 append_footnote_upc(ob, upc, 0);
499 }else{
500 blob_append_literal(ob, "fn-toodeep ");
501 }
502 if( nUsed <= 1 ){
503 blob_append_literal(ob, "fn-monoref'><sup class='fn-backrefs'>");
504 blob_appendf(ob,"<a id='footnote%s-a' href='", pos);
505 BLOB_APPEND_URI(ob, ctx);
506 blob_appendf(ob,"#noteref%s-a'>^</a>", pos);
507 }else{
508 int i;
509 blob_append_literal(ob, "fn-polyref'><sup class='fn-backrefs'>^");
510 for(i=0; i<nUsed && i<26; i++){
511 const int c = i + (unsigned)'a';
512 blob_appendf(ob," <a id='footnote%s-%c' href='", pos,c);
513 BLOB_APPEND_URI(ob, ctx);
514 blob_appendf(ob,"#noteref%s-%c'>%c</a>", pos,c, c);
515 }
516 /* It's unlikely that so many backrefs will be usefull */
517 /* but maybe for some machine generated documents... */
518 for(; i<nUsed && i<676; i++){
519 const bitfield64_t l = to_base26(i,0);
520 blob_appendf(ob," <a id='footnote%s-%s' href='", pos, l.c);
521 BLOB_APPEND_URI(ob, ctx);
522 blob_appendf(ob,"#noteref%s-%s'>%s</a>", pos,l.c, l.c);
523 }
524 if( i < nUsed ) blob_append_literal(ob," &hellip;");
525 }
526 blob_append_literal(ob,"</sup>\n");
527 if( bJoin ){
528 blob_append_literal(ob,"<sup class='fn-joined'></sup><ul>");
529 blob_append(ob,blob_buffer(text)+_jfi_sz,blob_size(text)-_jfi_sz);
530 }else if( nUsed ){
531 append_footnote_upc(ob, upc, 1);
532 blob_appendb(ob, text);
533 }else{
534 blob_append_literal(ob,"<i></i>\n"
535 "<pre><code class='language-markdown'>");
536 if( blob_size(upc) ){
537 blob_appendb(ob, upc);
538 }
539 html_escape(ob, blob_buffer(text), blob_size(text));
540 blob_append_literal(ob,"</code></pre>");
541 }
542 #undef _joined_footnote_indicator
543 #undef _jfi_sz
544 }else{ /* a footnote was defined but wasn't referenced */
545 /* make.footnote_item() invocations should pass args accordingly */
546 const struct Blob *id = text-1, *upc = text+1;
547 assert( !nUsed );
548 assert( text );
549 assert( blob_size(text) );
550 assert( blob_size(id) );
551 blob_append_literal(ob,"<li class='fn-unreferenced'>\n[^&nbsp;<code>");
552 html_escape(ob, blob_buffer(id), blob_size(id));
553 blob_append_literal(ob, "</code>&nbsp;]<i></i>\n"
554 "<pre><code class='language-markdown'>");
555 if( blob_size(upc) ){
556 blob_appendb(ob, upc);
557 }
558 html_escape(ob, blob_buffer(text), blob_size(text));
559 blob_append_literal(ob,"</code></pre>");
560 }
561 blob_append_literal(ob, "\n</li>\n");
562 }
563
564 static void html_footnotes(
565 struct Blob *ob, const struct Blob *items, void *opaque
566 ){
567 if( items && blob_size(items) ){
568 blob_append_literal(ob,
569 "\n<hr class='footnotes-separator'/>\n<ol class='footnotes'>\n");
570 blob_appendb(ob, items);
571 blob_append_literal(ob, "</ol>\n");
572 }
573 }
574
575 /* HTML span tags */
576
577 static int html_raw_html_tag(struct Blob *ob, struct Blob *text, void *opaque){
578 blob_append(ob, blob_buffer(text), blob_size(text));
@@ -319,21 +584,21 @@
584 struct Blob *link,
585 enum mkd_autolink type,
586 void *opaque
587 ){
588 if( !link || blob_size(link)<=0 ) return 0;
589 blob_append_literal(ob, "<a href=\"");
590 if( type==MKDA_IMPLICIT_EMAIL ) blob_append_literal(ob, "mailto:");
591 html_quote(ob, blob_buffer(link), blob_size(link));
592 blob_append_literal(ob, "\">");
593 if( type==MKDA_EXPLICIT_EMAIL && blob_size(link)>7 ){
594 /* remove "mailto:" from displayed text */
595 html_escape(ob, blob_buffer(link)+7, blob_size(link)-7);
596 }else{
597 html_escape(ob, blob_buffer(link), blob_size(link));
598 }
599 blob_append_literal(ob, "</a>");
600 return 1;
601 }
602
603 /*
604 ** The nSrc bytes at zSrc[] are Pikchr input text (allegedly). Process that
@@ -422,13 +687,13 @@
687 ){
688 if( text==0 ){
689 /* no-op */
690 }else if( nSep<=2 ){
691 /* One or two graves: an in-line code span */
692 blob_append_literal(ob, "<code>");
693 html_escape(ob, blob_buffer(text), blob_size(text));
694 blob_append_literal(ob, "</code>");
695 }else{
696 /* Three or more graves: a fenced code block */
697 int n = blob_size(text);
698 const char *z = blob_buffer(text);
699 int i;
@@ -460,25 +725,25 @@
725 struct Blob *ob,
726 struct Blob *text,
727 char c,
728 void *opaque
729 ){
730 blob_append_literal(ob, "<strong>");
731 blob_appendb(ob, text);
732 blob_append_literal(ob, "</strong>");
733 return 1;
734 }
735
736 static int html_emphasis(
737 struct Blob *ob,
738 struct Blob *text,
739 char c,
740 void *opaque
741 ){
742 blob_append_literal(ob, "<em>");
743 blob_appendb(ob, text);
744 blob_append_literal(ob, "</em>");
745 return 1;
746 }
747
748 static int html_image(
749 struct Blob *ob,
@@ -485,24 +750,24 @@
750 struct Blob *link,
751 struct Blob *title,
752 struct Blob *alt,
753 void *opaque
754 ){
755 blob_append_literal(ob, "<img src=\"");
756 html_quote(ob, blob_buffer(link), blob_size(link));
757 blob_append_literal(ob, "\" alt=\"");
758 html_quote(ob, blob_buffer(alt), blob_size(alt));
759 if( title && blob_size(title)>0 ){
760 blob_append_literal(ob, "\" title=\"");
761 html_quote(ob, blob_buffer(title), blob_size(title));
762 }
763 blob_append_literal(ob, "\" />");
764 return 1;
765 }
766
767 static int html_linebreak(struct Blob *ob, void *opaque){
768 blob_append_literal(ob, "<br />\n");
769 return 1;
770 }
771
772 static int html_link(
773 struct Blob *ob,
@@ -523,23 +788,23 @@
788 WIKI_MARKDOWNLINKS
789 ;
790 wiki_resolve_hyperlink(ob, flags, zLink, zClose, sizeof(zClose), 0, zTitle);
791 }
792 if( blob_size(content)==0 ){
793 if( link ) blob_appendb(ob, link);
794 }else{
795 blob_appendb(ob, content);
796 }
797 blob_append(ob, zClose, -1);
798 return 1;
799 }
800
801 /* Invoked for @name and #tag tagged words, marked up in the
802 ** output text in a way that JS and CSS can do something
803 ** interesting with them. This isn't standard Markdown, so
804 ** it's implementation-specific what occurs here. More, each
805 ** Fossil feature using Markdown is free to apply styling and
806 ** behavior to these in feature-specific ways.
807 */
808 static int html_tagspan(
809 struct Blob *ob, /* Write the output here */
810 struct Blob *text, /* The word after the tag character */
@@ -548,22 +813,22 @@
813 ){
814 if( text==0 ){
815 /* no-op */
816 }else{
817 char cPrefix = '!';
818 blob_append_literal(ob, "<span data-");
819 switch (type) {
820 case MKDT_ATREF:
821 cPrefix = '@'; blob_append_literal(ob, "atref"); break;
822 case MKDT_HASHTAG:
823 cPrefix = '#'; blob_append_literal(ob, "hashtag"); break;
824 case MKDT_NUMTAG:
825 cPrefix = '#'; blob_append_literal(ob, "numtag"); break;
826 }
827 blob_append_literal(ob, "=\"");
828 html_quote(ob, blob_buffer(text), blob_size(text));
829 blob_append_literal(ob, "\"");
830 blob_appendf(ob, ">%c%b</span>", cPrefix,text);
831 }
832 return 1;
833 }
834
@@ -571,13 +836,13 @@
836 struct Blob *ob,
837 struct Blob *text,
838 char c,
839 void *opaque
840 ){
841 blob_append_literal(ob, "<strong><em>");
842 blob_appendb(ob, text);
843 blob_append_literal(ob, "</em></strong>");
844 return 1;
845 }
846
847
848 static void html_normal_text(struct Blob *ob, struct Blob *text, void *opaque){
@@ -597,10 +862,11 @@
862 ){
863 struct mkd_renderer html_renderer = {
864 /* prolog and epilog */
865 html_prolog,
866 html_epilog,
867 html_footnotes,
868
869 /* block level elements */
870 html_blockcode,
871 html_blockquote,
872 html_blockhtml,
@@ -610,10 +876,11 @@
876 html_list_item,
877 html_paragraph,
878 html_table,
879 html_table_cell,
880 html_table_row,
881 html_footnote_item,
882
883 /* span level elements */
884 html_autolink,
885 html_codespan,
886 html_double_emphasis,
@@ -622,22 +889,30 @@
889 html_linebreak,
890 html_link,
891 html_raw_html_tag,
892 html_tagspan,
893 html_triple_emphasis,
894 html_footnote_ref,
895
896 /* low level elements */
897 0, /* entity */
898 html_normal_text,
899
900 /* misc. parameters */
901 "*_", /* emph_chars */
902 0 /* opaque */
903 };
904 static int invocation = -1; /* no marker for the first document */
905 static const char* zRU = 0; /* REQUEST_URI with escaped quotes */
906 MarkdownToHtml context;
907 memset(&context, 0, sizeof(context));
908 context.output_title = output_title;
909 context.unique = to_base26(invocation++,1);
910 if( !zRU ) zRU = escape_quotes(PD("REQUEST_URI",""));
911 #ifndef FOOTNOTES_WITHOUT_URI
912 blob_set( &context.reqURI, zRU );
913 #endif
914 html_renderer.opaque = &context;
915 if( output_title ) blob_reset(output_title);
916 blob_reset(output_body);
917 markdown(output_body, input_markdown, &html_renderer);
918 }
919
+362 -87
--- src/markdown_html.c
+++ src/markdown_html.c
@@ -29,37 +29,72 @@
2929
struct Blob *output_title,
3030
struct Blob *output_body);
3131
3232
#endif /* INTERFACE */
3333
34
+/*
35
+** Markdown-internal helper for generating unique link reference IDs.
36
+** Fields provide typed interpretation of the underline memory buffer.
37
+*/
38
+typedef union bitfield64_t bitfield64_t;
39
+union bitfield64_t{
40
+ char c[8]; /* interpret as the array of signed characters */
41
+ unsigned char b[8]; /* interpret as the array of unsigned characters */
42
+};
43
+
3444
/*
3545
** An instance of the following structure is passed through the
3646
** "opaque" pointer.
3747
*/
3848
typedef struct MarkdownToHtml MarkdownToHtml;
3949
struct MarkdownToHtml {
4050
Blob *output_title; /* Store the title here */
51
+ bitfield64_t unique; /* Enables construction of unique #id elements */
52
+
53
+ #ifndef FOOTNOTES_WITHOUT_URI
54
+ Blob reqURI; /* REQUEST_URI with escaped quotes */
55
+ #endif
4156
};
4257
4358
4459
/* INTER_BLOCK -- skip a line between block level elements */
4560
#define INTER_BLOCK(ob) \
4661
do { if( blob_size(ob)>0 ) blob_append_char(ob, '\n'); } while (0)
4762
48
-/* BLOB_APPEND_LITERAL -- append a string literal to a blob */
49
-#define BLOB_APPEND_LITERAL(blob, literal) \
50
- blob_append((blob), "" literal, (sizeof literal)-1)
51
- /*
52
- * The empty string in the second argument leads to a syntax error
53
- * when the macro is not used with a string literal. Unfortunately
54
- * the error is not overly explicit.
55
- */
56
-
57
-/* BLOB_APPEND_BLOB -- append blob contents to another */
58
-#define BLOB_APPEND_BLOB(dest, src) \
59
- blob_append((dest), blob_buffer(src), blob_size(src))
60
-
63
+/*
64
+** FOOTNOTES_WITHOUT_URI macro was introduced by [2c1f8f3592ef00e0]
65
+** to enable flexibility in rendering of footnote-specific hyperlinks.
66
+** It may be defined for a particular build in order to omit
67
+** full REQUEST_URIs within footnote-specific (and page-local) hyperlinks.
68
+** This *is* used for the builds that incorporate 'base-href-fix' branch
69
+** (which in turn fixes footnotes on the preview tab of /wikiedit page).
70
+*/
71
+#ifndef FOOTNOTES_WITHOUT_URI
72
+ #define BLOB_APPEND_URI(dest,ctx) blob_appendb(dest,&((ctx)->reqURI))
73
+#else
74
+ #define BLOB_APPEND_URI(dest,ctx)
75
+#endif
76
+
77
+/* Converts an integer to a textual base26 representation
78
+** with proper null-termination.
79
+ * Return empty string if that integer is negative. */
80
+static bitfield64_t to_base26(int i, int uppercase){
81
+ bitfield64_t x;
82
+ int j;
83
+ memset( &x, 0, sizeof(x) );
84
+ if( i >= 0 ){
85
+ for(j=7; j >= 0; j--){
86
+ x.b[j] = (unsigned char)(uppercase?'A':'a') + i%26;
87
+ if( (i /= 26) == 0 ) break;
88
+ }
89
+ assert( j > 0 ); /* because 2^32 < 26^7 */
90
+ for(i=0; i<8-j; i++) x.b[i] = x.b[i+j];
91
+ for( ; i<8 ; i++) x.b[i] = 0;
92
+ }
93
+ assert( x.c[7] == 0 );
94
+ return x;
95
+}
6196
6297
/* HTML escapes
6398
**
6499
** html_escape() converts < to &lt;, > to &gt;, and & to &amp;.
65100
** html_quote() goes further and converts " into &quot; and ' in &#39;.
@@ -78,19 +113,19 @@
78113
i++;
79114
}
80115
blob_append(ob, data+beg, i-beg);
81116
while( i<size ){
82117
if( data[i]=='<' ){
83
- BLOB_APPEND_LITERAL(ob, "&lt;");
118
+ blob_append_literal(ob, "&lt;");
84119
}else if( data[i]=='>' ){
85
- BLOB_APPEND_LITERAL(ob, "&gt;");
120
+ blob_append_literal(ob, "&gt;");
86121
}else if( data[i]=='&' ){
87
- BLOB_APPEND_LITERAL(ob, "&amp;");
122
+ blob_append_literal(ob, "&amp;");
88123
}else if( data[i]=='"' ){
89
- BLOB_APPEND_LITERAL(ob, "&quot;");
124
+ blob_append_literal(ob, "&quot;");
90125
}else if( data[i]=='\'' ){
91
- BLOB_APPEND_LITERAL(ob, "&#39;");
126
+ blob_append_literal(ob, "&#39;");
92127
}else{
93128
break;
94129
}
95130
i++;
96131
}
@@ -108,15 +143,15 @@
108143
i++;
109144
}
110145
blob_append(ob, data+beg, i-beg);
111146
while( i<size ){
112147
if( data[i]=='<' ){
113
- BLOB_APPEND_LITERAL(ob, "&lt;");
148
+ blob_append_literal(ob, "&lt;");
114149
}else if( data[i]=='>' ){
115
- BLOB_APPEND_LITERAL(ob, "&gt;");
150
+ blob_append_literal(ob, "&gt;");
116151
}else if( data[i]=='&' ){
117
- BLOB_APPEND_LITERAL(ob, "&amp;");
152
+ blob_append_literal(ob, "&amp;");
118153
}else{
119154
break;
120155
}
121156
i++;
122157
}
@@ -129,17 +164,17 @@
129164
/* Size of the prolog: "<div class='markdown'>\n" */
130165
#define PROLOG_SIZE 23
131166
132167
static void html_prolog(struct Blob *ob, void *opaque){
133168
INTER_BLOCK(ob);
134
- BLOB_APPEND_LITERAL(ob, "<div class=\"markdown\">\n");
169
+ blob_append_literal(ob, "<div class=\"markdown\">\n");
135170
assert( blob_size(ob)==PROLOG_SIZE );
136171
}
137172
138173
static void html_epilog(struct Blob *ob, void *opaque){
139174
INTER_BLOCK(ob);
140
- BLOB_APPEND_LITERAL(ob, "</div>\n");
175
+ blob_append_literal(ob, "</div>\n");
141176
}
142177
143178
static void html_blockhtml(struct Blob *ob, struct Blob *text, void *opaque){
144179
char *data = blob_buffer(text);
145180
size_t size = blob_size(text);
@@ -157,25 +192,25 @@
157192
blob_append(title, data+nTag, size - nTag - 5);
158193
return;
159194
}
160195
INTER_BLOCK(ob);
161196
blob_append(ob, data, size);
162
- BLOB_APPEND_LITERAL(ob, "\n");
197
+ blob_append_literal(ob, "\n");
163198
}
164199
165200
static void html_blockcode(struct Blob *ob, struct Blob *text, void *opaque){
166201
INTER_BLOCK(ob);
167
- BLOB_APPEND_LITERAL(ob, "<pre><code>");
202
+ blob_append_literal(ob, "<pre><code>");
168203
html_escape(ob, blob_buffer(text), blob_size(text));
169
- BLOB_APPEND_LITERAL(ob, "</code></pre>\n");
204
+ blob_append_literal(ob, "</code></pre>\n");
170205
}
171206
172207
static void html_blockquote(struct Blob *ob, struct Blob *text, void *opaque){
173208
INTER_BLOCK(ob);
174
- BLOB_APPEND_LITERAL(ob, "<blockquote>\n");
175
- BLOB_APPEND_BLOB(ob, text);
176
- BLOB_APPEND_LITERAL(ob, "</blockquote>\n");
209
+ blob_append_literal(ob, "<blockquote>\n");
210
+ blob_appendb(ob, text);
211
+ blob_append_literal(ob, "</blockquote>\n");
177212
}
178213
179214
static void html_header(
180215
struct Blob *ob,
181216
struct Blob *text,
@@ -184,22 +219,22 @@
184219
){
185220
struct Blob *title = ((MarkdownToHtml*)opaque)->output_title;
186221
/* The first header at the beginning of a text is considered as
187222
* a title and not output. */
188223
if( blob_size(ob)<=PROLOG_SIZE && title!=0 && blob_size(title)==0 ){
189
- BLOB_APPEND_BLOB(title, text);
224
+ blob_appendb(title, text);
190225
return;
191226
}
192227
INTER_BLOCK(ob);
193228
blob_appendf(ob, "<h%d>", level);
194
- BLOB_APPEND_BLOB(ob, text);
229
+ blob_appendb(ob, text);
195230
blob_appendf(ob, "</h%d>", level);
196231
}
197232
198233
static void html_hrule(struct Blob *ob, void *opaque){
199234
INTER_BLOCK(ob);
200
- BLOB_APPEND_LITERAL(ob, "<hr />\n");
235
+ blob_append_literal(ob, "<hr />\n");
201236
}
202237
203238
204239
static void html_list(
205240
struct Blob *ob,
@@ -210,11 +245,11 @@
210245
char ol[] = "ol";
211246
char ul[] = "ul";
212247
char *tag = (flags & MKD_LIST_ORDERED) ? ol : ul;
213248
INTER_BLOCK(ob);
214249
blob_appendf(ob, "<%s>\n", tag);
215
- BLOB_APPEND_BLOB(ob, text);
250
+ blob_appendb(ob, text);
216251
blob_appendf(ob, "</%s>\n", tag);
217252
}
218253
219254
static void html_list_item(
220255
struct Blob *ob,
@@ -223,20 +258,20 @@
223258
void *opaque
224259
){
225260
char *text_data = blob_buffer(text);
226261
size_t text_size = blob_size(text);
227262
while( text_size>0 && text_data[text_size-1]=='\n' ) text_size--;
228
- BLOB_APPEND_LITERAL(ob, "<li>");
263
+ blob_append_literal(ob, "<li>");
229264
blob_append(ob, text_data, text_size);
230
- BLOB_APPEND_LITERAL(ob, "</li>\n");
265
+ blob_append_literal(ob, "</li>\n");
231266
}
232267
233268
static void html_paragraph(struct Blob *ob, struct Blob *text, void *opaque){
234269
INTER_BLOCK(ob);
235
- BLOB_APPEND_LITERAL(ob, "<p>");
236
- BLOB_APPEND_BLOB(ob, text);
237
- BLOB_APPEND_LITERAL(ob, "</p>\n");
270
+ blob_append_literal(ob, "<p>");
271
+ blob_appendb(ob, text);
272
+ blob_append_literal(ob, "</p>\n");
238273
}
239274
240275
241276
static void html_table(
242277
struct Blob *ob,
@@ -243,71 +278,301 @@
243278
struct Blob *head_row,
244279
struct Blob *rows,
245280
void *opaque
246281
){
247282
INTER_BLOCK(ob);
248
- BLOB_APPEND_LITERAL(ob, "<table>\n");
283
+ blob_append_literal(ob, "<table>\n");
249284
if( head_row && blob_size(head_row)>0 ){
250
- BLOB_APPEND_LITERAL(ob, "<thead>\n");
251
- BLOB_APPEND_BLOB(ob, head_row);
252
- BLOB_APPEND_LITERAL(ob, "</thead>\n<tbody>\n");
285
+ blob_append_literal(ob, "<thead>\n");
286
+ blob_appendb(ob, head_row);
287
+ blob_append_literal(ob, "</thead>\n<tbody>\n");
253288
}
254289
if( rows ){
255
- BLOB_APPEND_BLOB(ob, rows);
290
+ blob_appendb(ob, rows);
256291
}
257292
if( head_row && blob_size(head_row)>0 ){
258
- BLOB_APPEND_LITERAL(ob, "</tbody>\n");
293
+ blob_append_literal(ob, "</tbody>\n");
259294
}
260
- BLOB_APPEND_LITERAL(ob, "</table>\n");
295
+ blob_append_literal(ob, "</table>\n");
261296
}
262297
263298
static void html_table_cell(
264299
struct Blob *ob,
265300
struct Blob *text,
266301
int flags,
267302
void *opaque
268303
){
269304
if( flags & MKD_CELL_HEAD ){
270
- BLOB_APPEND_LITERAL(ob, " <th");
305
+ blob_append_literal(ob, " <th");
271306
}else{
272
- BLOB_APPEND_LITERAL(ob, " <td");
307
+ blob_append_literal(ob, " <td");
273308
}
274309
switch( flags & MKD_CELL_ALIGN_MASK ){
275310
case MKD_CELL_ALIGN_LEFT: {
276
- BLOB_APPEND_LITERAL(ob, " align=\"left\"");
311
+ blob_append_literal(ob, " align=\"left\"");
277312
break;
278313
}
279314
case MKD_CELL_ALIGN_RIGHT: {
280
- BLOB_APPEND_LITERAL(ob, " align=\"right\"");
315
+ blob_append_literal(ob, " align=\"right\"");
281316
break;
282317
}
283318
case MKD_CELL_ALIGN_CENTER: {
284
- BLOB_APPEND_LITERAL(ob, " align=\"center\"");
319
+ blob_append_literal(ob, " align=\"center\"");
285320
break;
286321
}
287322
}
288
- BLOB_APPEND_LITERAL(ob, ">");
289
- BLOB_APPEND_BLOB(ob, text);
323
+ blob_append_literal(ob, ">");
324
+ blob_appendb(ob, text);
290325
if( flags & MKD_CELL_HEAD ){
291
- BLOB_APPEND_LITERAL(ob, "</th>\n");
326
+ blob_append_literal(ob, "</th>\n");
292327
}else{
293
- BLOB_APPEND_LITERAL(ob, "</td>\n");
328
+ blob_append_literal(ob, "</td>\n");
294329
}
295330
}
296331
297332
static void html_table_row(
298333
struct Blob *ob,
299334
struct Blob *cells,
300335
int flags,
301336
void *opaque
302337
){
303
- BLOB_APPEND_LITERAL(ob, " <tr>\n");
304
- BLOB_APPEND_BLOB(ob, cells);
305
- BLOB_APPEND_LITERAL(ob, " </tr>\n");
338
+ blob_append_literal(ob, " <tr>\n");
339
+ blob_appendb(ob, cells);
340
+ blob_append_literal(ob, " </tr>\n");
341
+}
342
+
343
+/*
344
+** Render a token of user provided classes.
345
+** If bHTML is true then render HTML for (presumably) visible text,
346
+** otherwise just a space-separated list of the derived classes.
347
+*/
348
+static void append_footnote_upc(
349
+ struct Blob *ob,
350
+ const struct Blob *upc, /* token of user-provided classes */
351
+ int bHTML
352
+){
353
+ const char *z = blob_buffer(upc);
354
+ int i, n = blob_size(upc);
355
+
356
+ if( n<3 ) return;
357
+ assert( z[0]=='.' && z[n-1] == ':' );
358
+ if( bHTML ){
359
+ blob_append_literal(ob, "<span class='fn-upc'>"
360
+ "<span class='fn-upcDot'>.</span>");
361
+ }
362
+ n = 0;
363
+ do{
364
+ z++;
365
+ if( *z!='.' && *z!=':' ){
366
+ assert( fossil_isalnum(*z) || *z=='-' );
367
+ n++;
368
+ continue;
369
+ }
370
+ assert( n );
371
+ if( bHTML ) blob_append_literal(ob, "<span class='");
372
+ blob_append_literal(ob, "fn-upc-");
373
+
374
+ for(i=-n; i<0; i++){
375
+ blob_append_char(ob, fossil_tolower(z[i]) );
376
+ }
377
+ if( bHTML ){
378
+ blob_append_literal(ob, "'>");
379
+ blob_append(ob, z-n, n);
380
+ blob_append_literal(ob, "</span>");
381
+ }else{
382
+ blob_append_char(ob, ' ');
383
+ }
384
+ n = 0;
385
+ if( bHTML ){
386
+ if( *z==':' ){
387
+ blob_append_literal(ob,"<span class='fn-upcColon'>:</span>");
388
+ }else{
389
+ blob_append_literal(ob,"<span class='fn-upcDot'>.</span>");
390
+ }
391
+ }
392
+ }while( *z != ':' );
393
+ if( bHTML ) blob_append_literal(ob,"</span>\n");
394
+}
395
+
396
+static int html_footnote_ref(
397
+ struct Blob *ob, const struct Blob *span, const struct Blob *upc,
398
+ int iMark, int locus, void *opaque
399
+){
400
+ const struct MarkdownToHtml* ctx = (struct MarkdownToHtml*)opaque;
401
+ const bitfield64_t l = to_base26(locus-1,0);
402
+ char pos[32];
403
+ memset(pos,0,32);
404
+ assert( locus > 0 );
405
+ /* expect BUGs if the following yields compiler warnings */
406
+ if( iMark > 0 ){ /* a regular reference to a footnote */
407
+ sprintf(pos, "%s-%d-%s", ctx->unique.c, iMark, l.c);
408
+ if(span && blob_size(span)) {
409
+ blob_append_literal(ob,"<span class='");
410
+ append_footnote_upc(ob, upc, 0);
411
+ blob_append_literal(ob,"notescope' id='noteref");
412
+ blob_appendf(ob,"%s'>",pos);
413
+ blob_appendb(ob, span);
414
+ blob_trim(ob);
415
+ blob_append_literal(ob,"<sup class='noteref'><a href='");
416
+ BLOB_APPEND_URI(ob, ctx);
417
+ blob_appendf(ob,"#footnote%s'>%d</a></sup></span>", pos, iMark);
418
+ }else{
419
+ blob_trim(ob);
420
+ blob_append_literal(ob,"<sup class='");
421
+ append_footnote_upc(ob, upc, 0);
422
+ blob_append_literal(ob,"noteref'><a href='");
423
+ BLOB_APPEND_URI(ob, ctx);
424
+ blob_appendf(ob,"#footnote%s' id='noteref%s'>%d</a></sup>",
425
+ pos, pos, iMark);
426
+ }
427
+ }else{ /* misreference */
428
+ assert( iMark == -1 );
429
+
430
+ sprintf(pos, "%s-%s", ctx->unique.c, l.c);
431
+ if(span && blob_size(span)) {
432
+ blob_appendf(ob, "<span class='notescope' id='misref%s'>", pos);
433
+ blob_appendb(ob, span);
434
+ blob_trim(ob);
435
+ blob_append_literal(ob, "<sup class='noteref misref'><a href='");
436
+ BLOB_APPEND_URI(ob, ctx);
437
+ blob_appendf(ob, "#misreference%s'>misref</a></sup></span>", pos);
438
+ }else{
439
+ blob_trim(ob);
440
+ blob_append_literal(ob, "<sup class='noteref misref'><a href='");
441
+ BLOB_APPEND_URI(ob, ctx);
442
+ blob_appendf(ob, "#misreference%s' id='misref%s'>", pos, pos);
443
+ blob_append_literal(ob, "misref</a></sup>");
444
+ }
445
+ }
446
+ return 1;
447
+}
448
+
449
+/* Render a single item of the footnotes list.
450
+ * Each backref gets a unique id to enable dynamic styling. */
451
+static void html_footnote_item(
452
+ struct Blob *ob, const struct Blob *text, int iMark, int nUsed, void *opaque
453
+){
454
+ const struct MarkdownToHtml* ctx = (struct MarkdownToHtml*)opaque;
455
+ const char * const unique = ctx->unique.c;
456
+ assert( nUsed >= 0 );
457
+ /* expect BUGs if the following yields compiler warnings */
458
+
459
+ if( iMark < 0 ){ /* misreferences */
460
+ assert( iMark == -1 );
461
+ assert( nUsed );
462
+ blob_append_literal(ob,"<li class='fn-misreference'>"
463
+ "<sup class='fn-backrefs'>");
464
+ if( nUsed == 1 ){
465
+ blob_appendf(ob,"<a id='misreference%s-a' href='", unique);
466
+ BLOB_APPEND_URI(ob, ctx);
467
+ blob_appendf(ob,"#misref%s-a'>^</a>", unique);
468
+ }else{
469
+ int i;
470
+ blob_append_char(ob, '^');
471
+ for(i=0; i<nUsed && i<26; i++){
472
+ const int c = i + (unsigned)'a';
473
+ blob_appendf(ob," <a id='misreference%s-%c' href='", unique,c);
474
+ BLOB_APPEND_URI(ob, ctx);
475
+ blob_appendf(ob,"#misref%s-%c'>%c</a>", unique,c, c);
476
+ }
477
+ if( i < nUsed ) blob_append_literal(ob," &hellip;");
478
+ }
479
+ blob_append_literal(ob,"</sup>\n<span>Misreference</span>");
480
+ }else if( iMark > 0 ){ /* regular, joined and overnested footnotes */
481
+ char pos[24];
482
+ int bJoin = 0;
483
+ #define _joined_footnote_indicator "<ul class='fn-joined'>"
484
+ #define _jfi_sz (sizeof(_joined_footnote_indicator)-1)
485
+ /* make.footnote_item() invocations should pass args accordingly */
486
+ const struct Blob *upc = text+1;
487
+ assert( text );
488
+ /* allow blob_size(text)==0 for constructs like [...](^ [] ()) */
489
+ memset(pos,0,24);
490
+ sprintf(pos, "%s-%d", unique, iMark);
491
+ blob_appendf(ob, "<li id='footnote%s' class='", pos);
492
+ if( nUsed ){
493
+ if( blob_size(text)>=_jfi_sz &&
494
+ !memcmp(blob_buffer(text),_joined_footnote_indicator,_jfi_sz)){
495
+ bJoin = 1;
496
+ blob_append_literal(ob, "fn-joined ");
497
+ }
498
+ append_footnote_upc(ob, upc, 0);
499
+ }else{
500
+ blob_append_literal(ob, "fn-toodeep ");
501
+ }
502
+ if( nUsed <= 1 ){
503
+ blob_append_literal(ob, "fn-monoref'><sup class='fn-backrefs'>");
504
+ blob_appendf(ob,"<a id='footnote%s-a' href='", pos);
505
+ BLOB_APPEND_URI(ob, ctx);
506
+ blob_appendf(ob,"#noteref%s-a'>^</a>", pos);
507
+ }else{
508
+ int i;
509
+ blob_append_literal(ob, "fn-polyref'><sup class='fn-backrefs'>^");
510
+ for(i=0; i<nUsed && i<26; i++){
511
+ const int c = i + (unsigned)'a';
512
+ blob_appendf(ob," <a id='footnote%s-%c' href='", pos,c);
513
+ BLOB_APPEND_URI(ob, ctx);
514
+ blob_appendf(ob,"#noteref%s-%c'>%c</a>", pos,c, c);
515
+ }
516
+ /* It's unlikely that so many backrefs will be usefull */
517
+ /* but maybe for some machine generated documents... */
518
+ for(; i<nUsed && i<676; i++){
519
+ const bitfield64_t l = to_base26(i,0);
520
+ blob_appendf(ob," <a id='footnote%s-%s' href='", pos, l.c);
521
+ BLOB_APPEND_URI(ob, ctx);
522
+ blob_appendf(ob,"#noteref%s-%s'>%s</a>", pos,l.c, l.c);
523
+ }
524
+ if( i < nUsed ) blob_append_literal(ob," &hellip;");
525
+ }
526
+ blob_append_literal(ob,"</sup>\n");
527
+ if( bJoin ){
528
+ blob_append_literal(ob,"<sup class='fn-joined'></sup><ul>");
529
+ blob_append(ob,blob_buffer(text)+_jfi_sz,blob_size(text)-_jfi_sz);
530
+ }else if( nUsed ){
531
+ append_footnote_upc(ob, upc, 1);
532
+ blob_appendb(ob, text);
533
+ }else{
534
+ blob_append_literal(ob,"<i></i>\n"
535
+ "<pre><code class='language-markdown'>");
536
+ if( blob_size(upc) ){
537
+ blob_appendb(ob, upc);
538
+ }
539
+ html_escape(ob, blob_buffer(text), blob_size(text));
540
+ blob_append_literal(ob,"</code></pre>");
541
+ }
542
+ #undef _joined_footnote_indicator
543
+ #undef _jfi_sz
544
+ }else{ /* a footnote was defined but wasn't referenced */
545
+ /* make.footnote_item() invocations should pass args accordingly */
546
+ const struct Blob *id = text-1, *upc = text+1;
547
+ assert( !nUsed );
548
+ assert( text );
549
+ assert( blob_size(text) );
550
+ assert( blob_size(id) );
551
+ blob_append_literal(ob,"<li class='fn-unreferenced'>\n[^&nbsp;<code>");
552
+ html_escape(ob, blob_buffer(id), blob_size(id));
553
+ blob_append_literal(ob, "</code>&nbsp;]<i></i>\n"
554
+ "<pre><code class='language-markdown'>");
555
+ if( blob_size(upc) ){
556
+ blob_appendb(ob, upc);
557
+ }
558
+ html_escape(ob, blob_buffer(text), blob_size(text));
559
+ blob_append_literal(ob,"</code></pre>");
560
+ }
561
+ blob_append_literal(ob, "\n</li>\n");
306562
}
307563
308
-
564
+static void html_footnotes(
565
+ struct Blob *ob, const struct Blob *items, void *opaque
566
+){
567
+ if( items && blob_size(items) ){
568
+ blob_append_literal(ob,
569
+ "\n<hr class='footnotes-separator'/>\n<ol class='footnotes'>\n");
570
+ blob_appendb(ob, items);
571
+ blob_append_literal(ob, "</ol>\n");
572
+ }
573
+}
309574
310575
/* HTML span tags */
311576
312577
static int html_raw_html_tag(struct Blob *ob, struct Blob *text, void *opaque){
313578
blob_append(ob, blob_buffer(text), blob_size(text));
@@ -319,21 +584,21 @@
319584
struct Blob *link,
320585
enum mkd_autolink type,
321586
void *opaque
322587
){
323588
if( !link || blob_size(link)<=0 ) return 0;
324
- BLOB_APPEND_LITERAL(ob, "<a href=\"");
325
- if( type==MKDA_IMPLICIT_EMAIL ) BLOB_APPEND_LITERAL(ob, "mailto:");
589
+ blob_append_literal(ob, "<a href=\"");
590
+ if( type==MKDA_IMPLICIT_EMAIL ) blob_append_literal(ob, "mailto:");
326591
html_quote(ob, blob_buffer(link), blob_size(link));
327
- BLOB_APPEND_LITERAL(ob, "\">");
592
+ blob_append_literal(ob, "\">");
328593
if( type==MKDA_EXPLICIT_EMAIL && blob_size(link)>7 ){
329594
/* remove "mailto:" from displayed text */
330595
html_escape(ob, blob_buffer(link)+7, blob_size(link)-7);
331596
}else{
332597
html_escape(ob, blob_buffer(link), blob_size(link));
333598
}
334
- BLOB_APPEND_LITERAL(ob, "</a>");
599
+ blob_append_literal(ob, "</a>");
335600
return 1;
336601
}
337602
338603
/*
339604
** The nSrc bytes at zSrc[] are Pikchr input text (allegedly). Process that
@@ -422,13 +687,13 @@
422687
){
423688
if( text==0 ){
424689
/* no-op */
425690
}else if( nSep<=2 ){
426691
/* One or two graves: an in-line code span */
427
- BLOB_APPEND_LITERAL(ob, "<code>");
692
+ blob_append_literal(ob, "<code>");
428693
html_escape(ob, blob_buffer(text), blob_size(text));
429
- BLOB_APPEND_LITERAL(ob, "</code>");
694
+ blob_append_literal(ob, "</code>");
430695
}else{
431696
/* Three or more graves: a fenced code block */
432697
int n = blob_size(text);
433698
const char *z = blob_buffer(text);
434699
int i;
@@ -460,25 +725,25 @@
460725
struct Blob *ob,
461726
struct Blob *text,
462727
char c,
463728
void *opaque
464729
){
465
- BLOB_APPEND_LITERAL(ob, "<strong>");
466
- BLOB_APPEND_BLOB(ob, text);
467
- BLOB_APPEND_LITERAL(ob, "</strong>");
730
+ blob_append_literal(ob, "<strong>");
731
+ blob_appendb(ob, text);
732
+ blob_append_literal(ob, "</strong>");
468733
return 1;
469734
}
470735
471736
static int html_emphasis(
472737
struct Blob *ob,
473738
struct Blob *text,
474739
char c,
475740
void *opaque
476741
){
477
- BLOB_APPEND_LITERAL(ob, "<em>");
478
- BLOB_APPEND_BLOB(ob, text);
479
- BLOB_APPEND_LITERAL(ob, "</em>");
742
+ blob_append_literal(ob, "<em>");
743
+ blob_appendb(ob, text);
744
+ blob_append_literal(ob, "</em>");
480745
return 1;
481746
}
482747
483748
static int html_image(
484749
struct Blob *ob,
@@ -485,24 +750,24 @@
485750
struct Blob *link,
486751
struct Blob *title,
487752
struct Blob *alt,
488753
void *opaque
489754
){
490
- BLOB_APPEND_LITERAL(ob, "<img src=\"");
755
+ blob_append_literal(ob, "<img src=\"");
491756
html_quote(ob, blob_buffer(link), blob_size(link));
492
- BLOB_APPEND_LITERAL(ob, "\" alt=\"");
757
+ blob_append_literal(ob, "\" alt=\"");
493758
html_quote(ob, blob_buffer(alt), blob_size(alt));
494759
if( title && blob_size(title)>0 ){
495
- BLOB_APPEND_LITERAL(ob, "\" title=\"");
760
+ blob_append_literal(ob, "\" title=\"");
496761
html_quote(ob, blob_buffer(title), blob_size(title));
497762
}
498
- BLOB_APPEND_LITERAL(ob, "\" />");
763
+ blob_append_literal(ob, "\" />");
499764
return 1;
500765
}
501766
502767
static int html_linebreak(struct Blob *ob, void *opaque){
503
- BLOB_APPEND_LITERAL(ob, "<br />\n");
768
+ blob_append_literal(ob, "<br />\n");
504769
return 1;
505770
}
506771
507772
static int html_link(
508773
struct Blob *ob,
@@ -523,23 +788,23 @@
523788
WIKI_MARKDOWNLINKS
524789
;
525790
wiki_resolve_hyperlink(ob, flags, zLink, zClose, sizeof(zClose), 0, zTitle);
526791
}
527792
if( blob_size(content)==0 ){
528
- if( link ) BLOB_APPEND_BLOB(ob, link);
793
+ if( link ) blob_appendb(ob, link);
529794
}else{
530
- BLOB_APPEND_BLOB(ob, content);
795
+ blob_appendb(ob, content);
531796
}
532797
blob_append(ob, zClose, -1);
533798
return 1;
534799
}
535800
536801
/* Invoked for @name and #tag tagged words, marked up in the
537802
** output text in a way that JS and CSS can do something
538803
** interesting with them. This isn't standard Markdown, so
539804
** it's implementation-specific what occurs here. More, each
540
-** Fossil feature using Markdown is free to apply markup and
805
+** Fossil feature using Markdown is free to apply styling and
541806
** behavior to these in feature-specific ways.
542807
*/
543808
static int html_tagspan(
544809
struct Blob *ob, /* Write the output here */
545810
struct Blob *text, /* The word after the tag character */
@@ -548,22 +813,22 @@
548813
){
549814
if( text==0 ){
550815
/* no-op */
551816
}else{
552817
char cPrefix = '!';
553
- BLOB_APPEND_LITERAL(ob, "<span data-");
818
+ blob_append_literal(ob, "<span data-");
554819
switch (type) {
555820
case MKDT_ATREF:
556
- cPrefix = '@'; BLOB_APPEND_LITERAL(ob, "atref"); break;
821
+ cPrefix = '@'; blob_append_literal(ob, "atref"); break;
557822
case MKDT_HASHTAG:
558
- cPrefix = '#'; BLOB_APPEND_LITERAL(ob, "hashtag"); break;
823
+ cPrefix = '#'; blob_append_literal(ob, "hashtag"); break;
559824
case MKDT_NUMTAG:
560
- cPrefix = '#'; BLOB_APPEND_LITERAL(ob, "numtag"); break;
825
+ cPrefix = '#'; blob_append_literal(ob, "numtag"); break;
561826
}
562
- BLOB_APPEND_LITERAL(ob, "=\"");
827
+ blob_append_literal(ob, "=\"");
563828
html_quote(ob, blob_buffer(text), blob_size(text));
564
- BLOB_APPEND_LITERAL(ob, "\"");
829
+ blob_append_literal(ob, "\"");
565830
blob_appendf(ob, ">%c%b</span>", cPrefix,text);
566831
}
567832
return 1;
568833
}
569834
@@ -571,13 +836,13 @@
571836
struct Blob *ob,
572837
struct Blob *text,
573838
char c,
574839
void *opaque
575840
){
576
- BLOB_APPEND_LITERAL(ob, "<strong><em>");
577
- BLOB_APPEND_BLOB(ob, text);
578
- BLOB_APPEND_LITERAL(ob, "</em></strong>");
841
+ blob_append_literal(ob, "<strong><em>");
842
+ blob_appendb(ob, text);
843
+ blob_append_literal(ob, "</em></strong>");
579844
return 1;
580845
}
581846
582847
583848
static void html_normal_text(struct Blob *ob, struct Blob *text, void *opaque){
@@ -597,10 +862,11 @@
597862
){
598863
struct mkd_renderer html_renderer = {
599864
/* prolog and epilog */
600865
html_prolog,
601866
html_epilog,
867
+ html_footnotes,
602868
603869
/* block level elements */
604870
html_blockcode,
605871
html_blockquote,
606872
html_blockhtml,
@@ -610,10 +876,11 @@
610876
html_list_item,
611877
html_paragraph,
612878
html_table,
613879
html_table_cell,
614880
html_table_row,
881
+ html_footnote_item,
615882
616883
/* span level elements */
617884
html_autolink,
618885
html_codespan,
619886
html_double_emphasis,
@@ -622,22 +889,30 @@
622889
html_linebreak,
623890
html_link,
624891
html_raw_html_tag,
625892
html_tagspan,
626893
html_triple_emphasis,
894
+ html_footnote_ref,
627895
628896
/* low level elements */
629897
0, /* entity */
630898
html_normal_text,
631899
632900
/* misc. parameters */
633901
"*_", /* emph_chars */
634902
0 /* opaque */
635903
};
904
+ static int invocation = -1; /* no marker for the first document */
905
+ static const char* zRU = 0; /* REQUEST_URI with escaped quotes */
636906
MarkdownToHtml context;
637907
memset(&context, 0, sizeof(context));
638908
context.output_title = output_title;
909
+ context.unique = to_base26(invocation++,1);
910
+ if( !zRU ) zRU = escape_quotes(PD("REQUEST_URI",""));
911
+ #ifndef FOOTNOTES_WITHOUT_URI
912
+ blob_set( &context.reqURI, zRU );
913
+ #endif
639914
html_renderer.opaque = &context;
640915
if( output_title ) blob_reset(output_title);
641916
blob_reset(output_body);
642917
markdown(output_body, input_markdown, &html_renderer);
643918
}
644919
--- src/markdown_html.c
+++ src/markdown_html.c
@@ -29,37 +29,72 @@
29 struct Blob *output_title,
30 struct Blob *output_body);
31
32 #endif /* INTERFACE */
33
 
 
 
 
 
 
 
 
 
 
34 /*
35 ** An instance of the following structure is passed through the
36 ** "opaque" pointer.
37 */
38 typedef struct MarkdownToHtml MarkdownToHtml;
39 struct MarkdownToHtml {
40 Blob *output_title; /* Store the title here */
 
 
 
 
 
41 };
42
43
44 /* INTER_BLOCK -- skip a line between block level elements */
45 #define INTER_BLOCK(ob) \
46 do { if( blob_size(ob)>0 ) blob_append_char(ob, '\n'); } while (0)
47
48 /* BLOB_APPEND_LITERAL -- append a string literal to a blob */
49 #define BLOB_APPEND_LITERAL(blob, literal) \
50 blob_append((blob), "" literal, (sizeof literal)-1)
51 /*
52 * The empty string in the second argument leads to a syntax error
53 * when the macro is not used with a string literal. Unfortunately
54 * the error is not overly explicit.
55 */
56
57 /* BLOB_APPEND_BLOB -- append blob contents to another */
58 #define BLOB_APPEND_BLOB(dest, src) \
59 blob_append((dest), blob_buffer(src), blob_size(src))
60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
62 /* HTML escapes
63 **
64 ** html_escape() converts < to &lt;, > to &gt;, and & to &amp;.
65 ** html_quote() goes further and converts " into &quot; and ' in &#39;.
@@ -78,19 +113,19 @@
78 i++;
79 }
80 blob_append(ob, data+beg, i-beg);
81 while( i<size ){
82 if( data[i]=='<' ){
83 BLOB_APPEND_LITERAL(ob, "&lt;");
84 }else if( data[i]=='>' ){
85 BLOB_APPEND_LITERAL(ob, "&gt;");
86 }else if( data[i]=='&' ){
87 BLOB_APPEND_LITERAL(ob, "&amp;");
88 }else if( data[i]=='"' ){
89 BLOB_APPEND_LITERAL(ob, "&quot;");
90 }else if( data[i]=='\'' ){
91 BLOB_APPEND_LITERAL(ob, "&#39;");
92 }else{
93 break;
94 }
95 i++;
96 }
@@ -108,15 +143,15 @@
108 i++;
109 }
110 blob_append(ob, data+beg, i-beg);
111 while( i<size ){
112 if( data[i]=='<' ){
113 BLOB_APPEND_LITERAL(ob, "&lt;");
114 }else if( data[i]=='>' ){
115 BLOB_APPEND_LITERAL(ob, "&gt;");
116 }else if( data[i]=='&' ){
117 BLOB_APPEND_LITERAL(ob, "&amp;");
118 }else{
119 break;
120 }
121 i++;
122 }
@@ -129,17 +164,17 @@
129 /* Size of the prolog: "<div class='markdown'>\n" */
130 #define PROLOG_SIZE 23
131
132 static void html_prolog(struct Blob *ob, void *opaque){
133 INTER_BLOCK(ob);
134 BLOB_APPEND_LITERAL(ob, "<div class=\"markdown\">\n");
135 assert( blob_size(ob)==PROLOG_SIZE );
136 }
137
138 static void html_epilog(struct Blob *ob, void *opaque){
139 INTER_BLOCK(ob);
140 BLOB_APPEND_LITERAL(ob, "</div>\n");
141 }
142
143 static void html_blockhtml(struct Blob *ob, struct Blob *text, void *opaque){
144 char *data = blob_buffer(text);
145 size_t size = blob_size(text);
@@ -157,25 +192,25 @@
157 blob_append(title, data+nTag, size - nTag - 5);
158 return;
159 }
160 INTER_BLOCK(ob);
161 blob_append(ob, data, size);
162 BLOB_APPEND_LITERAL(ob, "\n");
163 }
164
165 static void html_blockcode(struct Blob *ob, struct Blob *text, void *opaque){
166 INTER_BLOCK(ob);
167 BLOB_APPEND_LITERAL(ob, "<pre><code>");
168 html_escape(ob, blob_buffer(text), blob_size(text));
169 BLOB_APPEND_LITERAL(ob, "</code></pre>\n");
170 }
171
172 static void html_blockquote(struct Blob *ob, struct Blob *text, void *opaque){
173 INTER_BLOCK(ob);
174 BLOB_APPEND_LITERAL(ob, "<blockquote>\n");
175 BLOB_APPEND_BLOB(ob, text);
176 BLOB_APPEND_LITERAL(ob, "</blockquote>\n");
177 }
178
179 static void html_header(
180 struct Blob *ob,
181 struct Blob *text,
@@ -184,22 +219,22 @@
184 ){
185 struct Blob *title = ((MarkdownToHtml*)opaque)->output_title;
186 /* The first header at the beginning of a text is considered as
187 * a title and not output. */
188 if( blob_size(ob)<=PROLOG_SIZE && title!=0 && blob_size(title)==0 ){
189 BLOB_APPEND_BLOB(title, text);
190 return;
191 }
192 INTER_BLOCK(ob);
193 blob_appendf(ob, "<h%d>", level);
194 BLOB_APPEND_BLOB(ob, text);
195 blob_appendf(ob, "</h%d>", level);
196 }
197
198 static void html_hrule(struct Blob *ob, void *opaque){
199 INTER_BLOCK(ob);
200 BLOB_APPEND_LITERAL(ob, "<hr />\n");
201 }
202
203
204 static void html_list(
205 struct Blob *ob,
@@ -210,11 +245,11 @@
210 char ol[] = "ol";
211 char ul[] = "ul";
212 char *tag = (flags & MKD_LIST_ORDERED) ? ol : ul;
213 INTER_BLOCK(ob);
214 blob_appendf(ob, "<%s>\n", tag);
215 BLOB_APPEND_BLOB(ob, text);
216 blob_appendf(ob, "</%s>\n", tag);
217 }
218
219 static void html_list_item(
220 struct Blob *ob,
@@ -223,20 +258,20 @@
223 void *opaque
224 ){
225 char *text_data = blob_buffer(text);
226 size_t text_size = blob_size(text);
227 while( text_size>0 && text_data[text_size-1]=='\n' ) text_size--;
228 BLOB_APPEND_LITERAL(ob, "<li>");
229 blob_append(ob, text_data, text_size);
230 BLOB_APPEND_LITERAL(ob, "</li>\n");
231 }
232
233 static void html_paragraph(struct Blob *ob, struct Blob *text, void *opaque){
234 INTER_BLOCK(ob);
235 BLOB_APPEND_LITERAL(ob, "<p>");
236 BLOB_APPEND_BLOB(ob, text);
237 BLOB_APPEND_LITERAL(ob, "</p>\n");
238 }
239
240
241 static void html_table(
242 struct Blob *ob,
@@ -243,71 +278,301 @@
243 struct Blob *head_row,
244 struct Blob *rows,
245 void *opaque
246 ){
247 INTER_BLOCK(ob);
248 BLOB_APPEND_LITERAL(ob, "<table>\n");
249 if( head_row && blob_size(head_row)>0 ){
250 BLOB_APPEND_LITERAL(ob, "<thead>\n");
251 BLOB_APPEND_BLOB(ob, head_row);
252 BLOB_APPEND_LITERAL(ob, "</thead>\n<tbody>\n");
253 }
254 if( rows ){
255 BLOB_APPEND_BLOB(ob, rows);
256 }
257 if( head_row && blob_size(head_row)>0 ){
258 BLOB_APPEND_LITERAL(ob, "</tbody>\n");
259 }
260 BLOB_APPEND_LITERAL(ob, "</table>\n");
261 }
262
263 static void html_table_cell(
264 struct Blob *ob,
265 struct Blob *text,
266 int flags,
267 void *opaque
268 ){
269 if( flags & MKD_CELL_HEAD ){
270 BLOB_APPEND_LITERAL(ob, " <th");
271 }else{
272 BLOB_APPEND_LITERAL(ob, " <td");
273 }
274 switch( flags & MKD_CELL_ALIGN_MASK ){
275 case MKD_CELL_ALIGN_LEFT: {
276 BLOB_APPEND_LITERAL(ob, " align=\"left\"");
277 break;
278 }
279 case MKD_CELL_ALIGN_RIGHT: {
280 BLOB_APPEND_LITERAL(ob, " align=\"right\"");
281 break;
282 }
283 case MKD_CELL_ALIGN_CENTER: {
284 BLOB_APPEND_LITERAL(ob, " align=\"center\"");
285 break;
286 }
287 }
288 BLOB_APPEND_LITERAL(ob, ">");
289 BLOB_APPEND_BLOB(ob, text);
290 if( flags & MKD_CELL_HEAD ){
291 BLOB_APPEND_LITERAL(ob, "</th>\n");
292 }else{
293 BLOB_APPEND_LITERAL(ob, "</td>\n");
294 }
295 }
296
297 static void html_table_row(
298 struct Blob *ob,
299 struct Blob *cells,
300 int flags,
301 void *opaque
302 ){
303 BLOB_APPEND_LITERAL(ob, " <tr>\n");
304 BLOB_APPEND_BLOB(ob, cells);
305 BLOB_APPEND_LITERAL(ob, " </tr>\n");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
306 }
307
308
 
 
 
 
 
 
 
 
 
309
310 /* HTML span tags */
311
312 static int html_raw_html_tag(struct Blob *ob, struct Blob *text, void *opaque){
313 blob_append(ob, blob_buffer(text), blob_size(text));
@@ -319,21 +584,21 @@
319 struct Blob *link,
320 enum mkd_autolink type,
321 void *opaque
322 ){
323 if( !link || blob_size(link)<=0 ) return 0;
324 BLOB_APPEND_LITERAL(ob, "<a href=\"");
325 if( type==MKDA_IMPLICIT_EMAIL ) BLOB_APPEND_LITERAL(ob, "mailto:");
326 html_quote(ob, blob_buffer(link), blob_size(link));
327 BLOB_APPEND_LITERAL(ob, "\">");
328 if( type==MKDA_EXPLICIT_EMAIL && blob_size(link)>7 ){
329 /* remove "mailto:" from displayed text */
330 html_escape(ob, blob_buffer(link)+7, blob_size(link)-7);
331 }else{
332 html_escape(ob, blob_buffer(link), blob_size(link));
333 }
334 BLOB_APPEND_LITERAL(ob, "</a>");
335 return 1;
336 }
337
338 /*
339 ** The nSrc bytes at zSrc[] are Pikchr input text (allegedly). Process that
@@ -422,13 +687,13 @@
422 ){
423 if( text==0 ){
424 /* no-op */
425 }else if( nSep<=2 ){
426 /* One or two graves: an in-line code span */
427 BLOB_APPEND_LITERAL(ob, "<code>");
428 html_escape(ob, blob_buffer(text), blob_size(text));
429 BLOB_APPEND_LITERAL(ob, "</code>");
430 }else{
431 /* Three or more graves: a fenced code block */
432 int n = blob_size(text);
433 const char *z = blob_buffer(text);
434 int i;
@@ -460,25 +725,25 @@
460 struct Blob *ob,
461 struct Blob *text,
462 char c,
463 void *opaque
464 ){
465 BLOB_APPEND_LITERAL(ob, "<strong>");
466 BLOB_APPEND_BLOB(ob, text);
467 BLOB_APPEND_LITERAL(ob, "</strong>");
468 return 1;
469 }
470
471 static int html_emphasis(
472 struct Blob *ob,
473 struct Blob *text,
474 char c,
475 void *opaque
476 ){
477 BLOB_APPEND_LITERAL(ob, "<em>");
478 BLOB_APPEND_BLOB(ob, text);
479 BLOB_APPEND_LITERAL(ob, "</em>");
480 return 1;
481 }
482
483 static int html_image(
484 struct Blob *ob,
@@ -485,24 +750,24 @@
485 struct Blob *link,
486 struct Blob *title,
487 struct Blob *alt,
488 void *opaque
489 ){
490 BLOB_APPEND_LITERAL(ob, "<img src=\"");
491 html_quote(ob, blob_buffer(link), blob_size(link));
492 BLOB_APPEND_LITERAL(ob, "\" alt=\"");
493 html_quote(ob, blob_buffer(alt), blob_size(alt));
494 if( title && blob_size(title)>0 ){
495 BLOB_APPEND_LITERAL(ob, "\" title=\"");
496 html_quote(ob, blob_buffer(title), blob_size(title));
497 }
498 BLOB_APPEND_LITERAL(ob, "\" />");
499 return 1;
500 }
501
502 static int html_linebreak(struct Blob *ob, void *opaque){
503 BLOB_APPEND_LITERAL(ob, "<br />\n");
504 return 1;
505 }
506
507 static int html_link(
508 struct Blob *ob,
@@ -523,23 +788,23 @@
523 WIKI_MARKDOWNLINKS
524 ;
525 wiki_resolve_hyperlink(ob, flags, zLink, zClose, sizeof(zClose), 0, zTitle);
526 }
527 if( blob_size(content)==0 ){
528 if( link ) BLOB_APPEND_BLOB(ob, link);
529 }else{
530 BLOB_APPEND_BLOB(ob, content);
531 }
532 blob_append(ob, zClose, -1);
533 return 1;
534 }
535
536 /* Invoked for @name and #tag tagged words, marked up in the
537 ** output text in a way that JS and CSS can do something
538 ** interesting with them. This isn't standard Markdown, so
539 ** it's implementation-specific what occurs here. More, each
540 ** Fossil feature using Markdown is free to apply markup and
541 ** behavior to these in feature-specific ways.
542 */
543 static int html_tagspan(
544 struct Blob *ob, /* Write the output here */
545 struct Blob *text, /* The word after the tag character */
@@ -548,22 +813,22 @@
548 ){
549 if( text==0 ){
550 /* no-op */
551 }else{
552 char cPrefix = '!';
553 BLOB_APPEND_LITERAL(ob, "<span data-");
554 switch (type) {
555 case MKDT_ATREF:
556 cPrefix = '@'; BLOB_APPEND_LITERAL(ob, "atref"); break;
557 case MKDT_HASHTAG:
558 cPrefix = '#'; BLOB_APPEND_LITERAL(ob, "hashtag"); break;
559 case MKDT_NUMTAG:
560 cPrefix = '#'; BLOB_APPEND_LITERAL(ob, "numtag"); break;
561 }
562 BLOB_APPEND_LITERAL(ob, "=\"");
563 html_quote(ob, blob_buffer(text), blob_size(text));
564 BLOB_APPEND_LITERAL(ob, "\"");
565 blob_appendf(ob, ">%c%b</span>", cPrefix,text);
566 }
567 return 1;
568 }
569
@@ -571,13 +836,13 @@
571 struct Blob *ob,
572 struct Blob *text,
573 char c,
574 void *opaque
575 ){
576 BLOB_APPEND_LITERAL(ob, "<strong><em>");
577 BLOB_APPEND_BLOB(ob, text);
578 BLOB_APPEND_LITERAL(ob, "</em></strong>");
579 return 1;
580 }
581
582
583 static void html_normal_text(struct Blob *ob, struct Blob *text, void *opaque){
@@ -597,10 +862,11 @@
597 ){
598 struct mkd_renderer html_renderer = {
599 /* prolog and epilog */
600 html_prolog,
601 html_epilog,
 
602
603 /* block level elements */
604 html_blockcode,
605 html_blockquote,
606 html_blockhtml,
@@ -610,10 +876,11 @@
610 html_list_item,
611 html_paragraph,
612 html_table,
613 html_table_cell,
614 html_table_row,
 
615
616 /* span level elements */
617 html_autolink,
618 html_codespan,
619 html_double_emphasis,
@@ -622,22 +889,30 @@
622 html_linebreak,
623 html_link,
624 html_raw_html_tag,
625 html_tagspan,
626 html_triple_emphasis,
 
627
628 /* low level elements */
629 0, /* entity */
630 html_normal_text,
631
632 /* misc. parameters */
633 "*_", /* emph_chars */
634 0 /* opaque */
635 };
 
 
636 MarkdownToHtml context;
637 memset(&context, 0, sizeof(context));
638 context.output_title = output_title;
 
 
 
 
 
639 html_renderer.opaque = &context;
640 if( output_title ) blob_reset(output_title);
641 blob_reset(output_body);
642 markdown(output_body, input_markdown, &html_renderer);
643 }
644
--- src/markdown_html.c
+++ src/markdown_html.c
@@ -29,37 +29,72 @@
29 struct Blob *output_title,
30 struct Blob *output_body);
31
32 #endif /* INTERFACE */
33
34 /*
35 ** Markdown-internal helper for generating unique link reference IDs.
36 ** Fields provide typed interpretation of the underline memory buffer.
37 */
38 typedef union bitfield64_t bitfield64_t;
39 union bitfield64_t{
40 char c[8]; /* interpret as the array of signed characters */
41 unsigned char b[8]; /* interpret as the array of unsigned characters */
42 };
43
44 /*
45 ** An instance of the following structure is passed through the
46 ** "opaque" pointer.
47 */
48 typedef struct MarkdownToHtml MarkdownToHtml;
49 struct MarkdownToHtml {
50 Blob *output_title; /* Store the title here */
51 bitfield64_t unique; /* Enables construction of unique #id elements */
52
53 #ifndef FOOTNOTES_WITHOUT_URI
54 Blob reqURI; /* REQUEST_URI with escaped quotes */
55 #endif
56 };
57
58
59 /* INTER_BLOCK -- skip a line between block level elements */
60 #define INTER_BLOCK(ob) \
61 do { if( blob_size(ob)>0 ) blob_append_char(ob, '\n'); } while (0)
62
63 /*
64 ** FOOTNOTES_WITHOUT_URI macro was introduced by [2c1f8f3592ef00e0]
65 ** to enable flexibility in rendering of footnote-specific hyperlinks.
66 ** It may be defined for a particular build in order to omit
67 ** full REQUEST_URIs within footnote-specific (and page-local) hyperlinks.
68 ** This *is* used for the builds that incorporate 'base-href-fix' branch
69 ** (which in turn fixes footnotes on the preview tab of /wikiedit page).
70 */
71 #ifndef FOOTNOTES_WITHOUT_URI
72 #define BLOB_APPEND_URI(dest,ctx) blob_appendb(dest,&((ctx)->reqURI))
73 #else
74 #define BLOB_APPEND_URI(dest,ctx)
75 #endif
76
77 /* Converts an integer to a textual base26 representation
78 ** with proper null-termination.
79 * Return empty string if that integer is negative. */
80 static bitfield64_t to_base26(int i, int uppercase){
81 bitfield64_t x;
82 int j;
83 memset( &x, 0, sizeof(x) );
84 if( i >= 0 ){
85 for(j=7; j >= 0; j--){
86 x.b[j] = (unsigned char)(uppercase?'A':'a') + i%26;
87 if( (i /= 26) == 0 ) break;
88 }
89 assert( j > 0 ); /* because 2^32 < 26^7 */
90 for(i=0; i<8-j; i++) x.b[i] = x.b[i+j];
91 for( ; i<8 ; i++) x.b[i] = 0;
92 }
93 assert( x.c[7] == 0 );
94 return x;
95 }
96
97 /* HTML escapes
98 **
99 ** html_escape() converts < to &lt;, > to &gt;, and & to &amp;.
100 ** html_quote() goes further and converts " into &quot; and ' in &#39;.
@@ -78,19 +113,19 @@
113 i++;
114 }
115 blob_append(ob, data+beg, i-beg);
116 while( i<size ){
117 if( data[i]=='<' ){
118 blob_append_literal(ob, "&lt;");
119 }else if( data[i]=='>' ){
120 blob_append_literal(ob, "&gt;");
121 }else if( data[i]=='&' ){
122 blob_append_literal(ob, "&amp;");
123 }else if( data[i]=='"' ){
124 blob_append_literal(ob, "&quot;");
125 }else if( data[i]=='\'' ){
126 blob_append_literal(ob, "&#39;");
127 }else{
128 break;
129 }
130 i++;
131 }
@@ -108,15 +143,15 @@
143 i++;
144 }
145 blob_append(ob, data+beg, i-beg);
146 while( i<size ){
147 if( data[i]=='<' ){
148 blob_append_literal(ob, "&lt;");
149 }else if( data[i]=='>' ){
150 blob_append_literal(ob, "&gt;");
151 }else if( data[i]=='&' ){
152 blob_append_literal(ob, "&amp;");
153 }else{
154 break;
155 }
156 i++;
157 }
@@ -129,17 +164,17 @@
164 /* Size of the prolog: "<div class='markdown'>\n" */
165 #define PROLOG_SIZE 23
166
167 static void html_prolog(struct Blob *ob, void *opaque){
168 INTER_BLOCK(ob);
169 blob_append_literal(ob, "<div class=\"markdown\">\n");
170 assert( blob_size(ob)==PROLOG_SIZE );
171 }
172
173 static void html_epilog(struct Blob *ob, void *opaque){
174 INTER_BLOCK(ob);
175 blob_append_literal(ob, "</div>\n");
176 }
177
178 static void html_blockhtml(struct Blob *ob, struct Blob *text, void *opaque){
179 char *data = blob_buffer(text);
180 size_t size = blob_size(text);
@@ -157,25 +192,25 @@
192 blob_append(title, data+nTag, size - nTag - 5);
193 return;
194 }
195 INTER_BLOCK(ob);
196 blob_append(ob, data, size);
197 blob_append_literal(ob, "\n");
198 }
199
200 static void html_blockcode(struct Blob *ob, struct Blob *text, void *opaque){
201 INTER_BLOCK(ob);
202 blob_append_literal(ob, "<pre><code>");
203 html_escape(ob, blob_buffer(text), blob_size(text));
204 blob_append_literal(ob, "</code></pre>\n");
205 }
206
207 static void html_blockquote(struct Blob *ob, struct Blob *text, void *opaque){
208 INTER_BLOCK(ob);
209 blob_append_literal(ob, "<blockquote>\n");
210 blob_appendb(ob, text);
211 blob_append_literal(ob, "</blockquote>\n");
212 }
213
214 static void html_header(
215 struct Blob *ob,
216 struct Blob *text,
@@ -184,22 +219,22 @@
219 ){
220 struct Blob *title = ((MarkdownToHtml*)opaque)->output_title;
221 /* The first header at the beginning of a text is considered as
222 * a title and not output. */
223 if( blob_size(ob)<=PROLOG_SIZE && title!=0 && blob_size(title)==0 ){
224 blob_appendb(title, text);
225 return;
226 }
227 INTER_BLOCK(ob);
228 blob_appendf(ob, "<h%d>", level);
229 blob_appendb(ob, text);
230 blob_appendf(ob, "</h%d>", level);
231 }
232
233 static void html_hrule(struct Blob *ob, void *opaque){
234 INTER_BLOCK(ob);
235 blob_append_literal(ob, "<hr />\n");
236 }
237
238
239 static void html_list(
240 struct Blob *ob,
@@ -210,11 +245,11 @@
245 char ol[] = "ol";
246 char ul[] = "ul";
247 char *tag = (flags & MKD_LIST_ORDERED) ? ol : ul;
248 INTER_BLOCK(ob);
249 blob_appendf(ob, "<%s>\n", tag);
250 blob_appendb(ob, text);
251 blob_appendf(ob, "</%s>\n", tag);
252 }
253
254 static void html_list_item(
255 struct Blob *ob,
@@ -223,20 +258,20 @@
258 void *opaque
259 ){
260 char *text_data = blob_buffer(text);
261 size_t text_size = blob_size(text);
262 while( text_size>0 && text_data[text_size-1]=='\n' ) text_size--;
263 blob_append_literal(ob, "<li>");
264 blob_append(ob, text_data, text_size);
265 blob_append_literal(ob, "</li>\n");
266 }
267
268 static void html_paragraph(struct Blob *ob, struct Blob *text, void *opaque){
269 INTER_BLOCK(ob);
270 blob_append_literal(ob, "<p>");
271 blob_appendb(ob, text);
272 blob_append_literal(ob, "</p>\n");
273 }
274
275
276 static void html_table(
277 struct Blob *ob,
@@ -243,71 +278,301 @@
278 struct Blob *head_row,
279 struct Blob *rows,
280 void *opaque
281 ){
282 INTER_BLOCK(ob);
283 blob_append_literal(ob, "<table>\n");
284 if( head_row && blob_size(head_row)>0 ){
285 blob_append_literal(ob, "<thead>\n");
286 blob_appendb(ob, head_row);
287 blob_append_literal(ob, "</thead>\n<tbody>\n");
288 }
289 if( rows ){
290 blob_appendb(ob, rows);
291 }
292 if( head_row && blob_size(head_row)>0 ){
293 blob_append_literal(ob, "</tbody>\n");
294 }
295 blob_append_literal(ob, "</table>\n");
296 }
297
298 static void html_table_cell(
299 struct Blob *ob,
300 struct Blob *text,
301 int flags,
302 void *opaque
303 ){
304 if( flags & MKD_CELL_HEAD ){
305 blob_append_literal(ob, " <th");
306 }else{
307 blob_append_literal(ob, " <td");
308 }
309 switch( flags & MKD_CELL_ALIGN_MASK ){
310 case MKD_CELL_ALIGN_LEFT: {
311 blob_append_literal(ob, " align=\"left\"");
312 break;
313 }
314 case MKD_CELL_ALIGN_RIGHT: {
315 blob_append_literal(ob, " align=\"right\"");
316 break;
317 }
318 case MKD_CELL_ALIGN_CENTER: {
319 blob_append_literal(ob, " align=\"center\"");
320 break;
321 }
322 }
323 blob_append_literal(ob, ">");
324 blob_appendb(ob, text);
325 if( flags & MKD_CELL_HEAD ){
326 blob_append_literal(ob, "</th>\n");
327 }else{
328 blob_append_literal(ob, "</td>\n");
329 }
330 }
331
332 static void html_table_row(
333 struct Blob *ob,
334 struct Blob *cells,
335 int flags,
336 void *opaque
337 ){
338 blob_append_literal(ob, " <tr>\n");
339 blob_appendb(ob, cells);
340 blob_append_literal(ob, " </tr>\n");
341 }
342
343 /*
344 ** Render a token of user provided classes.
345 ** If bHTML is true then render HTML for (presumably) visible text,
346 ** otherwise just a space-separated list of the derived classes.
347 */
348 static void append_footnote_upc(
349 struct Blob *ob,
350 const struct Blob *upc, /* token of user-provided classes */
351 int bHTML
352 ){
353 const char *z = blob_buffer(upc);
354 int i, n = blob_size(upc);
355
356 if( n<3 ) return;
357 assert( z[0]=='.' && z[n-1] == ':' );
358 if( bHTML ){
359 blob_append_literal(ob, "<span class='fn-upc'>"
360 "<span class='fn-upcDot'>.</span>");
361 }
362 n = 0;
363 do{
364 z++;
365 if( *z!='.' && *z!=':' ){
366 assert( fossil_isalnum(*z) || *z=='-' );
367 n++;
368 continue;
369 }
370 assert( n );
371 if( bHTML ) blob_append_literal(ob, "<span class='");
372 blob_append_literal(ob, "fn-upc-");
373
374 for(i=-n; i<0; i++){
375 blob_append_char(ob, fossil_tolower(z[i]) );
376 }
377 if( bHTML ){
378 blob_append_literal(ob, "'>");
379 blob_append(ob, z-n, n);
380 blob_append_literal(ob, "</span>");
381 }else{
382 blob_append_char(ob, ' ');
383 }
384 n = 0;
385 if( bHTML ){
386 if( *z==':' ){
387 blob_append_literal(ob,"<span class='fn-upcColon'>:</span>");
388 }else{
389 blob_append_literal(ob,"<span class='fn-upcDot'>.</span>");
390 }
391 }
392 }while( *z != ':' );
393 if( bHTML ) blob_append_literal(ob,"</span>\n");
394 }
395
396 static int html_footnote_ref(
397 struct Blob *ob, const struct Blob *span, const struct Blob *upc,
398 int iMark, int locus, void *opaque
399 ){
400 const struct MarkdownToHtml* ctx = (struct MarkdownToHtml*)opaque;
401 const bitfield64_t l = to_base26(locus-1,0);
402 char pos[32];
403 memset(pos,0,32);
404 assert( locus > 0 );
405 /* expect BUGs if the following yields compiler warnings */
406 if( iMark > 0 ){ /* a regular reference to a footnote */
407 sprintf(pos, "%s-%d-%s", ctx->unique.c, iMark, l.c);
408 if(span && blob_size(span)) {
409 blob_append_literal(ob,"<span class='");
410 append_footnote_upc(ob, upc, 0);
411 blob_append_literal(ob,"notescope' id='noteref");
412 blob_appendf(ob,"%s'>",pos);
413 blob_appendb(ob, span);
414 blob_trim(ob);
415 blob_append_literal(ob,"<sup class='noteref'><a href='");
416 BLOB_APPEND_URI(ob, ctx);
417 blob_appendf(ob,"#footnote%s'>%d</a></sup></span>", pos, iMark);
418 }else{
419 blob_trim(ob);
420 blob_append_literal(ob,"<sup class='");
421 append_footnote_upc(ob, upc, 0);
422 blob_append_literal(ob,"noteref'><a href='");
423 BLOB_APPEND_URI(ob, ctx);
424 blob_appendf(ob,"#footnote%s' id='noteref%s'>%d</a></sup>",
425 pos, pos, iMark);
426 }
427 }else{ /* misreference */
428 assert( iMark == -1 );
429
430 sprintf(pos, "%s-%s", ctx->unique.c, l.c);
431 if(span && blob_size(span)) {
432 blob_appendf(ob, "<span class='notescope' id='misref%s'>", pos);
433 blob_appendb(ob, span);
434 blob_trim(ob);
435 blob_append_literal(ob, "<sup class='noteref misref'><a href='");
436 BLOB_APPEND_URI(ob, ctx);
437 blob_appendf(ob, "#misreference%s'>misref</a></sup></span>", pos);
438 }else{
439 blob_trim(ob);
440 blob_append_literal(ob, "<sup class='noteref misref'><a href='");
441 BLOB_APPEND_URI(ob, ctx);
442 blob_appendf(ob, "#misreference%s' id='misref%s'>", pos, pos);
443 blob_append_literal(ob, "misref</a></sup>");
444 }
445 }
446 return 1;
447 }
448
449 /* Render a single item of the footnotes list.
450 * Each backref gets a unique id to enable dynamic styling. */
451 static void html_footnote_item(
452 struct Blob *ob, const struct Blob *text, int iMark, int nUsed, void *opaque
453 ){
454 const struct MarkdownToHtml* ctx = (struct MarkdownToHtml*)opaque;
455 const char * const unique = ctx->unique.c;
456 assert( nUsed >= 0 );
457 /* expect BUGs if the following yields compiler warnings */
458
459 if( iMark < 0 ){ /* misreferences */
460 assert( iMark == -1 );
461 assert( nUsed );
462 blob_append_literal(ob,"<li class='fn-misreference'>"
463 "<sup class='fn-backrefs'>");
464 if( nUsed == 1 ){
465 blob_appendf(ob,"<a id='misreference%s-a' href='", unique);
466 BLOB_APPEND_URI(ob, ctx);
467 blob_appendf(ob,"#misref%s-a'>^</a>", unique);
468 }else{
469 int i;
470 blob_append_char(ob, '^');
471 for(i=0; i<nUsed && i<26; i++){
472 const int c = i + (unsigned)'a';
473 blob_appendf(ob," <a id='misreference%s-%c' href='", unique,c);
474 BLOB_APPEND_URI(ob, ctx);
475 blob_appendf(ob,"#misref%s-%c'>%c</a>", unique,c, c);
476 }
477 if( i < nUsed ) blob_append_literal(ob," &hellip;");
478 }
479 blob_append_literal(ob,"</sup>\n<span>Misreference</span>");
480 }else if( iMark > 0 ){ /* regular, joined and overnested footnotes */
481 char pos[24];
482 int bJoin = 0;
483 #define _joined_footnote_indicator "<ul class='fn-joined'>"
484 #define _jfi_sz (sizeof(_joined_footnote_indicator)-1)
485 /* make.footnote_item() invocations should pass args accordingly */
486 const struct Blob *upc = text+1;
487 assert( text );
488 /* allow blob_size(text)==0 for constructs like [...](^ [] ()) */
489 memset(pos,0,24);
490 sprintf(pos, "%s-%d", unique, iMark);
491 blob_appendf(ob, "<li id='footnote%s' class='", pos);
492 if( nUsed ){
493 if( blob_size(text)>=_jfi_sz &&
494 !memcmp(blob_buffer(text),_joined_footnote_indicator,_jfi_sz)){
495 bJoin = 1;
496 blob_append_literal(ob, "fn-joined ");
497 }
498 append_footnote_upc(ob, upc, 0);
499 }else{
500 blob_append_literal(ob, "fn-toodeep ");
501 }
502 if( nUsed <= 1 ){
503 blob_append_literal(ob, "fn-monoref'><sup class='fn-backrefs'>");
504 blob_appendf(ob,"<a id='footnote%s-a' href='", pos);
505 BLOB_APPEND_URI(ob, ctx);
506 blob_appendf(ob,"#noteref%s-a'>^</a>", pos);
507 }else{
508 int i;
509 blob_append_literal(ob, "fn-polyref'><sup class='fn-backrefs'>^");
510 for(i=0; i<nUsed && i<26; i++){
511 const int c = i + (unsigned)'a';
512 blob_appendf(ob," <a id='footnote%s-%c' href='", pos,c);
513 BLOB_APPEND_URI(ob, ctx);
514 blob_appendf(ob,"#noteref%s-%c'>%c</a>", pos,c, c);
515 }
516 /* It's unlikely that so many backrefs will be usefull */
517 /* but maybe for some machine generated documents... */
518 for(; i<nUsed && i<676; i++){
519 const bitfield64_t l = to_base26(i,0);
520 blob_appendf(ob," <a id='footnote%s-%s' href='", pos, l.c);
521 BLOB_APPEND_URI(ob, ctx);
522 blob_appendf(ob,"#noteref%s-%s'>%s</a>", pos,l.c, l.c);
523 }
524 if( i < nUsed ) blob_append_literal(ob," &hellip;");
525 }
526 blob_append_literal(ob,"</sup>\n");
527 if( bJoin ){
528 blob_append_literal(ob,"<sup class='fn-joined'></sup><ul>");
529 blob_append(ob,blob_buffer(text)+_jfi_sz,blob_size(text)-_jfi_sz);
530 }else if( nUsed ){
531 append_footnote_upc(ob, upc, 1);
532 blob_appendb(ob, text);
533 }else{
534 blob_append_literal(ob,"<i></i>\n"
535 "<pre><code class='language-markdown'>");
536 if( blob_size(upc) ){
537 blob_appendb(ob, upc);
538 }
539 html_escape(ob, blob_buffer(text), blob_size(text));
540 blob_append_literal(ob,"</code></pre>");
541 }
542 #undef _joined_footnote_indicator
543 #undef _jfi_sz
544 }else{ /* a footnote was defined but wasn't referenced */
545 /* make.footnote_item() invocations should pass args accordingly */
546 const struct Blob *id = text-1, *upc = text+1;
547 assert( !nUsed );
548 assert( text );
549 assert( blob_size(text) );
550 assert( blob_size(id) );
551 blob_append_literal(ob,"<li class='fn-unreferenced'>\n[^&nbsp;<code>");
552 html_escape(ob, blob_buffer(id), blob_size(id));
553 blob_append_literal(ob, "</code>&nbsp;]<i></i>\n"
554 "<pre><code class='language-markdown'>");
555 if( blob_size(upc) ){
556 blob_appendb(ob, upc);
557 }
558 html_escape(ob, blob_buffer(text), blob_size(text));
559 blob_append_literal(ob,"</code></pre>");
560 }
561 blob_append_literal(ob, "\n</li>\n");
562 }
563
564 static void html_footnotes(
565 struct Blob *ob, const struct Blob *items, void *opaque
566 ){
567 if( items && blob_size(items) ){
568 blob_append_literal(ob,
569 "\n<hr class='footnotes-separator'/>\n<ol class='footnotes'>\n");
570 blob_appendb(ob, items);
571 blob_append_literal(ob, "</ol>\n");
572 }
573 }
574
575 /* HTML span tags */
576
577 static int html_raw_html_tag(struct Blob *ob, struct Blob *text, void *opaque){
578 blob_append(ob, blob_buffer(text), blob_size(text));
@@ -319,21 +584,21 @@
584 struct Blob *link,
585 enum mkd_autolink type,
586 void *opaque
587 ){
588 if( !link || blob_size(link)<=0 ) return 0;
589 blob_append_literal(ob, "<a href=\"");
590 if( type==MKDA_IMPLICIT_EMAIL ) blob_append_literal(ob, "mailto:");
591 html_quote(ob, blob_buffer(link), blob_size(link));
592 blob_append_literal(ob, "\">");
593 if( type==MKDA_EXPLICIT_EMAIL && blob_size(link)>7 ){
594 /* remove "mailto:" from displayed text */
595 html_escape(ob, blob_buffer(link)+7, blob_size(link)-7);
596 }else{
597 html_escape(ob, blob_buffer(link), blob_size(link));
598 }
599 blob_append_literal(ob, "</a>");
600 return 1;
601 }
602
603 /*
604 ** The nSrc bytes at zSrc[] are Pikchr input text (allegedly). Process that
@@ -422,13 +687,13 @@
687 ){
688 if( text==0 ){
689 /* no-op */
690 }else if( nSep<=2 ){
691 /* One or two graves: an in-line code span */
692 blob_append_literal(ob, "<code>");
693 html_escape(ob, blob_buffer(text), blob_size(text));
694 blob_append_literal(ob, "</code>");
695 }else{
696 /* Three or more graves: a fenced code block */
697 int n = blob_size(text);
698 const char *z = blob_buffer(text);
699 int i;
@@ -460,25 +725,25 @@
725 struct Blob *ob,
726 struct Blob *text,
727 char c,
728 void *opaque
729 ){
730 blob_append_literal(ob, "<strong>");
731 blob_appendb(ob, text);
732 blob_append_literal(ob, "</strong>");
733 return 1;
734 }
735
736 static int html_emphasis(
737 struct Blob *ob,
738 struct Blob *text,
739 char c,
740 void *opaque
741 ){
742 blob_append_literal(ob, "<em>");
743 blob_appendb(ob, text);
744 blob_append_literal(ob, "</em>");
745 return 1;
746 }
747
748 static int html_image(
749 struct Blob *ob,
@@ -485,24 +750,24 @@
750 struct Blob *link,
751 struct Blob *title,
752 struct Blob *alt,
753 void *opaque
754 ){
755 blob_append_literal(ob, "<img src=\"");
756 html_quote(ob, blob_buffer(link), blob_size(link));
757 blob_append_literal(ob, "\" alt=\"");
758 html_quote(ob, blob_buffer(alt), blob_size(alt));
759 if( title && blob_size(title)>0 ){
760 blob_append_literal(ob, "\" title=\"");
761 html_quote(ob, blob_buffer(title), blob_size(title));
762 }
763 blob_append_literal(ob, "\" />");
764 return 1;
765 }
766
767 static int html_linebreak(struct Blob *ob, void *opaque){
768 blob_append_literal(ob, "<br />\n");
769 return 1;
770 }
771
772 static int html_link(
773 struct Blob *ob,
@@ -523,23 +788,23 @@
788 WIKI_MARKDOWNLINKS
789 ;
790 wiki_resolve_hyperlink(ob, flags, zLink, zClose, sizeof(zClose), 0, zTitle);
791 }
792 if( blob_size(content)==0 ){
793 if( link ) blob_appendb(ob, link);
794 }else{
795 blob_appendb(ob, content);
796 }
797 blob_append(ob, zClose, -1);
798 return 1;
799 }
800
801 /* Invoked for @name and #tag tagged words, marked up in the
802 ** output text in a way that JS and CSS can do something
803 ** interesting with them. This isn't standard Markdown, so
804 ** it's implementation-specific what occurs here. More, each
805 ** Fossil feature using Markdown is free to apply styling and
806 ** behavior to these in feature-specific ways.
807 */
808 static int html_tagspan(
809 struct Blob *ob, /* Write the output here */
810 struct Blob *text, /* The word after the tag character */
@@ -548,22 +813,22 @@
813 ){
814 if( text==0 ){
815 /* no-op */
816 }else{
817 char cPrefix = '!';
818 blob_append_literal(ob, "<span data-");
819 switch (type) {
820 case MKDT_ATREF:
821 cPrefix = '@'; blob_append_literal(ob, "atref"); break;
822 case MKDT_HASHTAG:
823 cPrefix = '#'; blob_append_literal(ob, "hashtag"); break;
824 case MKDT_NUMTAG:
825 cPrefix = '#'; blob_append_literal(ob, "numtag"); break;
826 }
827 blob_append_literal(ob, "=\"");
828 html_quote(ob, blob_buffer(text), blob_size(text));
829 blob_append_literal(ob, "\"");
830 blob_appendf(ob, ">%c%b</span>", cPrefix,text);
831 }
832 return 1;
833 }
834
@@ -571,13 +836,13 @@
836 struct Blob *ob,
837 struct Blob *text,
838 char c,
839 void *opaque
840 ){
841 blob_append_literal(ob, "<strong><em>");
842 blob_appendb(ob, text);
843 blob_append_literal(ob, "</em></strong>");
844 return 1;
845 }
846
847
848 static void html_normal_text(struct Blob *ob, struct Blob *text, void *opaque){
@@ -597,10 +862,11 @@
862 ){
863 struct mkd_renderer html_renderer = {
864 /* prolog and epilog */
865 html_prolog,
866 html_epilog,
867 html_footnotes,
868
869 /* block level elements */
870 html_blockcode,
871 html_blockquote,
872 html_blockhtml,
@@ -610,10 +876,11 @@
876 html_list_item,
877 html_paragraph,
878 html_table,
879 html_table_cell,
880 html_table_row,
881 html_footnote_item,
882
883 /* span level elements */
884 html_autolink,
885 html_codespan,
886 html_double_emphasis,
@@ -622,22 +889,30 @@
889 html_linebreak,
890 html_link,
891 html_raw_html_tag,
892 html_tagspan,
893 html_triple_emphasis,
894 html_footnote_ref,
895
896 /* low level elements */
897 0, /* entity */
898 html_normal_text,
899
900 /* misc. parameters */
901 "*_", /* emph_chars */
902 0 /* opaque */
903 };
904 static int invocation = -1; /* no marker for the first document */
905 static const char* zRU = 0; /* REQUEST_URI with escaped quotes */
906 MarkdownToHtml context;
907 memset(&context, 0, sizeof(context));
908 context.output_title = output_title;
909 context.unique = to_base26(invocation++,1);
910 if( !zRU ) zRU = escape_quotes(PD("REQUEST_URI",""));
911 #ifndef FOOTNOTES_WITHOUT_URI
912 blob_set( &context.reqURI, zRU );
913 #endif
914 html_renderer.opaque = &context;
915 if( output_title ) blob_reset(output_title);
916 blob_reset(output_body);
917 markdown(output_body, input_markdown, &html_renderer);
918 }
919
+1 -2
--- src/merge.c
+++ src/merge.c
@@ -407,12 +407,11 @@
407407
}
408408
if( forceFlag==0 && leaf_is_closed(vid) ){
409409
fossil_fatal("cannot merge into a closed leaf. Use --force to override");
410410
}
411411
if( !dryRunFlag ){
412
- if( autosync_loop(SYNC_PULL + SYNC_VERBOSE*verboseFlag,
413
- db_get_int("autosync-tries", 1), 1) ){
412
+ if( autosync_loop(SYNC_PULL + SYNC_VERBOSE*verboseFlag, 1, "merge") ){
414413
fossil_fatal("merge abandoned due to sync failure");
415414
}
416415
}
417416
418417
/* Find mid, the artifactID of the version to be merged into the current
419418
--- src/merge.c
+++ src/merge.c
@@ -407,12 +407,11 @@
407 }
408 if( forceFlag==0 && leaf_is_closed(vid) ){
409 fossil_fatal("cannot merge into a closed leaf. Use --force to override");
410 }
411 if( !dryRunFlag ){
412 if( autosync_loop(SYNC_PULL + SYNC_VERBOSE*verboseFlag,
413 db_get_int("autosync-tries", 1), 1) ){
414 fossil_fatal("merge abandoned due to sync failure");
415 }
416 }
417
418 /* Find mid, the artifactID of the version to be merged into the current
419
--- src/merge.c
+++ src/merge.c
@@ -407,12 +407,11 @@
407 }
408 if( forceFlag==0 && leaf_is_closed(vid) ){
409 fossil_fatal("cannot merge into a closed leaf. Use --force to override");
410 }
411 if( !dryRunFlag ){
412 if( autosync_loop(SYNC_PULL + SYNC_VERBOSE*verboseFlag, 1, "merge") ){
 
413 fossil_fatal("merge abandoned due to sync failure");
414 }
415 }
416
417 /* Find mid, the artifactID of the version to be merged into the current
418
+1 -1
--- src/repolist.c
+++ src/repolist.c
@@ -210,11 +210,11 @@
210210
if( rNow <= x.rMTime ){
211211
x.rMTime = rNow;
212212
}else if( x.rMTime<0.0 ){
213213
x.rMTime = rNow;
214214
}
215
- iAge = (int)(rNow - x.rMTime)*86400;
215
+ iAge = (double)(rNow - x.rMTime)*86400;
216216
zAge = human_readable_age(rNow - x.rMTime);
217217
if( x.rMTime==0.0 ){
218218
/* This repository has no entry in the "event" table.
219219
** Its age will still be maximum, so data-sortkey will work. */
220220
zAge = mprintf("unknown");
221221
--- src/repolist.c
+++ src/repolist.c
@@ -210,11 +210,11 @@
210 if( rNow <= x.rMTime ){
211 x.rMTime = rNow;
212 }else if( x.rMTime<0.0 ){
213 x.rMTime = rNow;
214 }
215 iAge = (int)(rNow - x.rMTime)*86400;
216 zAge = human_readable_age(rNow - x.rMTime);
217 if( x.rMTime==0.0 ){
218 /* This repository has no entry in the "event" table.
219 ** Its age will still be maximum, so data-sortkey will work. */
220 zAge = mprintf("unknown");
221
--- src/repolist.c
+++ src/repolist.c
@@ -210,11 +210,11 @@
210 if( rNow <= x.rMTime ){
211 x.rMTime = rNow;
212 }else if( x.rMTime<0.0 ){
213 x.rMTime = rNow;
214 }
215 iAge = (double)(rNow - x.rMTime)*86400;
216 zAge = human_readable_age(rNow - x.rMTime);
217 if( x.rMTime==0.0 ){
218 /* This repository has no entry in the "event" table.
219 ** Its age will still be maximum, so data-sortkey will work. */
220 zAge = mprintf("unknown");
221
+1 -1
--- src/stat.c
+++ src/stat.c
@@ -963,11 +963,11 @@
963963
*/
964964
if( !g.perm.Write && !db_get_boolean("artifact_stats_enable",0) ){
965965
login_needed(g.anon.Write);
966966
return;
967967
}
968
- load_control();
968
+ fossil_nice_default();
969969
970970
style_set_current_feature("stat");
971971
style_header("Artifact Statistics");
972972
style_submenu_element("Repository Stats", "stat");
973973
style_submenu_element("Artifact List", "bloblist");
974974
--- src/stat.c
+++ src/stat.c
@@ -963,11 +963,11 @@
963 */
964 if( !g.perm.Write && !db_get_boolean("artifact_stats_enable",0) ){
965 login_needed(g.anon.Write);
966 return;
967 }
968 load_control();
969
970 style_set_current_feature("stat");
971 style_header("Artifact Statistics");
972 style_submenu_element("Repository Stats", "stat");
973 style_submenu_element("Artifact List", "bloblist");
974
--- src/stat.c
+++ src/stat.c
@@ -963,11 +963,11 @@
963 */
964 if( !g.perm.Write && !db_get_boolean("artifact_stats_enable",0) ){
965 login_needed(g.anon.Write);
966 return;
967 }
968 fossil_nice_default();
969
970 style_set_current_feature("stat");
971 style_header("Artifact Statistics");
972 style_submenu_element("Repository Stats", "stat");
973 style_submenu_element("Artifact List", "bloblist");
974
+8 -1
--- src/style.c
+++ src/style.c
@@ -782,10 +782,17 @@
782782
image_url_var("background");
783783
if( !login_is_nobody() ){
784784
Th_Store("login", g.zLogin);
785785
}
786786
Th_MaybeStore("current_feature", feature_from_page_path(local_zCurrentPage) );
787
+ if( g.ftntsIssues[0] || g.ftntsIssues[1] ||
788
+ g.ftntsIssues[2] || g.ftntsIssues[3] ){
789
+ char buf[80];
790
+ sprintf(&buf[0],"%i %i %i %i",g.ftntsIssues[0],g.ftntsIssues[1],
791
+ g.ftntsIssues[2],g.ftntsIssues[3]);
792
+ Th_Store("footnotes_issues_counters", buf);
793
+ }
787794
}
788795
789796
/*
790797
** Draw the header.
791798
*/
@@ -1210,11 +1217,11 @@
12101217
** default.css. */
12111218
fossil_free(zFile);
12121219
}
12131220
12141221
/*
1215
-** WEBPAGE: style.css
1222
+** WEBPAGE: style.css loadavg-exempt
12161223
**
12171224
** Return the style sheet. The style sheet is assemblied from
12181225
** multiple sources, in order:
12191226
**
12201227
** (1) The built-in "default.css" style sheet containing basic defaults.
12211228
--- src/style.c
+++ src/style.c
@@ -782,10 +782,17 @@
782 image_url_var("background");
783 if( !login_is_nobody() ){
784 Th_Store("login", g.zLogin);
785 }
786 Th_MaybeStore("current_feature", feature_from_page_path(local_zCurrentPage) );
 
 
 
 
 
 
 
787 }
788
789 /*
790 ** Draw the header.
791 */
@@ -1210,11 +1217,11 @@
1210 ** default.css. */
1211 fossil_free(zFile);
1212 }
1213
1214 /*
1215 ** WEBPAGE: style.css
1216 **
1217 ** Return the style sheet. The style sheet is assemblied from
1218 ** multiple sources, in order:
1219 **
1220 ** (1) The built-in "default.css" style sheet containing basic defaults.
1221
--- src/style.c
+++ src/style.c
@@ -782,10 +782,17 @@
782 image_url_var("background");
783 if( !login_is_nobody() ){
784 Th_Store("login", g.zLogin);
785 }
786 Th_MaybeStore("current_feature", feature_from_page_path(local_zCurrentPage) );
787 if( g.ftntsIssues[0] || g.ftntsIssues[1] ||
788 g.ftntsIssues[2] || g.ftntsIssues[3] ){
789 char buf[80];
790 sprintf(&buf[0],"%i %i %i %i",g.ftntsIssues[0],g.ftntsIssues[1],
791 g.ftntsIssues[2],g.ftntsIssues[3]);
792 Th_Store("footnotes_issues_counters", buf);
793 }
794 }
795
796 /*
797 ** Draw the header.
798 */
@@ -1210,11 +1217,11 @@
1217 ** default.css. */
1218 fossil_free(zFile);
1219 }
1220
1221 /*
1222 ** WEBPAGE: style.css loadavg-exempt
1223 **
1224 ** Return the style sheet. The style sheet is assemblied from
1225 ** multiple sources, in order:
1226 **
1227 ** (1) The built-in "default.css" style sheet containing basic defaults.
1228
+8 -5
--- src/sync.c
+++ src/sync.c
@@ -112,18 +112,18 @@
112112
** not acquired unless autosync is set to "on".
113113
**
114114
** If dont-push setting is true, that is the same as having autosync
115115
** set to pullonly.
116116
*/
117
-int autosync(int flags){
117
+static int autosync(int flags, const char *zSubsys){
118118
const char *zAutosync;
119119
int rc;
120120
int configSync = 0; /* configuration changes transferred */
121121
if( g.fNoSync ){
122122
return 0;
123123
}
124
- zAutosync = db_get("autosync", 0);
124
+ zAutosync = db_get_for_subsystem("autosync", zSubsys);
125125
if( zAutosync==0 ) zAutosync = "on"; /* defend against misconfig */
126126
if( is_false(zAutosync) ) return 0;
127127
if( db_get_boolean("dont-push",0)
128128
|| sqlite3_strglob("*pull*", zAutosync)==0
129129
){
@@ -150,25 +150,28 @@
150150
return rc;
151151
}
152152
153153
/*
154154
** This routine will try a number of times to perform autosync with a
155
-** 0.5 second sleep between attempts.
155
+** 0.5 second sleep between attempts. The number of attempts is determined
156
+** by the "autosync-tries" setting, which defaults to 1.
156157
**
157158
** Return zero on success and non-zero on a failure. If failure occurs
158159
** and doPrompt flag is true, ask the user if they want to continue, and
159160
** if they answer "yes" then return zero in spite of the failure.
160161
*/
161
-int autosync_loop(int flags, int nTries, int doPrompt){
162
+int autosync_loop(int flags, int doPrompt, const char *zSubsystem){
162163
int n = 0;
163164
int rc = 0;
165
+ int nTries = db_get_int("autosync-tries", 1);
164166
if( (flags & (SYNC_PUSH|SYNC_PULL))==(SYNC_PUSH|SYNC_PULL)
165167
&& db_get_boolean("uv-sync",0)
166168
){
167169
flags |= SYNC_UNVERSIONED;
168170
}
169
- while( (n==0 || n<nTries) && (rc=autosync(flags)) ){
171
+ if( nTries<1 ) nTries = 1;
172
+ while( (n==0 || n<nTries) && (rc=autosync(flags, zSubsystem)) ){
170173
if( rc ){
171174
if( ++n<nTries ){
172175
fossil_warning("Autosync failed, making another attempt.");
173176
sqlite3_sleep(500);
174177
}else{
175178
--- src/sync.c
+++ src/sync.c
@@ -112,18 +112,18 @@
112 ** not acquired unless autosync is set to "on".
113 **
114 ** If dont-push setting is true, that is the same as having autosync
115 ** set to pullonly.
116 */
117 int autosync(int flags){
118 const char *zAutosync;
119 int rc;
120 int configSync = 0; /* configuration changes transferred */
121 if( g.fNoSync ){
122 return 0;
123 }
124 zAutosync = db_get("autosync", 0);
125 if( zAutosync==0 ) zAutosync = "on"; /* defend against misconfig */
126 if( is_false(zAutosync) ) return 0;
127 if( db_get_boolean("dont-push",0)
128 || sqlite3_strglob("*pull*", zAutosync)==0
129 ){
@@ -150,25 +150,28 @@
150 return rc;
151 }
152
153 /*
154 ** This routine will try a number of times to perform autosync with a
155 ** 0.5 second sleep between attempts.
 
156 **
157 ** Return zero on success and non-zero on a failure. If failure occurs
158 ** and doPrompt flag is true, ask the user if they want to continue, and
159 ** if they answer "yes" then return zero in spite of the failure.
160 */
161 int autosync_loop(int flags, int nTries, int doPrompt){
162 int n = 0;
163 int rc = 0;
 
164 if( (flags & (SYNC_PUSH|SYNC_PULL))==(SYNC_PUSH|SYNC_PULL)
165 && db_get_boolean("uv-sync",0)
166 ){
167 flags |= SYNC_UNVERSIONED;
168 }
169 while( (n==0 || n<nTries) && (rc=autosync(flags)) ){
 
170 if( rc ){
171 if( ++n<nTries ){
172 fossil_warning("Autosync failed, making another attempt.");
173 sqlite3_sleep(500);
174 }else{
175
--- src/sync.c
+++ src/sync.c
@@ -112,18 +112,18 @@
112 ** not acquired unless autosync is set to "on".
113 **
114 ** If dont-push setting is true, that is the same as having autosync
115 ** set to pullonly.
116 */
117 static int autosync(int flags, const char *zSubsys){
118 const char *zAutosync;
119 int rc;
120 int configSync = 0; /* configuration changes transferred */
121 if( g.fNoSync ){
122 return 0;
123 }
124 zAutosync = db_get_for_subsystem("autosync", zSubsys);
125 if( zAutosync==0 ) zAutosync = "on"; /* defend against misconfig */
126 if( is_false(zAutosync) ) return 0;
127 if( db_get_boolean("dont-push",0)
128 || sqlite3_strglob("*pull*", zAutosync)==0
129 ){
@@ -150,25 +150,28 @@
150 return rc;
151 }
152
153 /*
154 ** This routine will try a number of times to perform autosync with a
155 ** 0.5 second sleep between attempts. The number of attempts is determined
156 ** by the "autosync-tries" setting, which defaults to 1.
157 **
158 ** Return zero on success and non-zero on a failure. If failure occurs
159 ** and doPrompt flag is true, ask the user if they want to continue, and
160 ** if they answer "yes" then return zero in spite of the failure.
161 */
162 int autosync_loop(int flags, int doPrompt, const char *zSubsystem){
163 int n = 0;
164 int rc = 0;
165 int nTries = db_get_int("autosync-tries", 1);
166 if( (flags & (SYNC_PUSH|SYNC_PULL))==(SYNC_PUSH|SYNC_PULL)
167 && db_get_boolean("uv-sync",0)
168 ){
169 flags |= SYNC_UNVERSIONED;
170 }
171 if( nTries<1 ) nTries = 1;
172 while( (n==0 || n<nTries) && (rc=autosync(flags, zSubsystem)) ){
173 if( rc ){
174 if( ++n<nTries ){
175 fossil_warning("Autosync failed, making another attempt.");
176 sqlite3_sleep(500);
177 }else{
178
+1 -1
--- src/tar.c
+++ src/tar.c
@@ -756,11 +756,11 @@
756756
Blob tarball; /* Tarball accumulated here */
757757
const char *z;
758758
759759
login_check_credentials();
760760
if( !g.perm.Zip ){ login_needed(g.anon.Zip); return; }
761
- load_control();
761
+ fossil_nice_default();
762762
zName = fossil_strdup(PD("name",""));
763763
z = P("r");
764764
if( z==0 ) z = P("uuid");
765765
if( z==0 ) z = tar_uuid_from_name(&zName);
766766
if( z==0 ) z = "trunk";
767767
--- src/tar.c
+++ src/tar.c
@@ -756,11 +756,11 @@
756 Blob tarball; /* Tarball accumulated here */
757 const char *z;
758
759 login_check_credentials();
760 if( !g.perm.Zip ){ login_needed(g.anon.Zip); return; }
761 load_control();
762 zName = fossil_strdup(PD("name",""));
763 z = P("r");
764 if( z==0 ) z = P("uuid");
765 if( z==0 ) z = tar_uuid_from_name(&zName);
766 if( z==0 ) z = "trunk";
767
--- src/tar.c
+++ src/tar.c
@@ -756,11 +756,11 @@
756 Blob tarball; /* Tarball accumulated here */
757 const char *z;
758
759 login_check_credentials();
760 if( !g.perm.Zip ){ login_needed(g.anon.Zip); return; }
761 fossil_nice_default();
762 zName = fossil_strdup(PD("name",""));
763 z = P("r");
764 if( z==0 ) z = P("uuid");
765 if( z==0 ) z = tar_uuid_from_name(&zName);
766 if( z==0 ) z = "trunk";
767
+1 -2
--- src/update.c
+++ src/update.c
@@ -165,12 +165,11 @@
165165
166166
db_must_be_within_tree();
167167
vid = db_lget_int("checkout", 0);
168168
user_select();
169169
if( !dryRunFlag && !internalUpdate && !bNosync ){
170
- if( autosync_loop(SYNC_PULL + SYNC_VERBOSE*verboseFlag,
171
- db_get_int("autosync-tries", 1), 1) ){
170
+ if( autosync_loop(SYNC_PULL + SYNC_VERBOSE*verboseFlag, 1, "update") ){
172171
fossil_fatal("update abandoned due to sync failure");
173172
}
174173
}
175174
176175
/* Create any empty directories now, as well as after the update,
177176
--- src/update.c
+++ src/update.c
@@ -165,12 +165,11 @@
165
166 db_must_be_within_tree();
167 vid = db_lget_int("checkout", 0);
168 user_select();
169 if( !dryRunFlag && !internalUpdate && !bNosync ){
170 if( autosync_loop(SYNC_PULL + SYNC_VERBOSE*verboseFlag,
171 db_get_int("autosync-tries", 1), 1) ){
172 fossil_fatal("update abandoned due to sync failure");
173 }
174 }
175
176 /* Create any empty directories now, as well as after the update,
177
--- src/update.c
+++ src/update.c
@@ -165,12 +165,11 @@
165
166 db_must_be_within_tree();
167 vid = db_lget_int("checkout", 0);
168 user_select();
169 if( !dryRunFlag && !internalUpdate && !bNosync ){
170 if( autosync_loop(SYNC_PULL + SYNC_VERBOSE*verboseFlag, 1, "update") ){
 
171 fossil_fatal("update abandoned due to sync failure");
172 }
173 }
174
175 /* Create any empty directories now, as well as after the update,
176
+19
--- src/util.c
+++ src/util.c
@@ -896,5 +896,24 @@
896896
}
897897
}
898898
#endif
899899
return zBrowser;
900900
}
901
+
902
+/*
903
+** On non-Windows systems, calls nice(2) with the given level. Errors
904
+** are ignored. On Windows this is a no-op.
905
+*/
906
+void fossil_nice(int level){
907
+#ifndef _WIN32
908
+ nice(level);
909
+#else
910
+ (void)level;
911
+#endif
912
+}
913
+
914
+/*
915
+** Calls fossil_nice() with a default level.
916
+*/
917
+void fossil_nice_default(void){
918
+ fossil_nice(19);
919
+}
901920
--- src/util.c
+++ src/util.c
@@ -896,5 +896,24 @@
896 }
897 }
898 #endif
899 return zBrowser;
900 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
901
--- src/util.c
+++ src/util.c
@@ -896,5 +896,24 @@
896 }
897 }
898 #endif
899 return zBrowser;
900 }
901
902 /*
903 ** On non-Windows systems, calls nice(2) with the given level. Errors
904 ** are ignored. On Windows this is a no-op.
905 */
906 void fossil_nice(int level){
907 #ifndef _WIN32
908 nice(level);
909 #else
910 (void)level;
911 #endif
912 }
913
914 /*
915 ** Calls fossil_nice() with a default level.
916 */
917 void fossil_nice_default(void){
918 fossil_nice(19);
919 }
920
+14 -2
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1895,18 +1895,20 @@
18951895
** Render markdown in TEXT as HTML on stdout, where TEXT
18961896
** may be a file name or a markdown-formatted string.
18971897
**
18981898
** Options:
18991899
**
1900
-** --safe Restrict the output to use only "safe" HTML
1900
+** --safe Restrict the output to use only "safe" HTML
1901
+** --lint-footnotes Print stats for footnotes-related issues
19011902
*/
19021903
void test_markdown_render(void){
19031904
Blob in, out;
19041905
int i;
1905
- int bSafe = 0;
1906
+ int bSafe = 0, bFnLint = 0;
19061907
db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
19071908
bSafe = find_option("safe",0,0)!=0;
1909
+ bFnLint = find_option("lint-footnotes",0,0)!=0;
19081910
verify_all_options();
19091911
for(i=2; i<g.argc; i++){
19101912
blob_zero(&out);
19111913
if(file_isfile(g.argv[i], ExtFILE)){
19121914
blob_read_from_file(&in, g.argv[i], ExtFILE);
@@ -1924,10 +1926,20 @@
19241926
safe_html(&out);
19251927
blob_write_to_file(&out, "-");
19261928
blob_reset(&in);
19271929
blob_reset(&out);
19281930
}
1931
+ if( bFnLint && (g.ftntsIssues[0] || g.ftntsIssues[1]
1932
+ || g.ftntsIssues[2] || g.ftntsIssues[3] )){
1933
+ fossil_fatal("There were issues with footnotes:\n"
1934
+ " %8d misreference%s\n"
1935
+ " %8d unreferenced\n"
1936
+ " %8d splitted\n"
1937
+ " %8d overnested",
1938
+ g.ftntsIssues[0], g.ftntsIssues[0]==1?"":"s",
1939
+ g.ftntsIssues[1], g.ftntsIssues[2], g.ftntsIssues[3]);
1940
+ }
19291941
}
19301942
19311943
/*
19321944
** Search for a <title>...</title> at the beginning of a wiki page.
19331945
** Return true (nonzero) if a title is found. Return zero if there is
19341946
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1895,18 +1895,20 @@
1895 ** Render markdown in TEXT as HTML on stdout, where TEXT
1896 ** may be a file name or a markdown-formatted string.
1897 **
1898 ** Options:
1899 **
1900 ** --safe Restrict the output to use only "safe" HTML
 
1901 */
1902 void test_markdown_render(void){
1903 Blob in, out;
1904 int i;
1905 int bSafe = 0;
1906 db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
1907 bSafe = find_option("safe",0,0)!=0;
 
1908 verify_all_options();
1909 for(i=2; i<g.argc; i++){
1910 blob_zero(&out);
1911 if(file_isfile(g.argv[i], ExtFILE)){
1912 blob_read_from_file(&in, g.argv[i], ExtFILE);
@@ -1924,10 +1926,20 @@
1924 safe_html(&out);
1925 blob_write_to_file(&out, "-");
1926 blob_reset(&in);
1927 blob_reset(&out);
1928 }
 
 
 
 
 
 
 
 
 
 
1929 }
1930
1931 /*
1932 ** Search for a <title>...</title> at the beginning of a wiki page.
1933 ** Return true (nonzero) if a title is found. Return zero if there is
1934
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1895,18 +1895,20 @@
1895 ** Render markdown in TEXT as HTML on stdout, where TEXT
1896 ** may be a file name or a markdown-formatted string.
1897 **
1898 ** Options:
1899 **
1900 ** --safe Restrict the output to use only "safe" HTML
1901 ** --lint-footnotes Print stats for footnotes-related issues
1902 */
1903 void test_markdown_render(void){
1904 Blob in, out;
1905 int i;
1906 int bSafe = 0, bFnLint = 0;
1907 db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
1908 bSafe = find_option("safe",0,0)!=0;
1909 bFnLint = find_option("lint-footnotes",0,0)!=0;
1910 verify_all_options();
1911 for(i=2; i<g.argc; i++){
1912 blob_zero(&out);
1913 if(file_isfile(g.argv[i], ExtFILE)){
1914 blob_read_from_file(&in, g.argv[i], ExtFILE);
@@ -1924,10 +1926,20 @@
1926 safe_html(&out);
1927 blob_write_to_file(&out, "-");
1928 blob_reset(&in);
1929 blob_reset(&out);
1930 }
1931 if( bFnLint && (g.ftntsIssues[0] || g.ftntsIssues[1]
1932 || g.ftntsIssues[2] || g.ftntsIssues[3] )){
1933 fossil_fatal("There were issues with footnotes:\n"
1934 " %8d misreference%s\n"
1935 " %8d unreferenced\n"
1936 " %8d splitted\n"
1937 " %8d overnested",
1938 g.ftntsIssues[0], g.ftntsIssues[0]==1?"":"s",
1939 g.ftntsIssues[1], g.ftntsIssues[2], g.ftntsIssues[3]);
1940 }
1941 }
1942
1943 /*
1944 ** Search for a <title>...</title> at the beginning of a wiki page.
1945 ** Return true (nonzero) if a title is found. Return zero if there is
1946
+14 -2
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1895,18 +1895,20 @@
18951895
** Render markdown in TEXT as HTML on stdout, where TEXT
18961896
** may be a file name or a markdown-formatted string.
18971897
**
18981898
** Options:
18991899
**
1900
-** --safe Restrict the output to use only "safe" HTML
1900
+** --safe Restrict the output to use only "safe" HTML
1901
+** --lint-footnotes Print stats for footnotes-related issues
19011902
*/
19021903
void test_markdown_render(void){
19031904
Blob in, out;
19041905
int i;
1905
- int bSafe = 0;
1906
+ int bSafe = 0, bFnLint = 0;
19061907
db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
19071908
bSafe = find_option("safe",0,0)!=0;
1909
+ bFnLint = find_option("lint-footnotes",0,0)!=0;
19081910
verify_all_options();
19091911
for(i=2; i<g.argc; i++){
19101912
blob_zero(&out);
19111913
if(file_isfile(g.argv[i], ExtFILE)){
19121914
blob_read_from_file(&in, g.argv[i], ExtFILE);
@@ -1924,10 +1926,20 @@
19241926
safe_html(&out);
19251927
blob_write_to_file(&out, "-");
19261928
blob_reset(&in);
19271929
blob_reset(&out);
19281930
}
1931
+ if( bFnLint && (g.ftntsIssues[0] || g.ftntsIssues[1]
1932
+ || g.ftntsIssues[2] || g.ftntsIssues[3] )){
1933
+ fossil_fatal("There were issues with footnotes:\n"
1934
+ " %8d misreference%s\n"
1935
+ " %8d unreferenced\n"
1936
+ " %8d splitted\n"
1937
+ " %8d overnested",
1938
+ g.ftntsIssues[0], g.ftntsIssues[0]==1?"":"s",
1939
+ g.ftntsIssues[1], g.ftntsIssues[2], g.ftntsIssues[3]);
1940
+ }
19291941
}
19301942
19311943
/*
19321944
** Search for a <title>...</title> at the beginning of a wiki page.
19331945
** Return true (nonzero) if a title is found. Return zero if there is
19341946
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1895,18 +1895,20 @@
1895 ** Render markdown in TEXT as HTML on stdout, where TEXT
1896 ** may be a file name or a markdown-formatted string.
1897 **
1898 ** Options:
1899 **
1900 ** --safe Restrict the output to use only "safe" HTML
 
1901 */
1902 void test_markdown_render(void){
1903 Blob in, out;
1904 int i;
1905 int bSafe = 0;
1906 db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
1907 bSafe = find_option("safe",0,0)!=0;
 
1908 verify_all_options();
1909 for(i=2; i<g.argc; i++){
1910 blob_zero(&out);
1911 if(file_isfile(g.argv[i], ExtFILE)){
1912 blob_read_from_file(&in, g.argv[i], ExtFILE);
@@ -1924,10 +1926,20 @@
1924 safe_html(&out);
1925 blob_write_to_file(&out, "-");
1926 blob_reset(&in);
1927 blob_reset(&out);
1928 }
 
 
 
 
 
 
 
 
 
 
1929 }
1930
1931 /*
1932 ** Search for a <title>...</title> at the beginning of a wiki page.
1933 ** Return true (nonzero) if a title is found. Return zero if there is
1934
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1895,18 +1895,20 @@
1895 ** Render markdown in TEXT as HTML on stdout, where TEXT
1896 ** may be a file name or a markdown-formatted string.
1897 **
1898 ** Options:
1899 **
1900 ** --safe Restrict the output to use only "safe" HTML
1901 ** --lint-footnotes Print stats for footnotes-related issues
1902 */
1903 void test_markdown_render(void){
1904 Blob in, out;
1905 int i;
1906 int bSafe = 0, bFnLint = 0;
1907 db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
1908 bSafe = find_option("safe",0,0)!=0;
1909 bFnLint = find_option("lint-footnotes",0,0)!=0;
1910 verify_all_options();
1911 for(i=2; i<g.argc; i++){
1912 blob_zero(&out);
1913 if(file_isfile(g.argv[i], ExtFILE)){
1914 blob_read_from_file(&in, g.argv[i], ExtFILE);
@@ -1924,10 +1926,20 @@
1926 safe_html(&out);
1927 blob_write_to_file(&out, "-");
1928 blob_reset(&in);
1929 blob_reset(&out);
1930 }
1931 if( bFnLint && (g.ftntsIssues[0] || g.ftntsIssues[1]
1932 || g.ftntsIssues[2] || g.ftntsIssues[3] )){
1933 fossil_fatal("There were issues with footnotes:\n"
1934 " %8d misreference%s\n"
1935 " %8d unreferenced\n"
1936 " %8d splitted\n"
1937 " %8d overnested",
1938 g.ftntsIssues[0], g.ftntsIssues[0]==1?"":"s",
1939 g.ftntsIssues[1], g.ftntsIssues[2], g.ftntsIssues[3]);
1940 }
1941 }
1942
1943 /*
1944 ** Search for a <title>...</title> at the beginning of a wiki page.
1945 ** Return true (nonzero) if a title is found. Return zero if there is
1946
+2 -2
--- src/zip.c
+++ src/zip.c
@@ -255,11 +255,11 @@
255255
){
256256
z_stream stream;
257257
int nameLen;
258258
int toOut = 0;
259259
int iStart;
260
- int iCRC = 0;
260
+ unsigned long iCRC = 0;
261261
int nByte = 0;
262262
int nByteCompr = 0;
263263
int nBlob; /* Size of the blob */
264264
int iMethod; /* Compression method. */
265265
int iMode = 0644; /* Access permissions */
@@ -921,11 +921,11 @@
921921
zType = "SQL";
922922
}else{
923923
eType = ARCHIVE_ZIP;
924924
zType = "ZIP";
925925
}
926
- load_control();
926
+ fossil_nice_default();
927927
zName = fossil_strdup(PD("name",""));
928928
z = P("r");
929929
if( z==0 ) z = P("uuid");
930930
if( z==0 ) z = tar_uuid_from_name(&zName);
931931
if( z==0 ) z = "trunk";
932932
933933
ADDED test/markdown-test3.md
--- src/zip.c
+++ src/zip.c
@@ -255,11 +255,11 @@
255 ){
256 z_stream stream;
257 int nameLen;
258 int toOut = 0;
259 int iStart;
260 int iCRC = 0;
261 int nByte = 0;
262 int nByteCompr = 0;
263 int nBlob; /* Size of the blob */
264 int iMethod; /* Compression method. */
265 int iMode = 0644; /* Access permissions */
@@ -921,11 +921,11 @@
921 zType = "SQL";
922 }else{
923 eType = ARCHIVE_ZIP;
924 zType = "ZIP";
925 }
926 load_control();
927 zName = fossil_strdup(PD("name",""));
928 z = P("r");
929 if( z==0 ) z = P("uuid");
930 if( z==0 ) z = tar_uuid_from_name(&zName);
931 if( z==0 ) z = "trunk";
932
933 DDED test/markdown-test3.md
--- src/zip.c
+++ src/zip.c
@@ -255,11 +255,11 @@
255 ){
256 z_stream stream;
257 int nameLen;
258 int toOut = 0;
259 int iStart;
260 unsigned long iCRC = 0;
261 int nByte = 0;
262 int nByteCompr = 0;
263 int nBlob; /* Size of the blob */
264 int iMethod; /* Compression method. */
265 int iMode = 0644; /* Access permissions */
@@ -921,11 +921,11 @@
921 zType = "SQL";
922 }else{
923 eType = ARCHIVE_ZIP;
924 zType = "ZIP";
925 }
926 fossil_nice_default();
927 zName = fossil_strdup(PD("name",""));
928 z = P("r");
929 if( z==0 ) z = P("uuid");
930 if( z==0 ) z = tar_uuid_from_name(&zName);
931 if( z==0 ) z = "trunk";
932
933 DDED test/markdown-test3.md
--- a/test/markdown-test3.md
+++ b/test/markdown-test3.md
@@ -0,0 +1,194 @@
1
+
2
+Markdown Footnotes Test Document
3
+================================
4
+
5
+**This document** should help with testing of footnotes support that
6
+is introduced by the ["`markdown-footnotes`"][branch] branch.
7
+It **might look pretty misformatted unless rendered by the proper Fossil
8
+executable** that incorporates the abovementioned branch.[^1]
9
+That is also a humble attempt to explore the robustness of the Markdown parser.
10
+So please excuse for the mess in the [source code of this document][src].
11
+By no means the normal use of footnotes should look that scarry.
12
+
13
+Developers are invited to add test cases here[^here].
14
+It is suggested that the more simple is a test case the earlier it should
15
+appear in this document.[^ if glitch occurs ]
16
+
17
+
18
+[^lost3]: This note was defined at the begining of the document.
19
+
20
+[^duplicate]: This came from the begining of the document.
21
+
22
+A footnote's label should be case insensitive[^ case INSENSITIVE ],
23
+it is whitespace-savvy and can even contain newlines.[^ a
24
+multil[^].
25
+Markup within [a [text fragment](https://en.wikipedia.org/wiki/Lorem_ipsum)
26
+of a *span-bounded footnote*][^markup] should also be rendered.
27
+
28
+Another reference[^many-refs] to the preveously used footnote.
29
+
30
+[^lost2]: This note was defined in the middle of the document.
31
+ It references [its previous][^lost3]
32
+ and [the forthcoming][^lost1] siblings.
33
+
34
+[^i am strayed]:
35
+ This should be presented **verbatim** (without any [markup][^])
36
+ in the end of the footnotes.
37
+
38
+ Default skin renders label in red font and the main text in gray.
39
+ Other styling may also apply.
40
+
41
+Inline footnotes are supported.(^These may be usefull for adding
42
+<s>small</s> comments.)
43
+
44
+This is a corner case that is rendered as [an empty footnote](^ [] ()).
45
+
46
+If [undefined label is used][^] then red "`misref`" is emited instead of
47
+a numeric marker.[^ see it yourself ]
48
+This can be overridden by the skin though.
49
+
50
+The refenrence at the end of this sentence is the sole reason of
51
+rendering of <s>`lost1` and</s> [lost2][^].
52
+
53
+If several labeled footnote definitions have the same equal label then texts
54
+from all these definitions are joined.[^duplicate]
55
+
56
+Several references should be recognized as several distinct numbers.
57
+(^There should be an interval between numbers.) [^many-refs]
58
+
59
+If markup is ambigous between a span-bounded footnote and
60
+a "free-standing" footnote followed by another footnote
61
+then interpret as the later case.
62
+This facilitates the usage in the usual case
63
+when several footnotes are refenrenced at the end
64
+of a phrase.[^scipub][^many-refs](^All these four should
65
+be parsed as "free-standing" footnotes)[^Coelurosauria]
66
+
67
+An ambiguity between a link to an image and a *free-standing referenced
68
+footnote* should be resolved as a footnote![^not-image]
69
+
70
+A footnote may not be empty(^)
71
+or consist just of blank characters.(^
72
+ )
73
+
74
+The same holds for labeled footnotes. If definition of a labeled footnote
75
+is blank then it is not accepted by the first pass of the parser and
76
+is recognized during the second pass as misreference.
77
+[^ This definition consists of just blanks ]:
78
+
79
+
80
+<style>
81
+ li.fn-upc-example span.fn-upc {
82
+ border: solid 2px lightgreen;
83
+ border-radius: 0.25em;
84
+ padding-left: 2px;
85
+ padding-right: 2px;
86
+ margin-bottom: 0.2em;
87
+ }
88
+ li.fn-upc-example span.fn-upcDot:first-child {
89
+ font-weight: bold;
90
+ }
91
+ sup.noteref.fn-upc-example,
92
+ span.notescope.fn-upc-example sup.noteref {
93
+ border: solid 2px lightgreen;
94
+[^duplicate]:
95
+ Labeled footnote definition may appear anywhere.
96
+ That part came from inside of an inline style definition.
97
+ border-radius: 0.4em;
98
+ padding: 2px;
99
+ }
100
+ sup.noteref.fn-upc-example::after,
101
+ span.notescope.fn-upc-example sup.noteref::after {
102
+ content: " ⛄";
103
+ }
104
+ sup.noteref.fn-upc-example:hover::after,
105
+ span.notescope.fn-upc-example sup.noteref:hover::after {
106
+ content: " 👻";
107
+ }
108
+ li.fn-upc-l span.fn-upc {
109
+ font-size: 60%;
110
+ color: orange;
111
+ }
112
+ li.fn-upc-l span.fn-upc span.fn-upcDot {
113
+ display: none;
114
+ }
115
+</style>
116
+
117
+It is possible to provide a list of classes for a particular footnote and
118
+all its references. This is achieved by prepending a footnote's text with
119
+a special token that starts with dot and ends with colon.
120
+(^
121
+ .alpha-Numeric123.EXAMPLE:
122
+ This token defines a dot-separated list of CSS classes
123
+ which are added to that particular footnote and also to the
124
+ corresponding reference(s). Hypens ('-') are also allowed.
125
+ Classes from the token are tranformed to lowercase and are prepended
126
+ with `"fn-upc-"` to avoid collisions.
127
+)
128
+This feature is "*opt-in*": there is nothing wrong in starting a footnote's
129
+text with a token of that form while not defining any corresponding classes
130
+in the stylesheet.[^nostyle]
131
+If a footnote consists just of a valid userclass token then this token
132
+is not interpreted as such, instead it is emitted as plain text.
133
+(^
134
+ .bare.classlist.inside.inline.footnote:
135
+)[^bare1]
136
+[^bare2]
137
+
138
+[^duplicate]: .with.UPC.token:
139
+ When duplicates are joined their UPC tokens are treated as plain-text.
140
+ Blank characters between token and main text must be preserved.
141
+
142
+<html>
143
+ Click
144
+ <a href="?a=B&quote='&nonASCII=😂&script=<script>alert('Broken!');</script>">
145
+ here</a> and
146
+ <a href='?a=B&quote="&nonASCII=😂&script=<script>alert("Broken!");</script>'>
147
+ here</a>
148
+ to test escaping of REQUEST_URI in the generated footnote markers.
149
+</html>
150
+
151
+A depth of nesting must be limited.
152
+(^
153
+ .L.1: A long chain of nested inline footnotes...
154
+ (^
155
+ .L.2: is a rather unusual thing...
156
+ (^
157
+ .L.3: and requires extra CPU cycles for processing.
158
+ (^
159
+on a certain level.
160
+ (^
161
+ .L.7: A particular value for that limit...
162
+ (^
163
+ is hard-coded in src/markdown.c ...
164
+ (^
165
+ in function `markdown()` ...
166
+ (^
167
+ in variable named `maxDepth`.
168
+ (^
169
+ For the time being, its value is **5**
170
+ )
171
+ )
172
+ )
173
+ )
174
+ )
175
+ )
176
+ )
177
+ )
178
+ )
179
+ )
180
+)
181
+
182
+## Footnotes
183
+
184
+[branch]: /timeline?r=markdown-footnotes&nowiki
185
+
186
+[^' extentootnotes is a Fossil extension of
187
+ Markdown. Your other tools may have limited support for these.
188
+
189
+[^here]: [History of test/markdown-test3.md](/finfo/test/markdown-test3.md)
190
+
191
+[src]: /file/test/markdown-test3.md?ci=markdown-footnotes&txt&ln
192
+
193
+[^if glitch occurs]:
194
+ So that sim
--- a/test/markdown-test3.md
+++ b/test/markdown-test3.md
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/test/markdown-test3.md
+++ b/test/markdown-test3.md
@@ -0,0 +1,194 @@
1
2 Markdown Footnotes Test Document
3 ================================
4
5 **This document** should help with testing of footnotes support that
6 is introduced by the ["`markdown-footnotes`"][branch] branch.
7 It **might look pretty misformatted unless rendered by the proper Fossil
8 executable** that incorporates the abovementioned branch.[^1]
9 That is also a humble attempt to explore the robustness of the Markdown parser.
10 So please excuse for the mess in the [source code of this document][src].
11 By no means the normal use of footnotes should look that scarry.
12
13 Developers are invited to add test cases here[^here].
14 It is suggested that the more simple is a test case the earlier it should
15 appear in this document.[^ if glitch occurs ]
16
17
18 [^lost3]: This note was defined at the begining of the document.
19
20 [^duplicate]: This came from the begining of the document.
21
22 A footnote's label should be case insensitive[^ case INSENSITIVE ],
23 it is whitespace-savvy and can even contain newlines.[^ a
24 multil[^].
25 Markup within [a [text fragment](https://en.wikipedia.org/wiki/Lorem_ipsum)
26 of a *span-bounded footnote*][^markup] should also be rendered.
27
28 Another reference[^many-refs] to the preveously used footnote.
29
30 [^lost2]: This note was defined in the middle of the document.
31 It references [its previous][^lost3]
32 and [the forthcoming][^lost1] siblings.
33
34 [^i am strayed]:
35 This should be presented **verbatim** (without any [markup][^])
36 in the end of the footnotes.
37
38 Default skin renders label in red font and the main text in gray.
39 Other styling may also apply.
40
41 Inline footnotes are supported.(^These may be usefull for adding
42 <s>small</s> comments.)
43
44 This is a corner case that is rendered as [an empty footnote](^ [] ()).
45
46 If [undefined label is used][^] then red "`misref`" is emited instead of
47 a numeric marker.[^ see it yourself ]
48 This can be overridden by the skin though.
49
50 The refenrence at the end of this sentence is the sole reason of
51 rendering of <s>`lost1` and</s> [lost2][^].
52
53 If several labeled footnote definitions have the same equal label then texts
54 from all these definitions are joined.[^duplicate]
55
56 Several references should be recognized as several distinct numbers.
57 (^There should be an interval between numbers.) [^many-refs]
58
59 If markup is ambigous between a span-bounded footnote and
60 a "free-standing" footnote followed by another footnote
61 then interpret as the later case.
62 This facilitates the usage in the usual case
63 when several footnotes are refenrenced at the end
64 of a phrase.[^scipub][^many-refs](^All these four should
65 be parsed as "free-standing" footnotes)[^Coelurosauria]
66
67 An ambiguity between a link to an image and a *free-standing referenced
68 footnote* should be resolved as a footnote![^not-image]
69
70 A footnote may not be empty(^)
71 or consist just of blank characters.(^
72 )
73
74 The same holds for labeled footnotes. If definition of a labeled footnote
75 is blank then it is not accepted by the first pass of the parser and
76 is recognized during the second pass as misreference.
77 [^ This definition consists of just blanks ]:
78
79
80 <style>
81 li.fn-upc-example span.fn-upc {
82 border: solid 2px lightgreen;
83 border-radius: 0.25em;
84 padding-left: 2px;
85 padding-right: 2px;
86 margin-bottom: 0.2em;
87 }
88 li.fn-upc-example span.fn-upcDot:first-child {
89 font-weight: bold;
90 }
91 sup.noteref.fn-upc-example,
92 span.notescope.fn-upc-example sup.noteref {
93 border: solid 2px lightgreen;
94 [^duplicate]:
95 Labeled footnote definition may appear anywhere.
96 That part came from inside of an inline style definition.
97 border-radius: 0.4em;
98 padding: 2px;
99 }
100 sup.noteref.fn-upc-example::after,
101 span.notescope.fn-upc-example sup.noteref::after {
102 content: " ⛄";
103 }
104 sup.noteref.fn-upc-example:hover::after,
105 span.notescope.fn-upc-example sup.noteref:hover::after {
106 content: " 👻";
107 }
108 li.fn-upc-l span.fn-upc {
109 font-size: 60%;
110 color: orange;
111 }
112 li.fn-upc-l span.fn-upc span.fn-upcDot {
113 display: none;
114 }
115 </style>
116
117 It is possible to provide a list of classes for a particular footnote and
118 all its references. This is achieved by prepending a footnote's text with
119 a special token that starts with dot and ends with colon.
120 (^
121 .alpha-Numeric123.EXAMPLE:
122 This token defines a dot-separated list of CSS classes
123 which are added to that particular footnote and also to the
124 corresponding reference(s). Hypens ('-') are also allowed.
125 Classes from the token are tranformed to lowercase and are prepended
126 with `"fn-upc-"` to avoid collisions.
127 )
128 This feature is "*opt-in*": there is nothing wrong in starting a footnote's
129 text with a token of that form while not defining any corresponding classes
130 in the stylesheet.[^nostyle]
131 If a footnote consists just of a valid userclass token then this token
132 is not interpreted as such, instead it is emitted as plain text.
133 (^
134 .bare.classlist.inside.inline.footnote:
135 )[^bare1]
136 [^bare2]
137
138 [^duplicate]: .with.UPC.token:
139 When duplicates are joined their UPC tokens are treated as plain-text.
140 Blank characters between token and main text must be preserved.
141
142 <html>
143 Click
144 <a href="?a=B&quote='&nonASCII=😂&script=<script>alert('Broken!');</script>">
145 here</a> and
146 <a href='?a=B&quote="&nonASCII=😂&script=<script>alert("Broken!");</script>'>
147 here</a>
148 to test escaping of REQUEST_URI in the generated footnote markers.
149 </html>
150
151 A depth of nesting must be limited.
152 (^
153 .L.1: A long chain of nested inline footnotes...
154 (^
155 .L.2: is a rather unusual thing...
156 (^
157 .L.3: and requires extra CPU cycles for processing.
158 (^
159 on a certain level.
160 (^
161 .L.7: A particular value for that limit...
162 (^
163 is hard-coded in src/markdown.c ...
164 (^
165 in function `markdown()` ...
166 (^
167 in variable named `maxDepth`.
168 (^
169 For the time being, its value is **5**
170 )
171 )
172 )
173 )
174 )
175 )
176 )
177 )
178 )
179 )
180 )
181
182 ## Footnotes
183
184 [branch]: /timeline?r=markdown-footnotes&nowiki
185
186 [^' extentootnotes is a Fossil extension of
187 Markdown. Your other tools may have limited support for these.
188
189 [^here]: [History of test/markdown-test3.md](/finfo/test/markdown-test3.md)
190
191 [src]: /file/test/markdown-test3.md?ci=markdown-footnotes&txt&ln
192
193 [^if glitch occurs]:
194 So that sim
--- tools/makeheaders.c
+++ tools/makeheaders.c
@@ -2207,10 +2207,11 @@
22072207
while( *zArg && isspace(*zArg) && *zArg!='\n' ){
22082208
zArg++;
22092209
}
22102210
if( *zArg==0 || *zArg=='\n' ){ return 0; }
22112211
nArg = pToken->nText + (int)(pToken->zText - zArg);
2212
+ if (pToken->zText[pToken->nText-1] == '\r') { nArg--; }
22122213
if( nArg==9 && strncmp(zArg,"INTERFACE",9)==0 ){
22132214
PushIfMacro(0,0,0,pToken->nLine,PS_Interface);
22142215
}else if( nArg==16 && strncmp(zArg,"EXPORT_INTERFACE",16)==0 ){
22152216
PushIfMacro(0,0,0,pToken->nLine,PS_Export);
22162217
}else if( nArg==15 && strncmp(zArg,"LOCAL_INTERFACE",15)==0 ){
@@ -2228,10 +2229,11 @@
22282229
while( *zArg && isspace(*zArg) && *zArg!='\n' ){
22292230
zArg++;
22302231
}
22312232
if( *zArg==0 || *zArg=='\n' ){ return 0; }
22322233
nArg = pToken->nText + (int)(pToken->zText - zArg);
2234
+ if (pToken->zText[pToken->nText-1] == '\r') { nArg--; }
22332235
PushIfMacro("defined",zArg,nArg,pToken->nLine,0);
22342236
}else if( nCmd==6 && strncmp(zCmd,"ifndef",6)==0 ){
22352237
/*
22362238
** Push an #ifndef.
22372239
*/
@@ -2239,10 +2241,11 @@
22392241
while( *zArg && isspace(*zArg) && *zArg!='\n' ){
22402242
zArg++;
22412243
}
22422244
if( *zArg==0 || *zArg=='\n' ){ return 0; }
22432245
nArg = pToken->nText + (int)(pToken->zText - zArg);
2246
+ if (pToken->zText[pToken->nText-1] == '\r') { nArg--; }
22442247
PushIfMacro("!defined",zArg,nArg,pToken->nLine,0);
22452248
}else if( nCmd==4 && strncmp(zCmd,"else",4)==0 ){
22462249
/*
22472250
** Invert the #if on the top of the stack
22482251
*/
22492252
--- tools/makeheaders.c
+++ tools/makeheaders.c
@@ -2207,10 +2207,11 @@
2207 while( *zArg && isspace(*zArg) && *zArg!='\n' ){
2208 zArg++;
2209 }
2210 if( *zArg==0 || *zArg=='\n' ){ return 0; }
2211 nArg = pToken->nText + (int)(pToken->zText - zArg);
 
2212 if( nArg==9 && strncmp(zArg,"INTERFACE",9)==0 ){
2213 PushIfMacro(0,0,0,pToken->nLine,PS_Interface);
2214 }else if( nArg==16 && strncmp(zArg,"EXPORT_INTERFACE",16)==0 ){
2215 PushIfMacro(0,0,0,pToken->nLine,PS_Export);
2216 }else if( nArg==15 && strncmp(zArg,"LOCAL_INTERFACE",15)==0 ){
@@ -2228,10 +2229,11 @@
2228 while( *zArg && isspace(*zArg) && *zArg!='\n' ){
2229 zArg++;
2230 }
2231 if( *zArg==0 || *zArg=='\n' ){ return 0; }
2232 nArg = pToken->nText + (int)(pToken->zText - zArg);
 
2233 PushIfMacro("defined",zArg,nArg,pToken->nLine,0);
2234 }else if( nCmd==6 && strncmp(zCmd,"ifndef",6)==0 ){
2235 /*
2236 ** Push an #ifndef.
2237 */
@@ -2239,10 +2241,11 @@
2239 while( *zArg && isspace(*zArg) && *zArg!='\n' ){
2240 zArg++;
2241 }
2242 if( *zArg==0 || *zArg=='\n' ){ return 0; }
2243 nArg = pToken->nText + (int)(pToken->zText - zArg);
 
2244 PushIfMacro("!defined",zArg,nArg,pToken->nLine,0);
2245 }else if( nCmd==4 && strncmp(zCmd,"else",4)==0 ){
2246 /*
2247 ** Invert the #if on the top of the stack
2248 */
2249
--- tools/makeheaders.c
+++ tools/makeheaders.c
@@ -2207,10 +2207,11 @@
2207 while( *zArg && isspace(*zArg) && *zArg!='\n' ){
2208 zArg++;
2209 }
2210 if( *zArg==0 || *zArg=='\n' ){ return 0; }
2211 nArg = pToken->nText + (int)(pToken->zText - zArg);
2212 if (pToken->zText[pToken->nText-1] == '\r') { nArg--; }
2213 if( nArg==9 && strncmp(zArg,"INTERFACE",9)==0 ){
2214 PushIfMacro(0,0,0,pToken->nLine,PS_Interface);
2215 }else if( nArg==16 && strncmp(zArg,"EXPORT_INTERFACE",16)==0 ){
2216 PushIfMacro(0,0,0,pToken->nLine,PS_Export);
2217 }else if( nArg==15 && strncmp(zArg,"LOCAL_INTERFACE",15)==0 ){
@@ -2228,10 +2229,11 @@
2229 while( *zArg && isspace(*zArg) && *zArg!='\n' ){
2230 zArg++;
2231 }
2232 if( *zArg==0 || *zArg=='\n' ){ return 0; }
2233 nArg = pToken->nText + (int)(pToken->zText - zArg);
2234 if (pToken->zText[pToken->nText-1] == '\r') { nArg--; }
2235 PushIfMacro("defined",zArg,nArg,pToken->nLine,0);
2236 }else if( nCmd==6 && strncmp(zCmd,"ifndef",6)==0 ){
2237 /*
2238 ** Push an #ifndef.
2239 */
@@ -2239,10 +2241,11 @@
2241 while( *zArg && isspace(*zArg) && *zArg!='\n' ){
2242 zArg++;
2243 }
2244 if( *zArg==0 || *zArg=='\n' ){ return 0; }
2245 nArg = pToken->nText + (int)(pToken->zText - zArg);
2246 if (pToken->zText[pToken->nText-1] == '\r') { nArg--; }
2247 PushIfMacro("!defined",zArg,nArg,pToken->nLine,0);
2248 }else if( nCmd==4 && strncmp(zCmd,"else",4)==0 ){
2249 /*
2250 ** Invert the #if on the top of the stack
2251 */
2252
+15 -12
--- tools/mkindex.c
+++ tools/mkindex.c
@@ -80,22 +80,23 @@
8080
8181
/***************************************************************************
8282
** These macros must match similar macros in dispatch.c.
8383
**
8484
** Allowed values for CmdOrPage.eCmdFlags. */
85
-#define CMDFLAG_1ST_TIER 0x0001 /* Most important commands */
86
-#define CMDFLAG_2ND_TIER 0x0002 /* Obscure and seldom used commands */
87
-#define CMDFLAG_TEST 0x0004 /* Commands for testing only */
88
-#define CMDFLAG_WEBPAGE 0x0008 /* Web pages */
89
-#define CMDFLAG_COMMAND 0x0010 /* A command */
90
-#define CMDFLAG_SETTING 0x0020 /* A setting */
91
-#define CMDFLAG_VERSIONABLE 0x0040 /* A versionable setting */
92
-#define CMDFLAG_BLOCKTEXT 0x0080 /* Multi-line text setting */
93
-#define CMDFLAG_BOOLEAN 0x0100 /* A boolean setting */
94
-#define CMDFLAG_RAWCONTENT 0x0200 /* Do not interpret webpage content */
95
-#define CMDFLAG_SENSITIVE 0x0400 /* Security-sensitive setting */
96
-#define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */
85
+#define CMDFLAG_1ST_TIER 0x0001 /* Most important commands */
86
+#define CMDFLAG_2ND_TIER 0x0002 /* Obscure and seldom used commands */
87
+#define CMDFLAG_TEST 0x0004 /* Commands for testing only */
88
+#define CMDFLAG_WEBPAGE 0x0008 /* Web pages */
89
+#define CMDFLAG_COMMAND 0x0010 /* A command */
90
+#define CMDFLAG_SETTING 0x0020 /* A setting */
91
+#define CMDFLAG_VERSIONABLE 0x0040 /* A versionable setting */
92
+#define CMDFLAG_BLOCKTEXT 0x0080 /* Multi-line text setting */
93
+#define CMDFLAG_BOOLEAN 0x0100 /* A boolean setting */
94
+#define CMDFLAG_RAWCONTENT 0x0200 /* Do not interpret webpage content */
95
+#define CMDFLAG_SENSITIVE 0x0400 /* Security-sensitive setting */
96
+#define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */
97
+#define CMDFLAG_LDAVG_EXEMPT 0x1000 /* Exempt from load_control() */
9798
/**************************************************************************/
9899
99100
/*
100101
** Each entry looks like this:
101102
*/
@@ -260,10 +261,12 @@
260261
aEntry[nUsed].zDflt = string_dup(&zLine[i+8], j-8);
261262
}else if( j>9 && strncmp(&zLine[i], "variable=", 9)==0 ){
262263
aEntry[nUsed].zVar = string_dup(&zLine[i+9], j-9);
263264
}else if( j==6 && strncmp(&zLine[i], "hidden", 6)==0 ){
264265
aEntry[nUsed].eType |= CMDFLAG_HIDDEN;
266
+ }else if( j==14 && strncmp(&zLine[i], "loadavg-exempt", 14)==0 ){
267
+ aEntry[nUsed].eType |= CMDFLAG_LDAVG_EXEMPT;
265268
}else{
266269
fprintf(stderr, "%s:%d: unknown option: '%.*s'\n",
267270
zFile, nLine, j, &zLine[i]);
268271
nErr++;
269272
}
270273
--- tools/mkindex.c
+++ tools/mkindex.c
@@ -80,22 +80,23 @@
80
81 /***************************************************************************
82 ** These macros must match similar macros in dispatch.c.
83 **
84 ** Allowed values for CmdOrPage.eCmdFlags. */
85 #define CMDFLAG_1ST_TIER 0x0001 /* Most important commands */
86 #define CMDFLAG_2ND_TIER 0x0002 /* Obscure and seldom used commands */
87 #define CMDFLAG_TEST 0x0004 /* Commands for testing only */
88 #define CMDFLAG_WEBPAGE 0x0008 /* Web pages */
89 #define CMDFLAG_COMMAND 0x0010 /* A command */
90 #define CMDFLAG_SETTING 0x0020 /* A setting */
91 #define CMDFLAG_VERSIONABLE 0x0040 /* A versionable setting */
92 #define CMDFLAG_BLOCKTEXT 0x0080 /* Multi-line text setting */
93 #define CMDFLAG_BOOLEAN 0x0100 /* A boolean setting */
94 #define CMDFLAG_RAWCONTENT 0x0200 /* Do not interpret webpage content */
95 #define CMDFLAG_SENSITIVE 0x0400 /* Security-sensitive setting */
96 #define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */
 
97 /**************************************************************************/
98
99 /*
100 ** Each entry looks like this:
101 */
@@ -260,10 +261,12 @@
260 aEntry[nUsed].zDflt = string_dup(&zLine[i+8], j-8);
261 }else if( j>9 && strncmp(&zLine[i], "variable=", 9)==0 ){
262 aEntry[nUsed].zVar = string_dup(&zLine[i+9], j-9);
263 }else if( j==6 && strncmp(&zLine[i], "hidden", 6)==0 ){
264 aEntry[nUsed].eType |= CMDFLAG_HIDDEN;
 
 
265 }else{
266 fprintf(stderr, "%s:%d: unknown option: '%.*s'\n",
267 zFile, nLine, j, &zLine[i]);
268 nErr++;
269 }
270
--- tools/mkindex.c
+++ tools/mkindex.c
@@ -80,22 +80,23 @@
80
81 /***************************************************************************
82 ** These macros must match similar macros in dispatch.c.
83 **
84 ** Allowed values for CmdOrPage.eCmdFlags. */
85 #define CMDFLAG_1ST_TIER 0x0001 /* Most important commands */
86 #define CMDFLAG_2ND_TIER 0x0002 /* Obscure and seldom used commands */
87 #define CMDFLAG_TEST 0x0004 /* Commands for testing only */
88 #define CMDFLAG_WEBPAGE 0x0008 /* Web pages */
89 #define CMDFLAG_COMMAND 0x0010 /* A command */
90 #define CMDFLAG_SETTING 0x0020 /* A setting */
91 #define CMDFLAG_VERSIONABLE 0x0040 /* A versionable setting */
92 #define CMDFLAG_BLOCKTEXT 0x0080 /* Multi-line text setting */
93 #define CMDFLAG_BOOLEAN 0x0100 /* A boolean setting */
94 #define CMDFLAG_RAWCONTENT 0x0200 /* Do not interpret webpage content */
95 #define CMDFLAG_SENSITIVE 0x0400 /* Security-sensitive setting */
96 #define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */
97 #define CMDFLAG_LDAVG_EXEMPT 0x1000 /* Exempt from load_control() */
98 /**************************************************************************/
99
100 /*
101 ** Each entry looks like this:
102 */
@@ -260,10 +261,12 @@
261 aEntry[nUsed].zDflt = string_dup(&zLine[i+8], j-8);
262 }else if( j>9 && strncmp(&zLine[i], "variable=", 9)==0 ){
263 aEntry[nUsed].zVar = string_dup(&zLine[i+9], j-9);
264 }else if( j==6 && strncmp(&zLine[i], "hidden", 6)==0 ){
265 aEntry[nUsed].eType |= CMDFLAG_HIDDEN;
266 }else if( j==14 && strncmp(&zLine[i], "loadavg-exempt", 14)==0 ){
267 aEntry[nUsed].eType |= CMDFLAG_LDAVG_EXEMPT;
268 }else{
269 fprintf(stderr, "%s:%d: unknown option: '%.*s'\n",
270 zFile, nLine, j, &zLine[i]);
271 nErr++;
272 }
273
--- www/build.wiki
+++ www/build.wiki
@@ -379,5 +379,86 @@
379379
380380
The source of such warnings is not 100% certain.
381381
Some information about these (reportedly harmless) warnings can
382382
be found
383383
[https://stackoverflow.com/a/41900551 | on this StackOverflow post].
384
+
385
+
386
+
387
+<a id='fuzzer'></a>
388
+<h2>Building for Fuzz Testing</h2>
389
+
390
+This feature is primarily intended for fossil's developers and may
391
+change at any time. It is only known to work on Linux systems and has
392
+been seen to work on x86/64 and ARM.
393
+
394
+Fossil has builtin support for processing specific features using
395
+<tt>libfuzzer</tt>. The features which can be tested this way are
396
+found in the help text for the [/help?cmd=test-fuzz|test-fuzz
397
+command].
398
+
399
+Fuzzing requires:
400
+
401
+ * Customizing the build of fossil a small bit.
402
+ * The clang C compiler.
403
+ * libfuzzer. On Ubuntu-derived systems, it can be installed with
404
+ <tt>apt install libfuzzer-XYZ</tt>, where XYZ is a version number
405
+ (several versions may be available on any given system)
406
+
407
+
408
+First, modify the top-level <tt>Makefile.in</tt>:
409
+
410
+ * Extend the <tt>TCCFLAGS</tt> variable with: <tt>-fsanitize=fuzzer
411
+ -DFOSSIL_FUZZ</tt> (and see [/finfo/src/fuzz.c | src/fuzz.c] for
412
+ more options).
413
+ * Rename <tt>APPNAME</tt> from <tt>fossil</tt> to <tt>fossil-fuzz</tt>.
414
+
415
+Then rebuild:
416
+
417
+<pre></code>$ make clean
418
+$ ./configure CC=/path/to/clang
419
+$ make
420
+</code></pre>
421
+
422
+If clang is your default compiler, the <tt>CC</tt> configure option is
423
+not required.
424
+
425
+The resulting <tt>fossil-fuzz</tt> binary differs from the standard
426
+one primarily in that it runs the <tt>test-fuzz</tt> command by
427
+default. It needs to be told what to fuzz and needs to be given a
428
+directory of input files to seed the fuzzer with:
429
+
430
+
431
+<pre></code>$ mkdir cases
432
+ # Copy input files into ./cases. e.g. when fuzzing the markdown
433
+ # processor, copy any to-be-tested .md files into that directory.
434
+ # Then start the fuzzer:
435
+$ ./fossil-fuzz --fuzztype markdown cases
436
+</code></pre>
437
+
438
+As it works, it writes its mutated test files into the test-input
439
+directory, each one named in the form of a hash. When it finds a
440
+problem it will produce a stack trace for the offending code, will
441
+output the name of the file which triggered the crash (named
442
+<tt>cases/SOME_HASH</tt>) and may, depending on the nature of the
443
+problem, produce a file named <tt>crash-SOMETHING</tt>. In theory the
444
+crash file can be fed directly back into the fuzzer to reproduce the
445
+problem:
446
+
447
+<pre></code>$ ./fossil-fuzz --fuzztype markdown crash-SOMETHING
448
+</code></pre>
449
+
450
+But whether or not it will genuinely crash may depend on static
451
+app-level state which might not trigger the crash when running an
452
+individual test.
453
+
454
+For a detailed information about the fuzzer's flags and features, see:
455
+
456
+ * [https://llvm.org/docs/LibFuzzer.html]
457
+ * [https://github.com/google/fuzzing/blob/master/tutorial/libFuzzerTutorial.md]
458
+
459
+Flags for the fuzzer can be passed directly to fossil,
460
+e.g. <tt>-jobs=4</tt> to start four fuzzer jobs in parallel, but doing
461
+so may cause the fuzzer to <em>strip the --fuzztype flag</em>, leading
462
+to it testing the wrong thing. When passing on fuzzer-specific flags
463
+along with <tt>--fuzztype</tt>, be sure to check your system's process
464
+list to ensure that your <tt>--fuzztype</tt> flag is there.
384465
--- www/build.wiki
+++ www/build.wiki
@@ -379,5 +379,86 @@
379
380 The source of such warnings is not 100% certain.
381 Some information about these (reportedly harmless) warnings can
382 be found
383 [https://stackoverflow.com/a/41900551 | on this StackOverflow post].
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
384
--- www/build.wiki
+++ www/build.wiki
@@ -379,5 +379,86 @@
379
380 The source of such warnings is not 100% certain.
381 Some information about these (reportedly harmless) warnings can
382 be found
383 [https://stackoverflow.com/a/41900551 | on this StackOverflow post].
384
385
386
387 <a id='fuzzer'></a>
388 <h2>Building for Fuzz Testing</h2>
389
390 This feature is primarily intended for fossil's developers and may
391 change at any time. It is only known to work on Linux systems and has
392 been seen to work on x86/64 and ARM.
393
394 Fossil has builtin support for processing specific features using
395 <tt>libfuzzer</tt>. The features which can be tested this way are
396 found in the help text for the [/help?cmd=test-fuzz|test-fuzz
397 command].
398
399 Fuzzing requires:
400
401 * Customizing the build of fossil a small bit.
402 * The clang C compiler.
403 * libfuzzer. On Ubuntu-derived systems, it can be installed with
404 <tt>apt install libfuzzer-XYZ</tt>, where XYZ is a version number
405 (several versions may be available on any given system)
406
407
408 First, modify the top-level <tt>Makefile.in</tt>:
409
410 * Extend the <tt>TCCFLAGS</tt> variable with: <tt>-fsanitize=fuzzer
411 -DFOSSIL_FUZZ</tt> (and see [/finfo/src/fuzz.c | src/fuzz.c] for
412 more options).
413 * Rename <tt>APPNAME</tt> from <tt>fossil</tt> to <tt>fossil-fuzz</tt>.
414
415 Then rebuild:
416
417 <pre></code>$ make clean
418 $ ./configure CC=/path/to/clang
419 $ make
420 </code></pre>
421
422 If clang is your default compiler, the <tt>CC</tt> configure option is
423 not required.
424
425 The resulting <tt>fossil-fuzz</tt> binary differs from the standard
426 one primarily in that it runs the <tt>test-fuzz</tt> command by
427 default. It needs to be told what to fuzz and needs to be given a
428 directory of input files to seed the fuzzer with:
429
430
431 <pre></code>$ mkdir cases
432 # Copy input files into ./cases. e.g. when fuzzing the markdown
433 # processor, copy any to-be-tested .md files into that directory.
434 # Then start the fuzzer:
435 $ ./fossil-fuzz --fuzztype markdown cases
436 </code></pre>
437
438 As it works, it writes its mutated test files into the test-input
439 directory, each one named in the form of a hash. When it finds a
440 problem it will produce a stack trace for the offending code, will
441 output the name of the file which triggered the crash (named
442 <tt>cases/SOME_HASH</tt>) and may, depending on the nature of the
443 problem, produce a file named <tt>crash-SOMETHING</tt>. In theory the
444 crash file can be fed directly back into the fuzzer to reproduce the
445 problem:
446
447 <pre></code>$ ./fossil-fuzz --fuzztype markdown crash-SOMETHING
448 </code></pre>
449
450 But whether or not it will genuinely crash may depend on static
451 app-level state which might not trigger the crash when running an
452 individual test.
453
454 For a detailed information about the fuzzer's flags and features, see:
455
456 * [https://llvm.org/docs/LibFuzzer.html]
457 * [https://github.com/google/fuzzing/blob/master/tutorial/libFuzzerTutorial.md]
458
459 Flags for the fuzzer can be passed directly to fossil,
460 e.g. <tt>-jobs=4</tt> to start four fuzzer jobs in parallel, but doing
461 so may cause the fuzzer to <em>strip the --fuzztype flag</em>, leading
462 to it testing the wrong thing. When passing on fuzzer-specific flags
463 along with <tt>--fuzztype</tt>, be sure to check your system's process
464 list to ensure that your <tt>--fuzztype</tt> flag is there.
465
--- www/caps/login-groups.md
+++ www/caps/login-groups.md
@@ -1,32 +1,130 @@
11
# Login Groups
22
33
The Admin → Login-Groups UI feature and its corresponding [`login-group`
44
command][lg] solve a common problem with Fossil: you’ve created multiple
5
-repositories that some set of users all need access to, those users all
6
-have the same access level on all of these shared repositories, and you
7
-don’t want to redundantly configure the user set for each repository.
5
+repositories that some subset of users need access to, and you
6
+don’t want to redundantly administer the user credentials for each
7
+repository.
8
+
9
+
10
+## Restrictions
811
912
This feature ties changes to the “`user`” table in one repo to that in
10
-one or more other repos. With this configured, you get a new choice on
11
-the user edit screen, offering to make changes specific to the one
12
-repository only or to apply it to all others in the login group as well.
13
-
14
-A user can log into one repo in a login group only if that user has an
15
-entry in that repo’s user table. That is, setting up a login group
16
-doesn’t automatically transfer all user accounts from the joined repo to
17
-the joining repo. Only when a user exists by name in both repos will
18
-that user be able to share credentials across the repos.
19
-
20
-Login groups can have names, allowing one “master” repo to host multiple
21
-subsets of its users to other repos.
22
-
23
-Trust in login groups is transitive within a single server. If repo C
24
-joined repo B and repo B joined A, changes in C’s user table affect both
25
-A and B, if you tell Fossil that the change applies to all repos in the
26
-login group.
13
+one or more other repos, keyed by the user’s name. The interactions are
14
+non-obvious because although the goal is for the end result to “just
15
+work,” there are practical security and administration matters that
16
+complicate things:
17
+
18
+1. Login group handling only works between joined repositories for the
19
+ subset of users with the same name.
20
+
21
+1. If you’re logged in on one repo in a group, any other repo in that
22
+ group that has a matching user record will accept your valid login.
23
+
24
+1. When you set up a login group between two repos, the user tables
25
+ aren’t merged, so even though you may have users that appear in
26
+ both, they will retain their initial passwords, credentials, and so
27
+ forth.
28
+
29
+1. The same is true after the login group is created: changes you make
30
+ to the user table in one repo in the group only propagate to the
31
+ other repos in the group when you check the “Apply changes to all
32
+ repositories“ box in the “Scope” section of the user edit screen.
33
+ Otherwise, user changes remain local to the repo you made them on.
34
+
35
+1. Login groups only affect [the HTTP interfaces][wo]. Contrast things
36
+ like `ssh://` clones, where unless you [go out of your way][sh] to
37
+ force them to run over one of the HTTP interfaces that pays
38
+ attention to Fossil’s RBAC system, login groups aren’t consulted.
39
+
40
+
41
+## Interactions
42
+
43
+These restrictions combine in subtle and interesting ways. Examples:
44
+
45
+* **#1 and #2**: If you are logged into repo C as “charlie” and then
46
+ try to visit joined repo A where “charlie” doesn’t exist, your valid
47
+ login on C won’t get you into A.
48
+
49
+* **#2 and #3**: If “alice” exists in both of these same repos,
50
+ logging in on A gets her into C, but if she has different user
51
+ capabilities on each from the time before the two repos joined the
52
+ login group, her caps on A don’t apply to C, nor vice versa.
53
+
54
+ Let us say F is a forum-only repo, and W is a wiki-only repo, and
55
+ that Alice has forum-posting rights on F and wiki-editing rights on
56
+ W. If both repos are joined by a login group, Alice can log in on F
57
+ and then access W without logging in on it separately, but she
58
+ cannot then post a forum message on W even though she could on F.
59
+
60
+* **#3 and #4**: If you change the caps for user “alice” on one repo
61
+ in a group and tell Fossil to apply the changes to all repos in the
62
+ group, the new caps will *overwrite* those on the other repos, not
63
+ merge with them.
64
+
65
+ To extend the practical example from the prior point, let us say you
66
+ wish to grant Alice the “write unversioned” capability on both F and
67
+ W. If you check that single user cap box on F plus the “apply to
68
+ all” option, then “Apply Changes,” she will end up with forum +
69
+ unversioned caps on repo W, losing her wiki-editing caps in the
70
+ process.
71
+
72
+ If you want user caps to differ on each repo, you must administer
73
+ them separately even if there is a common subset of caps between all
74
+ repos in the group for that user. Remember: selecting the “apply to
75
+ all” box calls for an overwrite operation, not a merge.
76
+
77
+* **#4 and #1**: If you make a change to an existing user “bob” in
78
+ repo B and select the “apply to all” option, it will only affect
79
+ other repos in the group that have a user “bob” configured.
80
+
81
+ But, if you are instead creating user “bob” for the first time and
82
+ select that option, that user *will* be created in all repos. The
83
+ same is true of user deletion: that destructive action will
84
+ propagate through the group if you request it.
85
+
86
+* **#5 and #1**: If you have a user “daisy” on both repos A and B in a
87
+ login group, logging in over the web to A doesn’t let you push
88
+ changes into B over SSH. Without the workaround linked above, SSH
89
+ only pays attention to the operating system’s user authentication
90
+ system, not Fossil’s.
91
+
92
+ Inversely, if Daisy successfully logs in over SSH to repo B, she
93
+ gains no access to any of the other repos in that group. She needs
94
+ at least one valid login over HTTP to one of the group’s repos.
95
+
96
+
97
+## Discussion
98
+
99
+The end result of all of this is that you can have a subset of users
100
+with credentials only on repo A, a different subset only on B, and a
101
+third subset common to both. The only thing selecting which case applies
102
+is restriction #1 above.
103
+
104
+Login groups have names. A repo can be in only one of these named login
105
+groups at a time.
106
+
107
+Trust in login groups is transitive within a single server. Consider
108
+this sequence:
109
+
110
+```
111
+ $ cd /path/to/A/checkout
112
+ $ fossil login-group join --name G ~/museum/B.fossil
113
+ $ cd /path/to/C/checkout
114
+ $ fossil login-group join ~/museum/B.fossil
115
+```
116
+
117
+That creates login group G joining repo A to B, then joins C to B.
118
+Although we didn’t explicitly tie C to A, a successful login on C gets
119
+you into both A and B, within the restrictions set out above.
120
+
121
+Changes are transitive in the same way, provided you check that “apply
122
+to all” box on the user edit screen.
27123
28124
[lg]: /help?cmd=login-group
125
+[sh]: ../server/any/http-over-ssh.md
126
+[wo]: ./index.md#webonly
29127
30128
-----
31129
32130
*[Back to Administering User Capabilities](./)*
33131
--- www/caps/login-groups.md
+++ www/caps/login-groups.md
@@ -1,32 +1,130 @@
1 # Login Groups
2
3 The Admin → Login-Groups UI feature and its corresponding [`login-group`
4 command][lg] solve a common problem with Fossil: you’ve created multiple
5 repositories that some set of users all need access to, those users all
6 have the same access level on all of these shared repositories, and you
7 don’t want to redundantly configure the user set for each repository.
 
 
 
8
9 This feature ties changes to the “`user`” table in one repo to that in
10 one or more other repos. With this configured, you get a new choice on
11 the user edit screen, offering to make changes specific to the one
12 repository only or to apply it to all others in the login group as well.
13
14 A user can log into one repo in a login group only if that user has an
15 entry in that repo’s user table. That is, setting up a login group
16 doesn’t automatically transfer all user accounts from the joined repo to
17 the joining repo. Only when a user exists by name in both repos will
18 that user be able to share credentials across the repos.
19
20 Login groups can have names, allowing one “master” repo to host multiple
21 subsets of its users to other repos.
22
23 Trust in login groups is transitive within a single server. If repo C
24 joined repo B and repo B joined A, changes in C’s user table affect both
25 A and B, if you tell Fossil that the change applies to all repos in the
26 login group.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
28 [lg]: /help?cmd=login-group
 
 
29
30 -----
31
32 *[Back to Administering User Capabilities](./)*
33
--- www/caps/login-groups.md
+++ www/caps/login-groups.md
@@ -1,32 +1,130 @@
1 # Login Groups
2
3 The Admin → Login-Groups UI feature and its corresponding [`login-group`
4 command][lg] solve a common problem with Fossil: you’ve created multiple
5 repositories that some subset of users need access to, and you
6 don’t want to redundantly administer the user credentials for each
7 repository.
8
9
10 ## Restrictions
11
12 This feature ties changes to the “`user`” table in one repo to that in
13 one or more other repos, keyed by the user’s name. The interactions are
14 non-obvious because although the goal is for the end result to “just
15 work,” there are practical security and administration matters that
16 complicate things:
17
18 1. Login group handling only works between joined repositories for the
19 subset of users with the same name.
20
21 1. If you’re logged in on one repo in a group, any other repo in that
22 group that has a matching user record will accept your valid login.
23
24 1. When you set up a login group between two repos, the user tables
25 aren’t merged, so even though you may have users that appear in
26 both, they will retain their initial passwords, credentials, and so
27 forth.
28
29 1. The same is true after the login group is created: changes you make
30 to the user table in one repo in the group only propagate to the
31 other repos in the group when you check the “Apply changes to all
32 repositories“ box in the “Scope” section of the user edit screen.
33 Otherwise, user changes remain local to the repo you made them on.
34
35 1. Login groups only affect [the HTTP interfaces][wo]. Contrast things
36 like `ssh://` clones, where unless you [go out of your way][sh] to
37 force them to run over one of the HTTP interfaces that pays
38 attention to Fossil’s RBAC system, login groups aren’t consulted.
39
40
41 ## Interactions
42
43 These restrictions combine in subtle and interesting ways. Examples:
44
45 * **#1 and #2**: If you are logged into repo C as “charlie” and then
46 try to visit joined repo A where “charlie” doesn’t exist, your valid
47 login on C won’t get you into A.
48
49 * **#2 and #3**: If “alice” exists in both of these same repos,
50 logging in on A gets her into C, but if she has different user
51 capabilities on each from the time before the two repos joined the
52 login group, her caps on A don’t apply to C, nor vice versa.
53
54 Let us say F is a forum-only repo, and W is a wiki-only repo, and
55 that Alice has forum-posting rights on F and wiki-editing rights on
56 W. If both repos are joined by a login group, Alice can log in on F
57 and then access W without logging in on it separately, but she
58 cannot then post a forum message on W even though she could on F.
59
60 * **#3 and #4**: If you change the caps for user “alice” on one repo
61 in a group and tell Fossil to apply the changes to all repos in the
62 group, the new caps will *overwrite* those on the other repos, not
63 merge with them.
64
65 To extend the practical example from the prior point, let us say you
66 wish to grant Alice the “write unversioned” capability on both F and
67 W. If you check that single user cap box on F plus the “apply to
68 all” option, then “Apply Changes,” she will end up with forum +
69 unversioned caps on repo W, losing her wiki-editing caps in the
70 process.
71
72 If you want user caps to differ on each repo, you must administer
73 them separately even if there is a common subset of caps between all
74 repos in the group for that user. Remember: selecting the “apply to
75 all” box calls for an overwrite operation, not a merge.
76
77 * **#4 and #1**: If you make a change to an existing user “bob” in
78 repo B and select the “apply to all” option, it will only affect
79 other repos in the group that have a user “bob” configured.
80
81 But, if you are instead creating user “bob” for the first time and
82 select that option, that user *will* be created in all repos. The
83 same is true of user deletion: that destructive action will
84 propagate through the group if you request it.
85
86 * **#5 and #1**: If you have a user “daisy” on both repos A and B in a
87 login group, logging in over the web to A doesn’t let you push
88 changes into B over SSH. Without the workaround linked above, SSH
89 only pays attention to the operating system’s user authentication
90 system, not Fossil’s.
91
92 Inversely, if Daisy successfully logs in over SSH to repo B, she
93 gains no access to any of the other repos in that group. She needs
94 at least one valid login over HTTP to one of the group’s repos.
95
96
97 ## Discussion
98
99 The end result of all of this is that you can have a subset of users
100 with credentials only on repo A, a different subset only on B, and a
101 third subset common to both. The only thing selecting which case applies
102 is restriction #1 above.
103
104 Login groups have names. A repo can be in only one of these named login
105 groups at a time.
106
107 Trust in login groups is transitive within a single server. Consider
108 this sequence:
109
110 ```
111 $ cd /path/to/A/checkout
112 $ fossil login-group join --name G ~/museum/B.fossil
113 $ cd /path/to/C/checkout
114 $ fossil login-group join ~/museum/B.fossil
115 ```
116
117 That creates login group G joining repo A to B, then joins C to B.
118 Although we didn’t explicitly tie C to A, a successful login on C gets
119 you into both A and B, within the restrictions set out above.
120
121 Changes are transitive in the same way, provided you check that “apply
122 to all” box on the user edit screen.
123
124 [lg]: /help?cmd=login-group
125 [sh]: ../server/any/http-over-ssh.md
126 [wo]: ./index.md#webonly
127
128 -----
129
130 *[Back to Administering User Capabilities](./)*
131
--- www/changes.wiki
+++ www/changes.wiki
@@ -10,10 +10,14 @@
1010
and promote better situational awareness.
1111
* Performance enhancement for the
1212
[./checkin_names.wiki#root|"root:BRANCHNAME" style of tag],
1313
accomplished using a Common Table Expression in the underlying SQL.
1414
* Add the new "[/help?cmd=describe|fossil describe]" command.
15
+ * Markdown subsystem extended with [../src/markdown.md#ftnts|footnotes support].
16
+ See corresponding [../test/markdown-test3.md|test cases],
17
+ [/wiki?name=branch/markdown-footnotes#il|known limitations] and
18
+ [forum:/forumthread/ee1f1597e46ec07a|discussion].
1519
1620
<h2 id='v2_18'>Changes for version 2.18 (2022-02-23)</h2>
1721
* Added support for [./ssl-server.md|SSL/TLS server mode] for commands
1822
like "[/help?cmd=server|fossil server]" and "[/help?cmd=http|fossil http]"
1923
* The new [/help?cmd=cherry-pick|cherry-pick command] is an alias for
2024
--- www/changes.wiki
+++ www/changes.wiki
@@ -10,10 +10,14 @@
10 and promote better situational awareness.
11 * Performance enhancement for the
12 [./checkin_names.wiki#root|"root:BRANCHNAME" style of tag],
13 accomplished using a Common Table Expression in the underlying SQL.
14 * Add the new "[/help?cmd=describe|fossil describe]" command.
 
 
 
 
15
16 <h2 id='v2_18'>Changes for version 2.18 (2022-02-23)</h2>
17 * Added support for [./ssl-server.md|SSL/TLS server mode] for commands
18 like "[/help?cmd=server|fossil server]" and "[/help?cmd=http|fossil http]"
19 * The new [/help?cmd=cherry-pick|cherry-pick command] is an alias for
20
--- www/changes.wiki
+++ www/changes.wiki
@@ -10,10 +10,14 @@
10 and promote better situational awareness.
11 * Performance enhancement for the
12 [./checkin_names.wiki#root|"root:BRANCHNAME" style of tag],
13 accomplished using a Common Table Expression in the underlying SQL.
14 * Add the new "[/help?cmd=describe|fossil describe]" command.
15 * Markdown subsystem extended with [../src/markdown.md#ftnts|footnotes support].
16 See corresponding [../test/markdown-test3.md|test cases],
17 [/wiki?name=branch/markdown-footnotes#il|known limitations] and
18 [forum:/forumthread/ee1f1597e46ec07a|discussion].
19
20 <h2 id='v2_18'>Changes for version 2.18 (2022-02-23)</h2>
21 * Added support for [./ssl-server.md|SSL/TLS server mode] for commands
22 like "[/help?cmd=server|fossil server]" and "[/help?cmd=http|fossil http]"
23 * The new [/help?cmd=cherry-pick|cherry-pick command] is an alias for
24
--- www/checkin_names.wiki
+++ www/checkin_names.wiki
@@ -98,13 +98,13 @@
9898
is not anything special: it is simply a sequence of check-ins that
9999
share a common tag, so the same mechanism that resolves tag names
100100
also resolves branch names.
101101
102102
<a id="tagpfx"></a>
103
-Note also that there can — in theory, if rarely in practice — be an ambiguity between tag names
104
-and canonical names. Suppose, for example, you had a check-in with
105
-the canonical name deed28aa99… and you
103
+Note also that there can — in theory, if rarely in practice — be an ambiguity
104
+between tag names and canonical names. Suppose, for example, you had a
105
+check-in with the canonical name deed28aa99… and you
106106
also happened to have tagged a different check-in with "deed2". If
107107
you use the "deed2" name, does it choose the canonical name or the tag
108108
name? In such cases, you can prefix the tag name with "tag:".
109109
For example:
110110
@@ -183,12 +183,12 @@
183183
184184
<blockquote>
185185
http://fossil-scm.org/home/doc/<b>trunk</b>/www/index.wiki
186186
</blockquote>
187187
188
-The bold component of that URL is a check-in name. To see the stored
189
-content of the Fossil website repository as of January 1, 2009, one has merely to change
188
+The bold component of that URL is a check-in name. To see the stored content
189
+of the Fossil website repository as of January 1, 2009, one has merely to change
190190
the URL to the following:
191191
192192
<blockquote>
193193
http://fossil-scm.org/home/doc/<b>2009-01-01</b>/www/index.wiki
194194
</blockquote>
@@ -202,13 +202,13 @@
202202
A check-in name can also take the form of a tag or branch name followed by
203203
a colon and then a timestamp. The combination means to take the most
204204
recent check-in with the given tag or branch which is not more recent than
205205
the timestamp. So, for example:
206206
207
-<blockquote>
207
+<blockquote><tt>
208208
fossil update trunk:2010-07-01T14:30
209
-</blockquote>
209
+</tt></blockquote>
210210
211211
Would cause Fossil to update the working check-out to be the most recent
212212
check-in on the trunk that is not more recent than 14:30 (UTC) on
213213
July 1, 2010.
214214
@@ -218,13 +218,13 @@
218218
last check-in on the parent branch prior to the beginning of the branch.
219219
Such a label is useful, for example, in computing all diffs for a single
220220
branch. The following example will show all changes in the hypothetical
221221
branch "xyzzy":
222222
223
-<blockquote>
223
+<blockquote><tt>
224224
fossil diff --from root:xyzzy --to xyzzy
225
-</blockquote>
225
+</tt></blockquote>
226226
227227
<a id="merge-in"></a>
228228
That doesn't do what you might expect after you merge the parent
229229
branch's changes into the child branch: the above command will include
230230
changes made on the parent branch as well.
@@ -234,10 +234,19 @@
234234
the most recent merge-in point for that branch.
235235
The resulting diff will then show only the changes in
236236
the branch itself, omitting
237237
any changes that have already been merged in from the parent branch.
238238
239
+The prefixes "<tt>root:</tt>" and "<tt>merge-in:</tt>" can be chained: one
240
+can say for example
241
+
242
+<blockquote><tt>
243
+fossil info merge-in:xyzzy:2022-03-01
244
+</tt></blockquote>
245
+
246
+to get informations about the most recent merge-in point on the branch
247
+"xyzzy" that happened on or before March 1, 2022.
239248
240249
<h2 id="special">Special Tags</h2>
241250
242251
The tag "tip" means the most recent check-in. The "tip" tag is practically
243252
equivalent to the timestamp "9999-12-31".
244253
--- www/checkin_names.wiki
+++ www/checkin_names.wiki
@@ -98,13 +98,13 @@
98 is not anything special: it is simply a sequence of check-ins that
99 share a common tag, so the same mechanism that resolves tag names
100 also resolves branch names.
101
102 <a id="tagpfx"></a>
103 Note also that there can — in theory, if rarely in practice — be an ambiguity between tag names
104 and canonical names. Suppose, for example, you had a check-in with
105 the canonical name deed28aa99… and you
106 also happened to have tagged a different check-in with "deed2". If
107 you use the "deed2" name, does it choose the canonical name or the tag
108 name? In such cases, you can prefix the tag name with "tag:".
109 For example:
110
@@ -183,12 +183,12 @@
183
184 <blockquote>
185 http://fossil-scm.org/home/doc/<b>trunk</b>/www/index.wiki
186 </blockquote>
187
188 The bold component of that URL is a check-in name. To see the stored
189 content of the Fossil website repository as of January 1, 2009, one has merely to change
190 the URL to the following:
191
192 <blockquote>
193 http://fossil-scm.org/home/doc/<b>2009-01-01</b>/www/index.wiki
194 </blockquote>
@@ -202,13 +202,13 @@
202 A check-in name can also take the form of a tag or branch name followed by
203 a colon and then a timestamp. The combination means to take the most
204 recent check-in with the given tag or branch which is not more recent than
205 the timestamp. So, for example:
206
207 <blockquote>
208 fossil update trunk:2010-07-01T14:30
209 </blockquote>
210
211 Would cause Fossil to update the working check-out to be the most recent
212 check-in on the trunk that is not more recent than 14:30 (UTC) on
213 July 1, 2010.
214
@@ -218,13 +218,13 @@
218 last check-in on the parent branch prior to the beginning of the branch.
219 Such a label is useful, for example, in computing all diffs for a single
220 branch. The following example will show all changes in the hypothetical
221 branch "xyzzy":
222
223 <blockquote>
224 fossil diff --from root:xyzzy --to xyzzy
225 </blockquote>
226
227 <a id="merge-in"></a>
228 That doesn't do what you might expect after you merge the parent
229 branch's changes into the child branch: the above command will include
230 changes made on the parent branch as well.
@@ -234,10 +234,19 @@
234 the most recent merge-in point for that branch.
235 The resulting diff will then show only the changes in
236 the branch itself, omitting
237 any changes that have already been merged in from the parent branch.
238
 
 
 
 
 
 
 
 
 
239
240 <h2 id="special">Special Tags</h2>
241
242 The tag "tip" means the most recent check-in. The "tip" tag is practically
243 equivalent to the timestamp "9999-12-31".
244
--- www/checkin_names.wiki
+++ www/checkin_names.wiki
@@ -98,13 +98,13 @@
98 is not anything special: it is simply a sequence of check-ins that
99 share a common tag, so the same mechanism that resolves tag names
100 also resolves branch names.
101
102 <a id="tagpfx"></a>
103 Note also that there can — in theory, if rarely in practice — be an ambiguity
104 between tag names and canonical names. Suppose, for example, you had a
105 check-in with the canonical name deed28aa99… and you
106 also happened to have tagged a different check-in with "deed2". If
107 you use the "deed2" name, does it choose the canonical name or the tag
108 name? In such cases, you can prefix the tag name with "tag:".
109 For example:
110
@@ -183,12 +183,12 @@
183
184 <blockquote>
185 http://fossil-scm.org/home/doc/<b>trunk</b>/www/index.wiki
186 </blockquote>
187
188 The bold component of that URL is a check-in name. To see the stored content
189 of the Fossil website repository as of January 1, 2009, one has merely to change
190 the URL to the following:
191
192 <blockquote>
193 http://fossil-scm.org/home/doc/<b>2009-01-01</b>/www/index.wiki
194 </blockquote>
@@ -202,13 +202,13 @@
202 A check-in name can also take the form of a tag or branch name followed by
203 a colon and then a timestamp. The combination means to take the most
204 recent check-in with the given tag or branch which is not more recent than
205 the timestamp. So, for example:
206
207 <blockquote><tt>
208 fossil update trunk:2010-07-01T14:30
209 </tt></blockquote>
210
211 Would cause Fossil to update the working check-out to be the most recent
212 check-in on the trunk that is not more recent than 14:30 (UTC) on
213 July 1, 2010.
214
@@ -218,13 +218,13 @@
218 last check-in on the parent branch prior to the beginning of the branch.
219 Such a label is useful, for example, in computing all diffs for a single
220 branch. The following example will show all changes in the hypothetical
221 branch "xyzzy":
222
223 <blockquote><tt>
224 fossil diff --from root:xyzzy --to xyzzy
225 </tt></blockquote>
226
227 <a id="merge-in"></a>
228 That doesn't do what you might expect after you merge the parent
229 branch's changes into the child branch: the above command will include
230 changes made on the parent branch as well.
@@ -234,10 +234,19 @@
234 the most recent merge-in point for that branch.
235 The resulting diff will then show only the changes in
236 the branch itself, omitting
237 any changes that have already been merged in from the parent branch.
238
239 The prefixes "<tt>root:</tt>" and "<tt>merge-in:</tt>" can be chained: one
240 can say for example
241
242 <blockquote><tt>
243 fossil info merge-in:xyzzy:2022-03-01
244 </tt></blockquote>
245
246 to get informations about the most recent merge-in point on the branch
247 "xyzzy" that happened on or before March 1, 2022.
248
249 <h2 id="special">Special Tags</h2>
250
251 The tag "tip" means the most recent check-in. The "tip" tag is practically
252 equivalent to the timestamp "9999-12-31".
253
--- www/glossary.md
+++ www/glossary.md
@@ -298,7 +298,80 @@
298298
[h2cflp]: https://www.sqlite.org/howtocorrupt.html#_file_locking_problems
299299
[fpvsc]: https://marketplace.visualstudio.com/items?itemName=koog1000.fossil
300300
[open]: /help?cmd=open
301301
[mwd]: ./ckout-workflows.md#mcw
302302
[update]: /help?cmd=update
303
+
304
+
305
+## <a id="docs"></a>Embedded Documentation
306
+
307
+Serving as an alternative to Fossil’s built-in [wiki], the [embedded
308
+documentation feature][edoc] stores the same type of marked-up text
309
+files, but under Fossil’s powerful version control features.
310
+
311
+* The simple rule for determining whether to use the wiki or embedded
312
+ docs for any given document is whether the content is considered
313
+ “evergreen,” as with a Wikipedia article.
314
+
315
+ While Fossil’s wiki feature does store the history of each
316
+ document’s changes, Fossil always presents the current version of
317
+ the document unless you manually go out of your way to dig back into
318
+ the history. Then, having done so, links from that historical
319
+ version of the wiki document take you to the current versions of the
320
+ target documents, not to the version contemporaneous with the source
321
+ document.
322
+
323
+ The consequence is that if you say something like…
324
+
325
+ $ fossil up 2020-04-01
326
+ $ fossil ui --page wcontent
327
+
328
+ …you will **not** see the list of wiki articles as of April Fool’s Day in 2020, but
329
+ instead the list of *current* wiki article versions, the same as if you ran it
330
+ from a check-out of the tip-of-trunk.
331
+
332
+ Contrast embedded docs, which are not only version-controlled as
333
+ normal files are in Fossil, they participate in all the tagging,
334
+ branching, and other versioning features. There are several
335
+ consequences of this, such as that Fossil’s [special check-in
336
+ names][ciname] work with embedded doc URLs:
337
+
338
+ * <p>If you visit an embedded doc as `/doc/release/file.md` and
339
+ then click on a relative link from that document, you will remain on
340
+ the release branch. This lets you see not only the release
341
+ version of a software project but also the documentation as of
342
+ that release.</p>
343
+
344
+ * <p>If you visit `/doc/2020-04-01/file.md`, you will not only
345
+ pull up the version of `file.md` as of that date, relative links
346
+ will take you to contemporaneous versions of those embedded docs
347
+ as well.</p>
348
+
349
+ * <p>If you say `fossil up 2020-04-01 && fossil ui` and then visit
350
+ `/doc/ckout/file.md`, you’ll not only see the checked-out
351
+ version of the file as of that date, relative links will show
352
+ you other files within that checkout.</p>
353
+
354
+* Fossil’s wiki presents a flat list of articles, while embedded docs
355
+ are stored in the repository’s file hierarchy, a powerful
356
+ organizational tool well-suited to complicated documentation.
357
+
358
+* Your repository’s Home page is a good candidate for the wiki, as is
359
+ documentation meant for use only with the current version of the
360
+ repository’s contents.
361
+
362
+* If you are at all uncertain whether to use the wiki or the embedded
363
+ documentation feature, prefer the latter, since it is more powerful
364
+ and, with the addition of the [`/fileedit` feature][fef] in Fossil
365
+ 2.12, it’s nearly as easy to use.
366
+
367
+ (This very file is embedded documentation: clone
368
+ [Fossil’s self-hosting repository][fshr] and you will find it as
369
+ `www/glossary.md`.)
370
+
371
+[edoc]: ./embeddeddoc.wiki
372
+[fef]: ./fileedit-page.md
373
+[fshr]: ./selfhost.wiki
374
+[wiki]: ./wikitheory.wiki
375
+
303376
304377
<div style="height:50em" id="this-space-intentionally-left-blank"></div>
305378
--- www/glossary.md
+++ www/glossary.md
@@ -298,7 +298,80 @@
298 [h2cflp]: https://www.sqlite.org/howtocorrupt.html#_file_locking_problems
299 [fpvsc]: https://marketplace.visualstudio.com/items?itemName=koog1000.fossil
300 [open]: /help?cmd=open
301 [mwd]: ./ckout-workflows.md#mcw
302 [update]: /help?cmd=update
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
303
304 <div style="height:50em" id="this-space-intentionally-left-blank"></div>
305
--- www/glossary.md
+++ www/glossary.md
@@ -298,7 +298,80 @@
298 [h2cflp]: https://www.sqlite.org/howtocorrupt.html#_file_locking_problems
299 [fpvsc]: https://marketplace.visualstudio.com/items?itemName=koog1000.fossil
300 [open]: /help?cmd=open
301 [mwd]: ./ckout-workflows.md#mcw
302 [update]: /help?cmd=update
303
304
305 ## <a id="docs"></a>Embedded Documentation
306
307 Serving as an alternative to Fossil’s built-in [wiki], the [embedded
308 documentation feature][edoc] stores the same type of marked-up text
309 files, but under Fossil’s powerful version control features.
310
311 * The simple rule for determining whether to use the wiki or embedded
312 docs for any given document is whether the content is considered
313 “evergreen,” as with a Wikipedia article.
314
315 While Fossil’s wiki feature does store the history of each
316 document’s changes, Fossil always presents the current version of
317 the document unless you manually go out of your way to dig back into
318 the history. Then, having done so, links from that historical
319 version of the wiki document take you to the current versions of the
320 target documents, not to the version contemporaneous with the source
321 document.
322
323 The consequence is that if you say something like…
324
325 $ fossil up 2020-04-01
326 $ fossil ui --page wcontent
327
328 …you will **not** see the list of wiki articles as of April Fool’s Day in 2020, but
329 instead the list of *current* wiki article versions, the same as if you ran it
330 from a check-out of the tip-of-trunk.
331
332 Contrast embedded docs, which are not only version-controlled as
333 normal files are in Fossil, they participate in all the tagging,
334 branching, and other versioning features. There are several
335 consequences of this, such as that Fossil’s [special check-in
336 names][ciname] work with embedded doc URLs:
337
338 * <p>If you visit an embedded doc as `/doc/release/file.md` and
339 then click on a relative link from that document, you will remain on
340 the release branch. This lets you see not only the release
341 version of a software project but also the documentation as of
342 that release.</p>
343
344 * <p>If you visit `/doc/2020-04-01/file.md`, you will not only
345 pull up the version of `file.md` as of that date, relative links
346 will take you to contemporaneous versions of those embedded docs
347 as well.</p>
348
349 * <p>If you say `fossil up 2020-04-01 && fossil ui` and then visit
350 `/doc/ckout/file.md`, you’ll not only see the checked-out
351 version of the file as of that date, relative links will show
352 you other files within that checkout.</p>
353
354 * Fossil’s wiki presents a flat list of articles, while embedded docs
355 are stored in the repository’s file hierarchy, a powerful
356 organizational tool well-suited to complicated documentation.
357
358 * Your repository’s Home page is a good candidate for the wiki, as is
359 documentation meant for use only with the current version of the
360 repository’s contents.
361
362 * If you are at all uncertain whether to use the wiki or the embedded
363 documentation feature, prefer the latter, since it is more powerful
364 and, with the addition of the [`/fileedit` feature][fef] in Fossil
365 2.12, it’s nearly as easy to use.
366
367 (This very file is embedded documentation: clone
368 [Fossil’s self-hosting repository][fshr] and you will find it as
369 `www/glossary.md`.)
370
371 [edoc]: ./embeddeddoc.wiki
372 [fef]: ./fileedit-page.md
373 [fshr]: ./selfhost.wiki
374 [wiki]: ./wikitheory.wiki
375
376
377 <div style="height:50em" id="this-space-intentionally-left-blank"></div>
378
+34 -25
--- www/grep.md
+++ www/grep.md
@@ -1,58 +1,67 @@
11
# Fossil grep vs POSIX grep
22
33
As of Fossil 2.7, there is a `grep` command which acts roughly like
4
-POSIX's `grep -E` over all historical versions of a single file name.
4
+POSIX's `grep -E` over all historical versions of one or more managed files.
55
This document explains the commonalities and divergences between [POSIX
66
`grep`](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html)
77
and Fossil `grep`.
88
99
1010
## Options
1111
12
-Fossil `grep` supports only a small subset of the options specified for
12
+Fossil `grep` implements about half of the options specified for
1313
POSIX `grep`:
1414
1515
| Option | Meaning
1616
|--------|-------------------------------------------------------------
17
+| `-c` | report the count of matches rather than the matched text
1718
| `-i` | ignore case in matches
1819
| `-l` | list a checkin ID prefix for matching historical versions of the file
19
-| `-v` | print each checkin ID considered, regardless of whether it matches
20
-
21
-That leaves many divergences at the option level from POSIX `grep`:
22
-
23
-* There is no built-in way to get a count of matches, as with
24
- `grep -c`.
25
-
26
-* You cannot give more than one pattern, as with `grep -e` or
27
- `grep -f`.
20
+| `-q` | no output; return only a status code indicating the success of the match
21
+| `-s` | suppress error output about missing files
22
+| `-v` | invert the sense of the match
23
+
24
+That leaves several divergences at the option level from POSIX `grep`:
25
+
26
+* You cannot give more than one pattern, as with `grep -e` or
27
+ `grep -f`.
2828
2929
* There is no equivalent of `grep -F` to do literal fixed-string
3030
matches only.
31
+
32
+* There is no `-x` option for doing a whole-line match.
3133
3234
* `fossil grep -l` does not do precisely the same thing as POSIX
3335
`grep -l`: it lists checkin ID prefixes, not file names.
3436
3537
* Fossil always gives the line number in its output, which is to say
3638
that it acts like `grep -n`. There is no way to disable the line
3739
number in `fossil grep` output.
3840
39
-* There is no way to suppress all output, returning only a status code
40
- to indicate whether the pattern matched, as with `grep -q`.
41
-
42
-* There is no way to suppress error output, as with `grep -s`.
43
-
44
-* Fossil `grep` does not accept a directory name for Fossil to
45
- expand to the set of all files under that directory. This means
46
- Fossil `grep` has no equivalent of the common POSIX `grep -R`
47
- extension. (And if it did, it would probably have a different
48
- option letter, since `-R` in Fossil has a different meaning, by
49
- convention.)
50
-
51
-* You cannot invert the match, as with `grep -v`.
52
-
5341
Patches to remove those limitations will be thoughtfully considered.
42
+
43
+Fossil `grep` doesn’t support any of the GNU and BSD `grep` extensions.
44
+For instance, it doesn’t support the common `-R` extension to POSIX,
45
+which would presumably search a subtree of managed files. If Fossil does
46
+one day get this feature, it would have a different option letter, since
47
+`-R` in Fossil has a different meaning, by convention. Until then, you
48
+can get the same effect on systems with a POSIX shell like so:
49
+
50
+ $ fossil grep COMMAND: $(fossil ls src)
51
+
52
+If you run that in a check-out of the [Fossil self-hosting source
53
+repository][fshsr], that returns the first line of the built-in
54
+documentation for each Fossil command, across all historical verisons.
55
+
56
+Fossil `grep` has extensions relative to these other `grep` standards,
57
+such as `--verbose` to print each checkin ID considered, regardless of
58
+whether it matches. This one is noteworthy here because the behavior
59
+used to be under `-v` before we reassigned it to give POSIX-like `grep
60
+-v` behavior.
61
+
62
+[fshsr]: ./selfhost.wiki
5463
5564
5665
## Regular Expression Dialect
5766
5867
Fossil contains a built-in regular expression engine implementing a
5968
--- www/grep.md
+++ www/grep.md
@@ -1,58 +1,67 @@
1 # Fossil grep vs POSIX grep
2
3 As of Fossil 2.7, there is a `grep` command which acts roughly like
4 POSIX's `grep -E` over all historical versions of a single file name.
5 This document explains the commonalities and divergences between [POSIX
6 `grep`](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html)
7 and Fossil `grep`.
8
9
10 ## Options
11
12 Fossil `grep` supports only a small subset of the options specified for
13 POSIX `grep`:
14
15 | Option | Meaning
16 |--------|-------------------------------------------------------------
 
17 | `-i` | ignore case in matches
18 | `-l` | list a checkin ID prefix for matching historical versions of the file
19 | `-v` | print each checkin ID considered, regardless of whether it matches
20
21 That leaves many divergences at the option level from POSIX `grep`:
22
23 * There is no built-in way to get a count of matches, as with
24 `grep -c`.
25
26 * You cannot give more than one pattern, as with `grep -e` or
27 `grep -f`.
28
29 * There is no equivalent of `grep -F` to do literal fixed-string
30 matches only.
 
 
31
32 * `fossil grep -l` does not do precisely the same thing as POSIX
33 `grep -l`: it lists checkin ID prefixes, not file names.
34
35 * Fossil always gives the line number in its output, which is to say
36 that it acts like `grep -n`. There is no way to disable the line
37 number in `fossil grep` output.
38
39 * There is no way to suppress all output, returning only a status code
40 to indicate whether the pattern matched, as with `grep -q`.
41
42 * There is no way to suppress error output, as with `grep -s`.
43
44 * Fossil `grep` does not accept a directory name for Fossil to
45 expand to the set of all files under that directory. This means
46 Fossil `grep` has no equivalent of the common POSIX `grep -R`
47 extension. (And if it did, it would probably have a different
48 option letter, since `-R` in Fossil has a different meaning, by
49 convention.)
50
51 * You cannot invert the match, as with `grep -v`.
52
53 Patches to remove those limitations will be thoughtfully considered.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
55
56 ## Regular Expression Dialect
57
58 Fossil contains a built-in regular expression engine implementing a
59
--- www/grep.md
+++ www/grep.md
@@ -1,58 +1,67 @@
1 # Fossil grep vs POSIX grep
2
3 As of Fossil 2.7, there is a `grep` command which acts roughly like
4 POSIX's `grep -E` over all historical versions of one or more managed files.
5 This document explains the commonalities and divergences between [POSIX
6 `grep`](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html)
7 and Fossil `grep`.
8
9
10 ## Options
11
12 Fossil `grep` implements about half of the options specified for
13 POSIX `grep`:
14
15 | Option | Meaning
16 |--------|-------------------------------------------------------------
17 | `-c` | report the count of matches rather than the matched text
18 | `-i` | ignore case in matches
19 | `-l` | list a checkin ID prefix for matching historical versions of the file
20 | `-q` | no output; return only a status code indicating the success of the match
21 | `-s` | suppress error output about missing files
22 | `-v` | invert the sense of the match
23
24 That leaves several divergences at the option level from POSIX `grep`:
25
26 * You cannot give more than one pattern, as with `grep -e` or
27 `grep -f`.
 
28
29 * There is no equivalent of `grep -F` to do literal fixed-string
30 matches only.
31
32 * There is no `-x` option for doing a whole-line match.
33
34 * `fossil grep -l` does not do precisely the same thing as POSIX
35 `grep -l`: it lists checkin ID prefixes, not file names.
36
37 * Fossil always gives the line number in its output, which is to say
38 that it acts like `grep -n`. There is no way to disable the line
39 number in `fossil grep` output.
40
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41 Patches to remove those limitations will be thoughtfully considered.
42
43 Fossil `grep` doesn’t support any of the GNU and BSD `grep` extensions.
44 For instance, it doesn’t support the common `-R` extension to POSIX,
45 which would presumably search a subtree of managed files. If Fossil does
46 one day get this feature, it would have a different option letter, since
47 `-R` in Fossil has a different meaning, by convention. Until then, you
48 can get the same effect on systems with a POSIX shell like so:
49
50 $ fossil grep COMMAND: $(fossil ls src)
51
52 If you run that in a check-out of the [Fossil self-hosting source
53 repository][fshsr], that returns the first line of the built-in
54 documentation for each Fossil command, across all historical verisons.
55
56 Fossil `grep` has extensions relative to these other `grep` standards,
57 such as `--verbose` to print each checkin ID considered, regardless of
58 whether it matches. This one is noteworthy here because the behavior
59 used to be under `-v` before we reassigned it to give POSIX-like `grep
60 -v` behavior.
61
62 [fshsr]: ./selfhost.wiki
63
64
65 ## Regular Expression Dialect
66
67 Fossil contains a built-in regular expression engine implementing a
68
--- www/json-api/conventions.md
+++ www/json-api/conventions.md
@@ -181,12 +181,12 @@
181181
but few, if any, use negative values).
182182
183183
**Boolean** parameters are a bit schizophrenic...
184184
185185
In **CLI mode**, boolean flags do not have a value, per se, and thus
186
-require no string-to-bool conversion. e.g. `fossil foo -aBoolOpt
187
--non-bool-opt value`.
186
+require no string-to-bool conversion. e.g.
187
+`fossil foo -aBoolOpt -non-bool-opt value`.
188188
189189
Those which arrive as strings via **GET parameters** treat any of the
190190
following as true: a string starting with a character in the set
191191
`[1-9tT]`. All other string values are considered to be false for this
192192
purpose.
193193
--- www/json-api/conventions.md
+++ www/json-api/conventions.md
@@ -181,12 +181,12 @@
181 but few, if any, use negative values).
182
183 **Boolean** parameters are a bit schizophrenic...
184
185 In **CLI mode**, boolean flags do not have a value, per se, and thus
186 require no string-to-bool conversion. e.g. `fossil foo -aBoolOpt
187 -non-bool-opt value`.
188
189 Those which arrive as strings via **GET parameters** treat any of the
190 following as true: a string starting with a character in the set
191 `[1-9tT]`. All other string values are considered to be false for this
192 purpose.
193
--- www/json-api/conventions.md
+++ www/json-api/conventions.md
@@ -181,12 +181,12 @@
181 but few, if any, use negative values).
182
183 **Boolean** parameters are a bit schizophrenic...
184
185 In **CLI mode**, boolean flags do not have a value, per se, and thus
186 require no string-to-bool conversion. e.g.
187 `fossil foo -aBoolOpt -non-bool-opt value`.
188
189 Those which arrive as strings via **GET parameters** treat any of the
190 following as true: a string starting with a character in the set
191 `[1-9tT]`. All other string values are considered to be false for this
192 purpose.
193
--- www/json-api/hacking.md
+++ www/json-api/hacking.md
@@ -38,11 +38,11 @@
3838
3939
<a id="json-c-api"></a>
4040
# JSON C API
4141
4242
libcson, the underlying JSON API, is a separate project, included in
43
-fossil in "amalgamation" form: see `src/cson_amalgamation.[ch]`. It has
43
+fossil in "amalgamation" form: see `extsrc/cson_amalgamation.[ch]`. It has
4444
thorough API docs and a good deal of information is in its wiki:
4545
4646
[](https://fossil.wanderinghorse.net/wikis/cson/)
4747
4848
In particular:
@@ -51,12 +51,12 @@
5151
5252
gives an overview of its architecture. Occasionally new versions of it
5353
are pulled into the Fossil tree, but other developers generally need not
5454
concern themselves with that.
5555
56
-(Trivia: the cson wiki's back-end is fossil, living on top of a
57
-JavaScript+HTML5 application.)
56
+(Trivia: the cson wiki's back-end is fossil using this very JSON API,
57
+living on top of a custom JavaScript+HTML5 application.)
5858
5959
Only a small handful of low-level fossil routines actually input or
6060
output JSON text (only for reading in POST data and sending the
6161
response). In the C code we work with the higher-level JSON value
6262
abstractions provided by cson (conceptually similar to an XML DOM). All
@@ -309,11 +309,11 @@
309309
The `cson_sqlite3_xxx()` family of functions convert `sqlite3_stmt` rows
310310
to Arrays or Objects, or convert single columns to a JSON-compatible
311311
form. See `json_stmt_to_array_of_obj()`,
312312
`json_stmt_to_array_of_array()` (both in `src/json.c`), and
313313
`cson_sqlite3_column_to_value()` and friends (in
314
-`src/cson_amalgamation.h`). They work in an intuitive way for numeric
314
+`extsrc/cson_amalgamation.h`). They work in an intuitive way for numeric
315315
types, but they optimistically/natively *assume* that any fields of type
316316
TEXT or BLOB are actually UTF8 data, and treat them as such. cson's
317317
string class only handles UTF8 data and it is semantically illegal to
318318
feed them anything but UTF8. Violating this will likely result in
319319
down-stream errors (e.g. when emiting the JSON string output). **The
320320
--- www/json-api/hacking.md
+++ www/json-api/hacking.md
@@ -38,11 +38,11 @@
38
39 <a id="json-c-api"></a>
40 # JSON C API
41
42 libcson, the underlying JSON API, is a separate project, included in
43 fossil in "amalgamation" form: see `src/cson_amalgamation.[ch]`. It has
44 thorough API docs and a good deal of information is in its wiki:
45
46 [](https://fossil.wanderinghorse.net/wikis/cson/)
47
48 In particular:
@@ -51,12 +51,12 @@
51
52 gives an overview of its architecture. Occasionally new versions of it
53 are pulled into the Fossil tree, but other developers generally need not
54 concern themselves with that.
55
56 (Trivia: the cson wiki's back-end is fossil, living on top of a
57 JavaScript+HTML5 application.)
58
59 Only a small handful of low-level fossil routines actually input or
60 output JSON text (only for reading in POST data and sending the
61 response). In the C code we work with the higher-level JSON value
62 abstractions provided by cson (conceptually similar to an XML DOM). All
@@ -309,11 +309,11 @@
309 The `cson_sqlite3_xxx()` family of functions convert `sqlite3_stmt` rows
310 to Arrays or Objects, or convert single columns to a JSON-compatible
311 form. See `json_stmt_to_array_of_obj()`,
312 `json_stmt_to_array_of_array()` (both in `src/json.c`), and
313 `cson_sqlite3_column_to_value()` and friends (in
314 `src/cson_amalgamation.h`). They work in an intuitive way for numeric
315 types, but they optimistically/natively *assume* that any fields of type
316 TEXT or BLOB are actually UTF8 data, and treat them as such. cson's
317 string class only handles UTF8 data and it is semantically illegal to
318 feed them anything but UTF8. Violating this will likely result in
319 down-stream errors (e.g. when emiting the JSON string output). **The
320
--- www/json-api/hacking.md
+++ www/json-api/hacking.md
@@ -38,11 +38,11 @@
38
39 <a id="json-c-api"></a>
40 # JSON C API
41
42 libcson, the underlying JSON API, is a separate project, included in
43 fossil in "amalgamation" form: see `extsrc/cson_amalgamation.[ch]`. It has
44 thorough API docs and a good deal of information is in its wiki:
45
46 [](https://fossil.wanderinghorse.net/wikis/cson/)
47
48 In particular:
@@ -51,12 +51,12 @@
51
52 gives an overview of its architecture. Occasionally new versions of it
53 are pulled into the Fossil tree, but other developers generally need not
54 concern themselves with that.
55
56 (Trivia: the cson wiki's back-end is fossil using this very JSON API,
57 living on top of a custom JavaScript+HTML5 application.)
58
59 Only a small handful of low-level fossil routines actually input or
60 output JSON text (only for reading in POST data and sending the
61 response). In the C code we work with the higher-level JSON value
62 abstractions provided by cson (conceptually similar to an XML DOM). All
@@ -309,11 +309,11 @@
309 The `cson_sqlite3_xxx()` family of functions convert `sqlite3_stmt` rows
310 to Arrays or Objects, or convert single columns to a JSON-compatible
311 form. See `json_stmt_to_array_of_obj()`,
312 `json_stmt_to_array_of_array()` (both in `src/json.c`), and
313 `cson_sqlite3_column_to_value()` and friends (in
314 `extsrc/cson_amalgamation.h`). They work in an intuitive way for numeric
315 types, but they optimistically/natively *assume* that any fields of type
316 TEXT or BLOB are actually UTF8 data, and treat them as such. cson's
317 string class only handles UTF8 data and it is semantically illegal to
318 feed them anything but UTF8. Violating this will likely result in
319 down-stream errors (e.g. when emiting the JSON string output). **The
320
--- www/mkindex.tcl
+++ www/mkindex.tcl
@@ -78,10 +78,11 @@
7878
index.wiki {Home Page}
7979
inout.wiki {Import And Export To And From Git}
8080
interwiki.md {Interwiki Links}
8181
image-format-vs-repo-size.md {Image Format vs Fossil Repo Size}
8282
javascript.md {Use of JavaScript in Fossil}
83
+ json-api/index.md {JSON API}
8384
loadmgmt.md {Managing Server Load}
8485
makefile.wiki {The Fossil Build Process}
8586
mirrorlimitations.md {Limitations On Git Mirrors}
8687
mirrortogithub.md {How To Mirror A Fossil Repository On GitHub}
8788
/md_rules {Markdown Formatting Rules}
8889
--- www/mkindex.tcl
+++ www/mkindex.tcl
@@ -78,10 +78,11 @@
78 index.wiki {Home Page}
79 inout.wiki {Import And Export To And From Git}
80 interwiki.md {Interwiki Links}
81 image-format-vs-repo-size.md {Image Format vs Fossil Repo Size}
82 javascript.md {Use of JavaScript in Fossil}
 
83 loadmgmt.md {Managing Server Load}
84 makefile.wiki {The Fossil Build Process}
85 mirrorlimitations.md {Limitations On Git Mirrors}
86 mirrortogithub.md {How To Mirror A Fossil Repository On GitHub}
87 /md_rules {Markdown Formatting Rules}
88
--- www/mkindex.tcl
+++ www/mkindex.tcl
@@ -78,10 +78,11 @@
78 index.wiki {Home Page}
79 inout.wiki {Import And Export To And From Git}
80 interwiki.md {Interwiki Links}
81 image-format-vs-repo-size.md {Image Format vs Fossil Repo Size}
82 javascript.md {Use of JavaScript in Fossil}
83 json-api/index.md {JSON API}
84 loadmgmt.md {Managing Server Load}
85 makefile.wiki {The Fossil Build Process}
86 mirrorlimitations.md {Limitations On Git Mirrors}
87 mirrortogithub.md {How To Mirror A Fossil Repository On GitHub}
88 /md_rules {Markdown Formatting Rules}
89
--- www/permutedindex.html
+++ www/permutedindex.html
@@ -40,11 +40,11 @@
4040
<li><a href="contribute.wiki">Contributing Code or Documentation To The Fossil Project</a></li>
4141
<li><a href="copyright-release.html">Contributor License Agreement</a></li>
4242
<li><a href="private.wiki">Creating, Syncing, and Deleting Private Branches</a></li>
4343
<li><a href="customskin.md">Custom Skins</a></li>
4444
<li><a href="custom_ticket.wiki">Customizing The Ticket System</a></li>
45
-<li><a href="antibot.wiki">Defense against Spiders and Bots</a></li>
45
+<li><a href="antibot.wiki">Defense against Spiders and Robots</a></li>
4646
<li><a href="delta-manifests.md">Delta Manifests</a></li>
4747
<li><a href="contact.md">Developer Contact Information</a></li>
4848
<li><a href="caps/admin-v-setup.md">Differences Between Setup and Admin Users</a></li>
4949
<li><a href="alerts.md">Email Alerts And Notifications</a></li>
5050
<li><a href="embeddeddoc.wiki">Embedded Project Documentation</a></li>
@@ -87,10 +87,11 @@
8787
<li><a href="inout.wiki">Import And Export To And From Git</a></li>
8888
<li><a href="fossil-from-msvc.wiki">Integrating Fossil in the Microsoft Express 2010 IDE</a></li>
8989
<li><a href="interwiki.md">Interwiki Links</a></li>
9090
<li><a href="fossil-is-not-relational.md">Introduction to the (Non-relational) Fossil Data Model</a></li>
9191
<li><a href="blockchain.md">Is Fossil A Blockchain?</a></li>
92
+<li><a href="json-api/index.md">JSON API</a></li>
9293
<li><a href="mirrorlimitations.md">Limitations On Git Mirrors</a></li>
9394
<li><a href="../../../help">Lists of Commands and Webpages</a></li>
9495
<li><a href="loadmgmt.md">Managing Server Load</a></li>
9596
<li><a href="../../../md_rules">Markdown Formatting Rules</a></li>
9697
<li><a href="password.wiki">Password Management And Authentication</a></li>
9798
--- www/permutedindex.html
+++ www/permutedindex.html
@@ -40,11 +40,11 @@
40 <li><a href="contribute.wiki">Contributing Code or Documentation To The Fossil Project</a></li>
41 <li><a href="copyright-release.html">Contributor License Agreement</a></li>
42 <li><a href="private.wiki">Creating, Syncing, and Deleting Private Branches</a></li>
43 <li><a href="customskin.md">Custom Skins</a></li>
44 <li><a href="custom_ticket.wiki">Customizing The Ticket System</a></li>
45 <li><a href="antibot.wiki">Defense against Spiders and Bots</a></li>
46 <li><a href="delta-manifests.md">Delta Manifests</a></li>
47 <li><a href="contact.md">Developer Contact Information</a></li>
48 <li><a href="caps/admin-v-setup.md">Differences Between Setup and Admin Users</a></li>
49 <li><a href="alerts.md">Email Alerts And Notifications</a></li>
50 <li><a href="embeddeddoc.wiki">Embedded Project Documentation</a></li>
@@ -87,10 +87,11 @@
87 <li><a href="inout.wiki">Import And Export To And From Git</a></li>
88 <li><a href="fossil-from-msvc.wiki">Integrating Fossil in the Microsoft Express 2010 IDE</a></li>
89 <li><a href="interwiki.md">Interwiki Links</a></li>
90 <li><a href="fossil-is-not-relational.md">Introduction to the (Non-relational) Fossil Data Model</a></li>
91 <li><a href="blockchain.md">Is Fossil A Blockchain?</a></li>
 
92 <li><a href="mirrorlimitations.md">Limitations On Git Mirrors</a></li>
93 <li><a href="../../../help">Lists of Commands and Webpages</a></li>
94 <li><a href="loadmgmt.md">Managing Server Load</a></li>
95 <li><a href="../../../md_rules">Markdown Formatting Rules</a></li>
96 <li><a href="password.wiki">Password Management And Authentication</a></li>
97
--- www/permutedindex.html
+++ www/permutedindex.html
@@ -40,11 +40,11 @@
40 <li><a href="contribute.wiki">Contributing Code or Documentation To The Fossil Project</a></li>
41 <li><a href="copyright-release.html">Contributor License Agreement</a></li>
42 <li><a href="private.wiki">Creating, Syncing, and Deleting Private Branches</a></li>
43 <li><a href="customskin.md">Custom Skins</a></li>
44 <li><a href="custom_ticket.wiki">Customizing The Ticket System</a></li>
45 <li><a href="antibot.wiki">Defense against Spiders and Robots</a></li>
46 <li><a href="delta-manifests.md">Delta Manifests</a></li>
47 <li><a href="contact.md">Developer Contact Information</a></li>
48 <li><a href="caps/admin-v-setup.md">Differences Between Setup and Admin Users</a></li>
49 <li><a href="alerts.md">Email Alerts And Notifications</a></li>
50 <li><a href="embeddeddoc.wiki">Embedded Project Documentation</a></li>
@@ -87,10 +87,11 @@
87 <li><a href="inout.wiki">Import And Export To And From Git</a></li>
88 <li><a href="fossil-from-msvc.wiki">Integrating Fossil in the Microsoft Express 2010 IDE</a></li>
89 <li><a href="interwiki.md">Interwiki Links</a></li>
90 <li><a href="fossil-is-not-relational.md">Introduction to the (Non-relational) Fossil Data Model</a></li>
91 <li><a href="blockchain.md">Is Fossil A Blockchain?</a></li>
92 <li><a href="json-api/index.md">JSON API</a></li>
93 <li><a href="mirrorlimitations.md">Limitations On Git Mirrors</a></li>
94 <li><a href="../../../help">Lists of Commands and Webpages</a></li>
95 <li><a href="loadmgmt.md">Managing Server Load</a></li>
96 <li><a href="../../../md_rules">Markdown Formatting Rules</a></li>
97 <li><a href="password.wiki">Password Management And Authentication</a></li>
98

Keyboard Shortcuts

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